import { afterEach, describe, expect, it, vi } from 'vitest'; import { apiRequestInit, installSessionWatcher, onUnauthenticated } from '../../src/auth'; const nativeFetch = window.fetch; afterEach(() => { window.fetch = nativeFetch; }); describe('authenticated API request caching', () => { it('forces same-origin API reads past stale pre-login responses', () => { expect(apiRequestInit('/api/v1/system/status')).toMatchObject({ cache: 'no-store' }); expect(apiRequestInit(new URL('/api/v1/dashboards', window.location.href), { method: 'GET', cache: 'force-cache' })).toMatchObject({ method: 'GET', cache: 'no-store' }); }); it('does not rewrite non-API or cross-origin requests', () => { const init = { method: 'GET' } satisfies RequestInit; expect(apiRequestInit('/assets/app.js', init)).toBe(init); expect(apiRequestInit('https://example.com/api/v1/status', init)).toBe(init); }); it('revokes the shared API context after one 401 and stops further network churn', async () => { const transport = vi.fn(async () => new Response(null, { status: 401 })); window.fetch = transport; const notices = vi.fn(); const unsubscribe = onUnauthenticated(notices); installSessionWatcher(); expect((await window.fetch('/api/v1/system/status')).status).toBe(401); expect((await window.fetch('/api/v1/dashboards')).status).toBe(401); expect((await window.fetch('/api/v1/events')).status).toBe(401); expect(transport).toHaveBeenCalledTimes(1); expect(notices).toHaveBeenCalledTimes(1); unsubscribe(); }); });