aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dav/tests/unit
diff options
context:
space:
mode:
authorAnna Larch <anna@nextcloud.com>2022-12-12 20:46:37 +0100
committerAnna Larch <anna@nextcloud.com>2023-02-02 16:25:59 +0100
commit38e9cb6a052f4d0bc4e34293febbe9f132055a83 (patch)
treec634406b31b3d0c19b28a3c1684bdcd0325e7d03 /apps/dav/tests/unit
parentdb30974348ee88fbf81d9cc0f1a1071d1adcbd09 (diff)
downloadnextcloud-server-38e9cb6a052f4d0bc4e34293febbe9f132055a83.tar.gz
nextcloud-server-38e9cb6a052f4d0bc4e34293febbe9f132055a83.zip
Use recurrence instance to build iMip email
instead of the main VEVENT of a repeating event Fixes part of https://github.com/nextcloud/calendar/issues/3919 Signed-off-by: Anna Larch <anna@nextcloud.com>
Diffstat (limited to 'apps/dav/tests/unit')
-rw-r--r--apps/dav/tests/unit/CalDAV/EventComparisonServiceTest.php146
-rw-r--r--apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php649
-rw-r--r--apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php284
3 files changed, 875 insertions, 204 deletions
diff --git a/apps/dav/tests/unit/CalDAV/EventComparisonServiceTest.php b/apps/dav/tests/unit/CalDAV/EventComparisonServiceTest.php
new file mode 100644
index 00000000000..c21be3065c5
--- /dev/null
+++ b/apps/dav/tests/unit/CalDAV/EventComparisonServiceTest.php
@@ -0,0 +1,146 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2023 Daniel Kesselberg <mail@danielkesselberg.de>
+ *
+ * @author 2023 Daniel Kesselberg <mail@danielkesselberg.de>
+ *
+ * @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\CalDAV;
+
+use OCA\DAV\CalDAV\EventComparisonService;
+use Sabre\VObject\Component\VCalendar;
+use Sabre\VObject\Component\VEvent;
+use Test\TestCase;
+
+class EventComparisonServiceTest extends TestCase
+{
+ /** @var EventComparisonService */
+ private $eventComparisonService;
+
+ protected function setUp(): void
+ {
+ $this->eventComparisonService = new EventComparisonService();
+ }
+
+ public function testNoModifiedEvent(): void
+ {
+ $vCalendarOld = new VCalendar();
+ $vCalendarNew = new VCalendar();
+
+ $vEventOld = $vCalendarOld->add('VEVENT', [
+ 'UID' => 'uid-1234',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ 'RRULE' => 'FREQ=DAILY;INTERVAL=1;UNTIL=20160201T000000Z',
+ ]);
+ $vEventOld->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $vEventOld->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+
+ $vEventNew = $vCalendarNew->add('VEVENT', [
+ 'UID' => 'uid-1234',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ 'RRULE' => 'FREQ=DAILY;INTERVAL=1;UNTIL=20160201T000000Z',
+ ]);
+ $vEventNew->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $vEventNew->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+
+ $result = $this->eventComparisonService->findModified($vCalendarNew, $vCalendarOld);
+ $this->assertEmpty($result['old']);
+ $this->assertEmpty($result['new']);
+ }
+
+ public function testNewEvent(): void
+ {
+ $vCalendarOld = null;
+ $vCalendarNew = new VCalendar();
+
+ $vEventNew = $vCalendarNew->add('VEVENT', [
+ 'UID' => 'uid-1234',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ 'RRULE' => 'FREQ=DAILY;INTERVAL=1;UNTIL=20160201T000000Z',
+ ]);
+ $vEventNew->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $vEventNew->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+
+ $result = $this->eventComparisonService->findModified($vCalendarNew, $vCalendarOld);
+ $this->assertNull($result['old']);
+ $this->assertEquals([$vEventNew], $result['new']);
+ }
+
+ public function testModifiedUnmodifiedEvent(): void
+ {
+ $vCalendarOld = new VCalendar();
+ $vCalendarNew = new VCalendar();
+
+ $vEventOld1 = $vCalendarOld->add('VEVENT', [
+ 'UID' => 'uid-1234',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ ]);
+ $vEventOld1->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $vEventOld1->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+
+ $vEventOld2 = $vCalendarOld->add('VEVENT', [
+ 'UID' => 'uid-1235',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ ]);
+ $vEventOld2->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $vEventOld2->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+
+ $vEventNew1 = $vCalendarNew->add('VEVENT', [
+ 'UID' => 'uid-1234',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ ]);
+ $vEventNew1->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $vEventNew1->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+
+ $vEventNew2 = $vCalendarNew->add('VEVENT', [
+ 'UID' => 'uid-1235',
+ 'LAST-MODIFIED' => 123457,
+ 'SEQUENCE' => 3,
+ 'SUMMARY' => 'Fellowship meeting 2',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ ]);
+ $vEventNew2->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $vEventNew2->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+
+ $result = $this->eventComparisonService->findModified($vCalendarNew, $vCalendarOld);
+ $this->assertEquals([$vEventOld2], $result['old']);
+ $this->assertEquals([$vEventNew2], $result['new']);
+ }
+}
diff --git a/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php b/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php
index ecb602813cc..fdd707247ac 100644
--- a/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php
+++ b/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php
@@ -29,28 +29,27 @@
*/
namespace OCA\DAV\Tests\unit\CalDAV\Schedule;
+use OCA\DAV\CalDAV\EventComparisonService;
use OCA\DAV\CalDAV\Schedule\IMipPlugin;
+use OCA\DAV\CalDAV\Schedule\IMipService;
use OCP\AppFramework\Utility\ITimeFactory;
-use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Defaults;
use OCP\IConfig;
-use OCP\IDBConnection;
-use OCP\IL10N;
-use OCP\IURLGenerator;
use OCP\IUserManager;
-use OCP\L10N\IFactory;
use OCP\Mail\IAttachment;
use OCP\Mail\IEMailTemplate;
use OCP\Mail\IMailer;
use OCP\Mail\IMessage;
-use OCP\Security\ISecureRandom;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Sabre\VObject\Component\VCalendar;
+use Sabre\VObject\Component\VEvent;
use Sabre\VObject\ITip\Message;
use Test\TestCase;
+use function array_merge;
class IMipPluginTest extends TestCase {
+
/** @var IMessage|MockObject */
private $mailMessage;
@@ -72,19 +71,28 @@ class IMipPluginTest extends TestCase {
/** @var IUserManager|MockObject */
private $userManager;
- /** @var IQueryBuilder|MockObject */
- private $queryBuilder;
-
/** @var IMipPlugin */
private $plugin;
+ /** @var IMipService|MockObject */
+ private $service;
+
+ /** @var Defaults|MockObject */
+ private $defaults;
+
+ /** @var LoggerInterface|MockObject */
+ private $logger;
+
+ /** @var EventComparisonService|MockObject */
+ private $eventComparisonService;
+
protected function setUp(): void {
$this->mailMessage = $this->createMock(IMessage::class);
$this->mailMessage->method('setFrom')->willReturn($this->mailMessage);
$this->mailMessage->method('setReplyTo')->willReturn($this->mailMessage);
$this->mailMessage->method('setTo')->willReturn($this->mailMessage);
- $this->mailer = $this->getMockBuilder(IMailer::class)->disableOriginalConstructor()->getMock();
+ $this->mailer = $this->createMock(IMailer::class);
$this->mailer->method('createMessage')->willReturn($this->mailMessage);
$this->emailTemplate = $this->createMock(IEMailTemplate::class);
@@ -93,249 +101,482 @@ class IMipPluginTest extends TestCase {
$this->emailAttachment = $this->createMock(IAttachment::class);
$this->mailer->method('createAttachment')->willReturn($this->emailAttachment);
- /** @var LoggerInterface|MockObject $logger */
- $logger = $this->getMockBuilder(LoggerInterface::class)->disableOriginalConstructor()->getMock();
+ $this->logger = $this->createMock(LoggerInterface::class);
- $this->timeFactory = $this->getMockBuilder(ITimeFactory::class)->disableOriginalConstructor()->getMock();
+ $this->timeFactory = $this->createMock(ITimeFactory::class);
$this->timeFactory->method('getTime')->willReturn(1496912528); // 2017-01-01
$this->config = $this->createMock(IConfig::class);
$this->userManager = $this->createMock(IUserManager::class);
- $l10n = $this->createMock(IL10N::class);
- $l10n->method('t')
- ->willReturnCallback(function ($text, $parameters = []) {
- return vsprintf($text, $parameters);
- });
- $l10nFactory = $this->createMock(IFactory::class);
- $l10nFactory->method('get')->willReturn($l10n);
-
- $urlGenerator = $this->createMock(IURLGenerator::class);
-
- $this->queryBuilder = $this->createMock(IQueryBuilder::class);
- $db = $this->createMock(IDBConnection::class);
- $db->method('getQueryBuilder')
- ->with()
- ->willReturn($this->queryBuilder);
-
- $random = $this->createMock(ISecureRandom::class);
- $random->method('generate')
- ->with(60, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')
- ->willReturn('random_token');
-
- $defaults = $this->createMock(Defaults::class);
- $defaults->method('getName')
+ $this->defaults = $this->createMock(Defaults::class);
+ $this->defaults->method('getName')
->willReturn('Instance Name 123');
- $this->plugin = new IMipPlugin($this->config, $this->mailer, $logger, $this->timeFactory, $l10nFactory, $urlGenerator, $defaults, $random, $db, $this->userManager, 'user123');
+ $this->service = $this->createMock(IMipService::class);
+
+ $this->eventComparisonService = $this->createMock(EventComparisonService::class);
+
+ $this->plugin = new IMipPlugin(
+ $this->config,
+ $this->mailer,
+ $this->logger,
+ $this->timeFactory,
+ $this->defaults,
+ $this->userManager,
+ 'user123',
+ $this->service,
+ $this->eventComparisonService
+ );
}
- public function testDelivery(): void {
- $this->config
- ->expects($this->any())
- ->method('getAppValue')
- ->willReturnMap([
- ['dav', 'invitation_link_recipients', 'yes', 'yes'],
- ]);
- $this->mailer->method('validateMailAddress')->willReturn(true);
-
- $message = $this->_testMessage();
- $this->_expectSend();
+ public function testDeliveryNoSignificantChange(): void {
+ $message = new Message();
+ $message->method = 'REQUEST';
+ $message->message = new VCalendar();
+ $message->message->add('VEVENT', array_merge([
+ 'UID' => 'uid-1234',
+ 'SEQUENCE' => 0,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00')
+ ], []));
+ $message->message->VEVENT->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $message->message->VEVENT->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE']);
+ $message->sender = 'mailto:gandalf@wiz.ard';
+ $message->senderName = 'Mr. Wizard';
+ $message->recipient = 'mailto:' . 'frodo@hobb.it';
+ $message->significantChange = false;
$this->plugin->schedule($message);
- $this->assertEquals('1.1', $message->getScheduleStatus());
+ $this->assertEquals('1.0', $message->getScheduleStatus());
}
- public function testFailedDelivery(): void {
- $this->config
- ->expects($this->any())
+ public function testParsingSingle(): void {
+ $message = new Message();
+ $message->method = 'REQUEST';
+ $newVCalendar = new VCalendar();
+ $newVevent = new VEvent($newVCalendar, 'one', array_merge([
+ 'UID' => 'uid-1234',
+ 'SEQUENCE' => 1,
+ 'SUMMARY' => 'Fellowship meeting without (!) Boromir',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00')
+ ], []));
+ $newVevent->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $newVevent->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+ $message->message = $newVCalendar;
+ $message->sender = 'mailto:gandalf@wiz.ard';
+ $message->senderName = 'Mr. Wizard';
+ $message->recipient = 'mailto:' . 'frodo@hobb.it';
+ // save the old copy in the plugin
+ $oldVCalendar = new VCalendar();
+ $oldVEvent = new VEvent($oldVCalendar, 'one', [
+ 'UID' => 'uid-1234',
+ 'SEQUENCE' => 0,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00')
+ ]);
+ $oldVEvent->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $oldVEvent->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+ $oldVEvent->add('ATTENDEE', 'mailto:' . 'boromir@tra.it.or', ['RSVP' => 'TRUE']);
+ $oldVCalendar->add($oldVEvent);
+ $data = ['invitee_name' => 'Mr. Wizard',
+ 'meeting_title' => 'Fellowship meeting without (!) Boromir',
+ 'attendee_name' => 'frodo@hobb.it'
+ ];
+ $this->plugin->setVCalendar($oldVCalendar);
+ $this->service->expects(self::once())
+ ->method('getLastOccurrence')
+ ->willReturn('1496912700');
+ $this->mailer->expects(self::once())
+ ->method('validateMailAddress')
+ ->with('frodo@hobb.it')
+ ->willReturn(true);
+ $this->eventComparisonService->expects(self::once())
+ ->method('findModified')
+ ->willReturn(['new' => [$newVevent], 'old' => [$oldVEvent]]);
+ $this->service->expects(self::once())
+ ->method('buildBodyData')
+ ->with($newVevent, $oldVEvent)
+ ->willReturn($data);
+ $this->userManager->expects(self::never())
+ ->method('getDisplayName');
+ $this->service->expects(self::once())
+ ->method('getFrom');
+ $this->service->expects(self::once())
+ ->method('addSubjectAndHeading')
+ ->with($this->emailTemplate, 'request', 'Mr. Wizard', 'Fellowship meeting without (!) Boromir');
+ $this->service->expects(self::once())
+ ->method('addBulletList')
+ ->with($this->emailTemplate, $newVevent, $data);
+ $this->service->expects(self::once())
+ ->method('getAttendeeRsvpOrReqForParticipant')
+ ->willReturn(true);
+ $this->config->expects(self::once())
->method('getAppValue')
- ->willReturnMap([
- ['dav', 'invitation_link_recipients', 'yes', 'yes'],
- ]);
- $this->mailer->method('validateMailAddress')->willReturn(true);
-
- $message = $this->_testMessage();
- $this->mailer
+ ->with('dav', 'invitation_link_recipients', 'yes')
+ ->willReturn('yes');
+ $this->service->expects(self::once())
+ ->method('createInvitationToken')
+ ->with($message,$newVevent, '1496912700')
+ ->willReturn('token');
+ $this->service->expects(self::once())
+ ->method('addResponseButtons')
+ ->with($this->emailTemplate, 'token');
+ $this->service->expects(self::once())
+ ->method('addMoreOptionsButton')
+ ->with($this->emailTemplate, 'token');
+ $this->mailer->expects(self::once())
->method('send')
- ->willThrowException(new \Exception());
- $this->_expectSend();
- $this->plugin->schedule($message);
- $this->assertEquals('5.0', $message->getScheduleStatus());
- }
-
- public function testInvalidEmailDelivery(): void {
- $this->mailer->method('validateMailAddress')->willReturn(false);
-
- $message = $this->_testMessage();
+ ->willReturn([]);
$this->plugin->schedule($message);
- $this->assertEquals('5.0', $message->getScheduleStatus());
+ $this->assertEquals('1.1', $message->getScheduleStatus());
}
- public function testDeliveryWithNoCommonName(): void {
- $this->config
- ->expects($this->any())
- ->method('getAppValue')
- ->willReturnMap([
- ['dav', 'invitation_link_recipients', 'yes', 'yes'],
- ]);
- $this->mailer->method('validateMailAddress')->willReturn(true);
-
- $message = $this->_testMessage();
- $message->senderName = null;
-
- $this->userManager->expects($this->once())
+ public function testParsingRecurrence(): void {
+ $message = new Message();
+ $message->method = 'REQUEST';
+ $newVCalendar = new VCalendar();
+ $newVevent = new VEvent($newVCalendar, 'one', [
+ 'UID' => 'uid-1234',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ 'RRULE' => 'FREQ=DAILY;INTERVAL=1;UNTIL=20160201T000000Z'
+ ]);
+ $newVevent->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $newVevent->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+ $newvEvent2 = new VEvent($newVCalendar, 'two', [
+ 'UID' => 'uid-1234',
+ 'SEQUENCE' => 1,
+ 'SUMMARY' => 'Elevenses',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ 'RECURRENCE-ID' => new \DateTime('2016-01-01 00:00:00')
+ ]);
+ $newvEvent2->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $newvEvent2->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+ $message->message = $newVCalendar;
+ $message->sender = 'mailto:gandalf@wiz.ard';
+ $message->recipient = 'mailto:' . 'frodo@hobb.it';
+ // save the old copy in the plugin
+ $oldVCalendar = new VCalendar();
+ $oldVEvent = new VEvent($oldVCalendar, 'one', [
+ 'UID' => 'uid-1234',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ 'RRULE' => 'FREQ=DAILY;INTERVAL=1;UNTIL=20160201T000000Z'
+ ]);
+ $oldVEvent->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $oldVEvent->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+ $data = ['invitee_name' => 'Mr. Wizard',
+ 'meeting_title' => 'Elevenses',
+ 'attendee_name' => 'frodo@hobb.it'
+ ];
+ $this->plugin->setVCalendar($oldVCalendar);
+ $this->service->expects(self::once())
+ ->method('getLastOccurrence')
+ ->willReturn('1496912700');
+ $this->mailer->expects(self::once())
+ ->method('validateMailAddress')
+ ->with('frodo@hobb.it')
+ ->willReturn(true);
+ $this->eventComparisonService->expects(self::once())
+ ->method('findModified')
+ ->willReturn(['old' => [] ,'new' => [$newVevent]]);
+ $this->service->expects(self::once())
+ ->method('buildBodyData')
+ ->with($newVevent, null)
+ ->willReturn($data);
+ $this->userManager->expects(self::once())
->method('getDisplayName')
- ->with('user123')
->willReturn('Mr. Wizard');
-
- $this->_expectSend();
+ $this->service->expects(self::once())
+ ->method('getFrom');
+ $this->service->expects(self::once())
+ ->method('addSubjectAndHeading')
+ ->with($this->emailTemplate, 'request', 'Mr. Wizard', 'Elevenses');
+ $this->service->expects(self::once())
+ ->method('addBulletList')
+ ->with($this->emailTemplate, $newVevent, $data);
+ $this->service->expects(self::once())
+ ->method('getAttendeeRsvpOrReqForParticipant')
+ ->willReturn(true);
+ $this->config->expects(self::once())
+ ->method('getAppValue')
+ ->with('dav', 'invitation_link_recipients', 'yes')
+ ->willReturn('yes');
+ $this->service->expects(self::once())
+ ->method('createInvitationToken')
+ ->with($message, $newVevent, '1496912700')
+ ->willReturn('token');
+ $this->service->expects(self::once())
+ ->method('addResponseButtons')
+ ->with($this->emailTemplate, 'token');
+ $this->service->expects(self::once())
+ ->method('addMoreOptionsButton')
+ ->with($this->emailTemplate, 'token');
+ $this->mailer->expects(self::once())
+ ->method('send')
+ ->willReturn([]);
$this->plugin->schedule($message);
$this->assertEquals('1.1', $message->getScheduleStatus());
}
- /**
- * @dataProvider dataNoMessageSendForPastEvents
- */
- public function testNoMessageSendForPastEvents(array $veventParams, bool $expectsMail): void {
- $this->config
- ->method('getAppValue')
- ->willReturn('yes');
- $this->mailer->method('validateMailAddress')->willReturn(true);
-
- $message = $this->_testMessage($veventParams);
+ public function testEmailValidationFailed() {
+ $message = new Message();
+ $message->method = 'REQUEST';
+ $message->message = new VCalendar();
+ $message->message->add('VEVENT', array_merge([
+ 'UID' => 'uid-1234',
+ 'SEQUENCE' => 0,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00')
+ ], []));
+ $message->message->VEVENT->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $message->message->VEVENT->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE']);
+ $message->sender = 'mailto:gandalf@wiz.ard';
+ $message->senderName = 'Mr. Wizard';
+ $message->recipient = 'mailto:' . 'frodo@hobb.it';
- $this->_expectSend('frodo@hobb.it', $expectsMail, $expectsMail);
+ $this->service->expects(self::once())
+ ->method('getLastOccurrence')
+ ->willReturn('1496912700');
+ $this->mailer->expects(self::once())
+ ->method('validateMailAddress')
+ ->with('frodo@hobb.it')
+ ->willReturn(false);
$this->plugin->schedule($message);
-
- if ($expectsMail) {
- $this->assertEquals('1.1', $message->getScheduleStatus());
- } else {
- $this->assertEquals(false, $message->getScheduleStatus());
- }
+ $this->assertEquals('5.0', $message->getScheduleStatus());
}
- public function dataNoMessageSendForPastEvents() {
- return [
- [['DTSTART' => new \DateTime('2017-01-01 00:00:00')], false],
- [['DTSTART' => new \DateTime('2017-01-01 00:00:00'), 'DTEND' => new \DateTime('2017-01-01 00:00:00')], false],
- [['DTSTART' => new \DateTime('2017-01-01 00:00:00'), 'DTEND' => new \DateTime('2017-12-31 00:00:00')], true],
- [['DTSTART' => new \DateTime('2017-01-01 00:00:00'), 'DURATION' => 'P1D'], false],
- [['DTSTART' => new \DateTime('2017-01-01 00:00:00'), 'DURATION' => 'P52W'], true],
- [['DTSTART' => new \DateTime('2017-01-01 00:00:00'), 'DTEND' => new \DateTime('2017-01-01 00:00:00'), 'RRULE' => 'FREQ=WEEKLY'], true],
- [['DTSTART' => new \DateTime('2017-01-01 00:00:00'), 'DTEND' => new \DateTime('2017-01-01 00:00:00'), 'RRULE' => 'FREQ=WEEKLY;COUNT=3'], false],
- [['DTSTART' => new \DateTime('2017-01-01 00:00:00'), 'DTEND' => new \DateTime('2017-01-01 00:00:00'), 'RRULE' => 'FREQ=WEEKLY;UNTIL=20170301T000000Z'], false],
- [['DTSTART' => new \DateTime('2017-01-01 00:00:00'), 'DTEND' => new \DateTime('2017-01-01 00:00:00'), 'RRULE' => 'FREQ=WEEKLY;COUNT=33'], true],
- [['DTSTART' => new \DateTime('2017-01-01 00:00:00'), 'DTEND' => new \DateTime('2017-01-01 00:00:00'), 'RRULE' => 'FREQ=WEEKLY;UNTIL=20171001T000000Z'], true],
+ public function testFailedDelivery(): void {
+ $message = new Message();
+ $message->method = 'REQUEST';
+ $newVcalendar = new VCalendar();
+ $newVevent = new VEvent($newVcalendar, 'one', array_merge([
+ 'UID' => 'uid-1234',
+ 'SEQUENCE' => 1,
+ 'SUMMARY' => 'Fellowship meeting without (!) Boromir',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00')
+ ], []));
+ $newVevent->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $newVevent->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+ $message->message = $newVcalendar;
+ $message->sender = 'mailto:gandalf@wiz.ard';
+ $message->senderName = 'Mr. Wizard';
+ $message->recipient = 'mailto:' . 'frodo@hobb.it';
+ // save the old copy in the plugin
+ $oldVcalendar = new VCalendar();
+ $oldVevent = new VEvent($oldVcalendar, 'one', [
+ 'UID' => 'uid-1234',
+ 'SEQUENCE' => 0,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00')
+ ]);
+ $oldVevent->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $oldVevent->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+ $oldVevent->add('ATTENDEE', 'mailto:' . 'boromir@tra.it.or', ['RSVP' => 'TRUE']);
+ $oldVcalendar->add($oldVevent);
+ $data = ['invitee_name' => 'Mr. Wizard',
+ 'meeting_title' => 'Fellowship meeting without (!) Boromir',
+ 'attendee_name' => 'frodo@hobb.it'
];
- }
-
- /**
- * @dataProvider dataIncludeResponseButtons
- */
- public function testIncludeResponseButtons(string $config_setting, string $recipient, bool $has_buttons): void {
- $message = $this->_testMessage([], $recipient);
- $this->mailer->method('validateMailAddress')->willReturn(true);
-
- $this->_expectSend($recipient, true, $has_buttons);
- $this->config
- ->expects($this->any())
+ $this->plugin->setVCalendar($oldVcalendar);
+ $this->service->expects(self::once())
+ ->method('getLastOccurrence')
+ ->willReturn('1496912700');
+ $this->mailer->expects(self::once())
+ ->method('validateMailAddress')
+ ->with('frodo@hobb.it')
+ ->willReturn(true);
+ $this->eventComparisonService->expects(self::once())
+ ->method('findModified')
+ ->willReturn(['old' => [] ,'new' => [$newVevent]]);
+ $this->service->expects(self::once())
+ ->method('buildBodyData')
+ ->with($newVevent, null)
+ ->willReturn($data);
+ $this->userManager->expects(self::never())
+ ->method('getDisplayName');
+ $this->service->expects(self::once())
+ ->method('getFrom');
+ $this->service->expects(self::once())
+ ->method('addSubjectAndHeading')
+ ->with($this->emailTemplate, 'request', 'Mr. Wizard', 'Fellowship meeting without (!) Boromir');
+ $this->service->expects(self::once())
+ ->method('addBulletList')
+ ->with($this->emailTemplate, $newVevent, $data);
+ $this->service->expects(self::once())
+ ->method('getAttendeeRsvpOrReqForParticipant')
+ ->willReturn(true);
+ $this->config->expects(self::once())
->method('getAppValue')
- ->willReturnMap([
- ['dav', 'invitation_link_recipients', 'yes', $config_setting],
- ]);
-
+ ->with('dav', 'invitation_link_recipients', 'yes')
+ ->willReturn('yes');
+ $this->service->expects(self::once())
+ ->method('createInvitationToken')
+ ->with($message, $newVevent, '1496912700')
+ ->willReturn('token');
+ $this->service->expects(self::once())
+ ->method('addResponseButtons')
+ ->with($this->emailTemplate, 'token');
+ $this->service->expects(self::once())
+ ->method('addMoreOptionsButton')
+ ->with($this->emailTemplate, 'token');
+ $this->mailer->expects(self::once())
+ ->method('send')
+ ->willReturn([]);
+ $this->mailer
+ ->method('send')
+ ->willThrowException(new \Exception());
+ $this->logger->expects(self::once())
+ ->method('error');
$this->plugin->schedule($message);
- $this->assertEquals('1.1', $message->getScheduleStatus());
+ $this->assertEquals('5.0', $message->getScheduleStatus());
}
- public function dataIncludeResponseButtons() {
- return [
- // dav.invitation_link_recipients, recipient, $has_buttons
- [ 'yes', 'joe@internal.com', true],
- [ 'joe@internal.com', 'joe@internal.com', true],
- [ 'internal.com', 'joe@internal.com', true],
- [ 'pete@otherinternal.com,internal.com', 'joe@internal.com', true],
- [ 'no', 'joe@internal.com', false],
- [ 'internal.com', 'joe@external.com', false],
- [ 'jane@otherinternal.com,internal.com', 'joe@otherinternal.com', false],
+ public function testNoOldEvent(): void {
+ $message = new Message();
+ $message->method = 'REQUEST';
+ $newVCalendar = new VCalendar();
+ $newVevent = new VEvent($newVCalendar, 'VEVENT', array_merge([
+ 'UID' => 'uid-1234',
+ 'SEQUENCE' => 1,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00')
+ ], []));
+ $newVevent->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $newVevent->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+ $message->message = $newVCalendar;
+ $message->sender = 'mailto:gandalf@wiz.ard';
+ $message->senderName = 'Mr. Wizard';
+ $message->recipient = 'mailto:' . 'frodo@hobb.it';
+ $data = ['invitee_name' => 'Mr. Wizard',
+ 'meeting_title' => 'Fellowship meeting',
+ 'attendee_name' => 'frodo@hobb.it'
];
- }
- public function testMessageSendWhenEventWithoutName(): void {
- $this->config
+ $this->service->expects(self::once())
+ ->method('getLastOccurrence')
+ ->willReturn('1496912700');
+ $this->mailer->expects(self::once())
+ ->method('validateMailAddress')
+ ->with('frodo@hobb.it')
+ ->willReturn(true);
+ $this->eventComparisonService->expects(self::once())
+ ->method('findModified')
+ ->with($newVCalendar, null)
+ ->willReturn(['old' => [] ,'new' => [$newVevent]]);
+ $this->service->expects(self::once())
+ ->method('buildBodyData')
+ ->with($newVevent, null)
+ ->willReturn($data);
+ $this->userManager->expects(self::never())
+ ->method('getDisplayName');
+ $this->service->expects(self::once())
+ ->method('getFrom');
+ $this->service->expects(self::once())
+ ->method('addSubjectAndHeading')
+ ->with($this->emailTemplate, 'request', 'Mr. Wizard', 'Fellowship meeting');
+ $this->service->expects(self::once())
+ ->method('addBulletList')
+ ->with($this->emailTemplate, $newVevent, $data);
+ $this->service->expects(self::once())
+ ->method('getAttendeeRsvpOrReqForParticipant')
+ ->willReturn(true);
+ $this->config->expects(self::once())
->method('getAppValue')
+ ->with('dav', 'invitation_link_recipients', 'yes')
->willReturn('yes');
- $this->mailer->method('validateMailAddress')->willReturn(true);
-
- $message = $this->_testMessage(['SUMMARY' => '']);
- $this->_expectSend('frodo@hobb.it', true, true, 'Invitation: Untitled event');
- $this->emailTemplate->expects($this->once())
- ->method('addHeading')
- ->with('Invitation');
+ $this->service->expects(self::once())
+ ->method('createInvitationToken')
+ ->with($message, $newVevent, '1496912700')
+ ->willReturn('token');
+ $this->service->expects(self::once())
+ ->method('addResponseButtons')
+ ->with($this->emailTemplate, 'token');
+ $this->service->expects(self::once())
+ ->method('addMoreOptionsButton')
+ ->with($this->emailTemplate, 'token');
+ $this->mailer->expects(self::once())
+ ->method('send')
+ ->willReturn([]);
+ $this->mailer
+ ->method('send')
+ ->willReturn([]);
$this->plugin->schedule($message);
$this->assertEquals('1.1', $message->getScheduleStatus());
}
- private function _testMessage(array $attrs = [], string $recipient = 'frodo@hobb.it') {
+ public function testNoButtons(): void {
$message = new Message();
$message->method = 'REQUEST';
- $message->message = new VCalendar();
- $message->message->add('VEVENT', array_merge([
+ $newVCalendar = new VCalendar();
+ $newVevent = new VEvent($newVCalendar, 'VEVENT', array_merge([
'UID' => 'uid-1234',
- 'SEQUENCE' => 0,
+ 'SEQUENCE' => 1,
'SUMMARY' => 'Fellowship meeting',
- 'DTSTART' => new \DateTime('2018-01-01 00:00:00')
- ], $attrs));
- $message->message->VEVENT->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
- $message->message->VEVENT->add('ATTENDEE', 'mailto:'.$recipient, [ 'RSVP' => 'TRUE' ]);
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00')
+ ], []));
+ $newVevent->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $newVevent->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+ $message->message = $newVCalendar;
$message->sender = 'mailto:gandalf@wiz.ard';
- $message->senderName = 'Mr. Wizard';
- $message->recipient = 'mailto:'.$recipient;
- return $message;
- }
-
+ $message->recipient = 'mailto:' . 'frodo@hobb.it';
+ $data = ['invitee_name' => 'Mr. Wizard',
+ 'meeting_title' => 'Fellowship meeting',
+ 'attendee_name' => 'frodo@hobb.it'
+ ];
- private function _expectSend(string $recipient = 'frodo@hobb.it', bool $expectSend = true, bool $expectButtons = true, string $subject = 'Invitation: Fellowship meeting'): void {
- // if the event is in the past, we skip out
- if (!$expectSend) {
- $this->mailer
- ->expects($this->never())
- ->method('send');
- return;
- }
-
- $this->emailTemplate->expects($this->once())
- ->method('setSubject')
- ->with($subject);
- $this->mailMessage->expects($this->once())
- ->method('setTo')
- ->with([$recipient => null]);
- $this->mailMessage->expects($this->once())
- ->method('setReplyTo')
- ->with(['gandalf@wiz.ard' => 'Mr. Wizard']);
- $this->mailMessage->expects($this->once())
- ->method('setFrom')
- ->with(['invitations-noreply@localhost' => 'Mr. Wizard via Instance Name 123']);
+ $this->service->expects(self::once())
+ ->method('getLastOccurrence')
+ ->willReturn('1496912700');
+ $this->mailer->expects(self::once())
+ ->method('validateMailAddress')
+ ->with('frodo@hobb.it')
+ ->willReturn(true);
+ $this->eventComparisonService->expects(self::once())
+ ->method('findModified')
+ ->with($newVCalendar, null)
+ ->willReturn(['old' => [] ,'new' => [$newVevent]]);
+ $this->service->expects(self::once())
+ ->method('buildBodyData')
+ ->with($newVevent, null)
+ ->willReturn($data);
+ $this->userManager->expects(self::once())
+ ->method('getDisplayName')
+ ->willReturn('Mr. Wizard');
+ $this->service->expects(self::once())
+ ->method('getFrom');
+ $this->service->expects(self::once())
+ ->method('addSubjectAndHeading')
+ ->with($this->emailTemplate, 'request', 'Mr. Wizard', 'Fellowship meeting');
+ $this->service->expects(self::once())
+ ->method('addBulletList')
+ ->with($this->emailTemplate, $newVevent, $data);
+ $this->service->expects(self::once())
+ ->method('getAttendeeRsvpOrReqForParticipant')
+ ->willReturn(true);
+ $this->config->expects(self::once())
+ ->method('getAppValue')
+ ->with('dav', 'invitation_link_recipients', 'yes')
+ ->willReturn('no');
+ $this->service->expects(self::never())
+ ->method('createInvitationToken');
+ $this->service->expects(self::never())
+ ->method('addResponseButtons');
+ $this->service->expects(self::never())
+ ->method('addMoreOptionsButton');
+ $this->mailer->expects(self::once())
+ ->method('send')
+ ->willReturn([]);
$this->mailer
- ->expects($this->once())
- ->method('send');
-
- if ($expectButtons) {
- $this->queryBuilder->expects($this->once())
- ->method('insert')
- ->with('calendar_invitations')
- ->willReturn($this->queryBuilder);
- $this->queryBuilder->expects($this->once())
- ->method('values')
- ->willReturn($this->queryBuilder);
- $this->queryBuilder->expects($this->once())
- ->method('execute');
- } else {
- $this->queryBuilder->expects($this->never())
- ->method('insert')
- ->with('calendar_invitations');
- }
+ ->method('send')
+ ->willReturn([]);
+ $this->plugin->schedule($message);
+ $this->assertEquals('1.1', $message->getScheduleStatus());
}
}
diff --git a/apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php b/apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php
new file mode 100644
index 00000000000..000476050c7
--- /dev/null
+++ b/apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php
@@ -0,0 +1,284 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @copyright Copyright (c) 2017, Georg Ehrke
+ *
+ * @author brad2014 <brad2014@users.noreply.github.com>
+ * @author Brad Rubenstein <brad@wbr.tech>
+ * @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 Thomas Citharel <nextcloud@tcit.fr>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\DAV\Tests\unit\CalDAV\Schedule;
+
+use OC\L10N\L10N;
+use OC\L10N\LazyL10N;
+use OC\URLGenerator;
+use OCA\DAV\CalDAV\Schedule\IMipService;
+use OCP\IConfig;
+use OCP\IDBConnection;
+use OCP\L10N\IFactory as L10NFactory;
+use OCP\Security\ISecureRandom;
+use PHPUnit\Framework\MockObject\MockObject;
+use Sabre\VObject\Component\VCalendar;
+use Sabre\VObject\Component\VEvent;
+use Sabre\VObject\Property\ICalendar\DateTime;
+use Test\TestCase;
+
+class IMipServiceTest extends TestCase
+{
+ /** @var URLGenerator|MockObject */
+ private $urlGenerator;
+
+ /** @var IConfig|MockObject */
+ private $config;
+
+ /** @var IDBConnection|MockObject */
+ private $db;
+
+ /** @var ISecureRandom|MockObject */
+ private $random;
+
+ /** @var L10NFactory|MockObject */
+ private $l10nFactory;
+
+ /** @var L10N|MockObject */
+ private $l10n;
+
+ /** @var IMipService */
+ private $service;
+
+ protected function setUp(): void
+ {
+ $this->urlGenerator = $this->createMock(URLGenerator::class);
+ $this->config = $this->createMock(IConfig::class);
+ $this->db = $this->createMock(IDBConnection::class);
+ $this->random = $this->createMock(ISecureRandom::class);
+ $this->l10nFactory = $this->createMock(L10NFactory::class);
+ $this->l10n = $this->createMock(LazyL10N::class);
+ $this->l10nFactory->expects(self::once())
+ ->method('findGenericLanguage')
+ ->willReturn('en');
+ $this->l10nFactory->expects(self::once())
+ ->method('get')
+ ->with('dav', 'en')
+ ->willReturn($this->l10n);
+ $this->service = new IMipService(
+ $this->urlGenerator,
+ $this->config,
+ $this->db,
+ $this->random,
+ $this->l10nFactory
+ );
+ }
+
+ public function testGetFrom(): void
+ {
+ $senderName = "Detective McQueen";
+ $default = "Twin Lakes Police Department - Darkside Division";
+ $expected = "Detective McQueen via Twin Lakes Police Department - Darkside Division";
+
+ $this->l10n->expects(self::once())
+ ->method('t')
+ ->willReturn($expected);
+
+ $actual = $this->service->getFrom($senderName, $default);
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function testBuildBodyDataCreated(): void
+ {
+ $vCalendar = new VCalendar();
+ $oldVevent = null;
+ $newVevent = new VEvent($vCalendar, 'two', [
+ 'UID' => 'uid-1234',
+ 'SEQUENCE' => 3,
+ 'LAST-MODIFIED' => 789456,
+ 'SUMMARY' => 'Second Breakfast',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ 'RECURRENCE-ID' => new \DateTime('2016-01-01 00:00:00')
+ ]);
+
+ $expected = [
+ 'meeting_when' => $this->service->generateWhenString($newVevent),
+ 'meeting_description' => '',
+ 'meeting_title' => 'Second Breakfast',
+ 'meeting_location' => '',
+ 'meeting_url' => '',
+ 'meeting_url_html' => '',
+ ];
+
+ $actual = $this->service->buildBodyData($newVevent, $oldVevent);
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function testBuildBodyDataUpdate(): void
+ {
+ $vCalendar = new VCalendar();
+ $oldVevent = new VEvent($vCalendar, 'two', [
+ 'UID' => 'uid-1234',
+ 'SEQUENCE' => 1,
+ 'LAST-MODIFIED' => 456789,
+ 'SUMMARY' => 'Elevenses',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ 'RECURRENCE-ID' => new \DateTime('2016-01-01 00:00:00')
+ ]);
+ $oldVevent->add('ORGANIZER', 'mailto:gandalf@wiz.ard');
+ $oldVevent->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
+ $newVevent = new VEvent($vCalendar, 'two', [
+ 'UID' => 'uid-1234',
+ 'SEQUENCE' => 3,
+ 'LAST-MODIFIED' => 789456,
+ 'SUMMARY' => 'Second Breakfast',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ 'RECURRENCE-ID' => new \DateTime('2016-01-01 00:00:00')
+ ]);
+
+ $expected = [
+ 'meeting_when' => $this->service->generateWhenString($newVevent),
+ 'meeting_description' => '',
+ 'meeting_title' => 'Second Breakfast',
+ 'meeting_location' => '',
+ 'meeting_url' => '',
+ 'meeting_url_html' => '',
+ 'meeting_when_html' => $this->service->generateWhenString($newVevent),
+ 'meeting_title_html' => sprintf("<span style='text-decoration: line-through'>%s</span><br />%s", 'Elevenses', 'Second Breakfast'),
+ 'meeting_description_html' => '',
+ 'meeting_location_html' => ''
+ ];
+
+ $actual = $this->service->buildBodyData($newVevent, $oldVevent);
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function testGenerateWhenStringHourlyEvent(): void {
+ $vCalendar = new VCalendar();
+ $vevent = new VEvent($vCalendar, 'two', [
+ 'UID' => 'uid-1234',
+ 'SEQUENCE' => 1,
+ 'LAST-MODIFIED' => 456789,
+ 'SUMMARY' => 'Elevenses',
+ 'TZID' => 'Europe/Vienna',
+ 'DTSTART' => (new \DateTime('2016-01-01 08:00:00'))->setTimezone(new \DateTimeZone('Europe/Vienna')),
+ 'DTEND' => (new \DateTime('2016-01-01 09:00:00'))->setTimezone(new \DateTimeZone('Europe/Vienna')),
+ ]);
+
+ $this->l10n->expects(self::exactly(3))
+ ->method('l')
+ ->withConsecutive(
+ ['weekdayName', (new \DateTime('2016-01-01 08:00:00'))->setTimezone(new \DateTimeZone('Europe/Vienna')), ['width' => 'abbreviated']],
+ ['datetime', (new \DateTime('2016-01-01 08:00:00'))->setTimezone(new \DateTimeZone('Europe/Vienna')), ['width' => 'medium|short']],
+ ['time', (new \DateTime('2016-01-01 09:00:00'))->setTimezone(new \DateTimeZone('Europe/Vienna')), ['width' => 'short']]
+ )->willReturnOnConsecutiveCalls(
+ 'Fr.',
+ '01.01. 08:00',
+ '09:00'
+ );
+
+ $expected = 'Fr., 01.01. 08:00 - 09:00 (Europe/Vienna)';
+ $actual = $this->service->generateWhenString($vevent);
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function testGetLastOccurrenceRRULE(): void
+ {
+ $vCalendar = new VCalendar();
+ $vCalendar->add('VEVENT', [
+ 'UID' => 'uid-1234',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ 'RRULE' => 'FREQ=DAILY;INTERVAL=1;UNTIL=20160201T000000Z',
+ ]);
+
+ $occurrence = $this->service->getLastOccurrence($vCalendar);
+ $this->assertEquals(1454284800, $occurrence);
+ }
+
+ public function testGetLastOccurrenceEndDate(): void
+ {
+ $vCalendar = new VCalendar();
+ $vCalendar->add('VEVENT', [
+ 'UID' => 'uid-1234',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ 'DTEND' => new \DateTime('2017-01-01 00:00:00'),
+ ]);
+
+ $occurrence = $this->service->getLastOccurrence($vCalendar);
+ $this->assertEquals(1483228800, $occurrence);
+ }
+
+ public function testGetLastOccurrenceDuration(): void
+ {
+ $vCalendar = new VCalendar();
+ $vCalendar->add('VEVENT', [
+ 'UID' => 'uid-1234',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ 'DURATION' => 'P12W',
+ ]);
+
+ $occurrence = $this->service->getLastOccurrence($vCalendar);
+ $this->assertEquals(1458864000, $occurrence);
+ }
+
+ public function testGetLastOccurrenceAllDay(): void
+ {
+ $vCalendar = new VCalendar();
+ $vEvent = $vCalendar->add('VEVENT', [
+ 'UID' => 'uid-1234',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ ]);
+
+ // rewrite from DateTime to Date
+ $vEvent->DTSTART['VALUE'] = 'DATE';
+
+ $occurrence = $this->service->getLastOccurrence($vCalendar);
+ $this->assertEquals(1451692800, $occurrence);
+ }
+
+ public function testGetLastOccurrenceFallback(): void
+ {
+ $vCalendar = new VCalendar();
+ $vCalendar->add('VEVENT', [
+ 'UID' => 'uid-1234',
+ 'LAST-MODIFIED' => 123456,
+ 'SEQUENCE' => 2,
+ 'SUMMARY' => 'Fellowship meeting',
+ 'DTSTART' => new \DateTime('2016-01-01 00:00:00'),
+ ]);
+
+ $occurrence = $this->service->getLastOccurrence($vCalendar);
+ $this->assertEquals(1451606400, $occurrence);
+ }
+}