@@ -650,52 +650,59 @@ describe("resolveSessionOptionGroups", () => {
650650
651651describe ( "handleChatManualRefresh" , ( ) => {
652652 it ( "waits for chat history before scrolling and clearing refresh state" , async ( ) => {
653- let animationFrameCallback : FrameRequestCallback | null = null ;
653+ const animationFrame = { callback : undefined as FrameRequestCallback | undefined } ;
654654 const previousRequestAnimationFrame = globalThis . requestAnimationFrame ;
655655 Object . defineProperty ( globalThis , "requestAnimationFrame" , {
656656 configurable : true ,
657657 value : vi . fn ( ( callback : FrameRequestCallback ) => {
658- animationFrameCallback = callback ;
658+ animationFrame . callback = callback ;
659659 return 1 ;
660660 } ) ,
661661 } ) ;
662- let resolveRefresh ! : ( ) => void ;
663- refreshChatMock . mockReturnValueOnce (
664- new Promise < void > ( ( resolve ) => {
665- resolveRefresh = resolve ;
666- } ) ,
667- ) ;
668- const state = {
669- chatManualRefreshInFlight : false ,
670- chatNewMessagesBelow : true ,
671- updateComplete : Promise . resolve ( ) ,
672- resetToolStream : vi . fn ( ) ,
673- scrollToBottom : vi . fn ( ) ,
674- } as unknown as Parameters < typeof handleChatManualRefresh > [ 0 ] ;
675-
676- const run = handleChatManualRefresh ( state ) ;
677- await Promise . resolve ( ) ;
678-
679- expect ( state . scrollToBottom ) . not . toHaveBeenCalled ( ) ;
680- resolveRefresh ( ) ;
681- await run ;
682-
683- expect ( refreshChatMock ) . toHaveBeenCalledWith ( state , {
684- awaitHistory : true ,
685- scheduleScroll : false ,
686- } ) ;
687- expect ( state . scrollToBottom ) . toHaveBeenCalledWith ( { smooth : true } ) ;
688- expect ( state . chatManualRefreshInFlight ) . toBe ( true ) ;
689- expect ( animationFrameCallback ) . toBeTypeOf ( "function" ) ;
690-
691- animationFrameCallback ?.( 0 ) ;
692-
693- expect ( state . chatManualRefreshInFlight ) . toBe ( false ) ;
694- expect ( state . chatNewMessagesBelow ) . toBe ( false ) ;
695- Object . defineProperty ( globalThis , "requestAnimationFrame" , {
696- configurable : true ,
697- value : previousRequestAnimationFrame ,
698- } ) ;
662+ try {
663+ let resolveRefresh ! : ( ) => void ;
664+ refreshChatMock . mockReturnValueOnce (
665+ new Promise < void > ( ( resolve ) => {
666+ resolveRefresh = resolve ;
667+ } ) ,
668+ ) ;
669+ const state = {
670+ chatManualRefreshInFlight : false ,
671+ chatNewMessagesBelow : true ,
672+ updateComplete : Promise . resolve ( ) ,
673+ resetToolStream : vi . fn ( ) ,
674+ scrollToBottom : vi . fn ( ) ,
675+ } as unknown as Parameters < typeof handleChatManualRefresh > [ 0 ] ;
676+
677+ const run = handleChatManualRefresh ( state ) ;
678+ await Promise . resolve ( ) ;
679+
680+ expect ( state . scrollToBottom ) . not . toHaveBeenCalled ( ) ;
681+ resolveRefresh ( ) ;
682+ await run ;
683+
684+ expect ( refreshChatMock ) . toHaveBeenCalledWith ( state , {
685+ awaitHistory : true ,
686+ scheduleScroll : false ,
687+ } ) ;
688+ expect ( state . scrollToBottom ) . toHaveBeenCalledWith ( { smooth : true } ) ;
689+ expect ( state . chatManualRefreshInFlight ) . toBe ( true ) ;
690+ expect ( animationFrame . callback ) . toBeTypeOf ( "function" ) ;
691+
692+ const callback = animationFrame . callback ;
693+ if ( ! callback ) {
694+ throw new Error ( "expected manual refresh to schedule a frame callback" ) ;
695+ }
696+ callback ( 0 ) ;
697+
698+ expect ( state . chatManualRefreshInFlight ) . toBe ( false ) ;
699+ expect ( state . chatNewMessagesBelow ) . toBe ( false ) ;
700+ } finally {
701+ Object . defineProperty ( globalThis , "requestAnimationFrame" , {
702+ configurable : true ,
703+ value : previousRequestAnimationFrame ,
704+ } ) ;
705+ }
699706 } ) ;
700707} ) ;
701708
0 commit comments