mirror of
https://github.com/nextcloud/server.git
synced 2026-06-11 09:42:09 -04:00
feat(dav): expose Nextcloud groups to Contact's system addressbook contacts
And move event listeners related to SyncService to proper ones Note: Changes to user system addressbook cards are now always done in a QueuedJob Closes #38432 Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
e98be0a147
commit
dae23b7fd8
11 changed files with 498 additions and 33 deletions
|
|
@ -21,6 +21,7 @@ return array(
|
|||
'OCA\\DAV\\BackgroundJob\\PruneOutdatedSyncTokensJob' => $baseDir . '/../lib/BackgroundJob/PruneOutdatedSyncTokensJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\RefreshWebcalJob' => $baseDir . '/../lib/BackgroundJob/RefreshWebcalJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\RegisterRegenerateBirthdayCalendars' => $baseDir . '/../lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php',
|
||||
'OCA\\DAV\\BackgroundJob\\SyncSystemAddressBookAfterUsersChange' => $baseDir . '/../lib/BackgroundJob/SyncSystemAddressBookAfterUsersChange.php',
|
||||
'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => $baseDir . '/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\UploadCleanup' => $baseDir . '/../lib/BackgroundJob/UploadCleanup.php',
|
||||
'OCA\\DAV\\BackgroundJob\\UserStatusAutomation' => $baseDir . '/../lib/BackgroundJob/UserStatusAutomation.php',
|
||||
|
|
@ -258,8 +259,10 @@ return array(
|
|||
'OCA\\DAV\\Listener\\CalendarShareUpdateListener' => $baseDir . '/../lib/Listener/CalendarShareUpdateListener.php',
|
||||
'OCA\\DAV\\Listener\\CardListener' => $baseDir . '/../lib/Listener/CardListener.php',
|
||||
'OCA\\DAV\\Listener\\ClearPhotoCacheListener' => $baseDir . '/../lib/Listener/ClearPhotoCacheListener.php',
|
||||
'OCA\\DAV\\Listener\\GroupChangeListener' => $baseDir . '/../lib/Listener/GroupChangeListener.php',
|
||||
'OCA\\DAV\\Listener\\SubscriptionListener' => $baseDir . '/../lib/Listener/SubscriptionListener.php',
|
||||
'OCA\\DAV\\Listener\\TrustedServerRemovedListener' => $baseDir . '/../lib/Listener/TrustedServerRemovedListener.php',
|
||||
'OCA\\DAV\\Listener\\UserChangeListener' => $baseDir . '/../lib/Listener/UserChangeListener.php',
|
||||
'OCA\\DAV\\Listener\\UserPreferenceListener' => $baseDir . '/../lib/Listener/UserPreferenceListener.php',
|
||||
'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndex.php',
|
||||
'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class ComposerStaticInitDAV
|
|||
'OCA\\DAV\\BackgroundJob\\PruneOutdatedSyncTokensJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/PruneOutdatedSyncTokensJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\RefreshWebcalJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/RefreshWebcalJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\RegisterRegenerateBirthdayCalendars' => __DIR__ . '/..' . '/../lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php',
|
||||
'OCA\\DAV\\BackgroundJob\\SyncSystemAddressBookAfterUsersChange' => __DIR__ . '/..' . '/../lib/BackgroundJob/SyncSystemAddressBookAfterUsersChange.php',
|
||||
'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php',
|
||||
'OCA\\DAV\\BackgroundJob\\UploadCleanup' => __DIR__ . '/..' . '/../lib/BackgroundJob/UploadCleanup.php',
|
||||
'OCA\\DAV\\BackgroundJob\\UserStatusAutomation' => __DIR__ . '/..' . '/../lib/BackgroundJob/UserStatusAutomation.php',
|
||||
|
|
@ -273,8 +274,10 @@ class ComposerStaticInitDAV
|
|||
'OCA\\DAV\\Listener\\CalendarShareUpdateListener' => __DIR__ . '/..' . '/../lib/Listener/CalendarShareUpdateListener.php',
|
||||
'OCA\\DAV\\Listener\\CardListener' => __DIR__ . '/..' . '/../lib/Listener/CardListener.php',
|
||||
'OCA\\DAV\\Listener\\ClearPhotoCacheListener' => __DIR__ . '/..' . '/../lib/Listener/ClearPhotoCacheListener.php',
|
||||
'OCA\\DAV\\Listener\\GroupChangeListener' => __DIR__ . '/..' . '/../lib/Listener/GroupChangeListener.php',
|
||||
'OCA\\DAV\\Listener\\SubscriptionListener' => __DIR__ . '/..' . '/../lib/Listener/SubscriptionListener.php',
|
||||
'OCA\\DAV\\Listener\\TrustedServerRemovedListener' => __DIR__ . '/..' . '/../lib/Listener/TrustedServerRemovedListener.php',
|
||||
'OCA\\DAV\\Listener\\UserChangeListener' => __DIR__ . '/..' . '/../lib/Listener/UserChangeListener.php',
|
||||
'OCA\\DAV\\Listener\\UserPreferenceListener' => __DIR__ . '/..' . '/../lib/Listener/UserPreferenceListener.php',
|
||||
'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndex.php',
|
||||
'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ use OCA\DAV\Events\CardDeletedEvent;
|
|||
use OCA\DAV\Events\CardUpdatedEvent;
|
||||
use OCA\DAV\Events\SubscriptionCreatedEvent;
|
||||
use OCA\DAV\Events\SubscriptionDeletedEvent;
|
||||
use OCA\DAV\Listener\GroupChangeListener;
|
||||
use OCA\DAV\Listener\UserChangeListener;
|
||||
use OCP\Accounts\UserUpdatedEvent;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Federation\Events\TrustedServerRemovedEvent;
|
||||
|
|
@ -102,6 +104,10 @@ use OCP\Config\BeforePreferenceDeletedEvent;
|
|||
use OCP\Config\BeforePreferenceSetEvent;
|
||||
use OCP\Contacts\IManager as IContactsManager;
|
||||
use OCP\Files\AppData\IAppDataFactory;
|
||||
use OCP\Group\Events\BeforeGroupChangedEvent;
|
||||
use OCP\Group\Events\BeforeGroupDeletedEvent;
|
||||
use OCP\Group\Events\UserAddedEvent;
|
||||
use OCP\Group\Events\UserRemovedEvent;
|
||||
use OCP\IUser;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
|
@ -195,6 +201,12 @@ class Application extends App implements IBootstrap {
|
|||
$context->registerEventListener(BeforePreferenceDeletedEvent::class, UserPreferenceListener::class);
|
||||
$context->registerEventListener(BeforePreferenceSetEvent::class, UserPreferenceListener::class);
|
||||
|
||||
$context->registerEventListener(BeforeGroupChangedEvent::class, GroupChangeListener::class);
|
||||
$context->registerEventListener(BeforeGroupDeletedEvent::class, GroupChangeListener::class);
|
||||
$context->registerEventListener(UserAddedEvent::class, UserChangeListener::class);
|
||||
$context->registerEventListener(UserUpdatedEvent::class, UserChangeListener::class);
|
||||
$context->registerEventListener(UserRemovedEvent::class, UserChangeListener::class);
|
||||
|
||||
$context->registerNotifierService(Notifier::class);
|
||||
|
||||
$context->registerCalendarProvider(CalendarProvider::class);
|
||||
|
|
@ -227,13 +239,6 @@ class Application extends App implements IBootstrap {
|
|||
}
|
||||
});
|
||||
|
||||
$dispatcher->addListener(UserUpdatedEvent::class, function (UserUpdatedEvent $event) use ($container) {
|
||||
/** @var SyncService $syncService */
|
||||
$syncService = \OCP\Server::get(SyncService::class);
|
||||
$syncService->updateUser($event->getUser());
|
||||
});
|
||||
|
||||
|
||||
$dispatcher->addListener(CalendarShareUpdatedEvent::class, function (CalendarShareUpdatedEvent $event) use ($container) {
|
||||
/** @var Backend $backend */
|
||||
$backend = $container->query(Backend::class);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2023, Citharel Thomas <nextcloud@tcit.fr>
|
||||
*
|
||||
* @author Citharel Thomas <nextcloud@tcit.fr>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
namespace OCA\DAV\BackgroundJob;
|
||||
|
||||
use OCA\DAV\CardDAV\SyncService;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\QueuedJob;
|
||||
use OCP\IUser;
|
||||
|
||||
class SyncSystemAddressBookAfterUsersChange extends QueuedJob {
|
||||
private SyncService $syncService;
|
||||
|
||||
public function __construct(SyncService $syncService, ITimeFactory $time) {
|
||||
parent::__construct($time);
|
||||
$this->syncService = $syncService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IUser[] $argument
|
||||
* @return void
|
||||
*/
|
||||
public function run($argument): void {
|
||||
foreach ($argument as $user) {
|
||||
$this->syncService->updateUser($user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -28,7 +28,11 @@
|
|||
namespace OCA\DAV\CardDAV;
|
||||
|
||||
use Exception;
|
||||
use OCA\DAV\AppInfo\Application;
|
||||
use OCP\Accounts\IAccountManager;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IImage;
|
||||
use OCP\IUser;
|
||||
|
|
@ -42,12 +46,16 @@ class Converter {
|
|||
/** @var IAccountManager */
|
||||
private $accountManager;
|
||||
private IUserManager $userManager;
|
||||
private IGroupManager $groupManager;
|
||||
private IConfig $config;
|
||||
|
||||
public function __construct(IAccountManager $accountManager,
|
||||
IUserManager $userManager, IURLGenerator $urlGenerator) {
|
||||
IUserManager $userManager, IGroupManager $groupManager, IURLGenerator $urlGenerator, IConfig $config) {
|
||||
$this->accountManager = $accountManager;
|
||||
$this->userManager = $userManager;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function createCardFromUser(IUser $user): ?VCard {
|
||||
|
|
@ -151,6 +159,18 @@ class Converter {
|
|||
}
|
||||
}
|
||||
|
||||
if ($this->config->getAppValue(Application::APP_ID, 'system_addressbook_expose_groups', 'no') === 'yes') {
|
||||
$groupsToInclude = explode(',', $this->config->getAppValue(Application::APP_ID, 'system_addressbook_groups_to_include', ''));
|
||||
$groupsToIgnore = explode(',', $this->config->getAppValue(Application::APP_ID, 'system_addressbook_groups_to_ignore', ''));
|
||||
$groupNames = array_reduce($this->groupManager->getUserGroups($user), function ($groupNames, IGroup $group) use ($groupsToInclude, $groupsToIgnore) {
|
||||
if (!in_array($group->getGID(), $groupsToIgnore, true) && (empty($groupsToInclude) || in_array($group->getGID(), $groupsToInclude, true))) {
|
||||
$groupNames[] = $group->getDisplayName();
|
||||
}
|
||||
return $groupNames;
|
||||
}, []);
|
||||
$vCard->add(new Text($vCard, 'CATEGORIES', $groupNames));
|
||||
}
|
||||
|
||||
if ($publish && !empty($cloudId)) {
|
||||
$vCard->add(new Text($vCard, 'CLOUD', $cloudId));
|
||||
$vCard->validate();
|
||||
|
|
|
|||
56
apps/dav/lib/Listener/GroupChangeListener.php
Normal file
56
apps/dav/lib/Listener/GroupChangeListener.php
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2023 Thomas Citharel <nextcloud@tcit.fr>
|
||||
*
|
||||
* @author Thomas Citharel <nextcloud@tcit.fr>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
namespace OCA\DAV\Listener;
|
||||
|
||||
use OCA\DAV\AppInfo\Application;
|
||||
use OCA\DAV\BackgroundJob\SyncSystemAddressBookAfterUsersChange;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventListener;
|
||||
use OCP\Group\Events\BeforeGroupChangedEvent;
|
||||
use OCP\Group\Events\BeforeGroupDeletedEvent;
|
||||
use OCP\IConfig;
|
||||
|
||||
/**
|
||||
* @template-implements IEventListener<BeforeGroupChangedEvent|BeforeGroupDeletedEvent>
|
||||
*/
|
||||
class GroupChangeListener implements IEventListener {
|
||||
public function __construct(private IJobList $jobList, private IConfig $config) {
|
||||
}
|
||||
|
||||
public function handle(Event $event): void {
|
||||
if (!$this->canSyncBecauseOfGroupChange($event)) {
|
||||
// Not what we subscribed to
|
||||
return;
|
||||
}
|
||||
/** @var BeforeGroupChangedEvent|BeforeGroupDeletedEvent $event */
|
||||
$this->jobList->add(SyncSystemAddressBookAfterUsersChange::class, $event->getGroup()->getUsers());
|
||||
}
|
||||
|
||||
private function canSyncBecauseOfGroupChange(Event $event): bool {
|
||||
return ($event instanceof BeforeGroupChangedEvent || $event instanceof BeforeGroupDeletedEvent) && $this->config->getAppValue(Application::APP_ID, 'system_addressbook_expose_groups', 'no') === 'yes';
|
||||
}
|
||||
}
|
||||
60
apps/dav/lib/Listener/UserChangeListener.php
Normal file
60
apps/dav/lib/Listener/UserChangeListener.php
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2023 Thomas Citharel <nextcloud@tcit.fr>
|
||||
*
|
||||
* @author Thomas Citharel <nextcloud@tcit.fr>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
namespace OCA\DAV\Listener;
|
||||
|
||||
use OCA\DAV\AppInfo\Application;
|
||||
use OCA\DAV\BackgroundJob\SyncSystemAddressBookAfterUsersChange;
|
||||
use OCP\Accounts\UserUpdatedEvent;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventListener;
|
||||
use OCP\Group\Events\UserAddedEvent;
|
||||
use OCP\Group\Events\UserRemovedEvent;
|
||||
use OCP\IConfig;
|
||||
|
||||
/**
|
||||
* @template-implements IEventListener<UserUpdatedEvent|UserAddedEvent|UserRemovedEvent>
|
||||
*/
|
||||
class UserChangeListener implements IEventListener {
|
||||
public function __construct(private IJobList $jobList, private IConfig $config) {
|
||||
}
|
||||
|
||||
public function handle(Event $event): void {
|
||||
if (!($event instanceof UserUpdatedEvent || $event instanceof UserAddedEvent || $event instanceof UserRemovedEvent)) {
|
||||
// Not what we subscribed to
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->canSyncBecauseOfGroupMembershipChange($event)) {
|
||||
/** @var UserUpdatedEvent|UserAddedEvent|UserRemovedEvent $event */
|
||||
$this->jobList->add(SyncSystemAddressBookAfterUsersChange::class, [$event->getUser()]);
|
||||
}
|
||||
}
|
||||
|
||||
private function canSyncBecauseOfGroupMembershipChange(Event $event): bool {
|
||||
return $event instanceof UserUpdatedEvent || $this->config->getAppValue(Application::APP_ID, 'system_addressbook_expose_groups', 'no') === 'yes';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2018, Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
namespace OCA\DAV\Tests\unit\BackgroundJob;
|
||||
|
||||
use OCA\DAV\BackgroundJob\SyncSystemAddressBookAfterUsersChange;
|
||||
use OCA\DAV\CardDAV\SyncService;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\IUser;
|
||||
use Test\TestCase;
|
||||
|
||||
class SyncSystemAddressBookAfterUserChangeTest extends TestCase {
|
||||
private SyncService|MockObject $syncService;
|
||||
|
||||
private SyncSystemAddressBookAfterUsersChange $backgroundJob;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->syncService = $this->createMock(SyncService::class);
|
||||
$timeFactory = $this->createMock(ITimeFactory::class);
|
||||
|
||||
$this->backgroundJob = new SyncSystemAddressBookAfterUsersChange(
|
||||
$this->syncService, $timeFactory);
|
||||
}
|
||||
|
||||
public function testRun(): void {
|
||||
$user1 = $this->createMock(IUser::class);
|
||||
$user2 = $this->createMock(IUser::class);
|
||||
|
||||
$this->syncService->expects($this->exactly(2))->method('updateUser')->withConsecutive([$user1], [$user2]);
|
||||
|
||||
$this->backgroundJob->run([$user1, $user2]);
|
||||
}
|
||||
}
|
||||
|
|
@ -30,39 +30,45 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\DAV\Tests\unit\CardDAV;
|
||||
|
||||
use OCA\DAV\AppInfo\Application;
|
||||
use OCA\DAV\CardDAV\Converter;
|
||||
use OCP\Accounts\IAccount;
|
||||
use OCP\Accounts\IAccountManager;
|
||||
use OCP\Accounts\IAccountProperty;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IImage;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Sabre\VObject\Component\VCard;
|
||||
use Sabre\VObject\Reader;
|
||||
use Test\TestCase;
|
||||
|
||||
class ConverterTest extends TestCase {
|
||||
|
||||
/** @var IAccountManager|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $accountManager;
|
||||
/** @var IUserManager|(IUserManager&MockObject)|MockObject */
|
||||
private IAccountManager|MockObject $accountManager;
|
||||
private IUserManager|MockObject $userManager;
|
||||
private IGroupManager|MockObject $groupManager;
|
||||
private IURLGenerator|MockObject $urlGenerator;
|
||||
|
||||
/** @var IURLGenerator */
|
||||
private $urlGenerator;
|
||||
private IConfig|MockObject $config;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->accountManager = $this->createMock(IAccountManager::class);
|
||||
$this->userManager = $this->createMock(IUserManager::class);
|
||||
$this->groupManager = $this->createMock(IGroupManager::class);
|
||||
$this->urlGenerator = $this->createMock(IURLGenerator::class);
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IAccountProperty|MockObject
|
||||
*/
|
||||
protected function getAccountPropertyMock(string $name, ?string $value, string $scope) {
|
||||
protected function getAccountPropertyMock(string $name, ?string $value, string $scope): IAccountProperty|MockObject {
|
||||
$property = $this->createMock(IAccountProperty::class);
|
||||
$property->expects($this->any())
|
||||
->method('getName')
|
||||
|
|
@ -108,10 +114,10 @@ class ConverterTest extends TestCase {
|
|||
$user = $this->getUserMock((string)$displayName, $eMailAddress, $cloudId);
|
||||
$accountManager = $this->getAccountManager($user);
|
||||
|
||||
$converter = new Converter($accountManager, $this->userManager, $this->urlGenerator);
|
||||
$converter = new Converter($accountManager, $this->userManager, $this->groupManager, $this->urlGenerator, $this->config);
|
||||
$vCard = $converter->createCardFromUser($user);
|
||||
if ($expectedVCard !== null) {
|
||||
$this->assertInstanceOf('Sabre\VObject\Component\VCard', $vCard);
|
||||
$this->assertInstanceOf(VCard::class, $vCard);
|
||||
$cardData = $vCard->jsonSerialize();
|
||||
$this->compareData($expectedVCard, $cardData);
|
||||
} else {
|
||||
|
|
@ -129,7 +135,7 @@ class ConverterTest extends TestCase {
|
|||
->willReturn('Manager');
|
||||
$accountManager = $this->getAccountManager($user);
|
||||
|
||||
$converter = new Converter($accountManager, $this->userManager, $this->urlGenerator);
|
||||
$converter = new Converter($accountManager, $this->userManager, $this->groupManager, $this->urlGenerator, $this->config);
|
||||
$vCard = $converter->createCardFromUser($user);
|
||||
|
||||
$this->compareData(
|
||||
|
|
@ -142,7 +148,7 @@ class ConverterTest extends TestCase {
|
|||
);
|
||||
}
|
||||
|
||||
protected function compareData($expected, $data) {
|
||||
protected function compareData($expected, $data): void {
|
||||
foreach ($expected as $key => $value) {
|
||||
$found = false;
|
||||
foreach ($data[1] as $d) {
|
||||
|
|
@ -152,12 +158,12 @@ class ConverterTest extends TestCase {
|
|||
}
|
||||
}
|
||||
if (!$found) {
|
||||
$this->assertTrue(false, 'Expected data: ' . $key . ' not found.');
|
||||
$this->fail('Expected data: ' . $key . ' not found.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function providesNewUsers() {
|
||||
public function providesNewUsers(): array {
|
||||
return [
|
||||
[
|
||||
null
|
||||
|
|
@ -213,17 +219,15 @@ class ConverterTest extends TestCase {
|
|||
|
||||
/**
|
||||
* @dataProvider providesNames
|
||||
* @param $expected
|
||||
* @param $fullName
|
||||
*/
|
||||
public function testNameSplitter($expected, $fullName): void {
|
||||
$converter = new Converter($this->accountManager, $this->userManager, $this->urlGenerator);
|
||||
public function testNameSplitter(string $expected, string $fullName): void {
|
||||
$converter = new Converter($this->accountManager, $this->userManager, $this->groupManager, $this->urlGenerator, $this->config);
|
||||
$r = $converter->splitFullName($fullName);
|
||||
$r = implode(';', $r);
|
||||
$this->assertEquals($expected, $r);
|
||||
}
|
||||
|
||||
public function providesNames() {
|
||||
public function providesNames(): array {
|
||||
return [
|
||||
['Sauron;;;;', 'Sauron'],
|
||||
['Baggins;Bilbo;;;', 'Bilbo Baggins'],
|
||||
|
|
@ -231,13 +235,7 @@ class ConverterTest extends TestCase {
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $displayName
|
||||
* @param $eMailAddress
|
||||
* @param $cloudId
|
||||
* @return IUser | \PHPUnit\Framework\MockObject\MockObject
|
||||
*/
|
||||
protected function getUserMock(string $displayName, ?string $eMailAddress, ?string $cloudId) {
|
||||
protected function getUserMock(string $displayName, ?string $eMailAddress, ?string $cloudId): IUser|MockObject {
|
||||
$image0 = $this->getMockBuilder(IImage::class)->disableOriginalConstructor()->getMock();
|
||||
$image0->method('mimeType')->willReturn('image/jpeg');
|
||||
$image0->method('data')->willReturn('123456789');
|
||||
|
|
@ -249,4 +247,50 @@ class ConverterTest extends TestCase {
|
|||
$user->method('getAvatarImage')->willReturn($image0);
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForTestExposeGroups
|
||||
*/
|
||||
public function testExposeGroups(bool $exposeGroups, array $groups, string $groupsToInclude, string $groupsToIgnore, ?string $result): void {
|
||||
$user = $this->getUserMock("user", "user@domain.tld", "user@cloud.domain.tld");
|
||||
$this->config->expects($exposeGroups ? $this->exactly(3) :$this->once())->method('getAppValue')->withConsecutive(
|
||||
[Application::APP_ID, 'system_addressbook_expose_groups', 'no'],
|
||||
[Application::APP_ID, 'system_addressbook_groups_to_include', ''],
|
||||
[Application::APP_ID, 'system_addressbook_groups_to_ignore', '']
|
||||
)->willReturnOnConsecutiveCalls(
|
||||
$exposeGroups ? 'yes' : 'no',
|
||||
$groupsToInclude,
|
||||
$groupsToIgnore
|
||||
);
|
||||
|
||||
$ignoredGroups = explode(',', $groupsToIgnore);
|
||||
$includedGroups = explode(',', $groupsToInclude);
|
||||
|
||||
$this->groupManager->expects($exposeGroups ? $this->once() : $this->never())->method('getUserGroups')->with($user)->willReturn(array_map(function ($groupName) use ($groups, $exposeGroups, $includedGroups, $ignoredGroups) {
|
||||
$group = $this->createMock(IGroup::class);
|
||||
$group->expects($exposeGroups ? $this->once() : $this->never())->method('getGID')->willReturn($groupName);
|
||||
$group->expects($exposeGroups && !in_array($groupName, $ignoredGroups, true) && (empty($includedGroups) || in_array($groupName, $includedGroups, true)) ? $this->once() : $this->never())->method('getDisplayName')->willReturn($groupName);
|
||||
return $group;
|
||||
}, $groups));
|
||||
$accountManager = $this->getAccountManager($user);
|
||||
|
||||
$converter = new Converter($accountManager, $this->userManager, $this->groupManager, $this->urlGenerator, $this->config);
|
||||
$vCard = $converter->createCardFromUser($user);
|
||||
|
||||
$parsed = Reader::read($vCard->serialize(), Reader::OPTION_FORGIVING);
|
||||
|
||||
$this->assertEquals((string) $parsed->CATEGORIES, $result);
|
||||
}
|
||||
|
||||
public function dataForTestExposeGroups(): array {
|
||||
return [
|
||||
[false, ['myGroup1'], '', '', null],
|
||||
[true, ['myGroup1'], '', '', 'myGroup1'],
|
||||
[true, ['myGroup1', 'myGroup2'], '', '', 'myGroup1,myGroup2'],
|
||||
[true, ['myGroup1', 'myGroup2'], '', 'myGroup2,myGroup3', 'myGroup1'],
|
||||
[true, ['myGroup1', 'myGroup2', 'myGroup3', 'myGroup4'], '', 'myGroup2,myGroup3', 'myGroup1,myGroup4'],
|
||||
[true, ['myGroup1', 'myGroup2', 'myGroup3', 'myGroup4'], 'myGroup1, myGroup5', 'myGroup2,myGroup3', 'myGroup1'],
|
||||
[true, ['myGroup1', 'myGroup2'], '', 'myGroup2,myGroup3', 'myGroup1']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
81
apps/dav/tests/unit/Listener/GroupChangeListenerTest.php
Normal file
81
apps/dav/tests/unit/Listener/GroupChangeListenerTest.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2022 Thomas Citharel <nextcloud@tcit.fr>
|
||||
*
|
||||
* @author Thomas Citharel <nextcloud@tcit.fr>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
namespace OCA\DAV\Tests\Unit\Listener;
|
||||
|
||||
use OCA\DAV\AppInfo\Application;
|
||||
use OCA\DAV\BackgroundJob\SyncSystemAddressBookAfterUsersChange;
|
||||
use OCA\DAV\Listener\GroupChangeListener;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\Group\Events\BeforeGroupChangedEvent;
|
||||
use OCP\Group\Events\BeforeGroupCreatedEvent;
|
||||
use OCP\Group\Events\BeforeGroupDeletedEvent;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroup;
|
||||
use OCP\IUser;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Test\TestCase;
|
||||
|
||||
class GroupChangeListenerTest extends TestCase {
|
||||
private IJobList|MockObject $jobList;
|
||||
private IConfig|MockObject $config;
|
||||
private GroupChangeListener $listener;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->jobList = $this->createMock(IJobList::class);
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
|
||||
$this->listener = new GroupChangeListener(
|
||||
$this->jobList,
|
||||
$this->config
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForTestHandleGroupChangeEvent
|
||||
*/
|
||||
public function testHandleGroupChangeEvent(Event $event, array $users, string $groupsExposed, bool $willSync): void {
|
||||
$this->jobList->expects($willSync ? $this->once() : $this->never())->method('add')->with(SyncSystemAddressBookAfterUsersChange::class, $users);
|
||||
$this->config->expects($event instanceof BeforeGroupCreatedEvent ? $this->never() : $this->once())->method('getAppValue')->with(Application::APP_ID, 'system_addressbook_expose_groups', 'no')->willReturn($groupsExposed);
|
||||
$this->listener->handle($event);
|
||||
}
|
||||
|
||||
public function dataForTestHandleGroupChangeEvent(): array {
|
||||
$group = $this->createMock(IGroup::class);
|
||||
$users = [$this->createMock(IUser::class), $this->createMock(IUser::class)];
|
||||
$group->expects($this->any())->method('getUsers')->willReturn($users);
|
||||
return [
|
||||
[new BeforeGroupChangedEvent($group, 'displayName', 'NewDisplayName', 'OldDisplayName'), $users, 'no', false],
|
||||
[new BeforeGroupChangedEvent($group, 'displayName', 'NewDisplayName', 'OldDisplayName'), $users, 'yes', true],
|
||||
[new BeforeGroupDeletedEvent($group), $users, 'no', false],
|
||||
[new BeforeGroupDeletedEvent($group), $users, 'yes', true],
|
||||
[new BeforeGroupCreatedEvent('mygroup'), $users, 'no', false],
|
||||
[new BeforeGroupCreatedEvent('mygroup'), $users, 'yes', false],
|
||||
];
|
||||
}
|
||||
}
|
||||
82
apps/dav/tests/unit/Listener/UserChangeListenerTest.php
Normal file
82
apps/dav/tests/unit/Listener/UserChangeListenerTest.php
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2022 Thomas Citharel <nextcloud@tcit.fr>
|
||||
*
|
||||
* @author Thomas Citharel <nextcloud@tcit.fr>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
namespace OCA\DAV\Tests\Unit\Listener;
|
||||
|
||||
use OCA\DAV\AppInfo\Application;
|
||||
use OCA\DAV\BackgroundJob\SyncSystemAddressBookAfterUsersChange;
|
||||
use OCA\DAV\Listener\UserChangeListener;
|
||||
use OCP\Accounts\UserUpdatedEvent;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\Group\Events\UserAddedEvent;
|
||||
use OCP\Group\Events\UserRemovedEvent;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroup;
|
||||
use OCP\IUser;
|
||||
use OCP\User\Events\PostLoginEvent;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Test\TestCase;
|
||||
|
||||
class UserChangeListenerTest extends TestCase {
|
||||
private IJobList|MockObject $jobList;
|
||||
private UserChangeListener $listener;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->jobList = $this->createMock(IJobList::class);
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
|
||||
$this->listener = new UserChangeListener(
|
||||
$this->jobList,
|
||||
$this->config
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForTestHandleUserChangeEvent
|
||||
*/
|
||||
public function testHandleUserChangeEvent(Event $event, IUser $user, string $groupsExposed, bool $willSync): void {
|
||||
$this->config->expects(($event instanceof UserAddedEvent || $event instanceof UserRemovedEvent) ? $this->once() : $this->never())->method('getAppValue')->with(Application::APP_ID, 'system_addressbook_expose_groups', 'no')->willReturn($groupsExposed);
|
||||
$this->jobList->expects($willSync ? $this->once() : $this->never())->method('add')->with(SyncSystemAddressBookAfterUsersChange::class, [$user]);
|
||||
$this->listener->handle($event);
|
||||
}
|
||||
|
||||
public function dataForTestHandleUserChangeEvent(): array {
|
||||
$group = $this->createMock(IGroup::class);
|
||||
$user = $this->createMock(IUser::class);
|
||||
return [
|
||||
[new UserAddedEvent($group, $user), $user, 'yes', true],
|
||||
[new UserAddedEvent($group, $user), $user, 'no', false],
|
||||
[new UserUpdatedEvent($user, []), $user, 'yes', true],
|
||||
[new UserUpdatedEvent($user, []), $user, 'no', true],
|
||||
[new UserRemovedEvent($group, $user), $user, 'yes', true],
|
||||
[new UserRemovedEvent($group, $user), $user, 'no', false],
|
||||
[new PostLoginEvent($user, 'a', 'b', true), $user, 'yes', false],
|
||||
[new PostLoginEvent($user, 'a', 'b', true), $user, 'no', false],
|
||||
];
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue