mirror of
https://github.com/Buriburizaem0n/admin-frontend-domain.git
synced 2026-09-20 02:00:14 +00:00
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
This commit is contained in:
@@ -2,10 +2,10 @@ import { afterEach, beforeEach, expect, test, vi } from "vitest"
|
||||
|
||||
import { createApiToken, deleteApiToken, listApiTokens } from "../api/api-tokens"
|
||||
|
||||
const realFetch = global.fetch
|
||||
const realFetch = globalThis.fetch
|
||||
|
||||
function mockFetch(payload: unknown, ok = true, success = true) {
|
||||
global.fetch = vi.fn(async () => {
|
||||
globalThis.fetch = vi.fn(async () => {
|
||||
return new Response(JSON.stringify({ success, error: success ? "" : "boom", data: payload }), {
|
||||
status: ok ? 200 : 500,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -19,13 +19,13 @@ beforeEach(() => {
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers()
|
||||
global.fetch = realFetch
|
||||
globalThis.fetch = realFetch
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
test("listApiTokens GETs /api/v1/api-tokens and returns parsed array", async () => {
|
||||
const calls: Array<{ url: string; method: string }> = []
|
||||
global.fetch = vi.fn(async (input: any, init?: any) => {
|
||||
globalThis.fetch = vi.fn(async (input: any, init?: any) => {
|
||||
calls.push({ url: String(input), method: String(init?.method ?? "GET") })
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
@@ -54,7 +54,7 @@ test("listApiTokens GETs /api/v1/api-tokens and returns parsed array", async ()
|
||||
|
||||
test("createApiToken POSTs /api/v1/api-tokens and serializes scopes / server_ids / expires_in_days", async () => {
|
||||
let captured: { url: string; method: string; body: any } | null = null
|
||||
global.fetch = vi.fn(async (input: any, init?: any) => {
|
||||
globalThis.fetch = vi.fn(async (input: any, init?: any) => {
|
||||
captured = {
|
||||
url: String(input),
|
||||
method: String(init?.method ?? ""),
|
||||
@@ -103,7 +103,7 @@ test("listApiTokens normalizes null scopes to an empty array so the table cannot
|
||||
// Backend APIToken.Scopes() returns nil for ScopesCSV=="" which JSON-encodes
|
||||
// as null; migrated/legacy/hand-edited rows hit this. Without normalization
|
||||
// the list page does tok.scopes.map(...) on null and the whole page crashes.
|
||||
global.fetch = vi.fn(async () => {
|
||||
globalThis.fetch = vi.fn(async () => {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
success: true,
|
||||
@@ -122,7 +122,7 @@ test("listApiTokens normalizes null scopes to an empty array so the table cannot
|
||||
|
||||
test("deleteApiToken DELETEs /api/v1/api-tokens/:id", async () => {
|
||||
const calls: Array<{ url: string; method: string }> = []
|
||||
global.fetch = vi.fn(async (input: any, init?: any) => {
|
||||
globalThis.fetch = vi.fn(async (input: any, init?: any) => {
|
||||
calls.push({ url: String(input), method: String(init?.method ?? "GET") })
|
||||
return new Response(JSON.stringify({ success: true, data: null }), {
|
||||
status: 200,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, expect, test, vi } from "vitest"
|
||||
|
||||
import { FetcherMethod, fetcher } from "../api/api"
|
||||
|
||||
const realFetch = global.fetch
|
||||
const realFetch = globalThis.fetch
|
||||
|
||||
function setCookie(value: string) {
|
||||
Object.defineProperty(document, "cookie", { value, configurable: true })
|
||||
@@ -13,7 +13,7 @@ beforeEach(() => {
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
global.fetch = realFetch
|
||||
globalThis.fetch = realFetch
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
@@ -40,7 +40,7 @@ function headerOf(init: RequestInit | undefined, name: string): string | null {
|
||||
test("POST sends X-CSRF-Token mirrored from nz-csrf cookie", async () => {
|
||||
setCookie("nz-csrf=abc123; other=1")
|
||||
const seen: { init?: RequestInit }[] = []
|
||||
global.fetch = vi.fn(async (_input: any, init?: RequestInit) => {
|
||||
globalThis.fetch = vi.fn(async (_input: any, init?: RequestInit) => {
|
||||
seen.push({ init })
|
||||
return jsonOk()
|
||||
}) as unknown as typeof fetch
|
||||
@@ -53,7 +53,7 @@ test("POST sends X-CSRF-Token mirrored from nz-csrf cookie", async () => {
|
||||
test("DELETE sends X-CSRF-Token mirrored from nz-csrf cookie", async () => {
|
||||
setCookie("nz-csrf=del-token")
|
||||
const seen: { init?: RequestInit }[] = []
|
||||
global.fetch = vi.fn(async (_input: any, init?: RequestInit) => {
|
||||
globalThis.fetch = vi.fn(async (_input: any, init?: RequestInit) => {
|
||||
seen.push({ init })
|
||||
return jsonOk()
|
||||
}) as unknown as typeof fetch
|
||||
@@ -68,7 +68,7 @@ test("auto refresh-token uses POST (backend route is POST)", async () => {
|
||||
const { FetcherMethod: M, fetcher: f } = await import("../api/api")
|
||||
setCookie("nz-jwt=sess; nz-csrf=c")
|
||||
const seen: { url: string; init?: RequestInit }[] = []
|
||||
global.fetch = vi.fn(async (input: any, init?: RequestInit) => {
|
||||
globalThis.fetch = vi.fn(async (input: any, init?: RequestInit) => {
|
||||
seen.push({ url: String(input), init })
|
||||
return jsonOk()
|
||||
}) as unknown as typeof fetch
|
||||
@@ -83,13 +83,13 @@ test("auto refresh-token uses POST (backend route is POST)", async () => {
|
||||
// Revoke (DELETE) commonly returns 204 / empty body. The fetcher must not
|
||||
// blow up on response.json() of an empty body and must resolve successfully.
|
||||
test("DELETE tolerates an empty 204 response body", async () => {
|
||||
global.fetch = vi.fn(async () => new Response(null, { status: 204 })) as unknown as typeof fetch
|
||||
globalThis.fetch = vi.fn(async () => new Response(null, { status: 204 })) as unknown as typeof fetch
|
||||
|
||||
await expect(fetcher(FetcherMethod.DELETE, "/api/v1/api-tokens/9")).resolves.toBeUndefined()
|
||||
})
|
||||
|
||||
test("empty 200 body does not throw", async () => {
|
||||
global.fetch = vi.fn(
|
||||
globalThis.fetch = vi.fn(
|
||||
async () => new Response("", { status: 200 }),
|
||||
) as unknown as typeof fetch
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, expect, test, vi } from "vitest"
|
||||
|
||||
import { FetcherMethod, fetcher } from "../api/api"
|
||||
|
||||
const realFetch = global.fetch
|
||||
const realFetch = globalThis.fetch
|
||||
|
||||
beforeEach(() => {
|
||||
// Avoid the auto refresh-token branch interfering with assertions.
|
||||
@@ -10,7 +10,7 @@ beforeEach(() => {
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
global.fetch = realFetch
|
||||
globalThis.fetch = realFetch
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
@@ -19,7 +19,7 @@ afterEach(() => {
|
||||
// DELETE route. The wire-level method must match the requested FetcherMethod.
|
||||
test("fetcher uses HTTP DELETE for FetcherMethod.DELETE", async () => {
|
||||
const seen: { url: string; init?: RequestInit }[] = []
|
||||
global.fetch = vi.fn(async (input: any, init?: RequestInit) => {
|
||||
globalThis.fetch = vi.fn(async (input: any, init?: RequestInit) => {
|
||||
seen.push({ url: String(input), init })
|
||||
return new Response(JSON.stringify({ success: true, data: null }), {
|
||||
status: 200,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { afterEach, beforeEach, expect, test, vi } from "vitest"
|
||||
|
||||
const realFetch = global.fetch
|
||||
const realFetch = globalThis.fetch
|
||||
|
||||
function setCookie(value: string) {
|
||||
Object.defineProperty(document, "cookie", { value, configurable: true })
|
||||
@@ -19,7 +19,7 @@ beforeEach(() => {
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
global.fetch = realFetch
|
||||
globalThis.fetch = realFetch
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
@@ -31,7 +31,7 @@ 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[] = []
|
||||
global.fetch = vi.fn(async (input: any) => {
|
||||
globalThis.fetch = vi.fn(async (input: any) => {
|
||||
urls.push(String(input))
|
||||
return jsonOk()
|
||||
}) as unknown as typeof fetch
|
||||
@@ -46,7 +46,7 @@ test("auto refresh is deferred while nz-csrf cookie is missing", async () => {
|
||||
test("auto refresh fires after nz-csrf cookie becomes available", async () => {
|
||||
const { FetcherMethod, fetcher } = await import("../api/api")
|
||||
const urls: string[] = []
|
||||
global.fetch = vi.fn(async (input: any) => {
|
||||
globalThis.fetch = vi.fn(async (input: any) => {
|
||||
urls.push(String(input))
|
||||
return jsonOk()
|
||||
}) as unknown as typeof fetch
|
||||
|
||||
@@ -130,7 +130,7 @@ class MockWebSocket extends EventTarget implements WebSocket {
|
||||
onerror: ((this: WebSocket, ev: Event) => unknown) | null = null
|
||||
onmessage: ((this: WebSocket, ev: MessageEvent) => unknown) | null = null
|
||||
onopen: ((this: WebSocket, ev: Event) => unknown) | null = null
|
||||
readyState = MockWebSocket.CONNECTING
|
||||
readyState: 0 | 1 | 2 | 3 = MockWebSocket.CONNECTING
|
||||
sent: SentWebSocketData[] = []
|
||||
|
||||
constructor(url: string | URL) {
|
||||
|
||||
@@ -21,6 +21,7 @@ class TestResizeObserver implements ResizeObserver {
|
||||
class TestIntersectionObserver implements IntersectionObserver {
|
||||
readonly root: Element | Document | null = null
|
||||
readonly rootMargin = ""
|
||||
readonly scrollMargin = ""
|
||||
readonly thresholds: ReadonlyArray<number> = []
|
||||
|
||||
observe(): void {}
|
||||
|
||||
Reference in New Issue
Block a user