import assert from 'node:assert/strict' import test from 'node:test' import { coordinateCrossTabRefresh } from './crossTabRefresh.ts' test('reuses tokens rotated by another browser tab while waiting for the refresh lock', async () => { let currentRefreshToken = 'refresh-old' let refreshCalls = 0 const originalNavigator = globalThis.navigator Object.defineProperty(globalThis, 'navigator', { configurable: true, value: { locks: { async request(_name, callback) { currentRefreshToken = 'refresh-new' return callback() }, }, }, }) try { const result = await coordinateCrossTabRefresh({ lockName: 'client-refresh', observedRefreshToken: 'refresh-old', currentRefreshToken: () => currentRefreshToken, reuseCurrentSession: async () => 'access-new', refresh: async () => { refreshCalls += 1 return 'unexpected' }, }) assert.equal(result, 'access-new') assert.equal(refreshCalls, 0) } finally { Object.defineProperty(globalThis, 'navigator', { configurable: true, value: originalNavigator }) } }) test('refreshes normally when this tab owns the current refresh token', async () => { const originalNavigator = globalThis.navigator Object.defineProperty(globalThis, 'navigator', { configurable: true, value: { locks: { request: async (_name, callback) => callback() } }, }) try { const result = await coordinateCrossTabRefresh({ lockName: 'client-refresh', observedRefreshToken: 'refresh-old', currentRefreshToken: () => 'refresh-old', reuseCurrentSession: async () => 'unexpected', refresh: async (refreshToken) => `access-for-${refreshToken}`, }) assert.equal(result, 'access-for-refresh-old') } finally { Object.defineProperty(globalThis, 'navigator', { configurable: true, value: originalNavigator }) } }) test('does not wait for rotation after the shared session was removed', async () => { const originalNavigator = globalThis.navigator const refreshError = new Error('session removed') Object.defineProperty(globalThis, 'navigator', { configurable: true, value: {} }) try { await assert.rejects(coordinateCrossTabRefresh({ lockName: 'client-refresh', observedRefreshToken: 'refresh-old', currentRefreshToken: () => '', reuseCurrentSession: async () => 'unexpected', refresh: async () => { throw refreshError }, }), refreshError) } finally { Object.defineProperty(globalThis, 'navigator', { configurable: true, value: originalNavigator }) } })