






















@@ -2,6 +2,7 @@
22 * Tests for config gateway methods, writes, validation, and auth transitions.
33 */
44import { afterEach, describe, expect, it, vi } from "vitest";
5+import { withEnvAsync } from "../../test-utils/env.js";
56import {
67clearConfigSchemaResponseCacheForTests,
78configHandlers,
@@ -88,70 +89,69 @@ describe("resolveConfigOpenCommand", () => {
8889});
89909091describe("config.openFile", () => {
91-afterEach(() => {
92-delete process.env.OPENCLAW_CONFIG_PATH;
93-});
94-9592it("opens the configured file without shell interpolation", async () => {
96-process.env.OPENCLAW_CONFIG_PATH = "/tmp/config $(touch pwned).json";
97-execFileMock.mockImplementation((...args: unknown[]) => {
98-expect(["open", "xdg-open", "powershell.exe"]).toContain(args[0]);
99-expect(args[1]).toEqual(["/tmp/config $(touch pwned).json"]);
100-invokeExecFileCallback(args, null);
101-return {} as never;
93+await withEnvAsync({ OPENCLAW_CONFIG_PATH: "/tmp/config $(touch pwned).json" }, async () => {
94+execFileMock.mockImplementation((...args: unknown[]) => {
95+expect(["open", "xdg-open", "powershell.exe"]).toContain(args[0]);
96+expect(args[1]).toEqual(["/tmp/config $(touch pwned).json"]);
97+invokeExecFileCallback(args, null);
98+return {} as never;
99+});
100+101+const { respond } = await invokeConfigOpenFile();
102+103+expect(respond).toHaveBeenCalledWith(
104+true,
105+{
106+ok: true,
107+path: "/tmp/config $(touch pwned).json",
108+},
109+undefined,
110+);
102111});
103-104-const { respond } = await invokeConfigOpenFile();
105-106-expect(respond).toHaveBeenCalledWith(
107-true,
108-{
109-ok: true,
110-path: "/tmp/config $(touch pwned).json",
111-},
112-undefined,
113-);
114112});
115113116114it("returns a detailed error and logs details when the opener fails", async () => {
117-process.env.OPENCLAW_CONFIG_PATH = "/tmp/config.json";
118-mockExecFileError(Object.assign(new Error("spawn xdg-open ENOENT"), { code: "ENOENT" }));
119-120-const { respond, logGateway } = await invokeConfigOpenFile();
121-122-expect(respond).toHaveBeenCalledWith(
123-true,
124-{
125-ok: false,
126-path: "/tmp/config.json",
127-error: "Failed to open config file: spawn xdg-open ENOENT",
128-},
129-undefined,
130-);
131-expect(logGateway.warn).toHaveBeenCalledWith(
132-"config.openFile failed path=/tmp/config.json: spawn xdg-open ENOENT",
133-);
115+await withEnvAsync({ OPENCLAW_CONFIG_PATH: "/tmp/config.json" }, async () => {
116+mockExecFileError(Object.assign(new Error("spawn xdg-open ENOENT"), { code: "ENOENT" }));
117+118+const { respond, logGateway } = await invokeConfigOpenFile();
119+120+expect(respond).toHaveBeenCalledWith(
121+true,
122+{
123+ok: false,
124+path: "/tmp/config.json",
125+error: "Failed to open config file: spawn xdg-open ENOENT",
126+},
127+undefined,
128+);
129+expect(logGateway.warn).toHaveBeenCalledWith(
130+"config.openFile failed path=/tmp/config.json: spawn xdg-open ENOENT",
131+);
132+});
134133});
135134136135it("returns actionable headless environment error when xdg-open reports no method available", async () => {
137-process.env.OPENCLAW_CONFIG_PATH = "/tmp/config.json";
138-mockExecFileError(new Error("xdg-open: no method available for opening '/tmp/config.json'"));
139-140-const { respond, logGateway } = await invokeConfigOpenFile();
141-142-expect(respond).toHaveBeenCalledWith(
143-true,
144-{
145-ok: false,
146-path: "/tmp/config.json",
147-error:
148-"Cannot open file in headless environment. File path: /tmp/config.json. This environment appears to lack a graphical or terminal browser handler.",
149-},
150-undefined,
151-);
152-expect(logGateway.warn).toHaveBeenCalledWith(
153-"config.openFile failed path=/tmp/config.json: xdg-open: no method available for opening '/tmp/config.json'",
154-);
136+await withEnvAsync({ OPENCLAW_CONFIG_PATH: "/tmp/config.json" }, async () => {
137+mockExecFileError(new Error("xdg-open: no method available for opening '/tmp/config.json'"));
138+139+const { respond, logGateway } = await invokeConfigOpenFile();
140+141+expect(respond).toHaveBeenCalledWith(
142+true,
143+{
144+ok: false,
145+path: "/tmp/config.json",
146+error:
147+"Cannot open file in headless environment. File path: /tmp/config.json. This environment appears to lack a graphical or terminal browser handler.",
148+},
149+undefined,
150+);
151+expect(logGateway.warn).toHaveBeenCalledWith(
152+"config.openFile failed path=/tmp/config.json: xdg-open: no method available for opening '/tmp/config.json'",
153+);
154+});
155155});
156156});
157157此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。