@@ -256,6 +256,48 @@ public function testMoveCrossStorage(): void {
256256 $ this ->assertEquals ($ cached ['fileid ' ], $ cachedTarget ['fileid ' ]);
257257 }
258258
259+ public function testMoveCrossStorageMissingTargetParent (): void {
260+ $ storage2 = new Temporary ([]);
261+ $ cache2 = $ storage2 ->getCache ();
262+ Filesystem::mount ($ storage2 , [], '/bar ' );
263+ $ this ->storage ->file_put_contents ('foo.txt ' , 'qwerty ' );
264+ $ this ->updater ->update ('foo.txt ' );
265+ $ cached = $ this ->cache ->get ('foo.txt ' );
266+
267+ // the target parent exists on disk but is missing from the cache
268+ $ storage2 ->mkdir ('sub ' );
269+ $ this ->assertFalse ($ cache2 ->inCache ('sub ' ));
270+
271+ $ storage2 ->moveFromStorage ($ this ->storage , 'foo.txt ' , 'sub/bar.txt ' );
272+ $ storage2 ->getUpdater ()->renameFromStorage ($ this ->storage , 'foo.txt ' , 'sub/bar.txt ' );
273+
274+ $ this ->assertFalse ($ this ->cache ->inCache ('foo.txt ' ));
275+ $ this ->assertTrue ($ cache2 ->inCache ('sub ' ));
276+ $ this ->assertTrue ($ cache2 ->inCache ('sub/bar.txt ' ));
277+
278+ // the moved entry is attached to the scanned parent instead of being orphaned
279+ $ cachedTarget = $ cache2 ->get ('sub/bar.txt ' );
280+ $ this ->assertEquals ($ cache2 ->getId ('sub ' ), $ cachedTarget ['parent ' ]);
281+ $ this ->assertEquals ($ cached ['fileid ' ], $ cachedTarget ['fileid ' ]);
282+ }
283+
284+ public function testMoveCrossStorageSourceNotInCache (): void {
285+ $ storage2 = new Temporary ([]);
286+ $ cache2 = $ storage2 ->getCache ();
287+ Filesystem::mount ($ storage2 , [], '/bar ' );
288+ $ this ->storage ->file_put_contents ('foo.txt ' , 'qwerty ' );
289+ // the source was never scanned into the cache
290+ $ this ->assertFalse ($ this ->cache ->inCache ('foo.txt ' ));
291+
292+ $ storage2 ->moveFromStorage ($ this ->storage , 'foo.txt ' , 'bar.txt ' );
293+ $ storage2 ->getUpdater ()->renameFromStorage ($ this ->storage , 'foo.txt ' , 'bar.txt ' );
294+
295+ // the target still gets a cache entry
296+ $ this ->assertTrue ($ cache2 ->inCache ('bar.txt ' ));
297+ $ cachedTarget = $ cache2 ->get ('bar.txt ' );
298+ $ this ->assertEquals (6 , $ cachedTarget ['size ' ]);
299+ }
300+
259301 public function testMoveFolderCrossStorage (): void {
260302 $ storage2 = new Temporary ([]);
261303 $ cache2 = $ storage2 ->getCache ();
0 commit comments