mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-15 03:50:40 +00:00
148 lines
4.4 KiB
TypeScript
148 lines
4.4 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { makeTempWorkspace } from "../../test-helpers/workspace.js";
|
|
import { captureEnv } from "../../test-utils/env.js";
|
|
|
|
const runtimeLogs: string[] = [];
|
|
const runtimeErrors: string[] = [];
|
|
|
|
const serviceMock = vi.hoisted(() => ({
|
|
label: "Gateway",
|
|
loadedText: "loaded",
|
|
notLoadedText: "not loaded",
|
|
install: vi.fn(async (_opts?: { environment?: Record<string, string | undefined> }) => {}),
|
|
uninstall: vi.fn(async () => {}),
|
|
stop: vi.fn(async () => {}),
|
|
restart: vi.fn(async () => {}),
|
|
isLoaded: vi.fn(async () => false),
|
|
readCommand: vi.fn(async () => null),
|
|
readRuntime: vi.fn(async () => ({ status: "stopped" as const })),
|
|
}));
|
|
|
|
vi.mock("../../daemon/service.js", () => ({
|
|
resolveGatewayService: () => serviceMock,
|
|
}));
|
|
|
|
vi.mock("../../runtime.js", () => ({
|
|
defaultRuntime: {
|
|
log: (message: string) => runtimeLogs.push(message),
|
|
error: (message: string) => runtimeErrors.push(message),
|
|
exit: (code: number) => {
|
|
throw new Error(`__exit__:${code}`);
|
|
},
|
|
},
|
|
}));
|
|
|
|
const { runDaemonInstall } = await import("./install.js");
|
|
const { clearConfigCache } = await import("../../config/config.js");
|
|
|
|
async function readJson(filePath: string): Promise<Record<string, unknown>> {
|
|
return JSON.parse(await fs.readFile(filePath, "utf8")) as Record<string, unknown>;
|
|
}
|
|
|
|
describe("runDaemonInstall integration", () => {
|
|
let envSnapshot: ReturnType<typeof captureEnv>;
|
|
let tempHome: string;
|
|
let configPath: string;
|
|
|
|
beforeAll(async () => {
|
|
envSnapshot = captureEnv([
|
|
"HOME",
|
|
"OPENCLAW_STATE_DIR",
|
|
"OPENCLAW_CONFIG_PATH",
|
|
"OPENCLAW_GATEWAY_TOKEN",
|
|
"CLAWDBOT_GATEWAY_TOKEN",
|
|
"OPENCLAW_GATEWAY_PASSWORD",
|
|
"CLAWDBOT_GATEWAY_PASSWORD",
|
|
]);
|
|
tempHome = await makeTempWorkspace("openclaw-daemon-install-int-");
|
|
configPath = path.join(tempHome, "openclaw.json");
|
|
process.env.HOME = tempHome;
|
|
process.env.OPENCLAW_STATE_DIR = tempHome;
|
|
process.env.OPENCLAW_CONFIG_PATH = configPath;
|
|
});
|
|
|
|
afterAll(async () => {
|
|
envSnapshot.restore();
|
|
await fs.rm(tempHome, { recursive: true, force: true });
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
runtimeLogs.length = 0;
|
|
runtimeErrors.length = 0;
|
|
vi.clearAllMocks();
|
|
delete process.env.OPENCLAW_GATEWAY_TOKEN;
|
|
delete process.env.CLAWDBOT_GATEWAY_TOKEN;
|
|
delete process.env.OPENCLAW_GATEWAY_PASSWORD;
|
|
delete process.env.CLAWDBOT_GATEWAY_PASSWORD;
|
|
serviceMock.isLoaded.mockResolvedValue(false);
|
|
await fs.writeFile(configPath, JSON.stringify({}, null, 2));
|
|
clearConfigCache();
|
|
});
|
|
|
|
it("fails closed when token SecretRef is required but unresolved", async () => {
|
|
await fs.writeFile(
|
|
configPath,
|
|
JSON.stringify(
|
|
{
|
|
secrets: {
|
|
providers: {
|
|
default: { source: "env" },
|
|
},
|
|
},
|
|
gateway: {
|
|
auth: {
|
|
mode: "token",
|
|
token: {
|
|
source: "env",
|
|
provider: "default",
|
|
id: "MISSING_GATEWAY_TOKEN",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
);
|
|
clearConfigCache();
|
|
|
|
await expect(runDaemonInstall({ json: true })).rejects.toThrow("__exit__:1");
|
|
expect(serviceMock.install).not.toHaveBeenCalled();
|
|
const joined = runtimeLogs.join("\n");
|
|
expect(joined).toContain("SecretRef is configured but unresolved");
|
|
expect(joined).toContain("MISSING_GATEWAY_TOKEN");
|
|
});
|
|
|
|
it("auto-mints token when no source exists and persists the same token used for install env", async () => {
|
|
await fs.writeFile(
|
|
configPath,
|
|
JSON.stringify(
|
|
{
|
|
gateway: {
|
|
auth: {
|
|
mode: "token",
|
|
},
|
|
},
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
);
|
|
clearConfigCache();
|
|
|
|
await runDaemonInstall({ json: true });
|
|
|
|
expect(serviceMock.install).toHaveBeenCalledTimes(1);
|
|
const updated = await readJson(configPath);
|
|
const gateway = (updated.gateway ?? {}) as { auth?: { token?: string } };
|
|
const persistedToken = gateway.auth?.token;
|
|
expect(typeof persistedToken).toBe("string");
|
|
expect((persistedToken ?? "").length).toBeGreaterThan(0);
|
|
|
|
const installEnv = serviceMock.install.mock.calls[0]?.[0]?.environment;
|
|
expect(installEnv?.OPENCLAW_GATEWAY_TOKEN).toBe(persistedToken);
|
|
});
|
|
});
|