diff --git a/appinfo/routes.php b/appinfo/routes.php
index b05194360..93fa5662a 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -39,6 +39,8 @@
['name' => 'contact#searchPhoto', 'url' => '/v1/autocompletion/photo', 'verb' => 'POST'],
// Circles
['name' => 'contact#getCircleMembers', 'url' => '/v1/circles/getmembers', 'verb' => 'GET'],
+ // Contact Groups
+ ['name' => 'contact#getContactGroupMembers', 'url' => '/v1/autocompletion/groupmembers', 'verb' => 'POST'],
// Settings
['name' => 'settings#setConfig', 'url' => '/v1/config/{key}', 'verb' => 'POST'],
// Tools
diff --git a/lib/Controller/ContactController.php b/lib/Controller/ContactController.php
index af1ee7518..702258696 100644
--- a/lib/Controller/ContactController.php
+++ b/lib/Controller/ContactController.php
@@ -7,11 +7,14 @@
*/
namespace OCA\Calendar\Controller;
+use Exception;
+use OCA\Calendar\Service\ContactsService;
use OCA\Calendar\Service\ServiceException;
use OCA\Circles\Exceptions\CircleNotFoundException;
use OCP\App\IAppManager;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\QueryException;
use OCP\Contacts\IManager;
@@ -24,31 +27,21 @@
* @package OCA\Calendar\Controller
*/
class ContactController extends Controller {
- /** @var IManager */
- private $contactsManager;
-
- /** @var IAppManager */
- private $appManager;
-
- /** @var IUserManager */
- private $userManager;
-
/**
* ContactController constructor.
*
* @param string $appName
* @param IRequest $request
- * @param IManager $contacts
*/
- public function __construct(string $appName,
+ public function __construct(
+ string $appName,
IRequest $request,
- IManager $contacts,
- IAppManager $appManager,
- IUserManager $userManager) {
+ private IManager $contactsManager,
+ private IAppManager $appManager,
+ private IUserManager $userManager,
+ private ContactsService $contactsService,
+ ) {
parent::__construct($appName, $request);
- $this->contactsManager = $contacts;
- $this->appManager = $appManager;
- $this->userManager = $userManager;
}
/**
@@ -59,7 +52,7 @@ public function __construct(string $appName,
*
* @NoAdminRequired
*/
- public function searchLocation(string $search):JSONResponse {
+ public function searchLocation(string $search): JSONResponse {
if (!$this->contactsManager->isEnabled()) {
return new JSONResponse();
}
@@ -69,7 +62,7 @@ public function searchLocation(string $search):JSONResponse {
$contacts = [];
foreach ($result as $r) {
// Information about system users is fetched via DAV nowadays
- if (isset($r['isLocalSystemBook']) && $r['isLocalSystemBook']) {
+ if ($this->contactsService->isSystemBook($r)) {
continue;
}
@@ -77,19 +70,9 @@ public function searchLocation(string $search):JSONResponse {
continue;
}
- $name = $this->getNameFromContact($r);
- if (\is_string($r['ADR'])) {
- $r['ADR'] = [$r['ADR']];
- }
-
- $photo = isset($r['PHOTO'])
- ? $this->getPhotoUri($r['PHOTO'])
- : null;
-
- $addresses = [];
- foreach ($r['ADR'] as $address) {
- $addresses[] = trim(preg_replace("/\n+/", "\n", str_replace(';', "\n", $address)));
- }
+ $name = $this->contactsService->getNameFromContact($r);
+ $photo = $this->contactsService->getPhotoUri($r);
+ $addresses = $this->contactsService->getAddress($r);
$contacts[] = [
'name' => $name,
@@ -119,51 +102,78 @@ public function searchAttendee(string $search):JSONResponse {
$contacts = [];
foreach ($result as $r) {
- // Information about system users is fetched via DAV nowadays
- if (isset($r['isLocalSystemBook']) && $r['isLocalSystemBook']) {
+ if ($this->contactsService->isSystemBook($r) || !$this->contactsService->hasEmail($r)) {
continue;
}
-
- if (!isset($r['EMAIL'])) {
+ $name = $this->contactsService->getNameFromContact($r);
+ $email = $this->contactsService->getEmail($r);
+ $photo = $this->contactsService->getPhotoUri($r);
+ $timezoneId = $this->contactsService->getTimezoneId($r);
+ $lang = $this->contactsService->getLanguageId($r);
+ $contacts[] = [
+ 'name' => $name,
+ 'emails' => $email,
+ 'lang' => $lang,
+ 'tzid' => $timezoneId,
+ 'photo' => $photo,
+ 'type' => 'individual'
+ ];
+ }
+
+ $groups = $this->contactsManager->search($search, ['CATEGORIES']);
+ $groups = array_filter($groups, function ($group) {
+ return $this->contactsService->hasEmail($group);
+ });
+ $filtered = $this->contactsService->filterGroupsWithCount($groups, $search);
+ foreach ($filtered as $groupName => $count) {
+ if ($count === 0) {
continue;
}
+ $contacts[] = [
+ 'name' => $groupName,
+ 'emails' => ['mailto:group+' . urlencode($groupName) . '@group'],
+ 'lang' => '',
+ 'tzid' => '',
+ 'photo' => '',
+ 'type' => 'contactsgroup',
+ 'members' => $count,
+ ];
+ }
- $name = $this->getNameFromContact($r);
- if (\is_string($r['EMAIL'])) {
- $r['EMAIL'] = [$r['EMAIL']];
- }
+ return new JSONResponse($contacts);
+ }
- $photo = isset($r['PHOTO'])
- ? $this->getPhotoUri($r['PHOTO'])
- : null;
+ #[NoAdminRequired]
+ public function getContactGroupMembers(string $groupName): JSONResponse {
+ if (!$this->contactsManager->isEnabled()) {
+ return new JSONResponse();
+ }
- $lang = null;
- if (isset($r['LANG'])) {
- if (\is_array($r['LANG'])) {
- $lang = $r['LANG'][0];
- } else {
- $lang = $r['LANG'];
- }
+ $groupmembers = $this->contactsManager->search($groupName, ['CATEGORIES']);
+ $contacts = [];
+ foreach ($groupmembers as $r) {
+ if (!in_array($groupName, explode(',', $r['CATEGORIES']), true)) {
+ continue;
}
-
- $timezoneId = null;
- if (isset($r['TZ'])) {
- if (\is_array($r['TZ'])) {
- $timezoneId = $r['TZ'][0];
- } else {
- $timezoneId = $r['TZ'];
- }
+ if (!$this->contactsService->hasEmail($r) || $this->contactsService->isSystemBook($r)) {
+ continue;
}
-
+ $name = $this->contactsService->getNameFromContact($r);
+ $email = $this->contactsService->getEmail($r);
+ $photo = $this->contactsService->getPhotoUri($r);
+ $timezoneId = $this->contactsService->getTimezoneId($r);
+ $lang = $this->contactsService->getLanguageId($r);
$contacts[] = [
- 'name' => $name,
- 'emails' => $r['EMAIL'],
- 'lang' => $lang,
- 'tzid' => $timezoneId,
- 'photo' => $photo,
+ 'commonName' => $name,
+ 'email' => $email[0],
+ 'calendarUserType' => 'INDIVIDUAL',
+ 'language' => $lang,
+ 'timezoneId' => $timezoneId,
+ 'avatar' => $photo,
+ 'isUser' => false,
+ 'member' => 'mailto:group+' . urlencode($groupName) . '@group',
];
}
-
return new JSONResponse($contacts);
}
@@ -243,17 +253,14 @@ public function searchPhoto(string $search):JSONResponse {
$result = $this->contactsManager->search($search, ['EMAIL']);
foreach ($result as $r) {
- if (!isset($r['EMAIL'])) {
+ if (!$this->contactsService->hasEmail($r) || $this->contactsService->isSystemBook($r)) {
continue;
}
-
- if (\is_string($r['EMAIL'])) {
- $r['EMAIL'] = [$r['EMAIL']];
- }
+ $email = $this->contactsService->getEmail($r);
$match = false;
- foreach ($r['EMAIL'] as $email) {
- if ($email === $search) {
+ foreach ($email as $e) {
+ if ($e === $search) {
$match = true;
}
}
@@ -262,15 +269,12 @@ public function searchPhoto(string $search):JSONResponse {
continue;
}
- if (!isset($r['PHOTO'])) {
+ $photo = $this->contactsService->getPhotoUri($r);
+ if ($photo === null) {
continue;
}
- $name = $this->getNameFromContact($r);
- $photo = $this->getPhotoUri($r['PHOTO']);
- if (!$photo) {
- continue;
- }
+ $name = $this->contactsService->getNameFromContact($r);
return new JSONResponse([
'name' => $name,
@@ -281,28 +285,4 @@ public function searchPhoto(string $search):JSONResponse {
return new JSONResponse([], Http::STATUS_NOT_FOUND);
}
- /**
- * Extract name from an array containing a contact's information
- *
- * @param array $r
- * @return string
- */
- private function getNameFromContact(array $r):string {
- return $r['FN'] ?? '';
- }
-
- /**
- * Get photo uri from contact
- *
- * @param string $raw
- * @return string|null
- */
- private function getPhotoUri(string $raw):?string {
- $uriPrefix = 'VALUE=uri:';
- if (substr($raw, 0, strlen($uriPrefix)) === $uriPrefix) {
- return substr($raw, strpos($raw, 'http'));
- }
-
- return null;
- }
}
diff --git a/lib/Service/ContactsService.php b/lib/Service/ContactsService.php
new file mode 100644
index 000000000..2d35e3b54
--- /dev/null
+++ b/lib/Service/ContactsService.php
@@ -0,0 +1,144 @@
+
{{ option.commonName }}
-
+
{{ option.email }}
-
@@ -161,6 +161,21 @@ export default {
showInfo(this.$t('calendar', 'Note that members of circles get invited but are not synced yet.'))
this.resolveCircleMembers(selectedValue.id, selectedValue.email)
}
+ if (selectedValue.type === 'contactsgroup') {
+ showInfo(this.$t('calendar', 'Note that members of contact groups get invited but are not synced yet.'))
+ this.getContactGroupMembers(selectedValue.commonName)
+ let group = {
+ calendarUserType: 'GROUP',
+ commonName: selectedValue.commonName,
+ dropdownName: selectedValue.dropdownName,
+ email: selectedValue.email,
+ isUser: false,
+ subtitle: selectedValue.subtitle,
+ type: 'contactsgroup',
+ }
+ this.$emit('add-attendee', group)
+ return
+ }
this.$emit('add-attendee', selectedValue)
},
async resolveCircleMembers(circleId, groupId) {
@@ -180,6 +195,23 @@ export default {
}
})
},
+ async getContactGroupMembers(groupName) {
+ let results
+ try {
+ results = await HttpClient.post(linkTo('calendar', 'index.php') + '/v1/autocompletion/groupmembers', {
+ groupName,
+ })
+ } catch (error) {
+ console.debug(error)
+ return []
+ }
+
+ results.data.forEach((member) => {
+ if (!this.organizer || member.email !== this.organizer.uri) {
+ this.$emit('add-attendee', member)
+ }
+ })
+ },
async findAttendeesFromContactsAPI(query) {
let response
@@ -210,6 +242,24 @@ export default {
return
}
+ if(result.type === 'contactsgroup') {
+ arr.push({
+ calendarUserType: 'GROUP',
+ commonName: result.name,
+ subtitle: this.$n('calendar', '%n member', '%n members', result.members),
+ members: {length: result.members},
+ email,
+ isUser: false,
+ avatar: result.photo,
+ language: result.lang,
+ timezoneId: result.tzid,
+ hasMultipleEMails: false,
+ dropdownName: name,
+ type: 'contactsgroup',
+ })
+ return
+ }
+
arr.push({
calendarUserType: 'INDIVIDUAL',
commonName: result.name,
@@ -246,7 +296,7 @@ export default {
// We do not support GROUPS for now
if (principal.calendarUserType === 'GROUP') {
- return false
+ console.debug(principal)
}
// Do not include resources and rooms
diff --git a/src/views/EditSidebar.vue b/src/views/EditSidebar.vue
index ffec6df23..c0a1cb843 100644
--- a/src/views/EditSidebar.vue
+++ b/src/views/EditSidebar.vue
@@ -522,7 +522,6 @@ export default {
this.showPreloader = true
if (!this.isPrivate()) {
this.showModalNewAttachments.map(async (attachment, i) => {
- // console.log('Add share', attachment)
this.sharedProgress = Math.ceil(100 * (i + 1) / total)
// add share + change attachment
diff --git a/tests/php/unit/Controller/ContactControllerTest.php b/tests/php/unit/Controller/ContactControllerTest.php
index 3b176ee3c..afba3dfb7 100644
--- a/tests/php/unit/Controller/ContactControllerTest.php
+++ b/tests/php/unit/Controller/ContactControllerTest.php
@@ -8,6 +8,7 @@
namespace OCA\Calendar\Controller;
use ChristophWurst\Nextcloud\Testing\TestCase;
+use OCA\Calendar\Service\ContactsService;
use OCP\App\IAppManager;
use OCP\AppFramework\Http\JSONResponse;
use OCP\Contacts\IManager;
@@ -30,6 +31,7 @@ class ContactControllerTest extends TestCase {
/** @var IUserManager|MockObject */
private $userManager;
+ private ContactsService|MockObject $service;
/** @var ContactController */
protected $controller;
@@ -42,17 +44,22 @@ protected function setUp():void {
$this->manager = $this->createMock(IManager::class);
$this->appManager = $this->createMock(IAppManager::class);
$this->userManager = $this->createMock(IUserManager::class);
+ $this->service = $this->createMock(ContactsService::class);
$this->controller = new ContactController($this->appName,
- $this->request, $this->manager, $this->appManager, $this->userManager);
+ $this->request,
+ $this->manager,
+ $this->appManager,
+ $this->userManager,
+ $this->service
+ );
}
public function testSearchLocationDisabled():void {
- $this->manager->expects($this->once())
+ $this->manager->expects(self::once())
->method('isEnabled')
- ->with()
->willReturn(false);
- $this->manager->expects($this->never())
+ $this->manager->expects(self::never())
->method('search');
$response = $this->controller->searchLocation('search 123');
@@ -63,57 +70,89 @@ public function testSearchLocationDisabled():void {
}
public function testSearchLocation():void {
+ $user1 = [
+ 'FN' => 'Person 1',
+ 'ADR' => [
+ '33 42nd Street;Random Town;Some State;;United States',
+ ';;5 Random Ave;12782 Some big city;Yet another state;United States',
+ ],
+ 'EMAIL' => [
+ 'foo1@example.com',
+ 'foo2@example.com',
+ ],
+ 'LANG' => [
+ 'de',
+ 'en'
+ ],
+ 'TZ' => [
+ 'Europe/Berlin',
+ 'UTC'
+ ],
+ 'PHOTO' => 'VALUE=uri:http://foo.bar'
+ ];
+ $user2 = [
+ 'FN' => 'Person 2',
+ 'EMAIL' => 'foo3@example.com',
+ ];
+ $user3 = [
+ 'ADR' => [
+ 'ABC Street 2;01337 Village;;Germany',
+ ],
+ 'LANG' => 'en_us',
+ 'TZ' => 'Australia/Adelaide',
+ 'PHOTO' => 'VALUE:BINARY:4242424242'
+ ];
+ $user4 = [
+ 'isLocalSystemBook' => true,
+ 'FN' => 'Person 3',
+ 'ADR' => [
+ 'ABC Street 2;01337 Village;;Germany',
+ ],
+ 'LANG' => 'en_us',
+ 'TZ' => 'Australia/Adelaide',
+ 'PHOTO' => 'VALUE:BINARY:4242424242'
+ ];
+
$this->manager->expects(self::once())
->method('isEnabled')
- ->with()
->willReturn(true);
-
+ $this->service
+ ->method('isSystemBook')
+ ->willReturnMap([
+ [$user1, false],
+ [$user2, false],
+ [$user3, false],
+ [$user4, true],
+ ]);
+ $this->service
+ ->method('getNameFromContact')
+ ->willReturnMap([
+ [$user1, 'Person 1'],
+ [$user3, ''],
+ ]);
+ $this->service->method('getPhotoUri')
+ ->willReturnMap([
+ [$user1, 'http://foo.bar'],
+ [$user3, null]
+ ]);
+ $this->service->method('getAddress')
+ ->willReturnMap([
+ [$user1, [
+ "33 42nd Street\nRandom Town\nSome State\nUnited States",
+ "5 Random Ave\n12782 Some big city\nYet another state\nUnited States",
+ ]],
+ [$user3, [
+ "ABC Street 2\n01337 Village\nGermany",
+ ]],
+ ]);
$this->manager->expects(self::once())
->method('search')
->with('search 123', ['FN', 'ADR'])
->willReturn([
- [
- 'FN' => 'Person 1',
- 'ADR' => [
- '33 42nd Street;Random Town;Some State;;United States',
- ';;5 Random Ave;12782 Some big city;Yet another state;United States',
- ],
- 'EMAIL' => [
- 'foo1@example.com',
- 'foo2@example.com',
- ],
- 'LANG' => [
- 'de',
- 'en'
- ],
- 'TZ' => [
- 'Europe/Berlin',
- 'UTC'
- ],
- 'PHOTO' => 'VALUE=uri:http://foo.bar'
- ],
- [
- 'FN' => 'Person 2',
- 'EMAIL' => 'foo3@example.com',
- ],
- [
- 'ADR' => [
- 'ABC Street 2;01337 Village;;Germany',
- ],
- 'LANG' => 'en_us',
- 'TZ' => 'Australia/Adelaide',
- 'PHOTO' => 'VALUE:BINARY:4242424242'
- ],
- [
- 'isLocalSystemBook' => true,
- 'FN' => 'Person 3',
- 'ADR' => [
- 'ABC Street 2;01337 Village;;Germany',
- ],
- 'LANG' => 'en_us',
- 'TZ' => 'Australia/Adelaide',
- 'PHOTO' => 'VALUE:BINARY:4242424242'
- ],
+ $user1,
+ $user2,
+ $user3,
+ $user4,
]);
$response = $this->controller->searchLocation('search 123');
@@ -138,31 +177,44 @@ public function testSearchLocation():void {
$this->assertEquals(200, $response->getStatus());
}
- public function testSearchAttendeeDisabled():void {
- $this->manager->expects($this->once())
+ public function testGetGroupMembersNoResults() {
+ $this->manager->expects(self::once())
->method('isEnabled')
- ->with()
- ->willReturn(false);
-
- $this->manager->expects($this->never())
- ->method('search');
+ ->willReturn(true);
- $response = $this->controller->searchAttendee('search 123');
+ $groupname = 'groupname';
+ $this->manager->expects(self::once())
+ ->method('search')
+ ->with($groupname, ['CATEGORIES'])
+ ->willReturn([]);
- $this->assertInstanceOf(JSONResponse::class, $response);
- $this->assertEquals([], $response->getData());
- $this->assertEquals(200, $response->getStatus());
+ $this->controller->getContactGroupMembers($groupname);
}
- public function testSearchAttendee():void {
+ public function testGetGroupMembers() {
$this->manager->expects(self::once())
->method('isEnabled')
- ->with()
->willReturn(true);
-
+ $this->service->expects(self::once())
+ ->method('hasEmail')
+ ->willReturn(true);
+ $this->service->expects(self::once())
+ ->method('getNameFromContact')
+ ->willReturn('Person 1');
+ $this->service->expects(self::once())
+ ->method('getLanguageId')
+ ->willReturn('en_us');
+ $this->service->expects(self::once())
+ ->method('getTimezoneId')
+ ->willReturn('Australia/Adelaide');
+ $this->service->expects(self::once())
+ ->method('getEmail')
+ ->willReturn(['foo1@example.com']);
+
+ $groupname = 'group';
$this->manager->expects(self::once())
->method('search')
- ->with('search 123', ['FN', 'EMAIL'])
+ ->with($groupname, ['CATEGORIES'])
->willReturn([
[
'FN' => 'Person 1',
@@ -182,11 +234,13 @@ public function testSearchAttendee():void {
'Europe/Berlin',
'UTC'
],
- 'PHOTO' => 'VALUE=uri:http://foo.bar'
+ 'PHOTO' => 'VALUE=uri:http://foo.bar',
+ 'CATEGORIES' => 'groupname,group',
],
[
'FN' => 'Person 2',
'EMAIL' => 'foo3@example.com',
+ 'CATEGORIES' => 'groups,asecondgroup',
],
[
'ADR' => [
@@ -194,7 +248,8 @@ public function testSearchAttendee():void {
],
'LANG' => 'en_us',
'TZ' => 'Australia/Adelaide',
- 'PHOTO' => 'VALUE:BINARY:4242424242'
+ 'PHOTO' => 'VALUE:BINARY:4242424242',
+ 'CATEGORIES' => 'agroupthatswrong,asecondgroup',
],
[
'isLocalSystemBook' => true,
@@ -202,12 +257,141 @@ public function testSearchAttendee():void {
'ADR' => [
'ABC Street 2;01337 Village;;Germany',
],
+ 'EMAIL' => 'foo4@example.com',
'LANG' => 'en_us',
'TZ' => 'Australia/Adelaide',
- 'PHOTO' => 'VALUE:BINARY:4242424242'
+ 'PHOTO' => 'VALUE:BINARY:4242424242',
+ 'CATEGORIES' => 'groupppppp',
],
]);
+ $groupmembers = $this->controller->getContactGroupMembers($groupname);
+ $this->assertCount(1, $groupmembers->getData());
+ }
+
+ public function testSearchAttendeeDisabled():void {
+ $this->manager->expects(self::once())
+ ->method('isEnabled')
+ ->willReturn(false);
+
+ $this->manager->expects(self::never())
+ ->method('search');
+
+ $response = $this->controller->searchAttendee('search 123');
+
+ $this->assertInstanceOf(JSONResponse::class, $response);
+ $this->assertEquals([], $response->getData());
+ $this->assertEquals(200, $response->getStatus());
+ }
+
+ public function testSearchAttendee():void {
+ $user1 = [
+ 'FN' => 'Person 1',
+ 'ADR' => [
+ '33 42nd Street;Random Town;Some State;;United States',
+ ';;5 Random Ave;12782 Some big city;Yet another state;United States',
+ ],
+ 'EMAIL' => [
+ 'foo1@example.com',
+ 'foo2@example.com',
+ ],
+ 'LANG' => [
+ 'de',
+ 'en'
+ ],
+ 'TZ' => [
+ 'Europe/Berlin',
+ 'UTC'
+ ],
+ 'PHOTO' => 'VALUE=uri:http://foo.bar'
+ ];
+ $user2 = [
+ 'FN' => 'Person 2',
+ 'EMAIL' => 'foo3@example.com',
+ ];
+ $user3 = [
+ 'ADR' => [
+ 'ABC Street 2;01337 Village;;Germany',
+ ],
+ 'LANG' => 'en_us',
+ 'TZ' => 'Australia/Adelaide',
+ 'PHOTO' => 'VALUE:BINARY:4242424242'
+ ];
+ $user4 = [
+ 'isLocalSystemBook' => true,
+ 'FN' => 'Person 3',
+ 'ADR' => [
+ 'ABC Street 2;01337 Village;;Germany',
+ ],
+ 'LANG' => 'en_us',
+ 'TZ' => 'Australia/Adelaide',
+ 'PHOTO' => 'VALUE:BINARY:4242424242',
+ 'CATEGORIES' => 'search 123'
+ ];
+
+ $this->manager->expects(self::once())
+ ->method('isEnabled')
+ ->willReturn(true);
+ $this->service
+ ->method('hasEmail')
+ ->willReturnMap([
+ [$user1, true],
+ [$user2, true],
+ [$user3, false],
+ [$user4, true],
+ ]);
+ $this->service
+ ->method('isSystemBook')
+ ->willReturnMap([
+ [$user1, false],
+ [$user2, false],
+ [$user3, false],
+ [$user4, true],
+ ]);
+ $this->service
+ ->method('getNameFromContact')
+ ->willReturnMap([
+ [$user1, 'Person 1'],
+ [$user2, 'Person 2'],
+ [$user3, ''],
+ ]);
+ $this->service->expects(self::exactly(2))
+ ->method('getLanguageId')
+ ->willReturnMap([
+ [$user1, 'de'],
+ [$user3, 'en_us'],
+ ]);
+ $this->service->expects(self::exactly(2))
+ ->method('getTimezoneId')
+ ->willReturnMap([
+ [$user1, 'Europe/Berlin'],
+ [$user3, 'Australia/Adelaide'],
+ ]);
+ $this->service->expects(self::exactly(2))
+ ->method('getEmail')
+ ->willReturnMap([
+ [$user1, [
+ 'foo1@example.com',
+ 'foo2@example.com',
+ ]
+ ],
+ [$user2, ['foo3@example.com']],
+ [$user3, ['foo5@example.com']],
+ ]);
+ $this->service->method('getPhotoUri')
+ ->willReturnMap([
+ [$user1, 'http://foo.bar'],
+ [$user2, null],
+ [$user3, null],
+ [$user4, null],
+ ]);
+ $this->manager->expects(self::exactly(2))
+ ->method('search')
+ ->willReturnMap([
+ ['search 123', ['FN', 'EMAIL'], [], [$user1, $user2, $user3, $user4]],
+ ['search 123', ['CATEGORIES'], [], [$user4]]
+ ]);
+
$response = $this->controller->searchAttendee('search 123');
$this->assertInstanceOf(JSONResponse::class, $response);
@@ -221,6 +405,7 @@ public function testSearchAttendee():void {
'lang' => 'de',
'tzid' => 'Europe/Berlin',
'photo' => 'http://foo.bar',
+ 'type' => 'individual'
], [
'name' => 'Person 2',
'emails' => [
@@ -229,80 +414,102 @@ public function testSearchAttendee():void {
'lang' => null,
'tzid' => null,
'photo' => null,
+ 'type' => 'individual'
]
], $response->getData());
$this->assertEquals(200, $response->getStatus());
}
public function testSearchPhotoDisabled():void {
- $this->manager->expects($this->once())
+ $this->manager->expects(self::once())
->method('isEnabled')
- ->with()
->willReturn(false);
- $this->manager->expects($this->never())
+ $this->manager->expects(self::never())
->method('search');
$response = $this->controller->searchAttendee('search 123');
- $this->assertInstanceOf(JSONResponse::class, $response);
$this->assertEquals([], $response->getData());
$this->assertEquals(200, $response->getStatus());
}
public function testSearchPhoto():void {
+ $user1 = [
+ 'FN' => 'Person 1',
+ 'ADR' => [
+ '33 42nd Street;Random Town;Some State;;United States',
+ ';;5 Random Ave;12782 Some big city;Yet another state;United States',
+ ],
+ 'EMAIL' => [
+ 'foo1@example.com',
+ 'foo2@example.com',
+ ],
+ 'LANG' => [
+ 'de',
+ 'en'
+ ],
+ 'TZ' => [
+ 'Europe/Berlin',
+ 'UTC'
+ ],
+ 'PHOTO' => 'VALUE=uri:http://foo123.bar'
+ ];
+ $user2 = [
+ 'FN' => 'Person 2',
+ 'EMAIL' => 'foo3@example.com',
+ 'PHOTO' => 'VALUE=uri:http://foo.bar'
+ ];
+ $user3 = [
+ 'ADR' => [
+ 'ABC Street 2;01337 Village;;Germany',
+ ],
+ 'LANG' => 'en_us',
+ 'TZ' => 'Australia/Adelaide',
+ 'PHOTO' => 'VALUE:BINARY:4242424242'
+ ];
+ $user4 = [
+ 'isLocalSystemBook' => true,
+ 'FN' => 'Person 3',
+ 'ADR' => [
+ 'ABC Street 2;01337 Village;;Germany',
+ ],
+ 'EMAIL' => 'foo5@example.com',
+ 'LANG' => 'en_us',
+ 'TZ' => 'Australia/Adelaide',
+ 'PHOTO' => 'VALUE=uri:http://foo456.bar'
+ ];
+
$this->manager->expects(self::once())
->method('isEnabled')
- ->with()
->willReturn(true);
-
+ $this->service->method('hasEmail')->willReturnMap([
+ [$user1, true],
+ [$user2, true],
+ [$user3, false],
+ [$user3, true],
+ ]);
+ $this->service->method('isSystemBook');
+ $this->service->method('getEmail')
+ ->willReturnMap([
+ [$user1, [
+ 'foo1@example.com',
+ 'foo2@example.com',
+ ]
+ ],
+ [$user2, ['foo3@example.com']],
+ [$user3, ['foo5@example.com']],
+ ]);
+ $this->service->method('getNameFromContact')->willReturn('Person 2');
+ $this->service->method('getPhotoUri')->willReturn('http://foo.bar');
$this->manager->expects(self::once())
->method('search')
->with('foo3@example.com', ['EMAIL'])
->willReturn([
- [
- 'FN' => 'Person 1',
- 'ADR' => [
- '33 42nd Street;Random Town;Some State;;United States',
- ';;5 Random Ave;12782 Some big city;Yet another state;United States',
- ],
- 'EMAIL' => [
- 'foo1@example.com',
- 'foo2@example.com',
- ],
- 'LANG' => [
- 'de',
- 'en'
- ],
- 'TZ' => [
- 'Europe/Berlin',
- 'UTC'
- ],
- 'PHOTO' => 'VALUE=uri:http://foo123.bar'
- ],
- [
- 'FN' => 'Person 2',
- 'EMAIL' => 'foo3@example.com',
- 'PHOTO' => 'VALUE=uri:http://foo.bar'
- ],
- [
- 'ADR' => [
- 'ABC Street 2;01337 Village;;Germany',
- ],
- 'LANG' => 'en_us',
- 'TZ' => 'Australia/Adelaide',
- 'PHOTO' => 'VALUE:BINARY:4242424242'
- ],
- [
- 'isLocalSystemBook' => true,
- 'FN' => 'Person 3',
- 'ADR' => [
- 'ABC Street 2;01337 Village;;Germany',
- ],
- 'LANG' => 'en_us',
- 'TZ' => 'Australia/Adelaide',
- 'PHOTO' => 'VALUE=uri:http://foo456.bar'
- ],
+ $user1,
+ $user2,
+ $user3,
+ $user4,
]);
$response = $this->controller->searchPhoto('foo3@example.com');
diff --git a/tests/php/unit/Service/ContactsServiceTest.php b/tests/php/unit/Service/ContactsServiceTest.php
new file mode 100644
index 000000000..986573f92
--- /dev/null
+++ b/tests/php/unit/Service/ContactsServiceTest.php
@@ -0,0 +1,96 @@
+service = new ContactsService();
+ }
+
+ public function testGetEmail(): void {
+ $contact = ['EMAIL' => 'test@test.com'];
+ $this->assertEquals(['test@test.com'], $this->service->getEmail($contact));
+ }
+
+ public function testIsSystemBook(): void {
+ $contact = ['isLocalSystemBook' => true];
+ $this->assertTrue($this->service->isSystemBook($contact));
+ }
+
+ public function testIsNotSystemBook(): void {
+ $contact = ['isLocalSystemBook' => false];
+ $this->assertFalse($this->service->isSystemBook($contact));
+ }
+
+ public function testNotSetSystemBook(): void {
+ $this->assertFalse($this->service->isSystemBook([]));
+ }
+
+ public function testHasEmail(): void {
+ $contact = ['EMAIL' => 'test@test.com'];
+ $this->assertTrue($this->service->hasEmail($contact));
+ }
+
+ public function testHasNoEmail(): void {
+ $this->assertFalse($this->service->hasEmail([]));
+ }
+
+ public function testGetPhotoUri(): void {
+ $contact = ['PHOTO' => 'VALUE=uri:http://test'];
+ $this->assertEquals('http://test', $this->service->getPhotoUri($contact));
+ }
+
+ public function testGetPhotoInvalidUri(): void {
+ $contact = ['PHOTO' => 'VALUE=uri:thisisnotit'];
+ $this->assertNull($this->service->getPhotoUri($contact));
+ }
+
+ public function testGetPhotoUriNoPhoto(): void {
+ $this->assertNull($this->service->getPhotoUri([]));
+ }
+
+ public function testFilterGroupsWithCount(): void {
+ $contact = [
+ ['CATEGORIES' => 'The Proclaimers,I\'m gonna be,When I go out,I would walk 500 Miles,I would walk 500 more'],
+ ['CATEGORIES' => 'The Proclaimers,When I\'m lonely,I would walk 500 Miles,I would walk 500 more'],
+ ];
+
+ $searchterm = 'walk';
+
+ $expected = [
+ 'I would walk 500 Miles' => 2,
+ 'I would walk 500 more' => 2,
+ ];
+
+ $this->assertEqualsCanonicalizing($expected, $this->service->filterGroupsWithCount($contact, $searchterm));
+ }
+
+ public function testGetTimezoneId(): void {
+ $contact = ['TZ' => ['UTC']];
+ $this->assertEquals('UTC', $this->service->getTimezoneId($contact));
+ }
+
+ public function testGetLanguageId(): void {
+ $contact = ['LANG' => ['de_de']];
+ $this->assertEquals('de_de', $this->service->getLanguageId($contact));
+ }
+
+ public function testGetNameFromContact(): void {
+ $contact = ['FN' => 'test'];
+ $this->assertEquals('test', $this->service->getNameFromContact($contact));
+ }
+
+ public function testGetNameFromContactNoName(): void {
+ $this->assertEquals('', $this->service->getNameFromContact([]));
+ }
+}