const mockSignOut = jest.fn() jest.mock('../src/lib/supabase', () => ({ supabase: { auth: { signOut: (...args: unknown[]) => mockSignOut(...args), }, }, })) import { signOutWithLocalFallback } from '../src/lib/logout' describe('offline-safe logout boundary', () => { beforeEach(() => jest.clearAllMocks()) test('confirms remote revocation and still performs the secure local purge', async () => { mockSignOut.mockResolvedValue({ error: null }) const purge = jest.fn(async () => undefined) await expect(signOutWithLocalFallback(purge)).resolves.toEqual({ remoteRevocationConfirmed: true, }) expect(purge).toHaveBeenCalledTimes(1) }) test('logs this device out when the revocation endpoint is offline', async () => { mockSignOut.mockResolvedValue({ error: new Error('offline') }) const purge = jest.fn(async () => undefined) await expect(signOutWithLocalFallback(purge)).resolves.toEqual({ remoteRevocationConfirmed: false, }) expect(purge).toHaveBeenCalledTimes(1) }) test('also purges locally when the auth client throws a transport error', async () => { mockSignOut.mockRejectedValue(new Error('network down')) const purge = jest.fn(async () => undefined) await expect(signOutWithLocalFallback(purge)).resolves.toEqual({ remoteRevocationConfirmed: false, }) expect(purge).toHaveBeenCalledTimes(1) }) test('never reports logout success if secure local deletion fails', async () => { mockSignOut.mockResolvedValue({ error: new Error('offline') }) const purge = jest.fn(async () => { throw new Error('keychain deletion failed') }) await expect(signOutWithLocalFallback(purge)) .rejects.toThrow('keychain deletion failed') }) })