@@ -82,6 +82,85 @@ describe("GoogleDriveFileSystem", () => {
8282 expect ( requestSpy ) . toHaveBeenCalledTimes ( 1 ) ;
8383 } ) ;
8484
85+ it ( "writer should clear stale path cache and retry once on provider 404" , async ( ) => {
86+ const fs = new GoogleDriveFileSystem ( "/" , "token" ) ;
87+ const notFoundError = new FileSystemError ( {
88+ provider : "googledrive" ,
89+ message : "Parent not found" ,
90+ status : 404 ,
91+ notFound : true ,
92+ } ) ;
93+ const findFolderSpy = vi
94+ . spyOn ( fs , "findFolderByName" )
95+ . mockResolvedValueOnce ( { id : "stale-base-id" , name : "Base" } )
96+ . mockResolvedValueOnce ( { id : "fresh-base-id" , name : "Base" } ) ;
97+
98+ await fs . ensureDirExists ( "/Base" ) ;
99+
100+ const writer = await fs . create ( "Base/file.txt" ) ;
101+ const findFileSpy = vi
102+ . spyOn ( fs , "findFileInDirectory" )
103+ . mockRejectedValueOnce ( notFoundError )
104+ . mockResolvedValueOnce ( null ) ;
105+ const requestSpy = vi . spyOn ( fs , "request" ) . mockResolvedValue ( { } ) ;
106+
107+ await expect ( writer . write ( "content" ) ) . resolves . toBeUndefined ( ) ;
108+
109+ expect ( findFolderSpy . mock . calls ) . toEqual ( [
110+ [ "Base" , "appDataFolder" ] ,
111+ [ "Base" , "appDataFolder" ] ,
112+ ] ) ;
113+ expect ( findFileSpy . mock . calls ) . toEqual ( [
114+ [ "file.txt" , "stale-base-id" ] ,
115+ [ "file.txt" , "fresh-base-id" ] ,
116+ ] ) ;
117+ expect ( requestSpy ) . toHaveBeenCalledTimes ( 1 ) ;
118+ } ) ;
119+
120+ it ( "writer should not retry non-404 provider errors" , async ( ) => {
121+ const fs = new GoogleDriveFileSystem ( "/" , "token" ) ;
122+ const conflictError = new FileSystemError ( {
123+ provider : "googledrive" ,
124+ message : "Conflict" ,
125+ status : 409 ,
126+ conflict : true ,
127+ } ) ;
128+ const writer = await fs . create ( "Base/file.txt" ) ;
129+ const ensureSpy = vi . spyOn ( fs , "ensureDirExists" ) . mockResolvedValue ( "base-id" ) ;
130+ const findFileSpy = vi . spyOn ( fs , "findFileInDirectory" ) . mockRejectedValue ( conflictError ) ;
131+
132+ await expect ( writer . write ( "content" ) ) . rejects . toBe ( conflictError ) ;
133+
134+ expect ( ensureSpy ) . toHaveBeenCalledTimes ( 1 ) ;
135+ expect ( findFileSpy ) . toHaveBeenCalledTimes ( 1 ) ;
136+ } ) ;
137+
138+ it ( "list should clear stale path cache and retry once on provider 404" , async ( ) => {
139+ const fs = new GoogleDriveFileSystem ( "/Base" , "token" ) ;
140+ const notFoundError = new FileSystemError ( {
141+ provider : "googledrive" ,
142+ message : "Folder not found" ,
143+ status : 404 ,
144+ notFound : true ,
145+ } ) ;
146+ const findFolderSpy = vi . spyOn ( fs , "findFolderByName" ) . mockResolvedValueOnce ( { id : "stale-base-id" , name : "Base" } ) ;
147+
148+ await fs . ensureDirExists ( "/Base" ) ;
149+
150+ const requestSpy = vi
151+ . spyOn ( fs , "request" )
152+ . mockRejectedValueOnce ( notFoundError )
153+ . mockResolvedValueOnce ( { files : [ { id : "fresh-base-id" , name : "Base" } ] } )
154+ . mockResolvedValueOnce ( { files : [ ] } ) ;
155+
156+ await expect ( fs . list ( ) ) . resolves . toEqual ( [ ] ) ;
157+
158+ expect ( findFolderSpy ) . toHaveBeenCalledTimes ( 1 ) ;
159+ expect ( String ( requestSpy . mock . calls [ 0 ] [ 0 ] ) ) . toContain ( "stale-base-id" ) ;
160+ expect ( String ( requestSpy . mock . calls [ 1 ] [ 0 ] ) ) . toContain ( "name%3D'Base'" ) ;
161+ expect ( String ( requestSpy . mock . calls [ 2 ] [ 0 ] ) ) . toContain ( "fresh-base-id" ) ;
162+ } ) ;
163+
85164 it ( "request should return retry result after token refresh" , async ( ) => {
86165 await localStorageDAO . saveValue ( "netdisk:token:googledrive" , {
87166 accessToken : "expired-token" ,
0 commit comments