SharedStorageTest.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  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-only
  6. */
  7. namespace OCA\Files_Sharing\Tests;
  8. use OC\Files\Cache\FailedCache;
  9. use OC\Files\Filesystem;
  10. use OC\Files\Storage\FailedStorage;
  11. use OC\Files\Storage\Storage;
  12. use OC\Files\Storage\Temporary;
  13. use OC\Files\View;
  14. use OCA\Files_Sharing\SharedStorage;
  15. use OCA\Files_Trashbin\AppInfo\Application;
  16. use OCP\AppFramework\Bootstrap\IBootContext;
  17. use OCP\Constants;
  18. use OCP\Files\NotFoundException;
  19. use OCP\Share\IShare;
  20. /**
  21. * Class SharedStorageTest
  22. *
  23. * @group DB
  24. */
  25. class SharedStorageTest extends TestCase {
  26. protected function setUp(): void {
  27. parent::setUp();
  28. // register trashbin hooks
  29. $trashbinApp = new Application();
  30. $trashbinApp->boot($this->createMock(IBootContext::class));
  31. $this->folder = '/folder_share_storage_test';
  32. $this->filename = '/share-api-storage.txt';
  33. $this->view->mkdir($this->folder);
  34. // save file with content
  35. $this->view->file_put_contents($this->filename, 'root file');
  36. $this->view->file_put_contents($this->folder . $this->filename, 'file in subfolder');
  37. }
  38. protected function tearDown(): void {
  39. if ($this->view) {
  40. if ($this->view->file_exists($this->folder)) {
  41. $this->view->unlink($this->folder);
  42. }
  43. if ($this->view->file_exists($this->filename)) {
  44. $this->view->unlink($this->filename);
  45. }
  46. }
  47. Filesystem::getLoader()->removeStorageWrapper('oc_trashbin');
  48. parent::tearDown();
  49. }
  50. /**
  51. * if the parent of the mount point is gone then the mount point should move up
  52. *
  53. * @medium
  54. */
  55. public function testParentOfMountPointIsGone(): void {
  56. // share to user
  57. $share = $this->share(
  58. IShare::TYPE_USER,
  59. $this->folder,
  60. self::TEST_FILES_SHARING_API_USER1,
  61. self::TEST_FILES_SHARING_API_USER2,
  62. Constants::PERMISSION_ALL
  63. );
  64. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  65. $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
  66. $this->assertTrue($user2View->file_exists($this->folder));
  67. // create a local folder
  68. $result = $user2View->mkdir('localfolder');
  69. $this->assertTrue($result);
  70. // move mount point to local folder
  71. $result = $user2View->rename($this->folder, '/localfolder/' . $this->folder);
  72. $this->assertTrue($result);
  73. // mount point in the root folder should no longer exist
  74. $this->assertFalse($user2View->is_dir($this->folder));
  75. // delete the local folder
  76. /** @var Storage $storage */
  77. [$storage, $internalPath] = Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/localfolder');
  78. $storage->rmdir($internalPath);
  79. //enforce reload of the mount points
  80. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  81. //mount point should be back at the root
  82. $this->assertTrue($user2View->is_dir($this->folder));
  83. //cleanup
  84. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  85. $this->view->unlink($this->folder);
  86. }
  87. /**
  88. * @medium
  89. */
  90. public function testRenamePartFile(): void {
  91. // share to user
  92. $share = $this->share(
  93. IShare::TYPE_USER,
  94. $this->folder,
  95. self::TEST_FILES_SHARING_API_USER1,
  96. self::TEST_FILES_SHARING_API_USER2,
  97. Constants::PERMISSION_ALL
  98. );
  99. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  100. $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
  101. $this->assertTrue($user2View->file_exists($this->folder));
  102. // create part file
  103. $result = $user2View->file_put_contents($this->folder . '/foo.txt.part', 'some test data');
  104. $this->assertTrue(is_int($result));
  105. // rename part file to real file
  106. $result = $user2View->rename($this->folder . '/foo.txt.part', $this->folder . '/foo.txt');
  107. $this->assertTrue($result);
  108. // check if the new file really exists
  109. $this->assertTrue($user2View->file_exists($this->folder . '/foo.txt'));
  110. // check if the rename also affected the owner
  111. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  112. $this->assertTrue($this->view->file_exists($this->folder . '/foo.txt'));
  113. //cleanup
  114. $this->shareManager->deleteShare($share);
  115. }
  116. public function testFilesize(): void {
  117. $folderSize = $this->view->filesize($this->folder);
  118. $file1Size = $this->view->filesize($this->folder . $this->filename);
  119. $file2Size = $this->view->filesize($this->filename);
  120. $share1 = $this->share(
  121. IShare::TYPE_USER,
  122. $this->folder,
  123. self::TEST_FILES_SHARING_API_USER1,
  124. self::TEST_FILES_SHARING_API_USER2,
  125. Constants::PERMISSION_ALL
  126. );
  127. $share2 = $this->share(
  128. IShare::TYPE_USER,
  129. $this->filename,
  130. self::TEST_FILES_SHARING_API_USER1,
  131. self::TEST_FILES_SHARING_API_USER2,
  132. Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE
  133. );
  134. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  135. // compare file size between user1 and user2, should always be the same
  136. $this->assertSame($folderSize, Filesystem::filesize($this->folder));
  137. $this->assertSame($file1Size, Filesystem::filesize($this->folder . $this->filename));
  138. $this->assertSame($file2Size, Filesystem::filesize($this->filename));
  139. //cleanup
  140. $this->shareManager->deleteShare($share1);
  141. $this->shareManager->deleteShare($share2);
  142. }
  143. public function testGetPermissions(): void {
  144. $share = $this->share(
  145. IShare::TYPE_USER,
  146. $this->folder,
  147. self::TEST_FILES_SHARING_API_USER1,
  148. self::TEST_FILES_SHARING_API_USER2,
  149. Constants::PERMISSION_READ
  150. );
  151. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  152. $this->assertTrue(Filesystem::is_dir($this->folder));
  153. // for the share root we expect:
  154. // the read permissions (1)
  155. // the delete permission (8), to enable unshare
  156. $rootInfo = Filesystem::getFileInfo($this->folder);
  157. $this->assertSame(9, $rootInfo->getPermissions());
  158. // for the file within the shared folder we expect:
  159. // the read permissions (1)
  160. $subfileInfo = Filesystem::getFileInfo($this->folder . $this->filename);
  161. $this->assertSame(1, $subfileInfo->getPermissions());
  162. //cleanup
  163. $this->shareManager->deleteShare($share);
  164. }
  165. public function testFopenWithReadOnlyPermission(): void {
  166. $this->view->file_put_contents($this->folder . '/existing.txt', 'foo');
  167. $share = $this->share(
  168. IShare::TYPE_USER,
  169. $this->folder,
  170. self::TEST_FILES_SHARING_API_USER1,
  171. self::TEST_FILES_SHARING_API_USER2,
  172. Constants::PERMISSION_READ
  173. );
  174. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  175. $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
  176. // part file should be forbidden
  177. $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w');
  178. $this->assertFalse($handle);
  179. // regular file forbidden
  180. $handle = $user2View->fopen($this->folder . '/test.txt', 'w');
  181. $this->assertFalse($handle);
  182. // rename forbidden
  183. $this->assertFalse($user2View->rename($this->folder . '/existing.txt', $this->folder . '/existing2.txt'));
  184. // delete forbidden
  185. $this->assertFalse($user2View->unlink($this->folder . '/existing.txt'));
  186. //cleanup
  187. $this->shareManager->deleteShare($share);
  188. }
  189. public function testFopenWithCreateOnlyPermission(): void {
  190. $this->view->file_put_contents($this->folder . '/existing.txt', 'foo');
  191. $fileinfoFolder = $this->view->getFileInfo($this->folder);
  192. $share = $this->share(
  193. IShare::TYPE_USER,
  194. $this->folder,
  195. self::TEST_FILES_SHARING_API_USER1,
  196. self::TEST_FILES_SHARING_API_USER2,
  197. Constants::PERMISSION_READ | Constants::PERMISSION_CREATE
  198. );
  199. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  200. $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
  201. // create part file allowed
  202. $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w');
  203. $this->assertNotFalse($handle);
  204. fclose($handle);
  205. // create regular file allowed
  206. $handle = $user2View->fopen($this->folder . '/test-create.txt', 'w');
  207. $this->assertNotFalse($handle);
  208. fclose($handle);
  209. // rename file never allowed
  210. $this->assertFalse($user2View->rename($this->folder . '/test-create.txt', $this->folder . '/newtarget.txt'));
  211. $this->assertFalse($user2View->file_exists($this->folder . '/newtarget.txt'));
  212. // rename file not allowed if target exists
  213. $this->assertFalse($user2View->rename($this->folder . '/newtarget.txt', $this->folder . '/existing.txt'));
  214. // overwriting file not allowed
  215. $handle = $user2View->fopen($this->folder . '/existing.txt', 'w');
  216. $this->assertFalse($handle);
  217. // overwrite forbidden (no update permission)
  218. $this->assertFalse($user2View->rename($this->folder . '/test.txt.part', $this->folder . '/existing.txt'));
  219. // delete forbidden
  220. $this->assertFalse($user2View->unlink($this->folder . '/existing.txt'));
  221. //cleanup
  222. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  223. $this->shareManager->deleteShare($share);
  224. }
  225. public function testFopenWithUpdateOnlyPermission(): void {
  226. $this->view->file_put_contents($this->folder . '/existing.txt', 'foo');
  227. $share = $this->share(
  228. IShare::TYPE_USER,
  229. $this->folder,
  230. self::TEST_FILES_SHARING_API_USER1,
  231. self::TEST_FILES_SHARING_API_USER2,
  232. Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE
  233. );
  234. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  235. $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
  236. // create part file allowed
  237. $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w');
  238. $this->assertNotFalse($handle);
  239. fclose($handle);
  240. // create regular file not allowed
  241. $handle = $user2View->fopen($this->folder . '/test-create.txt', 'w');
  242. $this->assertFalse($handle);
  243. // rename part file not allowed to non-existing file
  244. $this->assertFalse($user2View->rename($this->folder . '/test.txt.part', $this->folder . '/nonexist.txt'));
  245. // rename part file allowed to target existing file
  246. $this->assertTrue($user2View->rename($this->folder . '/test.txt.part', $this->folder . '/existing.txt'));
  247. $this->assertTrue($user2View->file_exists($this->folder . '/existing.txt'));
  248. // rename regular file allowed
  249. $this->assertTrue($user2View->rename($this->folder . '/existing.txt', $this->folder . '/existing-renamed.txt'));
  250. $this->assertTrue($user2View->file_exists($this->folder . '/existing-renamed.txt'));
  251. // overwriting file directly is allowed
  252. $handle = $user2View->fopen($this->folder . '/existing-renamed.txt', 'w');
  253. $this->assertNotFalse($handle);
  254. fclose($handle);
  255. // delete forbidden
  256. $this->assertFalse($user2View->unlink($this->folder . '/existing-renamed.txt'));
  257. //cleanup
  258. $this->shareManager->deleteShare($share);
  259. }
  260. public function testFopenWithDeleteOnlyPermission(): void {
  261. $this->view->file_put_contents($this->folder . '/existing.txt', 'foo');
  262. $share = $this->share(
  263. IShare::TYPE_USER,
  264. $this->folder,
  265. self::TEST_FILES_SHARING_API_USER1,
  266. self::TEST_FILES_SHARING_API_USER2,
  267. Constants::PERMISSION_READ | Constants::PERMISSION_DELETE
  268. );
  269. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  270. $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
  271. // part file should be forbidden
  272. $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w');
  273. $this->assertFalse($handle);
  274. // regular file forbidden
  275. $handle = $user2View->fopen($this->folder . '/test.txt', 'w');
  276. $this->assertFalse($handle);
  277. // rename forbidden
  278. $this->assertFalse($user2View->rename($this->folder . '/existing.txt', $this->folder . '/existing2.txt'));
  279. // delete allowed
  280. $this->assertTrue($user2View->unlink($this->folder . '/existing.txt'));
  281. //cleanup
  282. $this->shareManager->deleteShare($share);
  283. }
  284. public function testMountSharesOtherUser(): void {
  285. $rootView = new View('');
  286. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  287. // share 2 different files with 2 different users
  288. $share1 = $this->share(
  289. IShare::TYPE_USER,
  290. $this->folder,
  291. self::TEST_FILES_SHARING_API_USER1,
  292. self::TEST_FILES_SHARING_API_USER2,
  293. Constants::PERMISSION_ALL
  294. );
  295. $share2 = $this->share(
  296. IShare::TYPE_USER,
  297. $this->filename,
  298. self::TEST_FILES_SHARING_API_USER1,
  299. self::TEST_FILES_SHARING_API_USER3,
  300. Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE
  301. );
  302. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  303. $this->assertTrue($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/' . $this->folder));
  304. $mountConfigManager = \OC::$server->getMountProviderCollection();
  305. $mounts = $mountConfigManager->getMountsForUser(\OC::$server->getUserManager()->get(self::TEST_FILES_SHARING_API_USER3));
  306. array_walk($mounts, [Filesystem::getMountManager(), 'addMount']);
  307. $this->assertTrue($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER3 . '/files/' . $this->filename));
  308. // make sure we didn't double setup shares for user 2 or mounted the shares for user 3 in user's 2 home
  309. $this->assertFalse($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/' . $this->folder . ' (2)'));
  310. $this->assertFalse($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/' . $this->filename));
  311. //cleanup
  312. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  313. $this->view->unlink($this->folder);
  314. $this->shareManager->deleteShare($share1);
  315. $this->shareManager->deleteShare($share2);
  316. }
  317. public function testCopyFromStorage(): void {
  318. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  319. $share = $this->share(
  320. IShare::TYPE_USER,
  321. $this->folder,
  322. self::TEST_FILES_SHARING_API_USER1,
  323. self::TEST_FILES_SHARING_API_USER2,
  324. Constants::PERMISSION_ALL
  325. );
  326. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  327. $view = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
  328. $this->assertTrue($view->file_exists($this->folder));
  329. [$sharedStorage,] = $view->resolvePath($this->folder);
  330. $this->assertTrue($sharedStorage->instanceOfStorage('OCA\Files_Sharing\ISharedStorage'));
  331. $sourceStorage = new Temporary([]);
  332. $sourceStorage->file_put_contents('foo.txt', 'asd');
  333. $sharedStorage->copyFromStorage($sourceStorage, 'foo.txt', 'bar.txt');
  334. $this->assertTrue($sharedStorage->file_exists('bar.txt'));
  335. $this->assertEquals('asd', $sharedStorage->file_get_contents('bar.txt'));
  336. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  337. $this->view->unlink($this->folder);
  338. $this->shareManager->deleteShare($share);
  339. }
  340. public function testMoveFromStorage(): void {
  341. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  342. $share = $this->share(
  343. IShare::TYPE_USER,
  344. $this->folder,
  345. self::TEST_FILES_SHARING_API_USER1,
  346. self::TEST_FILES_SHARING_API_USER2,
  347. Constants::PERMISSION_ALL
  348. );
  349. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  350. $view = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
  351. $this->assertTrue($view->file_exists($this->folder));
  352. [$sharedStorage,] = $view->resolvePath($this->folder);
  353. $this->assertTrue($sharedStorage->instanceOfStorage('OCA\Files_Sharing\ISharedStorage'));
  354. $sourceStorage = new Temporary([]);
  355. $sourceStorage->file_put_contents('foo.txt', 'asd');
  356. $sourceStorage->getScanner()->scan('');
  357. $sharedStorage->moveFromStorage($sourceStorage, 'foo.txt', 'bar.txt');
  358. $this->assertTrue($sharedStorage->file_exists('bar.txt'));
  359. $this->assertEquals('asd', $sharedStorage->file_get_contents('bar.txt'));
  360. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  361. $this->view->unlink($this->folder);
  362. $this->shareManager->deleteShare($share);
  363. }
  364. public function testNameConflict(): void {
  365. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  366. $view1 = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
  367. $view1->mkdir('foo');
  368. self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
  369. $view3 = new View('/' . self::TEST_FILES_SHARING_API_USER3 . '/files');
  370. $view3->mkdir('foo');
  371. // share a folder with the same name from two different users to the same user
  372. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  373. $share1 = $this->share(
  374. IShare::TYPE_GROUP,
  375. 'foo',
  376. self::TEST_FILES_SHARING_API_USER1,
  377. self::TEST_FILES_SHARING_API_GROUP1,
  378. Constants::PERMISSION_ALL
  379. );
  380. $this->shareManager->acceptShare($share1, self::TEST_FILES_SHARING_API_USER2);
  381. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  382. self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
  383. $share2 = $this->share(
  384. IShare::TYPE_GROUP,
  385. 'foo',
  386. self::TEST_FILES_SHARING_API_USER3,
  387. self::TEST_FILES_SHARING_API_GROUP1,
  388. Constants::PERMISSION_ALL
  389. );
  390. $this->shareManager->acceptShare($share2, self::TEST_FILES_SHARING_API_USER2);
  391. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  392. $view2 = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
  393. $this->assertTrue($view2->file_exists('/foo'));
  394. $this->assertTrue($view2->file_exists('/foo (2)'));
  395. $mount = $view2->getMount('/foo');
  396. $this->assertInstanceOf('\OCA\Files_Sharing\SharedMount', $mount);
  397. /** @var SharedStorage $storage */
  398. $storage = $mount->getStorage();
  399. $this->assertEquals(self::TEST_FILES_SHARING_API_USER1, $storage->getOwner(''));
  400. $this->shareManager->deleteShare($share1);
  401. $this->shareManager->deleteShare($share2);
  402. }
  403. public function testOwnerPermissions(): void {
  404. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  405. $share = $this->share(
  406. IShare::TYPE_USER,
  407. $this->folder,
  408. self::TEST_FILES_SHARING_API_USER1,
  409. self::TEST_FILES_SHARING_API_USER2,
  410. Constants::PERMISSION_ALL - Constants::PERMISSION_DELETE
  411. );
  412. self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
  413. $view = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
  414. $this->assertTrue($view->file_exists($this->folder));
  415. $view->file_put_contents($this->folder . '/newfile.txt', 'asd');
  416. self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
  417. $this->assertTrue($this->view->file_exists($this->folder . '/newfile.txt'));
  418. $this->assertEquals(Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE,
  419. $this->view->getFileInfo($this->folder . '/newfile.txt')->getPermissions());
  420. $this->view->unlink($this->folder);
  421. $this->shareManager->deleteShare($share);
  422. }
  423. public function testInitWithNonExistingUser(): void {
  424. $share = $this->createMock(IShare::class);
  425. $share->method('getShareOwner')->willReturn('unexist');
  426. $ownerView = $this->createMock(View::class);
  427. $storage = new SharedStorage([
  428. 'ownerView' => $ownerView,
  429. 'superShare' => $share,
  430. 'groupedShares' => [$share],
  431. 'user' => 'user1',
  432. ]);
  433. // trigger init
  434. $this->assertInstanceOf(FailedStorage::class, $storage->getSourceStorage());
  435. $this->assertInstanceOf(FailedCache::class, $storage->getCache());
  436. }
  437. public function testInitWithNotFoundSource(): void {
  438. $share = $this->createMock(IShare::class);
  439. $share->method('getShareOwner')->willReturn(self::TEST_FILES_SHARING_API_USER1);
  440. $share->method('getNodeId')->willReturn(1);
  441. $ownerView = $this->createMock(View::class);
  442. $ownerView->method('getPath')->will($this->throwException(new NotFoundException()));
  443. $storage = new SharedStorage([
  444. 'ownerView' => $ownerView,
  445. 'superShare' => $share,
  446. 'groupedShares' => [$share],
  447. 'user' => 'user1',
  448. ]);
  449. // trigger init
  450. $this->assertInstanceOf(FailedStorage::class, $storage->getSourceStorage());
  451. $this->assertInstanceOf(FailedCache::class, $storage->getCache());
  452. }
  453. }