ContactsStoreTest.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967
  1. <?php
  2. /**
  3. * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
  4. * @copyright 2017 Lukas Reschke <lukas@statuscode.ch>
  5. *
  6. * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
  7. * @author 2017 Lukas Reschke <lukas@statuscode.ch>
  8. *
  9. * @license GNU AGPL version 3 or any later version
  10. *
  11. * This program is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Affero General Public License as
  13. * published by the Free Software Foundation, either version 3 of the
  14. * License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Affero General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. *
  24. */
  25. namespace Tests\Contacts\ContactsMenu;
  26. use OC\Contacts\ContactsMenu\ContactsStore;
  27. use OC\KnownUser\KnownUserService;
  28. use OC\Profile\ProfileManager;
  29. use OCP\Contacts\IManager;
  30. use OCP\IConfig;
  31. use OCP\IGroupManager;
  32. use OCP\IURLGenerator;
  33. use OCP\IUser;
  34. use OCP\IUserManager;
  35. use OCP\L10N\IFactory as IL10NFactory;
  36. use PHPUnit\Framework\MockObject\MockObject;
  37. use Test\TestCase;
  38. class ContactsStoreTest extends TestCase {
  39. private ContactsStore $contactsStore;
  40. /** @var IManager|MockObject */
  41. private $contactsManager;
  42. /** @var ProfileManager */
  43. private $profileManager;
  44. /** @var IUserManager|MockObject */
  45. private $userManager;
  46. /** @var IURLGenerator */
  47. private $urlGenerator;
  48. /** @var IGroupManager|MockObject */
  49. private $groupManager;
  50. /** @var IConfig|MockObject */
  51. private $config;
  52. /** @var KnownUserService|MockObject */
  53. private $knownUserService;
  54. /** @var IL10NFactory */
  55. private $l10nFactory;
  56. protected function setUp(): void {
  57. parent::setUp();
  58. $this->contactsManager = $this->createMock(IManager::class);
  59. $this->userManager = $this->createMock(IUserManager::class);
  60. $this->profileManager = $this->createMock(ProfileManager::class);
  61. $this->urlGenerator = $this->createMock(IURLGenerator::class);
  62. $this->groupManager = $this->createMock(IGroupManager::class);
  63. $this->config = $this->createMock(IConfig::class);
  64. $this->knownUserService = $this->createMock(KnownUserService::class);
  65. $this->l10nFactory = $this->createMock(IL10NFactory::class);
  66. $this->contactsStore = new ContactsStore(
  67. $this->contactsManager,
  68. $this->config,
  69. $this->profileManager,
  70. $this->userManager,
  71. $this->urlGenerator,
  72. $this->groupManager,
  73. $this->knownUserService,
  74. $this->l10nFactory
  75. );
  76. }
  77. public function testGetContactsWithoutFilter() {
  78. /** @var IUser|MockObject $user */
  79. $user = $this->createMock(IUser::class);
  80. $this->contactsManager->expects($this->once())
  81. ->method('search')
  82. ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
  83. ->willReturn([
  84. [
  85. 'UID' => 123,
  86. ],
  87. [
  88. 'UID' => 567,
  89. 'FN' => 'Darren Roner',
  90. 'EMAIL' => [
  91. 'darren@roner.au'
  92. ],
  93. ],
  94. ]);
  95. $user->expects($this->exactly(2))
  96. ->method('getUID')
  97. ->willReturn('user123');
  98. $entries = $this->contactsStore->getContacts($user, '');
  99. $this->assertCount(2, $entries);
  100. $this->assertEquals([
  101. 'darren@roner.au'
  102. ], $entries[1]->getEMailAddresses());
  103. }
  104. public function testGetContactsHidesOwnEntry() {
  105. /** @var IUser|MockObject $user */
  106. $user = $this->createMock(IUser::class);
  107. $this->contactsManager->expects($this->once())
  108. ->method('search')
  109. ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
  110. ->willReturn([
  111. [
  112. 'UID' => 'user123',
  113. ],
  114. [
  115. 'UID' => 567,
  116. 'FN' => 'Darren Roner',
  117. 'EMAIL' => [
  118. 'darren@roner.au'
  119. ],
  120. ],
  121. ]);
  122. $user->expects($this->exactly(2))
  123. ->method('getUID')
  124. ->willReturn('user123');
  125. $entries = $this->contactsStore->getContacts($user, '');
  126. $this->assertCount(1, $entries);
  127. }
  128. public function testGetContactsWithoutBinaryImage() {
  129. /** @var IUser|MockObject $user */
  130. $user = $this->createMock(IUser::class);
  131. $this->urlGenerator->expects($this->any())
  132. ->method('linkToRouteAbsolute')
  133. ->with('core.GuestAvatar.getAvatar', $this->anything())
  134. ->willReturn('https://urlToNcAvatar.test');
  135. $this->contactsManager->expects($this->once())
  136. ->method('search')
  137. ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
  138. ->willReturn([
  139. [
  140. 'UID' => 123,
  141. ],
  142. [
  143. 'UID' => 567,
  144. 'FN' => 'Darren Roner',
  145. 'EMAIL' => [
  146. 'darren@roner.au'
  147. ],
  148. 'PHOTO' => base64_encode('photophotophoto'),
  149. ],
  150. ]);
  151. $user->expects($this->exactly(2))
  152. ->method('getUID')
  153. ->willReturn('user123');
  154. $entries = $this->contactsStore->getContacts($user, '');
  155. $this->assertCount(2, $entries);
  156. $this->assertSame('https://urlToNcAvatar.test', $entries[1]->getAvatar());
  157. }
  158. public function testGetContactsWithoutAvatarURI() {
  159. /** @var IUser|MockObject $user */
  160. $user = $this->createMock(IUser::class);
  161. $this->contactsManager->expects($this->once())
  162. ->method('search')
  163. ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
  164. ->willReturn([
  165. [
  166. 'UID' => 123,
  167. ],
  168. [
  169. 'UID' => 567,
  170. 'FN' => 'Darren Roner',
  171. 'EMAIL' => [
  172. 'darren@roner.au'
  173. ],
  174. 'PHOTO' => 'VALUE=uri:https://photo',
  175. ],
  176. ]);
  177. $user->expects($this->exactly(2))
  178. ->method('getUID')
  179. ->willReturn('user123');
  180. $entries = $this->contactsStore->getContacts($user, '');
  181. $this->assertCount(2, $entries);
  182. $this->assertEquals('https://photo', $entries[1]->getAvatar());
  183. }
  184. public function testGetContactsWhenUserIsInExcludeGroups() {
  185. $this->config
  186. ->method('getAppValue')
  187. ->willReturnMap([
  188. ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
  189. ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
  190. ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
  191. ['core', 'shareapi_exclude_groups', 'no', 'yes'],
  192. ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
  193. ['core', 'shareapi_exclude_groups_list', '', '["group1", "group5", "group6"]'],
  194. ]);
  195. /** @var IUser|MockObject $currentUser */
  196. $currentUser = $this->createMock(IUser::class);
  197. $currentUser->expects($this->exactly(2))
  198. ->method('getUID')
  199. ->willReturn('user001');
  200. $this->groupManager->expects($this->once())
  201. ->method('getUserGroupIds')
  202. ->with($this->equalTo($currentUser))
  203. ->willReturn(['group1', 'group2', 'group3']);
  204. $this->contactsManager->expects($this->once())
  205. ->method('search')
  206. ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
  207. ->willReturn([
  208. [
  209. 'UID' => 'user123',
  210. 'isLocalSystemBook' => true
  211. ],
  212. [
  213. 'UID' => 'user12345',
  214. 'isLocalSystemBook' => true
  215. ],
  216. ]);
  217. $entries = $this->contactsStore->getContacts($currentUser, '');
  218. $this->assertCount(0, $entries);
  219. }
  220. public function testGetContactsOnlyShareIfInTheSameGroup() {
  221. $this->config
  222. ->method('getAppValue')
  223. ->willReturnMap([
  224. ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
  225. ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
  226. ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
  227. ['core', 'shareapi_exclude_groups', 'no', 'no'],
  228. ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
  229. ]);
  230. /** @var IUser|MockObject $currentUser */
  231. $currentUser = $this->createMock(IUser::class);
  232. $currentUser->expects($this->exactly(2))
  233. ->method('getUID')
  234. ->willReturn('user001');
  235. $user1 = $this->createMock(IUser::class);
  236. $user2 = $this->createMock(IUser::class);
  237. $user3 = $this->createMock(IUser::class);
  238. $this->groupManager->expects($this->exactly(4))
  239. ->method('getUserGroupIds')
  240. ->withConsecutive(
  241. [$this->equalTo($currentUser)],
  242. [$this->equalTo($user1)],
  243. [$this->equalTo($user2)],
  244. [$this->equalTo($user3)]
  245. )
  246. ->willReturnOnConsecutiveCalls(
  247. ['group1', 'group2', 'group3'],
  248. ['group1'],
  249. ['group2', 'group3'],
  250. ['group8', 'group9']
  251. );
  252. $this->userManager->expects($this->exactly(3))
  253. ->method('get')
  254. ->withConsecutive(
  255. ['user1'],
  256. ['user2'],
  257. ['user3']
  258. )
  259. ->willReturnOnConsecutiveCalls($user1, $user2, $user3);
  260. $this->contactsManager->expects($this->once())
  261. ->method('search')
  262. ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
  263. ->willReturn([
  264. [
  265. 'UID' => 'user1',
  266. 'isLocalSystemBook' => true
  267. ],
  268. [
  269. 'UID' => 'user2',
  270. 'isLocalSystemBook' => true
  271. ],
  272. [
  273. 'UID' => 'user3',
  274. 'isLocalSystemBook' => true
  275. ],
  276. [
  277. 'UID' => 'contact',
  278. ],
  279. ]);
  280. $entries = $this->contactsStore->getContacts($currentUser, '');
  281. $this->assertCount(3, $entries);
  282. $this->assertEquals('user1', $entries[0]->getProperty('UID'));
  283. $this->assertEquals('user2', $entries[1]->getProperty('UID'));
  284. $this->assertEquals('contact', $entries[2]->getProperty('UID'));
  285. }
  286. public function testGetContactsOnlyEnumerateIfInTheSameGroup() {
  287. $this->config
  288. ->method('getAppValue')
  289. ->willReturnMap([
  290. ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
  291. ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'],
  292. ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
  293. ['core', 'shareapi_exclude_groups', 'no', 'no'],
  294. ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
  295. ]);
  296. /** @var IUser|MockObject $currentUser */
  297. $currentUser = $this->createMock(IUser::class);
  298. $currentUser->expects($this->exactly(2))
  299. ->method('getUID')
  300. ->willReturn('user001');
  301. $user1 = $this->createMock(IUser::class);
  302. $user2 = $this->createMock(IUser::class);
  303. $user3 = $this->createMock(IUser::class);
  304. $this->groupManager->expects($this->exactly(4))
  305. ->method('getUserGroupIds')
  306. ->withConsecutive(
  307. [$this->equalTo($currentUser)],
  308. [$this->equalTo($user1)],
  309. [$this->equalTo($user2)],
  310. [$this->equalTo($user3)]
  311. )
  312. ->willReturnOnConsecutiveCalls(
  313. ['group1', 'group2', 'group3'],
  314. ['group1'],
  315. ['group2', 'group3'],
  316. ['group8', 'group9']
  317. );
  318. $this->userManager->expects($this->exactly(3))
  319. ->method('get')
  320. ->withConsecutive(
  321. ['user1'],
  322. ['user2'],
  323. ['user3']
  324. )
  325. ->willReturn($user1, $user2, $user3);
  326. $this->contactsManager->expects($this->once())
  327. ->method('search')
  328. ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
  329. ->willReturn([
  330. [
  331. 'UID' => 'user1',
  332. 'isLocalSystemBook' => true
  333. ],
  334. [
  335. 'UID' => 'user2',
  336. 'isLocalSystemBook' => true
  337. ],
  338. [
  339. 'UID' => 'user3',
  340. 'isLocalSystemBook' => true
  341. ],
  342. [
  343. 'UID' => 'contact',
  344. ],
  345. ]);
  346. $entries = $this->contactsStore->getContacts($currentUser, '');
  347. $this->assertCount(3, $entries);
  348. $this->assertEquals('user1', $entries[0]->getProperty('UID'));
  349. $this->assertEquals('user2', $entries[1]->getProperty('UID'));
  350. $this->assertEquals('contact', $entries[2]->getProperty('UID'));
  351. }
  352. public function testGetContactsOnlyEnumerateIfPhoneBookMatch() {
  353. $this->config
  354. ->method('getAppValue')
  355. ->willReturnMap([
  356. ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
  357. ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
  358. ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'],
  359. ['core', 'shareapi_exclude_groups', 'no', 'no'],
  360. ['core', 'shareapi_only_share_with_group_members', 'no', 'no'],
  361. ]);
  362. /** @var IUser|MockObject $currentUser */
  363. $currentUser = $this->createMock(IUser::class);
  364. $currentUser->expects($this->exactly(2))
  365. ->method('getUID')
  366. ->willReturn('user001');
  367. $this->groupManager->expects($this->once())
  368. ->method('getUserGroupIds')
  369. ->with($this->equalTo($currentUser))
  370. ->willReturn(['group1', 'group2', 'group3']);
  371. $this->knownUserService->method('isKnownToUser')
  372. ->willReturnMap([
  373. ['user001', 'user1', true],
  374. ['user001', 'user2', true],
  375. ['user001', 'user3', false],
  376. ]);
  377. $this->contactsManager->expects($this->once())
  378. ->method('search')
  379. ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
  380. ->willReturn([
  381. [
  382. 'UID' => 'user1',
  383. 'isLocalSystemBook' => true
  384. ],
  385. [
  386. 'UID' => 'user2',
  387. 'isLocalSystemBook' => true
  388. ],
  389. [
  390. 'UID' => 'user3',
  391. 'isLocalSystemBook' => true
  392. ],
  393. [
  394. 'UID' => 'contact',
  395. ],
  396. ]);
  397. $entries = $this->contactsStore->getContacts($currentUser, '');
  398. $this->assertCount(3, $entries);
  399. $this->assertEquals('user1', $entries[0]->getProperty('UID'));
  400. $this->assertEquals('user2', $entries[1]->getProperty('UID'));
  401. $this->assertEquals('contact', $entries[2]->getProperty('UID'));
  402. }
  403. public function testGetContactsOnlyEnumerateIfPhoneBookMatchWithOwnGroupsOnly() {
  404. $this->config
  405. ->method('getAppValue')
  406. ->willReturnMap([
  407. ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
  408. ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
  409. ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'],
  410. ['core', 'shareapi_exclude_groups', 'no', 'no'],
  411. ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
  412. ]);
  413. /** @var IUser|MockObject $currentUser */
  414. $currentUser = $this->createMock(IUser::class);
  415. $currentUser->expects($this->exactly(2))
  416. ->method('getUID')
  417. ->willReturn('user001');
  418. $user1 = $this->createMock(IUser::class);
  419. $user2 = $this->createMock(IUser::class);
  420. $user3 = $this->createMock(IUser::class);
  421. $this->groupManager->expects($this->exactly(4))
  422. ->method('getUserGroupIds')
  423. ->withConsecutive(
  424. [$this->equalTo($currentUser)],
  425. [$this->equalTo($user1)],
  426. [$this->equalTo($user2)],
  427. [$this->equalTo($user3)]
  428. )
  429. ->willReturnOnConsecutiveCalls(
  430. ['group1', 'group2', 'group3'],
  431. ['group1'],
  432. ['group2', 'group3'],
  433. ['group8', 'group9']
  434. );
  435. $this->userManager->expects($this->exactly(3))
  436. ->method('get')
  437. ->withConsecutive(
  438. ['user1'],
  439. ['user2'],
  440. ['user3']
  441. )
  442. ->willReturnOnConsecutiveCalls($user1, $user2, $user3);
  443. $this->knownUserService->method('isKnownToUser')
  444. ->willReturnMap([
  445. ['user001', 'user1', true],
  446. ['user001', 'user2', true],
  447. ['user001', 'user3', true],
  448. ]);
  449. $this->contactsManager->expects($this->once())
  450. ->method('search')
  451. ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
  452. ->willReturn([
  453. [
  454. 'UID' => 'user1',
  455. 'isLocalSystemBook' => true
  456. ],
  457. [
  458. 'UID' => 'user2',
  459. 'isLocalSystemBook' => true
  460. ],
  461. [
  462. 'UID' => 'user3',
  463. 'isLocalSystemBook' => true
  464. ],
  465. [
  466. 'UID' => 'contact',
  467. ],
  468. ]);
  469. $entries = $this->contactsStore->getContacts($currentUser, '');
  470. $this->assertCount(3, $entries);
  471. $this->assertEquals('user1', $entries[0]->getProperty('UID'));
  472. $this->assertEquals('user2', $entries[1]->getProperty('UID'));
  473. $this->assertEquals('contact', $entries[2]->getProperty('UID'));
  474. }
  475. public function testGetContactsOnlyEnumerateIfPhoneBookOrSameGroup() {
  476. $this->config
  477. ->method('getAppValue')
  478. ->willReturnMap([
  479. ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
  480. ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'],
  481. ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'],
  482. ['core', 'shareapi_exclude_groups', 'no', 'no'],
  483. ['core', 'shareapi_only_share_with_group_members', 'no', 'no'],
  484. ]);
  485. /** @var IUser|MockObject $currentUser */
  486. $currentUser = $this->createMock(IUser::class);
  487. $currentUser->expects($this->exactly(2))
  488. ->method('getUID')
  489. ->willReturn('user001');
  490. $user1 = $this->createMock(IUser::class);
  491. $this->groupManager->expects($this->exactly(2))
  492. ->method('getUserGroupIds')
  493. ->withConsecutive(
  494. [$this->equalTo($currentUser)],
  495. [$this->equalTo($user1)]
  496. )
  497. ->willReturnOnConsecutiveCalls(
  498. ['group1', 'group2', 'group3'],
  499. ['group1']
  500. );
  501. $this->userManager->expects($this->once())
  502. ->method('get')
  503. ->with('user1')
  504. ->willReturn($user1);
  505. $this->knownUserService->method('isKnownToUser')
  506. ->willReturnMap([
  507. ['user001', 'user1', false],
  508. ['user001', 'user2', true],
  509. ['user001', 'user3', true],
  510. ]);
  511. $this->contactsManager->expects($this->once())
  512. ->method('search')
  513. ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
  514. ->willReturn([
  515. [
  516. 'UID' => 'user1',
  517. 'isLocalSystemBook' => true
  518. ],
  519. [
  520. 'UID' => 'user2',
  521. 'isLocalSystemBook' => true
  522. ],
  523. [
  524. 'UID' => 'user3',
  525. 'isLocalSystemBook' => true
  526. ],
  527. [
  528. 'UID' => 'contact',
  529. ],
  530. ]);
  531. $entries = $this->contactsStore->getContacts($currentUser, '');
  532. $this->assertCount(4, $entries);
  533. $this->assertEquals('user1', $entries[0]->getProperty('UID'));
  534. $this->assertEquals('user2', $entries[1]->getProperty('UID'));
  535. $this->assertEquals('user3', $entries[2]->getProperty('UID'));
  536. $this->assertEquals('contact', $entries[3]->getProperty('UID'));
  537. }
  538. public function testGetContactsOnlyEnumerateIfPhoneBookOrSameGroupInOwnGroupsOnly() {
  539. $this->config
  540. ->method('getAppValue')
  541. ->willReturnMap([
  542. ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
  543. ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'],
  544. ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'],
  545. ['core', 'shareapi_exclude_groups', 'no', 'no'],
  546. ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
  547. ]);
  548. /** @var IUser|MockObject $currentUser */
  549. $currentUser = $this->createMock(IUser::class);
  550. $currentUser->expects($this->exactly(2))
  551. ->method('getUID')
  552. ->willReturn('user001');
  553. $user1 = $this->createMock(IUser::class);
  554. $user2 = $this->createMock(IUser::class);
  555. $user3 = $this->createMock(IUser::class);
  556. $this->groupManager->expects($this->exactly(4))
  557. ->method('getUserGroupIds')
  558. ->withConsecutive(
  559. [$this->equalTo($currentUser)],
  560. [$this->equalTo($user1)],
  561. [$this->equalTo($user2)],
  562. [$this->equalTo($user3)]
  563. )
  564. ->willReturnOnConsecutiveCalls(
  565. ['group1', 'group2', 'group3'],
  566. ['group1'],
  567. ['group2', 'group3'],
  568. ['group8', 'group9']
  569. );
  570. $this->userManager->expects($this->exactly(3))
  571. ->method('get')
  572. ->withConsecutive(
  573. ['user1'],
  574. ['user2'],
  575. ['user3']
  576. )
  577. ->willReturnOnConsecutiveCalls($user1, $user2, $user3);
  578. $this->knownUserService->method('isKnownToUser')
  579. ->willReturnMap([
  580. ['user001', 'user1', false],
  581. ['user001', 'user2', true],
  582. ['user001', 'user3', true],
  583. ]);
  584. $this->contactsManager->expects($this->once())
  585. ->method('search')
  586. ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
  587. ->willReturn([
  588. [
  589. 'UID' => 'user1',
  590. 'isLocalSystemBook' => true
  591. ],
  592. [
  593. 'UID' => 'user2',
  594. 'isLocalSystemBook' => true
  595. ],
  596. [
  597. 'UID' => 'user3',
  598. 'isLocalSystemBook' => true
  599. ],
  600. [
  601. 'UID' => 'contact',
  602. ],
  603. ]);
  604. $entries = $this->contactsStore->getContacts($currentUser, '');
  605. $this->assertCount(3, $entries);
  606. $this->assertEquals('user1', $entries[0]->getProperty('UID'));
  607. $this->assertEquals('user2', $entries[1]->getProperty('UID'));
  608. $this->assertEquals('contact', $entries[2]->getProperty('UID'));
  609. }
  610. public function testGetContactsWithFilter() {
  611. $this->config
  612. ->method('getAppValue')
  613. ->willReturnMap([
  614. ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'no'],
  615. ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'],
  616. ]);
  617. /** @var IUser|MockObject $user */
  618. $user = $this->createMock(IUser::class);
  619. $this->contactsManager->expects($this->any())
  620. ->method('search')
  621. ->willReturn([
  622. [
  623. 'UID' => 'a567',
  624. 'FN' => 'Darren Roner',
  625. 'EMAIL' => [
  626. 'darren@roner.au',
  627. ],
  628. 'isLocalSystemBook' => true,
  629. ],
  630. [
  631. 'UID' => 'john',
  632. 'FN' => 'John Doe',
  633. 'EMAIL' => [
  634. 'john@example.com',
  635. ],
  636. 'isLocalSystemBook' => true,
  637. ],
  638. [
  639. 'FN' => 'Anne D',
  640. 'EMAIL' => [
  641. 'anne@example.com',
  642. ],
  643. 'isLocalSystemBook' => false,
  644. ],
  645. ]);
  646. $user->expects($this->any())
  647. ->method('getUID')
  648. ->willReturn('user123');
  649. // Complete match on UID should match
  650. $entry = $this->contactsStore->getContacts($user, 'a567');
  651. $this->assertSame(2, count($entry));
  652. $this->assertEquals([
  653. 'darren@roner.au'
  654. ], $entry[0]->getEMailAddresses());
  655. // Partial match on UID should not match
  656. $entry = $this->contactsStore->getContacts($user, 'a56');
  657. $this->assertSame(1, count($entry));
  658. $this->assertEquals([
  659. 'anne@example.com'
  660. ], $entry[0]->getEMailAddresses());
  661. // Complete match on email should match
  662. $entry = $this->contactsStore->getContacts($user, 'john@example.com');
  663. $this->assertSame(2, count($entry));
  664. $this->assertEquals([
  665. 'john@example.com'
  666. ], $entry[0]->getEMailAddresses());
  667. $this->assertEquals([
  668. 'anne@example.com'
  669. ], $entry[1]->getEMailAddresses());
  670. // Partial match on email should not match
  671. $entry = $this->contactsStore->getContacts($user, 'john@example.co');
  672. $this->assertSame(1, count($entry));
  673. $this->assertEquals([
  674. 'anne@example.com'
  675. ], $entry[0]->getEMailAddresses());
  676. // Match on FN should not match
  677. $entry = $this->contactsStore->getContacts($user, 'Darren Roner');
  678. $this->assertSame(1, count($entry));
  679. $this->assertEquals([
  680. 'anne@example.com'
  681. ], $entry[0]->getEMailAddresses());
  682. // Don't filter users in local addressbook
  683. $entry = $this->contactsStore->getContacts($user, 'Anne D');
  684. $this->assertSame(1, count($entry));
  685. $this->assertEquals([
  686. 'anne@example.com'
  687. ], $entry[0]->getEMailAddresses());
  688. }
  689. public function testGetContactsWithFilterWithoutFullMatch() {
  690. $this->config
  691. ->method('getAppValue')
  692. ->willReturnMap([
  693. ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'no'],
  694. ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'no'],
  695. ]);
  696. /** @var IUser|MockObject $user */
  697. $user = $this->createMock(IUser::class);
  698. $this->contactsManager->expects($this->any())
  699. ->method('search')
  700. ->willReturn([
  701. [
  702. 'UID' => 'a567',
  703. 'FN' => 'Darren Roner',
  704. 'EMAIL' => [
  705. 'darren@roner.au',
  706. ],
  707. 'isLocalSystemBook' => true,
  708. ],
  709. [
  710. 'UID' => 'john',
  711. 'FN' => 'John Doe',
  712. 'EMAIL' => [
  713. 'john@example.com',
  714. ],
  715. 'isLocalSystemBook' => true,
  716. ],
  717. [
  718. 'FN' => 'Anne D',
  719. 'EMAIL' => [
  720. 'anne@example.com',
  721. ],
  722. 'isLocalSystemBook' => false,
  723. ],
  724. ]);
  725. $user->expects($this->any())
  726. ->method('getUID')
  727. ->willReturn('user123');
  728. // Complete match on UID should not match
  729. $entry = $this->contactsStore->getContacts($user, 'a567');
  730. $this->assertSame(1, count($entry));
  731. $this->assertEquals([
  732. 'anne@example.com'
  733. ], $entry[0]->getEMailAddresses());
  734. // Partial match on UID should not match
  735. $entry = $this->contactsStore->getContacts($user, 'a56');
  736. $this->assertSame(1, count($entry));
  737. $this->assertEquals([
  738. 'anne@example.com'
  739. ], $entry[0]->getEMailAddresses());
  740. // Complete match on email should not match
  741. $entry = $this->contactsStore->getContacts($user, 'john@example.com');
  742. $this->assertSame(1, count($entry));
  743. $this->assertEquals([
  744. 'anne@example.com'
  745. ], $entry[0]->getEMailAddresses());
  746. // Partial match on email should not match
  747. $entry = $this->contactsStore->getContacts($user, 'john@example.co');
  748. $this->assertSame(1, count($entry));
  749. $this->assertEquals([
  750. 'anne@example.com'
  751. ], $entry[0]->getEMailAddresses());
  752. // Match on FN should not match
  753. $entry = $this->contactsStore->getContacts($user, 'Darren Roner');
  754. $this->assertSame(1, count($entry));
  755. $this->assertEquals([
  756. 'anne@example.com'
  757. ], $entry[0]->getEMailAddresses());
  758. // Don't filter users in local addressbook
  759. $entry = $this->contactsStore->getContacts($user, 'Anne D');
  760. $this->assertSame(1, count($entry));
  761. $this->assertEquals([
  762. 'anne@example.com'
  763. ], $entry[0]->getEMailAddresses());
  764. }
  765. public function testFindOneUser() {
  766. $this->config
  767. ->method('getAppValue')
  768. ->willReturnMap([
  769. ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
  770. ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
  771. ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
  772. ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'],
  773. ['core', 'shareapi_exclude_groups', 'no', 'yes'],
  774. ['core', 'shareapi_exclude_groups_list', '', ''],
  775. ['core', 'shareapi_only_share_with_group_members', 'no', 'no'],
  776. ]);
  777. /** @var IUser|MockObject $user */
  778. $user = $this->createMock(IUser::class);
  779. $this->contactsManager->expects($this->once())
  780. ->method('search')
  781. ->with($this->equalTo('a567'), $this->equalTo(['UID']))
  782. ->willReturn([
  783. [
  784. 'UID' => 123,
  785. 'isLocalSystemBook' => false
  786. ],
  787. [
  788. 'UID' => 'a567',
  789. 'FN' => 'Darren Roner',
  790. 'EMAIL' => [
  791. 'darren@roner.au'
  792. ],
  793. 'isLocalSystemBook' => true
  794. ],
  795. ]);
  796. $user->expects($this->any())
  797. ->method('getUID')
  798. ->willReturn('user123');
  799. $entry = $this->contactsStore->findOne($user, 0, 'a567');
  800. $this->assertEquals([
  801. 'darren@roner.au'
  802. ], $entry->getEMailAddresses());
  803. }
  804. public function testFindOneEMail() {
  805. /** @var IUser|MockObject $user */
  806. $user = $this->createMock(IUser::class);
  807. $this->contactsManager->expects($this->once())
  808. ->method('search')
  809. ->with($this->equalTo('darren@roner.au'), $this->equalTo(['EMAIL']))
  810. ->willReturn([
  811. [
  812. 'UID' => 123,
  813. 'isLocalSystemBook' => false
  814. ],
  815. [
  816. 'UID' => 'a567',
  817. 'FN' => 'Darren Roner',
  818. 'EMAIL' => [
  819. 'darren@roner.au'
  820. ],
  821. 'isLocalSystemBook' => false
  822. ],
  823. ]);
  824. $user->expects($this->any())
  825. ->method('getUID')
  826. ->willReturn('user123');
  827. $entry = $this->contactsStore->findOne($user, 4, 'darren@roner.au');
  828. $this->assertEquals([
  829. 'darren@roner.au'
  830. ], $entry->getEMailAddresses());
  831. }
  832. public function testFindOneNotSupportedType() {
  833. /** @var IUser|MockObject $user */
  834. $user = $this->createMock(IUser::class);
  835. $entry = $this->contactsStore->findOne($user, 42, 'darren@roner.au');
  836. $this->assertEquals(null, $entry);
  837. }
  838. public function testFindOneNoMatches() {
  839. /** @var IUser|MockObject $user */
  840. $user = $this->createMock(IUser::class);
  841. $this->contactsManager->expects($this->once())
  842. ->method('search')
  843. ->with($this->equalTo('a567'), $this->equalTo(['UID']))
  844. ->willReturn([
  845. [
  846. 'UID' => 123,
  847. 'isLocalSystemBook' => false
  848. ],
  849. [
  850. 'UID' => 'a567',
  851. 'FN' => 'Darren Roner',
  852. 'EMAIL' => [
  853. 'darren@roner.au123'
  854. ],
  855. 'isLocalSystemBook' => false
  856. ],
  857. ]);
  858. $user->expects($this->never())
  859. ->method('getUID');
  860. $entry = $this->contactsStore->findOne($user, 0, 'a567');
  861. $this->assertEquals(null, $entry);
  862. }
  863. }