Skip to content

Commit 5daff74

Browse files
[FSSDK-10616] overall test improvement (#279)
* [FSSDK-10616] experiment test improvement * [FSSDK-10616] logOnlyEventDispatcher improvement * [FSSDK-10616] logger improvement * [FSSDK-10616] utils improvement * [FSSDK-10616] hooks improvement * [FSSDK-10616] util test case readability improvement
1 parent 62a12ff commit 5daff74

8 files changed

+598
-108
lines changed

src/Experiment.spec.tsx

+67-67
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,14 @@ import { OptimizelyProvider } from './Provider';
2525
import { ReactSDKClient } from './client';
2626
import { OptimizelyVariation } from './Variation';
2727

28+
type Resolver = {
29+
resolve: (value: { success: boolean; reason?: string }) => void;
30+
reject: (reason?: string) => void;
31+
};
32+
2833
describe('<OptimizelyExperiment>', () => {
2934
const variationKey = 'matchingVariation';
30-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
31-
let resolver: any;
35+
let resolver: Resolver;
3236
let optimizelyMock: ReactSDKClient;
3337
let isReady: boolean;
3438

@@ -58,25 +62,48 @@ describe('<OptimizelyExperiment>', () => {
5862
getIsReadyPromiseFulfilled: () => true,
5963
getIsUsingSdkKey: () => true,
6064
onForcedVariationsUpdate: jest.fn().mockReturnValue(() => {}),
65+
setUser: jest.fn(),
6166
} as unknown as ReactSDKClient;
6267
});
6368

6469
it('does not throw an error when not rendered in the context of an OptimizelyProvider', () => {
65-
expect(() => {
66-
render(
70+
const { container } = render(
71+
<OptimizelyExperiment experiment="experiment1">
72+
{(variation: string | null) => <span data-testid="variation-key">{variation}</span>}
73+
</OptimizelyExperiment>
74+
);
75+
76+
expect(container).toBeDefined();
77+
});
78+
79+
it('isValidElement check works as expected', async () => {
80+
const { container } = render(
81+
<OptimizelyProvider optimizely={optimizelyMock}>
6782
<OptimizelyExperiment experiment="experiment1">
68-
{(variation: string) => <span data-testid="variation-key">{variation}</span>}
83+
{(variation: string | null) => (
84+
<>
85+
<span data-testid="variation-key">{variation}</span>
86+
{null}
87+
{<div />}
88+
</>
89+
)}
6990
</OptimizelyExperiment>
70-
);
71-
}).toBeDefined();
91+
</OptimizelyProvider>
92+
);
93+
resolver.resolve({ success: true });
94+
95+
await waitFor(() => {
96+
const validChildren = container.getElementsByTagName('span');
97+
expect(validChildren).toHaveLength(1);
98+
});
7299
});
73100

74101
describe('when isServerSide prop is false', () => {
75102
it('should wait client is ready then render result of activate', async () => {
76103
const { container, rerender } = render(
77104
<OptimizelyProvider optimizely={optimizelyMock} timeout={100}>
78105
<OptimizelyExperiment experiment="experiment1">
79-
{(variation: string) => <span data-testid="variation-key">{variation}</span>}
106+
{(variation: string | null) => <span data-testid="variation-key">{variation}</span>}
80107
</OptimizelyExperiment>
81108
</OptimizelyProvider>
82109
);
@@ -89,12 +116,10 @@ describe('<OptimizelyExperiment>', () => {
89116
// Simulate client becoming ready: onReady resolving, firing config update notification
90117
resolver.resolve({ success: true });
91118

92-
await optimizelyMock.onReady();
93-
94119
rerender(
95120
<OptimizelyProvider optimizely={optimizelyMock}>
96121
<OptimizelyExperiment experiment="experiment1">
97-
{(variation: string) => <span data-testid="variation-key">{variation}</span>}
122+
{(variation: string | null) => <span data-testid="variation-key">{variation}</span>}
98123
</OptimizelyExperiment>
99124
</OptimizelyProvider>
100125
);
@@ -108,7 +133,7 @@ describe('<OptimizelyExperiment>', () => {
108133
const { container } = render(
109134
<OptimizelyProvider optimizely={optimizelyMock} timeout={100}>
110135
<OptimizelyExperiment experiment="experiment1" timeout={200}>
111-
{(variation: string) => <span data-testid="variation-key">{variation}</span>}
136+
{(variation: string | null) => <span data-testid="variation-key">{variation}</span>}
112137
</OptimizelyExperiment>
113138
</OptimizelyProvider>
114139
);
@@ -120,16 +145,15 @@ describe('<OptimizelyExperiment>', () => {
120145

121146
// Simulate client becoming ready; onReady resolving, firing config update notification
122147
resolver.resolve({ success: true });
123-
await optimizelyMock.onReady();
124148

125-
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', undefined, undefined);
149+
await waitFor(() => expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', undefined, undefined));
126150
});
127151

128152
it(`should use the Experiment prop's timeout when there is no timeout passed to <Provider>`, async () => {
129153
const { container } = render(
130154
<OptimizelyProvider optimizely={optimizelyMock}>
131155
<OptimizelyExperiment experiment="experiment1" timeout={200}>
132-
{(variation: string) => <span data-testid="variation-key">{variation}</span>}
156+
{(variation: string | null) => <span data-testid="variation-key">{variation}</span>}
133157
</OptimizelyExperiment>
134158
</OptimizelyProvider>
135159
);
@@ -141,9 +165,8 @@ describe('<OptimizelyExperiment>', () => {
141165

142166
// Simulate client becoming ready
143167
resolver.resolve({ success: true });
144-
await optimizelyMock.onReady();
145168

146-
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', undefined, undefined);
169+
await waitFor(() => expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', undefined, undefined));
147170
});
148171

149172
it('should render using <OptimizelyVariation> when the variationKey matches', async () => {
@@ -162,14 +185,13 @@ describe('<OptimizelyExperiment>', () => {
162185
</OptimizelyExperiment>
163186
</OptimizelyProvider>
164187
);
188+
165189
// while it's waiting for onReady()
166190
expect(container.innerHTML).toBe('');
167191

168192
// Simulate client becoming ready
169193
resolver.resolve({ success: true });
170194

171-
await optimizelyMock.onReady();
172-
173195
await waitFor(() => expect(screen.getByTestId('variation-key')).toHaveTextContent('correct variation'));
174196
});
175197

@@ -194,8 +216,6 @@ describe('<OptimizelyExperiment>', () => {
194216
// Simulate client becoming ready
195217
resolver.resolve({ success: true });
196218

197-
await optimizelyMock.onReady();
198-
199219
await waitFor(() => expect(screen.getByTestId('variation-key')).toHaveTextContent('default variation'));
200220
});
201221

@@ -219,8 +239,6 @@ describe('<OptimizelyExperiment>', () => {
219239
// Simulate client becoming ready
220240
resolver.resolve({ success: true });
221241

222-
await optimizelyMock.onReady();
223-
224242
await waitFor(() => expect(screen.getByTestId('variation-key')).toHaveTextContent('matching variation'));
225243
});
226244

@@ -244,12 +262,10 @@ describe('<OptimizelyExperiment>', () => {
244262
// Simulate client becoming ready
245263
resolver.resolve({ success: true });
246264

247-
await optimizelyMock.onReady();
248-
249265
await waitFor(() => expect(screen.getByTestId('variation-key')).toHaveTextContent('default variation'));
250266
});
251267

252-
describe('a OptimizelyVariation with default & variation props', () => {
268+
describe('OptimizelyVariation with default & variation props', () => {
253269
it('should render default with NO matching variations ', async () => {
254270
const { container } = render(
255271
<OptimizelyProvider optimizely={optimizelyMock}>
@@ -270,8 +286,6 @@ describe('<OptimizelyExperiment>', () => {
270286
// Simulate client becoming ready
271287
resolver.resolve({ success: true });
272288

273-
await optimizelyMock.onReady();
274-
275289
await waitFor(() =>
276290
expect(screen.getByTestId('variation-key')).toHaveTextContent('default & non matching variation')
277291
);
@@ -297,8 +311,6 @@ describe('<OptimizelyExperiment>', () => {
297311
// Simulate client becoming ready
298312
resolver.resolve({ success: true });
299313

300-
await optimizelyMock.onReady();
301-
302314
await waitFor(() => expect(screen.getByTestId('variation-key')).toHaveTextContent('matching variation'));
303315
});
304316
});
@@ -329,8 +341,6 @@ describe('<OptimizelyExperiment>', () => {
329341
// Simulate client becoming ready
330342
resolver.resolve({ success: true });
331343

332-
await optimizelyMock.onReady();
333-
334344
await waitFor(() => expect(screen.getByTestId('variation-key')).toHaveTextContent('non-matching variation 3'));
335345
});
336346

@@ -354,8 +364,6 @@ describe('<OptimizelyExperiment>', () => {
354364
// Simulate client becoming ready
355365
resolver.resolve({ success: true });
356366

357-
await optimizelyMock.onReady();
358-
359367
expect(container.innerHTML).toBe('');
360368
});
361369

@@ -367,7 +375,7 @@ describe('<OptimizelyExperiment>', () => {
367375
overrideUserId="james123"
368376
overrideAttributes={{ betaUser: true }}
369377
>
370-
{(variation: string) => <span data-testid="variation-key">{variation}</span>}
378+
{(variation: string | null) => <span data-testid="variation-key">{variation}</span>}
371379
</OptimizelyExperiment>
372380
</OptimizelyProvider>
373381
);
@@ -380,18 +388,17 @@ describe('<OptimizelyExperiment>', () => {
380388
// Simulate client becoming ready
381389
resolver.resolve({ success: true });
382390

383-
await optimizelyMock.onReady();
384-
385-
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', 'james123', { betaUser: true });
386-
387-
await waitFor(() => expect(screen.getByTestId('variation-key')).toHaveTextContent('matchingVariation'));
391+
await waitFor(() => {
392+
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', 'james123', { betaUser: true });
393+
expect(screen.getByTestId('variation-key')).toHaveTextContent('matchingVariation');
394+
});
388395
});
389396

390397
it('should pass the values for clientReady and didTimeout', async () => {
391398
const { container } = render(
392399
<OptimizelyProvider optimizely={optimizelyMock} timeout={100}>
393400
<OptimizelyExperiment experiment="experiment1">
394-
{(variation: string, clientReady: boolean, didTimeout: boolean) => (
401+
{(variation: string | null, clientReady?: boolean, didTimeout?: boolean) => (
395402
<span data-testid="variation-key">{`${variation}|${clientReady}|${didTimeout}`}</span>
396403
)}
397404
</OptimizelyExperiment>
@@ -404,12 +411,10 @@ describe('<OptimizelyExperiment>', () => {
404411
// Simulate client becoming ready
405412
resolver.resolve({ success: true });
406413

407-
await optimizelyMock.onReady();
408-
409-
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', undefined, undefined);
410-
await waitFor(() =>
411-
expect(screen.getByTestId('variation-key')).toHaveTextContent('matchingVariation|true|false')
412-
);
414+
await waitFor(() => {
415+
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', undefined, undefined);
416+
expect(screen.getByTestId('variation-key')).toHaveTextContent('matchingVariation|true|false');
417+
});
413418
});
414419

415420
describe('when the onReady() promise return { success: false }', () => {
@@ -431,9 +436,8 @@ describe('<OptimizelyExperiment>', () => {
431436
expect(container.innerHTML).toBe('');
432437

433438
resolver.resolve({ success: false, reason: 'fail' });
434-
await optimizelyMock.onReady();
435439

436-
expect(container.innerHTML).toBe('');
440+
await waitFor(() => expect(container.innerHTML).toBe(''));
437441
});
438442
});
439443
});
@@ -443,9 +447,7 @@ describe('<OptimizelyExperiment>', () => {
443447
const { container } = render(
444448
<OptimizelyProvider optimizely={optimizelyMock} timeout={100}>
445449
<OptimizelyExperiment experiment="experiment1" autoUpdate={true}>
446-
{(variation: string, clientReady: boolean, didTimeout: boolean) => (
447-
<span data-testid="variation-key">{variation}</span>
448-
)}
450+
{(variation: string | null) => <span data-testid="variation-key">{variation}</span>}
449451
</OptimizelyExperiment>
450452
</OptimizelyProvider>
451453
);
@@ -457,11 +459,11 @@ describe('<OptimizelyExperiment>', () => {
457459
// Simulate client becoming ready
458460
resolver.resolve({ success: true });
459461
isReady = true;
460-
await act(async () => await optimizelyMock.onReady());
461-
462-
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', undefined, undefined);
463462

464-
await waitFor(() => expect(screen.getByTestId('variation-key')).toHaveTextContent('matchingVariation'));
463+
await waitFor(() => {
464+
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', undefined, undefined);
465+
expect(screen.getByTestId('variation-key')).toHaveTextContent('matchingVariation');
466+
});
465467

466468
// capture the OPTIMIZELY_CONFIG_UPDATE function
467469
// change the return value of activate
@@ -473,16 +475,14 @@ describe('<OptimizelyExperiment>', () => {
473475

474476
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', undefined, undefined);
475477
await waitFor(() => expect(screen.getByTestId('variation-key')).toHaveTextContent('newVariation'));
476-
expect(optimizelyMock.activate).toBeCalledTimes(2);
478+
expect(optimizelyMock.activate).toHaveBeenCalledTimes(2);
477479
});
478480

479481
it('should re-render when the user changes', async () => {
480482
const { container } = render(
481483
<OptimizelyProvider optimizely={optimizelyMock} timeout={100}>
482484
<OptimizelyExperiment experiment="experiment1" autoUpdate={true}>
483-
{(variation: string, clientReady: boolean, didTimeout: boolean) => (
484-
<span data-testid="variation-key">{variation}</span>
485-
)}
485+
{(variation: string | null) => <span data-testid="variation-key">{variation}</span>}
486486
</OptimizelyExperiment>
487487
</OptimizelyProvider>
488488
);
@@ -493,10 +493,11 @@ describe('<OptimizelyExperiment>', () => {
493493
// Simulate client becoming ready
494494
resolver.resolve({ success: true });
495495
isReady = true;
496-
await act(async () => await optimizelyMock.onReady());
497-
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', undefined, undefined);
498496

499-
await waitFor(() => expect(screen.getByTestId('variation-key')).toHaveTextContent('matchingVariation'));
497+
await waitFor(() => {
498+
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', undefined, undefined);
499+
expect(screen.getByTestId('variation-key')).toHaveTextContent('matchingVariation');
500+
});
500501

501502
// capture the onUserUpdate function
502503
const updateFn = (optimizelyMock.onUserUpdate as jest.Mock).mock.calls[0][0];
@@ -506,7 +507,7 @@ describe('<OptimizelyExperiment>', () => {
506507

507508
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1', undefined, undefined);
508509
await waitFor(() => expect(screen.getByTestId('variation-key')).toHaveTextContent('newVariation'));
509-
expect(optimizelyMock.activate).toBeCalledTimes(2);
510+
expect(optimizelyMock.activate).toHaveBeenCalledTimes(2);
510511
});
511512
});
512513

@@ -515,9 +516,7 @@ describe('<OptimizelyExperiment>', () => {
515516
render(
516517
<OptimizelyProvider optimizely={optimizelyMock} timeout={100} isServerSide={true}>
517518
<OptimizelyExperiment experiment="experiment1">
518-
{(variation: string, clientReady: boolean, didTimeout: boolean) => (
519-
<span data-testid="variation-key">{variation}</span>
520-
)}
519+
{(variation: string | null) => <span data-testid="variation-key">{variation}</span>}
521520
</OptimizelyExperiment>
522521
</OptimizelyProvider>
523522
);
@@ -541,6 +540,7 @@ describe('<OptimizelyExperiment>', () => {
541540
</OptimizelyExperiment>
542541
</OptimizelyProvider>
543542
);
543+
544544
await waitFor(() => expect(screen.getByTestId('variation-key')).toHaveTextContent('correct variation'));
545545
});
546546
});

0 commit comments

Comments
 (0)