11/* eslint-disable @typescript-eslint/no-floating-promises */
2+ import { noop } from 'lodash'
23import { Analytics } from '../../analytics'
34import { pWhile } from '../../../lib/p-while'
45import * as timer from '../../../lib/priority-queue/backoff'
@@ -9,6 +10,7 @@ import {
910import { Context , ContextCancelation } from '../../context'
1011import { Plugin } from '../../plugin'
1112import { EventQueue } from '../event-queue'
13+ import { pTimeout } from '../../callback'
1214
1315async function flushAll ( eq : EventQueue ) : Promise < Context [ ] > {
1416 const flushSpy = jest . spyOn ( eq , 'flush' )
@@ -164,6 +166,37 @@ describe('Flushing', () => {
164166 expect ( eq . queue . getAttempts ( fruitBasket ) ) . toEqual ( 2 )
165167 } )
166168
169+ test ( 'waits for critical tasks to finish before performing event deliveries' , async ( ) => {
170+ jest . useRealTimers ( )
171+
172+ const eq = new EventQueue ( )
173+
174+ let finishCriticalTask : ( ) => void = noop
175+ const startTask = ( ) =>
176+ new Promise < void > ( ( res ) => ( finishCriticalTask = res ) )
177+
178+ // some preceding events that've been scheduled
179+ const p1 = eq . dispatch ( fruitBasket )
180+ const p2 = eq . dispatch ( basketView )
181+ // a critical task has been kicked off
182+ eq . criticalTasks . run ( startTask )
183+ // a succeeding event
184+ const p3 = eq . dispatch ( shopper )
185+
186+ // even after a good amount of time, none of the events should be delivered
187+ await expect ( pTimeout ( Promise . race ( [ p1 , p2 , p3 ] ) , 1000 ) ) . rejects . toThrow ( )
188+
189+ // give the green light
190+ finishCriticalTask ( )
191+
192+ // now that the task is complete, the delivery should resume
193+ expect ( await Promise . all ( [ p1 , p2 , p3 ] ) ) . toMatchObject ( [
194+ fruitBasket ,
195+ basketView ,
196+ shopper ,
197+ ] )
198+ } )
199+
167200 test ( 'delivers events on retry' , async ( ) => {
168201 jest . useRealTimers ( )
169202
0 commit comments