SharesPluginTest.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Joas Schilling <coding@schilljs.com>
  6. * @author Maxence Lange <maxence@nextcloud.com>
  7. * @author Morris Jobke <hey@morrisjobke.de>
  8. * @author Robin Appelman <robin@icewind.nl>
  9. * @author Roeland Jago Douma <roeland@famdouma.nl>
  10. * @author Vincent Petry <pvince81@owncloud.com>
  11. *
  12. * @license AGPL-3.0
  13. *
  14. * This code is free software: you can redistribute it and/or modify
  15. * it under the terms of the GNU Affero General Public License, version 3,
  16. * as published by the Free Software Foundation.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Affero General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Affero General Public License, version 3,
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>
  25. *
  26. */
  27. namespace OCA\DAV\Tests\unit\Connector\Sabre;
  28. use OCA\DAV\Connector\Sabre\Directory;
  29. use OCA\DAV\Connector\Sabre\File;
  30. use OCA\DAV\Connector\Sabre\Node;
  31. use OCP\Files\Folder;
  32. use OCP\IUser;
  33. use OCP\IUserSession;
  34. use OCP\Share\IManager;
  35. use OCP\Share\IShare;
  36. use Sabre\DAV\Tree;
  37. class SharesPluginTest extends \Test\TestCase {
  38. const SHARETYPES_PROPERTYNAME = \OCA\DAV\Connector\Sabre\SharesPlugin::SHARETYPES_PROPERTYNAME;
  39. /**
  40. * @var \Sabre\DAV\Server
  41. */
  42. private $server;
  43. /**
  44. * @var \Sabre\DAV\Tree
  45. */
  46. private $tree;
  47. /**
  48. * @var \OCP\Share\IManager
  49. */
  50. private $shareManager;
  51. /**
  52. * @var \OCP\Files\Folder
  53. */
  54. private $userFolder;
  55. /**
  56. * @var \OCA\DAV\Connector\Sabre\SharesPlugin
  57. */
  58. private $plugin;
  59. protected function setUp(): void {
  60. parent::setUp();
  61. $this->server = new \Sabre\DAV\Server();
  62. $this->tree = $this->createMock(Tree::class);
  63. $this->shareManager = $this->createMock(IManager::class);
  64. $user = $this->createMock(IUser::class);
  65. $user->expects($this->once())
  66. ->method('getUID')
  67. ->will($this->returnValue('user1'));
  68. $userSession = $this->createMock(IUserSession::class);
  69. $userSession->expects($this->once())
  70. ->method('getUser')
  71. ->will($this->returnValue($user));
  72. $this->userFolder = $this->createMock(Folder::class);
  73. $this->plugin = new \OCA\DAV\Connector\Sabre\SharesPlugin(
  74. $this->tree,
  75. $userSession,
  76. $this->userFolder,
  77. $this->shareManager
  78. );
  79. $this->plugin->initialize($this->server);
  80. }
  81. /**
  82. * @dataProvider sharesGetPropertiesDataProvider
  83. */
  84. public function testGetProperties($shareTypes) {
  85. $sabreNode = $this->getMockBuilder(Node::class)
  86. ->disableOriginalConstructor()
  87. ->getMock();
  88. $sabreNode->expects($this->any())
  89. ->method('getId')
  90. ->will($this->returnValue(123));
  91. $sabreNode->expects($this->any())
  92. ->method('getPath')
  93. ->will($this->returnValue('/subdir'));
  94. // node API nodes
  95. $node = $this->getMockBuilder(Folder::class)
  96. ->disableOriginalConstructor()
  97. ->getMock();
  98. $this->userFolder->expects($this->once())
  99. ->method('get')
  100. ->with('/subdir')
  101. ->will($this->returnValue($node));
  102. $this->shareManager->expects($this->any())
  103. ->method('getSharesBy')
  104. ->with(
  105. $this->equalTo('user1'),
  106. $this->anything(),
  107. $this->anything(),
  108. $this->equalTo(false),
  109. $this->equalTo(-1)
  110. )
  111. ->will($this->returnCallback(function($userId, $requestedShareType, $node, $flag, $limit) use ($shareTypes){
  112. if (in_array($requestedShareType, $shareTypes)) {
  113. $share = $this->createMock(IShare::class);
  114. $share->method('getShareType')
  115. ->willReturn($requestedShareType);
  116. return [$share];
  117. }
  118. return [];
  119. }));
  120. $propFind = new \Sabre\DAV\PropFind(
  121. '/dummyPath',
  122. [self::SHARETYPES_PROPERTYNAME],
  123. 0
  124. );
  125. $this->plugin->handleGetProperties(
  126. $propFind,
  127. $sabreNode
  128. );
  129. $result = $propFind->getResultForMultiStatus();
  130. $this->assertEmpty($result[404]);
  131. unset($result[404]);
  132. $this->assertEquals($shareTypes, $result[200][self::SHARETYPES_PROPERTYNAME]->getShareTypes());
  133. }
  134. /**
  135. * @dataProvider sharesGetPropertiesDataProvider
  136. */
  137. public function testPreloadThenGetProperties($shareTypes) {
  138. $sabreNode1 = $this->createMock(File::class);
  139. $sabreNode1->method('getId')
  140. ->willReturn(111);
  141. $sabreNode2 = $this->createMock(File::class);
  142. $sabreNode2->method('getId')
  143. ->willReturn(222);
  144. $sabreNode2->method('getPath')
  145. ->willReturn('/subdir/foo');
  146. $sabreNode = $this->createMock(Directory::class);
  147. $sabreNode->method('getId')
  148. ->willReturn(123);
  149. // never, because we use getDirectoryListing from the Node API instead
  150. $sabreNode->expects($this->never())
  151. ->method('getChildren');
  152. $sabreNode->expects($this->any())
  153. ->method('getPath')
  154. ->will($this->returnValue('/subdir'));
  155. // node API nodes
  156. $node = $this->createMock(Folder::class);
  157. $node->method('getId')
  158. ->willReturn(123);
  159. $node1 = $this->createMock(File::class);
  160. $node1->method('getId')
  161. ->willReturn(111);
  162. $node2 = $this->createMock(File::class);
  163. $node2->method('getId')
  164. ->willReturn(222);
  165. $this->userFolder->method('get')
  166. ->with('/subdir')
  167. ->willReturn($node);
  168. $dummyShares = array_map(function($type) {
  169. $share = $this->getMockBuilder(IShare::class)->getMock();
  170. $share->expects($this->any())
  171. ->method('getShareType')
  172. ->will($this->returnValue($type));
  173. return $share;
  174. }, $shareTypes);
  175. $this->shareManager->expects($this->any())
  176. ->method('getSharesBy')
  177. ->with(
  178. $this->equalTo('user1'),
  179. $this->anything(),
  180. $this->anything(),
  181. $this->equalTo(false),
  182. $this->equalTo(-1)
  183. )
  184. ->will($this->returnCallback(function($userId, $requestedShareType, $node, $flag, $limit) use ($shareTypes, $dummyShares){
  185. if ($node->getId() === 111 && in_array($requestedShareType, $shareTypes)) {
  186. foreach ($dummyShares as $dummyShare) {
  187. if ($dummyShare->getShareType() === $requestedShareType) {
  188. return [$dummyShare];
  189. }
  190. }
  191. }
  192. return [];
  193. }));
  194. $this->shareManager->expects($this->any())
  195. ->method('getSharesInFolder')
  196. ->with(
  197. $this->equalTo('user1'),
  198. $this->anything(),
  199. $this->equalTo(true)
  200. )
  201. ->will($this->returnCallback(function ($userId, $node, $flag) use ($shareTypes, $dummyShares) {
  202. return [111 => $dummyShares];
  203. }));
  204. // simulate sabre recursive PROPFIND traversal
  205. $propFindRoot = new \Sabre\DAV\PropFind(
  206. '/subdir',
  207. [self::SHARETYPES_PROPERTYNAME],
  208. 1
  209. );
  210. $propFind1 = new \Sabre\DAV\PropFind(
  211. '/subdir/test.txt',
  212. [self::SHARETYPES_PROPERTYNAME],
  213. 0
  214. );
  215. $propFind2 = new \Sabre\DAV\PropFind(
  216. '/subdir/test2.txt',
  217. [self::SHARETYPES_PROPERTYNAME],
  218. 0
  219. );
  220. $this->plugin->handleGetProperties(
  221. $propFindRoot,
  222. $sabreNode
  223. );
  224. $this->plugin->handleGetProperties(
  225. $propFind1,
  226. $sabreNode1
  227. );
  228. $this->plugin->handleGetProperties(
  229. $propFind2,
  230. $sabreNode2
  231. );
  232. $result = $propFind1->getResultForMultiStatus();
  233. $this->assertEmpty($result[404]);
  234. unset($result[404]);
  235. $this->assertEquals($shareTypes, $result[200][self::SHARETYPES_PROPERTYNAME]->getShareTypes());
  236. }
  237. function sharesGetPropertiesDataProvider() {
  238. return [
  239. [[]],
  240. [[\OCP\Share::SHARE_TYPE_USER]],
  241. [[\OCP\Share::SHARE_TYPE_GROUP]],
  242. [[\OCP\Share::SHARE_TYPE_LINK]],
  243. [[\OCP\Share::SHARE_TYPE_REMOTE]],
  244. [[\OCP\Share::SHARE_TYPE_ROOM]],
  245. [[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP]],
  246. [[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK]],
  247. [[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK]],
  248. [[\OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK]],
  249. [[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_REMOTE]],
  250. ];
  251. }
  252. }