@@ -82,7 +82,38 @@ describe('hooks', () => {
82
82
let setForcedDecisionMock : jest . Mock < void > ;
83
83
let hooksLoggerErrorSpy : jest . SpyInstance ;
84
84
const REJECTION_REASON = 'A rejection reason you should never see in the test runner' ;
85
+ const getOnReadyTimeoutPromise = ( { timeout = 0 } : any ) : Promise < OnReadyResult > => {
86
+ const timeoutPromise = new Promise < OnReadyResult > ( ( resolve ) => {
87
+ setTimeout (
88
+ ( ) => {
89
+ resolve ( {
90
+ success : false ,
91
+ reason : NotReadyReason . TIMEOUT ,
92
+ dataReadyPromise : new Promise ( ( r ) =>
93
+ setTimeout (
94
+ ( ) =>
95
+ r ( {
96
+ success : readySuccess ,
97
+ } ) ,
98
+ mockDelay
99
+ )
100
+ ) ,
101
+ } ) ;
102
+ } ,
103
+ timeout || mockDelay + 1
104
+ ) ;
105
+ } ) ;
106
+
107
+ const clientAndUserReadyPromise = new Promise < OnReadyResult > ( ( resolve ) => {
108
+ setTimeout ( ( ) => {
109
+ resolve ( {
110
+ success : readySuccess ,
111
+ } ) ;
112
+ } , mockDelay ) ;
113
+ } ) ;
85
114
115
+ return Promise . race ( [ clientAndUserReadyPromise , timeoutPromise ] ) ;
116
+ } ;
86
117
beforeEach ( ( ) => {
87
118
getOnReadyPromise = ( { timeout = 0 } : any ) : Promise < OnReadyResult > =>
88
119
new Promise ( ( resolve ) => {
@@ -200,39 +231,7 @@ describe('hooks', () => {
200
231
mockDelay = 100 ;
201
232
readySuccess = false ;
202
233
// Todo: getOnReadyPromise might be moved in the top later
203
- getOnReadyPromise = ( { timeout = 0 } : any ) : Promise < OnReadyResult > => {
204
- const timeoutPromise = new Promise < OnReadyResult > ( ( resolve ) => {
205
- setTimeout (
206
- ( ) => {
207
- resolve ( {
208
- success : false ,
209
- reason : NotReadyReason . TIMEOUT ,
210
- dataReadyPromise : new Promise ( ( r ) =>
211
- setTimeout (
212
- ( ) =>
213
- r ( {
214
- success : readySuccess ,
215
- } ) ,
216
- mockDelay
217
- )
218
- ) ,
219
- } ) ;
220
- } ,
221
- timeout || mockDelay + 1
222
- ) ;
223
- } ) ;
224
-
225
- const clientAndUserReadyPromise = new Promise < OnReadyResult > ( ( resolve ) => {
226
- setTimeout ( ( ) => {
227
- resolve ( {
228
- success : readySuccess ,
229
- } ) ;
230
- } , mockDelay ) ;
231
- } ) ;
232
-
233
- return Promise . race ( [ clientAndUserReadyPromise , timeoutPromise ] ) ;
234
- } ;
235
-
234
+ getOnReadyPromise = getOnReadyTimeoutPromise ;
236
235
render (
237
236
< OptimizelyProvider optimizely = { optimizelyMock } >
238
237
< MyExperimentComponent options = { { timeout : mockDelay - 10 } } />
@@ -445,7 +444,7 @@ describe('hooks', () => {
445
444
} ) ;
446
445
} ) ;
447
446
448
- describe . skip ( 'useFeature' , ( ) => {
447
+ describe ( 'useFeature' , ( ) => {
449
448
it ( 'should render true when the feature is enabled' , async ( ) => {
450
449
isFeatureEnabledMock . mockReturnValue ( true ) ;
451
450
@@ -454,7 +453,6 @@ describe('hooks', () => {
454
453
< MyFeatureComponent />
455
454
</ OptimizelyProvider >
456
455
) ;
457
- await optimizelyMock . onReady ( ) ;
458
456
await waitFor ( ( ) => expect ( screen . getByTestId ( 'result' ) ) . toHaveTextContent ( 'true|{"foo":"bar"}|true|false' ) ) ;
459
457
} ) ;
460
458
@@ -467,44 +465,33 @@ describe('hooks', () => {
467
465
< MyFeatureComponent />
468
466
</ OptimizelyProvider >
469
467
) ;
470
- await optimizelyMock . onReady ( ) ;
471
468
await waitFor ( ( ) => expect ( screen . getByTestId ( 'result' ) ) . toHaveTextContent ( 'false|{}|true|false' ) ) ;
472
469
} ) ;
473
470
474
471
it ( 'should respect the timeout option passed' , async ( ) => {
472
+ mockDelay = 100 ;
475
473
isFeatureEnabledMock . mockReturnValue ( false ) ;
476
474
featureVariables = { } ;
477
475
readySuccess = false ;
478
-
476
+ getOnReadyPromise = getOnReadyTimeoutPromise ;
479
477
render (
480
478
< OptimizelyProvider optimizely = { optimizelyMock } >
481
- < MyFeatureComponent options = { { timeout : mockDelay } } />
479
+ < MyFeatureComponent options = { { timeout : mockDelay - 10 } } />
482
480
</ OptimizelyProvider >
483
481
) ;
484
482
485
- await waitFor ( ( ) => expect ( screen . getByTestId ( 'result' ) ) . toHaveTextContent ( 'false|{}|false|false' ) ) ; // initial render
486
-
487
- await optimizelyMock . onReady ( ) ;
488
- await waitFor ( ( ) => expect ( screen . getByTestId ( 'result' ) ) . toHaveTextContent ( 'false|{}|false|true' ) ) ; // when didTimeout
483
+ // Initial render
484
+ expect ( screen . getByTestId ( 'result' ) ) . toHaveTextContent ( 'false|{}|false|false' ) ;
489
485
490
- // Simulate datafile fetch completing after timeout has already passed
491
- // isFeatureEnabled now returns true, getFeatureVariables returns variable values
486
+ readySuccess = true ;
492
487
isFeatureEnabledMock . mockReturnValue ( true ) ;
493
488
featureVariables = mockFeatureVariables ;
494
- // Wait for completion of dataReadyPromise
495
- await optimizelyMock . onReady ( ) . then ( ( res ) => res . dataReadyPromise ) ;
496
489
497
- // Simulate datafile fetch completing after timeout has already passed
498
- // Activate now returns a variation
499
- activateMock . mockReturnValue ( '12345' ) ;
500
- // Wait for completion of dataReadyPromise
501
- await optimizelyMock . onReady ( ) . then ( ( res ) => res . dataReadyPromise ) ;
502
- await waitFor ( ( ) => expect ( screen . getByTestId ( 'result' ) ) . toHaveTextContent ( 'true|{"foo":"bar"}|true|true' ) ) ; // when clientReady
490
+ // When timeout is reached, but dataReadyPromise is resolved later with the feature enabled
491
+ await waitFor ( ( ) => expect ( screen . getByTestId ( 'result' ) ) . toHaveTextContent ( 'true|{"foo":"bar"}|true|true' ) ) ;
503
492
} ) ;
504
493
505
494
it ( 'should gracefully handle the client promise rejecting after timeout' , async ( ) => {
506
- jest . useFakeTimers ( ) ;
507
-
508
495
readySuccess = false ;
509
496
isFeatureEnabledMock . mockReturnValue ( true ) ;
510
497
getOnReadyPromise = ( ) : Promise < void > =>
@@ -516,11 +503,7 @@ describe('hooks', () => {
516
503
</ OptimizelyProvider >
517
504
) ;
518
505
519
- jest . advanceTimersByTime ( mockDelay + 1 ) ;
520
-
521
506
await waitFor ( ( ) => expect ( screen . getByTestId ( 'result' ) ) . toHaveTextContent ( 'false|{}|false|false' ) ) ;
522
-
523
- jest . useRealTimers ( ) ;
524
507
} ) ;
525
508
526
509
it ( 'should re-render when the user attributes change using autoUpdate' , async ( ) => {
@@ -535,7 +518,6 @@ describe('hooks', () => {
535
518
536
519
// TODO - Wrap this with async act() once we upgrade to React 16.9
537
520
// See https://github.com/facebook/react/issues/15379
538
- await optimizelyMock . onReady ( ) ;
539
521
await waitFor ( ( ) => expect ( screen . getByTestId ( 'result' ) ) . toHaveTextContent ( 'false|{}|true|false' ) ) ;
540
522
541
523
isFeatureEnabledMock . mockReturnValue ( true ) ;
@@ -559,7 +541,6 @@ describe('hooks', () => {
559
541
560
542
// TODO - Wrap this with async act() once we upgrade to React 16.9
561
543
// See https://github.com/facebook/react/issues/15379
562
- await optimizelyMock . onReady ( ) ;
563
544
await waitFor ( ( ) => expect ( screen . getByTestId ( 'result' ) ) . toHaveTextContent ( 'false|{}|true|false' ) ) ;
564
545
565
546
isFeatureEnabledMock . mockReturnValue ( true ) ;
0 commit comments