import React, { act } from "react"; (globalThis as Record).React = React; import assert from "node:assert/strict"; import { afterEach, it } from "node:test"; import { createRoot, type Root } from "react-dom/client"; import { parseHTML } from "linkedom"; import { AgentSection } from "../components/settings/agent-section.tsx"; import { I18nProvider } from "../components/i18n.tsx"; import type { ModelCatalogEntry, ModelsSettings } from "../src/core/index.ts"; const dom = parseHTML(""); Object.assign(globalThis, { window: dom.window, document: dom.document, Element: dom.window.Element, HTMLElement: dom.window.HTMLElement, CustomEvent: dom.window.CustomEvent, IS_REACT_ACT_ENVIRONMENT: true }); const originalFetch = globalThis.fetch; const chatgpt = { provider: "chatgpt", id: "gpt-5" }; const api = { provider: "openai", id: "gpt-5" }; const fixture: ModelCatalogEntry = { ...chatgpt, name: "Offline model", reasoning: true, input: ["text", "image"], supportedLevels: ["low", "high"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 8192, maxTokens: 2048 }; let root: Root | null = null; let host: HTMLDivElement; let writes: ModelsSettings[]; let saved: ModelsSettings; let waitForSave: (() => Promise) | undefined; let failSave = false; function button(slot: string, kind = "fast"): HTMLButtonElement { const found = document.querySelector(`[data-testid="slot-${kind}-${slot}"]`); assert(found); return found; } async function click(target: HTMLButtonElement) { await act(async () => target.click()); } async function mount() { writes = []; waitForSave = undefined; failSave = false; saved = { strong: { model: chatgpt, thinkingLevel: "high" }, cheap: { model: chatgpt, thinkingLevel: "low" }, vision: { model: api } }; const responses: Record = { "/api/models": { models: [fixture, { ...fixture, provider: "openai" }], slots: saved }, "/api/search": { available: false, engine: null, reason: "No search engine is configured." }, "/api/keys": { keys: [] }, "/api/settings/prompts": { prober: [], teacher: [] }, }; globalThis.fetch = async input => { const name = String(input); assert(name in responses); return Response.json(responses[name]); }; host = document.createElement("div"); document.body.appendChild(host); root = createRoot(host); function Harness() { const [models, setModels] = React.useState(saved); return {}} onCompactionChange={() => {}} onModelsChange={async next => { writes.push(next); await waitForSave?.(); if (failSave) throw new Error("offline save failure"); saved = next; setModels(next); }} />; } await act(async () => { root!.render(); }); } afterEach(async () => { await act(async () => root?.unmount()); root = null; host?.remove(); globalThis.fetch = originalFetch; }); it("Fast controls wait for stored truth, lock related edits while saving, and preserve other tiers", async () => { await mount(); assert.equal(button("strong").getAttribute("aria-pressed"), "false"); assert.equal(button("vision").disabled, true); assert.equal(button("strong").textContent, "Быстро"); let release!: () => void; const pending = new Promise(resolve => { release = resolve; }); waitForSave = () => pending; await click(button("strong")); assert.equal(writes.length, 1); for (const slot of ["strong", "cheap"]) for (const kind of ["fast", "model", "thinking"]) assert.equal(button(slot, kind).disabled, true); assert.equal(button("strong").getAttribute("aria-pressed"), "false", "unconfirmed billing choices must not appear saved"); await act(async () => { release(); }); waitForSave = undefined; assert.equal(button("strong").getAttribute("aria-pressed"), "true"); await click(button("cheap")); assert.equal(saved.strong?.fastMode, true); assert.equal(saved.cheap?.fastMode, true); assert.equal(saved.strong?.thinkingLevel, "high"); assert.equal(saved.vision?.fastMode, undefined); }); it("failed Fast saves retain the previous choice, show a Russian error, and allow retry", async () => { await mount(); failSave = true; await click(button("strong")); assert.equal(button("strong").getAttribute("aria-pressed"), "false"); assert.equal(button("strong").disabled, false); assert.equal(document.querySelector('[role="alert"]')?.textContent, "Не удалось сохранить настройки моделей"); failSave = false; await click(button("strong")); assert.equal(button("strong").getAttribute("aria-pressed"), "true"); assert.equal(document.querySelector('[role="alert"]'), null); });