From 0c24ab45af2ec1e19ae73d5e6c29ea6683491d40 Mon Sep 17 00:00:00 2001 From: clousky Date: Mon, 20 Apr 2026 10:11:51 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=85=20test(settings-api):=20add=20test=20?= =?UTF-8?q?harness=20for=20proper=20isolation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - create createSettingsApiHarness function with temp directory setup - add beforeEach/afterEach hooks for storage reset between tests - add after hook for cleanup - use dynamic imports after env setup to ensure proper initialization --- tests/unit/settings-api.test.ts | 86 +++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/tests/unit/settings-api.test.ts b/tests/unit/settings-api.test.ts index 27f7160d4e..1767dcc794 100644 --- a/tests/unit/settings-api.test.ts +++ b/tests/unit/settings-api.test.ts @@ -1,34 +1,88 @@ -import { describe, test } from "node:test"; +import { describe, test, beforeEach, afterEach, after } from "node:test"; import assert from "node:assert/strict"; +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; + +// --- Create harness function (similar to _chatPipelineHarness pattern) --- +async function createSettingsApiHarness() { + const testDataDir = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-settings-api-")); + process.env.DATA_DIR = testDataDir; + process.env.REQUIRE_API_KEY = "false"; + if (!process.env.API_KEY_SECRET) { + process.env.API_KEY_SECRET = "test-settings-api-secret-" + Date.now(); + } + + // --- Dynamic imports AFTER env setup --- + const core = await import("../../src/lib/db/core.ts"); + const { getSettings, updateSettings } = await import("../../src/lib/db/settings.ts"); + const settingsRoute = await import("../../src/app/api/settings/route.ts"); + + async function resetStorage() { + core.resetDbInstance(); + fs.rmSync(testDataDir, { recursive: true, force: true }); + fs.mkdirSync(testDataDir, { recursive: true }); + } + + function cleanup() { + core.resetDbInstance(); + fs.rmSync(testDataDir, { recursive: true, force: true }); + } + + return { + testDataDir, + core, + getSettings, + updateSettings, + settingsRoute, + resetStorage, + cleanup, + }; +} + +// --- Initialize harness --- +const harness = await createSettingsApiHarness(); + +// --- Static import for helper (doesn't depend on DB) --- import { makeManagementSessionRequest } from "../helpers/managementSession.ts"; -import { getSettings, updateSettings } from "../../src/lib/db/settings.ts"; -const settingsRoute = await import("../../src/app/api/settings/route.ts"); + +beforeEach(async () => { + await harness.resetStorage(); +}); + +afterEach(async () => { + await harness.resetStorage(); +}); + +after(() => { + harness.cleanup(); +}); describe("Settings API - debugMode and hiddenSidebarItems", () => { describe("debugMode", () => { test("updateSettings with debugMode=true succeeds", async () => { - const result = await updateSettings({ debugMode: true }); + const result = await harness.updateSettings({ debugMode: true }); assert.ok(result, "updateSettings should return truthy result"); - const settings = await getSettings(); + const settings = await harness.getSettings(); assert.strictEqual(settings.debugMode, true, "debugMode should be true"); }); test("updateSettings with debugMode=false succeeds", async () => { - const result = await updateSettings({ debugMode: false }); + const result = await harness.updateSettings({ debugMode: false }); assert.ok(result, "updateSettings should return truthy result"); - const settings = await getSettings(); + const settings = await harness.getSettings(); assert.strictEqual(settings.debugMode, false, "debugMode should be false"); }); }); describe("hiddenSidebarItems", () => { test("updateSettings with hiddenSidebarItems=['translator'] succeeds", async () => { - const result = await updateSettings({ hiddenSidebarItems: ["translator"] }); + const result = await harness.updateSettings({ hiddenSidebarItems: ["translator"] }); assert.ok(result, "updateSettings should return truthy result"); - const settings = await getSettings(); + const settings = await harness.getSettings(); assert.deepStrictEqual( settings.hiddenSidebarItems, ["translator"], @@ -37,10 +91,10 @@ describe("Settings API - debugMode and hiddenSidebarItems", () => { }); test("updateSettings with empty hiddenSidebarItems succeeds", async () => { - const result = await updateSettings({ hiddenSidebarItems: [] }); + const result = await harness.updateSettings({ hiddenSidebarItems: [] }); assert.ok(result, "updateSettings should return truthy result"); - const settings = await getSettings(); + const settings = await harness.getSettings(); assert.deepStrictEqual( settings.hiddenSidebarItems, [], @@ -51,13 +105,13 @@ describe("Settings API - debugMode and hiddenSidebarItems", () => { describe("combined updates", () => { test("updateSettings with both debugMode and hiddenSidebarItems succeeds", async () => { - const result = await updateSettings({ + const result = await harness.updateSettings({ debugMode: true, hiddenSidebarItems: ["translator"], }); assert.ok(result, "updateSettings should return truthy result"); - const settings = await getSettings(); + const settings = await harness.getSettings(); assert.strictEqual(settings.debugMode, true, "debugMode should be true"); assert.deepStrictEqual( settings.hiddenSidebarItems, @@ -67,12 +121,12 @@ describe("Settings API - debugMode and hiddenSidebarItems", () => { }); test("updateSettings persists antigravitySignatureCacheMode", async () => { - const result = await updateSettings({ + const result = await harness.updateSettings({ antigravitySignatureCacheMode: "bypass-strict", }); assert.ok(result, "updateSettings should return truthy result"); - const settings = await getSettings(); + const settings = await harness.getSettings(); assert.strictEqual( settings.antigravitySignatureCacheMode, "bypass-strict", @@ -81,7 +135,7 @@ describe("Settings API - debugMode and hiddenSidebarItems", () => { }); test("PUT /api/settings reuses the PATCH update flow", async () => { - const response = await settingsRoute.PUT( + const response = await harness.settingsRoute.PUT( await makeManagementSessionRequest("http://localhost/api/settings", { method: "PUT", body: { antigravitySignatureCacheMode: "bypass" },