NodeTest.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace Test\Files\Node;
  8. use OC\Files\FileInfo;
  9. use OC\Files\Mount\Manager;
  10. use OC\Files\View;
  11. use OC\Memcache\ArrayCache;
  12. use OCP\EventDispatcher\IEventDispatcher;
  13. use OCP\Files\IRootFolder;
  14. use OCP\Files\Mount\IMountPoint;
  15. use OCP\Files\Node;
  16. use OCP\Files\NotFoundException;
  17. use OCP\Files\Storage\IStorage;
  18. use OCP\ICacheFactory;
  19. use OCP\IUser;
  20. use OCP\IUserManager;
  21. use Psr\Log\LoggerInterface;
  22. /**
  23. * Class NodeTest
  24. *
  25. * @package Test\Files\Node
  26. */
  27. abstract class NodeTest extends \Test\TestCase {
  28. /** @var \OC\User\User */
  29. protected $user;
  30. /** @var \OC\Files\Mount\Manager */
  31. protected $manager;
  32. /** @var \OC\Files\View|\PHPUnit\Framework\MockObject\MockObject */
  33. protected $view;
  34. /** @var \OC\Files\Node\Root|\PHPUnit\Framework\MockObject\MockObject */
  35. protected $root;
  36. /** @var \OCP\Files\Config\IUserMountCache|\PHPUnit\Framework\MockObject\MockObject */
  37. protected $userMountCache;
  38. /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
  39. protected $logger;
  40. /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */
  41. protected $userManager;
  42. /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */
  43. protected $eventDispatcher;
  44. /** @var ICacheFactory|\PHPUnit\Framework\MockObject\MockObject */
  45. protected $cacheFactory;
  46. protected function setUp(): void {
  47. parent::setUp();
  48. $this->user = $this->createMock(IUser::class);
  49. $this->manager = $this->getMockBuilder(Manager::class)
  50. ->disableOriginalConstructor()
  51. ->getMock();
  52. $this->view = $this->getMockBuilder(View::class)
  53. ->disableOriginalConstructor()
  54. ->getMock();
  55. $this->view->expects($this->any())
  56. ->method('getRoot')
  57. ->willReturn('');
  58. $this->userMountCache = $this->getMockBuilder('\OCP\Files\Config\IUserMountCache')
  59. ->disableOriginalConstructor()
  60. ->getMock();
  61. $this->logger = $this->createMock(LoggerInterface::class);
  62. $this->userManager = $this->createMock(IUserManager::class);
  63. $this->eventDispatcher = $this->createMock(IEventDispatcher::class);
  64. $this->cacheFactory = $this->createMock(ICacheFactory::class);
  65. $this->cacheFactory->method('createLocal')
  66. ->willReturnCallback(function () {
  67. return new ArrayCache();
  68. });
  69. $this->root = $this->getMockBuilder('\OC\Files\Node\Root')
  70. ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  71. ->getMock();
  72. }
  73. /**
  74. * @return \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view
  75. */
  76. protected function getRootViewMock() {
  77. $view = $this->createMock(View::class);
  78. $view->expects($this->any())
  79. ->method('getRoot')
  80. ->willReturn('');
  81. return $view;
  82. }
  83. /**
  84. * @param IRootFolder $root
  85. * @param View $view
  86. * @param string $path
  87. * @return Node
  88. */
  89. abstract protected function createTestNode($root, $view, $path, array $data = [], $internalPath = '', $storage = null);
  90. /**
  91. * @return string
  92. */
  93. abstract protected function getNodeClass();
  94. /**
  95. * @return string
  96. */
  97. abstract protected function getNonExistingNodeClass();
  98. /**
  99. * @return string
  100. */
  101. abstract protected function getViewDeleteMethod();
  102. protected function getMockStorage() {
  103. $storage = $this->getMockBuilder(IStorage::class)
  104. ->disableOriginalConstructor()
  105. ->getMock();
  106. $storage->expects($this->any())
  107. ->method('getId')
  108. ->willReturn('home::someuser');
  109. return $storage;
  110. }
  111. protected function getFileInfo($data, $internalPath = '', $storage = null) {
  112. $mount = $this->createMock(IMountPoint::class);
  113. $mount->method('getStorage')
  114. ->willReturn($storage);
  115. return new FileInfo('', $this->getMockStorage(), $internalPath, $data, $mount);
  116. }
  117. public function testDelete(): void {
  118. $this->root->expects($this->exactly(2))
  119. ->method('emit')
  120. ->willReturn(true);
  121. $this->root->expects($this->any())
  122. ->method('getUser')
  123. ->willReturn($this->user);
  124. $this->view->expects($this->once())
  125. ->method('getFileInfo')
  126. ->with('/bar/foo')
  127. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_ALL]));
  128. $this->view->expects($this->once())
  129. ->method($this->getViewDeleteMethod())
  130. ->with('/bar/foo')
  131. ->willReturn(true);
  132. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  133. $node->delete();
  134. }
  135. public function testDeleteHooks(): void {
  136. $test = $this;
  137. $hooksRun = 0;
  138. /**
  139. * @param \OC\Files\Node\File $node
  140. */
  141. $preListener = function ($node) use (&$test, &$hooksRun) {
  142. $test->assertInstanceOf($this->getNodeClass(), $node);
  143. $test->assertEquals('foo', $node->getInternalPath());
  144. $test->assertEquals('/bar/foo', $node->getPath());
  145. $test->assertEquals(1, $node->getId());
  146. $hooksRun++;
  147. };
  148. /**
  149. * @param \OC\Files\Node\File $node
  150. */
  151. $postListener = function ($node) use (&$test, &$hooksRun) {
  152. $test->assertInstanceOf($this->getNonExistingNodeClass(), $node);
  153. $test->assertEquals('foo', $node->getInternalPath());
  154. $test->assertEquals('/bar/foo', $node->getPath());
  155. $test->assertEquals(1, $node->getId());
  156. $test->assertEquals('text/plain', $node->getMimeType());
  157. $hooksRun++;
  158. };
  159. $root = new \OC\Files\Node\Root(
  160. $this->manager,
  161. $this->view,
  162. $this->user,
  163. $this->userMountCache,
  164. $this->logger,
  165. $this->userManager,
  166. $this->eventDispatcher,
  167. $this->cacheFactory,
  168. );
  169. $root->listen('\OC\Files', 'preDelete', $preListener);
  170. $root->listen('\OC\Files', 'postDelete', $postListener);
  171. $this->view->expects($this->any())
  172. ->method('getFileInfo')
  173. ->with('/bar/foo')
  174. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_ALL, 'fileid' => 1, 'mimetype' => 'text/plain'], 'foo'));
  175. $this->view->expects($this->once())
  176. ->method($this->getViewDeleteMethod())
  177. ->with('/bar/foo')
  178. ->willReturn(true);
  179. $node = $this->createTestNode($root, $this->view, '/bar/foo');
  180. $node->delete();
  181. $this->assertEquals(2, $hooksRun);
  182. }
  183. public function testDeleteNotPermitted(): void {
  184. $this->expectException(\OCP\Files\NotPermittedException::class);
  185. $this->root->expects($this->any())
  186. ->method('getUser')
  187. ->willReturn($this->user);
  188. $this->view->expects($this->once())
  189. ->method('getFileInfo')
  190. ->with('/bar/foo')
  191. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_READ]));
  192. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  193. $node->delete();
  194. }
  195. public function testStat(): void {
  196. $this->root->expects($this->any())
  197. ->method('getUser')
  198. ->willReturn($this->user);
  199. $stat = [
  200. 'fileid' => 1,
  201. 'size' => 100,
  202. 'etag' => 'qwerty',
  203. 'mtime' => 50,
  204. 'permissions' => 0
  205. ];
  206. $this->view->expects($this->once())
  207. ->method('stat')
  208. ->with('/bar/foo')
  209. ->willReturn($stat);
  210. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  211. $this->assertEquals($stat, $node->stat());
  212. }
  213. public function testGetId(): void {
  214. $this->root->expects($this->any())
  215. ->method('getUser')
  216. ->willReturn($this->user);
  217. $stat = $this->getFileInfo([
  218. 'fileid' => 1,
  219. 'size' => 100,
  220. 'etag' => 'qwerty',
  221. 'mtime' => 50
  222. ]);
  223. $this->view->expects($this->once())
  224. ->method('getFileInfo')
  225. ->with('/bar/foo')
  226. ->willReturn($stat);
  227. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  228. $this->assertEquals(1, $node->getId());
  229. }
  230. public function testGetSize(): void {
  231. $this->root->expects($this->any())
  232. ->method('getUser')
  233. ->willReturn($this->user);
  234. $stat = $this->getFileInfo([
  235. 'fileid' => 1,
  236. 'size' => 100,
  237. 'etag' => 'qwerty',
  238. 'mtime' => 50
  239. ]);
  240. $this->view->expects($this->once())
  241. ->method('getFileInfo')
  242. ->with('/bar/foo')
  243. ->willReturn($stat);
  244. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  245. $this->assertEquals(100, $node->getSize());
  246. }
  247. public function testGetEtag(): void {
  248. $this->root->expects($this->any())
  249. ->method('getUser')
  250. ->willReturn($this->user);
  251. $stat = $this->getFileInfo([
  252. 'fileid' => 1,
  253. 'size' => 100,
  254. 'etag' => 'qwerty',
  255. 'mtime' => 50
  256. ]);
  257. $this->view->expects($this->once())
  258. ->method('getFileInfo')
  259. ->with('/bar/foo')
  260. ->willReturn($stat);
  261. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  262. $this->assertEquals('qwerty', $node->getEtag());
  263. }
  264. public function testGetMTime(): void {
  265. $this->root->expects($this->any())
  266. ->method('getUser')
  267. ->willReturn($this->user);
  268. $stat = $this->getFileInfo([
  269. 'fileid' => 1,
  270. 'size' => 100,
  271. 'etag' => 'qwerty',
  272. 'mtime' => 50
  273. ]);
  274. $this->view->expects($this->once())
  275. ->method('getFileInfo')
  276. ->with('/bar/foo')
  277. ->willReturn($stat);
  278. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  279. $this->assertEquals(50, $node->getMTime());
  280. }
  281. public function testGetStorage(): void {
  282. $this->root->expects($this->any())
  283. ->method('getUser')
  284. ->willReturn($this->user);
  285. /**
  286. * @var \OC\Files\Storage\Storage | \PHPUnit\Framework\MockObject\MockObject $storage
  287. */
  288. $storage = $this->getMockBuilder('\OC\Files\Storage\Storage')
  289. ->disableOriginalConstructor()
  290. ->getMock();
  291. $node = $this->createTestNode($this->root, $this->view, '/bar/foo', [], 'foo', $storage);
  292. $this->assertEquals($storage, $node->getStorage());
  293. }
  294. public function testGetPath(): void {
  295. $this->root->expects($this->any())
  296. ->method('getUser')
  297. ->willReturn($this->user);
  298. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  299. $this->assertEquals('/bar/foo', $node->getPath());
  300. }
  301. public function testGetInternalPath(): void {
  302. $this->root->expects($this->any())
  303. ->method('getUser')
  304. ->willReturn($this->user);
  305. /**
  306. * @var \OC\Files\Storage\Storage | \PHPUnit\Framework\MockObject\MockObject $storage
  307. */
  308. $storage = $this->getMockBuilder('\OC\Files\Storage\Storage')
  309. ->disableOriginalConstructor()
  310. ->getMock();
  311. $this->view->expects($this->once())
  312. ->method('getFileInfo')
  313. ->with('/bar/foo')
  314. ->willReturn($this->getFileInfo([], 'foo'));
  315. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  316. $this->assertEquals('foo', $node->getInternalPath());
  317. }
  318. public function testGetName(): void {
  319. $this->root->expects($this->any())
  320. ->method('getUser')
  321. ->willReturn($this->user);
  322. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  323. $this->assertEquals('foo', $node->getName());
  324. }
  325. public function testTouchSetMTime(): void {
  326. $this->root->expects($this->any())
  327. ->method('getUser')
  328. ->willReturn($this->user);
  329. $this->view->expects($this->once())
  330. ->method('touch')
  331. ->with('/bar/foo', 100)
  332. ->willReturn(true);
  333. $this->view->expects($this->once())
  334. ->method('getFileInfo')
  335. ->with('/bar/foo')
  336. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_ALL]));
  337. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  338. $node->touch(100);
  339. $this->assertEquals(100, $node->getMTime());
  340. }
  341. public function testTouchHooks(): void {
  342. $test = $this;
  343. $hooksRun = 0;
  344. /**
  345. * @param \OC\Files\Node\File $node
  346. */
  347. $preListener = function ($node) use (&$test, &$hooksRun) {
  348. $test->assertEquals('foo', $node->getInternalPath());
  349. $test->assertEquals('/bar/foo', $node->getPath());
  350. $hooksRun++;
  351. };
  352. /**
  353. * @param \OC\Files\Node\File $node
  354. */
  355. $postListener = function ($node) use (&$test, &$hooksRun) {
  356. $test->assertEquals('foo', $node->getInternalPath());
  357. $test->assertEquals('/bar/foo', $node->getPath());
  358. $hooksRun++;
  359. };
  360. $root = new \OC\Files\Node\Root(
  361. $this->manager,
  362. $this->view,
  363. $this->user,
  364. $this->userMountCache,
  365. $this->logger,
  366. $this->userManager,
  367. $this->eventDispatcher,
  368. $this->cacheFactory,
  369. );
  370. $root->listen('\OC\Files', 'preTouch', $preListener);
  371. $root->listen('\OC\Files', 'postTouch', $postListener);
  372. $this->view->expects($this->once())
  373. ->method('touch')
  374. ->with('/bar/foo', 100)
  375. ->willReturn(true);
  376. $this->view->expects($this->any())
  377. ->method('getFileInfo')
  378. ->with('/bar/foo')
  379. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_ALL], 'foo'));
  380. $node = $this->createTestNode($root, $this->view, '/bar/foo');
  381. $node->touch(100);
  382. $this->assertEquals(2, $hooksRun);
  383. }
  384. public function testTouchNotPermitted(): void {
  385. $this->expectException(\OCP\Files\NotPermittedException::class);
  386. $this->root->expects($this->any())
  387. ->method('getUser')
  388. ->willReturn($this->user);
  389. $this->view->expects($this->any())
  390. ->method('getFileInfo')
  391. ->with('/bar/foo')
  392. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_READ]));
  393. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  394. $node->touch(100);
  395. }
  396. public function testInvalidPath(): void {
  397. $this->expectException(\OCP\Files\InvalidPathException::class);
  398. $node = $this->createTestNode($this->root, $this->view, '/../foo');
  399. $node->getFileInfo();
  400. }
  401. public function testCopySameStorage(): void {
  402. $this->view->expects($this->any())
  403. ->method('copy')
  404. ->with('/bar/foo', '/bar/asd')
  405. ->willReturn(true);
  406. $this->view->expects($this->any())
  407. ->method('getFileInfo')
  408. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_ALL, 'fileid' => 3]));
  409. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  410. $parentNode = new \OC\Files\Node\Folder($this->root, $this->view, '/bar');
  411. $newNode = $this->createTestNode($this->root, $this->view, '/bar/asd');
  412. $this->root->method('get')
  413. ->willReturnMap([
  414. ['/bar/asd', $newNode],
  415. ['/bar', $parentNode]
  416. ]);
  417. $target = $node->copy('/bar/asd');
  418. $this->assertInstanceOf($this->getNodeClass(), $target);
  419. $this->assertEquals(3, $target->getId());
  420. }
  421. public function testCopyNotPermitted(): void {
  422. $this->expectException(\OCP\Files\NotPermittedException::class);
  423. /**
  424. * @var \OC\Files\Storage\Storage | \PHPUnit\Framework\MockObject\MockObject $storage
  425. */
  426. $storage = $this->createMock('\OC\Files\Storage\Storage');
  427. $this->root->expects($this->never())
  428. ->method('getMount');
  429. $storage->expects($this->never())
  430. ->method('copy');
  431. $this->view->expects($this->any())
  432. ->method('getFileInfo')
  433. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_READ, 'fileid' => 3]));
  434. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  435. $parentNode = new \OC\Files\Node\Folder($this->root, $this->view, '/bar');
  436. $this->root->expects($this->once())
  437. ->method('get')
  438. ->willReturnMap([
  439. ['/bar', $parentNode]
  440. ]);
  441. $node->copy('/bar/asd');
  442. }
  443. public function testCopyNoParent(): void {
  444. $this->expectException(\OCP\Files\NotFoundException::class);
  445. $this->view->expects($this->never())
  446. ->method('copy');
  447. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  448. $this->root->expects($this->once())
  449. ->method('get')
  450. ->with('/bar/asd')
  451. ->will($this->throwException(new NotFoundException()));
  452. $node->copy('/bar/asd/foo');
  453. }
  454. public function testCopyParentIsFile(): void {
  455. $this->expectException(\OCP\Files\NotPermittedException::class);
  456. $this->view->expects($this->never())
  457. ->method('copy');
  458. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  459. $parentNode = new \OC\Files\Node\File($this->root, $this->view, '/bar');
  460. $this->root->expects($this->once())
  461. ->method('get')
  462. ->willReturnMap([
  463. ['/bar', $parentNode]
  464. ]);
  465. $node->copy('/bar/asd');
  466. }
  467. public function testMoveSameStorage(): void {
  468. $this->view->expects($this->any())
  469. ->method('rename')
  470. ->with('/bar/foo', '/bar/asd')
  471. ->willReturn(true);
  472. $this->view->expects($this->any())
  473. ->method('getFileInfo')
  474. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_ALL, 'fileid' => 1]));
  475. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  476. $parentNode = new \OC\Files\Node\Folder($this->root, $this->view, '/bar');
  477. $this->root->expects($this->any())
  478. ->method('get')
  479. ->willReturnMap([['/bar', $parentNode], ['/bar/asd', $node]]);
  480. $target = $node->move('/bar/asd');
  481. $this->assertInstanceOf($this->getNodeClass(), $target);
  482. $this->assertEquals(1, $target->getId());
  483. $this->assertEquals('/bar/asd', $node->getPath());
  484. }
  485. public function moveOrCopyProvider() {
  486. return [
  487. ['move', 'rename', 'preRename', 'postRename'],
  488. ['copy', 'copy', 'preCopy', 'postCopy'],
  489. ];
  490. }
  491. /**
  492. * @dataProvider moveOrCopyProvider
  493. * @param string $operationMethod
  494. * @param string $viewMethod
  495. * @param string $preHookName
  496. * @param string $postHookName
  497. */
  498. public function testMoveCopyHooks($operationMethod, $viewMethod, $preHookName, $postHookName): void {
  499. /** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject $root */
  500. $root = $this->getMockBuilder('\OC\Files\Node\Root')
  501. ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
  502. ->setMethods(['get'])
  503. ->getMock();
  504. $this->view->expects($this->any())
  505. ->method($viewMethod)
  506. ->with('/bar/foo', '/bar/asd')
  507. ->willReturn(true);
  508. $this->view->expects($this->any())
  509. ->method('getFileInfo')
  510. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_ALL, 'fileid' => 1]));
  511. /**
  512. * @var \OC\Files\Node\File|\PHPUnit\Framework\MockObject\MockObject $node
  513. */
  514. $node = $this->createTestNode($root, $this->view, '/bar/foo');
  515. $parentNode = new \OC\Files\Node\Folder($root, $this->view, '/bar');
  516. $targetTestNode = $this->createTestNode($root, $this->view, '/bar/asd');
  517. $root->expects($this->any())
  518. ->method('get')
  519. ->willReturnMap([['/bar', $parentNode], ['/bar/asd', $targetTestNode]]);
  520. $hooksRun = 0;
  521. $preListener = function (Node $sourceNode, Node $targetNode) use (&$hooksRun, $node) {
  522. $this->assertSame($node, $sourceNode);
  523. $this->assertInstanceOf($this->getNodeClass(), $sourceNode);
  524. $this->assertInstanceOf($this->getNonExistingNodeClass(), $targetNode);
  525. $this->assertEquals('/bar/asd', $targetNode->getPath());
  526. $hooksRun++;
  527. };
  528. $postListener = function (Node $sourceNode, Node $targetNode) use (&$hooksRun, $node, $targetTestNode) {
  529. $this->assertSame($node, $sourceNode);
  530. $this->assertNotSame($node, $targetNode);
  531. $this->assertSame($targetTestNode, $targetNode);
  532. $this->assertInstanceOf($this->getNodeClass(), $sourceNode);
  533. $this->assertInstanceOf($this->getNodeClass(), $targetNode);
  534. $hooksRun++;
  535. };
  536. $preWriteListener = function (Node $targetNode) use (&$hooksRun) {
  537. $this->assertInstanceOf($this->getNonExistingNodeClass(), $targetNode);
  538. $this->assertEquals('/bar/asd', $targetNode->getPath());
  539. $hooksRun++;
  540. };
  541. $postWriteListener = function (Node $targetNode) use (&$hooksRun, $targetTestNode) {
  542. $this->assertSame($targetTestNode, $targetNode);
  543. $hooksRun++;
  544. };
  545. $root->listen('\OC\Files', $preHookName, $preListener);
  546. $root->listen('\OC\Files', 'preWrite', $preWriteListener);
  547. $root->listen('\OC\Files', $postHookName, $postListener);
  548. $root->listen('\OC\Files', 'postWrite', $postWriteListener);
  549. $node->$operationMethod('/bar/asd');
  550. $this->assertEquals(4, $hooksRun);
  551. }
  552. public function testMoveNotPermitted(): void {
  553. $this->expectException(\OCP\Files\NotPermittedException::class);
  554. $this->view->expects($this->any())
  555. ->method('getFileInfo')
  556. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_READ]));
  557. $this->view->expects($this->never())
  558. ->method('rename');
  559. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  560. $parentNode = new \OC\Files\Node\Folder($this->root, $this->view, '/bar');
  561. $this->root->expects($this->once())
  562. ->method('get')
  563. ->with('/bar')
  564. ->willReturn($parentNode);
  565. $node->move('/bar/asd');
  566. }
  567. public function testMoveNoParent(): void {
  568. $this->expectException(\OCP\Files\NotFoundException::class);
  569. /**
  570. * @var \OC\Files\Storage\Storage | \PHPUnit\Framework\MockObject\MockObject $storage
  571. */
  572. $storage = $this->createMock('\OC\Files\Storage\Storage');
  573. $storage->expects($this->never())
  574. ->method('rename');
  575. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  576. $this->root->expects($this->once())
  577. ->method('get')
  578. ->with('/bar')
  579. ->will($this->throwException(new NotFoundException()));
  580. $node->move('/bar/asd');
  581. }
  582. public function testMoveParentIsFile(): void {
  583. $this->expectException(\OCP\Files\NotPermittedException::class);
  584. $this->view->expects($this->never())
  585. ->method('rename');
  586. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  587. $parentNode = new \OC\Files\Node\File($this->root, $this->view, '/bar');
  588. $this->root->expects($this->once())
  589. ->method('get')
  590. ->with('/bar')
  591. ->willReturn($parentNode);
  592. $node->move('/bar/asd');
  593. }
  594. public function testMoveFailed(): void {
  595. $this->expectException(\OCP\Files\NotPermittedException::class);
  596. $this->view->expects($this->any())
  597. ->method('rename')
  598. ->with('/bar/foo', '/bar/asd')
  599. ->willReturn(false);
  600. $this->view->expects($this->any())
  601. ->method('getFileInfo')
  602. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_ALL, 'fileid' => 1]));
  603. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  604. $parentNode = new \OC\Files\Node\Folder($this->root, $this->view, '/bar');
  605. $this->root->expects($this->any())
  606. ->method('get')
  607. ->willReturnMap([['/bar', $parentNode], ['/bar/asd', $node]]);
  608. $node->move('/bar/asd');
  609. }
  610. public function testCopyFailed(): void {
  611. $this->expectException(\OCP\Files\NotPermittedException::class);
  612. $this->view->expects($this->any())
  613. ->method('copy')
  614. ->with('/bar/foo', '/bar/asd')
  615. ->willReturn(false);
  616. $this->view->expects($this->any())
  617. ->method('getFileInfo')
  618. ->willReturn($this->getFileInfo(['permissions' => \OCP\Constants::PERMISSION_ALL, 'fileid' => 1]));
  619. $node = $this->createTestNode($this->root, $this->view, '/bar/foo');
  620. $parentNode = new \OC\Files\Node\Folder($this->root, $this->view, '/bar');
  621. $this->root->expects($this->any())
  622. ->method('get')
  623. ->willReturnMap([['/bar', $parentNode], ['/bar/asd', $node]]);
  624. $node->copy('/bar/asd');
  625. }
  626. }