import { describe, expect, it } from "vitest"; import YAML from "yaml"; import { controlRequest, fetchWorker } from "@tests/worker/helpers/http"; type OpenApiDocument = { paths: Record; [key: string]: unknown; }; const expectedApiPaths = [ "/api/v1/auth/oidc/login", "/api/v1/auth/oidc/callback", "/api/v1/auth/logout", "/api/v1/me", "/api/v1/pats", "/api/v1/pats/{pat_id}", "/api/v1/calendars", "/api/v1/calendars/{calendar_id}", "/api/v1/addressbooks", "/api/v1/addressbooks/{addressbook_id}", "/api/v1/files/metadata", "/api/v1/files/list", "/api/v1/files/mkdir", "/api/v1/files/rename", "/api/v1/files/delete", ] as const; describe("control-plane OpenAPI routes", () => { it("serves the OpenAPI JSON document from the control-plane host", async () => { const response = await fetchWorker(controlRequest("/api/v1/openapi.json")); expect(response.status).toBe(200); const document = (await response.json()) as { paths?: Record }; for (const path of expectedApiPaths) { expect(document.paths).toHaveProperty(path); } }); it("serves equivalent OpenAPI YAML", async () => { const jsonResponse = await fetchWorker(controlRequest("/api/v1/openapi.json")); const yamlResponse = await fetchWorker(controlRequest("/api/v1/openapi.yaml")); expect(yamlResponse.status).toBe(200); const jsonDocument = (await jsonResponse.json()) as OpenApiDocument; const yamlDocument = YAML.parse(await yamlResponse.text()) as OpenApiDocument; expect(yamlDocument).toEqual(jsonDocument); }); it("serves Swagger UI for the OpenAPI document", async () => { const response = await fetchWorker(controlRequest("/api/v1/docs")); expect(response.status).toBe(200); expect(response.headers.get("content-type")).toContain("text/html"); const body = await response.text(); expect(body).toContain("SwaggerUIBundle"); expect(body).toContain("/api/v1/openapi.json"); }); it("returns common JSON errors in the documented shape", async () => { const response = await fetchWorker(controlRequest("/api/v1/me")); expect(response.status).toBe(401); await expect(response.json()).resolves.toEqual({ error: { code: "unauthorized", message: "API session required.", }, }); }); it("keeps healthz outside the OpenAPI path tree", async () => { const response = await fetchWorker(controlRequest("/healthz")); expect(response.status).toBe(200); await expect(response.json()).resolves.toEqual({ ok: true, service: "dab" }); }); });