@@ -25,10 +25,14 @@ import { OptimizelyProvider } from './Provider';
25
25
import { ReactSDKClient } from './client' ;
26
26
import { OptimizelyVariation } from './Variation' ;
27
27
28
+ type Resolver = {
29
+ resolve : ( value : { success : boolean ; reason ?: string } ) => void ;
30
+ reject : ( reason ?: string ) => void ;
31
+ } ;
32
+
28
33
describe ( '<OptimizelyExperiment>' , ( ) => {
29
34
const variationKey = 'matchingVariation' ;
30
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
- let resolver : any ;
35
+ let resolver : Resolver ;
32
36
let optimizelyMock : ReactSDKClient ;
33
37
let isReady : boolean ;
34
38
@@ -58,25 +62,48 @@ describe('<OptimizelyExperiment>', () => {
58
62
getIsReadyPromiseFulfilled : ( ) => true ,
59
63
getIsUsingSdkKey : ( ) => true ,
60
64
onForcedVariationsUpdate : jest . fn ( ) . mockReturnValue ( ( ) => { } ) ,
65
+ setUser : jest . fn ( ) ,
61
66
} as unknown as ReactSDKClient ;
62
67
} ) ;
63
68
64
69
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 } >
67
82
< 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
+ ) }
69
90
</ 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
+ } ) ;
72
99
} ) ;
73
100
74
101
describe ( 'when isServerSide prop is false' , ( ) => {
75
102
it ( 'should wait client is ready then render result of activate' , async ( ) => {
76
103
const { container, rerender } = render (
77
104
< OptimizelyProvider optimizely = { optimizelyMock } timeout = { 100 } >
78
105
< OptimizelyExperiment experiment = "experiment1" >
79
- { ( variation : string ) => < span data-testid = "variation-key" > { variation } </ span > }
106
+ { ( variation : string | null ) => < span data-testid = "variation-key" > { variation } </ span > }
80
107
</ OptimizelyExperiment >
81
108
</ OptimizelyProvider >
82
109
) ;
@@ -89,12 +116,10 @@ describe('<OptimizelyExperiment>', () => {
89
116
// Simulate client becoming ready: onReady resolving, firing config update notification
90
117
resolver . resolve ( { success : true } ) ;
91
118
92
- await optimizelyMock . onReady ( ) ;
93
-
94
119
rerender (
95
120
< OptimizelyProvider optimizely = { optimizelyMock } >
96
121
< OptimizelyExperiment experiment = "experiment1" >
97
- { ( variation : string ) => < span data-testid = "variation-key" > { variation } </ span > }
122
+ { ( variation : string | null ) => < span data-testid = "variation-key" > { variation } </ span > }
98
123
</ OptimizelyExperiment >
99
124
</ OptimizelyProvider >
100
125
) ;
@@ -108,7 +133,7 @@ describe('<OptimizelyExperiment>', () => {
108
133
const { container } = render (
109
134
< OptimizelyProvider optimizely = { optimizelyMock } timeout = { 100 } >
110
135
< 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 > }
112
137
</ OptimizelyExperiment >
113
138
</ OptimizelyProvider >
114
139
) ;
@@ -120,16 +145,15 @@ describe('<OptimizelyExperiment>', () => {
120
145
121
146
// Simulate client becoming ready; onReady resolving, firing config update notification
122
147
resolver . resolve ( { success : true } ) ;
123
- await optimizelyMock . onReady ( ) ;
124
148
125
- expect ( optimizelyMock . activate ) . toHaveBeenCalledWith ( 'experiment1' , undefined , undefined ) ;
149
+ await waitFor ( ( ) => expect ( optimizelyMock . activate ) . toHaveBeenCalledWith ( 'experiment1' , undefined , undefined ) ) ;
126
150
} ) ;
127
151
128
152
it ( `should use the Experiment prop's timeout when there is no timeout passed to <Provider>` , async ( ) => {
129
153
const { container } = render (
130
154
< OptimizelyProvider optimizely = { optimizelyMock } >
131
155
< 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 > }
133
157
</ OptimizelyExperiment >
134
158
</ OptimizelyProvider >
135
159
) ;
@@ -141,9 +165,8 @@ describe('<OptimizelyExperiment>', () => {
141
165
142
166
// Simulate client becoming ready
143
167
resolver . resolve ( { success : true } ) ;
144
- await optimizelyMock . onReady ( ) ;
145
168
146
- expect ( optimizelyMock . activate ) . toHaveBeenCalledWith ( 'experiment1' , undefined , undefined ) ;
169
+ await waitFor ( ( ) => expect ( optimizelyMock . activate ) . toHaveBeenCalledWith ( 'experiment1' , undefined , undefined ) ) ;
147
170
} ) ;
148
171
149
172
it ( 'should render using <OptimizelyVariation> when the variationKey matches' , async ( ) => {
@@ -162,14 +185,13 @@ describe('<OptimizelyExperiment>', () => {
162
185
</ OptimizelyExperiment >
163
186
</ OptimizelyProvider >
164
187
) ;
188
+
165
189
// while it's waiting for onReady()
166
190
expect ( container . innerHTML ) . toBe ( '' ) ;
167
191
168
192
// Simulate client becoming ready
169
193
resolver . resolve ( { success : true } ) ;
170
194
171
- await optimizelyMock . onReady ( ) ;
172
-
173
195
await waitFor ( ( ) => expect ( screen . getByTestId ( 'variation-key' ) ) . toHaveTextContent ( 'correct variation' ) ) ;
174
196
} ) ;
175
197
@@ -194,8 +216,6 @@ describe('<OptimizelyExperiment>', () => {
194
216
// Simulate client becoming ready
195
217
resolver . resolve ( { success : true } ) ;
196
218
197
- await optimizelyMock . onReady ( ) ;
198
-
199
219
await waitFor ( ( ) => expect ( screen . getByTestId ( 'variation-key' ) ) . toHaveTextContent ( 'default variation' ) ) ;
200
220
} ) ;
201
221
@@ -219,8 +239,6 @@ describe('<OptimizelyExperiment>', () => {
219
239
// Simulate client becoming ready
220
240
resolver . resolve ( { success : true } ) ;
221
241
222
- await optimizelyMock . onReady ( ) ;
223
-
224
242
await waitFor ( ( ) => expect ( screen . getByTestId ( 'variation-key' ) ) . toHaveTextContent ( 'matching variation' ) ) ;
225
243
} ) ;
226
244
@@ -244,12 +262,10 @@ describe('<OptimizelyExperiment>', () => {
244
262
// Simulate client becoming ready
245
263
resolver . resolve ( { success : true } ) ;
246
264
247
- await optimizelyMock . onReady ( ) ;
248
-
249
265
await waitFor ( ( ) => expect ( screen . getByTestId ( 'variation-key' ) ) . toHaveTextContent ( 'default variation' ) ) ;
250
266
} ) ;
251
267
252
- describe ( 'a OptimizelyVariation with default & variation props' , ( ) => {
268
+ describe ( 'OptimizelyVariation with default & variation props' , ( ) => {
253
269
it ( 'should render default with NO matching variations ' , async ( ) => {
254
270
const { container } = render (
255
271
< OptimizelyProvider optimizely = { optimizelyMock } >
@@ -270,8 +286,6 @@ describe('<OptimizelyExperiment>', () => {
270
286
// Simulate client becoming ready
271
287
resolver . resolve ( { success : true } ) ;
272
288
273
- await optimizelyMock . onReady ( ) ;
274
-
275
289
await waitFor ( ( ) =>
276
290
expect ( screen . getByTestId ( 'variation-key' ) ) . toHaveTextContent ( 'default & non matching variation' )
277
291
) ;
@@ -297,8 +311,6 @@ describe('<OptimizelyExperiment>', () => {
297
311
// Simulate client becoming ready
298
312
resolver . resolve ( { success : true } ) ;
299
313
300
- await optimizelyMock . onReady ( ) ;
301
-
302
314
await waitFor ( ( ) => expect ( screen . getByTestId ( 'variation-key' ) ) . toHaveTextContent ( 'matching variation' ) ) ;
303
315
} ) ;
304
316
} ) ;
@@ -329,8 +341,6 @@ describe('<OptimizelyExperiment>', () => {
329
341
// Simulate client becoming ready
330
342
resolver . resolve ( { success : true } ) ;
331
343
332
- await optimizelyMock . onReady ( ) ;
333
-
334
344
await waitFor ( ( ) => expect ( screen . getByTestId ( 'variation-key' ) ) . toHaveTextContent ( 'non-matching variation 3' ) ) ;
335
345
} ) ;
336
346
@@ -354,8 +364,6 @@ describe('<OptimizelyExperiment>', () => {
354
364
// Simulate client becoming ready
355
365
resolver . resolve ( { success : true } ) ;
356
366
357
- await optimizelyMock . onReady ( ) ;
358
-
359
367
expect ( container . innerHTML ) . toBe ( '' ) ;
360
368
} ) ;
361
369
@@ -367,7 +375,7 @@ describe('<OptimizelyExperiment>', () => {
367
375
overrideUserId = "james123"
368
376
overrideAttributes = { { betaUser : true } }
369
377
>
370
- { ( variation : string ) => < span data-testid = "variation-key" > { variation } </ span > }
378
+ { ( variation : string | null ) => < span data-testid = "variation-key" > { variation } </ span > }
371
379
</ OptimizelyExperiment >
372
380
</ OptimizelyProvider >
373
381
) ;
@@ -380,18 +388,17 @@ describe('<OptimizelyExperiment>', () => {
380
388
// Simulate client becoming ready
381
389
resolver . resolve ( { success : true } ) ;
382
390
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
+ } ) ;
388
395
} ) ;
389
396
390
397
it ( 'should pass the values for clientReady and didTimeout' , async ( ) => {
391
398
const { container } = render (
392
399
< OptimizelyProvider optimizely = { optimizelyMock } timeout = { 100 } >
393
400
< OptimizelyExperiment experiment = "experiment1" >
394
- { ( variation : string , clientReady : boolean , didTimeout : boolean ) => (
401
+ { ( variation : string | null , clientReady ? : boolean , didTimeout ? : boolean ) => (
395
402
< span data-testid = "variation-key" > { `${ variation } |${ clientReady } |${ didTimeout } ` } </ span >
396
403
) }
397
404
</ OptimizelyExperiment >
@@ -404,12 +411,10 @@ describe('<OptimizelyExperiment>', () => {
404
411
// Simulate client becoming ready
405
412
resolver . resolve ( { success : true } ) ;
406
413
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
+ } ) ;
413
418
} ) ;
414
419
415
420
describe ( 'when the onReady() promise return { success: false }' , ( ) => {
@@ -431,9 +436,8 @@ describe('<OptimizelyExperiment>', () => {
431
436
expect ( container . innerHTML ) . toBe ( '' ) ;
432
437
433
438
resolver . resolve ( { success : false , reason : 'fail' } ) ;
434
- await optimizelyMock . onReady ( ) ;
435
439
436
- expect ( container . innerHTML ) . toBe ( '' ) ;
440
+ await waitFor ( ( ) => expect ( container . innerHTML ) . toBe ( '' ) ) ;
437
441
} ) ;
438
442
} ) ;
439
443
} ) ;
@@ -443,9 +447,7 @@ describe('<OptimizelyExperiment>', () => {
443
447
const { container } = render (
444
448
< OptimizelyProvider optimizely = { optimizelyMock } timeout = { 100 } >
445
449
< 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 > }
449
451
</ OptimizelyExperiment >
450
452
</ OptimizelyProvider >
451
453
) ;
@@ -457,11 +459,11 @@ describe('<OptimizelyExperiment>', () => {
457
459
// Simulate client becoming ready
458
460
resolver . resolve ( { success : true } ) ;
459
461
isReady = true ;
460
- await act ( async ( ) => await optimizelyMock . onReady ( ) ) ;
461
-
462
- expect ( optimizelyMock . activate ) . toHaveBeenCalledWith ( 'experiment1' , undefined , undefined ) ;
463
462
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
+ } ) ;
465
467
466
468
// capture the OPTIMIZELY_CONFIG_UPDATE function
467
469
// change the return value of activate
@@ -473,16 +475,14 @@ describe('<OptimizelyExperiment>', () => {
473
475
474
476
expect ( optimizelyMock . activate ) . toHaveBeenCalledWith ( 'experiment1' , undefined , undefined ) ;
475
477
await waitFor ( ( ) => expect ( screen . getByTestId ( 'variation-key' ) ) . toHaveTextContent ( 'newVariation' ) ) ;
476
- expect ( optimizelyMock . activate ) . toBeCalledTimes ( 2 ) ;
478
+ expect ( optimizelyMock . activate ) . toHaveBeenCalledTimes ( 2 ) ;
477
479
} ) ;
478
480
479
481
it ( 'should re-render when the user changes' , async ( ) => {
480
482
const { container } = render (
481
483
< OptimizelyProvider optimizely = { optimizelyMock } timeout = { 100 } >
482
484
< 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 > }
486
486
</ OptimizelyExperiment >
487
487
</ OptimizelyProvider >
488
488
) ;
@@ -493,10 +493,11 @@ describe('<OptimizelyExperiment>', () => {
493
493
// Simulate client becoming ready
494
494
resolver . resolve ( { success : true } ) ;
495
495
isReady = true ;
496
- await act ( async ( ) => await optimizelyMock . onReady ( ) ) ;
497
- expect ( optimizelyMock . activate ) . toHaveBeenCalledWith ( 'experiment1' , undefined , undefined ) ;
498
496
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
+ } ) ;
500
501
501
502
// capture the onUserUpdate function
502
503
const updateFn = ( optimizelyMock . onUserUpdate as jest . Mock ) . mock . calls [ 0 ] [ 0 ] ;
@@ -506,7 +507,7 @@ describe('<OptimizelyExperiment>', () => {
506
507
507
508
expect ( optimizelyMock . activate ) . toHaveBeenCalledWith ( 'experiment1' , undefined , undefined ) ;
508
509
await waitFor ( ( ) => expect ( screen . getByTestId ( 'variation-key' ) ) . toHaveTextContent ( 'newVariation' ) ) ;
509
- expect ( optimizelyMock . activate ) . toBeCalledTimes ( 2 ) ;
510
+ expect ( optimizelyMock . activate ) . toHaveBeenCalledTimes ( 2 ) ;
510
511
} ) ;
511
512
} ) ;
512
513
@@ -515,9 +516,7 @@ describe('<OptimizelyExperiment>', () => {
515
516
render (
516
517
< OptimizelyProvider optimizely = { optimizelyMock } timeout = { 100 } isServerSide = { true } >
517
518
< 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 > }
521
520
</ OptimizelyExperiment >
522
521
</ OptimizelyProvider >
523
522
) ;
@@ -541,6 +540,7 @@ describe('<OptimizelyExperiment>', () => {
541
540
</ OptimizelyExperiment >
542
541
</ OptimizelyProvider >
543
542
) ;
543
+
544
544
await waitFor ( ( ) => expect ( screen . getByTestId ( 'variation-key' ) ) . toHaveTextContent ( 'correct variation' ) ) ;
545
545
} ) ;
546
546
} ) ;
0 commit comments