2015-10-30 20:28:21 -04:00
< ? php
2025-05-24 17:00:05 -04:00
declare ( strict_types = 1 );
2015-10-30 20:28:21 -04:00
/**
2024-05-28 06:34:11 -04:00
* SPDX - FileCopyrightText : 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX - FileCopyrightText : 2016 ownCloud , Inc .
* SPDX - License - Identifier : AGPL - 3.0 - only
2015-10-30 20:28:21 -04:00
*/
2022-04-01 11:31:37 -04:00
2016-05-25 10:04:15 -04:00
namespace OCA\DAV\Tests\unit\CalDAV ;
2015-10-30 20:28:21 -04:00
2023-09-20 11:45:54 -04:00
use DateInterval ;
2015-10-30 20:28:21 -04:00
use DateTime ;
2023-09-20 11:45:54 -04:00
use DateTimeImmutable ;
2015-10-30 20:28:21 -04:00
use DateTimeZone ;
use OCA\DAV\CalDAV\CalDavBackend ;
2016-01-28 11:16:11 -05:00
use OCA\DAV\CalDAV\Calendar ;
2022-05-18 05:10:36 -04:00
use OCA\DAV\DAV\Sharing\Plugin as SharingPlugin ;
2021-04-29 04:04:08 -04:00
use OCA\DAV\Events\CalendarDeletedEvent ;
2017-10-20 09:09:52 -04:00
use OCP\IConfig ;
2016-04-21 07:36:52 -04:00
use OCP\IL10N ;
2025-04-07 08:59:20 -04:00
use Psr\Log\NullLogger ;
2019-11-22 14:52:10 -05:00
use Sabre\DAV\Exception\NotFound ;
2015-10-30 20:28:21 -04:00
use Sabre\DAV\PropPatch ;
2015-11-20 07:35:23 -05:00
use Sabre\DAV\Xml\Property\Href ;
2016-01-28 14:30:40 -05:00
use Sabre\DAVACL\IACL ;
2024-03-08 02:14:05 -05:00
use function time ;
2015-10-30 20:28:21 -04:00
/**
* Class CalDavBackendTest
*/
2026-01-07 08:21:48 -05:00
#[\PHPUnit\Framework\Attributes\Group(name: 'DB')]
2017-10-05 06:32:46 -04:00
class CalDavBackendTest extends AbstractCalDavBackend {
2023-01-20 02:38:43 -05:00
public function testCalendarOperations () : void {
2015-10-30 20:28:21 -04:00
$calendarId = $this -> createTestCalendar ();
2022-07-28 07:11:38 -04:00
// update its display name
2015-10-30 20:28:21 -04:00
$patch = new PropPatch ([
'{DAV:}displayname' => 'Unit test' ,
'{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar used for unit testing'
]);
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2015-10-30 20:28:21 -04:00
$this -> backend -> updateCalendar ( $calendarId , $patch );
$patch -> commit ();
2016-08-30 09:11:33 -04:00
$this -> assertEquals ( 1 , $this -> backend -> getCalendarsForUserCount ( self :: UNIT_TEST_USER ));
2017-03-02 05:45:07 -05:00
$calendars = $this -> backend -> getCalendarsForUser ( self :: UNIT_TEST_USER );
$this -> assertCount ( 1 , $calendars );
$this -> assertEquals ( 'Unit test' , $calendars [ 0 ][ '{DAV:}displayname' ]);
$this -> assertEquals ( 'Calendar used for unit testing' , $calendars [ 0 ][ '{urn:ietf:params:xml:ns:caldav}calendar-description' ]);
2017-04-19 10:18:44 -04:00
$this -> assertEquals ( 'User\'s displayname' , $calendars [ 0 ][ '{http://nextcloud.com/ns}owner-displayname' ]);
2015-10-30 20:28:21 -04:00
// delete the address book
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2021-03-12 05:20:04 -05:00
$this -> backend -> deleteCalendar ( $calendars [ 0 ][ 'id' ], true );
2017-03-02 05:45:07 -05:00
$calendars = $this -> backend -> getCalendarsForUser ( self :: UNIT_TEST_USER );
2021-04-29 04:04:08 -04:00
self :: assertEmpty ( $calendars );
2015-10-30 20:28:21 -04:00
}
2025-05-24 17:00:05 -04:00
public static function providesSharingData () : array {
2016-01-28 14:30:40 -05:00
return [
[ true , true , true , false , [
[
'href' => 'principal:' . self :: UNIT_TEST_USER1 ,
'readOnly' => false
],
[
'href' => 'principal:' . self :: UNIT_TEST_GROUP ,
'readOnly' => true
]
2024-01-30 12:35:44 -05:00
], [
self :: UNIT_TEST_USER1 ,
self :: UNIT_TEST_GROUP ,
2016-01-28 14:30:40 -05:00
]],
2017-03-02 06:27:59 -05:00
[ true , true , true , false , [
[
'href' => 'principal:' . self :: UNIT_TEST_GROUP ,
'readOnly' => true ,
],
[
'href' => 'principal:' . self :: UNIT_TEST_GROUP2 ,
'readOnly' => false ,
],
2024-01-30 12:35:44 -05:00
], [
self :: UNIT_TEST_GROUP ,
self :: UNIT_TEST_GROUP2 ,
2017-03-02 06:27:59 -05:00
]],
[ true , true , true , true , [
[
'href' => 'principal:' . self :: UNIT_TEST_GROUP ,
'readOnly' => false ,
],
[
'href' => 'principal:' . self :: UNIT_TEST_GROUP2 ,
'readOnly' => true ,
],
2024-01-30 12:35:44 -05:00
], [
self :: UNIT_TEST_GROUP ,
self :: UNIT_TEST_GROUP2 ,
2017-03-02 06:27:59 -05:00
]],
2016-01-28 14:30:40 -05:00
[ true , false , false , false , [
[
'href' => 'principal:' . self :: UNIT_TEST_USER1 ,
'readOnly' => true
],
2024-01-30 12:35:44 -05:00
], [
self :: UNIT_TEST_USER1 ,
2016-01-28 14:30:40 -05:00
]],
];
}
2026-01-07 08:21:48 -05:00
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'providesSharingData')]
2024-01-30 12:35:44 -05:00
public function testCalendarSharing ( $userCanRead , $userCanWrite , $groupCanRead , $groupCanWrite , $add , $principals ) : void {
$logger = $this -> createMock ( \Psr\Log\LoggerInterface :: class );
$config = $this -> createMock ( IConfig :: class );
2024-09-19 12:54:43 -04:00
2017-03-02 05:45:07 -05:00
$l10n = $this -> createMock ( IL10N :: class );
2024-01-30 12:35:44 -05:00
$l10n -> expects ( $this -> any ())
2016-04-14 09:38:00 -04:00
-> method ( 't' )
2020-03-26 04:30:18 -04:00
-> willReturnCallback ( function ( $text , $parameters = []) {
2016-04-14 09:38:00 -04:00
return vsprintf ( $text , $parameters );
2020-03-25 17:21:27 -04:00
});
2016-04-14 09:38:00 -04:00
2017-10-05 06:32:46 -04:00
$this -> userManager -> expects ( $this -> any ())
-> method ( 'userExists' )
-> willReturn ( true );
2017-10-09 06:57:41 -04:00
$this -> groupManager -> expects ( $this -> any ())
2017-10-05 06:32:46 -04:00
-> method ( 'groupExists' )
-> willReturn ( true );
2024-01-30 12:35:44 -05:00
$this -> principal -> expects ( self :: atLeastOnce ())
-> method ( 'findByUri' )
-> willReturnOnConsecutiveCalls ( ... $principals );
2017-10-05 06:32:46 -04:00
2016-01-28 14:30:40 -05:00
$calendarId = $this -> createTestCalendar ();
2017-03-02 05:45:07 -05:00
$calendars = $this -> backend -> getCalendarsForUser ( self :: UNIT_TEST_USER );
$this -> assertCount ( 1 , $calendars );
2021-12-06 14:01:22 -05:00
$calendar = new Calendar ( $this -> backend , $calendars [ 0 ], $l10n , $config , $logger );
2016-01-28 14:30:40 -05:00
$this -> backend -> updateShares ( $calendar , $add , []);
2017-03-02 05:45:07 -05:00
$calendars = $this -> backend -> getCalendarsForUser ( self :: UNIT_TEST_USER1 );
$this -> assertCount ( 1 , $calendars );
2021-12-06 14:01:22 -05:00
$calendar = new Calendar ( $this -> backend , $calendars [ 0 ], $l10n , $config , $logger );
2016-01-28 14:30:40 -05:00
$acl = $calendar -> getACL ();
$this -> assertAcl ( self :: UNIT_TEST_USER , '{DAV:}read' , $acl );
$this -> assertAcl ( self :: UNIT_TEST_USER , '{DAV:}write' , $acl );
$this -> assertAccess ( $userCanRead , self :: UNIT_TEST_USER1 , '{DAV:}read' , $acl );
$this -> assertAccess ( $userCanWrite , self :: UNIT_TEST_USER1 , '{DAV:}write' , $acl );
$this -> assertEquals ( self :: UNIT_TEST_USER , $calendar -> getOwner ());
// test acls on the child
2017-03-02 05:45:07 -05:00
$uri = static :: getUniqueID ( 'calobj' );
2016-01-28 14:30:40 -05:00
$calData = <<< 'EOD'
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2016-01-28 14:30:40 -05:00
$this -> backend -> createCalendarObject ( $calendarId , $uri , $calData );
/** @var IACL $child */
$child = $calendar -> getChild ( $uri );
$acl = $child -> getACL ();
$this -> assertAcl ( self :: UNIT_TEST_USER , '{DAV:}read' , $acl );
$this -> assertAcl ( self :: UNIT_TEST_USER , '{DAV:}write' , $acl );
$this -> assertAccess ( $userCanRead , self :: UNIT_TEST_USER1 , '{DAV:}read' , $acl );
$this -> assertAccess ( $userCanWrite , self :: UNIT_TEST_USER1 , '{DAV:}write' , $acl );
2016-01-28 11:16:11 -05:00
2021-04-29 04:04:08 -04:00
// delete the calendar
$this -> dispatcher -> expects ( self :: once ())
-> method ( 'dispatchTyped' )
-> with ( self :: callback ( function ( $event ) {
return $event instanceof CalendarDeletedEvent ;
}));
2021-03-12 05:20:04 -05:00
$this -> backend -> deleteCalendar ( $calendars [ 0 ][ 'id' ], true );
2017-03-02 05:45:07 -05:00
$calendars = $this -> backend -> getCalendarsForUser ( self :: UNIT_TEST_USER );
2021-04-29 04:04:08 -04:00
self :: assertEmpty ( $calendars );
2016-01-28 11:16:11 -05:00
}
2023-01-20 02:38:43 -05:00
public function testCalendarObjectsOperations () : void {
2015-10-30 20:28:21 -04:00
$calendarId = $this -> createTestCalendar ();
// create a card
2017-03-02 05:45:07 -05:00
$uri = static :: getUniqueID ( 'calobj' );
2015-10-30 20:28:21 -04:00
$calData = <<< 'EOD'
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2015-10-30 20:28:21 -04:00
$this -> backend -> createCalendarObject ( $calendarId , $uri , $calData );
2022-05-18 05:10:36 -04:00
// get all the calendar objects
2015-10-30 20:28:21 -04:00
$calendarObjects = $this -> backend -> getCalendarObjects ( $calendarId );
2017-03-02 05:45:07 -05:00
$this -> assertCount ( 1 , $calendarObjects );
2015-10-30 20:28:21 -04:00
$this -> assertEquals ( $calendarId , $calendarObjects [ 0 ][ 'calendarid' ]);
2016-05-31 11:16:28 -04:00
$this -> assertArrayHasKey ( 'classification' , $calendarObjects [ 0 ]);
2015-10-30 20:28:21 -04:00
2022-05-18 05:10:36 -04:00
// get the calendar objects
2015-10-30 20:28:21 -04:00
$calendarObject = $this -> backend -> getCalendarObject ( $calendarId , $uri );
$this -> assertNotNull ( $calendarObject );
$this -> assertArrayHasKey ( 'id' , $calendarObject );
$this -> assertArrayHasKey ( 'uri' , $calendarObject );
$this -> assertArrayHasKey ( 'lastmodified' , $calendarObject );
$this -> assertArrayHasKey ( 'etag' , $calendarObject );
$this -> assertArrayHasKey ( 'size' , $calendarObject );
2016-05-31 11:16:28 -04:00
$this -> assertArrayHasKey ( 'classification' , $calendarObject );
2022-05-18 05:10:36 -04:00
$this -> assertArrayHasKey ( '{' . SharingPlugin :: NS_NEXTCLOUD . '}deleted-at' , $calendarObject );
2015-10-30 20:28:21 -04:00
$this -> assertEquals ( $calData , $calendarObject [ 'calendardata' ]);
// update the card
$calData = <<< 'EOD'
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
END : VEVENT
END : VCALENDAR
EOD ;
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2015-10-30 20:28:21 -04:00
$this -> backend -> updateCalendarObject ( $calendarId , $uri , $calData );
$calendarObject = $this -> backend -> getCalendarObject ( $calendarId , $uri );
$this -> assertEquals ( $calData , $calendarObject [ 'calendardata' ]);
// delete the card
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2015-10-30 20:28:21 -04:00
$this -> backend -> deleteCalendarObject ( $calendarId , $uri );
$calendarObjects = $this -> backend -> getCalendarObjects ( $calendarId );
2017-03-02 05:45:07 -05:00
$this -> assertCount ( 0 , $calendarObjects );
2015-10-30 20:28:21 -04:00
}
2020-07-23 07:38:49 -04:00
2023-01-20 02:38:43 -05:00
public function testMultipleCalendarObjectsWithSameUID () : void {
2019-11-27 09:27:18 -05:00
$this -> expectException ( \Sabre\DAV\Exception\BadRequest :: class );
$this -> expectExceptionMessage ( 'Calendar object with uid already exists in this calendar collection.' );
2017-11-01 17:00:53 -04:00
$calendarId = $this -> createTestCalendar ();
$calData = <<< 'EOD'
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8 - 1
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$uri0 = static :: getUniqueID ( 'event' );
$uri1 = static :: getUniqueID ( 'event' );
$this -> backend -> createCalendarObject ( $calendarId , $uri0 , $calData );
$this -> backend -> createCalendarObject ( $calendarId , $uri1 , $calData );
}
2023-01-20 02:38:43 -05:00
public function testMultiCalendarObjects () : void {
2015-10-30 20:28:21 -04:00
$calendarId = $this -> createTestCalendar ();
// create an event
2017-11-01 17:00:53 -04:00
$calData = [];
$calData [] = <<< 'EOD'
2015-10-30 20:28:21 -04:00
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
2017-11-01 17:00:53 -04:00
UID : 47 d15e3ec8 - 1
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$calData [] = <<< 'EOD'
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8 - 2
2015-10-30 20:28:21 -04:00
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
2017-11-01 17:00:53 -04:00
$calData [] = <<< 'EOD'
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8 - 3
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
2017-03-02 05:45:07 -05:00
$uri0 = static :: getUniqueID ( 'card' );
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2017-11-01 17:00:53 -04:00
$this -> backend -> createCalendarObject ( $calendarId , $uri0 , $calData [ 0 ]);
2017-03-02 05:45:07 -05:00
$uri1 = static :: getUniqueID ( 'card' );
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2017-11-01 17:00:53 -04:00
$this -> backend -> createCalendarObject ( $calendarId , $uri1 , $calData [ 1 ]);
2017-03-02 05:45:07 -05:00
$uri2 = static :: getUniqueID ( 'card' );
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2017-11-01 17:00:53 -04:00
$this -> backend -> createCalendarObject ( $calendarId , $uri2 , $calData [ 2 ]);
2015-10-30 20:28:21 -04:00
// get all the cards
$calendarObjects = $this -> backend -> getCalendarObjects ( $calendarId );
2017-03-02 05:45:07 -05:00
$this -> assertCount ( 3 , $calendarObjects );
2015-10-30 20:28:21 -04:00
// get the cards
$calendarObjects = $this -> backend -> getMultipleCalendarObjects ( $calendarId , [ $uri1 , $uri2 ]);
2017-03-02 05:45:07 -05:00
$this -> assertCount ( 2 , $calendarObjects );
2020-04-10 08:19:56 -04:00
foreach ( $calendarObjects as $card ) {
2015-10-30 20:28:21 -04:00
$this -> assertArrayHasKey ( 'id' , $card );
$this -> assertArrayHasKey ( 'uri' , $card );
$this -> assertArrayHasKey ( 'lastmodified' , $card );
$this -> assertArrayHasKey ( 'etag' , $card );
$this -> assertArrayHasKey ( 'size' , $card );
2016-05-31 11:16:28 -04:00
$this -> assertArrayHasKey ( 'classification' , $card );
2015-10-30 20:28:21 -04:00
}
2020-04-09 07:53:40 -04:00
usort ( $calendarObjects , function ( $a , $b ) {
2017-11-01 17:00:53 -04:00
return $a [ 'id' ] - $b [ 'id' ];
});
$this -> assertEquals ( $calData [ 1 ], $calendarObjects [ 0 ][ 'calendardata' ]);
$this -> assertEquals ( $calData [ 2 ], $calendarObjects [ 1 ][ 'calendardata' ]);
2015-10-30 20:28:21 -04:00
// delete the card
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2015-10-30 20:28:21 -04:00
$this -> backend -> deleteCalendarObject ( $calendarId , $uri0 );
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2015-10-30 20:28:21 -04:00
$this -> backend -> deleteCalendarObject ( $calendarId , $uri1 );
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2015-10-30 20:28:21 -04:00
$this -> backend -> deleteCalendarObject ( $calendarId , $uri2 );
$calendarObjects = $this -> backend -> getCalendarObjects ( $calendarId );
2017-03-02 05:45:07 -05:00
$this -> assertCount ( 0 , $calendarObjects );
2015-10-30 20:28:21 -04:00
}
2026-01-07 08:21:48 -05:00
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'providesCalendarQueryParameters')]
2023-01-20 02:38:43 -05:00
public function testCalendarQuery ( $expectedEventsInResult , $propFilters , $compFilter ) : void {
2015-10-30 20:28:21 -04:00
$calendarId = $this -> createTestCalendar ();
$events = [];
$events [ 0 ] = $this -> createEvent ( $calendarId , '20130912T130000Z' , '20130912T140000Z' );
$events [ 1 ] = $this -> createEvent ( $calendarId , '20130912T150000Z' , '20130912T170000Z' );
$events [ 2 ] = $this -> createEvent ( $calendarId , '20130912T173000Z' , '20130912T220000Z' );
2023-01-23 12:23:52 -05:00
if ( PHP_INT_SIZE > 8 ) {
$events [ 3 ] = $this -> createEvent ( $calendarId , '21130912T130000Z' , '22130912T130000Z' );
} else {
/* On 32bit we do not support events after 2038 */
$events [ 3 ] = $this -> createEvent ( $calendarId , '20370912T130000Z' , '20370912T130000Z' );
}
2015-10-30 20:28:21 -04:00
$result = $this -> backend -> calendarQuery ( $calendarId , [
'name' => '' ,
'prop-filters' => $propFilters ,
'comp-filters' => $compFilter
]);
2020-04-09 07:53:40 -04:00
$expectedEventsInResult = array_map ( function ( $index ) use ( $events ) {
2015-10-30 20:28:21 -04:00
return $events [ $index ];
}, $expectedEventsInResult );
2020-07-23 07:38:49 -04:00
$this -> assertEqualsCanonicalizing ( $expectedEventsInResult , $result );
2015-10-30 20:28:21 -04:00
}
2023-01-20 02:38:43 -05:00
public function testGetCalendarObjectByUID () : void {
2015-10-30 20:28:21 -04:00
$calendarId = $this -> createTestCalendar ();
2017-11-01 17:00:53 -04:00
$uri = static :: getUniqueID ( 'calobj' );
$calData = <<< 'EOD'
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> createCalendarObject ( $calendarId , $uri , $calData );
2015-10-30 20:28:21 -04:00
$co = $this -> backend -> getCalendarObjectByUID ( self :: UNIT_TEST_USER , '47d15e3ec8' );
$this -> assertNotNull ( $co );
}
2025-05-24 17:00:05 -04:00
public static function providesCalendarQueryParameters () : array {
2015-10-30 20:28:21 -04:00
return [
2016-04-25 08:32:41 -04:00
'all' => [[ 0 , 1 , 2 , 3 ], [], []],
2015-10-30 20:28:21 -04:00
'only-todos' => [[], [ 'name' => 'VTODO' ], []],
2016-04-25 08:32:41 -04:00
'only-events' => [[ 0 , 1 , 2 , 3 ], [], [[ 'name' => 'VEVENT' , 'is-not-defined' => false , 'comp-filters' => [], 'time-range' => [ 'start' => null , 'end' => null ], 'prop-filters' => []]],],
'start' => [[ 1 , 2 , 3 ], [], [[ 'name' => 'VEVENT' , 'is-not-defined' => false , 'comp-filters' => [], 'time-range' => [ 'start' => new DateTime ( '2013-09-12 14:00:00' , new DateTimeZone ( 'UTC' )), 'end' => null ], 'prop-filters' => []]],],
2015-10-30 20:28:21 -04:00
'end' => [[ 0 ], [], [[ 'name' => 'VEVENT' , 'is-not-defined' => false , 'comp-filters' => [], 'time-range' => [ 'start' => null , 'end' => new DateTime ( '2013-09-12 14:00:00' , new DateTimeZone ( 'UTC' ))], 'prop-filters' => []]],],
2023-01-23 12:23:52 -05:00
'future' => [[ 3 ], [], [[ 'name' => 'VEVENT' , 'is-not-defined' => false , 'comp-filters' => [], 'time-range' => [ 'start' => new DateTime ( '2036-09-12 14:00:00' , new DateTimeZone ( 'UTC' )), 'end' => null ], 'prop-filters' => []]],],
2015-10-30 20:28:21 -04:00
];
}
2024-07-18 20:25:41 -04:00
public function testCalendarSynchronization () : void {
2015-10-30 20:28:21 -04:00
2024-07-18 20:25:41 -04:00
// construct calendar for testing
$calendarId = $this -> createTestCalendar ();
2015-10-30 20:28:21 -04:00
2024-07-18 20:25:41 -04:00
/** test fresh sync state with NO events in calendar */
// construct test state
$stateTest = [ 'syncToken' => 1 , 'added' => [], 'modified' => [], 'deleted' => []];
// retrieve live state
$stateLive = $this -> backend -> getChangesForCalendar ( $calendarId , '' , 1 );
// test live state
$this -> assertEquals ( $stateTest , $stateLive , 'Failed test fresh sync state with NO events in calendar' );
/** test delta sync state with NO events in calendar */
// construct test state
$stateTest = [ 'syncToken' => 1 , 'added' => [], 'modified' => [], 'deleted' => []];
// retrieve live state
$stateLive = $this -> backend -> getChangesForCalendar ( $calendarId , '2' , 1 );
// test live state
$this -> assertEquals ( $stateTest , $stateLive , 'Failed test delta sync state with NO events in calendar' );
/** add events to calendar */
$event1 = $this -> createEvent ( $calendarId , '20240701T130000Z' , '20240701T140000Z' );
$event2 = $this -> createEvent ( $calendarId , '20240701T140000Z' , '20240701T150000Z' );
$event3 = $this -> createEvent ( $calendarId , '20240701T150000Z' , '20240701T160000Z' );
/** test fresh sync state with events in calendar */
// construct expected state
$stateTest = [ 'syncToken' => 4 , 'added' => [ $event1 , $event2 , $event3 ], 'modified' => [], 'deleted' => []];
sort ( $stateTest [ 'added' ]);
// retrieve live state
$stateLive = $this -> backend -> getChangesForCalendar ( $calendarId , '' , 1 );
// sort live state results
sort ( $stateLive [ 'added' ]);
sort ( $stateLive [ 'modified' ]);
sort ( $stateLive [ 'deleted' ]);
// test live state
$this -> assertEquals ( $stateTest , $stateLive , 'Failed test fresh sync state with events in calendar' );
/** test delta sync state with events in calendar */
// construct expected state
$stateTest = [ 'syncToken' => 4 , 'added' => [ $event2 , $event3 ], 'modified' => [], 'deleted' => []];
sort ( $stateTest [ 'added' ]);
// retrieve live state
$stateLive = $this -> backend -> getChangesForCalendar ( $calendarId , '2' , 1 );
// sort live state results
sort ( $stateLive [ 'added' ]);
sort ( $stateLive [ 'modified' ]);
sort ( $stateLive [ 'deleted' ]);
// test live state
$this -> assertEquals ( $stateTest , $stateLive , 'Failed test delta sync state with events in calendar' );
2025-04-07 08:59:20 -04:00
2024-07-18 20:25:41 -04:00
/** modify/delete events in calendar */
$this -> deleteEvent ( $calendarId , $event1 );
$this -> modifyEvent ( $calendarId , $event2 , '20250701T140000Z' , '20250701T150000Z' );
/** test fresh sync state with modified/deleted events in calendar */
// construct expected state
$stateTest = [ 'syncToken' => 6 , 'added' => [ $event2 , $event3 ], 'modified' => [], 'deleted' => []];
sort ( $stateTest [ 'added' ]);
// retrieve live state
$stateLive = $this -> backend -> getChangesForCalendar ( $calendarId , '' , 1 );
// sort live state results
sort ( $stateLive [ 'added' ]);
sort ( $stateLive [ 'modified' ]);
sort ( $stateLive [ 'deleted' ]);
// test live state
$this -> assertEquals ( $stateTest , $stateLive , 'Failed test fresh sync state with modified/deleted events in calendar' );
/** test delta sync state with modified/deleted events in calendar */
// construct expected state
$stateTest = [ 'syncToken' => 6 , 'added' => [ $event3 ], 'modified' => [ $event2 ], 'deleted' => [ $event1 ]];
// retrieve live state
$stateLive = $this -> backend -> getChangesForCalendar ( $calendarId , '3' , 1 );
// test live state
$this -> assertEquals ( $stateTest , $stateLive , 'Failed test delta sync state with modified/deleted events in calendar' );
/** test delta sync state with modified/deleted events in calendar and invalid token */
// construct expected state
$stateTest = [ 'syncToken' => 6 , 'added' => [], 'modified' => [], 'deleted' => []];
// retrieve live state
$stateLive = $this -> backend -> getChangesForCalendar ( $calendarId , '6' , 1 );
// test live state
$this -> assertEquals ( $stateTest , $stateLive , 'Failed test delta sync state with modified/deleted events in calendar and invalid token' );
2015-10-30 20:28:21 -04:00
}
2023-01-20 02:38:43 -05:00
public function testPublications () : void {
2021-06-04 04:57:41 -04:00
$this -> dispatcher -> expects ( self :: atLeastOnce ())
-> method ( 'dispatchTyped' );
2016-11-03 07:28:12 -04:00
2016-07-20 08:08:45 -04:00
$this -> backend -> createCalendar ( self :: UNIT_TEST_USER , 'Example' , []);
$calendarInfo = $this -> backend -> getCalendarsForUser ( self :: UNIT_TEST_USER )[ 0 ];
2020-08-11 15:32:18 -04:00
/** @var IL10N|\PHPUnit\Framework\MockObject\MockObject $l10n */
2017-03-02 05:45:07 -05:00
$l10n = $this -> createMock ( IL10N :: class );
2017-10-20 09:09:52 -04:00
$config = $this -> createMock ( IConfig :: class );
2021-12-06 14:01:22 -05:00
$logger = $this -> createMock ( \Psr\Log\LoggerInterface :: class );
$calendar = new Calendar ( $this -> backend , $calendarInfo , $l10n , $config , $logger );
2016-08-14 13:08:01 -04:00
$calendar -> setPublishStatus ( true );
2016-09-15 11:09:24 -04:00
$this -> assertNotEquals ( false , $calendar -> getPublishStatus ());
2016-07-20 08:08:45 -04:00
$publicCalendars = $this -> backend -> getPublicCalendars ();
2017-03-02 05:45:07 -05:00
$this -> assertCount ( 1 , $publicCalendars );
2016-07-20 08:08:45 -04:00
$this -> assertEquals ( true , $publicCalendars [ 0 ][ '{http://owncloud.org/ns}public' ]);
2017-04-19 10:18:44 -04:00
$this -> assertEquals ( 'User\'s displayname' , $publicCalendars [ 0 ][ '{http://nextcloud.com/ns}owner-displayname' ]);
2016-07-20 08:08:45 -04:00
2016-09-03 04:52:05 -04:00
$publicCalendarURI = $publicCalendars [ 0 ][ 'uri' ];
2016-08-14 13:08:01 -04:00
$publicCalendar = $this -> backend -> getPublicCalendar ( $publicCalendarURI );
$this -> assertEquals ( true , $publicCalendar [ '{http://owncloud.org/ns}public' ]);
$calendar -> setPublishStatus ( false );
$this -> assertEquals ( false , $calendar -> getPublishStatus ());
2018-01-24 12:10:16 -05:00
$this -> expectException ( NotFound :: class );
2016-10-13 05:04:22 -04:00
$this -> backend -> getPublicCalendar ( $publicCalendarURI );
2016-07-20 08:08:45 -04:00
}
2023-01-20 02:38:43 -05:00
public function testSubscriptions () : void {
2015-10-30 20:28:21 -04:00
$id = $this -> backend -> createSubscription ( self :: UNIT_TEST_USER , 'Subscription' , [
2016-07-01 07:42:35 -04:00
'{http://calendarserver.org/ns/}source' => new Href ( 'test-source' ),
'{http://apple.com/ns/ical/}calendar-color' => '#1C4587' ,
'{http://calendarserver.org/ns/}subscribed-strip-todos' => ''
2015-10-30 20:28:21 -04:00
]);
$subscriptions = $this -> backend -> getSubscriptionsForUser ( self :: UNIT_TEST_USER );
2017-03-02 05:45:07 -05:00
$this -> assertCount ( 1 , $subscriptions );
2016-07-01 07:42:35 -04:00
$this -> assertEquals ( '#1C4587' , $subscriptions [ 0 ][ '{http://apple.com/ns/ical/}calendar-color' ]);
$this -> assertEquals ( true , $subscriptions [ 0 ][ '{http://calendarserver.org/ns/}subscribed-strip-todos' ]);
2015-10-30 20:28:21 -04:00
$this -> assertEquals ( $id , $subscriptions [ 0 ][ 'id' ]);
$patch = new PropPatch ([
2020-04-09 03:22:29 -04:00
'{DAV:}displayname' => 'Unit test' ,
'{http://apple.com/ns/ical/}calendar-color' => '#ac0606' ,
2015-10-30 20:28:21 -04:00
]);
$this -> backend -> updateSubscription ( $id , $patch );
$patch -> commit ();
$subscriptions = $this -> backend -> getSubscriptionsForUser ( self :: UNIT_TEST_USER );
2017-03-02 05:45:07 -05:00
$this -> assertCount ( 1 , $subscriptions );
2015-10-30 20:28:21 -04:00
$this -> assertEquals ( $id , $subscriptions [ 0 ][ 'id' ]);
$this -> assertEquals ( 'Unit test' , $subscriptions [ 0 ][ '{DAV:}displayname' ]);
2016-07-01 07:42:35 -04:00
$this -> assertEquals ( '#ac0606' , $subscriptions [ 0 ][ '{http://apple.com/ns/ical/}calendar-color' ]);
2015-10-30 20:28:21 -04:00
$this -> backend -> deleteSubscription ( $id );
$subscriptions = $this -> backend -> getSubscriptionsForUser ( self :: UNIT_TEST_USER );
2017-03-02 05:45:07 -05:00
$this -> assertCount ( 0 , $subscriptions );
2015-10-30 20:28:21 -04:00
}
2025-05-24 17:00:05 -04:00
public static function providesSchedulingData () : array {
2020-10-05 09:12:57 -04:00
$data = <<< EOS
2018-02-21 04:18:38 -05:00
BEGIN : VCALENDAR
VERSION : 2.0
PRODID :-// Sabre //Sabre VObject 3.5.0//EN
CALSCALE : GREGORIAN
METHOD : REQUEST
BEGIN : VTIMEZONE
TZID : Europe / Warsaw
BEGIN : DAYLIGHT
TZOFFSETFROM :+ 0100
TZOFFSETTO :+ 0200
TZNAME : CEST
DTSTART : 19700329 T020000
RRULE : FREQ = YEARLY ; BYDAY =- 1 SU ; BYMONTH = 3
END : DAYLIGHT
BEGIN : STANDARD
TZOFFSETFROM :+ 0200
TZOFFSETTO :+ 0100
TZNAME : CET
DTSTART : 19701025 T030000
RRULE : FREQ = YEARLY ; BYDAY =- 1 SU ; BYMONTH = 10
END : STANDARD
END : VTIMEZONE
BEGIN : VEVENT
CREATED : 20170320 T131655Z
LAST - MODIFIED : 20170320 T135019Z
DTSTAMP : 20170320 T135019Z
UID : 7e908 a6d - 4 c4e - 48 d7 - bd62 - 59 ab80fbf1a3
SUMMARY : TEST Z pg_escape_bytea
ORGANIZER ; RSVP = TRUE ; PARTSTAT = ACCEPTED ; ROLE = CHAIR : mailto : k . klimczak @ gromar . e
u
ATTENDEE ; RSVP = TRUE ; CN = Zuzanna Leszek ; PARTSTAT = NEEDS - ACTION ; ROLE = REQ - PARTICI
PANT : mailto : z . leszek @ gromar . eu
ATTENDEE ; RSVP = TRUE ; CN = Marcin Pisarski ; PARTSTAT = NEEDS - ACTION ; ROLE = REQ - PARTIC
IPANT : mailto : m . pisarski @ gromar . eu
ATTENDEE ; RSVP = TRUE ; PARTSTAT = NEEDS - ACTION ; ROLE = REQ - PARTICIPANT : mailto : klimcz
ak . k @ gmail . com
ATTENDEE ; RSVP = TRUE ; PARTSTAT = NEEDS - ACTION ; ROLE = REQ - PARTICIPANT : mailto : k_klim
czak @ tlen . pl
DTSTART ; TZID = Europe / Warsaw : 20170325 T150000
DTEND ; TZID = Europe / Warsaw : 20170325 T160000
TRANSP : OPAQUE
DESCRIPTION : Magiczna treść uzyskana za pomocą magicznego proszku . \n\nę
2020-07-27 10:14:15 -04:00
żźćńłóÓŻŹĆŁĘ€śśśŚŚ\n \ , \ ,)))))))) \ ; \ , \n
2018-02-21 04:18:38 -05:00
__ )))))))))))))) \ , \n \\ |/ - \\ ((((( '' '' (((((((( . \n -*-==///
2020-07-27 10:14:15 -04:00
///(('' . `))))))\,\n /|\\ ))| o \;-. '(((((
\ ,( \ , \n ( ` | / ) \ ;)))) '
2018-02-21 04:18:38 -05:00
\ , _ )) ^ \ ;( ~ \n | | | \ ,))(((( _ _____ -
-----~~~-. % \ , \ ;( \ ;( > '\;' ~ \n o_ ) \ ; \ ; )))((( ` ~---
~ `:: \\ %%~~)(v\;(` ( '~\n \; ' '' ' `` ``
2020-07-27 10:14:15 -04:00
`: ` :::| \\\ , __\ , %% ) \ ; ` ' \ ; ~ \n | _
) / `:|` ---- ' `-' \n ______ / \\ /~ |
2018-02-21 04:18:38 -05:00
/ / \n /~ \ ; \ ; . ____ / \ ; \ ; ' / ___ -- \
2020-07-27 10:14:15 -04:00
, - ( ` \ ; \ ; \ ; / \n / // _\;______\;'------~~~~~ /\;\;/\\ /\n
// | | / \; \\\;\;\,\\\n (<_ | \;
/ '\,/-----' _ > \n \\_ | || _
//~\;~~~~~~~~~\n `\\_| (\,~~ -Tua Xiong\n
\\ ~ \\\n
2018-02-21 04:18:38 -05:00
~~ \n\n
SEQUENCE : 1
X - MOZ - GENERATION : 1
END : VEVENT
END : VCALENDAR
EOS ;
return [
'no data' => [ '' ],
'failing on postgres' => [ $data ]
];
}
/**
* @ param $objectData
*/
2026-01-07 08:21:48 -05:00
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'providesSchedulingData')]
2023-01-20 02:38:43 -05:00
public function testScheduling ( $objectData ) : void {
2018-02-21 04:18:38 -05:00
$this -> backend -> createSchedulingObject ( self :: UNIT_TEST_USER , 'Sample Schedule' , $objectData );
2015-11-16 09:49:46 -05:00
$sos = $this -> backend -> getSchedulingObjects ( self :: UNIT_TEST_USER );
2017-03-02 05:45:07 -05:00
$this -> assertCount ( 1 , $sos );
2015-11-16 09:49:46 -05:00
$so = $this -> backend -> getSchedulingObject ( self :: UNIT_TEST_USER , 'Sample Schedule' );
$this -> assertNotNull ( $so );
$this -> backend -> deleteSchedulingObject ( self :: UNIT_TEST_USER , 'Sample Schedule' );
$sos = $this -> backend -> getSchedulingObjects ( self :: UNIT_TEST_USER );
2017-03-02 05:45:07 -05:00
$this -> assertCount ( 0 , $sos );
2015-11-16 09:49:46 -05:00
}
2016-01-28 14:30:40 -05:00
2026-01-07 08:21:48 -05:00
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'providesCalDataForGetDenormalizedData')]
2023-01-20 02:38:43 -05:00
public function testGetDenormalizedData ( $expected , $key , $calData ) : void {
2023-01-30 05:31:49 -05:00
try {
$actual = $this -> backend -> getDenormalizedData ( $calData );
$this -> assertEquals ( $expected , $actual [ $key ]);
2023-08-14 09:06:52 -04:00
} catch ( \Throwable $e ) {
2023-01-30 05:31:49 -05:00
if (( $e -> getMessage () === 'Epoch doesn\'t fit in a PHP integer' ) && ( PHP_INT_SIZE < 8 )) {
$this -> markTestSkipped ( 'This fail on 32bits because of PHP limitations in DateTime' );
}
throw $e ;
}
2016-03-09 12:13:34 -05:00
}
2025-05-24 17:00:05 -04:00
public static function providesCalDataForGetDenormalizedData () : array {
2016-03-09 12:13:34 -05:00
return [
2016-10-13 06:15:10 -04:00
'first occurrence before unix epoch starts' => [ 0 , 'firstOccurence' , " BEGIN:VCALENDAR \r \n VERSION:2.0 \r \n PRODID:-//Sabre//Sabre VObject 4.1.1//EN \r \n CALSCALE:GREGORIAN \r \n BEGIN:VEVENT \r \n UID:413F269B-B51B-46B1-AFB6-40055C53A4DC \r \n DTSTAMP:20160309T095056Z \r \n DTSTART;VALUE=DATE:16040222 \r \n DTEND;VALUE=DATE:16040223 \r \n RRULE:FREQ=YEARLY \r \n SUMMARY:SUMMARY \r \n TRANSP:TRANSPARENT \r \n END:VEVENT \r \n END:VCALENDAR \r \n " ],
'no first occurrence because yearly' => [ null , 'firstOccurence' , " BEGIN:VCALENDAR \r \n VERSION:2.0 \r \n PRODID:-//Sabre//Sabre VObject 4.1.1//EN \r \n CALSCALE:GREGORIAN \r \n BEGIN:VEVENT \r \n UID:413F269B-B51B-46B1-AFB6-40055C53A4DC \r \n DTSTAMP:20160309T095056Z \r \n RRULE:FREQ=YEARLY \r \n SUMMARY:SUMMARY \r \n TRANSP:TRANSPARENT \r \n END:VEVENT \r \n END:VCALENDAR \r \n " ],
2022-04-01 11:31:37 -04:00
2020-09-27 17:05:15 -04:00
'last occurrence is max when only last VEVENT in group is weekly' => [( new DateTime ( CalDavBackend :: MAX_DATE )) -> getTimestamp (), 'lastOccurence' , " BEGIN:VCALENDAR \r \n VERSION:2.0 \r \n PRODID:-//Sabre//Sabre VObject 4.3.0//EN \r \n CALSCALE:GREGORIAN \r \n BEGIN:VEVENT \r \n DTSTART;TZID=America/Los_Angeles:20200812T103000 \r \n DTEND;TZID=America/Los_Angeles:20200812T110000 \r \n DTSTAMP:20200927T180638Z \r \n UID:asdfasdfasdf@google.com \r \n RECURRENCE-ID;TZID=America/Los_Angeles:20200811T123000 \r \n CREATED:20200626T181848Z \r \n LAST-MODIFIED:20200922T192707Z \r \n SUMMARY:Weekly 1:1 \r \n TRANSP:OPAQUE \r \n END:VEVENT \r \n BEGIN:VEVENT \r \n DTSTART;TZID=America/Los_Angeles:20200728T123000 \r \n DTEND;TZID=America/Los_Angeles:20200728T130000 \r \n EXDATE;TZID=America/Los_Angeles:20200818T123000 \r \n RRULE:FREQ=WEEKLY;BYDAY=TU \r \n DTSTAMP:20200927T180638Z \r \n UID:asdfasdfasdf@google.com \r \n CREATED:20200626T181848Z \r \n DESCRIPTION:Setting up recurring time on our calendars \r \n LAST-MODIFIED:20200922T192707Z \r \n SUMMARY:Weekly 1:1 \r \n TRANSP:OPAQUE \r \n END:VEVENT \r \n END:VCALENDAR \r \n " ],
2022-04-01 11:31:37 -04:00
'last occurrence before unix epoch starts' => [ 0 , 'lastOccurence' , " BEGIN:VCALENDAR \r \n VERSION:2.0 \r \n PRODID:-//Sabre//Sabre VObject 4.3.0//EN \r \n CALSCALE:GREGORIAN \r \n BEGIN:VEVENT \r \n DTSTART;VALUE=DATE:19110324 \r \n DTEND;VALUE=DATE:19110325 \r \n DTSTAMP:20200927T180638Z \r \n UID:asdfasdfasdf@google.com \r \n CREATED:20200626T181848Z \r \n DESCRIPTION:Very old event \r \n LAST-MODIFIED:20200922T192707Z \r \n SUMMARY:Some old event \r \n TRANSP:OPAQUE \r \n END:VEVENT \r \n END:VCALENDAR \r \n " ],
2024-08-23 09:10:27 -04:00
'first occurrence is found when not first VEVENT in group' => [( new DateTime ( '2020-09-01T110000' , new DateTimeZone ( 'America/Los_Angeles' ))) -> getTimestamp (), 'firstOccurence' , " BEGIN:VCALENDAR \r \n VERSION:2.0 \r \n PRODID:-//Sabre//Sabre VObject 4.3.0//EN \r \n CALSCALE:GREGORIAN \r \n BEGIN:VEVENT \r \n DTSTART;TZID=America/Los_Angeles:20201013T110000 \r \n DTEND;TZID=America/Los_Angeles:20201013T120000 \r \n DTSTAMP:20200927T180638Z \r \n UID:asdf0000@google.com \r \n RECURRENCE-ID;TZID=America/Los_Angeles:20201013T110000 \r \n CREATED:20160330T034726Z \r \n LAST-MODIFIED:20200925T042014Z \r \n STATUS:CONFIRMED \r \n TRANSP:OPAQUE \r \n END:VEVENT \r \n BEGIN:VEVENT \r \n DTSTART;TZID=America/Los_Angeles:20200901T110000 \r \n DTEND;TZID=America/Los_Angeles:20200901T120000 \r \n RRULE:FREQ=WEEKLY;BYDAY=TU \r \n EXDATE;TZID=America/Los_Angeles:20200922T110000 \r \n EXDATE;TZID=America/Los_Angeles:20200915T110000 \r \n EXDATE;TZID=America/Los_Angeles:20200908T110000 \r \n DTSTAMP:20200927T180638Z \r \n UID:asdf0000@google.com \r \n CREATED:20160330T034726Z \r \n LAST-MODIFIED:20200915T162810Z \r \n STATUS:CONFIRMED \r \n TRANSP:OPAQUE \r \n END:VEVENT \r \n END:VCALENDAR \r \n " ],
2022-04-01 11:31:37 -04:00
2016-04-19 05:33:37 -04:00
'CLASS:PRIVATE' => [ CalDavBackend :: CLASSIFICATION_PRIVATE , 'classification' , " BEGIN:VCALENDAR \r \n VERSION:2.0 \r \n PRODID:-//dmfs.org//mimedir.icalendar//EN \r \n BEGIN:VTIMEZONE \r \n TZID:Europe/Berlin \r \n X-LIC-LOCATION:Europe/Berlin \r \n BEGIN:DAYLIGHT \r \n TZOFFSETFROM:+0100 \r \n TZOFFSETTO:+0200 \r \n TZNAME:CEST \r \n DTSTART:19700329T020000 \r \n RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU \r \n END:DAYLIGHT \r \n BEGIN:STANDARD \r \n TZOFFSETFROM:+0200 \r \n TZOFFSETTO:+0100 \r \n TZNAME:CET \r \n DTSTART:19701025T030000 \r \n RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU \r \n END:STANDARD \r \n END:VTIMEZONE \r \n BEGIN:VEVENT \r \n DTSTART;TZID=Europe/Berlin:20160419T130000 \r \n SUMMARY:Test \r \n CLASS:PRIVATE \r \n TRANSP:OPAQUE \r \n STATUS:CONFIRMED \r \n DTEND;TZID=Europe/Berlin:20160419T140000 \r \n LAST-MODIFIED:20160419T074202Z \r \n DTSTAMP:20160419T074202Z \r \n CREATED:20160419T074202Z \r \n UID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310 \r \n END:VEVENT \r \n END:VCALENDAR " ],
2022-04-01 11:31:37 -04:00
2016-04-19 05:33:37 -04:00
'CLASS:PUBLIC' => [ CalDavBackend :: CLASSIFICATION_PUBLIC , 'classification' , " BEGIN:VCALENDAR \r \n VERSION:2.0 \r \n PRODID:-//dmfs.org//mimedir.icalendar//EN \r \n BEGIN:VTIMEZONE \r \n TZID:Europe/Berlin \r \n X-LIC-LOCATION:Europe/Berlin \r \n BEGIN:DAYLIGHT \r \n TZOFFSETFROM:+0100 \r \n TZOFFSETTO:+0200 \r \n TZNAME:CEST \r \n DTSTART:19700329T020000 \r \n RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU \r \n END:DAYLIGHT \r \n BEGIN:STANDARD \r \n TZOFFSETFROM:+0200 \r \n TZOFFSETTO:+0100 \r \n TZNAME:CET \r \n DTSTART:19701025T030000 \r \n RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU \r \n END:STANDARD \r \n END:VTIMEZONE \r \n BEGIN:VEVENT \r \n DTSTART;TZID=Europe/Berlin:20160419T130000 \r \n SUMMARY:Test \r \n CLASS:PUBLIC \r \n TRANSP:OPAQUE \r \n STATUS:CONFIRMED \r \n DTEND;TZID=Europe/Berlin:20160419T140000 \r \n LAST-MODIFIED:20160419T074202Z \r \n DTSTAMP:20160419T074202Z \r \n CREATED:20160419T074202Z \r \n UID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310 \r \n END:VEVENT \r \n END:VCALENDAR " ],
2022-04-01 11:31:37 -04:00
2016-04-19 05:33:37 -04:00
'CLASS:CONFIDENTIAL' => [ CalDavBackend :: CLASSIFICATION_CONFIDENTIAL , 'classification' , " BEGIN:VCALENDAR \r \n VERSION:2.0 \r \n PRODID:-//dmfs.org//mimedir.icalendar//EN \r \n BEGIN:VTIMEZONE \r \n TZID:Europe/Berlin \r \n X-LIC-LOCATION:Europe/Berlin \r \n BEGIN:DAYLIGHT \r \n TZOFFSETFROM:+0100 \r \n TZOFFSETTO:+0200 \r \n TZNAME:CEST \r \n DTSTART:19700329T020000 \r \n RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU \r \n END:DAYLIGHT \r \n BEGIN:STANDARD \r \n TZOFFSETFROM:+0200 \r \n TZOFFSETTO:+0100 \r \n TZNAME:CET \r \n DTSTART:19701025T030000 \r \n RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU \r \n END:STANDARD \r \n END:VTIMEZONE \r \n BEGIN:VEVENT \r \n DTSTART;TZID=Europe/Berlin:20160419T130000 \r \n SUMMARY:Test \r \n CLASS:CONFIDENTIAL \r \n TRANSP:OPAQUE \r \n STATUS:CONFIRMED \r \n DTEND;TZID=Europe/Berlin:20160419T140000 \r \n LAST-MODIFIED:20160419T074202Z \r \n DTSTAMP:20160419T074202Z \r \n CREATED:20160419T074202Z \r \n UID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310 \r \n END:VEVENT \r \n END:VCALENDAR " ],
2022-04-01 11:31:37 -04:00
2016-04-19 05:33:37 -04:00
'no class set -> public' => [ CalDavBackend :: CLASSIFICATION_PUBLIC , 'classification' , " BEGIN:VCALENDAR \r \n VERSION:2.0 \r \n PRODID:-//dmfs.org//mimedir.icalendar//EN \r \n BEGIN:VTIMEZONE \r \n TZID:Europe/Berlin \r \n X-LIC-LOCATION:Europe/Berlin \r \n BEGIN:DAYLIGHT \r \n TZOFFSETFROM:+0100 \r \n TZOFFSETTO:+0200 \r \n TZNAME:CEST \r \n DTSTART:19700329T020000 \r \n RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU \r \n END:DAYLIGHT \r \n BEGIN:STANDARD \r \n TZOFFSETFROM:+0200 \r \n TZOFFSETTO:+0100 \r \n TZNAME:CET \r \n DTSTART:19701025T030000 \r \n RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU \r \n END:STANDARD \r \n END:VTIMEZONE \r \n BEGIN:VEVENT \r \n DTSTART;TZID=Europe/Berlin:20160419T130000 \r \n SUMMARY:Test \r \n TRANSP:OPAQUE \r \n DTEND;TZID=Europe/Berlin:20160419T140000 \r \n LAST-MODIFIED:20160419T074202Z \r \n DTSTAMP:20160419T074202Z \r \n CREATED:20160419T074202Z \r \n UID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310 \r \n END:VEVENT \r \n END:VCALENDAR " ],
2022-04-01 11:31:37 -04:00
2016-04-19 05:33:37 -04:00
'unknown class -> private' => [ CalDavBackend :: CLASSIFICATION_PRIVATE , 'classification' , " BEGIN:VCALENDAR \r \n VERSION:2.0 \r \n PRODID:-//dmfs.org//mimedir.icalendar//EN \r \n BEGIN:VTIMEZONE \r \n TZID:Europe/Berlin \r \n X-LIC-LOCATION:Europe/Berlin \r \n BEGIN:DAYLIGHT \r \n TZOFFSETFROM:+0100 \r \n TZOFFSETTO:+0200 \r \n TZNAME:CEST \r \n DTSTART:19700329T020000 \r \n RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU \r \n END:DAYLIGHT \r \n BEGIN:STANDARD \r \n TZOFFSETFROM:+0200 \r \n TZOFFSETTO:+0100 \r \n TZNAME:CET \r \n DTSTART:19701025T030000 \r \n RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU \r \n END:STANDARD \r \n END:VTIMEZONE \r \n BEGIN:VEVENT \r \n DTSTART;TZID=Europe/Berlin:20160419T130000 \r \n SUMMARY:Test \r \n CLASS:VERTRAULICH \r \n TRANSP:OPAQUE \r \n STATUS:CONFIRMED \r \n DTEND;TZID=Europe/Berlin:20160419T140000 \r \n LAST-MODIFIED:20160419T074202Z \r \n DTSTAMP:20160419T074202Z \r \n CREATED:20160419T074202Z \r \n UID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310 \r \n END:VEVENT \r \n END:VCALENDAR " ],
2016-03-09 12:13:34 -05:00
];
}
2017-04-25 13:26:47 -04:00
2023-01-20 02:38:43 -05:00
public function testCalendarSearch () : void {
2017-04-25 13:26:47 -04:00
$calendarId = $this -> createTestCalendar ();
$uri = static :: getUniqueID ( 'calobj' );
$calData = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> createCalendarObject ( $calendarId , $uri , $calData );
$search1 = $this -> backend -> calendarSearch ( self :: UNIT_TEST_USER , [
'comps' => [
'VEVENT' ,
'VTODO'
],
'props' => [
'SUMMARY' ,
'LOCATION'
],
'search-term' => 'Test' ,
]);
$this -> assertEquals ( count ( $search1 ), 1 );
// update the card
$calData = <<< 'EOD'
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
2017-05-21 07:18:58 -04:00
SUMMARY : 123 Event 🙈
2017-04-25 13:26:47 -04:00
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
ATTENDEE ; CN = test : mailto : foo @ bar . com
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> updateCalendarObject ( $calendarId , $uri , $calData );
$search2 = $this -> backend -> calendarSearch ( self :: UNIT_TEST_USER , [
'comps' => [
'VEVENT' ,
'VTODO'
],
'props' => [
'SUMMARY' ,
'LOCATION'
],
'search-term' => 'Test' ,
]);
$this -> assertEquals ( count ( $search2 ), 0 );
$search3 = $this -> backend -> calendarSearch ( self :: UNIT_TEST_USER , [
'comps' => [
'VEVENT' ,
'VTODO'
],
'props' => [
'SUMMARY' ,
'LOCATION'
],
'params' => [
[
'property' => 'ATTENDEE' ,
'parameter' => 'CN'
]
],
'search-term' => 'Test' ,
]);
$this -> assertEquals ( count ( $search3 ), 1 );
// t matches both summary and attendee's CN, but we want unique results
$search4 = $this -> backend -> calendarSearch ( self :: UNIT_TEST_USER , [
'comps' => [
'VEVENT' ,
'VTODO'
],
'props' => [
'SUMMARY' ,
'LOCATION'
],
'params' => [
[
'property' => 'ATTENDEE' ,
'parameter' => 'CN'
]
],
'search-term' => 't' ,
]);
$this -> assertEquals ( count ( $search4 ), 1 );
$this -> backend -> deleteCalendarObject ( $calendarId , $uri );
$search5 = $this -> backend -> calendarSearch ( self :: UNIT_TEST_USER , [
'comps' => [
'VEVENT' ,
'VTODO'
],
'props' => [
'SUMMARY' ,
'LOCATION'
],
'params' => [
[
'property' => 'ATTENDEE' ,
'parameter' => 'CN'
]
],
'search-term' => 't' ,
]);
$this -> assertEquals ( count ( $search5 ), 0 );
}
2017-11-06 19:31:28 -05:00
2026-01-07 08:21:48 -05:00
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'searchDataProvider')]
2023-01-20 02:38:43 -05:00
public function testSearch ( bool $isShared , array $searchOptions , int $count ) : void {
2017-11-06 19:31:28 -05:00
$calendarId = $this -> createTestCalendar ();
$uris = [];
$calData = [];
$uris [] = static :: getUniqueID ( 'calobj' );
$calData [] = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : Nextcloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8 - 1
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$uris [] = static :: getUniqueID ( 'calobj' );
$calData [] = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : Nextcloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8 - 2
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : 123
LOCATION : Test
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$uris [] = static :: getUniqueID ( 'calobj' );
$calData [] = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : Nextcloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8 - 3
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : 123
ATTENDEE ; CN = test : mailto : foo @ bar . com
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PRIVATE
END : VEVENT
END : VCALENDAR
EOD ;
$uris [] = static :: getUniqueID ( 'calobj' );
$calData [] = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : Nextcloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8 - 4
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : 123
ATTENDEE ; CN = foobar : mailto : test @ bar . com
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : CONFIDENTIAL
END : VEVENT
END : VCALENDAR
EOD ;
$uriCount = count ( $uris );
2020-10-05 09:12:57 -04:00
for ( $i = 0 ; $i < $uriCount ; $i ++ ) {
2017-11-06 19:31:28 -05:00
$this -> backend -> createCalendarObject ( $calendarId ,
$uris [ $i ], $calData [ $i ]);
}
$calendarInfo = [
'id' => $calendarId ,
'principaluri' => 'user1' ,
'{http://owncloud.org/ns}owner-principal' => $isShared ? 'user2' : 'user1' ,
];
$result = $this -> backend -> search ( $calendarInfo , 'Test' ,
2020-01-05 15:07:36 -05:00
[ 'SUMMARY' , 'LOCATION' , 'ATTENDEE' ], $searchOptions , null , null );
2017-11-06 19:31:28 -05:00
$this -> assertCount ( $count , $result );
}
2025-05-24 17:00:05 -04:00
public static function searchDataProvider () : array {
2017-11-06 19:31:28 -05:00
return [
2020-01-05 15:27:41 -05:00
[ false , [], 4 ],
[ true , [ 'timerange' => [ 'start' => new DateTime ( '2013-09-12 13:00:00' ), 'end' => new DateTime ( '2013-09-12 14:00:00' )]], 2 ],
[ true , [ 'timerange' => [ 'start' => new DateTime ( '2013-09-12 15:00:00' ), 'end' => new DateTime ( '2013-09-12 16:00:00' )]], 0 ],
2017-11-06 19:31:28 -05:00
];
}
2018-06-28 07:07:33 -04:00
2023-01-20 02:38:43 -05:00
public function testSameUriSameIdForDifferentCalendarTypes () : void {
2018-06-28 07:07:33 -04:00
$calendarId = $this -> createTestCalendar ();
$subscriptionId = $this -> createTestSubscription ();
$uri = static :: getUniqueID ( 'calobj' );
$calData = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$calData2 = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event 123
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> createCalendarObject ( $calendarId , $uri , $calData );
$this -> backend -> createCalendarObject ( $subscriptionId , $uri , $calData2 , CalDavBackend :: CALENDAR_TYPE_SUBSCRIPTION );
$this -> assertEquals ( $calData , $this -> backend -> getCalendarObject ( $calendarId , $uri , CalDavBackend :: CALENDAR_TYPE_CALENDAR )[ 'calendardata' ]);
$this -> assertEquals ( $calData2 , $this -> backend -> getCalendarObject ( $subscriptionId , $uri , CalDavBackend :: CALENDAR_TYPE_SUBSCRIPTION )[ 'calendardata' ]);
}
2023-01-20 02:38:43 -05:00
public function testPurgeAllCachedEventsForSubscription () : void {
2018-06-28 07:07:33 -04:00
$subscriptionId = $this -> createTestSubscription ();
$uri = static :: getUniqueID ( 'calobj' );
$calData = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : ownCloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> createCalendarObject ( $subscriptionId , $uri , $calData , CalDavBackend :: CALENDAR_TYPE_SUBSCRIPTION );
$this -> backend -> purgeAllCachedEventsForSubscription ( $subscriptionId );
$this -> assertEquals ( null , $this -> backend -> getCalendarObject ( $subscriptionId , $uri , CalDavBackend :: CALENDAR_TYPE_SUBSCRIPTION ));
}
2017-07-26 06:33:32 -04:00
2023-01-20 02:38:43 -05:00
public function testCalendarMovement () : void {
2017-07-26 06:33:32 -04:00
$this -> backend -> createCalendar ( self :: UNIT_TEST_USER , 'Example' , []);
$this -> assertCount ( 1 , $this -> backend -> getCalendarsForUser ( self :: UNIT_TEST_USER ));
$calendarInfoUser = $this -> backend -> getCalendarsForUser ( self :: UNIT_TEST_USER )[ 0 ];
$this -> backend -> moveCalendar ( 'Example' , self :: UNIT_TEST_USER , self :: UNIT_TEST_USER1 );
$this -> assertCount ( 0 , $this -> backend -> getCalendarsForUser ( self :: UNIT_TEST_USER ));
$this -> assertCount ( 1 , $this -> backend -> getCalendarsForUser ( self :: UNIT_TEST_USER1 ));
$calendarInfoUser1 = $this -> backend -> getCalendarsForUser ( self :: UNIT_TEST_USER1 )[ 0 ];
$this -> assertEquals ( $calendarInfoUser [ 'id' ], $calendarInfoUser1 [ 'id' ]);
$this -> assertEquals ( $calendarInfoUser [ 'uri' ], $calendarInfoUser1 [ 'uri' ]);
}
2020-07-27 10:14:15 -04:00
public function testSearchPrincipal () : void {
$myPublic = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID :-// dmfs . org //mimedir.icalendar//EN
BEGIN : VTIMEZONE
TZID : Europe / Berlin
X - LIC - LOCATION : Europe / Berlin
BEGIN : DAYLIGHT
TZOFFSETFROM :+ 0100
TZOFFSETTO :+ 0200
TZNAME : CEST
DTSTART : 19700329 T020000
RRULE : FREQ = YEARLY ; BYMONTH = 3 ; BYDAY =- 1 SU
END : DAYLIGHT
BEGIN : STANDARD
TZOFFSETFROM :+ 0200
TZOFFSETTO :+ 0100
TZNAME : CET
DTSTART : 19701025 T030000
RRULE : FREQ = YEARLY ; BYMONTH = 10 ; BYDAY =- 1 SU
END : STANDARD
END : VTIMEZONE
BEGIN : VEVENT
DTSTART ; TZID = Europe / Berlin : 20160419 T130000
SUMMARY : My Test ( public )
CLASS : PUBLIC
TRANSP : OPAQUE
STATUS : CONFIRMED
DTEND ; TZID = Europe / Berlin : 20160419 T140000
LAST - MODIFIED : 20160419 T074202Z
DTSTAMP : 20160419 T074202Z
CREATED : 20160419 T074202Z
UID : 2e468 c48 - 7860 - 492 e - bc52 - 92 fa0daeeccf . 1461051722310 - 1
END : VEVENT
END : VCALENDAR
EOD ;
$myPrivate = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID :-// dmfs . org //mimedir.icalendar//EN
BEGIN : VTIMEZONE
TZID : Europe / Berlin
X - LIC - LOCATION : Europe / Berlin
BEGIN : DAYLIGHT
TZOFFSETFROM :+ 0100
TZOFFSETTO :+ 0200
TZNAME : CEST
DTSTART : 19700329 T020000
RRULE : FREQ = YEARLY ; BYMONTH = 3 ; BYDAY =- 1 SU
END : DAYLIGHT
BEGIN : STANDARD
TZOFFSETFROM :+ 0200
TZOFFSETTO :+ 0100
TZNAME : CET
DTSTART : 19701025 T030000
RRULE : FREQ = YEARLY ; BYMONTH = 10 ; BYDAY =- 1 SU
END : STANDARD
END : VTIMEZONE
BEGIN : VEVENT
DTSTART ; TZID = Europe / Berlin : 20160419 T130000
SUMMARY : My Test ( private )
CLASS : PRIVATE
TRANSP : OPAQUE
STATUS : CONFIRMED
DTEND ; TZID = Europe / Berlin : 20160419 T140000
LAST - MODIFIED : 20160419 T074202Z
DTSTAMP : 20160419 T074202Z
CREATED : 20160419 T074202Z
UID : 2e468 c48 - 7860 - 492 e - bc52 - 92 fa0daeeccf . 1461051722310 - 2
END : VEVENT
END : VCALENDAR
EOD ;
$myConfidential = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID :-// dmfs . org //mimedir.icalendar//EN
BEGIN : VTIMEZONE
TZID : Europe / Berlin
X - LIC - LOCATION : Europe / Berlin
BEGIN : DAYLIGHT
TZOFFSETFROM :+ 0100
TZOFFSETTO :+ 0200
TZNAME : CEST
DTSTART : 19700329 T020000
RRULE : FREQ = YEARLY ; BYMONTH = 3 ; BYDAY =- 1 SU
END : DAYLIGHT
BEGIN : STANDARD
TZOFFSETFROM :+ 0200
TZOFFSETTO :+ 0100
TZNAME : CET
DTSTART : 19701025 T030000
RRULE : FREQ = YEARLY ; BYMONTH = 10 ; BYDAY =- 1 SU
END : STANDARD
END : VTIMEZONE
BEGIN : VEVENT
DTSTART ; TZID = Europe / Berlin : 20160419 T130000
SUMMARY : My Test ( confidential )
CLASS : CONFIDENTIAL
TRANSP : OPAQUE
STATUS : CONFIRMED
DTEND ; TZID = Europe / Berlin : 20160419 T140000
LAST - MODIFIED : 20160419 T074202Z
DTSTAMP : 20160419 T074202Z
CREATED : 20160419 T074202Z
UID : 2e468 c48 - 7860 - 492 e - bc52 - 92 fa0daeeccf . 1461051722310 - 3
END : VEVENT
END : VCALENDAR
EOD ;
$sharerPublic = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID :-// dmfs . org //mimedir.icalendar//EN
BEGIN : VTIMEZONE
TZID : Europe / Berlin
X - LIC - LOCATION : Europe / Berlin
BEGIN : DAYLIGHT
TZOFFSETFROM :+ 0100
TZOFFSETTO :+ 0200
TZNAME : CEST
DTSTART : 19700329 T020000
RRULE : FREQ = YEARLY ; BYMONTH = 3 ; BYDAY =- 1 SU
END : DAYLIGHT
BEGIN : STANDARD
TZOFFSETFROM :+ 0200
TZOFFSETTO :+ 0100
TZNAME : CET
DTSTART : 19701025 T030000
RRULE : FREQ = YEARLY ; BYMONTH = 10 ; BYDAY =- 1 SU
END : STANDARD
END : VTIMEZONE
BEGIN : VEVENT
DTSTART ; TZID = Europe / Berlin : 20160419 T130000
SUMMARY : Sharer Test ( public )
CLASS : PUBLIC
TRANSP : OPAQUE
STATUS : CONFIRMED
DTEND ; TZID = Europe / Berlin : 20160419 T140000
LAST - MODIFIED : 20160419 T074202Z
DTSTAMP : 20160419 T074202Z
CREATED : 20160419 T074202Z
UID : 2e468 c48 - 7860 - 492 e - bc52 - 92 fa0daeeccf . 1461051722310 - 4
END : VEVENT
END : VCALENDAR
EOD ;
$sharerPrivate = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID :-// dmfs . org //mimedir.icalendar//EN
BEGIN : VTIMEZONE
TZID : Europe / Berlin
X - LIC - LOCATION : Europe / Berlin
BEGIN : DAYLIGHT
TZOFFSETFROM :+ 0100
TZOFFSETTO :+ 0200
TZNAME : CEST
DTSTART : 19700329 T020000
RRULE : FREQ = YEARLY ; BYMONTH = 3 ; BYDAY =- 1 SU
END : DAYLIGHT
BEGIN : STANDARD
TZOFFSETFROM :+ 0200
TZOFFSETTO :+ 0100
TZNAME : CET
DTSTART : 19701025 T030000
RRULE : FREQ = YEARLY ; BYMONTH = 10 ; BYDAY =- 1 SU
END : STANDARD
END : VTIMEZONE
BEGIN : VEVENT
DTSTART ; TZID = Europe / Berlin : 20160419 T130000
SUMMARY : Sharer Test ( private )
CLASS : PRIVATE
TRANSP : OPAQUE
STATUS : CONFIRMED
DTEND ; TZID = Europe / Berlin : 20160419 T140000
LAST - MODIFIED : 20160419 T074202Z
DTSTAMP : 20160419 T074202Z
CREATED : 20160419 T074202Z
UID : 2e468 c48 - 7860 - 492 e - bc52 - 92 fa0daeeccf . 1461051722310 - 5
END : VEVENT
END : VCALENDAR
EOD ;
$sharerConfidential = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID :-// dmfs . org //mimedir.icalendar//EN
BEGIN : VTIMEZONE
TZID : Europe / Berlin
X - LIC - LOCATION : Europe / Berlin
BEGIN : DAYLIGHT
TZOFFSETFROM :+ 0100
TZOFFSETTO :+ 0200
TZNAME : CEST
DTSTART : 19700329 T020000
RRULE : FREQ = YEARLY ; BYMONTH = 3 ; BYDAY =- 1 SU
END : DAYLIGHT
BEGIN : STANDARD
TZOFFSETFROM :+ 0200
TZOFFSETTO :+ 0100
TZNAME : CET
DTSTART : 19701025 T030000
RRULE : FREQ = YEARLY ; BYMONTH = 10 ; BYDAY =- 1 SU
END : STANDARD
END : VTIMEZONE
BEGIN : VEVENT
DTSTART ; TZID = Europe / Berlin : 20160419 T130000
SUMMARY : Sharer Test ( confidential )
CLASS : CONFIDENTIAL
TRANSP : OPAQUE
STATUS : CONFIRMED
DTEND ; TZID = Europe / Berlin : 20160419 T140000
LAST - MODIFIED : 20160419 T074202Z
DTSTAMP : 20160419 T074202Z
CREATED : 20160419 T074202Z
UID : 2e468 c48 - 7860 - 492 e - bc52 - 92 fa0daeeccf . 1461051722310 - 6
END : VEVENT
END : VCALENDAR
EOD ;
$l10n = $this -> createMock ( IL10N :: class );
$l10n
-> expects ( $this -> any ())
-> method ( 't' )
-> willReturnCallback ( function ( $text , $parameters = []) {
return vsprintf ( $text , $parameters );
});
$config = $this -> createMock ( IConfig :: class );
$this -> userManager -> expects ( $this -> any ())
-> method ( 'userExists' )
-> willReturn ( true );
$this -> groupManager -> expects ( $this -> any ())
-> method ( 'groupExists' )
-> willReturn ( true );
2024-01-30 12:35:44 -05:00
$this -> principal -> expects ( self :: atLeastOnce ())
-> method ( 'findByUri' )
-> willReturn ( self :: UNIT_TEST_USER );
2020-07-27 10:14:15 -04:00
$me = self :: UNIT_TEST_USER ;
$sharer = self :: UNIT_TEST_USER1 ;
$this -> backend -> createCalendar ( $me , 'calendar-uri-me' , []);
$this -> backend -> createCalendar ( $sharer , 'calendar-uri-sharer' , []);
$myCalendars = $this -> backend -> getCalendarsForUser ( $me );
$this -> assertCount ( 1 , $myCalendars );
$sharerCalendars = $this -> backend -> getCalendarsForUser ( $sharer );
$this -> assertCount ( 1 , $sharerCalendars );
2021-12-06 14:01:22 -05:00
$logger = $this -> createMock ( \Psr\Log\LoggerInterface :: class );
$sharerCalendar = new Calendar ( $this -> backend , $sharerCalendars [ 0 ], $l10n , $config , $logger );
2020-07-27 10:14:15 -04:00
$this -> backend -> updateShares ( $sharerCalendar , [
[
'href' => 'principal:' . $me ,
'readOnly' => false ,
],
], []);
$this -> assertCount ( 2 , $this -> backend -> getCalendarsForUser ( $me ));
$this -> backend -> createCalendarObject ( $myCalendars [ 0 ][ 'id' ], 'event0.ics' , $myPublic );
$this -> backend -> createCalendarObject ( $myCalendars [ 0 ][ 'id' ], 'event1.ics' , $myPrivate );
$this -> backend -> createCalendarObject ( $myCalendars [ 0 ][ 'id' ], 'event2.ics' , $myConfidential );
$this -> backend -> createCalendarObject ( $sharerCalendars [ 0 ][ 'id' ], 'event3.ics' , $sharerPublic );
$this -> backend -> createCalendarObject ( $sharerCalendars [ 0 ][ 'id' ], 'event4.ics' , $sharerPrivate );
$this -> backend -> createCalendarObject ( $sharerCalendars [ 0 ][ 'id' ], 'event5.ics' , $sharerConfidential );
$mySearchResults = $this -> backend -> searchPrincipalUri ( $me , 'Test' , [ 'VEVENT' ], [ 'SUMMARY' ], []);
$sharerSearchResults = $this -> backend -> searchPrincipalUri ( $sharer , 'Test' , [ 'VEVENT' ], [ 'SUMMARY' ], []);
$this -> assertCount ( 4 , $mySearchResults );
$this -> assertCount ( 3 , $sharerSearchResults );
$this -> assertEquals ( $myPublic , $mySearchResults [ 0 ][ 'calendardata' ]);
$this -> assertEquals ( $myPrivate , $mySearchResults [ 1 ][ 'calendardata' ]);
$this -> assertEquals ( $myConfidential , $mySearchResults [ 2 ][ 'calendardata' ]);
$this -> assertEquals ( $sharerPublic , $mySearchResults [ 3 ][ 'calendardata' ]);
$this -> assertEquals ( $sharerPublic , $sharerSearchResults [ 0 ][ 'calendardata' ]);
$this -> assertEquals ( $sharerPrivate , $sharerSearchResults [ 1 ][ 'calendardata' ]);
$this -> assertEquals ( $sharerConfidential , $sharerSearchResults [ 2 ][ 'calendardata' ]);
}
2022-10-02 06:07:51 -04:00
/**
* @ throws \OCP\DB\Exception
* @ throws \Sabre\DAV\Exception\BadRequest
*/
public function testPruneOutdatedSyncTokens () : void {
$calendarId = $this -> createTestCalendar ();
2023-06-04 17:01:42 -04:00
$changes = $this -> backend -> getChangesForCalendar ( $calendarId , '' , 1 );
$syncToken = $changes [ 'syncToken' ];
2022-10-02 06:07:51 -04:00
$uri = static :: getUniqueID ( 'calobj' );
$calData = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : Nextcloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> createCalendarObject ( $calendarId , $uri , $calData );
// update the card
$calData = <<< 'EOD'
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : Nextcloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : 123 Event 🙈
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
ATTENDEE ; CN = test : mailto : foo @ bar . com
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> updateCalendarObject ( $calendarId , $uri , $calData );
2024-03-08 02:14:05 -05:00
// Keep everything
$deleted = $this -> backend -> pruneOutdatedSyncTokens ( 0 , 0 );
self :: assertSame ( 0 , $deleted );
$deleted = $this -> backend -> pruneOutdatedSyncTokens ( 0 , time ());
2022-10-02 06:07:51 -04:00
// At least one from the object creation and one from the object update
$this -> assertGreaterThanOrEqual ( 2 , $deleted );
2023-06-04 17:01:42 -04:00
$changes = $this -> backend -> getChangesForCalendar ( $calendarId , $syncToken , 1 );
2022-10-02 06:07:51 -04:00
$this -> assertEmpty ( $changes [ 'added' ]);
$this -> assertEmpty ( $changes [ 'modified' ]);
$this -> assertEmpty ( $changes [ 'deleted' ]);
2023-06-04 17:01:42 -04:00
// Test that objects remain
// Currently changes are empty
$changes = $this -> backend -> getChangesForCalendar ( $calendarId , $syncToken , 100 );
$this -> assertEquals ( 0 , count ( $changes [ 'added' ] + $changes [ 'modified' ] + $changes [ 'deleted' ]));
// Create card
$uri = static :: getUniqueID ( 'calobj' );
2022-04-01 11:31:37 -04:00
$calData = <<< EOD
2023-06-04 17:01:42 -04:00
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : Nextcloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20230910 T125139Z
UID : 47 d15e3ec9
LAST - MODIFIED ; VALUE = DATE - TIME : 20230910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20230910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20230912 T130000Z
DTEND ; VALUE = DATE - TIME : 20230912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> createCalendarObject ( $calendarId , $uri , $calData );
// We now have one add
$changes = $this -> backend -> getChangesForCalendar ( $calendarId , $syncToken , 100 );
$this -> assertEquals ( 1 , count ( $changes [ 'added' ]));
$this -> assertEmpty ( $changes [ 'modified' ]);
$this -> assertEmpty ( $changes [ 'deleted' ]);
2022-04-01 11:31:37 -04:00
2023-06-04 17:01:42 -04:00
// update the card
$calData = <<< 'EOD'
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : Nextcloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20230910 T125139Z
UID : 47 d15e3ec9
LAST - MODIFIED ; VALUE = DATE - TIME : 20230910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20230910 T125139Z
SUMMARY : 123 Event 🙈
DTSTART ; VALUE = DATE - TIME : 20230912 T130000Z
DTEND ; VALUE = DATE - TIME : 20230912 T140000Z
ATTENDEE ; CN = test : mailto : foo @ bar . com
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> updateCalendarObject ( $calendarId , $uri , $calData );
// One add, one modify, but shortened to modify
$changes = $this -> backend -> getChangesForCalendar ( $calendarId , $syncToken , 100 );
$this -> assertEmpty ( $changes [ 'added' ]);
$this -> assertEquals ( 1 , count ( $changes [ 'modified' ]));
2022-04-01 11:31:37 -04:00
$this -> assertEmpty ( $changes [ 'deleted' ]);
2023-06-04 17:01:42 -04:00
// Delete all but last change
2024-03-08 02:14:05 -05:00
$deleted = $this -> backend -> pruneOutdatedSyncTokens ( 1 , time ());
2023-06-04 17:01:42 -04:00
$this -> assertEquals ( 1 , $deleted ); // We had two changes before, now one
// Only update should remain
$changes = $this -> backend -> getChangesForCalendar ( $calendarId , $syncToken , 100 );
$this -> assertEmpty ( $changes [ 'added' ]);
$this -> assertEquals ( 1 , count ( $changes [ 'modified' ]));
$this -> assertEmpty ( $changes [ 'deleted' ]);
2022-04-01 11:31:37 -04:00
2023-06-04 17:01:42 -04:00
// Check that no crash occurs when prune is called without current changes
2024-03-08 02:14:05 -05:00
$deleted = $this -> backend -> pruneOutdatedSyncTokens ( 1 , time ());
self :: assertSame ( 0 , $deleted );
2022-10-02 06:07:51 -04:00
}
2023-09-20 11:45:54 -04:00
2024-09-15 16:32:31 -04:00
public function testSearchAndExpandRecurrences () : void {
2023-09-20 11:45:54 -04:00
$calendarId = $this -> createTestCalendar ();
$calendarInfo = [
'id' => $calendarId ,
'principaluri' => 'user1' ,
'{http://owncloud.org/ns}owner-principal' => 'user1' ,
];
$calData = <<< 'EOD'
BEGIN : VCALENDAR
PRODID :-// IDN nextcloud . com //Calendar app 4.5.0-alpha.2//EN
CALSCALE : GREGORIAN
VERSION : 2.0
BEGIN : VEVENT
CREATED : 20230921 T133401Z
DTSTAMP : 20230921 T133448Z
LAST - MODIFIED : 20230921 T133448Z
SEQUENCE : 2
UID : 7 b7d5d12 - 683 c - 48 ce - 973 a - b3e1cb0bae2a
DTSTART ; VALUE = DATE : 20230912
DTEND ; VALUE = DATE : 20230913
STATUS : CONFIRMED
SUMMARY : Daily Event
RRULE : FREQ = DAILY
END : VEVENT
END : VCALENDAR
EOD ;
$uri = static :: getUniqueID ( 'calobj' );
$this -> backend -> createCalendarObject ( $calendarId , $uri , $calData );
$start = new DateTimeImmutable ( '2023-09-20T00:00:00Z' );
$end = $start -> add ( new DateInterval ( 'P14D' ));
$results = $this -> backend -> search (
$calendarInfo ,
'' ,
[],
[
'timerange' => [
'start' => $start ,
'end' => $end ,
]
],
null ,
null ,
);
$this -> assertCount ( 1 , $results );
$this -> assertCount ( 14 , $results [ 0 ][ 'objects' ]);
foreach ( $results as $result ) {
foreach ( $result [ 'objects' ] as $object ) {
$this -> assertEquals ( $object [ 'UID' ][ 0 ], '7b7d5d12-683c-48ce-973a-b3e1cb0bae2a' );
$this -> assertEquals ( $object [ 'SUMMARY' ][ 0 ], 'Daily Event' );
$this -> assertGreaterThanOrEqual (
$start -> getTimestamp (),
$object [ 'DTSTART' ][ 0 ] -> getTimestamp (),
'Recurrence starting before requested start' ,
);
$this -> assertLessThanOrEqual (
$end -> getTimestamp (),
$object [ 'DTSTART' ][ 0 ] -> getTimestamp (),
'Recurrence starting after requested end' ,
);
}
}
}
2024-03-11 11:27:23 -04:00
public function testRestoreChanges () : void {
$calendarId = $this -> createTestCalendar ();
$uri1 = static :: getUniqueID ( 'calobj1' ) . '.ics' ;
$calData = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : Nextcloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> createCalendarObject ( $calendarId , $uri1 , $calData );
$calData = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : Nextcloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec8
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event – UPDATED
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
SEQUENCE : 1
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> updateCalendarObject ( $calendarId , $uri1 , $calData );
$uri2 = static :: getUniqueID ( 'calobj2' ) . '.ics' ;
$calData = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : Nextcloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3ec9
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> createCalendarObject ( $calendarId , $uri2 , $calData );
$changesBefore = $this -> backend -> getChangesForCalendar ( $calendarId , null , 1 );
$this -> backend -> deleteCalendarObject ( $calendarId , $uri2 );
$uri3 = static :: getUniqueID ( 'calobj3' ) . '.ics' ;
$calData = <<< EOD
BEGIN : VCALENDAR
VERSION : 2.0
PRODID : Nextcloud Calendar
BEGIN : VEVENT
CREATED ; VALUE = DATE - TIME : 20130910 T125139Z
UID : 47 d15e3e10
LAST - MODIFIED ; VALUE = DATE - TIME : 20130910 T125139Z
DTSTAMP ; VALUE = DATE - TIME : 20130910 T125139Z
SUMMARY : Test Event
DTSTART ; VALUE = DATE - TIME : 20130912 T130000Z
DTEND ; VALUE = DATE - TIME : 20130912 T140000Z
CLASS : PUBLIC
END : VEVENT
END : VCALENDAR
EOD ;
$this -> backend -> createCalendarObject ( $calendarId , $uri3 , $calData );
$deleteChanges = $this -> db -> getQueryBuilder ();
$deleteChanges -> delete ( 'calendarchanges' )
-> where ( $deleteChanges -> expr () -> eq ( 'calendarid' , $deleteChanges -> createNamedParameter ( $calendarId )));
$deleteChanges -> executeStatement ();
$this -> backend -> restoreChanges ( $calendarId );
$changesAfter = $this -> backend -> getChangesForCalendar ( $calendarId , $changesBefore [ 'syncToken' ], 1 );
self :: assertEquals ([], $changesAfter [ 'added' ]);
self :: assertEqualsCanonicalizing ([ $uri1 , $uri3 ], $changesAfter [ 'modified' ]);
self :: assertEquals ([ $uri2 ], $changesAfter [ 'deleted' ]);
}
2024-05-07 09:55:47 -04:00
2024-09-15 16:32:31 -04:00
public function testSearchWithLimitAndTimeRange () : void {
2024-05-07 09:55:47 -04:00
$calendarId = $this -> createTestCalendar ();
$calendarInfo = [
'id' => $calendarId ,
'principaluri' => 'user1' ,
'{http://owncloud.org/ns}owner-principal' => 'user1' ,
];
$testFiles = [
2024-09-19 12:54:43 -04:00
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-1.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-2.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-3.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-4.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-5.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-6.ics' ,
2024-05-07 09:55:47 -04:00
];
foreach ( $testFiles as $testFile ) {
$objectUri = static :: getUniqueID ( 'search-limit-timerange-' );
$calendarData = \file_get_contents ( $testFile );
$this -> backend -> createCalendarObject ( $calendarId , $objectUri , $calendarData );
}
$start = new DateTimeImmutable ( '2024-05-06T00:00:00Z' );
$end = $start -> add ( new DateInterval ( 'P14D' ));
$results = $this -> backend -> search (
$calendarInfo ,
'' ,
[],
[
'timerange' => [
'start' => $start ,
'end' => $end ,
]
],
4 ,
null ,
);
$this -> assertCount ( 2 , $results );
$this -> assertEquals ( 'Cake Tasting' , $results [ 0 ][ 'objects' ][ 0 ][ 'SUMMARY' ][ 0 ]);
$this -> assertGreaterThanOrEqual (
$start -> getTimestamp (),
$results [ 0 ][ 'objects' ][ 0 ][ 'DTSTART' ][ 0 ] -> getTimestamp (),
'Recurrence starting before requested start' ,
);
$this -> assertEquals ( 'Pasta Day' , $results [ 1 ][ 'objects' ][ 0 ][ 'SUMMARY' ][ 0 ]);
$this -> assertGreaterThanOrEqual (
$start -> getTimestamp (),
$results [ 1 ][ 'objects' ][ 0 ][ 'DTSTART' ][ 0 ] -> getTimestamp (),
'Recurrence starting before requested start' ,
);
}
2024-09-15 16:32:31 -04:00
public function testSearchWithLimitAndTimeRangeShouldNotReturnMoreObjectsThenLimit () : void {
2024-05-07 09:55:47 -04:00
$calendarId = $this -> createTestCalendar ();
$calendarInfo = [
'id' => $calendarId ,
'principaluri' => 'user1' ,
'{http://owncloud.org/ns}owner-principal' => 'user1' ,
];
$testFiles = [
2024-09-19 12:54:43 -04:00
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-1.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-2.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-3.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-4.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-5.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-6.ics' ,
2024-05-07 09:55:47 -04:00
];
foreach ( $testFiles as $testFile ) {
$objectUri = static :: getUniqueID ( 'search-limit-timerange-' );
$calendarData = \file_get_contents ( $testFile );
$this -> backend -> createCalendarObject ( $calendarId , $objectUri , $calendarData );
}
$start = new DateTimeImmutable ( '2024-05-06T00:00:00Z' );
$end = $start -> add ( new DateInterval ( 'P14D' ));
$results = $this -> backend -> search (
$calendarInfo ,
'' ,
[],
[
'timerange' => [
'start' => $start ,
'end' => $end ,
]
],
1 ,
null ,
);
$this -> assertCount ( 1 , $results );
$this -> assertEquals ( 'Cake Tasting' , $results [ 0 ][ 'objects' ][ 0 ][ 'SUMMARY' ][ 0 ]);
$this -> assertGreaterThanOrEqual (
$start -> getTimestamp (),
$results [ 0 ][ 'objects' ][ 0 ][ 'DTSTART' ][ 0 ] -> getTimestamp (),
'Recurrence starting before requested start' ,
);
}
2024-09-15 16:32:31 -04:00
public function testSearchWithLimitAndTimeRangeShouldReturnObjectsInTheSameOrder () : void {
2024-05-07 09:55:47 -04:00
$calendarId = $this -> createTestCalendar ();
$calendarInfo = [
'id' => $calendarId ,
'principaluri' => 'user1' ,
'{http://owncloud.org/ns}owner-principal' => 'user1' ,
];
$testFiles = [
2024-09-19 12:54:43 -04:00
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-1.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-2.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-3.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-4.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-6.ics' , // <-- intentional!
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-5.ics' ,
2024-05-07 09:55:47 -04:00
];
foreach ( $testFiles as $testFile ) {
$objectUri = static :: getUniqueID ( 'search-limit-timerange-' );
$calendarData = \file_get_contents ( $testFile );
$this -> backend -> createCalendarObject ( $calendarId , $objectUri , $calendarData );
}
$start = new DateTimeImmutable ( '2024-05-06T00:00:00Z' );
$end = $start -> add ( new DateInterval ( 'P14D' ));
$results = $this -> backend -> search (
$calendarInfo ,
'' ,
[],
[
'timerange' => [
'start' => $start ,
'end' => $end ,
]
],
2 ,
null ,
);
$this -> assertCount ( 2 , $results );
$this -> assertEquals ( 'Cake Tasting' , $results [ 0 ][ 'objects' ][ 0 ][ 'SUMMARY' ][ 0 ]);
$this -> assertGreaterThanOrEqual (
$start -> getTimestamp (),
$results [ 0 ][ 'objects' ][ 0 ][ 'DTSTART' ][ 0 ] -> getTimestamp (),
'Recurrence starting before requested start' ,
);
$this -> assertEquals ( 'Pasta Day' , $results [ 1 ][ 'objects' ][ 0 ][ 'SUMMARY' ][ 0 ]);
$this -> assertGreaterThanOrEqual (
$start -> getTimestamp (),
$results [ 1 ][ 'objects' ][ 0 ][ 'DTSTART' ][ 0 ] -> getTimestamp (),
'Recurrence starting before requested start' ,
);
}
2024-05-15 06:55:40 -04:00
2024-09-15 16:32:31 -04:00
public function testSearchShouldReturnObjectsInTheSameOrderMissingDate () : void {
2024-05-15 06:55:40 -04:00
$calendarId = $this -> createTestCalendar ();
$calendarInfo = [
'id' => $calendarId ,
'principaluri' => 'user1' ,
'{http://owncloud.org/ns}owner-principal' => 'user1' ,
];
$testFiles = [
2024-09-19 12:54:43 -04:00
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-6.ics' , // <-- intentional!
__DIR__ . '/../test_fixtures/caldav-search-limit-timerange-5.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-missing-start-1.ics' ,
__DIR__ . '/../test_fixtures/caldav-search-missing-start-2.ics' ,
2024-05-15 06:55:40 -04:00
];
foreach ( $testFiles as $testFile ) {
$objectUri = static :: getUniqueID ( 'search-return-objects-in-same-order-' );
$calendarData = \file_get_contents ( $testFile );
$this -> backend -> createCalendarObject ( $calendarId , $objectUri , $calendarData );
}
$results = $this -> backend -> search (
$calendarInfo ,
'' ,
[],
[],
4 ,
null ,
);
$this -> assertCount ( 4 , $results );
$this -> assertEquals ( 'Cake Tasting' , $results [ 0 ][ 'objects' ][ 0 ][ 'SUMMARY' ][ 0 ]);
$this -> assertEquals ( 'Pasta Day' , $results [ 1 ][ 'objects' ][ 0 ][ 'SUMMARY' ][ 0 ]);
$this -> assertEquals ( 'Missing DTSTART 1' , $results [ 2 ][ 'objects' ][ 0 ][ 'SUMMARY' ][ 0 ]);
$this -> assertEquals ( 'Missing DTSTART 2' , $results [ 3 ][ 'objects' ][ 0 ][ 'SUMMARY' ][ 0 ]);
}
2025-04-07 08:59:20 -04:00
public function testUnshare () : void {
$principalGroup = 'principal:' . self :: UNIT_TEST_GROUP ;
$principalUser = 'principal:' . self :: UNIT_TEST_USER ;
$l10n = $this -> createMock ( IL10N :: class );
$l10n -> method ( 't' )
-> willReturnCallback ( fn ( $text , $parameters = []) => vsprintf ( $text , $parameters ));
$config = $this -> createMock ( IConfig :: class );
$logger = new NullLogger ();
$this -> principal -> expects ( $this -> exactly ( 2 ))
-> method ( 'findByUri' )
-> willReturnMap ([
[ $principalGroup , '' , self :: UNIT_TEST_GROUP ],
[ $principalUser , '' , self :: UNIT_TEST_USER ],
]);
$this -> groupManager -> expects ( $this -> once ())
-> method ( 'groupExists' )
-> willReturn ( true );
$this -> dispatcher -> expects ( $this -> exactly ( 2 ))
-> method ( 'dispatchTyped' );
$calendarId = $this -> createTestCalendar ();
$calendarInfo = $this -> backend -> getCalendarById ( $calendarId );
$calendar = new Calendar ( $this -> backend , $calendarInfo , $l10n , $config , $logger );
$this -> backend -> updateShares (
shareable : $calendar ,
add : [
[ 'href' => $principalGroup , 'readOnly' => false ]
],
remove : []
);
$this -> backend -> unshare (
shareable : $calendar ,
principal : $principalUser
);
}
2015-10-30 20:28:21 -04:00
}