import { afterEach, describe, expect, it, vi } from 'vitest' import { fetchLibraryOverview } from './librarySnapshots' // F16:overview 的非 2xx 响应曾被当成正常状态,页面随后在 `overview.gate.sync_allowed` // 上抛 TypeError(白屏)。这里把三种真实失败形状固定下来:401/503 与畸形 JSON。 const originalFetch = globalThis.fetch afterEach(() => { globalThis.fetch = originalFetch vi.restoreAllMocks() }) describe('fetchLibraryOverview(HTTP 状态与结构)', () => { it('401 的 {error} 不许被当成发布状态', async () => { globalThis.fetch = vi.fn( async () => new Response(JSON.stringify({ error: 'unauthenticated' }), { status: 401 }) ) as unknown as typeof fetch await expect(fetchLibraryOverview('internal')).rejects.toThrow(/HTTP 401/) }) it('503 的闸口拒绝同样必须报错', async () => { globalThis.fetch = vi.fn( async () => new Response(JSON.stringify({ available: false, reason: '存储不可用' }), { status: 503 }) ) as unknown as typeof fetch await expect(fetchLibraryOverview('internal')).rejects.toThrow(/HTTP 503/) }) it('200 但缺 gate/jobs 的结构不符也要报错', async () => { globalThis.fetch = vi.fn( async () => new Response(JSON.stringify({ scope: 'internal' }), { status: 200 }) ) as unknown as typeof fetch await expect(fetchLibraryOverview('internal')).rejects.toThrow(/结构不符合预期/) }) it('结构正确的 200 正常返回(避免把正常请求也拦掉)', async () => { const payload = { scope: 'internal', production: { state: 'unknown' }, prebackup: { state: 'unknown' }, diff: { state: 'unknown', added: [], updated: [], removed: [] }, jobs: [], gate: { sync_allowed: false, reasons: [] }, authorization: { state: 'none' }, capture_available: false, now: new Date().toISOString(), } globalThis.fetch = vi.fn( async () => new Response(JSON.stringify(payload), { status: 200 }) ) as unknown as typeof fetch const value = await fetchLibraryOverview('internal') expect(value?.gate.sync_allowed).toBe(false) }) })