Files
admin-frontend-domain/src/test/fetcher-refresh-selfheal.test.ts
T
naiba 2ff923220f fix: migrate to tailwind v4 and TS6, add oauth2 dashboard_host setting
- migrate Tailwind v3->v4 (postcss @tailwindcss/postcss, CSS-first @theme/@plugin/@custom-variant)
- fix TS6 build: ignoreDeprecations for baseUrl, react-day-picker v10 classNames, test type fixes
- add dashboard_host setting field with i18n
2026-06-06 01:39:25 +00:00

62 lines
2.2 KiB
TypeScript

import { afterEach, beforeEach, expect, test, vi } from "vitest"
const realFetch = globalThis.fetch
function setCookie(value: string) {
Object.defineProperty(document, "cookie", { value, configurable: true })
}
function jsonOk() {
return new Response(JSON.stringify({ success: true, data: null }), {
status: 200,
headers: { "Content-Type": "application/json" },
})
}
beforeEach(() => {
setCookie("")
vi.resetModules()
})
afterEach(() => {
globalThis.fetch = realFetch
vi.restoreAllMocks()
})
// Auto-refresh is a POST behind the CSRF gate. When the session still lacks the
// nz-csrf cookie (e.g. just upgraded), firing the refresh without a header only
// burns the 1h throttle window and 403s. The refresh must instead wait until a
// CSRF token is available so it can actually succeed once the cookie is seeded.
test("auto refresh is deferred while nz-csrf cookie is missing", async () => {
const { FetcherMethod, fetcher } = await import("../api/api")
setCookie("nz-jwt=session") // jwt present, but no nz-csrf yet
const urls: string[] = []
globalThis.fetch = vi.fn(async (input: any) => {
urls.push(String(input))
return jsonOk()
}) as unknown as typeof fetch
await fetcher(FetcherMethod.GET, "/api/v1/server")
expect(urls.some((u) => u.includes("/api/v1/refresh-token"))).toBe(false)
})
// Once the cookie exists, the next GET must be allowed to fire the refresh —
// proving the missing-cookie skip did not permanently consume the throttle.
test("auto refresh fires after nz-csrf cookie becomes available", async () => {
const { FetcherMethod, fetcher } = await import("../api/api")
const urls: string[] = []
globalThis.fetch = vi.fn(async (input: any) => {
urls.push(String(input))
return jsonOk()
}) as unknown as typeof fetch
setCookie("nz-jwt=session") // first GET: no csrf, refresh skipped
await fetcher(FetcherMethod.GET, "/api/v1/server")
expect(urls.some((u) => u.includes("/api/v1/refresh-token"))).toBe(false)
setCookie("nz-jwt=session; nz-csrf=seeded") // backend seeded it
await fetcher(FetcherMethod.GET, "/api/v1/server")
expect(urls.some((u) => u.includes("/api/v1/refresh-token"))).toBe(true)
})