From 57326feb8daf4256e91d6688000b6a7202f6a17c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 18 Apr 2026 23:48:16 +0100 Subject: [PATCH] test: share oauth mock setup --- .../oauth-common-mocks.test-support.ts | 48 +++++++++++++ ...-external-auth-passthrough.test-support.ts | 6 ++ ...auth-file-lock-passthrough.test-support.ts | 11 +++ .../oauth-lock-timeout-classification.test.ts | 51 ++++---------- .../auth-profiles/oauth-refresh-queue.test.ts | 59 ++-------------- .../oauth.adopt-identity.test.ts | 68 +++---------------- .../oauth.concurrent-agents.test.ts | 59 ++-------------- .../oauth.mirror-refresh.test.ts | 52 +------------- 8 files changed, 100 insertions(+), 254 deletions(-) create mode 100644 src/agents/auth-profiles/oauth-common-mocks.test-support.ts create mode 100644 src/agents/auth-profiles/oauth-external-auth-passthrough.test-support.ts create mode 100644 src/agents/auth-profiles/oauth-file-lock-passthrough.test-support.ts diff --git a/src/agents/auth-profiles/oauth-common-mocks.test-support.ts b/src/agents/auth-profiles/oauth-common-mocks.test-support.ts new file mode 100644 index 00000000000..374c7a6e837 --- /dev/null +++ b/src/agents/auth-profiles/oauth-common-mocks.test-support.ts @@ -0,0 +1,48 @@ +import { vi } from "vitest"; +import type { OAuthCredential } from "./types.js"; + +const oauthProviderRuntimeMocks = vi.hoisted(() => ({ + refreshProviderOAuthCredentialWithPluginMock: vi.fn( + async (_params?: { context?: unknown }) => undefined, + ), + formatProviderAuthProfileApiKeyWithPluginMock: vi.fn(() => undefined), +})); + +export function getOAuthProviderRuntimeMocks() { + return oauthProviderRuntimeMocks; +} + +vi.mock("../cli-credentials.js", () => ({ + readCodexCliCredentialsCached: () => null, + readMiniMaxCliCredentialsCached: () => null, + resetCliCredentialCachesForTest: () => undefined, + writeCodexCliCredentials: () => true, +})); + +vi.mock("../../plugins/provider-runtime.runtime.js", () => ({ + formatProviderAuthProfileApiKeyWithPlugin: (params: { context?: { access?: string } }) => + oauthProviderRuntimeMocks.formatProviderAuthProfileApiKeyWithPluginMock() ?? + params?.context?.access, + refreshProviderOAuthCredentialWithPlugin: + oauthProviderRuntimeMocks.refreshProviderOAuthCredentialWithPluginMock, +})); + +vi.mock("./doctor.js", () => ({ + formatAuthDoctorHint: async () => undefined, +})); + +vi.mock("./external-cli-sync.js", () => ({ + areOAuthCredentialsEquivalent: (a: unknown, b: unknown) => a === b, + hasUsableOAuthCredential: (credential: OAuthCredential | undefined, now = Date.now()) => + credential?.type === "oauth" && + credential.access.trim().length > 0 && + Number.isFinite(credential.expires) && + credential.expires - now > 5 * 60 * 1000, + isSafeToUseExternalCliCredential: () => true, + readExternalCliBootstrapCredential: () => null, + readManagedExternalCliCredential: () => null, + resolveExternalCliAuthProfiles: () => [], + shouldBootstrapFromExternalCliCredential: () => false, + shouldReplaceStoredOAuthCredential: (existing: unknown, incoming: unknown) => + existing !== incoming, +})); diff --git a/src/agents/auth-profiles/oauth-external-auth-passthrough.test-support.ts b/src/agents/auth-profiles/oauth-external-auth-passthrough.test-support.ts new file mode 100644 index 00000000000..8e0581ef78a --- /dev/null +++ b/src/agents/auth-profiles/oauth-external-auth-passthrough.test-support.ts @@ -0,0 +1,6 @@ +import { vi } from "vitest"; + +vi.mock("./external-auth.js", () => ({ + overlayExternalAuthProfiles: (store: T) => store, + shouldPersistExternalAuthProfile: () => true, +})); diff --git a/src/agents/auth-profiles/oauth-file-lock-passthrough.test-support.ts b/src/agents/auth-profiles/oauth-file-lock-passthrough.test-support.ts new file mode 100644 index 00000000000..5259f98dfb2 --- /dev/null +++ b/src/agents/auth-profiles/oauth-file-lock-passthrough.test-support.ts @@ -0,0 +1,11 @@ +import { vi } from "vitest"; + +vi.mock("../../infra/file-lock.js", () => ({ + resetFileLockStateForTest: () => undefined, + withFileLock: async (_filePath: string, _options: unknown, run: () => Promise) => run(), +})); + +vi.mock("../../plugin-sdk/file-lock.js", () => ({ + resetFileLockStateForTest: () => undefined, + withFileLock: async (_filePath: string, _options: unknown, run: () => Promise) => run(), +})); diff --git a/src/agents/auth-profiles/oauth-lock-timeout-classification.test.ts b/src/agents/auth-profiles/oauth-lock-timeout-classification.test.ts index fdb4f99c8ed..bce49a77333 100644 --- a/src/agents/auth-profiles/oauth-lock-timeout-classification.test.ts +++ b/src/agents/auth-profiles/oauth-lock-timeout-classification.test.ts @@ -2,6 +2,8 @@ import path from "node:path"; import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { FILE_LOCK_TIMEOUT_ERROR_CODE, type FileLockTimeoutError } from "../../infra/file-lock.js"; import { captureEnv } from "../../test-utils/env.js"; +import { getOAuthProviderRuntimeMocks } from "./oauth-common-mocks.test-support.js"; +import "./oauth-external-auth-passthrough.test-support.js"; import { OAUTH_AGENT_ENV_KEYS, createOAuthMainAgentDir, @@ -9,10 +11,15 @@ import { createExpiredOauthStore, removeOAuthTestTempRoot, resolveApiKeyForProfileInTest, + resetOAuthProviderRuntimeMocks, } from "./oauth-test-utils.js"; import { resolveAuthStorePath, resolveOAuthRefreshLockPath } from "./paths.js"; import { clearRuntimeAuthProfileStoreSnapshots, saveAuthProfileStore } from "./store.js"; -import type { OAuthCredential } from "./types.js"; + +const { + refreshProviderOAuthCredentialWithPluginMock, + formatProviderAuthProfileApiKeyWithPluginMock, +} = getOAuthProviderRuntimeMocks(); let resolveApiKeyForProfile: typeof import("./oauth.js").resolveApiKeyForProfile; let resetOAuthRefreshQueuesForTest: typeof import("./oauth.js").resetOAuthRefreshQueuesForTest; @@ -23,24 +30,11 @@ const { withFileLockMock } = vi.hoisted(() => ({ ), })); -vi.mock("../cli-credentials.js", () => ({ - readCodexCliCredentialsCached: () => null, - readMiniMaxCliCredentialsCached: () => null, - resetCliCredentialCachesForTest: () => undefined, - writeCodexCliCredentials: () => true, -})); - vi.mock("@mariozechner/pi-ai/oauth", () => ({ getOAuthApiKey: vi.fn(async () => null), getOAuthProviders: () => [{ id: "openai-codex" }], })); -vi.mock("../../plugins/provider-runtime.runtime.js", () => ({ - formatProviderAuthProfileApiKeyWithPlugin: (params: { context?: { access?: string } }) => - params?.context?.access, - refreshProviderOAuthCredentialWithPlugin: async () => undefined, -})); - vi.mock("../../infra/file-lock.js", () => ({ FILE_LOCK_TIMEOUT_ERROR_CODE: "file_lock_timeout", resetFileLockStateForTest: () => undefined, @@ -53,31 +47,6 @@ vi.mock("../../plugin-sdk/file-lock.js", () => ({ withFileLock: withFileLockMock, })); -vi.mock("./doctor.js", () => ({ - formatAuthDoctorHint: async () => undefined, -})); - -vi.mock("./external-auth.js", () => ({ - overlayExternalAuthProfiles: (store: T) => store, - shouldPersistExternalAuthProfile: () => true, -})); - -vi.mock("./external-cli-sync.js", () => ({ - areOAuthCredentialsEquivalent: (a: unknown, b: unknown) => a === b, - hasUsableOAuthCredential: (credential: OAuthCredential | undefined, now = Date.now()) => - credential?.type === "oauth" && - credential.access.trim().length > 0 && - Number.isFinite(credential.expires) && - credential.expires - now > 5 * 60 * 1000, - isSafeToUseExternalCliCredential: () => true, - readExternalCliBootstrapCredential: () => null, - readManagedExternalCliCredential: () => null, - resolveExternalCliAuthProfiles: () => [], - shouldBootstrapFromExternalCliCredential: () => false, - shouldReplaceStoredOAuthCredential: (existing: unknown, incoming: unknown) => - existing !== incoming, -})); - function createLockTimeoutError(lockPath: string): FileLockTimeoutError { return Object.assign(new Error(`file lock timeout for ${lockPath.slice(0, -5)}`), { code: FILE_LOCK_TIMEOUT_ERROR_CODE as typeof FILE_LOCK_TIMEOUT_ERROR_CODE, @@ -97,6 +66,10 @@ describe("OAuth refresh lock timeout classification", () => { }); beforeEach(async () => { + resetOAuthProviderRuntimeMocks({ + refreshProviderOAuthCredentialWithPluginMock, + formatProviderAuthProfileApiKeyWithPluginMock, + }); withFileLockMock.mockReset(); withFileLockMock.mockImplementation( async (_filePath: string, _options: unknown, run: () => Promise) => await run(), diff --git a/src/agents/auth-profiles/oauth-refresh-queue.test.ts b/src/agents/auth-profiles/oauth-refresh-queue.test.ts index cd6d435c792..a371be9bf61 100644 --- a/src/agents/auth-profiles/oauth-refresh-queue.test.ts +++ b/src/agents/auth-profiles/oauth-refresh-queue.test.ts @@ -2,6 +2,9 @@ import path from "node:path"; import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { resetFileLockStateForTest } from "../../infra/file-lock.js"; import { captureEnv } from "../../test-utils/env.js"; +import { getOAuthProviderRuntimeMocks } from "./oauth-common-mocks.test-support.js"; +import "./oauth-external-auth-passthrough.test-support.js"; +import "./oauth-file-lock-passthrough.test-support.js"; import { OAUTH_AGENT_ENV_KEYS, createOAuthMainAgentDir, @@ -17,71 +20,17 @@ import { ensureAuthProfileStore, saveAuthProfileStore, } from "./store.js"; -import type { OAuthCredential } from "./types.js"; const { refreshProviderOAuthCredentialWithPluginMock, formatProviderAuthProfileApiKeyWithPluginMock, -} = vi.hoisted(() => ({ - refreshProviderOAuthCredentialWithPluginMock: vi.fn( - async (_params?: { context?: unknown }) => undefined, - ), - formatProviderAuthProfileApiKeyWithPluginMock: vi.fn(() => undefined), -})); - -vi.mock("../cli-credentials.js", () => ({ - readCodexCliCredentialsCached: () => null, - readMiniMaxCliCredentialsCached: () => null, - resetCliCredentialCachesForTest: () => undefined, - writeCodexCliCredentials: () => true, -})); +} = getOAuthProviderRuntimeMocks(); vi.mock("@mariozechner/pi-ai/oauth", () => ({ getOAuthApiKey: vi.fn(async () => null), getOAuthProviders: () => [{ id: "openai-codex" }], })); -vi.mock("../../plugins/provider-runtime.runtime.js", () => ({ - formatProviderAuthProfileApiKeyWithPlugin: (params: { context?: { access?: string } }) => - formatProviderAuthProfileApiKeyWithPluginMock() ?? params?.context?.access, - refreshProviderOAuthCredentialWithPlugin: refreshProviderOAuthCredentialWithPluginMock, -})); - -vi.mock("../../infra/file-lock.js", () => ({ - resetFileLockStateForTest: () => undefined, - withFileLock: async (_filePath: string, _options: unknown, run: () => Promise) => run(), -})); - -vi.mock("../../plugin-sdk/file-lock.js", () => ({ - resetFileLockStateForTest: () => undefined, - withFileLock: async (_filePath: string, _options: unknown, run: () => Promise) => run(), -})); - -vi.mock("./doctor.js", () => ({ - formatAuthDoctorHint: async () => undefined, -})); - -vi.mock("./external-auth.js", () => ({ - overlayExternalAuthProfiles: (store: T) => store, - shouldPersistExternalAuthProfile: () => true, -})); - -vi.mock("./external-cli-sync.js", () => ({ - areOAuthCredentialsEquivalent: (a: unknown, b: unknown) => a === b, - hasUsableOAuthCredential: (credential: OAuthCredential | undefined, now = Date.now()) => - credential?.type === "oauth" && - credential.access.trim().length > 0 && - Number.isFinite(credential.expires) && - credential.expires - now > 5 * 60 * 1000, - isSafeToUseExternalCliCredential: () => true, - readExternalCliBootstrapCredential: () => null, - readManagedExternalCliCredential: () => null, - resolveExternalCliAuthProfiles: () => [], - shouldBootstrapFromExternalCliCredential: () => false, - shouldReplaceStoredOAuthCredential: (existing: unknown, incoming: unknown) => - existing !== incoming, -})); - describe("OAuth refresh in-process queue", () => { const envSnapshot = captureEnv(OAUTH_AGENT_ENV_KEYS); let tempRoot = ""; diff --git a/src/agents/auth-profiles/oauth.adopt-identity.test.ts b/src/agents/auth-profiles/oauth.adopt-identity.test.ts index bda95c77ebf..4fa47a74a95 100644 --- a/src/agents/auth-profiles/oauth.adopt-identity.test.ts +++ b/src/agents/auth-profiles/oauth.adopt-identity.test.ts @@ -3,6 +3,9 @@ import path from "node:path"; import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { resetFileLockStateForTest } from "../../infra/file-lock.js"; import { captureEnv } from "../../test-utils/env.js"; +import { getOAuthProviderRuntimeMocks } from "./oauth-common-mocks.test-support.js"; +import "./oauth-external-auth-passthrough.test-support.js"; +import "./oauth-file-lock-passthrough.test-support.js"; import { OAUTH_AGENT_ENV_KEYS, createOAuthMainAgentDir, @@ -19,76 +22,23 @@ import { ensureAuthProfileStore, saveAuthProfileStore, } from "./store.js"; -import type { AuthProfileStore, OAuthCredential } from "./types.js"; +import type { AuthProfileStore } from "./types.js"; + +const { + refreshProviderOAuthCredentialWithPluginMock, + formatProviderAuthProfileApiKeyWithPluginMock, +} = getOAuthProviderRuntimeMocks(); // Cross-account-leak defense-in-depth: each adopt site in oauth.ts calls the // shared identity copy gate before copying main-store credentials into the // sub-agent store. Unit tests cover policy variants; this suite proves each // production branch refuses a mismatched accountId. -const { - refreshProviderOAuthCredentialWithPluginMock, - formatProviderAuthProfileApiKeyWithPluginMock, -} = vi.hoisted(() => ({ - refreshProviderOAuthCredentialWithPluginMock: vi.fn( - async (_params?: { context?: unknown }) => undefined, - ), - formatProviderAuthProfileApiKeyWithPluginMock: vi.fn(() => undefined), -})); - -vi.mock("../cli-credentials.js", () => ({ - readCodexCliCredentialsCached: () => null, - readMiniMaxCliCredentialsCached: () => null, - resetCliCredentialCachesForTest: () => undefined, - writeCodexCliCredentials: () => true, -})); - vi.mock("@mariozechner/pi-ai/oauth", () => ({ getOAuthApiKey: vi.fn(async () => null), getOAuthProviders: () => [{ id: "openai-codex" }, { id: "anthropic" }], })); -vi.mock("../../plugins/provider-runtime.runtime.js", () => ({ - formatProviderAuthProfileApiKeyWithPlugin: (params: { context?: { access?: string } }) => - formatProviderAuthProfileApiKeyWithPluginMock() ?? params?.context?.access, - refreshProviderOAuthCredentialWithPlugin: refreshProviderOAuthCredentialWithPluginMock, -})); - -vi.mock("../../infra/file-lock.js", () => ({ - resetFileLockStateForTest: () => undefined, - withFileLock: async (_filePath: string, _options: unknown, run: () => Promise) => run(), -})); - -vi.mock("../../plugin-sdk/file-lock.js", () => ({ - resetFileLockStateForTest: () => undefined, - withFileLock: async (_filePath: string, _options: unknown, run: () => Promise) => run(), -})); - -vi.mock("./external-auth.js", () => ({ - overlayExternalAuthProfiles: (store: T) => store, - shouldPersistExternalAuthProfile: () => true, -})); - -vi.mock("./doctor.js", () => ({ - formatAuthDoctorHint: async () => undefined, -})); - -vi.mock("./external-cli-sync.js", () => ({ - areOAuthCredentialsEquivalent: (a: unknown, b: unknown) => a === b, - hasUsableOAuthCredential: (credential: OAuthCredential | undefined, now = Date.now()) => - credential?.type === "oauth" && - credential.access.trim().length > 0 && - Number.isFinite(credential.expires) && - credential.expires - now > 5 * 60 * 1000, - isSafeToUseExternalCliCredential: () => true, - readExternalCliBootstrapCredential: () => null, - readManagedExternalCliCredential: () => null, - resolveExternalCliAuthProfiles: () => [], - shouldBootstrapFromExternalCliCredential: () => false, - shouldReplaceStoredOAuthCredential: (existing: unknown, incoming: unknown) => - existing !== incoming, -})); - describe("OAuth credential adoption is identity-gated", () => { const envSnapshot = captureEnv(OAUTH_AGENT_ENV_KEYS); let tempRoot = ""; diff --git a/src/agents/auth-profiles/oauth.concurrent-agents.test.ts b/src/agents/auth-profiles/oauth.concurrent-agents.test.ts index 42bed5f0d33..c9e38907fb3 100644 --- a/src/agents/auth-profiles/oauth.concurrent-agents.test.ts +++ b/src/agents/auth-profiles/oauth.concurrent-agents.test.ts @@ -3,6 +3,8 @@ import path from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { resetFileLockStateForTest } from "../../infra/file-lock.js"; import { captureEnv } from "../../test-utils/env.js"; +import { getOAuthProviderRuntimeMocks } from "./oauth-common-mocks.test-support.js"; +import "./oauth-external-auth-passthrough.test-support.js"; import { OAUTH_AGENT_ENV_KEYS, createOAuthMainAgentDir, @@ -17,7 +19,11 @@ import { ensureAuthProfileStore, saveAuthProfileStore, } from "./store.js"; -import type { OAuthCredential } from "./types.js"; + +const { + refreshProviderOAuthCredentialWithPluginMock, + formatProviderAuthProfileApiKeyWithPluginMock, +} = getOAuthProviderRuntimeMocks(); let resolveApiKeyForProfile: typeof import("./oauth.js").resolveApiKeyForProfile; let resetOAuthRefreshQueuesForTest: typeof import("./oauth.js").resetOAuthRefreshQueuesForTest; @@ -26,62 +32,11 @@ async function loadOAuthModuleForTest() { ({ resolveApiKeyForProfile, resetOAuthRefreshQueuesForTest } = await import("./oauth.js")); } -const { - refreshProviderOAuthCredentialWithPluginMock, - formatProviderAuthProfileApiKeyWithPluginMock, -} = vi.hoisted(() => ({ - refreshProviderOAuthCredentialWithPluginMock: vi.fn( - async (_params?: { context?: unknown }) => undefined, - ), - formatProviderAuthProfileApiKeyWithPluginMock: vi.fn(() => undefined), -})); - -vi.mock("../cli-credentials.js", () => ({ - readCodexCliCredentialsCached: () => null, - readMiniMaxCliCredentialsCached: () => null, - resetCliCredentialCachesForTest: () => undefined, - writeCodexCliCredentials: () => true, -})); - vi.mock("@mariozechner/pi-ai/oauth", () => ({ getOAuthApiKey: vi.fn(async () => null), getOAuthProviders: () => [{ id: "openai-codex" }], })); -vi.mock("../../plugins/provider-runtime.runtime.js", () => ({ - formatProviderAuthProfileApiKeyWithPlugin: (params: { context?: { access?: string } }) => - formatProviderAuthProfileApiKeyWithPluginMock() ?? params?.context?.access, - refreshProviderOAuthCredentialWithPlugin: refreshProviderOAuthCredentialWithPluginMock, -})); - -vi.mock("./external-auth.js", () => ({ - overlayExternalAuthProfiles: (store: T) => store, - shouldPersistExternalAuthProfile: () => true, -})); - -vi.mock("./doctor.js", () => ({ - formatAuthDoctorHint: async () => undefined, -})); - -// External-CLI sync does real I/O against the user's Codex/MiniMax CLI -// credential files; it is slow and can pollute test state. Stub it to a no-op -// so the suite only exercises in-repo auth-profile logic. -vi.mock("./external-cli-sync.js", () => ({ - areOAuthCredentialsEquivalent: (a: unknown, b: unknown) => a === b, - hasUsableOAuthCredential: (credential: OAuthCredential | undefined, now = Date.now()) => - credential?.type === "oauth" && - credential.access.trim().length > 0 && - Number.isFinite(credential.expires) && - credential.expires - now > 5 * 60 * 1000, - isSafeToUseExternalCliCredential: () => true, - readExternalCliBootstrapCredential: () => null, - readManagedExternalCliCredential: () => null, - resolveExternalCliAuthProfiles: () => [], - shouldBootstrapFromExternalCliCredential: () => false, - shouldReplaceStoredOAuthCredential: (existing: unknown, incoming: unknown) => - existing !== incoming, -})); - describe("resolveApiKeyForProfile cross-agent refresh coordination (#26322)", () => { const envSnapshot = captureEnv(OAUTH_AGENT_ENV_KEYS); let tempRoot = ""; diff --git a/src/agents/auth-profiles/oauth.mirror-refresh.test.ts b/src/agents/auth-profiles/oauth.mirror-refresh.test.ts index 91be35af7cf..a4627af9ddf 100644 --- a/src/agents/auth-profiles/oauth.mirror-refresh.test.ts +++ b/src/agents/auth-profiles/oauth.mirror-refresh.test.ts @@ -4,6 +4,8 @@ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } import { resetFileLockStateForTest } from "../../infra/file-lock.js"; import { captureEnv } from "../../test-utils/env.js"; import { __testing as externalAuthTesting } from "./external-auth.js"; +import "./oauth-file-lock-passthrough.test-support.js"; +import { getOAuthProviderRuntimeMocks } from "./oauth-common-mocks.test-support.js"; import { OAUTH_AGENT_ENV_KEYS, createOAuthMainAgentDir, @@ -24,19 +26,7 @@ import type { AuthProfileStore, OAuthCredential } from "./types.js"; const { refreshProviderOAuthCredentialWithPluginMock, formatProviderAuthProfileApiKeyWithPluginMock, -} = vi.hoisted(() => ({ - refreshProviderOAuthCredentialWithPluginMock: vi.fn( - async (_params?: { context?: unknown }) => undefined, - ), - formatProviderAuthProfileApiKeyWithPluginMock: vi.fn(() => undefined), -})); - -vi.mock("../cli-credentials.js", () => ({ - readCodexCliCredentialsCached: () => null, - readMiniMaxCliCredentialsCached: () => null, - resetCliCredentialCachesForTest: () => undefined, - writeCodexCliCredentials: () => true, -})); +} = getOAuthProviderRuntimeMocks(); vi.mock("@mariozechner/pi-ai/oauth", () => ({ getOAuthProviders: () => [{ id: "anthropic" }, { id: "openai-codex" }], @@ -51,42 +41,6 @@ vi.mock("@mariozechner/pi-ai/oauth", () => ({ }), })); -vi.mock("../../plugins/provider-runtime.runtime.js", () => ({ - formatProviderAuthProfileApiKeyWithPlugin: (params: { context?: { access?: string } }) => - formatProviderAuthProfileApiKeyWithPluginMock() ?? params?.context?.access, - refreshProviderOAuthCredentialWithPlugin: refreshProviderOAuthCredentialWithPluginMock, -})); - -vi.mock("../../infra/file-lock.js", () => ({ - resetFileLockStateForTest: () => undefined, - withFileLock: async (_filePath: string, _options: unknown, run: () => Promise) => run(), -})); - -vi.mock("../../plugin-sdk/file-lock.js", () => ({ - resetFileLockStateForTest: () => undefined, - withFileLock: async (_filePath: string, _options: unknown, run: () => Promise) => run(), -})); - -vi.mock("./doctor.js", () => ({ - formatAuthDoctorHint: async () => undefined, -})); - -vi.mock("./external-cli-sync.js", () => ({ - areOAuthCredentialsEquivalent: (a: unknown, b: unknown) => a === b, - hasUsableOAuthCredential: (credential: OAuthCredential | undefined, now = Date.now()) => - credential?.type === "oauth" && - credential.access.trim().length > 0 && - Number.isFinite(credential.expires) && - credential.expires - now > 5 * 60 * 1000, - isSafeToUseExternalCliCredential: () => true, - readExternalCliBootstrapCredential: () => null, - readManagedExternalCliCredential: () => null, - resolveExternalCliAuthProfiles: () => [], - shouldBootstrapFromExternalCliCredential: () => false, - shouldReplaceStoredOAuthCredential: (existing: unknown, incoming: unknown) => - existing !== incoming, -})); - describe("resolveApiKeyForProfile OAuth refresh mirror-to-main (#26322)", () => { const envSnapshot = captureEnv(OAUTH_AGENT_ENV_KEYS); let tempRoot = "";