Skip to content

Commit fae169f

Browse files
mikechu-optimizelyMike Chu
andauthored
[FSSDK-9984] fix: initialization and setUser errors (#255)
* fix: remove successful fetch requirement for onReady * Revert "fix: remove successful fetch requirement for onReady" This reverts commit 566daaf. * fix: error with OnReadyResult being undefined * fix: setUser should use VUID if possible * revert: timeout of undefined * docs: update copyright year * revert: Provider.tsx copyright since no code change * build: bump JS SDK version * refactor: `res` should never be `undefined` * docs: add clarifying comment * revert: retrieval & use of current user context * wip: partial solution; needs collab * refactor: setUser logic updated * revert: move setUser back to Provider constructor * style: remove commented code * fix: fetchQualifiedSegments under SSR/sync scenario * ci: VS Code jest settings to run via extension * test: use NotReadyReason enum * test: use NotReadyReason & add missing getUserId in mock user context * fix: add onInitStateChange for default ready result * fix: logic in Promise.all user & client readiness * refactor: isReady() to isReactClientReady() * test: fixes for uses of getUserId() in setUser() * wip: fixing tests * wip: fixed more tests * revert: refactor of isReactClientReady() * docs: Update copyrights * fix: later setUser not getting new usercontext (manual testing) * fix: PR review changes * test: add initial OptimizelyProvider tests * fix: PR review changes * docs: add clarification inline comments * build: bump underlying JS SDK version to 5.3.0 * fix: add missing getProjectConfig() from JS SDK * refactor: omit getProjectConfig instead of implementing it * style: remove unused import --------- Co-authored-by: Mike Chu <michael.chu@optmizely.com>
1 parent a87fe08 commit fae169f

File tree

10 files changed

+347
-123
lines changed

10 files changed

+347
-123
lines changed

.vscode/launch.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"type": "node",
6+
"name": "vscode-jest-tests.v2.react-sdk",
7+
"request": "launch",
8+
"args": [
9+
"--runInBand",
10+
"--watchAll=false",
11+
"--testNamePattern",
12+
"${jest.testNamePattern}",
13+
"--runTestsByPath",
14+
"${jest.testFile}"
15+
],
16+
"cwd": "${workspaceFolder}",
17+
"console": "integratedTerminal",
18+
"internalConsoleOptions": "neverOpen",
19+
"program": "${workspaceFolder}/node_modules/.bin/jest",
20+
"windows": {
21+
"program": "${workspaceFolder}/node_modules/jest/bin/jest"
22+
}
23+
}
24+
]
25+
}

