Files
openclaw/src/cli/program/routes.test.ts
Vincent Koc 67b2d1b8e8 CLI: reduce channels add startup memory (#46784)
* CLI: lazy-load channel subcommand handlers

* Channels: defer add command dependencies

* CLI: skip status JSON plugin preload

* CLI: cover status JSON route preload

* Status: trim JSON security audit path

* Status: update JSON fast-path tests

* CLI: cover root help fast path

* CLI: fast-path root help

* Status: keep JSON security parity

* Status: restore JSON security tests

* CLI: document status plugin preload

* Channels: reuse Telegram account import
2026-03-15 09:10:40 -07:00

210 lines
6.9 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
import { findRoutedCommand } from "./routes.js";
const runConfigGetMock = vi.hoisted(() => vi.fn(async () => {}));
const runConfigUnsetMock = vi.hoisted(() => vi.fn(async () => {}));
const modelsListCommandMock = vi.hoisted(() => vi.fn(async () => {}));
const modelsStatusCommandMock = vi.hoisted(() => vi.fn(async () => {}));
vi.mock("../config-cli.js", () => ({
runConfigGet: runConfigGetMock,
runConfigUnset: runConfigUnsetMock,
}));
vi.mock("../../commands/models.js", () => ({
modelsListCommand: modelsListCommandMock,
modelsStatusCommand: modelsStatusCommandMock,
}));
describe("program routes", () => {
beforeEach(() => {
vi.clearAllMocks();
});
function expectRoute(path: string[]) {
const route = findRoutedCommand(path);
expect(route).not.toBeNull();
return route;
}
async function expectRunFalse(path: string[], argv: string[]) {
const route = expectRoute(path);
await expect(route?.run(argv)).resolves.toBe(false);
}
it("matches status route and always preloads plugins", () => {
const route = expectRoute(["status"]);
expect(route?.loadPlugins).toBe(true);
});
it("matches health route and preloads plugins only for text output", () => {
const route = expectRoute(["health"]);
expect(typeof route?.loadPlugins).toBe("function");
const shouldLoad = route?.loadPlugins as (argv: string[]) => boolean;
expect(shouldLoad(["node", "openclaw", "health"])).toBe(true);
expect(shouldLoad(["node", "openclaw", "health", "--json"])).toBe(false);
});
it("returns false when status timeout flag value is missing", async () => {
await expectRunFalse(["status"], ["node", "openclaw", "status", "--timeout"]);
});
it("returns false for sessions route when --store value is missing", async () => {
await expectRunFalse(["sessions"], ["node", "openclaw", "sessions", "--store"]);
});
it("returns false for sessions route when --active value is missing", async () => {
await expectRunFalse(["sessions"], ["node", "openclaw", "sessions", "--active"]);
});
it("returns false for sessions route when --agent value is missing", async () => {
await expectRunFalse(["sessions"], ["node", "openclaw", "sessions", "--agent"]);
});
it("does not fast-route sessions subcommands", () => {
expect(findRoutedCommand(["sessions", "cleanup"])).toBeNull();
});
it("does not match unknown routes", () => {
expect(findRoutedCommand(["definitely-not-real"])).toBeNull();
});
it("returns false for config get route when path argument is missing", async () => {
await expectRunFalse(["config", "get"], ["node", "openclaw", "config", "get", "--json"]);
});
it("returns false for config unset route when path argument is missing", async () => {
await expectRunFalse(["config", "unset"], ["node", "openclaw", "config", "unset"]);
});
it("passes config get path correctly when root option values precede command", async () => {
const route = expectRoute(["config", "get"]);
await expect(
route?.run([
"node",
"openclaw",
"--log-level",
"debug",
"config",
"get",
"update.channel",
"--json",
]),
).resolves.toBe(true);
expect(runConfigGetMock).toHaveBeenCalledWith({ path: "update.channel", json: true });
});
it("passes config unset path correctly when root option values precede command", async () => {
const route = expectRoute(["config", "unset"]);
await expect(
route?.run(["node", "openclaw", "--profile", "work", "config", "unset", "update.channel"]),
).resolves.toBe(true);
expect(runConfigUnsetMock).toHaveBeenCalledWith({ path: "update.channel" });
});
it("passes config get path when root value options appear after subcommand", async () => {
const route = expectRoute(["config", "get"]);
await expect(
route?.run([
"node",
"openclaw",
"config",
"get",
"--log-level",
"debug",
"update.channel",
"--json",
]),
).resolves.toBe(true);
expect(runConfigGetMock).toHaveBeenCalledWith({ path: "update.channel", json: true });
});
it("passes config unset path when root value options appear after subcommand", async () => {
const route = expectRoute(["config", "unset"]);
await expect(
route?.run(["node", "openclaw", "config", "unset", "--profile", "work", "update.channel"]),
).resolves.toBe(true);
expect(runConfigUnsetMock).toHaveBeenCalledWith({ path: "update.channel" });
});
it("returns false for config get route when unknown option appears", async () => {
await expectRunFalse(
["config", "get"],
["node", "openclaw", "config", "get", "--mystery", "value", "update.channel"],
);
});
it("returns false for memory status route when --agent value is missing", async () => {
await expectRunFalse(["memory", "status"], ["node", "openclaw", "memory", "status", "--agent"]);
});
it("returns false for models list route when --provider value is missing", async () => {
await expectRunFalse(["models", "list"], ["node", "openclaw", "models", "list", "--provider"]);
});
it("returns false for models status route when probe flags are missing values", async () => {
await expectRunFalse(
["models", "status"],
["node", "openclaw", "models", "status", "--probe-provider"],
);
await expectRunFalse(
["models", "status"],
["node", "openclaw", "models", "status", "--probe-timeout"],
);
await expectRunFalse(
["models", "status"],
["node", "openclaw", "models", "status", "--probe-concurrency"],
);
await expectRunFalse(
["models", "status"],
["node", "openclaw", "models", "status", "--probe-max-tokens"],
);
await expectRunFalse(
["models", "status"],
["node", "openclaw", "models", "status", "--probe-provider", "openai", "--agent"],
);
});
it("returns false for models status route when --probe-profile has no value", async () => {
await expectRunFalse(
["models", "status"],
["node", "openclaw", "models", "status", "--probe-profile"],
);
});
it("accepts negative-number probe profile values", async () => {
const route = expectRoute(["models", "status"]);
await expect(
route?.run([
"node",
"openclaw",
"models",
"status",
"--probe-provider",
"openai",
"--probe-timeout",
"5000",
"--probe-concurrency",
"2",
"--probe-max-tokens",
"64",
"--probe-profile",
"-1",
"--agent",
"default",
]),
).resolves.toBe(true);
expect(modelsStatusCommandMock).toHaveBeenCalledWith(
expect.objectContaining({
probeProvider: "openai",
probeTimeout: "5000",
probeConcurrency: "2",
probeMaxTokens: "64",
probeProfile: "-1",
agent: "default",
}),
expect.any(Object),
);
});
});