test(cli): dedupe acp secret file setup and cover password flag collisions

This commit is contained in:
Peter Steinberger
2026-02-21 19:11:29 +00:00
parent 4f835c4c0d
commit 0ecb07e6d1

View File

@@ -28,6 +28,27 @@ vi.mock("../runtime.js", () => ({
describe("acp cli option collisions", () => { describe("acp cli option collisions", () => {
let registerAcpCli: typeof import("./acp-cli.js").registerAcpCli; let registerAcpCli: typeof import("./acp-cli.js").registerAcpCli;
async function withSecretFiles<T>(
secrets: { token?: string; password?: string },
run: (files: { tokenFile?: string; passwordFile?: string }) => Promise<T>,
): Promise<T> {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-acp-cli-"));
try {
const files: { tokenFile?: string; passwordFile?: string } = {};
if (secrets.token !== undefined) {
files.tokenFile = path.join(dir, "token.txt");
await fs.writeFile(files.tokenFile, secrets.token, "utf8");
}
if (secrets.password !== undefined) {
files.passwordFile = path.join(dir, "password.txt");
await fs.writeFile(files.passwordFile, secrets.password, "utf8");
}
return await run(files);
} finally {
await fs.rm(dir, { recursive: true, force: true });
}
}
beforeAll(async () => { beforeAll(async () => {
({ registerAcpCli } = await import("./acp-cli.js")); ({ registerAcpCli } = await import("./acp-cli.js"));
}); });
@@ -57,14 +78,13 @@ describe("acp cli option collisions", () => {
const program = new Command(); const program = new Command();
registerAcpCli(program); registerAcpCli(program);
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-acp-cli-")); await withSecretFiles({ token: "tok_file\n", password: "pw_file\n" }, async (files) => {
const tokenFile = path.join(dir, "token.txt"); await program.parseAsync(
const passwordFile = path.join(dir, "password.txt"); ["acp", "--token-file", files.tokenFile ?? "", "--password-file", files.passwordFile ?? ""],
await fs.writeFile(tokenFile, "tok_file\n", "utf8"); {
await fs.writeFile(passwordFile, "pw_file\n", "utf8"); from: "user",
},
await program.parseAsync(["acp", "--token-file", tokenFile, "--password-file", passwordFile], { );
from: "user",
}); });
expect(serveAcpGateway).toHaveBeenCalledWith( expect(serveAcpGateway).toHaveBeenCalledWith(
@@ -80,12 +100,13 @@ describe("acp cli option collisions", () => {
const program = new Command(); const program = new Command();
registerAcpCli(program); registerAcpCli(program);
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-acp-cli-")); await withSecretFiles({ token: "tok_file\n" }, async (files) => {
const tokenFile = path.join(dir, "token.txt"); await program.parseAsync(
await fs.writeFile(tokenFile, "tok_file\n", "utf8"); ["acp", "--token", "tok_inline", "--token-file", files.tokenFile ?? ""],
{
await program.parseAsync(["acp", "--token", "tok_inline", "--token-file", tokenFile], { from: "user",
from: "user", },
);
}); });
expect(serveAcpGateway).not.toHaveBeenCalled(); expect(serveAcpGateway).not.toHaveBeenCalled();
@@ -95,6 +116,27 @@ describe("acp cli option collisions", () => {
expect(defaultRuntime.exit).toHaveBeenCalledWith(1); expect(defaultRuntime.exit).toHaveBeenCalledWith(1);
}); });
it("rejects mixed password flags and file flags", async () => {
const { registerAcpCli } = await import("./acp-cli.js");
const program = new Command();
registerAcpCli(program);
await withSecretFiles({ password: "pw_file\n" }, async (files) => {
await program.parseAsync(
["acp", "--password", "pw_inline", "--password-file", files.passwordFile ?? ""],
{
from: "user",
},
);
});
expect(serveAcpGateway).not.toHaveBeenCalled();
expect(defaultRuntime.error).toHaveBeenCalledWith(
expect.stringMatching(/Use either --password or --password-file/),
);
expect(defaultRuntime.exit).toHaveBeenCalledWith(1);
});
it("warns when inline secret flags are used", async () => { it("warns when inline secret flags are used", async () => {
const { registerAcpCli } = await import("./acp-cli.js"); const { registerAcpCli } = await import("./acp-cli.js");
const program = new Command(); const program = new Command();