Skip to content

Commit 62a12ff

Browse files
[FSSDK-10439] client provider test (#278)
* [FSSDK-10439] provider test cleanup * [FSSDK-10439] client test deprecated API update * [FSSDK-10439] client test: onReady, isReady, onUserUpdate, createInstance update * [FSSDK-10439] client test: getIsReadyPromiseFulfilled, getIsUsingSdkKey * [FSSDK-10439] client test: activate * [FSSDK-10439] client test: getVariation, getFeatureVariableString * [FSSDK-10439] client test: feature variable test case update * [FSSDK-10439] client test: feature variable test case update 2 * [FSSDK-10439] client test: track method test update * [FSSDK-10439] client test restructured complete * [FSSDK-10439] missing testcases added * [FSSDK-10439] improving existing testcases - feature, decide * [FSSDK-10439] testcase addition for decideForKeys, fetchQualifiedSegments * [FSSDK-10439] adding remaining coverage for client * [FSSDK-10439] provider coverage increased * [FSSDK-10439] adding spaces
1 parent 7e9bda9 commit 62a12ff

File tree

5 files changed

+2074
-1174
lines changed

5 files changed

+2074
-1174
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ build/
1212

1313
# test artifacts
1414
**.tgz
15+
coverage/

src/Provider.spec.tsx

Lines changed: 91 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,80 +16,134 @@
1616

1717
/// <reference types="jest" />
1818

19-
//jest.mock('./client');
20-
2119
import React from 'react';
22-
import { render, act } from '@testing-library/react';
20+
import { render, waitFor } from '@testing-library/react';
2321
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>');
2539

2640
describe('OptimizelyProvider', () => {
2741
let mockReactClient: ReactSDKClient;
28-
const config = {
29-
datafile: {},
42+
const user1 = {
43+
id: 'user1',
44+
attributes: { attr1: 'value1' },
3045
};
31-
3246
beforeEach(() => {
3347
mockReactClient = {
34-
user: {
35-
id: 'test-id',
36-
attributes: {},
37-
},
48+
user: user1,
3849
setUser: jest.fn().mockResolvedValue(undefined),
3950
} as unknown as ReactSDKClient;
4051
});
4152

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+
4264
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} />);
4666

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();
5174
});
5275

5376
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} />);
5778

5879
expect(mockReactClient.setUser).toHaveBeenCalledWith({
59-
id: 'user1',
80+
id: user1.id,
6081
attributes: {},
6182
});
6283
});
6384

6485
it('should render successfully without user or userId provided', () => {
65-
act(() => {
66-
render(<OptimizelyProvider optimizely={mockReactClient} />);
67-
});
86+
render(<OptimizelyProvider optimizely={mockReactClient} />);
6887

6988
expect(mockReactClient.setUser).toHaveBeenCalledWith(DefaultUser);
7089
});
7190

7291
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} />);
7893

79-
expect(mockReactClient.setUser).toHaveBeenCalledWith({
80-
id: 'user1',
81-
attributes: { attr1: 'value1' },
82-
});
94+
expect(mockReactClient.setUser).toHaveBeenCalledWith(user1);
8395
});
8496

8597
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' }} />);
8999

90100
expect(mockReactClient.setUser).toHaveBeenCalledWith({
91101
id: DefaultUser.id,
92102
attributes: { attr1: 'value1' },
93103
});
94104
});
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+
});
95149
});

src/Provider.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
import * as React from 'react';
1818
import { UserAttributes } from '@optimizely/optimizely-sdk';
1919
import { getLogger } from '@optimizely/optimizely-sdk';
20-
21-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2220
import { OptimizelyContextProvider } from './Context';
2321
import { ReactSDKClient, DefaultUser } from './client';
2422
import { areUsersEqual, UserInfo } from './utils';

0 commit comments

Comments
 (0)