197 lines
8.4 KiB
TypeScript
197 lines
8.4 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
test("logs.mjs pode ser importado com novas flags", async () => {
|
|
const mod = await import("../../bin/cli/commands/logs.mjs");
|
|
assert.equal(typeof mod.registerLogs, "function");
|
|
assert.equal(typeof mod.runLogsCommand, "function");
|
|
});
|
|
|
|
test("health.mjs exporta runHealthComponentsCommand", async () => {
|
|
const mod = await import("../../bin/cli/commands/health.mjs");
|
|
assert.equal(typeof mod.registerHealth, "function");
|
|
assert.equal(typeof mod.runHealthCommand, "function");
|
|
assert.equal(typeof mod.runHealthComponentsCommand, "function");
|
|
});
|
|
|
|
test("update.mjs exporta runUpdateCommand", async () => {
|
|
const mod = await import("../../bin/cli/commands/update.mjs");
|
|
assert.equal(typeof mod.registerUpdate, "function");
|
|
assert.equal(typeof mod.runUpdateCommand, "function");
|
|
});
|
|
|
|
test("keys.mjs exporta novos comandos", async () => {
|
|
const mod = await import("../../bin/cli/commands/keys.mjs");
|
|
assert.equal(typeof mod.registerKeys, "function");
|
|
assert.equal(typeof mod.runKeysRegenerateCommand, "function");
|
|
assert.equal(typeof mod.runKeysRevokeCommand, "function");
|
|
assert.equal(typeof mod.runKeysRevealCommand, "function");
|
|
assert.equal(typeof mod.runKeysUsageCommand, "function");
|
|
assert.equal(typeof mod.runKeysPolicyShowCommand, "function");
|
|
assert.equal(typeof mod.runKeysPolicySetCommand, "function");
|
|
assert.equal(typeof mod.runKeysExpirationListCommand, "function");
|
|
assert.equal(typeof mod.runKeysRotateCommand, "function");
|
|
assert.equal(typeof mod.runKeysListCommand, "function");
|
|
assert.equal(typeof mod.runKeysRemoveCommand, "function");
|
|
});
|
|
|
|
test("keys.mjs — runKeysListCommand sem server retorna 0 ou 1", async () => {
|
|
const { runKeysListCommand } = await import("../../bin/cli/commands/keys.mjs");
|
|
let code = 0;
|
|
try {
|
|
code = await runKeysListCommand({ json: true });
|
|
} catch {
|
|
code = 1;
|
|
}
|
|
assert.ok(code === 0 || code === 1);
|
|
});
|
|
|
|
test("provider-store.mjs exporta removeProviderConnectionByProvider", async () => {
|
|
const mod = await import("../../bin/cli/provider-store.mjs");
|
|
assert.equal(typeof mod.removeProviderConnectionByProvider, "function");
|
|
});
|
|
|
|
test("tunnel.mjs exporta subcomandos status/logs/info/rotate", async () => {
|
|
const mod = await import("../../bin/cli/commands/tunnel.mjs");
|
|
assert.equal(typeof mod.registerTunnel, "function");
|
|
assert.equal(typeof mod.runTunnelStatusCommand, "function");
|
|
assert.equal(typeof mod.runTunnelLogsCommand, "function");
|
|
assert.equal(typeof mod.runTunnelInfoCommand, "function");
|
|
assert.equal(typeof mod.runTunnelRotateCommand, "function");
|
|
});
|
|
|
|
test("backup.mjs exporta runBackupAutoEnableCommand/Disable/Status", async () => {
|
|
const mod = await import("../../bin/cli/commands/backup.mjs");
|
|
assert.equal(typeof mod.registerBackup, "function");
|
|
assert.equal(typeof mod.runBackupCommand, "function");
|
|
assert.equal(typeof mod.runBackupAutoEnableCommand, "function");
|
|
assert.equal(typeof mod.runBackupAutoDisableCommand, "function");
|
|
assert.equal(typeof mod.runBackupAutoStatusCommand, "function");
|
|
});
|
|
|
|
test("backup auto status sem arquivo retorna 0", async () => {
|
|
const { runBackupAutoStatusCommand } = await import("../../bin/cli/commands/backup.mjs");
|
|
const { tmpdir } = await import("node:os");
|
|
const orig = process.env.HOME;
|
|
process.env.HOME = tmpdir();
|
|
try {
|
|
const code = await runBackupAutoStatusCommand();
|
|
assert.ok(code === 0 || code === 1);
|
|
} finally {
|
|
process.env.HOME = orig;
|
|
}
|
|
});
|
|
|
|
test("tunnel — registerTunnel registra list/create/stop/status/logs/info/rotate", async () => {
|
|
const { registerTunnel } = await import("../../bin/cli/commands/tunnel.mjs");
|
|
const { Command } = await import("commander");
|
|
const prog = new Command().exitOverride();
|
|
registerTunnel(prog);
|
|
const tunnelCmd = prog.commands.find((c) => c.name() === "tunnel");
|
|
assert.ok(tunnelCmd, "tunnel command deve existir");
|
|
const names = tunnelCmd.commands.map((c) => c.name());
|
|
for (const sub of ["list", "create", "stop", "status", "logs", "info", "rotate"]) {
|
|
assert.ok(names.includes(sub), `tunnel ${sub} deve existir`);
|
|
}
|
|
});
|
|
|
|
test("health components com alertsOnly=true não lança", async () => {
|
|
// Server não está rodando — função deve retornar 1 sem throw.
|
|
const { runHealthComponentsCommand } = await import("../../bin/cli/commands/health.mjs");
|
|
const code = await runHealthComponentsCommand({ alertsOnly: true });
|
|
assert.ok(code === 0 || code === 1, "should return 0 or 1");
|
|
});
|
|
|
|
test("update --check com versão atual não lança", async () => {
|
|
const { runUpdateCommand } = await import("../../bin/cli/commands/update.mjs");
|
|
// Sem servidor npm disponível pode retornar erro — só garante que não throw.
|
|
let code = 0;
|
|
try {
|
|
code = await runUpdateCommand({ check: true, yes: true });
|
|
} catch {
|
|
code = 1;
|
|
}
|
|
assert.ok(code === 0 || code === 1);
|
|
});
|
|
|
|
test("test-provider.mjs exporta runTestProviderCommand com novas flags", async () => {
|
|
const mod = await import("../../bin/cli/commands/test-provider.mjs");
|
|
assert.equal(typeof mod.registerTestProvider, "function");
|
|
assert.equal(typeof mod.runTestProviderCommand, "function");
|
|
});
|
|
|
|
test("test-provider — registerTestProvider registra flags latency/repeat/compare/save", async () => {
|
|
const { registerTestProvider } = await import("../../bin/cli/commands/test-provider.mjs");
|
|
const { Command } = await import("commander");
|
|
const prog = new Command().exitOverride();
|
|
registerTestProvider(prog);
|
|
const testCmd = prog.commands.find((c) => c.name() === "test");
|
|
assert.ok(testCmd, "test command deve existir");
|
|
const optNames = testCmd.options.map((o: any) => o.long);
|
|
assert.ok(optNames.includes("--latency"), "--latency deve existir");
|
|
assert.ok(optNames.includes("--repeat"), "--repeat deve existir");
|
|
assert.ok(optNames.includes("--compare"), "--compare deve existir");
|
|
assert.ok(optNames.includes("--save"), "--save deve existir");
|
|
});
|
|
|
|
test("OAuthFlow.jsx — arquivo existe e exporta startOAuthTui", async () => {
|
|
const { readFileSync } = await import("node:fs");
|
|
const { fileURLToPath } = await import("node:url");
|
|
const path = new URL("../../bin/cli/tui/OAuthFlow.jsx", import.meta.url);
|
|
const src = readFileSync(fileURLToPath(path), "utf8");
|
|
assert.ok(
|
|
src.includes("export async function startOAuthTui"),
|
|
"startOAuthTui deve ser exportada"
|
|
);
|
|
});
|
|
|
|
test("EvalWatch.jsx — arquivo existe e exporta startEvalWatchTui", async () => {
|
|
const { readFileSync } = await import("node:fs");
|
|
const { fileURLToPath } = await import("node:url");
|
|
const path = new URL("../../bin/cli/tui/EvalWatch.jsx", import.meta.url);
|
|
const src = readFileSync(fileURLToPath(path), "utf8");
|
|
assert.ok(
|
|
src.includes("export async function startEvalWatchTui"),
|
|
"startEvalWatchTui deve ser exportada"
|
|
);
|
|
});
|
|
|
|
test("ProvidersTestAll.jsx — arquivo existe e exporta startProvidersTestTui", async () => {
|
|
const { readFileSync } = await import("node:fs");
|
|
const { fileURLToPath } = await import("node:url");
|
|
const path = new URL("../../bin/cli/tui/ProvidersTestAll.jsx", import.meta.url);
|
|
const src = readFileSync(fileURLToPath(path), "utf8");
|
|
assert.ok(
|
|
src.includes("export async function startProvidersTestTui"),
|
|
"startProvidersTestTui deve ser exportada"
|
|
);
|
|
});
|
|
|
|
test("backup matchesGlob — comportamento correto", async () => {
|
|
// Teste via leitura de arquivo para evitar efeitos colaterais de importação
|
|
const { readFileSync } = await import("node:fs");
|
|
const { fileURLToPath } = await import("node:url");
|
|
const src = readFileSync(
|
|
fileURLToPath(new URL("../../bin/cli/commands/backup.mjs", import.meta.url)),
|
|
"utf8"
|
|
);
|
|
// Garante que a função usa lógica correta (sem startsWith na branch sem *)
|
|
assert.ok(src.includes("return fileName === pattern;"), "non-glob deve usar igualdade exata");
|
|
assert.ok(!src.includes("fileName.startsWith(pattern)"), "não deve usar startsWith no non-glob");
|
|
// Garante que suporta multi-wildcard (sem early return parts.length !== 2)
|
|
assert.ok(!src.includes("parts.length !== 2"), "não deve bloquear multi-wildcard");
|
|
});
|
|
|
|
test("test-provider — compare requer pelo menos dois modelos sem server retorna 0 ou 1", async () => {
|
|
const { runTestProviderCommand } = await import("../../bin/cli/commands/test-provider.mjs");
|
|
let code = 0;
|
|
try {
|
|
code = await runTestProviderCommand("anthropic", undefined, {
|
|
compare: "gpt-4o,claude-3-5-sonnet",
|
|
});
|
|
} catch {
|
|
code = 1;
|
|
}
|
|
assert.ok(code === 0 || code === 1);
|
|
});
|