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