























@@ -0,0 +1,127 @@
1+import { beforeEach, describe, expect, it, vi } from "vitest";
2+import type { AuthProfileStore } from "../../agents/auth-profiles.js";
3+import type { OpenClawConfig } from "../../config/types.openclaw.js";
4+import type { OutputRuntimeEnv } from "../../runtime.js";
5+import { modelsAuthListCommand } from "./auth-list.js";
6+7+const mocks = vi.hoisted(() => ({
8+ensureAuthProfileStore: vi.fn(),
9+externalCliDiscoveryForProviderAuth: vi.fn(() => ({ kind: "none" })),
10+loadModelsConfig: vi.fn(),
11+resolveAuthProfileDisplayLabel: vi.fn(({ profileId }: { profileId: string }) => profileId),
12+resolveKnownAgentId: vi.fn(({ rawAgentId }: { rawAgentId?: string }) => rawAgentId ?? undefined),
13+}));
14+15+vi.mock("../../agents/agent-scope.js", () => ({
16+resolveAgentDir: (_cfg: OpenClawConfig, agentId: string) => `/tmp/openclaw/agents/${agentId}`,
17+resolveDefaultAgentId: () => "main",
18+}));
19+20+vi.mock("../../agents/auth-profiles.js", () => ({
21+ensureAuthProfileStore: mocks.ensureAuthProfileStore,
22+externalCliDiscoveryForProviderAuth: mocks.externalCliDiscoveryForProviderAuth,
23+resolveAuthProfileDisplayLabel: mocks.resolveAuthProfileDisplayLabel,
24+resolveAuthStatePathForDisplay: (agentDir: string) => `${agentDir}/auth-state.json`,
25+}));
26+27+vi.mock("./load-config.js", () => ({
28+loadModelsConfig: mocks.loadModelsConfig,
29+}));
30+31+vi.mock("./shared.js", () => ({
32+resolveKnownAgentId: mocks.resolveKnownAgentId,
33+}));
34+35+function createRuntime(): OutputRuntimeEnv & { logs: string[]; jsonPayloads: unknown[] } {
36+const logs: string[] = [];
37+const jsonPayloads: unknown[] = [];
38+return {
39+ logs,
40+ jsonPayloads,
41+log: (...args: unknown[]) => {
42+logs.push(args.map((value) => String(value)).join(" "));
43+},
44+error: vi.fn(),
45+exit: vi.fn((code: number) => {
46+throw new Error(`exit ${code}`);
47+}),
48+writeStdout: vi.fn(),
49+writeJson: (value: unknown) => {
50+jsonPayloads.push(value);
51+},
52+};
53+}
54+55+describe("modelsAuthListCommand", () => {
56+beforeEach(() => {
57+mocks.loadModelsConfig.mockReset().mockResolvedValue({} as OpenClawConfig);
58+mocks.ensureAuthProfileStore.mockReset();
59+mocks.externalCliDiscoveryForProviderAuth.mockClear();
60+mocks.resolveAuthProfileDisplayLabel.mockClear();
61+mocks.resolveKnownAgentId.mockClear();
62+});
63+64+it("filters profiles by provider and redacts credential material in JSON output", async () => {
65+const store: AuthProfileStore = {
66+version: 1,
67+profiles: {
68+"openai-codex:user@example.com": {
69+type: "oauth",
70+provider: "openai-codex",
71+access: "access-secret",
72+refresh: "refresh-secret",
73+expires: 1_800_000_000_000,
74+email: "user@example.com",
75+},
76+"anthropic:manual": {
77+type: "token",
78+provider: "anthropic",
79+token: "token-secret",
80+},
81+},
82+usageStats: {
83+"openai-codex:user@example.com": {
84+cooldownUntil: 1_800_000_010_000,
85+},
86+},
87+};
88+mocks.ensureAuthProfileStore.mockReturnValue(store);
89+const runtime = createRuntime();
90+91+await modelsAuthListCommand({ provider: "OpenAI-Codex", agent: "coder", json: true }, runtime);
92+93+expect(mocks.externalCliDiscoveryForProviderAuth).toHaveBeenCalledWith({
94+cfg: {},
95+provider: "openai-codex",
96+});
97+expect(runtime.jsonPayloads).toHaveLength(1);
98+expect(JSON.stringify(runtime.jsonPayloads[0])).not.toContain("secret");
99+expect(runtime.jsonPayloads[0]).toMatchObject({
100+agentId: "coder",
101+provider: "openai-codex",
102+profiles: [
103+{
104+id: "openai-codex:user@example.com",
105+provider: "openai-codex",
106+type: "oauth",
107+email: "user@example.com",
108+expiresAt: "2027-01-15T08:00:00.000Z",
109+cooldownUntil: "2027-01-15T08:00:10.000Z",
110+},
111+],
112+});
113+});
114+115+it("prints an empty profile list without failing", async () => {
116+mocks.ensureAuthProfileStore.mockReturnValue({ version: 1, profiles: {} });
117+const runtime = createRuntime();
118+119+await modelsAuthListCommand({}, runtime);
120+121+expect(runtime.logs).toEqual([
122+"Agent: main",
123+"Auth state file: /tmp/openclaw/agents/main/auth-state.json",
124+"Profiles: (none)",
125+]);
126+});
127+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。