mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:00:42 +00:00
test: share oauth mock setup
This commit is contained in:
48
src/agents/auth-profiles/oauth-common-mocks.test-support.ts
Normal file
48
src/agents/auth-profiles/oauth-common-mocks.test-support.ts
Normal file
@@ -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,
|
||||
}));
|
||||
@@ -0,0 +1,6 @@
|
||||
import { vi } from "vitest";
|
||||
|
||||
vi.mock("./external-auth.js", () => ({
|
||||
overlayExternalAuthProfiles: <T>(store: T) => store,
|
||||
shouldPersistExternalAuthProfile: () => true,
|
||||
}));
|
||||
@@ -0,0 +1,11 @@
|
||||
import { vi } from "vitest";
|
||||
|
||||
vi.mock("../../infra/file-lock.js", () => ({
|
||||
resetFileLockStateForTest: () => undefined,
|
||||
withFileLock: async <T>(_filePath: string, _options: unknown, run: () => Promise<T>) => run(),
|
||||
}));
|
||||
|
||||
vi.mock("../../plugin-sdk/file-lock.js", () => ({
|
||||
resetFileLockStateForTest: () => undefined,
|
||||
withFileLock: async <T>(_filePath: string, _options: unknown, run: () => Promise<T>) => run(),
|
||||
}));
|
||||
@@ -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: <T>(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 <T>(_filePath: string, _options: unknown, run: () => Promise<T>) => await run(),
|
||||
|
||||
@@ -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 <T>(_filePath: string, _options: unknown, run: () => Promise<T>) => run(),
|
||||
}));
|
||||
|
||||
vi.mock("../../plugin-sdk/file-lock.js", () => ({
|
||||
resetFileLockStateForTest: () => undefined,
|
||||
withFileLock: async <T>(_filePath: string, _options: unknown, run: () => Promise<T>) => run(),
|
||||
}));
|
||||
|
||||
vi.mock("./doctor.js", () => ({
|
||||
formatAuthDoctorHint: async () => undefined,
|
||||
}));
|
||||
|
||||
vi.mock("./external-auth.js", () => ({
|
||||
overlayExternalAuthProfiles: <T>(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 = "";
|
||||
|
||||
@@ -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 <T>(_filePath: string, _options: unknown, run: () => Promise<T>) => run(),
|
||||
}));
|
||||
|
||||
vi.mock("../../plugin-sdk/file-lock.js", () => ({
|
||||
resetFileLockStateForTest: () => undefined,
|
||||
withFileLock: async <T>(_filePath: string, _options: unknown, run: () => Promise<T>) => run(),
|
||||
}));
|
||||
|
||||
vi.mock("./external-auth.js", () => ({
|
||||
overlayExternalAuthProfiles: <T>(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 = "";
|
||||
|
||||
@@ -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: <T>(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 = "";
|
||||
|
||||
@@ -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 <T>(_filePath: string, _options: unknown, run: () => Promise<T>) => run(),
|
||||
}));
|
||||
|
||||
vi.mock("../../plugin-sdk/file-lock.js", () => ({
|
||||
resetFileLockStateForTest: () => undefined,
|
||||
withFileLock: async <T>(_filePath: string, _options: unknown, run: () => Promise<T>) => 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 = "";
|
||||
|
||||
Reference in New Issue
Block a user