From 0e49eec0561acdfb4cf079eb728c68c793187735 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 21 Feb 2026 19:26:59 +0000 Subject: [PATCH] test(commands): dedupe auth-sync fixture and cover invalid profile handling --- src/commands/models.list.auth-sync.test.ts | 159 +++++++++++++-------- 1 file changed, 103 insertions(+), 56 deletions(-) diff --git a/src/commands/models.list.auth-sync.test.ts b/src/commands/models.list.auth-sync.test.ts index 159859bb2a5..43242706397 100644 --- a/src/commands/models.list.auth-sync.test.ts +++ b/src/commands/models.list.auth-sync.test.ts @@ -16,67 +16,114 @@ async function pathExists(pathname: string): Promise { } } +type AuthSyncFixture = { + root: string; + stateDir: string; + agentDir: string; + configPath: string; + authPath: string; +}; + +async function withAuthSyncFixture(run: (fixture: AuthSyncFixture) => Promise) { + const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-models-list-auth-sync-")); + try { + const stateDir = path.join(root, "state"); + const agentDir = path.join(stateDir, "agents", "main", "agent"); + const configPath = path.join(stateDir, "openclaw.json"); + const authPath = path.join(agentDir, "auth.json"); + + await fs.mkdir(agentDir, { recursive: true }); + await fs.writeFile(configPath, "{}\n", "utf8"); + + await withEnvAsync( + { + OPENCLAW_STATE_DIR: stateDir, + OPENCLAW_AGENT_DIR: agentDir, + PI_CODING_AGENT_DIR: agentDir, + OPENCLAW_CONFIG_PATH: configPath, + OPENROUTER_API_KEY: undefined, + }, + async () => { + clearConfigCache(); + await run({ root, stateDir, agentDir, configPath, authPath }); + }, + ); + } finally { + clearConfigCache(); + await fs.rm(root, { recursive: true, force: true }); + } +} + +function createRuntime() { + return { + log: vi.fn(), + error: vi.fn(), + }; +} + +function getProviderRow(payloadText: string, providerPrefix: string) { + const payload = JSON.parse(payloadText) as { + models?: Array<{ key?: string; available?: boolean }>; + }; + return payload.models?.find((model) => String(model.key ?? "").startsWith(providerPrefix)); +} + describe("models list auth-profile sync", () => { it("marks models available when auth exists only in auth-profiles.json", async () => { - const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-models-list-auth-sync-")); - - try { - const stateDir = path.join(root, "state"); - const agentDir = path.join(stateDir, "agents", "main", "agent"); - const configPath = path.join(stateDir, "openclaw.json"); - await fs.mkdir(agentDir, { recursive: true }); - await fs.writeFile(configPath, "{}\n", "utf8"); - - await withEnvAsync( + await withAuthSyncFixture(async ({ agentDir, authPath }) => { + saveAuthProfileStore( { - OPENCLAW_STATE_DIR: stateDir, - OPENCLAW_AGENT_DIR: agentDir, - PI_CODING_AGENT_DIR: agentDir, - OPENCLAW_CONFIG_PATH: configPath, - OPENROUTER_API_KEY: undefined, - }, - async () => { - saveAuthProfileStore( - { - version: 1, - profiles: { - "openrouter:default": { - type: "api_key", - provider: "openrouter", - key: "sk-or-v1-regression-test", - }, - }, + version: 1, + profiles: { + "openrouter:default": { + type: "api_key", + provider: "openrouter", + key: "sk-or-v1-regression-test", }, - agentDir, - ); - - const authPath = path.join(agentDir, "auth.json"); - expect(await pathExists(authPath)).toBe(false); - - clearConfigCache(); - const runtime = { - log: vi.fn(), - error: vi.fn(), - }; - - await modelsListCommand({ all: true, json: true }, runtime as never); - - expect(runtime.error).not.toHaveBeenCalled(); - expect(runtime.log).toHaveBeenCalledTimes(1); - const payload = JSON.parse(String(runtime.log.mock.calls[0]?.[0])) as { - models?: Array<{ key?: string; available?: boolean }>; - }; - const openrouter = payload.models?.find((model) => - String(model.key ?? "").startsWith("openrouter/"), - ); - expect(openrouter).toBeDefined(); - expect(openrouter?.available).toBe(true); - expect(await pathExists(authPath)).toBe(true); + }, }, + agentDir, ); - } finally { - clearConfigCache(); - await fs.rm(root, { recursive: true, force: true }); - } + + expect(await pathExists(authPath)).toBe(false); + + const runtime = createRuntime(); + await modelsListCommand({ all: true, json: true }, runtime as never); + + expect(runtime.error).not.toHaveBeenCalled(); + expect(runtime.log).toHaveBeenCalledTimes(1); + const openrouter = getProviderRow(String(runtime.log.mock.calls[0]?.[0]), "openrouter/"); + expect(openrouter).toBeDefined(); + expect(openrouter?.available).toBe(true); + expect(await pathExists(authPath)).toBe(true); + }); + }); + + it("keeps providers unavailable when auth profile credentials are invalid", async () => { + await withAuthSyncFixture(async ({ agentDir, authPath }) => { + saveAuthProfileStore( + { + version: 1, + profiles: { + "openrouter:default": { + type: "api_key", + provider: "openrouter", + key: " ", + }, + }, + }, + agentDir, + ); + + const runtime = createRuntime(); + await modelsListCommand({ all: true, json: true }, runtime as never); + + expect(runtime.error).not.toHaveBeenCalled(); + expect(runtime.log).toHaveBeenCalledTimes(1); + const openrouter = getProviderRow(String(runtime.log.mock.calls[0]?.[0]), "openrouter/"); + expect(openrouter).toBeDefined(); + expect(openrouter?.available).not.toBe(true); + expect(await pathExists(authPath)).toBe(false); + }); }); });