"Fossies" - the Fresh Open Source Software Archive

Member "dav-4.0.3/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php" (10 Jan 2020, 50025 Bytes) of package /linux/www/dav-4.0.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "AbstractPDOTest.php": 4.0.2_vs_4.0.3.

    1 <?php
    2 
    3 declare(strict_types=1);
    4 
    5 namespace Sabre\CalDAV\Backend;
    6 
    7 use Sabre\CalDAV;
    8 use Sabre\DAV;
    9 use Sabre\DAV\PropPatch;
   10 use Sabre\DAV\Xml\Element\Sharee;
   11 
   12 abstract class AbstractPDOTest extends \PHPUnit\Framework\TestCase
   13 {
   14     use DAV\DbTestHelperTrait;
   15 
   16     protected $pdo;
   17 
   18     public function setUp()
   19     {
   20         $this->dropTables([
   21             'calendarobjects',
   22             'calendars',
   23             'calendarinstances',
   24             'calendarchanges',
   25             'calendarsubscriptions',
   26             'schedulingobjects',
   27         ]);
   28         $this->createSchema('calendars');
   29 
   30         $this->pdo = $this->getDb();
   31     }
   32 
   33     public function testConstruct()
   34     {
   35         $backend = new PDO($this->pdo);
   36         $this->assertTrue($backend instanceof PDO);
   37     }
   38 
   39     /**
   40      * @depends testConstruct
   41      */
   42     public function testGetCalendarsForUserNoCalendars()
   43     {
   44         $backend = new PDO($this->pdo);
   45         $calendars = $backend->getCalendarsForUser('principals/user2');
   46         $this->assertEquals([], $calendars);
   47     }
   48 
   49     /**
   50      * @depends testConstruct
   51      */
   52     public function testCreateCalendarAndFetch()
   53     {
   54         $backend = new PDO($this->pdo);
   55         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', [
   56             '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT']),
   57             '{DAV:}displayname' => 'Hello!',
   58             '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'),
   59         ]);
   60         $calendars = $backend->getCalendarsForUser('principals/user2');
   61 
   62         $elementCheck = [
   63             'uri' => 'somerandomid',
   64             '{DAV:}displayname' => 'Hello!',
   65             '{urn:ietf:params:xml:ns:caldav}calendar-description' => '',
   66             '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'),
   67             'share-access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
   68         ];
   69 
   70         $this->assertInternalType('array', $calendars);
   71         $this->assertEquals(1, count($calendars));
   72 
   73         foreach ($elementCheck as $name => $value) {
   74             $this->assertArrayHasKey($name, $calendars[0]);
   75             $this->assertEquals($value, $calendars[0][$name]);
   76         }
   77     }
   78 
   79     /**
   80      * @depends testConstruct
   81      */
   82     public function testUpdateCalendarAndFetch()
   83     {
   84         $backend = new PDO($this->pdo);
   85 
   86         //Creating a new calendar
   87         $newId = $backend->createCalendar('principals/user2', 'somerandomid', []);
   88 
   89         $propPatch = new PropPatch([
   90             '{DAV:}displayname' => 'myCalendar',
   91             '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'),
   92         ]);
   93 
   94         // Updating the calendar
   95         $backend->updateCalendar($newId, $propPatch);
   96         $result = $propPatch->commit();
   97 
   98         // Verifying the result of the update
   99         $this->assertTrue($result);
  100 
  101         // Fetching all calendars from this user
  102         $calendars = $backend->getCalendarsForUser('principals/user2');
  103 
  104         // Checking if all the information is still correct
  105         $elementCheck = [
  106             'id' => $newId,
  107             'uri' => 'somerandomid',
  108             '{DAV:}displayname' => 'myCalendar',
  109             '{urn:ietf:params:xml:ns:caldav}calendar-description' => '',
  110             '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => '',
  111             '{http://calendarserver.org/ns/}getctag' => 'http://sabre.io/ns/sync/2',
  112             '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'),
  113         ];
  114 
  115         $this->assertInternalType('array', $calendars);
  116         $this->assertEquals(1, count($calendars));
  117 
  118         foreach ($elementCheck as $name => $value) {
  119             $this->assertArrayHasKey($name, $calendars[0]);
  120             $this->assertEquals($value, $calendars[0][$name]);
  121         }
  122     }
  123 
  124     /**
  125      * @depends testConstruct
  126      * @expectedException \InvalidArgumentException
  127      */
  128     public function testUpdateCalendarBadId()
  129     {
  130         $backend = new PDO($this->pdo);
  131 
  132         //Creating a new calendar
  133         $newId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  134 
  135         $propPatch = new PropPatch([
  136             '{DAV:}displayname' => 'myCalendar',
  137             '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'),
  138         ]);
  139 
  140         // Updating the calendar
  141         $backend->updateCalendar('raaaa', $propPatch);
  142     }
  143 
  144     /**
  145      * @depends testUpdateCalendarAndFetch
  146      */
  147     public function testUpdateCalendarUnknownProperty()
  148     {
  149         $backend = new PDO($this->pdo);
  150 
  151         //Creating a new calendar
  152         $newId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  153 
  154         $propPatch = new PropPatch([
  155             '{DAV:}displayname' => 'myCalendar',
  156             '{DAV:}yourmom' => 'wittycomment',
  157         ]);
  158 
  159         // Updating the calendar
  160         $backend->updateCalendar($newId, $propPatch);
  161         $propPatch->commit();
  162 
  163         // Verifying the result of the update
  164         $this->assertEquals([
  165             '{DAV:}yourmom' => 403,
  166             '{DAV:}displayname' => 424,
  167         ], $propPatch->getResult());
  168     }
  169 
  170     /**
  171      * @depends testCreateCalendarAndFetch
  172      */
  173     public function testDeleteCalendar()
  174     {
  175         $backend = new PDO($this->pdo);
  176         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', [
  177             '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT']),
  178             '{DAV:}displayname' => 'Hello!',
  179         ]);
  180 
  181         $backend->deleteCalendar($returnedId);
  182 
  183         $calendars = $backend->getCalendarsForUser('principals/user2');
  184         $this->assertEquals([], $calendars);
  185     }
  186 
  187     /**
  188      * @depends testCreateCalendarAndFetch
  189      * @expectedException \InvalidArgumentException
  190      */
  191     public function testDeleteCalendarBadID()
  192     {
  193         $backend = new PDO($this->pdo);
  194         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', [
  195             '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT']),
  196             '{DAV:}displayname' => 'Hello!',
  197         ]);
  198 
  199         $backend->deleteCalendar('bad-id');
  200     }
  201 
  202     /**
  203      * @depends testCreateCalendarAndFetch
  204      * @expectedException \Sabre\DAV\Exception
  205      */
  206     public function testCreateCalendarIncorrectComponentSet()
  207     {
  208         $backend = new PDO($this->pdo);
  209 
  210         //Creating a new calendar
  211         $newId = $backend->createCalendar('principals/user2', 'somerandomid', [
  212             '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => 'blabla',
  213         ]);
  214     }
  215 
  216     public function testCreateCalendarObject()
  217     {
  218         $backend = new PDO($this->pdo);
  219         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  220 
  221         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  222 
  223         $backend->createCalendarObject($returnedId, 'random-id', $object);
  224 
  225         $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
  226 
  227         $row = $result->fetch(\PDO::FETCH_ASSOC);
  228         if (is_resource($row['calendardata'])) {
  229             $row['calendardata'] = stream_get_contents($row['calendardata']);
  230         }
  231 
  232         $this->assertEquals([
  233             'etag' => md5($object),
  234             'size' => strlen($object),
  235             'calendardata' => $object,
  236             'firstoccurence' => strtotime('20120101'),
  237             'lastoccurence' => strtotime('20120101') + (3600 * 24),
  238             'componenttype' => 'VEVENT',
  239         ], $row);
  240     }
  241 
  242     public function testGetMultipleObjects()
  243     {
  244         $backend = new PDO($this->pdo);
  245         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  246 
  247         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  248 
  249         $backend->createCalendarObject($returnedId, 'id-1', $object);
  250         $backend->createCalendarObject($returnedId, 'id-2', $object);
  251 
  252         $check = [
  253             [
  254                 'id' => 1,
  255                 'etag' => '"'.md5($object).'"',
  256                 'uri' => 'id-1',
  257                 'size' => strlen($object),
  258                 'calendardata' => $object,
  259                 'lastmodified' => null,
  260             ],
  261             [
  262                 'id' => 2,
  263                 'etag' => '"'.md5($object).'"',
  264                 'uri' => 'id-2',
  265                 'size' => strlen($object),
  266                 'calendardata' => $object,
  267                 'lastmodified' => null,
  268             ],
  269         ];
  270 
  271         $result = $backend->getMultipleCalendarObjects($returnedId, ['id-1', 'id-2']);
  272 
  273         foreach ($check as $index => $props) {
  274             foreach ($props as $key => $expected) {
  275                 $actual = $result[$index][$key];
  276 
  277                 switch ($key) {
  278                     case 'lastmodified':
  279                         $this->assertInternalType('int', $actual);
  280                         break;
  281                     case 'calendardata':
  282                         if (is_resource($actual)) {
  283                             $actual = stream_get_contents($actual);
  284                         }
  285                         // no break intentional
  286                     default:
  287                         $this->assertEquals($expected, $actual);
  288                 }
  289             }
  290         }
  291     }
  292 
  293     /**
  294      * @depends testGetMultipleObjects
  295      * @expectedException \InvalidArgumentException
  296      */
  297     public function testGetMultipleObjectsBadId()
  298     {
  299         $backend = new PDO($this->pdo);
  300         $backend->getMultipleCalendarObjects('bad-id', ['foo-bar']);
  301     }
  302 
  303     /**
  304      * @expectedException \Sabre\DAV\Exception\BadRequest
  305      * @depends testCreateCalendarObject
  306      */
  307     public function testCreateCalendarObjectNoComponent()
  308     {
  309         $backend = new PDO($this->pdo);
  310         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  311 
  312         $object = "BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nEND:VCALENDAR\r\n";
  313 
  314         $backend->createCalendarObject($returnedId, 'random-id', $object);
  315     }
  316 
  317     /**
  318      * @depends testCreateCalendarObject
  319      */
  320     public function testCreateCalendarObjectDuration()
  321     {
  322         $backend = new PDO($this->pdo);
  323         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  324 
  325         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nDURATION:P2D\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  326 
  327         $backend->createCalendarObject($returnedId, 'random-id', $object);
  328 
  329         $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
  330 
  331         $row = $result->fetch(\PDO::FETCH_ASSOC);
  332         if (is_resource($row['calendardata'])) {
  333             $row['calendardata'] = stream_get_contents($row['calendardata']);
  334         }
  335 
  336         $this->assertEquals([
  337             'etag' => md5($object),
  338             'size' => strlen($object),
  339             'calendardata' => $object,
  340             'firstoccurence' => strtotime('20120101'),
  341             'lastoccurence' => strtotime('20120101') + (3600 * 48),
  342             'componenttype' => 'VEVENT',
  343         ], $row);
  344     }
  345 
  346     /**
  347      * @depends testCreateCalendarObject
  348      * @expectedException \InvalidArgumentException
  349      */
  350     public function testCreateCalendarObjectBadId()
  351     {
  352         $backend = new PDO($this->pdo);
  353         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  354 
  355         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nDURATION:P2D\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  356 
  357         $backend->createCalendarObject('bad-id', 'random-id', $object);
  358     }
  359 
  360     /**
  361      * @depends testCreateCalendarObject
  362      */
  363     public function testCreateCalendarObjectNoDTEND()
  364     {
  365         $backend = new PDO($this->pdo);
  366         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  367 
  368         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  369 
  370         $backend->createCalendarObject($returnedId, 'random-id', $object);
  371 
  372         $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
  373         $row = $result->fetch(\PDO::FETCH_ASSOC);
  374         if (is_resource($row['calendardata'])) {
  375             $row['calendardata'] = stream_get_contents($row['calendardata']);
  376         }
  377 
  378         $this->assertEquals([
  379             'etag' => md5($object),
  380             'size' => strlen($object),
  381             'calendardata' => $object,
  382             'firstoccurence' => strtotime('2012-01-01 10:00:00'),
  383             'lastoccurence' => strtotime('2012-01-01 10:00:00'),
  384             'componenttype' => 'VEVENT',
  385         ], $row);
  386     }
  387 
  388     /**
  389      * @depends testCreateCalendarObject
  390      */
  391     public function testCreateCalendarObjectWithDTEND()
  392     {
  393         $backend = new PDO($this->pdo);
  394         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  395 
  396         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nDTEND:20120101T110000Z\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  397 
  398         $backend->createCalendarObject($returnedId, 'random-id', $object);
  399 
  400         $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
  401         $row = $result->fetch(\PDO::FETCH_ASSOC);
  402         if (is_resource($row['calendardata'])) {
  403             $row['calendardata'] = stream_get_contents($row['calendardata']);
  404         }
  405 
  406         $this->assertEquals([
  407             'etag' => md5($object),
  408             'size' => strlen($object),
  409             'calendardata' => $object,
  410             'firstoccurence' => strtotime('2012-01-01 10:00:00'),
  411             'lastoccurence' => strtotime('2012-01-01 11:00:00'),
  412             'componenttype' => 'VEVENT',
  413         ], $row);
  414     }
  415 
  416     /**
  417      * @depends testCreateCalendarObject
  418      */
  419     public function testCreateCalendarObjectInfiniteRecurrence()
  420     {
  421         $backend = new PDO($this->pdo);
  422         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  423 
  424         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nRRULE:FREQ=DAILY\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  425 
  426         $backend->createCalendarObject($returnedId, 'random-id', $object);
  427 
  428         $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
  429         $row = $result->fetch(\PDO::FETCH_ASSOC);
  430         if (is_resource($row['calendardata'])) {
  431             $row['calendardata'] = stream_get_contents($row['calendardata']);
  432         }
  433 
  434         $this->assertEquals([
  435             'etag' => md5($object),
  436             'size' => strlen($object),
  437             'calendardata' => $object,
  438             'firstoccurence' => strtotime('2012-01-01 10:00:00'),
  439             'lastoccurence' => strtotime(PDO::MAX_DATE),
  440             'componenttype' => 'VEVENT',
  441         ], $row);
  442     }
  443 
  444     /**
  445      * @depends testCreateCalendarObject
  446      */
  447     public function testCreateCalendarObjectEndingRecurrence()
  448     {
  449         $backend = new PDO($this->pdo);
  450         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  451 
  452         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nDTEND;VALUE=DATE-TIME:20120101T110000Z\r\nUID:foo\r\nRRULE:FREQ=DAILY;COUNT=1000\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  453 
  454         $backend->createCalendarObject($returnedId, 'random-id', $object);
  455 
  456         $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
  457         $row = $result->fetch(\PDO::FETCH_ASSOC);
  458         if (is_resource($row['calendardata'])) {
  459             $row['calendardata'] = stream_get_contents($row['calendardata']);
  460         }
  461 
  462         $this->assertEquals([
  463             'etag' => md5($object),
  464             'size' => strlen($object),
  465             'calendardata' => $object,
  466             'firstoccurence' => strtotime('2012-01-01 10:00:00'),
  467             'lastoccurence' => strtotime('2012-01-01 11:00:00') + (3600 * 24 * 999),
  468             'componenttype' => 'VEVENT',
  469         ], $row);
  470     }
  471 
  472     /**
  473      * @depends testCreateCalendarObject
  474      */
  475     public function testCreateCalendarObjectTask()
  476     {
  477         $backend = new PDO($this->pdo);
  478         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  479 
  480         $object = "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nDUE;VALUE=DATE-TIME:20120101T100000Z\r\nEND:VTODO\r\nEND:VCALENDAR\r\n";
  481 
  482         $backend->createCalendarObject($returnedId, 'random-id', $object);
  483 
  484         $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
  485         $row = $result->fetch(\PDO::FETCH_ASSOC);
  486         if (is_resource($row['calendardata'])) {
  487             $row['calendardata'] = stream_get_contents($row['calendardata']);
  488         }
  489 
  490         $this->assertEquals([
  491             'etag' => md5($object),
  492             'size' => strlen($object),
  493             'calendardata' => $object,
  494             'firstoccurence' => null,
  495             'lastoccurence' => null,
  496             'componenttype' => 'VTODO',
  497         ], $row);
  498     }
  499 
  500     /**
  501      * @depends testCreateCalendarObject
  502      */
  503     public function testGetCalendarObjects()
  504     {
  505         $backend = new PDO($this->pdo);
  506         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  507 
  508         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  509         $backend->createCalendarObject($returnedId, 'random-id', $object);
  510 
  511         $data = $backend->getCalendarObjects($returnedId);
  512 
  513         $this->assertEquals(1, count($data));
  514         $data = $data[0];
  515 
  516         $this->assertEquals('random-id', $data['uri']);
  517         $this->assertEquals(strlen($object), $data['size']);
  518     }
  519 
  520     /**
  521      * @depends testGetCalendarObjects
  522      * @expectedException \InvalidArgumentException
  523      */
  524     public function testGetCalendarObjectsBadId()
  525     {
  526         $backend = new PDO($this->pdo);
  527         $backend->getCalendarObjects('bad-id');
  528     }
  529 
  530     /**
  531      * @depends testGetCalendarObjects
  532      * @expectedException \InvalidArgumentException
  533      */
  534     public function testGetCalendarObjectBadId()
  535     {
  536         $backend = new PDO($this->pdo);
  537         $backend->getCalendarObject('bad-id', 'foo-bar');
  538     }
  539 
  540     /**
  541      * @depends testCreateCalendarObject
  542      */
  543     public function testGetCalendarObjectByUID()
  544     {
  545         $backend = new PDO($this->pdo);
  546         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  547 
  548         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  549         $backend->createCalendarObject($returnedId, 'random-id', $object);
  550 
  551         $this->assertNull(
  552             $backend->getCalendarObjectByUID('principals/user2', 'bar')
  553         );
  554         $this->assertEquals(
  555             'somerandomid/random-id',
  556             $backend->getCalendarObjectByUID('principals/user2', 'foo')
  557         );
  558     }
  559 
  560     /**
  561      * @depends testCreateCalendarObject
  562      */
  563     public function testUpdateCalendarObject()
  564     {
  565         $backend = new PDO($this->pdo);
  566         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  567 
  568         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  569         $object2 = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20130101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  570         $backend->createCalendarObject($returnedId, 'random-id', $object);
  571         $backend->updateCalendarObject($returnedId, 'random-id', $object2);
  572 
  573         $data = $backend->getCalendarObject($returnedId, 'random-id');
  574 
  575         if (is_resource($data['calendardata'])) {
  576             $data['calendardata'] = stream_get_contents($data['calendardata']);
  577         }
  578 
  579         $this->assertEquals($object2, $data['calendardata']);
  580         $this->assertEquals('random-id', $data['uri']);
  581     }
  582 
  583     /**
  584      * @depends testUpdateCalendarObject
  585      * @expectedException \InvalidArgumentException
  586      */
  587     public function testUpdateCalendarObjectBadId()
  588     {
  589         $backend = new PDO($this->pdo);
  590         $backend->updateCalendarObject('bad-id', 'object-id', 'objectdata');
  591     }
  592 
  593     /**
  594      * @depends testCreateCalendarObject
  595      */
  596     public function testDeleteCalendarObject()
  597     {
  598         $backend = new PDO($this->pdo);
  599         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  600 
  601         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  602         $backend->createCalendarObject($returnedId, 'random-id', $object);
  603         $backend->deleteCalendarObject($returnedId, 'random-id');
  604 
  605         $data = $backend->getCalendarObject($returnedId, 'random-id');
  606         $this->assertNull($data);
  607     }
  608 
  609     /**
  610      * @depends testDeleteCalendarObject
  611      * @expectedException \InvalidArgumentException
  612      */
  613     public function testDeleteCalendarObjectBadId()
  614     {
  615         $backend = new PDO($this->pdo);
  616         $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
  617 
  618         $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
  619         $backend->createCalendarObject($returnedId, 'random-id', $object);
  620         $backend->deleteCalendarObject('bad-id', 'random-id');
  621     }
  622 
  623     public function testCalendarQueryNoResult()
  624     {
  625         $abstract = new PDO($this->pdo);
  626         $filters = [
  627             'name' => 'VCALENDAR',
  628             'comp-filters' => [
  629                 [
  630                     'name' => 'VJOURNAL',
  631                     'comp-filters' => [],
  632                     'prop-filters' => [],
  633                     'is-not-defined' => false,
  634                     'time-range' => null,
  635                 ],
  636             ],
  637             'prop-filters' => [],
  638             'is-not-defined' => false,
  639             'time-range' => null,
  640         ];
  641 
  642         $this->assertEquals([
  643         ], $abstract->calendarQuery([1, 1], $filters));
  644     }
  645 
  646     /**
  647      * @expectedException \InvalidArgumentException
  648      * @depends testCalendarQueryNoResult
  649      */
  650     public function testCalendarQueryBadId()
  651     {
  652         $abstract = new PDO($this->pdo);
  653         $filters = [
  654             'name' => 'VCALENDAR',
  655             'comp-filters' => [
  656                 [
  657                     'name' => 'VJOURNAL',
  658                     'comp-filters' => [],
  659                     'prop-filters' => [],
  660                     'is-not-defined' => false,
  661                     'time-range' => null,
  662                 ],
  663             ],
  664             'prop-filters' => [],
  665             'is-not-defined' => false,
  666             'time-range' => null,
  667         ];
  668 
  669         $abstract->calendarQuery('bad-id', $filters);
  670     }
  671 
  672     public function testCalendarQueryTodo()
  673     {
  674         $backend = new PDO($this->pdo);
  675         $backend->createCalendarObject([1, 1], 'todo', "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
  676         $backend->createCalendarObject([1, 1], 'event', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
  677 
  678         $filters = [
  679             'name' => 'VCALENDAR',
  680             'comp-filters' => [
  681                 [
  682                     'name' => 'VTODO',
  683                     'comp-filters' => [],
  684                     'prop-filters' => [],
  685                     'is-not-defined' => false,
  686                     'time-range' => null,
  687                 ],
  688             ],
  689             'prop-filters' => [],
  690             'is-not-defined' => false,
  691             'time-range' => null,
  692         ];
  693 
  694         $this->assertEquals([
  695             'todo',
  696         ], $backend->calendarQuery([1, 1], $filters));
  697     }
  698 
  699     public function testCalendarQueryTodoNotMatch()
  700     {
  701         $backend = new PDO($this->pdo);
  702         $backend->createCalendarObject([1, 1], 'todo', "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
  703         $backend->createCalendarObject([1, 1], 'event', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
  704 
  705         $filters = [
  706             'name' => 'VCALENDAR',
  707             'comp-filters' => [
  708                 [
  709                     'name' => 'VTODO',
  710                     'comp-filters' => [],
  711                     'prop-filters' => [
  712                         [
  713                             'name' => 'summary',
  714                             'text-match' => null,
  715                             'time-range' => null,
  716                             'param-filters' => [],
  717                             'is-not-defined' => false,
  718                         ],
  719                     ],
  720                     'is-not-defined' => false,
  721                     'time-range' => null,
  722                 ],
  723             ],
  724             'prop-filters' => [],
  725             'is-not-defined' => false,
  726             'time-range' => null,
  727         ];
  728 
  729         $this->assertEquals([
  730         ], $backend->calendarQuery([1, 1], $filters));
  731     }
  732 
  733     public function testCalendarQueryNoFilter()
  734     {
  735         $backend = new PDO($this->pdo);
  736         $backend->createCalendarObject([1, 1], 'todo', "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
  737         $backend->createCalendarObject([1, 1], 'event', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
  738 
  739         $filters = [
  740             'name' => 'VCALENDAR',
  741             'comp-filters' => [],
  742             'prop-filters' => [],
  743             'is-not-defined' => false,
  744             'time-range' => null,
  745         ];
  746 
  747         $result = $backend->calendarQuery([1, 1], $filters);
  748         $this->assertTrue(in_array('todo', $result));
  749         $this->assertTrue(in_array('event', $result));
  750     }
  751 
  752     public function testCalendarQueryTimeRange()
  753     {
  754         $backend = new PDO($this->pdo);
  755         $backend->createCalendarObject([1, 1], 'todo', "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
  756         $backend->createCalendarObject([1, 1], 'event', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
  757         $backend->createCalendarObject([1, 1], 'event2', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
  758 
  759         $filters = [
  760             'name' => 'VCALENDAR',
  761             'comp-filters' => [
  762                 [
  763                     'name' => 'VEVENT',
  764                     'comp-filters' => [],
  765                     'prop-filters' => [],
  766                     'is-not-defined' => false,
  767                     'time-range' => [
  768                         'start' => new \DateTime('20120103'),
  769                         'end' => new \DateTime('20120104'),
  770                     ],
  771                 ],
  772             ],
  773             'prop-filters' => [],
  774             'is-not-defined' => false,
  775             'time-range' => null,
  776         ];
  777 
  778         $this->assertEquals([
  779             'event2',
  780         ], $backend->calendarQuery([1, 1], $filters));
  781     }
  782 
  783     public function testCalendarQueryTimeRangeNoEnd()
  784     {
  785         $backend = new PDO($this->pdo);
  786         $backend->createCalendarObject([1, 1], 'todo', "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
  787         $backend->createCalendarObject([1, 1], 'event', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
  788         $backend->createCalendarObject([1, 1], 'event2', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
  789 
  790         $filters = [
  791             'name' => 'VCALENDAR',
  792             'comp-filters' => [
  793                 [
  794                     'name' => 'VEVENT',
  795                     'comp-filters' => [],
  796                     'prop-filters' => [],
  797                     'is-not-defined' => false,
  798                     'time-range' => [
  799                         'start' => new \DateTime('20120102'),
  800                         'end' => null,
  801                     ],
  802                 ],
  803             ],
  804             'prop-filters' => [],
  805             'is-not-defined' => false,
  806             'time-range' => null,
  807         ];
  808 
  809         $this->assertEquals([
  810             'event2',
  811         ], $backend->calendarQuery([1, 1], $filters));
  812     }
  813 
  814     public function testGetChanges()
  815     {
  816         $backend = new PDO($this->pdo);
  817         $id = $backend->createCalendar(
  818             'principals/user1',
  819             'bla',
  820             []
  821         );
  822         $result = $backend->getChangesForCalendar($id, null, 1);
  823 
  824         $this->assertEquals([
  825             'syncToken' => 1,
  826             'modified' => [],
  827             'deleted' => [],
  828             'added' => [],
  829         ], $result);
  830 
  831         $currentToken = $result['syncToken'];
  832 
  833         $dummyTodo = "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n";
  834 
  835         $backend->createCalendarObject($id, 'todo1.ics', $dummyTodo);
  836         $backend->createCalendarObject($id, 'todo2.ics', $dummyTodo);
  837         $backend->createCalendarObject($id, 'todo3.ics', $dummyTodo);
  838         $backend->updateCalendarObject($id, 'todo1.ics', $dummyTodo);
  839         $backend->deleteCalendarObject($id, 'todo2.ics');
  840 
  841         $result = $backend->getChangesForCalendar($id, $currentToken, 1);
  842 
  843         $this->assertEquals([
  844             'syncToken' => 6,
  845             'modified' => ['todo1.ics'],
  846             'deleted' => ['todo2.ics'],
  847             'added' => ['todo3.ics'],
  848         ], $result);
  849 
  850         $result = $backend->getChangesForCalendar($id, null, 1);
  851 
  852         $this->assertEquals([
  853             'syncToken' => 6,
  854             'modified' => [],
  855             'deleted' => [],
  856             'added' => ['todo1.ics', 'todo3.ics'],
  857         ], $result);
  858     }
  859 
  860     /**
  861      * @depends testGetChanges
  862      * @expectedException \InvalidArgumentException
  863      */
  864     public function testGetChangesBadId()
  865     {
  866         $backend = new PDO($this->pdo);
  867         $id = $backend->createCalendar(
  868             'principals/user1',
  869             'bla',
  870             []
  871         );
  872         $backend->getChangesForCalendar('bad-id', null, 1);
  873     }
  874 
  875     public function testCreateSubscriptions()
  876     {
  877         $props = [
  878             '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal.ics', false),
  879             '{DAV:}displayname' => 'cal',
  880             '{http://apple.com/ns/ical/}refreshrate' => 'P1W',
  881             '{http://apple.com/ns/ical/}calendar-color' => '#FF00FFFF',
  882             '{http://calendarserver.org/ns/}subscribed-strip-todos' => true,
  883             //'{http://calendarserver.org/ns/}subscribed-strip-alarms' => true,
  884             '{http://calendarserver.org/ns/}subscribed-strip-attachments' => true,
  885         ];
  886 
  887         $backend = new PDO($this->pdo);
  888         $backend->createSubscription('principals/user1', 'sub1', $props);
  889 
  890         $subs = $backend->getSubscriptionsForUser('principals/user1');
  891 
  892         $expected = $props;
  893         $expected['id'] = 1;
  894         $expected['uri'] = 'sub1';
  895         $expected['principaluri'] = 'principals/user1';
  896 
  897         unset($expected['{http://calendarserver.org/ns/}source']);
  898         $expected['source'] = 'http://example.org/cal.ics';
  899 
  900         $this->assertEquals(1, count($subs));
  901         foreach ($expected as $k => $v) {
  902             $this->assertEquals($subs[0][$k], $expected[$k]);
  903         }
  904     }
  905 
  906     /**
  907      * @expectedException \Sabre\DAV\Exception\Forbidden
  908      */
  909     public function testCreateSubscriptionFail()
  910     {
  911         $props = [
  912         ];
  913 
  914         $backend = new PDO($this->pdo);
  915         $backend->createSubscription('principals/user1', 'sub1', $props);
  916     }
  917 
  918     public function testUpdateSubscriptions()
  919     {
  920         $props = [
  921             '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal.ics', false),
  922             '{DAV:}displayname' => 'cal',
  923             '{http://apple.com/ns/ical/}refreshrate' => 'P1W',
  924             '{http://apple.com/ns/ical/}calendar-color' => '#FF00FFFF',
  925             '{http://calendarserver.org/ns/}subscribed-strip-todos' => true,
  926             //'{http://calendarserver.org/ns/}subscribed-strip-alarms' => true,
  927             '{http://calendarserver.org/ns/}subscribed-strip-attachments' => true,
  928         ];
  929 
  930         $backend = new PDO($this->pdo);
  931         $backend->createSubscription('principals/user1', 'sub1', $props);
  932 
  933         $newProps = [
  934             '{DAV:}displayname' => 'new displayname',
  935             '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal2.ics', false),
  936         ];
  937 
  938         $propPatch = new DAV\PropPatch($newProps);
  939         $backend->updateSubscription(1, $propPatch);
  940         $result = $propPatch->commit();
  941 
  942         $this->assertTrue($result);
  943 
  944         $subs = $backend->getSubscriptionsForUser('principals/user1');
  945 
  946         $expected = array_merge($props, $newProps);
  947         $expected['id'] = 1;
  948         $expected['uri'] = 'sub1';
  949         $expected['principaluri'] = 'principals/user1';
  950 
  951         unset($expected['{http://calendarserver.org/ns/}source']);
  952         $expected['source'] = 'http://example.org/cal2.ics';
  953 
  954         $this->assertEquals(1, count($subs));
  955         foreach ($expected as $k => $v) {
  956             $this->assertEquals($subs[0][$k], $expected[$k]);
  957         }
  958     }
  959 
  960     public function testUpdateSubscriptionsFail()
  961     {
  962         $props = [
  963             '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal.ics', false),
  964             '{DAV:}displayname' => 'cal',
  965             '{http://apple.com/ns/ical/}refreshrate' => 'P1W',
  966             '{http://apple.com/ns/ical/}calendar-color' => '#FF00FFFF',
  967             '{http://calendarserver.org/ns/}subscribed-strip-todos' => true,
  968             //'{http://calendarserver.org/ns/}subscribed-strip-alarms' => true,
  969             '{http://calendarserver.org/ns/}subscribed-strip-attachments' => true,
  970         ];
  971 
  972         $backend = new PDO($this->pdo);
  973         $backend->createSubscription('principals/user1', 'sub1', $props);
  974 
  975         $propPatch = new DAV\PropPatch([
  976             '{DAV:}displayname' => 'new displayname',
  977             '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal2.ics', false),
  978             '{DAV:}unknown' => 'foo',
  979         ]);
  980 
  981         $backend->updateSubscription(1, $propPatch);
  982         $propPatch->commit();
  983 
  984         $this->assertEquals([
  985             '{DAV:}unknown' => 403,
  986             '{DAV:}displayname' => 424,
  987             '{http://calendarserver.org/ns/}source' => 424,
  988         ], $propPatch->getResult());
  989     }
  990 
  991     public function testDeleteSubscriptions()
  992     {
  993         $props = [
  994             '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal.ics', false),
  995             '{DAV:}displayname' => 'cal',
  996             '{http://apple.com/ns/ical/}refreshrate' => 'P1W',
  997             '{http://apple.com/ns/ical/}calendar-color' => '#FF00FFFF',
  998             '{http://calendarserver.org/ns/}subscribed-strip-todos' => true,
  999             //'{http://calendarserver.org/ns/}subscribed-strip-alarms' => true,
 1000             '{http://calendarserver.org/ns/}subscribed-strip-attachments' => true,
 1001         ];
 1002 
 1003         $backend = new PDO($this->pdo);
 1004         $backend->createSubscription('principals/user1', 'sub1', $props);
 1005 
 1006         $newProps = [
 1007             '{DAV:}displayname' => 'new displayname',
 1008             '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal2.ics', false),
 1009         ];
 1010 
 1011         $backend->deleteSubscription(1);
 1012 
 1013         $subs = $backend->getSubscriptionsForUser('principals/user1');
 1014         $this->assertEquals(0, count($subs));
 1015     }
 1016 
 1017     public function testSchedulingMethods()
 1018     {
 1019         $backend = new PDO($this->pdo);
 1020 
 1021         $calData = "BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n";
 1022 
 1023         $backend->createSchedulingObject(
 1024             'principals/user1',
 1025             'schedule1.ics',
 1026             $calData
 1027         );
 1028 
 1029         $calDataResource = "BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n";
 1030         $stream = fopen('data://text/plain,'.$calData, 'r');
 1031 
 1032         $backend->createSchedulingObject(
 1033             'principals/user1',
 1034             'schedule1-resource.ics',
 1035             $stream
 1036         );
 1037 
 1038         $expected = [
 1039             'calendardata' => $calData,
 1040             'uri' => 'schedule1.ics',
 1041             'etag' => '"'.md5($calData).'"',
 1042             'size' => strlen($calData),
 1043         ];
 1044 
 1045         $expectedResource = [
 1046             'calendardata' => $calDataResource,
 1047             'uri' => 'schedule1-resource.ics',
 1048             'etag' => '"'.md5($calDataResource).'"',
 1049             'size' => strlen($calDataResource),
 1050         ];
 1051 
 1052         $result = $backend->getSchedulingObject('principals/user1', 'schedule1.ics');
 1053         foreach ($expected as $k => $v) {
 1054             $this->assertArrayHasKey($k, $result);
 1055             if (is_resource($result[$k])) {
 1056                 $result[$k] = stream_get_contents($result[$k]);
 1057             }
 1058             $this->assertEquals($v, $result[$k]);
 1059         }
 1060 
 1061         $resultResource = $backend->getSchedulingObject('principals/user1', 'schedule1-resource.ics');
 1062         foreach ($expected as $k => $v) {
 1063             $this->assertArrayHasKey($k, $result);
 1064             if (is_resource($result[$k])) {
 1065                 $result[$k] = stream_get_contents($result[$k]);
 1066             }
 1067             $this->assertEquals($v, $result[$k]);
 1068         }
 1069 
 1070         $backend->deleteSchedulingObject('principals/user1', 'schedule1-resource.ics');
 1071 
 1072         $results = $backend->getSchedulingObjects('principals/user1');
 1073 
 1074         $this->assertEquals(1, count($results));
 1075         $result = $results[0];
 1076         foreach ($expected as $k => $v) {
 1077             if (is_resource($result[$k])) {
 1078                 $result[$k] = stream_get_contents($result[$k]);
 1079             }
 1080             $this->assertEquals($v, $result[$k]);
 1081         }
 1082 
 1083         $backend->deleteSchedulingObject('principals/user1', 'schedule1.ics');
 1084         $result = $backend->getSchedulingObject('principals/user1', 'schedule1.ics');
 1085 
 1086         $this->assertNull($result);
 1087     }
 1088 
 1089     public function testGetInvites()
 1090     {
 1091         $backend = new PDO($this->pdo);
 1092 
 1093         // creating a new calendar
 1094         $backend->createCalendar('principals/user1', 'somerandomid', []);
 1095         $calendar = $backend->getCalendarsForUser('principals/user1')[0];
 1096 
 1097         $result = $backend->getInvites($calendar['id']);
 1098         $expected = [
 1099             new Sharee([
 1100                 'href' => 'principals/user1',
 1101                 'principal' => 'principals/user1',
 1102                 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
 1103                 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
 1104             ]),
 1105         ];
 1106 
 1107         $this->assertEquals($expected, $result);
 1108     }
 1109 
 1110     /**
 1111      * @depends testGetInvites
 1112      * @expectedException \InvalidArgumentException
 1113      */
 1114     public function testGetInvitesBadId()
 1115     {
 1116         $backend = new PDO($this->pdo);
 1117 
 1118         // creating a new calendar
 1119         $backend->createCalendar('principals/user1', 'somerandomid', []);
 1120         $calendar = $backend->getCalendarsForUser('principals/user1')[0];
 1121 
 1122         $backend->getInvites('bad-id');
 1123     }
 1124 
 1125     /**
 1126      * @depends testCreateCalendarAndFetch
 1127      */
 1128     public function testUpdateInvites()
 1129     {
 1130         $backend = new PDO($this->pdo);
 1131 
 1132         // creating a new calendar
 1133         $backend->createCalendar('principals/user1', 'somerandomid', []);
 1134         $calendar = $backend->getCalendarsForUser('principals/user1')[0];
 1135 
 1136         $ownerSharee = new Sharee([
 1137             'href' => 'principals/user1',
 1138             'principal' => 'principals/user1',
 1139             'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
 1140             'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
 1141         ]);
 1142 
 1143         // Add a new invite
 1144         $backend->updateInvites(
 1145             $calendar['id'],
 1146             [
 1147                 new Sharee([
 1148                     'href' => 'mailto:user@example.org',
 1149                     'principal' => 'principals/user2',
 1150                     'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
 1151                     'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
 1152                     'properties' => ['{DAV:}displayname' => 'User 2'],
 1153                 ]),
 1154             ]
 1155         );
 1156 
 1157         $result = $backend->getInvites($calendar['id']);
 1158         $expected = [
 1159             $ownerSharee,
 1160             new Sharee([
 1161                 'href' => 'mailto:user@example.org',
 1162                 'principal' => 'principals/user2',
 1163                 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
 1164                 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
 1165                 'properties' => [
 1166                     '{DAV:}displayname' => 'User 2',
 1167                 ],
 1168             ]),
 1169         ];
 1170         $this->assertEquals($expected, $result);
 1171 
 1172         // Checking calendar_instances too
 1173         $expectedCalendar = [
 1174             'id' => [1, 2],
 1175             'principaluri' => 'principals/user2',
 1176             '{http://calendarserver.org/ns/}getctag' => 'http://sabre.io/ns/sync/1',
 1177             '{http://sabredav.org/ns}sync-token' => '1',
 1178             'share-access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
 1179             'read-only' => true,
 1180             'share-resource-uri' => '/ns/share/1',
 1181         ];
 1182         $calendars = $backend->getCalendarsForUser('principals/user2');
 1183 
 1184         foreach ($expectedCalendar as $k => $v) {
 1185             $this->assertEquals(
 1186                 $v,
 1187                 $calendars[0][$k],
 1188                 'Key '.$k.' in calendars array did not have the expected value.'
 1189             );
 1190         }
 1191 
 1192         // Updating an invite
 1193         $backend->updateInvites(
 1194             $calendar['id'],
 1195             [
 1196                 new Sharee([
 1197                     'href' => 'mailto:user@example.org',
 1198                     'principal' => 'principals/user2',
 1199                     'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE,
 1200                     'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
 1201                 ]),
 1202             ]
 1203         );
 1204 
 1205         $result = $backend->getInvites($calendar['id']);
 1206         $expected = [
 1207             $ownerSharee,
 1208             new Sharee([
 1209                 'href' => 'mailto:user@example.org',
 1210                 'principal' => 'principals/user2',
 1211                 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE,
 1212                 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
 1213                 'properties' => [
 1214                     '{DAV:}displayname' => 'User 2',
 1215                 ],
 1216             ]),
 1217         ];
 1218         $this->assertEquals($expected, $result);
 1219 
 1220         // Removing an invite
 1221         $backend->updateInvites(
 1222             $calendar['id'],
 1223             [
 1224                 new Sharee([
 1225                     'href' => 'mailto:user@example.org',
 1226                     'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS,
 1227                 ]),
 1228             ]
 1229         );
 1230 
 1231         $result = $backend->getInvites($calendar['id']);
 1232         $expected = [
 1233             $ownerSharee,
 1234         ];
 1235         $this->assertEquals($expected, $result);
 1236 
 1237         // Preventing the owner share from being removed
 1238         $backend->updateInvites(
 1239             $calendar['id'],
 1240             [
 1241                 new Sharee([
 1242                     'href' => 'principals/user2',
 1243                     'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS,
 1244                 ]),
 1245             ]
 1246         );
 1247 
 1248         $result = $backend->getInvites($calendar['id']);
 1249         $expected = [
 1250             new Sharee([
 1251                 'href' => 'principals/user1',
 1252                 'principal' => 'principals/user1',
 1253                 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
 1254                 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
 1255             ]),
 1256         ];
 1257         $this->assertEquals($expected, $result);
 1258     }
 1259 
 1260     /**
 1261      * @depends testUpdateInvites
 1262      * @expectedException \InvalidArgumentException
 1263      */
 1264     public function testUpdateInvitesBadId()
 1265     {
 1266         $backend = new PDO($this->pdo);
 1267         // Add a new invite
 1268         $backend->updateInvites(
 1269             'bad-id',
 1270             []
 1271         );
 1272     }
 1273 
 1274     /**
 1275      * @depends testUpdateInvites
 1276      */
 1277     public function testUpdateInvitesNoPrincipal()
 1278     {
 1279         $backend = new PDO($this->pdo);
 1280 
 1281         // creating a new calendar
 1282         $backend->createCalendar('principals/user1', 'somerandomid', []);
 1283         $calendar = $backend->getCalendarsForUser('principals/user1')[0];
 1284 
 1285         $ownerSharee = new Sharee([
 1286             'href' => 'principals/user1',
 1287             'principal' => 'principals/user1',
 1288             'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
 1289             'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
 1290         ]);
 1291 
 1292         // Add a new invite
 1293         $backend->updateInvites(
 1294             $calendar['id'],
 1295             [
 1296                 new Sharee([
 1297                     'href' => 'mailto:user@example.org',
 1298                     'principal' => null,
 1299                     'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
 1300                     'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
 1301                     'properties' => ['{DAV:}displayname' => 'User 2'],
 1302                 ]),
 1303             ]
 1304         );
 1305 
 1306         $result = $backend->getInvites($calendar['id']);
 1307         $expected = [
 1308             $ownerSharee,
 1309             new Sharee([
 1310                 'href' => 'mailto:user@example.org',
 1311                 'principal' => null,
 1312                 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
 1313                 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_INVALID,
 1314                 'properties' => [
 1315                     '{DAV:}displayname' => 'User 2',
 1316                 ],
 1317             ]),
 1318         ];
 1319         $this->assertEquals($expected, $result, null, 0.0, 10, true); // Last argument is $canonicalize = true, which allows us to compare, ignoring the order, because it's different between MySQL and Sqlite.
 1320     }
 1321 
 1322     /**
 1323      * @depends testUpdateInvites
 1324      */
 1325     public function testDeleteSharedCalendar()
 1326     {
 1327         $backend = new PDO($this->pdo);
 1328 
 1329         // creating a new calendar
 1330         $backend->createCalendar('principals/user1', 'somerandomid', []);
 1331         $calendar = $backend->getCalendarsForUser('principals/user1')[0];
 1332 
 1333         $ownerSharee = new Sharee([
 1334             'href' => 'principals/user1',
 1335             'principal' => 'principals/user1',
 1336             'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
 1337             'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
 1338         ]);
 1339 
 1340         // Add a new invite
 1341         $backend->updateInvites(
 1342             $calendar['id'],
 1343             [
 1344                 new Sharee([
 1345                     'href' => 'mailto:user@example.org',
 1346                     'principal' => 'principals/user2',
 1347                     'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
 1348                     'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
 1349                     'properties' => ['{DAV:}displayname' => 'User 2'],
 1350                 ]),
 1351             ]
 1352         );
 1353 
 1354         $expectedCalendar = [
 1355             'id' => [1, 2],
 1356             'principaluri' => 'principals/user2',
 1357             '{http://calendarserver.org/ns/}getctag' => 'http://sabre.io/ns/sync/1',
 1358             '{http://sabredav.org/ns}sync-token' => '1',
 1359             'share-access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
 1360             'read-only' => true,
 1361             'share-resource-uri' => '/ns/share/1',
 1362         ];
 1363         $calendars = $backend->getCalendarsForUser('principals/user2');
 1364 
 1365         foreach ($expectedCalendar as $k => $v) {
 1366             $this->assertEquals(
 1367                 $v,
 1368                 $calendars[0][$k],
 1369                 'Key '.$k.' in calendars array did not have the expected value.'
 1370             );
 1371         }
 1372 
 1373         // Removing the shared calendar.
 1374         $backend->deleteCalendar($calendars[0]['id']);
 1375 
 1376         $this->assertEquals(
 1377             [],
 1378             $backend->getCalendarsForUser('principals/user2')
 1379         );
 1380 
 1381         $result = $backend->getInvites($calendar['id']);
 1382         $expected = [
 1383             new Sharee([
 1384                 'href' => 'principals/user1',
 1385                 'principal' => 'principals/user1',
 1386                 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
 1387                 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
 1388             ]),
 1389         ];
 1390         $this->assertEquals($expected, $result);
 1391     }
 1392 
 1393     /**
 1394      * @expectedException \Sabre\DAV\Exception\NotImplemented
 1395      */
 1396     public function testSetPublishStatus()
 1397     {
 1398         $backend = new PDO($this->pdo);
 1399         $backend->setPublishStatus([1, 1], true);
 1400     }
 1401 }