From 577e5cc74bea27714ac8f0b1ad874b05a7c47a8f Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 21 Feb 2026 12:52:21 +0000 Subject: [PATCH] refactor(test): dedupe gateway env setup and add env util coverage --- src/gateway/test-helpers.server.ts | 103 ++++++----------------------- src/test-utils/env.test.ts | 56 ++++++++++++++++ 2 files changed, 75 insertions(+), 84 deletions(-) create mode 100644 src/test-utils/env.test.ts diff --git a/src/gateway/test-helpers.server.ts b/src/gateway/test-helpers.server.ts index feb527c57..9c28b5648 100644 --- a/src/gateway/test-helpers.server.ts +++ b/src/gateway/test-helpers.server.ts @@ -43,18 +43,22 @@ async function getServerModule() { return await serverModulePromise; } -let previousHome: string | undefined; -let previousUserProfile: string | undefined; -let previousStateDir: string | undefined; -let previousConfigPath: string | undefined; -let previousSkipBrowserControl: string | undefined; -let previousSkipGmailWatcher: string | undefined; -let previousSkipCanvasHost: string | undefined; -let previousBundledPluginsDir: string | undefined; -let previousSkipChannels: string | undefined; -let previousSkipProviders: string | undefined; -let previousSkipCron: string | undefined; -let previousMinimalGateway: string | undefined; +const GATEWAY_TEST_ENV_KEYS = [ + "HOME", + "USERPROFILE", + "OPENCLAW_STATE_DIR", + "OPENCLAW_CONFIG_PATH", + "OPENCLAW_SKIP_BROWSER_CONTROL_SERVER", + "OPENCLAW_SKIP_GMAIL_WATCHER", + "OPENCLAW_SKIP_CANVAS_HOST", + "OPENCLAW_BUNDLED_PLUGINS_DIR", + "OPENCLAW_SKIP_CHANNELS", + "OPENCLAW_SKIP_PROVIDERS", + "OPENCLAW_SKIP_CRON", + "OPENCLAW_TEST_MINIMAL_GATEWAY", +] as const; + +let gatewayEnvSnapshot: ReturnType | undefined; let tempHome: string | undefined; let tempConfigRoot: string | undefined; @@ -87,18 +91,7 @@ export async function writeSessionStore(params: { } async function setupGatewayTestHome() { - previousHome = process.env.HOME; - previousUserProfile = process.env.USERPROFILE; - previousStateDir = process.env.OPENCLAW_STATE_DIR; - previousConfigPath = process.env.OPENCLAW_CONFIG_PATH; - previousSkipBrowserControl = process.env.OPENCLAW_SKIP_BROWSER_CONTROL_SERVER; - previousSkipGmailWatcher = process.env.OPENCLAW_SKIP_GMAIL_WATCHER; - previousSkipCanvasHost = process.env.OPENCLAW_SKIP_CANVAS_HOST; - previousBundledPluginsDir = process.env.OPENCLAW_BUNDLED_PLUGINS_DIR; - previousSkipChannels = process.env.OPENCLAW_SKIP_CHANNELS; - previousSkipProviders = process.env.OPENCLAW_SKIP_PROVIDERS; - previousSkipCron = process.env.OPENCLAW_SKIP_CRON; - previousMinimalGateway = process.env.OPENCLAW_TEST_MINIMAL_GATEWAY; + gatewayEnvSnapshot = captureEnv([...GATEWAY_TEST_ENV_KEYS]); tempHome = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-gateway-home-")); process.env.HOME = tempHome; process.env.USERPROFILE = tempHome; @@ -176,66 +169,8 @@ async function cleanupGatewayTestHome(options: { restoreEnv: boolean }) { vi.useRealTimers(); resetLogger(); if (options.restoreEnv) { - if (previousHome === undefined) { - delete process.env.HOME; - } else { - process.env.HOME = previousHome; - } - if (previousUserProfile === undefined) { - delete process.env.USERPROFILE; - } else { - process.env.USERPROFILE = previousUserProfile; - } - if (previousStateDir === undefined) { - delete process.env.OPENCLAW_STATE_DIR; - } else { - process.env.OPENCLAW_STATE_DIR = previousStateDir; - } - if (previousConfigPath === undefined) { - delete process.env.OPENCLAW_CONFIG_PATH; - } else { - process.env.OPENCLAW_CONFIG_PATH = previousConfigPath; - } - if (previousSkipBrowserControl === undefined) { - delete process.env.OPENCLAW_SKIP_BROWSER_CONTROL_SERVER; - } else { - process.env.OPENCLAW_SKIP_BROWSER_CONTROL_SERVER = previousSkipBrowserControl; - } - if (previousSkipGmailWatcher === undefined) { - delete process.env.OPENCLAW_SKIP_GMAIL_WATCHER; - } else { - process.env.OPENCLAW_SKIP_GMAIL_WATCHER = previousSkipGmailWatcher; - } - if (previousSkipCanvasHost === undefined) { - delete process.env.OPENCLAW_SKIP_CANVAS_HOST; - } else { - process.env.OPENCLAW_SKIP_CANVAS_HOST = previousSkipCanvasHost; - } - if (previousBundledPluginsDir === undefined) { - delete process.env.OPENCLAW_BUNDLED_PLUGINS_DIR; - } else { - process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = previousBundledPluginsDir; - } - if (previousSkipChannels === undefined) { - delete process.env.OPENCLAW_SKIP_CHANNELS; - } else { - process.env.OPENCLAW_SKIP_CHANNELS = previousSkipChannels; - } - if (previousSkipProviders === undefined) { - delete process.env.OPENCLAW_SKIP_PROVIDERS; - } else { - process.env.OPENCLAW_SKIP_PROVIDERS = previousSkipProviders; - } - if (previousSkipCron === undefined) { - delete process.env.OPENCLAW_SKIP_CRON; - } else { - process.env.OPENCLAW_SKIP_CRON = previousSkipCron; - } - if (previousMinimalGateway === undefined) { - delete process.env.OPENCLAW_TEST_MINIMAL_GATEWAY; - } else { - process.env.OPENCLAW_TEST_MINIMAL_GATEWAY = previousMinimalGateway; - } + gatewayEnvSnapshot?.restore(); + gatewayEnvSnapshot = undefined; } if (options.restoreEnv && tempHome) { await fs.rm(tempHome, { diff --git a/src/test-utils/env.test.ts b/src/test-utils/env.test.ts new file mode 100644 index 000000000..dce4e8946 --- /dev/null +++ b/src/test-utils/env.test.ts @@ -0,0 +1,56 @@ +import { describe, expect, it } from "vitest"; +import { captureEnv, captureFullEnv, withEnv, withEnvAsync } from "./env.js"; + +describe("env test utils", () => { + it("captureEnv restores mutated keys", () => { + const keyA = "OPENCLAW_ENV_TEST_A"; + const keyB = "OPENCLAW_ENV_TEST_B"; + const snapshot = captureEnv([keyA, keyB]); + const prevA = process.env[keyA]; + const prevB = process.env[keyB]; + process.env[keyA] = "mutated"; + delete process.env[keyB]; + + snapshot.restore(); + + expect(process.env[keyA]).toBe(prevA); + expect(process.env[keyB]).toBe(prevB); + }); + + it("captureFullEnv restores added keys and baseline values", () => { + const key = "OPENCLAW_ENV_TEST_ADDED"; + const prevHome = process.env.HOME; + const snapshot = captureFullEnv(); + process.env[key] = "1"; + delete process.env.HOME; + + snapshot.restore(); + + expect(process.env[key]).toBeUndefined(); + expect(process.env.HOME).toBe(prevHome); + }); + + it("withEnv applies values only inside callback", () => { + const key = "OPENCLAW_ENV_TEST_SYNC"; + const prev = process.env[key]; + + const seen = withEnv({ [key]: "inside" }, () => process.env[key]); + + expect(seen).toBe("inside"); + expect(process.env[key]).toBe(prev); + }); + + it("withEnvAsync restores values when callback throws", async () => { + const key = "OPENCLAW_ENV_TEST_ASYNC"; + const prev = process.env[key]; + + await expect( + withEnvAsync({ [key]: "inside" }, async () => { + expect(process.env[key]).toBe("inside"); + throw new Error("boom"); + }), + ).rejects.toThrow("boom"); + + expect(process.env[key]).toBe(prev); + }); +});