FolderTest.php 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  1. <?php
  2. /**
  3. * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace Test\Files\Node;
  9. use OC\Files\Cache\Cache;
  10. use OC\Files\Cache\CacheEntry;
  11. use OC\Files\Config\CachedMountInfo;
  12. use OC\Files\FileInfo;
  13. use OC\Files\Mount\Manager;
  14. use OC\Files\Mount\MountPoint;
  15. use OC\Files\Node\File;
  16. use OC\Files\Node\Folder;
  17. use OC\Files\Node\Node;
  18. use OC\Files\Node\Root;
  19. use OC\Files\Search\SearchBinaryOperator;
  20. use OC\Files\Search\SearchComparison;
  21. use OC\Files\Search\SearchOrder;
  22. use OC\Files\Search\SearchQuery;
  23. use OC\Files\Storage\Temporary;
  24. use OC\Files\Storage\Wrapper\Jail;
  25. use OCP\Files\Cache\ICacheEntry;
  26. use OCP\Files\IRootFolder;
  27. use OCP\Files\Mount\IMountPoint;
  28. use OCP\Files\NotFoundException;
  29. use OCP\Files\Search\ISearchBinaryOperator;
  30. use OCP\Files\Search\ISearchComparison;
  31. use OCP\Files\Search\ISearchOrder;
  32. use OCP\Files\Storage;
  33. use PHPUnit\Framework\MockObject\MockObject;
  34. /**
  35. * Class FolderTest
  36. *
  37. * @group DB
  38. *
  39. * @package Test\Files\Node
  40. */
  41. class FolderTest extends NodeTest {
  42. protected function createTestNode($root, $view, $path, array $data = [], $internalPath = '', $storage = null) {
  43. $view->expects($this->any())
  44. ->method('getRoot')
  45. ->willReturn('');
  46. if ($data || $internalPath || $storage) {
  47. return new Folder($root, $view, $path, $this->getFileInfo($data, $internalPath, $storage));
  48. } else {
  49. return new Folder($root, $view, $path);
  50. }
  51. }
  52. protected function getNodeClass() {
  53. return '\OC\Files\Node\Folder';
  54. }
  55. protected function getNonExistingNodeClass() {
  56. return '\OC\Files\Node\NonExistingFolder';
  57. }
  58. protected function getViewDeleteMethod() {
  59. return 'rmdir';
  60. }
  61. public function testGetDirectoryContent() {
  62. $manager = $this->createMock(Manager::class);
  63. /**
  64. * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view
  65. */
  66. $root = $this->getMockBuilder(Root::class)
  67. ->setConstructorArgs([$manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  68. ->getMock();
  69. $root->expects($this->any())
  70. ->method('getUser')
  71. ->willReturn($this->user);
  72. $this->view->expects($this->any())
  73. ->method('getDirectoryContent')
  74. ->with('/bar/foo')
  75. ->willReturn([
  76. new FileInfo('/bar/foo/asd', null, 'foo/asd', ['fileid' => 2, 'path' => '/bar/foo/asd', 'name' => 'asd', 'size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain'], null),
  77. new FileInfo('/bar/foo/qwerty', null, 'foo/qwerty', ['fileid' => 3, 'path' => '/bar/foo/qwerty', 'name' => 'qwerty', 'size' => 200, 'mtime' => 55, 'mimetype' => 'httpd/unix-directory'], null),
  78. ]);
  79. $this->view->method('getFileInfo')
  80. ->willReturn($this->createMock(FileInfo::class));
  81. $this->view->method('getRelativePath')
  82. ->willReturn('/bar/foo');
  83. $node = new Folder($root, $this->view, '/bar/foo');
  84. $children = $node->getDirectoryListing();
  85. $this->assertEquals(2, count($children));
  86. $this->assertInstanceOf('\OC\Files\Node\File', $children[0]);
  87. $this->assertInstanceOf('\OC\Files\Node\Folder', $children[1]);
  88. $this->assertEquals('asd', $children[0]->getName());
  89. $this->assertEquals('qwerty', $children[1]->getName());
  90. $this->assertEquals(2, $children[0]->getId());
  91. $this->assertEquals(3, $children[1]->getId());
  92. }
  93. public function testGet() {
  94. $manager = $this->createMock(Manager::class);
  95. $view = $this->getRootViewMock();
  96. $root = $this->getMockBuilder(Root::class)
  97. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  98. ->getMock();
  99. $root->expects($this->any())
  100. ->method('getUser')
  101. ->willReturn($this->user);
  102. $node = new File($root, $view, '/bar/foo/asd');
  103. $root->method('get')
  104. ->with('/bar/foo/asd')
  105. ->willReturn($node);
  106. $parentNode = new Folder($root, $view, '/bar/foo');
  107. self::assertEquals($node, $parentNode->get('asd'));
  108. }
  109. public function testNodeExists() {
  110. $manager = $this->createMock(Manager::class);
  111. $view = $this->getRootViewMock();
  112. $root = $this->getMockBuilder(Root::class)
  113. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  114. ->getMock();
  115. $root->expects($this->any())
  116. ->method('getUser')
  117. ->willReturn($this->user);
  118. $child = new Folder($root, $view, '/bar/foo/asd');
  119. $root->method('get')
  120. ->with('/bar/foo/asd')
  121. ->willReturn($child);
  122. $node = new Folder($root, $view, '/bar/foo');
  123. $this->assertTrue($node->nodeExists('asd'));
  124. }
  125. public function testNodeExistsNotExists() {
  126. $manager = $this->createMock(Manager::class);
  127. $view = $this->getRootViewMock();
  128. $root = $this->getMockBuilder(Root::class)
  129. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  130. ->getMock();
  131. $root->expects($this->any())
  132. ->method('getUser')
  133. ->willReturn($this->user);
  134. $root->method('get')
  135. ->with('/bar/foo/asd')
  136. ->will($this->throwException(new NotFoundException()));
  137. $node = new Folder($root, $view, '/bar/foo');
  138. $this->assertFalse($node->nodeExists('asd'));
  139. }
  140. public function testNewFolder() {
  141. $manager = $this->createMock(Manager::class);
  142. $view = $this->getRootViewMock();
  143. $root = $this->getMockBuilder(Root::class)
  144. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  145. ->getMock();
  146. $root->expects($this->any())
  147. ->method('getUser')
  148. ->willReturn($this->user);
  149. $view->method('getFileInfo')
  150. ->with('/bar/foo')
  151. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_ALL]));
  152. $view->method('mkdir')
  153. ->with('/bar/foo/asd')
  154. ->willReturn(true);
  155. $node = new Folder($root, $view, '/bar/foo');
  156. $child = new Folder($root, $view, '/bar/foo/asd', null, $node);
  157. $result = $node->newFolder('asd');
  158. $this->assertEquals($child, $result);
  159. }
  160. public function testNewFolderDeepParent() {
  161. $manager = $this->createMock(Manager::class);
  162. $view = $this->getRootViewMock();
  163. $root = $this->getMockBuilder(Root::class)
  164. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  165. ->getMock();
  166. $root->expects($this->any())
  167. ->method('getUser')
  168. ->willReturn($this->user);
  169. $view->method('getFileInfo')
  170. ->with('/foobar')
  171. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_ALL]));
  172. $view->method('mkdir')
  173. ->with('/foobar/asd/sdf')
  174. ->willReturn(true);
  175. $node = new Folder($root, $view, '/foobar');
  176. $child = new Folder($root, $view, '/foobar/asd/sdf', null, null);
  177. $result = $node->newFolder('asd/sdf');
  178. $this->assertEquals($child, $result);
  179. }
  180. public function testNewFolderNotPermitted() {
  181. $this->expectException(\OCP\Files\NotPermittedException::class);
  182. $manager = $this->createMock(Manager::class);
  183. $view = $this->getRootViewMock();
  184. $root = $this->getMockBuilder(Root::class)
  185. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  186. ->getMock();
  187. $root->method('getUser')
  188. ->willReturn($this->user);
  189. $view->method('getFileInfo')
  190. ->with('/bar/foo')
  191. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_READ]));
  192. $node = new Folder($root, $view, '/bar/foo');
  193. $node->newFolder('asd');
  194. }
  195. public function testNewFile() {
  196. $manager = $this->createMock(Manager::class);
  197. $view = $this->getRootViewMock();
  198. $root = $this->getMockBuilder(Root::class)
  199. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  200. ->getMock();
  201. $root->expects($this->any())
  202. ->method('getUser')
  203. ->willReturn($this->user);
  204. $view->method('getFileInfo')
  205. ->with('/bar/foo')
  206. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_ALL]));
  207. $view->method('touch')
  208. ->with('/bar/foo/asd')
  209. ->willReturn(true);
  210. $node = new Folder($root, $view, '/bar/foo');
  211. $child = new \OC\Files\Node\File($root, $view, '/bar/foo/asd', null, $node);
  212. $result = $node->newFile('asd');
  213. $this->assertEquals($child, $result);
  214. }
  215. public function testNewFileNotPermitted() {
  216. $this->expectException(\OCP\Files\NotPermittedException::class);
  217. $manager = $this->createMock(Manager::class);
  218. $view = $this->getRootViewMock();
  219. $root = $this->getMockBuilder(Root::class)
  220. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  221. ->getMock();
  222. $root->method('getUser')
  223. ->willReturn($this->user);
  224. $view->method('getFileInfo')
  225. ->with('/bar/foo')
  226. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_READ]));
  227. $node = new Folder($root, $view, '/bar/foo');
  228. $node->newFile('asd');
  229. }
  230. public function testGetFreeSpace() {
  231. $manager = $this->createMock(Manager::class);
  232. $view = $this->getRootViewMock();
  233. $root = $this->getMockBuilder(Root::class)
  234. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  235. ->getMock();
  236. $root->method('getUser')
  237. ->willReturn($this->user);
  238. $view->method('free_space')
  239. ->with('/bar/foo')
  240. ->willReturn(100);
  241. $node = new Folder($root, $view, '/bar/foo');
  242. $this->assertEquals(100, $node->getFreeSpace());
  243. }
  244. public function testSearch() {
  245. $manager = $this->createMock(Manager::class);
  246. $view = $this->getRootViewMock();
  247. $root = $this->getMockBuilder(Root::class)
  248. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  249. ->getMock();
  250. $root->method('getUser')
  251. ->willReturn($this->user);
  252. /** @var Storage\IStorage&MockObject $storage */
  253. $storage = $this->createMock(Storage\IStorage::class);
  254. $storage->method('getId')->willReturn('test::1');
  255. $cache = new Cache($storage);
  256. $storage->method('getCache')
  257. ->willReturn($cache);
  258. $storage->expects($this->atLeastOnce())
  259. ->method('getOwner')
  260. ->with('qwerty')
  261. ->willReturn(false);
  262. $mount = $this->createMock(IMountPoint::class);
  263. $mount->expects($this->atLeastOnce())
  264. ->method('getStorage')
  265. ->willReturn($storage);
  266. $mount->expects($this->atLeastOnce())
  267. ->method('getInternalPath')
  268. ->willReturn('foo');
  269. $cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  270. $cache->insert('foo', ['size' => 200, 'mtime' => 55, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  271. $cache->insert('foo/qwerty', ['size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain']);
  272. $root->method('getMountsIn')
  273. ->with('/bar/foo')
  274. ->willReturn([]);
  275. $root->method('getMount')
  276. ->with('/bar/foo')
  277. ->willReturn($mount);
  278. $node = new Folder($root, $view, '/bar/foo');
  279. $result = $node->search('qw');
  280. $cache->clear();
  281. $this->assertEquals(1, count($result));
  282. $this->assertEquals('/bar/foo/qwerty', $result[0]->getPath());
  283. }
  284. public function testSearchInRoot() {
  285. $manager = $this->createMock(Manager::class);
  286. $view = $this->getRootViewMock();
  287. $root = $this->getMockBuilder(Root::class)
  288. ->setMethods(['getUser', 'getMountsIn', 'getMount'])
  289. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  290. ->getMock();
  291. $root->expects($this->any())
  292. ->method('getUser')
  293. ->willReturn($this->user);
  294. /** @var \PHPUnit\Framework\MockObject\MockObject|Storage $storage */
  295. $storage = $this->createMock(Storage::class);
  296. $storage->method('getId')->willReturn('test::2');
  297. $cache = new Cache($storage);
  298. $mount = $this->createMock(IMountPoint::class);
  299. $mount->method('getStorage')
  300. ->willReturn($storage);
  301. $mount->method('getInternalPath')
  302. ->willReturn('files');
  303. $storage->method('getCache')
  304. ->willReturn($cache);
  305. $storage->method('getOwner')
  306. ->willReturn('owner');
  307. $cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  308. $cache->insert('files', ['size' => 200, 'mtime' => 55, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  309. $cache->insert('files/foo', ['size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain']);
  310. $root->method('getMountsIn')
  311. ->with('')
  312. ->willReturn([]);
  313. $root->method('getMount')
  314. ->with('')
  315. ->willReturn($mount);
  316. $result = $root->search('foo');
  317. $cache->clear();
  318. $this->assertEquals(1, count($result));
  319. $this->assertEquals('/foo', $result[0]->getPath());
  320. }
  321. public function testSearchInStorageRoot() {
  322. $manager = $this->createMock(Manager::class);
  323. $view = $this->getRootViewMock();
  324. $root = $this->getMockBuilder(Root::class)
  325. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  326. ->getMock();
  327. $root->method('getUser')
  328. ->willReturn($this->user);
  329. $storage = $this->createMock(Storage::class);
  330. $storage->method('getId')->willReturn('test::1');
  331. $cache = new Cache($storage);
  332. $mount = $this->createMock(IMountPoint::class);
  333. $mount->method('getStorage')
  334. ->willReturn($storage);
  335. $mount->method('getInternalPath')
  336. ->willReturn('');
  337. $storage->method('getCache')
  338. ->willReturn($cache);
  339. $storage->method('getOwner')
  340. ->willReturn('owner');
  341. $cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  342. $cache->insert('foo', ['size' => 200, 'mtime' => 55, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  343. $cache->insert('foo/qwerty', ['size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain']);
  344. $root->method('getMountsIn')
  345. ->with('/bar')
  346. ->willReturn([]);
  347. $root->method('getMount')
  348. ->with('/bar')
  349. ->willReturn($mount);
  350. $node = new Folder($root, $view, '/bar');
  351. $result = $node->search('qw');
  352. $cache->clear();
  353. $this->assertEquals(1, count($result));
  354. $this->assertEquals('/bar/foo/qwerty', $result[0]->getPath());
  355. }
  356. public function testSearchSubStorages() {
  357. $manager = $this->createMock(Manager::class);
  358. $view = $this->getRootViewMock();
  359. $root = $this->getMockBuilder(Root::class)
  360. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  361. ->getMock();
  362. $root->expects($this->any())
  363. ->method('getUser')
  364. ->willReturn($this->user);
  365. $storage = $this->createMock(Storage::class);
  366. $storage->method('getId')->willReturn('test::1');
  367. $cache = new Cache($storage);
  368. $subStorage = $this->createMock(Storage::class);
  369. $subStorage->method('getId')->willReturn('test::2');
  370. $subCache = new Cache($subStorage);
  371. $subMount = $this->getMockBuilder(MountPoint::class)->setConstructorArgs([Temporary::class, ''])->getMock();
  372. $mount = $this->createMock(IMountPoint::class);
  373. $mount->method('getStorage')
  374. ->willReturn($storage);
  375. $mount->method('getInternalPath')
  376. ->willReturn('foo');
  377. $subMount->method('getStorage')
  378. ->willReturn($subStorage);
  379. $subMount->method('getMountPoint')
  380. ->willReturn('/bar/foo/bar/');
  381. $storage->method('getCache')
  382. ->willReturn($cache);
  383. $storage->method('getOwner')
  384. ->willReturn('owner');
  385. $subStorage->method('getCache')
  386. ->willReturn($subCache);
  387. $subStorage->method('getOwner')
  388. ->willReturn('owner');
  389. $cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  390. $cache->insert('foo', ['size' => 200, 'mtime' => 55, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  391. $cache->insert('foo/qwerty', ['size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain']);
  392. $subCache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  393. $subCache->insert('asd', ['size' => 200, 'mtime' => 55, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  394. $subCache->insert('asd/qwerty', ['size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain']);
  395. $root->method('getMountsIn')
  396. ->with('/bar/foo')
  397. ->willReturn([$subMount]);
  398. $root->method('getMount')
  399. ->with('/bar/foo')
  400. ->willReturn($mount);
  401. $node = new Folder($root, $view, '/bar/foo');
  402. $result = $node->search('qw');
  403. $cache->clear();
  404. $subCache->clear();
  405. $this->assertEquals(2, count($result));
  406. }
  407. public function testIsSubNode() {
  408. $rootFolderMock = $this->createMock(IRootFolder::class);
  409. $file = new Node($rootFolderMock, $this->view, '/foo/bar');
  410. $folder = new Folder($rootFolderMock, $this->view, '/foo');
  411. $this->assertTrue($folder->isSubNode($file));
  412. $this->assertFalse($folder->isSubNode($folder));
  413. $file = new Node($rootFolderMock, $this->view, '/foobar');
  414. $this->assertFalse($folder->isSubNode($file));
  415. }
  416. public function testGetById() {
  417. $manager = $this->createMock(Manager::class);
  418. $view = $this->getRootViewMock();
  419. $root = $this->getMockBuilder(Root::class)
  420. ->setMethods(['getMountsIn', 'getMount'])
  421. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  422. ->getMock();
  423. $storage = $this->createMock(\OC\Files\Storage\Storage::class);
  424. $mount = new MountPoint($storage, '/bar');
  425. $storage->method('getId')->willReturn('');
  426. $cache = $this->getMockBuilder(Cache::class)->setConstructorArgs([$storage])->getMock();
  427. $fileInfo = new CacheEntry(['path' => 'foo/qwerty', 'mimetype' => 'text/plain'], null);
  428. $storage->method('getCache')
  429. ->willReturn($cache);
  430. $storage->method('getOwner')
  431. ->willReturn('owner');
  432. $this->userMountCache->expects($this->any())
  433. ->method('getMountsForFileId')
  434. ->with(1)
  435. ->willReturn([new CachedMountInfo(
  436. $this->user,
  437. 1,
  438. 0,
  439. '/bar/',
  440. 'test',
  441. 1,
  442. ''
  443. )]);
  444. $cache->method('get')
  445. ->with(1)
  446. ->willReturn($fileInfo);
  447. $root->method('getMountsIn')
  448. ->with('/bar/foo')
  449. ->willReturn([]);
  450. $manager->method('getMountsByMountProvider')
  451. ->willReturn([$mount]);
  452. $node = new Folder($root, $view, '/bar/foo');
  453. $result = $node->getById(1);
  454. $this->assertEquals(1, count($result));
  455. $this->assertEquals('/bar/foo/qwerty', $result[0]->getPath());
  456. }
  457. public function testGetByIdMountRoot() {
  458. $manager = $this->createMock(Manager::class);
  459. $view = $this->getRootViewMock();
  460. $root = $this->getMockBuilder(Root::class)
  461. ->setMethods(['getMountsIn', 'getMount'])
  462. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  463. ->getMock();
  464. $storage = $this->createMock(\OC\Files\Storage\Storage::class);
  465. $mount = new MountPoint($storage, '/bar');
  466. $storage->method('getId')->willReturn('');
  467. $cache = $this->getMockBuilder(Cache::class)->setConstructorArgs([$storage])->getMock();
  468. $fileInfo = new CacheEntry(['path' => '', 'mimetype' => 'text/plain'], null);
  469. $storage->method('getCache')
  470. ->willReturn($cache);
  471. $storage->method('getOwner')
  472. ->willReturn('owner');
  473. $this->userMountCache->expects($this->any())
  474. ->method('getMountsForFileId')
  475. ->with(1)
  476. ->willReturn([new CachedMountInfo(
  477. $this->user,
  478. 1,
  479. 0,
  480. '/bar/',
  481. 'test',
  482. 1,
  483. ''
  484. )]);
  485. $cache->method('get')
  486. ->with(1)
  487. ->willReturn($fileInfo);
  488. $manager->method('getMountsByMountProvider')
  489. ->willReturn([$mount]);
  490. $node = new Folder($root, $view, '/bar');
  491. $result = $node->getById(1);
  492. $this->assertEquals(1, count($result));
  493. $this->assertEquals('/bar', $result[0]->getPath());
  494. }
  495. public function testGetByIdOutsideFolder() {
  496. $manager = $this->createMock(Manager::class);
  497. $view = $this->getRootViewMock();
  498. $root = $this->getMockBuilder(Root::class)
  499. ->setMethods(['getMountsIn', 'getMount'])
  500. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  501. ->getMock();
  502. $storage = $this->createMock(\OC\Files\Storage\Storage::class);
  503. $mount = new MountPoint($storage, '/bar');
  504. $storage->method('getId')->willReturn('');
  505. $cache = $this->getMockBuilder(Cache::class)->setConstructorArgs([$storage])->getMock();
  506. $fileInfo = new CacheEntry(['path' => 'foobar', 'mimetype' => 'text/plain'], null);
  507. $storage->method('getCache')
  508. ->willReturn($cache);
  509. $storage->method('getOwner')
  510. ->willReturn('owner');
  511. $this->userMountCache->expects($this->any())
  512. ->method('getMountsForFileId')
  513. ->with(1)
  514. ->willReturn([new CachedMountInfo(
  515. $this->user,
  516. 1,
  517. 0,
  518. '/bar/',
  519. 'test',
  520. 1,
  521. ''
  522. )]);
  523. $cache->method('get')
  524. ->with(1)
  525. ->willReturn($fileInfo);
  526. $manager->method('getMountsByMountProvider')
  527. ->willReturn([$mount]);
  528. $node = new Folder($root, $view, '/bar/foo');
  529. $result = $node->getById(1);
  530. $this->assertEquals(0, count($result));
  531. }
  532. public function testGetByIdMultipleStorages() {
  533. $manager = $this->createMock(Manager::class);
  534. $view = $this->getRootViewMock();
  535. $root = $this->getMockBuilder(Root::class)
  536. ->setMethods(['getMountsIn', 'getMount'])
  537. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  538. ->getMock();
  539. $storage = $this->createMock(\OC\Files\Storage\Storage::class);
  540. $mount1 = new MountPoint($storage, '/bar');
  541. $mount2 = new MountPoint($storage, '/bar/foo/asd');
  542. $storage->method('getId')->willReturn('');
  543. $cache = $this->getMockBuilder(Cache::class)->setConstructorArgs([$storage])->getMock();
  544. $fileInfo = new CacheEntry(['path' => 'foo/qwerty', 'mimetype' => 'text/plain'], null);
  545. $storage->method('getCache')
  546. ->willReturn($cache);
  547. $storage->method('getOwner')
  548. ->willReturn('owner');
  549. $this->userMountCache->method('getMountsForFileId')
  550. ->with(1)
  551. ->willReturn([
  552. new CachedMountInfo(
  553. $this->user,
  554. 1,
  555. 0,
  556. '/bar/',
  557. 'test',
  558. 1,
  559. ''
  560. ),
  561. ]);
  562. $cache->method('get')
  563. ->with(1)
  564. ->willReturn($fileInfo);
  565. $manager->method('getMountsByMountProvider')
  566. ->willReturn([$mount1, $mount2]);
  567. $node = new Folder($root, $view, '/bar/foo');
  568. $result = $node->getById(1);
  569. $this->assertEquals(2, count($result));
  570. $this->assertEquals('/bar/foo/qwerty', $result[0]->getPath());
  571. $this->assertEquals('/bar/foo/asd/foo/qwerty', $result[1]->getPath());
  572. }
  573. public function uniqueNameProvider() {
  574. return [
  575. // input, existing, expected
  576. ['foo', [], 'foo'],
  577. ['foo', ['foo'], 'foo (2)'],
  578. ['foo', ['foo', 'foo (2)'], 'foo (3)'],
  579. ];
  580. }
  581. /**
  582. * @dataProvider uniqueNameProvider
  583. */
  584. public function testGetUniqueName($name, $existingFiles, $expected) {
  585. $manager = $this->createMock(Manager::class);
  586. $folderPath = '/bar/foo';
  587. $view = $this->getRootViewMock();
  588. $root = $this->getMockBuilder(Root::class)
  589. ->setMethods(['getUser', 'getMountsIn', 'getMount'])
  590. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  591. ->getMock();
  592. $view->expects($this->any())
  593. ->method('file_exists')
  594. ->willReturnCallback(function ($path) use ($existingFiles, $folderPath) {
  595. foreach ($existingFiles as $existing) {
  596. if ($folderPath . '/' . $existing === $path) {
  597. return true;
  598. }
  599. }
  600. return false;
  601. });
  602. $node = new Folder($root, $view, $folderPath);
  603. $this->assertEquals($expected, $node->getNonExistingName($name));
  604. }
  605. public function testRecent(): void {
  606. $manager = $this->createMock(Manager::class);
  607. $folderPath = '/bar/foo';
  608. $view = $this->getRootViewMock();
  609. /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\Node\Root $root */
  610. $root = $this->getMockBuilder(Root::class)
  611. ->setMethods(['getUser', 'getMountsIn', 'getMount'])
  612. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  613. ->getMock();
  614. /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\FileInfo $folderInfo */
  615. $folderInfo = $this->getMockBuilder(FileInfo::class)
  616. ->disableOriginalConstructor()->getMock();
  617. $baseTime = time();
  618. $storage = new Temporary();
  619. $mount = new MountPoint($storage, '');
  620. $folderInfo->expects($this->any())
  621. ->method('getMountPoint')
  622. ->willReturn($mount);
  623. $root->method('getMount')
  624. ->willReturn($mount);
  625. $root->method('getMountsIn')
  626. ->willReturn([]);
  627. $cache = $storage->getCache();
  628. $cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  629. $cache->insert('bar', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  630. $cache->insert('bar/foo', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  631. $cache->insert('bar/asd', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  632. $id1 = $cache->put('bar/foo/inside.txt', [
  633. 'storage_mtime' => $baseTime,
  634. 'mtime' => $baseTime,
  635. 'mimetype' => 'text/plain',
  636. 'size' => 3,
  637. 'permissions' => \OCP\Constants::PERMISSION_ALL,
  638. ]);
  639. $id2 = $cache->put('bar/foo/old.txt', [
  640. 'storage_mtime' => $baseTime - 100,
  641. 'mtime' => $baseTime - 100,
  642. 'mimetype' => 'text/plain',
  643. 'size' => 3,
  644. 'permissions' => \OCP\Constants::PERMISSION_READ,
  645. ]);
  646. $cache->put('bar/asd/outside.txt', [
  647. 'storage_mtime' => $baseTime,
  648. 'mtime' => $baseTime,
  649. 'mimetype' => 'text/plain',
  650. 'size' => 3,
  651. ]);
  652. $id3 = $cache->put('bar/foo/older.txt', [
  653. 'storage_mtime' => $baseTime - 600,
  654. 'mtime' => $baseTime - 600,
  655. 'mimetype' => 'text/plain',
  656. 'size' => 3,
  657. 'permissions' => \OCP\Constants::PERMISSION_ALL,
  658. ]);
  659. $node = new Folder($root, $view, $folderPath, $folderInfo);
  660. $nodes = $node->getRecent(5);
  661. $ids = array_map(function (Node $node) {
  662. return (int)$node->getId();
  663. }, $nodes);
  664. $this->assertEquals([$id1, $id2, $id3], $ids);
  665. }
  666. public function testRecentFolder() {
  667. $manager = $this->createMock(Manager::class);
  668. $folderPath = '/bar/foo';
  669. $view = $this->getRootViewMock();
  670. /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\Node\Root $root */
  671. $root = $this->getMockBuilder(Root::class)
  672. ->setMethods(['getUser', 'getMountsIn', 'getMount'])
  673. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  674. ->getMock();
  675. /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\FileInfo $folderInfo */
  676. $folderInfo = $this->getMockBuilder(FileInfo::class)
  677. ->disableOriginalConstructor()->getMock();
  678. $baseTime = time();
  679. $storage = new Temporary();
  680. $mount = new MountPoint($storage, '');
  681. $folderInfo->expects($this->any())
  682. ->method('getMountPoint')
  683. ->willReturn($mount);
  684. $root->method('getMount')
  685. ->willReturn($mount);
  686. $root->method('getMountsIn')
  687. ->willReturn([]);
  688. $cache = $storage->getCache();
  689. $cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  690. $cache->insert('bar', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  691. $cache->insert('bar/foo', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  692. $id1 = $cache->put('bar/foo/folder', [
  693. 'storage_mtime' => $baseTime,
  694. 'mtime' => $baseTime,
  695. 'mimetype' => \OCP\Files\FileInfo::MIMETYPE_FOLDER,
  696. 'size' => 3,
  697. 'permissions' => 0,
  698. ]);
  699. $id2 = $cache->put('bar/foo/folder/bar.txt', [
  700. 'storage_mtime' => $baseTime,
  701. 'mtime' => $baseTime,
  702. 'mimetype' => 'text/plain',
  703. 'size' => 3,
  704. 'parent' => $id1,
  705. 'permissions' => \OCP\Constants::PERMISSION_ALL,
  706. ]);
  707. $id3 = $cache->put('bar/foo/folder/asd.txt', [
  708. 'storage_mtime' => $baseTime - 100,
  709. 'mtime' => $baseTime - 100,
  710. 'mimetype' => 'text/plain',
  711. 'size' => 3,
  712. 'parent' => $id1,
  713. 'permissions' => \OCP\Constants::PERMISSION_ALL,
  714. ]);
  715. $node = new Folder($root, $view, $folderPath, $folderInfo);
  716. $nodes = $node->getRecent(5);
  717. $ids = array_map(function (Node $node) {
  718. return (int)$node->getId();
  719. }, $nodes);
  720. $this->assertEquals([$id2, $id3], $ids);
  721. $this->assertEquals($baseTime, $nodes[0]->getMTime());
  722. $this->assertEquals($baseTime - 100, $nodes[1]->getMTime());
  723. }
  724. public function testRecentJail() {
  725. $manager = $this->createMock(Manager::class);
  726. $folderPath = '/bar/foo';
  727. $view = $this->getRootViewMock();
  728. /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\Node\Root $root */
  729. $root = $this->getMockBuilder(Root::class)
  730. ->setMethods(['getUser', 'getMountsIn', 'getMount'])
  731. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  732. ->getMock();
  733. /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\FileInfo $folderInfo */
  734. $folderInfo = $this->getMockBuilder(FileInfo::class)
  735. ->disableOriginalConstructor()->getMock();
  736. $baseTime = time();
  737. $storage = new Temporary();
  738. $jail = new Jail([
  739. 'storage' => $storage,
  740. 'root' => 'folder',
  741. ]);
  742. $mount = new MountPoint($jail, '/bar/foo');
  743. $folderInfo->expects($this->any())
  744. ->method('getMountPoint')
  745. ->willReturn($mount);
  746. $root->method('getMount')
  747. ->willReturn($mount);
  748. $root->method('getMountsIn')
  749. ->willReturn([]);
  750. $cache = $storage->getCache();
  751. $cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  752. $cache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  753. $id1 = $cache->put('folder/inside.txt', [
  754. 'storage_mtime' => $baseTime,
  755. 'mtime' => $baseTime,
  756. 'mimetype' => 'text/plain',
  757. 'size' => 3,
  758. 'permissions' => \OCP\Constants::PERMISSION_ALL,
  759. ]);
  760. $cache->put('outside.txt', [
  761. 'storage_mtime' => $baseTime - 100,
  762. 'mtime' => $baseTime - 100,
  763. 'mimetype' => 'text/plain',
  764. 'size' => 3,
  765. ]);
  766. $node = new Folder($root, $view, $folderPath, $folderInfo);
  767. $nodes = $node->getRecent(5);
  768. $ids = array_map(function (Node $node) {
  769. return (int)$node->getId();
  770. }, $nodes);
  771. $this->assertEquals([$id1], $ids);
  772. }
  773. public function offsetLimitProvider() {
  774. return [
  775. [0, 10, ['/bar/foo/foo1', '/bar/foo/foo2', '/bar/foo/foo3', '/bar/foo/foo4', '/bar/foo/sub1/foo5', '/bar/foo/sub1/foo6', '/bar/foo/sub2/foo7', '/bar/foo/sub2/foo8'], []],
  776. [0, 5, ['/bar/foo/foo1', '/bar/foo/foo2', '/bar/foo/foo3', '/bar/foo/foo4', '/bar/foo/sub1/foo5'], []],
  777. [0, 2, ['/bar/foo/foo1', '/bar/foo/foo2'], []],
  778. [3, 2, ['/bar/foo/foo4', '/bar/foo/sub1/foo5'], []],
  779. [3, 5, ['/bar/foo/foo4', '/bar/foo/sub1/foo5', '/bar/foo/sub1/foo6', '/bar/foo/sub2/foo7', '/bar/foo/sub2/foo8'], []],
  780. [5, 2, ['/bar/foo/sub1/foo6', '/bar/foo/sub2/foo7'], []],
  781. [6, 2, ['/bar/foo/sub2/foo7', '/bar/foo/sub2/foo8'], []],
  782. [7, 2, ['/bar/foo/sub2/foo8'], []],
  783. [10, 2, [], []],
  784. [0, 5, ['/bar/foo/sub2/foo7', '/bar/foo/foo1', '/bar/foo/sub1/foo5', '/bar/foo/foo2', '/bar/foo/foo3'], [new SearchOrder(ISearchOrder::DIRECTION_ASCENDING, 'mtime')]],
  785. [3, 2, ['/bar/foo/foo2', '/bar/foo/foo3'], [new SearchOrder(ISearchOrder::DIRECTION_ASCENDING, 'mtime')]],
  786. [0, 5, ['/bar/foo/sub1/foo5', '/bar/foo/sub1/foo6', '/bar/foo/sub2/foo7', '/bar/foo/foo1', '/bar/foo/foo2'], [
  787. new SearchOrder(ISearchOrder::DIRECTION_DESCENDING, 'size'),
  788. new SearchOrder(ISearchOrder::DIRECTION_ASCENDING, 'mtime')
  789. ]],
  790. ];
  791. }
  792. /**
  793. * @dataProvider offsetLimitProvider
  794. * @param int $offset
  795. * @param int $limit
  796. * @param string[] $expectedPaths
  797. * @param ISearchOrder[] $ordering
  798. * @throws NotFoundException
  799. * @throws \OCP\Files\InvalidPathException
  800. */
  801. public function testSearchSubStoragesLimitOffset(int $offset, int $limit, array $expectedPaths, array $ordering) {
  802. if (!$ordering) {
  803. $ordering = [new SearchOrder(ISearchOrder::DIRECTION_ASCENDING, 'fileid')];
  804. }
  805. $manager = $this->createMock(Manager::class);
  806. $view = $this->getRootViewMock();
  807. $root = $this->getMockBuilder(Root::class)
  808. ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  809. ->getMock();
  810. $root->expects($this->any())
  811. ->method('getUser')
  812. ->willReturn($this->user);
  813. $storage = $this->createMock(Storage::class);
  814. $storage->method('getId')->willReturn('test::1');
  815. $cache = new Cache($storage);
  816. $subStorage1 = $this->createMock(Storage::class);
  817. $subStorage1->method('getId')->willReturn('test::2');
  818. $subCache1 = new Cache($subStorage1);
  819. $subMount1 = $this->getMockBuilder(MountPoint::class)->setConstructorArgs([Temporary::class, ''])->getMock();
  820. $subStorage2 = $this->createMock(Storage::class);
  821. $subStorage2->method('getId')->willReturn('test::3');
  822. $subCache2 = new Cache($subStorage2);
  823. $subMount2 = $this->getMockBuilder(MountPoint::class)->setConstructorArgs([Temporary::class, ''])->getMock();
  824. $mount = $this->createMock(IMountPoint::class);
  825. $mount->method('getStorage')
  826. ->willReturn($storage);
  827. $mount->method('getInternalPath')
  828. ->willReturn('foo');
  829. $subMount1->method('getStorage')
  830. ->willReturn($subStorage1);
  831. $subMount1->method('getMountPoint')
  832. ->willReturn('/bar/foo/sub1/');
  833. $storage->method('getCache')
  834. ->willReturn($cache);
  835. $storage->method('getOwner')
  836. ->willReturn('owner');
  837. $subStorage1->method('getCache')
  838. ->willReturn($subCache1);
  839. $subStorage1->method('getOwner')
  840. ->willReturn('owner');
  841. $subMount2->method('getStorage')
  842. ->willReturn($subStorage2);
  843. $subMount2->method('getMountPoint')
  844. ->willReturn('/bar/foo/sub2/');
  845. $subStorage2->method('getCache')
  846. ->willReturn($subCache2);
  847. $subStorage2->method('getOwner')
  848. ->willReturn('owner');
  849. $cache->insert('', ['size' => 0, 'mtime' => 10, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  850. $cache->insert('foo', ['size' => 0, 'mtime' => 10, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  851. $cache->insert('foo/foo1', ['size' => 200, 'mtime' => 10, 'mimetype' => 'text/plain']);
  852. $cache->insert('foo/foo2', ['size' => 200, 'mtime' => 20, 'mimetype' => 'text/plain']);
  853. $cache->insert('foo/foo3', ['size' => 200, 'mtime' => 30, 'mimetype' => 'text/plain']);
  854. $cache->insert('foo/foo4', ['size' => 200, 'mtime' => 40, 'mimetype' => 'text/plain']);
  855. $subCache1->insert('', ['size' => 0, 'mtime' => 10, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  856. $subCache1->insert('foo5', ['size' => 300, 'mtime' => 15, 'mimetype' => 'text/plain']);
  857. $subCache1->insert('foo6', ['size' => 300, 'mtime' => 50, 'mimetype' => 'text/plain']);
  858. $subCache2->insert('', ['size' => 0, 'mtime' => 10, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
  859. $subCache2->insert('foo7', ['size' => 200, 'mtime' => 5, 'mimetype' => 'text/plain']);
  860. $subCache2->insert('foo8', ['size' => 200, 'mtime' => 60, 'mimetype' => 'text/plain']);
  861. $root->method('getMountsIn')
  862. ->with('/bar/foo')
  863. ->willReturn([$subMount1, $subMount2]);
  864. $root->method('getMount')
  865. ->with('/bar/foo')
  866. ->willReturn($mount);
  867. $node = new Folder($root, $view, '/bar/foo');
  868. $comparison = new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%foo%');
  869. $operator = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  870. $comparison,
  871. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', ICacheEntry::DIRECTORY_MIMETYPE)]),
  872. ]);
  873. $query = new SearchQuery($operator, $limit, $offset, $ordering);
  874. $result = $node->search($query);
  875. $cache->clear();
  876. $subCache1->clear();
  877. $subCache2->clear();
  878. $ids = array_map(function (Node $info) {
  879. return $info->getPath();
  880. }, $result);
  881. $this->assertEquals($expectedPaths, $ids);
  882. }
  883. }