Files
openclaw/src/cli/users-cli.test.ts
T
Peter Steinberger a8b7290f34 feat(gateway): durable user profiles with email aliases and avatars (#111224)
* feat(gateway): durable user profiles with email aliases and avatars

* fix(gateway): compress merge tombstones, content-hash avatar ETags, users CLI json output

* fix(gateway): lean profile listing, scoped avatar routing, typed email validation

* fix(gateway): protocol-complete profile payloads and consistent store reads

* fix(gateway): mark profile schema ensured only after commit

* fix(gateway): avatar endpoint HEAD support and RFC If-None-Match

* fix(gateway): profiles CI conformance — bindings, lint, knip, sql boundary

* feat(gateway): self-service profile edits for authenticated users

* fix(gateway): users.self bootstrap, tombstone-aware ownership, escaped CLI output

* fix(gateway): raw-DDL allowlist entry and lean profile exports
2026-07-19 00:58:43 -07:00

75 lines
2.0 KiB
TypeScript

import { Command } from "commander";
import { afterEach, describe, expect, it, vi } from "vitest";
import { registerUsersCli, testApi } from "./users-cli.js";
const callGatewayFromCli = vi.hoisted(() => vi.fn());
vi.mock("./gateway-rpc.js", () => ({ callGatewayFromCli }));
afterEach(() => {
vi.restoreAllMocks();
callGatewayFromCli.mockReset();
});
describe("registerUsersCli", () => {
it("routes link-email through the admin gateway method", async () => {
const program = new Command().exitOverride();
registerUsersCli(program);
await program.parseAsync([
"node",
"openclaw",
"users",
"link-email",
"Ada@example.com",
"--to",
"p-1",
]);
expect(callGatewayFromCli).toHaveBeenCalledWith(
"users.linkEmail",
expect.objectContaining({ to: "p-1" }),
{ email: "Ada@example.com", targetProfileId: "p-1" },
{ scopes: ["operator.admin"] },
);
});
it("prints the link result as JSON when requested", async () => {
const output = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
callGatewayFromCli.mockResolvedValue({ profile: { id: "p-1" } });
const program = new Command().exitOverride();
registerUsersCli(program);
await program.parseAsync([
"node",
"openclaw",
"users",
"link-email",
"Ada@example.com",
"--to",
"p-1",
"--json",
]);
expect(output).toHaveBeenCalledWith('{\n "profile": {\n "id": "p-1"\n }\n}\n');
});
it("escapes untrusted profile fields in human list output", () => {
const output = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
testApi.writeUsersList(
{
profiles: [
{
id: "p-1",
displayName: "Ada\n\t\u001b[2J\u0007",
emails: ["ada@example.com\nnext@example.com"],
},
],
},
false,
);
expect(output).toHaveBeenCalledWith("p-1\tAda\\n\\t\tada@example.com\\nnext@example.com\n");
});
});