
























@@ -93,6 +93,25 @@ function resolveOpenAICodexProfile(params: { profileId: string; agentDir: string
9393});
9494}
959596+function requireOAuthProfile(store: AuthProfileStore, profileId: string): OAuthCredential {
97+const profile = store.profiles[profileId];
98+expect(profile?.type).toBe("oauth");
99+if (!profile || profile.type !== "oauth") {
100+throw new Error(`expected OAuth profile ${profileId}`);
101+}
102+return profile;
103+}
104+105+function requireOAuthContext(context: unknown): OAuthCredential {
106+expect(context && typeof context === "object").toBe(true);
107+if (!context || typeof context !== "object") {
108+throw new Error("expected OAuth credential context");
109+}
110+const credential = context as OAuthCredential;
111+expect(credential.type).toBe("oauth");
112+return credential;
113+}
114+96115describe("resolveApiKeyForProfile openai-codex refresh fallback", () => {
97116const envSnapshot = captureEnv(OAUTH_AGENT_ENV_KEYS);
98117let tempRoot = "";
@@ -214,13 +233,11 @@ describe("resolveApiKeyForProfile openai-codex refresh fallback", () => {
214233});
215234216235const persisted = await readPersistedStore(agentDir);
217-expect(persisted.profiles[profileId]).toMatchObject({
218-type: "oauth",
219-provider: "openai-codex",
220-access: "rotated-access-token",
221-refresh: "rotated-refresh-token",
222-accountId: "acct-rotated",
223-});
236+const profile = requireOAuthProfile(persisted, profileId);
237+expect(profile.provider).toBe("openai-codex");
238+expect(profile.access).toBe("rotated-access-token");
239+expect(profile.refresh).toBe("rotated-refresh-token");
240+expect(profile.accountId).toBe("acct-rotated");
224241});
225242226243it("refreshes imported Codex credentials into the canonical auth store without writing back to .codex", async () => {
@@ -269,19 +286,12 @@ describe("resolveApiKeyForProfile openai-codex refresh fallback", () => {
269286email: undefined,
270287});
271288const persisted = await readPersistedStore(agentDir);
272-expect(persisted.profiles[profileId]).toMatchObject({
273-type: "oauth",
274-provider: "openai-codex",
275-access: "rotated-cli-access-token",
276-refresh: "rotated-cli-refresh-token",
277-accountId: "acct-rotated",
278-});
279-expect(persisted.profiles[profileId]).not.toEqual(
280-expect.objectContaining({
281-provider: "openai-codex",
282-access: "expired-access-token",
283-}),
284-);
289+const profile = requireOAuthProfile(persisted, profileId);
290+expect(profile.provider).toBe("openai-codex");
291+expect(profile.access).toBe("rotated-cli-access-token");
292+expect(profile.refresh).toBe("rotated-cli-refresh-token");
293+expect(profile.accountId).toBe("acct-rotated");
294+expect(profile.access).not.toBe("expired-access-token");
285295});
286296287297it("ignores mismatched fresh Codex CLI credentials when canonical local auth is bound to another account", async () => {
@@ -306,11 +316,10 @@ describe("resolveApiKeyForProfile openai-codex refresh fallback", () => {
306316});
307317refreshProviderOAuthCredentialWithPluginMock.mockImplementationOnce(
308318async (params?: { context?: unknown }) => {
309-expect(params?.context).toMatchObject({
310-access: "expired-local-access-token",
311-refresh: "local-refresh-token",
312-accountId: "acct-local",
313-});
319+const context = requireOAuthContext(params?.context);
320+expect(context.access).toBe("expired-local-access-token");
321+expect(context.refresh).toBe("local-refresh-token");
322+expect(context.accountId).toBe("acct-local");
314323return {
315324type: "oauth",
316325provider: "openai-codex",
@@ -335,18 +344,13 @@ describe("resolveApiKeyForProfile openai-codex refresh fallback", () => {
335344});
336345337346const persisted = await readPersistedStore(agentDir);
338-expect(persisted.profiles[profileId]).toMatchObject({
339-access: "fresh-local-access-token",
340-refresh: "fresh-local-refresh-token",
341-accountId: "acct-local",
342-});
343-expect(persisted.profiles[profileId]).not.toEqual(
344-expect.objectContaining({
345-access: "fresh-cli-access-token",
346-refresh: "fresh-cli-refresh-token",
347-accountId: "acct-external",
348-}),
349-);
347+const profile = requireOAuthProfile(persisted, profileId);
348+expect(profile.access).toBe("fresh-local-access-token");
349+expect(profile.refresh).toBe("fresh-local-refresh-token");
350+expect(profile.accountId).toBe("acct-local");
351+expect(profile.access).not.toBe("fresh-cli-access-token");
352+expect(profile.refresh).not.toBe("fresh-cli-refresh-token");
353+expect(profile.accountId).not.toBe("acct-external");
350354});
351355352356it("keeps the canonical refresh token when imported Codex CLI state is expired", async () => {
@@ -376,10 +380,9 @@ describe("resolveApiKeyForProfile openai-codex refresh fallback", () => {
376380});
377381refreshProviderOAuthCredentialWithPluginMock.mockImplementationOnce(
378382async (params?: { context?: unknown }) => {
379-expect(params?.context).toMatchObject({
380-access: "expired-local-access-token",
381-refresh: "stale-local-refresh-token",
382-});
383+const context = requireOAuthContext(params?.context);
384+expect(context.access).toBe("expired-local-access-token");
385+expect(context.refresh).toBe("stale-local-refresh-token");
383386return {
384387type: "oauth",
385388provider: "openai-codex",
@@ -403,15 +406,10 @@ describe("resolveApiKeyForProfile openai-codex refresh fallback", () => {
403406});
404407405408const persisted = await readPersistedStore(agentDir);
406-expect(persisted.profiles[profileId]).toMatchObject({
407-access: "fresh-access-token",
408-refresh: "fresh-refresh-token",
409-});
410-expect(persisted.profiles[profileId]).not.toEqual(
411-expect.objectContaining({
412-refresh: "fresh-cli-refresh-token",
413-}),
414-);
409+const profile = requireOAuthProfile(persisted, profileId);
410+expect(profile.access).toBe("fresh-access-token");
411+expect(profile.refresh).toBe("fresh-refresh-token");
412+expect(profile.refresh).not.toBe("fresh-cli-refresh-token");
415413});
416414417415it("adopts fresher stored credentials after refresh_token_reused", async () => {
@@ -516,10 +514,9 @@ describe("resolveApiKeyForProfile openai-codex refresh fallback", () => {
516514517515expect(getOAuthApiKeyMock).toHaveBeenCalledTimes(2);
518516const persisted = await readPersistedStore(agentDir);
519-expect(persisted.profiles[profileId]).toMatchObject({
520-access: "retried-access-token",
521-refresh: "retried-refresh-token",
522-});
517+const profile = requireOAuthProfile(persisted, profileId);
518+expect(profile.access).toBe("retried-access-token");
519+expect(profile.refresh).toBe("retried-refresh-token");
523520});
524521525522it("keeps throwing for non-codex providers on the same refresh error", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。