GroupPluginTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace Test\Collaboration\Collaborators;
  7. use OC\Collaboration\Collaborators\GroupPlugin;
  8. use OC\Collaboration\Collaborators\SearchResult;
  9. use OCP\Collaboration\Collaborators\ISearchResult;
  10. use OCP\IConfig;
  11. use OCP\IGroup;
  12. use OCP\IGroupManager;
  13. use OCP\IUser;
  14. use OCP\IUserSession;
  15. use OCP\Share\IShare;
  16. use Test\TestCase;
  17. class GroupPluginTest extends TestCase {
  18. /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
  19. protected $config;
  20. /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */
  21. protected $groupManager;
  22. /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
  23. protected $session;
  24. /** @var ISearchResult */
  25. protected $searchResult;
  26. /** @var GroupPlugin */
  27. protected $plugin;
  28. /** @var int */
  29. protected $limit = 2;
  30. /** @var int */
  31. protected $offset = 0;
  32. /** @var IUser|\PHPUnit\Framework\MockObject\MockObject */
  33. protected $user;
  34. protected function setUp(): void {
  35. parent::setUp();
  36. $this->config = $this->createMock(IConfig::class);
  37. $this->groupManager = $this->createMock(IGroupManager::class);
  38. $this->session = $this->createMock(IUserSession::class);
  39. $this->searchResult = new SearchResult();
  40. $this->user = $this->getUserMock('admin', 'Administrator');
  41. }
  42. public function instantiatePlugin() {
  43. // cannot be done within setUp, because dependent mocks needs to be set
  44. // up with configuration etc. first
  45. $this->plugin = new GroupPlugin(
  46. $this->config,
  47. $this->groupManager,
  48. $this->session
  49. );
  50. }
  51. public function getUserMock($uid, $displayName) {
  52. $user = $this->createMock(IUser::class);
  53. $user->expects($this->any())
  54. ->method('getUID')
  55. ->willReturn($uid);
  56. $user->expects($this->any())
  57. ->method('getDisplayName')
  58. ->willReturn($displayName);
  59. return $user;
  60. }
  61. /**
  62. * @param string $gid
  63. * @param null $displayName
  64. * @param bool $hide
  65. * @return IGroup|\PHPUnit\Framework\MockObject\MockObject
  66. */
  67. protected function getGroupMock($gid, $displayName = null, $hide = false) {
  68. $group = $this->createMock(IGroup::class);
  69. $group->expects($this->any())
  70. ->method('getGID')
  71. ->willReturn($gid);
  72. if (is_null($displayName)) {
  73. // note: this is how the Group class behaves
  74. $displayName = $gid;
  75. }
  76. $group->expects($this->any())
  77. ->method('getDisplayName')
  78. ->willReturn($displayName);
  79. $group->method('hideFromCollaboration')
  80. ->willReturn($hide);
  81. return $group;
  82. }
  83. public function dataGetGroups(): array {
  84. return [
  85. ['test', false, true, false, [], [], [], [], true, false],
  86. ['test', false, false, false, [], [], [], [], true, false],
  87. // group sharing disabled
  88. ['test', false, true, true, [], [], [], [], false, false],
  89. // group without display name
  90. [
  91. 'test', false, true, false,
  92. [$this->getGroupMock('test1')],
  93. [],
  94. [],
  95. [['label' => 'test1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']]],
  96. true,
  97. false,
  98. ],
  99. // group with display name, search by id
  100. [
  101. 'test', false, true, false,
  102. [$this->getGroupMock('test1', 'Test One')],
  103. [],
  104. [],
  105. [['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']]],
  106. true,
  107. false,
  108. ],
  109. // group with display name, search by display name
  110. [
  111. 'one', false, true, false,
  112. [$this->getGroupMock('test1', 'Test One')],
  113. [],
  114. [],
  115. [['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']]],
  116. true,
  117. false,
  118. ],
  119. // group with display name, search by display name, exact expected
  120. [
  121. 'Test One', false, true, false,
  122. [$this->getGroupMock('test1', 'Test One')],
  123. [],
  124. [['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']]],
  125. [],
  126. true,
  127. false,
  128. ],
  129. [
  130. 'test', false, false, false,
  131. [$this->getGroupMock('test1')],
  132. [],
  133. [],
  134. [],
  135. true,
  136. false,
  137. ],
  138. [
  139. 'test', false, true, false,
  140. [
  141. $this->getGroupMock('test'),
  142. $this->getGroupMock('test1'),
  143. ],
  144. [],
  145. [['label' => 'test', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test']]],
  146. [['label' => 'test1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']]],
  147. false,
  148. false,
  149. ],
  150. [
  151. 'test', false, false, false,
  152. [
  153. $this->getGroupMock('test'),
  154. $this->getGroupMock('test1'),
  155. ],
  156. [],
  157. [['label' => 'test', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test']]],
  158. [],
  159. true,
  160. false,
  161. ],
  162. [
  163. 'test', false, true, false,
  164. [
  165. $this->getGroupMock('test0'),
  166. $this->getGroupMock('test1'),
  167. ],
  168. [],
  169. [],
  170. [
  171. ['label' => 'test0', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test0']],
  172. ['label' => 'test1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']],
  173. ],
  174. false,
  175. null,
  176. ],
  177. [
  178. 'test', false, false, false,
  179. [
  180. $this->getGroupMock('test0'),
  181. $this->getGroupMock('test1'),
  182. ],
  183. [],
  184. [],
  185. [],
  186. true,
  187. null,
  188. ],
  189. [
  190. 'test', false, true, false,
  191. [
  192. $this->getGroupMock('test0'),
  193. $this->getGroupMock('test1'),
  194. ],
  195. [],
  196. [
  197. ['label' => 'test', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test']],
  198. ],
  199. [
  200. ['label' => 'test0', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test0']],
  201. ['label' => 'test1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']],
  202. ],
  203. false,
  204. $this->getGroupMock('test'),
  205. ],
  206. [
  207. 'test', false, false, false,
  208. [
  209. $this->getGroupMock('test0'),
  210. $this->getGroupMock('test1'),
  211. ],
  212. [],
  213. [
  214. ['label' => 'test', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test']],
  215. ],
  216. [],
  217. true,
  218. $this->getGroupMock('test'),
  219. ],
  220. ['test', true, true, false, [], [], [], [], true, false],
  221. ['test', true, false, false, [], [], [], [], true, false],
  222. [
  223. 'test', true, true, false,
  224. [
  225. $this->getGroupMock('test1'),
  226. $this->getGroupMock('test2'),
  227. ],
  228. [$this->getGroupMock('test1')],
  229. [],
  230. [['label' => 'test1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']]],
  231. false,
  232. false,
  233. ],
  234. [
  235. 'test', true, false, false,
  236. [
  237. $this->getGroupMock('test1'),
  238. $this->getGroupMock('test2'),
  239. ],
  240. [$this->getGroupMock('test1')],
  241. [],
  242. [],
  243. true,
  244. false,
  245. ],
  246. [
  247. 'test', true, true, false,
  248. [
  249. $this->getGroupMock('test'),
  250. $this->getGroupMock('test1'),
  251. ],
  252. [$this->getGroupMock('test')],
  253. [['label' => 'test', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test']]],
  254. [],
  255. false,
  256. false,
  257. ],
  258. [
  259. 'test', true, false, false,
  260. [
  261. $this->getGroupMock('test'),
  262. $this->getGroupMock('test1'),
  263. ],
  264. [$this->getGroupMock('test')],
  265. [['label' => 'test', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test']]],
  266. [],
  267. true,
  268. false,
  269. ],
  270. [
  271. 'test', true, true, false,
  272. [
  273. $this->getGroupMock('test'),
  274. $this->getGroupMock('test1'),
  275. ],
  276. [$this->getGroupMock('test1')],
  277. [],
  278. [['label' => 'test1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']]],
  279. false,
  280. false,
  281. ],
  282. [
  283. 'test', true, false, false,
  284. [
  285. $this->getGroupMock('test'),
  286. $this->getGroupMock('test1'),
  287. ],
  288. [$this->getGroupMock('test1')],
  289. [],
  290. [],
  291. true,
  292. false,
  293. ],
  294. [
  295. 'test', true, true, false,
  296. [
  297. $this->getGroupMock('test'),
  298. $this->getGroupMock('test1'),
  299. ],
  300. [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
  301. [['label' => 'test', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test']]],
  302. [['label' => 'test1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']]],
  303. false,
  304. false,
  305. ],
  306. [
  307. 'test', true, false, false,
  308. [
  309. $this->getGroupMock('test'),
  310. $this->getGroupMock('test1'),
  311. ],
  312. [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
  313. [['label' => 'test', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test']]],
  314. [],
  315. true,
  316. false,
  317. ],
  318. [
  319. 'test', true, true, false,
  320. [
  321. $this->getGroupMock('test0'),
  322. $this->getGroupMock('test1'),
  323. ],
  324. [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
  325. [],
  326. [
  327. ['label' => 'test0', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test0']],
  328. ['label' => 'test1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']],
  329. ],
  330. false,
  331. null,
  332. ],
  333. [
  334. 'test', true, false, false,
  335. [
  336. $this->getGroupMock('test0'),
  337. $this->getGroupMock('test1'),
  338. ],
  339. [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
  340. [],
  341. [],
  342. true,
  343. null,
  344. ],
  345. [
  346. 'test', true, true, false,
  347. [
  348. $this->getGroupMock('test0'),
  349. $this->getGroupMock('test1'),
  350. ],
  351. [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
  352. [
  353. ['label' => 'test', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test']],
  354. ],
  355. [
  356. ['label' => 'test0', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test0']],
  357. ['label' => 'test1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']],
  358. ],
  359. false,
  360. $this->getGroupMock('test'),
  361. ],
  362. [
  363. 'test', true, false, false,
  364. [
  365. $this->getGroupMock('test0'),
  366. $this->getGroupMock('test1'),
  367. ],
  368. [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
  369. [
  370. ['label' => 'test', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test']],
  371. ],
  372. [],
  373. true,
  374. $this->getGroupMock('test'),
  375. ],
  376. [
  377. 'test', false, false, false,
  378. [
  379. $this->getGroupMock('test', null, true),
  380. $this->getGroupMock('test1'),
  381. ],
  382. [],
  383. [],
  384. [],
  385. true,
  386. false,
  387. ],
  388. ];
  389. }
  390. /**
  391. * @dataProvider dataGetGroups
  392. *
  393. * @param string $searchTerm
  394. * @param bool $shareWithGroupOnly
  395. * @param bool $shareeEnumeration
  396. * @param bool $groupSharingDisabled
  397. * @param array $groupResponse
  398. * @param array $userGroupsResponse
  399. * @param array $exactExpected
  400. * @param array $expected
  401. * @param bool $reachedEnd
  402. * @param bool|IGroup $singleGroup
  403. */
  404. public function testSearch(
  405. string $searchTerm,
  406. bool $shareWithGroupOnly,
  407. bool $shareeEnumeration,
  408. bool $groupSharingDisabled,
  409. array $groupResponse,
  410. array $userGroupsResponse,
  411. array $exactExpected,
  412. array $expected,
  413. bool $reachedEnd,
  414. $singleGroup
  415. ): void {
  416. $this->config->expects($this->any())
  417. ->method('getAppValue')
  418. ->willReturnCallback(
  419. function ($appName, $key, $default) use ($shareWithGroupOnly, $shareeEnumeration, $groupSharingDisabled) {
  420. if ($appName !== 'core') {
  421. return $default;
  422. }
  423. switch ($key) {
  424. case 'shareapi_only_share_with_group_members':
  425. return $shareWithGroupOnly ? 'yes' : 'no';
  426. case 'shareapi_allow_share_dialog_user_enumeration':
  427. return $shareeEnumeration ? 'yes' : 'no';
  428. case 'shareapi_allow_group_sharing':
  429. return $groupSharingDisabled ? 'no' : 'yes';
  430. default:
  431. return $default;
  432. }
  433. }
  434. );
  435. $this->instantiatePlugin();
  436. if (!$groupSharingDisabled) {
  437. $this->groupManager->expects($this->once())
  438. ->method('search')
  439. ->with($searchTerm, $this->limit, $this->offset)
  440. ->willReturn($groupResponse);
  441. }
  442. if ($singleGroup !== false) {
  443. $this->groupManager->expects($this->once())
  444. ->method('get')
  445. ->with($searchTerm)
  446. ->willReturn($singleGroup);
  447. }
  448. if ($shareWithGroupOnly) {
  449. $this->session->expects($this->any())
  450. ->method('getUser')
  451. ->willReturn($this->user);
  452. $numGetUserGroupsCalls = empty($groupResponse) ? 0 : 1;
  453. $this->groupManager->expects($this->exactly($numGetUserGroupsCalls))
  454. ->method('getUserGroups')
  455. ->with($this->user)
  456. ->willReturn($userGroupsResponse);
  457. }
  458. $moreResults = $this->plugin->search($searchTerm, $this->limit, $this->offset, $this->searchResult);
  459. $result = $this->searchResult->asArray();
  460. if (!$groupSharingDisabled) {
  461. $this->assertEquals($exactExpected, $result['exact']['groups']);
  462. $this->assertEquals($expected, $result['groups']);
  463. }
  464. $this->assertSame($reachedEnd, $moreResults);
  465. }
  466. }