SharesPluginTest.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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\DAV\Tests\unit\Connector\Sabre;
  8. use OCA\DAV\Connector\Sabre\Directory;
  9. use OCA\DAV\Connector\Sabre\File;
  10. use OCA\DAV\Connector\Sabre\Node;
  11. use OCA\DAV\Connector\Sabre\SharesPlugin;
  12. use OCA\DAV\Upload\UploadFile;
  13. use OCP\Files\Folder;
  14. use OCP\IUser;
  15. use OCP\IUserSession;
  16. use OCP\Share\IManager;
  17. use OCP\Share\IShare;
  18. use Sabre\DAV\Tree;
  19. class SharesPluginTest extends \Test\TestCase {
  20. public const SHARETYPES_PROPERTYNAME = SharesPlugin::SHARETYPES_PROPERTYNAME;
  21. /**
  22. * @var \Sabre\DAV\Server
  23. */
  24. private $server;
  25. /**
  26. * @var \Sabre\DAV\Tree
  27. */
  28. private $tree;
  29. /**
  30. * @var \OCP\Share\IManager
  31. */
  32. private $shareManager;
  33. /**
  34. * @var Folder
  35. */
  36. private $userFolder;
  37. /**
  38. * @var SharesPlugin
  39. */
  40. private $plugin;
  41. protected function setUp(): void {
  42. parent::setUp();
  43. $this->server = new \Sabre\DAV\Server();
  44. $this->tree = $this->createMock(Tree::class);
  45. $this->shareManager = $this->createMock(IManager::class);
  46. $user = $this->createMock(IUser::class);
  47. $user->expects($this->once())
  48. ->method('getUID')
  49. ->willReturn('user1');
  50. $userSession = $this->createMock(IUserSession::class);
  51. $userSession->expects($this->once())
  52. ->method('getUser')
  53. ->willReturn($user);
  54. $this->userFolder = $this->createMock(Folder::class);
  55. $this->plugin = new SharesPlugin(
  56. $this->tree,
  57. $userSession,
  58. $this->userFolder,
  59. $this->shareManager
  60. );
  61. $this->plugin->initialize($this->server);
  62. }
  63. /**
  64. * @dataProvider sharesGetPropertiesDataProvider
  65. */
  66. public function testGetProperties($shareTypes): void {
  67. $sabreNode = $this->getMockBuilder(Node::class)
  68. ->disableOriginalConstructor()
  69. ->getMock();
  70. $sabreNode->expects($this->any())
  71. ->method('getId')
  72. ->willReturn(123);
  73. $sabreNode->expects($this->any())
  74. ->method('getPath')
  75. ->willReturn('/subdir');
  76. // node API nodes
  77. $node = $this->getMockBuilder(Folder::class)
  78. ->disableOriginalConstructor()
  79. ->getMock();
  80. $sabreNode->method('getNode')
  81. ->willReturn($node);
  82. $this->shareManager->expects($this->any())
  83. ->method('getSharesBy')
  84. ->with(
  85. $this->equalTo('user1'),
  86. $this->anything(),
  87. $this->equalTo($node),
  88. $this->equalTo(false),
  89. $this->equalTo(-1)
  90. )
  91. ->willReturnCallback(function ($userId, $requestedShareType, $node, $flag, $limit) use ($shareTypes) {
  92. if (in_array($requestedShareType, $shareTypes)) {
  93. $share = $this->createMock(IShare::class);
  94. $share->method('getShareType')
  95. ->willReturn($requestedShareType);
  96. return [$share];
  97. }
  98. return [];
  99. });
  100. $this->shareManager->expects($this->any())
  101. ->method('getSharedWith')
  102. ->with(
  103. $this->equalTo('user1'),
  104. $this->anything(),
  105. $this->equalTo($node),
  106. $this->equalTo(-1)
  107. )
  108. ->willReturn([]);
  109. $propFind = new \Sabre\DAV\PropFind(
  110. '/dummyPath',
  111. [self::SHARETYPES_PROPERTYNAME],
  112. 0
  113. );
  114. $this->plugin->handleGetProperties(
  115. $propFind,
  116. $sabreNode
  117. );
  118. $result = $propFind->getResultForMultiStatus();
  119. $this->assertEmpty($result[404]);
  120. unset($result[404]);
  121. $this->assertEquals($shareTypes, $result[200][self::SHARETYPES_PROPERTYNAME]->getShareTypes());
  122. }
  123. /**
  124. * @dataProvider sharesGetPropertiesDataProvider
  125. */
  126. public function testPreloadThenGetProperties($shareTypes): void {
  127. $sabreNode1 = $this->createMock(File::class);
  128. $sabreNode1->method('getId')
  129. ->willReturn(111);
  130. $sabreNode2 = $this->createMock(File::class);
  131. $sabreNode2->method('getId')
  132. ->willReturn(222);
  133. $sabreNode2->method('getPath')
  134. ->willReturn('/subdir/foo');
  135. $sabreNode = $this->createMock(Directory::class);
  136. $sabreNode->method('getId')
  137. ->willReturn(123);
  138. // never, because we use getDirectoryListing from the Node API instead
  139. $sabreNode->expects($this->never())
  140. ->method('getChildren');
  141. $sabreNode->expects($this->any())
  142. ->method('getPath')
  143. ->willReturn('/subdir');
  144. // node API nodes
  145. $node = $this->createMock(Folder::class);
  146. $node->method('getId')
  147. ->willReturn(123);
  148. $node1 = $this->createMock(\OC\Files\Node\File::class);
  149. $node1->method('getId')
  150. ->willReturn(111);
  151. $node2 = $this->createMock(\OC\Files\Node\File::class);
  152. $node2->method('getId')
  153. ->willReturn(222);
  154. $sabreNode->method('getNode')
  155. ->willReturn($node);
  156. $sabreNode1->method('getNode')
  157. ->willReturn($node1);
  158. $sabreNode2->method('getNode')
  159. ->willReturn($node2);
  160. $dummyShares = array_map(function ($type) {
  161. $share = $this->getMockBuilder(IShare::class)->getMock();
  162. $share->expects($this->any())
  163. ->method('getShareType')
  164. ->willReturn($type);
  165. return $share;
  166. }, $shareTypes);
  167. $this->shareManager->expects($this->any())
  168. ->method('getSharesBy')
  169. ->with(
  170. $this->equalTo('user1'),
  171. $this->anything(),
  172. $this->anything(),
  173. $this->equalTo(false),
  174. $this->equalTo(-1)
  175. )
  176. ->willReturnCallback(function ($userId, $requestedShareType, $node, $flag, $limit) use ($shareTypes, $dummyShares) {
  177. if ($node->getId() === 111 && in_array($requestedShareType, $shareTypes)) {
  178. foreach ($dummyShares as $dummyShare) {
  179. if ($dummyShare->getShareType() === $requestedShareType) {
  180. return [$dummyShare];
  181. }
  182. }
  183. }
  184. return [];
  185. });
  186. $this->shareManager->expects($this->any())
  187. ->method('getSharedWith')
  188. ->with(
  189. $this->equalTo('user1'),
  190. $this->anything(),
  191. $this->equalTo($node),
  192. $this->equalTo(-1)
  193. )
  194. ->willReturn([]);
  195. $this->shareManager->expects($this->any())
  196. ->method('getSharesInFolder')
  197. ->with(
  198. $this->equalTo('user1'),
  199. $this->anything(),
  200. $this->equalTo(true)
  201. )
  202. ->willReturnCallback(function ($userId, $node, $flag) use ($shareTypes, $dummyShares) {
  203. return [111 => $dummyShares];
  204. });
  205. // simulate sabre recursive PROPFIND traversal
  206. $propFindRoot = new \Sabre\DAV\PropFind(
  207. '/subdir',
  208. [self::SHARETYPES_PROPERTYNAME],
  209. 1
  210. );
  211. $propFind1 = new \Sabre\DAV\PropFind(
  212. '/subdir/test.txt',
  213. [self::SHARETYPES_PROPERTYNAME],
  214. 0
  215. );
  216. $propFind2 = new \Sabre\DAV\PropFind(
  217. '/subdir/test2.txt',
  218. [self::SHARETYPES_PROPERTYNAME],
  219. 0
  220. );
  221. $this->plugin->handleGetProperties(
  222. $propFindRoot,
  223. $sabreNode
  224. );
  225. $this->plugin->handleGetProperties(
  226. $propFind1,
  227. $sabreNode1
  228. );
  229. $this->plugin->handleGetProperties(
  230. $propFind2,
  231. $sabreNode2
  232. );
  233. $result = $propFind1->getResultForMultiStatus();
  234. $this->assertEmpty($result[404]);
  235. unset($result[404]);
  236. $this->assertEquals($shareTypes, $result[200][self::SHARETYPES_PROPERTYNAME]->getShareTypes());
  237. }
  238. public function sharesGetPropertiesDataProvider() {
  239. return [
  240. [[]],
  241. [[IShare::TYPE_USER]],
  242. [[IShare::TYPE_GROUP]],
  243. [[IShare::TYPE_LINK]],
  244. [[IShare::TYPE_REMOTE]],
  245. [[IShare::TYPE_ROOM]],
  246. [[IShare::TYPE_DECK]],
  247. [[IShare::TYPE_SCIENCEMESH]],
  248. [[IShare::TYPE_USER, IShare::TYPE_GROUP]],
  249. [[IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_LINK]],
  250. [[IShare::TYPE_USER, IShare::TYPE_LINK]],
  251. [[IShare::TYPE_GROUP, IShare::TYPE_LINK]],
  252. [[IShare::TYPE_USER, IShare::TYPE_REMOTE]],
  253. ];
  254. }
  255. public function testGetPropertiesSkipChunks(): void {
  256. $sabreNode = $this->getMockBuilder(UploadFile::class)
  257. ->disableOriginalConstructor()
  258. ->getMock();
  259. $propFind = new \Sabre\DAV\PropFind(
  260. '/dummyPath',
  261. [self::SHARETYPES_PROPERTYNAME],
  262. 0
  263. );
  264. $this->plugin->handleGetProperties(
  265. $propFind,
  266. $sabreNode
  267. );
  268. $result = $propFind->getResultForMultiStatus();
  269. $this->assertCount(1, $result[404]);
  270. }
  271. }