import type Database from "bun:sqlite"; import { describe, expect, test } from "bun:test"; import type { RuntimeMode } from "../../../src/shared/api"; import { createNoopLogger } from "../../../src/server/logger"; import { createMigratedMemoryTestDatabase } from "../../helpers"; const MODE: RuntimeMode = "test"; const LOG = createNoopLogger(); async function getSettingsViaHandler(req: Request, db: Database): Promise { const { handleGetSettings: h } = await import("../../../src/server/routes/settings"); return h(req, db, MODE, LOG); } async function updateSettingsViaHandler(req: Request, db: Database): Promise { const { handleUpdateSettings: h } = await import("../../../src/server/routes/settings"); return h(req, db, MODE, LOG); } async function withRouteDb(callback: (db: Database) => Promise): Promise { const handle = createMigratedMemoryTestDatabase("route-settings-test"); try { await callback(handle.db); handle.close(); } finally { handle.cleanup(); } } describe("设置 API 路由", () => { test("GET /api/settings 返回默认值", async () => { await withRouteDb(async (db) => { const req = new Request("http://localhost/api/settings"); const res = await getSettingsViaHandler(req, db); expect(res.status).toBe(200); const body = (await res.json()) as { theme: string }; expect(body).toEqual({ theme: "system" }); }); }); test("PUT /api/settings 写入后 GET 验证一致性", async () => { await withRouteDb(async (db) => { const putReq = new Request("http://localhost/api/settings", { body: JSON.stringify({ theme: "dark" }), headers: { "Content-Type": "application/json" }, method: "PUT", }); const putRes = await updateSettingsViaHandler(putReq, db); expect(putRes.status).toBe(200); const putBody = (await putRes.json()) as { theme: string }; expect(putBody).toEqual({ theme: "dark" }); const getReq = new Request("http://localhost/api/settings"); const getRes = await getSettingsViaHandler(getReq, db); expect(getRes.status).toBe(200); const getBody = (await getRes.json()) as { theme: string }; expect(getBody).toEqual({ theme: "dark" }); }); }); test("PUT /api/settings 部分更新", async () => { await withRouteDb(async (db) => { const req1 = new Request("http://localhost/api/settings", { body: JSON.stringify({ theme: "dark" }), headers: { "Content-Type": "application/json" }, method: "PUT", }); await updateSettingsViaHandler(req1, db); const req2 = new Request("http://localhost/api/settings", { body: JSON.stringify({ theme: "light" }), headers: { "Content-Type": "application/json" }, method: "PUT", }); const res2 = await updateSettingsViaHandler(req2, db); expect(res2.status).toBe(200); const body = (await res2.json()) as { theme: string }; expect(body).toEqual({ theme: "light" }); }); }); test("PUT /api/settings 非法 JSON 返回 400", async () => { await withRouteDb(async (db) => { const req = new Request("http://localhost/api/settings", { body: "not-json", headers: { "Content-Type": "application/json" }, method: "PUT", }); const res = await updateSettingsViaHandler(req, db); expect(res.status).toBe(400); }); }); test("PUT /api/settings theme 非字符串返回 400", async () => { await withRouteDb(async (db) => { const req = new Request("http://localhost/api/settings", { body: JSON.stringify({ theme: 123 }), headers: { "Content-Type": "application/json" }, method: "PUT", }); const res = await updateSettingsViaHandler(req, db); expect(res.status).toBe(400); }); }); test("PUT /api/settings 非法 theme 值返回 400", async () => { await withRouteDb(async (db) => { const req = new Request("http://localhost/api/settings", { body: JSON.stringify({ theme: "auto" }), headers: { "Content-Type": "application/json" }, method: "PUT", }); const res = await updateSettingsViaHandler(req, db); expect(res.status).toBe(400); }); }); test("PUT /api/settings theme=system 合法", async () => { await withRouteDb(async (db) => { const req = new Request("http://localhost/api/settings", { body: JSON.stringify({ theme: "system" }), headers: { "Content-Type": "application/json" }, method: "PUT", }); const res = await updateSettingsViaHandler(req, db); expect(res.status).toBe(200); }); }); test("PUT /api/settings 空 body 不报错", async () => { await withRouteDb(async (db) => { const req = new Request("http://localhost/api/settings", { body: JSON.stringify({}), headers: { "Content-Type": "application/json" }, method: "PUT", }); const res = await updateSettingsViaHandler(req, db); expect(res.status).toBe(200); const body = (await res.json()) as { theme: string }; expect(body).toEqual({ theme: "system" }); }); }); });