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