From b4e048e60a938ff986440f342dcb7d8f3274fd85 Mon Sep 17 00:00:00 2001 From: Shakker Date: Fri, 5 Jun 2026 00:12:38 +0100 Subject: [PATCH] test: reset gateway token env per case --- .../local/gateway-config.test.ts | 96 +++++++++---------- 1 file changed, 45 insertions(+), 51 deletions(-) diff --git a/src/commands/onboard-non-interactive/local/gateway-config.test.ts b/src/commands/onboard-non-interactive/local/gateway-config.test.ts index 7f7647ae41b0..84db50d98696 100644 --- a/src/commands/onboard-non-interactive/local/gateway-config.test.ts +++ b/src/commands/onboard-non-interactive/local/gateway-config.test.ts @@ -1,6 +1,7 @@ // Non-interactive gateway config tests cover port, bind, auth token, and SecretRef preservation behavior. -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; +import { withEnv } from "../../../test-utils/env.js"; import type { OnboardOptions } from "../../onboard-types.js"; import { applyNonInteractiveGatewayConfig } from "./gateway-config.js"; @@ -44,40 +45,33 @@ function applyGatewayConfig({ nextConfig = {} as OpenClawConfig, opts = baseOpts, runtime = createRuntime(), + env = {}, }: { nextConfig?: OpenClawConfig; opts?: OnboardOptions; runtime?: ReturnType; + env?: Record; } = {}) { - return applyNonInteractiveGatewayConfig({ - nextConfig, - opts, - runtime: runtime as never, - defaultPort: 18789, - }); + return withEnv( + { + OPENCLAW_GATEWAY_TOKEN: undefined, + [SAMPLE_SECRET_REF.id]: undefined, + ...env, + }, + () => { + return applyNonInteractiveGatewayConfig({ + nextConfig, + opts, + runtime: runtime as never, + defaultPort: 18789, + }); + }, + ); } describe("applyNonInteractiveGatewayConfig token resolution chain", () => { - const originalEnvToken = process.env.OPENCLAW_GATEWAY_TOKEN; - const originalRefValue = process.env[SAMPLE_SECRET_REF.id]; - beforeEach(() => { vi.clearAllMocks(); - delete process.env.OPENCLAW_GATEWAY_TOKEN; - delete process.env[SAMPLE_SECRET_REF.id]; - }); - - afterEach(() => { - if (originalEnvToken === undefined) { - delete process.env.OPENCLAW_GATEWAY_TOKEN; - } else { - process.env.OPENCLAW_GATEWAY_TOKEN = originalEnvToken; - } - if (originalRefValue === undefined) { - delete process.env[SAMPLE_SECRET_REF.id]; - } else { - process.env[SAMPLE_SECRET_REF.id] = originalRefValue; - } }); // --- Plaintext preservation (the original regression) --- @@ -94,10 +88,12 @@ describe("applyNonInteractiveGatewayConfig token resolution chain", () => { it("prefers existing plaintext token over ambient OPENCLAW_GATEWAY_TOKEN on re-onboard", () => { // A stale shell/launchd OPENCLAW_GATEWAY_TOKEN must not rotate a // persisted token — that would break already-paired clients. - process.env.OPENCLAW_GATEWAY_TOKEN = "stale-env-token"; const nextConfig = createTokenConfig("existing-user-token"); - const result = applyGatewayConfig({ nextConfig }); + const result = applyGatewayConfig({ + nextConfig, + env: { OPENCLAW_GATEWAY_TOKEN: "stale-env-token" }, + }); expect(result?.nextConfig.gateway?.auth?.token).toBe("existing-user-token"); expect(randomToken).not.toHaveBeenCalled(); @@ -116,9 +112,7 @@ describe("applyNonInteractiveGatewayConfig token resolution chain", () => { }); it("uses OPENCLAW_GATEWAY_TOKEN to fill an empty config on first-run", () => { - process.env.OPENCLAW_GATEWAY_TOKEN = "env-token"; - - const result = applyGatewayConfig(); + const result = applyGatewayConfig({ env: { OPENCLAW_GATEWAY_TOKEN: "env-token" } }); expect(result?.nextConfig.gateway?.auth?.token).toBe("env-token"); expect(randomToken).not.toHaveBeenCalled(); @@ -144,20 +138,24 @@ describe("applyNonInteractiveGatewayConfig token resolution chain", () => { it("preserves an existing SecretRef even when ambient OPENCLAW_GATEWAY_TOKEN is set", () => { // A stale ambient env must not declassify a configured SecretRef. - process.env.OPENCLAW_GATEWAY_TOKEN = "stale-env-token"; const nextConfig = createTokenConfig(SAMPLE_SECRET_REF); - const result = applyGatewayConfig({ nextConfig }); + const result = applyGatewayConfig({ + nextConfig, + env: { OPENCLAW_GATEWAY_TOKEN: "stale-env-token" }, + }); expect(result?.nextConfig.gateway?.auth?.token).toEqual(SAMPLE_SECRET_REF); expect(randomToken).not.toHaveBeenCalled(); }); it("leaves env-source SecretRef resolution to the health probe path", () => { - process.env[SAMPLE_SECRET_REF.id] = "resolved-secret-value"; const nextConfig = createTokenConfig(SAMPLE_SECRET_REF); - const result = applyGatewayConfig({ nextConfig }); + const result = applyGatewayConfig({ + nextConfig, + env: { [SAMPLE_SECRET_REF.id]: "resolved-secret-value" }, + }); expect(result?.nextConfig.gateway?.auth?.token).toEqual(SAMPLE_SECRET_REF); expect(randomToken).not.toHaveBeenCalled(); @@ -177,25 +175,21 @@ describe("applyNonInteractiveGatewayConfig token resolution chain", () => { it("overrides an existing SecretRef when --gateway-token-ref-env is provided", () => { const newRefId = "OPENCLAW_GATEWAY_TOKEN_NEW_REF"; - process.env[newRefId] = "resolved-new-ref-value"; - try { - const nextConfig = createTokenConfig(SAMPLE_SECRET_REF); + const nextConfig = createTokenConfig(SAMPLE_SECRET_REF); - const result = applyGatewayConfig({ - nextConfig, - opts: { gatewayTokenRefEnv: newRefId } as OnboardOptions, - }); + const result = applyGatewayConfig({ + nextConfig, + opts: { gatewayTokenRefEnv: newRefId } as OnboardOptions, + env: { [newRefId]: "resolved-new-ref-value" }, + }); - const newToken = result?.nextConfig.gateway?.auth?.token; - expect(typeof newToken).toBe("object"); - const newTokenRef = typeof newToken === "object" && newToken !== null ? newToken : undefined; - expect(newTokenRef?.source).toBe("env"); - expect(newTokenRef?.id).toBe(newRefId); - expect(newToken).not.toEqual(SAMPLE_SECRET_REF); - expect(randomToken).not.toHaveBeenCalled(); - } finally { - delete process.env[newRefId]; - } + const newToken = result?.nextConfig.gateway?.auth?.token; + expect(typeof newToken).toBe("object"); + const newTokenRef = typeof newToken === "object" && newToken !== null ? newToken : undefined; + expect(newTokenRef?.source).toBe("env"); + expect(newTokenRef?.id).toBe(newRefId); + expect(newToken).not.toEqual(SAMPLE_SECRET_REF); + expect(randomToken).not.toHaveBeenCalled(); }); it("fails when --gateway-token-ref-env points to a missing env var", () => {