11import { beforeEach , describe , expect , it , vi } from "vitest" ;
22import { 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+
414vi . 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" ;
2636import { syncAccountStorageFromCodexCli } from "../lib/codex-cli/sync.js" ;
2737import { loadCodexCliState } from "../lib/codex-cli/state.js" ;
2838import { setCodexCliActiveSelection } from "../lib/codex-cli/writer.js" ;
2939
3040describe ( "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