mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-20 09:09:35 +02:00
52 lines
2.5 KiB
TypeScript
52 lines
2.5 KiB
TypeScript
// test/split-pane-per-device-setting.test.ts
|
|||
|
|
// Port: none (pure static analysis — runs in CI, no browser/server).
|
||
|
|
//
|
||
|
|
// Regression guard for the review finding that landed the blocker: moving
|
||
|
|
// showSplitButton into settings-ui.js's per-device `displayKeys` set is only
|
||
|
|
// HALF of making a setting per-device. The other half is stripping it out of
|
||
|
|
// the object `saveAppSettings()` PUTs to `/api/settings` — displayKeys is a
|
||
|
|
// client-side merge policy, not a wire filter. Without the strip, every save
|
||
|
|
// sent `showSplitButton` in the body, `SettingsUpdateSchema` (.strict()) does
|
||
|
|
// not declare it, the server answered 400 INVALID_INPUT, and because the
|
||
|
|
// call site never checked `res.ok` the UI still reported "Settings saved"
|
||
|
|
// while NOTHING persisted — workspaceHooksEnabled, agentSkillEnabled,
|
||
|
|
// tunnelEnabled, claudeModel, every toggle, on every save, on every device.
|
||
|
|
//
|
||
|
|
// Mirrors test/terminal-auto-copy.test.ts's "keeps the toggle per-device"
|
||
|
|
// guard for autoCopySelection — same three-way rule, same shape of test.
|
||
|
|
import { describe, it, expect } from 'vitest';
|
||
|
|
import { readFileSync } from 'node:fs';
|
||
|
|
import { fileURLToPath } from 'node:url';
|
||
|
|
import { join } from 'node:path';
|
||
|
|
|
||
|
|
const HERE = fileURLToPath(new URL('.', import.meta.url));
|
||
|
|
const PUBLIC = join(HERE, '../src/web/public');
|
||
|
|
|
||
|
|
function read(file: string): string {
|
||
|
|
return readFileSync(join(PUBLIC, file), 'utf8');
|
||
|
|
}
|
||
|
|
|
||
|
|
describe('showSplitButton stays per-device: display key, stripped from the PUT, absent from the schema', () => {
|
||
|
|
const settingsUi = read('settings-ui.js');
|
||
|
|
const schemas = readFileSync(join(HERE, '../src/web/schemas.ts'), 'utf8');
|
||
|
|
|
||
|
|
it('is in the client-side displayKeys merge policy', () => {
|
||
|
|
const displayKeys = settingsUi.slice(
|
||
|
|
settingsUi.indexOf('const displayKeys = new Set(['),
|
||
|
|
settingsUi.indexOf('])', settingsUi.indexOf('const displayKeys = new Set(['))
|
||
|
|
);
|
||
|
|
expect(displayKeys).toContain("'showSplitButton'");
|
||
|
|
});
|
||
|
|
|
||
|
|
it('is stripped out of the object saveAppSettings() PUTs to the server', () => {
|
||
|
|
// The strip is a destructure: `showSplitButton: _ssp,` pulls the key out
|
||
|
|
// of `settings` so it never reaches `...serverSettings` in the PUT body.
|
||
|
|
expect(settingsUi).toContain('showSplitButton: _ssp,');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('is never declared in the .strict() SettingsUpdateSchema', () => {
|
||
|
|
// Not even in a comment — a mention there reads as "this is a real
|
||
|
|
// field" to the next person grepping schemas.ts for it.
|
||
|
|
expect(schemas).not.toContain('showSplitButton');
|
||
|
|
});
|
||
|
|
});
|