


























@@ -11,6 +11,7 @@ import {
1111stageDefaultAgentConfigEntry,
1212stageConfigPreset,
1313updateConfigFormValue,
14+updateConfigRawValue,
1415type ConfigState,
1516} from "./config.ts";
1617@@ -183,7 +184,7 @@ describe("applyConfigSnapshot", () => {
183184expect(state.configDraftBaseHash).toBe("hash-remote");
184185});
185186186-it("forces form mode when the snapshot does not include raw text", () => {
187+it("keeps raw mode when editable config can be serialized without raw text", () => {
187188const state = createState();
188189state.configFormMode = "raw";
189190@@ -195,9 +196,57 @@ describe("applyConfigSnapshot", () => {
195196raw: null,
196197});
197198198-expect(state.configFormMode).toBe("form");
199+expect(state.configFormMode).toBe("raw");
199200expect(state.configRaw).toBe('{\n "gateway": {\n "mode": "local"\n }\n}\n');
200201});
202+203+it("does not clobber raw edits while dirty", () => {
204+const state = createState();
205+state.configFormMode = "raw";
206+applyConfigSnapshot(state, {
207+hash: "hash-original",
208+config: { gateway: { mode: "local" } },
209+valid: true,
210+issues: [],
211+raw: '{\n "gateway": { "mode": "local" }\n}\n',
212+});
213+214+updateConfigRawValue(state, '{\n "gateway": { "mode": "remote" }\n}\n');
215+applyConfigSnapshot(state, {
216+hash: "hash-refreshed",
217+config: { gateway: { mode: "external" } },
218+valid: true,
219+issues: [],
220+raw: '{\n "gateway": { "mode": "external" }\n}\n',
221+});
222+223+expect(state.configSnapshot?.hash).toBe("hash-refreshed");
224+expect(state.configDraftBaseHash).toBe("hash-original");
225+expect(state.configRaw).toBe('{\n "gateway": { "mode": "remote" }\n}\n');
226+});
227+});
228+229+describe("updateConfigRawValue", () => {
230+it("tracks raw edits as pending changes", () => {
231+const state = createState();
232+applyConfigSnapshot(state, {
233+hash: "hash-original",
234+config: { gateway: { mode: "local" } },
235+valid: true,
236+issues: [],
237+raw: '{\n "gateway": { "mode": "local" }\n}\n',
238+});
239+240+updateConfigRawValue(state, '{\n "gateway": { "mode": "remote" }\n}\n');
241+242+expect(state.configFormDirty).toBe(true);
243+expect(state.configDraftBaseHash).toBe("hash-original");
244+245+updateConfigRawValue(state, '{\n "gateway": { "mode": "local" }\n}\n');
246+247+expect(state.configFormDirty).toBe(false);
248+expect(state.configDraftBaseHash).toBe("hash-original");
249+});
201250});
202251203252describe("loadConfig", () => {
@@ -707,6 +756,29 @@ describe("applyConfig", () => {
707756});
708757709758describe("saveConfig", () => {
759+it("submits generated raw text when the snapshot did not include raw text", async () => {
760+const request = createRequestWithConfigGet();
761+const state = createState();
762+state.connected = true;
763+state.client = { request } as unknown as ConfigState["client"];
764+state.configFormMode = "raw";
765+applyConfigSnapshot(state, {
766+hash: "hash-generated-raw",
767+sourceConfig: { gateway: { mode: "local" } },
768+config: { gateway: { mode: "local", runtimeOnly: true } },
769+valid: true,
770+issues: [],
771+raw: null,
772+});
773+774+await saveConfig(state);
775+776+expect(request).toHaveBeenCalledWith("config.set", {
777+raw: '{\n "gateway": {\n "mode": "local"\n }\n}\n',
778+baseHash: "hash-generated-raw",
779+});
780+});
781+710782it("submits the original draft base hash after a dirty config refresh", async () => {
711783const request = createRequestWithConfigGet();
712784const state = createState();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。