@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
22import { promises as fs , existsSync } from "node:fs" ;
33import { basename , dirname , join } from "node:path" ;
44import { tmpdir } from "node:os" ;
5- import {
5+ import {
66 deduplicateAccounts ,
77 deduplicateAccountsByEmail ,
88 normalizeAccountStorage ,
@@ -25,11 +25,6 @@ import {
2525 withFlaggedAccountStorageTransaction ,
2626} from "../lib/storage.js" ;
2727
28- // Mocking the behavior we're about to implement for TDD
29- // Since the functions aren't in lib/storage.ts yet, we'll need to mock them or
30- // accept that this test won't even compile/run until we add them.
31- // But Task 0 says: "Tests should fail initially (RED phase)"
32-
3328describe ( "storage" , ( ) => {
3429 describe ( "getWorkspaceIdentityKey" , ( ) => {
3530 it ( "uses organizationId and accountId when both are present" , ( ) => {
@@ -141,56 +136,43 @@ describe("storage", () => {
141136 } ) ;
142137
143138 it ( "should export accounts to a file" , async ( ) => {
144- // @ts -ignore - exportAccounts doesn't exist yet
145- const { exportAccounts } = await import ( "../lib/storage.js" ) ;
146-
147139 const storage = {
148140 version : 3 ,
149141 activeIndex : 0 ,
150142 accounts : [ { accountId : "test" , refreshToken : "ref" , addedAt : 1 , lastUsed : 2 } ]
151143 } ;
152- // @ts -ignore
153144 await saveAccounts ( storage ) ;
154-
155- // @ts -ignore
145+
156146 await exportAccounts ( exportPath ) ;
157-
147+
158148 expect ( existsSync ( exportPath ) ) . toBe ( true ) ;
159149 const exported = JSON . parse ( await fs . readFile ( exportPath , "utf-8" ) ) ;
160150 expect ( exported . accounts [ 0 ] . accountId ) . toBe ( "test" ) ;
161151 } ) ;
162152
163153 it ( "should fail export if file exists and force is false" , async ( ) => {
164- // @ts -ignore
165- const { exportAccounts } = await import ( "../lib/storage.js" ) ;
166154 await fs . writeFile ( exportPath , "exists" ) ;
167-
168- // @ts -ignore
155+
169156 await expect ( exportAccounts ( exportPath , false ) ) . rejects . toThrow ( / a l r e a d y e x i s t s / ) ;
170157 } ) ;
171158
172159 it ( "should import accounts from a file and merge" , async ( ) => {
173- // @ts -ignore
174- const { importAccounts } = await import ( "../lib/storage.js" ) ;
175-
176160 const existing = {
177161 version : 3 ,
178162 activeIndex : 0 ,
179163 accounts : [ { accountId : "existing" , refreshToken : "ref1" , addedAt : 1 , lastUsed : 2 } ]
180164 } ;
181- // @ts -ignore
182165 await saveAccounts ( existing ) ;
183-
166+
184167 const toImport = {
185168 version : 3 ,
186169 activeIndex : 0 ,
187170 accounts : [ { accountId : "new" , refreshToken : "ref2" , addedAt : 3 , lastUsed : 4 } ]
188171 } ;
189172 await fs . writeFile ( exportPath , JSON . stringify ( toImport ) ) ;
190-
191- // @ts -ignore
173+
192174 await importAccounts ( exportPath ) ;
193-
175+
194176 const loaded = await loadAccounts ( ) ;
195177 expect ( loaded ?. accounts ) . toHaveLength ( 2 ) ;
196178 expect ( loaded ?. accounts . map ( a => a . accountId ) ) . toContain ( "new" ) ;
@@ -222,6 +204,32 @@ describe("storage", () => {
222204 expect ( loaded ?. accounts [ 0 ] ?. accountId ) . toBe ( "existing" ) ;
223205 } ) ;
224206
207+ it ( "keeps preview and apply counts aligned for the same import fixture" , async ( ) => {
208+ await saveAccounts ( {
209+ version : 3 ,
210+ activeIndex : 0 ,
211+ accounts : [ { accountId : "existing" , refreshToken : "ref1" , addedAt : 1 , lastUsed : 2 } ] ,
212+ } ) ;
213+
214+ await fs . writeFile (
215+ exportPath ,
216+ JSON . stringify ( {
217+ version : 3 ,
218+ activeIndex : 0 ,
219+ accounts : [ { accountId : "preview" , refreshToken : "ref2" , addedAt : 3 , lastUsed : 4 } ] ,
220+ } ) ,
221+ ) ;
222+
223+ const preview = await previewImportAccounts ( exportPath ) ;
224+ const applied = await importAccounts ( exportPath ) ;
225+
226+ expect ( preview ) . toMatchObject ( {
227+ imported : applied . imported ,
228+ skipped : applied . skipped ,
229+ total : applied . total ,
230+ } ) ;
231+ } ) ;
232+
225233 it ( "creates timestamped backup paths in storage backups directory" , ( ) => {
226234 const path = createTimestampedBackupPath ( ) ;
227235 const expectedBackupDir = join ( dirname ( testStoragePath ) , "backups" ) ;
@@ -625,9 +633,6 @@ describe("storage", () => {
625633 } ) ;
626634
627635 it ( "should enforce MAX_ACCOUNTS during import" , async ( ) => {
628- // @ts -ignore
629- const { importAccounts } = await import ( "../lib/storage.js" ) ;
630-
631636 const manyAccounts = Array . from ( { length : 21 } , ( _ , i ) => ( {
632637 accountId : `acct${ i } ` ,
633638 refreshToken : `ref${ i } ` ,
@@ -641,31 +646,26 @@ describe("storage", () => {
641646 accounts : manyAccounts
642647 } ;
643648 await fs . writeFile ( exportPath , JSON . stringify ( toImport ) ) ;
644-
645- // @ts -ignore
649+
646650 await expect ( importAccounts ( exportPath ) ) . rejects . toThrow ( / e x c e e d m a x i m u m / ) ;
647651 } ) ;
648652
649653 it ( "should fail export when no accounts exist" , async ( ) => {
650- const { exportAccounts } = await import ( "../lib/storage.js" ) ;
651654 setStoragePathDirect ( testStoragePath ) ;
652655 await expect ( exportAccounts ( exportPath ) ) . rejects . toThrow ( / N o a c c o u n t s t o e x p o r t / ) ;
653656 } ) ;
654657
655658 it ( "should fail import when file does not exist" , async ( ) => {
656- const { importAccounts } = await import ( "../lib/storage.js" ) ;
657659 const nonexistentPath = join ( testWorkDir , "nonexistent-file.json" ) ;
658660 await expect ( importAccounts ( nonexistentPath ) ) . rejects . toThrow ( / I m p o r t f i l e n o t f o u n d / ) ;
659661 } ) ;
660662
661663 it ( "should fail import when file contains invalid JSON" , async ( ) => {
662- const { importAccounts } = await import ( "../lib/storage.js" ) ;
663664 await fs . writeFile ( exportPath , "not valid json {[" ) ;
664665 await expect ( importAccounts ( exportPath ) ) . rejects . toThrow ( / I n v a l i d J S O N / ) ;
665666 } ) ;
666667
667668 it ( "should fail import when file contains invalid format" , async ( ) => {
668- const { importAccounts } = await import ( "../lib/storage.js" ) ;
669669 await fs . writeFile ( exportPath , JSON . stringify ( { invalid : "format" } ) ) ;
670670 await expect ( importAccounts ( exportPath ) ) . rejects . toThrow ( / I n v a l i d a c c o u n t s t o r a g e f o r m a t / ) ;
671671 } ) ;
@@ -756,7 +756,7 @@ describe("storage", () => {
756756 preImportBackupPrefix : "codex-pre-import-backup" ,
757757 backupMode : "required" ,
758758 } ) ,
759- ) . rejects . toThrow ( / P r e - i m p o r t b a c k u p f a i l e d : T i m e d o u t w r i t i n g f i l e / ) ;
759+ ) . rejects . toThrow ( " Pre-import backup failed" ) ;
760760 } finally {
761761 writeSpy . mockRestore ( ) ;
762762 }
0 commit comments