.vscode/settings.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
{
2-
"jest.autoRun": {
3-
"onStartup": ["all-tests"]
4-
}
2+
"jest.runMode": "on-demand",
3+
"jest.jestCommandLine": "~/.nvm/nvm-exec yarn test"
54
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"access": "public"
3535
},
3636
"dependencies": {
37-
"@optimizely/optimizely-sdk": "^5.2.0",
37+
"@optimizely/optimizely-sdk": "^5.3.0",
3838
"hoist-non-react-statics": "^3.3.0",
3939
"prop-types": "^15.6.2",
4040
"utility-types": "^2.1.0 || ^3.0.0"

src/Feature.spec.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2018-2019, 2023 Optimizely
2+
* Copyright 2018-2019, 2023-2024 Optimizely
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ import { render, screen, waitFor } from '@testing-library/react';
2222
import '@testing-library/jest-dom/extend-expect';
2323

2424
import { OptimizelyProvider } from './Provider';
25-
import { ReactSDKClient, VariableValuesObject } from './client';
25+
import { NotReadyReason, ReactSDKClient, VariableValuesObject } from './client';
2626
import { OptimizelyFeature } from './Feature';
2727

2828
describe('<OptimizelyFeature>', () => {
@@ -298,7 +298,7 @@ describe('<OptimizelyFeature>', () => {
298298

299299
// while it's waiting for onReady()
300300
expect(container.innerHTML).toBe('');
301-
resolver.resolve({ success: false, reason: 'fail', dataReadyPromise: Promise.resolve() });
301+
resolver.resolve({ success: false, reason: NotReadyReason.TIMEOUT, dataReadyPromise: Promise.resolve() });
302302

303303
// Simulate config update notification firing after datafile fetched
304304
await optimizelyMock.onReady().then(res => res.dataReadyPromise);

src/Provider.spec.tsx

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* Copyright 2024 Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/// <reference types="jest" />
18+
19+
//jest.mock('./client');
20+
21+
import React from 'react';
22+
import { render, act } from '@testing-library/react';
23+
import { OptimizelyProvider } from './Provider';
24+
import { DefaultUser, ReactSDKClient, createInstance } from './client';
25+
26+
describe('OptimizelyProvider', () => {
27+
let mockReactClient: ReactSDKClient;
28+
const config = {
29+
datafile: {},
30+
};
31+
32+
beforeEach(() => {
33+
mockReactClient = ({
34+
user: {
35+
id: 'test-id',
36+
attributes: {},
37+
},
38+
setUser: jest.fn().mockResolvedValue(undefined),
39+
} as unknown) as ReactSDKClient;
40+
});
41+
42+
it('should render successfully with user provided', () => {
43+
act(() => {
44+
render(<OptimizelyProvider optimizely={mockReactClient} user={{ id: 'user1' }} />);
45+
});
46+
47+
expect(mockReactClient.setUser).toHaveBeenCalledWith({
48+
id: 'user1',
49+
attributes: {},
50+
});
51+
});
52+
53+
it('should render successfully with userId provided', () => {
54+
act(() => {
55+
render(<OptimizelyProvider optimizely={mockReactClient} userId="user1" />);
56+
});
57+
58+
expect(mockReactClient.setUser).toHaveBeenCalledWith({
59+
id: 'user1',
60+
attributes: {},
61+
});
62+
});
63+
64+
it('should render successfully without user or userId provided', () => {
65+
act(() => {
66+
render(<OptimizelyProvider optimizely={mockReactClient} />);
67+
});
68+
69+
expect(mockReactClient.setUser).toHaveBeenCalledWith(DefaultUser);
70+
});
71+
72+
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+
});
78+
79+
expect(mockReactClient.setUser).toHaveBeenCalledWith({
80+
id: 'user1',
81+
attributes: { attr1: 'value1' },
82+
});
83+
});
84+
85+
it('should succeed just userAttributes provided', () => {
86+
act(() => {
87+
render(<OptimizelyProvider optimizely={mockReactClient} userAttributes={{ attr1: 'value1' }} />);
88+
});
89+
90+
expect(mockReactClient.setUser).toHaveBeenCalledWith({
91+
id: DefaultUser.id,
92+
attributes: { attr1: 'value1' },
93+
});
94+
});
95+
});

src/Provider.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2022-2023, Optimizely
2+
* Copyright 2022-2024, Optimizely
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,9 +43,7 @@ interface OptimizelyProviderState {
4343
export class OptimizelyProvider extends React.Component<OptimizelyProviderProps, OptimizelyProviderState> {
4444
constructor(props: OptimizelyProviderProps) {
4545
super(props);
46-
}
4746

48-
componentDidMount(): void {
4947
this.setUserInOptimizely();
5048
}
5149

@@ -78,12 +76,15 @@ export class OptimizelyProvider extends React.Component<OptimizelyProviderProps,
7876
// deprecation warning
7977
logger.warn('Passing userId and userAttributes as props is deprecated, please switch to using `user` prop');
8078
} else {
81-
finalUser = DefaultUser;
79+
finalUser = {
80+
id: DefaultUser.id,
81+
attributes: userAttributes || DefaultUser.attributes,
82+
};
8283
}
8384

85+
// if user is a promise, setUser occurs in the then block above
8486
if (finalUser) {
8587
try {
86-
await optimizely.onReady();
8788
await optimizely.setUser(finalUser);
8889
} catch {
8990
logger.error('Error while trying to set user.');

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy