mirror of https://github.com/openclaw/openclaw.git
126 lines
3.7 KiB
TypeScript
126 lines
3.7 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const withProgress = vi.hoisted(() => vi.fn(async (_opts, run) => run({ setLabel: vi.fn() })));
|
|
const loadConfig = vi.hoisted(() => vi.fn());
|
|
const resolveGatewayInstallToken = vi.hoisted(() => vi.fn());
|
|
const buildGatewayInstallPlan = vi.hoisted(() => vi.fn());
|
|
const note = vi.hoisted(() => vi.fn());
|
|
const serviceIsLoaded = vi.hoisted(() => vi.fn(async () => false));
|
|
const serviceInstall = vi.hoisted(() => vi.fn(async () => {}));
|
|
const ensureSystemdUserLingerInteractive = vi.hoisted(() => vi.fn(async () => {}));
|
|
|
|
vi.mock("../cli/progress.js", () => ({
|
|
withProgress,
|
|
}));
|
|
|
|
vi.mock("../config/config.js", () => ({
|
|
loadConfig,
|
|
}));
|
|
|
|
vi.mock("./gateway-install-token.js", () => ({
|
|
resolveGatewayInstallToken,
|
|
}));
|
|
|
|
vi.mock("./daemon-install-helpers.js", () => ({
|
|
buildGatewayInstallPlan,
|
|
gatewayInstallErrorHint: vi.fn(() => "hint"),
|
|
}));
|
|
|
|
vi.mock("../terminal/note.js", () => ({
|
|
note,
|
|
}));
|
|
|
|
vi.mock("./configure.shared.js", () => ({
|
|
confirm: vi.fn(async () => true),
|
|
select: vi.fn(async () => "node"),
|
|
}));
|
|
|
|
vi.mock("./daemon-runtime.js", () => ({
|
|
DEFAULT_GATEWAY_DAEMON_RUNTIME: "node",
|
|
GATEWAY_DAEMON_RUNTIME_OPTIONS: [{ value: "node", label: "Node" }],
|
|
}));
|
|
|
|
vi.mock("../daemon/service.js", () => ({
|
|
resolveGatewayService: vi.fn(() => ({
|
|
isLoaded: serviceIsLoaded,
|
|
install: serviceInstall,
|
|
})),
|
|
}));
|
|
|
|
vi.mock("./onboard-helpers.js", () => ({
|
|
guardCancel: (value: unknown) => value,
|
|
}));
|
|
|
|
vi.mock("./systemd-linger.js", () => ({
|
|
ensureSystemdUserLingerInteractive,
|
|
}));
|
|
|
|
const { maybeInstallDaemon } = await import("./configure.daemon.js");
|
|
|
|
describe("maybeInstallDaemon", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
serviceIsLoaded.mockResolvedValue(false);
|
|
serviceInstall.mockResolvedValue(undefined);
|
|
loadConfig.mockReturnValue({});
|
|
resolveGatewayInstallToken.mockResolvedValue({
|
|
token: undefined,
|
|
tokenRefConfigured: true,
|
|
warnings: [],
|
|
});
|
|
buildGatewayInstallPlan.mockResolvedValue({
|
|
programArguments: ["openclaw", "gateway", "run"],
|
|
workingDirectory: "/tmp",
|
|
environment: {},
|
|
});
|
|
});
|
|
|
|
it("does not serialize SecretRef token into service environment", async () => {
|
|
await maybeInstallDaemon({
|
|
runtime: { log: vi.fn(), error: vi.fn(), exit: vi.fn() },
|
|
port: 18789,
|
|
});
|
|
|
|
expect(resolveGatewayInstallToken).toHaveBeenCalledTimes(1);
|
|
expect(buildGatewayInstallPlan).toHaveBeenCalledTimes(1);
|
|
expect("token" in buildGatewayInstallPlan.mock.calls[0][0]).toBe(false);
|
|
expect(serviceInstall).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("blocks install when token SecretRef is unresolved", async () => {
|
|
resolveGatewayInstallToken.mockResolvedValue({
|
|
token: undefined,
|
|
tokenRefConfigured: true,
|
|
unavailableReason: "gateway.auth.token SecretRef is configured but unresolved (boom).",
|
|
warnings: [],
|
|
});
|
|
|
|
await maybeInstallDaemon({
|
|
runtime: { log: vi.fn(), error: vi.fn(), exit: vi.fn() },
|
|
port: 18789,
|
|
});
|
|
|
|
expect(note).toHaveBeenCalledWith(
|
|
expect.stringContaining("Gateway install blocked"),
|
|
"Gateway",
|
|
);
|
|
expect(buildGatewayInstallPlan).not.toHaveBeenCalled();
|
|
expect(serviceInstall).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("continues daemon install flow when service status probe throws", async () => {
|
|
serviceIsLoaded.mockRejectedValueOnce(
|
|
new Error("systemctl is-enabled unavailable: Failed to connect to bus"),
|
|
);
|
|
|
|
await expect(
|
|
maybeInstallDaemon({
|
|
runtime: { log: vi.fn(), error: vi.fn(), exit: vi.fn() },
|
|
port: 18789,
|
|
}),
|
|
).resolves.toBeUndefined();
|
|
|
|
expect(serviceInstall).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|