|
16 | 16 |
|
17 | 17 | /// <reference types="jest" />
|
18 | 18 |
|
19 |
| -//jest.mock('./client'); |
20 |
| - |
21 | 19 | import React from 'react';
|
22 |
| -import { render, act } from '@testing-library/react'; |
| 20 | +import { render, waitFor } from '@testing-library/react'; |
23 | 21 | import { OptimizelyProvider } from './Provider';
|
24 |
| -import { DefaultUser, ReactSDKClient, createInstance } from './client'; |
| 22 | +import { DefaultUser, ReactSDKClient } from './client'; |
| 23 | +import { getLogger } from '@optimizely/optimizely-sdk'; |
| 24 | + |
| 25 | +jest.mock('@optimizely/optimizely-sdk', () => { |
| 26 | + const originalModule = jest.requireActual('@optimizely/optimizely-sdk'); |
| 27 | + return { |
| 28 | + ...originalModule, |
| 29 | + getLogger: jest.fn().mockReturnValue({ |
| 30 | + error: jest.fn(), |
| 31 | + warn: jest.fn(), |
| 32 | + info: jest.fn(), |
| 33 | + debug: jest.fn(), |
| 34 | + }), |
| 35 | + }; |
| 36 | +}); |
| 37 | + |
| 38 | +const logger = getLogger('<OptimizelyProvider>'); |
25 | 39 |
|
26 | 40 | describe('OptimizelyProvider', () => {
|
27 | 41 | let mockReactClient: ReactSDKClient;
|
28 |
| - const config = { |
29 |
| - datafile: {}, |
| 42 | + const user1 = { |
| 43 | + id: 'user1', |
| 44 | + attributes: { attr1: 'value1' }, |
30 | 45 | };
|
31 |
| - |
32 | 46 | beforeEach(() => {
|
33 | 47 | mockReactClient = {
|
34 |
| - user: { |
35 |
| - id: 'test-id', |
36 |
| - attributes: {}, |
37 |
| - }, |
| 48 | + user: user1, |
38 | 49 | setUser: jest.fn().mockResolvedValue(undefined),
|
39 | 50 | } as unknown as ReactSDKClient;
|
40 | 51 | });
|
41 | 52 |
|
| 53 | + it('should log error if optimizely is not provided', async () => { |
| 54 | + // @ts-ignore |
| 55 | + render(<OptimizelyProvider optimizely={null} />); |
| 56 | + expect(logger.error).toHaveBeenCalled(); |
| 57 | + }); |
| 58 | + |
| 59 | + it('should resolve user promise and set user in optimizely', async () => { |
| 60 | + render(<OptimizelyProvider optimizely={mockReactClient} user={Promise.resolve(user1)} />); |
| 61 | + await waitFor(() => expect(mockReactClient.setUser).toHaveBeenCalledWith(user1)); |
| 62 | + }); |
| 63 | + |
42 | 64 | it('should render successfully with user provided', () => {
|
43 |
| - act(() => { |
44 |
| - render(<OptimizelyProvider optimizely={mockReactClient} user={{ id: 'user1' }} />); |
45 |
| - }); |
| 65 | + render(<OptimizelyProvider optimizely={mockReactClient} user={user1} />); |
46 | 66 |
|
47 |
| - expect(mockReactClient.setUser).toHaveBeenCalledWith({ |
48 |
| - id: 'user1', |
49 |
| - attributes: {}, |
50 |
| - }); |
| 67 | + expect(mockReactClient.setUser).toHaveBeenCalledWith(user1); |
| 68 | + }); |
| 69 | + |
| 70 | + it('should throw error, if setUser throws error', () => { |
| 71 | + mockReactClient.setUser = jest.fn().mockRejectedValue(new Error('error')); |
| 72 | + render(<OptimizelyProvider optimizely={mockReactClient} user={user1} />); |
| 73 | + expect(logger.error).toHaveBeenCalled(); |
51 | 74 | });
|
52 | 75 |
|
53 | 76 | it('should render successfully with userId provided', () => {
|
54 |
| - act(() => { |
55 |
| - render(<OptimizelyProvider optimizely={mockReactClient} userId="user1" />); |
56 |
| - }); |
| 77 | + render(<OptimizelyProvider optimizely={mockReactClient} userId={user1.id} />); |
57 | 78 |
|
58 | 79 | expect(mockReactClient.setUser).toHaveBeenCalledWith({
|
59 |
| - id: 'user1', |
| 80 | + id: user1.id, |
60 | 81 | attributes: {},
|
61 | 82 | });
|
62 | 83 | });
|
63 | 84 |
|
64 | 85 | it('should render successfully without user or userId provided', () => {
|
65 |
| - act(() => { |
66 |
| - render(<OptimizelyProvider optimizely={mockReactClient} />); |
67 |
| - }); |
| 86 | + render(<OptimizelyProvider optimizely={mockReactClient} />); |
68 | 87 |
|
69 | 88 | expect(mockReactClient.setUser).toHaveBeenCalledWith(DefaultUser);
|
70 | 89 | });
|
71 | 90 |
|
72 | 91 | it('should render successfully with user id & attributes provided', () => {
|
73 |
| - act(() => { |
74 |
| - render( |
75 |
| - <OptimizelyProvider optimizely={mockReactClient} user={{ id: 'user1', attributes: { attr1: 'value1' } }} /> |
76 |
| - ); |
77 |
| - }); |
| 92 | + render(<OptimizelyProvider optimizely={mockReactClient} user={user1} />); |
78 | 93 |
|
79 |
| - expect(mockReactClient.setUser).toHaveBeenCalledWith({ |
80 |
| - id: 'user1', |
81 |
| - attributes: { attr1: 'value1' }, |
82 |
| - }); |
| 94 | + expect(mockReactClient.setUser).toHaveBeenCalledWith(user1); |
83 | 95 | });
|
84 | 96 |
|
85 | 97 | it('should succeed just userAttributes provided', () => {
|
86 |
| - act(() => { |
87 |
| - render(<OptimizelyProvider optimizely={mockReactClient} userAttributes={{ attr1: 'value1' }} />); |
88 |
| - }); |
| 98 | + render(<OptimizelyProvider optimizely={mockReactClient} userAttributes={{ attr1: 'value1' }} />); |
89 | 99 |
|
90 | 100 | expect(mockReactClient.setUser).toHaveBeenCalledWith({
|
91 | 101 | id: DefaultUser.id,
|
92 | 102 | attributes: { attr1: 'value1' },
|
93 | 103 | });
|
94 | 104 | });
|
| 105 | + |
| 106 | + it('should not update when isServerSide is true', () => { |
| 107 | + // Initial render |
| 108 | + const { rerender } = render(<OptimizelyProvider optimizely={mockReactClient} isServerSide={true} user={user1} />); |
| 109 | + |
| 110 | + // Reset mock to clear the initial constructor call |
| 111 | + (mockReactClient.setUser as jest.Mock).mockClear(); |
| 112 | + |
| 113 | + // Re-render with same `isServerSide` value |
| 114 | + rerender(<OptimizelyProvider optimizely={mockReactClient} isServerSide={true} user={user1} />); |
| 115 | + |
| 116 | + expect(mockReactClient.setUser).not.toHaveBeenCalled(); |
| 117 | + }); |
| 118 | + |
| 119 | + it('should set user if optimizely.user.id is not set', () => { |
| 120 | + mockReactClient.user = { id: '', attributes: {} }; |
| 121 | + const { rerender } = render(<OptimizelyProvider optimizely={mockReactClient} />); |
| 122 | + |
| 123 | + // Change props to trigger componentDidUpdate |
| 124 | + rerender(<OptimizelyProvider optimizely={mockReactClient} user={user1} />); |
| 125 | + |
| 126 | + expect(mockReactClient.setUser).toHaveBeenCalledWith(user1); |
| 127 | + }); |
| 128 | + |
| 129 | + it('should update user if users are not equal', () => { |
| 130 | + const user2 = { id: 'user-2', attributes: {} }; |
| 131 | + |
| 132 | + const { rerender } = render(<OptimizelyProvider optimizely={mockReactClient} user={user1} />); |
| 133 | + |
| 134 | + // Change props to a different user to trigger componentDidUpdate |
| 135 | + rerender(<OptimizelyProvider optimizely={mockReactClient} user={user2} />); |
| 136 | + |
| 137 | + expect(mockReactClient.setUser).toHaveBeenCalledWith(user2); |
| 138 | + }); |
| 139 | + |
| 140 | + it('should not update user if users are equal', () => { |
| 141 | + const { rerender } = render(<OptimizelyProvider optimizely={mockReactClient} user={user1} />); |
| 142 | + // Reset mock to clear the initial constructor call |
| 143 | + (mockReactClient.setUser as jest.Mock).mockClear(); |
| 144 | + // Change props with the same user to trigger componentDidUpdate |
| 145 | + rerender(<OptimizelyProvider optimizely={mockReactClient} user={user1} />); |
| 146 | + |
| 147 | + expect(mockReactClient.setUser).not.toHaveBeenCalled(); |
| 148 | + }); |
95 | 149 | });
|
0 commit comments