LookupPluginTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
  4. *
  5. * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  6. *
  7. * @license GNU AGPL version 3 or any later version
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as
  11. * published by the Free Software Foundation, either version 3 of the
  12. * License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. */
  23. namespace Test\Collaboration\Collaborators;
  24. use OC\Collaboration\Collaborators\LookupPlugin;
  25. use OC\Federation\CloudId;
  26. use OCP\Collaboration\Collaborators\ISearchResult;
  27. use OCP\Collaboration\Collaborators\SearchResultType;
  28. use OCP\Federation\ICloudId;
  29. use OCP\Federation\ICloudIdManager;
  30. use OCP\Http\Client\IClient;
  31. use OCP\Http\Client\IClientService;
  32. use OCP\Http\Client\IResponse;
  33. use OCP\IConfig;
  34. use OCP\ILogger;
  35. use OCP\IUser;
  36. use OCP\IUserSession;
  37. use OCP\Share\IShare;
  38. use Test\TestCase;
  39. class LookupPluginTest extends TestCase {
  40. /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
  41. protected $config;
  42. /** @var IClientService|\PHPUnit\Framework\MockObject\MockObject */
  43. protected $clientService;
  44. /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
  45. protected $userSession;
  46. /** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */
  47. protected $cloudIdManager;
  48. /** @var LookupPlugin */
  49. protected $plugin;
  50. /** @var ILogger|\PHPUnit\Framework\MockObject\MockObject */
  51. protected $logger;
  52. protected function setUp(): void {
  53. parent::setUp();
  54. $this->userSession = $this->createMock(IUserSession::class);
  55. $this->cloudIdManager = $this->createMock(ICloudIdManager::class);
  56. $this->config = $this->createMock(IConfig::class);
  57. $this->logger = $this->createMock(ILogger::class);
  58. $this->clientService = $this->createMock(IClientService::class);
  59. $cloudId = $this->createMock(ICloudId::class);
  60. $cloudId->expects($this->any())->method('getRemote')->willReturn('myNextcloud.net');
  61. $user = $this->createMock(IUser::class);
  62. $user->expects($this->any())->method('getCloudId')->willReturn('user@myNextcloud.net');
  63. $this->userSession->expects($this->any())->method('getUser')
  64. ->willReturn($user);
  65. $this->cloudIdManager->expects($this->any())->method('resolveCloudId')
  66. ->willReturnCallback(function ($cloudId) {
  67. if ($cloudId === 'user@myNextcloud.net') {
  68. return new CloudId('user@myNextcloud.net', 'user', 'myNextcloud.net');
  69. }
  70. return new CloudId('user@someNextcloud.net', 'user', 'someNextcloud.net');
  71. });
  72. $this->plugin = new LookupPlugin(
  73. $this->config,
  74. $this->clientService,
  75. $this->userSession,
  76. $this->cloudIdManager,
  77. $this->logger
  78. );
  79. }
  80. public function testSearchNoLookupServerURI() {
  81. $this->config->expects($this->once())
  82. ->method('getAppValue')
  83. ->with('files_sharing', 'lookupServerEnabled', 'yes')
  84. ->willReturn('yes');
  85. $this->config->expects($this->at(0))
  86. ->method('getSystemValue')
  87. ->with('gs.enabled', false)
  88. ->willReturn(false);
  89. $this->config->expects($this->at(2))
  90. ->method('getSystemValue')
  91. ->with('has_internet_connection', true)
  92. ->willReturn(true);
  93. $this->config->expects($this->at(3))
  94. ->method('getSystemValue')
  95. ->with('lookup_server', 'https://lookup.nextcloud.com')
  96. ->willReturn('');
  97. $this->clientService->expects($this->never())
  98. ->method('newClient');
  99. /** @var ISearchResult|\PHPUnit\Framework\MockObject\MockObject $searchResult */
  100. $searchResult = $this->createMock(ISearchResult::class);
  101. $this->plugin->search('foobar', 10, 0, $searchResult);
  102. }
  103. public function testSearchNoInternet() {
  104. $this->config->expects($this->once())
  105. ->method('getAppValue')
  106. ->with('files_sharing', 'lookupServerEnabled', 'yes')
  107. ->willReturn('yes');
  108. $this->config->expects($this->at(0))
  109. ->method('getSystemValue')
  110. ->with('gs.enabled', false)
  111. ->willReturn(false);
  112. $this->config->expects($this->at(2))
  113. ->method('getSystemValue')
  114. ->with('has_internet_connection', true)
  115. ->willReturn(false);
  116. $this->clientService->expects($this->never())
  117. ->method('newClient');
  118. /** @var ISearchResult|\PHPUnit\Framework\MockObject\MockObject $searchResult */
  119. $searchResult = $this->createMock(ISearchResult::class);
  120. $this->plugin->search('foobar', 10, 0, $searchResult);
  121. }
  122. /**
  123. * @dataProvider searchDataProvider
  124. * @param array $searchParams
  125. */
  126. public function testSearch(array $searchParams) {
  127. $type = new SearchResultType('lookup');
  128. /** @var ISearchResult|\PHPUnit\Framework\MockObject\MockObject $searchResult */
  129. $searchResult = $this->createMock(ISearchResult::class);
  130. $searchResult->expects($this->once())
  131. ->method('addResultSet')
  132. ->with($type, $searchParams['expectedResult'], []);
  133. $this->config->expects($this->once())
  134. ->method('getAppValue')
  135. ->with('files_sharing', 'lookupServerEnabled', 'yes')
  136. ->willReturn('yes');
  137. $this->config->expects($this->at(0))
  138. ->method('getSystemValue')
  139. ->with('gs.enabled', false)
  140. ->willReturn(false);
  141. $this->config->expects($this->at(2))
  142. ->method('getSystemValue')
  143. ->with('has_internet_connection', true)
  144. ->willReturn(true);
  145. $this->config->expects($this->at(3))
  146. ->method('getSystemValue')
  147. ->with('lookup_server', 'https://lookup.nextcloud.com')
  148. ->willReturn($searchParams['server']);
  149. $response = $this->createMock(IResponse::class);
  150. $response->expects($this->once())
  151. ->method('getBody')
  152. ->willReturn(json_encode($searchParams['resultBody']));
  153. $client = $this->createMock(IClient::class);
  154. $client->expects($this->once())
  155. ->method('get')
  156. ->willReturnCallback(function ($url) use ($searchParams, $response) {
  157. $this->assertSame(strpos($url, $searchParams['server'] . '/users?search='), 0);
  158. $this->assertNotFalse(strpos($url, urlencode($searchParams['search'])));
  159. return $response;
  160. });
  161. $this->clientService->expects($this->once())
  162. ->method('newClient')
  163. ->willReturn($client);
  164. $moreResults = $this->plugin->search(
  165. $searchParams['search'],
  166. $searchParams['limit'],
  167. $searchParams['offset'],
  168. $searchResult
  169. );
  170. $this->assertFalse($moreResults);
  171. }
  172. /**
  173. * @dataProvider dataSearchEnableDisableLookupServer
  174. * @param array $searchParams
  175. * @param bool $GSEnabled
  176. * @param bool $LookupEnabled
  177. */
  178. public function testSearchEnableDisableLookupServer(array $searchParams, $GSEnabled, $LookupEnabled) {
  179. $type = new SearchResultType('lookup');
  180. /** @var ISearchResult|\PHPUnit\Framework\MockObject\MockObject $searchResult */
  181. $searchResult = $this->createMock(ISearchResult::class);
  182. $this->config->expects($this->once())
  183. ->method('getAppValue')
  184. ->with('files_sharing', 'lookupServerEnabled', 'yes')
  185. ->willReturn($LookupEnabled ? 'yes' : 'no');
  186. $this->config->expects($this->at(0))
  187. ->method('getSystemValue')
  188. ->with('gs.enabled', false)
  189. ->willReturn($GSEnabled);
  190. if ($GSEnabled || $LookupEnabled) {
  191. $searchResult->expects($this->once())
  192. ->method('addResultSet')
  193. ->with($type, $searchParams['expectedResult'], []);
  194. $this->config->expects($this->at(2))
  195. ->method('getSystemValue')
  196. ->with('has_internet_connection', true)
  197. ->willReturn(true);
  198. $this->config->expects($this->at(3))
  199. ->method('getSystemValue')
  200. ->with('lookup_server', 'https://lookup.nextcloud.com')
  201. ->willReturn($searchParams['server']);
  202. $response = $this->createMock(IResponse::class);
  203. $response->expects($this->once())
  204. ->method('getBody')
  205. ->willReturn(json_encode($searchParams['resultBody']));
  206. $client = $this->createMock(IClient::class);
  207. $client->expects($this->once())
  208. ->method('get')
  209. ->willReturnCallback(function ($url) use ($searchParams, $response) {
  210. $this->assertSame(strpos($url, $searchParams['server'] . '/users?search='), 0);
  211. $this->assertNotFalse(strpos($url, urlencode($searchParams['search'])));
  212. return $response;
  213. });
  214. $this->clientService->expects($this->once())
  215. ->method('newClient')
  216. ->willReturn($client);
  217. } else {
  218. $searchResult->expects($this->never())->method('addResultSet');
  219. }
  220. $moreResults = $this->plugin->search(
  221. $searchParams['search'],
  222. $searchParams['limit'],
  223. $searchParams['offset'],
  224. $searchResult
  225. );
  226. $this->assertFalse($moreResults);
  227. }
  228. public function testSearchLookupServerDisabled() {
  229. $this->config->expects($this->once())
  230. ->method('getAppValue')
  231. ->with('files_sharing', 'lookupServerEnabled', 'yes')
  232. ->willReturn('no');
  233. /** @var ISearchResult|\PHPUnit\Framework\MockObject\MockObject $searchResult */
  234. $searchResult = $this->createMock(ISearchResult::class);
  235. $searchResult->expects($this->never())
  236. ->method('addResultSet');
  237. $searchResult->expects($this->never())
  238. ->method('markExactIdMatch');
  239. $this->assertFalse($this->plugin->search('irr', 10, 0, $searchResult));
  240. }
  241. public function dataSearchEnableDisableLookupServer() {
  242. $fedIDs = [
  243. 'foo@enceladus.moon',
  244. 'foobar@enceladus.moon',
  245. 'foongus@enceladus.moon',
  246. ];
  247. return [
  248. [[
  249. 'search' => 'foo',
  250. 'limit' => 10,
  251. 'offset' => 0,
  252. 'server' => 'https://lookup.example.io',
  253. 'resultBody' => [
  254. ['federationId' => $fedIDs[0]],
  255. ['federationId' => $fedIDs[1]],
  256. ['federationId' => $fedIDs[2]],
  257. ],
  258. 'expectedResult' => [
  259. [
  260. 'label' => $fedIDs[0],
  261. 'value' => [
  262. 'shareType' => IShare::TYPE_REMOTE,
  263. 'shareWith' => $fedIDs[0]
  264. ],
  265. 'extra' => ['federationId' => $fedIDs[0]],
  266. ],
  267. [
  268. 'label' => $fedIDs[1],
  269. 'value' => [
  270. 'shareType' => IShare::TYPE_REMOTE,
  271. 'shareWith' => $fedIDs[1]
  272. ],
  273. 'extra' => ['federationId' => $fedIDs[1]],
  274. ],
  275. [
  276. 'label' => $fedIDs[2],
  277. 'value' => [
  278. 'shareType' => IShare::TYPE_REMOTE,
  279. 'shareWith' => $fedIDs[2]
  280. ],
  281. 'extra' => ['federationId' => $fedIDs[2]],
  282. ],
  283. ]
  284. ],// GS , Lookup
  285. true, true
  286. ],
  287. [[
  288. 'search' => 'foo',
  289. 'limit' => 10,
  290. 'offset' => 0,
  291. 'server' => 'https://lookup.example.io',
  292. 'resultBody' => [
  293. ['federationId' => $fedIDs[0]],
  294. ['federationId' => $fedIDs[1]],
  295. ['federationId' => $fedIDs[2]],
  296. ],
  297. 'expectedResult' => [
  298. [
  299. 'label' => $fedIDs[0],
  300. 'value' => [
  301. 'shareType' => IShare::TYPE_REMOTE,
  302. 'shareWith' => $fedIDs[0]
  303. ],
  304. 'extra' => ['federationId' => $fedIDs[0]],
  305. ],
  306. [
  307. 'label' => $fedIDs[1],
  308. 'value' => [
  309. 'shareType' => IShare::TYPE_REMOTE,
  310. 'shareWith' => $fedIDs[1]
  311. ],
  312. 'extra' => ['federationId' => $fedIDs[1]],
  313. ],
  314. [
  315. 'label' => $fedIDs[2],
  316. 'value' => [
  317. 'shareType' => IShare::TYPE_REMOTE,
  318. 'shareWith' => $fedIDs[2]
  319. ],
  320. 'extra' => ['federationId' => $fedIDs[2]],
  321. ],
  322. ]
  323. ],// GS , Lookup
  324. true, false
  325. ],
  326. [[
  327. 'search' => 'foo',
  328. 'limit' => 10,
  329. 'offset' => 0,
  330. 'server' => 'https://lookup.example.io',
  331. 'resultBody' => [
  332. ['federationId' => $fedIDs[0]],
  333. ['federationId' => $fedIDs[1]],
  334. ['federationId' => $fedIDs[2]],
  335. ],
  336. 'expectedResult' => [
  337. [
  338. 'label' => $fedIDs[0],
  339. 'value' => [
  340. 'shareType' => IShare::TYPE_REMOTE,
  341. 'shareWith' => $fedIDs[0]
  342. ],
  343. 'extra' => ['federationId' => $fedIDs[0]],
  344. ],
  345. [
  346. 'label' => $fedIDs[1],
  347. 'value' => [
  348. 'shareType' => IShare::TYPE_REMOTE,
  349. 'shareWith' => $fedIDs[1]
  350. ],
  351. 'extra' => ['federationId' => $fedIDs[1]],
  352. ],
  353. [
  354. 'label' => $fedIDs[2],
  355. 'value' => [
  356. 'shareType' => IShare::TYPE_REMOTE,
  357. 'shareWith' => $fedIDs[2]
  358. ],
  359. 'extra' => ['federationId' => $fedIDs[2]],
  360. ],
  361. ]
  362. ],// GS , Lookup
  363. false, true
  364. ],
  365. [[
  366. 'search' => 'foo',
  367. 'limit' => 10,
  368. 'offset' => 0,
  369. 'server' => 'https://lookup.example.io',
  370. 'resultBody' => [
  371. ['federationId' => $fedIDs[0]],
  372. ['federationId' => $fedIDs[1]],
  373. ['federationId' => $fedIDs[2]],
  374. ],
  375. 'expectedResult' => [
  376. [
  377. 'label' => $fedIDs[0],
  378. 'value' => [
  379. 'shareType' => IShare::TYPE_REMOTE,
  380. 'shareWith' => $fedIDs[0]
  381. ],
  382. 'extra' => ['federationId' => $fedIDs[0]],
  383. ],
  384. [
  385. 'label' => $fedIDs[1],
  386. 'value' => [
  387. 'shareType' => IShare::TYPE_REMOTE,
  388. 'shareWith' => $fedIDs[1]
  389. ],
  390. 'extra' => ['federationId' => $fedIDs[1]],
  391. ],
  392. [
  393. 'label' => $fedIDs[2],
  394. 'value' => [
  395. 'shareType' => IShare::TYPE_REMOTE,
  396. 'shareWith' => $fedIDs[2]
  397. ],
  398. 'extra' => ['federationId' => $fedIDs[2]],
  399. ],
  400. ]
  401. ],// GS , Lookup
  402. false, false
  403. ],
  404. ];
  405. }
  406. public function searchDataProvider() {
  407. $fedIDs = [
  408. 'foo@enceladus.moon',
  409. 'foobar@enceladus.moon',
  410. 'foongus@enceladus.moon',
  411. ];
  412. return [
  413. // #0, standard search with results
  414. [[
  415. 'search' => 'foo',
  416. 'limit' => 10,
  417. 'offset' => 0,
  418. 'server' => 'https://lookup.example.io',
  419. 'resultBody' => [
  420. ['federationId' => $fedIDs[0]],
  421. ['federationId' => $fedIDs[1]],
  422. ['federationId' => $fedIDs[2]],
  423. ],
  424. 'expectedResult' => [
  425. [
  426. 'label' => $fedIDs[0],
  427. 'value' => [
  428. 'shareType' => IShare::TYPE_REMOTE,
  429. 'shareWith' => $fedIDs[0]
  430. ],
  431. 'extra' => ['federationId' => $fedIDs[0]],
  432. ],
  433. [
  434. 'label' => $fedIDs[1],
  435. 'value' => [
  436. 'shareType' => IShare::TYPE_REMOTE,
  437. 'shareWith' => $fedIDs[1]
  438. ],
  439. 'extra' => ['federationId' => $fedIDs[1]],
  440. ],
  441. [
  442. 'label' => $fedIDs[2],
  443. 'value' => [
  444. 'shareType' => IShare::TYPE_REMOTE,
  445. 'shareWith' => $fedIDs[2]
  446. ],
  447. 'extra' => ['federationId' => $fedIDs[2]],
  448. ],
  449. ]
  450. ]],
  451. // #1, search without results
  452. [[
  453. 'search' => 'foo',
  454. 'limit' => 10,
  455. 'offset' => 0,
  456. 'server' => 'https://lookup.example.io',
  457. 'resultBody' => [],
  458. 'expectedResult' => [],
  459. ]],
  460. ];
  461. }
  462. }