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