multipass/test/cli.test.ts
Peter Steinberger a69c2b5a1c
Some checks failed
CI / verify (push) Has been cancelled
build: update typescript tooling
2026-05-03 16:29:58 +01:00

220 lines
6.6 KiB
TypeScript

import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { runCli } from "../src/cli/program.js";
import { captureWrites, createTempDir, disposeTempDir, writeText } from "./test-helpers.js";
const directories: string[] = [];
const ansiPattern = new RegExp(String.raw`\u001B\[[0-?]*[ -/]*[@-~]`, "g");
const stripAnsi = (value: string): string => value.replace(ansiPattern, "");
afterEach(async () => {
process.exitCode = 0;
await Promise.all(directories.splice(0).map(disposeTempDir));
});
const createConfig = async (): Promise<string> => {
const directory = await createTempDir();
directories.push(directory);
const configPath = path.join(directory, "multipass.yaml");
await writeText(
configPath,
[
"configVersion: 1",
"providers:",
" local:",
" adapter: loopback",
" platform: loopback",
" loopback:",
" delayMs: 0",
"fixtures:",
" - id: roundtrip-fixture",
" provider: local",
" mode: roundtrip",
" target:",
" id: echo-bot",
" behavior: echo",
" - id: send-fixture",
" provider: local",
" mode: send",
" target:",
" id: sink-bot",
" behavior: sink",
].join("\n"),
);
return configPath;
};
describe("cli", () => {
it("lists providers and fixtures", async () => {
const configPath = await createConfig();
const captured = captureWrites();
try {
expect(await runCli(["node", "multipass", "--config", configPath, "providers"])).toBe(0);
expect(await runCli(["node", "multipass", "--config", configPath, "fixtures"])).toBe(0);
} finally {
captured.restore();
}
expect(captured.stdout.join("")).toContain("configured providers:");
expect(captured.stdout.join("")).toContain("roundtrip-fixture");
});
it("runs doctor, probe, send, roundtrip, and suite commands", async () => {
const configPath = await createConfig();
const captured = captureWrites();
try {
expect(await runCli(["node", "multipass", "--config", configPath, "doctor"])).toBe(0);
expect(
await runCli(["node", "multipass", "--config", configPath, "probe", "roundtrip-fixture"]),
).toBe(0);
expect(
await runCli(["node", "multipass", "--config", configPath, "send", "send-fixture"]),
).toBe(0);
expect(
await runCli([
"node",
"multipass",
"--config",
configPath,
"roundtrip",
"roundtrip-fixture",
]),
).toBe(0);
expect(
await runCli([
"node",
"multipass",
"--config",
configPath,
"run",
"roundtrip-fixture",
"send-fixture",
]),
).toBe(0);
} finally {
captured.restore();
}
const stdout = stripAnsi(captured.stdout.join(""));
expect(stdout).toContain("doctor ok");
expect(stdout).toContain("PASS roundtrip-fixture");
expect(stdout).toContain("suite 2/2 passed");
});
it("reports CLI errors to stderr", async () => {
const configPath = await createConfig();
const captured = captureWrites();
let exitCode: number;
try {
exitCode = await runCli(["node", "multipass", "--config", configPath, "probe", "missing"]);
} finally {
captured.restore();
}
expect(exitCode!).toBe(10);
expect(captured.stderr.join("")).toContain("No fixture found");
});
it("doctor reports missing slack env", async () => {
const directory = await createTempDir();
directories.push(directory);
const configPath = path.join(directory, "multipass.yaml");
await writeText(
configPath,
[
"configVersion: 1",
"providers:",
" slack-native:",
" adapter: slack",
" platform: slack",
" slack: {}",
"fixtures:",
" - id: slack-agent",
" provider: slack-native",
" mode: agent",
" target:",
" id: C1234567890",
].join("\n"),
);
const originalBotToken = process.env.SLACK_BOT_TOKEN;
const originalSigningSecret = process.env.SLACK_SIGNING_SECRET;
delete process.env.SLACK_BOT_TOKEN;
delete process.env.SLACK_SIGNING_SECRET;
const captured = captureWrites();
let exitCode: number;
try {
exitCode = await runCli(["node", "multipass", "--config", configPath, "doctor"]);
} finally {
captured.restore();
if (originalBotToken !== undefined) {
process.env.SLACK_BOT_TOKEN = originalBotToken;
}
if (originalSigningSecret !== undefined) {
process.env.SLACK_SIGNING_SECRET = originalSigningSecret;
}
}
expect(exitCode!).toBe(10);
expect(captured.stdout.join("")).toContain("missing env SLACK_BOT_TOKEN");
expect(captured.stdout.join("")).toContain("missing env SLACK_SIGNING_SECRET");
});
it("doctor reports missing discord bot token", async () => {
const directory = await createTempDir();
directories.push(directory);
const configPath = path.join(directory, "multipass.yaml");
await writeText(
configPath,
[
"configVersion: 1",
"providers:",
" discord-native:",
" adapter: discord",
" platform: discord",
" discord: {}",
"fixtures:",
" - id: discord-agent",
" provider: discord-native",
" mode: agent",
" target:",
' id: "123456789012345678"',
" metadata:",
' guildId: "987654321098765432"',
].join("\n"),
);
const originalBotToken = process.env.DISCORD_BOT_TOKEN;
const originalPublicKey = process.env.DISCORD_PUBLIC_KEY;
const originalApplicationId = process.env.DISCORD_APPLICATION_ID;
delete process.env.DISCORD_BOT_TOKEN;
delete process.env.DISCORD_PUBLIC_KEY;
delete process.env.DISCORD_APPLICATION_ID;
const captured = captureWrites();
let exitCode: number;
try {
exitCode = await runCli(["node", "multipass", "--config", configPath, "doctor"]);
} finally {
captured.restore();
if (originalBotToken !== undefined) {
process.env.DISCORD_BOT_TOKEN = originalBotToken;
}
if (originalPublicKey !== undefined) {
process.env.DISCORD_PUBLIC_KEY = originalPublicKey;
}
if (originalApplicationId !== undefined) {
process.env.DISCORD_APPLICATION_ID = originalApplicationId;
}
}
expect(exitCode!).toBe(10);
expect(captured.stdout.join("")).toContain("missing discord.botToken or DISCORD_BOT_TOKEN");
});
});