

























@@ -0,0 +1,102 @@
1+import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2+import {
3+resetLegacyOpenClawEnvWarningForTest,
4+warnLegacyOpenClawEnvVars,
5+} from "./env-deprecation.js";
6+7+describe("warnLegacyOpenClawEnvVars", () => {
8+const originalNodeEnv = process.env.NODE_ENV;
9+const originalVitest = process.env.VITEST;
10+let emitWarning: ReturnType<typeof vi.spyOn>;
11+12+beforeEach(() => {
13+resetLegacyOpenClawEnvWarningForTest();
14+emitWarning = vi.spyOn(process, "emitWarning").mockImplementation(() => {});
15+delete process.env.NODE_ENV;
16+delete process.env.VITEST;
17+});
18+19+afterEach(() => {
20+emitWarning.mockRestore();
21+resetLegacyOpenClawEnvWarningForTest();
22+restoreEnv("NODE_ENV", originalNodeEnv);
23+restoreEnv("VITEST", originalVitest);
24+});
25+26+it("warns with counts and prefixes instead of secret-shaped env names", () => {
27+warnLegacyOpenClawEnvVars({
28+CLAWDBOT_GATEWAY_TOKEN: "old-token",
29+MOLTBOT_GATEWAY_PASSWORD: "old-password", // pragma: allowlist secret
30+"CLAWDBOT_MALICIOUS\nforged": "old-value",
31+});
32+33+expect(emitWarning).toHaveBeenCalledOnce();
34+const [message, options] = emitWarning.mock.calls[0] as [
35+string,
36+{ code: string; type: string },
37+];
38+expect(message).toContain("Legacy CLAWDBOT_*, MOLTBOT_* environment variables");
39+expect(message).toContain("3 total");
40+expect(message).toContain("replacing the legacy prefix with OPENCLAW_");
41+expect(message).not.toContain("GATEWAY_TOKEN");
42+expect(message).not.toContain("GATEWAY_PASSWORD");
43+expect(message).not.toContain("forged");
44+expect(options).toEqual({
45+code: "OPENCLAW_LEGACY_ENV_VARS",
46+type: "DeprecationWarning",
47+});
48+});
49+50+it("does not warn for current OPENCLAW names", () => {
51+warnLegacyOpenClawEnvVars({ OPENCLAW_GATEWAY_TOKEN: "token" });
52+53+expect(emitWarning).not.toHaveBeenCalled();
54+});
55+56+it("warns only once after a successful emit", () => {
57+warnLegacyOpenClawEnvVars({ CLAWDBOT_GATEWAY_TOKEN: "old-token" });
58+warnLegacyOpenClawEnvVars({ MOLTBOT_GATEWAY_TOKEN: "old-token" });
59+60+expect(emitWarning).toHaveBeenCalledOnce();
61+});
62+63+it("retries if emitWarning throws before the warning is emitted", () => {
64+emitWarning
65+.mockImplementationOnce(() => {
66+throw new Error("warning sink failed");
67+})
68+.mockImplementationOnce(() => {});
69+70+expect(() => warnLegacyOpenClawEnvVars({ CLAWDBOT_GATEWAY_TOKEN: "old-token" })).toThrow(
71+"warning sink failed",
72+);
73+warnLegacyOpenClawEnvVars({ CLAWDBOT_GATEWAY_TOKEN: "old-token" });
74+75+expect(emitWarning).toHaveBeenCalledTimes(2);
76+});
77+78+it("suppresses warning noise based on the passed env", () => {
79+warnLegacyOpenClawEnvVars({
80+CLAWDBOT_GATEWAY_TOKEN: "old-token",
81+VITEST: "true",
82+});
83+84+expect(emitWarning).not.toHaveBeenCalled();
85+});
86+87+it("does not let process.env test flags suppress a synthetic env", () => {
88+process.env.VITEST = "true";
89+90+warnLegacyOpenClawEnvVars({ CLAWDBOT_GATEWAY_TOKEN: "old-token" });
91+92+expect(emitWarning).toHaveBeenCalledOnce();
93+});
94+});
95+96+function restoreEnv(name: string, value: string | undefined): void {
97+if (value === undefined) {
98+delete process.env[name];
99+return;
100+}
101+process.env[name] = value;
102+}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。