mirror of
https://github.com/nextcloud/server.git
synced 2026-04-15 22:11:17 -04:00
refactor(dav): move shared logic to a dedicated example contact service
Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
This commit is contained in:
parent
07bf0099a1
commit
960b3ec0eb
14 changed files with 225 additions and 205 deletions
|
|
@ -11,9 +11,6 @@ return [
|
|||
['name' => 'invitation_response#decline', 'url' => '/invitation/decline/{token}', 'verb' => 'GET'],
|
||||
['name' => 'invitation_response#options', 'url' => '/invitation/moreOptions/{token}', 'verb' => 'GET'],
|
||||
['name' => 'invitation_response#processMoreOptionsResult', 'url' => '/invitation/moreOptions/{token}', 'verb' => 'POST'],
|
||||
['name' => 'example_content#getDefaultContact', 'url' => '/api/defaultcontact/contact', 'verb' => 'GET'],
|
||||
['name' => 'example_content#setDefaultContact', 'url' => '/api/defaultcontact/contact', 'verb' => 'PUT'],
|
||||
['name' => 'example_content#setEnableDefaultContact', 'url' => '/api/defaultcontact/config', 'verb' => 'PUT'],
|
||||
],
|
||||
'ocs' => [
|
||||
['name' => 'direct#getUrl', 'url' => '/api/v1/direct', 'verb' => 'POST'],
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ return array(
|
|||
'OCA\\DAV\\Server' => $baseDir . '/../lib/Server.php',
|
||||
'OCA\\DAV\\ServerFactory' => $baseDir . '/../lib/ServerFactory.php',
|
||||
'OCA\\DAV\\Service\\AbsenceService' => $baseDir . '/../lib/Service/AbsenceService.php',
|
||||
'OCA\\DAV\\Service\\DefaultContactService' => $baseDir . '/../lib/Service/DefaultContactService.php',
|
||||
'OCA\\DAV\\Service\\ExampleContactService' => $baseDir . '/../lib/Service/ExampleContactService.php',
|
||||
'OCA\\DAV\\Service\\ExampleEventService' => $baseDir . '/../lib/Service/ExampleEventService.php',
|
||||
'OCA\\DAV\\Settings\\Admin\\SystemAddressBookSettings' => $baseDir . '/../lib/Settings/Admin/SystemAddressBookSettings.php',
|
||||
'OCA\\DAV\\Settings\\AvailabilitySettings' => $baseDir . '/../lib/Settings/AvailabilitySettings.php',
|
||||
|
|
|
|||
|
|
@ -381,7 +381,7 @@ class ComposerStaticInitDAV
|
|||
'OCA\\DAV\\Server' => __DIR__ . '/..' . '/../lib/Server.php',
|
||||
'OCA\\DAV\\ServerFactory' => __DIR__ . '/..' . '/../lib/ServerFactory.php',
|
||||
'OCA\\DAV\\Service\\AbsenceService' => __DIR__ . '/..' . '/../lib/Service/AbsenceService.php',
|
||||
'OCA\\DAV\\Service\\DefaultContactService' => __DIR__ . '/..' . '/../lib/Service/DefaultContactService.php',
|
||||
'OCA\\DAV\\Service\\ExampleContactService' => __DIR__ . '/..' . '/../lib/Service/ExampleContactService.php',
|
||||
'OCA\\DAV\\Service\\ExampleEventService' => __DIR__ . '/..' . '/../lib/Service/ExampleEventService.php',
|
||||
'OCA\\DAV\\Settings\\Admin\\SystemAddressBookSettings' => __DIR__ . '/..' . '/../lib/Settings/Admin/SystemAddressBookSettings.php',
|
||||
'OCA\\DAV\\Settings\\AvailabilitySettings' => __DIR__ . '/..' . '/../lib/Settings/AvailabilitySettings.php',
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||
namespace OCA\DAV\Controller;
|
||||
|
||||
use OCA\DAV\AppInfo\Application;
|
||||
use OCA\DAV\Service\ExampleContactService;
|
||||
use OCA\DAV\Service\ExampleEventService;
|
||||
use OCP\AppFramework\ApiController;
|
||||
use OCP\AppFramework\Http;
|
||||
|
|
@ -17,103 +18,50 @@ use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
|||
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
|
||||
use OCP\AppFramework\Http\DataDownloadResponse;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\Files\AppData\IAppDataFactory;
|
||||
use OCP\Files\IAppData;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ExampleContentController extends ApiController {
|
||||
private IAppData $appData;
|
||||
|
||||
public function __construct(
|
||||
IRequest $request,
|
||||
private IConfig $config,
|
||||
private IAppConfig $appConfig,
|
||||
private IAppDataFactory $appDataFactory,
|
||||
private LoggerInterface $logger,
|
||||
private ExampleEventService $exampleEventService,
|
||||
private readonly LoggerInterface $logger,
|
||||
private readonly ExampleEventService $exampleEventService,
|
||||
private readonly ExampleContactService $exampleContactService,
|
||||
) {
|
||||
parent::__construct(Application::APP_ID, $request);
|
||||
$this->appData = $this->appDataFactory->get('dav');
|
||||
}
|
||||
|
||||
public function setEnableDefaultContact($allow) {
|
||||
if ($allow === 'yes' && !$this->defaultContactExists()) {
|
||||
#[FrontpageRoute(verb: 'PUT', url: '/api/defaultcontact/config')]
|
||||
public function setEnableDefaultContact(bool $allow): JSONResponse {
|
||||
if ($allow && !$this->exampleContactService->defaultContactExists()) {
|
||||
try {
|
||||
$this->setCard();
|
||||
$this->exampleContactService->setCard();
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Could not create default contact', ['exception' => $e]);
|
||||
return new JSONResponse([], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
$this->config->setAppValue(Application::APP_ID, 'enableDefaultContact', $allow);
|
||||
$this->exampleContactService->setDefaultContactEnabled($allow);
|
||||
return new JSONResponse([], Http::STATUS_OK);
|
||||
}
|
||||
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/api/defaultcontact/contact')]
|
||||
public function getDefaultContact(): DataDownloadResponse {
|
||||
$cardData = $this->getCard()
|
||||
$cardData = $this->exampleContactService->getCard()
|
||||
?? file_get_contents(__DIR__ . '/../ExampleContentFiles/exampleContact.vcf');
|
||||
return new DataDownloadResponse($cardData, 'example_contact.vcf', 'text/vcard');
|
||||
}
|
||||
|
||||
#[FrontpageRoute(verb: 'PUT', url: '/api/defaultcontact/contact')]
|
||||
public function setDefaultContact(?string $contactData = null) {
|
||||
if (!$this->config->getAppValue(Application::APP_ID, 'enableDefaultContact', 'yes')) {
|
||||
if (!$this->exampleContactService->isDefaultContactEnabled()) {
|
||||
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
||||
}
|
||||
$this->setCard($contactData);
|
||||
$this->exampleContactService->setCard($contactData);
|
||||
return new JSONResponse([], Http::STATUS_OK);
|
||||
}
|
||||
|
||||
private function getCard(): ?string {
|
||||
try {
|
||||
$folder = $this->appData->getFolder('defaultContact');
|
||||
} catch (NotFoundException $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$folder->fileExists('defaultContact.vcf')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $folder->getFile('defaultContact.vcf')->getContent();
|
||||
}
|
||||
|
||||
private function setCard(?string $cardData = null) {
|
||||
try {
|
||||
$folder = $this->appData->getFolder('defaultContact');
|
||||
} catch (NotFoundException $e) {
|
||||
$folder = $this->appData->newFolder('defaultContact');
|
||||
}
|
||||
|
||||
$isCustom = true;
|
||||
if (is_null($cardData)) {
|
||||
$cardData = file_get_contents(__DIR__ . '/../ExampleContentFiles/exampleContact.vcf');
|
||||
$isCustom = false;
|
||||
}
|
||||
|
||||
if (!$cardData) {
|
||||
throw new \Exception('Could not read exampleContact.vcf');
|
||||
}
|
||||
|
||||
$file = (!$folder->fileExists('defaultContact.vcf')) ? $folder->newFile('defaultContact.vcf') : $folder->getFile('defaultContact.vcf');
|
||||
$file->putContent($cardData);
|
||||
|
||||
$this->appConfig->setValueBool(Application::APP_ID, 'hasCustomDefaultContact', $isCustom);
|
||||
}
|
||||
|
||||
private function defaultContactExists(): bool {
|
||||
try {
|
||||
$folder = $this->appData->getFolder('defaultContact');
|
||||
} catch (NotFoundException $e) {
|
||||
return false;
|
||||
}
|
||||
return $folder->fileExists('defaultContact.vcf');
|
||||
}
|
||||
|
||||
#[FrontpageRoute(verb: 'POST', url: '/api/exampleEvent/enable')]
|
||||
public function setCreateExampleEvent(bool $enable): JSONResponse {
|
||||
$this->exampleEventService->setCreateExampleEvent($enable);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace OCA\DAV\Listener;
|
|||
use OCA\DAV\CalDAV\CalDavBackend;
|
||||
use OCA\DAV\CardDAV\CardDavBackend;
|
||||
use OCA\DAV\CardDAV\SyncService;
|
||||
use OCA\DAV\Service\DefaultContactService;
|
||||
use OCA\DAV\Service\ExampleContactService;
|
||||
use OCA\DAV\Service\ExampleEventService;
|
||||
use OCP\Accounts\UserUpdatedEvent;
|
||||
use OCP\Defaults;
|
||||
|
|
@ -46,7 +46,7 @@ class UserEventsListener implements IEventListener {
|
|||
private CalDavBackend $calDav,
|
||||
private CardDavBackend $cardDav,
|
||||
private Defaults $themingDefaults,
|
||||
private DefaultContactService $defaultContactService,
|
||||
private ExampleContactService $exampleContactService,
|
||||
private ExampleEventService $exampleEventService,
|
||||
private LoggerInterface $logger,
|
||||
) {
|
||||
|
|
@ -175,7 +175,7 @@ class UserEventsListener implements IEventListener {
|
|||
}
|
||||
}
|
||||
if ($addressBookId) {
|
||||
$this->defaultContactService->createDefaultContact($addressBookId);
|
||||
$this->exampleContactService->createDefaultContact($addressBookId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,77 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\Service;
|
||||
|
||||
use OCA\DAV\AppInfo\Application;
|
||||
use OCA\DAV\CardDAV\CardDavBackend;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\Files\AppData\IAppDataFactory;
|
||||
use OCP\IAppConfig;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
class DefaultContactService {
|
||||
public function __construct(
|
||||
private CardDavBackend $cardDav,
|
||||
private IAppManager $appManager,
|
||||
private IAppDataFactory $appDataFactory,
|
||||
private IAppConfig $config,
|
||||
private LoggerInterface $logger,
|
||||
) {
|
||||
}
|
||||
|
||||
public function createDefaultContact(int $addressBookId): void {
|
||||
$enableDefaultContact = $this->config->getValueString(Application::APP_ID, 'enableDefaultContact', 'yes');
|
||||
if ($enableDefaultContact !== 'yes') {
|
||||
return;
|
||||
}
|
||||
$appData = $this->appDataFactory->get('dav');
|
||||
try {
|
||||
$folder = $appData->getFolder('defaultContact');
|
||||
$defaultContactFile = $folder->getFile('defaultContact.vcf');
|
||||
$data = $defaultContactFile->getContent();
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Couldn\'t get default contact file', ['exception' => $e]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the UID is unique
|
||||
$newUid = Uuid::v4()->toRfc4122();
|
||||
$newRev = date('Ymd\THis\Z');
|
||||
$vcard = \Sabre\VObject\Reader::read($data, \Sabre\VObject\Reader::OPTION_FORGIVING);
|
||||
if ($vcard->UID) {
|
||||
$vcard->UID->setValue($newUid);
|
||||
} else {
|
||||
$vcard->add('UID', $newUid);
|
||||
}
|
||||
if ($vcard->REV) {
|
||||
$vcard->REV->setValue($newRev);
|
||||
} else {
|
||||
$vcard->add('REV', $newRev);
|
||||
}
|
||||
|
||||
// Level 3 means that the document is invalid
|
||||
// https://sabre.io/vobject/vcard/#validating-vcard
|
||||
$level3Warnings = array_filter($vcard->validate(), function ($warning) {
|
||||
return $warning['level'] === 3;
|
||||
});
|
||||
|
||||
if (!empty($level3Warnings)) {
|
||||
$this->logger->error('Default contact is invalid', ['warnings' => $level3Warnings]);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$this->cardDav->createCard($addressBookId, 'default', $vcard->serialize(), false);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error($e->getMessage(), ['exception' => $e]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
132
apps/dav/lib/Service/ExampleContactService.php
Normal file
132
apps/dav/lib/Service/ExampleContactService.php
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\Service;
|
||||
|
||||
use OCA\DAV\AppInfo\Application;
|
||||
use OCA\DAV\CardDAV\CardDavBackend;
|
||||
use OCP\AppFramework\Services\IAppConfig;
|
||||
use OCP\Files\AppData\IAppDataFactory;
|
||||
use OCP\Files\IAppData;
|
||||
use OCP\Files\NotFoundException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
class ExampleContactService {
|
||||
private readonly IAppData $appData;
|
||||
|
||||
public function __construct(
|
||||
IAppDataFactory $appDataFactory,
|
||||
private readonly IAppConfig $appConfig,
|
||||
private readonly LoggerInterface $logger,
|
||||
private readonly CardDavBackend $cardDav,
|
||||
) {
|
||||
$this->appData = $appDataFactory->get(Application::APP_ID);
|
||||
}
|
||||
|
||||
public function isDefaultContactEnabled(): bool {
|
||||
return $this->appConfig->getAppValueBool('enableDefaultContact', true);
|
||||
}
|
||||
|
||||
public function setDefaultContactEnabled(bool $value): void {
|
||||
$this->appConfig->setAppValueBool('enableDefaultContact', $value);
|
||||
}
|
||||
|
||||
public function getCard(): ?string {
|
||||
try {
|
||||
$folder = $this->appData->getFolder('defaultContact');
|
||||
} catch (NotFoundException $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$folder->fileExists('defaultContact.vcf')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $folder->getFile('defaultContact.vcf')->getContent();
|
||||
}
|
||||
|
||||
public function setCard(?string $cardData = null) {
|
||||
try {
|
||||
$folder = $this->appData->getFolder('defaultContact');
|
||||
} catch (NotFoundException $e) {
|
||||
$folder = $this->appData->newFolder('defaultContact');
|
||||
}
|
||||
|
||||
$isCustom = true;
|
||||
if (is_null($cardData)) {
|
||||
$cardData = file_get_contents(__DIR__ . '/../ExampleContentFiles/exampleContact.vcf');
|
||||
$isCustom = false;
|
||||
}
|
||||
|
||||
if (!$cardData) {
|
||||
throw new \Exception('Could not read exampleContact.vcf');
|
||||
}
|
||||
|
||||
$file = (!$folder->fileExists('defaultContact.vcf')) ? $folder->newFile('defaultContact.vcf') : $folder->getFile('defaultContact.vcf');
|
||||
$file->putContent($cardData);
|
||||
|
||||
$this->appConfig->setAppValueBool('hasCustomDefaultContact', $isCustom);
|
||||
}
|
||||
|
||||
public function defaultContactExists(): bool {
|
||||
try {
|
||||
$folder = $this->appData->getFolder('defaultContact');
|
||||
} catch (NotFoundException $e) {
|
||||
return false;
|
||||
}
|
||||
return $folder->fileExists('defaultContact.vcf');
|
||||
}
|
||||
|
||||
public function createDefaultContact(int $addressBookId): void {
|
||||
if (!$this->isDefaultContactEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$folder = $this->appData->getFolder('defaultContact');
|
||||
$defaultContactFile = $folder->getFile('defaultContact.vcf');
|
||||
$data = $defaultContactFile->getContent();
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Couldn\'t get default contact file', ['exception' => $e]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the UID is unique
|
||||
$newUid = Uuid::v4()->toRfc4122();
|
||||
$newRev = date('Ymd\THis\Z');
|
||||
$vcard = \Sabre\VObject\Reader::read($data, \Sabre\VObject\Reader::OPTION_FORGIVING);
|
||||
if ($vcard->UID) {
|
||||
$vcard->UID->setValue($newUid);
|
||||
} else {
|
||||
$vcard->add('UID', $newUid);
|
||||
}
|
||||
if ($vcard->REV) {
|
||||
$vcard->REV->setValue($newRev);
|
||||
} else {
|
||||
$vcard->add('REV', $newRev);
|
||||
}
|
||||
|
||||
// Level 3 means that the document is invalid
|
||||
// https://sabre.io/vobject/vcard/#validating-vcard
|
||||
$level3Warnings = array_filter($vcard->validate(), static function ($warning) {
|
||||
return $warning['level'] === 3;
|
||||
});
|
||||
|
||||
if (!empty($level3Warnings)) {
|
||||
$this->logger->error('Default contact is invalid', ['warnings' => $level3Warnings]);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$this->cardDav->createCard($addressBookId, 'default', $vcard->serialize(), false);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error($e->getMessage(), ['exception' => $e]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,21 +9,21 @@ declare(strict_types=1);
|
|||
namespace OCA\DAV\Settings;
|
||||
|
||||
use OCA\DAV\AppInfo\Application;
|
||||
use OCA\DAV\Service\ExampleContactService;
|
||||
use OCA\DAV\Service\ExampleEventService;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\AppFramework\Services\IAppConfig;
|
||||
use OCP\AppFramework\Services\IInitialState;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\IConfig;
|
||||
use OCP\Settings\ISettings;
|
||||
|
||||
class ExampleContentSettings implements ISettings {
|
||||
public function __construct(
|
||||
private readonly IConfig $config,
|
||||
private readonly IAppConfig $appConfig,
|
||||
private readonly IInitialState $initialState,
|
||||
private readonly IAppManager $appManager,
|
||||
private readonly ExampleEventService $exampleEventService,
|
||||
private readonly ExampleContactService $exampleContactService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -43,11 +43,13 @@ class ExampleContentSettings implements ISettings {
|
|||
}
|
||||
|
||||
if ($contactsEnabled) {
|
||||
$enableDefaultContact = $this->config->getAppValue(Application::APP_ID, 'enableDefaultContact', 'yes');
|
||||
$this->initialState->provideInitialState('enableDefaultContact', $enableDefaultContact);
|
||||
$this->initialState->provideInitialState(
|
||||
'enableDefaultContact',
|
||||
$this->exampleContactService->isDefaultContactEnabled(),
|
||||
);
|
||||
$this->initialState->provideInitialState(
|
||||
'hasCustomDefaultContact',
|
||||
$this->appConfig->getValueBool(Application::APP_ID, 'hasCustomDefaultContact'),
|
||||
$this->appConfig->getAppValueBool('hasCustomDefaultContact'),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ import IconCheck from '@mdi/svg/svg/check.svg?raw'
|
|||
import logger from '../service/logger.js'
|
||||
import ExampleContentDownloadButton from './ExampleContentDownloadButton.vue'
|
||||
|
||||
const enableDefaultContact = loadState('dav', 'enableDefaultContact') === 'yes'
|
||||
const enableDefaultContact = loadState('dav', 'enableDefaultContact')
|
||||
const hasCustomDefaultContact = loadState('dav', 'hasCustomDefaultContact')
|
||||
|
||||
export default {
|
||||
|
|
@ -106,7 +106,7 @@ export default {
|
|||
methods: {
|
||||
updateEnableDefaultContact() {
|
||||
axios.put(generateUrl('apps/dav/api/defaultcontact/config'), {
|
||||
allow: this.enableDefaultContact ? 'no' : 'yes',
|
||||
allow: !this.enableDefaultContact,
|
||||
}).then(() => {
|
||||
this.enableDefaultContact = !this.enableDefaultContact
|
||||
}).catch(() => {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use OCA\DAV\CalDAV\CalDavBackend;
|
|||
use OCA\DAV\CardDAV\CardDavBackend;
|
||||
use OCA\DAV\CardDAV\SyncService;
|
||||
use OCA\DAV\Listener\UserEventsListener;
|
||||
use OCA\DAV\Service\DefaultContactService;
|
||||
use OCA\DAV\Service\ExampleContactService;
|
||||
use OCA\DAV\Service\ExampleEventService;
|
||||
use OCP\Defaults;
|
||||
use OCP\IUser;
|
||||
|
|
@ -29,7 +29,7 @@ class UserEventsListenerTest extends TestCase {
|
|||
private CalDavBackend&MockObject $calDavBackend;
|
||||
private CardDavBackend&MockObject $cardDavBackend;
|
||||
private Defaults&MockObject $defaults;
|
||||
private DefaultContactService&MockObject $defaultContactService;
|
||||
private ExampleContactService&MockObject $exampleContactService;
|
||||
private ExampleEventService&MockObject $exampleEventService;
|
||||
private LoggerInterface&MockObject $logger;
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ class UserEventsListenerTest extends TestCase {
|
|||
$this->calDavBackend = $this->createMock(CalDavBackend::class);
|
||||
$this->cardDavBackend = $this->createMock(CardDavBackend::class);
|
||||
$this->defaults = $this->createMock(Defaults::class);
|
||||
$this->defaultContactService = $this->createMock(DefaultContactService::class);
|
||||
$this->exampleContactService = $this->createMock(ExampleContactService::class);
|
||||
$this->exampleEventService = $this->createMock(ExampleEventService::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ class UserEventsListenerTest extends TestCase {
|
|||
$this->calDavBackend,
|
||||
$this->cardDavBackend,
|
||||
$this->defaults,
|
||||
$this->defaultContactService,
|
||||
$this->exampleContactService,
|
||||
$this->exampleEventService,
|
||||
$this->logger,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -10,56 +10,60 @@ declare(strict_types=1);
|
|||
namespace OCA\DAV\Tests\unit\Service;
|
||||
|
||||
use OCA\DAV\CardDAV\CardDavBackend;
|
||||
use OCA\DAV\Service\DefaultContactService;
|
||||
use OCA\DAV\Service\ExampleContactService;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\Services\IAppConfig;
|
||||
use OCP\Files\AppData\IAppDataFactory;
|
||||
use OCP\Files\IAppData;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\SimpleFS\ISimpleFile;
|
||||
use OCP\Files\SimpleFS\ISimpleFolder;
|
||||
use OCP\IAppConfig;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
use Test\TestCase;
|
||||
|
||||
class DefaultContactServiceTest extends TestCase {
|
||||
protected DefaultContactService $service;
|
||||
class ExampleContactServiceTest extends TestCase {
|
||||
protected ExampleContactService $service;
|
||||
protected CardDavBackend&MockObject $cardDav;
|
||||
protected IAppManager&MockObject $appManager;
|
||||
protected IAppDataFactory&MockObject $appDataFactory;
|
||||
protected LoggerInterface&MockObject $logger;
|
||||
protected IAppConfig&MockObject $config;
|
||||
protected IAppConfig&MockObject $appConfig;
|
||||
protected IAppData&MockObject $appData;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->cardDav = $this->createMock(CardDavBackend::class);
|
||||
$this->appManager = $this->createMock(IAppManager::class);
|
||||
$this->appDataFactory = $this->createMock(IAppDataFactory::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->config = $this->createMock(IAppConfig::class);
|
||||
$this->appConfig = $this->createMock(IAppConfig::class);
|
||||
|
||||
$this->service = new DefaultContactService(
|
||||
$this->cardDav,
|
||||
$this->appManager,
|
||||
$this->appData = $this->createMock(IAppData::class);
|
||||
$this->appDataFactory->method('get')
|
||||
->with('dav')
|
||||
->willReturn($this->appData);
|
||||
|
||||
$this->service = new ExampleContactService(
|
||||
$this->appDataFactory,
|
||||
$this->config,
|
||||
$this->appConfig,
|
||||
$this->logger,
|
||||
$this->cardDav,
|
||||
);
|
||||
}
|
||||
|
||||
public function testCreateDefaultContactWithInvalidCard(): void {
|
||||
// Invalid vCard missing required FN property
|
||||
$vcardContent = "BEGIN:VCARD\nVERSION:3.0\nEND:VCARD";
|
||||
$this->config->method('getValueString')->willReturn('yes');
|
||||
$appData = $this->createMock(IAppData::class);
|
||||
$this->appConfig->method('getAppValueBool')
|
||||
->with('enableDefaultContact', true)
|
||||
->willReturn(true);
|
||||
$folder = $this->createMock(ISimpleFolder::class);
|
||||
$file = $this->createMock(ISimpleFile::class);
|
||||
$file->method('getContent')->willReturn($vcardContent);
|
||||
$folder->method('getFile')->willReturn($file);
|
||||
$appData->method('getFolder')->willReturn($folder);
|
||||
$this->appDataFactory->method('get')->willReturn($appData);
|
||||
$this->appData->method('getFolder')->willReturn($folder);
|
||||
|
||||
$this->logger->expects($this->once())
|
||||
->method('error')
|
||||
|
|
@ -76,14 +80,14 @@ class DefaultContactServiceTest extends TestCase {
|
|||
$originalRev = '20200101T000000Z';
|
||||
$vcardContent = "BEGIN:VCARD\nVERSION:3.0\nFN:Test User\nUID:$originalUid\nREV:$originalRev\nEND:VCARD";
|
||||
|
||||
$this->config->method('getValueString')->willReturn('yes');
|
||||
$appData = $this->createMock(IAppData::class);
|
||||
$this->appConfig->method('getAppValueBool')
|
||||
->with('enableDefaultContact', true)
|
||||
->willReturn(true);
|
||||
$folder = $this->createMock(ISimpleFolder::class);
|
||||
$file = $this->createMock(ISimpleFile::class);
|
||||
$file->method('getContent')->willReturn($vcardContent);
|
||||
$folder->method('getFile')->willReturn($file);
|
||||
$appData->method('getFolder')->willReturn($folder);
|
||||
$this->appDataFactory->method('get')->willReturn($appData);
|
||||
$this->appData->method('getFolder')->willReturn($folder);
|
||||
|
||||
$capturedCardData = null;
|
||||
$this->cardDav->expects($this->once())
|
||||
|
|
@ -107,10 +111,10 @@ class DefaultContactServiceTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testDefaultContactFileDoesNotExist(): void {
|
||||
$appData = $this->createMock(IAppData::class);
|
||||
$this->config->method('getValueString')->willReturn('yes');
|
||||
$appData->method('getFolder')->willThrowException(new NotFoundException());
|
||||
$this->appDataFactory->method('get')->willReturn($appData);
|
||||
$this->appConfig->method('getAppValueBool')
|
||||
->with('enableDefaultContact', true)
|
||||
->willReturn(true);
|
||||
$this->appData->method('getFolder')->willThrowException(new NotFoundException());
|
||||
|
||||
$this->cardDav->expects($this->never())
|
||||
->method('createCard');
|
||||
|
|
@ -121,14 +125,14 @@ class DefaultContactServiceTest extends TestCase {
|
|||
public function testUidAndRevAreAddedIfMissing(): void {
|
||||
$vcardContent = "BEGIN:VCARD\nVERSION:3.0\nFN:Test User\nEND:VCARD";
|
||||
|
||||
$this->config->method('getValueString')->willReturn('yes');
|
||||
$appData = $this->createMock(IAppData::class);
|
||||
$this->appConfig->method('getAppValueBool')
|
||||
->with('enableDefaultContact', true)
|
||||
->willReturn(true);
|
||||
$folder = $this->createMock(ISimpleFolder::class);
|
||||
$file = $this->createMock(ISimpleFile::class);
|
||||
$file->method('getContent')->willReturn($vcardContent);
|
||||
$folder->method('getFile')->willReturn($file);
|
||||
$appData->method('getFolder')->willReturn($folder);
|
||||
$this->appDataFactory->method('get')->willReturn($appData);
|
||||
$this->appData->method('getFolder')->willReturn($folder);
|
||||
|
||||
$capturedCardData = 'new-card-data';
|
||||
|
||||
|
|
@ -154,7 +158,9 @@ class DefaultContactServiceTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testDefaultContactIsNotCreatedIfEnabled(): void {
|
||||
$this->config->method('getValueString')->willReturn('no');
|
||||
$this->appConfig->method('getAppValueBool')
|
||||
->with('enableDefaultContact', true)
|
||||
->willReturn(false);
|
||||
$this->logger->expects($this->never())
|
||||
->method('error');
|
||||
$this->cardDav->expects($this->never())
|
||||
|
|
@ -162,4 +168,27 @@ class DefaultContactServiceTest extends TestCase {
|
|||
|
||||
$this->service->createDefaultContact(123);
|
||||
}
|
||||
|
||||
public static function provideDefaultContactEnableData(): array {
|
||||
return [[true], [false]];
|
||||
}
|
||||
|
||||
/** @dataProvider provideDefaultContactEnableData */
|
||||
public function testIsDefaultContactEnabled(bool $enabled): void {
|
||||
$this->appConfig->expects(self::once())
|
||||
->method('getAppValueBool')
|
||||
->with('enableDefaultContact', true)
|
||||
->willReturn($enabled);
|
||||
|
||||
$this->assertEquals($enabled, $this->service->isDefaultContactEnabled());
|
||||
}
|
||||
|
||||
/** @dataProvider provideDefaultContactEnableData */
|
||||
public function testSetDefaultContactEnabled(bool $enabled): void {
|
||||
$this->appConfig->expects(self::once())
|
||||
->method('setAppValueBool')
|
||||
->with('enableDefaultContact', $enabled);
|
||||
|
||||
$this->service->setDefaultContactEnabled($enabled);
|
||||
}
|
||||
}
|
||||
|
|
@ -782,12 +782,6 @@
|
|||
<code><![CDATA[setAppValue]]></code>
|
||||
</DeprecatedMethod>
|
||||
</file>
|
||||
<file src="apps/dav/lib/Controller/ExampleContentController.php">
|
||||
<DeprecatedMethod>
|
||||
<code><![CDATA[getAppValue]]></code>
|
||||
<code><![CDATA[setAppValue]]></code>
|
||||
</DeprecatedMethod>
|
||||
</file>
|
||||
<file src="apps/dav/lib/Controller/InvitationResponseController.php">
|
||||
<UndefinedPropertyAssignment>
|
||||
<code><![CDATA[$vEvent->DTSTAMP]]></code>
|
||||
|
|
@ -1021,11 +1015,6 @@
|
|||
<code><![CDATA[getAppValue]]></code>
|
||||
</DeprecatedMethod>
|
||||
</file>
|
||||
<file src="apps/dav/lib/Settings/ExampleContentSettings.php">
|
||||
<DeprecatedMethod>
|
||||
<code><![CDATA[getAppValue]]></code>
|
||||
</DeprecatedMethod>
|
||||
</file>
|
||||
<file src="apps/dav/lib/SetupChecks/NeedsSystemAddressBookSync.php">
|
||||
<DeprecatedMethod>
|
||||
<code><![CDATA[getAppValue]]></code>
|
||||
|
|
|
|||
4
dist/dav-settings-example-content.js
vendored
4
dist/dav-settings-example-content.js
vendored
File diff suppressed because one or more lines are too long
2
dist/dav-settings-example-content.js.map
vendored
2
dist/dav-settings-example-content.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue