FolderTest.php 32 KB

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