Files
deerflow-code/frontend-web/src/core/settings/composer-scope.test.ts
T

149 lines
5.0 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import {
mergeComposerScope,
parseComposerScopeInput,
pickComposerScope,
resetComposerScope,
} from "./composer-scope.ts";
import type { LocalSettings } from "./local";
// Mirrors DEFAULT_LOCAL_SETTINGS without importing ./local at runtime (its
// dependency chain uses extensionless imports node --test cannot resolve).
const DEFAULTS = {
notification: { enabled: true },
display: {
streamSpeedMeterEnabled: true,
ragModeEnabled: false,
artifactDirectoryModeEnabled: false,
contextCompressionEnabled: false,
citationCleanupWords: [],
fontScale: 1,
fontScaleMode: "text",
},
context: {
model_name: undefined,
mode: undefined,
reasoning_effort: undefined,
writing_mode: false,
},
} as LocalSettings;
function sampleSettings(): LocalSettings {
return {
...DEFAULTS,
display: {
...DEFAULTS.display,
ragModeEnabled: true,
contextCompressionEnabled: true,
fontScale: 1.25,
},
context: {
...DEFAULTS.context,
model_name: "MiniMax-M2.7-fash",
mode: "thinking",
writing_mode: true,
},
} as LocalSettings;
}
const COMPOSER_ONLY_JSON = {
context: {
model_name: "MiniMax-M2.7-fash",
mode: "thinking",
writing_mode: true,
},
display: {
ragModeEnabled: true,
artifactDirectoryModeEnabled: false,
contextCompressionEnabled: true,
},
};
test("pickComposerScope extracts only the composer fields", () => {
const picked = JSON.parse(JSON.stringify(pickComposerScope(sampleSettings())));
assert.deepEqual(picked, COMPOSER_ONLY_JSON);
});
test("resetComposerScope keeps global preferences, drops composer fields", () => {
const reset = resetComposerScope(sampleSettings(), DEFAULTS);
assert.equal(reset.display.fontScale, 1.25);
assert.equal(reset.display.ragModeEnabled, false);
assert.equal(reset.display.artifactDirectoryModeEnabled, false);
assert.equal(reset.display.contextCompressionEnabled, false);
assert.equal(reset.context.model_name, undefined);
assert.equal(reset.context.mode, undefined);
assert.equal(reset.context.writing_mode, false);
});
test("mergeComposerScope overlays the session document on the base", () => {
const merged = mergeComposerScope(DEFAULTS, {
context: { mode: "pro" },
display: { contextCompressionEnabled: true },
});
assert.equal(merged.context.mode, "pro");
assert.equal(merged.context.writing_mode, false);
assert.equal(merged.display.contextCompressionEnabled, true);
assert.equal(merged.display.ragModeEnabled, false);
assert.equal(merged.display.fontScale, 1);
});
test("parseComposerScopeInput degrades junk to defaults", () => {
const empty = parseComposerScopeInput(null);
assert.equal(empty.context.model_name, undefined);
assert.equal(empty.context.mode, undefined);
assert.equal(empty.context.writing_mode, false);
assert.equal(empty.display.ragModeEnabled, false);
const parsed = parseComposerScopeInput({
context: {
model_name: 42,
mode: "bogus",
reasoning_effort: "medium",
writing_mode: "yes",
},
display: { ragModeEnabled: 1, contextCompressionEnabled: true },
});
assert.equal(parsed.context.model_name, undefined);
assert.equal(parsed.context.mode, undefined);
assert.equal(parsed.context.reasoning_effort, "medium");
assert.equal(parsed.context.writing_mode, false);
assert.equal(parsed.display.ragModeEnabled, false);
assert.equal(parsed.display.contextCompressionEnabled, true);
});
test("save/read round trip keeps composer choices out of the global doc", () => {
const settings = sampleSettings();
// What saveLocalSettings persists: composer fields → sessionStorage,
// everything else → localStorage with composer fields at defaults.
const sessionDoc = JSON.parse(JSON.stringify(pickComposerScope(settings)));
const globalDoc = JSON.parse(JSON.stringify(
resetComposerScope(settings, DEFAULTS),
));
// What getLocalSettings reconstructs: merge the parsed global doc over the
// defaults (mergeLocalSettings also resets its composer fields), then
// overlay the parsed session doc.
const globalView = resetComposerScope(
{
...DEFAULTS,
...globalDoc,
notification: { ...DEFAULTS.notification, ...globalDoc.notification },
context: { ...DEFAULTS.context, ...globalDoc.context },
display: { ...DEFAULTS.display, ...globalDoc.display },
} as LocalSettings,
DEFAULTS,
);
const restored = mergeComposerScope(
globalView,
parseComposerScopeInput(sessionDoc),
);
assert.deepEqual(pickComposerScope(restored), pickComposerScope(settings));
assert.equal(restored.display.fontScale, 1.25);
// The persisted global document itself carries no composer state: dropped
// keys for the undefined defaults, default values for the booleans.
assert.equal(globalDoc.context.mode, undefined);
assert.equal("model_name" in globalDoc.context, false);
assert.equal(globalDoc.context.writing_mode, false);
assert.equal(globalDoc.display.ragModeEnabled, false);
});