From 807968e4df358ef05bf5082a43bc9da92e8b50aa Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 21 Feb 2026 18:33:54 +0000 Subject: [PATCH] refactor(test): replace manual PATH restore with env helpers --- src/hooks/gmail-setup-utils.test.ts | 34 +++++++++++++-------------- src/infra/exec-safe-bin-trust.test.ts | 10 ++++---- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/hooks/gmail-setup-utils.test.ts b/src/hooks/gmail-setup-utils.test.ts index 2f71ddfcf..1d4c81c0f 100644 --- a/src/hooks/gmail-setup-utils.test.ts +++ b/src/hooks/gmail-setup-utils.test.ts @@ -2,6 +2,7 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { beforeEach, describe, expect, it, vi } from "vitest"; +import { withEnvAsync } from "../test-utils/env.js"; import { ensureTailscaleEndpoint, resetGmailSetupUtilsCachesForTest, @@ -25,7 +26,6 @@ describe("resolvePythonExecutablePath", () => { "resolves a working python path and caches the result", async () => { const tmp = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-python-")); - const originalPath = process.env.PATH; try { const realPython = path.join(tmp, "python-real"); await fs.writeFile(realPython, "#!/bin/sh\nexit 0\n", "utf-8"); @@ -37,25 +37,25 @@ describe("resolvePythonExecutablePath", () => { await fs.writeFile(shim, "#!/bin/sh\nexit 0\n", "utf-8"); await fs.chmod(shim, 0o755); - process.env.PATH = `${shimDir}${path.delimiter}/usr/bin`; + await withEnvAsync({ PATH: `${shimDir}${path.delimiter}/usr/bin` }, async () => { + runCommandWithTimeoutMock.mockResolvedValue({ + stdout: `${realPython}\n`, + stderr: "", + code: 0, + signal: null, + killed: false, + }); - runCommandWithTimeoutMock.mockResolvedValue({ - stdout: `${realPython}\n`, - stderr: "", - code: 0, - signal: null, - killed: false, + const resolved = await resolvePythonExecutablePath(); + expect(resolved).toBe(realPython); + + await withEnvAsync({ PATH: "/bin" }, async () => { + const cached = await resolvePythonExecutablePath(); + expect(cached).toBe(realPython); + }); + expect(runCommandWithTimeoutMock).toHaveBeenCalledTimes(1); }); - - const resolved = await resolvePythonExecutablePath(); - expect(resolved).toBe(realPython); - - process.env.PATH = "/bin"; - const cached = await resolvePythonExecutablePath(); - expect(cached).toBe(realPython); - expect(runCommandWithTimeoutMock).toHaveBeenCalledTimes(1); } finally { - process.env.PATH = originalPath; await fs.rm(tmp, { recursive: true, force: true }); } }, diff --git a/src/infra/exec-safe-bin-trust.test.ts b/src/infra/exec-safe-bin-trust.test.ts index c370b8122..f7b19f283 100644 --- a/src/infra/exec-safe-bin-trust.test.ts +++ b/src/infra/exec-safe-bin-trust.test.ts @@ -1,5 +1,6 @@ import path from "node:path"; import { describe, expect, it } from "vitest"; +import { withEnv } from "../test-utils/env.js"; import { buildTrustedSafeBinDirs, getTrustedSafeBinDirs, @@ -56,16 +57,13 @@ describe("exec safe bin trust", () => { }); it("uses startup PATH snapshot when pathEnv is omitted", () => { - const originalPath = process.env.PATH; const injected = `/tmp/openclaw-path-injected-${Date.now()}`; const initial = getTrustedSafeBinDirs({ refresh: true }); - try { - process.env.PATH = `${injected}${path.delimiter}${originalPath ?? ""}`; + + withEnv({ PATH: `${injected}${path.delimiter}${process.env.PATH ?? ""}` }, () => { const refreshed = getTrustedSafeBinDirs({ refresh: true }); expect(refreshed.has(path.resolve(injected))).toBe(false); expect([...refreshed].toSorted()).toEqual([...initial].toSorted()); - } finally { - process.env.PATH = originalPath; - } + }); }); });