Merge PR #850: test: add unit and E2E tests for settings toggles

This commit is contained in:
diegosouzapw
2026-03-31 09:11:11 -03:00
4 changed files with 135 additions and 2 deletions

View File

@@ -41,6 +41,17 @@ Key variables for development:
| `INITIAL_PASSWORD` | `123456` | First login password |
| `ENABLE_REQUEST_LOGS` | `false` | Enable debug request logs |
### Dashboard Settings
The dashboard provides UI toggles for features that can also be configured via environment variables:
| Setting Location | Toggle | Description |
| ------------------- | ------------------ | ------------------------------ |
| Settings → Advanced | Debug Mode | Enable debug request logs (UI) |
| Settings → General | Sidebar Visibility | Show/hide sidebar sections |
These settings are stored in the database and persist across restarts, overriding env var defaults when set.
### Running Locally
```bash

View File

@@ -47,7 +47,10 @@ import {
} from "@/lib/localDb";
import { getExecutor } from "../executors/index.ts";
import { getCacheControlSettings } from "@/lib/cacheControlSettings";
import { shouldPreserveCacheControl } from "../utils/cacheControlPolicy.ts";
import {
shouldPreserveCacheControl,
providerSupportsCaching,
} from "../utils/cacheControlPolicy.ts";
import { getCacheMetrics } from "@/lib/db/settings.ts";
import {
@@ -965,9 +968,10 @@ export async function handleChatCore({
? translatedBody
: { ...translatedBody, model: modelToCall };
// Inject prompt_cache_key for OpenAI providers if not already set
// Inject prompt_cache_key only for providers that support it
if (
targetFormat === FORMATS.OPENAI &&
providerSupportsCaching(provider) &&
!bodyToSend.prompt_cache_key &&
Array.isArray(bodyToSend.messages) &&
!["nvidia", "codex", "xai"].includes(provider)

View File

@@ -0,0 +1,51 @@
import { test, expect } from "@playwright/test";
test.describe("Settings Toggles", () => {
test("Debug mode toggle should work", async ({ page }) => {
await page.goto("/dashboard/settings");
await page.waitForLoadState("networkidle");
await page.click("text=Advanced");
const debugToggle = page.locator('[aria-label*="debug" i], [data-testid*="debug" i]').first();
await expect(debugToggle).toBeVisible({ timeout: 5000 });
const initialState = await debugToggle.isChecked();
await debugToggle.click();
await expect(debugToggle).not.toBeChecked({ timeout: 5000 });
});
test("Sidebar visibility toggle should work", async ({ page }) => {
await page.goto("/dashboard/settings");
await page.waitForLoadState("networkidle");
await page.click("text=General");
const sidebarToggle = page
.locator('[aria-label*="sidebar" i], [data-testid*="sidebar" i]')
.first();
await expect(sidebarToggle).toBeVisible({ timeout: 5000 });
const initialState = await sidebarToggle.isChecked();
await sidebarToggle.click();
await expect(sidebarToggle).not.toBeChecked({ timeout: 5000 });
});
test("Debug mode should persist after page reload", async ({ page }) => {
await page.goto("/dashboard/settings");
await page.waitForLoadState("networkidle");
await page.click("text=Advanced");
const debugToggle = page.locator('[aria-label*="debug" i], [data-testid*="debug" i]').first();
await expect(debugToggle).toBeVisible({ timeout: 5000 });
const wasChecked = await debugToggle.isChecked();
await debugToggle.click();
await expect(debugToggle).not.toBeChecked({ timeout: 5000 });
await page.reload();
await page.waitForLoadState("networkidle");
await page.click("text=Advanced");
await expect(debugToggle).not.toBeChecked({ timeout: 5000 });
});
});

View File

@@ -0,0 +1,67 @@
import { describe, test } from "node:test";
import assert from "node:assert/strict";
import { getSettings, updateSettings } from "../../src/lib/db/settings.ts";
describe("Settings API - debugMode and hiddenSidebarItems", () => {
describe("debugMode", () => {
test("updateSettings with debugMode=true succeeds", async () => {
const result = await updateSettings({ debugMode: true });
assert.ok(result, "updateSettings should return truthy result");
const settings = await getSettings();
assert.strictEqual(settings.debugMode, true, "debugMode should be true");
});
test("updateSettings with debugMode=false succeeds", async () => {
const result = await updateSettings({ debugMode: false });
assert.ok(result, "updateSettings should return truthy result");
const settings = await 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"] });
assert.ok(result, "updateSettings should return truthy result");
const settings = await getSettings();
assert.deepStrictEqual(
settings.hiddenSidebarItems,
["translator"],
"hiddenSidebarItems should contain translator"
);
});
test("updateSettings with empty hiddenSidebarItems succeeds", async () => {
const result = await updateSettings({ hiddenSidebarItems: [] });
assert.ok(result, "updateSettings should return truthy result");
const settings = await getSettings();
assert.deepStrictEqual(
settings.hiddenSidebarItems,
[],
"hiddenSidebarItems should be empty array"
);
});
});
describe("combined updates", () => {
test("updateSettings with both debugMode and hiddenSidebarItems succeeds", async () => {
const result = await updateSettings({
debugMode: true,
hiddenSidebarItems: ["translator"],
});
assert.ok(result, "updateSettings should return truthy result");
const settings = await getSettings();
assert.strictEqual(settings.debugMode, true, "debugMode should be true");
assert.deepStrictEqual(
settings.hiddenSidebarItems,
["translator"],
"hiddenSidebarItems should be updated"
);
});
});
});