diff --git a/lib/private/Files/Utils/Scanner.php b/lib/private/Files/Utils/Scanner.php index 2831e4f4d8299..718877f00a12f 100644 --- a/lib/private/Files/Utils/Scanner.php +++ b/lib/private/Files/Utils/Scanner.php @@ -208,7 +208,7 @@ public function scan(string $dir = '', $recursive = \OC\Files\Cache\Scanner::SCA }); $scanner->listen('\OC\Files\Cache\Scanner', 'addToCache', function ($path, $storageId, $data, $fileId) use ($storage): void { $this->triggerPropagator($storage, $path); - if ($fileId) { + if ($fileId !== -1) { $this->eventDispatcher->dispatchTyped(new FileCacheUpdated($storage, $path)); } else { $this->eventDispatcher->dispatchTyped(new NodeAddedToCache($storage, $path)); diff --git a/tests/lib/Files/Utils/ScannerTest.php b/tests/lib/Files/Utils/ScannerTest.php index 435e7b38ee908..643d3d37e87cf 100644 --- a/tests/lib/Files/Utils/ScannerTest.php +++ b/tests/lib/Files/Utils/ScannerTest.php @@ -17,6 +17,8 @@ use OC\Files\Utils\Scanner; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Config\IMountProvider; +use OCP\Files\Events\FileCacheUpdated; +use OCP\Files\Events\NodeAddedToCache; use OCP\Files\Config\IMountProviderCollection; use OCP\Files\Storage\IStorageFactory; use OCP\IDBConnection; @@ -209,6 +211,53 @@ public function testPropagateEtag(): void { $this->assertNotEquals($oldRoot->getEtag(), $newRoot->getEtag()); } + public function testScanDispatchesAddedForNewAndUpdatedForChangedEntries(): void { + $storage = new Temporary([]); + $mount = new MountPoint($storage, ''); + Filesystem::getMountManager()->addMount($mount); + + $storage->mkdir('folder'); + $storage->file_put_contents('folder/bar.txt', 'qwerty'); + $storage->touch('folder/bar.txt', time() - 200); + + /** @var list $events */ + $events = []; + $dispatcher = $this->createMock(IEventDispatcher::class); + $dispatcher->method('dispatchTyped') + ->willReturnCallback(function (object $event) use (&$events): void { + $events[] = $event; + }); + + $scanner = new TestScanner( + Server::get(IUserManager::class)->get(''), + Server::get(IDBConnection::class), + $dispatcher, + Server::get(LoggerInterface::class), + Server::get(SetupManager::class), + ); + $scanner->addMount($mount); + + $pathsForEvents = function (string $class) use (&$events): array { + return array_values(array_map( + static fn (object $event): string => $event->getPath(), + array_filter($events, static fn (object $event): bool => $event instanceof $class), + )); + }; + + // first scan: everything is new, nothing is updated + $scanner->scan(''); + $this->assertContains('folder/bar.txt', $pathsForEvents(NodeAddedToCache::class)); + $this->assertContains('folder', $pathsForEvents(NodeAddedToCache::class)); + $this->assertSame([], $pathsForEvents(FileCacheUpdated::class)); + + // re-scan after modifying the file: updated, not new + $events = []; + $storage->file_put_contents('folder/bar.txt', 'qwerty asdf'); + $scanner->scan(''); + $this->assertContains('folder/bar.txt', $pathsForEvents(FileCacheUpdated::class)); + $this->assertSame([], $pathsForEvents(NodeAddedToCache::class)); + } + public function testShallow(): void { $storage = new Temporary([]); $mount = new MountPoint($storage, '');