@@ -39,7 +39,10 @@ describe('Session ID manager', () => {
3939
4040 persistence = {
4141 props : { [ SESSION_ID ] : undefined } ,
42- register : jest . fn ( ) ,
42+ register : jest . fn ( ) . mockImplementation ( ( props ) => {
43+ // Mock the behavior of register - it should update the props
44+ Object . assign ( persistence . props , props )
45+ } ) ,
4346 _disabled : false ,
4447 }
4548 ; ( sessionStore . _is_supported as jest . Mock ) . mockReturnValue ( true )
@@ -393,22 +396,69 @@ describe('Session ID manager', () => {
393396 expect ( sessionIdManager [ '_enforceIdleTimeout' ] ) . toEqual ( originalTimer )
394397 } )
395398
396- /** timer doesn't advance and fire this? */
397- it . skip ( 'resets session id despite no activity after timeout' , ( ) => {
398- ; ( uuidv7 as jest . Mock ) . mockImplementationOnce ( ( ) => 'originalUUID' )
399+ it ( 'resets session when idle timeout is exceeded' , async ( ) => {
400+ jest . useFakeTimers ( )
399401
400402 const sessionIdManager = sessionIdMgr ( persistence )
401- const { sessionId : originalSessionId } = sessionIdManager . checkAndGetSessionAndWindowId (
402- undefined ,
403- timestamp
404- )
405- expect ( originalSessionId ) . toBeDefined ( )
403+ const resetSpy = jest . spyOn ( sessionIdManager , 'resetSessionId' )
404+
405+ // Start with a fresh session
406+ sessionIdManager . checkAndGetSessionAndWindowId ( false , timestamp )
407+
408+ // Set up persistence to simulate inactivity - session was last active long ago
409+ const idleTimestamp = timestamp - ( sessionIdManager . sessionTimeoutMs + 1000 )
410+ persistence . props [ SESSION_ID ] = [ idleTimestamp , 'oldSessionID' , idleTimestamp ]
411+
412+ // Fast-forward time to trigger the idle timeout timer
413+ const idleTimeoutMs = sessionIdManager . sessionTimeoutMs * 1.1
414+ jest . advanceTimersByTime ( idleTimeoutMs + 1000 )
415+
416+ // Timer should have fired and called resetSessionId
417+ expect ( resetSpy ) . toHaveBeenCalled ( )
418+
419+ // After reset, persistence.register should have been called with null values
420+ expect ( persistence . register ) . toHaveBeenCalledWith ( { [ SESSION_ID ] : [ null , null , null ] } )
421+
422+ // Next call should generate a new session due to no session ID
423+ const newSessionData = sessionIdManager . checkAndGetSessionAndWindowId ( false )
424+ expect ( newSessionData . sessionId ) . toBe ( 'newUUID' )
425+ expect ( newSessionData . sessionId ) . not . toEqual ( 'oldSessionID' )
426+ expect ( newSessionData . changeReason ?. noSessionId ) . toBe ( true )
427+
428+ jest . useRealTimers ( )
429+ } )
430+
431+ it ( 'timer checks current session activity before resetting' , async ( ) => {
432+ jest . useFakeTimers ( )
433+
434+ const sessionIdManager = sessionIdMgr ( persistence )
435+ const resetSpy = jest . spyOn ( sessionIdManager , 'resetSessionId' )
436+
437+ // Mock _getSessionId to control what the timer sees
438+ const getSessionIdSpy = jest . spyOn ( sessionIdManager as any , '_getSessionId' )
439+
440+ // Start with a fresh session
441+ sessionIdManager . checkAndGetSessionAndWindowId ( false , timestamp )
442+
443+ // Initially set up an idle session
444+ const idleTimestamp = timestamp - ( sessionIdManager . sessionTimeoutMs + 1000 )
445+ getSessionIdSpy . mockReturnValue ( [ idleTimestamp , 'sharedSessionID' , timestamp ] )
446+
447+ // Fast-forward time almost to when timer fires
448+ const idleTimeoutMs = sessionIdManager . sessionTimeoutMs * 1.1
449+ jest . advanceTimersByTime ( idleTimeoutMs - 100 )
450+
451+ // Before timer fires, change mock to return recent activity (simulating another window updating)
452+ const recentTimestamp = new Date ( ) . getTime ( ) - 1000 // 1 second ago
453+ getSessionIdSpy . mockReturnValue ( [ recentTimestamp , 'sharedSessionID' , timestamp ] )
454+
455+ // Let the timer fire
456+ jest . advanceTimersByTime ( 200 )
406457
407- jest . advanceTimersByTime ( DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS * 1.1 + 1 )
458+ // The timer should NOT have reset the session because it found recent activity
459+ expect ( resetSpy ) . not . toHaveBeenCalled ( )
408460
409- const { sessionId : finalSessionId } = sessionIdManager . checkAndGetSessionAndWindowId ( undefined , timestamp )
410- expect ( finalSessionId ) . toBeDefined ( )
411- expect ( finalSessionId ) . not . toEqual ( originalSessionId )
461+ jest . useRealTimers ( )
412462 } )
413463 } )
414464} )
0 commit comments