11// @ts -nocheck
22import { loggerMock } from '../../logger/__tests__/sdkLogger.mock' ;
33import SplitIO from '../../../types/splitio' ;
4- import { SDK_READY , SDK_READY_FROM_CACHE , SDK_READY_TIMED_OUT , SDK_UPDATE , SDK_SPLITS_ARRIVED , SDK_SEGMENTS_ARRIVED } from '../constants' ;
4+ import { SDK_READY , SDK_READY_FROM_CACHE , SDK_READY_TIMED_OUT , SDK_UPDATE , SDK_SPLITS_ARRIVED , SDK_SEGMENTS_ARRIVED , SDK_SPLITS_CACHE_LOADED } from '../constants' ;
55import { sdkReadinessManagerFactory } from '../sdkReadinessManager' ;
66import { IReadinessManager } from '../types' ;
77import { ERROR_CLIENT_LISTENER , CLIENT_READY_FROM_CACHE , CLIENT_READY , CLIENT_NO_LISTENER } from '../../logger/constants' ;
@@ -20,6 +20,12 @@ const EventEmitterMock = jest.fn(() => ({
2020
2121// Makes readinessManager emit SDK_READY & update isReady flag
2222function emitReadyEvent ( readinessManager : IReadinessManager ) {
23+ if ( readinessManager . gate instanceof EventEmitter ) {
24+ readinessManager . splits . emit ( SDK_SPLITS_ARRIVED ) ;
25+ readinessManager . segments . emit ( SDK_SEGMENTS_ARRIVED ) ;
26+ return ;
27+ }
28+
2329 readinessManager . splits . once . mock . calls [ 0 ] [ 1 ] ( ) ;
2430 readinessManager . splits . on . mock . calls [ 0 ] [ 1 ] ( ) ;
2531 readinessManager . segments . once . mock . calls [ 0 ] [ 1 ] ( ) ;
@@ -32,14 +38,19 @@ const timeoutErrorMessage = 'Split SDK emitted SDK_READY_TIMED_OUT event.';
3238
3339// Makes readinessManager emit SDK_READY_TIMED_OUT & update hasTimedout flag
3440function emitTimeoutEvent ( readinessManager : IReadinessManager ) {
41+ if ( readinessManager . gate instanceof EventEmitter ) {
42+ readinessManager . timeout ( ) ;
43+ return ;
44+ }
45+
3546 readinessManager . gate . once . mock . calls [ 1 ] [ 1 ] ( timeoutErrorMessage ) ;
3647 readinessManager . hasTimedout = ( ) => true ;
3748 if ( readinessManager . gate . once . mock . calls [ 4 ] ) readinessManager . gate . once . mock . calls [ 4 ] [ 1 ] ( timeoutErrorMessage ) ; // whenReady promise
3849}
3950
4051describe ( 'SDK Readiness Manager - Event emitter' , ( ) => {
4152
42- afterEach ( ( ) => { loggerMock . mockClear ( ) ; } ) ;
53+ beforeEach ( ( ) => { loggerMock . mockClear ( ) ; } ) ;
4354
4455 test ( 'Providing the gate object to get the SDK status interface that manages events' , ( ) => {
4556 expect ( typeof sdkReadinessManagerFactory ) . toBe ( 'function' ) ; // The module exposes a function.
@@ -203,82 +214,74 @@ describe('SDK Readiness Manager - Event emitter', () => {
203214 } ) ;
204215} ) ;
205216
206- describe ( 'SDK Readiness Manager - whenReady promise ' , ( ) => {
217+ describe ( 'SDK Readiness Manager - Promises ' , ( ) => {
207218
208- test ( '.whenReady() promise behavior for clients' , async ( ) => {
209- const sdkReadinessManager = sdkReadinessManagerFactory ( EventEmitterMock , fullSettings ) ;
219+ test ( '.whenReady() and .whenReadyFromCache() promises resolves when SDK_READY is emitted' , async ( ) => {
220+ const sdkReadinessManager = sdkReadinessManagerFactory ( EventEmitter , fullSettings ) ;
221+
222+ // make the SDK ready from cache
223+ sdkReadinessManager . readinessManager . splits . emit ( SDK_SPLITS_CACHE_LOADED ) ;
224+ expect ( await sdkReadinessManager . sdkStatus . whenReadyFromCache ( ) ) . toBe ( false ) ;
225+
226+ // validate error log for SDK_READY_FROM_CACHE
227+ expect ( loggerMock . error ) . not . toBeCalled ( ) ;
228+ sdkReadinessManager . readinessManager . gate . on ( SDK_READY_FROM_CACHE , ( ) => { } ) ;
229+ expect ( loggerMock . error ) . toBeCalledWith ( ERROR_CLIENT_LISTENER , [ 'SDK_READY_FROM_CACHE' ] ) ;
210230
231+ const readyFromCache = sdkReadinessManager . sdkStatus . whenReadyFromCache ( ) ;
211232 const ready = sdkReadinessManager . sdkStatus . whenReady ( ) ;
212- expect ( ready instanceof Promise ) . toBe ( true ) ; // It should return a promise.
213233
214234 // make the SDK ready
215235 emitReadyEvent ( sdkReadinessManager . readinessManager ) ;
236+ expect ( await sdkReadinessManager . sdkStatus . whenReadyFromCache ( ) ) . toBe ( true ) ;
216237
217238 let testPassedCount = 0 ;
218- await ready . then (
219- ( ) => {
220- expect ( 'It should be a promise that will be resolved when the SDK is ready.' ) ;
221- testPassedCount ++ ;
222- } ,
223- ( ) => { throw new Error ( 'It should be resolved on ready event, not rejected.' ) ; }
224- ) ;
239+ function incTestPassedCount ( ) { testPassedCount ++ ; }
240+ function throwTestFailed ( ) { throw new Error ( 'It should be resolved, not rejected.' ) ; }
225241
226- // any subsequent call to .whenReady() must be a resolved promise
227- await sdkReadinessManager . sdkStatus . whenReady ( ) . then (
228- ( ) => {
229- expect ( 'A subsequent call should be a resolved promise.' ) ;
230- testPassedCount ++ ;
231- } ,
232- ( ) => { throw new Error ( 'It should be resolved on ready event, not rejected.' ) ; }
233- ) ;
242+ await readyFromCache . then ( incTestPassedCount , throwTestFailed ) ;
243+ await ready . then ( incTestPassedCount , throwTestFailed ) ;
234244
235- // control assertion. stubs already reset.
236- expect ( testPassedCount ) . toBe ( 2 ) ;
245+ // any subsequent call to .whenReady() and .whenReadyFromCache() must be a resolved promise
246+ await sdkReadinessManager . sdkStatus . whenReady ( ) . then ( incTestPassedCount , throwTestFailed ) ;
247+ await sdkReadinessManager . sdkStatus . whenReadyFromCache ( ) . then ( incTestPassedCount , throwTestFailed ) ;
237248
238- const sdkReadinessManagerForTimedout = sdkReadinessManagerFactory ( EventEmitterMock , fullSettings ) ;
249+ expect ( testPassedCount ) . toBe ( 4 ) ;
250+ } ) ;
239251
252+ test ( '.whenReady() and .whenReadyFromCache() promises reject when SDK_READY_TIMED_OUT is emitted before SDK_READY' , async ( ) => {
253+ const sdkReadinessManagerForTimedout = sdkReadinessManagerFactory ( EventEmitter , fullSettings ) ;
254+
255+ const readyFromCacheForTimeout = sdkReadinessManagerForTimedout . sdkStatus . whenReadyFromCache ( ) ;
240256 const readyForTimeout = sdkReadinessManagerForTimedout . sdkStatus . whenReady ( ) ;
241257
242258 emitTimeoutEvent ( sdkReadinessManagerForTimedout . readinessManager ) ; // make the SDK timeout
243259
244- await readyForTimeout . then (
245- ( ) => { throw new Error ( 'It should be a promise that was rejected on SDK_READY_TIMED_OUT, not resolved.' ) ; } ,
246- ( ) => {
247- expect ( 'It should be a promise that will be rejected when the SDK is timed out.' ) ;
248- testPassedCount ++ ;
249- }
250- ) ;
260+ let testPassedCount = 0 ;
261+ function incTestPassedCount ( ) { testPassedCount ++ ; }
262+ function throwTestFailed ( ) { throw new Error ( 'It should rejected, not resolved.' ) ; }
251263
252- // any subsequent call to .whenReady() must be a rejected promise until the SDK is ready
253- await sdkReadinessManagerForTimedout . sdkStatus . whenReady ( ) . then (
254- ( ) => { throw new Error ( 'It should be a promise that was rejected on SDK_READY_TIMED_OUT, not resolved.' ) ; } ,
255- ( ) => {
256- expect ( 'A subsequent call should be a rejected promise.' ) ;
257- testPassedCount ++ ;
258- }
259- ) ;
264+ await readyFromCacheForTimeout . then ( throwTestFailed , incTestPassedCount ) ;
265+ await readyForTimeout . then ( throwTestFailed , incTestPassedCount ) ;
266+
267+ // any subsequent call to .whenReady() and .whenReadyFromCache() must be a rejected promise until the SDK is ready
268+ await sdkReadinessManagerForTimedout . sdkStatus . whenReadyFromCache ( ) . then ( throwTestFailed , incTestPassedCount ) ;
269+ await sdkReadinessManagerForTimedout . sdkStatus . whenReady ( ) . then ( throwTestFailed , incTestPassedCount ) ;
260270
261271 // make the SDK ready
262272 emitReadyEvent ( sdkReadinessManagerForTimedout . readinessManager ) ;
263273
264274 // once SDK_READY, `.whenReady()` returns a resolved promise
265- await sdkReadinessManagerForTimedout . sdkStatus . whenReady ( ) . then (
266- ( ) => {
267- expect ( 'It should be a resolved promise when the SDK is ready, even after an SDK timeout.' ) ;
268- loggerMock . mockClear ( ) ;
269- testPassedCount ++ ;
270- expect ( testPassedCount ) . toBe ( 5 ) ;
271- } ,
272- ( ) => { throw new Error ( 'It should be resolved on ready event, not rejected.' ) ; }
273- ) ;
275+ await sdkReadinessManagerForTimedout . sdkStatus . whenReady ( ) . then ( incTestPassedCount , throwTestFailed ) ;
276+ await sdkReadinessManagerForTimedout . sdkStatus . whenReadyFromCache ( ) . then ( incTestPassedCount , throwTestFailed ) ;
277+
278+ expect ( testPassedCount ) . toBe ( 6 ) ;
274279 } ) ;
275280
276- test ( 'whenReady promise count as a callback and resolves on SDK_READY' , ( done ) => {
281+ test ( 'whenReady promise counts as an SDK_READY listener ' , ( done ) => {
277282 let sdkReadinessManager = sdkReadinessManagerFactory ( EventEmitter , fullSettings ) ;
278283
279- // Emit ready event
280- sdkReadinessManager . readinessManager . splits . emit ( SDK_SPLITS_ARRIVED ) ;
281- sdkReadinessManager . readinessManager . segments . emit ( SDK_SEGMENTS_ARRIVED ) ;
284+ emitReadyEvent ( sdkReadinessManager . readinessManager ) ;
282285
283286 expect ( loggerMock . warn ) . toBeCalledWith ( CLIENT_NO_LISTENER ) ; // We should get a warning if the SDK get's ready before calling the whenReady method or attaching a listener to the ready event
284287 loggerMock . warn . mockClear ( ) ;
@@ -291,16 +294,17 @@ describe('SDK Readiness Manager - whenReady promise', () => {
291294 throw new Error ( 'This should not be called as the promise is being resolved.' ) ;
292295 } ) ;
293296
294- // Emit ready event
295- sdkReadinessManager . readinessManager . splits . emit ( SDK_SPLITS_ARRIVED ) ;
296- sdkReadinessManager . readinessManager . segments . emit ( SDK_SEGMENTS_ARRIVED ) ;
297+ emitReadyEvent ( sdkReadinessManager . readinessManager ) ;
297298
298299 expect ( loggerMock . warn ) . not . toBeCalled ( ) ; // But if we have a listener or call the whenReady method, we get no warnings.
299300 } ) ;
300301} ) ;
301302
302303// @TODO : remove in next major
303304describe ( 'SDK Readiness Manager - Ready promise' , ( ) => {
305+
306+ beforeEach ( ( ) => { loggerMock . mockClear ( ) ; } ) ;
307+
304308 test ( 'ready promise count as a callback and resolves on SDK_READY' , ( done ) => {
305309 const sdkReadinessManager = sdkReadinessManagerFactory ( EventEmitterMock , fullSettings ) ;
306310 const readyPromise = sdkReadinessManager . sdkStatus . ready ( ) ;
0 commit comments