mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
test: share oauth test helpers
This commit is contained in:
@@ -4,19 +4,18 @@ 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 {
|
||||
OAUTH_AGENT_ENV_KEYS,
|
||||
createExpiredOauthStore,
|
||||
resolveApiKeyForProfileInTest,
|
||||
} from "./oauth-test-utils.js";
|
||||
import { resolveAuthStorePath, resolveOAuthRefreshLockPath } from "./paths.js";
|
||||
import { clearRuntimeAuthProfileStoreSnapshots, saveAuthProfileStore } from "./store.js";
|
||||
import type { AuthProfileStore, OAuthCredential } from "./types.js";
|
||||
import type { OAuthCredential } from "./types.js";
|
||||
|
||||
let resolveApiKeyForProfile: typeof import("./oauth.js").resolveApiKeyForProfile;
|
||||
let resetOAuthRefreshQueuesForTest: typeof import("./oauth.js").resetOAuthRefreshQueuesForTest;
|
||||
|
||||
function resolveApiKeyForProfileInTest(
|
||||
params: Omit<Parameters<typeof resolveApiKeyForProfile>[0], "cfg">,
|
||||
) {
|
||||
return resolveApiKeyForProfile({ cfg: {}, ...params });
|
||||
}
|
||||
|
||||
const { withFileLockMock } = vi.hoisted(() => ({
|
||||
withFileLockMock: vi.fn(
|
||||
async <T>(_filePath: string, _options: unknown, run: () => Promise<T>) => await run(),
|
||||
@@ -78,24 +77,6 @@ vi.mock("./external-cli-sync.js", () => ({
|
||||
existing !== incoming,
|
||||
}));
|
||||
|
||||
function createExpiredOauthStore(params: {
|
||||
profileId: string;
|
||||
provider: string;
|
||||
}): AuthProfileStore {
|
||||
return {
|
||||
version: 1,
|
||||
profiles: {
|
||||
[params.profileId]: {
|
||||
type: "oauth",
|
||||
provider: params.provider,
|
||||
access: "stale-access",
|
||||
refresh: "stale-refresh",
|
||||
expires: Date.now() - 60_000,
|
||||
} satisfies OAuthCredential,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -104,11 +85,7 @@ function createLockTimeoutError(lockPath: string): FileLockTimeoutError {
|
||||
}
|
||||
|
||||
describe("OAuth refresh lock timeout classification", () => {
|
||||
const envSnapshot = captureEnv([
|
||||
"OPENCLAW_STATE_DIR",
|
||||
"OPENCLAW_AGENT_DIR",
|
||||
"PI_CODING_AGENT_DIR",
|
||||
]);
|
||||
const envSnapshot = captureEnv(OAUTH_AGENT_ENV_KEYS);
|
||||
let tempRoot = "";
|
||||
let agentDir = "";
|
||||
let caseIndex = 0;
|
||||
@@ -155,7 +132,7 @@ describe("OAuth refresh lock timeout classification", () => {
|
||||
});
|
||||
|
||||
try {
|
||||
await resolveApiKeyForProfileInTest({
|
||||
await resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store,
|
||||
profileId,
|
||||
agentDir,
|
||||
@@ -194,7 +171,7 @@ describe("OAuth refresh lock timeout classification", () => {
|
||||
});
|
||||
|
||||
try {
|
||||
await resolveApiKeyForProfileInTest({
|
||||
await resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store,
|
||||
profileId,
|
||||
agentDir,
|
||||
|
||||
@@ -4,19 +4,18 @@ 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 {
|
||||
OAUTH_AGENT_ENV_KEYS,
|
||||
createExpiredOauthStore,
|
||||
resolveApiKeyForProfileInTest,
|
||||
} from "./oauth-test-utils.js";
|
||||
import { resolveApiKeyForProfile, resetOAuthRefreshQueuesForTest } from "./oauth.js";
|
||||
import {
|
||||
clearRuntimeAuthProfileStoreSnapshots,
|
||||
ensureAuthProfileStore,
|
||||
saveAuthProfileStore,
|
||||
} from "./store.js";
|
||||
import type { AuthProfileStore, OAuthCredential } from "./types.js";
|
||||
|
||||
function resolveApiKeyForProfileInTest(
|
||||
params: Omit<Parameters<typeof resolveApiKeyForProfile>[0], "cfg">,
|
||||
) {
|
||||
return resolveApiKeyForProfile({ cfg: {}, ...params });
|
||||
}
|
||||
import type { OAuthCredential } from "./types.js";
|
||||
|
||||
const {
|
||||
refreshProviderOAuthCredentialWithPluginMock,
|
||||
@@ -81,30 +80,8 @@ vi.mock("./external-cli-sync.js", () => ({
|
||||
existing !== incoming,
|
||||
}));
|
||||
|
||||
function createExpiredOauthStore(params: {
|
||||
profileId: string;
|
||||
provider: string;
|
||||
}): AuthProfileStore {
|
||||
return {
|
||||
version: 1,
|
||||
profiles: {
|
||||
[params.profileId]: {
|
||||
type: "oauth",
|
||||
provider: params.provider,
|
||||
access: "stale-access",
|
||||
refresh: "stale-refresh",
|
||||
expires: Date.now() - 60_000,
|
||||
} satisfies OAuthCredential,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("OAuth refresh in-process queue", () => {
|
||||
const envSnapshot = captureEnv([
|
||||
"OPENCLAW_STATE_DIR",
|
||||
"OPENCLAW_AGENT_DIR",
|
||||
"PI_CODING_AGENT_DIR",
|
||||
]);
|
||||
const envSnapshot = captureEnv(OAUTH_AGENT_ENV_KEYS);
|
||||
let tempRoot = "";
|
||||
let agentDir = "";
|
||||
let caseIndex = 0;
|
||||
@@ -163,12 +140,12 @@ describe("OAuth refresh in-process queue", () => {
|
||||
});
|
||||
|
||||
const [first, second] = await Promise.all([
|
||||
resolveApiKeyForProfileInTest({
|
||||
resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store: ensureAuthProfileStore(agentDir),
|
||||
profileId,
|
||||
agentDir,
|
||||
}).catch((e) => e),
|
||||
resolveApiKeyForProfileInTest({
|
||||
resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store: ensureAuthProfileStore(agentDir),
|
||||
profileId,
|
||||
agentDir,
|
||||
@@ -230,7 +207,7 @@ describe("OAuth refresh in-process queue", () => {
|
||||
|
||||
const results = await Promise.all(
|
||||
Array.from({ length: 10 }, () =>
|
||||
resolveApiKeyForProfileInTest({
|
||||
resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store: ensureAuthProfileStore(agentDir),
|
||||
profileId,
|
||||
agentDir,
|
||||
|
||||
54
src/agents/auth-profiles/oauth-test-utils.ts
Normal file
54
src/agents/auth-profiles/oauth-test-utils.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import type { resolveApiKeyForProfile } from "./oauth.js";
|
||||
import type { AuthProfileStore, OAuthCredential } from "./types.js";
|
||||
|
||||
export const OAUTH_AGENT_ENV_KEYS = [
|
||||
"OPENCLAW_STATE_DIR",
|
||||
"OPENCLAW_AGENT_DIR",
|
||||
"PI_CODING_AGENT_DIR",
|
||||
];
|
||||
|
||||
export function resolveApiKeyForProfileInTest(
|
||||
resolver: typeof resolveApiKeyForProfile,
|
||||
params: Omit<Parameters<typeof resolveApiKeyForProfile>[0], "cfg">,
|
||||
) {
|
||||
return resolver({ cfg: {}, ...params });
|
||||
}
|
||||
|
||||
export function oauthCred(params: {
|
||||
provider: string;
|
||||
access: string;
|
||||
refresh: string;
|
||||
expires: number;
|
||||
accountId?: string;
|
||||
email?: string;
|
||||
}): OAuthCredential {
|
||||
return { type: "oauth", ...params };
|
||||
}
|
||||
|
||||
export function storeWith(profileId: string, cred: OAuthCredential): AuthProfileStore {
|
||||
return { version: 1, profiles: { [profileId]: cred } };
|
||||
}
|
||||
|
||||
export function createExpiredOauthStore(params: {
|
||||
profileId: string;
|
||||
provider: string;
|
||||
access?: string;
|
||||
refresh?: string;
|
||||
accountId?: string;
|
||||
email?: string;
|
||||
}): AuthProfileStore {
|
||||
return {
|
||||
version: 1,
|
||||
profiles: {
|
||||
[params.profileId]: {
|
||||
type: "oauth",
|
||||
provider: params.provider,
|
||||
access: params.access ?? "cached-access-token",
|
||||
refresh: params.refresh ?? "refresh-token",
|
||||
expires: Date.now() - 60_000,
|
||||
accountId: params.accountId,
|
||||
email: params.email,
|
||||
} satisfies OAuthCredential,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -4,6 +4,12 @@ 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 {
|
||||
OAUTH_AGENT_ENV_KEYS,
|
||||
oauthCred,
|
||||
resolveApiKeyForProfileInTest,
|
||||
storeWith,
|
||||
} from "./oauth-test-utils.js";
|
||||
import { resolveApiKeyForProfile, resetOAuthRefreshQueuesForTest } from "./oauth.js";
|
||||
import {
|
||||
clearRuntimeAuthProfileStoreSnapshots,
|
||||
@@ -17,12 +23,6 @@ import type { AuthProfileStore, OAuthCredential } from "./types.js";
|
||||
// sub-agent store. Unit tests cover policy variants; this suite proves each
|
||||
// production branch refuses a mismatched accountId.
|
||||
|
||||
function resolveApiKeyForProfileInTest(
|
||||
params: Omit<Parameters<typeof resolveApiKeyForProfile>[0], "cfg">,
|
||||
) {
|
||||
return resolveApiKeyForProfile({ cfg: {}, ...params });
|
||||
}
|
||||
|
||||
const {
|
||||
refreshProviderOAuthCredentialWithPluginMock,
|
||||
formatProviderAuthProfileApiKeyWithPluginMock,
|
||||
@@ -86,27 +86,8 @@ vi.mock("./external-cli-sync.js", () => ({
|
||||
existing !== incoming,
|
||||
}));
|
||||
|
||||
function oauthCred(params: {
|
||||
provider: string;
|
||||
access: string;
|
||||
refresh: string;
|
||||
expires: number;
|
||||
accountId?: string;
|
||||
email?: string;
|
||||
}): OAuthCredential {
|
||||
return { type: "oauth", ...params };
|
||||
}
|
||||
|
||||
function storeWith(profileId: string, cred: OAuthCredential): AuthProfileStore {
|
||||
return { version: 1, profiles: { [profileId]: cred } };
|
||||
}
|
||||
|
||||
describe("OAuth credential adoption is identity-gated", () => {
|
||||
const envSnapshot = captureEnv([
|
||||
"OPENCLAW_STATE_DIR",
|
||||
"OPENCLAW_AGENT_DIR",
|
||||
"PI_CODING_AGENT_DIR",
|
||||
]);
|
||||
const envSnapshot = captureEnv(OAUTH_AGENT_ENV_KEYS);
|
||||
let tempRoot = "";
|
||||
let caseIndex = 0;
|
||||
let mainAgentDir = "";
|
||||
@@ -183,7 +164,7 @@ describe("OAuth credential adoption is identity-gated", () => {
|
||||
mainAgentDir,
|
||||
);
|
||||
|
||||
const result = await resolveApiKeyForProfileInTest({
|
||||
const result = await resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store: ensureAuthProfileStore(subAgentDir),
|
||||
profileId,
|
||||
agentDir: subAgentDir,
|
||||
@@ -252,7 +233,7 @@ describe("OAuth credential adoption is identity-gated", () => {
|
||||
}) as never,
|
||||
);
|
||||
|
||||
const result = await resolveApiKeyForProfileInTest({
|
||||
const result = await resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store: ensureAuthProfileStore(subAgentDir),
|
||||
profileId,
|
||||
agentDir: subAgentDir,
|
||||
@@ -333,7 +314,7 @@ describe("OAuth credential adoption is identity-gated", () => {
|
||||
});
|
||||
|
||||
await expect(
|
||||
resolveApiKeyForProfileInTest({
|
||||
resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store: ensureAuthProfileStore(subAgentDir),
|
||||
profileId,
|
||||
agentDir: subAgentDir,
|
||||
|
||||
@@ -4,12 +4,17 @@ 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 {
|
||||
OAUTH_AGENT_ENV_KEYS,
|
||||
createExpiredOauthStore,
|
||||
resolveApiKeyForProfileInTest,
|
||||
} from "./oauth-test-utils.js";
|
||||
import {
|
||||
clearRuntimeAuthProfileStoreSnapshots,
|
||||
ensureAuthProfileStore,
|
||||
saveAuthProfileStore,
|
||||
} from "./store.js";
|
||||
import type { AuthProfileStore, OAuthCredential } from "./types.js";
|
||||
import type { OAuthCredential } from "./types.js";
|
||||
|
||||
let resolveApiKeyForProfile: typeof import("./oauth.js").resolveApiKeyForProfile;
|
||||
let resetOAuthRefreshQueuesForTest: typeof import("./oauth.js").resetOAuthRefreshQueuesForTest;
|
||||
@@ -18,12 +23,6 @@ async function loadOAuthModuleForTest() {
|
||||
({ resolveApiKeyForProfile, resetOAuthRefreshQueuesForTest } = await import("./oauth.js"));
|
||||
}
|
||||
|
||||
function resolveApiKeyForProfileInTest(
|
||||
params: Omit<Parameters<typeof resolveApiKeyForProfile>[0], "cfg">,
|
||||
) {
|
||||
return resolveApiKeyForProfile({ cfg: {}, ...params });
|
||||
}
|
||||
|
||||
const {
|
||||
refreshProviderOAuthCredentialWithPluginMock,
|
||||
formatProviderAuthProfileApiKeyWithPluginMock,
|
||||
@@ -80,36 +79,8 @@ vi.mock("./external-cli-sync.js", () => ({
|
||||
existing !== incoming,
|
||||
}));
|
||||
|
||||
function createExpiredOauthStore(params: {
|
||||
profileId: string;
|
||||
provider: string;
|
||||
access?: string;
|
||||
refresh?: string;
|
||||
accountId?: string;
|
||||
email?: string;
|
||||
}): AuthProfileStore {
|
||||
return {
|
||||
version: 1,
|
||||
profiles: {
|
||||
[params.profileId]: {
|
||||
type: "oauth",
|
||||
provider: params.provider,
|
||||
access: params.access ?? "cached-access-token",
|
||||
refresh: params.refresh ?? "refresh-token",
|
||||
expires: Date.now() - 60_000,
|
||||
accountId: params.accountId,
|
||||
email: params.email,
|
||||
} satisfies OAuthCredential,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("resolveApiKeyForProfile cross-agent refresh coordination (#26322)", () => {
|
||||
const envSnapshot = captureEnv([
|
||||
"OPENCLAW_STATE_DIR",
|
||||
"OPENCLAW_AGENT_DIR",
|
||||
"PI_CODING_AGENT_DIR",
|
||||
]);
|
||||
const envSnapshot = captureEnv(OAUTH_AGENT_ENV_KEYS);
|
||||
let tempRoot = "";
|
||||
let mainAgentDir = "";
|
||||
|
||||
@@ -183,7 +154,7 @@ describe("resolveApiKeyForProfile cross-agent refresh coordination (#26322)", ()
|
||||
// performed; the remaining agents adopt the resulting fresh credentials.
|
||||
const results = await Promise.all(
|
||||
subAgents.map((agentDir) =>
|
||||
resolveApiKeyForProfileInTest({
|
||||
resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store: ensureAuthProfileStore(agentDir),
|
||||
profileId,
|
||||
agentDir,
|
||||
|
||||
@@ -5,6 +5,11 @@ 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_AGENT_ENV_KEYS,
|
||||
createExpiredOauthStore,
|
||||
resolveApiKeyForProfileInTest,
|
||||
} from "./oauth-test-utils.js";
|
||||
import { resolveApiKeyForProfile, resetOAuthRefreshQueuesForTest } from "./oauth.js";
|
||||
import {
|
||||
clearRuntimeAuthProfileStoreSnapshots,
|
||||
@@ -13,12 +18,6 @@ import {
|
||||
} from "./store.js";
|
||||
import type { AuthProfileStore, OAuthCredential } from "./types.js";
|
||||
|
||||
function resolveApiKeyForProfileInTest(
|
||||
params: Omit<Parameters<typeof resolveApiKeyForProfile>[0], "cfg">,
|
||||
) {
|
||||
return resolveApiKeyForProfile({ cfg: {}, ...params });
|
||||
}
|
||||
|
||||
const {
|
||||
refreshProviderOAuthCredentialWithPluginMock,
|
||||
formatProviderAuthProfileApiKeyWithPluginMock,
|
||||
@@ -85,36 +84,8 @@ vi.mock("./external-cli-sync.js", () => ({
|
||||
existing !== incoming,
|
||||
}));
|
||||
|
||||
function createExpiredOauthStore(params: {
|
||||
profileId: string;
|
||||
provider: string;
|
||||
access?: string;
|
||||
refresh?: string;
|
||||
accountId?: string;
|
||||
email?: string;
|
||||
}): AuthProfileStore {
|
||||
return {
|
||||
version: 1,
|
||||
profiles: {
|
||||
[params.profileId]: {
|
||||
type: "oauth",
|
||||
provider: params.provider,
|
||||
access: params.access ?? "cached-access-token",
|
||||
refresh: params.refresh ?? "refresh-token",
|
||||
expires: Date.now() - 60_000,
|
||||
accountId: params.accountId,
|
||||
email: params.email,
|
||||
} satisfies OAuthCredential,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("resolveApiKeyForProfile OAuth refresh mirror-to-main (#26322)", () => {
|
||||
const envSnapshot = captureEnv([
|
||||
"OPENCLAW_STATE_DIR",
|
||||
"OPENCLAW_AGENT_DIR",
|
||||
"PI_CODING_AGENT_DIR",
|
||||
]);
|
||||
const envSnapshot = captureEnv(OAUTH_AGENT_ENV_KEYS);
|
||||
let tempRoot = "";
|
||||
let caseIndex = 0;
|
||||
let mainAgentDir = "";
|
||||
@@ -178,7 +149,7 @@ describe("resolveApiKeyForProfile OAuth refresh mirror-to-main (#26322)", () =>
|
||||
}) as never,
|
||||
);
|
||||
|
||||
const result = await resolveApiKeyForProfileInTest({
|
||||
const result = await resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store: ensureAuthProfileStore(subAgentDir),
|
||||
profileId,
|
||||
agentDir: subAgentDir,
|
||||
@@ -222,7 +193,7 @@ describe("resolveApiKeyForProfile OAuth refresh mirror-to-main (#26322)", () =>
|
||||
// Main-agent refresh uses undefined agentDir; the mirror path is a no-op
|
||||
// (local == main). Just make sure the main store still reflects the refresh
|
||||
// and no double-write happens.
|
||||
const result = await resolveApiKeyForProfileInTest({
|
||||
const result = await resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store: ensureAuthProfileStore(undefined),
|
||||
profileId,
|
||||
agentDir: undefined,
|
||||
@@ -274,7 +245,7 @@ describe("resolveApiKeyForProfile OAuth refresh mirror-to-main (#26322)", () =>
|
||||
|
||||
// Refresh mock intentionally left as default-undefined — it should not
|
||||
// be called, the pre-refresh adopt wins.
|
||||
const result = await resolveApiKeyForProfileInTest({
|
||||
const result = await resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store: ensureAuthProfileStore(subAgentDir),
|
||||
profileId,
|
||||
agentDir: subAgentDir,
|
||||
@@ -337,7 +308,7 @@ describe("resolveApiKeyForProfile OAuth refresh mirror-to-main (#26322)", () =>
|
||||
throw new Error("upstream 503 service unavailable");
|
||||
});
|
||||
|
||||
const result = await resolveApiKeyForProfileInTest({
|
||||
const result = await resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store: ensureAuthProfileStore(subAgentDir),
|
||||
profileId,
|
||||
agentDir: subAgentDir,
|
||||
@@ -380,7 +351,7 @@ describe("resolveApiKeyForProfile OAuth refresh mirror-to-main (#26322)", () =>
|
||||
}) as never,
|
||||
);
|
||||
|
||||
const result = await resolveApiKeyForProfileInTest({
|
||||
const result = await resolveApiKeyForProfileInTest(resolveApiKeyForProfile, {
|
||||
store: ensureAuthProfileStore(subAgentDir),
|
||||
profileId,
|
||||
agentDir: subAgentDir,
|
||||
|
||||
@@ -4,6 +4,7 @@ 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 { OAUTH_AGENT_ENV_KEYS, createExpiredOauthStore } from "./oauth-test-utils.js";
|
||||
import {
|
||||
clearRuntimeAuthProfileStoreSnapshots,
|
||||
ensureAuthProfileStore,
|
||||
@@ -77,36 +78,8 @@ async function readPersistedStore(agentDir: string): Promise<AuthProfileStore> {
|
||||
) as AuthProfileStore;
|
||||
}
|
||||
|
||||
function createExpiredOauthStore(params: {
|
||||
profileId: string;
|
||||
provider: string;
|
||||
access?: string;
|
||||
refresh?: string;
|
||||
accountId?: string;
|
||||
email?: string;
|
||||
}): AuthProfileStore {
|
||||
return {
|
||||
version: 1,
|
||||
profiles: {
|
||||
[params.profileId]: {
|
||||
type: "oauth",
|
||||
provider: params.provider,
|
||||
access: params.access ?? "cached-access-token",
|
||||
refresh: params.refresh ?? "refresh-token",
|
||||
expires: Date.now() - 60_000,
|
||||
accountId: params.accountId,
|
||||
email: params.email,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("resolveApiKeyForProfile openai-codex refresh fallback", () => {
|
||||
const envSnapshot = captureEnv([
|
||||
"OPENCLAW_STATE_DIR",
|
||||
"OPENCLAW_AGENT_DIR",
|
||||
"PI_CODING_AGENT_DIR",
|
||||
]);
|
||||
const envSnapshot = captureEnv(OAUTH_AGENT_ENV_KEYS);
|
||||
let tempRoot = "";
|
||||
let agentDir = "";
|
||||
let caseIndex = 0;
|
||||
|
||||
Reference in New Issue
Block a user