65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|||
|
|
import { coordinateCrossTabRefresh } 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, callback: () => Promise<string>) => {
|
||
|
|
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, callback: () => Promise<string>) => 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')
|
||
|
|
})
|
||
|
|
})
|