|
1 | 1 | import { describe, expect, it, beforeEach, afterEach, vi } from "vitest"; |
2 | | -import type { AccountManager, ManagedAccount, OAuthAuthDetails } from "../lib/accounts.js"; |
| 2 | +import type { AccountManager, ManagedAccount } from "../lib/accounts.js"; |
3 | 3 | import { |
4 | 4 | extractAccountEmail, |
5 | 5 | extractAccountId, |
6 | 6 | sanitizeEmail, |
7 | 7 | } from "../lib/auth/token-utils.js"; |
| 8 | +import { CodexAuthError } from "../lib/errors.js"; |
8 | 9 | import { findMatchingAccountIndex } from "../lib/storage.js"; |
| 10 | +import type { OAuthAuthDetails } from "../lib/types.js"; |
9 | 11 |
|
10 | 12 | const refreshExpiringAccountsMock = vi.fn(); |
11 | 13 | const applyRefreshResultMock = vi.fn(); |
@@ -872,4 +874,48 @@ describe("refresh-guardian", () => { |
872 | 874 | expect(stats.networkFailed).toBe(1); |
873 | 875 | expect(stats.rateLimited).toBe(1); |
874 | 876 | }); |
| 877 | + |
| 878 | + it("treats non-retryable commit failures as auth cooldowns", async () => { |
| 879 | + const accountA = createManagedAccount(0); |
| 880 | + const manager = createManagerMock([accountA]); |
| 881 | + const commitRefreshedAuthMock = manager |
| 882 | + .commitRefreshedAuth as ReturnType<typeof vi.fn>; |
| 883 | + commitRefreshedAuthMock.mockRejectedValueOnce( |
| 884 | + new CodexAuthError("refresh persistence failed", { retryable: false }), |
| 885 | + ); |
| 886 | + |
| 887 | + const { RefreshGuardian } = await import("../lib/refresh-guardian.js"); |
| 888 | + const guardian = new RefreshGuardian(() => manager, { |
| 889 | + bufferMs: 60_000, |
| 890 | + intervalMs: 5_000, |
| 891 | + }); |
| 892 | + |
| 893 | + refreshExpiringAccountsMock.mockResolvedValue( |
| 894 | + new Map([ |
| 895 | + [ |
| 896 | + 0, |
| 897 | + { |
| 898 | + refreshed: true, |
| 899 | + reason: "success", |
| 900 | + tokenResult: { |
| 901 | + type: "success", |
| 902 | + access: "access-0", |
| 903 | + refresh: "refresh-0-new", |
| 904 | + expires: Date.now() + 3_600_000, |
| 905 | + }, |
| 906 | + }, |
| 907 | + ], |
| 908 | + ]), |
| 909 | + ); |
| 910 | + |
| 911 | + await guardian.tick(); |
| 912 | + |
| 913 | + expect( |
| 914 | + manager.markAccountCoolingDown as ReturnType<typeof vi.fn>, |
| 915 | + ).toHaveBeenCalledWith(accountA, 60_000, "auth-failure"); |
| 916 | + const stats = guardian.getStats(); |
| 917 | + expect(stats.failed).toBe(1); |
| 918 | + expect(stats.authFailed).toBe(1); |
| 919 | + expect(stats.networkFailed).toBe(0); |
| 920 | + }); |
875 | 921 | }); |
0 commit comments