SearchTest.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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\Search;
  8. use OC\Collaboration\Collaborators\SearchResult;
  9. use OCP\Collaboration\Collaborators\ISearch;
  10. use OCP\Collaboration\Collaborators\ISearchPlugin;
  11. use OCP\Collaboration\Collaborators\SearchResultType;
  12. use OCP\IContainer;
  13. use OCP\Share\IShare;
  14. use Test\TestCase;
  15. class SearchTest extends TestCase {
  16. /** @var IContainer|\PHPUnit\Framework\MockObject\MockObject */
  17. protected $container;
  18. /** @var ISearch */
  19. protected $search;
  20. protected function setUp(): void {
  21. parent::setUp();
  22. $this->container = $this->createMock(IContainer::class);
  23. $this->search = new Search($this->container);
  24. }
  25. /**
  26. * @dataProvider dataSearchSharees
  27. */
  28. public function testSearch(
  29. string $searchTerm,
  30. array $shareTypes,
  31. int $page,
  32. int $perPage,
  33. array $mockedUserResult,
  34. array $mockedGroupsResult,
  35. array $mockedRemotesResult,
  36. array $mockedMailResult,
  37. array $expected,
  38. bool $expectedMoreResults
  39. ): void {
  40. $searchResult = new SearchResult();
  41. $userPlugin = $this->createMock(ISearchPlugin::class);
  42. $userPlugin->expects($this->any())
  43. ->method('search')
  44. ->willReturnCallback(function () use ($searchResult, $mockedUserResult, $expectedMoreResults) {
  45. $type = new SearchResultType('users');
  46. $searchResult->addResultSet($type, $mockedUserResult);
  47. return $expectedMoreResults;
  48. });
  49. $groupPlugin = $this->createMock(ISearchPlugin::class);
  50. $groupPlugin->expects($this->any())
  51. ->method('search')
  52. ->willReturnCallback(function () use ($searchResult, $mockedGroupsResult, $expectedMoreResults) {
  53. $type = new SearchResultType('groups');
  54. $searchResult->addResultSet($type, $mockedGroupsResult);
  55. return $expectedMoreResults;
  56. });
  57. $remotePlugin = $this->createMock(ISearchPlugin::class);
  58. $remotePlugin->expects($this->any())
  59. ->method('search')
  60. ->willReturnCallback(function () use ($searchResult, $mockedRemotesResult, $expectedMoreResults) {
  61. if ($mockedRemotesResult !== null) {
  62. $type = new SearchResultType('remotes');
  63. $searchResult->addResultSet($type, $mockedRemotesResult['results'], $mockedRemotesResult['exact']);
  64. if ($mockedRemotesResult['exactIdMatch'] === true) {
  65. $searchResult->markExactIdMatch($type);
  66. }
  67. }
  68. return $expectedMoreResults;
  69. });
  70. $mailPlugin = $this->createMock(ISearchPlugin::class);
  71. $mailPlugin->expects($this->any())
  72. ->method('search')
  73. ->willReturnCallback(function () use ($searchResult, $mockedMailResult, $expectedMoreResults) {
  74. $type = new SearchResultType('emails');
  75. $searchResult->addResultSet($type, $mockedMailResult);
  76. return $expectedMoreResults;
  77. });
  78. $this->container->expects($this->any())
  79. ->method('resolve')
  80. ->willReturnCallback(function ($class) use ($searchResult, $userPlugin, $groupPlugin, $remotePlugin, $mailPlugin) {
  81. if ($class === SearchResult::class) {
  82. return $searchResult;
  83. } elseif ($class === $userPlugin) {
  84. return $userPlugin;
  85. } elseif ($class === $groupPlugin) {
  86. return $groupPlugin;
  87. } elseif ($class === $remotePlugin) {
  88. return $remotePlugin;
  89. } elseif ($class === $mailPlugin) {
  90. return $mailPlugin;
  91. }
  92. return null;
  93. });
  94. $this->search->registerPlugin(['shareType' => 'SHARE_TYPE_USER', 'class' => $userPlugin]);
  95. $this->search->registerPlugin(['shareType' => 'SHARE_TYPE_GROUP', 'class' => $groupPlugin]);
  96. $this->search->registerPlugin(['shareType' => 'SHARE_TYPE_REMOTE', 'class' => $remotePlugin]);
  97. $this->search->registerPlugin(['shareType' => 'SHARE_TYPE_EMAIL', 'class' => $mailPlugin]);
  98. [$results, $moreResults] = $this->search->search($searchTerm, $shareTypes, false, $perPage, $perPage * ($page - 1));
  99. $this->assertEquals($expected, $results);
  100. $this->assertSame($expectedMoreResults, $moreResults);
  101. }
  102. public function dataSearchSharees() {
  103. return [
  104. // #0
  105. [
  106. 'test', [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE], 1, 2, [], [], ['results' => [], 'exact' => [], 'exactIdMatch' => false],
  107. [],
  108. [
  109. 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
  110. 'users' => [],
  111. 'groups' => [],
  112. 'remotes' => [],
  113. ],
  114. false
  115. ],
  116. // #1
  117. [
  118. 'test', [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE], 1, 2, [], [], ['results' => [], 'exact' => [], 'exactIdMatch' => false],
  119. [],
  120. [
  121. 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
  122. 'users' => [],
  123. 'groups' => [],
  124. 'remotes' => [],
  125. ],
  126. false
  127. ],
  128. // #2
  129. [
  130. 'test', [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE], 1, 2, [
  131. ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
  132. ], [
  133. ['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']],
  134. ], [
  135. 'results' => [['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']]], 'exact' => [], 'exactIdMatch' => false,
  136. ],
  137. [],
  138. [
  139. 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
  140. 'users' => [
  141. ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
  142. ],
  143. 'groups' => [
  144. ['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']],
  145. ],
  146. 'remotes' => [
  147. ['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']],
  148. ],
  149. ], true,
  150. ],
  151. // #3 No groups requested
  152. [
  153. 'test', [IShare::TYPE_USER, IShare::TYPE_REMOTE], 1, 2, [
  154. ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
  155. ], [], [
  156. 'results' => [['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']]], 'exact' => [], 'exactIdMatch' => false
  157. ],
  158. [],
  159. [
  160. 'exact' => ['users' => [], 'remotes' => []],
  161. 'users' => [
  162. ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
  163. ],
  164. 'remotes' => [
  165. ['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']],
  166. ],
  167. ], false,
  168. ],
  169. // #4 Share type restricted to user - Only one user
  170. [
  171. 'test', [IShare::TYPE_USER], 1, 2, [
  172. ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
  173. ], [], [], [],
  174. [
  175. 'exact' => ['users' => []],
  176. 'users' => [
  177. ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
  178. ],
  179. ], false,
  180. ],
  181. // #5 Share type restricted to user - Multipage result
  182. [
  183. 'test', [IShare::TYPE_USER], 1, 2, [
  184. ['label' => 'test 1', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
  185. ['label' => 'test 2', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2']],
  186. ], [], [], [],
  187. [
  188. 'exact' => ['users' => []],
  189. 'users' => [
  190. ['label' => 'test 1', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
  191. ['label' => 'test 2', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2']],
  192. ],
  193. ], true,
  194. ],
  195. // #6 Mail shares filtered out in favor of remote shares
  196. [
  197. 'test', // search term
  198. [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE, IShare::TYPE_EMAIL], // plugins
  199. 1, // page
  200. 10, // per page
  201. [ // user result
  202. ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
  203. ],
  204. [ // group result
  205. ['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']],
  206. ],
  207. [ // remote result
  208. 'results' => [
  209. ['label' => 'testz@remote.tld', 'uuid' => 'f3d78140-abcc-46df-b58d-c7cc1176aadf','value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote.tld']]
  210. ],
  211. 'exact' => [],
  212. 'exactIdMatch' => false,
  213. ],
  214. [ // mail result
  215. ['label' => 'test Two', 'uuid' => 'b2321e9e-31af-43ac-a406-583fb26d1964', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test2@remote.tld']],
  216. ['label' => 'test One', 'uuid' => 'f3d78140-abcc-46df-b58d-c7cc1176aadf', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'testz@remote.tld']],
  217. ],
  218. [ // expected result
  219. 'exact' => ['users' => [], 'groups' => [], 'remotes' => [], 'emails' => []],
  220. 'users' => [
  221. ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
  222. ],
  223. 'groups' => [
  224. ['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']],
  225. ],
  226. 'remotes' => [
  227. ['label' => 'testz@remote.tld', 'uuid' => 'f3d78140-abcc-46df-b58d-c7cc1176aadf', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote.tld']],
  228. ],
  229. 'emails' => [
  230. // one passes, another is filtered out
  231. ['label' => 'test Two', 'uuid' => 'b2321e9e-31af-43ac-a406-583fb26d1964', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test2@remote.tld']]
  232. ]
  233. ],
  234. false, // expected more results indicator
  235. ],
  236. ];
  237. }
  238. }