aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/sabre/dav/tests/Sabre/CalDAV
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sabre/dav/tests/Sabre/CalDAV')
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php550
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractTest.php88
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php400
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php39
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php25
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php359
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryParserTest.php540
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php122
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php804
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php255
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php110
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php104
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php104
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php159
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyRequestTest.php282
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php97
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php227
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php63
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php135
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue203Test.php139
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php98
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php90
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php100
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php78
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php90
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php101
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteReplyTest.php134
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteTest.php230
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/SystemStatusTest.php61
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/OutboxPostTest.php545
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php1126
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php19
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php101
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php39
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php126
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Property/AllowedSharingModesTest.php46
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Property/InviteTest.php196
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Property/ScheduleCalendarTranspTest.php99
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarComponentSetTest.php67
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarDataTest.php44
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCollationSetTest.php46
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/IMip/Mock.php52
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php68
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ShareableCalendarTest.php62
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php122
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php391
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php208
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsSharedCalendarsTest.php93
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsTest.php207
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php250
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/VersionTest.php17
51 files changed, 9508 insertions, 0 deletions
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php
new file mode 100644
index 000000000..2224f0b63
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php
@@ -0,0 +1,550 @@
+<?php
+
+namespace Sabre\CalDAV\Backend;
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
+
+ protected $pdo;
+
+ function testConstruct() {
+
+ $backend = new PDO($this->pdo);
+ $this->assertTrue($backend instanceof PDO);
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testGetCalendarsForUserNoCalendars() {
+
+ $backend = new PDO($this->pdo);
+ $calendars = $backend->getCalendarsForUser('principals/user2');
+ $this->assertEquals(array(),$calendars);
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testCreateCalendarAndFetch() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array(
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Property\SupportedCalendarComponentSet(array('VEVENT')),
+ '{DAV:}displayname' => 'Hello!',
+ '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Property\ScheduleCalendarTransp('transparent'),
+ ));
+ $calendars = $backend->getCalendarsForUser('principals/user2');
+
+ $elementCheck = array(
+ 'id' => $returnedId,
+ 'uri' => 'somerandomid',
+ '{DAV:}displayname' => 'Hello!',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => '',
+ '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Property\ScheduleCalendarTransp('transparent'),
+ );
+
+ $this->assertInternalType('array',$calendars);
+ $this->assertEquals(1,count($calendars));
+
+ foreach($elementCheck as $name=>$value) {
+
+ $this->assertArrayHasKey($name, $calendars[0]);
+ $this->assertEquals($value,$calendars[0][$name]);
+
+ }
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testUpdateCalendarAndFetch() {
+
+ $backend = new PDO($this->pdo);
+
+ //Creating a new calendar
+ $newId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ // Updating the calendar
+ $result = $backend->updateCalendar($newId,array(
+ '{DAV:}displayname' => 'myCalendar',
+ '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Property\ScheduleCalendarTransp('transparent'),
+ ));
+
+ // Verifying the result of the update
+ $this->assertEquals(true, $result);
+
+ // Fetching all calendars from this user
+ $calendars = $backend->getCalendarsForUser('principals/user2');
+
+ // Checking if all the information is still correct
+ $elementCheck = array(
+ 'id' => $newId,
+ 'uri' => 'somerandomid',
+ '{DAV:}displayname' => 'myCalendar',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => '',
+ '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => '',
+ '{http://calendarserver.org/ns/}getctag' => '2',
+ '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Property\ScheduleCalendarTransp('transparent'),
+ );
+
+ $this->assertInternalType('array',$calendars);
+ $this->assertEquals(1,count($calendars));
+
+ foreach($elementCheck as $name=>$value) {
+
+ $this->assertArrayHasKey($name, $calendars[0]);
+ $this->assertEquals($value,$calendars[0][$name]);
+
+ }
+
+ }
+
+ /**
+ * @depends testUpdateCalendarAndFetch
+ */
+ function testUpdateCalendarUnknownProperty() {
+
+ $backend = new PDO($this->pdo);
+
+ //Creating a new calendar
+ $newId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ // Updating the calendar
+ $result = $backend->updateCalendar($newId,array(
+ '{DAV:}displayname' => 'myCalendar',
+ '{DAV:}yourmom' => 'wittycomment',
+ ));
+
+ // Verifying the result of the update
+ $this->assertEquals(array(
+ '403' => array('{DAV:}yourmom' => null),
+ '424' => array('{DAV:}displayname' => null),
+ ), $result);
+
+ }
+
+ /**
+ * @depends testCreateCalendarAndFetch
+ */
+ function testDeleteCalendar() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array(
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Property\SupportedCalendarComponentSet(array('VEVENT')),
+ '{DAV:}displayname' => 'Hello!',
+ ));
+
+ $backend->deleteCalendar($returnedId);
+
+ $calendars = $backend->getCalendarsForUser('principals/user2');
+ $this->assertEquals(array(),$calendars);
+
+ }
+
+ /**
+ * @depends testCreateCalendarAndFetch
+ * @expectedException \Sabre\DAV\Exception
+ */
+ function testCreateCalendarIncorrectComponentSet() {;
+
+ $backend = new PDO($this->pdo);
+
+ //Creating a new calendar
+ $newId = $backend->createCalendar('principals/user2','somerandomid',array(
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => 'blabla',
+ ));
+
+ }
+
+ function testCreateCalendarObject() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $this->assertEquals(array(
+ 'etag' => md5($object),
+ 'size' => strlen($object),
+ 'calendardata' => $object,
+ 'firstoccurence' => strtotime('20120101'),
+ 'lastoccurence' => strtotime('20120101')+(3600*24),
+ 'componenttype' => 'VEVENT',
+ ), $result->fetch(\PDO::FETCH_ASSOC));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ * @depends testCreateCalendarObject
+ */
+ function testCreateCalendarObjectNoComponent() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testCreateCalendarObjectDuration() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nDURATION:P2D\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $this->assertEquals(array(
+ 'etag' => md5($object),
+ 'size' => strlen($object),
+ 'calendardata' => $object,
+ 'firstoccurence' => strtotime('20120101'),
+ 'lastoccurence' => strtotime('20120101')+(3600*48),
+ 'componenttype' => 'VEVENT',
+ ), $result->fetch(\PDO::FETCH_ASSOC));
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testCreateCalendarObjectNoDTEND() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $this->assertEquals(array(
+ 'etag' => md5($object),
+ 'size' => strlen($object),
+ 'calendardata' => $object,
+ 'firstoccurence' => strtotime('2012-01-01 10:00:00'),
+ 'lastoccurence' => strtotime('2012-01-01 10:00:00'),
+ 'componenttype' => 'VEVENT',
+ ), $result->fetch(\PDO::FETCH_ASSOC));
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testCreateCalendarObjectInfiniteReccurence() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nRRULE:FREQ=DAILY\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $this->assertEquals(array(
+ 'etag' => md5($object),
+ 'size' => strlen($object),
+ 'calendardata' => $object,
+ 'firstoccurence' => strtotime('2012-01-01 10:00:00'),
+ 'lastoccurence' => strtotime(PDO::MAX_DATE),
+ 'componenttype' => 'VEVENT',
+ ), $result->fetch(\PDO::FETCH_ASSOC));
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testCreateCalendarObjectEndingReccurence() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nDTEND;VALUE=DATE-TIME:20120101T110000Z\r\nRRULE:FREQ=DAILY;COUNT=1000\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $this->assertEquals(array(
+ 'etag' => md5($object),
+ 'size' => strlen($object),
+ 'calendardata' => $object,
+ 'firstoccurence' => strtotime('2012-01-01 10:00:00'),
+ 'lastoccurence' => strtotime('2012-01-01 11:00:00') + (3600 * 24 * 999),
+ 'componenttype' => 'VEVENT',
+ ), $result->fetch(\PDO::FETCH_ASSOC));
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testCreateCalendarObjectTask() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nDUE;VALUE=DATE-TIME:20120101T100000Z\r\nEND:VTODO\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $this->assertEquals(array(
+ 'etag' => md5($object),
+ 'size' => strlen($object),
+ 'calendardata' => $object,
+ 'firstoccurence' => null,
+ 'lastoccurence' => null,
+ 'componenttype' => 'VTODO',
+ ), $result->fetch(\PDO::FETCH_ASSOC));
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testGetCalendarObjects() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $data = $backend->getCalendarObjects($returnedId,'random-id');
+
+ $this->assertEquals(1, count($data));
+ $data = $data[0];
+
+ $this->assertEquals($returnedId, $data['calendarid']);
+ $this->assertEquals('random-id', $data['uri']);
+ $this->assertEquals(strlen($object),$data['size']);
+
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testUpdateCalendarObject() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+ $object2 = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20130101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+ $backend->updateCalendarObject($returnedId, 'random-id', $object2);
+
+ $data = $backend->getCalendarObject($returnedId,'random-id');
+
+ $this->assertEquals($object2, $data['calendardata']);
+ $this->assertEquals($returnedId, $data['calendarid']);
+ $this->assertEquals('random-id', $data['uri']);
+
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testDeleteCalendarObject() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+ $backend->deleteCalendarObject($returnedId, 'random-id');
+
+ $data = $backend->getCalendarObject($returnedId,'random-id');
+ $this->assertNull($data);
+
+ }
+
+ function testCalendarQueryNoResult() {
+
+ $abstract = new PDO($this->pdo);
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VJOURNAL',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $this->assertEquals(array(
+ ), $abstract->calendarQuery(1, $filters));
+
+ }
+
+ function testCalendarQueryTodo() {
+
+ $backend = new PDO($this->pdo);
+ $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VTODO',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $this->assertEquals(array(
+ "todo",
+ ), $backend->calendarQuery(1, $filters));
+
+ }
+ function testCalendarQueryTodoNotMatch() {
+
+ $backend = new PDO($this->pdo);
+ $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VTODO',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(
+ array(
+ 'name' => 'summary',
+ 'text-match' => null,
+ 'time-range' => null,
+ 'param-filters' => array(),
+ 'is-not-defined' => false,
+ ),
+ ),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $this->assertEquals(array(
+ ), $backend->calendarQuery(1, $filters));
+
+ }
+
+ function testCalendarQueryNoFilter() {
+
+ $backend = new PDO($this->pdo);
+ $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $result = $backend->calendarQuery(1, $filters);
+ $this->assertTrue(in_array('todo', $result));
+ $this->assertTrue(in_array('event', $result));
+
+ }
+
+ function testCalendarQueryTimeRange() {
+
+ $backend = new PDO($this->pdo);
+ $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event2", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('20120103'),
+ 'end' => new \DateTime('20120104'),
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $this->assertEquals(array(
+ "event2",
+ ), $backend->calendarQuery(1, $filters));
+
+ }
+ function testCalendarQueryTimeRangeNoEnd() {
+
+ $backend = new PDO($this->pdo);
+ $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event2", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('20120102'),
+ 'end' => null,
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $this->assertEquals(array(
+ "event2",
+ ), $backend->calendarQuery(1, $filters));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractTest.php
new file mode 100644
index 000000000..04fb16df5
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractTest.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Sabre\CalDAV\Backend;
+
+class AbstractTest extends \PHPUnit_Framework_TestCase {
+
+ function testUpdateCalendar() {
+
+ $abstract = new AbstractMock();
+ $this->assertEquals(false, $abstract->updateCalendar('randomid', array('{DAV:}displayname' => 'anything')));
+
+ }
+
+ function testCalendarQuery() {
+
+ $abstract = new AbstractMock();
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $this->assertEquals(array(
+ 'event1.ics',
+ ), $abstract->calendarQuery(1, $filters));
+
+ }
+
+}
+
+class AbstractMock extends AbstractBackend {
+
+ function getCalendarsForUser($principalUri) { }
+ function createCalendar($principalUri,$calendarUri,array $properties) { }
+ function deleteCalendar($calendarId) { }
+ function getCalendarObjects($calendarId) {
+
+ return array(
+ array(
+ 'id' => 1,
+ 'calendarid' => 1,
+ 'uri' => 'event1.ics',
+ ),
+ array(
+ 'id' => 2,
+ 'calendarid' => 1,
+ 'uri' => 'task1.ics',
+ ),
+ );
+
+ }
+ function getCalendarObject($calendarId,$objectUri) {
+
+ switch($objectUri) {
+
+ case 'event1.ics' :
+ return array(
+ 'id' => 1,
+ 'calendarid' => 1,
+ 'uri' => 'event1.ics',
+ 'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
+ );
+ case 'task1.ics' :
+ return array(
+ 'id' => 1,
+ 'calendarid' => 1,
+ 'uri' => 'event1.ics',
+ 'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n",
+ );
+
+ }
+
+ }
+ function createCalendarObject($calendarId,$objectUri,$calendarData) { }
+ function updateCalendarObject($calendarId,$objectUri,$calendarData) { }
+ function deleteCalendarObject($calendarId,$objectUri) { }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php
new file mode 100644
index 000000000..d196297f7
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php
@@ -0,0 +1,400 @@
+<?php
+
+namespace Sabre\CalDAV\Backend;
+use Sabre\DAV;
+use Sabre\CalDAV;
+
+class Mock extends AbstractBackend implements NotificationSupport, SharingSupport {
+
+ private $calendarData;
+ private $calendars;
+ private $notifications;
+ private $shares = array();
+
+ function __construct(array $calendars, array $calendarData, array $notifications = array()) {
+
+ $this->calendars = $calendars;
+ $this->calendarData = $calendarData;
+ $this->notifications = $notifications;
+
+ }
+
+ /**
+ * Returns a list of calendars for a principal.
+ *
+ * Every project is an array with the following keys:
+ * * id, a unique id that will be used by other functions to modify the
+ * calendar. This can be the same as the uri or a database key.
+ * * uri, which the basename of the uri with which the calendar is
+ * accessed.
+ * * principalUri. The owner of the calendar. Almost always the same as
+ * principalUri passed to this method.
+ *
+ * Furthermore it can contain webdav properties in clark notation. A very
+ * common one is '{DAV:}displayname'.
+ *
+ * @param string $principalUri
+ * @return array
+ */
+ function getCalendarsForUser($principalUri) {
+
+ $r = array();
+ foreach($this->calendars as $row) {
+ if ($row['principaluri'] == $principalUri) {
+ $r[] = $row;
+ }
+ }
+
+ return $r;
+
+ }
+
+ /**
+ * Creates a new calendar for a principal.
+ *
+ * If the creation was a success, an id must be returned that can be used to reference
+ * this calendar in other methods, such as updateCalendar.
+ *
+ * This function must return a server-wide unique id that can be used
+ * later to reference the calendar.
+ *
+ * @param string $principalUri
+ * @param string $calendarUri
+ * @param array $properties
+ * @return string|int
+ */
+ function createCalendar($principalUri,$calendarUri,array $properties) {
+
+ $id = DAV\UUIDUtil::getUUID();
+ $this->calendars[] = array_merge(array(
+ 'id' => $id,
+ 'principaluri' => $principalUri,
+ 'uri' => $calendarUri,
+ '{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Property\SupportedCalendarComponentSet(array('VEVENT','VTODO')),
+ ), $properties);
+
+ return $id;
+
+ }
+
+ /**
+ * Updates properties on this node,
+ *
+ * The properties array uses the propertyName in clark-notation as key,
+ * and the array value for the property value. In the case a property
+ * should be deleted, the property value will be null.
+ *
+ * This method must be atomic. If one property cannot be changed, the
+ * entire operation must fail.
+ *
+ * If the operation was successful, true can be returned.
+ * If the operation failed, false can be returned.
+ *
+ * Deletion of a non-existent property is always successful.
+ *
+ * Lastly, it is optional to return detailed information about any
+ * failures. In this case an array should be returned with the following
+ * structure:
+ *
+ * array(
+ * 403 => array(
+ * '{DAV:}displayname' => null,
+ * ),
+ * 424 => array(
+ * '{DAV:}owner' => null,
+ * )
+ * )
+ *
+ * In this example it was forbidden to update {DAV:}displayname.
+ * (403 Forbidden), which in turn also caused {DAV:}owner to fail
+ * (424 Failed Dependency) because the request needs to be atomic.
+ *
+ * @param string $calendarId
+ * @param array $properties
+ * @return bool|array
+ */
+ public function updateCalendar($calendarId, array $properties) {
+
+ return false;
+
+ }
+
+ /**
+ * Delete a calendar and all it's objects
+ *
+ * @param string $calendarId
+ * @return void
+ */
+ public function deleteCalendar($calendarId) {
+
+ foreach($this->calendars as $k=>$calendar) {
+ if ($calendar['id'] === $calendarId) {
+ unset($this->calendars[$k]);
+ }
+ }
+
+ }
+
+ /**
+ * Returns all calendar objects within a calendar object.
+ *
+ * Every item contains an array with the following keys:
+ * * id - unique identifier which will be used for subsequent updates
+ * * calendardata - The iCalendar-compatible calendar data
+ * * uri - a unique key which will be used to construct the uri. This can be any arbitrary string.
+ * * lastmodified - a timestamp of the last modification time
+ * * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
+ * ' "abcdef"')
+ * * calendarid - The calendarid as it was passed to this function.
+ *
+ * Note that the etag is optional, but it's highly encouraged to return for
+ * speed reasons.
+ *
+ * The calendardata is also optional. If it's not returned
+ * 'getCalendarObject' will be called later, which *is* expected to return
+ * calendardata.
+ *
+ * @param string $calendarId
+ * @return array
+ */
+ public function getCalendarObjects($calendarId) {
+
+ if (!isset($this->calendarData[$calendarId]))
+ return array();
+
+ $objects = $this->calendarData[$calendarId];
+
+ foreach($objects as $uri => &$object) {
+ $object['calendarid'] = $calendarId;
+ $object['uri'] = $uri;
+
+ }
+ return $objects;
+
+ }
+
+ /**
+ * Returns information from a single calendar object, based on it's object
+ * uri.
+ *
+ * The returned array must have the same keys as getCalendarObjects. The
+ * 'calendardata' object is required here though, while it's not required
+ * for getCalendarObjects.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @return array
+ */
+ function getCalendarObject($calendarId,$objectUri) {
+
+ if (!isset($this->calendarData[$calendarId][$objectUri])) {
+ throw new DAV\Exception\NotFound('Object could not be found');
+ }
+ $object = $this->calendarData[$calendarId][$objectUri];
+ $object['calendarid'] = $calendarId;
+ $object['uri'] = $objectUri;
+ return $object;
+
+ }
+
+ /**
+ * Creates a new calendar object.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @param string $calendarData
+ * @return void
+ */
+ function createCalendarObject($calendarId,$objectUri,$calendarData) {
+
+ $this->calendarData[$calendarId][$objectUri] = array(
+ 'calendardata' => $calendarData,
+ 'calendarid' => $calendarId,
+ 'uri' => $objectUri,
+ );
+
+ }
+
+ /**
+ * Updates an existing calendarobject, based on it's uri.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @param string $calendarData
+ * @return void
+ */
+ function updateCalendarObject($calendarId,$objectUri,$calendarData) {
+
+ $this->calendarData[$calendarId][$objectUri] = array(
+ 'calendardata' => $calendarData,
+ 'calendarid' => $calendarId,
+ 'uri' => $objectUri,
+ );
+
+ }
+
+ /**
+ * Deletes an existing calendar object.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @return void
+ */
+ function deleteCalendarObject($calendarId,$objectUri) {
+
+ throw new Exception('Not implemented');
+
+
+ }
+
+ /**
+ * Returns a list of notifications for a given principal url.
+ *
+ * The returned array should only consist of implementations of
+ * Sabre\CalDAV\Notifications\INotificationType.
+ *
+ * @param string $principalUri
+ * @return array
+ */
+ public function getNotificationsForPrincipal($principalUri) {
+
+ if (isset($this->notifications[$principalUri])) {
+ return $this->notifications[$principalUri];
+ }
+ return array();
+
+ }
+
+ /**
+ * This deletes a specific notifcation.
+ *
+ * This may be called by a client once it deems a notification handled.
+ *
+ * @param string $principalUri
+ * @param Sabre\CalDAV\Notifications\INotificationType $notification
+ * @return void
+ */
+ public function deleteNotification($principalUri, CalDAV\Notifications\INotificationType $notification) {
+
+ foreach($this->notifications[$principalUri] as $key=>$value) {
+ if ($notification === $value) {
+ unset($this->notifications[$principalUri][$key]);
+ }
+ }
+
+ }
+
+ /**
+ * Updates the list of shares.
+ *
+ * The first array is a list of people that are to be added to the
+ * calendar.
+ *
+ * Every element in the add array has the following properties:
+ * * href - A url. Usually a mailto: address
+ * * commonName - Usually a first and last name, or false
+ * * summary - A description of the share, can also be false
+ * * readOnly - A boolean value
+ *
+ * Every element in the remove array is just the address string.
+ *
+ * Note that if the calendar is currently marked as 'not shared' by and
+ * this method is called, the calendar should be 'upgraded' to a shared
+ * calendar.
+ *
+ * @param mixed $calendarId
+ * @param array $add
+ * @param array $remove
+ * @return void
+ */
+ public function updateShares($calendarId, array $add, array $remove) {
+
+ if (!isset($this->shares[$calendarId])) {
+ $this->shares[$calendarId] = array();
+ }
+
+ foreach($add as $val) {
+ $val['status'] = CalDAV\SharingPlugin::STATUS_NORESPONSE;
+ $this->shares[$calendarId][] = $val;
+ }
+
+ foreach($this->shares[$calendarId] as $k=>$share) {
+
+ if (in_array($share['href'], $remove)) {
+ unset($this->shares[$calendarId][$k]);
+ }
+
+ }
+
+ // Re-numbering keys
+ $this->shares[$calendarId] = array_values($this->shares[$calendarId]);
+
+ }
+
+ /**
+ * Returns the list of people whom this calendar is shared with.
+ *
+ * Every element in this array should have the following properties:
+ * * href - Often a mailto: address
+ * * commonName - Optional, for example a first + last name
+ * * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
+ * * readOnly - boolean
+ * * summary - Optional, a description for the share
+ *
+ * @param mixed $calendarId
+ * @return array
+ */
+ public function getShares($calendarId) {
+
+ if (!isset($this->shares[$calendarId])) {
+ return array();
+ }
+
+ return $this->shares[$calendarId];
+
+ }
+
+ /**
+ * This method is called when a user replied to a request to share.
+ *
+ * @param string href The sharee who is replying (often a mailto: address)
+ * @param int status One of the SharingPlugin::STATUS_* constants
+ * @param string $calendarUri The url to the calendar thats being shared
+ * @param string $inReplyTo The unique id this message is a response to
+ * @param string $summary A description of the reply
+ * @return void
+ */
+ public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null) {
+
+ // This operation basically doesn't do anything yet
+ if ($status === CalDAV\SharingPlugin::STATUS_ACCEPTED) {
+ return 'calendars/blabla/calendar';
+ }
+
+ }
+
+ /**
+ * Publishes a calendar
+ *
+ * @param mixed $calendarId
+ * @param bool $value
+ * @return void
+ */
+ public function setPublishStatus($calendarId, $value) {
+
+ foreach($this->calendars as $k=>$cal) {
+ if ($cal['id'] === $calendarId) {
+ if (!$value) {
+ unset($cal['{http://calendarserver.org/ns/}publish-url']);
+ } else {
+ $cal['{http://calendarserver.org/ns/}publish-url'] = 'http://example.org/public/ ' . $calendarId . '.ics';
+ }
+ return;
+ }
+ }
+
+ throw new DAV\Exception('Calendar with id "' . $calendarId . '" not found');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php
new file mode 100644
index 000000000..15c1d91fd
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Sabre\CalDAV\Backend;
+
+require_once 'Sabre/TestUtil.php';
+require_once 'Sabre/CalDAV/TestUtil.php';
+require_once 'Sabre/CalDAV/Backend/AbstractPDOTest.php';
+
+class PDOMySQLTest extends AbstractPDOTest {
+
+ function setup() {
+
+ if (!SABRE_HASMYSQL) $this->markTestSkipped('MySQL driver is not available, or not properly configured');
+ $pdo = \Sabre\TestUtil::getMySQLDB();
+ if (!$pdo) $this->markTestSkipped('Could not connect to mysql database');
+
+ $pdo->query('DROP TABLE IF EXISTS calendarobjects, calendars');
+
+ $queries = explode(
+ ';',
+ file_get_contents(__DIR__ . '/../../../../examples/sql/mysql.calendars.sql')
+ );
+
+ foreach($queries as $query) {
+ $query = trim($query," \r\n\t");
+ if ($query)
+ $pdo->exec($query);
+ }
+ $this->pdo = $pdo;
+
+ }
+
+ function teardown() {
+
+ $this->pdo = null;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php
new file mode 100644
index 000000000..c50f06986
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Sabre\CalDAV\Backend;
+
+use Sabre\CalDAV;
+
+require_once 'Sabre/CalDAV/Backend/AbstractPDOTest.php';
+
+class PDOSQLiteTest extends AbstractPDOTest {
+
+ function setup() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $this->pdo = CalDAV\TestUtil::getSQLiteDB();
+
+ }
+
+ function teardown() {
+
+ $this->pdo = null;
+ unlink(SABRE_TEMPDIR . '/testdb.sqlite');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php
new file mode 100644
index 000000000..eab10eae7
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php
@@ -0,0 +1,359 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\DAVACL;
+
+require_once 'Sabre/CalDAV/TestUtil.php';
+
+class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\CalDAV\Backend_PDO
+ */
+ protected $backend;
+ /**
+ * @var Sabre\CalDAV\Calendar
+ */
+ protected $calendar;
+ protected $principalBackend;
+
+ function setup() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $this->backend = TestUtil::getBackend();
+
+ $calendars = $this->backend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(2,count($calendars));
+ $this->calendar = new Calendar($this->backend, $calendars[0]);
+
+ }
+
+ function teardown() {
+
+ unset($this->calendar);
+ unset($this->backend);
+
+ }
+
+ function testSetup() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $this->assertInternalType('string',$children[0]->getName());
+ $this->assertInternalType('string',$children[0]->get());
+ $this->assertInternalType('string',$children[0]->getETag());
+ $this->assertEquals('text/calendar; charset=utf-8', $children[0]->getContentType());
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testInvalidArg1() {
+
+ $obj = new CalendarObject(
+ new Backend\Mock(array(),array()),
+ array(),
+ array()
+ );
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testInvalidArg2() {
+
+ $obj = new CalendarObject(
+ new Backend\Mock(array(),array()),
+ array(),
+ array('calendarid' => '1')
+ );
+
+ }
+
+ /**
+ * @depends testSetup
+ */
+ function testPut() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+ $newData = TestUtil::getTestCalendarData();
+
+ $children[0]->put($newData);
+ $this->assertEquals($newData, $children[0]->get());
+
+ }
+
+ /**
+ * @depends testSetup
+ */
+ function testPutStream() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+ $newData = TestUtil::getTestCalendarData();
+
+ $stream = fopen('php://temp','r+');
+ fwrite($stream, $newData);
+ rewind($stream);
+ $children[0]->put($stream);
+ $this->assertEquals($newData, $children[0]->get());
+
+ }
+
+
+ /**
+ * @depends testSetup
+ */
+ function testDelete() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+ $obj->delete();
+
+ $children2 = $this->calendar->getChildren();
+ $this->assertEquals(count($children)-1, count($children2));
+
+ }
+
+ /**
+ * @depends testSetup
+ */
+ function testGetLastModified() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+
+ $lastMod = $obj->getLastModified();
+ $this->assertTrue(is_int($lastMod) || ctype_digit($lastMod));
+
+ }
+
+ /**
+ * @depends testSetup
+ */
+ function testGetSize() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+
+ $size = $obj->getSize();
+ $this->assertInternalType('int', $size);
+
+ }
+
+ function testGetOwner() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+ $this->assertEquals('principals/user1', $obj->getOwner());
+
+ }
+
+ function testGetGroup() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+ $this->assertNull($obj->getGroup());
+
+ }
+
+ function testGetACL() {
+
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1/calendar-proxy-read',
+ 'protected' => true,
+ ),
+ );
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+ $this->assertEquals($expected, $obj->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetACL() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+ $obj->setACL(array());
+
+ }
+
+ function testGet() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+
+ $expected = "BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:Asia/Seoul
+BEGIN:DAYLIGHT
+TZOFFSETFROM:+0900
+RRULE:FREQ=YEARLY;UNTIL=19880507T150000Z;BYMONTH=5;BYDAY=2SU
+DTSTART:19870510T000000
+TZNAME:GMT+09:00
+TZOFFSETTO:+1000
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:+1000
+DTSTART:19881009T000000
+TZNAME:GMT+09:00
+TZOFFSETTO:+0900
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20100225T154229Z
+UID:39A6B5ED-DD51-4AFE-A683-C35EE3749627
+TRANSP:TRANSPARENT
+SUMMARY:Something here
+DTSTAMP:20100228T130202Z
+DTSTART;TZID=Asia/Seoul:20100223T060000
+DTEND;TZID=Asia/Seoul:20100223T070000
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR";
+
+
+
+ $this->assertEquals($expected, $obj->get());
+
+ }
+
+ function testGetRefetch() {
+
+ $backend = new Backend\Mock(array(), array(
+ 1 => array(
+ 'foo' => array(
+ 'calendardata' => 'foo',
+ 'uri' => 'foo'
+ ),
+ )
+ ));
+ $obj = new CalendarObject($backend, array(), array('calendarid' => 1, 'uri' => 'foo'));
+
+ $this->assertEquals('foo', $obj->get());
+
+ }
+
+ function testGetEtag1() {
+
+ $objectInfo = array(
+ 'calendardata' => 'foo',
+ 'uri' => 'foo',
+ 'etag' => 'bar',
+ 'calendarid' => 1
+ );
+
+ $backend = new Backend\Mock(array(), array());
+ $obj = new CalendarObject($backend, array(), $objectInfo);
+
+ $this->assertEquals('bar', $obj->getETag());
+
+ }
+
+ function testGetEtag2() {
+
+ $objectInfo = array(
+ 'calendardata' => 'foo',
+ 'uri' => 'foo',
+ 'calendarid' => 1
+ );
+
+ $backend = new Backend\Mock(array(), array());
+ $obj = new CalendarObject($backend, array(), $objectInfo);
+
+ $this->assertEquals('"' . md5('foo') . '"', $obj->getETag());
+
+ }
+
+ function testGetSupportedPrivilegesSet() {
+
+ $objectInfo = array(
+ 'calendardata' => 'foo',
+ 'uri' => 'foo',
+ 'calendarid' => 1
+ );
+
+ $backend = new Backend\Mock(array(), array());
+ $obj = new CalendarObject($backend, array(), $objectInfo);
+ $this->assertNull($obj->getSupportedPrivilegeSet());
+
+ }
+
+ function testGetSize1() {
+
+ $objectInfo = array(
+ 'calendardata' => 'foo',
+ 'uri' => 'foo',
+ 'calendarid' => 1
+ );
+
+ $backend = new Backend\Mock(array(), array());
+ $obj = new CalendarObject($backend, array(), $objectInfo);
+ $this->assertEquals(3, $obj->getSize());
+
+ }
+
+ function testGetSize2() {
+
+ $objectInfo = array(
+ 'uri' => 'foo',
+ 'calendarid' => 1,
+ 'size' => 4,
+ );
+
+ $backend = new Backend\Mock(array(), array());
+ $obj = new CalendarObject($backend, array(), $objectInfo);
+ $this->assertEquals(4, $obj->getSize());
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryParserTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryParserTest.php
new file mode 100644
index 000000000..fdfe4de89
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryParserTest.php
@@ -0,0 +1,540 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\DAV;
+
+class CalendarQueryParserTest extends \PHPUnit_Framework_TestCase {
+
+ function parse($xml) {
+
+ $xml =
+'<?xml version="1.0"?>
+<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
+' . implode("\n", $xml) . '
+</c:calendar-query>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $q = new CalendarQueryParser($dom);
+ $q->parse();
+ return $q->filters;
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testNoFilter() {
+
+ $xml = array();
+ $this->parse($xml);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testTwoCompFilter() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VEVENT" />',
+ ' <c:comp-filter name="VEVENT" />',
+ '</c:filter>'
+ );
+ $this->parse($xml);
+
+ }
+
+ function testBasicFilter() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR" />',
+ '</c:filter>'
+ );
+ $result = $this->parse($xml);
+
+ $expected = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => false
+ );
+
+ $this->assertEquals(
+ $expected,
+ $result
+ );
+
+ }
+
+ function testCompIsNotDefined() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR">',
+ ' <c:comp-filter name="VEVENT">',
+ ' <c:is-not-defined/>',
+ ' </c:comp-filter>',
+ ' </c:comp-filter>',
+ '</c:filter>'
+ );
+ $result = $this->parse($xml);
+
+ $expected = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => true,
+ 'time-range' => false
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => false
+ );
+
+ $this->assertEquals(
+ $expected,
+ $result
+ );
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testCompTimeRangeOnVCALENDAR() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR">',
+ ' <c:time-range start="20110101T000000Z" end="20111231T235959Z" />',
+ ' </c:comp-filter>',
+ '</c:filter>'
+ );
+ $result = $this->parse($xml);
+
+ }
+
+ function testCompTimeRange() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR">',
+ ' <c:comp-filter name="VEVENT">',
+ ' <c:time-range start="20110101T000000Z" end="20111231T235959Z" />',
+ ' </c:comp-filter>',
+ ' <c:comp-filter name="VTODO">',
+ ' <c:time-range start="20110101T000000Z" />',
+ ' </c:comp-filter>',
+ ' <c:comp-filter name="VJOURNAL">',
+ ' <c:time-range end="20111231T235959Z" />',
+ ' </c:comp-filter>',
+ ' </c:comp-filter>',
+ '</c:filter>'
+ );
+ $result = $this->parse($xml);
+
+ $expected = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 00:00:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-12-31 23:59:59', new \DateTimeZone('GMT')),
+ ),
+ ),
+ array(
+ 'name' => 'VTODO',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 00:00:00', new \DateTimeZone('GMT')),
+ 'end' => null,
+ ),
+ ),
+ array(
+ 'name' => 'VJOURNAL',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => null,
+ 'end' => new \DateTime('2011-12-31 23:59:59', new \DateTimeZone('GMT')),
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => false
+ );
+
+ $this->assertEquals(
+ $expected,
+ $result
+ );
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testCompTimeRangeBadRange() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR">',
+ ' <c:comp-filter name="VEVENT">',
+ ' <c:time-range start="20110101T000000Z" end="20100101T000000Z" />',
+ ' </c:comp-filter>',
+ ' </c:comp-filter>',
+ '</c:filter>'
+ );
+ $this->parse($xml);
+
+ }
+
+ function testProp() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR">',
+ ' <c:comp-filter name="VEVENT">',
+ ' <c:prop-filter name="SUMMARY">',
+ ' <c:text-match>vacation</c:text-match>',
+ ' </c:prop-filter>',
+ ' </c:comp-filter>',
+ ' </c:comp-filter>',
+ '</c:filter>'
+ );
+ $result = $this->parse($xml);
+
+ $expected = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'is-not-defined' => false,
+ 'comp-filters' => array(),
+ 'prop-filters' => array(
+ array(
+ 'name' => 'SUMMARY',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'text-match' => array(
+ 'negate-condition' => false,
+ 'collation' => 'i;ascii-casemap',
+ 'value' => 'vacation',
+ ),
+ 'time-range' => null,
+ ),
+ ),
+ 'time-range' => null,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => false
+ );
+
+ $this->assertEquals(
+ $expected,
+ $result
+ );
+
+ }
+
+ function testComplex() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR">',
+ ' <c:comp-filter name="VEVENT">',
+ ' <c:prop-filter name="SUMMARY">',
+ ' <c:text-match collation="i;unicode-casemap">vacation</c:text-match>',
+ ' </c:prop-filter>',
+ ' <c:prop-filter name="DTSTAMP">',
+ ' <c:time-range start="20110704T000000Z" />',
+ ' </c:prop-filter>',
+ ' <c:prop-filter name="ORGANIZER">',
+ ' <c:is-not-defined />',
+ ' </c:prop-filter>',
+ ' <c:prop-filter name="DTSTART">',
+ ' <c:param-filter name="VALUE">',
+ ' <c:text-match negate-condition="yes">DATE</c:text-match>',
+ ' </c:param-filter>',
+ ' </c:prop-filter>',
+ ' </c:comp-filter>',
+ ' </c:comp-filter>',
+ '</c:filter>'
+ );
+ $result = $this->parse($xml);
+
+ $expected = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'is-not-defined' => false,
+ 'comp-filters' => array(),
+ 'prop-filters' => array(
+ array(
+ 'name' => 'SUMMARY',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'text-match' => array(
+ 'negate-condition' => false,
+ 'collation' => 'i;unicode-casemap',
+ 'value' => 'vacation',
+ ),
+ 'time-range' => null,
+ ),
+ array(
+ 'name' => 'DTSTAMP',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'text-match' => null,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-07-04 00:00:00', new \DateTimeZone('GMT')),
+ 'end' => null,
+ ),
+ ),
+ array(
+ 'name' => 'ORGANIZER',
+ 'is-not-defined' => true,
+ 'param-filters' => array(),
+ 'text-match' => null,
+ 'time-range' => null,
+ ),
+ array(
+ 'name' => 'DTSTART',
+ 'is-not-defined' => false,
+ 'param-filters' => array(
+ array(
+ 'name' => 'VALUE',
+ 'is-not-defined' => false,
+ 'text-match' => array(
+ 'negate-condition' => true,
+ 'value' => 'DATE',
+ 'collation' => 'i;ascii-casemap',
+ ),
+ ),
+ ),
+ 'text-match' => null,
+ 'time-range' => null,
+ ),
+ ),
+ 'time-range' => null,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => false
+ );
+
+ $this->assertEquals(
+ $expected,
+ $result
+ );
+
+ }
+
+ function testOther1() {
+
+ // This body was exactly sent to us from the sabredav mailing list. Checking if this parses correctly.
+
+ $body = <<<BLA
+<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:"
+xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data/>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20090101T000000Z" end="20121202T000000Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>
+BLA;
+
+ $dom = DAV\XMLUtil::loadDOMDocument($body);
+
+ $q = new CalendarQueryParser($dom);
+ $q->parse();
+
+ $this->assertEquals(array(
+ '{urn:ietf:params:xml:ns:caldav}calendar-data',
+ '{DAV:}getetag',
+ ), $q->requestedProperties);
+
+ $expectedFilters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'time-range' => array(
+ 'start' => new \DateTime('2009-01-01 00:00:00', new \DateTimeZone('UTC')),
+ 'end' => new \DateTime('2012-12-02 00:00:00', new \DateTimeZone('UTC')),
+ ),
+ 'is-not-defined' => false,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'time-range' => null,
+ 'is-not-defined' => false,
+ );
+
+ $this->assertEquals($expectedFilters, $q->filters);
+
+ }
+
+ function testExpand() {
+
+ $xml = array(
+ '<d:prop>',
+ ' <c:calendar-data>',
+ ' <c:expand start="20110101T000000Z" end="20120101T000000Z"/>',
+ ' </c:calendar-data>',
+ '</d:prop>',
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR" />',
+ '</c:filter>'
+ );
+
+ $xml =
+'<?xml version="1.0"?>
+<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
+' . implode("\n", $xml) . '
+</c:calendar-query>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+ $q = new CalendarQueryParser($dom);
+ $q->parse();
+
+
+ $expected = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => false
+ );
+
+ $this->assertEquals(
+ $expected,
+ $q->filters
+ );
+
+ $this->assertEquals(array(
+ '{urn:ietf:params:xml:ns:caldav}calendar-data',
+ ), $q->requestedProperties);
+
+ $this->assertEquals(
+ array(
+ 'start' => new \DateTime('2011-01-01 00:00:00', new \DateTimeZone('UTC')),
+ 'end' => new \DateTime('2012-01-01 00:00:00', new \DateTimeZone('UTC')),
+ ),
+ $q->expand
+ );
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testExpandNoStart() {
+
+ $xml = array(
+ '<d:prop>',
+ ' <c:calendar-data>',
+ ' <c:expand end="20120101T000000Z"/>',
+ ' </c:calendar-data>',
+ '</d:prop>',
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR" />',
+ '</c:filter>'
+ );
+
+ $xml =
+'<?xml version="1.0"?>
+<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
+' . implode("\n", $xml) . '
+</c:calendar-query>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+ $q = new CalendarQueryParser($dom);
+ $q->parse();
+
+ }
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testExpandNoEnd() {
+
+ $xml = array(
+ '<d:prop>',
+ ' <c:calendar-data>',
+ ' <c:expand start="20120101T000000Z"/>',
+ ' </c:calendar-data>',
+ '</d:prop>',
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR" />',
+ '</c:filter>'
+ );
+
+ $xml =
+'<?xml version="1.0"?>
+<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
+' . implode("\n", $xml) . '
+</c:calendar-query>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+ $q = new CalendarQueryParser($dom);
+ $q->parse();
+
+ }
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testExpandBadTimes() {
+
+ $xml = array(
+ '<d:prop>',
+ ' <c:calendar-data>',
+ ' <c:expand start="20120101T000000Z" end="19980101T000000Z"/>',
+ ' </c:calendar-data>',
+ '</d:prop>',
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR" />',
+ '</c:filter>'
+ );
+
+ $xml =
+'<?xml version="1.0"?>
+<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
+' . implode("\n", $xml) . '
+</c:calendar-query>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+ $q = new CalendarQueryParser($dom);
+ $q->parse();
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php
new file mode 100644
index 000000000..9de24d3aa
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\VObject;
+
+class CalendarQueryVAlarmTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * This test is specifically for a time-range query on a VALARM, contained
+ * in a VEVENT that's recurring
+ */
+ function testValarm() {
+
+ $vcalendar = new VObject\Component\VCalendar();
+
+ $vevent = $vcalendar->createComponent('VEVENT');
+ $vevent->RRULE = 'FREQ=MONTHLY';
+ $vevent->DTSTART = '20120101T120000Z';
+ $vevent->UID = 'bla';
+
+ $valarm = $vcalendar->createComponent('VALARM');
+ $valarm->TRIGGER = '-P15D';
+ $vevent->add($valarm);
+
+
+ $vcalendar->add($vevent);
+
+ $filter = array(
+ 'name' => 'VCALENDAR',
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ 'prop-filters' => array(),
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ 'prop-filters' => array(),
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VALARM',
+ 'is-not-defined' => false,
+ 'prop-filters' => array(),
+ 'comp-filters' => array(),
+ 'time-range' => array(
+ 'start' => new \DateTime('2012-05-10'),
+ 'end' => new \DateTime('2012-05-20'),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $validator = new CalendarQueryValidator();
+ $this->assertTrue($validator->validate($vcalendar, $filter));
+
+ $vcalendar = new VObject\Component\VCalendar();
+
+ // A limited recurrence rule, should return false
+ $vevent = $vcalendar->createComponent('VEVENT');
+ $vevent->RRULE = 'FREQ=MONTHLY;COUNT=1';
+ $vevent->DTSTART = '20120101T120000Z';
+ $vevent->UID = 'bla';
+
+ $valarm = $vcalendar->createComponent('VALARM');
+ $valarm->TRIGGER = '-P15D';
+ $vevent->add($valarm);
+
+ $vcalendar->add($vevent);
+
+ $this->assertFalse($validator->validate($vcalendar, $filter));
+ }
+
+ function testAlarmWayBefore() {
+
+ $vcalendar = new VObject\Component\VCalendar();
+
+ $vevent = $vcalendar->createComponent('VEVENT');
+ $vevent->DTSTART = '20120101T120000Z';
+ $vevent->UID = 'bla';
+
+ $valarm = $vcalendar->createComponent('VALARM');
+ $valarm->TRIGGER = '-P2W1D';
+ $vevent->add($valarm);
+
+ $vcalendar->add($vevent);
+
+ $filter = array(
+ 'name' => 'VCALENDAR',
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ 'prop-filters' => array(),
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ 'prop-filters' => array(),
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VALARM',
+ 'is-not-defined' => false,
+ 'prop-filters' => array(),
+ 'comp-filters' => array(),
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-12-10'),
+ 'end' => new \DateTime('2011-12-20'),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $validator = new CalendarQueryValidator();
+ $this->assertTrue($validator->validate($vcalendar, $filter));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php
new file mode 100644
index 000000000..deb70d205
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php
@@ -0,0 +1,804 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\VObject;
+use Sabre\DAV;
+
+class CalendarQueryValidatorTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @dataProvider provider
+ */
+ function testValid($icalObject, $filters, $outcome) {
+
+ $validator = new CalendarQueryValidator();
+
+ // Wrapping filter in a VCALENDAR component filter, as this is always
+ // there anyway.
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array($filters),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $vObject = VObject\Reader::read($icalObject);
+
+ switch($outcome) {
+ case 0 :
+ $this->assertFalse($validator->validate($vObject, $filters));
+ break;
+ case 1 :
+ $this->assertTrue($validator->validate($vObject, $filters));
+ break;
+ case -1 :
+ try {
+ $validator->validate($vObject, $filters);
+ } catch (DAV\Exception $e) {
+ // Success
+ } catch (\LogicException $e) {
+ // Success
+ }
+ break;
+
+ }
+
+ }
+
+ function provider() {
+
+ $blob1 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+SUMMARY:hi
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob2 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+SUMMARY:hi
+BEGIN:VALARM
+ACTION:DISPLAY
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob3 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+SUMMARY:hi
+DTSTART;VALUE=DATE:20110704
+END:VEVENT
+END:VCALENDAR
+yow;
+ $blob4 = <<<yow
+BEGIN:VCARD
+VERSION:3.0
+FN:Evert
+END:VCARD
+yow;
+
+ $blob5 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DTEND:20110102T120000Z
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob6 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DURATION:PT5H
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob7 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20110101
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob8 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob9 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+DTSTART:20110101T120000Z
+DURATION:PT1H
+END:VTODO
+END:VCALENDAR
+yow;
+ $blob10 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+DTSTART:20110101T120000Z
+DUE:20110101T130000Z
+END:VTODO
+END:VCALENDAR
+yow;
+ $blob11 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+DTSTART:20110101T120000Z
+END:VTODO
+END:VCALENDAR
+yow;
+
+ $blob12 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+DUE:20110101T130000Z
+END:VTODO
+END:VCALENDAR
+yow;
+
+ $blob13 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+COMPLETED:20110101T130000Z
+CREATED:20110101T110000Z
+END:VTODO
+END:VCALENDAR
+yow;
+
+ $blob14 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+COMPLETED:20110101T130000Z
+END:VTODO
+END:VCALENDAR
+yow;
+
+ $blob15 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+CREATED:20110101T110000Z
+END:VTODO
+END:VCALENDAR
+yow;
+
+
+ $blob16 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+END:VTODO
+END:VCALENDAR
+yow;
+
+ $blob17 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VJOURNAL
+END:VJOURNAL
+END:VCALENDAR
+yow;
+
+ $blob18 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VJOURNAL
+DTSTART:20110101T120000Z
+END:VJOURNAL
+END:VCALENDAR
+yow;
+
+ $blob19 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VJOURNAL
+DTSTART;VALUE=DATE:20110101
+END:VJOURNAL
+END:VCALENDAR
+yow;
+
+ $blob20 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VFREEBUSY
+END:VFREEBUSY
+END:VCALENDAR
+yow;
+
+ $blob21 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+BEGIN:VALARM
+TRIGGER:-PT1H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob22 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION:-PT1H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob23 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION;RELATED=END:-PT1H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob24 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DTEND:20110101T130000Z
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION;RELATED=END:-PT2H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob25 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DURATION:PT1H
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION;RELATED=END:-PT2H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob26 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DURATION:PT1H
+BEGIN:VALARM
+TRIGGER;VALUE=DATE-TIME:20110101T110000Z
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+
+ $blob27 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+DTSTART:20110101T120000Z
+DUE:20110101T130000Z
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION;RELATED=END:-PT2H
+END:VALARM
+END:VTODO
+END:VCALENDAR
+yow;
+
+ $blob28 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VJOURNAL
+DTSTART:20110101T120000Z
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION;RELATED=END:-PT2H
+END:VALARM
+END:VJOURNAL
+END:VCALENDAR
+yow;
+
+ $blob29 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DURATION:PT1H
+BEGIN:VALARM
+TRIGGER;VALUE=DATE-TIME:20110101T090000Z
+REPEAT:2
+DURATION:PT1H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob30 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DURATION:PT1H
+BEGIN:VALARM
+TRIGGER;VALUE=DATE-TIME:20110101T090000Z
+DURATION:PT1H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob31 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20080101T120000Z
+DURATION:PT1H
+RRULE:FREQ=YEARLY
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob32 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20080102T120000Z
+DURATION:PT1H
+RRULE:FREQ=YEARLY
+END:VEVENT
+END:VCALENDAR
+yow;
+ $blob33 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20120628
+RRULE:FREQ=DAILY
+END:VEVENT
+END:VCALENDAR
+yow;
+ $blob34 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20120628
+RRULE:FREQ=DAILY
+BEGIN:VALARM
+TRIGGER:P52W
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $filter1 = array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+ $filter2 = $filter1;
+ $filter2['name'] = 'VTODO';
+
+ $filter3 = $filter1;
+ $filter3['is-not-defined'] = true;
+
+ $filter4 = $filter1;
+ $filter4['name'] = 'VTODO';
+ $filter4['is-not-defined'] = true;
+
+ $filter5 = $filter1;
+ $filter5['comp-filters'] = array(
+ array(
+ 'name' => 'VALARM',
+ 'is-not-defined' => false,
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'time-range' => null,
+ ),
+ );
+ $filter6 = $filter1;
+ $filter6['prop-filters'] = array(
+ array(
+ 'name' => 'SUMMARY',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'time-range' => null,
+ 'text-match' => null,
+ ),
+ );
+ $filter7 = $filter6;
+ $filter7['prop-filters'][0]['name'] = 'DESCRIPTION';
+
+ $filter8 = $filter6;
+ $filter8['prop-filters'][0]['is-not-defined'] = true;
+
+ $filter9 = $filter7;
+ $filter9['prop-filters'][0]['is-not-defined'] = true;
+
+ $filter10 = $filter5;
+ $filter10['prop-filters'] = $filter6['prop-filters'];
+
+ // Param filters
+ $filter11 = $filter1;
+ $filter11['prop-filters'] = array(
+ array(
+ 'name' => 'DTSTART',
+ 'is-not-defined' => false,
+ 'param-filters' => array(
+ array(
+ 'name' => 'VALUE',
+ 'is-not-defined' => false,
+ 'text-match' => null,
+ ),
+ ),
+ 'time-range' => null,
+ 'text-match' => null,
+ ),
+ );
+
+ $filter12 = $filter11;
+ $filter12['prop-filters'][0]['param-filters'][0]['name'] = 'TZID';
+
+ $filter13 = $filter11;
+ $filter13['prop-filters'][0]['param-filters'][0]['is-not-defined'] = true;
+
+ $filter14 = $filter12;
+ $filter14['prop-filters'][0]['param-filters'][0]['is-not-defined'] = true;
+
+ // Param text filter
+ $filter15 = $filter11;
+ $filter15['prop-filters'][0]['param-filters'][0]['text-match'] = array(
+ 'collation' => 'i;ascii-casemap',
+ 'value' => 'dAtE',
+ 'negate-condition' => false,
+ );
+ $filter16 = $filter15;
+ $filter16['prop-filters'][0]['param-filters'][0]['text-match']['collation'] = 'i;octet';
+
+ $filter17 = $filter15;
+ $filter17['prop-filters'][0]['param-filters'][0]['text-match']['negate-condition'] = true;
+
+ $filter18 = $filter15;
+ $filter18['prop-filters'][0]['param-filters'][0]['text-match']['negate-condition'] = true;
+ $filter18['prop-filters'][0]['param-filters'][0]['text-match']['collation'] = 'i;octet';
+
+ // prop + text
+ $filter19 = $filter5;
+ $filter19['comp-filters'][0]['prop-filters'] = array(
+ array(
+ 'name' => 'action',
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ 'param-filters' => array(),
+ 'text-match' => array(
+ 'collation' => 'i;ascii-casemap',
+ 'value' => 'display',
+ 'negate-condition' => false,
+ ),
+ ),
+ );
+
+ // Time range
+ $filter20 = array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
+ ),
+ );
+ // Time range, no end date
+ $filter21 = $filter20;
+ $filter21['time-range']['end'] = null;
+
+ // Time range, no start date
+ $filter22 = $filter20;
+ $filter22['time-range']['start'] = null;
+
+ // Time range, other dates
+ $filter23 = $filter20;
+ $filter23['time-range'] = array(
+ 'start' => new \DateTime('2011-02-01 10:00:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-02-01 13:00:00', new \DateTimeZone('GMT')),
+ );
+ // Time range
+ $filter24 = array(
+ 'name' => 'VTODO',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
+ ),
+ );
+ // Time range, other dates (1 month in the future)
+ $filter25 = $filter24;
+ $filter25['time-range'] = array(
+ 'start' => new \DateTime('2011-02-01 10:00:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-02-01 13:00:00', new \DateTimeZone('GMT')),
+ );
+ $filter26 = $filter24;
+ $filter26['time-range'] = array(
+ 'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
+ );
+
+ // Time range for VJOURNAL
+ $filter27 = array(
+ 'name' => 'VJOURNAL',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
+ ),
+ );
+ $filter28 = $filter27;
+ $filter28['time-range'] = array(
+ 'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
+ );
+ // Time range for VFREEBUSY
+ $filter29 = array(
+ 'name' => 'VFREEBUSY',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
+ ),
+ );
+ // Time range filter on property
+ $filter30 = array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(
+ array(
+ 'name' => 'DTSTART',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
+ ),
+ 'text-match' => null,
+ ),
+ ),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ // Time range for alarm
+ $filter31 = array(
+ 'name' => 'VEVENT',
+ 'prop-filters' => array(),
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VALARM',
+ 'is-not-defined' => false,
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 10:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 11:15:00', new \DateTimeZone('GMT')),
+ ),
+ 'text-match' => null,
+ ),
+ ),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+ $filter32 = $filter31;
+ $filter32['comp-filters'][0]['time-range'] = array(
+ 'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
+ );
+
+ $filter33 = $filter31;
+ $filter33['name'] = 'VTODO';
+ $filter34 = $filter32;
+ $filter34['name'] = 'VTODO';
+ $filter35 = $filter31;
+ $filter35['name'] = 'VJOURNAL';
+ $filter36 = $filter32;
+ $filter36['name'] = 'VJOURNAL';
+
+ // Time range filter on non-datetime property
+ $filter37 = array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(
+ array(
+ 'name' => 'SUMMARY',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
+ ),
+ 'text-match' => null,
+ ),
+ ),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $filter38 = array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2012-07-01 00:00:00', new \DateTimeZone('UTC')),
+ 'end' => new \DateTime('2012-08-01 00:00:00', new \DateTimeZone('UTC')),
+ )
+ );
+ $filter39 = array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VALARM',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2012-09-01 00:00:00', new \DateTimeZone('UTC')),
+ 'end' => new \DateTime('2012-10-01 00:00:00', new \DateTimeZone('UTC')),
+ )
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ return array(
+
+ // Component check
+
+ array($blob1, $filter1, 1),
+ array($blob1, $filter2, 0),
+ array($blob1, $filter3, 0),
+ array($blob1, $filter4, 1),
+
+ // Subcomponent check
+ array($blob1, $filter5, 0),
+ array($blob2, $filter5, 1),
+
+ // Property check
+ array($blob1, $filter6, 1),
+ array($blob1, $filter7, 0),
+ array($blob1, $filter8, 0),
+ array($blob1, $filter9, 1),
+
+ // Subcomponent + property
+ array($blob2, $filter10, 1),
+
+ // Param filter
+ array($blob3, $filter11, 1),
+ array($blob3, $filter12, 0),
+ array($blob3, $filter13, 0),
+ array($blob3, $filter14, 1),
+
+ // Param + text
+ array($blob3, $filter15, 1),
+ array($blob3, $filter16, 0),
+ array($blob3, $filter17, 0),
+ array($blob3, $filter18, 1),
+
+ // Prop + text
+ array($blob2, $filter19, 1),
+
+ // Incorrect object (vcard)
+ array($blob4, $filter1, -1),
+
+ // Time-range for event
+ array($blob5, $filter20, 1),
+ array($blob6, $filter20, 1),
+ array($blob7, $filter20, 1),
+ array($blob8, $filter20, 1),
+
+ array($blob5, $filter21, 1),
+ array($blob5, $filter22, 1),
+
+ array($blob5, $filter23, 0),
+ array($blob6, $filter23, 0),
+ array($blob7, $filter23, 0),
+ array($blob8, $filter23, 0),
+
+ // Time-range for todo
+ array($blob9, $filter24, 1),
+ array($blob9, $filter25, 0),
+ array($blob9, $filter26, 1),
+ array($blob10, $filter24, 1),
+ array($blob10, $filter25, 0),
+ array($blob10, $filter26, 1),
+
+ array($blob11, $filter24, 0),
+ array($blob11, $filter25, 0),
+ array($blob11, $filter26, 1),
+
+ array($blob12, $filter24, 1),
+ array($blob12, $filter25, 0),
+ array($blob12, $filter26, 0),
+
+ array($blob13, $filter24, 1),
+ array($blob13, $filter25, 0),
+ array($blob13, $filter26, 1),
+
+ array($blob14, $filter24, 1),
+ array($blob14, $filter25, 0),
+ array($blob14, $filter26, 0),
+
+ array($blob15, $filter24, 1),
+ array($blob15, $filter25, 1),
+ array($blob15, $filter26, 1),
+
+ array($blob16, $filter24, 1),
+ array($blob16, $filter25, 1),
+ array($blob16, $filter26, 1),
+
+ // Time-range for journals
+ array($blob17, $filter27, 0),
+ array($blob17, $filter28, 0),
+ array($blob18, $filter27, 0),
+ array($blob18, $filter28, 1),
+ array($blob19, $filter27, 1),
+ array($blob19, $filter28, 1),
+
+ // Time-range for free-busy
+ array($blob20, $filter29, -1),
+
+ // Time-range on property
+ array($blob5, $filter30, 1),
+ array($blob3, $filter37, -1),
+ array($blob3, $filter30, 0),
+
+ // Time-range on alarm in vevent
+ array($blob21, $filter31, 1),
+ array($blob21, $filter32, 0),
+ array($blob22, $filter31, 1),
+ array($blob22, $filter32, 0),
+ array($blob23, $filter31, 1),
+ array($blob23, $filter32, 0),
+ array($blob24, $filter31, 1),
+ array($blob24, $filter32, 0),
+ array($blob25, $filter31, 1),
+ array($blob25, $filter32, 0),
+ array($blob26, $filter31, 1),
+ array($blob26, $filter32, 0),
+
+ // Time-range on alarm for vtodo
+ array($blob27, $filter33, 1),
+ array($blob27, $filter34, 0),
+
+ // Time-range on alarm for vjournal
+ array($blob28, $filter35, -1),
+ array($blob28, $filter36, -1),
+
+ // Time-range on alarm with duration
+ array($blob29, $filter31, 1),
+ array($blob29, $filter32, 0),
+ array($blob30, $filter31, 0),
+ array($blob30, $filter32, 0),
+
+ // Time-range with RRULE
+ array($blob31, $filter20, 1),
+ array($blob32, $filter20, 0),
+
+ // Bug reported on mailing list, related to all-day events.
+ array($blob33, $filter38, 1),
+
+ // Event in timerange, but filtered alarm is in the far future.
+ array($blob34, $filter39, 0),
+ );
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php
new file mode 100644
index 000000000..2b2690d42
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php
@@ -0,0 +1,255 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\DAVACL;
+
+require_once 'Sabre/CalDAV/TestUtil.php';
+
+class CalendarTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\CalDAV\Backend_PDO
+ */
+ protected $backend;
+ protected $principalBackend;
+ /**
+ * @var Sabre\CalDAV\Calendar
+ */
+ protected $calendar;
+ /**
+ * @var array
+ */
+ protected $calendars;
+
+ function setup() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+
+ $this->backend = TestUtil::getBackend();
+
+ $this->calendars = $this->backend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(2, count($this->calendars));
+ $this->calendar = new Calendar($this->backend, $this->calendars[0]);
+
+
+ }
+
+ function teardown() {
+
+ unset($this->backend);
+
+ }
+
+ function testSimple() {
+
+ $this->assertEquals($this->calendars[0]['uri'], $this->calendar->getName());
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testUpdateProperties() {
+
+ $result = $this->calendar->updateProperties(array(
+ '{DAV:}displayname' => 'NewName',
+ ));
+
+ $this->assertEquals(true, $result);
+
+ $calendars2 = $this->backend->getCalendarsForUser('principals/user1');
+ $this->assertEquals('NewName',$calendars2[0]['{DAV:}displayname']);
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testGetProperties() {
+
+ $question = array(
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-data',
+ '{urn:ietf:params:xml:ns:caldav}supported-collation-set',
+ '{DAV:}owner',
+ );
+
+ $result = $this->calendar->getProperties($question);
+
+ foreach($question as $q) $this->assertArrayHasKey($q,$result);
+
+ $this->assertEquals(array('VEVENT','VTODO'), $result['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']->getValue());
+
+ $this->assertTrue($result['{urn:ietf:params:xml:ns:caldav}supported-collation-set'] instanceof Property\SupportedCollationSet);
+
+ $this->assertTrue($result['{DAV:}owner'] instanceof DAVACL\Property\Principal);
+ $this->assertEquals('principals/user1', $result['{DAV:}owner']->getHref());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotFound
+ * @depends testSimple
+ */
+ function testGetChildNotFound() {
+
+ $this->calendar->getChild('randomname');
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testGetChildren() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertEquals(1,count($children));
+
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ }
+
+ /**
+ * @depends testGetChildren
+ */
+ function testChildExists() {
+
+ $this->assertFalse($this->calendar->childExists('foo'));
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($this->calendar->childExists($children[0]->getName()));
+ }
+
+
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testCreateDirectory() {
+
+ $this->calendar->createDirectory('hello');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetName() {
+
+ $this->calendar->setName('hello');
+
+ }
+
+ function testGetLastModified() {
+
+ $this->assertNull($this->calendar->getLastModified());
+
+ }
+
+ function testCreateFile() {
+
+ $file = fopen('php://memory','r+');
+ fwrite($file,TestUtil::getTestCalendarData());
+ rewind($file);
+
+ $this->calendar->createFile('hello',$file);
+
+ $file = $this->calendar->getChild('hello');
+ $this->assertTrue($file instanceof CalendarObject);
+
+ }
+
+ function testCreateFileNoSupportedComponents() {
+
+ $file = fopen('php://memory','r+');
+ fwrite($file,TestUtil::getTestCalendarData());
+ rewind($file);
+
+ $calendar = new Calendar($this->backend, $this->calendars[1]);
+ $calendar->createFile('hello',$file);
+
+ $file = $calendar->getChild('hello');
+ $this->assertTrue($file instanceof CalendarObject);
+
+ }
+
+ function testDelete() {
+
+ $this->calendar->delete();
+
+ $calendars = $this->backend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(1, count($calendars));
+ }
+
+ function testGetOwner() {
+
+ $this->assertEquals('principals/user1',$this->calendar->getOwner());
+
+ }
+
+ function testGetGroup() {
+
+ $this->assertNull($this->calendar->getGroup());
+
+ }
+
+ function testGetACL() {
+
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1/calendar-proxy-read',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
+ 'principal' => '{DAV:}authenticated',
+ 'protected' => true,
+ ),
+ );
+ $this->assertEquals($expected, $this->calendar->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetACL() {
+
+ $this->calendar->setACL(array());
+
+ }
+
+ function testGetSupportedPrivilegesSet() {
+
+ $result = $this->calendar->getSupportedPrivilegeSet();
+
+ $this->assertEquals(
+ '{' . Plugin::NS_CALDAV . '}read-free-busy',
+ $result['aggregates'][0]['aggregates'][2]['privilege']
+ );
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php
new file mode 100644
index 000000000..5a78a0522
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php
@@ -0,0 +1,110 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittests is created to find out why recurring events have wrong DTSTART value
+ *
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class ExpandEventsDTSTARTandDTENDTest extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:foobar
+DTEND;TZID=Europe/Berlin:20120207T191500
+RRULE:FREQ=DAILY;INTERVAL=1;COUNT=3
+SUMMARY:RecurringEvents 3 times
+DTSTART;TZID=Europe/Berlin:20120207T181500
+END:VEVENT
+BEGIN:VEVENT
+CREATED:20120207T111900Z
+UID:foobar
+DTEND;TZID=Europe/Berlin:20120208T191500
+SUMMARY:RecurringEvents 3 times OVERWRITTEN
+DTSTART;TZID=Europe/Berlin:20120208T181500
+RECURRENCE-ID;TZID=Europe/Berlin:20120208T181500
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testExpand() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120205T230000Z" end="20120212T225959Z"/>
+ </C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20120205T230000Z" end="20120212T225959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ // Everts super awesome xml parser.
+ $body = substr(
+ $response->body,
+ $start = strpos($response->body, 'BEGIN:VCALENDAR'),
+ strpos($response->body, 'END:VCALENDAR') - $start + 13
+ );
+ $body = str_replace('&#13;','',$body);
+
+ $vObject = VObject\Reader::read($body);
+
+ // check if DTSTARTs and DTENDs are correct
+ foreach ($vObject->VEVENT as $vevent) {
+ /** @var $vevent Sabre\VObject\Component\VEvent */
+ foreach ($vevent->children as $child) {
+ /** @var $child Sabre\VObject\Property */
+
+ if ($child->name == 'DTSTART') {
+ // DTSTART has to be one of three valid values
+ $this->assertContains($child->getValue(), array('20120207T171500Z', '20120208T171500Z', '20120209T171500Z'), 'DTSTART is not a valid value: '.$child->getValue());
+ } elseif ($child->name == 'DTEND') {
+ // DTEND has to be one of three valid values
+ $this->assertContains($child->getValue(), array('20120207T181500Z', '20120208T181500Z', '20120209T181500Z'), 'DTEND is not a valid value: '.$child->getValue());
+ }
+ }
+ }
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php
new file mode 100644
index 000000000..a179bf7f8
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php
@@ -0,0 +1,104 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittests is created to find out why recurring events have wrong DTSTART value
+ *
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class ExpandEventsDTSTARTandDTENDbyDayTest extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:foobar
+DTEND;TZID=Europe/Berlin:20120207T191500
+RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,TH
+SUMMARY:RecurringEvents on tuesday and thursday
+DTSTART;TZID=Europe/Berlin:20120207T181500
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testExpandRecurringByDayEvent() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120210T230000Z" end="20120217T225959Z"/>
+ </C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20120210T230000Z" end="20120217T225959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ // Everts super awesome xml parser.
+ $body = substr(
+ $response->body,
+ $start = strpos($response->body, 'BEGIN:VCALENDAR'),
+ strpos($response->body, 'END:VCALENDAR') - $start + 13
+ );
+ $body = str_replace('&#13;','',$body);
+
+ $vObject = VObject\Reader::read($body);
+
+ $this->assertEquals(2, count($vObject->VEVENT));
+
+ // check if DTSTARTs and DTENDs are correct
+ foreach ($vObject->VEVENT as $vevent) {
+ /** @var $vevent Sabre\VObject\Component\VEvent */
+ foreach ($vevent->children as $child) {
+ /** @var $child Sabre\VObject\Property */
+
+ if ($child->name == 'DTSTART') {
+ // DTSTART has to be one of two valid values
+ $this->assertContains($child->getValue(), array('20120214T171500Z', '20120216T171500Z'), 'DTSTART is not a valid value: '.$child->getValue());
+ } elseif ($child->name == 'DTEND') {
+ // DTEND has to be one of two valid values
+ $this->assertContains($child->getValue(), array('20120214T181500Z', '20120216T181500Z'), 'DTEND is not a valid value: '.$child->getValue());
+ }
+ }
+ }
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php
new file mode 100644
index 000000000..96e7c6f09
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php
@@ -0,0 +1,104 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittests is created to find out why certain events show up twice.
+ *
+ * Hopefully, by the time I'm done with this, I've both found the problem, and
+ * fixed it :)
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class ExpandEventsDoubleEventsTest extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:foobar
+DTEND;TZID=Europe/Berlin:20120207T191500
+RRULE:FREQ=DAILY;INTERVAL=1;COUNT=3
+SUMMARY:RecurringEvents 3 times
+DTSTART;TZID=Europe/Berlin:20120207T181500
+END:VEVENT
+BEGIN:VEVENT
+CREATED:20120207T111900Z
+UID:foobar
+DTEND;TZID=Europe/Berlin:20120208T191500
+SUMMARY:RecurringEvents 3 times OVERWRITTEN
+DTSTART;TZID=Europe/Berlin:20120208T181500
+RECURRENCE-ID;TZID=Europe/Berlin:20120208T181500
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testExpand() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120205T230000Z" end="20120212T225959Z"/>
+ </C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20120205T230000Z" end="20120212T225959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ // Everts super awesome xml parser.
+ $body = substr(
+ $response->body,
+ $start = strpos($response->body, 'BEGIN:VCALENDAR'),
+ strpos($response->body, 'END:VCALENDAR') - $start + 13
+ );
+ $body = str_replace('&#13;','',$body);
+
+ $vObject = VObject\Reader::read($body);
+
+ // We only expect 3 events
+ $this->assertEquals(3, count($vObject->VEVENT),'We got 6 events instead of 3. Output: ' . $body);
+
+ // TZID should be gone
+ $this->assertFalse(isset($vObject->VEVENT->DTSTART['TZID']));
+
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php
new file mode 100644
index 000000000..93eca9ee9
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php
@@ -0,0 +1,159 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAV;
+use Sabre\DAVACL;
+use Sabre\HTTP;
+
+require_once 'Sabre/CalDAV/Backend/Mock.php';
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class FreeBusyReportTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\CalDAV\Plugin
+ */
+ protected $plugin;
+ /**
+ * @var Sabre\DAV\Server
+ */
+ protected $server;
+
+ function setUp() {
+
+ $obj1 = <<<ics
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20111005T120000Z
+DURATION:PT1H
+END:VEVENT
+END:VCALENDAR
+ics;
+ $obj2 = fopen('php://memory','r+');
+ fwrite($obj2,<<<ics
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20121005T120000Z
+DURATION:PT1H
+END:VEVENT
+END:VCALENDAR
+ics
+ );
+ rewind($obj2);
+
+ $calendarData = array(
+ 1 => array(
+ 'obj1' => array(
+ 'calendarid' => 1,
+ 'uri' => 'event1.ics',
+ 'calendardata' => $obj1,
+ ),
+ 'obj2' => array(
+ 'calendarid' => 1,
+ 'uri' => 'event2.ics',
+ 'calendardata' => $obj2
+ )
+ ),
+ );
+
+
+ $caldavBackend = new Backend\Mock(array(), $calendarData);
+
+ $calendar = new Calendar($caldavBackend, array(
+ 'id' => 1,
+ 'uri' => 'calendar',
+ 'principaluri' => 'principals/user1',
+ ));
+
+ $this->server = new DAV\Server(array($calendar));
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_URI' => '/calendar',
+ ));
+ $this->server->httpRequest = $request;
+ $this->server->httpResponse = new HTTP\ResponseMock();
+
+ $this->plugin = new Plugin();
+ $this->server->addPlugin($this->plugin);
+ $this->server->addPlugin(new DAVACL\Plugin());
+
+ }
+
+ function testFreeBusyReport() {
+
+ $reportXML = <<<XML
+<?xml version="1.0"?>
+<c:free-busy-query xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <c:time-range start="20111001T000000Z" end="20111101T000000Z" />
+</c:free-busy-query>
+XML;
+
+ $dom = DAV\XMLUtil::loadDOMDocument($reportXML);
+ $this->plugin->report('{urn:ietf:params:xml:ns:caldav}free-busy-query', $dom);
+
+ $this->assertEquals('HTTP/1.1 200 OK', $this->server->httpResponse->status);
+ $this->assertEquals('text/calendar', $this->server->httpResponse->headers['Content-Type']);
+ $this->assertTrue(strpos($this->server->httpResponse->body,'BEGIN:VFREEBUSY')!==false);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testFreeBusyReportNoTimeRange() {
+
+ $reportXML = <<<XML
+<?xml version="1.0"?>
+<c:free-busy-query xmlns:c="urn:ietf:params:xml:ns:caldav">
+</c:free-busy-query>
+XML;
+
+ $dom = DAV\XMLUtil::loadDOMDocument($reportXML);
+ $this->plugin->report('{urn:ietf:params:xml:ns:caldav}free-busy-query', $dom);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotImplemented
+ */
+ function testFreeBusyReportWrongNode() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_URI' => '/',
+ ));
+ $this->server->httpRequest = $request;
+
+ $reportXML = <<<XML
+<?xml version="1.0"?>
+<c:free-busy-query xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <c:time-range start="20111001T000000Z" end="20111101T000000Z" />
+</c:free-busy-query>
+XML;
+
+ $dom = DAV\XMLUtil::loadDOMDocument($reportXML);
+ $this->plugin->report('{urn:ietf:params:xml:ns:caldav}free-busy-query', $dom);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ */
+ function testFreeBusyReportNoACLPlugin() {
+
+ $this->server = new DAV\Server();
+ $this->plugin = new Plugin();
+ $this->server->addPlugin($this->plugin);
+
+ $reportXML = <<<XML
+<?xml version="1.0"?>
+<c:free-busy-query xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <c:time-range start="20111001T000000Z" end="20111101T000000Z" />
+</c:free-busy-query>
+XML;
+
+ $dom = DAV\XMLUtil::loadDOMDocument($reportXML);
+ $this->plugin->report('{urn:ietf:params:xml:ns:caldav}free-busy-query', $dom);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyRequestTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyRequestTest.php
new file mode 100644
index 000000000..62252e6a1
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyRequestTest.php
@@ -0,0 +1,282 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAV;
+use Sabre\DAVACL;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class FreeBusyRequestTest extends \PHPUnit_Framework_TestCase {
+
+ protected $plugin;
+ protected $server;
+ protected $aclPlugin;
+ protected $request;
+ protected $authPlugin;
+
+ function setUp() {
+
+ $calendars = array(
+ array(
+ 'principaluri' => 'principals/user2',
+ 'id' => 1,
+ 'uri' => 'calendar1',
+ ),
+ );
+ $calendarobjects = array(
+ 1 => array( '1.ics' => array(
+ 'uri' => '1.ics',
+ 'calendardata' => 'BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T130000
+DURATION:PT1H
+END:VEVENT
+END:VCALENDAR',
+ 'calendarid' => 1,
+ ))
+
+ );
+
+ $principalBackend = new DAVACL\PrincipalBackend\Mock();
+ $caldavBackend = new Backend\Mock($calendars, $calendarobjects);
+
+ $tree = array(
+ new DAVACL\PrincipalCollection($principalBackend),
+ new CalendarRootNode($principalBackend, $caldavBackend),
+ );
+
+ $this->request = new HTTP\Request(array(
+ 'CONTENT_TYPE' => 'text/calendar',
+ ));
+ $this->response = new HTTP\ResponseMock();
+
+ $this->server = new DAV\Server($tree);
+ $this->server->httpRequest = $this->request;
+ $this->server->httpResponse = $this->response;
+
+ $this->aclPlugin = new DAVACL\Plugin();
+ $this->server->addPlugin($this->aclPlugin);
+
+ $authBackend = new DAV\Auth\Backend\Mock();
+ $authBackend->setCurrentUser('user1');
+ $this->authPlugin = new DAV\Auth\Plugin($authBackend,'SabreDAV');
+ $this->server->addPlugin($this->authPlugin);
+
+ $this->plugin = new Plugin();
+ $this->server->addPlugin($this->plugin);
+
+ }
+
+ function testWrongMethod() {
+
+ $this->assertNull(
+ $this->plugin->unknownMethod('PUT','calendars/user1/outbox')
+ );
+
+ }
+
+ function testWrongContentType() {
+
+ $this->server->httpRequest = new HTTP\Request(array(
+ 'CONTENT_TYPE' => 'text/plain',
+ ));
+
+ $this->assertNull(
+ $this->plugin->unknownMethod('POST','calendars/user1/outbox')
+ );
+
+ }
+
+ function testNotFound() {
+
+ $this->assertNull(
+ $this->plugin->unknownMethod('POST','calendars/user1/blabla')
+ );
+
+ }
+
+ function testNotOutbox() {
+
+ $this->assertNull(
+ $this->plugin->unknownMethod('POST','calendars/user1/inbox')
+ );
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testNoItipMethod() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+BEGIN:VFREEBUSY
+END:VFREEBUSY
+END:VCALENDAR
+ICS;
+
+ $this->request->setBody($body);
+ $this->plugin->unknownMethod('POST','calendars/user1/outbox');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testNoVFreeBusy() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+METHOD:REQUEST
+BEGIN:VEVENT
+END:VEVENT
+END:VCALENDAR
+ICS;
+
+ $this->request->setBody($body);
+ $this->plugin->unknownMethod('POST','calendars/user1/outbox');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ function testIncorrectOrganizer() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+METHOD:REQUEST
+BEGIN:VFREEBUSY
+ORGANIZER:mailto:john@wayne.org
+END:VFREEBUSY
+END:VCALENDAR
+ICS;
+
+ $this->request->setBody($body);
+ $this->plugin->unknownMethod('POST','calendars/user1/outbox');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testNoAttendees() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+METHOD:REQUEST
+BEGIN:VFREEBUSY
+ORGANIZER:mailto:user1.sabredav@sabredav.org
+END:VFREEBUSY
+END:VCALENDAR
+ICS;
+
+ $this->request->setBody($body);
+ $this->plugin->unknownMethod('POST','calendars/user1/outbox');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testNoDTStart() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+METHOD:REQUEST
+BEGIN:VFREEBUSY
+ORGANIZER:mailto:user1.sabredav@sabredav.org
+ATTENDEE:mailto:user2.sabredav@sabredav.org
+END:VFREEBUSY
+END:VCALENDAR
+ICS;
+
+ $this->request->setBody($body);
+ $this->plugin->unknownMethod('POST','calendars/user1/outbox');
+
+ }
+
+ function testSucceed() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+METHOD:REQUEST
+BEGIN:VFREEBUSY
+ORGANIZER:mailto:user1.sabredav@sabredav.org
+ATTENDEE:mailto:user2.sabredav@sabredav.org
+ATTENDEE:mailto:user3.sabredav@sabredav.org
+DTSTART:20110101T080000Z
+DTEND:20110101T180000Z
+END:VFREEBUSY
+END:VCALENDAR
+ICS;
+
+ // Lazily making the current principal an admin.
+ $this->aclPlugin->adminPrincipals[] = 'principals/user1';
+
+ $this->request->setBody($body);
+ $this->assertFalse($this->plugin->unknownMethod('POST','calendars/user1/outbox'));
+
+ $this->assertEquals('HTTP/1.1 200 OK' , $this->response->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ ), $this->response->headers);
+
+ $strings = array(
+ '<d:href>mailto:user2.sabredav@sabredav.org</d:href>',
+ '<d:href>mailto:user3.sabredav@sabredav.org</d:href>',
+ '<cal:request-status>2.0;Success</cal:request-status>',
+ '<cal:request-status>3.7;Could not find principal</cal:request-status>',
+ 'FREEBUSY;FBTYPE=BUSY:20110101T130000Z/20110101T140000Z',
+ );
+
+ foreach($strings as $string) {
+ $this->assertTrue(
+ strpos($this->response->body, $string)!==false,
+ 'The response body did not contain: ' . $string .'Full response: ' . $this->response->body
+ );
+ }
+
+
+ }
+
+ function testNoPrivilege() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+METHOD:REQUEST
+BEGIN:VFREEBUSY
+ORGANIZER:mailto:user1.sabredav@sabredav.org
+ATTENDEE:mailto:user2.sabredav@sabredav.org
+DTSTART:20110101T080000Z
+DTEND:20110101T180000Z
+END:VFREEBUSY
+END:VCALENDAR
+ICS;
+
+ $this->request->setBody($body);
+ $this->assertFalse($this->plugin->unknownMethod('POST','calendars/user1/outbox'));
+
+ $this->assertEquals('HTTP/1.1 200 OK' , $this->response->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ ), $this->response->headers);
+
+ $strings = array(
+ '<d:href>mailto:user2.sabredav@sabredav.org</d:href>',
+ '<cal:request-status>3.7;No calendar-home-set property found</cal:request-status>',
+ );
+
+ foreach($strings as $string) {
+ $this->assertTrue(
+ strpos($this->response->body, $string)!==false,
+ 'The response body did not contain: ' . $string .'Full response: ' . $this->response->body
+ );
+ }
+
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php
new file mode 100644
index 000000000..4e4c2cbf1
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittest is created to check if queries for time-range include the start timestamp or not
+ *
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class GetEventsByTimerangeTest extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+CREATED:20120313T142342Z
+UID:171EBEFC-C951-499D-B234-7BA7D677B45D
+DTEND;TZID=Europe/Berlin:20120227T000000
+TRANSP:OPAQUE
+SUMMARY:Monday 0h
+DTSTART;TZID=Europe/Berlin:20120227T000000
+DTSTAMP:20120313T142416Z
+SEQUENCE:4
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testQueryTimerange() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120226T230000Z" end="20120228T225959Z"/>
+ </C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20120226T230000Z" end="20120228T225959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ if (strpos($response->body, 'BEGIN:VCALENDAR') === false) {
+ $this->fail('Got no events instead of 1. Output: '.$response->body);
+ }
+
+ // Everts super awesome xml parser.
+ $body = substr(
+ $response->body,
+ $start = strpos($response->body, 'BEGIN:VCALENDAR'),
+ strpos($response->body, 'END:VCALENDAR') - $start + 13
+ );
+ $body = str_replace('&#13;','',$body);
+
+ $vObject = VObject\Reader::read($body);
+
+ // We expect 1 event
+ $this->assertEquals(1, count($vObject->VEVENT), 'We got 0 events instead of 1. Output: ' . $body);
+
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php
new file mode 100644
index 000000000..be21796dd
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php
@@ -0,0 +1,227 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+use Sabre\DAVACL;
+
+require_once 'Sabre/CalDAV/TestUtil.php';
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class ICSExportPluginTest extends \PHPUnit_Framework_TestCase {
+
+ function testInit() {
+
+ $p = new ICSExportPlugin();
+ $s = new DAV\Server();
+ $s->addPlugin($p);
+
+ }
+
+ function testBeforeMethod() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $cbackend = TestUtil::getBackend();
+
+ $props = array(
+ 'uri'=>'UUID-123467',
+ 'principaluri' => 'admin',
+ 'id' => 1,
+ );
+ $tree = array(
+ new Calendar($cbackend,$props),
+ );
+
+ $p = new ICSExportPlugin();
+
+ $s = new DAV\Server($tree);
+ $s->addPlugin($p);
+ $s->addPlugin(new Plugin());
+
+ $h = new HTTP\Request(array(
+ 'QUERY_STRING' => 'export',
+ ));
+
+ $s->httpRequest = $h;
+ $s->httpResponse = new HTTP\ResponseMock();
+
+ $this->assertFalse($p->beforeMethod('GET','UUID-123467?export'));
+
+ $this->assertEquals('HTTP/1.1 200 OK',$s->httpResponse->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'text/calendar',
+ ), $s->httpResponse->headers);
+
+ $obj = VObject\Reader::read($s->httpResponse->body);
+
+ $this->assertEquals(5,count($obj->children()));
+ $this->assertEquals(1,count($obj->VERSION));
+ $this->assertEquals(1,count($obj->CALSCALE));
+ $this->assertEquals(1,count($obj->PRODID));
+ $this->assertTrue(strpos((string)$obj->PRODID, DAV\Version::VERSION)!==false);
+ $this->assertEquals(1,count($obj->VTIMEZONE));
+ $this->assertEquals(1,count($obj->VEVENT));
+
+ }
+ function testBeforeMethodNoVersion() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $cbackend = TestUtil::getBackend();
+
+ $props = array(
+ 'uri'=>'UUID-123467',
+ 'principaluri' => 'admin',
+ 'id' => 1,
+ );
+ $tree = array(
+ new Calendar($cbackend,$props),
+ );
+
+ $p = new ICSExportPlugin();
+
+ $s = new DAV\Server($tree);
+
+ $s->addPlugin($p);
+ $s->addPlugin(new Plugin());
+
+ $h = new HTTP\Request(array(
+ 'QUERY_STRING' => 'export',
+ ));
+
+ $s->httpRequest = $h;
+ $s->httpResponse = new HTTP\ResponseMock();
+
+ DAV\Server::$exposeVersion = false;
+ $this->assertFalse($p->beforeMethod('GET','UUID-123467?export'));
+ DAV\Server::$exposeVersion = true;
+
+ $this->assertEquals('HTTP/1.1 200 OK',$s->httpResponse->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'text/calendar',
+ ), $s->httpResponse->headers);
+
+ $obj = VObject\Reader::read($s->httpResponse->body);
+
+ $this->assertEquals(5,count($obj->children()));
+ $this->assertEquals(1,count($obj->VERSION));
+ $this->assertEquals(1,count($obj->CALSCALE));
+ $this->assertEquals(1,count($obj->PRODID));
+ $this->assertFalse(strpos((string)$obj->PRODID, DAV\Version::VERSION)!==false);
+ $this->assertEquals(1,count($obj->VTIMEZONE));
+ $this->assertEquals(1,count($obj->VEVENT));
+
+ }
+
+ function testBeforeMethodNoGET() {
+
+ $p = new ICSExportPlugin();
+
+ $s = new DAV\Server();
+ $s->addPlugin($p);
+
+ $this->assertNull($p->beforeMethod('POST','UUID-123467?export'));
+
+ }
+
+ function testBeforeMethodNoExport() {
+
+ $p = new ICSExportPlugin();
+
+ $s = new DAV\Server();
+ $s->addPlugin($p);
+
+ $this->assertNull($p->beforeMethod('GET','UUID-123467'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testACLIntegrationBlocked() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $cbackend = TestUtil::getBackend();
+
+ $props = array(
+ 'uri'=>'UUID-123467',
+ 'principaluri' => 'admin',
+ 'id' => 1,
+ );
+ $tree = array(
+ new Calendar($cbackend,$props),
+ );
+
+ $p = new ICSExportPlugin();
+
+ $s = new DAV\Server($tree);
+ $s->addPlugin($p);
+ $s->addPlugin(new Plugin());
+ $s->addPlugin(new DAVACL\Plugin());
+
+ $h = new HTTP\Request(array(
+ 'QUERY_STRING' => 'export',
+ ));
+
+ $s->httpRequest = $h;
+ $s->httpResponse = new HTTP\ResponseMock();
+
+ $p->beforeMethod('GET','UUID-123467?export');
+
+ }
+
+ function testACLIntegrationNotBlocked() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $cbackend = TestUtil::getBackend();
+ $pbackend = new DAVACL\PrincipalBackend\Mock();
+
+ $props = array(
+ 'uri'=>'UUID-123467',
+ 'principaluri' => 'admin',
+ 'id' => 1,
+ );
+ $tree = array(
+ new Calendar($cbackend,$props),
+ new DAVACL\PrincipalCollection($pbackend),
+ );
+
+ $p = new ICSExportPlugin();
+
+ $s = new DAV\Server($tree);
+ $s->addPlugin($p);
+ $s->addPlugin(new Plugin());
+ $s->addPlugin(new DAVACL\Plugin());
+ $s->addPlugin(new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'SabreDAV'));
+
+ // Forcing login
+ $s->getPlugin('acl')->adminPrincipals = array('principals/admin');
+
+ $h = new HTTP\Request(array(
+ 'QUERY_STRING' => 'export',
+ 'REQUEST_URI' => '/UUID-123467',
+ 'REQUEST_METHOD' => 'GET',
+ ));
+
+ $s->httpRequest = $h;
+ $s->httpResponse = new HTTP\ResponseMock();
+
+ $s->exec();
+
+ $this->assertEquals('HTTP/1.1 200 OK',$s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
+ $this->assertEquals(array(
+ 'Content-Type' => 'text/calendar',
+ ), $s->httpResponse->headers);
+
+ $obj = VObject\Reader::read($s->httpResponse->body);
+
+ $this->assertEquals(5,count($obj->children()));
+ $this->assertEquals(1,count($obj->VERSION));
+ $this->assertEquals(1,count($obj->CALSCALE));
+ $this->assertEquals(1,count($obj->PRODID));
+ $this->assertEquals(1,count($obj->VTIMEZONE));
+ $this->assertEquals(1,count($obj->VEVENT));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php
new file mode 100644
index 000000000..f925224f2
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\VObject;
+use Sabre\DAV;
+
+class Issue166Test extends \PHPUnit_Framework_TestCase {
+
+ function testFlaw() {
+
+ $input = <<<HI
+BEGIN:VCALENDAR
+PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+TZID:Asia/Pyongyang
+X-LIC-LOCATION:Asia/Pyongyang
+BEGIN:STANDARD
+TZOFFSETFROM:+0900
+TZOFFSETTO:+0900
+TZNAME:KST
+DTSTART:19700101T000000
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20111118T010857Z
+LAST-MODIFIED:20111118T010937Z
+DTSTAMP:20111118T010937Z
+UID:a03245b3-9947-9a48-a088-863c74e0fdd8
+SUMMARY:New Event
+RRULE:FREQ=YEARLY
+DTSTART;TZID=Asia/Pyongyang:19960102T111500
+DTEND;TZID=Asia/Pyongyang:19960102T121500
+END:VEVENT
+END:VCALENDAR
+HI;
+
+ $validator = new CalendarQueryValidator();
+
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-12-01'),
+ 'end' => new \DateTime('2012-02-01'),
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+ $input = VObject\Reader::read($input);
+ $this->assertTrue($validator->validate($input,$filters));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php
new file mode 100644
index 000000000..ce6d364f6
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\VObject;
+use Sabre\DAV;
+
+class Issue172Test extends \PHPUnit_Framework_TestCase {
+
+ // DateTimeZone() native name: America/Los_Angeles (GMT-8 in January)
+ function testBuiltInTimezoneName() {
+ $input = <<<HI
+BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+DTSTART;TZID=America/Los_Angeles:20120118T204500
+DTEND;TZID=America/Los_Angeles:20120118T214500
+END:VEVENT
+END:VCALENDAR
+HI;
+ $validator = new CalendarQueryValidator();
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2012-01-18 21:00:00 GMT-08:00'),
+ 'end' => new \DateTime('2012-01-18 21:00:00 GMT-08:00'),
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ );
+ $input = VObject\Reader::read($input);
+ $this->assertTrue($validator->validate($input,$filters));
+ }
+
+ // Pacific Standard Time, translates to America/Los_Angeles (GMT-8 in January)
+ function testOutlookTimezoneName() {
+ $input = <<<HI
+BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VTIMEZONE
+TZID:Pacific Standard Time
+BEGIN:STANDARD
+DTSTART:16010101T030000
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0100
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:16010101T020000
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0200
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTART;TZID=Pacific Standard Time:20120113T100000
+DTEND;TZID=Pacific Standard Time:20120113T110000
+END:VEVENT
+END:VCALENDAR
+HI;
+ $validator = new CalendarQueryValidator();
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
+ 'end' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ );
+ $input = VObject\Reader::read($input);
+ $this->assertTrue($validator->validate($input,$filters));
+ }
+
+ // X-LIC-LOCATION, translates to America/Los_Angeles (GMT-8 in January)
+ function testLibICalLocationName() {
+ $input = <<<HI
+BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VTIMEZONE
+TZID:My own timezone name
+X-LIC-LOCATION:America/Los_Angeles
+BEGIN:STANDARD
+DTSTART:16010101T030000
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0100
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:16010101T020000
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0200
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTART;TZID=My own timezone name:20120113T100000
+DTEND;TZID=My own timezone name:20120113T110000
+END:VEVENT
+END:VCALENDAR
+HI;
+ $validator = new CalendarQueryValidator();
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
+ 'end' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ );
+ $input = VObject\Reader::read($input);
+ $this->assertTrue($validator->validate($input,$filters));
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue203Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue203Test.php
new file mode 100644
index 000000000..8cc8ad31f
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue203Test.php
@@ -0,0 +1,139 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittest is created to find out why an overwritten DAILY event has wrong DTSTART, DTEND, SUMMARY and RECURRENCEID
+ *
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Issue203Test extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:20120330T155305CEST-6585fBUVgV
+DTSTAMP:20120330T135305Z
+DTSTART;TZID=Europe/Berlin:20120326T155200
+DTEND;TZID=Europe/Berlin:20120326T165200
+RRULE:FREQ=DAILY;COUNT=2;INTERVAL=1
+SUMMARY:original summary
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+UID:20120330T155305CEST-6585fBUVgV
+DTSTAMP:20120330T135352Z
+DESCRIPTION:
+DTSTART;TZID=Europe/Berlin:20120328T155200
+DTEND;TZID=Europe/Berlin:20120328T165200
+RECURRENCE-ID;TZID=Europe/Berlin:20120327T155200
+SEQUENCE:1
+SUMMARY:overwritten summary
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testIssue203() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120325T220000Z" end="20120401T215959Z"/>
+ </C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20120325T220000Z" end="20120401T215959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ // Everts super awesome xml parser.
+ $body = substr(
+ $response->body,
+ $start = strpos($response->body, 'BEGIN:VCALENDAR'),
+ strpos($response->body, 'END:VCALENDAR') - $start + 13
+ );
+ $body = str_replace('&#13;','',$body);
+
+ $vObject = VObject\Reader::read($body);
+
+ $this->assertEquals(2, count($vObject->VEVENT));
+
+
+ $expectedEvents = array(
+ array(
+ 'DTSTART' => '20120326T135200Z',
+ 'DTEND' => '20120326T145200Z',
+ 'SUMMARY' => 'original summary',
+ ),
+ array(
+ 'DTSTART' => '20120328T135200Z',
+ 'DTEND' => '20120328T145200Z',
+ 'SUMMARY' => 'overwritten summary',
+ 'RECURRENCE-ID' => '20120327T135200Z',
+ )
+ );
+
+ // try to match agains $expectedEvents array
+ foreach ($expectedEvents as $expectedEvent) {
+
+ $matching = false;
+
+ foreach ($vObject->VEVENT as $vevent) {
+ /** @var $vevent Sabre\VObject\Component\VEvent */
+
+ foreach ($vevent->children as $child) {
+ /** @var $child Sabre\VObject\Property */
+
+ if (isset($expectedEvent[$child->name])) {
+ if ($expectedEvent[$child->name] != $child->getValue()) {
+ continue 2;
+ }
+ }
+ }
+
+ $matching = true;
+ break;
+ }
+
+ $this->assertTrue($matching, 'Did not find the following event in the response: '.var_export($expectedEvent, true));
+ }
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php
new file mode 100644
index 000000000..db336c806
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php
@@ -0,0 +1,98 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittest is created to check if a VALARM TRIGGER of PT0S is supported
+ *
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Issue205Test extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:20120330T155305CEST-6585fBUVgV
+DTSTAMP:20120330T135305Z
+DTSTART;TZID=Europe/Berlin:20120326T155200
+DTEND;TZID=Europe/Berlin:20120326T165200
+SUMMARY:original summary
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:AUDIO
+ATTACH;VALUE=URI:Basso
+TRIGGER:PT0S
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testIssue205() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120325T220000Z" end="20120401T215959Z"/>
+ </C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:comp-filter name="VALARM">
+ <C:time-range start="20120325T220000Z" end="20120401T215959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ $this->assertFalse(strpos($response->body, '<s:exception>Exception</s:exception>'), 'Exception occurred: ' . $response->body);
+ $this->assertFalse(strpos($response->body, 'Unknown or bad format'), 'DateTime unknown format Exception: ' . $response->body);
+
+ // Everts super awesome xml parser.
+ $body = substr(
+ $response->body,
+ $start = strpos($response->body, 'BEGIN:VCALENDAR'),
+ strpos($response->body, 'END:VCALENDAR') - $start + 13
+ );
+ $body = str_replace('&#13;','',$body);
+
+ $vObject = VObject\Reader::read($body);
+
+ $this->assertEquals(1, count($vObject->VEVENT));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php
new file mode 100644
index 000000000..5e28c804b
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php
@@ -0,0 +1,90 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittest is created to check for an endless loop in Sabre\CalDAV\CalendarQueryValidator
+ *
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Issue211Test extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:20120418T172519CEST-3510gh1hVw
+DTSTAMP:20120418T152519Z
+DTSTART;VALUE=DATE:20120330
+DTEND;VALUE=DATE:20120531
+EXDATE;TZID=Europe/Berlin:20120330T000000
+RRULE:FREQ=YEARLY;INTERVAL=1
+SEQUENCE:1
+SUMMARY:Birthday
+TRANSP:TRANSPARENT
+BEGIN:VALARM
+ACTION:EMAIL
+ATTENDEE:MAILTO:xxx@domain.de
+DESCRIPTION:Dies ist eine Kalender Erinnerung
+SUMMARY:Kalender Alarm Erinnerung
+TRIGGER;VALUE=DATE-TIME:20120329T060000Z
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testIssue211() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data/>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:comp-filter name="VALARM">
+ <C:time-range start="20120426T220000Z" end="20120427T215959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ // if this assert is reached, the endless loop is gone
+ // There should be no matching events
+ $this->assertFalse(strpos('BEGIN:VEVENT', $response->body));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php
new file mode 100644
index 000000000..c701df544
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\HTTP;
+
+/**
+ * This unittest is created to check for an endless loop in CalendarQueryValidator
+ *
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Issue220Test extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+DTSTART;TZID=Europe/Berlin:20120601T180000
+SUMMARY:Brot backen
+RRULE:FREQ=DAILY;INTERVAL=1;WKST=MO
+TRANSP:OPAQUE
+DURATION:PT20M
+LAST-MODIFIED:20120601T064634Z
+CREATED:20120601T064634Z
+DTSTAMP:20120601T064634Z
+UID:b64f14c5-dccc-4eda-947f-bdb1f763fbcd
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION:-PT5M
+ACTION:DISPLAY
+DESCRIPTION:Default Event Notification
+X-WR-ALARMUID:cd952c1b-b3d6-41fb-b0a6-ec3a1a5bdd58
+END:VALARM
+END:VEVENT
+BEGIN:VEVENT
+DTSTART;TZID=Europe/Berlin:20120606T180000
+SUMMARY:Brot backen
+TRANSP:OPAQUE
+STATUS:CANCELLED
+DTEND;TZID=Europe/Berlin:20120606T182000
+LAST-MODIFIED:20120605T094310Z
+SEQUENCE:1
+RECURRENCE-ID:20120606T160000Z
+UID:b64f14c5-dccc-4eda-947f-bdb1f763fbcd
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testIssue220() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data/>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:comp-filter name="VALARM">
+ <C:time-range start="20120607T161646Z" end="20120612T161646Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ $this->assertFalse(strpos($response->body, '<s:exception>PHPUnit_Framework_Error_Warning</s:exception>'), 'Error Warning occurred: ' . $response->body);
+ $this->assertFalse(strpos($response->body, 'Invalid argument supplied for foreach()'), 'Invalid argument supplied for foreach(): ' . $response->body);
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status);
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php
new file mode 100644
index 000000000..e8b6dfaa6
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php
@@ -0,0 +1,78 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+
+/**
+ * This unittest is created to check if the time-range filter is working correctly with all-day-events
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Issue228Test extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:20120730T113415CEST-6804EGphkd@xxxxxx.de
+DTSTAMP:20120730T093415Z
+DTSTART;VALUE=DATE:20120729
+DTEND;VALUE=DATE:20120730
+SUMMARY:sunday event
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testIssue228() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120730T095609Z"
+ end="20120813T095609Z"/>
+</C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20120730T095609Z" end="20120813T095609Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ // We must check if absolutely nothing was returned from this query.
+ $this->assertFalse(strpos($response->body, 'BEGIN:VCALENDAR'));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php
new file mode 100644
index 000000000..eaed4f503
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php
@@ -0,0 +1,90 @@
+<?php
+
+namespace Sabre\CalDAV\Notifications;
+
+use Sabre\CalDAV;
+
+class CollectionTest extends \PHPUnit_Framework_TestCase {
+
+ protected $caldavBackend;
+ protected $principalUri;
+ protected $notification;
+
+ function getInstance() {
+
+ $this->principalUri = 'principals/user1';
+
+ $this->notification = new Notification\SystemStatus(1,'"1"');
+
+ $this->caldavBackend = new CalDAV\Backend\Mock(array(),array(), array(
+ 'principals/user1' => array(
+ $this->notification
+ )
+ ));
+
+ return new Collection($this->caldavBackend, $this->principalUri);
+
+ }
+
+ function testGetChildren() {
+
+ $col = $this->getInstance();
+ $this->assertEquals('notifications', $col->getName());
+
+ $this->assertEquals(array(
+ new Node($this->caldavBackend, $this->principalUri, $this->notification)
+ ), $col->getChildren());
+
+ }
+
+ function testGetOwner() {
+
+ $col = $this->getInstance();
+ $this->assertEquals('principals/user1', $col->getOwner());
+
+ }
+
+ function testGetGroup() {
+
+ $col = $this->getInstance();
+ $this->assertNull($col->getGroup());
+
+ }
+
+ function testGetACL() {
+
+ $col = $this->getInstance();
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->principalUri,
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => $this->principalUri,
+ 'protected' => true,
+ ),
+ );
+
+ $this->assertEquals($expected, $col->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotImplemented
+ */
+ function testSetACL() {
+
+ $col = $this->getInstance();
+ $col->setACL(array());
+
+ }
+
+ function testGetSupportedPrivilegeSet() {
+
+ $col = $this->getInstance();
+ $this->assertNull($col->getSupportedPrivilegeSet());
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php
new file mode 100644
index 000000000..28e43ce08
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php
@@ -0,0 +1,101 @@
+<?php
+
+namespace Sabre\CalDAV\Notifications;
+
+use Sabre\CalDAV;
+
+class NodeTest extends \PHPUnit_Framework_TestCase {
+
+ protected $systemStatus;
+ protected $caldavBackend;
+
+ function getInstance() {
+
+ $principalUri = 'principals/user1';
+
+ $this->systemStatus = new Notification\SystemStatus(1,'"1"');
+
+ $this->caldavBackend = new CalDAV\Backend\Mock(array(),array(), array(
+ 'principals/user1' => array(
+ $this->systemStatus
+ )
+ ));
+
+ $node = new Node($this->caldavBackend, 'principals/user1', $this->systemStatus);
+ return $node;
+
+ }
+
+ function testGetId() {
+
+ $node = $this->getInstance();
+ $this->assertEquals($this->systemStatus->getId() . '.xml', $node->getName());
+
+ }
+
+ function testGetEtag() {
+
+ $node = $this->getInstance();
+ $this->assertEquals('"1"', $node->getETag());
+
+ }
+
+ function testGetNotificationType() {
+
+ $node = $this->getInstance();
+ $this->assertEquals($this->systemStatus, $node->getNotificationType());
+
+ }
+
+ function testDelete() {
+
+ $node = $this->getInstance();
+ $node->delete();
+ $this->assertEquals(array(), $this->caldavBackend->getNotificationsForPrincipal('principals/user1'));
+
+ }
+
+ function testGetGroup() {
+
+ $node = $this->getInstance();
+ $this->assertNull($node->getGroup());
+
+ }
+
+ function testGetACL() {
+
+ $node = $this->getInstance();
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ );
+
+ $this->assertEquals($expected, $node->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotImplemented
+ */
+ function testSetACL() {
+
+ $node = $this->getInstance();
+ $node->setACL(array());
+
+ }
+
+ function testGetSupportedPrivilegeSet() {
+
+ $node = $this->getInstance();
+ $this->assertNull($node->getSupportedPrivilegeSet());
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteReplyTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteReplyTest.php
new file mode 100644
index 000000000..c53f68cee
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteReplyTest.php
@@ -0,0 +1,134 @@
+<?php
+
+namespace Sabre\CalDAV\Notifications\Notification;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class InviteReplyTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @dataProvider dataProvider
+ */
+ function testSerializers($notification, $expected) {
+
+ $notification = new InviteReply($notification);
+
+ $this->assertEquals('foo', $notification->getId());
+ $this->assertEquals('"1"', $notification->getETag());
+
+ $simpleExpected = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:invite-reply/></cs:root>' . "\n";
+
+ $dom = new \DOMDocument('1.0','UTF-8');
+ $elem = $dom->createElement('cs:root');
+ $elem->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+ $dom->appendChild($elem);
+ $notification->serialize(new DAV\Server(), $elem);
+ $this->assertEquals($simpleExpected, $dom->saveXML());
+
+ $dom = new \DOMDocument('1.0','UTF-8');
+ $dom->formatOutput = true;
+ $elem = $dom->createElement('cs:root');
+ $elem->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+ $elem->setAttribute('xmlns:d','DAV:');
+ $dom->appendChild($elem);
+ $notification->serializeBody(new DAV\Server(), $elem);
+ $this->assertEquals($expected, $dom->saveXML());
+
+
+ }
+
+ function dataProvider() {
+
+ $dtStamp = new \DateTime('2012-01-01 00:00:00 GMT');
+ return array(
+ array(
+ array(
+ 'id' => 'foo',
+ 'dtStamp' => $dtStamp,
+ 'etag' => '"1"',
+ 'inReplyTo' => 'bar',
+ 'href' => 'mailto:foo@example.org',
+ 'type' => CalDAV\SharingPlugin::STATUS_ACCEPTED,
+ 'hostUrl' => 'calendar'
+ ),
+<<<FOO
+<?xml version="1.0" encoding="UTF-8"?>
+<cs:root xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:">
+ <cs:dtstamp>20120101T000000Z</cs:dtstamp>
+ <cs:invite-reply>
+ <cs:uid>foo</cs:uid>
+ <cs:in-reply-to>bar</cs:in-reply-to>
+ <d:href>mailto:foo@example.org</d:href>
+ <cs:invite-accepted/>
+ <cs:hosturl>
+ <d:href>/calendar</d:href>
+ </cs:hosturl>
+ </cs:invite-reply>
+</cs:root>
+
+FOO
+ ),
+ array(
+ array(
+ 'id' => 'foo',
+ 'dtStamp' => $dtStamp,
+ 'etag' => '"1"',
+ 'inReplyTo' => 'bar',
+ 'href' => 'mailto:foo@example.org',
+ 'type' => CalDAV\SharingPlugin::STATUS_DECLINED,
+ 'hostUrl' => 'calendar',
+ 'summary' => 'Summary!'
+ ),
+<<<FOO
+<?xml version="1.0" encoding="UTF-8"?>
+<cs:root xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:">
+ <cs:dtstamp>20120101T000000Z</cs:dtstamp>
+ <cs:invite-reply>
+ <cs:uid>foo</cs:uid>
+ <cs:in-reply-to>bar</cs:in-reply-to>
+ <d:href>mailto:foo@example.org</d:href>
+ <cs:invite-declined/>
+ <cs:hosturl>
+ <d:href>/calendar</d:href>
+ </cs:hosturl>
+ <cs:summary>Summary!</cs:summary>
+ </cs:invite-reply>
+</cs:root>
+
+FOO
+ ),
+
+ );
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testMissingArg() {
+
+ new InviteReply(array());
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testUnknownArg() {
+
+ new InviteReply(array(
+ 'foo-i-will-break' => true,
+
+ 'id' => 1,
+ 'etag' => '"bla"',
+ 'href' => 'abc',
+ 'dtStamp' => 'def',
+ 'inReplyTo' => 'qrs',
+ 'type' => 'ghi',
+ 'hostUrl' => 'jkl',
+ ));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteTest.php
new file mode 100644
index 000000000..d2c114f4c
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteTest.php
@@ -0,0 +1,230 @@
+<?php
+
+namespace Sabre\CalDAV\Notifications\Notification;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class InviteTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @dataProvider dataProvider
+ */
+ function testSerializers($notification, $expected) {
+
+ $notification = new Invite($notification);
+
+ $this->assertEquals('foo', $notification->getId());
+ $this->assertEquals('"1"', $notification->getETag());
+
+ $simpleExpected = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:invite-notification/></cs:root>' . "\n";
+
+ $dom = new \DOMDocument('1.0','UTF-8');
+ $elem = $dom->createElement('cs:root');
+ $elem->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+ $dom->appendChild($elem);
+ $notification->serialize(new DAV\Server(), $elem);
+ $this->assertEquals($simpleExpected, $dom->saveXML());
+
+ $dom = new \DOMDocument('1.0','UTF-8');
+ $dom->formatOutput = true;
+ $elem = $dom->createElement('cs:root');
+ $elem->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+ $elem->setAttribute('xmlns:d','DAV:');
+ $elem->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+ $dom->appendChild($elem);
+ $notification->serializeBody(new DAV\Server(), $elem);
+ $this->assertEquals($expected, $dom->saveXML());
+
+
+ }
+
+ function dataProvider() {
+
+ $dtStamp = new \DateTime('2012-01-01 00:00:00', new \DateTimeZone('GMT'));
+ return array(
+ array(
+ array(
+ 'id' => 'foo',
+ 'dtStamp' => $dtStamp,
+ 'etag' => '"1"',
+ 'href' => 'mailto:foo@example.org',
+ 'type' => CalDAV\SharingPlugin::STATUS_ACCEPTED,
+ 'readOnly' => true,
+ 'hostUrl' => 'calendar',
+ 'organizer' => 'principal/user1',
+ 'commonName' => 'John Doe',
+ 'summary' => 'Awesome stuff!'
+ ),
+<<<FOO
+<?xml version="1.0" encoding="UTF-8"?>
+<cs:root xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:cal="urn:ietf:params:xml:ns:caldav">
+ <cs:dtstamp>20120101T000000Z</cs:dtstamp>
+ <cs:invite-notification>
+ <cs:uid>foo</cs:uid>
+ <d:href>mailto:foo@example.org</d:href>
+ <cs:invite-accepted/>
+ <cs:hosturl>
+ <d:href>/calendar</d:href>
+ </cs:hosturl>
+ <cs:access>
+ <cs:read/>
+ </cs:access>
+ <cs:organizer-cn>John Doe</cs:organizer-cn>
+ <cs:organizer>
+ <d:href>/principal/user1</d:href>
+ <cs:common-name>John Doe</cs:common-name>
+ </cs:organizer>
+ <cs:summary>Awesome stuff!</cs:summary>
+ </cs:invite-notification>
+</cs:root>
+
+FOO
+ ),
+ array(
+ array(
+ 'id' => 'foo',
+ 'dtStamp' => $dtStamp,
+ 'etag' => '"1"',
+ 'href' => 'mailto:foo@example.org',
+ 'type' => CalDAV\SharingPlugin::STATUS_DECLINED,
+ 'readOnly' => true,
+ 'hostUrl' => 'calendar',
+ 'organizer' => 'principal/user1',
+ 'commonName' => 'John Doe',
+ ),
+<<<FOO
+<?xml version="1.0" encoding="UTF-8"?>
+<cs:root xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:cal="urn:ietf:params:xml:ns:caldav">
+ <cs:dtstamp>20120101T000000Z</cs:dtstamp>
+ <cs:invite-notification>
+ <cs:uid>foo</cs:uid>
+ <d:href>mailto:foo@example.org</d:href>
+ <cs:invite-declined/>
+ <cs:hosturl>
+ <d:href>/calendar</d:href>
+ </cs:hosturl>
+ <cs:access>
+ <cs:read/>
+ </cs:access>
+ <cs:organizer-cn>John Doe</cs:organizer-cn>
+ <cs:organizer>
+ <d:href>/principal/user1</d:href>
+ <cs:common-name>John Doe</cs:common-name>
+ </cs:organizer>
+ </cs:invite-notification>
+</cs:root>
+
+FOO
+ ),
+ array(
+ array(
+ 'id' => 'foo',
+ 'dtStamp' => $dtStamp,
+ 'etag' => '"1"',
+ 'href' => 'mailto:foo@example.org',
+ 'type' => CalDAV\SharingPlugin::STATUS_NORESPONSE,
+ 'readOnly' => true,
+ 'hostUrl' => 'calendar',
+ 'organizer' => 'principal/user1',
+ 'firstName' => 'Foo',
+ 'lastName' => 'Bar',
+ ),
+<<<FOO
+<?xml version="1.0" encoding="UTF-8"?>
+<cs:root xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:cal="urn:ietf:params:xml:ns:caldav">
+ <cs:dtstamp>20120101T000000Z</cs:dtstamp>
+ <cs:invite-notification>
+ <cs:uid>foo</cs:uid>
+ <d:href>mailto:foo@example.org</d:href>
+ <cs:invite-noresponse/>
+ <cs:hosturl>
+ <d:href>/calendar</d:href>
+ </cs:hosturl>
+ <cs:access>
+ <cs:read/>
+ </cs:access>
+ <cs:organizer-first>Foo</cs:organizer-first>
+ <cs:organizer-last>Bar</cs:organizer-last>
+ <cs:organizer>
+ <d:href>/principal/user1</d:href>
+ <cs:first-name>Foo</cs:first-name>
+ <cs:last-name>Bar</cs:last-name>
+ </cs:organizer>
+ </cs:invite-notification>
+</cs:root>
+
+FOO
+ ),
+ array(
+ array(
+ 'id' => 'foo',
+ 'dtStamp' => $dtStamp,
+ 'etag' => '"1"',
+ 'href' => 'mailto:foo@example.org',
+ 'type' => CalDAV\SharingPlugin::STATUS_DELETED,
+ 'readOnly' => false,
+ 'hostUrl' => 'calendar',
+ 'organizer' => 'mailto:user1@fruux.com',
+ 'supportedComponents' => new CalDAV\Property\SupportedCalendarComponentSet(array('VEVENT','VTODO')),
+ ),
+<<<FOO
+<?xml version="1.0" encoding="UTF-8"?>
+<cs:root xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:cal="urn:ietf:params:xml:ns:caldav">
+ <cs:dtstamp>20120101T000000Z</cs:dtstamp>
+ <cs:invite-notification>
+ <cs:uid>foo</cs:uid>
+ <d:href>mailto:foo@example.org</d:href>
+ <cs:invite-deleted/>
+ <cs:hosturl>
+ <d:href>/calendar</d:href>
+ </cs:hosturl>
+ <cs:access>
+ <cs:read-write/>
+ </cs:access>
+ <cs:organizer>
+ <d:href>mailto:user1@fruux.com</d:href>
+ </cs:organizer>
+ <cal:supported-calendar-component-set>
+ <cal:comp name="VEVENT"/>
+ <cal:comp name="VTODO"/>
+ </cal:supported-calendar-component-set>
+ </cs:invite-notification>
+</cs:root>
+
+FOO
+ ),
+
+ );
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testMissingArg() {
+
+ new Invite(array());
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testUnknownArg() {
+
+ new Invite(array(
+ 'foo-i-will-break' => true,
+
+ 'id' => 1,
+ 'etag' => '"bla"',
+ 'href' => 'abc',
+ 'dtStamp' => 'def',
+ 'type' => 'ghi',
+ 'readOnly' => true,
+ 'hostUrl' => 'jkl',
+ 'organizer' => 'mno',
+ ));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/SystemStatusTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/SystemStatusTest.php
new file mode 100644
index 000000000..8dc494932
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/SystemStatusTest.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Sabre\CalDAV\Notifications\Notification;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class SystemStatusTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @dataProvider dataProvider
+ */
+ function testSerializers($notification, $expected1, $expected2) {
+
+ $this->assertEquals('foo', $notification->getId());
+ $this->assertEquals('"1"', $notification->getETag());
+
+
+ $dom = new \DOMDocument('1.0','UTF-8');
+ $elem = $dom->createElement('cs:root');
+ $elem->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+ $dom->appendChild($elem);
+ $notification->serialize(new DAV\Server(), $elem);
+ $this->assertEquals($expected1, $dom->saveXML());
+
+ $dom = new \DOMDocument('1.0','UTF-8');
+ $elem = $dom->createElement('cs:root');
+ $elem->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+ $dom->appendChild($elem);
+ $notification->serializeBody(new DAV\Server(), $elem);
+ $this->assertEquals($expected2, $dom->saveXML());
+
+
+ }
+
+ function dataProvider() {
+
+ return array(
+
+ array(
+ new SystemStatus('foo', '"1"'),
+ '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:systemstatus type="high"/></cs:root>' . "\n",
+ '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:systemstatus type="high"/></cs:root>' . "\n",
+ ),
+
+ array(
+ new SystemStatus('foo', '"1"', SystemStatus::TYPE_MEDIUM,'bar'),
+ '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:systemstatus type="medium"/></cs:root>' . "\n",
+ '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:systemstatus type="medium"><cs:description>bar</cs:description></cs:systemstatus></cs:root>' . "\n",
+ ),
+
+ array(
+ new SystemStatus('foo', '"1"', SystemStatus::TYPE_LOW,null,'http://example.org/'),
+ '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:systemstatus type="low"/></cs:root>' . "\n",
+ '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:systemstatus type="low"><d:href>http://example.org/</d:href></cs:systemstatus></cs:root>' . "\n",
+ )
+ );
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/OutboxPostTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/OutboxPostTest.php
new file mode 100644
index 000000000..5a5a4e75c
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/OutboxPostTest.php
@@ -0,0 +1,545 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+use Sabre\DAV;
+
+require_once 'Sabre/DAVServerTest.php';
+require_once 'Sabre/CalDAV/Schedule/IMip/Mock.php';
+
+class OutboxPostTest extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ function testPostPassThruNotFound() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/notfound',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $this->assertHTTPStatus(501, $req);
+
+ }
+
+ function testPostPassThruNotTextCalendar() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/admin/outbox',
+ ));
+
+ $this->assertHTTPStatus(501, $req);
+
+ }
+
+ function testPostPassThruNoOutBox() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $this->assertHTTPStatus(501, $req);
+
+ }
+
+ function testNoOriginator() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/admin/outbox',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(400, $req);
+
+ }
+
+ function testNoRecipient() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/admin/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:orig@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(400, $req);
+
+ }
+
+ function testBadOriginator() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/admin/outbox',
+ 'HTTP_ORIGINATOR' => 'nomailto:orig@example.org',
+ 'HTTP_RECIPIENT' => 'mailto:user1@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(403, $req);
+
+ }
+
+ function testBadRecipient() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/admin/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:orig@example.org',
+ 'HTTP_RECIPIENT' => 'http://user1@example.org, mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(400, $req);
+
+ }
+
+ function testIncorrectOriginator() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/admin/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:orig@example.org',
+ 'HTTP_RECIPIENT' => 'mailto:user1@example.org, mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(403, $req);
+
+ }
+
+ function testInvalidIcalBody() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+ $req->setBody('foo');
+
+ $this->assertHTTPStatus(400, $req);
+
+ }
+
+ function testNoVEVENT() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'BEGIN:VTIMEZONE',
+ 'END:VTIMEZONE',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(400, $req);
+
+ }
+
+ function testNoMETHOD() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(400, $req);
+
+ }
+
+ function testUnsupportedMethod() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:PUBLISH',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(501, $req);
+
+ }
+
+ function testNoIMIPHandler() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+
+ $response = $this->request($req);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ ), $response->headers);
+
+ // Lazily checking the body for a few expected values.
+ $this->assertTrue(strpos($response->body, '5.2;')!==false);
+ $this->assertTrue(strpos($response->body,'user2@example.org')!==false);
+
+
+ }
+
+ function testSuccessRequest() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'SUMMARY:An invitation',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $handler = new Schedule\IMip\Mock('server@example.org');
+
+ $this->caldavPlugin->setIMIPhandler($handler);
+
+ $response = $this->request($req);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ ), $response->headers);
+
+ // Lazily checking the body for a few expected values.
+ $this->assertTrue(strpos($response->body, '2.0;')!==false);
+ $this->assertTrue(strpos($response->body,'user2@example.org')!==false);
+
+ $this->assertEquals(array(
+ array(
+ 'to' => 'user2@example.org',
+ 'subject' => 'Invitation for: An invitation',
+ 'body' => implode("\r\n", $body) . "\r\n",
+ 'headers' => array(
+ 'Reply-To: user1.sabredav@sabredav.org',
+ 'From: server@example.org',
+ 'Content-Type: text/calendar; method=REQUEST; charset=utf-8',
+ 'X-Sabre-Version: ' . DAV\Version::VERSION . '-' . DAV\Version::STABILITY,
+ ),
+ )
+ ), $handler->getSentEmails());
+
+ }
+
+ function testSuccessRequestUseRelativePrincipal() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => '/principals/user1/',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'SUMMARY:An invitation',
+ 'ORGANIZER:mailto:user1.sabredav@sabredav.org',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $handler = new Schedule\IMip\Mock('server@example.org');
+
+ $this->caldavPlugin->setIMIPhandler($handler);
+
+ $response = $this->request($req);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status, 'Full body: ' . $response->body);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ ), $response->headers);
+
+ // Lazily checking the body for a few expected values.
+ $this->assertTrue(strpos($response->body, '2.0;')!==false);
+ $this->assertTrue(strpos($response->body,'user2@example.org')!==false);
+
+ $this->assertEquals(array(
+ array(
+ 'to' => 'user2@example.org',
+ 'subject' => 'Invitation for: An invitation',
+ 'body' => implode("\r\n", $body) . "\r\n",
+ 'headers' => array(
+ 'Reply-To: user1.sabredav@sabredav.org',
+ 'From: server@example.org',
+ 'Content-Type: text/calendar; method=REQUEST; charset=utf-8',
+ 'X-Sabre-Version: ' . DAV\Version::VERSION . '-' . DAV\Version::STABILITY,
+ ),
+ )
+ ), $handler->getSentEmails());
+
+ }
+
+ function testSuccessRequestUpperCased() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'MAILTO:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'MAILTO:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'SUMMARY:An invitation',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $handler = new Schedule\IMip\Mock('server@example.org');
+
+ $this->caldavPlugin->setIMIPhandler($handler);
+
+ $response = $this->request($req);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ ), $response->headers);
+
+ // Lazily checking the body for a few expected values.
+ $this->assertTrue(strpos($response->body, '2.0;')!==false);
+ $this->assertTrue(strpos($response->body,'user2@example.org')!==false);
+
+ $this->assertEquals(array(
+ array(
+ 'to' => 'user2@example.org',
+ 'subject' => 'Invitation for: An invitation',
+ 'body' => implode("\r\n", $body) . "\r\n",
+ 'headers' => array(
+ 'Reply-To: user1.sabredav@sabredav.org',
+ 'From: server@example.org',
+ 'Content-Type: text/calendar; method=REQUEST; charset=utf-8',
+ 'X-Sabre-Version: ' . DAV\Version::VERSION . '-' . DAV\Version::STABILITY,
+ ),
+ )
+ ), $handler->getSentEmails());
+
+ }
+
+ function testSuccessReply() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REPLY',
+ 'BEGIN:VEVENT',
+ 'SUMMARY:An invitation',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $handler = new Schedule\IMip\Mock('server@example.org');
+
+ $this->caldavPlugin->setIMIPhandler($handler);
+ $this->assertHTTPStatus(200, $req);
+
+ $this->assertEquals(array(
+ array(
+ 'to' => 'user2@example.org',
+ 'subject' => 'Response for: An invitation',
+ 'body' => implode("\r\n", $body) . "\r\n",
+ 'headers' => array(
+ 'Reply-To: user1.sabredav@sabredav.org',
+ 'From: server@example.org',
+ 'Content-Type: text/calendar; method=REPLY; charset=utf-8',
+ 'X-Sabre-Version: ' . DAV\Version::VERSION . '-' . DAV\Version::STABILITY,
+ ),
+ )
+ ), $handler->getSentEmails());
+
+ }
+
+ function testSuccessCancel() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:CANCEL',
+ 'BEGIN:VEVENT',
+ 'SUMMARY:An invitation',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $handler = new Schedule\IMip\Mock('server@example.org');
+
+ $this->caldavPlugin->setIMIPhandler($handler);
+ $this->assertHTTPStatus(200, $req);
+
+ $this->assertEquals(array(
+ array(
+ 'to' => 'user2@example.org',
+ 'subject' => 'Cancelled event: An invitation',
+ 'body' => implode("\r\n", $body) . "\r\n",
+ 'headers' => array(
+ 'Reply-To: user1.sabredav@sabredav.org',
+ 'From: server@example.org',
+ 'Content-Type: text/calendar; method=CANCEL; charset=utf-8',
+ 'X-Sabre-Version: ' . DAV\Version::VERSION . '-' . DAV\Version::STABILITY,
+ ),
+ )
+ ), $handler->getSentEmails());
+
+
+ }
+
+ function testUseRelativePrincipalNoFallback() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => '/principals/user1/',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'SUMMARY:An invitation',
+ 'ORGANIZER:rrrrrr',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $handler = new Schedule\IMip\Mock('server@example.org');
+
+ $this->caldavPlugin->setIMIPhandler($handler);
+
+ $response = $this->request($req);
+ $this->assertEquals('HTTP/1.1 403 Forbidden', $response->status, 'Full body: ' . $response->body);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php
new file mode 100644
index 000000000..fb7dc316a
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php
@@ -0,0 +1,1126 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\DAVACL;
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+require_once 'Sabre/CalDAV/TestUtil.php';
+
+class PluginTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\DAV\Server
+ */
+ protected $server;
+ /**
+ * @var Sabre\CalDAV\Plugin
+ */
+ protected $plugin;
+ protected $response;
+ /**
+ * @var Sabre\CalDAV\Backend\PDO
+ */
+ protected $caldavBackend;
+
+ function setup() {
+
+ $this->caldavBackend = new Backend\Mock(array(
+ array(
+ 'id' => 1,
+ 'uri' => 'UUID-123467',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'user1 calendar',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar description',
+ '{http://apple.com/ns/ical/}calendar-order' => '1',
+ '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Property\SupportedCalendarComponentSet(array('VEVENT','VTODO')),
+ ),
+ array(
+ 'id' => 2,
+ 'uri' => 'UUID-123468',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'user1 calendar2',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar description',
+ '{http://apple.com/ns/ical/}calendar-order' => '1',
+ '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Property\SupportedCalendarComponentSet(array('VEVENT','VTODO')),
+ )
+ ), array(
+ 1 => array(
+ 'UUID-2345' => array(
+ 'calendardata' => TestUtil::getTestCalendarData(),
+ )
+ )
+ ));
+ $principalBackend = new DAVACL\PrincipalBackend\Mock();
+ $principalBackend->setGroupMemberSet('principals/admin/calendar-proxy-read',array('principals/user1'));
+ $principalBackend->setGroupMemberSet('principals/admin/calendar-proxy-write',array('principals/user1'));
+ $principalBackend->addPrincipal(array(
+ 'uri' => 'principals/admin/calendar-proxy-read',
+ ));
+ $principalBackend->addPrincipal(array(
+ 'uri' => 'principals/admin/calendar-proxy-write',
+ ));
+
+ $calendars = new CalendarRootNode($principalBackend,$this->caldavBackend);
+ $principals = new Principal\Collection($principalBackend);
+
+ $root = new DAV\SimpleCollection('root');
+ $root->addChild($calendars);
+ $root->addChild($principals);
+
+ $objectTree = new DAV\ObjectTree($root);
+ $this->server = new DAV\Server($objectTree);
+ $this->server->debugExceptions = true;
+ $this->server->setBaseUri('/');
+ $this->plugin = new Plugin();
+ $this->server->addPlugin($this->plugin);
+
+ // Adding ACL plugin
+ $this->server->addPlugin(new DAVACL\Plugin());
+
+ // Adding Auth plugin, and ensuring that we are logged in.
+ $authBackend = new DAV\Auth\Backend\Mock();
+ $authBackend->defaultUser = 'user1';
+ $authPlugin = new DAV\Auth\Plugin($authBackend, 'SabreDAV');
+ $this->server->addPlugin($authPlugin);
+
+ $authPlugin->beforeMethod('GET', '/');
+
+ $this->response = new HTTP\ResponseMock();
+ $this->server->httpResponse = $this->response;
+
+ }
+
+ function testSimple() {
+
+ $this->assertEquals(array('MKCALENDAR'), $this->plugin->getHTTPMethods('calendars/user1/randomnewcalendar'));
+ $this->assertEquals(array('calendar-access','calendar-proxy'), $this->plugin->getFeatures());
+ $this->assertArrayHasKey('urn:ietf:params:xml:ns:caldav', $this->server->xmlNamespaces);
+
+ }
+
+ function testUnknownMethodPassThrough() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'MKBREAKFAST',
+ 'REQUEST_URI' => '/',
+ ));
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $this->response->status,'Incorrect status returned. Full response body:' . $this->response->body);
+
+ }
+
+ function testReportPassThrough() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/',
+ ));
+ $request->setBody('<?xml version="1.0"?><s:somereport xmlns:s="http://www.rooftopsolutions.nl/NS/example" />');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden', $this->response->status);
+
+ }
+
+ function testMkCalendarBadLocation() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'MKCALENDAR',
+ 'REQUEST_URI' => '/blabla',
+ ));
+
+ $body = '<?xml version="1.0" encoding="utf-8" ?>
+ <C:mkcalendar xmlns:D="DAV:"
+ xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:set>
+ <D:prop>
+ <D:displayname>Lisa\'s Events</D:displayname>
+ <C:calendar-description xml:lang="en"
+ >Calendar restricted to events.</C:calendar-description>
+ <C:supported-calendar-component-set>
+ <C:comp name="VEVENT"/>
+ </C:supported-calendar-component-set>
+ <C:calendar-timezone><![CDATA[BEGIN:VCALENDAR
+ PRODID:-//Example Corp.//CalDAV Client//EN
+ VERSION:2.0
+ BEGIN:VTIMEZONE
+ TZID:US-Eastern
+ LAST-MODIFIED:19870101T000000Z
+ BEGIN:STANDARD
+ DTSTART:19671029T020000
+ RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+ TZOFFSETFROM:-0400
+ TZOFFSETTO:-0500
+ TZNAME:Eastern Standard Time (US & Canada)
+ END:STANDARD
+ BEGIN:DAYLIGHT
+ DTSTART:19870405T020000
+ RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+ TZOFFSETFROM:-0500
+ TZOFFSETTO:-0400
+ TZNAME:Eastern Daylight Time (US & Canada)
+ END:DAYLIGHT
+ END:VTIMEZONE
+ END:VCALENDAR
+ ]]></C:calendar-timezone>
+ </D:prop>
+ </D:set>
+ </C:mkcalendar>';
+
+ $request->setBody($body);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden', $this->response->status);
+
+ }
+
+ function testMkCalendarNoParentNode() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'MKCALENDAR',
+ 'REQUEST_URI' => '/doesntexist/calendar',
+ ));
+
+ $body = '<?xml version="1.0" encoding="utf-8" ?>
+ <C:mkcalendar xmlns:D="DAV:"
+ xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:set>
+ <D:prop>
+ <D:displayname>Lisa\'s Events</D:displayname>
+ <C:calendar-description xml:lang="en"
+ >Calendar restricted to events.</C:calendar-description>
+ <C:supported-calendar-component-set>
+ <C:comp name="VEVENT"/>
+ </C:supported-calendar-component-set>
+ <C:calendar-timezone><![CDATA[BEGIN:VCALENDAR
+ PRODID:-//Example Corp.//CalDAV Client//EN
+ VERSION:2.0
+ BEGIN:VTIMEZONE
+ TZID:US-Eastern
+ LAST-MODIFIED:19870101T000000Z
+ BEGIN:STANDARD
+ DTSTART:19671029T020000
+ RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+ TZOFFSETFROM:-0400
+ TZOFFSETTO:-0500
+ TZNAME:Eastern Standard Time (US & Canada)
+ END:STANDARD
+ BEGIN:DAYLIGHT
+ DTSTART:19870405T020000
+ RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+ TZOFFSETFROM:-0500
+ TZOFFSETTO:-0400
+ TZNAME:Eastern Daylight Time (US & Canada)
+ END:DAYLIGHT
+ END:VTIMEZONE
+ END:VCALENDAR
+ ]]></C:calendar-timezone>
+ </D:prop>
+ </D:set>
+ </C:mkcalendar>';
+
+ $request->setBody($body);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 409 Conflict', $this->response->status);
+
+ }
+
+ function testMkCalendarExistingCalendar() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'MKCALENDAR',
+ 'REQUEST_URI' => '/calendars/user1/UUID-123467',
+ ));
+
+ $body = '<?xml version="1.0" encoding="utf-8" ?>
+ <C:mkcalendar xmlns:D="DAV:"
+ xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:set>
+ <D:prop>
+ <D:displayname>Lisa\'s Events</D:displayname>
+ <C:calendar-description xml:lang="en"
+ >Calendar restricted to events.</C:calendar-description>
+ <C:supported-calendar-component-set>
+ <C:comp name="VEVENT"/>
+ </C:supported-calendar-component-set>
+ <C:calendar-timezone><![CDATA[BEGIN:VCALENDAR
+ PRODID:-//Example Corp.//CalDAV Client//EN
+ VERSION:2.0
+ BEGIN:VTIMEZONE
+ TZID:US-Eastern
+ LAST-MODIFIED:19870101T000000Z
+ BEGIN:STANDARD
+ DTSTART:19671029T020000
+ RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+ TZOFFSETFROM:-0400
+ TZOFFSETTO:-0500
+ TZNAME:Eastern Standard Time (US & Canada)
+ END:STANDARD
+ BEGIN:DAYLIGHT
+ DTSTART:19870405T020000
+ RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+ TZOFFSETFROM:-0500
+ TZOFFSETTO:-0400
+ TZNAME:Eastern Daylight Time (US & Canada)
+ END:DAYLIGHT
+ END:VTIMEZONE
+ END:VCALENDAR
+ ]]></C:calendar-timezone>
+ </D:prop>
+ </D:set>
+ </C:mkcalendar>';
+
+ $request->setBody($body);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 405 Method Not Allowed', $this->response->status);
+
+ }
+
+ function testMkCalendarSucceed() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'MKCALENDAR',
+ 'REQUEST_URI' => '/calendars/user1/NEWCALENDAR',
+ ));
+
+ $timezone = 'BEGIN:VCALENDAR
+PRODID:-//Example Corp.//CalDAV Client//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+TZID:US-Eastern
+LAST-MODIFIED:19870101T000000Z
+BEGIN:STANDARD
+DTSTART:19671029T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+TZNAME:Eastern Standard Time (US & Canada)
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:19870405T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+TZNAME:Eastern Daylight Time (US & Canada)
+END:DAYLIGHT
+END:VTIMEZONE
+END:VCALENDAR';
+
+ $body = '<?xml version="1.0" encoding="utf-8" ?>
+ <C:mkcalendar xmlns:D="DAV:"
+ xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:set>
+ <D:prop>
+ <D:displayname>Lisa\'s Events</D:displayname>
+ <C:calendar-description xml:lang="en"
+ >Calendar restricted to events.</C:calendar-description>
+ <C:supported-calendar-component-set>
+ <C:comp name="VEVENT"/>
+ </C:supported-calendar-component-set>
+ <C:calendar-timezone><![CDATA[' . $timezone . ']]></C:calendar-timezone>
+ </D:prop>
+ </D:set>
+ </C:mkcalendar>';
+
+ $request->setBody($body);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 201 Created', $this->response->status,'Invalid response code received. Full response body: ' .$this->response->body);
+
+ $calendars = $this->caldavBackend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(3, count($calendars));
+
+ $newCalendar = null;
+ foreach($calendars as $calendar) {
+ if ($calendar['uri'] === 'NEWCALENDAR') {
+ $newCalendar = $calendar;
+ break;
+ }
+ }
+
+ $this->assertInternalType('array',$newCalendar);
+
+ $keys = array(
+ 'uri' => 'NEWCALENDAR',
+ 'id' => null,
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar restricted to events.',
+ '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => $timezone,
+ '{DAV:}displayname' => 'Lisa\'s Events',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => null,
+ );
+
+ foreach($keys as $key=>$value) {
+
+ $this->assertArrayHasKey($key, $newCalendar);
+
+ if (is_null($value)) continue;
+ $this->assertEquals($value, $newCalendar[$key]);
+
+ }
+ $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
+ $this->assertTrue($newCalendar[$sccs] instanceof Property\SupportedCalendarComponentSet);
+ $this->assertEquals(array('VEVENT'),$newCalendar[$sccs]->getValue());
+
+ }
+
+ function testMkCalendarEmptyBodySucceed() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'MKCALENDAR',
+ 'REQUEST_URI' => '/calendars/user1/NEWCALENDAR',
+ ));
+
+ $request->setBody('');
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 201 Created', $this->response->status,'Invalid response code received. Full response body: ' .$this->response->body);
+
+ $calendars = $this->caldavBackend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(3, count($calendars));
+
+ $newCalendar = null;
+ foreach($calendars as $calendar) {
+ if ($calendar['uri'] === 'NEWCALENDAR') {
+ $newCalendar = $calendar;
+ break;
+ }
+ }
+
+ $this->assertInternalType('array',$newCalendar);
+
+ $keys = array(
+ 'uri' => 'NEWCALENDAR',
+ 'id' => null,
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => null,
+ );
+
+ foreach($keys as $key=>$value) {
+
+ $this->assertArrayHasKey($key, $newCalendar);
+
+ if (is_null($value)) continue;
+ $this->assertEquals($value, $newCalendar[$key]);
+
+ }
+ $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
+ $this->assertTrue($newCalendar[$sccs] instanceof Property\SupportedCalendarComponentSet);
+ $this->assertEquals(array('VEVENT','VTODO'),$newCalendar[$sccs]->getValue());
+
+ }
+
+ function testPrincipalProperties() {
+
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_HOST' => 'sabredav.org',
+ ));
+ $this->server->httpRequest = $httpRequest;
+
+ $props = $this->server->getPropertiesForPath('/principals/user1',array(
+ '{urn:ietf:params:xml:ns:caldav}calendar-home-set',
+ '{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL',
+ '{urn:ietf:params:xml:ns:caldav}calendar-user-address-set',
+ '{' . Plugin::NS_CALENDARSERVER . '}calendar-proxy-read-for',
+ '{' . Plugin::NS_CALENDARSERVER . '}calendar-proxy-write-for',
+ '{' . Plugin::NS_CALENDARSERVER . '}notification-URL',
+ ));
+
+ $this->assertArrayHasKey(0,$props);
+ $this->assertArrayHasKey(200,$props[0]);
+
+
+ $this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}calendar-home-set',$props[0][200]);
+ $prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}calendar-home-set'];
+ $this->assertTrue($prop instanceof DAV\Property\Href);
+ $this->assertEquals('calendars/user1/',$prop->getHref());
+
+ $this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL',$props[0][200]);
+ $prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL'];
+ $this->assertTrue($prop instanceof DAV\Property\Href);
+ $this->assertEquals('calendars/user1/outbox',$prop->getHref());
+
+ $this->assertArrayHasKey('{'.Plugin::NS_CALENDARSERVER .'}notification-URL',$props[0][200]);
+ $prop = $props[0][200]['{'.Plugin::NS_CALENDARSERVER .'}notification-URL'];
+ $this->assertTrue($prop instanceof DAV\Property\Href);
+ $this->assertEquals('calendars/user1/notifications/',$prop->getHref());
+
+
+ $this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}calendar-user-address-set',$props[0][200]);
+ $prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}calendar-user-address-set'];
+ $this->assertTrue($prop instanceof DAV\Property\HrefList);
+ $this->assertEquals(array('mailto:user1.sabredav@sabredav.org','/principals/user1/'),$prop->getHrefs());
+
+ $this->assertArrayHasKey('{http://calendarserver.org/ns/}calendar-proxy-read-for', $props[0][200]);
+ $prop = $props[0][200]['{http://calendarserver.org/ns/}calendar-proxy-read-for'];
+ $this->assertInstanceOf('Sabre\\DAV\\Property\\HrefList', $prop);
+ $this->assertEquals(array('principals/admin'), $prop->getHrefs());
+
+ $this->assertArrayHasKey('{http://calendarserver.org/ns/}calendar-proxy-write-for', $props[0][200]);
+ $prop = $props[0][200]['{http://calendarserver.org/ns/}calendar-proxy-write-for'];
+ $this->assertInstanceOf('Sabre\\DAV\\Property\\HrefList', $prop);
+ $this->assertEquals(array('principals/admin'), $prop->getHrefs());
+
+
+ }
+
+ function testSupportedReportSetPropertyNonCalendar() {
+
+ $props = $this->server->getPropertiesForPath('/calendars/user1',array(
+ '{DAV:}supported-report-set',
+ ));
+
+ $this->assertArrayHasKey(0,$props);
+ $this->assertArrayHasKey(200,$props[0]);
+ $this->assertArrayHasKey('{DAV:}supported-report-set',$props[0][200]);
+
+ $prop = $props[0][200]['{DAV:}supported-report-set'];
+
+ $this->assertInstanceOf('\\Sabre\\DAV\\Property\\SupportedReportSet', $prop);
+ $value = array(
+ '{DAV:}expand-property',
+ '{DAV:}principal-property-search',
+ '{DAV:}principal-search-property-set'
+ );
+ $this->assertEquals($value,$prop->getValue());
+
+ }
+
+ /**
+ * @depends testSupportedReportSetPropertyNonCalendar
+ */
+ function testSupportedReportSetProperty() {
+
+ $props = $this->server->getPropertiesForPath('/calendars/user1/UUID-123467',array(
+ '{DAV:}supported-report-set',
+ ));
+
+ $this->assertArrayHasKey(0,$props);
+ $this->assertArrayHasKey(200,$props[0]);
+ $this->assertArrayHasKey('{DAV:}supported-report-set',$props[0][200]);
+
+ $prop = $props[0][200]['{DAV:}supported-report-set'];
+
+ $this->assertTrue($prop instanceof \Sabre\DAV\Property\SupportedReportSet);
+ $value = array(
+ '{urn:ietf:params:xml:ns:caldav}calendar-multiget',
+ '{urn:ietf:params:xml:ns:caldav}calendar-query',
+ '{urn:ietf:params:xml:ns:caldav}free-busy-query',
+ '{DAV:}expand-property',
+ '{DAV:}principal-property-search',
+ '{DAV:}principal-search-property-set'
+ );
+ $this->assertEquals($value,$prop->getValue());
+
+ }
+
+ /**
+ * @depends testSupportedReportSetProperty
+ */
+ function testCalendarMultiGetReport() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data />' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>' .
+ '</c:calendar-multiget>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body);
+
+ $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($this->response->body));
+
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:href',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getetag',
+ '/d:multistatus/d:response/d:propstat/d:prop/c:calendar-data',
+ '/d:multistatus/d:response/d:propstat/d:status' => 'HTTP/1.1 200 OK',
+ );
+
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result));
+
+ if (!is_int($v1)) $this->assertEquals($v2,(string)$result[0]);
+
+ }
+
+ // The response object should have a reference to the Asia/Seoul
+ // timezone.
+ $this->assertTrue(strpos($this->response->body,'Asia/Seoul')!==false);
+
+ }
+
+ /**
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarMultiGetReportExpand() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data>' .
+ ' <c:expand start="20110101T000000Z" end="20111231T235959Z" />' .
+ ' </c:calendar-data>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>' .
+ '</c:calendar-multiget>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body);
+
+ $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($this->response->body));
+
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:href',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getetag',
+ '/d:multistatus/d:response/d:propstat/d:prop/c:calendar-data',
+ '/d:multistatus/d:response/d:propstat/d:status' => 'HTTP/1.1 200 OK',
+ );
+
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result));
+
+ if (!is_int($v1)) $this->assertEquals($v2,(string)$result[0]);
+
+ }
+ // The response object should no longer hold references to timezones.
+ $this->assertTrue(strpos($this->response->body,'Asia/Seoul')===false);
+
+ }
+
+ /**
+ * @depends testSupportedReportSetProperty
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarQueryReport() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data>' .
+ ' <c:expand start="20000101T000000Z" end="20101231T235959Z" />' .
+ ' </c:calendar-data>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<c:filter>' .
+ ' <c:comp-filter name="VCALENDAR">' .
+ ' <c:comp-filter name="VEVENT" />' .
+ ' </c:comp-filter>' .
+ '</c:filter>' .
+ '</c:calendar-query>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1/UUID-123467',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
+
+ $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($this->response->body));
+
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:href',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getetag',
+ '/d:multistatus/d:response/d:propstat/d:prop/c:calendar-data',
+ '/d:multistatus/d:response/d:propstat/d:status' => 'HTTP/1.1 200 OK',
+ );
+
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result), 'We expected 1 ' . $xpath . ' elements. We\'ve found ' . count($result) . '. Full result: ' . $this->response->body);
+
+ if (!is_int($v1)) $this->assertEquals($v2,(string)$result[0]);
+
+ }
+
+ }
+
+ /**
+ * @depends testCalendarQueryReport
+ */
+ function testCalendarQueryReportNoCalData() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<c:filter>' .
+ ' <c:comp-filter name="VCALENDAR">' .
+ ' <c:comp-filter name="VEVENT" />' .
+ ' </c:comp-filter>' .
+ '</c:filter>' .
+ '</c:calendar-query>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1//UUID-123467',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
+
+ $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($this->response->body));
+
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:href',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getetag',
+ '/d:multistatus/d:response/d:propstat/d:status' => 'HTTP/1.1 200 OK',
+ );
+
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result), 'We expected 1 ' . $xpath . ' elements. We\'ve found ' . count($result) . '. Full result: ' . $this->response->body);
+
+ if (!is_int($v1)) $this->assertEquals($v2,(string)$result[0]);
+
+ }
+
+ }
+
+ /**
+ * @depends testCalendarQueryReport
+ */
+ function testCalendarQueryReportNoFilters() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data />' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '</c:calendar-query>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1//UUID-123467',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
+
+ }
+
+ /**
+ * @depends testSupportedReportSetProperty
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarQueryReport1Object() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data>' .
+ ' <c:expand start="20000101T000000Z" end="20101231T235959Z" />' .
+ ' </c:calendar-data>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<c:filter>' .
+ ' <c:comp-filter name="VCALENDAR">' .
+ ' <c:comp-filter name="VEVENT" />' .
+ ' </c:comp-filter>' .
+ '</c:filter>' .
+ '</c:calendar-query>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1/UUID-123467/UUID-2345',
+ 'HTTP_DEPTH' => '0',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
+
+ $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($this->response->body));
+
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:href',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getetag',
+ '/d:multistatus/d:response/d:propstat/d:prop/c:calendar-data',
+ '/d:multistatus/d:response/d:propstat/d:status' => 'HTTP/1.1 200 OK',
+ );
+
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result), 'We expected 1 ' . $xpath . ' elements. We\'ve found ' . count($result) . '. Full result: ' . $this->response->body);
+
+ if (!is_int($v1)) $this->assertEquals($v2,(string)$result[0]);
+
+ }
+
+ }
+
+ /**
+ * @depends testSupportedReportSetProperty
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarQueryReport1ObjectNoCalData() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<c:filter>' .
+ ' <c:comp-filter name="VCALENDAR">' .
+ ' <c:comp-filter name="VEVENT" />' .
+ ' </c:comp-filter>' .
+ '</c:filter>' .
+ '</c:calendar-query>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1/UUID-123467/UUID-2345',
+ 'HTTP_DEPTH' => '0',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
+
+ $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($this->response->body));
+
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:href',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getetag',
+ '/d:multistatus/d:response/d:propstat/d:status' => 'HTTP/1.1 200 OK',
+ );
+
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result), 'We expected 1 ' . $xpath . ' elements. We\'ve found ' . count($result) . '. Full result: ' . $this->response->body);
+
+ if (!is_int($v1)) $this->assertEquals($v2,(string)$result[0]);
+
+ }
+
+ }
+
+ function testHTMLActionsPanel() {
+
+ $output = '';
+ $r = $this->server->broadcastEvent('onHTMLActionsPanel', array($this->server->tree->getNodeForPath('calendars/user1'), &$output));
+ $this->assertFalse($r);
+
+ $this->assertTrue(!!strpos($output,'Display name'));
+
+ }
+
+ function testBrowserPostAction() {
+
+ $r = $this->server->broadcastEvent('onBrowserPostAction', array('calendars/user1', 'mkcalendar', array(
+ 'name' => 'NEWCALENDAR',
+ '{DAV:}displayname' => 'foo',
+ )));
+ $this->assertFalse($r);
+
+ $calendars = $this->caldavBackend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(3, count($calendars));
+
+ $newCalendar = null;
+ foreach($calendars as $calendar) {
+ if ($calendar['uri'] === 'NEWCALENDAR') {
+ $newCalendar = $calendar;
+ break;
+ }
+ }
+ if (!$newCalendar)
+ $this->fail('Could not find newly created calendar');
+
+
+ }
+
+ /**
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarMultiGetReportNoEnd() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data>' .
+ ' <c:expand start="20110101T000000Z" />' .
+ ' </c:calendar-data>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>' .
+ '</c:calendar-multiget>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body);
+
+ }
+
+ /**
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarMultiGetReportNoStart() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data>' .
+ ' <c:expand end="20110101T000000Z" />' .
+ ' </c:calendar-data>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>' .
+ '</c:calendar-multiget>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body);
+
+ }
+
+ /**
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarMultiGetReportEndBeforeStart() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data>' .
+ ' <c:expand start="20200101T000000Z" end="20110101T000000Z" />' .
+ ' </c:calendar-data>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>' .
+ '</c:calendar-multiget>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body);
+
+ }
+
+ function testNotificationProperties() {
+
+ $request = array(
+ '{' . Plugin::NS_CALENDARSERVER . '}notificationtype',
+ );
+ $result = array();
+ $notification = new Notifications\Node(
+ $this->caldavBackend,
+ 'principals/user1',
+ new Notifications\Notification\SystemStatus('foo','"1"')
+ );
+ $this->plugin->beforeGetProperties('foo', $notification, $request, $result);
+
+ $this->assertEquals(
+ array(
+ 200 => array(
+ '{' . Plugin::NS_CALENDARSERVER . '}notificationtype' => $notification->getNotificationType()
+ )
+ ), $result);
+
+ }
+
+ function testNotificationGet() {
+
+ $notification = new Notifications\Node(
+ $this->caldavBackend,
+ 'principals/user1',
+ new Notifications\Notification\SystemStatus('foo','"1"')
+ );
+
+ $server = new DAV\Server(array($notification));
+ $caldav = new Plugin();
+
+ $server->httpRequest = new HTTP\Request(array(
+ 'REQUEST_URI' => '/foo.xml',
+ ));
+ $httpResponse = new HTTP\ResponseMock();
+ $server->httpResponse = $httpResponse;
+
+ $server->addPlugin($caldav);
+
+ $caldav->beforeMethod('GET','foo.xml');
+
+ $this->assertEquals('HTTP/1.1 200 OK', $httpResponse->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ 'ETag' => '"1"',
+ ), $httpResponse->headers);
+
+ $expected =
+'<?xml version="1.0" encoding="UTF-8"?>
+<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/">
+ <cs:systemstatus type="high"/>
+</cs:notification>
+';
+
+ $this->assertEquals($expected, $httpResponse->body);
+
+ }
+
+ function testGETPassthrough() {
+
+ $server = new DAV\Server();
+ $caldav = new Plugin();
+
+ $httpResponse = new HTTP\ResponseMock();
+ $server->httpResponse = $httpResponse;
+
+ $server->addPlugin($caldav);
+
+ $caldav->beforeMethod('GET','foo');
+
+ $this->assertNull($caldav->beforeMethod('GET','foozz'));
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php
new file mode 100644
index 000000000..625f64211
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Sabre\CalDAV\Principal;
+use Sabre\DAVACL;
+
+class CollectionTest extends \PHPUnit_Framework_TestCase {
+
+ function testGetChildForPrincipal() {
+
+ $back = new DAVACL\PrincipalBackend\Mock();
+ $col = new Collection($back);
+ $r = $col->getChildForPrincipal(array(
+ 'uri' => 'principals/admin',
+ ));
+ $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\User', $r);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php
new file mode 100644
index 000000000..1ee999a92
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php
@@ -0,0 +1,101 @@
+<?php
+
+namespace Sabre\CalDAV\Principal;
+use Sabre\DAVACL;
+
+class ProxyReadTest extends \PHPUnit_Framework_TestCase {
+
+ protected $backend;
+
+ function getInstance() {
+
+ $backend = new DAVACL\PrincipalBackend\Mock();
+ $principal = new ProxyRead($backend, array(
+ 'uri' => 'principal/user',
+ ));
+ $this->backend = $backend;
+ return $principal;
+
+ }
+
+ function testGetName() {
+
+ $i = $this->getInstance();
+ $this->assertEquals('calendar-proxy-read', $i->getName());
+
+ }
+ function testGetDisplayName() {
+
+ $i = $this->getInstance();
+ $this->assertEquals('calendar-proxy-read', $i->getDisplayName());
+
+ }
+
+ function testGetLastModified() {
+
+ $i = $this->getInstance();
+ $this->assertNull($i->getLastModified());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ function testDelete() {
+
+ $i = $this->getInstance();
+ $i->delete();
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ function testSetName() {
+
+ $i = $this->getInstance();
+ $i->setName('foo');
+
+ }
+
+ function testGetAlternateUriSet() {
+
+ $i = $this->getInstance();
+ $this->assertEquals(array(), $i->getAlternateUriSet());
+
+ }
+
+ function testGetPrincipalUri() {
+
+ $i = $this->getInstance();
+ $this->assertEquals('principal/user/calendar-proxy-read', $i->getPrincipalUrl());
+
+ }
+
+ function testGetGroupMemberSet() {
+
+ $i = $this->getInstance();
+ $this->assertEquals(array(), $i->getGroupMemberSet());
+
+ }
+
+ function testGetGroupMembership() {
+
+ $i = $this->getInstance();
+ $this->assertEquals(array(), $i->getGroupMembership());
+
+ }
+
+ function testSetGroupMemberSet() {
+
+ $i = $this->getInstance();
+ $i->setGroupMemberSet(array('principals/foo'));
+
+ $expected = array(
+ $i->getPrincipalUrl() => array('principals/foo')
+ );
+
+ $this->assertEquals($expected, $this->backend->groupMembers);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php
new file mode 100644
index 000000000..c0186ff0d
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Sabre\CalDAV\Principal;
+use Sabre\DAVACL;
+
+class ProxyWriteTest extends ProxyReadTest {
+
+ function getInstance() {
+
+ $backend = new DAVACL\PrincipalBackend\Mock();
+ $principal = new ProxyWrite($backend, array(
+ 'uri' => 'principal/user',
+ ));
+ $this->backend = $backend;
+ return $principal;
+
+ }
+
+ function testGetName() {
+
+ $i = $this->getInstance();
+ $this->assertEquals('calendar-proxy-write', $i->getName());
+
+ }
+ function testGetDisplayName() {
+
+ $i = $this->getInstance();
+ $this->assertEquals('calendar-proxy-write', $i->getDisplayName());
+
+ }
+
+ function testGetPrincipalUri() {
+
+ $i = $this->getInstance();
+ $this->assertEquals('principal/user/calendar-proxy-write', $i->getPrincipalUrl());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php
new file mode 100644
index 000000000..d41692f2a
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php
@@ -0,0 +1,126 @@
+<?php
+
+namespace Sabre\CalDAV\Principal;
+use Sabre\DAVACL;
+
+class UserTest extends \PHPUnit_Framework_TestCase {
+
+ function getInstance() {
+
+ $backend = new DAVACL\PrincipalBackend\Mock();
+ $backend->addPrincipal(array(
+ 'uri' => 'principals/user/calendar-proxy-read',
+ ));
+ $backend->addPrincipal(array(
+ 'uri' => 'principals/user/calendar-proxy-write',
+ ));
+ $backend->addPrincipal(array(
+ 'uri' => 'principals/user/random',
+ ));
+ return new User($backend, array(
+ 'uri' => 'principals/user',
+ ));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ function testCreateFile() {
+
+ $u = $this->getInstance();
+ $u->createFile('test');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ function testCreateDirectory() {
+
+ $u = $this->getInstance();
+ $u->createDirectory('test');
+
+ }
+
+ function testGetChildProxyRead() {
+
+ $u = $this->getInstance();
+ $child = $u->getChild('calendar-proxy-read');
+ $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyRead', $child);
+
+ }
+
+ function testGetChildProxyWrite() {
+
+ $u = $this->getInstance();
+ $child = $u->getChild('calendar-proxy-write');
+ $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyWrite', $child);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotFound
+ */
+ function testGetChildNotFound() {
+
+ $u = $this->getInstance();
+ $child = $u->getChild('foo');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotFound
+ */
+ function testGetChildNotFound2() {
+
+ $u = $this->getInstance();
+ $child = $u->getChild('random');
+
+ }
+
+ function testGetChildren() {
+
+ $u = $this->getInstance();
+ $children = $u->getChildren();
+ $this->assertEquals(2, count($children));
+ $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyRead', $children[0]);
+ $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyWrite', $children[1]);
+
+ }
+
+ function testChildExist() {
+
+ $u = $this->getInstance();
+ $this->assertTrue($u->childExists('calendar-proxy-read'));
+ $this->assertTrue($u->childExists('calendar-proxy-write'));
+ $this->assertFalse($u->childExists('foo'));
+
+ }
+
+ function testGetACL() {
+
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user/calendar-proxy-read',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ );
+
+ $u = $this->getInstance();
+ $this->assertEquals($expected, $u->getACL());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Property/AllowedSharingModesTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/AllowedSharingModesTest.php
new file mode 100644
index 000000000..733ea1108
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/AllowedSharingModesTest.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Sabre\CalDAV\Property;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class AllowedSharingModesTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $sccs = new AllowedSharingModes(true,true);
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerialize() {
+
+ $property = new AllowedSharingModes(true,true);
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+ $root->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '" xmlns:cs="' . CalDAV\Plugin::NS_CALENDARSERVER . '">' .
+'<cs:can-be-shared/>' .
+'<cs:can-be-published/>' .
+'</d:root>
+', $xml);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Property/InviteTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/InviteTest.php
new file mode 100644
index 000000000..349a6e080
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/InviteTest.php
@@ -0,0 +1,196 @@
+<?php
+
+namespace Sabre\CalDAV\Property;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class InviteTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $sccs = new Invite(array());
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerialize() {
+
+ $property = new Invite(array(
+ array(
+ 'href' => 'mailto:user1@example.org',
+ 'status' => CalDAV\SharingPlugin::STATUS_ACCEPTED,
+ 'readOnly' => false,
+ ),
+ array(
+ 'href' => 'mailto:user2@example.org',
+ 'commonName' => 'John Doe',
+ 'status' => CalDAV\SharingPlugin::STATUS_DECLINED,
+ 'readOnly' => true,
+ ),
+ array(
+ 'href' => 'mailto:user3@example.org',
+ 'commonName' => 'Joe Shmoe',
+ 'status' => CalDAV\SharingPlugin::STATUS_NORESPONSE,
+ 'readOnly' => true,
+ 'summary' => 'Something, something',
+ ),
+ array(
+ 'href' => 'mailto:user4@example.org',
+ 'commonName' => 'Hoe Boe',
+ 'status' => CalDAV\SharingPlugin::STATUS_INVALID,
+ 'readOnly' => true,
+ ),
+ ), array(
+ 'href' => 'mailto:thedoctor@example.org',
+ 'commonName' => 'The Doctor',
+ 'firstName' => 'The',
+ 'lastName' => 'Doctor',
+ ));
+
+ $doc = new \DOMDocument();
+ $doc->formatOutput = true;
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+ $root->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '" xmlns:cs="' . CalDAV\Plugin::NS_CALENDARSERVER . '">
+ <cs:organizer>
+ <d:href>mailto:thedoctor@example.org</d:href>
+ <cs:common-name>The Doctor</cs:common-name>
+ <cs:first-name>The</cs:first-name>
+ <cs:last-name>Doctor</cs:last-name>
+ </cs:organizer>
+ <cs:user>
+ <d:href>mailto:user1@example.org</d:href>
+ <cs:invite-accepted/>
+ <cs:access>
+ <cs:read-write/>
+ </cs:access>
+ </cs:user>
+ <cs:user>
+ <d:href>mailto:user2@example.org</d:href>
+ <cs:common-name>John Doe</cs:common-name>
+ <cs:invite-declined/>
+ <cs:access>
+ <cs:read/>
+ </cs:access>
+ </cs:user>
+ <cs:user>
+ <d:href>mailto:user3@example.org</d:href>
+ <cs:common-name>Joe Shmoe</cs:common-name>
+ <cs:invite-noresponse/>
+ <cs:access>
+ <cs:read/>
+ </cs:access>
+ <cs:summary>Something, something</cs:summary>
+ </cs:user>
+ <cs:user>
+ <d:href>mailto:user4@example.org</d:href>
+ <cs:common-name>Hoe Boe</cs:common-name>
+ <cs:invite-invalid/>
+ <cs:access>
+ <cs:read/>
+ </cs:access>
+ </cs:user>
+</d:root>
+', $xml);
+
+ }
+
+ /**
+ * @depends testSerialize
+ */
+ public function testUnserialize() {
+
+ $input = array(
+ array(
+ 'href' => 'mailto:user1@example.org',
+ 'status' => CalDAV\SharingPlugin::STATUS_ACCEPTED,
+ 'readOnly' => false,
+ 'commonName' => '',
+ 'summary' => '',
+ ),
+ array(
+ 'href' => 'mailto:user2@example.org',
+ 'commonName' => 'John Doe',
+ 'status' => CalDAV\SharingPlugin::STATUS_DECLINED,
+ 'readOnly' => true,
+ 'summary' => '',
+ ),
+ array(
+ 'href' => 'mailto:user3@example.org',
+ 'commonName' => 'Joe Shmoe',
+ 'status' => CalDAV\SharingPlugin::STATUS_NORESPONSE,
+ 'readOnly' => true,
+ 'summary' => 'Something, something',
+ ),
+ array(
+ 'href' => 'mailto:user4@example.org',
+ 'commonName' => 'Hoe Boe',
+ 'status' => CalDAV\SharingPlugin::STATUS_INVALID,
+ 'readOnly' => true,
+ 'summary' => '',
+ ),
+ );
+
+ // Creating the xml
+ $doc = new \DOMDocument();
+ $doc->formatOutput = true;
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+ $root->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $inputProperty = new Invite($input);
+ $inputProperty->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ // Parsing it again
+
+ $doc2 = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $outputProperty = Invite::unserialize($doc2->firstChild);
+
+ $this->assertEquals($input, $outputProperty->getValue());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ */
+ function testUnserializeNoStatus() {
+
+$xml = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '" xmlns:cs="' . CalDAV\Plugin::NS_CALENDARSERVER . '">
+ <cs:user>
+ <d:href>mailto:user1@example.org</d:href>
+ <!-- <cs:invite-accepted/> -->
+ <cs:access>
+ <cs:read-write/>
+ </cs:access>
+ </cs:user>
+</d:root>';
+
+ $doc2 = DAV\XMLUtil::loadDOMDocument($xml);
+ $outputProperty = Invite::unserialize($doc2->firstChild);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Property/ScheduleCalendarTranspTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/ScheduleCalendarTranspTest.php
new file mode 100644
index 000000000..1ace0b18f
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/ScheduleCalendarTranspTest.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace Sabre\CalDAV\Property;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class ScheduleCalendarTranspTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $sccs = new ScheduleCalendarTransp('transparent');
+ $this->assertEquals('transparent', $sccs->getValue());
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testBadArg() {
+
+ $sccs = new ScheduleCalendarTransp('foo');
+
+ }
+
+ function values() {
+
+ return array(
+ array('transparent'),
+ array('opaque'),
+ );
+
+ }
+
+ /**
+ * @depends testSimple
+ * @dataProvider values
+ */
+ function testSerialize($value) {
+
+ $property = new ScheduleCalendarTransp($value);
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:' . $value . '/>' .
+'</d:root>
+', $xml);
+
+ }
+
+ /**
+ * @depends testSimple
+ * @dataProvider values
+ */
+ function testUnserializer($value) {
+
+ $xml = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:'.$value.'/>' .
+'</d:root>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $property = ScheduleCalendarTransp::unserialize($dom->firstChild);
+
+ $this->assertTrue($property instanceof ScheduleCalendarTransp);
+ $this->assertEquals($value, $property->getValue());
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testUnserializerBadData() {
+
+ $xml = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:foo/>' .
+'</d:root>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $this->assertNull(ScheduleCalendarTransp::unserialize($dom->firstChild));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarComponentSetTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarComponentSetTest.php
new file mode 100644
index 000000000..3e5d5f5fc
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarComponentSetTest.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Sabre\CalDAV\Property;
+
+class SupportedCalendarComponentSetTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $sccs = new SupportedCalendarComponentSet(array('VEVENT'));
+ $this->assertEquals(array('VEVENT'), $sccs->getValue());
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerialize() {
+
+ $property = new SupportedCalendarComponentSet(array('VEVENT','VJOURNAL'));
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',\Sabre\CalDAV\Plugin::NS_CALDAV);
+
+ $doc->appendChild($root);
+ $server = new \Sabre\DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . \Sabre\CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:comp name="VEVENT"/>' .
+'<cal:comp name="VJOURNAL"/>' .
+'</d:root>
+', $xml);
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testUnserializer() {
+
+ $xml = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . \Sabre\CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:comp name="VEVENT"/>' .
+'<cal:comp name="VJOURNAL"/>' .
+'</d:root>';
+
+ $dom = \Sabre\DAV\XMLUtil::loadDOMDocument($xml);
+
+ $property = SupportedCalendarComponentSet::unserialize($dom->firstChild);
+
+ $this->assertTrue($property instanceof SupportedCalendarComponentSet);
+ $this->assertEquals(array(
+ 'VEVENT',
+ 'VJOURNAL',
+ ),
+ $property->getValue());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarDataTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarDataTest.php
new file mode 100644
index 000000000..3e016368c
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarDataTest.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Sabre\CalDAV\Property;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class SupportedCalendarDataTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $sccs = new SupportedCalendarData();
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerialize() {
+
+ $property = new SupportedCalendarData();
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:calendar-data content-type="text/calendar" version="2.0"/>' .
+'</d:root>
+', $xml);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCollationSetTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCollationSetTest.php
new file mode 100644
index 000000000..669e31553
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCollationSetTest.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Sabre\CalDAV\Property;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class SupportedCollationSetTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $scs = new SupportedCollationSet();
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerialize() {
+
+ $property = new SupportedCollationSet();
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:supported-collation>i;ascii-casemap</cal:supported-collation>' .
+'<cal:supported-collation>i;octet</cal:supported-collation>' .
+'<cal:supported-collation>i;unicode-casemap</cal:supported-collation>' .
+'</d:root>
+', $xml);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/IMip/Mock.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/IMip/Mock.php
new file mode 100644
index 000000000..200274ce8
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/IMip/Mock.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Sabre\CalDAV\Schedule\IMip;
+
+/**
+ * iMIP handler.
+ *
+ * This class is responsible for sending out iMIP messages. iMIP is the
+ * email-based transport for iTIP. iTIP deals with scheduling operations for
+ * iCalendar objects.
+ *
+ * If you want to customize the email that gets sent out, you can do so by
+ * extending this class and overriding the sendMessage method.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Mock extends \Sabre\CalDAV\Schedule\IMip {
+
+ protected $emails = array();
+
+ /**
+ * This function is reponsible for sending the actual email.
+ *
+ * @param string $to Recipient email address
+ * @param string $subject Subject of the email
+ * @param string $body iCalendar body
+ * @param array $headers List of headers
+ * @return void
+ */
+ protected function mail($to, $subject, $body, array $headers) {
+
+ $this->emails[] = array(
+ 'to' => $to,
+ 'subject' => $subject,
+ 'body' => $body,
+ 'headers' => $headers,
+ );
+
+ }
+
+ public function getSentEmails() {
+
+ return $this->emails;
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php
new file mode 100644
index 000000000..60ce9a2ad
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Sabre\CalDAV\Schedule;
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class OutboxTest extends \PHPUnit_Framework_TestCase {
+
+ function testSetup() {
+
+ $outbox = new Outbox('principals/user1');
+ $this->assertEquals('outbox', $outbox->getName());
+ $this->assertEquals(array(), $outbox->getChildren());
+ $this->assertEquals('principals/user1', $outbox->getOwner());
+ $this->assertEquals(null, $outbox->getGroup());
+
+ $this->assertEquals(array(
+ array(
+ 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-query-freebusy',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-post-vevent',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ ), $outbox->getACL());
+
+ $ok = false;
+ try {
+ $outbox->setACL(array());
+ } catch (DAV\Exception\MethodNotAllowed $e) {
+ $ok = true;
+ }
+ if (!$ok) {
+ $this->fail('Exception was not emitted');
+ }
+
+ }
+
+ function testGetSupportedPrivilegeSet() {
+
+ $outbox = new Outbox('principals/user1');
+ $r = $outbox->getSupportedPrivilegeSet();
+
+ $ok = 0;
+ foreach($r['aggregates'] as $priv) {
+
+ if ($priv['privilege'] == '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-query-freebusy') {
+ $ok++;
+ }
+ if ($priv['privilege'] == '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-post-vevent') {
+ $ok++;
+ }
+ }
+
+ $this->assertEquals(2, $ok, "We're missing one or more privileges");
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ShareableCalendarTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ShareableCalendarTest.php
new file mode 100644
index 000000000..2f79351f1
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ShareableCalendarTest.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAVACL;
+
+class ShareableCalendarTest extends \PHPUnit_Framework_TestCase {
+
+ protected $backend;
+ protected $instance;
+
+ function setUp() {
+
+ $props = array(
+ 'id' => 1,
+ );
+
+ $this->backend = new Backend\Mock(
+ array($props),
+ array(),
+ array()
+ );
+ $this->backend->updateShares(1, array(
+ array(
+ 'href' => 'mailto:removeme@example.org',
+ 'commonName' => 'To be removed',
+ 'readOnly' => true,
+ ),
+ ), array());
+
+ $this->instance = new ShareableCalendar($this->backend, $props);
+
+ }
+
+ function testUpdateShares() {
+
+ $this->instance->updateShares(array(
+ array(
+ 'href' => 'mailto:test@example.org',
+ 'commonName' => 'Foo Bar',
+ 'summary' => 'Booh',
+ 'readOnly' => false,
+ ),
+ ), array('mailto:removeme@example.org'));
+
+ $this->assertEquals(array(array(
+ 'href' => 'mailto:test@example.org',
+ 'commonName' => 'Foo Bar',
+ 'summary' => 'Booh',
+ 'readOnly' => false,
+ 'status' => SharingPlugin::STATUS_NORESPONSE,
+ )), $this->instance->getShares());
+
+ }
+
+ function testPublish() {
+
+ $this->instance->setPublishStatus(true);
+ $this->instance->setPublishStatus(false);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php
new file mode 100644
index 000000000..955831917
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAVACL;
+
+class SharedCalendarTest extends \PHPUnit_Framework_TestCase {
+
+ protected $backend;
+
+ function getInstance(array $props = null) {
+
+ if (is_null($props)) {
+ $props = array(
+ 'id' => 1,
+ '{http://calendarserver.org/ns/}shared-url' => 'calendars/owner/original',
+ '{http://sabredav.org/ns}owner-principal' => 'principals/owner',
+ '{http://sabredav.org/ns}read-only' => false,
+ 'principaluri' => 'principals/sharee',
+ );
+ }
+
+ $this->backend = new Backend\Mock(
+ array($props),
+ array(),
+ array()
+ );
+ $this->backend->updateShares(1, array(
+ array(
+ 'href' => 'mailto:removeme@example.org',
+ 'commonName' => 'To be removed',
+ 'readOnly' => true,
+ ),
+ ), array());
+
+ return new SharedCalendar($this->backend, $props);
+
+ }
+
+ function testGetSharedUrl() {
+ $this->assertEquals('calendars/owner/original', $this->getInstance()->getSharedUrl());
+ }
+
+ function testGetShares() {
+
+ $this->assertEquals(array(array(
+ 'href' => 'mailto:removeme@example.org',
+ 'commonName' => 'To be removed',
+ 'readOnly' => true,
+ 'status' => SharingPlugin::STATUS_NORESPONSE,
+ )), $this->getInstance()->getShares());
+
+ }
+
+ function testGetOwner() {
+ $this->assertEquals('principals/owner', $this->getInstance()->getOwner());
+ }
+
+ function testGetACL() {
+
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/owner',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/owner',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/owner/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/owner/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/owner/calendar-proxy-read',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
+ 'principal' => '{DAV:}authenticated',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/sharee',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/sharee',
+ 'protected' => true,
+ ),
+ );
+
+ $this->assertEquals($expected, $this->getInstance()->getACL());
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testCreateInstanceMissingArg() {
+
+ $this->getInstance(array(
+ 'id' => 1,
+ '{http://calendarserver.org/ns/}shared-url' => 'calendars/owner/original',
+ '{http://sabredav.org/ns}read-only' => false,
+ 'principaluri' => 'principals/sharee',
+ ));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php
new file mode 100644
index 000000000..60a71fd7f
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php
@@ -0,0 +1,391 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+class SharingPluginTest extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+ protected $setupCalDAVSharing = true;
+ protected $setupACL = true;
+ protected $autoLogin = 'user1';
+
+ function setUp() {
+
+ $this->caldavCalendars = array(
+ array(
+ 'principaluri' => 'principals/user1',
+ 'id' => 1,
+ 'uri' => 'cal1',
+ ),
+ array(
+ 'principaluri' => 'principals/user1',
+ 'id' => 2,
+ 'uri' => 'cal2',
+ '{' . Plugin::NS_CALENDARSERVER . '}shared-url' => 'calendars/user1/cal2',
+ '{http://sabredav.org/ns}owner-principal' => 'principals/user2',
+ '{http://sabredav.org/ns}read-only' => 'true',
+ ),
+ array(
+ 'principaluri' => 'principals/user1',
+ 'id' => 3,
+ 'uri' => 'cal3',
+ ),
+ );
+
+ parent::setUp();
+
+ // Making the logged in user an admin, for full access:
+ $this->aclPlugin->adminPrincipals[] = 'principals/user1';
+ $this->aclPlugin->adminPrincipals[] = 'principals/user2';
+
+ }
+
+ function testSimple() {
+
+ $this->assertInstanceOf('Sabre\\CalDAV\\SharingPlugin', $this->server->getPlugin('caldav-sharing'));
+
+ }
+
+ function testGetFeatures() {
+
+ $this->assertEquals(array('calendarserver-sharing'), $this->caldavSharingPlugin->getFeatures());
+
+ }
+
+ function testBeforeGetShareableCalendar() {
+
+ // Forcing the server to authenticate:
+ $this->authPlugin->beforeMethod('GET','');
+ $props = $this->server->getProperties('calendars/user1/cal1', array(
+ '{' . Plugin::NS_CALENDARSERVER . '}invite',
+ '{' . Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes',
+ ));
+
+ $this->assertInstanceOf('Sabre\\CalDAV\\Property\\Invite', $props['{' . Plugin::NS_CALENDARSERVER . '}invite']);
+ $this->assertInstanceOf('Sabre\\CalDAV\\Property\\AllowedSharingModes', $props['{' . Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes']);
+
+ }
+
+ function testBeforeGetSharedCalendar() {
+
+ $props = $this->server->getProperties('calendars/user1/cal2', array(
+ '{' . Plugin::NS_CALENDARSERVER . '}shared-url',
+ '{' . Plugin::NS_CALENDARSERVER . '}invite',
+ ));
+
+ $this->assertInstanceOf('Sabre\\CalDAV\\Property\\Invite', $props['{' . Plugin::NS_CALENDARSERVER . '}invite']);
+ $this->assertInstanceOf('Sabre\\DAV\\Property\\IHref', $props['{' . Plugin::NS_CALENDARSERVER . '}shared-url']);
+
+ }
+
+ function testUpdateProperties() {
+
+ $this->caldavBackend->updateShares(1,
+ array(
+ array(
+ 'href' => 'mailto:joe@example.org',
+ ),
+ ),
+ array()
+ );
+ $result = $this->server->updateProperties('calendars/user1/cal1', array(
+ '{DAV:}resourcetype' => new DAV\Property\ResourceType(array('{DAV:}collection'))
+ ));
+
+ $this->assertEquals(array(
+ 200 => array(
+ '{DAV:}resourcetype' => null,
+ ),
+ 'href' => 'calendars/user1/cal1',
+ ), $result);
+
+ $this->assertEquals(0, count($this->caldavBackend->getShares(1)));
+
+ }
+
+ function testUpdatePropertiesPassThru() {
+
+ $result = $this->server->updateProperties('calendars/user1/cal3', array(
+ '{DAV:}foo' => 'bar',
+ ));
+
+ $this->assertEquals(array(
+ 403 => array(
+ '{DAV:}foo' => null,
+ ),
+ 'href' => 'calendars/user1/cal3',
+ ), $result);
+
+ }
+
+ function testUnknownMethodNoPOST() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PATCH',
+ 'REQUEST_URI' => '/',
+ ));
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+
+ function testUnknownMethodNoXML() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/',
+ 'CONTENT_TYPE' => 'text/plain',
+ ));
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+
+ function testUnknownMethodNoNode() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/foo',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+
+ function testShareRequest() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal1',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = <<<RRR
+<?xml version="1.0"?>
+<cs:share xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:">
+ <cs:set>
+ <d:href>mailto:joe@example.org</d:href>
+ <cs:common-name>Joe Shmoe</cs:common-name>
+ <cs:read-write />
+ </cs:set>
+ <cs:remove>
+ <d:href>mailto:nancy@example.org</d:href>
+ </cs:remove>
+</cs:share>
+RRR;
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status, $response->body);
+
+ $this->assertEquals(array(array(
+ 'href' => 'mailto:joe@example.org',
+ 'commonName' => 'Joe Shmoe',
+ 'readOnly' => false,
+ 'status' => SharingPlugin::STATUS_NORESPONSE,
+ 'summary' => '',
+ )), $this->caldavBackend->getShares(1));
+
+ // Verifying that the calendar is now marked shared.
+ $props = $this->server->getProperties('calendars/user1/cal1', array('{DAV:}resourcetype'));
+ $this->assertTrue(
+ $props['{DAV:}resourcetype']->is('{http://calendarserver.org/ns/}shared-owner')
+ );
+
+ }
+
+ function testShareRequestNoShareableCalendar() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal2',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:share xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
+ <cs:set>
+ <d:href>mailto:joe@example.org</d:href>
+ <cs:common-name>Joe Shmoe</cs:common-name>
+ <cs:read-write />
+ </cs:set>
+ <cs:remove>
+ <d:href>mailto:nancy@example.org</d:href>
+ </cs:remove>
+</cs:share>
+';
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+
+ function testInviteReply() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:invite-reply xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
+ <cs:hosturl><d:href>/principals/owner</d:href></cs:hosturl>
+ <cs:invite-accepted />
+</cs:invite-reply>
+';
+
+ $request->setBody($xml);
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status, $response->body);
+
+ }
+
+ function testInviteBadXML() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:invite-reply xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
+</cs:invite-reply>
+';
+ $request->setBody($xml);
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, $response->body);
+
+ }
+
+ function testInviteWrongUrl() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal1',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:invite-reply xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
+ <cs:hosturl><d:href>/principals/owner</d:href></cs:hosturl>
+</cs:invite-reply>
+';
+ $request->setBody($xml);
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ // If the plugin did not handle this request, it must ensure that the
+ // body is still accessible by other plugins.
+ $this->assertEquals($xml, $request->getBody(true));
+
+ }
+
+ function testPublish() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal1',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:publish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
+';
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 202 Accepted', $response->status, $response->body);
+
+ }
+
+ function testUnpublish() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal1',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:unpublish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
+';
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status, $response->body);
+
+ }
+
+ function testPublishWrongUrl() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal2',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:publish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
+';
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+
+ function testUnpublishWrongUrl() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal2',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:unpublish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
+';
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+
+ function testUnknownXmlDoc() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal2',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:foo-bar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />';
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php b/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php
new file mode 100644
index 000000000..19acea200
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php
@@ -0,0 +1,208 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+class TestUtil {
+
+ static function getBackend() {
+
+ $backend = new Backend\PDO(self::getSQLiteDB());
+ return $backend;
+
+ }
+
+ static function getSQLiteDB() {
+
+ if (file_exists(SABRE_TEMPDIR . '/testdb.sqlite'))
+ unlink(SABRE_TEMPDIR . '/testdb.sqlite');
+
+ $pdo = new \PDO('sqlite:' . SABRE_TEMPDIR . '/testdb.sqlite');
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
+
+ // Yup this is definitely not 'fool proof', but good enough for now.
+ $queries = explode(';', file_get_contents(__DIR__ . '/../../../examples/sql/sqlite.calendars.sql'));
+ foreach($queries as $query) {
+ $pdo->exec($query);
+ }
+ // Inserting events through a backend class.
+ $backend = new Backend\PDO($pdo);
+ $calendarId = $backend->createCalendar(
+ 'principals/user1',
+ 'UUID-123467',
+ array(
+ '{DAV:}displayname' => 'user1 calendar',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar description',
+ '{http://apple.com/ns/ical/}calendar-order' => '1',
+ '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
+ )
+ );
+ $backend->createCalendar(
+ 'principals/user1',
+ 'UUID-123468',
+ array(
+ '{DAV:}displayname' => 'user1 calendar2',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar description',
+ '{http://apple.com/ns/ical/}calendar-order' => '1',
+ '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
+ )
+ );
+ $backend->createCalendarObject($calendarId, 'UUID-2345', self::getTestCalendarData());
+ return $pdo;
+
+ }
+
+ static function getTestCalendarData($type = 1) {
+
+ $calendarData = 'BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:Asia/Seoul
+BEGIN:DAYLIGHT
+TZOFFSETFROM:+0900
+RRULE:FREQ=YEARLY;UNTIL=19880507T150000Z;BYMONTH=5;BYDAY=2SU
+DTSTART:19870510T000000
+TZNAME:GMT+09:00
+TZOFFSETTO:+1000
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:+1000
+DTSTART:19881009T000000
+TZNAME:GMT+09:00
+TZOFFSETTO:+0900
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20100225T154229Z
+UID:39A6B5ED-DD51-4AFE-A683-C35EE3749627
+TRANSP:TRANSPARENT
+SUMMARY:Something here
+DTSTAMP:20100228T130202Z';
+
+ switch($type) {
+ case 1 :
+ $calendarData.="\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDTEND;TZID=Asia/Seoul:20100223T070000\n";
+ break;
+ case 2 :
+ $calendarData.="\nDTSTART:20100223T060000\nDTEND:20100223T070000\n";
+ break;
+ case 3 :
+ $calendarData.="\nDTSTART;VALUE=DATE:20100223\nDTEND;VALUE=DATE:20100223\n";
+ break;
+ case 4 :
+ $calendarData.="\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDURATION:PT1H\n";
+ break;
+ case 5 :
+ $calendarData.="\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDURATION:-P5D\n";
+ break;
+ case 6 :
+ $calendarData.="\nDTSTART;VALUE=DATE:20100223\n";
+ break;
+ case 7 :
+ $calendarData.="\nDTSTART;VALUE=DATETIME:20100223T060000\n";
+ break;
+
+ // No DTSTART, so intentionally broken
+ case 'X' :
+ $calendarData.="\n";
+ break;
+ }
+
+
+ $calendarData.='ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR';
+
+ return $calendarData;
+
+ }
+
+ static function getTestTODO($type = 'due') {
+
+ switch($type) {
+
+ case 'due' :
+ $extra = "DUE:20100104T000000Z";
+ break;
+ case 'due2' :
+ $extra = "DUE:20060104T000000Z";
+ break;
+ case 'due_date' :
+ $extra = "DUE;VALUE=DATE:20060104";
+ break;
+ case 'due_tz' :
+ $extra = "DUE;TZID=Asia/Seoul:20060104T000000Z";
+ break;
+ case 'due_dtstart' :
+ $extra = "DTSTART:20050223T060000Z\nDUE:20060104T000000Z";
+ break;
+ case 'due_dtstart2' :
+ $extra = "DTSTART:20090223T060000Z\nDUE:20100104T000000Z";
+ break;
+ case 'dtstart' :
+ $extra = 'DTSTART:20100223T060000Z';
+ break;
+ case 'dtstart2' :
+ $extra = 'DTSTART:20060223T060000Z';
+ break;
+ case 'dtstart_date' :
+ $extra = 'DTSTART;VALUE=DATE:20100223';
+ break;
+ case 'dtstart_tz' :
+ $extra = 'DTSTART;TZID=Asia/Seoul:20100223T060000Z';
+ break;
+ case 'dtstart_duration' :
+ $extra = "DTSTART:20061023T060000Z\nDURATION:PT1H";
+ break;
+ case 'dtstart_duration2' :
+ $extra = "DTSTART:20101023T060000Z\nDURATION:PT1H";
+ break;
+ case 'completed' :
+ $extra = 'COMPLETED:20060601T000000Z';
+ break;
+ case 'completed2' :
+ $extra = 'COMPLETED:20090601T000000Z';
+ break;
+ case 'created' :
+ $extra = 'CREATED:20060601T000000Z';
+ break;
+ case 'created2' :
+ $extra = 'CREATED:20090601T000000Z';
+ break;
+ case 'completedcreated' :
+ $extra = "CREATED:20060601T000000Z\nCOMPLETED:20070101T000000Z";
+ break;
+ case 'completedcreated2' :
+ $extra = "CREATED:20090601T000000Z\nCOMPLETED:20100101T000000Z";
+ break;
+ case 'notime' :
+ $extra = 'X-FILLER:oh hello';
+ break;
+ default :
+ throw new Exception('Unknown type: ' . $type);
+
+ }
+
+ $todo = 'BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Corp.//CalDAV Client//EN
+BEGIN:VTODO
+DTSTAMP:20060205T235335Z
+' . $extra . '
+STATUS:NEEDS-ACTION
+SUMMARY:Task #1
+UID:DDDEEB7915FA61233B861457@example.com
+BEGIN:VALARM
+ACTION:AUDIO
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VTODO
+END:VCALENDAR';
+
+ return $todo;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsSharedCalendarsTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsSharedCalendarsTest.php
new file mode 100644
index 000000000..4c3bae3a4
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsSharedCalendarsTest.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAVACL;
+
+require_once 'Sabre/CalDAV/TestUtil.php';
+
+/**
+ * @covers Sabre\CalDAV\UserCalendars
+ */
+class UserCalendarsSharedCalendarsTest extends \PHPUnit_Framework_TestCase {
+
+ protected $backend;
+
+ function getInstance() {
+
+ $calendars = array(
+ array(
+ 'id' => 1,
+ 'principaluri' => 'principals/user1',
+ ),
+ array(
+ 'id' => 2,
+ '{http://calendarserver.org/ns/}shared-url' => 'calendars/owner/cal1',
+ '{http://sabredav.org/ns}owner-principal' => 'principal/owner',
+ '{http://sabredav.org/ns}read-only' => false,
+ 'principaluri' => 'principals/user1',
+ ),
+ );
+
+ $this->backend = new Backend\Mock(
+ $calendars,
+ array(),
+ array()
+ );
+
+ return new UserCalendars($this->backend, array(
+ 'uri' => 'principals/user1'
+ ));
+
+ }
+
+ function testSimple() {
+
+ $instance = $this->getInstance();
+ $this->assertEquals('user1', $instance->getName());
+
+ }
+
+ function testGetChildren() {
+
+ $instance = $this->getInstance();
+ $children = $instance->getChildren();
+ $this->assertEquals(4, count($children));
+
+ // Testing if we got all the objects back.
+ $hasShareable = false;
+ $hasShared = false;
+ $hasOutbox = false;
+ $hasNotifications = false;
+
+ foreach($children as $child) {
+
+ if ($child instanceof IShareableCalendar) {
+ $hasShareable = true;
+ }
+ if ($child instanceof ISharedCalendar) {
+ $hasShared = true;
+ }
+ if ($child instanceof Schedule\IOutbox) {
+ $hasOutbox = true;
+ }
+ if ($child instanceof Notifications\ICollection) {
+ $hasNotifications = true;
+ }
+
+ }
+ if (!$hasShareable) $this->fail('Missing node!');
+ if (!$hasShared) $this->fail('Missing node!');
+ if (!$hasOutbox) $this->fail('Missing node!');
+ if (!$hasNotifications) $this->fail('Missing node!');
+
+ }
+
+ function testShareReply() {
+
+ $instance = $this->getInstance();
+ $instance->shareReply('uri', SharingPlugin::STATUS_DECLINED, 'curi', '1');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsTest.php
new file mode 100644
index 000000000..453c872e5
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsTest.php
@@ -0,0 +1,207 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\DAVACL;
+use Sabre\DAV;
+
+require_once 'Sabre/CalDAV/TestUtil.php';
+
+/**
+ * @covers Sabre\CalDAV\UserCalendars
+ */
+class UserCalendarsTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\CalDAV\UserCalendars
+ */
+ protected $usercalendars;
+ /**
+ * @var Sabre\CalDAV\Backend\PDO
+ */
+ protected $backend;
+
+ function setup() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $this->backend = TestUtil::getBackend();
+ $this->usercalendars = new UserCalendars($this->backend, array(
+ 'uri' => 'principals/user1'
+ ));
+
+ }
+
+ function testSimple() {
+
+ $this->assertEquals('user1',$this->usercalendars->getName());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotFound
+ * @depends testSimple
+ */
+ function testGetChildNotFound() {
+
+ $this->usercalendars->getChild('randomname');
+
+ }
+
+ function testChildExists() {
+
+ $this->assertFalse($this->usercalendars->childExists('foo'));
+ $this->assertTrue($this->usercalendars->childExists('UUID-123467'));
+
+ }
+
+ function testGetOwner() {
+
+ $this->assertEquals('principals/user1', $this->usercalendars->getOwner());
+
+ }
+
+ function testGetGroup() {
+
+ $this->assertNull($this->usercalendars->getGroup());
+
+ }
+
+ function testGetACL() {
+
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1/calendar-proxy-read',
+ 'protected' => true,
+ ),
+ );
+ $this->assertEquals($expected, $this->usercalendars->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetACL() {
+
+ $this->usercalendars->setACL(array());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ * @depends testSimple
+ */
+ function testSetName() {
+
+ $this->usercalendars->setName('bla');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ * @depends testSimple
+ */
+ function testDelete() {
+
+ $this->usercalendars->delete();
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testGetLastModified() {
+
+ $this->assertNull($this->usercalendars->getLastModified());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ * @depends testSimple
+ */
+ function testCreateFile() {
+
+ $this->usercalendars->createFile('bla');
+
+ }
+
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ * @depends testSimple
+ */
+ function testCreateDirectory() {
+
+ $this->usercalendars->createDirectory('bla');
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testCreateExtendedCollection() {
+
+ $result = $this->usercalendars->createExtendedCollection('newcalendar', array('{DAV:}collection', '{urn:ietf:params:xml:ns:caldav}calendar'), array());
+ $this->assertNull($result);
+ $cals = $this->backend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(3,count($cals));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\InvalidResourceType
+ * @depends testSimple
+ */
+ function testCreateExtendedCollectionBadResourceType() {
+
+ $this->usercalendars->createExtendedCollection('newcalendar', array('{DAV:}collection','{DAV:}blabla'), array());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\InvalidResourceType
+ * @depends testSimple
+ */
+ function testCreateExtendedCollectionNotACalendar() {
+
+ $this->usercalendars->createExtendedCollection('newcalendar', array('{DAV:}collection'), array());
+
+ }
+
+ function testGetSupportedPrivilegesSet() {
+
+ $this->assertNull($this->usercalendars->getSupportedPrivilegeSet());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotImplemented
+ */
+ function testShareReplyFail() {
+
+ $this->usercalendars->shareReply('uri', SharingPlugin::STATUS_DECLINED, 'curi', '1');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php
new file mode 100644
index 000000000..6634b9c3b
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php
@@ -0,0 +1,250 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAV;
+use Sabre\DAVACL;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class ValidateICalTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\DAV\Server
+ */
+ protected $server;
+ /**
+ * @var Sabre\CalDAV\Backend\Mock
+ */
+ protected $calBackend;
+
+ function setUp() {
+
+ $calendars = array(
+ array(
+ 'id' => 'calendar1',
+ 'principaluri' => 'principals/admin',
+ 'uri' => 'calendar1',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Property\SupportedCalendarComponentSet( array('VEVENT','VTODO','VJOURNAL') ),
+ ),
+ array(
+ 'id' => 'calendar2',
+ 'principaluri' => 'principals/admin',
+ 'uri' => 'calendar2',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Property\SupportedCalendarComponentSet( array('VTODO','VJOURNAL') ),
+ )
+ );
+
+ $this->calBackend = new Backend\Mock($calendars,array());
+ $principalBackend = new DAVACL\PrincipalBackend\Mock();
+
+ $tree = array(
+ new CalendarRootNode($principalBackend, $this->calBackend),
+ );
+
+ $this->server = new DAV\Server($tree);
+ $this->server->debugExceptions = true;
+
+ $plugin = new Plugin();
+ $this->server->addPlugin($plugin);
+
+ $response = new HTTP\ResponseMock();
+ $this->server->httpResponse = $response;
+
+ }
+
+ function request(HTTP\Request $request) {
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ return $this->server->httpResponse;
+
+ }
+
+ function testCreateFile() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 415 Unsupported Media Type', $response->status);
+
+ }
+
+ function testCreateFileValid() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 201 Created', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+ $expected = array(
+ 'uri' => 'blabla.ics',
+ 'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
+ 'calendarid' => 'calendar1',
+ );
+
+ $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1','blabla.ics'));
+
+ }
+
+ function testCreateFileNoComponents() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testCreateFileNoUID() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testCreateFileVCard() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCARD\r\nEND:VCARD\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 415 Unsupported Media Type', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testCreateFile2Components() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nBEGIN:VJOURNAL\r\nUID:foo\r\nEND:VJOURNAL\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testCreateFile2UIDS() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nBEGIN:VEVENT\r\nUID:bar\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testCreateFileWrongComponent() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VFREEBUSY\r\nUID:foo\r\nEND:VFREEBUSY\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testUpdateFile() {
+
+ $this->calBackend->createCalendarObject('calendar1','blabla.ics','foo');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 415 Unsupported Media Type', $response->status);
+
+ }
+
+ function testUpdateFileParsableBody() {
+
+ $this->calBackend->createCalendarObject('calendar1','blabla.ics','foo');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $body = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+ $request->setBody($body);
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 204 No Content', $response->status);
+
+ $expected = array(
+ 'uri' => 'blabla.ics',
+ 'calendardata' => $body,
+ 'calendarid' => 'calendar1',
+ );
+
+ $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1','blabla.ics'));
+
+ }
+
+ function testCreateFileInvalidComponent() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar2/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testUpdateFileInvalidComponent() {
+
+ $this->calBackend->createCalendarObject('calendar2','blabla.ics','foo');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar2/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/VersionTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/VersionTest.php
new file mode 100644
index 000000000..a4e093e35
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/VersionTest.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+class VersionTest extends \PHPUnit_Framework_TestCase {
+
+ function testString() {
+
+ $v = Version::VERSION;
+ $this->assertEquals(-1, version_compare('1.0.0',$v));
+
+ $s = Version::STABILITY;
+ $this->assertTrue($s == 'alpha' || $s == 'beta' || $s =='stable');
+
+ }
+
+}