MailPluginTest.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  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\MailPlugin;
  25. use OC\Collaboration\Collaborators\SearchResult;
  26. use OC\Federation\CloudIdManager;
  27. use OCP\Collaboration\Collaborators\SearchResultType;
  28. use OCP\Contacts\IManager;
  29. use OCP\Federation\ICloudIdManager;
  30. use OCP\IConfig;
  31. use OCP\IGroupManager;
  32. use OCP\IUser;
  33. use OCP\IUserSession;
  34. use OCP\Share\IShare;
  35. use Test\TestCase;
  36. class MailPluginTest extends TestCase {
  37. /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
  38. protected $config;
  39. /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
  40. protected $contactsManager;
  41. /** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */
  42. protected $cloudIdManager;
  43. /** @var MailPlugin */
  44. protected $plugin;
  45. /** @var SearchResult */
  46. protected $searchResult;
  47. /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */
  48. protected $groupManager;
  49. /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
  50. protected $userSession;
  51. protected function setUp(): void {
  52. parent::setUp();
  53. $this->config = $this->createMock(IConfig::class);
  54. $this->contactsManager = $this->createMock(IManager::class);
  55. $this->groupManager = $this->createMock(IGroupManager::class);
  56. $this->userSession = $this->createMock(IUserSession::class);
  57. $this->cloudIdManager = new CloudIdManager($this->contactsManager);
  58. $this->searchResult = new SearchResult();
  59. }
  60. public function instantiatePlugin() {
  61. $this->plugin = new MailPlugin($this->contactsManager, $this->cloudIdManager, $this->config, $this->groupManager, $this->userSession);
  62. }
  63. /**
  64. * @dataProvider dataGetEmail
  65. *
  66. * @param string $searchTerm
  67. * @param array $contacts
  68. * @param bool $shareeEnumeration
  69. * @param array $expected
  70. * @param bool $reachedEnd
  71. */
  72. public function testSearch($searchTerm, $contacts, $shareeEnumeration, $expected, $exactIdMatch, $reachedEnd) {
  73. $this->config->expects($this->any())
  74. ->method('getAppValue')
  75. ->willReturnCallback(
  76. function ($appName, $key, $default) use ($shareeEnumeration) {
  77. if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
  78. return $shareeEnumeration ? 'yes' : 'no';
  79. }
  80. return $default;
  81. }
  82. );
  83. $this->instantiatePlugin();
  84. $currentUser = $this->createMock(IUser::class);
  85. $currentUser->method('getUID')
  86. ->willReturn('current');
  87. $this->userSession->method('getUser')
  88. ->willReturn($currentUser);
  89. $this->contactsManager->expects($this->any())
  90. ->method('search')
  91. ->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) {
  92. if ($search === $searchTerm) {
  93. return $contacts;
  94. }
  95. return [];
  96. });
  97. $moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
  98. $result = $this->searchResult->asArray();
  99. $this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
  100. $this->assertEquals($expected, $result);
  101. $this->assertSame($reachedEnd, $moreResults);
  102. }
  103. public function dataGetEmail() {
  104. return [
  105. // data set 0
  106. ['test', [], true, ['emails' => [], 'exact' => ['emails' => []]], false, false],
  107. // data set 1
  108. ['test', [], false, ['emails' => [], 'exact' => ['emails' => []]], false, false],
  109. // data set 2
  110. [
  111. 'test@remote.com',
  112. [],
  113. true,
  114. ['emails' => [], 'exact' => ['emails' => [['uuid' => 'test@remote.com', 'label' => 'test@remote.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]],
  115. false,
  116. false,
  117. ],
  118. // data set 3
  119. [ // no valid email address
  120. 'test@remote',
  121. [],
  122. true,
  123. ['emails' => [], 'exact' => ['emails' => []]],
  124. false,
  125. false,
  126. ],
  127. // data set 4
  128. [
  129. 'test@remote.com',
  130. [],
  131. false,
  132. ['emails' => [], 'exact' => ['emails' => [['uuid' => 'test@remote.com', 'label' => 'test@remote.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]],
  133. false,
  134. false,
  135. ],
  136. // data set 5
  137. [
  138. 'test',
  139. [
  140. [
  141. 'UID' => 'uid3',
  142. 'FN' => 'User3 @ Localhost',
  143. ],
  144. [
  145. 'UID' => 'uid2',
  146. 'FN' => 'User2 @ Localhost',
  147. 'EMAIL' => [
  148. ],
  149. ],
  150. [
  151. 'UID' => 'uid1',
  152. 'FN' => 'User @ Localhost',
  153. 'EMAIL' => [
  154. 'username@localhost',
  155. ],
  156. ],
  157. ],
  158. true,
  159. ['emails' => [['uuid' => 'uid1', 'name' => 'User @ Localhost', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => []]],
  160. false,
  161. false,
  162. ],
  163. // data set 6
  164. [
  165. 'test',
  166. [
  167. [
  168. 'UID' => 'uid3',
  169. 'FN' => 'User3 @ Localhost',
  170. ],
  171. [
  172. 'UID' => 'uid2',
  173. 'FN' => 'User2 @ Localhost',
  174. 'EMAIL' => [
  175. ],
  176. ],
  177. [
  178. 'UID' => 'uid1',
  179. 'FN' => 'User @ Localhost',
  180. 'EMAIL' => [
  181. 'username@localhost',
  182. ],
  183. ],
  184. ],
  185. false,
  186. ['emails' => [], 'exact' => ['emails' => []]],
  187. false,
  188. false,
  189. ],
  190. // data set 7
  191. [
  192. 'test@remote.com',
  193. [
  194. [
  195. 'UID' => 'uid3',
  196. 'FN' => 'User3 @ Localhost',
  197. ],
  198. [
  199. 'UID' => 'uid2',
  200. 'FN' => 'User2 @ Localhost',
  201. 'EMAIL' => [
  202. ],
  203. ],
  204. [
  205. 'UID' => 'uid1',
  206. 'FN' => 'User @ Localhost',
  207. 'EMAIL' => [
  208. 'username@localhost',
  209. ],
  210. ],
  211. ],
  212. true,
  213. ['emails' => [['uuid' => 'uid1', 'name' => 'User @ Localhost', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => [['label' => 'test@remote.com', 'uuid' => 'test@remote.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]],
  214. false,
  215. false,
  216. ],
  217. // data set 8
  218. [
  219. 'test@remote.com',
  220. [
  221. [
  222. 'UID' => 'uid3',
  223. 'FN' => 'User3 @ Localhost',
  224. ],
  225. [
  226. 'UID' => 'uid2',
  227. 'FN' => 'User2 @ Localhost',
  228. 'EMAIL' => [
  229. ],
  230. ],
  231. [
  232. 'UID' => 'uid1',
  233. 'FN' => 'User @ Localhost',
  234. 'EMAIL' => [
  235. 'username@localhost',
  236. ],
  237. ],
  238. ],
  239. false,
  240. ['emails' => [], 'exact' => ['emails' => [['label' => 'test@remote.com', 'uuid' => 'test@remote.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]],
  241. false,
  242. false,
  243. ],
  244. // data set 9
  245. [
  246. 'username@localhost',
  247. [
  248. [
  249. 'UID' => 'uid3',
  250. 'FN' => 'User3 @ Localhost',
  251. ],
  252. [
  253. 'UID' => 'uid2',
  254. 'FN' => 'User2 @ Localhost',
  255. 'EMAIL' => [
  256. ],
  257. ],
  258. [
  259. 'UID' => 'uid1',
  260. 'FN' => 'User @ Localhost',
  261. 'EMAIL' => [
  262. 'username@localhost',
  263. ],
  264. ],
  265. ],
  266. true,
  267. ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ Localhost', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]],
  268. true,
  269. false,
  270. ],
  271. // data set 10
  272. [
  273. 'username@localhost',
  274. [
  275. [
  276. 'UID' => 'uid1',
  277. 'FN' => 'User3 @ Localhost',
  278. ],
  279. [
  280. 'UID' => 'uid2',
  281. 'FN' => 'User2 @ Localhost',
  282. 'EMAIL' => [
  283. ],
  284. ],
  285. [
  286. 'UID' => 'uid1',
  287. 'FN' => 'User @ Localhost',
  288. 'EMAIL' => [
  289. 'username@localhost',
  290. ],
  291. ],
  292. ],
  293. false,
  294. ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ Localhost', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]],
  295. true,
  296. false,
  297. ],
  298. // data set 11
  299. // contact with space
  300. [
  301. 'user name@localhost',
  302. [
  303. [
  304. 'UID' => 'uid3',
  305. 'FN' => 'User3 @ Localhost',
  306. ],
  307. [
  308. 'UID' => 'uid2',
  309. 'FN' => 'User2 @ Localhost',
  310. 'EMAIL' => [
  311. ],
  312. ],
  313. [
  314. 'UID' => 'uid1',
  315. 'FN' => 'User Name @ Localhost',
  316. 'EMAIL' => [
  317. 'user name@localhost',
  318. ],
  319. ],
  320. ],
  321. false,
  322. ['emails' => [], 'exact' => ['emails' => [['name' => 'User Name @ Localhost', 'uuid' => 'uid1', 'type' => '', 'label' => 'User Name @ Localhost (user name@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'user name@localhost']]]]],
  323. true,
  324. false,
  325. ],
  326. // data set 12
  327. // remote with space, no contact
  328. [
  329. 'user space@remote.com',
  330. [
  331. [
  332. 'UID' => 'uid3',
  333. 'FN' => 'User3 @ Localhost',
  334. ],
  335. [
  336. 'UID' => 'uid2',
  337. 'FN' => 'User2 @ Localhost',
  338. 'EMAIL' => [
  339. ],
  340. ],
  341. [
  342. 'UID' => 'uid1',
  343. 'FN' => 'User @ Localhost',
  344. 'EMAIL' => [
  345. 'username@localhost',
  346. ],
  347. ],
  348. ],
  349. false,
  350. ['emails' => [], 'exact' => ['emails' => []]],
  351. false,
  352. false,
  353. ],
  354. // data set 13
  355. // Local user found by email
  356. [
  357. 'test@example.com',
  358. [
  359. [
  360. 'UID' => 'uid1',
  361. 'FN' => 'User',
  362. 'EMAIL' => ['test@example.com'],
  363. 'CLOUD' => ['test@localhost'],
  364. 'isLocalSystemBook' => true,
  365. ]
  366. ],
  367. false,
  368. ['users' => [], 'exact' => ['users' => [['uuid' => 'uid1', 'name' => 'User', 'label' => 'User (test@example.com)','value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'shareWithDisplayNameUnique' => 'test@example.com']]]],
  369. true,
  370. false,
  371. ],
  372. // data set 14
  373. // Current local user found by email => no result
  374. [
  375. 'test@example.com',
  376. [
  377. [
  378. 'UID' => 'uid1',
  379. 'FN' => 'User',
  380. 'EMAIL' => ['test@example.com'],
  381. 'CLOUD' => ['current@localhost'],
  382. 'isLocalSystemBook' => true,
  383. ]
  384. ],
  385. true,
  386. ['exact' => []],
  387. false,
  388. false,
  389. ],
  390. // data set 15
  391. // Pagination and "more results" for user matches byyyyyyy emails
  392. [
  393. 'test@example',
  394. [
  395. [
  396. 'UID' => 'uid1',
  397. 'FN' => 'User1',
  398. 'EMAIL' => ['test@example.com'],
  399. 'CLOUD' => ['test1@localhost'],
  400. 'isLocalSystemBook' => true,
  401. ],
  402. [
  403. 'UID' => 'uid2',
  404. 'FN' => 'User2',
  405. 'EMAIL' => ['test@example.de'],
  406. 'CLOUD' => ['test2@localhost'],
  407. 'isLocalSystemBook' => true,
  408. ],
  409. [
  410. 'UID' => 'uid3',
  411. 'FN' => 'User3',
  412. 'EMAIL' => ['test@example.org'],
  413. 'CLOUD' => ['test3@localhost'],
  414. 'isLocalSystemBook' => true,
  415. ],
  416. [
  417. 'UID' => 'uid4',
  418. 'FN' => 'User4',
  419. 'EMAIL' => ['test@example.net'],
  420. 'CLOUD' => ['test4@localhost'],
  421. 'isLocalSystemBook' => true,
  422. ],
  423. ],
  424. true,
  425. ['users' => [
  426. ['uuid' => 'uid1', 'name' => 'User1', 'label' => 'User1 (test@example.com)', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'shareWithDisplayNameUnique' => 'test@example.com'],
  427. ['uuid' => 'uid2', 'name' => 'User2', 'label' => 'User2 (test@example.de)', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'shareWithDisplayNameUnique' => 'test@example.de'],
  428. ], 'emails' => [], 'exact' => ['users' => [], 'emails' => []]],
  429. false,
  430. true,
  431. ],
  432. // data set 16
  433. // Pagination and "more results" for normal emails
  434. [
  435. 'test@example',
  436. [
  437. [
  438. 'UID' => 'uid1',
  439. 'FN' => 'User1',
  440. 'EMAIL' => ['test@example.com'],
  441. 'CLOUD' => ['test1@localhost'],
  442. ],
  443. [
  444. 'UID' => 'uid2',
  445. 'FN' => 'User2',
  446. 'EMAIL' => ['test@example.de'],
  447. 'CLOUD' => ['test2@localhost'],
  448. ],
  449. [
  450. 'UID' => 'uid3',
  451. 'FN' => 'User3',
  452. 'EMAIL' => ['test@example.org'],
  453. 'CLOUD' => ['test3@localhost'],
  454. ],
  455. [
  456. 'UID' => 'uid4',
  457. 'FN' => 'User4',
  458. 'EMAIL' => ['test@example.net'],
  459. 'CLOUD' => ['test4@localhost'],
  460. ],
  461. ],
  462. true,
  463. ['emails' => [
  464. ['uuid' => 'uid1', 'name' => 'User1', 'type' => '', 'label' => 'User1 (test@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@example.com']],
  465. ['uuid' => 'uid2', 'name' => 'User2', 'type' => '', 'label' => 'User2 (test@example.de)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@example.de']],
  466. ], 'exact' => ['emails' => []]],
  467. false,
  468. true,
  469. ],
  470. // data set 17
  471. // multiple email addresses with type
  472. [
  473. 'User Name',
  474. [
  475. [
  476. 'UID' => 'uid3',
  477. 'FN' => 'User3',
  478. ],
  479. [
  480. 'UID' => 'uid2',
  481. 'FN' => 'User2',
  482. 'EMAIL' => [
  483. ],
  484. ],
  485. [
  486. 'UID' => 'uid1',
  487. 'FN' => 'User Name',
  488. 'EMAIL' => [
  489. ['type' => 'HOME', 'value' => 'username@localhost'],
  490. ['type' => 'WORK', 'value' => 'username@other'],
  491. ],
  492. ],
  493. ],
  494. false,
  495. ['emails' => [
  496. ], 'exact' => ['emails' => [
  497. ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'HOME', 'label' => 'User Name (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']],
  498. ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'WORK', 'label' => 'User Name (username@other)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@other']]
  499. ]]],
  500. false,
  501. false,
  502. ],
  503. ];
  504. }
  505. /**
  506. * @dataProvider dataGetEmailGroupsOnly
  507. *
  508. * @param string $searchTerm
  509. * @param array $contacts
  510. * @param array $expected
  511. * @param bool $exactIdMatch
  512. * @param bool $reachedEnd
  513. * @param array groups
  514. */
  515. public function testSearchGroupsOnly($searchTerm, $contacts, $expected, $exactIdMatch, $reachedEnd, $userToGroupMapping) {
  516. $this->config->expects($this->any())
  517. ->method('getAppValue')
  518. ->willReturnCallback(
  519. function ($appName, $key, $default) {
  520. if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
  521. return 'yes';
  522. } elseif ($appName === 'core' && $key === 'shareapi_only_share_with_group_members') {
  523. return 'yes';
  524. }
  525. return $default;
  526. }
  527. );
  528. $this->instantiatePlugin();
  529. /** @var \OCP\IUser | \PHPUnit\Framework\MockObject\MockObject */
  530. $currentUser = $this->createMock('\OCP\IUser');
  531. $currentUser->expects($this->any())
  532. ->method('getUID')
  533. ->willReturn('currentUser');
  534. $this->contactsManager->expects($this->any())
  535. ->method('search')
  536. ->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) {
  537. if ($search === $searchTerm) {
  538. return $contacts;
  539. }
  540. return [];
  541. });
  542. $this->userSession->expects($this->any())
  543. ->method('getUser')
  544. ->willReturn($currentUser);
  545. $this->groupManager->expects($this->any())
  546. ->method('getUserGroupIds')
  547. ->willReturnCallback(function (\OCP\IUser $user) use ($userToGroupMapping) {
  548. return $userToGroupMapping[$user->getUID()];
  549. });
  550. $this->groupManager->expects($this->any())
  551. ->method('isInGroup')
  552. ->willReturnCallback(function ($userId, $group) use ($userToGroupMapping) {
  553. return in_array($group, $userToGroupMapping[$userId]);
  554. });
  555. $moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
  556. $result = $this->searchResult->asArray();
  557. $this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
  558. $this->assertEquals($expected, $result);
  559. $this->assertSame($reachedEnd, $moreResults);
  560. }
  561. public function dataGetEmailGroupsOnly() {
  562. return [
  563. // The user `User` can share with the current user
  564. [
  565. 'test',
  566. [
  567. [
  568. 'FN' => 'User',
  569. 'EMAIL' => ['test@example.com'],
  570. 'CLOUD' => ['test@localhost'],
  571. 'isLocalSystemBook' => true,
  572. 'UID' => 'User'
  573. ]
  574. ],
  575. ['users' => [['label' => 'User (test@example.com)', 'uuid' => 'User', 'name' => 'User', 'value' => ['shareType' => 0, 'shareWith' => 'test'],'shareWithDisplayNameUnique' => 'test@example.com',]], 'emails' => [], 'exact' => ['emails' => [], 'users' => []]],
  576. false,
  577. false,
  578. [
  579. "currentUser" => ["group1"],
  580. "User" => ["group1"]
  581. ]
  582. ],
  583. // The user `User` cannot share with the current user
  584. [
  585. 'test',
  586. [
  587. [
  588. 'FN' => 'User',
  589. 'EMAIL' => ['test@example.com'],
  590. 'CLOUD' => ['test@localhost'],
  591. 'isLocalSystemBook' => true,
  592. 'UID' => 'User'
  593. ]
  594. ],
  595. ['emails'=> [], 'exact' => ['emails' => []]],
  596. false,
  597. false,
  598. [
  599. "currentUser" => ["group1"],
  600. "User" => ["group2"]
  601. ]
  602. ],
  603. // The user `User` cannot share with the current user, but there is an exact match on the e-mail address -> share by e-mail
  604. [
  605. 'test@example.com',
  606. [
  607. [
  608. 'FN' => 'User',
  609. 'EMAIL' => ['test@example.com'],
  610. 'CLOUD' => ['test@localhost'],
  611. 'isLocalSystemBook' => true,
  612. 'UID' => 'User'
  613. ]
  614. ],
  615. ['emails' => [], 'exact' => ['emails' => [['label' => 'test@example.com', 'uuid' => 'test@example.com', 'value' => ['shareType' => 4,'shareWith' => 'test@example.com']]]]],
  616. false,
  617. false,
  618. [
  619. "currentUser" => ["group1"],
  620. "User" => ["group2"]
  621. ]
  622. ]
  623. ];
  624. }
  625. }