import { afterEach, describe, expect, it, vi } from 'vitest' import { coordinateCrossTabRefresh, CrossTabRefreshTimeoutError } from './crossTabRefresh' afterEach(() => vi.unstubAllGlobals()) describe('cross-tab refresh coordination', () => { it('reuses the rotated session after waiting for another tab', async () => { let currentRefreshToken = 'refresh-old' const refresh = vi.fn() const reuseCurrentSession = vi.fn(async () => 'access-new') vi.stubGlobal('navigator', { locks: { request: vi.fn(async (_name: string, _options: LockOptions, callback: () => Promise) => { currentRefreshToken = 'refresh-new' return callback() }), }, }) await expect(coordinateCrossTabRefresh({ lockName: 'admin-refresh', observedRefreshToken: 'refresh-old', currentRefreshToken: () => currentRefreshToken, reuseCurrentSession, refresh, })).resolves.toBe('access-new') expect(reuseCurrentSession).toHaveBeenCalledOnce() expect(refresh).not.toHaveBeenCalled() }) it('performs the refresh when the token has not changed', async () => { const refresh = vi.fn(async () => 'access-new') vi.stubGlobal('navigator', { locks: { request: vi.fn(async (_name: string, _options: LockOptions, callback: () => Promise) => callback()) }, }) await expect(coordinateCrossTabRefresh({ lockName: 'admin-refresh', observedRefreshToken: 'refresh-old', currentRefreshToken: () => 'refresh-old', reuseCurrentSession: vi.fn(), refresh, })).resolves.toBe('access-new') expect(refresh).toHaveBeenCalledWith('refresh-old') }) it('does not wait for rotation after the shared session was removed', async () => { const refreshError = new Error('session removed') const refresh = vi.fn(async () => { throw refreshError }) vi.stubGlobal('navigator', {}) await expect(coordinateCrossTabRefresh({ lockName: 'admin-refresh', observedRefreshToken: 'refresh-old', currentRefreshToken: () => '', reuseCurrentSession: vi.fn(), refresh, })).rejects.toBe(refreshError) expect(refresh).toHaveBeenCalledWith('refresh-old') }) it('aborts a refresh lock that cannot be acquired', async () => { vi.stubGlobal('navigator', { locks: { request: vi.fn((_name: string, options: LockOptions) => new Promise((_resolve, reject) => { options.signal?.addEventListener('abort', () => reject(options.signal?.reason), { once: true }) })), }, }) await expect(coordinateCrossTabRefresh({ lockName: 'admin-refresh', lockTimeoutMs: 5, observedRefreshToken: 'refresh-old', currentRefreshToken: () => 'refresh-old', reuseCurrentSession: vi.fn(), refresh: vi.fn(), })).rejects.toBeInstanceOf(CrossTabRefreshTimeoutError) }) })