"Fossies" - the Fresh Open Source Software Archive

Member "dav-4.0.3/tests/Sabre/CalDAV/PluginTest.php" (10 Jan 2020, 38049 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 "PluginTest.php": 4.0.2_vs_4.0.3.

    1 <?php
    2 
    3 declare(strict_types=1);
    4 
    5 namespace Sabre\CalDAV;
    6 
    7 use DateTime;
    8 use DateTimeZone;
    9 use Sabre\DAV;
   10 use Sabre\DAVACL;
   11 use Sabre\HTTP;
   12 
   13 class PluginTest extends \PHPUnit\Framework\TestCase
   14 {
   15     /**
   16      * @var DAV\Server
   17      */
   18     protected $server;
   19     /**
   20      * @var Plugin
   21      */
   22     protected $plugin;
   23     protected $response;
   24     /**
   25      * @var Backend\PDO
   26      */
   27     protected $caldavBackend;
   28 
   29     public function setup()
   30     {
   31         $caldavNS = '{urn:ietf:params:xml:ns:caldav}';
   32 
   33         $this->caldavBackend = new Backend\Mock([
   34             [
   35                 'id' => 1,
   36                 'uri' => 'UUID-123467',
   37                 'principaluri' => 'principals/user1',
   38                 '{DAV:}displayname' => 'user1 calendar',
   39                 $caldavNS.'calendar-description' => 'Calendar description',
   40                 '{http://apple.com/ns/ical/}calendar-order' => '1',
   41                 '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
   42                 $caldavNS.'supported-calendar-component-set' => new Xml\Property\SupportedCalendarComponentSet(['VEVENT', 'VTODO']),
   43             ],
   44             [
   45                 'id' => 2,
   46                 'uri' => 'UUID-123468',
   47                 'principaluri' => 'principals/user1',
   48                 '{DAV:}displayname' => 'user1 calendar2',
   49                 $caldavNS.'calendar-description' => 'Calendar description',
   50                 '{http://apple.com/ns/ical/}calendar-order' => '1',
   51                 '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
   52                 $caldavNS.'supported-calendar-component-set' => new Xml\Property\SupportedCalendarComponentSet(['VEVENT', 'VTODO']),
   53             ],
   54         ], [
   55             1 => [
   56                 'UUID-2345' => [
   57                     'calendardata' => TestUtil::getTestCalendarData(),
   58                 ],
   59             ],
   60         ]);
   61         $principalBackend = new DAVACL\PrincipalBackend\Mock();
   62         $principalBackend->setGroupMemberSet('principals/admin/calendar-proxy-read', ['principals/user1']);
   63         $principalBackend->setGroupMemberSet('principals/admin/calendar-proxy-write', ['principals/user1']);
   64         $principalBackend->addPrincipal([
   65             'uri' => 'principals/admin/calendar-proxy-read',
   66         ]);
   67         $principalBackend->addPrincipal([
   68             'uri' => 'principals/admin/calendar-proxy-write',
   69         ]);
   70 
   71         $calendars = new CalendarRoot($principalBackend, $this->caldavBackend);
   72         $principals = new Principal\Collection($principalBackend);
   73 
   74         $root = new DAV\SimpleCollection('root');
   75         $root->addChild($calendars);
   76         $root->addChild($principals);
   77 
   78         $this->server = new DAV\Server($root);
   79         $this->server->sapi = new HTTP\SapiMock();
   80         $this->server->debugExceptions = true;
   81         $this->server->setBaseUri('/');
   82         $this->plugin = new Plugin();
   83         $this->server->addPlugin($this->plugin);
   84 
   85         // Adding ACL plugin
   86         $aclPlugin = new DAVACL\Plugin();
   87         $aclPlugin->allowUnauthenticatedAccess = false;
   88         $this->server->addPlugin($aclPlugin);
   89 
   90         // Adding Auth plugin, and ensuring that we are logged in.
   91         $authBackend = new DAV\Auth\Backend\Mock();
   92         $authBackend->setPrincipal('principals/user1');
   93         $authPlugin = new DAV\Auth\Plugin($authBackend);
   94         $authPlugin->beforeMethod(new \Sabre\HTTP\Request('GET', '/'), new \Sabre\HTTP\Response());
   95         $this->server->addPlugin($authPlugin);
   96 
   97         // This forces a login
   98         $authPlugin->beforeMethod(new HTTP\Request('GET', '/'), new HTTP\Response());
   99 
  100         $this->response = new HTTP\ResponseMock();
  101         $this->server->httpResponse = $this->response;
  102     }
  103 
  104     public function testSimple()
  105     {
  106         $this->assertEquals(['MKCALENDAR'], $this->plugin->getHTTPMethods('calendars/user1/randomnewcalendar'));
  107         $this->assertEquals(['calendar-access', 'calendar-proxy'], $this->plugin->getFeatures());
  108         $this->assertEquals(
  109             'caldav',
  110             $this->plugin->getPluginInfo()['name']
  111         );
  112     }
  113 
  114     public function testUnknownMethodPassThrough()
  115     {
  116         $request = new HTTP\Request('MKBREAKFAST', '/');
  117 
  118         $this->server->httpRequest = $request;
  119         $this->server->exec();
  120 
  121         $this->assertEquals(501, $this->response->status, 'Incorrect status returned. Full response body:'.$this->response->getBodyAsString());
  122     }
  123 
  124     public function testGetWithoutContentType()
  125     {
  126         $request = new HTTP\Request('GET', '/');
  127         $this->plugin->httpAfterGet($request, $this->response);
  128         $this->assertTrue(true);
  129     }
  130 
  131     public function testReportPassThrough()
  132     {
  133         $request = new HTTP\Request('REPORT', '/', ['Content-Type' => 'application/xml']);
  134         $request->setBody('<?xml version="1.0"?><s:somereport xmlns:s="http://www.rooftopsolutions.nl/NS/example" />');
  135 
  136         $this->server->httpRequest = $request;
  137         $this->server->exec();
  138 
  139         $this->assertEquals(415, $this->response->status);
  140     }
  141 
  142     public function testMkCalendarBadLocation()
  143     {
  144         $request = new HTTP\Request('MKCALENDAR', '/blabla');
  145 
  146         $body = '<?xml version="1.0" encoding="utf-8" ?>
  147    <C:mkcalendar xmlns:D="DAV:"
  148                  xmlns:C="urn:ietf:params:xml:ns:caldav">
  149      <D:set>
  150        <D:prop>
  151          <D:displayname>Lisa\'s Events</D:displayname>
  152          <C:calendar-description xml:lang="en"
  153    >Calendar restricted to events.</C:calendar-description>
  154          <C:supported-calendar-component-set>
  155            <C:comp name="VEVENT"/>
  156          </C:supported-calendar-component-set>
  157          <C:calendar-timezone><![CDATA[BEGIN:VCALENDAR
  158    PRODID:-//Example Corp.//CalDAV Client//EN
  159    VERSION:2.0
  160    BEGIN:VTIMEZONE
  161    TZID:US-Eastern
  162    LAST-MODIFIED:19870101T000000Z
  163    BEGIN:STANDARD
  164    DTSTART:19671029T020000
  165    RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
  166    TZOFFSETFROM:-0400
  167    TZOFFSETTO:-0500
  168    TZNAME:Eastern Standard Time (US & Canada)
  169    END:STANDARD
  170    BEGIN:DAYLIGHT
  171    DTSTART:19870405T020000
  172    RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
  173    TZOFFSETFROM:-0500
  174    TZOFFSETTO:-0400
  175    TZNAME:Eastern Daylight Time (US & Canada)
  176    END:DAYLIGHT
  177    END:VTIMEZONE
  178    END:VCALENDAR
  179    ]]></C:calendar-timezone>
  180        </D:prop>
  181      </D:set>
  182    </C:mkcalendar>';
  183 
  184         $request->setBody($body);
  185         $this->server->httpRequest = $request;
  186         $this->server->exec();
  187 
  188         $this->assertEquals(403, $this->response->status);
  189     }
  190 
  191     public function testMkCalendarNoParentNode()
  192     {
  193         $request = new HTTP\Request('MKCALENDAR', '/doesntexist/calendar');
  194 
  195         $body = '<?xml version="1.0" encoding="utf-8" ?>
  196    <C:mkcalendar xmlns:D="DAV:"
  197                  xmlns:C="urn:ietf:params:xml:ns:caldav">
  198      <D:set>
  199        <D:prop>
  200          <D:displayname>Lisa\'s Events</D:displayname>
  201          <C:calendar-description xml:lang="en"
  202    >Calendar restricted to events.</C:calendar-description>
  203          <C:supported-calendar-component-set>
  204            <C:comp name="VEVENT"/>
  205          </C:supported-calendar-component-set>
  206          <C:calendar-timezone><![CDATA[BEGIN:VCALENDAR
  207    PRODID:-//Example Corp.//CalDAV Client//EN
  208    VERSION:2.0
  209    BEGIN:VTIMEZONE
  210    TZID:US-Eastern
  211    LAST-MODIFIED:19870101T000000Z
  212    BEGIN:STANDARD
  213    DTSTART:19671029T020000
  214    RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
  215    TZOFFSETFROM:-0400
  216    TZOFFSETTO:-0500
  217    TZNAME:Eastern Standard Time (US & Canada)
  218    END:STANDARD
  219    BEGIN:DAYLIGHT
  220    DTSTART:19870405T020000
  221    RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
  222    TZOFFSETFROM:-0500
  223    TZOFFSETTO:-0400
  224    TZNAME:Eastern Daylight Time (US & Canada)
  225    END:DAYLIGHT
  226    END:VTIMEZONE
  227    END:VCALENDAR
  228    ]]></C:calendar-timezone>
  229        </D:prop>
  230      </D:set>
  231    </C:mkcalendar>';
  232 
  233         $request->setBody($body);
  234         $this->server->httpRequest = $request;
  235         $this->server->exec();
  236 
  237         $this->assertEquals(409, $this->response->status);
  238     }
  239 
  240     public function testMkCalendarExistingCalendar()
  241     {
  242         $request = HTTP\Sapi::createFromServerArray([
  243             'REQUEST_METHOD' => 'MKCALENDAR',
  244             'REQUEST_URI' => '/calendars/user1/UUID-123467',
  245         ]);
  246 
  247         $body = '<?xml version="1.0" encoding="utf-8" ?>
  248    <C:mkcalendar xmlns:D="DAV:"
  249                  xmlns:C="urn:ietf:params:xml:ns:caldav">
  250      <D:set>
  251        <D:prop>
  252          <D:displayname>Lisa\'s Events</D:displayname>
  253          <C:calendar-description xml:lang="en"
  254    >Calendar restricted to events.</C:calendar-description>
  255          <C:supported-calendar-component-set>
  256            <C:comp name="VEVENT"/>
  257          </C:supported-calendar-component-set>
  258          <C:calendar-timezone><![CDATA[BEGIN:VCALENDAR
  259    PRODID:-//Example Corp.//CalDAV Client//EN
  260    VERSION:2.0
  261    BEGIN:VTIMEZONE
  262    TZID:US-Eastern
  263    LAST-MODIFIED:19870101T000000Z
  264    BEGIN:STANDARD
  265    DTSTART:19671029T020000
  266    RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
  267    TZOFFSETFROM:-0400
  268    TZOFFSETTO:-0500
  269    TZNAME:Eastern Standard Time (US & Canada)
  270    END:STANDARD
  271    BEGIN:DAYLIGHT
  272    DTSTART:19870405T020000
  273    RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
  274    TZOFFSETFROM:-0500
  275    TZOFFSETTO:-0400
  276    TZNAME:Eastern Daylight Time (US & Canada)
  277    END:DAYLIGHT
  278    END:VTIMEZONE
  279    END:VCALENDAR
  280    ]]></C:calendar-timezone>
  281        </D:prop>
  282      </D:set>
  283    </C:mkcalendar>';
  284 
  285         $request->setBody($body);
  286         $this->server->httpRequest = $request;
  287         $this->server->exec();
  288 
  289         $this->assertEquals(405, $this->response->status);
  290     }
  291 
  292     public function testMkCalendarSucceed()
  293     {
  294         $request = new HTTP\Request('MKCALENDAR', '/calendars/user1/NEWCALENDAR');
  295 
  296         $timezone = 'BEGIN:VCALENDAR
  297 PRODID:-//Example Corp.//CalDAV Client//EN
  298 VERSION:2.0
  299 BEGIN:VTIMEZONE
  300 TZID:US-Eastern
  301 LAST-MODIFIED:19870101T000000Z
  302 BEGIN:STANDARD
  303 DTSTART:19671029T020000
  304 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
  305 TZOFFSETFROM:-0400
  306 TZOFFSETTO:-0500
  307 TZNAME:Eastern Standard Time (US & Canada)
  308 END:STANDARD
  309 BEGIN:DAYLIGHT
  310 DTSTART:19870405T020000
  311 RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
  312 TZOFFSETFROM:-0500
  313 TZOFFSETTO:-0400
  314 TZNAME:Eastern Daylight Time (US & Canada)
  315 END:DAYLIGHT
  316 END:VTIMEZONE
  317 END:VCALENDAR';
  318 
  319         $body = '<?xml version="1.0" encoding="utf-8" ?>
  320    <C:mkcalendar xmlns:D="DAV:"
  321                  xmlns:C="urn:ietf:params:xml:ns:caldav">
  322      <D:set>
  323        <D:prop>
  324          <D:displayname>Lisa\'s Events</D:displayname>
  325          <C:calendar-description xml:lang="en"
  326    >Calendar restricted to events.</C:calendar-description>
  327          <C:supported-calendar-component-set>
  328            <C:comp name="VEVENT"/>
  329          </C:supported-calendar-component-set>
  330          <C:calendar-timezone><![CDATA['.$timezone.']]></C:calendar-timezone>
  331        </D:prop>
  332      </D:set>
  333    </C:mkcalendar>';
  334 
  335         $request->setBody($body);
  336         $this->server->httpRequest = $request;
  337         $this->server->exec();
  338 
  339         $this->assertEquals(201, $this->response->status, 'Invalid response code received. Full response body: '.$this->response->getBodyAsString());
  340 
  341         $calendars = $this->caldavBackend->getCalendarsForUser('principals/user1');
  342         $this->assertEquals(3, count($calendars));
  343 
  344         $newCalendar = null;
  345         foreach ($calendars as $calendar) {
  346             if ('NEWCALENDAR' === $calendar['uri']) {
  347                 $newCalendar = $calendar;
  348                 break;
  349             }
  350         }
  351 
  352         $this->assertInternalType('array', $newCalendar);
  353 
  354         $keys = [
  355             'uri' => 'NEWCALENDAR',
  356             'id' => null,
  357             '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar restricted to events.',
  358             '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => $timezone,
  359             '{DAV:}displayname' => 'Lisa\'s Events',
  360             '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => null,
  361         ];
  362 
  363         foreach ($keys as $key => $value) {
  364             $this->assertArrayHasKey($key, $newCalendar);
  365 
  366             if (is_null($value)) {
  367                 continue;
  368             }
  369             $this->assertEquals($value, $newCalendar[$key]);
  370         }
  371         $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
  372         $this->assertTrue($newCalendar[$sccs] instanceof Xml\Property\SupportedCalendarComponentSet);
  373         $this->assertEquals(['VEVENT'], $newCalendar[$sccs]->getValue());
  374     }
  375 
  376     public function testMkCalendarEmptyBodySucceed()
  377     {
  378         $request = new HTTP\Request('MKCALENDAR', '/calendars/user1/NEWCALENDAR');
  379 
  380         $request->setBody('');
  381         $this->server->httpRequest = $request;
  382         $this->server->exec();
  383 
  384         $this->assertEquals(201, $this->response->status, 'Invalid response code received. Full response body: '.$this->response->getBodyAsString());
  385 
  386         $calendars = $this->caldavBackend->getCalendarsForUser('principals/user1');
  387         $this->assertEquals(3, count($calendars));
  388 
  389         $newCalendar = null;
  390         foreach ($calendars as $calendar) {
  391             if ('NEWCALENDAR' === $calendar['uri']) {
  392                 $newCalendar = $calendar;
  393                 break;
  394             }
  395         }
  396 
  397         $this->assertInternalType('array', $newCalendar);
  398 
  399         $keys = [
  400             'uri' => 'NEWCALENDAR',
  401             'id' => null,
  402             '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => null,
  403         ];
  404 
  405         foreach ($keys as $key => $value) {
  406             $this->assertArrayHasKey($key, $newCalendar);
  407 
  408             if (is_null($value)) {
  409                 continue;
  410             }
  411             $this->assertEquals($value, $newCalendar[$key]);
  412         }
  413         $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
  414         $this->assertTrue($newCalendar[$sccs] instanceof Xml\Property\SupportedCalendarComponentSet);
  415         $this->assertEquals(['VEVENT', 'VTODO'], $newCalendar[$sccs]->getValue());
  416     }
  417 
  418     public function testMkCalendarBadXml()
  419     {
  420         $request = new HTTP\Request('MKCALENDAR', '/blabla');
  421         $body = 'This is not xml';
  422 
  423         $request->setBody($body);
  424         $this->server->httpRequest = $request;
  425         $this->server->exec();
  426 
  427         $this->assertEquals(400, $this->response->status);
  428     }
  429 
  430     public function testPrincipalProperties()
  431     {
  432         $httpRequest = new HTTP\Request('FOO', '/blabla', ['Host' => 'sabredav.org']);
  433         $this->server->httpRequest = $httpRequest;
  434 
  435         $props = $this->server->getPropertiesForPath('/principals/user1', [
  436             '{'.Plugin::NS_CALDAV.'}calendar-home-set',
  437             '{'.Plugin::NS_CALENDARSERVER.'}calendar-proxy-read-for',
  438             '{'.Plugin::NS_CALENDARSERVER.'}calendar-proxy-write-for',
  439             '{'.Plugin::NS_CALENDARSERVER.'}notification-URL',
  440             '{'.Plugin::NS_CALENDARSERVER.'}email-address-set',
  441         ]);
  442 
  443         $this->assertArrayHasKey(0, $props);
  444         $this->assertArrayHasKey(200, $props[0]);
  445 
  446         $this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}calendar-home-set', $props[0][200]);
  447         $prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}calendar-home-set'];
  448         $this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $prop);
  449         $this->assertEquals('calendars/user1/', $prop->getHref());
  450 
  451         $this->assertArrayHasKey('{http://calendarserver.org/ns/}calendar-proxy-read-for', $props[0][200]);
  452         $prop = $props[0][200]['{http://calendarserver.org/ns/}calendar-proxy-read-for'];
  453         $this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $prop);
  454         $this->assertEquals(['principals/admin/'], $prop->getHrefs());
  455 
  456         $this->assertArrayHasKey('{http://calendarserver.org/ns/}calendar-proxy-write-for', $props[0][200]);
  457         $prop = $props[0][200]['{http://calendarserver.org/ns/}calendar-proxy-write-for'];
  458         $this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $prop);
  459         $this->assertEquals(['principals/admin/'], $prop->getHrefs());
  460 
  461         $this->assertArrayHasKey('{'.Plugin::NS_CALENDARSERVER.'}email-address-set', $props[0][200]);
  462         $prop = $props[0][200]['{'.Plugin::NS_CALENDARSERVER.'}email-address-set'];
  463         $this->assertInstanceOf('Sabre\\CalDAV\\Xml\\Property\\EmailAddressSet', $prop);
  464         $this->assertEquals(['user1.sabredav@sabredav.org'], $prop->getValue());
  465     }
  466 
  467     public function testSupportedReportSetPropertyNonCalendar()
  468     {
  469         $props = $this->server->getPropertiesForPath('/calendars/user1', [
  470             '{DAV:}supported-report-set',
  471         ]);
  472 
  473         $this->assertArrayHasKey(0, $props);
  474         $this->assertArrayHasKey(200, $props[0]);
  475         $this->assertArrayHasKey('{DAV:}supported-report-set', $props[0][200]);
  476 
  477         $prop = $props[0][200]['{DAV:}supported-report-set'];
  478 
  479         $this->assertInstanceOf('\\Sabre\\DAV\\Xml\\Property\\SupportedReportSet', $prop);
  480         $value = [
  481             '{DAV:}expand-property',
  482             '{DAV:}principal-match',
  483             '{DAV:}principal-property-search',
  484             '{DAV:}principal-search-property-set',
  485         ];
  486         $this->assertEquals($value, $prop->getValue());
  487     }
  488 
  489     /**
  490      * @depends testSupportedReportSetPropertyNonCalendar
  491      */
  492     public function testSupportedReportSetProperty()
  493     {
  494         $props = $this->server->getPropertiesForPath('/calendars/user1/UUID-123467', [
  495             '{DAV:}supported-report-set',
  496         ]);
  497 
  498         $this->assertArrayHasKey(0, $props);
  499         $this->assertArrayHasKey(200, $props[0]);
  500         $this->assertArrayHasKey('{DAV:}supported-report-set', $props[0][200]);
  501 
  502         $prop = $props[0][200]['{DAV:}supported-report-set'];
  503 
  504         $this->assertInstanceOf('\\Sabre\\DAV\\Xml\\Property\\SupportedReportSet', $prop);
  505         $value = [
  506             '{urn:ietf:params:xml:ns:caldav}calendar-multiget',
  507             '{urn:ietf:params:xml:ns:caldav}calendar-query',
  508             '{urn:ietf:params:xml:ns:caldav}free-busy-query',
  509             '{DAV:}expand-property',
  510             '{DAV:}principal-match',
  511             '{DAV:}principal-property-search',
  512             '{DAV:}principal-search-property-set',
  513         ];
  514         $this->assertEquals($value, $prop->getValue());
  515     }
  516 
  517     public function testSupportedReportSetUserCalendars()
  518     {
  519         $this->server->addPlugin(new \Sabre\DAV\Sync\Plugin());
  520 
  521         $props = $this->server->getPropertiesForPath('/calendars/user1', [
  522             '{DAV:}supported-report-set',
  523         ]);
  524 
  525         $this->assertArrayHasKey(0, $props);
  526         $this->assertArrayHasKey(200, $props[0]);
  527         $this->assertArrayHasKey('{DAV:}supported-report-set', $props[0][200]);
  528 
  529         $prop = $props[0][200]['{DAV:}supported-report-set'];
  530 
  531         $this->assertInstanceOf('\\Sabre\\DAV\\Xml\\Property\\SupportedReportSet', $prop);
  532         $value = [
  533             '{DAV:}sync-collection',
  534             '{DAV:}expand-property',
  535             '{DAV:}principal-match',
  536             '{DAV:}principal-property-search',
  537             '{DAV:}principal-search-property-set',
  538         ];
  539         $this->assertEquals($value, $prop->getValue());
  540     }
  541 
  542     /**
  543      * @depends testSupportedReportSetProperty
  544      */
  545     public function testCalendarMultiGetReport()
  546     {
  547         $body =
  548             '<?xml version="1.0"?>'.
  549             '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">'.
  550             '<d:prop>'.
  551             '  <c:calendar-data />'.
  552             '  <d:getetag />'.
  553             '</d:prop>'.
  554             '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>'.
  555             '</c:calendar-multiget>';
  556 
  557         $request = new HTTP\Request('REPORT', '/calendars/user1', ['Depth' => '1']);
  558         $request->setBody($body);
  559 
  560         $this->server->httpRequest = $request;
  561         $this->server->exec();
  562 
  563         $this->assertEquals(207, $this->response->status, 'Invalid HTTP status received. Full response body');
  564 
  565         $expectedIcal = TestUtil::getTestCalendarData();
  566 
  567         $expected = <<<XML
  568 <?xml version="1.0"?>
  569 <d:multistatus xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
  570 <d:response>
  571   <d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>
  572   <d:propstat>
  573     <d:prop>
  574       <cal:calendar-data>$expectedIcal</cal:calendar-data>
  575       <d:getetag>"e207e33c10e5fb9c12cfb35b5d9116e1"</d:getetag>
  576     </d:prop>
  577     <d:status>HTTP/1.1 200 OK</d:status>
  578   </d:propstat>
  579 </d:response>
  580 </d:multistatus>
  581 XML;
  582 
  583         $this->assertXmlStringEqualsXmlString($expected, $this->response->getBodyAsString());
  584     }
  585 
  586     /**
  587      * @depends testCalendarMultiGetReport
  588      */
  589     public function testCalendarMultiGetReportExpand()
  590     {
  591         $body =
  592             '<?xml version="1.0"?>'.
  593             '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">'.
  594             '<d:prop>'.
  595             '  <c:calendar-data>'.
  596             '     <c:expand start="20110101T000000Z" end="20111231T235959Z" />'.
  597             '  </c:calendar-data>'.
  598             '  <d:getetag />'.
  599             '</d:prop>'.
  600             '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>'.
  601             '</c:calendar-multiget>';
  602 
  603         $request = new HTTP\Request('REPORT', '/calendars/user1', ['Depth' => '1']);
  604         $request->setBody($body);
  605 
  606         $this->server->httpRequest = $request;
  607         $this->server->exec();
  608 
  609         $bodyAsString = $this->response->getBodyAsString();
  610         $this->assertEquals(207, $this->response->status, 'Invalid HTTP status received. Full response body: '.$bodyAsString);
  611 
  612         $expectedIcal = TestUtil::getTestCalendarData();
  613         $expectedIcal = \Sabre\VObject\Reader::read($expectedIcal);
  614         $expectedIcal = $expectedIcal->expand(
  615             new DateTime('2011-01-01 00:00:00', new DateTimeZone('UTC')),
  616             new DateTime('2011-12-31 23:59:59', new DateTimeZone('UTC'))
  617         );
  618         $expectedIcal = str_replace("\r\n", "&#xD;\n", $expectedIcal->serialize());
  619 
  620         $expected = <<<XML
  621 <?xml version="1.0"?>
  622 <d:multistatus xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
  623 <d:response>
  624   <d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>
  625   <d:propstat>
  626     <d:prop>
  627       <cal:calendar-data>$expectedIcal</cal:calendar-data>
  628       <d:getetag>"e207e33c10e5fb9c12cfb35b5d9116e1"</d:getetag>
  629     </d:prop>
  630     <d:status>HTTP/1.1 200 OK</d:status>
  631   </d:propstat>
  632 </d:response>
  633 </d:multistatus>
  634 XML;
  635 
  636         $this->assertXmlStringEqualsXmlString($expected, $bodyAsString);
  637     }
  638 
  639     /**
  640      * @depends testSupportedReportSetProperty
  641      * @depends testCalendarMultiGetReport
  642      */
  643     public function testCalendarQueryReport()
  644     {
  645         $body =
  646             '<?xml version="1.0"?>'.
  647             '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">'.
  648             '<d:prop>'.
  649             '  <c:calendar-data>'.
  650             '     <c:expand start="20000101T000000Z" end="20101231T235959Z" />'.
  651             '  </c:calendar-data>'.
  652             '  <d:getetag />'.
  653             '</d:prop>'.
  654             '<c:filter>'.
  655             '  <c:comp-filter name="VCALENDAR">'.
  656             '    <c:comp-filter name="VEVENT" />'.
  657             '  </c:comp-filter>'.
  658             '</c:filter>'.
  659             '</c:calendar-query>';
  660 
  661         $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467', ['Depth' => '1']);
  662         $request->setBody($body);
  663 
  664         $this->server->httpRequest = $request;
  665         $this->server->exec();
  666 
  667         $bodyAsString = $this->response->getBodyAsString();
  668         $this->assertEquals(207, $this->response->status, 'Received an unexpected status. Full response body: '.$bodyAsString);
  669 
  670         $expectedIcal = TestUtil::getTestCalendarData();
  671         $expectedIcal = \Sabre\VObject\Reader::read($expectedIcal);
  672         $expectedIcal = $expectedIcal->expand(
  673             new DateTime('2000-01-01 00:00:00', new DateTimeZone('UTC')),
  674             new DateTime('2010-12-31 23:59:59', new DateTimeZone('UTC'))
  675         );
  676         $expectedIcal = str_replace("\r\n", "&#xD;\n", $expectedIcal->serialize());
  677 
  678         $expected = <<<XML
  679 <?xml version="1.0"?>
  680 <d:multistatus xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
  681 <d:response>
  682   <d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>
  683   <d:propstat>
  684     <d:prop>
  685       <cal:calendar-data>$expectedIcal</cal:calendar-data>
  686       <d:getetag>"e207e33c10e5fb9c12cfb35b5d9116e1"</d:getetag>
  687     </d:prop>
  688     <d:status>HTTP/1.1 200 OK</d:status>
  689   </d:propstat>
  690 </d:response>
  691 </d:multistatus>
  692 XML;
  693 
  694         $this->assertXmlStringEqualsXmlString($expected, $bodyAsString);
  695     }
  696 
  697     /**
  698      * @depends testSupportedReportSetProperty
  699      * @depends testCalendarMultiGetReport
  700      */
  701     public function testCalendarQueryReportWindowsPhone()
  702     {
  703         $body =
  704             '<?xml version="1.0"?>'.
  705             '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">'.
  706             '<d:prop>'.
  707             '  <c:calendar-data>'.
  708             '     <c:expand start="20000101T000000Z" end="20101231T235959Z" />'.
  709             '  </c:calendar-data>'.
  710             '  <d:getetag />'.
  711             '</d:prop>'.
  712             '<c:filter>'.
  713             '  <c:comp-filter name="VCALENDAR">'.
  714             '    <c:comp-filter name="VEVENT" />'.
  715             '  </c:comp-filter>'.
  716             '</c:filter>'.
  717             '</c:calendar-query>';
  718 
  719         $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467', [
  720             'Depth' => '0',
  721             'User-Agent' => 'MSFT-WP/8.10.14219 (gzip)',
  722         ]);
  723 
  724         $request->setBody($body);
  725 
  726         $this->server->httpRequest = $request;
  727         $this->server->exec();
  728 
  729         $bodyAsString = $this->response->getBodyAsString();
  730         $this->assertEquals(207, $this->response->status, 'Received an unexpected status. Full response body: '.$bodyAsString);
  731 
  732         $expectedIcal = TestUtil::getTestCalendarData();
  733         $expectedIcal = \Sabre\VObject\Reader::read($expectedIcal);
  734         $expectedIcal = $expectedIcal->expand(
  735             new DateTime('2000-01-01 00:00:00', new DateTimeZone('UTC')),
  736             new DateTime('2010-12-31 23:59:59', new DateTimeZone('UTC'))
  737         );
  738         $expectedIcal = str_replace("\r\n", "&#xD;\n", $expectedIcal->serialize());
  739 
  740         $expected = <<<XML
  741 <?xml version="1.0"?>
  742 <d:multistatus xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
  743 <d:response>
  744   <d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>
  745   <d:propstat>
  746     <d:prop>
  747       <cal:calendar-data>$expectedIcal</cal:calendar-data>
  748       <d:getetag>"e207e33c10e5fb9c12cfb35b5d9116e1"</d:getetag>
  749     </d:prop>
  750     <d:status>HTTP/1.1 200 OK</d:status>
  751   </d:propstat>
  752 </d:response>
  753 </d:multistatus>
  754 XML;
  755 
  756         $this->assertXmlStringEqualsXmlString($expected, $bodyAsString);
  757     }
  758 
  759     /**
  760      * @depends testSupportedReportSetProperty
  761      * @depends testCalendarMultiGetReport
  762      */
  763     public function testCalendarQueryReportBadDepth()
  764     {
  765         $body =
  766             '<?xml version="1.0"?>'.
  767             '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">'.
  768             '<d:prop>'.
  769             '  <c:calendar-data>'.
  770             '     <c:expand start="20000101T000000Z" end="20101231T235959Z" />'.
  771             '  </c:calendar-data>'.
  772             '  <d:getetag />'.
  773             '</d:prop>'.
  774             '<c:filter>'.
  775             '  <c:comp-filter name="VCALENDAR">'.
  776             '    <c:comp-filter name="VEVENT" />'.
  777             '  </c:comp-filter>'.
  778             '</c:filter>'.
  779             '</c:calendar-query>';
  780 
  781         $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467', [
  782             'Depth' => '0',
  783         ]);
  784         $request->setBody($body);
  785 
  786         $this->server->httpRequest = $request;
  787         $this->server->exec();
  788 
  789         $this->assertEquals(400, $this->response->status, 'Received an unexpected status. Full response body: '.$this->response->getBodyAsString());
  790     }
  791 
  792     /**
  793      * @depends testCalendarQueryReport
  794      */
  795     public function testCalendarQueryReportNoCalData()
  796     {
  797         $body =
  798             '<?xml version="1.0"?>'.
  799             '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">'.
  800             '<d:prop>'.
  801             '  <d:getetag />'.
  802             '</d:prop>'.
  803             '<c:filter>'.
  804             '  <c:comp-filter name="VCALENDAR">'.
  805             '    <c:comp-filter name="VEVENT" />'.
  806             '  </c:comp-filter>'.
  807             '</c:filter>'.
  808             '</c:calendar-query>';
  809 
  810         $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467', [
  811             'Depth' => '1',
  812         ]);
  813         $request->setBody($body);
  814 
  815         $this->server->httpRequest = $request;
  816         $this->server->exec();
  817 
  818         $bodyAsString = $this->server->httpResponse->getBodyAsString();
  819         $this->assertEquals(207, $this->response->status, 'Received an unexpected status. Full response body: '.$bodyAsString);
  820 
  821         $expected = <<<XML
  822 <?xml version="1.0"?>
  823 <d:multistatus xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
  824 <d:response>
  825   <d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>
  826   <d:propstat>
  827     <d:prop>
  828       <d:getetag>"e207e33c10e5fb9c12cfb35b5d9116e1"</d:getetag>
  829     </d:prop>
  830     <d:status>HTTP/1.1 200 OK</d:status>
  831   </d:propstat>
  832 </d:response>
  833 </d:multistatus>
  834 XML;
  835 
  836         $this->assertXmlStringEqualsXmlString($expected, $bodyAsString);
  837     }
  838 
  839     /**
  840      * @depends testCalendarQueryReport
  841      */
  842     public function testCalendarQueryReportNoFilters()
  843     {
  844         $body =
  845             '<?xml version="1.0"?>'.
  846             '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">'.
  847             '<d:prop>'.
  848             '  <c:calendar-data />'.
  849             '  <d:getetag />'.
  850             '</d:prop>'.
  851             '</c:calendar-query>';
  852 
  853         $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467');
  854         $request->setBody($body);
  855 
  856         $this->server->httpRequest = $request;
  857         $this->server->exec();
  858 
  859         $this->assertEquals(400, $this->response->status, 'Received an unexpected status. Full response body: '.$this->response->getBodyAsString());
  860     }
  861 
  862     /**
  863      * @depends testSupportedReportSetProperty
  864      * @depends testCalendarMultiGetReport
  865      */
  866     public function testCalendarQueryReport1Object()
  867     {
  868         $body =
  869             '<?xml version="1.0"?>'.
  870             '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">'.
  871             '<d:prop>'.
  872             '  <c:calendar-data>'.
  873             '     <c:expand start="20000101T000000Z" end="20101231T235959Z" />'.
  874             '  </c:calendar-data>'.
  875             '  <d:getetag />'.
  876             '</d:prop>'.
  877             '<c:filter>'.
  878             '  <c:comp-filter name="VCALENDAR">'.
  879             '    <c:comp-filter name="VEVENT" />'.
  880             '  </c:comp-filter>'.
  881             '</c:filter>'.
  882             '</c:calendar-query>';
  883 
  884         $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467/UUID-2345', ['Depth' => '0']);
  885         $request->setBody($body);
  886 
  887         $this->server->httpRequest = $request;
  888         $this->server->exec();
  889 
  890         $bodyAsString = $this->server->httpResponse->getBodyAsString();
  891         $this->assertEquals(207, $this->response->status, 'Received an unexpected status. Full response body: '.$bodyAsString);
  892 
  893         $expectedIcal = TestUtil::getTestCalendarData();
  894         $expectedIcal = \Sabre\VObject\Reader::read($expectedIcal);
  895         $expectedIcal = $expectedIcal->expand(
  896             new DateTime('2000-01-01 00:00:00', new DateTimeZone('UTC')),
  897             new DateTime('2010-12-31 23:59:59', new DateTimeZone('UTC'))
  898         );
  899         $expectedIcal = str_replace("\r\n", "&#xD;\n", $expectedIcal->serialize());
  900 
  901         $expected = <<<XML
  902 <?xml version="1.0"?>
  903 <d:multistatus xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
  904 <d:response>
  905   <d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>
  906   <d:propstat>
  907     <d:prop>
  908       <cal:calendar-data>$expectedIcal</cal:calendar-data>
  909       <d:getetag>"e207e33c10e5fb9c12cfb35b5d9116e1"</d:getetag>
  910     </d:prop>
  911     <d:status>HTTP/1.1 200 OK</d:status>
  912   </d:propstat>
  913 </d:response>
  914 </d:multistatus>
  915 XML;
  916 
  917         $this->assertXmlStringEqualsXmlString($expected, $bodyAsString);
  918     }
  919 
  920     /**
  921      * @depends testSupportedReportSetProperty
  922      * @depends testCalendarMultiGetReport
  923      */
  924     public function testCalendarQueryReport1ObjectNoCalData()
  925     {
  926         $body =
  927             '<?xml version="1.0"?>'.
  928             '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">'.
  929             '<d:prop>'.
  930             '  <d:getetag />'.
  931             '</d:prop>'.
  932             '<c:filter>'.
  933             '  <c:comp-filter name="VCALENDAR">'.
  934             '    <c:comp-filter name="VEVENT" />'.
  935             '  </c:comp-filter>'.
  936             '</c:filter>'.
  937             '</c:calendar-query>';
  938 
  939         $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467/UUID-2345', ['Depth' => '0']);
  940         $request->setBody($body);
  941 
  942         $this->server->httpRequest = $request;
  943         $this->server->exec();
  944 
  945         $bodyAsString = $this->server->httpResponse->getBodyAsString();
  946         $this->assertEquals(207, $this->response->status, 'Received an unexpected status. Full response body: '.$bodyAsString);
  947 
  948         $expected = <<<XML
  949 <?xml version="1.0"?>
  950 <d:multistatus xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
  951 <d:response>
  952   <d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>
  953   <d:propstat>
  954     <d:prop>
  955       <d:getetag>"e207e33c10e5fb9c12cfb35b5d9116e1"</d:getetag>
  956     </d:prop>
  957     <d:status>HTTP/1.1 200 OK</d:status>
  958   </d:propstat>
  959 </d:response>
  960 </d:multistatus>
  961 XML;
  962 
  963         $this->assertXmlStringEqualsXmlString($expected, $bodyAsString);
  964     }
  965 
  966     public function testHTMLActionsPanel()
  967     {
  968         $output = '';
  969         $r = $this->server->emit('onHTMLActionsPanel', [$this->server->tree->getNodeForPath('calendars/user1'), &$output]);
  970         $this->assertFalse($r);
  971 
  972         $this->assertTrue((bool) strpos($output, 'Display name'));
  973     }
  974 
  975     /**
  976      * @depends testCalendarMultiGetReport
  977      */
  978     public function testCalendarMultiGetReportNoEnd()
  979     {
  980         $body =
  981             '<?xml version="1.0"?>'.
  982             '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">'.
  983             '<d:prop>'.
  984             '  <c:calendar-data>'.
  985             '     <c:expand start="20110101T000000Z" />'.
  986             '  </c:calendar-data>'.
  987             '  <d:getetag />'.
  988             '</d:prop>'.
  989             '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>'.
  990             '</c:calendar-multiget>';
  991 
  992         $request = new HTTP\Request('REPORT', '/calendars/user1', ['Depth' => '1']);
  993         $request->setBody($body);
  994 
  995         $this->server->httpRequest = $request;
  996         $this->server->exec();
  997 
  998         $this->assertEquals(400, $this->response->status, 'Invalid HTTP status received. Full response body: '.$this->response->getBodyAsString());
  999     }
 1000 
 1001     /**
 1002      * @depends testCalendarMultiGetReport
 1003      */
 1004     public function testCalendarMultiGetReportNoStart()
 1005     {
 1006         $body =
 1007             '<?xml version="1.0"?>'.
 1008             '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">'.
 1009             '<d:prop>'.
 1010             '  <c:calendar-data>'.
 1011             '     <c:expand end="20110101T000000Z" />'.
 1012             '  </c:calendar-data>'.
 1013             '  <d:getetag />'.
 1014             '</d:prop>'.
 1015             '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>'.
 1016             '</c:calendar-multiget>';
 1017 
 1018         $request = new HTTP\Request('REPORT', '/calendars/user1', ['Depth' => '1']);
 1019         $request->setBody($body);
 1020 
 1021         $this->server->httpRequest = $request;
 1022         $this->server->exec();
 1023 
 1024         $this->assertEquals(400, $this->response->status, 'Invalid HTTP status received. Full response body: '.$this->response->getBodyAsString());
 1025     }
 1026 
 1027     /**
 1028      * @depends testCalendarMultiGetReport
 1029      */
 1030     public function testCalendarMultiGetReportEndBeforeStart()
 1031     {
 1032         $body =
 1033             '<?xml version="1.0"?>'.
 1034             '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">'.
 1035             '<d:prop>'.
 1036             '  <c:calendar-data>'.
 1037             '     <c:expand start="20200101T000000Z" end="20110101T000000Z" />'.
 1038             '  </c:calendar-data>'.
 1039             '  <d:getetag />'.
 1040             '</d:prop>'.
 1041             '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>'.
 1042             '</c:calendar-multiget>';
 1043 
 1044         $request = new HTTP\Request('REPORT', '/calendars/user1', ['Depth' => '1']);
 1045         $request->setBody($body);
 1046 
 1047         $this->server->httpRequest = $request;
 1048         $this->server->exec();
 1049 
 1050         $this->assertEquals(400, $this->response->status, 'Invalid HTTP status received. Full response body: '.$this->response->getBodyAsString());
 1051     }
 1052 
 1053     /**
 1054      * @depends testSupportedReportSetPropertyNonCalendar
 1055      */
 1056     public function testCalendarProperties()
 1057     {
 1058         $ns = '{urn:ietf:params:xml:ns:caldav}';
 1059         $props = $this->server->getProperties('calendars/user1/UUID-123467', [
 1060             $ns.'max-resource-size',
 1061             $ns.'supported-calendar-data',
 1062             $ns.'supported-collation-set',
 1063         ]);
 1064 
 1065         $this->assertEquals([
 1066             $ns.'max-resource-size' => 10000000,
 1067             $ns.'supported-calendar-data' => new Xml\Property\SupportedCalendarData(),
 1068             $ns.'supported-collation-set' => new Xml\Property\SupportedCollationSet(),
 1069         ], $props);
 1070     }
 1071 }