Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FSSDK-9984] fix: initialization and setUser errors #255

Merged
merged 37 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
566daaf
fix: remove successful fetch requirement for onReady
Mar 18, 2024
77c4f56
Revert "fix: remove successful fetch requirement for onReady"
Mar 19, 2024
0f190d6
fix: error with OnReadyResult being undefined
Mar 21, 2024
2fc9703
fix: setUser should use VUID if possible
Mar 21, 2024
6da3ae3
Merge branch 'master' into mike/FSSDK-9984/fix-initialization-error
Mar 21, 2024
682e8a7
revert: timeout of undefined
Mar 21, 2024
bbea7ca
docs: update copyright year
Mar 21, 2024
21348c1
revert: Provider.tsx copyright since no code change
Mar 22, 2024
cb15720
build: bump JS SDK version
Mar 25, 2024
fd5cfd1
refactor: `res` should never be `undefined`
Mar 25, 2024
ae88a38
docs: add clarifying comment
Mar 25, 2024
1c1c501
revert: retrieval & use of current user context
Mar 27, 2024
92f09fb
wip: partial solution; needs collab
Mar 28, 2024
6bc5c45
refactor: setUser logic updated
Mar 29, 2024
8e9c122
revert: move setUser back to Provider constructor
Mar 29, 2024
7d5adc6
style: remove commented code
Mar 29, 2024
39b45c0
fix: fetchQualifiedSegments under SSR/sync scenario
Mar 29, 2024
b541ff4
ci: VS Code jest settings to run via extension
Apr 1, 2024
41c51fa
test: use NotReadyReason enum
Apr 1, 2024
8164582
test: use NotReadyReason & add missing getUserId in mock user context
Apr 1, 2024
286838f
fix: add onInitStateChange for default ready result
Apr 1, 2024
425de33
fix: logic in Promise.all user & client readiness
Apr 1, 2024
81be217
refactor: isReady() to isReactClientReady()
Apr 2, 2024
2d6dd19
test: fixes for uses of getUserId() in setUser()
Apr 2, 2024
e8116eb
wip: fixing tests
Apr 3, 2024
12a5b78
wip: fixed more tests
Apr 3, 2024
08ef8de
revert: refactor of isReactClientReady()
Apr 3, 2024
bdb469c
docs: Update copyrights
Apr 3, 2024
8967c15
fix: later setUser not getting new usercontext (manual testing)
Apr 3, 2024
01e72c7
fix: PR review changes
Apr 5, 2024
569cf66
test: add initial OptimizelyProvider tests
Apr 5, 2024
b0503cf
fix: PR review changes
Apr 5, 2024
f5b9a14
docs: add clarification inline comments
Apr 5, 2024
d349a05
build: bump underlying JS SDK version to 5.3.0
Apr 8, 2024
24f0ae8
fix: add missing getProjectConfig() from JS SDK
Apr 8, 2024
0a9951c
refactor: omit getProjectConfig instead of implementing it
Apr 8, 2024
ac5075c
style: remove unused import
Apr 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"name": "vscode-jest-tests.v2.react-sdk",
"request": "launch",
"args": [
"--runInBand",
"--watchAll=false",
"--testNamePattern",
"${jest.testNamePattern}",
"--runTestsByPath",
"${jest.testFile}"
],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"windows": {
"program": "${workspaceFolder}/node_modules/jest/bin/jest"
}
}
]
}
5 changes: 2 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"jest.autoRun": {
"onStartup": ["all-tests"]
}
"jest.runMode": "on-demand",
"jest.jestCommandLine": "~/.nvm/nvm-exec yarn test"
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"access": "public"
},
"dependencies": {
"@optimizely/optimizely-sdk": "^5.2.0",
"@optimizely/optimizely-sdk": "^5.3.0",
"hoist-non-react-statics": "^3.3.0",
"prop-types": "^15.6.2",
"utility-types": "^2.1.0 || ^3.0.0"
Expand Down
6 changes: 3 additions & 3 deletions src/Feature.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2018-2019, 2023 Optimizely
* Copyright 2018-2019, 2023-2024 Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -22,7 +22,7 @@ import { render, screen, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';

import { OptimizelyProvider } from './Provider';
import { ReactSDKClient, VariableValuesObject } from './client';
import { NotReadyReason, ReactSDKClient, VariableValuesObject } from './client';
import { OptimizelyFeature } from './Feature';

describe('<OptimizelyFeature>', () => {
Expand Down Expand Up @@ -298,7 +298,7 @@ describe('<OptimizelyFeature>', () => {

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

// Simulate config update notification firing after datafile fetched
await optimizelyMock.onReady().then(res => res.dataReadyPromise);
Expand Down
95 changes: 95 additions & 0 deletions src/Provider.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* Copyright 2024 Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

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

//jest.mock('./client');

import React from 'react';
import { render, act } from '@testing-library/react';
import { OptimizelyProvider } from './Provider';
import { DefaultUser, ReactSDKClient, createInstance } from './client';

describe('OptimizelyProvider', () => {
let mockReactClient: ReactSDKClient;
const config = {
datafile: {},
};

beforeEach(() => {
mockReactClient = ({
user: {
id: 'test-id',
attributes: {},
},
setUser: jest.fn().mockResolvedValue(undefined),
} as unknown) as ReactSDKClient;
});

it('should render successfully with user provided', () => {
act(() => {
render(<OptimizelyProvider optimizely={mockReactClient} user={{ id: 'user1' }} />);
});

expect(mockReactClient.setUser).toHaveBeenCalledWith({
id: 'user1',
attributes: {},
});
});

it('should render successfully with userId provided', () => {
act(() => {
render(<OptimizelyProvider optimizely={mockReactClient} userId="user1" />);
});

expect(mockReactClient.setUser).toHaveBeenCalledWith({
id: 'user1',
attributes: {},
});
});

it('should render successfully without user or userId provided', () => {
act(() => {
render(<OptimizelyProvider optimizely={mockReactClient} />);
});

expect(mockReactClient.setUser).toHaveBeenCalledWith(DefaultUser);
});

it('should render successfully with user id & attributes provided', () => {
act(() => {
render(
<OptimizelyProvider optimizely={mockReactClient} user={{ id: 'user1', attributes: { attr1: 'value1' } }} />
);
});

expect(mockReactClient.setUser).toHaveBeenCalledWith({
id: 'user1',
attributes: { attr1: 'value1' },
});
});

it('should succeed just userAttributes provided', () => {
act(() => {
render(<OptimizelyProvider optimizely={mockReactClient} userAttributes={{ attr1: 'value1' }} />);
});

expect(mockReactClient.setUser).toHaveBeenCalledWith({
id: DefaultUser.id,
attributes: { attr1: 'value1' },
});
});
});
11 changes: 6 additions & 5 deletions src/Provider.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2022-2023, Optimizely
* Copyright 2022-2024, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -43,9 +43,7 @@ interface OptimizelyProviderState {
export class OptimizelyProvider extends React.Component<OptimizelyProviderProps, OptimizelyProviderState> {
constructor(props: OptimizelyProviderProps) {
super(props);
}

componentDidMount(): void {
this.setUserInOptimizely();
}

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

// if user is a promise, setUser occurs in the then block above
if (finalUser) {
try {
await optimizely.onReady();
await optimizely.setUser(finalUser);
} catch {
logger.error('Error while trying to set user.');
Expand Down
Loading
Loading