Skip to content

Commit 5995ee8

Browse files
[FSSDK-10440] test debug
1 parent 90ca7dd commit 5995ee8

File tree

3 files changed

+59
-45
lines changed

3 files changed

+59
-45
lines changed

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ module.exports = {
2525
'@typescript-eslint/no-empty-function': 'off',
2626
'no-shadow': 'error',
2727
},
28-
};
28+
};

src/hooks.spec.tsx

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { render, renderHook, screen, waitFor } from '@testing-library/react';
2222
import '@testing-library/jest-dom';
2323

2424
import { OptimizelyProvider } from './Provider';
25-
import { OnReadyResult, ReactSDKClient, VariableValuesObject } from './client';
25+
import { NotReadyReason, OnReadyResult, ReactSDKClient, VariableValuesObject } from './client';
2626
import { useExperiment, useFeature, useDecision, useTrackEvent, hooksLogger } from './hooks';
2727
import { OptimizelyDecision } from './utils';
2828
const defaultDecision: OptimizelyDecision = {
@@ -46,6 +46,7 @@ const MyFeatureComponent = ({ options = {}, overrides = {} }: any) => {
4646

4747
const MyExperimentComponent = ({ options = {}, overrides = {} }: any) => {
4848
const [variation, clientReady, didTimeout] = useExperiment('experiment1', { ...options }, { ...overrides });
49+
console.log('MyExperimentComponent', [variation, clientReady, didTimeout]);
4950
return <span data-testid="result">{`${variation}|${clientReady}|${didTimeout}`}</span>;
5051
};
5152

@@ -71,6 +72,7 @@ describe('hooks', () => {
7172
let notificationListenerCallbacks: Array<() => void>;
7273
let optimizelyMock: ReactSDKClient;
7374
let readySuccess: boolean;
75+
// let reason: NotReadyReason;
7476
let userUpdateCallbacks: Array<() => void>;
7577
let UseExperimentLoggingComponent: React.FunctionComponent<any>;
7678
let UseFeatureLoggingComponent: React.FunctionComponent<any>;
@@ -84,19 +86,26 @@ describe('hooks', () => {
8486

8587
beforeEach(() => {
8688
getOnReadyPromise = ({ timeout = 0 }: any): Promise<OnReadyResult> =>
87-
new Promise(resolve => {
88-
setTimeout(function() {
89-
resolve(
90-
Object.assign(
91-
{
92-
success: readySuccess,
93-
},
94-
!readySuccess && {
95-
dataReadyPromise: new Promise(r => setTimeout(r, mockDelay)),
96-
}
97-
)
98-
);
99-
}, timeout || mockDelay);
89+
new Promise((resolve) => {
90+
resolve(
91+
Object.assign(
92+
{
93+
success: readySuccess,
94+
reason: NotReadyReason.TIMEOUT,
95+
},
96+
!readySuccess && {
97+
dataReadyPromise: new Promise((r) =>
98+
setTimeout(
99+
() =>
100+
r({
101+
success: true,
102+
}),
103+
mockDelay
104+
)
105+
),
106+
}
107+
)
108+
);
100109
});
101110
activateMock = jest.fn();
102111
isFeatureEnabledMock = jest.fn();
@@ -109,21 +118,21 @@ describe('hooks', () => {
109118
decideMock = jest.fn();
110119
setForcedDecisionMock = jest.fn();
111120
hooksLoggerErrorSpy = jest.spyOn(hooksLogger, 'error');
112-
optimizelyMock = ({
121+
optimizelyMock = {
113122
activate: activateMock,
114-
onReady: jest.fn().mockImplementation(config => getOnReadyPromise(config || {})),
123+
onReady: jest.fn().mockImplementation((config) => getOnReadyPromise(config || {})),
115124
getFeatureVariables: jest.fn().mockImplementation(() => featureVariables),
116125
isFeatureEnabled: isFeatureEnabledMock,
117126
getVuid: jest.fn().mockReturnValue('vuid_95bf72cebc774dfd8e8e580a5a1'),
118-
onUserUpdate: jest.fn().mockImplementation(handler => {
127+
onUserUpdate: jest.fn().mockImplementation((handler) => {
119128
userUpdateCallbacks.push(handler);
120129
return () => {};
121130
}),
122131
notificationCenter: {
123132
addNotificationListener: jest.fn().mockImplementation((type, handler) => {
124133
notificationListenerCallbacks.push(handler);
125134
}),
126-
removeNotificationListener: jest.fn().mockImplementation(id => {}),
135+
removeNotificationListener: jest.fn().mockImplementation((id) => {}),
127136
},
128137
user: {
129138
id: 'testuser',
@@ -132,15 +141,16 @@ describe('hooks', () => {
132141
isReady: () => readySuccess,
133142
getIsReadyPromiseFulfilled: () => true,
134143
getIsUsingSdkKey: () => true,
135-
onForcedVariationsUpdate: jest.fn().mockImplementation(handler => {
144+
onForcedVariationsUpdate: jest.fn().mockImplementation((handler) => {
136145
forcedVariationUpdateCallbacks.push(handler);
137146
return () => {};
138147
}),
139148
getForcedVariations: jest.fn().mockReturnValue({}),
140149
decide: decideMock,
141150
setForcedDecision: setForcedDecisionMock,
142151
track: jest.fn(),
143-
} as unknown) as ReactSDKClient;
152+
setUser: jest.fn(),
153+
} as unknown as ReactSDKClient;
144154

145155
mockLog = jest.fn();
146156
UseExperimentLoggingComponent = ({ options = {}, overrides = {} }: any) => {
@@ -164,8 +174,8 @@ describe('hooks', () => {
164174

165175
afterEach(async () => {
166176
await optimizelyMock.onReady().then(
167-
res => res.dataReadyPromise,
168-
err => null
177+
(res) => res.dataReadyPromise,
178+
(err) => null
169179
);
170180
hooksLoggerErrorSpy.mockReset();
171181
});
@@ -195,7 +205,7 @@ describe('hooks', () => {
195205
await waitFor(() => expect(screen.getByTestId('result')).toHaveTextContent('null|true|false'));
196206
});
197207

198-
it('should respect the timeout option passed', async () => {
208+
it.only('should respect the timeout option passed', async () => {
199209
activateMock.mockReturnValue(null);
200210
readySuccess = false;
201211

@@ -211,10 +221,11 @@ describe('hooks', () => {
211221

212222
// Simulate datafile fetch completing after timeout has already passed
213223
// Activate now returns a variation
214-
activateMock.mockReturnValue('12345');
224+
// readySuccess = true;
225+
// activateMock.mockReturnValue('12345');
215226
// Wait for completion of dataReadyPromise
216-
await optimizelyMock.onReady().then(res => res.dataReadyPromise);
217-
await waitFor(() => expect(screen.getByTestId('result')).toHaveTextContent('12345|true|true')); // when clientReady
227+
// await optimizelyMock.onReady().then((res) => res.dataReadyPromise);
228+
// await waitFor(() => expect(screen.getByTestId('result')).toHaveTextContent('12345|true|true')); // when clientReady
218229
});
219230

220231
it('should gracefully handle the client promise rejecting after timeout', async () => {
@@ -255,7 +266,7 @@ describe('hooks', () => {
255266
activateMock.mockReturnValue('12345');
256267
// Simulate the user object changing
257268
await act(async () => {
258-
userUpdateCallbacks.forEach(fn => fn());
269+
userUpdateCallbacks.forEach((fn) => fn());
259270
});
260271
// component.update();
261272
// await waitFor(() => expect(screen.getByTestId('result')).toHaveTextContent('12345|true|false');
@@ -278,7 +289,7 @@ describe('hooks', () => {
278289
activateMock.mockReturnValue('12345');
279290
// Simulate the user object changing
280291
await act(async () => {
281-
userUpdateCallbacks.forEach(fn => fn());
292+
userUpdateCallbacks.forEach((fn) => fn());
282293
});
283294
await waitFor(() => expect(screen.getByTestId('result')).toHaveTextContent('null|true|false'));
284295
});
@@ -299,7 +310,7 @@ describe('hooks', () => {
299310
it('should re-render after the client becomes ready', async () => {
300311
readySuccess = false;
301312
let resolveReadyPromise: (result: { success: boolean; dataReadyPromise: Promise<any> }) => void;
302-
const readyPromise: Promise<any> = new Promise(res => {
313+
const readyPromise: Promise<any> = new Promise((res) => {
303314
resolveReadyPromise = (result): void => {
304315
readySuccess = true;
305316
res(result);
@@ -472,13 +483,13 @@ describe('hooks', () => {
472483
isFeatureEnabledMock.mockReturnValue(true);
473484
featureVariables = mockFeatureVariables;
474485
// Wait for completion of dataReadyPromise
475-
await optimizelyMock.onReady().then(res => res.dataReadyPromise);
486+
await optimizelyMock.onReady().then((res) => res.dataReadyPromise);
476487

477488
// Simulate datafile fetch completing after timeout has already passed
478489
// Activate now returns a variation
479490
activateMock.mockReturnValue('12345');
480491
// Wait for completion of dataReadyPromise
481-
await optimizelyMock.onReady().then(res => res.dataReadyPromise);
492+
await optimizelyMock.onReady().then((res) => res.dataReadyPromise);
482493
await waitFor(() => expect(screen.getByTestId('result')).toHaveTextContent('true|{"foo":"bar"}|true|true')); // when clientReady
483494
});
484495

@@ -522,7 +533,7 @@ describe('hooks', () => {
522533
featureVariables = mockFeatureVariables;
523534
// Simulate the user object changing
524535
await act(async () => {
525-
userUpdateCallbacks.forEach(fn => fn());
536+
userUpdateCallbacks.forEach((fn) => fn());
526537
});
527538
await waitFor(() => expect(screen.getByTestId('result')).toHaveTextContent('true|{"foo":"bar"}|true|false'));
528539
});
@@ -546,7 +557,7 @@ describe('hooks', () => {
546557
featureVariables = mockFeatureVariables;
547558
// Simulate the user object changing
548559
act(() => {
549-
userUpdateCallbacks.forEach(fn => fn());
560+
userUpdateCallbacks.forEach((fn) => fn());
550561
});
551562
// component.update();
552563
await waitFor(() => expect(screen.getByTestId('result')).toHaveTextContent('false|{}|true|false'));
@@ -567,7 +578,7 @@ describe('hooks', () => {
567578
it('should re-render after the client becomes ready', async () => {
568579
readySuccess = false;
569580
let resolveReadyPromise: (result: { success: boolean; dataReadyPromise: Promise<any> }) => void;
570-
const readyPromise: Promise<any> = new Promise(res => {
581+
const readyPromise: Promise<any> = new Promise((res) => {
571582
resolveReadyPromise = (result): void => {
572583
readySuccess = true;
573584
res(result);
@@ -731,11 +742,11 @@ describe('hooks', () => {
731742
variables: { foo: 'bar' },
732743
});
733744

734-
await optimizelyMock.onReady().then(res => res.dataReadyPromise);
745+
await optimizelyMock.onReady().then((res) => res.dataReadyPromise);
735746

736747
// Simulate datafile fetch completing after timeout has already passed
737748
// Wait for completion of dataReadyPromise
738-
await optimizelyMock.onReady().then(res => res.dataReadyPromise);
749+
await optimizelyMock.onReady().then((res) => res.dataReadyPromise);
739750

740751
await waitFor(() => expect(screen.getByTestId('result')).toHaveTextContent('true|{"foo":"bar"}|true|true')); // when clientReady
741752
});
@@ -781,7 +792,7 @@ describe('hooks', () => {
781792
});
782793
// Simulate the user object changing
783794
await act(async () => {
784-
userUpdateCallbacks.forEach(fn => fn());
795+
userUpdateCallbacks.forEach((fn) => fn());
785796
});
786797
await waitFor(() => expect(screen.getByTestId('result')).toHaveTextContent('true|{"foo":"bar"}|true|false'));
787798
});
@@ -806,7 +817,7 @@ describe('hooks', () => {
806817
});
807818
// Simulate the user object changing
808819
await act(async () => {
809-
userUpdateCallbacks.forEach(fn => fn());
820+
userUpdateCallbacks.forEach((fn) => fn());
810821
});
811822
await waitFor(() => expect(screen.getByTestId('result')).toHaveTextContent('false|{}|true|false'));
812823
});
@@ -827,7 +838,7 @@ describe('hooks', () => {
827838
it('should re-render after the client becomes ready', async () => {
828839
readySuccess = false;
829840
let resolveReadyPromise: (result: { success: boolean; dataReadyPromise: Promise<any> }) => void;
830-
const readyPromise: Promise<any> = new Promise(res => {
841+
const readyPromise: Promise<any> = new Promise((res) => {
831842
resolveReadyPromise = (result): void => {
832843
readySuccess = true;
833844
res(result);

src/hooks.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,29 +170,32 @@ function subscribeToInitialization(
170170
});
171171
break;
172172
case NotReadyReason.TIMEOUT:
173+
console.log('Timeoiut', res.reason)
173174
hooksLogger.info(`Client did not become ready before timeout of ${timeout} ms, reason="${res.message}"`);
174175
onInitStateChange({
175176
clientReady: false,
176177
didTimeout: true,
177178
});
178-
res.dataReadyPromise?.then(() => {
179+
res.dataReadyPromise?.then((r) => {
180+
console.log('r', r)
179181
hooksLogger.info('Client became ready after timeout already elapsed');
180182
onInitStateChange({
181-
clientReady: true,
183+
clientReady: r.success, // true
182184
didTimeout: true,
183185
});
184186
});
185187
break;
186188
default:
189+
console.log('subscribeToInitialization default case', res)
187190
hooksLogger.warn(`Other reason client not ready, reason="${res.message}"`);
188191
onInitStateChange({
189-
clientReady: false,
192+
clientReady: !!res.success,
190193
didTimeout: true, // assume timeout
191194
});
192195
res.dataReadyPromise?.then(() => {
193196
hooksLogger.info('Client became ready later');
194197
onInitStateChange({
195-
clientReady: true,
198+
clientReady: !!res.success,
196199
didTimeout: true, // assume timeout
197200
});
198201
});
@@ -304,7 +307,7 @@ export const useExperiment: UseExperiment = (experimentKey, options = {}, overri
304307
}),
305308
[getCurrentDecision, optimizely]
306309
);
307-
310+
console.log('useExperiment', state)
308311
return [state.variation, state.clientReady, state.didTimeout];
309312
};
310313

0 commit comments

Comments
 (0)