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