diff options
Diffstat (limited to 'vendor/sabre/dav/tests/Sabre/CalDAV')
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(' ','',$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(' ','',$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(' ','',$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(' ','',$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(' ','',$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(' ','',$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'); + + } + +} |