@@ -26,6 +26,12 @@ jest.mock("@/utils", () => ({
26
26
} ,
27
27
} ) ) ;
28
28
29
+ // Helper function to wait for async notifications to complete
30
+ const waitForAsyncNotifications = async ( ) => {
31
+ // Wait for the next tick of the event loop to ensure async operations complete
32
+ await new Promise ( ( resolve ) => setImmediate ( resolve ) ) ;
33
+ } ;
34
+
29
35
// Mock the verify and chunks modules
30
36
jest . mock ( "@/verify" , ( ) => ( {
31
37
verifyEvents : jest . fn ( ( ) => ( source$ : Observable < any > ) => source$ ) ,
@@ -86,7 +92,7 @@ describe("Agent Mutations", () => {
86
92
expect ( agent . messages [ 1 ] ) . toBe ( userMessage ) ;
87
93
88
94
// Wait for async notifications
89
- await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
95
+ await waitForAsyncNotifications ( ) ;
90
96
91
97
// Should fire onNewMessage and onMessagesChanged
92
98
expect ( mockSubscriber . onNewMessage ) . toHaveBeenCalledWith ( {
@@ -116,7 +122,7 @@ describe("Agent Mutations", () => {
116
122
agent . addMessage ( assistantMessage ) ;
117
123
118
124
// Wait for async notifications
119
- await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
125
+ await waitForAsyncNotifications ( ) ;
120
126
121
127
expect ( mockSubscriber . onNewMessage ) . toHaveBeenCalledWith ( {
122
128
message : assistantMessage ,
@@ -165,7 +171,7 @@ describe("Agent Mutations", () => {
165
171
agent . addMessage ( assistantMessage ) ;
166
172
167
173
// Wait for async notifications
168
- await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
174
+ await waitForAsyncNotifications ( ) ;
169
175
170
176
expect ( mockSubscriber . onNewMessage ) . toHaveBeenCalledWith ( {
171
177
message : assistantMessage ,
@@ -236,7 +242,7 @@ describe("Agent Mutations", () => {
236
242
expect ( agent . messages ) . toHaveLength ( initialLength + 3 ) ;
237
243
238
244
// Wait for async notifications
239
- await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
245
+ await waitForAsyncNotifications ( ) ;
240
246
241
247
// Should fire onNewMessage for each message
242
248
expect ( mockSubscriber . onNewMessage ) . toHaveBeenCalledTimes ( 3 ) ;
@@ -266,7 +272,7 @@ describe("Agent Mutations", () => {
266
272
expect ( agent . messages ) . toHaveLength ( initialLength ) ;
267
273
268
274
// Wait for async notifications
269
- await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
275
+ await waitForAsyncNotifications ( ) ;
270
276
271
277
// Should still fire onMessagesChanged even for empty array
272
278
expect ( mockSubscriber . onMessagesChanged ) . toHaveBeenCalledTimes ( 1 ) ;
@@ -310,7 +316,7 @@ describe("Agent Mutations", () => {
310
316
expect ( agent . messages [ 1 ] ) . toEqual ( newMessages [ 1 ] ) ;
311
317
312
318
// Wait for async notifications
313
- await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
319
+ await waitForAsyncNotifications ( ) ;
314
320
315
321
// Should ONLY fire onMessagesChanged
316
322
expect ( mockSubscriber . onMessagesChanged ) . toHaveBeenCalledTimes ( 1 ) ;
@@ -331,7 +337,7 @@ describe("Agent Mutations", () => {
331
337
expect ( agent . messages ) . toHaveLength ( 0 ) ;
332
338
333
339
// Wait for async notifications
334
- await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
340
+ await waitForAsyncNotifications ( ) ;
335
341
336
342
expect ( mockSubscriber . onMessagesChanged ) . toHaveBeenCalledTimes ( 1 ) ;
337
343
expect ( mockSubscriber . onNewMessage ) . not . toHaveBeenCalled ( ) ;
@@ -354,7 +360,7 @@ describe("Agent Mutations", () => {
354
360
expect ( agent . state ) . not . toBe ( newState ) ; // Should be a clone
355
361
356
362
// Wait for async notifications
357
- await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
363
+ await waitForAsyncNotifications ( ) ;
358
364
359
365
// Should ONLY fire onStateChanged
360
366
expect ( mockSubscriber . onStateChanged ) . toHaveBeenCalledTimes ( 1 ) ;
@@ -376,40 +382,38 @@ describe("Agent Mutations", () => {
376
382
expect ( agent . state ) . toEqual ( { } ) ;
377
383
378
384
// Wait for async notifications
379
- await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
385
+ await waitForAsyncNotifications ( ) ;
380
386
381
387
expect ( mockSubscriber . onStateChanged ) . toHaveBeenCalledTimes ( 1 ) ;
382
388
} ) ;
383
389
} ) ;
384
390
385
- describe ( "sequential execution" , ( ) => {
386
- it ( "should execute subscriber notifications sequentially " , async ( ) => {
391
+ describe ( "execution order " , ( ) => {
392
+ it ( "should execute subscriber notifications in registration order " , async ( ) => {
387
393
const callOrder : string [ ] = [ ] ;
388
394
389
- const slowSubscriber : RunAgentSubscriber = {
390
- onNewMessage : jest . fn ( ) . mockImplementation ( async ( ) => {
391
- await new Promise ( ( resolve ) => setTimeout ( resolve , 20 ) ) ;
392
- callOrder . push ( "slow-newMessage" ) ;
395
+ const firstSubscriber : RunAgentSubscriber = {
396
+ onNewMessage : jest . fn ( ) . mockImplementation ( ( ) => {
397
+ callOrder . push ( "first-newMessage" ) ;
393
398
} ) ,
394
- onMessagesChanged : jest . fn ( ) . mockImplementation ( async ( ) => {
395
- await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
396
- callOrder . push ( "slow-messagesChanged" ) ;
399
+ onMessagesChanged : jest . fn ( ) . mockImplementation ( ( ) => {
400
+ callOrder . push ( "first-messagesChanged" ) ;
397
401
} ) ,
398
402
} ;
399
403
400
- const fastSubscriber : RunAgentSubscriber = {
404
+ const secondSubscriber : RunAgentSubscriber = {
401
405
onNewMessage : jest . fn ( ) . mockImplementation ( ( ) => {
402
- callOrder . push ( "fast -newMessage" ) ;
406
+ callOrder . push ( "second -newMessage" ) ;
403
407
} ) ,
404
408
onMessagesChanged : jest . fn ( ) . mockImplementation ( ( ) => {
405
- callOrder . push ( "fast -messagesChanged" ) ;
409
+ callOrder . push ( "second -messagesChanged" ) ;
406
410
} ) ,
407
411
} ;
408
412
409
413
// Clear the default subscriber and add our test subscribers
410
414
agent . subscribers = [ ] ;
411
- agent . subscribe ( slowSubscriber ) ;
412
- agent . subscribe ( fastSubscriber ) ;
415
+ agent . subscribe ( firstSubscriber ) ;
416
+ agent . subscribe ( secondSubscriber ) ;
413
417
414
418
const message : Message = {
415
419
id : "test-msg" ,
@@ -419,15 +423,17 @@ describe("Agent Mutations", () => {
419
423
420
424
agent . addMessage ( message ) ;
421
425
422
- // Wait for all async operations to complete
423
- await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
426
+ // Wait for all async operations to complete by polling until all calls are made
427
+ while ( callOrder . length < 4 ) {
428
+ await waitForAsyncNotifications ( ) ;
429
+ }
424
430
425
431
// Verify sequential execution order
426
432
expect ( callOrder ) . toEqual ( [
427
- "slow -newMessage" ,
428
- "fast -newMessage" ,
429
- "slow -messagesChanged" ,
430
- "fast -messagesChanged" ,
433
+ "first -newMessage" ,
434
+ "second -newMessage" ,
435
+ "first -messagesChanged" ,
436
+ "second -messagesChanged" ,
431
437
] ) ;
432
438
} ) ;
433
439
} ) ;
@@ -464,7 +470,7 @@ describe("Agent Mutations", () => {
464
470
agent . addMessage ( message ) ;
465
471
466
472
// Wait for async notifications
467
- await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
473
+ await waitForAsyncNotifications ( ) ;
468
474
469
475
// All subscribers should receive notifications
470
476
[ mockSubscriber , subscriber2 , subscriber3 ] . forEach ( ( sub ) => {
0 commit comments