Skip to content

Commit 412b379

Browse files
committed
test-align-transactional-account-persistence-mocks
1 parent fe99c82 commit 412b379

2 files changed

Lines changed: 34 additions & 12 deletions

File tree

test/accounts-edge.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { OAuthAuthDetails } from "../lib/types.js";
33

44
const mockLoadAccounts = vi.fn();
55
const mockSaveAccounts = vi.fn();
6+
const mockWithAccountStorageTransaction = vi.fn();
67
const mockLoadCodexCliState = vi.fn();
78
const mockSyncAccountStorageFromCodexCli = vi.fn();
89
const mockSetCodexCliActiveSelection = vi.fn();
@@ -14,6 +15,7 @@ vi.mock("../lib/storage.js", async (importOriginal) => {
1415
...actual,
1516
loadAccounts: mockLoadAccounts,
1617
saveAccounts: mockSaveAccounts,
18+
withAccountStorageTransaction: mockWithAccountStorageTransaction,
1719
};
1820
});
1921

@@ -81,6 +83,11 @@ describe("accounts edge branches", () => {
8183
vi.clearAllMocks();
8284
mockLoadAccounts.mockResolvedValue(null);
8385
mockSaveAccounts.mockResolvedValue(undefined);
86+
mockWithAccountStorageTransaction.mockImplementation(async (handler) =>
87+
handler(null, async (storage) => {
88+
await mockSaveAccounts(storage);
89+
}),
90+
);
8491
mockLoadCodexCliState.mockResolvedValue(null);
8592
mockSyncAccountStorageFromCodexCli.mockImplementation(async (storage) => ({
8693
storage,

test/accounts-load-from-disk.test.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
import { beforeEach, describe, expect, it, vi } from "vitest";
22
import { AccountManager } from "../lib/accounts.js";
33

4+
const {
5+
mockLoadAccounts,
6+
mockSaveAccounts,
7+
mockWithAccountStorageTransaction,
8+
} = vi.hoisted(() => ({
9+
mockLoadAccounts: vi.fn(),
10+
mockSaveAccounts: vi.fn(),
11+
mockWithAccountStorageTransaction: vi.fn(),
12+
}));
13+
414
vi.mock("../lib/storage.js", async (importOriginal) => {
515
const actual = await importOriginal<typeof import("../lib/storage.js")>();
616
return {
717
...actual,
8-
loadAccounts: vi.fn(),
9-
saveAccounts: vi.fn().mockResolvedValue(undefined),
18+
loadAccounts: mockLoadAccounts,
19+
saveAccounts: mockSaveAccounts,
20+
withAccountStorageTransaction: mockWithAccountStorageTransaction,
1021
};
1122
});
1223

@@ -22,16 +33,20 @@ vi.mock("../lib/codex-cli/writer.js", () => ({
2233
setCodexCliActiveSelection: vi.fn().mockResolvedValue(undefined),
2334
}));
2435

25-
import { loadAccounts, saveAccounts } from "../lib/storage.js";
2636
import { syncAccountStorageFromCodexCli } from "../lib/codex-cli/sync.js";
2737
import { loadCodexCliState } from "../lib/codex-cli/state.js";
2838
import { setCodexCliActiveSelection } from "../lib/codex-cli/writer.js";
2939

3040
describe("AccountManager loadFromDisk", () => {
3141
beforeEach(() => {
3242
vi.clearAllMocks();
33-
vi.mocked(loadAccounts).mockResolvedValue(null);
34-
vi.mocked(saveAccounts).mockResolvedValue(undefined);
43+
mockLoadAccounts.mockResolvedValue(null);
44+
mockSaveAccounts.mockResolvedValue(undefined);
45+
mockWithAccountStorageTransaction.mockImplementation(async (handler) =>
46+
handler(null, async (storage) => {
47+
await mockSaveAccounts(storage);
48+
}),
49+
);
3550
vi.mocked(syncAccountStorageFromCodexCli).mockResolvedValue({
3651
changed: false,
3752
storage: null,
@@ -56,15 +71,15 @@ describe("AccountManager loadFromDisk", () => {
5671
],
5772
};
5873

59-
vi.mocked(loadAccounts).mockResolvedValue(stored);
74+
mockLoadAccounts.mockResolvedValue(stored);
6075
vi.mocked(syncAccountStorageFromCodexCli).mockResolvedValue({
6176
changed: true,
6277
storage: synced,
6378
});
6479

6580
const manager = await AccountManager.loadFromDisk();
6681

67-
expect(saveAccounts).toHaveBeenCalledWith(synced);
82+
expect(mockSaveAccounts).toHaveBeenCalledWith(synced);
6883
expect(manager.getAccountCount()).toBe(2);
6984
expect(manager.getCurrentAccount()?.refreshToken).toBe("stored-refresh");
7085
});
@@ -81,7 +96,7 @@ describe("AccountManager loadFromDisk", () => {
8196
changed: true,
8297
storage: synced,
8398
});
84-
vi.mocked(saveAccounts).mockRejectedValueOnce(new Error("forced persist failure"));
99+
mockSaveAccounts.mockRejectedValueOnce(new Error("forced persist failure"));
85100

86101
const manager = await AccountManager.loadFromDisk();
87102

@@ -91,7 +106,7 @@ describe("AccountManager loadFromDisk", () => {
91106

92107
it("hydrates missing access/accountId fields from Codex CLI token cache", async () => {
93108
const now = Date.now();
94-
vi.mocked(loadAccounts).mockResolvedValue({
109+
mockLoadAccounts.mockResolvedValue({
95110
version: 3 as const,
96111
activeIndex: 0,
97112
accounts: [
@@ -122,12 +137,12 @@ describe("AccountManager loadFromDisk", () => {
122137
expect(account?.expires).toBe(now + 120_000);
123138
expect(account?.accountId).toBe("acct-123");
124139
expect(account?.accountIdSource).toBe("token");
125-
expect(saveAccounts).toHaveBeenCalledTimes(1);
140+
expect(mockSaveAccounts).toHaveBeenCalledTimes(1);
126141
});
127142

128143
it("skips expired Codex CLI cache entries and does not persist", async () => {
129144
const now = Date.now();
130-
vi.mocked(loadAccounts).mockResolvedValue({
145+
mockLoadAccounts.mockResolvedValue({
131146
version: 3 as const,
132147
activeIndex: 0,
133148
accounts: [
@@ -156,7 +171,7 @@ describe("AccountManager loadFromDisk", () => {
156171

157172
expect(account?.access).toBeUndefined();
158173
expect(account?.accountId).toBeUndefined();
159-
expect(saveAccounts).not.toHaveBeenCalled();
174+
expect(mockSaveAccounts).not.toHaveBeenCalled();
160175
});
161176

162177
it("syncCodexCliActiveSelectionForIndex ignores invalid indices and syncs a valid one", async () => {

0 commit comments

Comments
 (0)