LookupPluginTest.php 14 KB

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