1<?php 2 3namespace Sabre\CalDAV; 4 5use Sabre\DAV; 6use Sabre\HTTP; 7use Sabre\VObject; 8use Sabre\DAVACL; 9 10require_once 'Sabre/CalDAV/TestUtil.php'; 11require_once 'Sabre/HTTP/ResponseMock.php'; 12 13class ICSExportPluginTest extends \PHPUnit_Framework_TestCase { 14 15 function setUp() { 16 17 if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available'); 18 19 } 20 21 function testInit() { 22 23 $p = new ICSExportPlugin(); 24 $s = new DAV\Server(); 25 $s->addPlugin($p); 26 $this->assertEquals($p, $s->getPlugin('ics-export')); 27 28 } 29 30 function testBeforeMethod() { 31 32 $cbackend = TestUtil::getBackend(); 33 34 $props = [ 35 'uri'=>'UUID-123467', 36 'principaluri' => 'admin', 37 'id' => 1, 38 '{DAV:}displayname' => 'Hello!', 39 '{http://apple.com/ns/ical/}calendar-color' => '#AA0000FF', 40 ]; 41 $tree = [ 42 new Calendar($cbackend,$props), 43 ]; 44 45 $p = new ICSExportPlugin(); 46 47 $s = new DAV\Server($tree); 48 $s->addPlugin($p); 49 $s->addPlugin(new Plugin()); 50 51 $h = HTTP\Sapi::createFromServerArray([ 52 'REQUEST_URI' => '/UUID-123467?export', 53 'REQUEST_METHOD' => 'GET', 54 ]); 55 56 $s->httpRequest = $h; 57 $s->httpResponse = new HTTP\ResponseMock(); 58 59 $this->assertFalse($p->httpGet($h, $s->httpResponse)); 60 61 $this->assertEquals(200, $s->httpResponse->status); 62 $this->assertEquals([ 63 'Content-Type' => ['text/calendar'], 64 ], $s->httpResponse->getHeaders()); 65 66 $obj = VObject\Reader::read($s->httpResponse->body); 67 68 $this->assertEquals(7,count($obj->children())); 69 $this->assertEquals(1,count($obj->VERSION)); 70 $this->assertEquals(1,count($obj->CALSCALE)); 71 $this->assertEquals(1,count($obj->PRODID)); 72 $this->assertTrue(strpos((string)$obj->PRODID, DAV\Version::VERSION)!==false); 73 $this->assertEquals(1,count($obj->VTIMEZONE)); 74 $this->assertEquals(1,count($obj->VEVENT)); 75 $this->assertEquals("Hello!", $obj->{"X-WR-CALNAME"}); 76 $this->assertEquals("#AA0000FF", $obj->{"X-APPLE-CALENDAR-COLOR"}); 77 78 } 79 function testBeforeMethodNoVersion() { 80 81 if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available'); 82 $cbackend = TestUtil::getBackend(); 83 84 $props = [ 85 'uri'=>'UUID-123467', 86 'principaluri' => 'admin', 87 'id' => 1, 88 ]; 89 $tree = [ 90 new Calendar($cbackend,$props), 91 ]; 92 93 $p = new ICSExportPlugin(); 94 95 $s = new DAV\Server($tree); 96 97 $s->addPlugin($p); 98 $s->addPlugin(new Plugin()); 99 100 $h = HTTP\Sapi::createFromServerArray([ 101 'REQUEST_URI' => '/UUID-123467?export', 102 'REQUEST_METHOD' => 'GET', 103 ]); 104 105 $s->httpRequest = $h; 106 $s->httpResponse = new HTTP\ResponseMock(); 107 108 DAV\Server::$exposeVersion = false; 109 $this->assertFalse($p->httpGet($h, $s->httpResponse)); 110 DAV\Server::$exposeVersion = true; 111 112 $this->assertEquals(200, $s->httpResponse->status); 113 $this->assertEquals([ 114 'Content-Type' => ['text/calendar'], 115 ], $s->httpResponse->getHeaders()); 116 117 $obj = VObject\Reader::read($s->httpResponse->body); 118 119 $this->assertEquals(5,count($obj->children())); 120 $this->assertEquals(1,count($obj->VERSION)); 121 $this->assertEquals(1,count($obj->CALSCALE)); 122 $this->assertEquals(1,count($obj->PRODID)); 123 $this->assertFalse(strpos((string)$obj->PRODID, DAV\Version::VERSION)!==false); 124 $this->assertEquals(1,count($obj->VTIMEZONE)); 125 $this->assertEquals(1,count($obj->VEVENT)); 126 127 } 128 129 function testBeforeMethodNoExport() { 130 131 $p = new ICSExportPlugin(); 132 133 $s = new DAV\Server(); 134 $s->addPlugin($p); 135 136 $h = HTTP\Sapi::createFromServerArray([ 137 'REQUEST_URI' => '/UUID-123467', 138 'REQUEST_METHOD' => 'GET', 139 ]); 140 $this->assertNull($p->httpGet($h, $s->httpResponse)); 141 142 } 143 144 function testACLIntegrationBlocked() { 145 146 $cbackend = TestUtil::getBackend(); 147 148 $props = array( 149 'uri'=>'UUID-123467', 150 'principaluri' => 'admin', 151 'id' => 1, 152 ); 153 $tree = array( 154 new Calendar($cbackend,$props), 155 ); 156 157 $p = new ICSExportPlugin(); 158 159 $s = new DAV\Server($tree); 160 $s->addPlugin($p); 161 $s->addPlugin(new Plugin()); 162 $s->addPlugin(new DAVACL\Plugin()); 163 164 $h = HTTP\Sapi::createFromServerArray([ 165 'REQUEST_URI' => '/UUID-123467?export', 166 ]); 167 168 $s->httpRequest = $h; 169 $s->httpResponse = new HTTP\ResponseMock(); 170 171 $p->httpGet($h, $s->httpResponse); 172 173 // If the ACL system blocked this request, the effect will be that 174 // there's no response, because the calendar information could not be 175 // fetched. 176 $this->assertNull($s->httpResponse->getStatus()); 177 178 } 179 180 function testACLIntegrationNotBlocked() { 181 182 $cbackend = TestUtil::getBackend(); 183 $pbackend = new DAVACL\PrincipalBackend\Mock(); 184 185 $props = array( 186 'uri'=>'UUID-123467', 187 'principaluri' => 'admin', 188 'id' => 1, 189 ); 190 $tree = array( 191 new Calendar($cbackend,$props), 192 new DAVACL\PrincipalCollection($pbackend), 193 ); 194 195 $p = new ICSExportPlugin(); 196 197 $s = new DAV\Server($tree); 198 $s->sapi = new HTTP\SapiMock(); 199 $s->addPlugin($p); 200 $s->addPlugin(new Plugin()); 201 $s->addPlugin(new DAVACL\Plugin()); 202 $s->addPlugin(new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'SabreDAV')); 203 204 // Forcing login 205 $s->getPlugin('acl')->adminPrincipals = array('principals/admin'); 206 207 208 $h = HTTP\Sapi::createFromServerArray([ 209 'REQUEST_URI' => '/UUID-123467?export', 210 'REQUEST_METHOD' => 'GET', 211 ]); 212 213 $s->httpRequest = $h; 214 $s->httpResponse = new HTTP\ResponseMock(); 215 216 $s->exec(); 217 218 $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body); 219 $this->assertEquals(array( 220 'X-Sabre-Version' => [DAV\Version::VERSION], 221 'Content-Type' => ['text/calendar'], 222 ), $s->httpResponse->getHeaders()); 223 224 $obj = VObject\Reader::read($s->httpResponse->body); 225 226 $this->assertEquals(5,count($obj->children())); 227 $this->assertEquals(1,count($obj->VERSION)); 228 $this->assertEquals(1,count($obj->CALSCALE)); 229 $this->assertEquals(1,count($obj->PRODID)); 230 $this->assertEquals(1,count($obj->VTIMEZONE)); 231 $this->assertEquals(1,count($obj->VEVENT)); 232 233 } 234 235 function testBadStartParam() { 236 237 $cbackend = TestUtil::getBackend(); 238 $pbackend = new DAVACL\PrincipalBackend\Mock(); 239 240 $props = array( 241 'uri'=>'UUID-123467', 242 'principaluri' => 'admin', 243 'id' => 1, 244 ); 245 $tree = array( 246 new Calendar($cbackend,$props), 247 new DAVACL\PrincipalCollection($pbackend), 248 ); 249 250 $p = new ICSExportPlugin(); 251 252 $s = new DAV\Server($tree); 253 $s->sapi = new HTTP\SapiMock(); 254 $s->addPlugin($p); 255 $s->addPlugin(new Plugin()); 256 257 $h = HTTP\Sapi::createFromServerArray([ 258 'REQUEST_URI' => '/UUID-123467?export&start=foo', 259 'REQUEST_METHOD' => 'GET', 260 ]); 261 262 $s->httpRequest = $h; 263 $s->httpResponse = new HTTP\ResponseMock(); 264 265 $s->exec(); 266 267 $this->assertEquals(400, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body); 268 269 } 270 271 function testBadEndParam() { 272 273 $cbackend = TestUtil::getBackend(); 274 $pbackend = new DAVACL\PrincipalBackend\Mock(); 275 276 $props = array( 277 'uri'=>'UUID-123467', 278 'principaluri' => 'admin', 279 'id' => 1, 280 ); 281 $tree = array( 282 new Calendar($cbackend,$props), 283 new DAVACL\PrincipalCollection($pbackend), 284 ); 285 286 $p = new ICSExportPlugin(); 287 288 $s = new DAV\Server($tree); 289 $s->sapi = new HTTP\SapiMock(); 290 $s->addPlugin($p); 291 $s->addPlugin(new Plugin()); 292 293 $h = HTTP\Sapi::createFromServerArray([ 294 'REQUEST_URI' => '/UUID-123467?export&end=foo', 295 'REQUEST_METHOD' => 'GET', 296 ]); 297 298 $s->httpRequest = $h; 299 $s->httpResponse = new HTTP\ResponseMock(); 300 301 $s->exec(); 302 303 $this->assertEquals(400, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body); 304 305 } 306 307 function testFilterStartEnd() { 308 309 $cbackend = TestUtil::getBackend(); 310 $pbackend = new DAVACL\PrincipalBackend\Mock(); 311 312 $props = array( 313 'uri'=>'UUID-123467', 314 'principaluri' => 'admin', 315 'id' => 1, 316 ); 317 $tree = array( 318 new Calendar($cbackend,$props), 319 new DAVACL\PrincipalCollection($pbackend), 320 ); 321 322 $p = new ICSExportPlugin(); 323 324 $s = new DAV\Server($tree); 325 $s->sapi = new HTTP\SapiMock(); 326 $s->addPlugin($p); 327 $s->addPlugin(new Plugin()); 328 329 $h = HTTP\Sapi::createFromServerArray([ 330 'REQUEST_URI' => '/UUID-123467?export&start=1&end=2', 331 'REQUEST_METHOD' => 'GET', 332 ]); 333 334 $s->httpRequest = $h; 335 $s->httpResponse = new HTTP\ResponseMock(); 336 337 $s->exec(); 338 339 $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body); 340 $obj = VObject\Reader::read($s->httpResponse->body); 341 342 $this->assertEquals(0,count($obj->VTIMEZONE)); 343 $this->assertEquals(0,count($obj->VEVENT)); 344 345 } 346 347 function testExpandNoStart() { 348 349 $cbackend = TestUtil::getBackend(); 350 $pbackend = new DAVACL\PrincipalBackend\Mock(); 351 352 $props = array( 353 'uri'=>'UUID-123467', 354 'principaluri' => 'admin', 355 'id' => 1, 356 ); 357 $tree = array( 358 new Calendar($cbackend,$props), 359 new DAVACL\PrincipalCollection($pbackend), 360 ); 361 362 $p = new ICSExportPlugin(); 363 364 $s = new DAV\Server($tree); 365 $s->sapi = new HTTP\SapiMock(); 366 $s->addPlugin($p); 367 $s->addPlugin(new Plugin()); 368 369 $h = HTTP\Sapi::createFromServerArray([ 370 'REQUEST_URI' => '/UUID-123467?export&expand=1&end=1', 371 'REQUEST_METHOD' => 'GET', 372 ]); 373 374 $s->httpRequest = $h; 375 $s->httpResponse = new HTTP\ResponseMock(); 376 377 $s->exec(); 378 379 $this->assertEquals(400, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body); 380 381 } 382 383 function testExpand() { 384 385 $cbackend = TestUtil::getBackend(); 386 $pbackend = new DAVACL\PrincipalBackend\Mock(); 387 388 $props = array( 389 'uri'=>'UUID-123467', 390 'principaluri' => 'admin', 391 'id' => 1, 392 ); 393 $tree = array( 394 new Calendar($cbackend,$props), 395 new DAVACL\PrincipalCollection($pbackend), 396 ); 397 398 $p = new ICSExportPlugin(); 399 400 $s = new DAV\Server($tree); 401 $s->sapi = new HTTP\SapiMock(); 402 $s->addPlugin($p); 403 $s->addPlugin(new Plugin()); 404 405 $h = HTTP\Sapi::createFromServerArray([ 406 'REQUEST_URI' => '/UUID-123467?export&start=1&end=2000000000&expand=1', 407 'REQUEST_METHOD' => 'GET', 408 ]); 409 410 $s->httpRequest = $h; 411 $s->httpResponse = new HTTP\ResponseMock(); 412 413 $s->exec(); 414 415 $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body); 416 $obj = VObject\Reader::read($s->httpResponse->body); 417 418 $this->assertEquals(0,count($obj->VTIMEZONE)); 419 $this->assertEquals(1,count($obj->VEVENT)); 420 421 } 422 423 function testJCal() { 424 425 $cbackend = TestUtil::getBackend(); 426 $pbackend = new DAVACL\PrincipalBackend\Mock(); 427 428 $props = array( 429 'uri'=>'UUID-123467', 430 'principaluri' => 'admin', 431 'id' => 1, 432 ); 433 $tree = array( 434 new Calendar($cbackend,$props), 435 new DAVACL\PrincipalCollection($pbackend), 436 ); 437 438 $p = new ICSExportPlugin(); 439 440 $s = new DAV\Server($tree); 441 $s->sapi = new HTTP\SapiMock(); 442 $s->addPlugin($p); 443 $s->addPlugin(new Plugin()); 444 445 $h = HTTP\Sapi::createFromServerArray([ 446 'REQUEST_URI' => '/UUID-123467?export', 447 'REQUEST_METHOD' => 'GET', 448 'HTTP_ACCEPT' => 'application/calendar+json', 449 ]); 450 451 $s->httpRequest = $h; 452 $s->httpResponse = new HTTP\ResponseMock(); 453 454 $s->exec(); 455 456 $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body); 457 $this->assertEquals('application/calendar+json', $s->httpResponse->getHeader('Content-Type')); 458 459 } 460 461 function testJCalInUrl() { 462 463 $cbackend = TestUtil::getBackend(); 464 $pbackend = new DAVACL\PrincipalBackend\Mock(); 465 466 $props = array( 467 'uri'=>'UUID-123467', 468 'principaluri' => 'admin', 469 'id' => 1, 470 ); 471 $tree = array( 472 new Calendar($cbackend,$props), 473 new DAVACL\PrincipalCollection($pbackend), 474 ); 475 476 $p = new ICSExportPlugin(); 477 478 $s = new DAV\Server($tree); 479 $s->sapi = new HTTP\SapiMock(); 480 $s->addPlugin($p); 481 $s->addPlugin(new Plugin()); 482 483 $h = HTTP\Sapi::createFromServerArray([ 484 'REQUEST_URI' => '/UUID-123467?export&accept=jcal', 485 'REQUEST_METHOD' => 'GET', 486 ]); 487 488 $s->httpRequest = $h; 489 $s->httpResponse = new HTTP\ResponseMock(); 490 491 $s->exec(); 492 493 $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body); 494 $this->assertEquals('application/calendar+json', $s->httpResponse->getHeader('Content-Type')); 495 496 } 497 498 function testNegotiateDefault() { 499 500 $cbackend = TestUtil::getBackend(); 501 $pbackend = new DAVACL\PrincipalBackend\Mock(); 502 503 $props = array( 504 'uri'=>'UUID-123467', 505 'principaluri' => 'admin', 506 'id' => 1, 507 ); 508 $tree = array( 509 new Calendar($cbackend,$props), 510 new DAVACL\PrincipalCollection($pbackend), 511 ); 512 513 $p = new ICSExportPlugin(); 514 515 $s = new DAV\Server($tree); 516 $s->sapi = new HTTP\SapiMock(); 517 $s->addPlugin($p); 518 $s->addPlugin(new Plugin()); 519 520 $h = HTTP\Sapi::createFromServerArray([ 521 'REQUEST_URI' => '/UUID-123467?export', 522 'REQUEST_METHOD' => 'GET', 523 'HTTP_ACCEPT' => 'text/plain', 524 ]); 525 526 $s->httpRequest = $h; 527 $s->httpResponse = new HTTP\ResponseMock(); 528 529 $s->exec(); 530 531 $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body); 532 $this->assertEquals('text/calendar', $s->httpResponse->getHeader('Content-Type')); 533 534 } 535 536 function testFilterComponentVEVENT() { 537 538 $cbackend = TestUtil::getBackend(); 539 $pbackend = new DAVACL\PrincipalBackend\Mock(); 540 541 $props = array( 542 'uri'=>'UUID-123467', 543 'principaluri' => 'admin', 544 'id' => 1, 545 ); 546 // add a todo to the calendar (see /tests/Sabre/TestUtil) 547 $cbackend->createCalendarObject(1, 'UUID-3456', TestUtil::getTestTODO()); 548 549 $tree = array( 550 new Calendar($cbackend,$props), 551 new DAVACL\PrincipalCollection($pbackend), 552 ); 553 554 $p = new ICSExportPlugin(); 555 556 $s = new DAV\Server($tree); 557 $s->sapi = new HTTP\SapiMock(); 558 $s->addPlugin($p); 559 $s->addPlugin(new Plugin()); 560 561 $h = HTTP\Sapi::createFromServerArray([ 562 'REQUEST_URI' => '/UUID-123467?export&componentType=VEVENT', 563 'REQUEST_METHOD' => 'GET', 564 ]); 565 566 $s->httpRequest = $h; 567 $s->httpResponse = new HTTP\ResponseMock(); 568 569 $s->exec(); 570 571 $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body); 572 $obj = VObject\Reader::read($s->httpResponse->body); 573 574 $this->assertEquals(1,count($obj->VTIMEZONE)); 575 $this->assertEquals(1,count($obj->VEVENT)); 576 $this->assertEquals(0,count($obj->VTODO)); 577 578 } 579 580 function testFilterComponentVTODO() { 581 582 $cbackend = TestUtil::getBackend(); 583 $pbackend = new DAVACL\PrincipalBackend\Mock(); 584 585 $props = [ 586 'uri'=>'UUID-123467', 587 'principaluri' => 'admin', 588 'id' => 1, 589 ]; 590 // add a todo to the calendar (see /tests/Sabre/TestUtil) 591 $cbackend->createCalendarObject(1, 'UUID-3456', TestUtil::getTestTODO()); 592 593 $tree = [ 594 new Calendar($cbackend,$props), 595 new DAVACL\PrincipalCollection($pbackend), 596 ]; 597 598 $p = new ICSExportPlugin(); 599 600 $s = new DAV\Server($tree); 601 $s->sapi = new HTTP\SapiMock(); 602 $s->addPlugin($p); 603 $s->addPlugin(new Plugin()); 604 605 $h = HTTP\Sapi::createFromServerArray([ 606 'REQUEST_URI' => '/UUID-123467?export&componentType=VTODO', 607 'REQUEST_METHOD' => 'GET', 608 ]); 609 610 $s->httpRequest = $h; 611 $s->httpResponse = new HTTP\ResponseMock(); 612 613 $s->exec(); 614 615 $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body); 616 $obj = VObject\Reader::read($s->httpResponse->body); 617 618 $this->assertEquals(0,count($obj->VTIMEZONE)); 619 $this->assertEquals(0,count($obj->VEVENT)); 620 $this->assertEquals(1,count($obj->VTODO)); 621 622 } 623 624 function testFilterComponentBadComponent() { 625 626 $cbackend = TestUtil::getBackend(); 627 $pbackend = new DAVACL\PrincipalBackend\Mock(); 628 629 $props = [ 630 'uri'=>'UUID-123467', 631 'principaluri' => 'admin', 632 'id' => 1, 633 ]; 634 // add a todo to the calendar (see /tests/Sabre/TestUtil) 635 $cbackend->createCalendarObject(1, 'UUID-3456', TestUtil::getTestTODO()); 636 637 $tree = [ 638 new Calendar($cbackend,$props), 639 new DAVACL\PrincipalCollection($pbackend), 640 ]; 641 642 $p = new ICSExportPlugin(); 643 644 $s = new DAV\Server($tree); 645 $s->sapi = new HTTP\SapiMock(); 646 $s->addPlugin($p); 647 $s->addPlugin(new Plugin()); 648 649 $h = HTTP\Sapi::createFromServerArray([ 650 'REQUEST_URI' => '/UUID-123467?export&componentType=VVOODOO', 651 'REQUEST_METHOD' => 'GET', 652 ]); 653 654 $s->httpRequest = $h; 655 $s->httpResponse = new HTTP\ResponseMock(); 656 657 $s->exec(); 658 659 $this->assertEquals(400, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body); 660 661 } 662} 663