Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
/* @vitest-environment jsdom */
import { render } from "lit";
import { describe, expect, it, vi } from "vitest";
import { renderQuickSettings, type QuickSettingsProps } from "./config-quick.ts";
function createProps(overrides: Partial<QuickSettingsProps> = {}): QuickSettingsProps {
return {
currentModel: "gpt-5.5",
thinkingLevel: "off",
fastMode: false,
onModelChange: vi.fn(),
onThinkingChange: vi.fn(),
onFastModeToggle: vi.fn(),
channels: [],
onChannelConfigure: vi.fn(),
apiKeys: [],
onApiKeyChange: vi.fn(),
automation: {
cronJobCount: 0,
skillCount: 0,
mcpServerCount: 0,
},
onManageCron: vi.fn(),
onBrowseSkills: vi.fn(),
onConfigureMcp: vi.fn(),
security: {
gatewayAuth: "Unknown",
execPolicy: "Allowlist",
deviceAuth: true,
},
onSecurityConfigure: vi.fn(),
theme: "claw",
themeMode: "system",
hasCustomTheme: false,
customThemeLabel: null,
borderRadius: 50,
setTheme: vi.fn(),
onOpenCustomThemeImport: vi.fn(),
setThemeMode: vi.fn(),
setBorderRadius: vi.fn(),
userName: "Val",
userAvatar: null,
onUserNameChange: vi.fn(),
onUserAvatarChange: vi.fn(),
configObject: {},
onApplyPreset: vi.fn(),
onAdvancedSettings: vi.fn(),
connected: true,
gatewayUrl: "ws://localhost:18789",
assistantName: "OpenClaw",
version: "2026.4.22",
...overrides,
};
}
describe("renderQuickSettings", () => {
it("uses stacked columns for the compact settings layout", () => {
const container = document.createElement("div");
render(renderQuickSettings(createProps()), container);
expect(container.querySelectorAll(".qs-stack")).toHaveLength(4);
expect(container.querySelectorAll(".qs-card--span-all")).toHaveLength(1);
});
it("rejects oversized avatar uploads before reading them", () => {
const onUserAvatarChange = vi.fn();
const fileReader = vi.fn();
vi.stubGlobal("FileReader", fileReader);
try {
const container = document.createElement("div");
render(renderQuickSettings(createProps({ onUserAvatarChange })), container);
const input = container.querySelector('input[type="file"]') as HTMLInputElement | null;
expect(input).not.toBeNull();
if (!input) {
return;
}
const file = new File([new Uint8Array(1_500_001)], "avatar.png", { type: "image/png" });
Object.defineProperty(input, "files", {
configurable: true,
value: [file],
});
input.dispatchEvent(new Event("change"));
expect(fileReader).not.toHaveBeenCalled();
expect(onUserAvatarChange).not.toHaveBeenCalled();
} finally {
vi.unstubAllGlobals();
}
});
it("always shows the custom theme option in quick settings", () => {
const container = document.createElement("div");
render(renderQuickSettings(createProps()), container);
expect(
Array.from(container.querySelectorAll("button")).some(
(button) => button.textContent?.trim() === "Custom",
),
).toBe(true);
});
it("routes custom clicks into the tweakcn importer until a custom theme exists", () => {
const setTheme = vi.fn();
const onOpenCustomThemeImport = vi.fn();
const container = document.createElement("div");
render(
renderQuickSettings(
createProps({
hasCustomTheme: false,
setTheme,
onOpenCustomThemeImport,
}),
),
container,
);
const customButton = Array.from(container.querySelectorAll("button")).find(
(button) => button.textContent?.trim() === "Custom",
);
customButton?.click();
expect(onOpenCustomThemeImport).toHaveBeenCalledTimes(1);
expect(setTheme).not.toHaveBeenCalled();
});
it("applies the imported custom theme from quick settings once it exists", () => {
const setTheme = vi.fn();
const onOpenCustomThemeImport = vi.fn();
const container = document.createElement("div");
render(
renderQuickSettings(
createProps({
theme: "claw",
hasCustomTheme: true,
setTheme,
onOpenCustomThemeImport,
}),
),
container,
);
const customButton = Array.from(container.querySelectorAll("button")).find(
(button) => button.textContent?.trim() === "Custom",
);
customButton?.click();
expect(setTheme).toHaveBeenCalledWith("custom", expect.any(Object));
expect(onOpenCustomThemeImport).not.toHaveBeenCalled();
});
});
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet am 2026-04-27)
¤
*© Formatika GbR, Deutschland
|
|