diff options
Diffstat (limited to 'vendor/sabre/dav/tests/Sabre')
173 files changed, 27097 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'); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php new file mode 100644 index 000000000..94081fc8b --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php @@ -0,0 +1,41 @@ +<?php + +namespace Sabre\CardDAV; + +use Sabre\DAV; +use Sabre\DAVACL; + +abstract class AbstractPluginTest extends \PHPUnit_Framework_TestCase { + + /** + * @var Sabre\CardDAV\Plugin + */ + protected $plugin; + /** + * @var Sabre\DAV\Server + */ + protected $server; + /** + * @var Sabre\CardDAV\Backend\Mock; + */ + protected $backend; + + function setUp() { + + $this->backend = new Backend\Mock(); + $principalBackend = new DAVACL\PrincipalBackend\Mock(); + + $tree = array( + new AddressBookRoot($principalBackend, $this->backend), + new DAVACL\PrincipalCollection($principalBackend) + ); + + $this->plugin = new Plugin(); + $this->plugin->directories = array('directory'); + $this->server = new DAV\Server($tree); + $this->server->addPlugin($this->plugin); + $this->server->debugExceptions = true; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryParserTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryParserTest.php new file mode 100644 index 000000000..51bea6c6c --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryParserTest.php @@ -0,0 +1,329 @@ +<?php + +namespace Sabre\CardDAV; + +use Sabre\DAV; + +class AddressBookQueryParserTest extends \PHPUnit_Framework_TestCase { + + function parse($xml) { + + $xml = implode("\n", $xml); + $dom = DAV\XMLUtil::loadDOMDocument($xml); + + $q = new AddressBookQueryParser($dom); + $q->parse(); + return $q; + + } + + function testFilterBasic() { + + $xml = array( + '<?xml version="1.0"?>', + '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">', + ' <d:prop>', + ' <d:foo />', + ' </d:prop>', + ' <c:filter>', + ' <c:prop-filter name="NICKNAME" />', + ' </c:filter>', + '</c:addressbook-query>' + ); + + $q = $this->parse($xml); + + $this->assertEquals( + array('{DAV:}foo'), + $q->requestedProperties + ); + + $this->assertEquals( + array( + array( + 'name' => 'NICKNAME', + 'test' => 'anyof', + 'is-not-defined' => false, + 'param-filters' => array(), + 'text-matches' => array(), + ), + ), + $q->filters + ); + + $this->assertNull($q->limit); + $this->assertEquals('anyof', $q->test); + + } + + function testNoFilter() { + + // This is non-standard, but helps working around a KDE bug + $xml = array( + '<?xml version="1.0"?>', + '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">', + ' <d:prop>', + ' <d:foo />', + ' </d:prop>', + '</c:addressbook-query>' + ); + + $q = $this->parse($xml); + + $this->assertEquals( + array('{DAV:}foo'), + $q->requestedProperties + ); + + $this->assertEquals( + array(), + $q->filters + ); + + $this->assertNull($q->limit); + $this->assertEquals('anyof', $q->test); + + } + + /** + * @expectedException Sabre\DAV\Exception\BadRequest + */ + function testFilterDoubleFilter() { + + $xml = array( + '<?xml version="1.0"?>', + '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">', + ' <d:prop>', + ' <d:foo />', + ' </d:prop>', + ' <c:filter>', + ' <c:prop-filter name="NICKNAME" />', + ' </c:filter>', + ' <c:filter>', + ' <c:prop-filter name="NICKNAME" />', + ' </c:filter>', + '</c:addressbook-query>' + ); + + $q = $this->parse($xml); + + } + /** + * @expectedException Sabre\DAV\Exception\BadRequest + */ + function testFilterCorruptTest() { + + $xml = array( + '<?xml version="1.0"?>', + '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">', + ' <d:prop>', + ' <d:foo />', + ' </d:prop>', + ' <c:filter test="foo">', + ' <c:prop-filter name="NICKNAME" />', + ' </c:filter>', + '</c:addressbook-query>' + ); + + $q = $this->parse($xml); + + } + + function testPropFilter() { + + $xml = array( + '<?xml version="1.0"?>', + '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">', + ' <d:prop>', + ' <d:foo />', + ' </d:prop>', + ' <c:filter test="allof">', + ' <c:prop-filter name="NICKNAME" />', + ' <c:prop-filter name="EMAIL" test="allof" />', + ' <c:prop-filter name="FN">', + ' <c:is-not-defined />', + ' </c:prop-filter>', + ' </c:filter>', + ' <c:limit><c:nresults>4</c:nresults></c:limit>', + '</c:addressbook-query>' + ); + + $q = $this->parse($xml); + + $this->assertEquals( + array( + array( + 'name' => 'NICKNAME', + 'test' => 'anyof', + 'is-not-defined' => false, + 'param-filters' => array(), + 'text-matches' => array(), + ), + array( + 'name' => 'EMAIL', + 'test' => 'allof', + 'is-not-defined' => false, + 'param-filters' => array(), + 'text-matches' => array(), + ), + array( + 'name' => 'FN', + 'test' => 'anyof', + 'is-not-defined' => true, + 'param-filters' => array(), + 'text-matches' => array(), + ), + ), + $q->filters + ); + + $this->assertEquals(4,$q->limit); + $this->assertEquals('allof', $q->test); + + } + + function testParamFilter() { + + $xml = array( + '<?xml version="1.0"?>', + '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">', + ' <d:prop>', + ' <d:foo />', + ' </d:prop>', + ' <c:filter>', + ' <c:prop-filter name="NICKNAME">', + ' <c:param-filter name="BLA" />', + ' <c:param-filter name="BLA2">', + ' <c:is-not-defined />', + ' </c:param-filter>', + ' </c:prop-filter>', + ' </c:filter>', + '</c:addressbook-query>' + ); + + $q = $this->parse($xml); + + $this->assertEquals( + array( + array( + 'name' => 'NICKNAME', + 'test' => 'anyof', + 'is-not-defined' => false, + 'param-filters' => array( + array( + 'name' => 'BLA', + 'is-not-defined' => false, + 'text-match' => null + ), + array( + 'name' => 'BLA2', + 'is-not-defined' => true, + 'text-match' => null + ), + ), + 'text-matches' => array(), + ), + ), + $q->filters + ); + + } + + function testTextMatch() { + + $xml = array( + '<?xml version="1.0"?>', + '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">', + ' <d:prop>', + ' <d:foo />', + ' </d:prop>', + ' <c:filter>', + ' <c:prop-filter name="NICKNAME">', + ' <c:text-match>evert</c:text-match>', + ' <c:text-match collation="i;octet">evert</c:text-match>', + ' <c:text-match negate-condition="yes">rene</c:text-match>', + ' <c:text-match match-type="starts-with">e</c:text-match>', + ' <c:param-filter name="BLA">', + ' <c:text-match>foo</c:text-match>', + ' </c:param-filter>', + ' </c:prop-filter>', + ' </c:filter>', + '</c:addressbook-query>' + ); + + $q = $this->parse($xml); + + $this->assertEquals( + array( + array( + 'name' => 'NICKNAME', + 'test' => 'anyof', + 'is-not-defined' => false, + 'param-filters' => array( + array( + 'name' => 'BLA', + 'is-not-defined' => false, + 'text-match' => array( + 'negate-condition' => false, + 'collation' => 'i;unicode-casemap', + 'match-type' => 'contains', + 'value' => 'foo', + ), + ), + ), + 'text-matches' => array( + array( + 'negate-condition' => false, + 'collation' => 'i;unicode-casemap', + 'match-type' => 'contains', + 'value' => 'evert', + ), + array( + 'negate-condition' => false, + 'collation' => 'i;octet', + 'match-type' => 'contains', + 'value' => 'evert', + ), + array( + 'negate-condition' => true, + 'collation' => 'i;unicode-casemap', + 'match-type' => 'contains', + 'value' => 'rene', + ), + array( + 'negate-condition' => false, + 'collation' => 'i;unicode-casemap', + 'match-type' => 'starts-with', + 'value' => 'e', + ), + ), + ), + ), + $q->filters + ); + + } + + /** + * @expectedException Sabre\DAV\Exception\BadRequest + */ + function testBadTextMatch() { + + $xml = array( + '<?xml version="1.0"?>', + '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">', + ' <d:prop>', + ' <d:foo />', + ' </d:prop>', + ' <c:filter>', + ' <c:prop-filter name="NICKNAME">', + ' <c:text-match match-type="foo">evert</c:text-match>', + ' </c:prop-filter>', + ' </c:filter>', + '</c:addressbook-query>' + ); + + $q = $this->parse($xml); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php new file mode 100644 index 000000000..c79f7e877 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php @@ -0,0 +1,192 @@ +<?php + +namespace Sabre\CardDAV; + +use Sabre\HTTP; +use Sabre\DAV; + +require_once 'Sabre/CardDAV/AbstractPluginTest.php'; +require_once 'Sabre/HTTP/ResponseMock.php'; + +class AddressBookQueryTest extends AbstractPluginTest { + + function testQuery() { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'REPORT', + 'REQUEST_URI' => '/addressbooks/user1/book1', + 'HTTP_DEPTH' => '1', + )); + + $request->setBody( +'<?xml version="1.0"?> +<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav"> + <d:prop> + <d:getetag /> + </d:prop> + <c:filter> + <c:prop-filter name="uid" /> + </c:filter> +</c:addressbook-query>' + ); + + $response = new HTTP\ResponseMock(); + + $this->server->httpRequest = $request; + $this->server->httpResponse = $response; + + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status, 'Incorrect status code. Full response body:' . $response->body); + + // using the client for parsing + $client = new DAV\Client(array('baseUri'=>'/')); + + $result = $client->parseMultiStatus($response->body); + + $this->assertEquals(array( + '/addressbooks/user1/book1/card1' => array( + 200 => array( + '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"', + ), + ), + '/addressbooks/user1/book1/card2' => array( + 404 => array( + '{DAV:}getetag' => null, + ), + ) + ), $result); + + + } + + function testQueryDepth0() { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'REPORT', + 'REQUEST_URI' => '/addressbooks/user1/book1/card1', + 'HTTP_DEPTH' => '0', + )); + + $request->setBody( +'<?xml version="1.0"?> +<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav"> + <d:prop> + <d:getetag /> + </d:prop> + <c:filter> + <c:prop-filter name="uid" /> + </c:filter> +</c:addressbook-query>' + ); + + $response = new HTTP\ResponseMock(); + + $this->server->httpRequest = $request; + $this->server->httpResponse = $response; + + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status, 'Incorrect status code. Full response body:' . $response->body); + + // using the client for parsing + $client = new DAV\Client(array('baseUri'=>'/')); + + $result = $client->parseMultiStatus($response->body); + + $this->assertEquals(array( + '/addressbooks/user1/book1/card1' => array( + 200 => array( + '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"', + ), + ), + ), $result); + + + } + + function testQueryNoMatch() { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'REPORT', + 'REQUEST_URI' => '/addressbooks/user1/book1', + 'HTTP_DEPTH' => '1', + )); + + $request->setBody( +'<?xml version="1.0"?> +<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav"> + <d:prop> + <d:getetag /> + </d:prop> + <c:filter> + <c:prop-filter name="email" /> + </c:filter> +</c:addressbook-query>' + ); + + $response = new HTTP\ResponseMock(); + + $this->server->httpRequest = $request; + $this->server->httpResponse = $response; + + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status, 'Incorrect status code. Full response body:' . $response->body); + + // using the client for parsing + $client = new DAV\Client(array('baseUri'=>'/')); + + $result = $client->parseMultiStatus($response->body); + + $this->assertEquals(array(), $result); + + } + + function testQueryLimit() { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'REPORT', + 'REQUEST_URI' => '/addressbooks/user1/book1', + 'HTTP_DEPTH' => '1', + )); + + $request->setBody( +'<?xml version="1.0"?> +<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav"> + <d:prop> + <d:getetag /> + </d:prop> + <c:filter> + <c:prop-filter name="uid" /> + </c:filter> + <c:limit><c:nresults>1</c:nresults></c:limit> +</c:addressbook-query>' + ); + + $response = new HTTP\ResponseMock(); + + $this->server->httpRequest = $request; + $this->server->httpResponse = $response; + + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status, 'Incorrect status code. Full response body:' . $response->body); + + // using the client for parsing + $client = new DAV\Client(array('baseUri'=>'/')); + + $result = $client->parseMultiStatus($response->body); + + $this->assertEquals(array( + '/addressbooks/user1/book1/card1' => array( + 200 => array( + '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD"). '"', + ), + ), + ), $result); + + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookRootTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookRootTest.php new file mode 100644 index 000000000..6eaff5db0 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookRootTest.php @@ -0,0 +1,31 @@ +<?php + +namespace Sabre\CardDAV; + +use Sabre\DAVACL; + +class AddressBookRootTest extends \PHPUnit_Framework_TestCase { + + function testGetName() { + + $pBackend = new DAVACL\PrincipalBackend\Mock(); + $cBackend = new Backend\Mock(); + $root = new AddressBookRoot($pBackend, $cBackend); + $this->assertEquals('addressbooks', $root->getName()); + + } + + function testGetChildForPrincipal() { + + $pBackend = new DAVACL\PrincipalBackend\Mock(); + $cBackend = new Backend\Mock(); + $root = new AddressBookRoot($pBackend, $cBackend); + + $children = $root->getChildren(); + $this->assertEquals(3, count($children)); + + $this->assertInstanceOf('Sabre\\CardDAV\\UserAddressBooks', $children[0]); + $this->assertEquals('user1', $children[0]->getName()); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php new file mode 100644 index 000000000..aac749b37 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php @@ -0,0 +1,162 @@ +<?php + +namespace Sabre\CardDAV; + + +require_once 'Sabre/CardDAV/Backend/Mock.php'; + +class AddressBookTest extends \PHPUnit_Framework_TestCase { + + /** + * @var Sabre\CardDAV\AddressBook + */ + protected $ab; + protected $backend; + + function setUp() { + + $this->backend = new Backend\Mock(); + $this->ab = new AddressBook( + $this->backend, + array( + 'uri' => 'book1', + 'id' => 'foo', + '{DAV:}displayname' => 'd-name', + 'principaluri' => 'principals/user1', + ) + ); + + } + + function testGetName() { + + $this->assertEquals('book1', $this->ab->getName()); + + } + + function testGetChild() { + + $card = $this->ab->getChild('card1'); + $this->assertInstanceOf('Sabre\\CardDAV\\Card', $card); + $this->assertEquals('card1', $card->getName()); + + } + + /** + * @expectedException Sabre\DAV\Exception\NotFound + */ + function testGetChildNotFound() { + + $card = $this->ab->getChild('card3'); + + } + + function testGetChildren() { + + $cards = $this->ab->getChildren(); + $this->assertEquals(2, count($cards)); + + $this->assertEquals('card1', $cards[0]->getName()); + $this->assertEquals('card2', $cards[1]->getName()); + + } + + /** + * @expectedException Sabre\DAV\Exception\MethodNotAllowed + */ + function testCreateDirectory() { + + $this->ab->createDirectory('name'); + + } + + function testCreateFile() { + + $file = fopen('php://memory','r+'); + fwrite($file,'foo'); + rewind($file); + $this->ab->createFile('card2',$file); + + $this->assertEquals('foo', $this->backend->cards['foo']['card2']); + + } + + function testDelete() { + + $this->ab->delete(); + $this->assertEquals(array(), $this->backend->addressBooks); + + } + + /** + * @expectedException Sabre\DAV\Exception\MethodNotAllowed + */ + function testSetName() { + + $this->ab->setName('foo'); + + } + + function testGetLastModified() { + + $this->assertNull($this->ab->getLastModified()); + + } + + function testUpdateProperties() { + + $this->assertTrue( + $this->ab->updateProperties(array('{DAV:}displayname' => 'barrr')) + ); + + $this->assertEquals('barrr', $this->backend->addressBooks[0]['{DAV:}displayname']); + + } + + function testGetProperties() { + + $props = $this->ab->getProperties(array('{DAV:}displayname')); + $this->assertEquals(array( + '{DAV:}displayname' => 'd-name', + ), $props); + + } + + function testACLMethods() { + + $this->assertEquals('principals/user1', $this->ab->getOwner()); + $this->assertNull($this->ab->getGroup()); + $this->assertEquals(array( + array( + 'privilege' => '{DAV:}read', + 'principal' => 'principals/user1', + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}write', + 'principal' => 'principals/user1', + 'protected' => true, + ), + ), $this->ab->getACL()); + + } + + /** + * @expectedException Sabre\DAV\Exception\MethodNotAllowed + */ + function testSetACL() { + + $this->ab->setACL(array()); + + } + + function testGetSupportedPrivilegeSet() { + + $this->assertNull( + $this->ab->getSupportedPrivilegeSet() + ); + + } + + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php new file mode 100644 index 000000000..623188d32 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php @@ -0,0 +1,249 @@ +<?php + +namespace Sabre\CardDAV\Backend; + +use Sabre\CardDAV; + +abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase { + + /** + * @var CardDAV\Backend\PDO + */ + protected $backend; + + /** + * @abstract + * @return PDO + */ + abstract function getPDO(); + + public function setUp() { + + $this->backend = new PDO($this->getPDO()); + + } + + public function testGetAddressBooksForUser() { + + $result = $this->backend->getAddressBooksForUser('principals/user1'); + + $expected = array( + array( + 'id' => 1, + 'uri' => 'book1', + 'principaluri' => 'principals/user1', + '{DAV:}displayname' => 'book1', + '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1', + '{http://calendarserver.org/ns/}getctag' => 1, + '{' . CardDAV\Plugin::NS_CARDDAV . '}supported-address-data' => new CardDAV\Property\SupportedAddressData(), + ) + ); + + $this->assertEquals($expected, $result); + + } + + public function testUpdateAddressBookInvalidProp() { + + $result = $this->backend->updateAddressBook(1, array( + '{DAV:}displayname' => 'updated', + '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'updated', + '{DAV:}foo' => 'bar', + )); + + $this->assertFalse($result); + + $result = $this->backend->getAddressBooksForUser('principals/user1'); + + $expected = array( + array( + 'id' => 1, + 'uri' => 'book1', + 'principaluri' => 'principals/user1', + '{DAV:}displayname' => 'book1', + '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1', + '{http://calendarserver.org/ns/}getctag' => 1, + '{' . CardDAV\Plugin::NS_CARDDAV . '}supported-address-data' => new CardDAV\Property\SupportedAddressData(), + ) + ); + + $this->assertEquals($expected, $result); + + } + + public function testUpdateAddressBookNoProps() { + + $result = $this->backend->updateAddressBook(1, array()); + + $this->assertFalse($result); + + $result = $this->backend->getAddressBooksForUser('principals/user1'); + + $expected = array( + array( + 'id' => 1, + 'uri' => 'book1', + 'principaluri' => 'principals/user1', + '{DAV:}displayname' => 'book1', + '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1', + '{http://calendarserver.org/ns/}getctag' => 1, + '{' . CardDAV\Plugin::NS_CARDDAV . '}supported-address-data' => new CardDAV\Property\SupportedAddressData(), + ) + ); + + $this->assertEquals($expected, $result); + + + } + + public function testUpdateAddressBookSuccess() { + + $result = $this->backend->updateAddressBook(1, array( + '{DAV:}displayname' => 'updated', + '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'updated', + )); + + $this->assertTrue($result); + + $result = $this->backend->getAddressBooksForUser('principals/user1'); + + $expected = array( + array( + 'id' => 1, + 'uri' => 'book1', + 'principaluri' => 'principals/user1', + '{DAV:}displayname' => 'updated', + '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'updated', + '{http://calendarserver.org/ns/}getctag' => 2, + '{' . CardDAV\Plugin::NS_CARDDAV . '}supported-address-data' => new CardDAV\Property\SupportedAddressData(), + ) + ); + + $this->assertEquals($expected, $result); + + + } + + public function testDeleteAddressBook() { + + $this->backend->deleteAddressBook(1); + + $this->assertEquals(array(), $this->backend->getAddressBooksForUser('principals/user1')); + + } + + /** + * @expectedException Sabre\DAV\Exception\BadRequest + */ + public function testCreateAddressBookUnsupportedProp() { + + $this->backend->createAddressBook('principals/user1','book2', array( + '{DAV:}foo' => 'bar', + )); + + } + + public function testCreateAddressBookSuccess() { + + $this->backend->createAddressBook('principals/user1','book2', array( + '{DAV:}displayname' => 'book2', + '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 2', + )); + + $expected = array( + array( + 'id' => 1, + 'uri' => 'book1', + 'principaluri' => 'principals/user1', + '{DAV:}displayname' => 'book1', + '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1', + '{http://calendarserver.org/ns/}getctag' => 1, + '{' . CardDAV\Plugin::NS_CARDDAV . '}supported-address-data' => new CardDAV\Property\SupportedAddressData(), + ), + array( + 'id' => 2, + 'uri' => 'book2', + 'principaluri' => 'principals/user1', + '{DAV:}displayname' => 'book2', + '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 2', + '{http://calendarserver.org/ns/}getctag' => 1, + '{' . CardDAV\Plugin::NS_CARDDAV . '}supported-address-data' => new CardDAV\Property\SupportedAddressData(), + ) + ); + $result = $this->backend->getAddressBooksForUser('principals/user1'); + $this->assertEquals($expected, $result); + + } + + public function testGetCards() { + + $result = $this->backend->getCards(1); + + $expected = array( + array( + 'id' => 1, + 'uri' => 'card1', + 'carddata' => 'card1', + 'lastmodified' => 0, + ) + ); + + $this->assertEquals($expected, $result); + + } + + public function testGetCard() { + + $result = $this->backend->getCard(1,'card1'); + + $expected = array( + 'id' => 1, + 'uri' => 'card1', + 'carddata' => 'card1', + 'lastmodified' => 0, + ); + + $this->assertEquals($expected, $result); + + } + + /** + * @depends testGetCard + */ + public function testCreateCard() { + + $result = $this->backend->createCard(1, 'card2', 'data2'); + $this->assertEquals('"' . md5('data2') . '"', $result); + $result = $this->backend->getCard(1,'card2'); + $this->assertEquals(2, $result['id']); + $this->assertEquals('card2', $result['uri']); + $this->assertEquals('data2', $result['carddata']); + + } + + /** + * @depends testGetCard + */ + public function testUpdateCard() { + + $result = $this->backend->updateCard(1, 'card1', 'newdata'); + $this->assertEquals('"' . md5('newdata') . '"', $result); + + $result = $this->backend->getCard(1,'card1'); + $this->assertEquals(1, $result['id']); + $this->assertEquals('newdata', $result['carddata']); + + } + + /** + * @depends testGetCard + */ + public function testDeleteCard() { + + $this->backend->deleteCard(1, 'card1'); + $result = $this->backend->getCard(1,'card1'); + $this->assertFalse($result); + + } +} + diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php new file mode 100644 index 000000000..ab7ac4e6a --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php @@ -0,0 +1,130 @@ +<?php + +namespace Sabre\CardDAV\Backend; + +class Mock extends AbstractBackend { + + public $addressBooks; + public $cards; + + function __construct($addressBooks = null, $cards = null) { + + $this->addressBooks = $addressBooks; + $this->cards = $cards; + + if (is_null($this->addressBooks)) { + $this->addressBooks = array( + array( + 'id' => 'foo', + 'uri' => 'book1', + 'principaluri' => 'principals/user1', + '{DAV:}displayname' => 'd-name', + ), + ); + + $card2 = fopen('php://memory','r+'); + fwrite($card2,"BEGIN:VCARD\nVERSION:3.0\nUID:45678\nEND:VCARD"); + rewind($card2); + $this->cards = array( + 'foo' => array( + 'card1' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD", + 'card2' => $card2, + ), + ); + } + + } + + + function getAddressBooksForUser($principalUri) { + + $books = array(); + foreach($this->addressBooks as $book) { + if ($book['principaluri'] === $principalUri) { + $books[] = $book; + } + } + return $books; + + } + + function updateAddressBook($addressBookId, array $mutations) { + + foreach($this->addressBooks as &$book) { + if ($book['id'] !== $addressBookId) + continue; + + foreach($mutations as $key=>$value) { + $book[$key] = $value; + } + return true; + } + return false; + + } + + function createAddressBook($principalUri, $url, array $properties) { + + $this->addressBooks[] = array_merge($properties, array( + 'id' => $url, + 'uri' => $url, + 'principaluri' => $principalUri, + )); + + } + + function deleteAddressBook($addressBookId) { + + foreach($this->addressBooks as $key=>$value) { + if ($value['id'] === $addressBookId) + unset($this->addressBooks[$key]); + } + unset($this->cards[$addressBookId]); + + } + + function getCards($addressBookId) { + + $cards = array(); + foreach($this->cards[$addressBookId] as $uri=>$data) { + $cards[] = array( + 'uri' => $uri, + 'carddata' => $data, + ); + } + return $cards; + + } + + function getCard($addressBookId, $cardUri) { + + if (!isset($this->cards[$addressBookId][$cardUri])) { + return false; + } + + return array( + 'uri' => $cardUri, + 'carddata' => $this->cards[$addressBookId][$cardUri], + ); + + } + + function createCard($addressBookId, $cardUri, $cardData) { + + $this->cards[$addressBookId][$cardUri] = $cardData; + + } + + function updateCard($addressBookId, $cardUri, $cardData) { + + $this->cards[$addressBookId][$cardUri] = $cardData; + + } + + function deleteCard($addressBookId, $cardUri) { + + unset($this->cards[$addressBookId][$cardUri]); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php new file mode 100644 index 000000000..b2f871f6e --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php @@ -0,0 +1,60 @@ +<?php + +namespace Sabre\CardDAV\Backend; + +require_once 'Sabre/TestUtil.php'; + +class PDOMySQLTest extends AbstractPDOTest { + + /** + * @return PDO + */ + public function getPDO() { + + 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 addressbooks"); + $pdo->query("DROP TABLE IF EXISTS cards"); + $pdo->query(" +CREATE TABLE addressbooks ( + id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + principaluri VARCHAR(255), + displayname VARCHAR(255), + uri VARCHAR(100), + description TEXT, + ctag INT(11) UNSIGNED NOT NULL DEFAULT '1' +); +"); + + $pdo->query(" +INSERT INTO addressbooks + (principaluri, displayname, uri, description, ctag) +VALUES + ('principals/user1', 'book1', 'book1', 'addressbook 1', 1); +"); + + $pdo->query(" +CREATE TABLE cards ( + id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + addressbookid INT(11) UNSIGNED NOT NULL, + carddata TEXT, + uri VARCHAR(100), + lastmodified INT(11) UNSIGNED +); +"); + + $pdo->query(" +INSERT INTO cards + (addressbookid, carddata, uri, lastmodified) +VALUES + (1, 'card1', 'card1', 0); +"); + return $pdo; + + } + +} + diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php new file mode 100644 index 000000000..a9bbb0bd1 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php @@ -0,0 +1,69 @@ +<?php + +namespace Sabre\CardDAV\Backend; + +require_once 'Sabre/TestUtil.php'; + +class PDOSqliteTest extends AbstractPDOTest { + + function tearDown() { + + if (file_exists(SABRE_TEMPDIR . '/pdobackend')) unlink(SABRE_TEMPDIR . '/pdobackend'); + if (file_exists(SABRE_TEMPDIR . '/pdobackend2')) unlink(SABRE_TEMPDIR . '/pdobackend2'); + + } + + /** + * @return PDO + */ + function getPDO() { + + if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available'); + $pdo = new \PDO('sqlite:'.SABRE_TEMPDIR.'/pdobackend'); + $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION); + + $pdo->query("DROP TABLE IF EXISTS addressbooks"); + $pdo->query("DROP TABLE IF EXISTS cards"); + $pdo->query(" +CREATE TABLE addressbooks ( + id integer primary key asc, + principaluri text, + displayname text, + uri text, + description text, + ctag integer +); + +"); + + $pdo->query(" +INSERT INTO addressbooks + (principaluri, displayname, uri, description, ctag) +VALUES + ('principals/user1', 'book1', 'book1', 'addressbook 1', 1); +"); + + $pdo->query(" + +CREATE TABLE cards ( + id integer primary key asc, + addressbookid integer, + carddata text, + uri text, + lastmodified integer +); + +"); + $pdo->query(" +INSERT INTO cards + (addressbookid, carddata, uri, lastmodified) +VALUES + (1, 'card1', 'card1', 0); +"); + + return $pdo; + + } + +} + diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php new file mode 100644 index 000000000..438bd2ea5 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php @@ -0,0 +1,184 @@ +<?php + +namespace Sabre\CardDAV; + +class CardTest extends \PHPUnit_Framework_TestCase { + + /** + * @var Sabre\CardDAV\Card + */ + protected $card; + /** + * @var Sabre\CardDAV\MockBackend + */ + protected $backend; + + function setUp() { + + $this->backend = new Backend\Mock(); + $this->card = new Card( + $this->backend, + array( + 'uri' => 'book1', + 'id' => 'foo', + 'principaluri' => 'principals/user1', + ), + array( + 'uri' => 'card1', + 'addressbookid' => 'foo', + 'carddata' => 'card', + ) + ); + + } + + function testGet() { + + $result = $this->card->get(); + $this->assertEquals('card', $result); + + } + function testGet2() { + + $this->card = new Card( + $this->backend, + array( + 'uri' => 'book1', + 'id' => 'foo', + 'principaluri' => 'principals/user1', + ), + array( + 'uri' => 'card1', + 'addressbookid' => 'foo', + ) + ); + $result = $this->card->get(); + $this->assertEquals("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD", $result); + + } + + + /** + * @depends testGet + */ + function testPut() { + + $file = fopen('php://memory','r+'); + fwrite($file, 'newdata'); + rewind($file); + $this->card->put($file); + $result = $this->card->get(); + $this->assertEquals('newdata', $result); + + } + + + function testDelete() { + + $this->card->delete(); + $this->assertEquals(1, count($this->backend->cards['foo'])); + + } + + function testGetContentType() { + + $this->assertEquals('text/x-vcard; charset=utf-8', $this->card->getContentType()); + + } + + function testGetETag() { + + $this->assertEquals('"' . md5('card') . '"' , $this->card->getETag()); + + } + + function testGetETag2() { + + $card = new Card( + $this->backend, + array( + 'uri' => 'book1', + 'id' => 'foo', + 'principaluri' => 'principals/user1', + ), + array( + 'uri' => 'card1', + 'addressbookid' => 'foo', + 'carddata' => 'card', + 'etag' => '"blabla"', + ) + ); + $this->assertEquals('"blabla"' , $card->getETag()); + + } + + function testGetLastModified() { + + $this->assertEquals(null, $this->card->getLastModified()); + + } + + function testGetSize() { + + $this->assertEquals(4, $this->card->getSize()); + $this->assertEquals(4, $this->card->getSize()); + + } + + function testGetSize2() { + + $card = new Card( + $this->backend, + array( + 'uri' => 'book1', + 'id' => 'foo', + 'principaluri' => 'principals/user1', + ), + array( + 'uri' => 'card1', + 'addressbookid' => 'foo', + 'etag' => '"blabla"', + 'size' => 4, + ) + ); + $this->assertEquals(4, $card->getSize()); + + } + + function testACLMethods() { + + $this->assertEquals('principals/user1', $this->card->getOwner()); + $this->assertNull($this->card->getGroup()); + $this->assertEquals(array( + array( + 'privilege' => '{DAV:}read', + 'principal' => 'principals/user1', + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}write', + 'principal' => 'principals/user1', + 'protected' => true, + ), + ), $this->card->getACL()); + + } + + /** + * @expectedException Sabre\DAV\Exception\MethodNotAllowed + */ + function testSetACL() { + + $this->card->setACL(array()); + + } + + function testGetSupportedPrivilegeSet() { + + $this->assertNull( + $this->card->getSupportedPrivilegeSet() + ); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php new file mode 100644 index 000000000..431cd2524 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php @@ -0,0 +1,30 @@ +<?php + +namespace Sabre\CardDAV; + +use Sabre\DAV; + +class IDirectoryTest extends \PHPUnit_Framework_TestCase { + + function testResourceType() { + + $tree = array( + new DirectoryMock('directory') + ); + + $server = new DAV\Server($tree); + $plugin = new Plugin(); + $server->addPlugin($plugin); + + $props = $server->getProperties('directory', array('{DAV:}resourcetype')); + $this->assertTrue($props['{DAV:}resourcetype']->is('{' . Plugin::NS_CARDDAV . '}directory')); + + } + +} + +class DirectoryMock extends DAV\SimpleCollection implements IDirectory { + + + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php new file mode 100644 index 000000000..12922c6fd --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php @@ -0,0 +1,55 @@ +<?php + +namespace Sabre\CardDAV; + +use Sabre\HTTP; +use Sabre\DAV; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class MultiGetTest extends AbstractPluginTest { + + function testMultiGet() { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'REPORT', + 'REQUEST_URI' => '/addressbooks/user1/book1', + )); + + $request->setBody( +'<?xml version="1.0"?> +<c:addressbook-multiget xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav"> + <d:prop> + <d:getetag /> + <c:address-data /> + </d:prop> + <d:href>/addressbooks/user1/book1/card1</d:href> +</c:addressbook-multiget>' + ); + + $response = new HTTP\ResponseMock(); + + $this->server->httpRequest = $request; + $this->server->httpResponse = $response; + + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status, 'Incorrect status code. Full response body:' . $response->body); + + // using the client for parsing + $client = new DAV\Client(array('baseUri'=>'/')); + + $result = $client->parseMultiStatus($response->body); + + $this->assertEquals(array( + '/addressbooks/user1/book1/card1' => array( + 200 => array( + '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"', + '{urn:ietf:params:xml:ns:carddav}address-data' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD", + ) + ) + ), $result); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php new file mode 100644 index 000000000..297ebf496 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php @@ -0,0 +1,149 @@ +<?php + +namespace Sabre\CardDAV; + +use Sabre\DAV; + +require_once 'Sabre/CardDAV/AbstractPluginTest.php'; + +class PluginTest extends AbstractPluginTest { + + function testConstruct() { + + $this->assertEquals('card', $this->server->xmlNamespaces[Plugin::NS_CARDDAV]); + $this->assertEquals('{' . Plugin::NS_CARDDAV . '}addressbook', $this->server->resourceTypeMapping['Sabre\\CardDAV\\IAddressBook']); + + $this->assertTrue(in_array('addressbook', $this->plugin->getFeatures())); + + } + + function testSupportedReportSet() { + + $this->assertEquals(array( + '{' . Plugin::NS_CARDDAV . '}addressbook-multiget', + '{' . Plugin::NS_CARDDAV . '}addressbook-query', + ), $this->plugin->getSupportedReportSet('addressbooks/user1/book1')); + + } + + function testSupportedReportSetEmpty() { + + $this->assertEquals(array( + ), $this->plugin->getSupportedReportSet('')); + + } + + function testAddressBookHomeSet() { + + $result = $this->server->getProperties('principals/user1', array('{' . Plugin::NS_CARDDAV . '}addressbook-home-set')); + + $this->assertEquals(1, count($result)); + $this->assertTrue(isset($result['{' . Plugin::NS_CARDDAV . '}addressbook-home-set'])); + $this->assertEquals('addressbooks/user1/', $result['{' . Plugin::NS_CARDDAV . '}addressbook-home-set']->getHref()); + + } + + function testMeCardTest() { + + $result = $this->server->getProperties( + 'addressbooks/user1', + array( + '{http://calendarserver.org/ns/}me-card', + ) + ); + + $this->assertEquals( + array( + '{http://calendarserver.org/ns/}me-card' => + new DAV\Property\Href('addressbooks/user1/book1/vcard1.vcf') + ), + $result + ); + + } + + function testDirectoryGateway() { + + $result = $this->server->getProperties('principals/user1', array('{' . Plugin::NS_CARDDAV . '}directory-gateway')); + + $this->assertEquals(1, count($result)); + $this->assertTrue(isset($result['{' . Plugin::NS_CARDDAV . '}directory-gateway'])); + $this->assertEquals(array('directory'), $result['{' . Plugin::NS_CARDDAV . '}directory-gateway']->getHrefs()); + + } + + function testReportPassThrough() { + + $this->assertNull($this->plugin->report('{DAV:}foo', new \DomDocument())); + + } + + function testHTMLActionsPanel() { + + $output = ''; + $r = $this->server->broadcastEvent('onHTMLActionsPanel', array($this->server->tree->getNodeForPath('addressbooks/user1'), &$output)); + $this->assertFalse($r); + + $this->assertTrue(!!strpos($output,'Display name')); + + } + + function testBrowserPostAction() { + + $r = $this->server->broadcastEvent('onBrowserPostAction', array('addressbooks/user1', 'mkaddressbook', array( + 'name' => 'NEWADDRESSBOOK', + '{DAV:}displayname' => 'foo', + ))); + $this->assertFalse($r); + + $addressbooks = $this->backend->getAddressBooksforUser('principals/user1'); + $this->assertEquals(2, count($addressbooks)); + + $newAddressBook = null; + foreach($addressbooks as $addressbook) { + if ($addressbook['uri'] === 'NEWADDRESSBOOK') { + $newAddressBook = $addressbook; + break; + } + } + if (!$newAddressBook) + $this->fail('Could not find newly created addressbook'); + + } + + function testUpdatePropertiesMeCard() { + + $result = $this->server->updateProperties('addressbooks/user1', array( + '{http://calendarserver.org/ns/}me-card' => new DAV\Property\Href('/addressbooks/user1/book1/vcard2',true), + )); + + $this->assertEquals( + array( + 'href' => 'addressbooks/user1', + 200 => array( + '{http://calendarserver.org/ns/}me-card' => null, + ), + ), + $result + ); + + } + + function testUpdatePropertiesMeCardBadValue() { + + $result = $this->server->updateProperties('addressbooks/user1', array( + '{http://calendarserver.org/ns/}me-card' => new DAV\Property\HrefList(array()), + )); + + $this->assertEquals( + array( + 'href' => 'addressbooks/user1', + 400 => array( + '{http://calendarserver.org/ns/}me-card' => null, + ), + ), + $result + ); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Property/SupportedAddressDataTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Property/SupportedAddressDataTest.php new file mode 100644 index 000000000..a0e4130d5 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Property/SupportedAddressDataTest.php @@ -0,0 +1,44 @@ +<?php + +namespace Sabre\CardDAV\Property; + +use Sabre\CardDAV; +use Sabre\DAV; + +class SupportedAddressDataDataTest extends \PHPUnit_Framework_TestCase { + + function testSimple() { + + $property = new SupportedAddressData(); + + } + + /** + * @depends testSimple + */ + function testSerialize() { + + $property = new SupportedAddressData(); + + $doc = new \DOMDocument(); + $root = $doc->createElementNS(CardDAV\Plugin::NS_CARDDAV, 'card:root'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $server = new DAV\Server(); + + $property->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<card:root xmlns:card="' . CardDAV\Plugin::NS_CARDDAV . '" xmlns:d="DAV:">' . +'<card:address-data-type content-type="text/vcard" version="3.0"/>' . +//'<card:address-data-type content-type="text/vcard" version="4.0"/>' . +'</card:root> +', $xml); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php new file mode 100644 index 000000000..2a62bd2f9 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php @@ -0,0 +1,43 @@ +<?php + +namespace Sabre\CardDAV; + +use Sabre\HTTP; + +class SogoStripContentType extends \Sabre\DAVServerTest { + + protected $setupCardDAV = true; + protected $carddavAddressBooks = array( + array( + 'id' => 1, + 'uri' => 'book1', + 'principaluri' => 'principals/user1', + ), + ); + protected $carddavCards = array( + 1 => array( + 'card1.vcf' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD", + ), + ); + + function testDontStrip() { + + $result = $this->server->getProperties('addressbooks/user1/book1/card1.vcf',array('{DAV:}getcontenttype')); + $this->assertEquals(array( + '{DAV:}getcontenttype' => 'text/x-vcard; charset=utf-8' + ), $result); + + } + function testStrip() { + + $this->server->httpRequest = new HTTP\Request(array( + 'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2 Lightning/1.2.1', + )); + $result = $this->server->getProperties('addressbooks/user1/book1/card1.vcf',array('{DAV:}getcontenttype')); + $this->assertEquals(array( + '{DAV:}getcontenttype' => 'text/x-vcard' + ), $result); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/TestUtil.php b/vendor/sabre/dav/tests/Sabre/CardDAV/TestUtil.php new file mode 100644 index 000000000..9f84566af --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/TestUtil.php @@ -0,0 +1,68 @@ +<?php + +namespace Sabre\CardDAV; + +use PDO; + +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.addressbooks.sql')); + foreach($queries as $query) { + $pdo->exec($query); + } + // Inserting events through a backend class. + $backend = new Backend\PDO($pdo); + $addressbookId = $backend->createAddressBook( + 'principals/user1', + 'UUID-123467', + array( + '{DAV:}displayname' => 'user1 addressbook', + '{urn:ietf:params:xml:ns:carddav}addressbook-description' => 'AddressBook description', + ) + ); + $backend->createAddressBook( + 'principals/user1', + 'UUID-123468', + array( + '{DAV:}displayname' => 'user1 addressbook2', + '{urn:ietf:params:xml:ns:carddav}addressbook-description' => 'AddressBook description', + ) + ); + $backend->createCard($addressbookId, 'UUID-2345', self::getTestCardData()); + return $pdo; + + } + + static function getTestCardData($type = 1) { + + $addressbookData = 'BEGIN:VCARD +VERSION:3.0 +PRODID:-//Acme Inc.//RoadRunner 1.0//EN +FN:Wile E. Coyote +N:Coyote;Wile;Erroll;; +ORG:Acme Inc. +UID:39A6B5ED-DD51-4AFE-A683-C35EE3749627 +REV:2012-06-20T07:00:39+00:00 +END:VCARD'; + + return $addressbookData; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/UserAddressBooksTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/UserAddressBooksTest.php new file mode 100644 index 000000000..a6ecf3e47 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/UserAddressBooksTest.php @@ -0,0 +1,162 @@ +<?php + +namespace Sabre\CardDAV; + +class UserAddressBooksTest extends \PHPUnit_Framework_TestCase { + + /** + * @var Sabre\CardDAV\UserAddressBooks + */ + protected $s; + protected $backend; + + function setUp() { + + $this->backend = new Backend\Mock(); + $this->s = new UserAddressBooks( + $this->backend, + 'principals/user1' + ); + + } + + function testGetName() { + + $this->assertEquals('user1', $this->s->getName()); + + } + + /** + * @expectedException Sabre\DAV\Exception\MethodNotAllowed + */ + function testSetName() { + + $this->s->setName('user2'); + + } + + /** + * @expectedException Sabre\DAV\Exception\MethodNotAllowed + */ + function testDelete() { + + $this->s->delete(); + + } + + function testGetLastModified() { + + $this->assertNull($this->s->getLastModified()); + + } + + /** + * @expectedException Sabre\DAV\Exception\MethodNotAllowed + */ + function testCreateFile() { + + $this->s->createFile('bla'); + + } + + /** + * @expectedException Sabre\DAV\Exception\MethodNotAllowed + */ + function testCreateDirectory() { + + $this->s->createDirectory('bla'); + + } + + function testGetChild() { + + $child = $this->s->getChild('book1'); + $this->assertInstanceOf('Sabre\\CardDAV\\AddressBook', $child); + $this->assertEquals('book1', $child->getName()); + + } + + /** + * @expectedException Sabre\DAV\Exception\NotFound + */ + function testGetChild404() { + + $this->s->getChild('book2'); + + } + + function testGetChildren() { + + $children = $this->s->getChildren(); + $this->assertEquals(1, count($children)); + $this->assertInstanceOf('Sabre\\CardDAV\\AddressBook', $children[0]); + $this->assertEquals('book1', $children[0]->getName()); + + } + + function testCreateExtendedCollection() { + + $resourceType = array( + '{' . Plugin::NS_CARDDAV . '}addressbook', + '{DAV:}collection', + ); + $this->s->createExtendedCollection('book2', $resourceType, array('{DAV:}displayname' => 'a-book 2')); + + $this->assertEquals(array( + 'id' => 'book2', + 'uri' => 'book2', + '{DAV:}displayname' => 'a-book 2', + 'principaluri' => 'principals/user1', + ), $this->backend->addressBooks[1]); + + } + + /** + * @expectedException Sabre\DAV\Exception\InvalidResourceType + */ + function testCreateExtendedCollectionInvalid() { + + $resourceType = array( + '{DAV:}collection', + ); + $this->s->createExtendedCollection('book2', $resourceType, array('{DAV:}displayname' => 'a-book 2')); + + } + + + function testACLMethods() { + + $this->assertEquals('principals/user1', $this->s->getOwner()); + $this->assertNull($this->s->getGroup()); + $this->assertEquals(array( + array( + 'privilege' => '{DAV:}read', + 'principal' => 'principals/user1', + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}write', + 'principal' => 'principals/user1', + 'protected' => true, + ), + ), $this->s->getACL()); + + } + + /** + * @expectedException Sabre\DAV\Exception\MethodNotAllowed + */ + function testSetACL() { + + $this->s->setACL(array()); + + } + + function testGetSupportedPrivilegeSet() { + + $this->assertNull( + $this->s->getSupportedPrivilegeSet() + ); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php new file mode 100644 index 000000000..84da59311 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php @@ -0,0 +1,75 @@ +<?php + +namespace Sabre\CardDAV; + +use Sabre\HTTP; + +class VCFExportTest extends \Sabre\DAVServerTest { + + protected $setupCardDAV = true; + protected $autoLogin = 'user1'; + protected $setupACL = true; + + protected $carddavAddressBooks = array( + array( + 'id' => 'book1', + 'uri' => 'book1', + 'principaluri' => 'principals/user1', + ) + ); + protected $carddavCards = array( + 'book1' => array( + "card1" => "BEGIN:VCARD\r\nFN:Person1\r\nEND:VCARD\r\n", + "card2" => "BEGIN:VCARD\r\nFN:Person2\r\nEND:VCARD", + "card3" => "BEGIN:VCARD\r\nFN:Person3\r\nEND:VCARD\r\n", + "card4" => "BEGIN:VCARD\nFN:Person4\nEND:VCARD\n", + ) + ); + + function setUp() { + + parent::setUp(); + $this->server->addPlugin( + new VCFExportPlugin() + ); + + } + + function testSimple() { + + $this->assertInstanceOf('Sabre\\CardDAV\\VCFExportPlugin', $this->server->getPlugin('Sabre\\CardDAV\\VCFExportPlugin')); + + } + + function testExport() { + + $request = new HTTP\Request(array( + 'REQUEST_URI' => '/addressbooks/user1/book1?export', + 'QUERY_STRING' => 'export', + 'REQUEST_METHOD' => 'GET', + )); + + $response = $this->request($request); + $this->assertEquals('HTTP/1.1 200 OK', $response->status, $response->body); + + $expected = "BEGIN:VCARD +FN:Person1 +END:VCARD +BEGIN:VCARD +FN:Person2 +END:VCARD +BEGIN:VCARD +FN:Person3 +END:VCARD +BEGIN:VCARD +FN:Person4 +END:VCARD +"; + // We actually expected windows line endings + $expected = str_replace("\n","\r\n", $expected); + + $this->assertEquals($expected, $response->body); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php new file mode 100644 index 000000000..c87716c10 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php @@ -0,0 +1,204 @@ +<?php + +namespace Sabre\CardDAV; + +require_once 'Sabre/CardDAV/AbstractPluginTest.php'; + +class ValidateFilterTest extends AbstractPluginTest { + + /** + * @dataProvider data + */ + function testFilter($input, $filters, $test, $result, $message = null) { + + if ($result) { + $this->assertTrue($this->plugin->validateFilters($input, $filters, $test), $message); + } else { + $this->assertFalse($this->plugin->validateFilters($input, $filters, $test), $message); + } + + } + + function data() { + + $body1 = <<<HELLO +BEGIN:VCARD +VERSION:3.0 +ORG:Company; +TITLE:Title +TEL;TYPE=IPHONE;TYPE=pref:(222) 22 22 22 +TEL;TYPE=HOME:(33) 333 66 66 +TEL;TYPE=WORK:(444) 44 44 44 +TEL;TYPE=MAIN:(55) 555 55 55 +ITEM4.TEL:(111) 11 11 11 +ITEM5.TEL:(6) 66 66 66 66 +ITEM6.TEL:(77) 777 77 77 +UID:3151DE6A-BC35-4612-B340-B53A034A2B27 +ITEM1.EMAIL:1111@111.com +ITEM2.EMAIL:bbbbb@bbbb.com +ITEM3.EMAIL:ccccc@ccccc.com +FN:First Last +N:Last;First;Middle;Dr +BDAY:1985-07-20 +ADR;TYPE=HOME:;;Street;City;;3556;Montenegro +ADR;TYPE=WORK:;;Street\\nStreet2;Harkema;;35444;Australia +URL:http://google.com +END:VCARD +HELLO; + + // Check if TITLE is defined + $filter1 = + array('name' => 'title', 'is-not-defined' => false, 'param-filters' => array(), 'text-matches' => array()); + + // Check if FOO is defined + $filter2 = + array('name' => 'foo', 'is-not-defined' => false, 'param-filters' => array(), 'text-matches' => array()); + + // Check if TITLE is not defined + $filter3 = + array('name' => 'title', 'is-not-defined' => true, 'param-filters' => array(), 'text-matches' => array()); + + // Check if FOO is not defined + $filter4 = + array('name' => 'foo', 'is-not-defined' => true, 'param-filters' => array(), 'text-matches' => array()); + + // Check if TEL[TYPE] is defined + $filter5 = + array( + 'name' => 'tel', + 'is-not-defined' => false, + 'test' => 'anyof', + 'param-filters' => array( + array( + 'name' => 'type', + 'is-not-defined' => false, + 'text-match' => null + ), + ), + 'text-matches' => array(), + ); + + // Check if TEL[FOO] is defined + $filter6 = $filter5; + $filter6['param-filters'][0]['name'] = 'FOO'; + + // Check if TEL[TYPE] is not defined + $filter7 = $filter5; + $filter7['param-filters'][0]['is-not-defined'] = true; + + // Check if TEL[FOO] is not defined + $filter8 = $filter5; + $filter8['param-filters'][0]['name'] = 'FOO'; + $filter8['param-filters'][0]['is-not-defined'] = true; + + // Combining property filters + $filter9 = $filter5; + $filter9['param-filters'][] = $filter6['param-filters'][0]; + + $filter10 = $filter5; + $filter10['param-filters'][] = $filter6['param-filters'][0]; + $filter10['test'] = 'allof'; + + // Check if URL contains 'google' + $filter11 = + array( + 'name' => 'url', + 'is-not-defined' => false, + 'test' => 'anyof', + 'param-filters' => array(), + 'text-matches' => array( + array( + 'match-type' => 'contains', + 'value' => 'google', + 'negate-condition' => false, + 'collation' => 'i;octet', + ), + ), + ); + + // Check if URL contains 'bing' + $filter12 = $filter11; + $filter12['text-matches'][0]['value'] = 'bing'; + + // Check if URL does not contain 'google' + $filter13 = $filter11; + $filter13['text-matches'][0]['negate-condition'] = true; + + // Check if URL does not contain 'bing' + $filter14 = $filter11; + $filter14['text-matches'][0]['value'] = 'bing'; + $filter14['text-matches'][0]['negate-condition'] = true; + + // Param filter with text + $filter15 = $filter5; + $filter15['param-filters'][0]['text-match'] = array( + 'match-type' => 'contains', + 'value' => 'WORK', + 'collation' => 'i;octet', + 'negate-condition' => false, + ); + $filter16 = $filter15; + $filter16['param-filters'][0]['text-match']['negate-condition'] = true; + + + // Param filter + text filter + $filter17 = $filter5; + $filter17['test'] = 'anyof'; + $filter17['text-matches'][] = array( + 'match-type' => 'contains', + 'value' => '444', + 'collation' => 'i;octet', + 'negate-condition' => false, + ); + + $filter18 = $filter17; + $filter18['text-matches'][0]['negate-condition'] = true; + + $filter18['test'] = 'allof'; + + return array( + + // Basic filters + array($body1, array($filter1), 'anyof',true), + array($body1, array($filter2), 'anyof',false), + array($body1, array($filter3), 'anyof',false), + array($body1, array($filter4), 'anyof',true), + + // Combinations + array($body1, array($filter1, $filter2), 'anyof',true), + array($body1, array($filter1, $filter2), 'allof',false), + array($body1, array($filter1, $filter4), 'anyof',true), + array($body1, array($filter1, $filter4), 'allof',true), + array($body1, array($filter2, $filter3), 'anyof',false), + array($body1, array($filter2, $filter3), 'allof',false), + + // Basic parameters + array($body1, array($filter5), 'anyof', true, 'TEL;TYPE is defined, so this should return true'), + array($body1, array($filter6), 'anyof', false, 'TEL;FOO is not defined, so this should return false'), + + array($body1, array($filter7), 'anyof', false, 'TEL;TYPE is defined, so this should return false'), + array($body1, array($filter8), 'anyof', true, 'TEL;TYPE is not defined, so this should return true'), + + // Combined parameters + array($body1, array($filter9), 'anyof', true), + array($body1, array($filter10), 'anyof', false), + + // Text-filters + array($body1, array($filter11), 'anyof', true), + array($body1, array($filter12), 'anyof', false), + array($body1, array($filter13), 'anyof', false), + array($body1, array($filter14), 'anyof', true), + + // Param filter with text-match + array($body1, array($filter15), 'anyof', true), + array($body1, array($filter16), 'anyof', false), + + // Param filter + text filter + array($body1, array($filter17), 'anyof', true), + array($body1, array($filter18), 'anyof', false), + array($body1, array($filter18), 'anyof', false), + ); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php new file mode 100644 index 000000000..1f52f30a7 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php @@ -0,0 +1,155 @@ +<?php + +namespace Sabre\CardDAV; + +use Sabre\DAV; +use Sabre\HTTP; +use Sabre\DAVACL; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class ValidateVCardTest extends \PHPUnit_Framework_TestCase { + + protected $server; + protected $cardBackend; + + function setUp() { + + $addressbooks = array( + array( + 'id' => 'addressbook1', + 'principaluri' => 'principals/admin', + 'uri' => 'addressbook1', + ) + ); + + $this->cardBackend = new Backend\Mock($addressbooks,array()); + $principalBackend = new DAVACL\PrincipalBackend\Mock(); + + $tree = array( + new AddressBookRoot($principalBackend, $this->cardBackend), + ); + + $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' => '/addressbooks/admin/addressbook1/blabla.vcf', + )); + + $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' => '/addressbooks/admin/addressbook1/blabla.vcf', + )); + $request->setBody("BEGIN:VCARD\r\nUID:foo\r\nEND:VCARD\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.vcf', + 'carddata' => "BEGIN:VCARD\r\nUID:foo\r\nEND:VCARD\r\n", + ); + + $this->assertEquals($expected, $this->cardBackend->getCard('addressbook1','blabla.vcf')); + + } + + function testCreateFileNoUID() { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PUT', + 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf', + )); + $request->setBody("BEGIN:VCARD\r\nEND:VCARD\r\n"); + + $response = $this->request($request); + + $this->assertEquals('HTTP/1.1 201 Created', $response->status, 'Incorrect status returned! Full response body: ' . $response->body); + + $foo = $this->cardBackend->getCard('addressbook1','blabla.vcf'); + $this->assertTrue(strpos($foo['carddata'],'UID')!==false); + } + + + function testCreateFileVCalendar() { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PUT', + 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf', + )); + $request->setBody("BEGIN:VCALENDAR\r\nEND:VCALENDAR\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 testUpdateFile() { + + $this->cardBackend->createCard('addressbook1','blabla.vcf','foo'); + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PUT', + 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf', + )); + + $response = $this->request($request); + + $this->assertEquals('HTTP/1.1 415 Unsupported Media Type', $response->status); + + } + + function testUpdateFileParsableBody() { + + $this->cardBackend->createCard('addressbook1','blabla.vcf','foo'); + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PUT', + 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf', + )); + $body = "BEGIN:VCARD\r\nUID:foo\r\nEND:VCARD\r\n"; + $request->setBody($body); + + $response = $this->request($request); + + $this->assertEquals('HTTP/1.1 204 No Content', $response->status); + + $expected = array( + 'uri' => 'blabla.vcf', + 'carddata' => $body, + ); + + $this->assertEquals($expected, $this->cardBackend->getCard('addressbook1','blabla.vcf')); + + } +} + +?> diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/VersionTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/VersionTest.php new file mode 100644 index 000000000..02943b2d3 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/CardDAV/VersionTest.php @@ -0,0 +1,17 @@ +<?php + +namespace Sabre\CardDAV; + +class VersionTest extends \PHPUnit_Framework_TestCase { + + function testString() { + + $v = Version::VERSION; + $this->assertEquals(-1, version_compare('0.1',$v)); + + $s = Version::STABILITY; + $this->assertTrue($s == 'alpha' || $s == 'beta' || $s =='stable'); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php b/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php new file mode 100644 index 000000000..357675686 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php @@ -0,0 +1,64 @@ +<?php + +namespace Sabre\DAV; + +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +abstract class AbstractServer extends \PHPUnit_Framework_TestCase { + + /** + * @var Sabre\HTTP\ResponseMock + */ + protected $response; + protected $request; + /** + * @var Sabre\DAV\Server + */ + protected $server; + protected $tempDir = SABRE_TEMPDIR; + + function setUp() { + + $this->response = new HTTP\ResponseMock(); + $this->server = new Server($this->getRootNode()); + $this->server->httpResponse = $this->response; + $this->server->debugExceptions = true; + file_put_contents(SABRE_TEMPDIR . '/test.txt', 'Test contents'); + mkdir(SABRE_TEMPDIR . '/dir'); + file_put_contents(SABRE_TEMPDIR . '/dir/child.txt', 'Child contents'); + + + } + + function tearDown() { + + $this->deleteTree(SABRE_TEMPDIR,false); + + } + + protected function getRootNode() { + + return new FS\Directory(SABRE_TEMPDIR); + + } + + private function deleteTree($path,$deleteRoot = true) { + + foreach(scandir($path) as $node) { + + if ($node=='.' || $node=='.svn' || $node=='..') continue; + $myPath = $path.'/'. $node; + if (is_file($myPath)) { + unlink($myPath); + } else { + $this->deleteTree($myPath); + } + + } + if ($deleteRoot) rmdir($path); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php new file mode 100644 index 000000000..36d23c5c0 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php @@ -0,0 +1,91 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +use Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class AbstractBasicTest extends \PHPUnit_Framework_TestCase { + + /** + * @expectedException Sabre\DAV\Exception\NotAuthenticated + */ + public function testAuthenticateNoHeaders() { + + $response = new HTTP\ResponseMock(); + $server = new DAV\Server(); + $server->httpResponse = $response; + + $backend = new AbstractBasicMock(); + $backend->authenticate($server,'myRealm'); + + } + + /** + * @expectedException Sabre\DAV\Exception\NotAuthenticated + */ + public function testAuthenticateUnknownUser() { + + $response = new HTTP\ResponseMock(); + $tree = new DAV\ObjectTree(new DAV\SimpleCollection('bla')); + $server = new DAV\Server($tree); + $server->httpResponse = $response; + + $request = new HTTP\Request(array( + 'PHP_AUTH_USER' => 'username', + 'PHP_AUTH_PW' => 'wrongpassword', + )); + $server->httpRequest = $request; + + $backend = new AbstractBasicMock(); + $backend->authenticate($server,'myRealm'); + + } + + public function testAuthenticate() { + + $response = new HTTP\ResponseMock(); + $tree = new DAV\ObjectTree(new DAV\SimpleCollection('bla')); + $server = new DAV\Server($tree); + $server->httpResponse = $response; + + $request = new HTTP\Request(array( + 'PHP_AUTH_USER' => 'username', + 'PHP_AUTH_PW' => 'password', + )); + $server->httpRequest = $request; + + $backend = new AbstractBasicMock(); + $this->assertTrue($backend->authenticate($server,'myRealm')); + + $result = $backend->getCurrentUser(); + + $this->assertEquals('username', $result); + + } + + +} + + +class AbstractBasicMock extends AbstractBasic { + + /** + * Validates a username and password + * + * This method should return true or false depending on if login + * succeeded. + * + * @param string $username + * @param string $password + * @return bool + */ + function validateUserPass($username, $password) { + + return ($username == 'username' && $password == 'password'); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php new file mode 100644 index 000000000..495690c4e --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php @@ -0,0 +1,149 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +use Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class AbstractDigestTest extends \PHPUnit_Framework_TestCase { + + /** + * @expectedException Sabre\DAV\Exception\NotAuthenticated + */ + public function testAuthenticateNoHeaders() { + + $response = new HTTP\ResponseMock(); + $server = new DAV\Server(); + $server->httpResponse = $response; + + $backend = new AbstractDigestMock(); + $backend->authenticate($server,'myRealm'); + + } + + /** + * @expectedException Sabre\DAV\Exception + */ + public function testAuthenticateBadGetUserInfoResponse() { + + $response = new HTTP\ResponseMock(); + $server = new DAV\Server(); + $server->httpResponse = $response; + + $header = 'username=null, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1'; + $request = new HTTP\Request(array( + 'PHP_AUTH_DIGEST' => $header, + )); + $server->httpRequest = $request; + + $backend = new AbstractDigestMock(); + $backend->authenticate($server,'myRealm'); + + } + + /** + * @expectedException Sabre\DAV\Exception + */ + public function testAuthenticateBadGetUserInfoResponse2() { + + $response = new HTTP\ResponseMock(); + $server = new DAV\Server(); + $server->httpResponse = $response; + + $header = 'username=array, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1'; + $request = new HTTP\Request(array( + 'PHP_AUTH_DIGEST' => $header, + )); + $server->httpRequest = $request; + + $backend = new AbstractDigestMock(); + $backend->authenticate($server,'myRealm'); + + } + + /** + * @expectedException Sabre\DAV\Exception\NotAuthenticated + */ + public function testAuthenticateUnknownUser() { + + $response = new HTTP\ResponseMock(); + $server = new DAV\Server(); + $server->httpResponse = $response; + + $header = 'username=false, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1'; + $request = new HTTP\Request(array( + 'PHP_AUTH_DIGEST' => $header, + )); + $server->httpRequest = $request; + + $backend = new AbstractDigestMock(); + $backend->authenticate($server,'myRealm'); + + } + + /** + * @expectedException Sabre\DAV\Exception\NotAuthenticated + */ + public function testAuthenticateBadPassword() { + + $response = new HTTP\ResponseMock(); + $server = new DAV\Server(); + $server->httpResponse = $response; + + $header = 'username=user, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1'; + $request = new HTTP\Request(array( + 'PHP_AUTH_DIGEST' => $header, + 'REQUEST_METHOD' => 'PUT', + )); + $server->httpRequest = $request; + + $backend = new AbstractDigestMock(); + $backend->authenticate($server,'myRealm'); + + } + + public function testAuthenticate() { + + $response = new HTTP\ResponseMock(); + $server = new DAV\Server(); + $server->httpResponse = $response; + + $digestHash = md5('HELLO:12345:1:1:auth:' . md5('GET:/')); + $header = 'username=user, realm=myRealm, nonce=12345, uri=/, response='.$digestHash.', opaque=1, qop=auth, nc=1, cnonce=1'; + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'GET', + 'PHP_AUTH_DIGEST' => $header, + 'REQUEST_URI' => '/', + )); + $server->httpRequest = $request; + + $backend = new AbstractDigestMock(); + $this->assertTrue($backend->authenticate($server,'myRealm')); + + $result = $backend->getCurrentUser(); + + $this->assertEquals('user', $result); + $this->assertEquals('HELLO', $backend->getDigestHash('myRealm', $result)); + + } + + +} + + +class AbstractDigestMock extends AbstractDigest { + + function getDigestHash($realm, $userName) { + + switch($userName) { + case 'null' : return null; + case 'false' : return false; + case 'array' : return array(); + case 'user' : return 'HELLO'; + } + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php new file mode 100644 index 000000000..d22923d51 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php @@ -0,0 +1,35 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +use Sabre\DAV; + +abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase { + + abstract function getPDO(); + + function testConstruct() { + + $pdo = $this->getPDO(); + $backend = new PDO($pdo); + $this->assertTrue($backend instanceof PDO); + + } + + /** + * @depends testConstruct + */ + function testUserInfo() { + + $pdo = $this->getPDO(); + $backend = new PDO($pdo); + + $this->assertNull($backend->getDigestHash('realm','blabla')); + + $expected = 'hash'; + + $this->assertEquals($expected, $backend->getDigestHash('realm','user')); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php new file mode 100644 index 000000000..b1ed555d4 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php @@ -0,0 +1,45 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +use Sabre\DAV; +use Sabre\HTTP; + +class ApacheTest extends \PHPUnit_Framework_TestCase { + + function testConstruct() { + + $backend = new Apache(); + + } + + /** + * @expectedException Sabre\DAV\Exception + */ + function testNoHeader() { + + $server = new DAV\Server(); + $backend = new Apache(); + $backend->authenticate($server,'Realm'); + + } + + function testRemoteUser() { + + $backend = new Apache(); + + $server = new DAV\Server(); + $request = new HTTP\Request(array( + 'REMOTE_USER' => 'username', + )); + $server->httpRequest = $request; + + $this->assertTrue($backend->authenticate($server, 'Realm')); + + $userInfo = 'username'; + + $this->assertEquals($userInfo, $backend->getCurrentUser()); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php new file mode 100644 index 000000000..72f150ab6 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php @@ -0,0 +1,42 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +class FileTest extends \PHPUnit_Framework_TestCase { + + function tearDown() { + + if (file_exists(SABRE_TEMPDIR . '/filebackend')) unlink(SABRE_TEMPDIR .'/filebackend'); + + } + + function testConstruct() { + + $file = new File(); + $this->assertTrue($file instanceof File); + + } + + /** + * @expectedException Sabre\DAV\Exception + */ + function testLoadFileBroken() { + + file_put_contents(SABRE_TEMPDIR . '/backend','user:realm:hash'); + $file = new File(); + $file->loadFile(SABRE_TEMPDIR .'/backend'); + + } + + function testLoadFile() { + + file_put_contents(SABRE_TEMPDIR . '/backend','user:realm:' . md5('user:realm:password')); + $file = new File(); + $file->loadFile(SABRE_TEMPDIR . '/backend'); + + $this->assertFalse($file->getDigestHash('realm','blabla')); + $this->assertEquals(md5('user:realm:password'), $file->getDigesthash('realm','user')); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php new file mode 100644 index 000000000..fdad8a605 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php @@ -0,0 +1,37 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +use Sabre\DAV; + +class Mock implements BackendInterface { + + protected $currentUser; + + public $defaultUser = 'admin'; + + /** + * @param Sabre\DAV\Server $server + * @param string $realm + * @throws Sabre\DAV\Exception\NotAuthenticated + */ + function authenticate(DAV\Server $server, $realm) { + + if ($realm=='failme') throw new DAV\Exception\NotAuthenticated('deliberate fail'); + $this->currentUser = $this->defaultUser; + + } + + function setCurrentUser($user) { + + $this->currentUser = $user; + + } + + function getCurrentUser() { + + return $this->currentUser; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php new file mode 100644 index 000000000..ede432de2 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php @@ -0,0 +1,31 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +require_once 'Sabre/TestUtil.php'; + +class PDOMySQLTest extends AbstractPDOTest { + + function getPDO() { + + 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 users"); + $pdo->query(" +create table users ( + id integer unsigned not null primary key auto_increment, + username varchar(50), + digesta1 varchar(32), + email varchar(80), + displayname varchar(80), + unique(username) +);"); + + $pdo->query("INSERT INTO users (username,digesta1,email,displayname) VALUES ('user','hash','user@example.org','User')"); + + return $pdo; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php new file mode 100644 index 000000000..abfb031bb --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php @@ -0,0 +1,28 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +require_once 'Sabre/DAV/Auth/Backend/AbstractPDOTest.php'; + +class PDOSQLiteTest extends AbstractPDOTest { + + function tearDown() { + + if (file_exists(SABRE_TEMPDIR . '/pdobackend')) unlink(SABRE_TEMPDIR . '/pdobackend'); + if (file_exists(SABRE_TEMPDIR . '/pdobackend2')) unlink(SABRE_TEMPDIR . '/pdobackend2'); + + } + + function getPDO() { + + if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available'); + $pdo = new \PDO('sqlite:'.SABRE_TEMPDIR.'/pdobackend'); + $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION); + $pdo->query('CREATE TABLE users (username TEXT, digesta1 TEXT, email VARCHAR(80), displayname VARCHAR(80))'); + $pdo->query('INSERT INTO users VALUES ("user","hash","user@example.org","User")'); + + return $pdo; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php new file mode 100644 index 000000000..2096a04d7 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php @@ -0,0 +1,84 @@ +<?php + +namespace Sabre\DAV\Auth; + +use Sabre\HTTP; +use Sabre\DAV; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class PluginTest extends \PHPUnit_Framework_TestCase { + + function testInit() { + + $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla')); + $plugin = new Plugin(new Backend\Mock(),'realm'); + $this->assertTrue($plugin instanceof Plugin); + $fakeServer->addPlugin($plugin); + $this->assertEquals($plugin, $fakeServer->getPlugin('auth')); + + } + + /** + * @depends testInit + */ + function testAuthenticate() { + + $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla')); + $plugin = new Plugin(new Backend\Mock(),'realm'); + $fakeServer->addPlugin($plugin); + $fakeServer->broadCastEvent('beforeMethod',array('GET','/')); + + } + + + + /** + * @depends testInit + * @expectedException Sabre\DAV\Exception\NotAuthenticated + */ + function testAuthenticateFail() { + + $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla')); + $plugin = new Plugin(new Backend\Mock(),'failme'); + $fakeServer->addPlugin($plugin); + $fakeServer->broadCastEvent('beforeMethod',array('GET','/')); + + } + + function testReportPassThrough() { + + $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla')); + $plugin = new Plugin(new Backend\Mock(),'realm'); + $fakeServer->addPlugin($plugin); + + $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" />'); + + $fakeServer->httpRequest = $request; + $fakeServer->httpResponse = new HTTP\ResponseMock(); + $fakeServer->exec(); + + $this->assertEquals('HTTP/1.1 403 Forbidden', $fakeServer->httpResponse->status); + + } + + /** + * @depends testInit + */ + function testGetCurrentUserPrincipal() { + + $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla')); + $plugin = new Plugin(new Backend\Mock(),'realm'); + $fakeServer->addPlugin($plugin); + $fakeServer->broadCastEvent('beforeMethod',array('GET','/')); + $this->assertEquals('admin', $plugin->getCurrentUser()); + + } + +} + diff --git a/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php new file mode 100644 index 000000000..fdc2403db --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php @@ -0,0 +1,234 @@ +<?php + +namespace Sabre\DAV; + +class BasicNodeTest extends \PHPUnit_Framework_TestCase { + + /** + * @expectedException Sabre\DAV\Exception\Forbidden + */ + public function testPut() { + + $file = new FileMock(); + $file->put('hi'); + + } + + /** + * @expectedException Sabre\DAV\Exception\Forbidden + */ + public function testGet() { + + $file = new FileMock(); + $file->get(); + + } + + public function testGetSize() { + + $file = new FileMock(); + $this->assertEquals(0,$file->getSize()); + + } + + + public function testGetETag() { + + $file = new FileMock(); + $this->assertNull($file->getETag()); + + } + + public function testGetContentType() { + + $file = new FileMock(); + $this->assertNull($file->getContentType()); + + } + + /** + * @expectedException Sabre\DAV\Exception\Forbidden + */ + public function testDelete() { + + $file = new FileMock(); + $file->delete(); + + } + + /** + * @expectedException Sabre\DAV\Exception\Forbidden + */ + public function testSetName() { + + $file = new FileMock(); + $file->setName('hi'); + + } + + public function testGetLastModified() { + + $file = new FileMock(); + // checking if lastmod is within the range of a few seconds + $lastMod = $file->getLastModified(); + $compareTime = ($lastMod + 1)-time(); + $this->assertTrue($compareTime < 3); + + } + + public function testGetChild() { + + $dir = new DirectoryMock(); + $file = $dir->getChild('mockfile'); + $this->assertTrue($file instanceof FileMock); + + } + + public function testChildExists() { + + $dir = new DirectoryMock(); + $this->assertTrue($dir->childExists('mockfile')); + + } + + public function testChildExistsFalse() { + + $dir = new DirectoryMock(); + $this->assertFalse($dir->childExists('mockfile2')); + + } + + /** + * @expectedException Sabre\DAV\Exception\NotFound + */ + public function testGetChild404() { + + $dir = new DirectoryMock(); + $file = $dir->getChild('blabla'); + + } + + /** + * @expectedException Sabre\DAV\Exception\Forbidden + */ + public function testCreateFile() { + + $dir = new DirectoryMock(); + $dir->createFile('hello','data'); + + } + + /** + * @expectedException Sabre\DAV\Exception\Forbidden + */ + public function testCreateDirectory() { + + $dir = new DirectoryMock(); + $dir->createDirectory('hello'); + + } + + public function testSimpleDirectoryConstruct() { + + $dir = new SimpleCollection('simpledir',array()); + + } + + /** + * @depends testSimpleDirectoryConstruct + */ + public function testSimpleDirectoryConstructChild() { + + $file = new FileMock(); + $dir = new SimpleCollection('simpledir',array($file)); + $file2 = $dir->getChild('mockfile'); + + $this->assertEquals($file,$file2); + + } + + /** + * @expectedException Sabre\DAV\Exception + * @depends testSimpleDirectoryConstruct + */ + public function testSimpleDirectoryBadParam() { + + $dir = new SimpleCollection('simpledir',array('string shouldn\'t be here')); + + } + + /** + * @depends testSimpleDirectoryConstruct + */ + public function testSimpleDirectoryAddChild() { + + $file = new FileMock(); + $dir = new SimpleCollection('simpledir'); + $dir->addChild($file); + $file2 = $dir->getChild('mockfile'); + + $this->assertEquals($file,$file2); + + } + + /** + * @depends testSimpleDirectoryConstruct + * @depends testSimpleDirectoryAddChild + */ + public function testSimpleDirectoryGetChildren() { + + $file = new FileMock(); + $dir = new SimpleCollection('simpledir'); + $dir->addChild($file); + + $this->assertEquals(array($file),$dir->getChildren()); + + } + + /* + * @depends testSimpleDirectoryConstruct + */ + public function testSimpleDirectoryGetName() { + + $dir = new SimpleCollection('simpledir'); + $this->assertEquals('simpledir',$dir->getName()); + + } + + /** + * @depends testSimpleDirectoryConstruct + * @expectedException Sabre\DAV\Exception\NotFound + */ + public function testSimpleDirectoryGetChild404() { + + $dir = new SimpleCollection('simpledir'); + $dir->getChild('blabla'); + + } +} + +class DirectoryMock extends Collection { + + function getName() { + + return 'mockdir'; + + } + + function getChildren() { + + return array(new FileMock()); + + } + +} + +class FileMock extends File { + + function getName() { + + return 'mockfile'; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php new file mode 100644 index 000000000..6fc65f9e8 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php @@ -0,0 +1,68 @@ +<?php + +namespace Sabre\DAV\Browser; + +use Sabre\DAV; + +require_once 'Sabre/DAV/AbstractServer.php'; +class GuessContentTypeTest extends DAV\AbstractServer { + + function setUp() { + + parent::setUp(); + file_put_contents(SABRE_TEMPDIR . '/somefile.jpg','blabla'); + file_put_contents(SABRE_TEMPDIR . '/somefile.hoi','blabla'); + + } + + function tearDown() { + + unlink(SABRE_TEMPDIR . '/somefile.jpg'); + parent::tearDown(); + } + + function testGetProperties() { + + $properties = array( + '{DAV:}getcontenttype', + ); + $result = $this->server->getPropertiesForPath('/somefile.jpg',$properties); + $this->assertArrayHasKey(0,$result); + $this->assertArrayHasKey(404,$result[0]); + $this->assertArrayHasKey('{DAV:}getcontenttype',$result[0][404]); + + } + + /** + * @depends testGetProperties + */ + function testGetPropertiesPluginEnabled() { + + $this->server->addPlugin(new GuessContentType()); + $properties = array( + '{DAV:}getcontenttype', + ); + $result = $this->server->getPropertiesForPath('/somefile.jpg',$properties); + $this->assertArrayHasKey(0,$result); + $this->assertArrayHasKey(200,$result[0]); + $this->assertArrayHasKey('{DAV:}getcontenttype',$result[0][200]); + $this->assertEquals('image/jpeg',$result[0][200]['{DAV:}getcontenttype']); + + } + + /** + * @depends testGetPropertiesPluginEnabled + */ + function testGetPropertiesUnknown() { + + $this->server->addPlugin(new GuessContentType()); + $properties = array( + '{DAV:}getcontenttype', + ); + $result = $this->server->getPropertiesForPath('/somefile.hoi',$properties); + $this->assertArrayHasKey(0,$result); + $this->assertArrayHasKey(404,$result[0]); + $this->assertArrayHasKey('{DAV:}getcontenttype',$result[0][404]); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php new file mode 100644 index 000000000..169675e7e --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php @@ -0,0 +1,44 @@ +<?php + +namespace Sabre\DAV\Browser; + +use Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/DAV/AbstractServer.php'; + +class MapGetToPropFindTest extends DAV\AbstractServer { + + function setUp() { + + parent::setUp(); + $this->server->addPlugin(new MapGetToPropFind()); + + } + + function testCollectionGet() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'GET', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody(''); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + 'DAV' => '1, 3, extended-mkcol', + 'Vary' => 'Brief,Prefer', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Incorrect status response received. Full response body: ' . $this->response->body); + + } + + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php new file mode 100644 index 000000000..c3c4bdebb --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php @@ -0,0 +1,114 @@ +<?php + +namespace Sabre\DAV\Browser; + +use Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/DAV/AbstractServer.php'; + +class PluginTest extends DAV\AbstractServer{ + + function setUp() { + + parent::setUp(); + $this->server->addPlugin(new Plugin()); + + } + + function testCollectionGet() { + + $serverVars = array( + 'REQUEST_URI' => '/dir', + 'REQUEST_METHOD' => 'GET', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals(array( + 'Content-Type' => 'text/html; charset=utf-8', + ), + $this->response->headers + ); + + $this->assertTrue(strpos($this->response->body, 'Index for dir/') !== false); + $this->assertTrue(strpos($this->response->body, '<a href="/dir/child.txt"><img src="/?sabreAction=asset&assetName=icons%2Ffile.png" alt="" width="24" />')!==false); + + } + + function testNotFound() { + + $serverVars = array( + 'REQUEST_URI' => '/random', + 'REQUEST_METHOD' => 'GET', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 404 Not Found',$this->response->status); + + } + + function testPostOtherContentType() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'POST', + 'CONTENT_TYPE' => 'text/xml', + ); + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 501 Not Implemented', $this->response->status); + + } + + function testPostNoSabreAction() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'POST', + 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', + ); + $postVars = array(); + + $request = new HTTP\Request($serverVars,$postVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 501 Not Implemented', $this->response->status); + + } + + function testPostMkCol() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'POST', + 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', + ); + $postVars = array( + 'sabreAction' => 'mkcol', + 'name' => 'new_collection', + ); + + $request = new HTTP\Request($serverVars,$postVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 302 Found', $this->response->status); + $this->assertEquals(array( + 'Location' => '/', + ), $this->response->headers); + + $this->assertTrue(is_dir(SABRE_TEMPDIR . '/new_collection')); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php b/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php new file mode 100644 index 000000000..6e74e6ec0 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php @@ -0,0 +1,32 @@ +<?php + +namespace Sabre\DAV; + +class ClientMock extends Client { + + public $response; + + public $url; + public $curlSettings; + + protected function curlRequest($url, $curlSettings) { + + $this->url = $url; + $this->curlSettings = $curlSettings; + return $this->response; + + } + + /** + * Just making this method public + * + * @param string $url + * @return string + */ + public function getAbsoluteUrl($url) { + + return parent::getAbsoluteUrl($url); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php new file mode 100644 index 000000000..9c3532a47 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php @@ -0,0 +1,949 @@ +<?php + +namespace Sabre\DAV; + +require_once 'Sabre/DAV/ClientMock.php'; + +class ClientTest extends \PHPUnit_Framework_TestCase { + + function testConstruct() { + + $client = new ClientMock(array( + 'baseUri' => '/', + )); + + } + + /** + * @expectedException InvalidArgumentException + */ + function testConstructNoBaseUri() { + + $client = new ClientMock(array()); + + } + + function testRequest() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 45, + 'http_code' => 200, + ), + 0, + "" + ); + + $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain')); + + $this->assertEquals('http://example.org/foo/bar/baz', $client->url); + $this->assertEquals(array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 5, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => 'sillybody', + CURLOPT_HEADER => true, + CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), + ), $client->curlSettings); + + $this->assertEquals(array( + 'statusCode' => 200, + 'headers' => array( + 'content-type' => 'text/plain', + ), + 'body' => 'Hello there!' + ), $result); + + + } + + + function testRequestProxy() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + 'proxy' => 'http://localhost:8000/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 45, + 'http_code' => 200, + ), + 0, + "" + ); + + $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain')); + + $this->assertEquals('http://example.org/foo/bar/baz', $client->url); + $this->assertEquals(array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 5, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => 'sillybody', + CURLOPT_HEADER => true, + CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), + CURLOPT_PROXY => 'http://localhost:8000/', + ), $client->curlSettings); + + $this->assertEquals(array( + 'statusCode' => 200, + 'headers' => array( + 'content-type' => 'text/plain', + ), + 'body' => 'Hello there!' + ), $result); + + } + + function testRequestCAInfo() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 45, + 'http_code' => 200, + ), + 0, + "" + ); + + $client->addTrustedCertificates('bla'); + + $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain')); + + $this->assertEquals('http://example.org/foo/bar/baz', $client->url); + $this->assertEquals(array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 5, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => 'sillybody', + CURLOPT_HEADER => true, + CURLOPT_CAINFO => 'bla', + CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), + ), $client->curlSettings); + + } + + function testRequestSslPeer() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 45, + 'http_code' => 200, + ), + 0, + "" + ); + + $client->setVerifyPeer(true); + + $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain')); + + $this->assertEquals('http://example.org/foo/bar/baz', $client->url); + $this->assertEquals(array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 5, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => 'sillybody', + CURLOPT_HEADER => true, + CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), + CURLOPT_SSL_VERIFYPEER => true + ), $client->curlSettings); + + } + + function testRequestAuth() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + 'userName' => 'user', + 'password' => 'password', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 45, + 'http_code' => 200, + ), + 0, + "" + ); + + $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain')); + + $this->assertEquals('http://example.org/foo/bar/baz', $client->url); + $this->assertEquals(array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 5, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => 'sillybody', + CURLOPT_HEADER => true, + CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), + CURLOPT_HTTPAUTH => CURLAUTH_BASIC | CURLAUTH_DIGEST, + CURLOPT_USERPWD => 'user:password' + ), $client->curlSettings); + + $this->assertEquals(array( + 'statusCode' => 200, + 'headers' => array( + 'content-type' => 'text/plain', + ), + 'body' => 'Hello there!' + ), $result); + + } + + function testRequestAuthBasic() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + 'userName' => 'user', + 'password' => 'password', + 'authType' => Client::AUTH_BASIC, + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 45, + 'http_code' => 200, + ), + 0, + "" + ); + + $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain')); + + $this->assertEquals('http://example.org/foo/bar/baz', $client->url); + $this->assertEquals(array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 5, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => 'sillybody', + CURLOPT_HEADER => true, + CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), + CURLOPT_HTTPAUTH => CURLAUTH_BASIC, + CURLOPT_USERPWD => 'user:password' + ), $client->curlSettings); + + $this->assertEquals(array( + 'statusCode' => 200, + 'headers' => array( + 'content-type' => 'text/plain', + ), + 'body' => 'Hello there!' + ), $result); + + } + + function testRequestAuthDigest() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + 'userName' => 'user', + 'password' => 'password', + 'authType' => Client::AUTH_DIGEST, + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 45, + 'http_code' => 200, + ), + 0, + "" + ); + + $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain')); + + $this->assertEquals('http://example.org/foo/bar/baz', $client->url); + $this->assertEquals(array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 5, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => 'sillybody', + CURLOPT_HEADER => true, + CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), + CURLOPT_HTTPAUTH => CURLAUTH_DIGEST, + CURLOPT_USERPWD => 'user:password' + ), $client->curlSettings); + + $this->assertEquals(array( + 'statusCode' => 200, + 'headers' => array( + 'content-type' => 'text/plain', + ), + 'body' => 'Hello there!' + ), $result); + + } + function testRequestError() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 45, + 'http_code' => 200, + ), + CURLE_COULDNT_CONNECT, + "Could not connect, or something" + ); + + $caught = false; + try { + $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain')); + } catch (Exception $e) { + $caught = true; + } + if (!$caught) { + $this->markTestFailed('Exception was not thrown'); + } + + } + + function testRequestHTTPError() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 400 Bad Request", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 45, + 'http_code' => 400, + ), + 0, + "" + ); + + $caught = false; + try { + $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain')); + } catch (Exception $e) { + $caught = true; + } + if (!$caught) { + $this->fail('Exception was not thrown'); + } + + } + + function testRequestHTTP404() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 404 Not Found", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 45, + 'http_code' => 404, + ), + 0, + "" + ); + + $caught = false; + try { + $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain')); + } catch (Exception\NotFound $e) { + $caught = true; + } + if (!$caught) { + $this->fail('Exception was not thrown'); + } + + } + + /** + * @dataProvider supportedHTTPCodes + */ + function testSpecificHTTPErrors($error) { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 $error blabla", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 42, + 'http_code' => $error, + ), + 0, + "" + ); + + try { + $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain')); + $this->fail('Exception was not thrown'); + } catch (Exception $e) { + $this->assertEquals($e->getHTTPCode(), $error); + } + + + } + + public function supportedHTTPCodes() { + + return array( + array(400), + array(401), + array(402), + array(403), + array(404), + array(405), + array(409), + array(412), + array(416), + array(500), + array(501), + array(507), + ); + + } + + function testUnsupportedHTTPError() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 580 blabla", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 42, + 'http_code' => "580" + ), + 0, + "" + ); + + try { + $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain')); + $this->fail('Exception was not thrown'); + } catch (Exception $e) { + $this->assertEquals(500, $e->getHTTPCode()); + } + + + } + + function testGetAbsoluteUrl() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/', + )); + + $this->assertEquals( + 'http://example.org/foo/bar', + $client->getAbsoluteUrl('bar') + ); + + $this->assertEquals( + 'http://example.org/bar', + $client->getAbsoluteUrl('/bar') + ); + + $this->assertEquals( + 'http://example.com/bar', + $client->getAbsoluteUrl('http://example.com/bar') + ); + + } + + function testOptions() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "DAV: feature1, feature2", + "", + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 40, + 'http_code' => 200, + ), + 0, + "" + ); + + $result = $client->options(); + $this->assertEquals( + array('feature1', 'feature2'), + $result + ); + + } + + function testOptionsNoDav() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "", + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 20, + 'http_code' => 200, + ), + 0, + "" + ); + + $result = $client->options(); + $this->assertEquals( + array(), + $result + ); + + } + + /** + * @expectedException InvalidArgumentException + */ + function testPropFindNoXML() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "", + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 20, + 'http_code' => 200, + ), + 0, + "" + ); + + $client->propfind('', array('{DAV:}foo','{DAV:}bar')); + + } + + function testPropFind() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "", + "<?xml version=\"1.0\"?>", + "<d:multistatus xmlns:d=\"DAV:\">", + " <d:response>", + " <d:href>/foo/bar/</d:href>", + " <d:propstat>", + " <d:prop>", + " <d:foo>hello</d:foo>", + " </d:prop>", + " <d:status>HTTP/1.1 200 OK</d:status>", + " </d:propstat>", + " <d:propstat>", + " <d:prop>", + " <d:bar />", + " </d:prop>", + " <d:status>HTTP/1.1 404 Not Found</d:status>", + " </d:propstat>", + " </d:response>", + "</d:multistatus>", + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 19, + 'http_code' => 200, + ), + 0, + "" + ); + + $result = $client->propfind('', array('{DAV:}foo','{DAV:}bar')); + + $this->assertEquals(array( + '{DAV:}foo' => 'hello', + ), $result); + + $requestBody = array( + '<?xml version="1.0"?>', + '<d:propfind xmlns:d="DAV:">', + ' <d:prop>', + ' <d:foo />', + ' <d:bar />', + ' </d:prop>', + '</d:propfind>' + ); + $requestBody = implode("\n", $requestBody); + + $this->assertEquals($requestBody, $client->curlSettings[CURLOPT_POSTFIELDS]); + + } + + /** + * This was reported in Issue 235. + * + * If no '200 Ok' properties are returned, the client will throw an + * E_NOTICE. + */ + function testPropFindNo200s() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "", + "<?xml version=\"1.0\"?>", + "<d:multistatus xmlns:d=\"DAV:\">", + " <d:response>", + " <d:href>/foo/bar/</d:href>", + " <d:propstat>", + " <d:prop>", + " <d:bar />", + " </d:prop>", + " <d:status>HTTP/1.1 404 Not Found</d:status>", + " </d:propstat>", + " </d:response>", + "</d:multistatus>", + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 19, + 'http_code' => 200, + ), + 0, + "" + ); + + $result = $client->propfind('', array('{DAV:}foo','{DAV:}bar')); + + $this->assertEquals(array( + ), $result); + + } + + function testPropFindDepth1CustomProp() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "", + "<?xml version=\"1.0\"?>", + "<d:multistatus xmlns:d=\"DAV:\" xmlns:x=\"urn:custom\">", + " <d:response>", + " <d:href>/foo/bar/</d:href>", + " <d:propstat>", + " <d:prop>", + " <d:foo>hello</d:foo>", + " <x:bar>world</x:bar>", + " </d:prop>", + " <d:status>HTTP/1.1 200 OK</d:status>", + " </d:propstat>", + " </d:response>", + "</d:multistatus>", + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 19, + 'http_code' => 200, + ), + 0, + "" + ); + + $result = $client->propfind('', array('{DAV:}foo','{urn:custom}bar'),1); + + $this->assertEquals(array( + "/foo/bar/" => array( + '{DAV:}foo' => 'hello', + '{urn:custom}bar' => 'world', + ), + ), $result); + + $requestBody = array( + '<?xml version="1.0"?>', + '<d:propfind xmlns:d="DAV:">', + ' <d:prop>', + ' <d:foo />', + ' <x:bar xmlns:x="urn:custom"/>', + ' </d:prop>', + '</d:propfind>' + ); + $requestBody = implode("\n", $requestBody); + + $this->assertEquals($requestBody, $client->curlSettings[CURLOPT_POSTFIELDS]); + + } + + function testPropPatch() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "", + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 20, + 'http_code' => 200, + ), + 0, + "" + ); + + $client->proppatch('', array( + '{DAV:}foo' => 'newvalue', + '{urn:custom}foo' => 'newvalue2', + '{DAV:}bar' => null, + '{urn:custom}bar' => null, + )); + + $requestBody = array( + '<?xml version="1.0"?>', + '<d:propertyupdate xmlns:d="DAV:">', + '<d:set><d:prop>', + ' <d:foo>newvalue</d:foo>', + '</d:prop></d:set>', + '<d:set><d:prop>', + ' <x:foo xmlns:x="urn:custom">newvalue2</x:foo>', + '</d:prop></d:set>', + '<d:remove><d:prop>', + ' <d:bar />', + '</d:prop></d:remove>', + '<d:remove><d:prop>', + ' <x:bar xmlns:x="urn:custom"/>', + '</d:prop></d:remove>', + '</d:propertyupdate>' + ); + $requestBody = implode("\n", $requestBody); + + $this->assertEquals($requestBody, $client->curlSettings[CURLOPT_POSTFIELDS]); + + } + + function testHEADRequest() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 45, + 'http_code' => 200, + ), + 0, + "" + ); + + $result = $client->request('HEAD', 'baz'); + + $this->assertEquals('http://example.org/foo/bar/baz', $client->url); + $this->assertEquals(array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 5, + CURLOPT_CUSTOMREQUEST => 'HEAD', + CURLOPT_NOBODY => true, + CURLOPT_HEADER => true, + CURLOPT_HTTPHEADER => array(), + CURLOPT_POSTFIELDS => null, + ), $client->curlSettings); + + } + + function testPUTRequest() { + + $client = new ClientMock(array( + 'baseUri' => 'http://example.org/foo/bar/', + )); + + $responseBlob = array( + "HTTP/1.1 200 OK", + "Content-Type: text/plain", + "", + "Hello there!" + ); + + $client->response = array( + implode("\r\n", $responseBlob), + array( + 'header_size' => 45, + 'http_code' => 200, + ), + 0, + "" + ); + + $result = $client->request('PUT', 'bar','newcontent'); + + $this->assertEquals('http://example.org/foo/bar/bar', $client->url); + $this->assertEquals(array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 5, + CURLOPT_CUSTOMREQUEST => "PUT", + CURLOPT_POSTFIELDS => 'newcontent', + CURLOPT_HEADER => true, + CURLOPT_HTTPHEADER => array(), + ), $client->curlSettings); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php new file mode 100644 index 000000000..c06d6aa1f --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php @@ -0,0 +1,68 @@ +<?php + +namespace Sabre\DAV\Exception; + +use + Sabre\DAV, + DOMDocument; + +class LockedTest extends \PHPUnit_Framework_TestCase { + + function testSerialize() { + + $dom = new DOMDocument('1.0'); + $dom->formatOutput = true; + $root = $dom->createElement('d:root'); + + $dom->appendChild($root); + $root->setAttribute('xmlns:d','DAV:'); + + $lockInfo = new DAV\Locks\LockInfo(); + $lockInfo->uri = '/foo'; + $locked = new Locked($lockInfo); + + $locked->serialize(new DAV\Server(), $root); + + $output = $dom->saveXML(); + + $expected = '<?xml version="1.0"?> +<d:root xmlns:d="DAV:"> + <d:lock-token-submitted xmlns:d="DAV:"> + <d:href>/foo</d:href> + </d:lock-token-submitted> +</d:root> +'; + + $this->assertEquals($expected, $output); + + } + + function testSerializeAmpersand() { + + $dom = new DOMDocument('1.0'); + $dom->formatOutput = true; + $root = $dom->createElement('d:root'); + + $dom->appendChild($root); + $root->setAttribute('xmlns:d','DAV:'); + + $lockInfo = new DAV\Locks\LockInfo(); + $lockInfo->uri = '/foo&bar'; + $locked = new Locked($lockInfo); + + $locked->serialize(new DAV\Server(), $root); + + $output = $dom->saveXML(); + + $expected = '<?xml version="1.0"?> +<d:root xmlns:d="DAV:"> + <d:lock-token-submitted xmlns:d="DAV:"> + <d:href>/foo&bar</d:href> + </d:lock-token-submitted> +</d:root> +'; + + $this->assertEquals($expected, $output); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Exception/PaymentRequiredTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Exception/PaymentRequiredTest.php new file mode 100644 index 000000000..7142937b4 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Exception/PaymentRequiredTest.php @@ -0,0 +1,14 @@ +<?php + +namespace Sabre\DAV\Exception; + +class PaymentRequiredTest extends \PHPUnit_Framework_TestCase { + + function testGetHTTPCode() { + + $ex = new PaymentRequired(); + $this->assertEquals(402, $ex->getHTTPCode()); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php new file mode 100644 index 000000000..6d6bf5668 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php @@ -0,0 +1,30 @@ +<?php + +namespace Sabre\DAV; + +class ExceptionTest extends \PHPUnit_Framework_TestCase { + + function testStatus() { + + $e = new Exception(); + $this->assertEquals(500,$e->getHTTPCode()); + + } + + function testExceptionStatuses() { + + $c = array( + 'Sabre\\DAV\\Exception\\NotAuthenticated' => 401, + 'Sabre\\DAV\\Exception\\InsufficientStorage' => 507, + ); + + foreach($c as $class=>$status) { + + $obj = new $class(); + $this->assertEquals($status, $obj->getHTTPCode()); + + } + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php new file mode 100644 index 000000000..265f9f1c1 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php @@ -0,0 +1,95 @@ +<?php + +namespace Sabre\DAV\FSExt; + +use Sabre\DAV; + +require_once 'Sabre/TestUtil.php'; + +class FileTest extends \PHPUnit_Framework_TestCase { + + function setUp() { + + file_put_contents(SABRE_TEMPDIR . '/file.txt', 'Contents'); + + } + + function tearDown() { + + \Sabre\TestUtil::clearTempDir(); + + } + + function testPut() { + + $file = new File(SABRE_TEMPDIR . '/file.txt'); + $result = $file->put('New contents'); + + $this->assertEquals('New contents',file_get_contents(SABRE_TEMPDIR . '/file.txt')); + $this->assertEquals('"' . md5('New contents') . '"', $result); + + } + + function testRange() { + + $file = new File(SABRE_TEMPDIR . '/file.txt'); + $file->put('0000000'); + $file->putRange('111',3); + + $this->assertEquals('0011100',file_get_contents(SABRE_TEMPDIR . '/file.txt')); + + } + + function testRangeStream() { + + $stream = fopen('php://memory','r+'); + fwrite($stream, "222"); + rewind($stream); + + $file = new File(SABRE_TEMPDIR . '/file.txt'); + $file->put('0000000'); + $file->putRange($stream,3); + + $this->assertEquals('0022200',file_get_contents(SABRE_TEMPDIR . '/file.txt')); + + } + + + function testGet() { + + $file = new File(SABRE_TEMPDIR . '/file.txt'); + $this->assertEquals('Contents',stream_get_contents($file->get())); + + } + + function testDelete() { + + $file = new File(SABRE_TEMPDIR . '/file.txt'); + $file->delete(); + + $this->assertFalse(file_exists(SABRE_TEMPDIR . '/file.txt')); + + } + + function testGetETag() { + + $file = new File(SABRE_TEMPDIR . '/file.txt'); + $this->assertEquals('"' . md5('Contents') . '"',$file->getETag()); + + } + + function testGetContentType() { + + $file = new File(SABRE_TEMPDIR . '/file.txt'); + $this->assertNull($file->getContentType()); + + } + + function testGetSize() { + + $file = new File(SABRE_TEMPDIR . '/file.txt'); + $this->assertEquals(8,$file->getSize()); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/NodeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/NodeTest.php new file mode 100644 index 000000000..275075b4c --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/NodeTest.php @@ -0,0 +1,178 @@ +<?php + +namespace Sabre\DAV\FSExt; +use Sabre\DAV; + +require_once 'Sabre/TestUtil.php'; + +class NodeTest extends \PHPUnit_Framework_TestCase { + + function setUp() { + + mkdir(SABRE_TEMPDIR . '/dir'); + file_put_contents(SABRE_TEMPDIR . '/dir/file.txt', 'Contents'); + file_put_contents(SABRE_TEMPDIR . '/dir/file2.txt', 'Contents2'); + + } + + function tearDown() { + + \Sabre\TestUtil::clearTempDir(); + + } + + function testUpdateProperties() { + + $file = new File(SABRE_TEMPDIR . '/dir/file.txt'); + $properties = array( + '{http://sabredav.org/NS/2010}test1' => 'foo', + '{http://sabredav.org/NS/2010}test2' => 'bar', + ); + + $result = $file->updateProperties($properties); + $expected = true; + + $this->assertEquals($expected, $result); + + $getProperties = $file->getProperties(array_keys($properties)); + + $this->assertEquals($properties, $getProperties); + + } + + /** + * @depends testUpdateProperties + */ + function testUpdatePropertiesAgain() { + + $file = new File(SABRE_TEMPDIR . '/dir/file.txt'); + $mutations = array( + '{http://sabredav.org/NS/2010}test1' => 'foo', + '{http://sabredav.org/NS/2010}test2' => 'bar', + ); + + $result = $file->updateProperties($mutations); + + $this->assertEquals(true, $result); + + $mutations = array( + '{http://sabredav.org/NS/2010}test1' => 'foo', + '{http://sabredav.org/NS/2010}test3' => 'baz', + ); + + $result = $file->updateProperties($mutations); + + $this->assertEquals(true, $result); + } + + /** + * @depends testUpdateProperties + */ + function testUpdatePropertiesDelete() { + + $file = new File(SABRE_TEMPDIR . '/dir/file.txt'); + + $mutations = array( + '{http://sabredav.org/NS/2010}test1' => 'foo', + '{http://sabredav.org/NS/2010}test2' => 'bar', + ); + + $result = $file->updateProperties($mutations); + + $this->assertEquals(true, $result); + + $mutations = array( + '{http://sabredav.org/NS/2010}test1' => null, + '{http://sabredav.org/NS/2010}test3' => null + ); + + $result = $file->updateProperties($mutations); + + $this->assertEquals(true, $result); + + $properties = $file->getProperties(array('http://sabredav.org/NS/2010}test1','{http://sabredav.org/NS/2010}test2','{http://sabredav.org/NS/2010}test3')); + + $this->assertEquals(array( + '{http://sabredav.org/NS/2010}test2' => 'bar', + ), $properties); + } + + /** + * @depends testUpdateProperties + */ + function testUpdatePropertiesMove() { + + $file = new File(SABRE_TEMPDIR . '/dir/file.txt'); + + $mutations = array( + '{http://sabredav.org/NS/2010}test1' => 'foo', + '{http://sabredav.org/NS/2010}test2' => 'bar', + ); + + $result = $file->updateProperties($mutations); + + $this->assertEquals(true, $result); + + $properties = $file->getProperties(array('{http://sabredav.org/NS/2010}test1','{http://sabredav.org/NS/2010}test2','{http://sabredav.org/NS/2010}test3')); + + $this->assertEquals(array( + '{http://sabredav.org/NS/2010}test1' => 'foo', + '{http://sabredav.org/NS/2010}test2' => 'bar', + ), $properties); + + // Renaming + $file->setName('file3.txt'); + + $this->assertFalse(file_exists(SABRE_TEMPDIR . '/dir/file.txt')); + $this->assertTrue(file_exists(SABRE_TEMPDIR . '/dir/file3.txt')); + $this->assertEquals('file3.txt',$file->getName()); + + $newFile = new File(SABRE_TEMPDIR . '/dir/file3.txt'); + $this->assertEquals('file3.txt',$newFile->getName()); + + $properties = $newFile->getProperties(array('{http://sabredav.org/NS/2010}test1','{http://sabredav.org/NS/2010}test2','{http://sabredav.org/NS/2010}test3')); + + $this->assertEquals(array( + '{http://sabredav.org/NS/2010}test1' => 'foo', + '{http://sabredav.org/NS/2010}test2' => 'bar', + ), $properties); + } + + /** + * @depends testUpdatePropertiesMove + */ + function testUpdatePropertiesDeleteBleed() { + + $file = new File(SABRE_TEMPDIR . '/dir/file.txt'); + $mutations = array( + '{http://sabredav.org/NS/2010}test1' => 'foo', + '{http://sabredav.org/NS/2010}test2' => 'bar', + ); + + $result = $file->updateProperties($mutations); + + $this->assertEquals(true, $result); + + $properties = $file->getProperties(array('{http://sabredav.org/NS/2010}test1','{http://sabredav.org/NS/2010}test2','{http://sabredav.org/NS/2010}test3')); + + $this->assertEquals(array( + '{http://sabredav.org/NS/2010}test1' => 'foo', + '{http://sabredav.org/NS/2010}test2' => 'bar', + ), $properties); + + // Deleting + $file->delete(); + + $this->assertFalse(file_exists(SABRE_TEMPDIR . '/dir/file.txt')); + + // Creating it again + file_put_contents(SABRE_TEMPDIR . '/dir/file.txt','New Contents'); + $file = new File(SABRE_TEMPDIR . '/dir/file.txt'); + + $properties = $file->getProperties(array('http://sabredav.org/NS/2010}test1','{http://sabredav.org/NS/2010}test2','{http://sabredav.org/NS/2010}test3')); + + $this->assertEquals(array(), $properties); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php new file mode 100644 index 000000000..907ede40b --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php @@ -0,0 +1,224 @@ +<?php + +namespace Sabre\DAV\FSExt; + +use Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/DAV/AbstractServer.php'; + +class ServerTest extends DAV\AbstractServer{ + + protected function getRootNode() { + + return new Directory($this->tempDir); + + } + + function testGet() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'GET', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 13, + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + 'ETag' => '"' .md5_file($this->tempDir . '/test.txt') . '"', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals('Test contents', stream_get_contents($this->response->body)); + + } + + function testHEAD() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'HEAD', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 13, + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + 'ETag' => '"' . md5_file($this->tempDir . '/test.txt') . '"', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals('', $this->response->body); + + } + + function testPut() { + + $serverVars = array( + 'REQUEST_URI' => '/testput.txt', + 'REQUEST_METHOD' => 'PUT', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing new file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Length' => 0, + 'ETag' => '"' . md5('Testing new file') . '"', + ), $this->response->headers); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals('', $this->response->body); + $this->assertEquals('Testing new file',file_get_contents($this->tempDir . '/testput.txt')); + + } + + function testPutAlreadyExists() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_IF_NONE_MATCH' => '*', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing new file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status); + $this->assertNotEquals('Testing new file',file_get_contents($this->tempDir . '/test.txt')); + + } + + function testMkcol() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'MKCOL', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody(""); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Length' => '0', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals('', $this->response->body); + $this->assertTrue(is_dir($this->tempDir . '/testcol')); + + } + + function testPutUpdate() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing updated file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('0', $this->response->headers['Content-Length']); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status); + $this->assertEquals('', $this->response->body); + $this->assertEquals('Testing updated file',file_get_contents($this->tempDir . '/test.txt')); + + } + + function testDelete() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'DELETE', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Length' => '0', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status); + $this->assertEquals('', $this->response->body); + $this->assertFalse(file_exists($this->tempDir . '/test.txt')); + + } + + function testDeleteDirectory() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'DELETE', + ); + + mkdir($this->tempDir.'/testcol'); + file_put_contents($this->tempDir.'/testcol/test.txt','Hi! I\'m a file with a short lifespan'); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Length' => '0', + ),$this->response->headers); + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status); + $this->assertEquals('', $this->response->body); + $this->assertFalse(file_exists($this->tempDir . '/col')); + + } + + function testOptions() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'OPTIONS', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'DAV' => '1, 3, extended-mkcol', + 'MS-Author-Via' => 'DAV', + 'Allow' => 'OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT', + 'Accept-Ranges' => 'bytes', + 'Content-Length' => '0', + 'X-Sabre-Version'=> DAV\Version::VERSION, + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals('', $this->response->body); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/HTTPPreferParsingTest.php b/vendor/sabre/dav/tests/Sabre/DAV/HTTPPreferParsingTest.php new file mode 100644 index 000000000..45865b2a1 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/HTTPPreferParsingTest.php @@ -0,0 +1,200 @@ +<?php + +namespace Sabre\DAV; + +use Sabre\HTTP; + +class HTTPPReferParsingTest extends \Sabre\DAVServerTest { + + function testParseSimple() { + + $httpRequest = new HTTP\Request(array( + 'HTTP_PREFER' => 'return-asynch', + )); + + $server = new Server(); + $server->httpRequest = $httpRequest; + + $this->assertEquals(array( + 'return-asynch' => true, + 'return-minimal' => false, + 'return-representation' => false, + 'strict' => false, + 'lenient' => false, + 'wait' => null, + ), $server->getHTTPPrefer()); + + } + + function testParseValue() { + + $httpRequest = new HTTP\Request(array( + 'HTTP_PREFER' => 'wait=10', + )); + + $server = new Server(); + $server->httpRequest = $httpRequest; + + $this->assertEquals(array( + 'return-asynch' => false, + 'return-minimal' => false, + 'return-representation' => false, + 'strict' => false, + 'lenient' => false, + 'wait' => 10, + ), $server->getHTTPPrefer()); + + } + + function testParseMultiple() { + + $httpRequest = new HTTP\Request(array( + 'HTTP_PREFER' => 'return-minimal, strict,lenient', + )); + + $server = new Server(); + $server->httpRequest = $httpRequest; + + $this->assertEquals(array( + 'return-asynch' => false, + 'return-minimal' => true, + 'return-representation' => false, + 'strict' => true, + 'lenient' => true, + 'wait' => null, + ), $server->getHTTPPrefer()); + + } + + function testParseWeirdValue() { + + $httpRequest = new HTTP\Request(array( + 'HTTP_PREFER' => 'BOOOH', + )); + + $server = new Server(); + $server->httpRequest = $httpRequest; + + $this->assertEquals(array( + 'strict' => false, + 'lenient' => false, + 'wait' => null, + 'return-asynch' => false, + 'return-minimal' => false, + 'return-representation' => false, + ), $server->getHTTPPrefer()); + + } + + function testBrief() { + + $httpRequest = new HTTP\Request(array( + 'HTTP_BRIEF' => 't', + )); + + $server = new Server(); + $server->httpRequest = $httpRequest; + + $this->assertEquals(array( + 'strict' => false, + 'lenient' => false, + 'wait' => null, + 'return-asynch' => false, + 'return-minimal' => true, + 'return-representation' => false, + ), $server->getHTTPPrefer()); + + } + + /** + * propfindMinimal + * + * @return void + */ + function testpropfindMinimal() { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PROPFIND', + 'REQUEST_URI' => '/', + 'HTTP_PREFER' => 'return-minimal', + )); + $request->setBody(<<<BLA +<?xml version="1.0"?> +<d:propfind xmlns:d="DAV:"> + <d:prop> + <d:something /> + <d:resourcetype /> + </d:prop> +</d:propfind> +BLA + ); + + $response = $this->request($request); + + $this->assertTrue(strpos($response->body, 'resourcetype')!==false); + $this->assertTrue(strpos($response->body, 'something')===false); + + } + + function testproppatchMinimal() { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PROPPATCH', + 'REQUEST_URI' => '/', + 'HTTP_PREFER' => 'return-minimal', + )); + $request->setBody(<<<BLA +<?xml version="1.0"?> +<d:proppatch xmlns:d="DAV:"> + <d:set> + <d:prop> + <d:something>nope!</d:something> + </d:prop> + </d:set> +</d:proppatch> +BLA + ); + + $this->server->subscribeEvent('updateProperties', function(&$props, &$result) { + + if (isset($props['{DAV:}something'])) { + unset($props['{DAV:}something']); + $result[200]['{DAV:}something'] = null; + } + + }); + + $response = $this->request($request); + + $this->assertEquals(0, strlen($response->body), 'Expected empty body: ' . $response->body); + $this->assertEquals('HTTP/1.1 204 No Content', $response->status); + + } + + function testproppatchMinimalError() { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PROPPATCH', + 'REQUEST_URI' => '/', + 'HTTP_PREFER' => 'return-minimal', + )); + $request->setBody(<<<BLA +<?xml version="1.0"?> +<d:proppatch xmlns:d="DAV:"> + <d:set> + <d:prop> + <d:something>nope!</d:something> + </d:prop> + </d:set> +</d:proppatch> +BLA + ); + + $response = $this->request($request); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status); + $this->assertTrue(strpos($response->body, 'something')!==false); + $this->assertTrue(strpos($response->body, 'HTTP/1.1 403 Forbidden')!==false); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php b/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php new file mode 100644 index 000000000..c3fba4aae --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php @@ -0,0 +1,105 @@ +<?php + +namespace Sabre\DAV; + +use Sabre\HTTP; + +require_once 'Sabre/TestUtil.php'; + +class Issue33Test extends \PHPUnit_Framework_TestCase { + + function setUp() { + + \Sabre\TestUtil::clearTempDir(); + + } + + function testCopyMoveInfo() { + + $bar = new SimpleCollection('bar'); + $root = new SimpleCollection('webdav',array($bar)); + + $server = new Server($root); + $server->setBaseUri('/webdav/'); + + $serverVars = array( + 'REQUEST_URI' => '/webdav/bar', + 'HTTP_DESTINATION' => 'http://dev2.tribalos.com/webdav/%C3%A0fo%C3%B3', + 'HTTP_OVERWRITE' => 'F', + ); + + $request = new HTTP\Request($serverVars); + + $server->httpRequest = $request; + + $info = $server->getCopyAndMoveInfo(); + + $this->assertEquals('%C3%A0fo%C3%B3', urlencode($info['destination'])); + $this->assertFalse($info['destinationExists']); + $this->assertFalse($info['destinationNode']); + + } + + function testTreeMove() { + + mkdir(SABRE_TEMPDIR . '/issue33'); + $dir = new FS\Directory(SABRE_TEMPDIR . '/issue33'); + + $dir->createDirectory('bar'); + + $tree = new ObjectTree($dir); + $tree->move('bar',urldecode('%C3%A0fo%C3%B3')); + + $node = $tree->getNodeForPath(urldecode('%C3%A0fo%C3%B3')); + $this->assertEquals(urldecode('%C3%A0fo%C3%B3'),$node->getName()); + + } + + function testDirName() { + + $dirname1 = 'bar'; + $dirname2 = urlencode('%C3%A0fo%C3%B3');; + + $this->assertTrue(dirname($dirname1)==dirname($dirname2)); + + } + + /** + * @depends testTreeMove + * @depends testCopyMoveInfo + */ + function testEverything() { + + // Request object + $serverVars = array( + 'REQUEST_METHOD' => 'MOVE', + 'REQUEST_URI' => '/webdav/bar', + 'HTTP_DESTINATION' => 'http://dev2.tribalos.com/webdav/%C3%A0fo%C3%B3', + 'HTTP_OVERWRITE' => 'F', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody(''); + + $response = new HTTP\ResponseMock(); + + // Server setup + mkdir(SABRE_TEMPDIR . '/issue33'); + $dir = new FS\Directory(SABRE_TEMPDIR . '/issue33'); + + $dir->createDirectory('bar'); + + $tree = new ObjectTree($dir); + + $server = new Server($tree); + $server->setBaseUri('/webdav/'); + + $server->httpRequest = $request; + $server->httpResponse = $response; + $server->exec(); + + $this->assertTrue(file_exists(SABRE_TEMPDIR . '/issue33/' . urldecode('%C3%A0fo%C3%B3'))); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php new file mode 100644 index 000000000..f39e9a036 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php @@ -0,0 +1,196 @@ +<?php + +namespace Sabre\DAV\Locks\Backend; + +use Sabre\DAV; + +abstract class AbstractTest extends \PHPUnit_Framework_TestCase { + + /** + * @abstract + * @return AbstractBackend + */ + abstract function getBackend(); + + function testSetup() { + + $backend = $this->getBackend(); + $this->assertInstanceOf('Sabre\\DAV\\Locks\\Backend\\AbstractBackend', $backend); + + } + + /** + * @depends testSetup + */ + function testGetLocks() { + + $backend = $this->getBackend(); + + $lock = new DAV\Locks\LockInfo(); + $lock->owner = 'Sinterklaas'; + $lock->timeout = 60; + $lock->created = time(); + $lock->token = 'MY-UNIQUE-TOKEN'; + $lock->uri ='someuri'; + + $this->assertTrue($backend->lock('someuri', $lock)); + + $locks = $backend->getLocks('someuri', false); + + $this->assertEquals(1,count($locks)); + $this->assertEquals('Sinterklaas',$locks[0]->owner); + $this->assertEquals('someuri',$locks[0]->uri); + + } + + /** + * @depends testGetLocks + */ + function testGetLocksParent() { + + $backend = $this->getBackend(); + + $lock = new DAV\Locks\LockInfo(); + $lock->owner = 'Sinterklaas'; + $lock->timeout = 60; + $lock->created = time(); + $lock->depth = DAV\Server::DEPTH_INFINITY; + $lock->token = 'MY-UNIQUE-TOKEN'; + + $this->assertTrue($backend->lock('someuri', $lock)); + + $locks = $backend->getLocks('someuri/child', false); + + $this->assertEquals(1,count($locks)); + $this->assertEquals('Sinterklaas',$locks[0]->owner); + $this->assertEquals('someuri',$locks[0]->uri); + + } + + + /** + * @depends testGetLocks + */ + function testGetLocksParentDepth0() { + + $backend = $this->getBackend(); + + $lock = new DAV\Locks\LockInfo(); + $lock->owner = 'Sinterklaas'; + $lock->timeout = 60; + $lock->created = time(); + $lock->depth = 0; + $lock->token = 'MY-UNIQUE-TOKEN'; + + $this->assertTrue($backend->lock('someuri', $lock)); + + $locks = $backend->getLocks('someuri/child', false); + + $this->assertEquals(0,count($locks)); + + } + + function testGetLocksChildren() { + + $backend = $this->getBackend(); + + $lock = new DAV\Locks\LockInfo(); + $lock->owner = 'Sinterklaas'; + $lock->timeout = 60; + $lock->created = time(); + $lock->depth = 0; + $lock->token = 'MY-UNIQUE-TOKEN'; + + $this->assertTrue($backend->lock('someuri/child', $lock)); + + $locks = $backend->getLocks('someuri/child', false); + $this->assertEquals(1,count($locks)); + + $locks = $backend->getLocks('someuri', false); + $this->assertEquals(0,count($locks)); + + $locks = $backend->getLocks('someuri', true); + $this->assertEquals(1,count($locks)); + + } + + /** + * @depends testGetLocks + */ + function testLockRefresh() { + + $backend = $this->getBackend(); + + $lock = new DAV\Locks\LockInfo(); + $lock->owner = 'Sinterklaas'; + $lock->timeout = 60; + $lock->created = time(); + $lock->token = 'MY-UNIQUE-TOKEN'; + + $this->assertTrue($backend->lock('someuri', $lock)); + /* Second time */ + + $lock->owner = 'Santa Clause'; + $this->assertTrue($backend->lock('someuri', $lock)); + + $locks = $backend->getLocks('someuri', false); + + $this->assertEquals(1,count($locks)); + + $this->assertEquals('Santa Clause',$locks[0]->owner); + $this->assertEquals('someuri',$locks[0]->uri); + + } + + /** + * @depends testGetLocks + */ + function testUnlock() { + + $backend = $this->getBackend(); + + $lock = new DAV\Locks\LockInfo(); + $lock->owner = 'Sinterklaas'; + $lock->timeout = 60; + $lock->created = time(); + $lock->token = 'MY-UNIQUE-TOKEN'; + + $this->assertTrue($backend->lock('someuri', $lock)); + + $locks = $backend->getLocks('someuri', false); + $this->assertEquals(1,count($locks)); + + $this->assertTrue($backend->unlock('someuri',$lock)); + + $locks = $backend->getLocks('someuri', false); + $this->assertEquals(0,count($locks)); + + } + + /** + * @depends testUnlock + */ + function testUnlockUnknownToken() { + + $backend = $this->getBackend(); + + $lock = new DAV\Locks\LockInfo(); + $lock->owner = 'Sinterklaas'; + $lock->timeout = 60; + $lock->created = time(); + $lock->token = 'MY-UNIQUE-TOKEN'; + + $this->assertTrue($backend->lock('someuri', $lock)); + + $locks = $backend->getLocks('someuri', false); + $this->assertEquals(1,count($locks)); + + $lock->token = 'SOME-OTHER-TOKEN'; + $this->assertFalse($backend->unlock('someuri',$lock)); + + $locks = $backend->getLocks('someuri', false); + $this->assertEquals(1,count($locks)); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FSTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FSTest.php new file mode 100644 index 000000000..651abf786 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FSTest.php @@ -0,0 +1,31 @@ +<?php + +namespace Sabre\DAV\Locks\Backend; + +require_once 'Sabre/TestUtil.php'; + +class FSTest extends AbstractTest { + + function getBackend() { + + \Sabre\TestUtil::clearTempDir(); + mkdir(SABRE_TEMPDIR . '/locks'); + $backend = new FS(SABRE_TEMPDIR . '/locks/'); + return $backend; + + } + + function tearDown() { + + \Sabre\TestUtil::clearTempDir(); + + } + + function testGetLocksChildren() { + + // We're skipping this test. This doesn't work, and it will + // never. The class is deprecated anyway. + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FileTest.php new file mode 100644 index 000000000..537996f3b --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FileTest.php @@ -0,0 +1,24 @@ +<?php + +namespace Sabre\DAV\Locks\Backend; + +require_once 'Sabre/TestUtil.php'; + +class FileTest extends AbstractTest { + + function getBackend() { + + \Sabre\TestUtil::clearTempDir(); + $backend = new File(SABRE_TEMPDIR . '/lockdb'); + return $backend; + + } + + + function tearDown() { + + \Sabre\TestUtil::clearTempDir(); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php new file mode 100644 index 000000000..b6f06224c --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php @@ -0,0 +1,32 @@ +<?php + +namespace Sabre\DAV\Locks\Backend; + +require_once 'Sabre/TestUtil.php'; + +class PDOMySQLTest extends AbstractTest { + + function getBackend() { + + if (!SABRE_HASMYSQL) $this->markTestSkipped('MySQL driver is not available, or it was not properly configured'); + $pdo = \Sabre\TestUtil::getMySQLDB(); + if (!$pdo) $this->markTestSkipped('Could not connect to MySQL database'); + $pdo->query('DROP TABLE IF EXISTS locks;'); + $pdo->query(" +CREATE TABLE locks ( + id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + owner VARCHAR(100), + timeout INTEGER UNSIGNED, + created INTEGER, + token VARCHAR(100), + scope TINYINT, + depth TINYINT, + uri text +);"); + + $backend = new PDO($pdo); + return $backend; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php new file mode 100644 index 000000000..d6336c7b2 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php @@ -0,0 +1,29 @@ +<?php + +namespace Sabre\DAV\Locks\Backend; + +require_once 'Sabre/TestUtil.php'; +require_once 'Sabre/DAV/Locks/Backend/AbstractTest.php'; + +class PDOTest extends AbstractTest { + + function getBackend() { + + if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available'); + \Sabre\TestUtil::clearTempDir(); + mkdir(SABRE_TEMPDIR . '/pdolocks'); + $pdo = new \PDO('sqlite:' . SABRE_TEMPDIR . '/pdolocks/db.sqlite'); + $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION); + $pdo->query('CREATE TABLE locks ( id integer primary key asc, owner text, timeout text, created integer, token text, scope integer, depth integer, uri text)'); + $backend = new PDO($pdo); + return $backend; + + } + + function tearDown() { + + \Sabre\TestUtil::clearTempDir(); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/GetIfConditionsTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/GetIfConditionsTest.php new file mode 100644 index 000000000..7b2cd0db0 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/GetIfConditionsTest.php @@ -0,0 +1,375 @@ +<?php + +namespace Sabre\DAV\Locks; + +use Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; +require_once 'Sabre/DAV/AbstractServer.php'; + +class GetIfConditionsTest extends DAV\AbstractServer { + + /** + * @var Sabre\DAV\Locks\Plugin + */ + protected $locksPlugin; + + function setUp() { + + parent::setUp(); + $locksPlugin = new Plugin(); + $this->server->addPlugin($locksPlugin); + $this->locksPlugin = $locksPlugin; + + } + + function testNoConditions() { + + $serverVars = array( + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + + $conditions = $this->locksPlugin->getIfConditions(); + $this->assertEquals(array(),$conditions); + + } + + function testLockToken() { + + $serverVars = array( + 'HTTP_IF' => '(<opaquelocktoken:token1>)', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + + $conditions = $this->locksPlugin->getIfConditions(); + + $compare = array( + + array( + 'uri' => '', + 'tokens' => array( + array( + 1, + 'opaquelocktoken:token1', + '', + ), + ), + + ), + + ); + + $this->assertEquals($compare,$conditions); + + } + + function testNotLockToken() { + + $serverVars = array( + 'HTTP_IF' => '(Not <opaquelocktoken:token1>)', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + + $conditions = $this->locksPlugin->getIfConditions(); + + $compare = array( + + array( + 'uri' => '', + 'tokens' => array( + array( + 0, + 'opaquelocktoken:token1', + '', + ), + ), + + ), + + ); + $this->assertEquals($compare,$conditions); + + } + + function testLockTokenUrl() { + + $serverVars = array( + 'HTTP_IF' => '<http://www.example.com/> (<opaquelocktoken:token1>)', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + + $conditions = $this->locksPlugin->getIfConditions(); + + $compare = array( + + array( + 'uri' => 'http://www.example.com/', + 'tokens' => array( + array( + 1, + 'opaquelocktoken:token1', + '', + ), + ), + + ), + + ); + $this->assertEquals($compare,$conditions); + + } + + function test2LockTokens() { + + $serverVars = array( + 'HTTP_IF' => '(<opaquelocktoken:token1>) (Not <opaquelocktoken:token2>)', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + + $conditions = $this->locksPlugin->getIfConditions(); + + $compare = array( + + array( + 'uri' => '', + 'tokens' => array( + array( + 1, + 'opaquelocktoken:token1', + '', + ), + array( + 0, + 'opaquelocktoken:token2', + '', + ), + ), + + ), + + ); + $this->assertEquals($compare,$conditions); + + } + + function test2UriLockTokens() { + + $serverVars = array( + 'HTTP_IF' => '<http://www.example.org/node1> (<opaquelocktoken:token1>) <http://www.example.org/node2> (Not <opaquelocktoken:token2>)', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + + $conditions = $this->locksPlugin->getIfConditions(); + + $compare = array( + + array( + 'uri' => 'http://www.example.org/node1', + 'tokens' => array( + array( + 1, + 'opaquelocktoken:token1', + '', + ), + ), + ), + array( + 'uri' => 'http://www.example.org/node2', + 'tokens' => array( + array( + 0, + 'opaquelocktoken:token2', + '', + ), + ), + + ), + + ); + $this->assertEquals($compare,$conditions); + + } + + function test2UriMultiLockTokens() { + + $serverVars = array( + 'HTTP_IF' => '<http://www.example.org/node1> (<opaquelocktoken:token1>) (<opaquelocktoken:token2>) <http://www.example.org/node2> (Not <opaquelocktoken:token3>)', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + + $conditions = $this->locksPlugin->getIfConditions(); + + $compare = array( + + array( + 'uri' => 'http://www.example.org/node1', + 'tokens' => array( + array( + 1, + 'opaquelocktoken:token1', + '', + ), + array( + 1, + 'opaquelocktoken:token2', + '', + ), + ), + ), + array( + 'uri' => 'http://www.example.org/node2', + 'tokens' => array( + array( + 0, + 'opaquelocktoken:token3', + '', + ), + ), + + ), + + ); + $this->assertEquals($compare,$conditions); + + } + + function testEtag() { + + $serverVars = array( + 'HTTP_IF' => '([etag1])', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + + $conditions = $this->locksPlugin->getIfConditions(); + + $compare = array( + + array( + 'uri' => '', + 'tokens' => array( + array( + 1, + '', + 'etag1', + ), + ), + ), + + ); + $this->assertEquals($compare,$conditions); + + } + + function test2Etags() { + + $serverVars = array( + 'HTTP_IF' => '<http://www.example.org/> ([etag1]) ([etag2])', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + + $conditions = $this->locksPlugin->getIfConditions(); + + $compare = array( + + array( + 'uri' => 'http://www.example.org/', + 'tokens' => array( + array( + 1, + '', + 'etag1', + ), + array( + 1, + '', + 'etag2', + ), + ), + ), + + ); + $this->assertEquals($compare,$conditions); + + } + + function testComplexIf() { + + $serverVars = array( + 'HTTP_IF' => '<http://www.example.org/node1> (<opaquelocktoken:token1> [etag1]) ' . + '(Not <opaquelocktoken:token2>) ([etag2]) <http://www.example.org/node2> ' . + '(<opaquelocktoken:token3>) (Not <opaquelocktoken:token4>) ([etag3])', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + + $conditions = $this->locksPlugin->getIfConditions(); + + $compare = array( + + array( + 'uri' => 'http://www.example.org/node1', + 'tokens' => array( + array( + 1, + 'opaquelocktoken:token1', + 'etag1', + ), + array( + 0, + 'opaquelocktoken:token2', + '', + ), + array( + 1, + '', + 'etag2', + ), + ), + ), + array( + 'uri' => 'http://www.example.org/node2', + 'tokens' => array( + array( + 1, + 'opaquelocktoken:token3', + '', + ), + array( + 0, + 'opaquelocktoken:token4', + '', + ), + array( + 1, + '', + 'etag3', + ), + ), + ), + + ); + $this->assertEquals($compare,$conditions); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php new file mode 100644 index 000000000..b3d7d447b --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php @@ -0,0 +1,123 @@ +<?php + +namespace Sabre\DAV\Locks; + +use Sabre\HTTP; +use Sabre\DAV; + +require_once 'Sabre/HTTP/ResponseMock.php'; +require_once 'Sabre/TestUtil.php'; + +class MSWordTest extends \PHPUnit_Framework_TestCase { + + function testLockEtc() { + + mkdir(SABRE_TEMPDIR . '/mstest'); + $tree = new DAV\FS\Directory(SABRE_TEMPDIR . '/mstest'); + + $server = new DAV\Server($tree); + $server->debugExceptions = true; + $locksBackend = new Backend\File(SABRE_TEMPDIR . '/locksdb'); + $locksPlugin = new Plugin($locksBackend); + $server->addPlugin($locksPlugin); + + $response1 = new HTTP\ResponseMock(); + + $server->httpRequest = $this->getLockRequest(); + $server->httpResponse = $response1; + $server->exec(); + + $this->assertEquals('HTTP/1.1 201 Created', $server->httpResponse->status); + $this->assertTrue(isset($server->httpResponse->headers['Lock-Token'])); + $lockToken = $server->httpResponse->headers['Lock-Token']; + + //sleep(10); + + $response2 = new HTTP\ResponseMock(); + + $server->httpRequest = $this->getLockRequest2(); + $server->httpResponse = $response2; + $server->exec(); + + $this->assertEquals('HTTP/1.1 201 Created', $server->httpResponse->status); + $this->assertTrue(isset($server->httpResponse->headers['Lock-Token'])); + + //sleep(10); + + $response3 = new HTTP\ResponseMock(); + $server->httpRequest = $this->getPutRequest($lockToken); + $server->httpResponse = $response3; + $server->exec(); + + $this->assertEquals('HTTP/1.1 204 No Content', $server->httpResponse->status); + + } + + function tearDown() { + + \Sabre\TestUtil::clearTempDir(); + + } + + function getLockRequest() { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'LOCK', + 'HTTP_CONTENT_TYPE' => 'application/xml', + 'HTTP_TIMEOUT' => 'Second-3600', + 'REQUEST_URI' => '/Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx', + )); + + $request->setBody('<D:lockinfo xmlns:D="DAV:"> + <D:lockscope> + <D:exclusive /> + </D:lockscope> + <D:locktype> + <D:write /> + </D:locktype> + <D:owner> + <D:href>PC-Vista\User</D:href> + </D:owner> +</D:lockinfo>'); + + return $request; + + } + function getLockRequest2() { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'LOCK', + 'HTTP_CONTENT_TYPE' => 'application/xml', + 'HTTP_TIMEOUT' => 'Second-3600', + 'REQUEST_URI' => '/~$Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx', + )); + + $request->setBody('<D:lockinfo xmlns:D="DAV:"> + <D:lockscope> + <D:exclusive /> + </D:lockscope> + <D:locktype> + <D:write /> + </D:locktype> + <D:owner> + <D:href>PC-Vista\User</D:href> + </D:owner> +</D:lockinfo>'); + + return $request; + + } + + function getPutRequest($lockToken) { + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PUT', + 'REQUEST_URI' => '/Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx', + 'HTTP_IF' => 'If: ('.$lockToken.')', + )); + $request->setBody('FAKE BODY'); + return $request; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php new file mode 100644 index 000000000..a45dafdf1 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php @@ -0,0 +1,966 @@ +<?php + +namespace Sabre\DAV\Locks; + +use Sabre\HTTP; +use Sabre\DAV; + +require_once 'Sabre/DAV/AbstractServer.php'; + +class PluginTest extends DAV\AbstractServer { + + /** + * @var Sabre\DAV\Locks\Plugin + */ + protected $locksPlugin; + + function setUp() { + + parent::setUp(); + $locksBackend = new Backend\File(SABRE_TEMPDIR . '/locksdb'); + $locksPlugin = new Plugin($locksBackend); + $this->server->addPlugin($locksPlugin); + $this->locksPlugin = $locksPlugin; + + } + + function testGetFeatures() { + + $this->assertEquals(array(2),$this->locksPlugin->getFeatures()); + + } + + function testGetHTTPMethods() { + + $this->assertEquals(array('LOCK','UNLOCK'),$this->locksPlugin->getHTTPMethods('')); + + } + + function testGetHTTPMethodsNoBackend() { + + $locksPlugin = new Plugin(); + $this->server->addPlugin($locksPlugin); + $this->assertEquals(array(),$locksPlugin->getHTTPMethods('')); + + } + + function testUnknownMethodPassthough() { + + $this->assertNull($this->locksPlugin->unknownMethod('BLA','/')); + + } + + function testLockNoBody() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody(''); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status); + + } + + function testLock() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status,'Got an incorrect status back. Response body: ' . $this->response->body); + + $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); + $xml = simplexml_load_string($body); + $xml->registerXPathNamespace('d','urn:DAV'); + + $elements = array( + '/d:prop', + '/d:prop/d:lockdiscovery', + '/d:prop/d:lockdiscovery/d:activelock', + '/d:prop/d:lockdiscovery/d:activelock/d:locktype', + '/d:prop/d:lockdiscovery/d:activelock/d:lockroot', + '/d:prop/d:lockdiscovery/d:activelock/d:lockroot/d:href', + '/d:prop/d:lockdiscovery/d:activelock/d:locktype/d:write', + '/d:prop/d:lockdiscovery/d:activelock/d:lockscope', + '/d:prop/d:lockdiscovery/d:activelock/d:lockscope/d:exclusive', + '/d:prop/d:lockdiscovery/d:activelock/d:depth', + '/d:prop/d:lockdiscovery/d:activelock/d:owner', + '/d:prop/d:lockdiscovery/d:activelock/d:timeout', + '/d:prop/d:lockdiscovery/d:activelock/d:locktoken', + '/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href', + ); + + foreach($elements as $elem) { + $data = $xml->xpath($elem); + $this->assertEquals(1,count($data),'We expected 1 match for the xpath expression "' . $elem . '". ' . count($data) . ' were found. Full response body: ' . $this->response->body); + } + + $depth = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:depth'); + $this->assertEquals('infinity',(string)$depth[0]); + + $token = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href'); + $this->assertEquals($this->response->headers['Lock-Token'],'<' . (string)$token[0] . '>','Token in response body didn\'t match token in response header.'); + + } + + /** + * @depends testLock + */ + function testDoubleLock() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->response = new HTTP\ResponseMock(); + $this->server->httpResponse = $this->response; + + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status); + + } + + /** + * @depends testLock + */ + function testLockRefresh() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $lockToken = $this->response->headers['Lock-Token']; + + $this->response = new HTTP\ResponseMock(); + $this->server->httpResponse = $this->response; + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + 'HTTP_IF' => '(' . $lockToken . ')', + ); + $request = new HTTP\Request($serverVars); + $request->setBody(''); + $this->server->httpRequest = $request; + + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status,'We received an incorrect status code. Full response body: ' . $this->response->body); + + } + + /** + * @depends testLock + */ + function testLockNoFile() { + + $serverVars = array( + 'REQUEST_URI' => '/notfound.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + + } + + /** + * @depends testLock + */ + function testUnlockNoToken() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'UNLOCK', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status); + + } + + /** + * @depends testLock + */ + function testUnlockBadToken() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'UNLOCK', + 'HTTP_LOCK_TOKEN' => '<opaquelocktoken:blablabla>', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status,'Got an incorrect status code. Full response body: ' . $this->response->body); + + } + + /** + * @depends testLock + */ + function testLockPutNoToken() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('newbody'); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status); + + } + + /** + * @depends testLock + */ + function testUnlock() { + + $request = new HTTP\Request(array()); + $this->server->httpRequest = $request; + + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->invokeMethod('LOCK','test.txt'); + $lockToken = $this->server->httpResponse->headers['Lock-Token']; + + $serverVars = array( + 'HTTP_LOCK_TOKEN' => $lockToken, + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->httpResponse = new HTTP\ResponseMock(); + $this->server->invokeMethod('UNLOCK', 'test.txt'); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->server->httpResponse->status,'Got an incorrect status code. Full response body: ' . $this->response->body); + $this->assertEquals(array( + 'Content-Length' => '0', + ), + $this->server->httpResponse->headers + ); + + + } + + /** + * @depends testLock + */ + function testUnlockWindowsBug() { + + $request = new HTTP\Request(array()); + $this->server->httpRequest = $request; + + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->invokeMethod('LOCK','test.txt'); + $lockToken = $this->server->httpResponse->headers['Lock-Token']; + + // See Issue 123 + $lockToken = trim($lockToken,'<>'); + + $serverVars = array( + 'HTTP_LOCK_TOKEN' => $lockToken, + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->httpResponse = new HTTP\ResponseMock(); + $this->server->invokeMethod('UNLOCK', 'test.txt'); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->server->httpResponse->status,'Got an incorrect status code. Full response body: ' . $this->response->body); + $this->assertEquals(array( + 'Content-Length' => '0', + ), + $this->server->httpResponse->headers + ); + + + } + + /** + * @depends testLock + */ + function testLockRetainOwner() { + + $request = new HTTP\Request(array()); + $this->server->httpRequest = $request; + + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner>Evert</D:owner> +</D:lockinfo>'); + + $this->server->invokeMethod('LOCK','test.txt'); + $lockToken = $this->server->httpResponse->headers['Lock-Token']; + + $locks = $this->locksPlugin->getLocks('test.txt'); + $this->assertEquals(1,count($locks)); + $this->assertEquals('Evert',$locks[0]->owner); + + + } + + /** + * @depends testLock + */ + function testLockPutBadToken() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_IF' => '(<opaquelocktoken:token1>)', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('newbody'); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status); + + } + + /** + * @depends testLock + */ + function testLockDeleteParent() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir', + 'REQUEST_METHOD' => 'DELETE', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + /** + * @depends testLock + */ + function testLockDeleteSucceed() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'DELETE', + 'HTTP_IF' => '(' . $this->response->headers['Lock-Token'] . ')', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + + /** + * @depends testLock + */ + function testLockCopyLockSource() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'COPY', + 'HTTP_DESTINATION' => '/dir/child2.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'Copy must succeed if only the source is locked, but not the destination'); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + /** + * @depends testLock + */ + function testLockCopyLockDestination() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child2.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'COPY', + 'HTTP_DESTINATION' => '/dir/child2.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status,'Copy must succeed if only the source is locked, but not the destination'); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + + /** + * @depends testLock + */ + function testLockMoveLockSourceLocked() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'MOVE', + 'HTTP_DESTINATION' => '/dir/child2.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status,'Copy must succeed if only the source is locked, but not the destination'); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + + /** + * @depends testLock + */ + function testLockMoveLockSourceSucceed() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'MOVE', + 'HTTP_DESTINATION' => '/dir/child2.txt', + 'HTTP_IF' => '(' . $this->response->headers['Lock-Token'] . ')', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'A valid lock-token was provided for the source, so this MOVE operation must succeed. Full response body: ' . $this->response->body); + + } + + /** + * @depends testLock + */ + function testLockMoveLockDestination() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child2.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'MOVE', + 'HTTP_DESTINATION' => '/dir/child2.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status,'Copy must succeed if only the source is locked, but not the destination'); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + /** + * @depends testLock + */ + function testLockMoveLockParent() { + + $serverVars = array( + 'REQUEST_URI' => '/dir', + 'REQUEST_METHOD' => 'LOCK', + 'HTTP_DEPTH' => 'infinite', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'MOVE', + 'HTTP_DESTINATION' => '/dir/child2.txt', + 'HTTP_IF' => '</dir> (' . $this->response->headers['Lock-Token'] . ')', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'We locked the parent of both the source and destination, but the move didn\'t succeed.'); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + + /** + * @depends testLock + */ + function testLockPutGoodToken() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_IF' => '('.$this->response->headers['Lock-Token'].')', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('newbody'); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status); + + } + + function testPutWithIncorrectETag() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_IF' => '(["etag1"])', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('newbody'); + $this->server->httpRequest = $request; + $this->server->exec(); + $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status); + + } + + /** + * @depends testPutWithIncorrectETag + */ + function testPutWithCorrectETag() { + + // We need an etag-enabled file node. + $tree = new DAV\ObjectTree(new DAV\FSExt\Directory(SABRE_TEMPDIR)); + $this->server->tree = $tree; + + $etag = md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')); + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_IF' => '(["'.$etag.'"])', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('newbody'); + $this->server->httpRequest = $request; + $this->server->exec(); + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status, 'Incorrect status received. Full response body:' . $this->response->body); + + } + + function testGetTimeoutHeader() { + + $request = new HTTP\Request(array( + 'HTTP_TIMEOUT' => 'second-100', + )); + + $this->server->httpRequest = $request; + $this->assertEquals(100, $this->locksPlugin->getTimeoutHeader()); + + } + + + function testGetTimeoutHeaderNotSet() { + + $request = new HTTP\Request(array( + )); + + $this->server->httpRequest = $request; + $this->assertEquals(0, $this->locksPlugin->getTimeoutHeader()); + + } + + + function testGetTimeoutHeaderInfinite() { + + $request = new HTTP\Request(array( + 'HTTP_TIMEOUT' => 'infinite', + )); + + $this->server->httpRequest = $request; + $this->assertEquals(LockInfo::TIMEOUT_INFINITE, $this->locksPlugin->getTimeoutHeader()); + + } + + /** + * @expectedException Sabre\DAV\Exception\BadRequest + */ + function testGetTimeoutHeaderInvalid() { + + $request = new HTTP\Request(array( + 'HTTP_TIMEOUT' => 'yourmom', + )); + + $this->server->httpRequest = $request; + $this->locksPlugin->getTimeoutHeader(); + + } + + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php new file mode 100644 index 000000000..e818fe043 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php @@ -0,0 +1,58 @@ +<?php + +namespace Sabre\DAV\Mount; + +use Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/DAV/AbstractServer.php'; + +class PluginTest extends DAV\AbstractServer { + + function setUp() { + + parent::setUp(); + $this->server->addPlugin(new Plugin()); + + } + + function testPassThrough() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'GET', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 501 Not Implemented',$this->response->status,'We expected GET to not be implemented for Directories. Response body: ' . $this->response->body); + + } + + function testMountResponse() { + + $serverVars = array( + 'REQUEST_URI' => '/?mount', + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'mount', + 'HTTP_HOST' => 'example.org', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $xml = simplexml_load_string($this->response->body); + $this->assertTrue($xml==true,'Response was not a valid xml document'); + + $xml->registerXPathNamespace('dm','http://purl.org/NET/webdav/mount'); + $url = $xml->xpath('//dm:url'); + $this->assertEquals('http://example.org/',(string)$url[0]); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php new file mode 100644 index 000000000..330058b6d --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php @@ -0,0 +1,100 @@ +<?php + +namespace Sabre\DAV; + +require_once 'Sabre/TestUtil.php'; + +class ObjectTreeTest extends \PHPUnit_Framework_TestCase { + + protected $tree; + + function setup() { + + \Sabre\TestUtil::clearTempDir(); + mkdir(SABRE_TEMPDIR . '/root'); + mkdir(SABRE_TEMPDIR . '/root/subdir'); + file_put_contents(SABRE_TEMPDIR . '/root/file.txt','contents'); + file_put_contents(SABRE_TEMPDIR . '/root/subdir/subfile.txt','subcontents'); + $rootNode = new FSExt\Directory(SABRE_TEMPDIR . '/root'); + $this->tree = new ObjectTree($rootNode); + + } + + function teardown() { + + \Sabre\TestUtil::clearTempDir(); + + } + + function testGetRootNode() { + + $root = $this->tree->getNodeForPath(''); + $this->assertInstanceOf('Sabre\\DAV\\FSExt\\Directory',$root); + + } + + function testGetSubDir() { + + $root = $this->tree->getNodeForPath('subdir'); + $this->assertInstanceOf('Sabre\\DAV\\FSExt\\Directory',$root); + + } + + function testCopyFile() { + + $this->tree->copy('file.txt','file2.txt'); + $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/file2.txt')); + $this->assertEquals('contents',file_get_contents(SABRE_TEMPDIR.'/root/file2.txt')); + + } + + /** + * @depends testCopyFile + */ + function testCopyDirectory() { + + $this->tree->copy('subdir','subdir2'); + $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2')); + $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2/subfile.txt')); + $this->assertEquals('subcontents',file_get_contents(SABRE_TEMPDIR.'/root/subdir2/subfile.txt')); + + } + + /** + * @depends testCopyFile + */ + function testMoveFile() { + + $this->tree->move('file.txt','file2.txt'); + $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/file2.txt')); + $this->assertFalse(file_exists(SABRE_TEMPDIR.'/root/file.txt')); + $this->assertEquals('contents',file_get_contents(SABRE_TEMPDIR.'/root/file2.txt')); + + } + + /** + * @depends testMoveFile + */ + function testMoveFileNewParent() { + + $this->tree->move('file.txt','subdir/file2.txt'); + $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir/file2.txt')); + $this->assertFalse(file_exists(SABRE_TEMPDIR.'/root/file.txt')); + $this->assertEquals('contents',file_get_contents(SABRE_TEMPDIR.'/root/subdir/file2.txt')); + + } + + /** + * @depends testCopyDirectory + */ + function testMoveDirectory() { + + $this->tree->move('subdir','subdir2'); + $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2')); + $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2/subfile.txt')); + $this->assertFalse(file_exists(SABRE_TEMPDIR.'/root/subdir')); + $this->assertEquals('subcontents',file_get_contents(SABRE_TEMPDIR.'/root/subdir2/subfile.txt')); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php new file mode 100644 index 000000000..e8cdc1666 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php @@ -0,0 +1,79 @@ +<?php + +namespace Sabre\DAV\PartialUpdate; +use Sabre\DAV; + +class FileMock implements IFile { + + protected $data = ''; + + function put($str) { + + if (is_resource($str)) { + $str = stream_get_contents($str); + } + $this->data = $str; + + } + + function putRange($str,$start) { + + if (is_resource($str)) { + $str = stream_get_contents($str); + } + $this->data = substr($this->data, 0, $start) . $str . substr($this->data, $start + strlen($str)); + + + + } + + function get() { + + return $this->data; + + } + + function getContentType() { + + return 'text/plain'; + + } + + function getSize() { + + return strlen($this->data); + + } + + function getETag() { + + return '"' . $this->data . '"'; + + } + + function delete() { + + throw new DAV\Exception\MethodNotAllowed(); + + } + + function setName($name) { + + throw new DAV\Exception\MethodNotAllowed(); + + } + + function getName() { + + return 'partial'; + + } + + function getLastModified() { + + return null; + + } + + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/PluginTest.php new file mode 100644 index 000000000..7b90429d4 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/PluginTest.php @@ -0,0 +1,130 @@ +<?php + +namespace Sabre\DAV\PartialUpdate; + +use Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/DAV/PartialUpdate/FileMock.php'; + +class PluginTest extends \Sabre\DAVServerTest { + + protected $node; + protected $plugin; + + public function setUp() { + + $this->node = new FileMock(); + $this->tree[] = $this->node; + + parent::setUp(); + + $this->plugin = new Plugin(); + $this->server->addPlugin($this->plugin); + + + + } + + public function testInit() { + + $this->assertEquals('partialupdate', $this->plugin->getPluginName()); + $this->assertEquals(array('sabredav-partialupdate'), $this->plugin->getFeatures()); + $this->assertEquals(array( + 'PATCH' + ), $this->plugin->getHTTPMethods('partial')); + $this->assertEquals(array( + ), $this->plugin->getHTTPMethods('')); + + $this->assertNull($this->plugin->unknownMethod('FOO','partial')); + + } + + public function testPatchNoRange() { + + $this->node->put('00000000'); + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PATCH', + 'REQUEST_URI' => '/partial', + )); + $response = $this->request($request); + + $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, 'Full response body:' . $response->body); + + } + + public function testPatchNotSupported() { + + $this->node->put('00000000'); + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PATCH', + 'REQUEST_URI' => '/', + 'X_UPDATE_RANGE' => '3-4', + + )); + $request->setBody( + '111' + ); + $response = $this->request($request); + + $this->assertEquals('HTTP/1.1 405 Method Not Allowed', $response->status, 'Full response body:' . $response->body); + + } + + public function testPatchNoContentType() { + + $this->node->put('00000000'); + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PATCH', + 'REQUEST_URI' => '/partial', + 'HTTP_X_UPDATE_RANGE' => 'bytes=3-4', + + )); + $request->setBody( + '111' + ); + $response = $this->request($request); + + $this->assertEquals('HTTP/1.1 415 Unsupported Media Type', $response->status, 'Full response body:' . $response->body); + + } + + public function testPatchBadRange() { + + $this->node->put('00000000'); + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PATCH', + 'REQUEST_URI' => '/partial', + 'HTTP_X_UPDATE_RANGE' => 'bytes=3-4', + 'HTTP_CONTENT_TYPE' => 'application/x-sabredav-partialupdate', + )); + $request->setBody( + '111' + ); + $response = $this->request($request); + + $this->assertEquals('HTTP/1.1 416 Requested Range Not Satisfiable', $response->status, 'Full response body:' . $response->body); + + } + + public function testPatchSuccess() { + + $this->node->put('00000000'); + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PATCH', + 'REQUEST_URI' => '/partial', + 'HTTP_X_UPDATE_RANGE' => 'bytes=3-5', + 'HTTP_CONTENT_TYPE' => 'application/x-sabredav-partialupdate', + 'HTTP_CONTENT_LENGTH' => 3, + )); + $request->setBody( + '111' + ); + $response = $this->request($request); + + $this->assertEquals('HTTP/1.1 204 No Content', $response->status, 'Full response body:' . $response->body); + $this->assertEquals('00111000', $this->node->get()); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/GetLastModifiedTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/GetLastModifiedTest.php new file mode 100644 index 000000000..de8ca1283 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/GetLastModifiedTest.php @@ -0,0 +1,75 @@ +<?php + +namespace Sabre\DAV\Property; + +use Sabre\DAV; +use Sabre\HTTP; + +class GetLastModifiedTest extends \PHPUnit_Framework_TestCase { + + function testConstructDateTime() { + + $dt = new \DateTime('2010-03-14 16:35', new \DateTimeZone('UTC')); + $lastMod = new GetLastModified($dt); + $this->assertEquals($dt->format(\DateTime::ATOM), $lastMod->getTime()->format(\DateTime::ATOM)); + + } + + function testConstructString() { + + $dt = new \DateTime('2010-03-14 16:35', new \DateTimeZone('UTC')); + $lastMod = new GetLastModified('2010-03-14 16:35'); + $this->assertEquals($dt->format(\DateTime::ATOM), $lastMod->getTime()->format(\DateTime::ATOM)); + + } + + function testConstructInt() { + + $dt = new \DateTime('2010-03-14 16:35', new \DateTimeZone('UTC')); + $lastMod = new GetLastModified((int)$dt->format('U')); + $this->assertEquals($dt->format(\DateTime::ATOM), $lastMod->getTime()->format(\DateTime::ATOM)); + + } + + function testSerialize() { + + $dt = new \DateTime('2010-03-14 16:35', new \DateTimeZone('UTC')); + $lastMod = new GetLastModified($dt); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:getlastmodified'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $server = new DAV\Server(); + + $lastMod->serialize($server, $root); + + $xml = $doc->saveXML(); + + /* + $this->assertEquals( +'<?xml version="1.0"?> +<d:getlastmodified xmlns:d="DAV:" xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">' . +HTTP\Util::toHTTPDate($dt) . +'</d:getlastmodified> +', $xml); + */ + $this->assertEquals( +'<?xml version="1.0"?> +<d:getlastmodified xmlns:d="DAV:">' . +HTTP\Util::toHTTPDate($dt) . +'</d:getlastmodified> +', $xml); + + $ok = false; + try { + GetLastModified::unserialize(DAV\XMLUtil::loadDOMDocument($xml)->firstChild); + } catch (DAV\Exception $e) { + $ok = true; + } + if (!$ok) $this->markTestFailed('Unserialize should not be supported'); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/HrefListTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/HrefListTest.php new file mode 100644 index 000000000..fe2bc81f9 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/HrefListTest.php @@ -0,0 +1,91 @@ +<?php + +namespace Sabre\DAV\Property; +use Sabre\DAV; + +class HrefListTest extends \PHPUnit_Framework_TestCase { + + function testConstruct() { + + $href = new HrefList(array('foo','bar')); + $this->assertEquals(array('foo','bar'),$href->getHrefs()); + + } + + function testSerialize() { + + $href = new HrefList(array('foo','bar')); + $this->assertEquals(array('foo','bar'),$href->getHrefs()); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:anything'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $server = new DAV\Server(); + $server->setBaseUri('/bla/'); + + $href->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<d:anything xmlns:d="DAV:"><d:href>/bla/foo</d:href><d:href>/bla/bar</d:href></d:anything> +', $xml); + + } + + function testSerializeNoPrefix() { + + $href = new HrefList(array('foo','bar'), false); + $this->assertEquals(array('foo','bar'),$href->getHrefs()); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:anything'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $server = new DAV\Server(); + $server->setBaseUri('/bla/'); + + $href->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<d:anything xmlns:d="DAV:"><d:href>foo</d:href><d:href>bar</d:href></d:anything> +', $xml); + + } + + function testUnserialize() { + + $xml = '<?xml version="1.0"?> +<d:anything xmlns:d="urn:DAV"><d:href>/bla/foo</d:href><d:href>/bla/bar</d:href></d:anything> +'; + + $dom = new \DOMDocument(); + $dom->loadXML($xml); + + $href = HrefList::unserialize($dom->firstChild); + $this->assertEquals(array('/bla/foo','/bla/bar'),$href->getHrefs()); + + } + + function testUnserializeIncompatible() { + + $xml = '<?xml version="1.0"?> +<d:anything xmlns:d="urn:DAV"><d:href2>/bla/foo</d:href2></d:anything> +'; + + $dom = new \DOMDocument(); + $dom->loadXML($xml); + + $href = HrefList::unserialize($dom->firstChild); + $this->assertEquals(array(), $href->getHrefs()); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/HrefTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/HrefTest.php new file mode 100644 index 000000000..e5607f51b --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/HrefTest.php @@ -0,0 +1,119 @@ +<?php + +namespace Sabre\DAV\Property; + +use Sabre\DAV; + +class HrefTest extends \PHPUnit_Framework_TestCase { + + function testConstruct() { + + $href = new Href('path'); + $this->assertEquals('path',$href->getHref()); + + } + + function testSerialize() { + + $href = new Href('path'); + $this->assertEquals('path',$href->getHref()); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:anything'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $server = new DAV\Server(); + $server->setBaseUri('/bla/'); + + $href->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<d:anything xmlns:d="DAV:"><d:href>/bla/path</d:href></d:anything> +', $xml); + + } + + function testSerializeNoPrefix() { + + $href = new Href('path',false); + $this->assertEquals('path',$href->getHref()); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:anything'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $server = new DAV\Server(); + $server->setBaseUri('/bla/'); + + $href->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<d:anything xmlns:d="DAV:"><d:href>path</d:href></d:anything> +', $xml); + + } + + function testUnserialize() { + + $xml = '<?xml version="1.0"?> +<d:anything xmlns:d="urn:DAV"><d:href>/bla/path</d:href></d:anything> +'; + + $dom = new \DOMDocument(); + $dom->loadXML($xml); + + $href = Href::unserialize($dom->firstChild); + $this->assertEquals('/bla/path',$href->getHref()); + + } + + function testUnserializeIncompatible() { + + $xml = '<?xml version="1.0"?> +<d:anything xmlns:d="urn:DAV"><d:href2>/bla/path</d:href2></d:anything> +'; + + $dom = new \DOMDocument(); + $dom->loadXML($xml); + + $href = Href::unserialize($dom->firstChild); + $this->assertNull($href); + + } + + /** + * This method tests if hrefs containing & are correctly encoded. + */ + function testSerializeEntity() { + + $href = new Href('http://example.org/?a&b', false); + $this->assertEquals('http://example.org/?a&b',$href->getHref()); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:anything'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $server = new DAV\Server(); + $server->setBaseUri('/bla/'); + + $href->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<d:anything xmlns:d="DAV:"><d:href>http://example.org/?a&b</d:href></d:anything> +', $xml); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/ResourceTypeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/ResourceTypeTest.php new file mode 100644 index 000000000..8a579baec --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/ResourceTypeTest.php @@ -0,0 +1,111 @@ +<?php + +namespace Sabre\DAV\Property; + +use Sabre\DAV; + +class ResourceTypeTest extends \PHPUnit_Framework_TestCase { + + function testConstruct() { + + $resourceType = new ResourceType(array('{DAV:}collection')); + $this->assertEquals(array('{DAV:}collection'),$resourceType->getValue()); + + $resourceType = new ResourceType(DAV\Server::NODE_FILE); + $this->assertEquals(array(),$resourceType->getValue()); + + $resourceType = new ResourceType(DAV\Server::NODE_DIRECTORY); + $this->assertEquals(array('{DAV:}collection'),$resourceType->getValue()); + + $resourceType = new ResourceType('{DAV:}principal'); + $this->assertEquals(array('{DAV:}principal'),$resourceType->getValue()); + + } + + /** + * @depends testConstruct + */ + function testSerialize() { + + $resourceType = new ResourceType(array('{DAV:}collection','{DAV:}principal')); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:anything'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $server = new DAV\Server(); + $resourceType->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<d:anything xmlns:d="DAV:"><d:collection/><d:principal/></d:anything> +', $xml); + + } + + /** + * @depends testSerialize + */ + function testSerializeCustomNS() { + + $resourceType = new ResourceType(array('{http://example.org/NS}article')); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:anything'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $server = new DAV\Server(); + $resourceType->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<d:anything xmlns:d="DAV:"><custom:article xmlns:custom="http://example.org/NS"/></d:anything> +', $xml); + + } + + /** + * @depends testConstruct + */ + function testIs() { + + $resourceType = new ResourceType(array('{DAV:}collection','{DAV:}principal')); + $this->assertTrue($resourceType->is('{DAV:}collection')); + $this->assertFalse($resourceType->is('{DAV:}blabla')); + + } + + /** + * @depends testConstruct + */ + function testAdd() { + + $resourceType = new ResourceType(array('{DAV:}collection','{DAV:}principal')); + $resourceType->add('{DAV:}foo'); + $this->assertEquals(array('{DAV:}collection','{DAV:}principal','{DAV:}foo'), $resourceType->getValue()); + + } + + /** + * @depends testConstruct + */ + function testUnserialize() { + + $xml ='<?xml version="1.0"?> +<d:anything xmlns:d="DAV:"><d:collection/><d:principal/></d:anything> +'; + + $dom = DAV\XMLUtil::loadDOMDocument($xml); + + $resourceType = ResourceType::unserialize($dom->firstChild); + $this->assertEquals(array('{DAV:}collection','{DAV:}principal'),$resourceType->getValue()); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseListTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseListTest.php new file mode 100644 index 000000000..d13066b80 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseListTest.php @@ -0,0 +1,19 @@ +<?php + +namespace Sabre\DAV\Property; + +class ResponseListTest extends \PHPUnit_Framework_TestCase { + + /** + * This was the only part not yet covered by other tests, so I'm going to + * be lazy and (for now) only test this case. + * + * @expectedException InvalidArgumentException + */ + public function testInvalidArg() { + + $response = new ResponseList(array(1,2)); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseTest.php new file mode 100644 index 000000000..073cbb2ce --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseTest.php @@ -0,0 +1,230 @@ +<?php + +namespace Sabre\DAV\Property; + +use Sabre\DAV; + +class ResponseTest extends \PHPUnit_Framework_TestCase { + + function testSimple() { + + $innerProps = array( + 200 => array( + '{DAV:}displayname' => 'my file', + ), + 404 => array( + '{DAV:}owner' => null, + ) + ); + + $property = new Response('uri',$innerProps); + + $this->assertEquals('uri',$property->getHref()); + $this->assertEquals($innerProps,$property->getResponseProperties()); + + + } + + /** + * @depends testSimple + */ + function testSerialize() { + + $innerProps = array( + 200 => array( + '{DAV:}displayname' => 'my file', + ), + 404 => array( + '{DAV:}owner' => null, + ) + ); + + $property = new Response('uri',$innerProps); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:root'); + $root->setAttribute('xmlns:d','DAV:'); + + $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:">' . +'<d:response>' . +'<d:href>/uri</d:href>' . +'<d:propstat>' . +'<d:prop>' . +'<d:displayname>my file</d:displayname>' . +'</d:prop>' . +'<d:status>HTTP/1.1 200 OK</d:status>' . +'</d:propstat>' . +'<d:propstat>' . +'<d:prop>' . +'<d:owner/>' . +'</d:prop>' . +'<d:status>HTTP/1.1 404 Not Found</d:status>' . +'</d:propstat>' . +'</d:response>' . +'</d:root> +', $xml); + + } + + /** + * This one is specifically for testing properties with no namespaces, which is legal xml + * + * @depends testSerialize + */ + function testSerializeEmptyNamespace() { + + $innerProps = array( + 200 => array( + '{}propertyname' => 'value', + ), + ); + + $property = new Response('uri',$innerProps); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:root'); + $root->setAttribute('xmlns:d','DAV:'); + + $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:">' . +'<d:response>' . +'<d:href>/uri</d:href>' . +'<d:propstat>' . +'<d:prop>' . +'<propertyname xmlns="">value</propertyname>' . +'</d:prop>' . +'<d:status>HTTP/1.1 200 OK</d:status>' . +'</d:propstat>' . +'</d:response>' . +'</d:root> +', $xml); + + } + + /** + * This one is specifically for testing properties with no namespaces, which is legal xml + * + * @depends testSerialize + */ + function testSerializeCustomNamespace() { + + $innerProps = array( + 200 => array( + '{http://sabredav.org/NS/example}propertyname' => 'value', + ), + ); + + $property = new Response('uri',$innerProps); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:root'); + $root->setAttribute('xmlns:d','DAV:'); + + $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:">' . +'<d:response>' . +'<d:href>/uri</d:href>' . +'<d:propstat>' . +'<d:prop>' . +'<x2:propertyname xmlns:x2="http://sabredav.org/NS/example">value</x2:propertyname>' . +'</d:prop>' . +'<d:status>HTTP/1.1 200 OK</d:status>' . +'</d:propstat>' . +'</d:response>' . +'</d:root> +', $xml); + + } + + /** + * @depends testSerialize + */ + function testSerializeComplexProperty() { + + $innerProps = array( + 200 => array( + '{DAV:}link' => new Href('http://sabredav.org/', false) + ), + ); + + $property = new Response('uri',$innerProps); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:root'); + $root->setAttribute('xmlns:d','DAV:'); + + $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:">' . +'<d:response>' . +'<d:href>/uri</d:href>' . +'<d:propstat>' . +'<d:prop>' . +'<d:link><d:href>http://sabredav.org/</d:href></d:link>' . +'</d:prop>' . +'<d:status>HTTP/1.1 200 OK</d:status>' . +'</d:propstat>' . +'</d:response>' . +'</d:root> +', $xml); + + } + + /** + * @depends testSerialize + * @expectedException Sabre\DAV\Exception + */ + function testSerializeBreak() { + + $innerProps = array( + 200 => array( + '{DAV:}link' => new \STDClass() + ), + ); + + $property = new Response('uri',$innerProps); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:root'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $server = new DAV\Server(); + + $property->serialize($server, $root); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/SupportedReportSetTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/SupportedReportSetTest.php new file mode 100644 index 000000000..445e22ab3 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/SupportedReportSetTest.php @@ -0,0 +1,128 @@ +<?php + +namespace Sabre\DAV\Property; + +use Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; +require_once 'Sabre/DAV/AbstractServer.php'; + +class SupportedReportSetTest extends DAV\AbstractServer { + + public function sendPROPFIND($body) { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'PROPFIND', + 'HTTP_DEPTH' => '0', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($body); + + $this->server->httpRequest = ($request); + $this->server->exec(); + + } + + /** + * @covers Sabre\DAV\Property\SupportedReportSet + */ + function testNoReports() { + + $xml = '<?xml version="1.0"?> +<d:propfind xmlns:d="DAV:"> + <d:prop> + <d:supported-report-set /> + </d:prop> +</d:propfind>'; + + $this->sendPROPFIND($xml); + + $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'We expected a multi-status response. Full response body: ' . $this->response->body); + + $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); + $xml = simplexml_load_string($body); + $xml->registerXPathNamespace('d','urn:DAV'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop'); + $this->assertEquals(1,count($data),'We expected 1 \'d:prop\' element'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supported-report-set'); + $this->assertEquals(1,count($data),'We expected 1 \'d:supported-report-set\' element'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:status'); + $this->assertEquals(1,count($data),'We expected 1 \'d:status\' element'); + + $this->assertEquals('HTTP/1.1 200 OK',(string)$data[0],'The status for this property should have been 200'); + + } + + /** + * @covers Sabre\DAV\Property\SupportedReportSet + * @depends testNoReports + */ + function testCustomReport() { + + // Intercepting the report property + $this->server->subscribeEvent('afterGetProperties',array($this,'addProp')); + + $xml = '<?xml version="1.0"?> +<d:propfind xmlns:d="DAV:"> + <d:prop> + <d:supported-report-set /> + </d:prop> +</d:propfind>'; + + $this->sendPROPFIND($xml); + + $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'We expected a multi-status response. Full response body: ' . $this->response->body); + + $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); + $xml = simplexml_load_string($body); + $xml->registerXPathNamespace('d','urn:DAV'); + $xml->registerXPathNamespace('x','http://www.rooftopsolutions.nl/testnamespace'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop'); + $this->assertEquals(1,count($data),'We expected 1 \'d:prop\' element'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supported-report-set'); + $this->assertEquals(1,count($data),'We expected 1 \'d:supported-report-set\' element'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supported-report-set/d:supported-report'); + $this->assertEquals(2,count($data),'We expected 2 \'d:supported-report\' elements'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supported-report-set/d:supported-report/d:report'); + $this->assertEquals(2,count($data),'We expected 2 \'d:report\' elements'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supported-report-set/d:supported-report/d:report/x:myreport'); + $this->assertEquals(1,count($data),'We expected 1 \'x:myreport\' element. Full body: ' . $this->response->body); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supported-report-set/d:supported-report/d:report/d:anotherreport'); + $this->assertEquals(1,count($data),'We expected 1 \'d:anotherreport\' element. Full body: ' . $this->response->body); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:status'); + $this->assertEquals(1,count($data),'We expected 1 \'d:status\' element'); + + $this->assertEquals('HTTP/1.1 200 OK',(string)$data[0],'The status for this property should have been 200'); + + } + + /** + * This method is used as a callback for afterGetProperties + */ + function addProp($path, &$properties) { + + if (isset($properties[200]['{DAV:}supported-report-set'])) { + $properties[200]['{DAV:}supported-report-set']->addReport('{http://www.rooftopsolutions.nl/testnamespace}myreport'); + $properties[200]['{DAV:}supported-report-set']->addReport('{DAV:}anotherreport'); + } + + } + + + +} + +?> diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerCopyMoveTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerCopyMoveTest.php new file mode 100644 index 000000000..88e107c19 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerCopyMoveTest.php @@ -0,0 +1,268 @@ +<?php + +namespace Sabre\DAV; + +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class ServerCopyMoveTest extends \PHPUnit_Framework_TestCase { + + private $response; + /** + * @var Server + */ + private $server; + + function setUp() { + + $this->response = new HTTP\ResponseMock(); + $dir = new FS\Directory(SABRE_TEMPDIR); + $tree = new ObjectTree($dir); + $this->server = new Server($tree); + $this->server->debugExceptions = true; + $this->server->httpResponse = $this->response; + file_put_contents(SABRE_TEMPDIR . '/test.txt', 'Test contents'); + file_put_contents(SABRE_TEMPDIR . '/test2.txt', 'Test contents2'); + mkdir(SABRE_TEMPDIR . '/col'); + file_put_contents(SABRE_TEMPDIR . 'col/test.txt', 'Test contents'); + + } + + function tearDown() { + + $cleanUp = array('test.txt','testput.txt','testcol','test2.txt','test3.txt','col/test.txt','col','col2/test.txt','col2'); + foreach($cleanUp as $file) { + $tmpFile = SABRE_TEMPDIR . '/' . $file; + if (file_exists($tmpFile)) { + + if (is_dir($tmpFile)) { + rmdir($tmpFile); + } else { + unlink($tmpFile); + } + + } + } + + } + + + function testCopyOverWrite() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'COPY', + 'HTTP_DESTINATION' => '/test2.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status,'Received an incorrect HTTP status. Full body inspection: ' . $this->response->body); + $this->assertEquals(array( + 'Content-Length' => '0', + ), + $this->response->headers + ); + + $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR. '/test2.txt')); + + } + + function testCopyToSelf() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'COPY', + 'HTTP_DESTINATION' => '/test.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status,'Received an incorrect HTTP status. Full body inspection: ' . $this->response->body); + $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR. '/test.txt')); + + } + + function testMoveToSelf() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'MOVE', + 'HTTP_DESTINATION' => '/test.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status,'Received an incorrect HTTP status. Full body inspection: ' . $this->response->body); + $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR. '/test.txt')); + + } + + function testMoveOverWrite() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'MOVE', + 'HTTP_DESTINATION' => '/test2.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Length' => 0, + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status); + $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR . '/test2.txt')); + $this->assertFalse(file_exists(SABRE_TEMPDIR . '/test.txt'),'The sourcefile test.txt should no longer exist at this point'); + + } + + function testBlockedOverWrite() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'COPY', + 'HTTP_DESTINATION' => '/test2.txt', + 'HTTP_OVERWRITE' => 'F', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status); + $this->assertEquals('Test contents2',file_get_contents(SABRE_TEMPDIR . '/test2.txt')); + + + } + + function testNonExistantParent() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'COPY', + 'HTTP_DESTINATION' => '/testcol2/test2.txt', + 'HTTP_OVERWRITE' => 'F', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status); + + } + + function testRandomOverwriteHeader() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'COPY', + 'HTTP_DESTINATION' => '/testcol2/test2.txt', + 'HTTP_OVERWRITE' => 'SURE!', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status); + + } + + function testCopyDirectory() { + + $serverVars = array( + 'REQUEST_URI' => '/col', + 'REQUEST_METHOD' => 'COPY', + 'HTTP_DESTINATION' => '/col2', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Length' => '0', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR . '/col2/test.txt')); + + } + + function testSimpleCopyFile() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'COPY', + 'HTTP_DESTINATION' => '/test3.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Length' => '0', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR . '/test3.txt')); + + } + + function testSimpleCopyCollection() { + + $serverVars = array( + 'REQUEST_URI' => '/col', + 'REQUEST_METHOD' => 'COPY', + 'HTTP_DESTINATION' => '/col2', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'Incorrect status received. Full response body: ' . $this->response->body); + + $this->assertEquals(array( + 'Content-Length' => '0', + ), + $this->response->headers + ); + + + $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR . '/col2/test.txt')); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php new file mode 100644 index 000000000..2c7a074df --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php @@ -0,0 +1,76 @@ +<?php + +namespace Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/DAV/AbstractServer.php'; + +class ServerEventsTest extends AbstractServer { + + private $tempPath; + + private $exception; + + function testAfterBind() { + + $this->server->subscribeEvent('afterBind',array($this,'afterBindHandler')); + $newPath = 'afterBind'; + + $this->tempPath = ''; + $this->server->createFile($newPath,'body'); + $this->assertEquals($newPath, $this->tempPath); + + } + + function afterBindHandler($path) { + + $this->tempPath = $path; + + } + + function testBeforeBindCancel() { + + $this->server->subscribeEvent('beforeBind', array($this,'beforeBindCancelHandler')); + $this->assertFalse($this->server->createFile('bla','body')); + + // Also testing put() + $req = new HTTP\Request(array( + 'REQUEST_METHOD' => 'PUT', + 'REQUEST_URI' => '/barbar', + )); + + $this->server->httpRequest = $req; + $this->server->exec(); + + $this->assertEquals('',$this->server->httpResponse->status); + + } + + function beforeBindCancelHandler() { + + return false; + + } + + function testException() { + + $this->server->subscribeEvent('exception', array($this, 'exceptionHandler')); + + $req = new HTTP\Request(array( + 'REQUEST_METHOD' => 'GET', + 'REQUEST_URI' => '/not/exisitng', + )); + $this->server->httpRequest = $req; + $this->server->exec(); + + $this->assertInstanceOf('Sabre\\DAV\\Exception\\NotFound', $this->exception); + + } + + function exceptionHandler(Exception $exception) { + + $this->exception = $exception; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerFinderBlockTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerFinderBlockTest.php new file mode 100644 index 000000000..180f27b2a --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerFinderBlockTest.php @@ -0,0 +1,53 @@ +<?php + +namespace Sabre\DAV; + +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; +require_once 'Sabre/DAV/AbstractServer.php'; + +class ServerFinderBlockTest extends AbstractServer{ + + function testPut() { + + $serverVars = array( + 'REQUEST_URI' => '/testput.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_X_EXPECTED_ENTITY_LENGTH' => '20', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing finder'); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('', $this->response->body); + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals('0', $this->response->headers['Content-Length']); + + $this->assertEquals('Testing finder',file_get_contents(SABRE_TEMPDIR . '/testput.txt')); + + } + + function testPutFail() { + + $serverVars = array( + 'REQUEST_URI' => '/testput.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_X_EXPECTED_ENTITY_LENGTH' => '20', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody(''); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status); + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertFalse(file_exists(SABRE_TEMPDIR . '/testput.txt')); + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php new file mode 100644 index 000000000..34b084dcd --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php @@ -0,0 +1,371 @@ +<?php + +namespace Sabre\DAV; + +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; +require_once 'Sabre/DAV/AbstractServer.php'; +require_once 'Sabre/DAV/Exception.php'; + +class ServerMKCOLTest extends AbstractServer { + + function testMkcol() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'MKCOL', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody(""); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Length' => '0', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals('', $this->response->body); + $this->assertTrue(is_dir($this->tempDir . '/testcol')); + + } + + /** + * @depends testMkcol + */ + function testMKCOLUnknownBody() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'MKCOL', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody("Hello"); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 415 Unsupported Media Type',$this->response->status); + + } + + /** + * @depends testMkcol + */ + function testMKCOLBrokenXML() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'MKCOL', + 'HTTP_CONTENT_TYPE' => 'application/xml', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody("Hello"); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status); + + } + + /** + * @depends testMkcol + */ + function testMKCOLUnknownXML() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'MKCOL', + 'HTTP_CONTENT_TYPE' => 'application/xml', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?><html></html>'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 415 Unsupported Media Type',$this->response->status); + + } + + /** + * @depends testMkcol + */ + function testMKCOLNoResourceType() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'MKCOL', + 'HTTP_CONTENT_TYPE' => 'application/xml', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<mkcol xmlns="DAV:"> + <set> + <prop> + <displayname>Evert</displayname> + </prop> + </set> +</mkcol>'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body); + + } + + /** + * @depends testMKCOLNoResourceType + */ + function testMKCOLIncorrectResourceType() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'MKCOL', + 'HTTP_CONTENT_TYPE' => 'application/xml', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<mkcol xmlns="DAV:"> + <set> + <prop> + <resourcetype><blabla /></resourcetype> + </prop> + </set> +</mkcol>'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body); + + } + + /** + * @depends testMKCOLIncorrectResourceType + */ + function testMKCOLIncorrectResourceType2() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'MKCOL', + 'HTTP_CONTENT_TYPE' => 'application/xml', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<mkcol xmlns="DAV:"> + <set> + <prop> + <resourcetype><collection /><blabla /></resourcetype> + </prop> + </set> +</mkcol>'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body); + + } + + /** + * @depends testMKCOLIncorrectResourceType2 + */ + function testMKCOLSuccess() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'MKCOL', + 'HTTP_CONTENT_TYPE' => 'application/xml', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<mkcol xmlns="DAV:"> + <set> + <prop> + <resourcetype><collection /></resourcetype> + </prop> + </set> +</mkcol>'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Length' => '0', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body); + + } + + /** + * @depends testMKCOLIncorrectResourceType2 + */ + function testMKCOLWhiteSpaceResourceType() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'MKCOL', + 'HTTP_CONTENT_TYPE' => 'application/xml', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<mkcol xmlns="DAV:"> + <set> + <prop> + <resourcetype> + <collection /> + </resourcetype> + </prop> + </set> +</mkcol>'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Length' => '0', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body); + + } + + /** + * @depends testMKCOLIncorrectResourceType2 + */ + function testMKCOLNoParent() { + + $serverVars = array( + 'REQUEST_URI' => '/testnoparent/409me', + 'REQUEST_METHOD' => 'MKCOL', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody(''); + + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body); + + } + + /** + * @depends testMKCOLIncorrectResourceType2 + */ + function testMKCOLParentIsNoCollection() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt/409me', + 'REQUEST_METHOD' => 'MKCOL', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody(''); + + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body); + + } + + /** + * @depends testMKCOLIncorrectResourceType2 + */ + function testMKCOLAlreadyExists() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'MKCOL', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody(''); + + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + 'Allow' => 'OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 405 Method Not Allowed',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body); + + } + + /** + * @depends testMKCOLSuccess + * @depends testMKCOLAlreadyExists + */ + function testMKCOLAndProps() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'MKCOL', + 'HTTP_CONTENT_TYPE' => 'application/xml', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<mkcol xmlns="DAV:"> + <set> + <prop> + <resourcetype><collection /></resourcetype> + <displayname>my new collection</displayname> + </prop> + </set> +</mkcol>'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php new file mode 100644 index 000000000..8f1451b49 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php @@ -0,0 +1,98 @@ +<?php + +namespace Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/DAV/AbstractServer.php'; +require_once 'Sabre/DAV/TestPlugin.php'; + +class ServerPluginTest extends AbstractServer { + + /** + * @var Sabre\DAV\TestPlugin + */ + protected $testPlugin; + + function setUp() { + + parent::setUp(); + + $testPlugin = new TestPlugin(); + $this->server->addPlugin($testPlugin); + $this->testPlugin = $testPlugin; + + } + + /** + * @covers \Sabre\DAV\ServerPlugin + */ + function testBaseClass() { + + $p = new ServerPluginMock(); + $this->assertEquals(array(),$p->getFeatures()); + $this->assertEquals(array(),$p->getHTTPMethods('')); + + } + + function testOptions() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'OPTIONS', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'DAV' => '1, 3, extended-mkcol, drinking', + 'MS-Author-Via' => 'DAV', + 'Allow' => 'OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT, BEER, WINE', + 'Accept-Ranges' => 'bytes', + 'Content-Length' => '0', + 'X-Sabre-Version' => Version::VERSION, + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals('', $this->response->body); + $this->assertEquals('OPTIONS',$this->testPlugin->beforeMethod); + + + } + + function testGetPlugin() { + + $this->assertEquals($this->testPlugin,$this->server->getPlugin(get_class($this->testPlugin))); + + } + + function testUnknownPlugin() { + + $this->assertNull($this->server->getPlugin('SomeRandomClassName')); + + } + + function testGetSupportedReportSet() { + + $this->assertEquals(array(), $this->testPlugin->getSupportedReportSet('/')); + + } + + function testGetPlugins() { + + $this->assertEquals( + array(get_class($this->testPlugin) => $this->testPlugin), + $this->server->getPlugins() + ); + + } + + +} + +class ServerPluginMock extends ServerPlugin { + + function initialize(Server $s) { } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerPreconditionTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerPreconditionTest.php new file mode 100644 index 000000000..ea09852a7 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerPreconditionTest.php @@ -0,0 +1,395 @@ +<?php + +namespace Sabre\DAV; + +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase { + + /** + * @covers Sabre\DAV\Server::checkPreconditions + * @expectedException Sabre\DAV\Exception\PreconditionFailed + */ + function testIfMatchNoNode() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_MATCH' => '*', + 'REQUEST_URI' => '/bar' + )); + $server->httpRequest = $httpRequest; + + $server->checkPreconditions(); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + function testIfMatchHasNode() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_MATCH' => '*', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + + $this->assertTrue($server->checkPreconditions()); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + * @expectedException Sabre\DAV\Exception\PreconditionFailed + */ + function testIfMatchWrongEtag() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_MATCH' => '1234', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + + $server->checkPreconditions(); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + function testIfMatchCorrectEtag() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_MATCH' => '"abc123"', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + + $this->assertTrue($server->checkPreconditions()); + + } + + /** + * Evolution sometimes uses \" instead of " for If-Match headers. + * + * @covers \Sabre\DAV\Server::checkPreconditions + * @depends testIfMatchCorrectEtag + */ + function testIfMatchEvolutionEtag() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_MATCH' => '\\"abc123\\"', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + + $this->assertTrue($server->checkPreconditions()); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + function testIfMatchMultiple() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_MATCH' => '"hellothere", "abc123"', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + + $this->assertTrue($server->checkPreconditions()); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + function testIfNoneMatchNoNode() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_NONE_MATCH' => '*', + 'REQUEST_URI' => '/bar' + )); + $server->httpRequest = $httpRequest; + + $this->assertTrue($server->checkPreconditions()); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + * @expectedException Sabre\DAV\Exception\PreconditionFailed + */ + function testIfNoneMatchHasNode() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_NONE_MATCH' => '*', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + + $server->checkPreconditions(); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + function testIfNoneMatchWrongEtag() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_NONE_MATCH' => '"1234"', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + + $this->assertTrue($server->checkPreconditions()); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + function testIfNoneMatchWrongEtagMultiple() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_NONE_MATCH' => '"1234", "5678"', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + + $this->assertTrue($server->checkPreconditions()); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + * @expectedException Sabre\DAV\Exception\PreconditionFailed + */ + public function testIfNoneMatchCorrectEtag() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_NONE_MATCH' => '"abc123"', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + + $server->checkPreconditions(); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + * @expectedException Sabre\DAV\Exception\PreconditionFailed + */ + public function testIfNoneMatchCorrectEtagMultiple() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_NONE_MATCH' => '"1234", "abc123"', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + + $server->checkPreconditions(); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + public function testIfNoneMatchCorrectEtagAsGet() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_NONE_MATCH' => '"abc123"', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + $server->httpResponse = new HTTP\ResponseMock(); + + $this->assertFalse($server->checkPreconditions(true)); + $this->assertEquals('HTTP/1.1 304 Not Modified',$server->httpResponse->status); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + public function testIfModifiedSinceUnModified() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_MODIFIED_SINCE' => 'Sun, 06 Nov 1994 08:49:37 GMT', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + $server->httpResponse = new HTTP\ResponseMock(); + $this->assertFalse($server->checkPreconditions()); + + $this->assertEquals('HTTP/1.1 304 Not Modified',$server->httpResponse->status); + $this->assertEquals(array( + 'Last-Modified' => 'Sat, 06 Apr 1985 23:30:00 GMT', + ), $server->httpResponse->headers); + + } + + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + public function testIfModifiedSinceModified() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_MODIFIED_SINCE' => 'Tue, 06 Nov 1984 08:49:37 GMT', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + $server->httpResponse = new HTTP\ResponseMock(); + $this->assertTrue($server->checkPreconditions()); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + public function testIfModifiedSinceInvalidDate() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_MODIFIED_SINCE' => 'Your mother', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + $server->httpResponse = new HTTP\ResponseMock(); + + // Invalid dates must be ignored, so this should return true + $this->assertTrue($server->checkPreconditions()); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + public function testIfModifiedSinceInvalidDate2() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_MODIFIED_SINCE' => 'Sun, 06 Nov 1994 08:49:37 EST', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + $server->httpResponse = new HTTP\ResponseMock(); + $this->assertTrue($server->checkPreconditions()); + + } + + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + public function testIfUnmodifiedSinceUnModified() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_UNMODIFIED_SINCE' => 'Sun, 06 Nov 1994 08:49:37 GMT', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + $this->assertTrue($server->checkPreconditions()); + + } + + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + * @expectedException Sabre\DAV\Exception\PreconditionFailed + */ + public function testIfUnmodifiedSinceModified() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_UNMODIFIED_SINCE' => 'Tue, 06 Nov 1984 08:49:37 GMT', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + $server->httpResponse = new HTTP\ResponseMock(); + $server->checkPreconditions(); + + } + + /** + * @covers \Sabre\DAV\Server::checkPreconditions + */ + public function testIfUnmodifiedSinceInvalidDate() { + + $root = new SimpleCollection('root',array(new ServerPreconditionsNode())); + $server = new Server($root); + $httpRequest = new HTTP\Request(array( + 'HTTP_IF_UNMODIFIED_SINCE' => 'Sun, 06 Nov 1984 08:49:37 CET', + 'REQUEST_URI' => '/foo' + )); + $server->httpRequest = $httpRequest; + $server->httpResponse = new HTTP\ResponseMock(); + $this->assertTrue($server->checkPreconditions()); + + } + + +} + +class ServerPreconditionsNode extends File { + + function getETag() { + + return '"abc123"'; + + } + + function getLastModified() { + + /* my birthday & time, I believe */ + return strtotime('1985-04-07 01:30 +02:00'); + + } + + function getName() { + + return 'foo'; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerPropsTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerPropsTest.php new file mode 100644 index 000000000..859a91070 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerPropsTest.php @@ -0,0 +1,413 @@ +<?php + +namespace Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; +require_once 'Sabre/DAV/AbstractServer.php'; + +class ServerPropsTest extends AbstractServer { + + protected function getRootNode() { + + return new FSExt\Directory(SABRE_TEMPDIR); + + } + + function setUp() { + + if (file_exists(SABRE_TEMPDIR.'../.sabredav')) unlink(SABRE_TEMPDIR.'../.sabredav'); + parent::setUp(); + file_put_contents(SABRE_TEMPDIR . '/test2.txt', 'Test contents2'); + mkdir(SABRE_TEMPDIR . '/col'); + file_put_contents(SABRE_TEMPDIR . 'col/test.txt', 'Test contents'); + $this->server->addPlugin(new Locks\Plugin(new Locks\Backend\File(SABRE_TEMPDIR . '/.locksdb'))); + + } + + function tearDown() { + + parent::tearDown(); + if (file_exists(SABRE_TEMPDIR.'../.locksdb')) unlink(SABRE_TEMPDIR.'../.locksdb'); + + } + + private function sendRequest($body) { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'PROPFIND', + 'HTTP_DEPTH' => '0', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($body); + + $this->server->httpRequest = ($request); + $this->server->exec(); + + } + + public function testPropFindEmptyBody() { + + $hasFired = false; + + $self = $this; + // Also testing the beforeGetPropertiesForPath event. + $this->server->subscribeEvent('beforeGetPropertiesForPath', function($path, $properties, $depth) use ($self, &$hasFired) { + + $hasFired = true; + $self->assertEquals('', $path); + $self->assertEquals(array(), $properties); + $self->assertEquals(0, $depth); + + }); + + $this->sendRequest(""); + + $this->assertTrue($hasFired); + + $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + 'DAV' => '1, 3, extended-mkcol, 2', + 'Vary' => 'Brief,Prefer', + ), + $this->response->headers + ); + + $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); + $xml = simplexml_load_string($body); + $xml->registerXPathNamespace('d','urn:DAV'); + + list($data) = $xml->xpath('/d:multistatus/d:response/d:href'); + $this->assertEquals('/',(string)$data,'href element should have been /'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:resourcetype'); + $this->assertEquals(1,count($data)); + + } + + function testSupportedLocks() { + + $xml = '<?xml version="1.0"?> +<d:propfind xmlns:d="DAV:"> + <d:prop> + <d:supportedlock /> + </d:prop> +</d:propfind>'; + + $this->sendRequest($xml); + + $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); + $xml = simplexml_load_string($body); + $xml->registerXPathNamespace('d','urn:DAV'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry'); + $this->assertEquals(2,count($data),'We expected two \'d:lockentry\' tags'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:lockscope'); + $this->assertEquals(2,count($data),'We expected two \'d:lockscope\' tags'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:locktype'); + $this->assertEquals(2,count($data),'We expected two \'d:locktype\' tags'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:lockscope/d:shared'); + $this->assertEquals(1,count($data),'We expected a \'d:shared\' tag'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:lockscope/d:exclusive'); + $this->assertEquals(1,count($data),'We expected a \'d:exclusive\' tag'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:locktype/d:write'); + $this->assertEquals(2,count($data),'We expected two \'d:write\' tags'); + } + + function testLockDiscovery() { + + $xml = '<?xml version="1.0"?> +<d:propfind xmlns:d="DAV:"> + <d:prop> + <d:lockdiscovery /> + </d:prop> +</d:propfind>'; + + $this->sendRequest($xml); + + $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); + $xml = simplexml_load_string($body); + $xml->registerXPathNamespace('d','urn:DAV'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:lockdiscovery'); + $this->assertEquals(1,count($data),'We expected a \'d:lockdiscovery\' tag'); + + } + + function testUnknownProperty() { + + $xml = '<?xml version="1.0"?> +<d:propfind xmlns:d="DAV:"> + <d:prop> + <d:macaroni /> + </d:prop> +</d:propfind>'; + + $this->sendRequest($xml); + $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); + $xml = simplexml_load_string($body); + $xml->registerXPathNamespace('d','urn:DAV'); + $pathTests = array( + '/d:multistatus', + '/d:multistatus/d:response', + '/d:multistatus/d:response/d:propstat', + '/d:multistatus/d:response/d:propstat/d:status', + '/d:multistatus/d:response/d:propstat/d:prop', + '/d:multistatus/d:response/d:propstat/d:prop/d:macaroni', + ); + foreach($pathTests as $test) { + $this->assertTrue(count($xml->xpath($test))==true,'We expected the ' . $test . ' element to appear in the response, we got: ' . $body); + } + + $val = $xml->xpath('/d:multistatus/d:response/d:propstat/d:status'); + $this->assertEquals(1,count($val),$body); + $this->assertEquals('HTTP/1.1 404 Not Found',(string)$val[0]); + + } + + /** + * @covers Sabre\DAV\Server::parsePropPatchRequest + */ + public function testParsePropPatchRequest() { + + $body = '<?xml version="1.0"?> +<d:propertyupdate xmlns:d="DAV:" xmlns:s="http://sabredav.org/NS/test"> + <d:set><d:prop><s:someprop>somevalue</s:someprop></d:prop></d:set> + <d:remove><d:prop><s:someprop2 /></d:prop></d:remove> + <d:set><d:prop><s:someprop3>removeme</s:someprop3></d:prop></d:set> + <d:remove><d:prop><s:someprop3 /></d:prop></d:remove> +</d:propertyupdate>'; + + $result = $this->server->parsePropPatchRequest($body); + $this->assertEquals(array( + '{http://sabredav.org/NS/test}someprop' => 'somevalue', + '{http://sabredav.org/NS/test}someprop2' => null, + '{http://sabredav.org/NS/test}someprop3' => null, + ), $result); + + } + + /** + * @covers Sabre\DAV\Server::updateProperties + */ + public function testUpdateProperties() { + + $props = array( + '{http://sabredav.org/NS/test}someprop' => 'somevalue', + ); + + $result = $this->server->updateProperties('/test2.txt',$props); + + $this->assertEquals(array( + '200' => array('{http://sabredav.org/NS/test}someprop' => null), + 'href' => '/test2.txt', + ), $result); + + } + + /** + * @covers Sabre\DAV\Server::updateProperties + * @depends testUpdateProperties + */ + public function testUpdatePropertiesProtected() { + + $props = array( + '{http://sabredav.org/NS/test}someprop' => 'somevalue', + '{DAV:}getcontentlength' => 50, + ); + + $result = $this->server->updateProperties('/test2.txt',$props); + + $this->assertEquals(array( + '424' => array('{http://sabredav.org/NS/test}someprop' => null), + '403' => array('{DAV:}getcontentlength' => null), + 'href' => '/test2.txt', + ), $result); + + } + + /** + * @covers Sabre\DAV\Server::updateProperties + * @depends testUpdateProperties + */ + public function testUpdatePropertiesFail1() { + + $dir = new PropTestDirMock('updatepropsfalse'); + $objectTree = new ObjectTree($dir); + $this->server->tree = $objectTree; + + $props = array( + '{http://sabredav.org/NS/test}someprop' => 'somevalue', + ); + + $result = $this->server->updateProperties('/',$props); + + $this->assertEquals(array( + '403' => array('{http://sabredav.org/NS/test}someprop' => null), + 'href' => '/', + ), $result); + + } + + /** + * @covers Sabre\DAV\Server::updateProperties + * @depends testUpdateProperties + */ + public function testUpdatePropertiesFail2() { + + $dir = new PropTestDirMock('updatepropsarray'); + $objectTree = new ObjectTree($dir); + $this->server->tree = $objectTree; + + $props = array( + '{http://sabredav.org/NS/test}someprop' => 'somevalue', + ); + + $result = $this->server->updateProperties('/',$props); + + $this->assertEquals(array( + '402' => array('{http://sabredav.org/NS/test}someprop' => null), + 'href' => '/', + ), $result); + + } + + /** + * @covers Sabre\DAV\Server::updateProperties + * @depends testUpdateProperties + * @expectedException Sabre\DAV\Exception + */ + public function testUpdatePropertiesFail3() { + + $dir = new PropTestDirMock('updatepropsobj'); + $objectTree = new ObjectTree($dir); + $this->server->tree = $objectTree; + + $props = array( + '{http://sabredav.org/NS/test}someprop' => 'somevalue', + ); + + $result = $this->server->updateProperties('/',$props); + + } + + /** + * @depends testParsePropPatchRequest + * @depends testUpdateProperties + * @covers Sabre\DAV\Server::httpPropPatch + */ + public function testPropPatch() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'PROPPATCH', + ); + + $body = '<?xml version="1.0"?> +<d:propertyupdate xmlns:d="DAV:" xmlns:s="http://www.rooftopsolutions.nl/testnamespace"> + <d:set><d:prop><s:someprop>somevalue</s:someprop></d:prop></d:set> +</d:propertyupdate>'; + + $request = new HTTP\Request($serverVars); + $request->setBody($body); + + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + 'Vary' => 'Brief,Prefer', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'We got the wrong status. Full XML response: ' . $this->response->body); + + $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); + $xml = simplexml_load_string($body); + $xml->registerXPathNamespace('d','urn:DAV'); + $xml->registerXPathNamespace('bla','http://www.rooftopsolutions.nl/testnamespace'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop'); + $this->assertEquals(1,count($data),'We expected one \'d:prop\' element. Response body: ' . $body); + + $data = $xml->xpath('//bla:someprop'); + $this->assertEquals(1,count($data),'We expected one \'s:someprop\' element. Response body: ' . $body); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:status'); + $this->assertEquals(1,count($data),'We expected one \'s:status\' element. Response body: ' . $body); + + $this->assertEquals('HTTP/1.1 200 OK',(string)$data[0]); + + } + + /** + * @depends testPropPatch + */ + public function testPropPatchAndFetch() { + + $this->testPropPatch(); + $xml = '<?xml version="1.0"?> +<d:propfind xmlns:d="DAV:" xmlns:s="http://www.rooftopsolutions.nl/testnamespace"> + <d:prop> + <s:someprop /> + </d:prop> +</d:propfind>'; + + $this->sendRequest($xml); + + $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); + $xml = simplexml_load_string($body); + $xml->registerXPathNamespace('d','urn:DAV'); + $xml->registerXPathNamespace('bla','http://www.rooftopsolutions.nl/testnamespace'); + + $xpath='//bla:someprop'; + $result = $xml->xpath($xpath); + $this->assertEquals(1,count($result),'We couldn\'t find our new property in the response. Full response body:' . "\n" . $body); + $this->assertEquals('somevalue',(string)$result[0],'We couldn\'t find our new property in the response. Full response body:' . "\n" . $body); + + } + +} + +class PropTestDirMock extends SimpleCollection implements IProperties { + + public $type; + + function __construct($type) { + + $this->type =$type; + parent::__construct('root'); + + } + + function updateProperties($updateProperties) { + + switch($this->type) { + case 'updatepropsfalse' : return false; + case 'updatepropsarray' : + $r = array(402 => array()); + foreach($updateProperties as $k=>$v) $r[402][$k] = null; + return $r; + case 'updatepropsobj' : + return new \STDClass(); + } + + } + + function getProperties($requestedPropeties) { + + return array(); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerRangeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerRangeTest.php new file mode 100644 index 000000000..a06fcb0be --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerRangeTest.php @@ -0,0 +1,274 @@ +<?php + +namespace Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/DAV/AbstractServer.php'; + +class ServerRangeTest extends AbstractServer{ + + protected function getRootNode() { + + return new FSExt\Directory(SABRE_TEMPDIR); + + } + + function testRange() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'GET', + 'HTTP_RANGE' => 'bytes=2-5', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 4, + 'Content-Range' => 'bytes 2-5/13', + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')). '"', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 206 Partial Content',$this->response->status); + $this->assertEquals('st c', stream_get_contents($this->response->body)); + + } + + /** + * @depends testRange + */ + function testStartRange() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'GET', + 'HTTP_RANGE' => 'bytes=2-', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 11, + 'Content-Range' => 'bytes 2-12/13', + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')) . '"', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 206 Partial Content',$this->response->status); + $this->assertEquals('st contents', stream_get_contents($this->response->body)); + + } + + /** + * @depends testRange + */ + function testEndRange() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'GET', + 'HTTP_RANGE' => 'bytes=-8', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 8, + 'Content-Range' => 'bytes 5-12/13', + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')). '"', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 206 Partial Content',$this->response->status); + $this->assertEquals('contents', stream_get_contents($this->response->body)); + + } + + /** + * @depends testRange + */ + function testTooHighRange() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'GET', + 'HTTP_RANGE' => 'bytes=100-200', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 416 Requested Range Not Satisfiable',$this->response->status); + + } + + /** + * @depends testRange + */ + function testCrazyRange() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'GET', + 'HTTP_RANGE' => 'bytes=8-4', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 416 Requested Range Not Satisfiable',$this->response->status); + + } + + /** + * @depends testRange + * @covers \Sabre\DAV\Server::httpGet + */ + function testIfRangeEtag() { + + $node = $this->server->tree->getNodeForPath('test.txt'); + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'GET', + 'HTTP_RANGE' => 'bytes=2-5', + 'HTTP_IF_RANGE' => $node->getETag(), + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 4, + 'Content-Range' => 'bytes 2-5/13', + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')) . '"', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 206 Partial Content',$this->response->status); + $this->assertEquals('st c', stream_get_contents($this->response->body)); + + } + + /** + * @depends testRange + * @covers \Sabre\DAV\Server::httpGet + */ + function testIfRangeEtagIncorrect() { + + $node = $this->server->tree->getNodeForPath('test.txt'); + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'GET', + 'HTTP_RANGE' => 'bytes=2-5', + 'HTTP_IF_RANGE' => $node->getETag() . 'blabla', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 13, + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')) . '"', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals('Test contents', stream_get_contents($this->response->body)); + + } + + /** + * @depends testRange + * @covers \Sabre\DAV\Server::httpGet + */ + function testIfRangeModificationDate() { + + $node = $this->server->tree->getNodeForPath('test.txt'); + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'GET', + 'HTTP_RANGE' => 'bytes=2-5', + 'HTTP_IF_RANGE' => 'tomorrow', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 4, + 'Content-Range' => 'bytes 2-5/13', + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')) . '"', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 206 Partial Content',$this->response->status); + $this->assertEquals('st c', stream_get_contents($this->response->body)); + + } + + /** + * @depends testRange + * @covers \Sabre\DAV\Server::httpGet + */ + function testIfRangeModificationDateModified() { + + $node = $this->server->tree->getNodeForPath('test.txt'); + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'GET', + 'HTTP_RANGE' => 'bytes=2-5', + 'HTTP_IF_RANGE' => '-2 years', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 13, + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')) . '"', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals('Test contents', stream_get_contents($this->response->body)); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php new file mode 100644 index 000000000..afcd5c98f --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php @@ -0,0 +1,767 @@ +<?php + +namespace Sabre\DAV; + +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; +require_once 'Sabre/DAV/AbstractServer.php'; +require_once 'Sabre/DAV/Exception.php'; + +class ServerSimpleTest extends AbstractServer{ + + function testConstructArray() { + + $nodes = array( + new SimpleCollection('hello') + ); + + $server = new Server($nodes); + $this->assertEquals($nodes[0], $server->tree->getNodeForPath('hello')); + + } + + /** + * @expectedException Sabre\DAV\Exception + */ + function testConstructIncorrectObj() { + + $nodes = array( + new SimpleCollection('hello'), + new \STDClass(), + ); + + $server = new Server($nodes); + + } + + /** + * @expectedException Sabre\DAV\Exception + */ + function testConstructInvalidArg() { + + $server = new Server(1); + + } + + function testGet() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'GET', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 13, + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals('Test contents', stream_get_contents($this->response->body)); + + } + function testGetHttp10() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'GET', + 'SERVER_PROTOCOL' => 'HTTP/1.0', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 13, + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.0 200 OK',$this->response->status); + $this->assertEquals('Test contents', stream_get_contents($this->response->body)); + + } + + function testGetDoesntExist() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt_randomblbla', + 'REQUEST_METHOD' => 'GET', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + $this->assertEquals('HTTP/1.1 404 Not Found',$this->response->status); + + } + + function testGetDoesntExist2() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt/randomblbla', + 'REQUEST_METHOD' => 'GET', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + $this->assertEquals('HTTP/1.1 404 Not Found',$this->response->status); + + } + + /** + * This test should have the exact same result as testGet. + * + * The idea is that double slashes // are converted to single ones / + * + */ + function testGetDoubleSlash() { + + $serverVars = array( + 'REQUEST_URI' => '//test.txt', + 'REQUEST_METHOD' => 'GET', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 13, + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals('Test contents', stream_get_contents($this->response->body)); + + } + + + function testHEAD() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'HEAD', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 13, + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals('', $this->response->body); + + } + + function testPut() { + + $serverVars = array( + 'REQUEST_URI' => '/testput.txt', + 'REQUEST_METHOD' => 'PUT', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing new file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('', $this->response->body); + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals(array( + "Content-Length" => "0", + ), $this->response->headers); + + $this->assertEquals('Testing new file',file_get_contents($this->tempDir . '/testput.txt')); + + } + + function testPutAlreadyExists() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_IF_NONE_MATCH' => '*', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing new file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status); + $this->assertNotEquals('Testing new file',file_get_contents($this->tempDir . '/test.txt')); + + } + + function testPutUpdate() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing updated file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('0', $this->response->headers['Content-Length']); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status); + $this->assertEquals('', $this->response->body); + $this->assertEquals('Testing updated file',file_get_contents($this->tempDir . '/test.txt')); + + } + + function testPutNoParentCollection() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt/item.txt', + 'REQUEST_METHOD' => 'PUT', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing updated file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status); + + } + + function testPutContentRange() { + + $serverVars = array( + 'REQUEST_URI' => '/testput.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_CONTENT_RANGE' => 'bytes/100-200', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing new file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 501 Not Implemented',$this->response->status); + + } + + + function testDelete() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'DELETE', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Length' => '0', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status); + $this->assertEquals('', $this->response->body); + $this->assertFalse(file_exists($this->tempDir . '/test.txt')); + + } + + function testDeleteDirectory() { + + $serverVars = array( + 'REQUEST_URI' => '/testcol', + 'REQUEST_METHOD' => 'DELETE', + ); + + mkdir($this->tempDir.'/testcol'); + file_put_contents($this->tempDir.'/testcol/test.txt','Hi! I\'m a file with a short lifespan'); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Length' => '0', + ),$this->response->headers); + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status); + $this->assertEquals('', $this->response->body); + $this->assertFalse(file_exists($this->tempDir . '/col')); + + } + + function testOptions() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'OPTIONS', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'DAV' => '1, 3, extended-mkcol', + 'MS-Author-Via' => 'DAV', + 'Allow' => 'OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT', + 'Accept-Ranges' => 'bytes', + 'Content-Length' => '0', + 'X-Sabre-Version' => Version::VERSION, + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals('', $this->response->body); + + + } + function testNonExistantMethod() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'BLABLA', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 501 Not Implemented',$this->response->status); + + + } + + function testGETOnCollection() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'GET', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 501 Not Implemented',$this->response->status); + + } + + function testHEADOnCollection() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'HEAD', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + } + + function testBaseUri() { + + $serverVars = array( + 'REQUEST_URI' => '/blabla/test.txt', + 'REQUEST_METHOD' => 'GET', + ); + + $request = new HTTP\Request($serverVars); + $this->server->setBaseUri('/blabla/'); + $this->assertEquals('/blabla/',$this->server->getBaseUri()); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => 13, + 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))), + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals('Test contents', stream_get_contents($this->response->body)); + + } + + function testBaseUriAddSlash() { + + $tests = array( + '/' => '/', + '/foo' => '/foo/', + '/foo/' => '/foo/', + '/foo/bar' => '/foo/bar/', + '/foo/bar/' => '/foo/bar/', + ); + + foreach($tests as $test=>$result) { + $this->server->setBaseUri($test); + + $this->assertEquals($result, $this->server->getBaseUri()); + + } + + } + + function testCalculateUri() { + + $uris = array( + 'http://www.example.org/root/somepath', + '/root/somepath', + '/root/somepath/', + ); + + $this->server->setBaseUri('/root/'); + + foreach($uris as $uri) { + + $this->assertEquals('somepath',$this->server->calculateUri($uri)); + + } + + $this->server->setBaseUri('/root'); + + foreach($uris as $uri) { + + $this->assertEquals('somepath',$this->server->calculateUri($uri)); + + } + + $this->assertEquals('', $this->server->calculateUri('/root')); + + } + + function testCalculateUriSpecialChars() { + + $uris = array( + 'http://www.example.org/root/%C3%A0fo%C3%B3', + '/root/%C3%A0fo%C3%B3', + '/root/%C3%A0fo%C3%B3/' + ); + + $this->server->setBaseUri('/root/'); + + foreach($uris as $uri) { + + $this->assertEquals("\xc3\xa0fo\xc3\xb3",$this->server->calculateUri($uri)); + + } + + $this->server->setBaseUri('/root'); + + foreach($uris as $uri) { + + $this->assertEquals("\xc3\xa0fo\xc3\xb3",$this->server->calculateUri($uri)); + + } + + $this->server->setBaseUri('/'); + + foreach($uris as $uri) { + + $this->assertEquals("root/\xc3\xa0fo\xc3\xb3",$this->server->calculateUri($uri)); + + } + + } + + function testBaseUriCheck() { + + $uris = array( + 'http://www.example.org/root/somepath', + '/root/somepath', + '/root/somepath/' + ); + + try { + + $this->server->setBaseUri('root/'); + $this->server->calculateUri('/root/testuri'); + + $this->fail('Expected an exception'); + + } catch (Exception\Forbidden $e) { + + // This was expected + + } + + } + + /** + * @covers \Sabre\DAV\Server::guessBaseUri + */ + function testGuessBaseUri() { + + $serverVars = array( + 'REQUEST_URI' => '/index.php/root', + 'PATH_INFO' => '/root', + ); + + $httpRequest = new HTTP\Request($serverVars); + $server = new Server(); + $server->httpRequest = $httpRequest; + + $this->assertEquals('/index.php/', $server->guessBaseUri()); + + } + + /** + * @depends testGuessBaseUri + * @covers Sabre\DAV\Server::guessBaseUri + */ + function testGuessBaseUriPercentEncoding() { + + $serverVars = array( + 'REQUEST_URI' => '/index.php/dir/path2/path%20with%20spaces', + 'PATH_INFO' => '/dir/path2/path with spaces', + ); + + $httpRequest = new HTTP\Request($serverVars); + $server = new Server(); + $server->httpRequest = $httpRequest; + + $this->assertEquals('/index.php/', $server->guessBaseUri()); + + } + + /** + * @depends testGuessBaseUri + * @covers \Sabre\DAV\Server::guessBaseUri + */ + /* + function testGuessBaseUriPercentEncoding2() { + + $this->markTestIncomplete('This behaviour is not yet implemented'); + $serverVars = array( + 'REQUEST_URI' => '/some%20directory+mixed/index.php/dir/path2/path%20with%20spaces', + 'PATH_INFO' => '/dir/path2/path with spaces', + ); + + $httpRequest = new HTTP\Request($serverVars); + $server = new Server(); + $server->httpRequest = $httpRequest; + + $this->assertEquals('/some%20directory+mixed/index.php/', $server->guessBaseUri()); + + }*/ + + function testGuessBaseUri2() { + + $serverVars = array( + 'REQUEST_URI' => '/index.php/root/', + 'PATH_INFO' => '/root/', + ); + + $httpRequest = new HTTP\Request($serverVars); + $server = new Server(); + $server->httpRequest = $httpRequest; + + $this->assertEquals('/index.php/', $server->guessBaseUri()); + + } + + function testGuessBaseUriNoPathInfo() { + + $serverVars = array( + 'REQUEST_URI' => '/index.php/root', + ); + + $httpRequest = new HTTP\Request($serverVars); + $server = new Server(); + $server->httpRequest = $httpRequest; + + $this->assertEquals('/', $server->guessBaseUri()); + + } + + function testGuessBaseUriNoPathInfo2() { + + $serverVars = array( + 'REQUEST_URI' => '/a/b/c/test.php', + ); + + $httpRequest = new HTTP\Request($serverVars); + $server = new Server(); + $server->httpRequest = $httpRequest; + + $this->assertEquals('/', $server->guessBaseUri()); + + } + + + /** + * @covers \Sabre\DAV\Server::guessBaseUri + * @depends testGuessBaseUri + */ + function testGuessBaseUriQueryString() { + + $serverVars = array( + 'REQUEST_URI' => '/index.php/root?query_string=blabla', + 'PATH_INFO' => '/root', + ); + + $httpRequest = new HTTP\Request($serverVars); + $server = new Server(); + $server->httpRequest = $httpRequest; + + $this->assertEquals('/index.php/', $server->guessBaseUri()); + + } + + /** + * @covers \Sabre\DAV\Server::guessBaseUri + * @depends testGuessBaseUri + * @expectedException \Sabre\DAV\Exception + */ + function testGuessBaseUriBadConfig() { + + $serverVars = array( + 'REQUEST_URI' => '/index.php/root/heyyy', + 'PATH_INFO' => '/root', + ); + + $httpRequest = new HTTP\Request($serverVars); + $server = new Server(); + $server->httpRequest = $httpRequest; + + $server->guessBaseUri(); + + } + + function testTriggerException() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'FOO', + ); + + $httpRequest = new HTTP\Request($serverVars); + $this->server->httpRequest = $httpRequest; + $this->server->subscribeEvent('beforeMethod',array($this,'exceptionTrigger')); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $this->assertEquals('HTTP/1.1 500 Internal Server Error',$this->response->status); + + } + + function exceptionTrigger() { + + throw new Exception('Hola'); + + } + + function testReportNotFound() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'REPORT', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->httpRequest->setBody('<?xml version="1.0"?><bla:myreport xmlns:bla="http://www.rooftopsolutions.nl/NS"></bla:myreport>'); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status,'We got an incorrect status back. Full response body follows: ' . $this->response->body); + + } + + function testReportIntercepted() { + + $serverVars = array( + 'REQUEST_URI' => '/', + 'REQUEST_METHOD' => 'REPORT', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->httpRequest->setBody('<?xml version="1.0"?><bla:myreport xmlns:bla="http://www.rooftopsolutions.nl/NS"></bla:myreport>'); + $this->server->subscribeEvent('report',array($this,'reportHandler')); + $this->server->exec(); + + $this->assertEquals(array( + 'testheader' => 'testvalue', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 418 I\'m a teapot',$this->response->status,'We got an incorrect status back. Full response body follows: ' . $this->response->body); + + } + + function reportHandler($reportName) { + + if ($reportName=='{http://www.rooftopsolutions.nl/NS}myreport') { + $this->server->httpResponse->sendStatus(418); + $this->server->httpResponse->setHeader('testheader','testvalue'); + return false; + } + else return; + + } + + function testGetPropertiesForChildren() { + + $result = $this->server->getPropertiesForChildren('',array( + '{DAV:}getcontentlength', + )); + + $expected = array( + 'test.txt' => array('{DAV:}getcontentlength' => 13), + 'dir/' => array(), + ); + + $this->assertEquals($expected,$result); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php new file mode 100644 index 000000000..a73e8d13f --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php @@ -0,0 +1,130 @@ +<?php + +namespace Sabre\DAV; +use Sabre\HTTP; + +class ServerUpdatePropertiesTest extends \PHPUnit_Framework_TestCase { + + function testUpdatePropertiesFail() { + + $tree = array( + new SimpleCollection('foo'), + ); + $server = new Server($tree); + + $result = $server->updateProperties('foo', array( + '{DAV:}foo' => 'bar' + )); + + $expected = array( + 'href' => 'foo', + '403' => array( + '{DAV:}foo' => null, + ), + ); + $this->assertEquals($expected, $result); + + } + + function testUpdatePropertiesProtected() { + + $tree = array( + new SimpleCollection('foo'), + ); + $server = new Server($tree); + + $result = $server->updateProperties('foo', array( + '{DAV:}getetag' => 'bla', + '{DAV:}foo' => 'bar' + )); + + $expected = array( + 'href' => 'foo', + '403' => array( + '{DAV:}getetag' => null, + ), + '424' => array( + '{DAV:}foo' => null, + ), + ); + $this->assertEquals($expected, $result); + + } + + function testUpdatePropertiesEventFail() { + + $tree = array( + new SimpleCollection('foo'), + ); + $server = new Server($tree); + $server->subscribeEvent('updateProperties', array($this,'updatepropfail')); + + $result = $server->updateProperties('foo', array( + '{DAV:}foo' => 'bar', + '{DAV:}foo2' => 'bla', + )); + + $expected = array( + 'href' => 'foo', + '404' => array( + '{DAV:}foo' => null, + ), + '424' => array( + '{DAV:}foo2' => null, + ), + ); + $this->assertEquals($expected, $result); + + } + + function updatePropFail(&$propertyDelta, &$result, $node) { + + $result[404] = array( + '{DAV:}foo' => null, + ); + unset($propertyDelta['{DAV:}foo']); + return false; + + } + + + function testUpdatePropertiesEventSuccess() { + + $tree = array( + new SimpleCollection('foo'), + ); + $server = new Server($tree); + $server->subscribeEvent('updateProperties', array($this,'updatepropsuccess')); + + $result = $server->updateProperties('foo', array( + '{DAV:}foo' => 'bar', + '{DAV:}foo2' => 'bla', + )); + + $expected = array( + 'href' => 'foo', + '200' => array( + '{DAV:}foo' => null, + ), + '201' => array( + '{DAV:}foo2' => null, + ), + ); + $this->assertEquals($expected, $result); + + } + + function updatePropSuccess(&$propertyDelta, &$result, $node) { + + $result[200] = array( + '{DAV:}foo' => null, + ); + $result[201] = array( + '{DAV:}foo2' => null, + ); + unset($propertyDelta['{DAV:}foo']); + unset($propertyDelta['{DAV:}foo2']); + return; + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php new file mode 100644 index 000000000..de8b05734 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php @@ -0,0 +1,19 @@ +<?php + +namespace Sabre\DAV; + +class SimpleFileTest extends \PHPUnit_Framework_TestCase { + + function testAll() { + + $file = new SimpleFile('filename.txt','contents','text/plain'); + + $this->assertEquals('filename.txt', $file->getName()); + $this->assertEquals('contents', $file->get()); + $this->assertEquals('8', $file->getSize()); + $this->assertEquals('"' . md5('contents') . '"', $file->getETag()); + $this->assertEquals('text/plain', $file->getContentType()); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php b/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php new file mode 100644 index 000000000..941d1f913 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php @@ -0,0 +1,122 @@ +<?php + +namespace Sabre\DAV; + +class StringUtilTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider dataset + */ + function testTextMatch($haystack, $needle, $collation, $matchType, $result) { + + $this->assertEquals($result, StringUtil::textMatch($haystack, $needle, $collation, $matchType)); + + } + + function dataset() { + + return array( + array('FOOBAR', 'FOO', 'i;octet', 'contains', true), + array('FOOBAR', 'foo', 'i;octet', 'contains', false), + array('FÖÖBAR', 'FÖÖ', 'i;octet', 'contains', true), + array('FÖÖBAR', 'föö', 'i;octet', 'contains', false), + array('FOOBAR', 'FOOBAR', 'i;octet', 'equals', true), + array('FOOBAR', 'fooBAR', 'i;octet', 'equals', false), + array('FOOBAR', 'FOO', 'i;octet', 'starts-with', true), + array('FOOBAR', 'foo', 'i;octet', 'starts-with', false), + array('FOOBAR', 'BAR', 'i;octet', 'starts-with', false), + array('FOOBAR', 'bar', 'i;octet', 'starts-with', false), + array('FOOBAR', 'FOO', 'i;octet', 'ends-with', false), + array('FOOBAR', 'foo', 'i;octet', 'ends-with', false), + array('FOOBAR', 'BAR', 'i;octet', 'ends-with', true), + array('FOOBAR', 'bar', 'i;octet', 'ends-with', false), + + array('FOOBAR', 'FOO', 'i;ascii-casemap', 'contains', true), + array('FOOBAR', 'foo', 'i;ascii-casemap', 'contains', true), + array('FÖÖBAR', 'FÖÖ', 'i;ascii-casemap', 'contains', true), + array('FÖÖBAR', 'föö', 'i;ascii-casemap', 'contains', false), + array('FOOBAR', 'FOOBAR', 'i;ascii-casemap', 'equals', true), + array('FOOBAR', 'fooBAR', 'i;ascii-casemap', 'equals', true), + array('FOOBAR', 'FOO', 'i;ascii-casemap', 'starts-with', true), + array('FOOBAR', 'foo', 'i;ascii-casemap', 'starts-with', true), + array('FOOBAR', 'BAR', 'i;ascii-casemap', 'starts-with', false), + array('FOOBAR', 'bar', 'i;ascii-casemap', 'starts-with', false), + array('FOOBAR', 'FOO', 'i;ascii-casemap', 'ends-with', false), + array('FOOBAR', 'foo', 'i;ascii-casemap', 'ends-with', false), + array('FOOBAR', 'BAR', 'i;ascii-casemap', 'ends-with', true), + array('FOOBAR', 'bar', 'i;ascii-casemap', 'ends-with', true), + + array('FOOBAR', 'FOO', 'i;unicode-casemap', 'contains', true), + array('FOOBAR', 'foo', 'i;unicode-casemap', 'contains', true), + array('FÖÖBAR', 'FÖÖ', 'i;unicode-casemap', 'contains', true), + array('FÖÖBAR', 'föö', 'i;unicode-casemap', 'contains', true), + array('FOOBAR', 'FOOBAR', 'i;unicode-casemap', 'equals', true), + array('FOOBAR', 'fooBAR', 'i;unicode-casemap', 'equals', true), + array('FOOBAR', 'FOO', 'i;unicode-casemap', 'starts-with', true), + array('FOOBAR', 'foo', 'i;unicode-casemap', 'starts-with', true), + array('FOOBAR', 'BAR', 'i;unicode-casemap', 'starts-with', false), + array('FOOBAR', 'bar', 'i;unicode-casemap', 'starts-with', false), + array('FOOBAR', 'FOO', 'i;unicode-casemap', 'ends-with', false), + array('FOOBAR', 'foo', 'i;unicode-casemap', 'ends-with', false), + array('FOOBAR', 'BAR', 'i;unicode-casemap', 'ends-with', true), + array('FOOBAR', 'bar', 'i;unicode-casemap', 'ends-with', true), + ); + + } + + /** + * @expectedException Sabre\DAV\Exception\BadRequest + */ + public function testBadCollation() { + + StringUtil::textMatch('foobar','foo','blabla','contains'); + + } + + + /** + * @expectedException Sabre\DAV\Exception\BadRequest + */ + public function testBadMatchType() { + + StringUtil::textMatch('foobar','foo','i;octet','booh'); + + } + + public function testEnsureUTF8_ascii() { + + $inputString = "harkema"; + $outputString = "harkema"; + + $this->assertEquals( + $outputString, + StringUtil::ensureUTF8($inputString) + ); + + } + + public function testEnsureUTF8_latin1() { + + $inputString = "m\xfcnster"; + $outputString = "münster"; + + $this->assertEquals( + $outputString, + StringUtil::ensureUTF8($inputString) + ); + + } + + public function testEnsureUTF8_utf8() { + + $inputString = "m\xc3\xbcnster"; + $outputString = "münster"; + + $this->assertEquals( + $outputString, + StringUtil::ensureUTF8($inputString) + ); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php b/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php new file mode 100644 index 000000000..d136eeb17 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php @@ -0,0 +1,252 @@ +<?php + +namespace Sabre\DAV; + +use Sabre\HTTP; + +class TemporaryFileFilterTest extends AbstractServer { + + function setUp() { + + parent::setUp(); + $plugin = new TemporaryFileFilterPlugin(SABRE_TEMPDIR . '/tff'); + $this->server->addPlugin($plugin); + + } + + function testPutNormal() { + + $serverVars = array( + 'REQUEST_URI' => '/testput.txt', + 'REQUEST_METHOD' => 'PUT', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing new file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('', $this->response->body); + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals('0', $this->response->headers['Content-Length']); + + $this->assertEquals('Testing new file',file_get_contents(SABRE_TEMPDIR . '/testput.txt')); + + } + + function testPutTemp() { + + // mimicking an OS/X resource fork + $serverVars = array( + 'REQUEST_URI' => '/._testput.txt', + 'REQUEST_METHOD' => 'PUT', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing new file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('', $this->response->body); + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals(array( + 'X-Sabre-Temp' => 'true', + ),$this->response->headers); + + $this->assertFalse(file_exists(SABRE_TEMPDIR . '/._testput.txt'),'._testput.txt should not exist in the regular file structure.'); + + } + + function testPutTempIfNoneMatch() { + + // mimicking an OS/X resource fork + $serverVars = array( + 'REQUEST_URI' => '/._testput.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_IF_NONE_MATCH' => '*', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing new file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('', $this->response->body); + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals(array( + 'X-Sabre-Temp' => 'true', + ),$this->response->headers); + + $this->assertFalse(file_exists(SABRE_TEMPDIR . '/._testput.txt'),'._testput.txt should not exist in the regular file structure.'); + + + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status); + $this->assertEquals(array( + 'X-Sabre-Temp' => 'true', + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + } + + function testPutGet() { + + // mimicking an OS/X resource fork + $serverVars = array( + 'REQUEST_URI' => '/._testput.txt', + 'REQUEST_METHOD' => 'PUT', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing new file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('', $this->response->body); + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals(array( + 'X-Sabre-Temp' => 'true', + ),$this->response->headers); + + $serverVars = array( + 'REQUEST_URI' => '/._testput.txt', + 'REQUEST_METHOD' => 'GET', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + $this->assertEquals(array( + 'X-Sabre-Temp' => 'true', + 'Content-Length' => 16, + 'Content-Type' => 'application/octet-stream', + ),$this->response->headers); + + $this->assertEquals('Testing new file',stream_get_contents($this->response->body)); + + } + + function testLockNonExistant() { + + mkdir(SABRE_TEMPDIR . '/locksdir'); + $locksBackend = new Locks\Backend\FS(SABRE_TEMPDIR . '/locksdir'); + $locksPlugin = new Locks\Plugin($locksBackend); + $this->server->addPlugin($locksPlugin); + + // mimicking an OS/X resource fork + $serverVars = array( + 'REQUEST_URI' => '/._testlock.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + $this->assertEquals('true',$this->response->headers['X-Sabre-Temp']); + + $this->assertFalse(file_exists(SABRE_TEMPDIR . '/._testlock.txt'),'._testlock.txt should not exist in the regular file structure.'); + + } + + function testPutDelete() { + + // mimicking an OS/X resource fork + $serverVars = array( + 'REQUEST_URI' => '/._testput.txt', + 'REQUEST_METHOD' => 'PUT', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing new file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('', $this->response->body); + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals(array( + 'X-Sabre-Temp' => 'true', + ),$this->response->headers); + + $serverVars = array( + 'REQUEST_URI' => '/._testput.txt', + 'REQUEST_METHOD' => 'DELETE', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status, "Incorrect status code received. Full body:\n". $this->response->body); + $this->assertEquals(array( + 'X-Sabre-Temp' => 'true', + ),$this->response->headers); + + $this->assertEquals('',$this->response->body); + + } + + function testPutPropfind() { + + // mimicking an OS/X resource fork + $serverVars = array( + 'REQUEST_URI' => '/._testput.txt', + 'REQUEST_METHOD' => 'PUT', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('Testing new file'); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('', $this->response->body); + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + $this->assertEquals(array( + 'X-Sabre-Temp' => 'true', + ),$this->response->headers); + + $serverVars = array( + 'REQUEST_URI' => '/._testput.txt', + 'REQUEST_METHOD' => 'PROPFIND', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody(''); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Incorrect status code returned. Body: ' . $this->response->body); + $this->assertEquals(array( + 'X-Sabre-Temp' => 'true', + 'Content-Type' => 'application/xml; charset=utf-8', + ),$this->response->headers); + + $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); + $xml = simplexml_load_string($body); + $xml->registerXPathNamespace('d','urn:DAV'); + + list($data) = $xml->xpath('/d:multistatus/d:response/d:href'); + $this->assertEquals('/._testput.txt',(string)$data,'href element should have been /._testput.txt'); + + $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:resourcetype'); + $this->assertEquals(1,count($data)); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php b/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php new file mode 100644 index 000000000..9cf5edbb0 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php @@ -0,0 +1,34 @@ +<?php + +namespace Sabre\DAV; + +class TestPlugin extends ServerPlugin { + + public $beforeMethod; + + function getFeatures() { + + return array('drinking'); + + } + + function getHTTPMethods($uri) { + + return array('BEER','WINE'); + + } + + function initialize(Server $server) { + + $server->subscribeEvent('beforeMethod',array($this,'beforeMethod')); + + } + + function beforeMethod($method) { + + $this->beforeMethod = $method; + return true; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Tree/FilesystemTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Tree/FilesystemTest.php new file mode 100644 index 000000000..19b08460f --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Tree/FilesystemTest.php @@ -0,0 +1,88 @@ +<?php + +namespace Sabre\DAV\Tree; + +use Sabre\DAV; + +/** + * @covers Sabre\DAV\Tree + * @covers Sabre\DAV\Tree\Filesystem + * @covers Sabre\DAV\FS\Node + * @covers Sabre\DAV\FS\File + * @covers Sabre\DAV\FS\Directory + */ +class FilesystemTest extends \PHPUnit_Framework_TestCase { + + function setUp() { + + \Sabre\TestUtil::clearTempDir(); + file_put_contents(SABRE_TEMPDIR. '/file.txt','Body'); + mkdir(SABRE_TEMPDIR.'/dir'); + file_put_contents(SABRE_TEMPDIR.'/dir/subfile.txt','Body'); + + } + + function tearDown() { + + \Sabre\TestUtil::clearTempDir(); + + } + + function testGetNodeForPath_File() { + + $fs = new Filesystem(SABRE_TEMPDIR); + $node = $fs->getNodeForPath('file.txt'); + $this->assertTrue($node instanceof DAV\FS\File); + + } + + /** + * @expectedException \Sabre\DAV\Exception\NotFound + */ + function testGetNodeForPath_DoesntExist() { + + $fs = new Filesystem(SABRE_TEMPDIR); + $node = $fs->getNodeForPath('whoop/file.txt'); + + } + + function testGetNodeForPath_Directory() { + + $fs = new Filesystem(SABRE_TEMPDIR); + $node = $fs->getNodeForPath('dir'); + $this->assertTrue($node instanceof DAV\FS\Directory); + $this->assertEquals('dir', $node->getName()); + $this->assertInternalType('array', $node->getChildren()); + + } + + function testCopy() { + + $fs = new Filesystem(SABRE_TEMPDIR); + $fs->copy('file.txt','file2.txt'); + $this->assertTrue(file_exists(SABRE_TEMPDIR . '/file2.txt')); + $this->assertEquals('Body',file_get_contents(SABRE_TEMPDIR . '/file2.txt')); + + } + + function testCopyDir() { + + $fs = new Filesystem(SABRE_TEMPDIR); + $fs->copy('dir','dir2'); + $this->assertTrue(file_exists(SABRE_TEMPDIR . '/dir2')); + $this->assertEquals('Body',file_get_contents(SABRE_TEMPDIR . '/dir2/subfile.txt')); + + } + + function testMove() { + + $fs = new Filesystem(SABRE_TEMPDIR); + $fs->move('file.txt','file2.txt'); + $this->assertTrue(file_exists(SABRE_TEMPDIR . '/file2.txt')); + $this->assertTrue(!file_exists(SABRE_TEMPDIR . '/file.txt')); + $this->assertEquals('Body',file_get_contents(SABRE_TEMPDIR . '/file2.txt')); + + } + + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php new file mode 100644 index 000000000..90df6427e --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php @@ -0,0 +1,175 @@ +<?php + +namespace Sabre\DAV; + +/** + * @covers \Sabre\DAV\Tree + */ +class TreeTest extends \PHPUnit_Framework_TestCase { + + function testNodeExists() { + + $tree = new TreeMock(); + + $this->assertTrue($tree->nodeExists('hi')); + $this->assertFalse($tree->nodeExists('hello')); + + } + + function testCopy() { + + $tree = new TreeMock(); + $tree->copy('hi','hi2'); + + $this->assertArrayHasKey('hi2', $tree->getNodeForPath('')->newDirectories); + $this->assertEquals('foobar', $tree->getNodeForPath('hi/file')->get()); + $this->assertEquals(array('test1'=>'value'), $tree->getNodeForPath('hi/file')->getProperties(array())); + + } + + function testMove() { + + $tree = new TreeMock(); + $tree->move('hi','hi2'); + + $this->assertEquals('hi2', $tree->getNodeForPath('hi')->getName()); + $this->assertTrue($tree->getNodeForPath('hi')->isRenamed); + + } + + function testDeepMove() { + + $tree = new TreeMock(); + $tree->move('hi/sub','hi2'); + + $this->assertArrayHasKey('hi2', $tree->getNodeForPath('')->newDirectories); + $this->assertTrue($tree->getNodeForPath('hi/sub')->isDeleted); + + } + + function testDelete() { + + $tree = new TreeMock(); + $tree->delete('hi'); + $this->assertTrue($tree->getNodeForPath('hi')->isDeleted); + + } + + function testGetChildren() { + + $tree = new TreeMock(); + $children = $tree->getChildren(''); + $this->assertEquals(1,count($children)); + $this->assertEquals('hi', $children[0]->getName()); + + } + +} + +class TreeMock extends Tree { + + private $nodes = array(); + + function __construct() { + + $this->nodes['hi/sub'] = new TreeDirectoryTester('sub'); + $this->nodes['hi/file'] = new TreeFileTester('file'); + $this->nodes['hi/file']->properties = array('test1' => 'value'); + $this->nodes['hi/file']->data = 'foobar'; + $this->nodes['hi'] = new TreeDirectoryTester('hi',array($this->nodes['hi/sub'], $this->nodes['hi/file'])); + $this->nodes[''] = new TreeDirectoryTester('hi', array($this->nodes['hi'])); + + } + + function getNodeForPath($path) { + + if (isset($this->nodes[$path])) return $this->nodes[$path]; + throw new Exception\NotFound('item not found'); + + } + +} + +class TreeDirectoryTester extends SimpleCollection { + + public $newDirectories = array(); + public $newFiles = array(); + public $isDeleted = false; + public $isRenamed = false; + + function createDirectory($name) { + + $this->newDirectories[$name] = true; + + } + + function createFile($name,$data = null) { + + $this->newFiles[$name] = $data; + + } + + function getChild($name) { + + if (isset($this->newDirectories[$name])) return new TreeDirectoryTester($name); + if (isset($this->newFiles[$name])) return new TreeFileTester($name, $this->newFiles[$name]); + return parent::getChild($name); + + } + + function delete() { + + $this->isDeleted = true; + + } + + function setName($name) { + + $this->isRenamed = true; + $this->name = $name; + + } + +} + +class TreeFileTester extends File implements IProperties { + + public $name; + public $data; + public $properties; + + function __construct($name, $data = null) { + + $this->name = $name; + if (is_null($data)) $data = 'bla'; + $this->data = $data; + + } + + function getName() { + + return $this->name; + + } + + function get() { + + return $this->data; + + } + + function getProperties($properties) { + + return $this->properties; + + } + + function updateProperties($properties) { + + $this->properties = $properties; + return true; + + } + +} + diff --git a/vendor/sabre/dav/tests/Sabre/DAV/URLUtilTest.php b/vendor/sabre/dav/tests/Sabre/DAV/URLUtilTest.php new file mode 100644 index 000000000..f17ca4b85 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/URLUtilTest.php @@ -0,0 +1,131 @@ +<?php + +namespace Sabre\DAV; + +class URLUtilTest extends \PHPUnit_Framework_TestCase{ + + function testEncodePath() { + + $str = ''; + for($i=0;$i<128;$i++) $str.=chr($i); + + $newStr = URLUtil::encodePath($str); + + $this->assertEquals( + '%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f'. + '%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f'. + '%20%21%22%23%24%25%26%27()%2a%2b%2c-./'. + '0123456789%3a%3b%3c%3d%3e%3f'. + '%40ABCDEFGHIJKLMNO' . + 'PQRSTUVWXYZ%5b%5c%5d%5e_' . + '%60abcdefghijklmno' . + 'pqrstuvwxyz%7b%7c%7d~%7f', + $newStr); + + $this->assertEquals($str,URLUtil::decodePath($newStr)); + + } + + function testEncodePathSegment() { + + $str = ''; + for($i=0;$i<128;$i++) $str.=chr($i); + + $newStr = URLUtil::encodePathSegment($str); + + // Note: almost exactly the same as the last test, with the + // exception of the encoding of / (ascii code 2f) + $this->assertEquals( + '%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f'. + '%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f'. + '%20%21%22%23%24%25%26%27()%2a%2b%2c-.%2f'. + '0123456789%3a%3b%3c%3d%3e%3f'. + '%40ABCDEFGHIJKLMNO' . + 'PQRSTUVWXYZ%5b%5c%5d%5e_' . + '%60abcdefghijklmno' . + 'pqrstuvwxyz%7b%7c%7d~%7f', + $newStr); + + $this->assertEquals($str,URLUtil::decodePathSegment($newStr)); + + } + + function testDecode() { + + $str = 'Hello%20Test+Test2.txt'; + $newStr = URLUtil::decodePath($str); + $this->assertEquals('Hello Test+Test2.txt',$newStr); + + } + + /** + * @depends testDecode + */ + function testDecodeUmlaut() { + + $str = 'Hello%C3%BC.txt'; + $newStr = URLUtil::decodePath($str); + $this->assertEquals("Hello\xC3\xBC.txt",$newStr); + + } + + /** + * @depends testDecodeUmlaut + */ + function testDecodeUmlautLatin1() { + + $str = 'Hello%FC.txt'; + $newStr = URLUtil::decodePath($str); + $this->assertEquals("Hello\xC3\xBC.txt",$newStr); + + } + + /** + * This testcase was sent by a bug reporter + * + * @depends testDecode + */ + function testDecodeAccentsWindows7() { + + $str = '/webdav/%C3%A0fo%C3%B3'; + $newStr = URLUtil::decodePath($str); + $this->assertEquals(strtolower($str),URLUtil::encodePath($newStr)); + + } + + function testSplitPath() { + + $strings = array( + + // input // expected result + '/foo/bar' => array('/foo','bar'), + '/foo/bar/' => array('/foo','bar'), + 'foo/bar/' => array('foo','bar'), + 'foo/bar' => array('foo','bar'), + 'foo/bar/baz' => array('foo/bar','baz'), + 'foo/bar/baz/' => array('foo/bar','baz'), + 'foo' => array('','foo'), + 'foo/' => array('','foo'), + '/foo/' => array('','foo'), + '/foo' => array('','foo'), + '' => array(null,null), + + // UTF-8 + "/\xC3\xA0fo\xC3\xB3/bar" => array("/\xC3\xA0fo\xC3\xB3",'bar'), + "/\xC3\xA0foo/b\xC3\xBCr/" => array("/\xC3\xA0foo","b\xC3\xBCr"), + "foo/\xC3\xA0\xC3\xBCr" => array("foo","\xC3\xA0\xC3\xBCr"), + + ); + + foreach($strings as $input => $expected) { + + $output = URLUtil::splitPath($input); + $this->assertEquals($expected, $output, 'The expected output for \'' . $input . '\' was incorrect'); + + + } + + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/UUIDUtilTest.php b/vendor/sabre/dav/tests/Sabre/DAV/UUIDUtilTest.php new file mode 100644 index 000000000..f005ecc75 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/UUIDUtilTest.php @@ -0,0 +1,25 @@ +<?php + +namespace Sabre\DAV; + +class UUIDUtilTest extends \PHPUnit_Framework_TestCase { + + function testValidateUUID() { + + $this->assertTrue( + UUIDUtil::validateUUID('11111111-2222-3333-4444-555555555555') + ); + $this->assertFalse( + UUIDUtil::validateUUID(' 11111111-2222-3333-4444-555555555555') + ); + $this->assertTrue( + UUIDUtil::validateUUID('ffffffff-2222-3333-4444-555555555555') + ); + $this->assertFalse( + UUIDUtil::validateUUID('fffffffg-2222-3333-4444-555555555555') + ); + + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/XMLUtilTest.php b/vendor/sabre/dav/tests/Sabre/DAV/XMLUtilTest.php new file mode 100644 index 000000000..1d2bfd133 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/XMLUtilTest.php @@ -0,0 +1,284 @@ +<?php + +namespace Sabre\DAV; + +class XMLUtilTest extends \PHPUnit_Framework_TestCase { + + function testToClarkNotation() { + + $dom = new \DOMDocument(); + $dom->loadXML('<?xml version="1.0"?><test1 xmlns="http://www.example.org/">Testdoc</test1>'); + + $this->assertEquals( + '{http://www.example.org/}test1', + XMLUtil::toClarkNotation($dom->firstChild) + ); + + } + + function testToClarkNotation2() { + + $dom = new \DOMDocument(); + $dom->loadXML('<?xml version="1.0"?><s:test1 xmlns:s="http://www.example.org/">Testdoc</s:test1>'); + + $this->assertEquals( + '{http://www.example.org/}test1', + XMLUtil::toClarkNotation($dom->firstChild) + ); + + } + + function testToClarkNotationDAVNamespace() { + + $dom = new \DOMDocument(); + $dom->loadXML('<?xml version="1.0"?><s:test1 xmlns:s="urn:DAV">Testdoc</s:test1>'); + + $this->assertEquals( + '{DAV:}test1', + XMLUtil::toClarkNotation($dom->firstChild) + ); + + } + + function testToClarkNotationNoElem() { + + $dom = new \DOMDocument(); + $dom->loadXML('<?xml version="1.0"?><s:test1 xmlns:s="urn:DAV">Testdoc</s:test1>'); + + $this->assertNull( + XMLUtil::toClarkNotation($dom->firstChild->firstChild) + ); + + } + + function testConvertDAVNamespace() { + + $xml='<?xml version="1.0"?><document xmlns="DAV:">blablabla</document>'; + $this->assertEquals( + '<?xml version="1.0"?><document xmlns="urn:DAV">blablabla</document>', + XMLUtil::convertDAVNamespace($xml) + ); + + } + + function testConvertDAVNamespace2() { + + $xml='<?xml version="1.0"?><s:document xmlns:s="DAV:">blablabla</s:document>'; + $this->assertEquals( + '<?xml version="1.0"?><s:document xmlns:s="urn:DAV">blablabla</s:document>', + XMLUtil::convertDAVNamespace($xml) + ); + + } + + function testConvertDAVNamespace3() { + + $xml='<?xml version="1.0"?><s:document xmlns="http://bla" xmlns:s="DAV:" xmlns:z="http://othernamespace">blablabla</s:document>'; + $this->assertEquals( + '<?xml version="1.0"?><s:document xmlns="http://bla" xmlns:s="urn:DAV" xmlns:z="http://othernamespace">blablabla</s:document>', + XMLUtil::convertDAVNamespace($xml) + ); + + } + + function testConvertDAVNamespace4() { + + $xml='<?xml version="1.0"?><document xmlns=\'DAV:\'>blablabla</document>'; + $this->assertEquals( + '<?xml version="1.0"?><document xmlns=\'urn:DAV\'>blablabla</document>', + XMLUtil::convertDAVNamespace($xml) + ); + + } + + function testConvertDAVNamespaceMixedQuotes() { + + $xml='<?xml version="1.0"?><document xmlns=\'DAV:" xmlns="Another attribute\'>blablabla</document>'; + $this->assertEquals( + $xml, + XMLUtil::convertDAVNamespace($xml) + ); + + } + + /** + * @depends testConvertDAVNamespace + */ + function testLoadDOMDocument() { + + $xml='<?xml version="1.0"?><document></document>'; + $dom = XMLUtil::loadDOMDocument($xml); + $this->assertTrue($dom instanceof \DOMDocument); + + } + + /** + * @depends testLoadDOMDocument + * @expectedException Sabre\DAV\Exception\BadRequest + */ + function testLoadDOMDocumentEmpty() { + + XMLUtil::loadDOMDocument(''); + + } + + /** + * @expectedException Sabre\DAV\Exception\BadRequest + * @depends testConvertDAVNamespace + */ + function testLoadDOMDocumentInvalid() { + + $xml='<?xml version="1.0"?><document></docu'; + $dom = XMLUtil::loadDOMDocument($xml); + + } + + /** + * @depends testLoadDOMDocument + */ + function testLoadDOMDocumentUTF16() { + + $xml='<?xml version="1.0" encoding="UTF-16"?><root xmlns="DAV:">blabla</root>'; + $xml = iconv('UTF-8','UTF-16LE',$xml); + $dom = XMLUtil::loadDOMDocument($xml); + $this->assertEquals('blabla',$dom->firstChild->nodeValue); + + } + + + function testParseProperties() { + + $xml='<?xml version="1.0"?> +<root xmlns="DAV:"> + <prop> + <displayname>Calendars</displayname> + </prop> +</root>'; + + $dom = XMLUtil::loadDOMDocument($xml); + $properties = XMLUtil::parseProperties($dom->firstChild); + + $this->assertEquals(array( + '{DAV:}displayname' => 'Calendars', + ), $properties); + + + + } + + /** + * @depends testParseProperties + */ + function testParsePropertiesEmpty() { + + $xml='<?xml version="1.0"?> +<root xmlns="DAV:" xmlns:s="http://www.rooftopsolutions.nl/example"> + <prop> + <displayname>Calendars</displayname> + </prop> + <prop> + <s:example /> + </prop> +</root>'; + + $dom = XMLUtil::loadDOMDocument($xml); + $properties = XMLUtil::parseProperties($dom->firstChild); + + $this->assertEquals(array( + '{DAV:}displayname' => 'Calendars', + '{http://www.rooftopsolutions.nl/example}example' => null + ), $properties); + + } + + + /** + * @depends testParseProperties + */ + function testParsePropertiesComplex() { + + $xml='<?xml version="1.0"?> +<root xmlns="DAV:"> + <prop> + <displayname>Calendars</displayname> + </prop> + <prop> + <someprop>Complex value <b>right here</b></someprop> + </prop> +</root>'; + + $dom = XMLUtil::loadDOMDocument($xml); + $properties = XMLUtil::parseProperties($dom->firstChild); + + $this->assertEquals(array( + '{DAV:}displayname' => 'Calendars', + '{DAV:}someprop' => 'Complex value right here', + ), $properties); + + } + + + /** + * @depends testParseProperties + */ + function testParsePropertiesNoProperties() { + + $xml='<?xml version="1.0"?> +<root xmlns="DAV:"> + <prop> + </prop> +</root>'; + + $dom = XMLUtil::loadDOMDocument($xml); + $properties = XMLUtil::parseProperties($dom->firstChild); + + $this->assertEquals(array(), $properties); + + } + + function testParsePropertiesMapHref() { + + $xml='<?xml version="1.0"?> +<root xmlns="DAV:"> + <prop> + <displayname>Calendars</displayname> + </prop> + <prop> + <someprop><href>http://sabredav.org/</href></someprop> + </prop> +</root>'; + + $dom = XMLUtil::loadDOMDocument($xml); + $properties = XMLUtil::parseProperties($dom->firstChild,array('{DAV:}someprop'=>'Sabre\\DAV\\Property\\Href')); + + $this->assertEquals(array( + '{DAV:}displayname' => 'Calendars', + '{DAV:}someprop' => new Property\Href('http://sabredav.org/',false), + ), $properties); + + } + + function testParseClarkNotation() { + + $this->assertEquals(array( + 'DAV:', + 'foo', + ), XMLUtil::parseClarkNotation('{DAV:}foo')); + + $this->assertEquals(array( + 'http://example.org/ns/bla', + 'bar-soap', + ), XMLUtil::parseClarkNotation('{http://example.org/ns/bla}bar-soap')); + } + + /** + * @expectedException InvalidArgumentException + */ + function testParseClarkNotationFail() { + + XMLUtil::parseClarkNotation('}foo'); + + } + +} + diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php new file mode 100644 index 000000000..9960180a3 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php @@ -0,0 +1,331 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + +class ACLMethodTest extends \PHPUnit_Framework_TestCase { + + /** + * @expectedException Sabre\DAV\Exception\BadRequest + */ + function testCallback() { + + $acl = new Plugin(); + $server = new DAV\Server(); + $server->addPlugin($acl); + + $acl->unknownMethod('ACL','test'); + + } + + function testCallbackPassthru() { + + $acl = new Plugin(); + $server = new DAV\Server(); + $server->addPlugin($acl); + + $this->assertNull($acl->unknownMethod('FOO','test')); + + } + + /** + + /** + * @expectedException Sabre\DAV\Exception\MethodNotAllowed + */ + function testNotSupportedByNode() { + + $tree = array( + new DAV\SimpleCollection('test'), + ); + $acl = new Plugin(); + $server = new DAV\Server($tree); + $server->httpRequest = new HTTP\Request(); + $body = '<?xml version="1.0"?> +<d:acl xmlns:d="DAV:"> +</d:acl>'; + $server->httpRequest->setBody($body); + $server->addPlugin($acl); + + $acl->httpACL('test'); + + } + + function testSuccessSimple() { + + $tree = array( + new MockACLNode('test',array()), + ); + $acl = new Plugin(); + $server = new DAV\Server($tree); + $server->httpRequest = new HTTP\Request(); + $body = '<?xml version="1.0"?> +<d:acl xmlns:d="DAV:"> +</d:acl>'; + $server->httpRequest->setBody($body); + $server->addPlugin($acl); + + $this->assertNull($acl->httpACL('test')); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NotRecognizedPrincipal + */ + function testUnrecognizedPrincipal() { + + $tree = array( + new MockACLNode('test',array()), + ); + $acl = new Plugin(); + $server = new DAV\Server($tree); + $server->httpRequest = new HTTP\Request(); + $body = '<?xml version="1.0"?> +<d:acl xmlns:d="DAV:"> + <d:ace> + <d:grant><d:privilege><d:read /></d:privilege></d:grant> + <d:principal><d:href>/principals/notfound</d:href></d:principal> + </d:ace> +</d:acl>'; + $server->httpRequest->setBody($body); + $server->addPlugin($acl); + + $acl->httpACL('test'); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NotRecognizedPrincipal + */ + function testUnrecognizedPrincipal2() { + + $tree = array( + new MockACLNode('test',array()), + new DAV\SimpleCollection('principals',array( + new DAV\SimpleCollection('notaprincipal'), + )), + ); + $acl = new Plugin(); + $server = new DAV\Server($tree); + $server->httpRequest = new HTTP\Request(); + $body = '<?xml version="1.0"?> +<d:acl xmlns:d="DAV:"> + <d:ace> + <d:grant><d:privilege><d:read /></d:privilege></d:grant> + <d:principal><d:href>/principals/notaprincipal</d:href></d:principal> + </d:ace> +</d:acl>'; + $server->httpRequest->setBody($body); + $server->addPlugin($acl); + + $acl->httpACL('test'); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NotSupportedPrivilege + */ + function testUnknownPrivilege() { + + $tree = array( + new MockACLNode('test',array()), + ); + $acl = new Plugin(); + $server = new DAV\Server($tree); + $server->httpRequest = new HTTP\Request(); + $body = '<?xml version="1.0"?> +<d:acl xmlns:d="DAV:"> + <d:ace> + <d:grant><d:privilege><d:bananas /></d:privilege></d:grant> + <d:principal><d:href>/principals/notfound</d:href></d:principal> + </d:ace> +</d:acl>'; + $server->httpRequest->setBody($body); + $server->addPlugin($acl); + + $acl->httpACL('test'); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NoAbstract + */ + function testAbstractPrivilege() { + + $tree = array( + new MockACLNode('test',array()), + ); + $acl = new Plugin(); + $server = new DAV\Server($tree); + $server->httpRequest = new HTTP\Request(); + $body = '<?xml version="1.0"?> +<d:acl xmlns:d="DAV:"> + <d:ace> + <d:grant><d:privilege><d:read-acl /></d:privilege></d:grant> + <d:principal><d:href>/principals/notfound</d:href></d:principal> + </d:ace> +</d:acl>'; + $server->httpRequest->setBody($body); + $server->addPlugin($acl); + + $acl->httpACL('test'); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\AceConflict + */ + function testUpdateProtectedPrivilege() { + + $oldACL = array( + array( + 'principal' => 'principals/notfound', + 'privilege' => '{DAV:}write', + 'protected' => true, + ), + ); + + $tree = array( + new MockACLNode('test',$oldACL), + ); + $acl = new Plugin(); + $server = new DAV\Server($tree); + $server->httpRequest = new HTTP\Request(); + $body = '<?xml version="1.0"?> +<d:acl xmlns:d="DAV:"> + <d:ace> + <d:grant><d:privilege><d:read /></d:privilege></d:grant> + <d:principal><d:href>/principals/notfound</d:href></d:principal> + </d:ace> +</d:acl>'; + $server->httpRequest->setBody($body); + $server->addPlugin($acl); + + $acl->httpACL('test'); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\AceConflict + */ + function testUpdateProtectedPrivilege2() { + + $oldACL = array( + array( + 'principal' => 'principals/notfound', + 'privilege' => '{DAV:}write', + 'protected' => true, + ), + ); + + $tree = array( + new MockACLNode('test',$oldACL), + ); + $acl = new Plugin(); + $server = new DAV\Server($tree); + $server->httpRequest = new HTTP\Request(); + $body = '<?xml version="1.0"?> +<d:acl xmlns:d="DAV:"> + <d:ace> + <d:grant><d:privilege><d:write /></d:privilege></d:grant> + <d:principal><d:href>/principals/foo</d:href></d:principal> + </d:ace> +</d:acl>'; + $server->httpRequest->setBody($body); + $server->addPlugin($acl); + + $acl->httpACL('test'); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\AceConflict + */ + function testUpdateProtectedPrivilege3() { + + $oldACL = array( + array( + 'principal' => 'principals/notfound', + 'privilege' => '{DAV:}write', + 'protected' => true, + ), + ); + + $tree = array( + new MockACLNode('test',$oldACL), + ); + $acl = new Plugin(); + $server = new DAV\Server($tree); + $server->httpRequest = new HTTP\Request(); + $body = '<?xml version="1.0"?> +<d:acl xmlns:d="DAV:"> + <d:ace> + <d:grant><d:privilege><d:write /></d:privilege></d:grant> + <d:principal><d:href>/principals/notfound</d:href></d:principal> + </d:ace> +</d:acl>'; + $server->httpRequest->setBody($body); + $server->addPlugin($acl); + + $acl->httpACL('test'); + + } + + function testSuccessComplex () { + + $oldACL = array( + array( + 'principal' => 'principals/foo', + 'privilege' => '{DAV:}write', + 'protected' => true, + ), + array( + 'principal' => 'principals/bar', + 'privilege' => '{DAV:}read', + ), + ); + + $tree = array( + $node = new MockACLNode('test',$oldACL), + new DAV\SimpleCollection('principals', array( + new MockPrincipal('foo','principals/foo'), + new MockPrincipal('baz','principals/baz'), + )), + ); + $acl = new Plugin(); + $server = new DAV\Server($tree); + $server->httpRequest = new HTTP\Request(); + $body = '<?xml version="1.0"?> +<d:acl xmlns:d="DAV:"> + <d:ace> + <d:grant><d:privilege><d:write /></d:privilege></d:grant> + <d:principal><d:href>/principals/foo</d:href></d:principal> + <d:protected /> + </d:ace> + <d:ace> + <d:grant><d:privilege><d:write /></d:privilege></d:grant> + <d:principal><d:href>/principals/baz</d:href></d:principal> + </d:ace> +</d:acl>'; + $server->httpRequest->setBody($body); + $server->addPlugin($acl); + + $this->assertFalse($acl->unknownMethod('ACL','test')); + + $this->assertEquals(array( + array( + 'principal' => 'principals/foo', + 'privilege' => '{DAV:}write', + 'protected' => true, + ), + array( + 'principal' => 'principals/baz', + 'privilege' => '{DAV:}write', + 'protected' => false, + ), + ), $node->getACL()); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php new file mode 100644 index 000000000..3a9b35b45 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php @@ -0,0 +1,139 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + +class AllowAccessTest extends \PHPUnit_Framework_TestCase { + + /** + * @var DAV\Server + */ + protected $server; + + function setUp() { + + $nodes = array( + new DAV\SimpleCollection('testdir'), + ); + + $this->server = new DAV\Server($nodes); + $aclPlugin = new Plugin(); + $aclPlugin->allowAccessToNodesWithoutACL = true; + $this->server->addPlugin($aclPlugin); + + } + + function testGet() { + + $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('GET','testdir'))); + + } + + function testGetDoesntExist() { + + $r = $this->server->broadcastEvent('beforeMethod',array('GET','foo')); + $this->assertTrue($r); + + } + + function testHEAD() { + + $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('HEAD','testdir'))); + + } + + function testOPTIONS() { + + $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('OPTIONS','testdir'))); + + } + + function testPUT() { + + $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('PUT','testdir'))); + + } + + function testACL() { + + $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('ACL','testdir'))); + + } + + function testPROPPATCH() { + + $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('PROPPATCH','testdir'))); + + } + + function testCOPY() { + + $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('COPY','testdir'))); + + } + + function testMOVE() { + + $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('MOVE','testdir'))); + + } + + function testLOCK() { + + $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('LOCK','testdir'))); + + } + + function testBeforeBind() { + + $this->assertTrue($this->server->broadcastEvent('beforeBind',array('testdir/file'))); + + } + + + function testBeforeUnbind() { + + $this->assertTrue($this->server->broadcastEvent('beforeUnbind',array('testdir'))); + + } + + function testAfterGetProperties() { + + $properties = array( + 'href' => 'foo', + '200' => array( + '{DAV:}displayname' => 'foo', + '{DAV:}getcontentlength' => 500, + ), + '404' => array( + '{DAV:}bar' => null, + ), + '403' => array( + '{DAV:}owner' => null, + ), + ); + + $expected = array( + 'href' => 'foo', + '200' => array( + '{DAV:}displayname' => 'foo', + '{DAV:}getcontentlength' => 500, + ), + '404' => array( + '{DAV:}bar' => null, + ), + '403' => array( + '{DAV:}owner' => null, + ), + ); + + $r = $this->server->broadcastEvent('afterGetProperties',array('testdir',&$properties)); + $this->assertTrue($r); + + $this->assertEquals($expected, $properties); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php new file mode 100644 index 000000000..345d2cc5d --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php @@ -0,0 +1,190 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + +class BlockAccessTest extends \PHPUnit_Framework_TestCase { + + /** + * @var DAV\Server + */ + protected $server; + protected $plugin; + + function setUp() { + + $nodes = array( + new DAV\SimpleCollection('testdir'), + ); + + $this->server = new DAV\Server($nodes); + $this->plugin = new Plugin(); + $this->plugin->allowAccessToNodesWithoutACL = false; + $this->server->addPlugin($this->plugin); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NeedPrivileges + */ + function testGet() { + + $this->server->broadcastEvent('beforeMethod',array('GET','testdir')); + + } + + function testGetDoesntExist() { + + $r = $this->server->broadcastEvent('beforeMethod',array('GET','foo')); + $this->assertTrue($r); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NeedPrivileges + */ + function testHEAD() { + + $this->server->broadcastEvent('beforeMethod',array('HEAD','testdir')); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NeedPrivileges + */ + function testOPTIONS() { + + $this->server->broadcastEvent('beforeMethod',array('OPTIONS','testdir')); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NeedPrivileges + */ + function testPUT() { + + $this->server->broadcastEvent('beforeMethod',array('PUT','testdir')); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NeedPrivileges + */ + function testPROPPATCH() { + + $this->server->broadcastEvent('beforeMethod',array('PROPPATCH','testdir')); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NeedPrivileges + */ + function testCOPY() { + + $this->server->broadcastEvent('beforeMethod',array('COPY','testdir')); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NeedPrivileges + */ + function testMOVE() { + + $this->server->broadcastEvent('beforeMethod',array('MOVE','testdir')); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NeedPrivileges + */ + function testACL() { + + $this->server->broadcastEvent('beforeMethod',array('ACL','testdir')); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NeedPrivileges + */ + function testLOCK() { + + $this->server->broadcastEvent('beforeMethod',array('LOCK','testdir')); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NeedPrivileges + */ + function testBeforeBind() { + + $this->server->broadcastEvent('beforeBind',array('testdir/file')); + + } + + /** + * @expectedException Sabre\DAVACL\Exception\NeedPrivileges + */ + function testBeforeUnbind() { + + $this->server->broadcastEvent('beforeUnbind',array('testdir')); + + } + + function testBeforeGetProperties() { + + $requestedProperties = array( + '{DAV:}displayname', + '{DAV:}getcontentlength', + '{DAV:}bar', + '{DAV:}owner', + ); + $returnedProperties = array(); + + $arguments = array( + 'testdir', + new DAV\SimpleCollection('testdir'), + &$requestedProperties, + &$returnedProperties + ); + $r = $this->server->broadcastEvent('beforeGetProperties',$arguments); + $this->assertTrue($r); + + $expected = array( + '403' => array( + '{DAV:}displayname' => null, + '{DAV:}getcontentlength' => null, + '{DAV:}bar' => null, + '{DAV:}owner' => null, + ), + ); + + $this->assertEquals($expected, $returnedProperties); + $this->assertEquals(array(), $requestedProperties); + + } + + function testBeforeGetPropertiesNoListing() { + + $this->plugin->hideNodesFromListings = true; + + $requestedProperties = array( + '{DAV:}displayname', + '{DAV:}getcontentlength', + '{DAV:}bar', + '{DAV:}owner', + ); + $returnedProperties = array(); + + $arguments = array( + 'testdir', + new DAV\SimpleCollection('testdir'), + &$requestedProperties, + &$returnedProperties + ); + $r = $this->server->broadcastEvent('beforeGetProperties',$arguments); + $this->assertFalse($r); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php new file mode 100644 index 000000000..fc48af67f --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php @@ -0,0 +1,39 @@ +<?php + +namespace Sabre\DAVACL\Exception; + +use Sabre\DAV; + +class AceConflictTest extends \PHPUnit_Framework_TestCase { + + function testSerialize() { + + $ex = new AceConflict('message'); + + $server = new DAV\Server(); + $dom = new \DOMDocument('1.0','utf-8'); + $root = $dom->createElementNS('DAV:','d:root'); + $dom->appendChild($root); + + $ex->serialize($server, $root); + + $xpaths = array( + '/d:root' => 1, + '/d:root/d:no-ace-conflict' => 1, + ); + + // Reloading because PHP DOM sucks + $dom2 = new \DOMDocument('1.0', 'utf-8'); + $dom2->loadXML($dom->saveXML()); + + $dxpath = new \DOMXPath($dom2); + $dxpath->registerNamespace('d','DAV:'); + foreach($xpaths as $xpath=>$count) { + + $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count); + + } + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php new file mode 100644 index 000000000..7e66adab6 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php @@ -0,0 +1,49 @@ +<?php + +namespace Sabre\DAVACL\Exception; + +use Sabre\DAV; + +class NeedPrivilegesTest extends \PHPUnit_Framework_TestCase { + + function testSerialize() { + + $uri = 'foo'; + $privileges = array( + '{DAV:}read', + '{DAV:}write', + ); + $ex = new NeedPrivileges($uri, $privileges); + + $server = new DAV\Server(); + $dom = new \DOMDocument('1.0','utf-8'); + $root = $dom->createElementNS('DAV:','d:root'); + $dom->appendChild($root); + + $ex->serialize($server, $root); + + $xpaths = array( + '/d:root' => 1, + '/d:root/d:need-privileges' => 1, + '/d:root/d:need-privileges/d:resource' => 2, + '/d:root/d:need-privileges/d:resource/d:href' => 2, + '/d:root/d:need-privileges/d:resource/d:privilege' => 2, + '/d:root/d:need-privileges/d:resource/d:privilege/d:read' => 1, + '/d:root/d:need-privileges/d:resource/d:privilege/d:write' => 1, + ); + + // Reloading because PHP DOM sucks + $dom2 = new \DOMDocument('1.0', 'utf-8'); + $dom2->loadXML($dom->saveXML()); + + $dxpath = new \DOMXPath($dom2); + $dxpath->registerNamespace('d','DAV:'); + foreach($xpaths as $xpath=>$count) { + + $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count); + + } + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php new file mode 100644 index 000000000..2406c1c38 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php @@ -0,0 +1,39 @@ +<?php + +namespace Sabre\DAVACL\Exception; + +use Sabre\DAV; + +class NoAbstractTest extends \PHPUnit_Framework_TestCase { + + function testSerialize() { + + $ex = new NoAbstract('message'); + + $server = new DAV\Server(); + $dom = new \DOMDocument('1.0','utf-8'); + $root = $dom->createElementNS('DAV:','d:root'); + $dom->appendChild($root); + + $ex->serialize($server, $root); + + $xpaths = array( + '/d:root' => 1, + '/d:root/d:no-abstract' => 1, + ); + + // Reloading because PHP DOM sucks + $dom2 = new \DOMDocument('1.0', 'utf-8'); + $dom2->loadXML($dom->saveXML()); + + $dxpath = new \DOMXPath($dom2); + $dxpath->registerNamespace('d','DAV:'); + foreach($xpaths as $xpath=>$count) { + + $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count); + + } + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php new file mode 100644 index 000000000..6077b0ba5 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php @@ -0,0 +1,39 @@ +<?php + +namespace Sabre\DAVACL\Exception; + +use Sabre\DAV; + +class NotRecognizedPrincipalTest extends \PHPUnit_Framework_TestCase { + + function testSerialize() { + + $ex = new NotRecognizedPrincipal('message'); + + $server = new DAV\Server(); + $dom = new \DOMDocument('1.0','utf-8'); + $root = $dom->createElementNS('DAV:','d:root'); + $dom->appendChild($root); + + $ex->serialize($server, $root); + + $xpaths = array( + '/d:root' => 1, + '/d:root/d:recognized-principal' => 1, + ); + + // Reloading because PHP DOM sucks + $dom2 = new \DOMDocument('1.0', 'utf-8'); + $dom2->loadXML($dom->saveXML()); + + $dxpath = new \DOMXPath($dom2); + $dxpath->registerNamespace('d','DAV:'); + foreach($xpaths as $xpath=>$count) { + + $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count); + + } + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php new file mode 100644 index 000000000..8e7b3685d --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php @@ -0,0 +1,39 @@ +<?php + +namespace Sabre\DAVACL\Exception; + +use Sabre\DAV; + +class NotSupportedPrivilegeTest extends \PHPUnit_Framework_TestCase { + + function testSerialize() { + + $ex = new NotSupportedPrivilege('message'); + + $server = new DAV\Server(); + $dom = new \DOMDocument('1.0','utf-8'); + $root = $dom->createElementNS('DAV:','d:root'); + $dom->appendChild($root); + + $ex->serialize($server, $root); + + $xpaths = array( + '/d:root' => 1, + '/d:root/d:not-supported-privilege' => 1, + ); + + // Reloading because PHP DOM sucks + $dom2 = new \DOMDocument('1.0', 'utf-8'); + $dom2->loadXML($dom->saveXML()); + + $dxpath = new \DOMXPath($dom2); + $dxpath->registerNamespace('d','DAV:'); + foreach($xpaths as $xpath=>$count) { + + $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count); + + } + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php new file mode 100644 index 000000000..324788d4a --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php @@ -0,0 +1,358 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class ExpandPropertiesTest extends \PHPUnit_Framework_TestCase { + + function getServer() { + + $tree = array( + new MockPropertyNode('node1', array( + '{http://sabredav.org/ns}simple' => 'foo', + '{http://sabredav.org/ns}href' => new DAV\Property\Href('node2'), + '{DAV:}displayname' => 'Node 1', + )), + new MockPropertyNode('node2', array( + '{http://sabredav.org/ns}simple' => 'simple', + '{http://sabredav.org/ns}hreflist' => new DAV\Property\HrefList(array('node1','node3')), + '{DAV:}displayname' => 'Node 2', + )), + new MockPropertyNode('node3', array( + '{http://sabredav.org/ns}simple' => 'simple', + '{DAV:}displayname' => 'Node 3', + )), + ); + + $fakeServer = new DAV\Server($tree); + $fakeServer->debugExceptions = true; + $fakeServer->httpResponse = new HTTP\ResponseMock(); + $plugin = new Plugin(); + $plugin->allowAccessToNodesWithoutACL = true; + + $this->assertTrue($plugin instanceof Plugin); + $fakeServer->addPlugin($plugin); + $this->assertEquals($plugin, $fakeServer->getPlugin('acl')); + + return $fakeServer; + + } + + function testSimple() { + + $xml = '<?xml version="1.0"?> +<d:expand-property xmlns:d="DAV:"> + <d:property name="displayname" /> + <d:property name="foo" namespace="http://www.sabredav.org/NS/2010/nonexistant" /> + <d:property name="simple" namespace="http://sabredav.org/ns" /> + <d:property name="href" namespace="http://sabredav.org/ns" /> +</d:expand-property>'; + + $serverVars = array( + 'REQUEST_METHOD' => 'REPORT', + 'HTTP_DEPTH' => '0', + 'REQUEST_URI' => '/node1', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($xml); + + $server = $this->getServer(); + $server->httpRequest = $request; + + $server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status,'Incorrect status code received. Full body: ' . $server->httpResponse->body); + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), $server->httpResponse->headers); + + + $check = array( + '/d:multistatus', + '/d:multistatus/d:response' => 1, + '/d:multistatus/d:response/d:href' => 1, + '/d:multistatus/d:response/d:propstat' => 2, + '/d:multistatus/d:response/d:propstat/d:prop' => 2, + '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:simple' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:href' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:href' => 1, + ); + + $xml = simplexml_load_string($server->httpResponse->body); + $xml->registerXPathNamespace('d','DAV:'); + $xml->registerXPathNamespace('s','http://sabredav.org/ns'); + foreach($check as $v1=>$v2) { + + $xpath = is_int($v1)?$v2:$v1; + + $result = $xml->xpath($xpath); + + $count = 1; + if (!is_int($v1)) $count = $v2; + + $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response: ' . $server->httpResponse->body); + + } + + } + + /** + * @depends testSimple + */ + function testExpand() { + + $xml = '<?xml version="1.0"?> +<d:expand-property xmlns:d="DAV:"> + <d:property name="href" namespace="http://sabredav.org/ns"> + <d:property name="displayname" /> + </d:property> +</d:expand-property>'; + + $serverVars = array( + 'REQUEST_METHOD' => 'REPORT', + 'HTTP_DEPTH' => '0', + 'REQUEST_URI' => '/node1', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($xml); + + $server = $this->getServer(); + $server->httpRequest = $request; + + $server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status, 'Incorrect response status received. Full response body: ' . $server->httpResponse->body); + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), $server->httpResponse->headers); + + + $check = array( + '/d:multistatus', + '/d:multistatus/d:response' => 1, + '/d:multistatus/d:response/d:href' => 1, + '/d:multistatus/d:response/d:propstat' => 1, + '/d:multistatus/d:response/d:propstat/d:prop' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:href' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:href' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop/d:displayname' => 1, + ); + + $xml = simplexml_load_string($server->httpResponse->body); + $xml->registerXPathNamespace('d','DAV:'); + $xml->registerXPathNamespace('s','http://sabredav.org/ns'); + foreach($check as $v1=>$v2) { + + $xpath = is_int($v1)?$v2:$v1; + + $result = $xml->xpath($xpath); + + $count = 1; + if (!is_int($v1)) $count = $v2; + + $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result)); + + } + + } + + /** + * @depends testSimple + */ + function testExpandHrefList() { + + $xml = '<?xml version="1.0"?> +<d:expand-property xmlns:d="DAV:"> + <d:property name="hreflist" namespace="http://sabredav.org/ns"> + <d:property name="displayname" /> + </d:property> +</d:expand-property>'; + + $serverVars = array( + 'REQUEST_METHOD' => 'REPORT', + 'HTTP_DEPTH' => '0', + 'REQUEST_URI' => '/node2', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($xml); + + $server = $this->getServer(); + $server->httpRequest = $request; + + $server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status); + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), $server->httpResponse->headers); + + + $check = array( + '/d:multistatus', + '/d:multistatus/d:response' => 1, + '/d:multistatus/d:response/d:href' => 1, + '/d:multistatus/d:response/d:propstat' => 1, + '/d:multistatus/d:response/d:propstat/d:prop' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response' => 2, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:href' => 2, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat' => 2, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop' => 2, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/d:displayname' => 2, + ); + + $xml = simplexml_load_string($server->httpResponse->body); + $xml->registerXPathNamespace('d','DAV:'); + $xml->registerXPathNamespace('s','http://sabredav.org/ns'); + foreach($check as $v1=>$v2) { + + $xpath = is_int($v1)?$v2:$v1; + + $result = $xml->xpath($xpath); + + $count = 1; + if (!is_int($v1)) $count = $v2; + + $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result)); + + } + + } + + /** + * @depends testExpand + */ + function testExpandDeep() { + + $xml = '<?xml version="1.0"?> +<d:expand-property xmlns:d="DAV:"> + <d:property name="hreflist" namespace="http://sabredav.org/ns"> + <d:property name="href" namespace="http://sabredav.org/ns"> + <d:property name="displayname" /> + </d:property> + <d:property name="displayname" /> + </d:property> +</d:expand-property>'; + + $serverVars = array( + 'REQUEST_METHOD' => 'REPORT', + 'HTTP_DEPTH' => '0', + 'REQUEST_URI' => '/node2', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($xml); + + $server = $this->getServer(); + $server->httpRequest = $request; + + $server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status); + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), $server->httpResponse->headers); + + + $check = array( + '/d:multistatus', + '/d:multistatus/d:response' => 1, + '/d:multistatus/d:response/d:href' => 1, + '/d:multistatus/d:response/d:propstat' => 1, + '/d:multistatus/d:response/d:propstat/d:prop' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response' => 2, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:href' => 2, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat' => 3, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop' => 3, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/d:displayname' => 2, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href' => 2, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:href' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop' => 1, + '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop/d:displayname' => 1, + ); + + $xml = simplexml_load_string($server->httpResponse->body); + $xml->registerXPathNamespace('d','DAV:'); + $xml->registerXPathNamespace('s','http://sabredav.org/ns'); + foreach($check as $v1=>$v2) { + + $xpath = is_int($v1)?$v2:$v1; + + $result = $xml->xpath($xpath); + + $count = 1; + if (!is_int($v1)) $count = $v2; + + $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result)); + + } + + } +} +class MockPropertyNode implements DAV\INode, DAV\IProperties { + + function __construct($name, array $properties) { + + $this->name = $name; + $this->properties = $properties; + + } + + function getName() { + + return $this->name; + + } + + function getProperties($requestedProperties) { + + $returnedProperties = array(); + foreach($requestedProperties as $requestedProperty) { + if (isset($this->properties[$requestedProperty])) { + $returnedProperties[$requestedProperty] = + $this->properties[$requestedProperty]; + } + } + return $returnedProperties; + + } + + function delete() { + + throw new DAV\Exception('Not implemented'); + + } + + function setName($name) { + + throw new DAV\Exception('Not implemented'); + + } + + function getLastModified() { + + return null; + + } + + function updateProperties($properties) { + + throw new DAV\Exception('Not implemented'); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php b/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php new file mode 100644 index 000000000..7b3e8fc12 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php @@ -0,0 +1,56 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + +class MockACLNode extends DAV\Node implements IACL { + + public $name; + public $acl; + + function __construct($name, array $acl = array()) { + + $this->name = $name; + $this->acl = $acl; + + } + + function getName() { + + return $this->name; + + } + + function getOwner() { + + return null; + + } + + function getGroup() { + + return null; + + } + + function getACL() { + + return $this->acl; + + } + + function setACL(array $acl) { + + $this->acl = $acl; + + } + + function getSupportedPrivilegeSet() { + + return null; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php b/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php new file mode 100644 index 000000000..dd8542b8d --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php @@ -0,0 +1,66 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + +class MockPrincipal extends DAV\Node implements IPrincipal { + + public $name; + public $principalUrl; + public $groupMembership = array(); + public $groupMemberSet = array(); + + function __construct($name,$principalUrl,array $groupMembership = array(), array $groupMemberSet = array()) { + + $this->name = $name; + $this->principalUrl = $principalUrl; + $this->groupMembership = $groupMembership; + $this->groupMemberSet = $groupMemberSet; + + } + + function getName() { + + return $this->name; + + } + + function getDisplayName() { + + return $this->getName(); + + } + + function getAlternateUriSet() { + + return array(); + + } + + function getPrincipalUrl() { + + return $this->principalUrl; + + } + + function getGroupMemberSet() { + + return $this->groupMemberSet; + + } + + function getGroupMemberShip() { + + return $this->groupMembership; + + } + + function setGroupMemberSet(array $groupMemberSet) { + + $this->groupMemberSet = $groupMemberSet; + + } +} + diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php new file mode 100644 index 000000000..23c4b6e85 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php @@ -0,0 +1,83 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + + +require_once 'Sabre/DAVACL/MockACLNode.php'; +require_once 'Sabre/HTTP/ResponseMock.php'; + +class PluginAdminTest extends \PHPUnit_Framework_TestCase { + + function testNoAdminAccess() { + + $principalBackend = new PrincipalBackend\Mock(); + + $tree = array( + new MockACLNode('adminonly', array()), + new PrincipalCollection($principalBackend), + ); + + $fakeServer = new DAV\Server($tree); + $plugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'realm'); + $fakeServer->addPlugin($plugin); + $plugin = new Plugin(); + $fakeServer->addPlugin($plugin); + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'OPTIONS', + 'HTTP_DEPTH' => 1, + 'REQUEST_URI' => '/adminonly', + )); + + $response = new HTTP\ResponseMock(); + + $fakeServer->httpRequest = $request; + $fakeServer->httpResponse = $response; + + $fakeServer->exec(); + + $this->assertEquals('HTTP/1.1 403 Forbidden', $response->status); + + } + + /** + * @depends testNoAdminAccess + */ + function testAdminAccess() { + + $principalBackend = new PrincipalBackend\Mock(); + + $tree = array( + new MockACLNode('adminonly', array()), + new PrincipalCollection($principalBackend), + ); + + $fakeServer = new DAV\Server($tree); + $plugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'realm'); + $fakeServer->addPlugin($plugin); + $plugin = new Plugin(); + $plugin->adminPrincipals = array( + 'principals/admin', + ); + $fakeServer->addPlugin($plugin); + + $request = new HTTP\Request(array( + 'REQUEST_METHOD' => 'OPTIONS', + 'HTTP_DEPTH' => 1, + 'REQUEST_URI' => '/adminonly', + )); + + $response = new HTTP\ResponseMock(); + + $fakeServer->httpRequest = $request; + $fakeServer->httpResponse = $response; + + $fakeServer->exec(); + + $this->assertEquals('HTTP/1.1 200 OK', $response->status); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php new file mode 100644 index 000000000..8c0626e50 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php @@ -0,0 +1,407 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + + +class PluginPropertiesTest extends \PHPUnit_Framework_TestCase { + + function testPrincipalCollectionSet() { + + $plugin = new Plugin(); + $plugin->principalCollectionSet = array( + 'principals1', + 'principals2', + ); + + $requestedProperties = array( + '{DAV:}principal-collection-set', + ); + + $returnedProperties = array( + 200 => array(), + 404 => array(), + ); + + $server = new DAV\Server(); + $server->addPlugin($plugin); + + $this->assertNull($plugin->beforeGetProperties('', new DAV\SimpleCollection('root'), $requestedProperties, $returnedProperties)); + + $this->assertEquals(1,count($returnedProperties[200])); + $this->assertArrayHasKey('{DAV:}principal-collection-set',$returnedProperties[200]); + $this->assertInstanceOf('Sabre\\DAV\\Property\\HrefList', $returnedProperties[200]['{DAV:}principal-collection-set']); + + $expected = array( + 'principals1/', + 'principals2/', + ); + + + $this->assertEquals($expected, $returnedProperties[200]['{DAV:}principal-collection-set']->getHrefs()); + + + } + + function testCurrentUserPrincipal() { + + $fakeServer = new DAV\Server(); + $plugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'realm'); + $fakeServer->addPlugin($plugin); + $plugin = new Plugin(); + $fakeServer->addPlugin($plugin); + + + $requestedProperties = array( + '{DAV:}current-user-principal', + ); + + $returnedProperties = array( + 200 => array(), + 404 => array(), + ); + + $this->assertNull($plugin->beforeGetProperties('', new DAV\SimpleCollection('root'), $requestedProperties, $returnedProperties)); + + $this->assertEquals(1,count($returnedProperties[200])); + $this->assertArrayHasKey('{DAV:}current-user-principal',$returnedProperties[200]); + $this->assertInstanceOf('Sabre\DAVACL\Property\Principal', $returnedProperties[200]['{DAV:}current-user-principal']); + $this->assertEquals(Property\Principal::UNAUTHENTICATED, $returnedProperties[200]['{DAV:}current-user-principal']->getType()); + + // This will force the login + $fakeServer->broadCastEvent('beforeMethod',array('GET','')); + + + $requestedProperties = array( + '{DAV:}current-user-principal', + ); + + $returnedProperties = array( + 200 => array(), + 404 => array(), + ); + + + $this->assertNull($plugin->beforeGetProperties('', new DAV\SimpleCollection('root'), $requestedProperties, $returnedProperties)); + + + $this->assertEquals(1,count($returnedProperties[200])); + $this->assertArrayHasKey('{DAV:}current-user-principal',$returnedProperties[200]); + $this->assertInstanceOf('Sabre\DAVACL\Property\Principal', $returnedProperties[200]['{DAV:}current-user-principal']); + $this->assertEquals(Property\Principal::HREF, $returnedProperties[200]['{DAV:}current-user-principal']->getType()); + $this->assertEquals('principals/admin/', $returnedProperties[200]['{DAV:}current-user-principal']->getHref()); + + } + + function testSupportedPrivilegeSet() { + + $plugin = new Plugin(); + $server = new DAV\Server(); + $server->addPlugin($plugin); + + $requestedProperties = array( + '{DAV:}supported-privilege-set', + ); + + $returnedProperties = array( + 200 => array(), + 404 => array(), + ); + + + $this->assertNull($plugin->beforeGetProperties('', new DAV\SimpleCollection('root'), $requestedProperties, $returnedProperties)); + + $this->assertEquals(1,count($returnedProperties[200])); + $this->assertArrayHasKey('{DAV:}supported-privilege-set',$returnedProperties[200]); + $this->assertInstanceOf('Sabre\\DAVACL\\Property\\SupportedPrivilegeSet', $returnedProperties[200]['{DAV:}supported-privilege-set']); + + $server = new DAV\Server(); + $prop = $returnedProperties[200]['{DAV:}supported-privilege-set']; + + $dom = new \DOMDocument('1.0', 'utf-8'); + $root = $dom->createElement('d:root'); + $root->setAttribute('xmlns:d','DAV:'); + $dom->appendChild($root); + $prop->serialize($server, $root); + + + $xpaths = array( + '/d:root' => 1, + '/d:root/d:supported-privilege' => 1, + '/d:root/d:supported-privilege/d:privilege' => 1, + '/d:root/d:supported-privilege/d:privilege/d:all' => 1, + '/d:root/d:supported-privilege/d:abstract' => 1, + '/d:root/d:supported-privilege/d:supported-privilege' => 2, + '/d:root/d:supported-privilege/d:supported-privilege/d:privilege' => 2, + '/d:root/d:supported-privilege/d:supported-privilege/d:privilege/d:read' => 1, + '/d:root/d:supported-privilege/d:supported-privilege/d:privilege/d:write' => 1, + '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege' => 8, + '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege' => 8, + '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:read-acl' => 1, + '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:read-current-user-privilege-set' => 1, + '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-content' => 1, + '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-properties' => 1, + '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-acl' => 1, + '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:bind' => 1, + '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:unbind' => 1, + '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:unlock' => 1, + '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:abstract' => 8, + ); + + + // reloading because php dom sucks + $dom2 = new \DOMDocument('1.0', 'utf-8'); + $dom2->loadXML($dom->saveXML()); + + $dxpath = new \DOMXPath($dom2); + $dxpath->registerNamespace('d','DAV:'); + foreach($xpaths as $xpath=>$count) { + + $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count); + + } + + } + + function testACL() { + + $plugin = new Plugin(); + + $nodes = array( + new MockACLNode('foo', array( + array( + 'principal' => 'principals/admin', + 'privilege' => '{DAV:}read', + ) + )), + new DAV\SimpleCollection('principals', array( + $principal = new MockPrincipal('admin','principals/admin'), + )), + + ); + + $server = new DAV\Server($nodes); + $server->addPlugin($plugin); + $authPlugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'realm'); + $server->addPlugin($authPlugin); + + // Force login + $authPlugin->beforeMethod('BLA','foo'); + + $requestedProperties = array( + '{DAV:}acl', + ); + + $returnedProperties = array( + 200 => array(), + 404 => array(), + ); + + + $this->assertNull($plugin->beforeGetProperties('foo', $nodes[0], $requestedProperties, $returnedProperties)); + + $this->assertEquals(1,count($returnedProperties[200]),'The {DAV:}acl property did not return from the list. Full list: ' . print_r($returnedProperties,true)); + $this->assertArrayHasKey('{DAV:}acl',$returnedProperties[200]); + $this->assertInstanceOf('Sabre\\DAVACL\\Property\\ACL', $returnedProperties[200]['{DAV:}acl']); + + } + + function testACLRestrictions() { + + $plugin = new Plugin(); + + $nodes = array( + new MockACLNode('foo', array( + array( + 'principal' => 'principals/admin', + 'privilege' => '{DAV:}read', + ) + )), + new DAV\SimpleCollection('principals', array( + $principal = new MockPrincipal('admin','principals/admin'), + )), + + ); + + $server = new DAV\Server($nodes); + $server->addPlugin($plugin); + $authPlugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'realm'); + $server->addPlugin($authPlugin); + + // Force login + $authPlugin->beforeMethod('BLA','foo'); + + $requestedProperties = array( + '{DAV:}acl-restrictions', + ); + + $returnedProperties = array( + 200 => array(), + 404 => array(), + ); + + + $this->assertNull($plugin->beforeGetProperties('foo', $nodes[0], $requestedProperties, $returnedProperties)); + + $this->assertEquals(1,count($returnedProperties[200]),'The {DAV:}acl-restrictions property did not return from the list. Full list: ' . print_r($returnedProperties,true)); + $this->assertArrayHasKey('{DAV:}acl-restrictions',$returnedProperties[200]); + $this->assertInstanceOf('Sabre\\DAVACL\\Property\\ACLRestrictions', $returnedProperties[200]['{DAV:}acl-restrictions']); + + } + + function testAlternateUriSet() { + + $tree = array( + new DAV\SimpleCollection('principals', array( + $principal = new MockPrincipal('user','principals/user'), + )), + ); + + $fakeServer = new DAV\Server($tree); + //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend(),'realm'); + //$fakeServer->addPlugin($plugin); + $plugin = new Plugin(); + $fakeServer->addPlugin($plugin); + + $requestedProperties = array( + '{DAV:}alternate-URI-set', + ); + $returnedProperties = array(); + + $result = $plugin->beforeGetProperties('principals/user',$principal,$requestedProperties,$returnedProperties); + + $this->assertNull($result); + + $this->assertTrue(isset($returnedProperties[200])); + $this->assertTrue(isset($returnedProperties[200]['{DAV:}alternate-URI-set'])); + $this->assertInstanceOf('Sabre\\DAV\\Property\\HrefList', $returnedProperties[200]['{DAV:}alternate-URI-set']); + + $this->assertEquals(array(), $returnedProperties[200]['{DAV:}alternate-URI-set']->getHrefs()); + + } + + function testPrincipalURL() { + + $tree = array( + new DAV\SimpleCollection('principals', array( + $principal = new MockPrincipal('user','principals/user'), + )), + ); + + $fakeServer = new DAV\Server($tree); + //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend(),'realm'); + //$fakeServer->addPlugin($plugin); + $plugin = new Plugin(); + $fakeServer->addPlugin($plugin); + + $requestedProperties = array( + '{DAV:}principal-URL', + ); + $returnedProperties = array(); + + $result = $plugin->beforeGetProperties('principals/user',$principal,$requestedProperties,$returnedProperties); + + $this->assertNull($result); + + $this->assertTrue(isset($returnedProperties[200])); + $this->assertTrue(isset($returnedProperties[200]['{DAV:}principal-URL'])); + $this->assertInstanceOf('Sabre\\DAV\\Property\\Href', $returnedProperties[200]['{DAV:}principal-URL']); + + $this->assertEquals('principals/user/', $returnedProperties[200]['{DAV:}principal-URL']->getHref()); + + } + + function testGroupMemberSet() { + + $tree = array( + new DAV\SimpleCollection('principals', array( + $principal = new MockPrincipal('user','principals/user'), + )), + ); + + $fakeServer = new DAV\Server($tree); + //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend(),'realm'); + //$fakeServer->addPlugin($plugin); + $plugin = new Plugin(); + $fakeServer->addPlugin($plugin); + + $requestedProperties = array( + '{DAV:}group-member-set', + ); + $returnedProperties = array(); + + $result = $plugin->beforeGetProperties('principals/user',$principal,$requestedProperties,$returnedProperties); + + $this->assertNull($result); + + $this->assertTrue(isset($returnedProperties[200])); + $this->assertTrue(isset($returnedProperties[200]['{DAV:}group-member-set'])); + $this->assertInstanceOf('Sabre\\DAV\\Property\\HrefList', $returnedProperties[200]['{DAV:}group-member-set']); + + $this->assertEquals(array(), $returnedProperties[200]['{DAV:}group-member-set']->getHrefs()); + + } + + function testGroupMemberShip() { + + $tree = array( + new DAV\SimpleCollection('principals', array( + $principal = new MockPrincipal('user','principals/user'), + )), + ); + + $fakeServer = new DAV\Server($tree); + //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend(),'realm'); + //$fakeServer->addPlugin($plugin); + $plugin = new Plugin(); + $fakeServer->addPlugin($plugin); + + $requestedProperties = array( + '{DAV:}group-membership', + ); + $returnedProperties = array(); + + $result = $plugin->beforeGetProperties('principals/user',$principal,$requestedProperties,$returnedProperties); + + $this->assertNull($result); + + $this->assertTrue(isset($returnedProperties[200])); + $this->assertTrue(isset($returnedProperties[200]['{DAV:}group-membership'])); + $this->assertInstanceOf('Sabre\\DAV\\Property\\HrefList', $returnedProperties[200]['{DAV:}group-membership']); + + $this->assertEquals(array(), $returnedProperties[200]['{DAV:}group-membership']->getHrefs()); + + } + + function testGetDisplayName() { + + $tree = array( + new DAV\SimpleCollection('principals', array( + $principal = new MockPrincipal('user','principals/user'), + )), + ); + + $fakeServer = new DAV\Server($tree); + //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend(),'realm'); + //$fakeServer->addPlugin($plugin); + $plugin = new Plugin(); + $fakeServer->addPlugin($plugin); + + $requestedProperties = array( + '{DAV:}displayname', + ); + $returnedProperties = array(); + + $result = $plugin->beforeGetProperties('principals/user',$principal,$requestedProperties,$returnedProperties); + + $this->assertNull($result); + + $this->assertTrue(isset($returnedProperties[200])); + $this->assertTrue(isset($returnedProperties[200]['{DAV:}displayname'])); + + $this->assertEquals('user', $returnedProperties[200]['{DAV:}displayname']); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php new file mode 100644 index 000000000..53568654f --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php @@ -0,0 +1,127 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + + +require_once 'Sabre/DAVACL/MockPrincipal.php'; + +class PluginUpdatePropertiesTest extends \PHPUnit_Framework_TestCase { + + public function testUpdatePropertiesPassthrough() { + + $tree = array( + new DAV\SimpleCollection('foo'), + ); + $server = new DAV\Server($tree); + $server->addPlugin(new Plugin()); + + $result = $server->updateProperties('foo', array( + '{DAV:}foo' => 'bar', + )); + + $expected = array( + 'href' => 'foo', + '403' => array( + '{DAV:}foo' => null, + ), + ); + + $this->assertEquals($expected, $result); + + } + + public function testRemoveGroupMembers() { + + $tree = array( + new MockPrincipal('foo','foo'), + ); + $server = new DAV\Server($tree); + $server->addPlugin(new Plugin()); + + $result = $server->updateProperties('foo', array( + '{DAV:}group-member-set' => null, + )); + + $expected = array( + 'href' => 'foo', + '200' => array( + '{DAV:}group-member-set' => null, + ), + ); + + $this->assertEquals($expected, $result); + $this->assertEquals(array(),$tree[0]->getGroupMemberSet()); + + } + + public function testSetGroupMembers() { + + $tree = array( + new MockPrincipal('foo','foo'), + ); + $server = new DAV\Server($tree); + $server->addPlugin(new Plugin()); + + $result = $server->updateProperties('foo', array( + '{DAV:}group-member-set' => new DAV\Property\HrefList(array('/bar','/baz'), true), + )); + + $expected = array( + 'href' => 'foo', + '200' => array( + '{DAV:}group-member-set' => null, + ), + ); + + $this->assertEquals($expected, $result); + $this->assertEquals(array('bar','baz'),$tree[0]->getGroupMemberSet()); + + } + + /** + * @expectedException Sabre\DAV\Exception + */ + public function testSetBadValue() { + + $tree = array( + new MockPrincipal('foo','foo'), + ); + $server = new DAV\Server($tree); + $server->addPlugin(new Plugin()); + + $result = $server->updateProperties('foo', array( + '{DAV:}group-member-set' => new \StdClass(), + )); + + } + + public function testSetBadNode() { + + $tree = array( + new DAV\SimpleCollection('foo'), + ); + $server = new DAV\Server($tree); + $server->addPlugin(new Plugin()); + + $result = $server->updateProperties('foo', array( + '{DAV:}group-member-set' => new DAV\Property\HrefList(array('/bar','/baz'),false), + '{DAV:}bar' => 'baz', + )); + + $expected = array( + 'href' => 'foo', + '403' => array( + '{DAV:}group-member-set' => null, + ), + '424' => array( + '{DAV:}bar' => null, + ), + ); + + $this->assertEquals($expected, $result); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php new file mode 100644 index 000000000..3fe75ca0e --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php @@ -0,0 +1,178 @@ +<?php + +namespace Sabre\DAVACL\PrincipalBackend; + +use Sabre\DAV; +use Sabre\HTTP; + + +abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase { + + abstract function getPDO(); + + function testConstruct() { + + $pdo = $this->getPDO(); + $backend = new PDO($pdo); + $this->assertTrue($backend instanceof PDO); + + } + + /** + * @depends testConstruct + */ + function testGetPrincipalsByPrefix() { + + $pdo = $this->getPDO(); + $backend = new PDO($pdo); + + $expected = array( + array( + 'uri' => 'principals/user', + '{http://sabredav.org/ns}email-address' => 'user@example.org', + '{DAV:}displayname' => 'User', + ), + array( + 'uri' => 'principals/group', + '{http://sabredav.org/ns}email-address' => 'group@example.org', + '{DAV:}displayname' => 'Group', + ), + ); + + $this->assertEquals($expected, $backend->getPrincipalsByPrefix('principals')); + $this->assertEquals(array(), $backend->getPrincipalsByPrefix('foo')); + + } + + /** + * @depends testConstruct + */ + function testGetPrincipalByPath() { + + $pdo = $this->getPDO(); + $backend = new PDO($pdo); + + $expected = array( + 'id' => 1, + 'uri' => 'principals/user', + '{http://sabredav.org/ns}email-address' => 'user@example.org', + '{DAV:}displayname' => 'User', + ); + + $this->assertEquals($expected, $backend->getPrincipalByPath('principals/user')); + $this->assertEquals(null, $backend->getPrincipalByPath('foo')); + + } + + function testGetGroupMemberSet() { + + $pdo = $this->getPDO(); + $backend = new PDO($pdo); + $expected = array('principals/user'); + + $this->assertEquals($expected,$backend->getGroupMemberSet('principals/group')); + + } + + function testGetGroupMembership() { + + $pdo = $this->getPDO(); + $backend = new PDO($pdo); + $expected = array('principals/group'); + + $this->assertEquals($expected,$backend->getGroupMembership('principals/user')); + + } + + function testSetGroupMemberSet() { + + $pdo = $this->getPDO(); + + // Start situation + $backend = new PDO($pdo); + $this->assertEquals(array('principals/user'), $backend->getGroupMemberSet('principals/group')); + + // Removing all principals + $backend->setGroupMemberSet('principals/group', array()); + $this->assertEquals(array(), $backend->getGroupMemberSet('principals/group')); + + // Adding principals again + $backend->setGroupMemberSet('principals/group', array('principals/user')); + $this->assertEquals(array('principals/user'), $backend->getGroupMemberSet('principals/group')); + + + } + + function testSearchPrincipals() { + + $pdo = $this->getPDO(); + + $backend = new PDO($pdo); + + $result = $backend->searchPrincipals('principals', array('{DAV:}blabla' => 'foo')); + $this->assertEquals(array(), $result); + + $result = $backend->searchPrincipals('principals', array('{DAV:}displayname' => 'ou')); + $this->assertEquals(array('principals/group'), $result); + + $result = $backend->searchPrincipals('principals', array('{DAV:}displayname' => 'UsEr', '{http://sabredav.org/ns}email-address' => 'USER@EXAMPLE')); + $this->assertEquals(array('principals/user'), $result); + + $result = $backend->searchPrincipals('mom', array('{DAV:}displayname' => 'UsEr', '{http://sabredav.org/ns}email-address' => 'USER@EXAMPLE')); + $this->assertEquals(array(), $result); + + } + + function testUpdatePrincipal() { + + $pdo = $this->getPDO(); + $backend = new PDO($pdo); + + $result = $backend->updatePrincipal('principals/user', array( + '{DAV:}displayname' => 'pietje', + '{http://sabredav.org/ns}vcard-url' => 'blabla', + )); + + $this->assertTrue($result); + + $this->assertEquals(array( + 'id' => 1, + 'uri' => 'principals/user', + '{DAV:}displayname' => 'pietje', + '{http://sabredav.org/ns}vcard-url' => 'blabla', + '{http://sabredav.org/ns}email-address' => 'user@example.org', + ), $backend->getPrincipalByPath('principals/user')); + + } + + function testUpdatePrincipalUnknownField() { + + $pdo = $this->getPDO(); + $backend = new PDO($pdo); + + $result = $backend->updatePrincipal('principals/user', array( + '{DAV:}displayname' => 'pietje', + '{http://sabredav.org/ns}vcard-url' => 'blabla', + '{DAV:}unknown' => 'foo', + )); + + $this->assertEquals(array( + 424 => array( + '{DAV:}displayname' => null, + '{http://sabredav.org/ns}vcard-url' => null, + ), + 403 => array( + '{DAV:}unknown' => null, + ), + ), $result); + + $this->assertEquals(array( + 'id' => '1', + 'uri' => 'principals/user', + '{DAV:}displayname' => 'User', + '{http://sabredav.org/ns}email-address' => 'user@example.org', + ), $backend->getPrincipalByPath('principals/user')); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/Mock.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/Mock.php new file mode 100644 index 000000000..354446e34 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/Mock.php @@ -0,0 +1,184 @@ +<?php + +namespace Sabre\DAVACL\PrincipalBackend; + +class Mock extends AbstractBackend { + + public $groupMembers = array(); + public $principals; + + function __construct() { + + $this->principals = array( + array( + 'uri' => 'principals/user1', + '{DAV:}displayname' => 'User 1', + '{http://sabredav.org/ns}email-address' => 'user1.sabredav@sabredav.org', + '{http://sabredav.org/ns}vcard-url' => 'addressbooks/user1/book1/vcard1.vcf', + ), + array( + 'uri' => 'principals/admin', + '{DAV:}displayname' => 'Admin', + ), + array( + 'uri' => 'principals/user2', + '{DAV:}displayname' => 'User 2', + '{http://sabredav.org/ns}email-address' => 'user2.sabredav@sabredav.org', + ), + ); + + + } + + function getPrincipalsByPrefix($prefix) { + + $prefix = trim($prefix,'/') . '/'; + $return = array(); + + foreach($this->principals as $principal) { + + if (strpos($principal['uri'], $prefix)!==0) continue; + + $return[] = $principal; + + } + + return $return; + + } + + function addPrincipal(array $principal) { + + $this->principals[] = $principal; + + } + + function getPrincipalByPath($path) { + + foreach($this->getPrincipalsByPrefix('principals') as $principal) { + if ($principal['uri'] === $path) return $principal; + } + + } + + function searchPrincipals($prefixPath, array $searchProperties) { + + $matches = array(); + foreach($this->getPrincipalsByPrefix($prefixPath) as $principal) { + + foreach($searchProperties as $key=>$value) { + + if (!isset($principal[$key])) { + continue 2; + } + if (mb_stripos($principal[$key],$value, 0, 'UTF-8')===false) { + continue 2; + } + + } + $matches[] = $principal['uri']; + + } + return $matches; + + } + + function getGroupMemberSet($path) { + + return isset($this->groupMembers[$path]) ? $this->groupMembers[$path] : array(); + + } + + function getGroupMembership($path) { + + $membership = array(); + foreach($this->groupMembers as $group=>$members) { + if (in_array($path, $members)) $membership[] = $group; + } + return $membership; + + } + + function setGroupMemberSet($path, array $members) { + + $this->groupMembers[$path] = $members; + + } + + /** + * Updates one ore more webdav properties on a principal. + * + * The list of mutations is supplied as an array. Each key in the array is + * a propertyname, such as {DAV:}displayname. + * + * Each value is the actual value to be updated. If a value is null, it + * must be deleted. + * + * This method should be atomic. It must either completely succeed, or + * completely fail. Success and failure can simply be returned as 'true' or + * 'false'. + * + * It is also possible to return detailed failure information. In that case + * an array such as this should be returned: + * + * array( + * 200 => array( + * '{DAV:}prop1' => null, + * ), + * 201 => array( + * '{DAV:}prop2' => null, + * ), + * 403 => array( + * '{DAV:}prop3' => null, + * ), + * 424 => array( + * '{DAV:}prop4' => null, + * ), + * ); + * + * In this previous example prop1 was successfully updated or deleted, and + * prop2 was succesfully created. + * + * prop3 failed to update due to '403 Forbidden' and because of this prop4 + * also could not be updated with '424 Failed dependency'. + * + * This last example was actually incorrect. While 200 and 201 could appear + * in 1 response, if there's any error (403) the other properties should + * always fail with 423 (failed dependency). + * + * But anyway, if you don't want to scratch your head over this, just + * return true or false. + * + * @param string $path + * @param array $mutations + * @return array|bool + */ + public function updatePrincipal($path, $mutations) { + + $value = null; + foreach($this->principals as $principalIndex=>$value) { + if ($value['uri'] === $path) { + $principal = $value; + break; + } + } + if (!$principal) return false; + + foreach($mutations as $prop=>$value) { + + if (is_null($value) && isset($principal[$prop])) { + unset($principal[$prop]); + } else { + $principal[$prop] = $value; + } + + } + + $this->principals[$principalIndex] = $principal; + + return true; + + } + + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php new file mode 100644 index 000000000..84ba062ca --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php @@ -0,0 +1,45 @@ +<?php + +namespace Sabre\DAVACL\PrincipalBackend; + +use Sabre\DAV; +use Sabre\HTTP; + + +require_once 'Sabre/TestUtil.php'; + +class PDOMySQLTest extends AbstractPDOTest { + + function getPDO() { + + 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 principals"); + $pdo->query(" +create table principals ( + id integer unsigned not null primary key auto_increment, + uri varchar(50), + email varchar(80), + displayname VARCHAR(80), + vcardurl VARCHAR(80), + unique(uri) +);"); + + $pdo->query("INSERT INTO principals (uri,email,displayname) VALUES ('principals/user','user@example.org','User')"); + $pdo->query("INSERT INTO principals (uri,email,displayname) VALUES ('principals/group','group@example.org','Group')"); + $pdo->query("DROP TABLE IF EXISTS groupmembers"); + $pdo->query("CREATE TABLE groupmembers ( + id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + principal_id INTEGER UNSIGNED NOT NULL, + member_id INTEGER UNSIGNED NOT NULL, + UNIQUE(principal_id, member_id) + );"); + + $pdo->query("INSERT INTO groupmembers (principal_id,member_id) VALUES (2,1)"); + + return $pdo; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php new file mode 100644 index 000000000..192e188f9 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php @@ -0,0 +1,42 @@ +<?php + +namespace Sabre\DAVACL\PrincipalBackend; + +use Sabre\DAV; +use Sabre\HTTP; + + +require_once 'Sabre/DAV/Auth/Backend/AbstractPDOTest.php'; + +class PDOSQLiteTest extends AbstractPDOTest { + + function tearDown() { + + if (file_exists(SABRE_TEMPDIR . '/pdobackend')) unlink(SABRE_TEMPDIR . '/pdobackend'); + if (file_exists(SABRE_TEMPDIR . '/pdobackend2')) unlink(SABRE_TEMPDIR . '/pdobackend2'); + + } + + function getPDO() { + + if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available'); + $pdo = new \PDO('sqlite:'.SABRE_TEMPDIR.'/pdobackend'); + $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION); + $pdo->query('CREATE TABLE principals (id INTEGER PRIMARY KEY ASC, uri TEXT, email VARCHAR(80), displayname VARCHAR(80), vcardurl VARCHAR(80))'); + $pdo->query('INSERT INTO principals VALUES (1, "principals/user","user@example.org","User",null)'); + $pdo->query('INSERT INTO principals VALUES (2, "principals/group","group@example.org","Group",null)'); + + $pdo->query("CREATE TABLE groupmembers ( + id INTEGER PRIMARY KEY ASC, + principal_id INT, + member_id INT, + UNIQUE(principal_id, member_id) + );"); + + $pdo->query("INSERT INTO groupmembers (principal_id,member_id) VALUES (2,1)"); + + return $pdo; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php new file mode 100644 index 000000000..10b0c04da --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php @@ -0,0 +1,52 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + + +class PrincipalCollectionTest extends \PHPUnit_Framework_TestCase { + + public function testBasic() { + + $backend = new PrincipalBackend\Mock(); + $pc = new PrincipalCollection($backend); + $this->assertTrue($pc instanceof PrincipalCollection); + + $this->assertEquals('principals',$pc->getName()); + + } + + /** + * @depends testBasic + */ + public function testGetChildren() { + + $backend = new PrincipalBackend\Mock(); + $pc = new PrincipalCollection($backend); + + $children = $pc->getChildren(); + $this->assertTrue(is_array($children)); + + foreach($children as $child) { + $this->assertTrue($child instanceof IPrincipal); + } + + } + + /** + * @depends testBasic + * @expectedException Sabre\DAV\Exception\MethodNotAllowed + */ + public function testGetChildrenDisable() { + + $backend = new PrincipalBackend\Mock(); + $pc = new PrincipalCollection($backend); + $pc->disableListing = true; + + $children = $pc->getChildren(); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php new file mode 100644 index 000000000..9c3be4f9a --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php @@ -0,0 +1,246 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase { + + function getServer() { + + $backend = new PrincipalBackend\Mock(); + + $dir = new DAV\SimpleCollection('root'); + $principals = new PrincipalCollection($backend); + $dir->addChild($principals); + + $fakeServer = new DAV\Server(new DAV\ObjectTree($dir)); + $fakeServer->httpResponse = new HTTP\ResponseMock(); + $fakeServer->debugExceptions = true; + $plugin = new MockPlugin($backend,'realm'); + $plugin->allowAccessToNodesWithoutACL = true; + + $this->assertTrue($plugin instanceof Plugin); + $fakeServer->addPlugin($plugin); + $this->assertEquals($plugin, $fakeServer->getPlugin('acl')); + + return $fakeServer; + + } + + function testDepth1() { + + $xml = '<?xml version="1.0"?> +<d:principal-property-search xmlns:d="DAV:"> + <d:property-search> + <d:prop> + <d:displayname /> + </d:prop> + <d:match>user</d:match> + </d:property-search> + <d:prop> + <d:displayname /> + <d:getcontentlength /> + </d:prop> +</d:principal-property-search>'; + + $serverVars = array( + 'REQUEST_METHOD' => 'REPORT', + 'HTTP_DEPTH' => '1', + 'REQUEST_URI' => '/principals', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($xml); + + $server = $this->getServer(); + $server->httpRequest = $request; + + $server->exec(); + + $this->assertEquals('HTTP/1.1 400 Bad request', $server->httpResponse->status); + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), $server->httpResponse->headers); + + } + + + function testUnknownSearchField() { + + $xml = '<?xml version="1.0"?> +<d:principal-property-search xmlns:d="DAV:"> + <d:property-search> + <d:prop> + <d:yourmom /> + </d:prop> + <d:match>user</d:match> + </d:property-search> + <d:prop> + <d:displayname /> + <d:getcontentlength /> + </d:prop> +</d:principal-property-search>'; + + $serverVars = array( + 'REQUEST_METHOD' => 'REPORT', + 'HTTP_DEPTH' => '0', + 'REQUEST_URI' => '/principals', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($xml); + + $server = $this->getServer(); + $server->httpRequest = $request; + + $server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status); + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + 'Vary' => 'Brief,Prefer', + ), $server->httpResponse->headers); + + } + + function testCorrect() { + + $xml = '<?xml version="1.0"?> +<d:principal-property-search xmlns:d="DAV:"> + <d:apply-to-principal-collection-set /> + <d:property-search> + <d:prop> + <d:displayname /> + </d:prop> + <d:match>user</d:match> + </d:property-search> + <d:prop> + <d:displayname /> + <d:getcontentlength /> + </d:prop> +</d:principal-property-search>'; + + $serverVars = array( + 'REQUEST_METHOD' => 'REPORT', + 'HTTP_DEPTH' => '0', + 'REQUEST_URI' => '/', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($xml); + + $server = $this->getServer(); + $server->httpRequest = $request; + + $server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status, $server->httpResponse->body); + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + 'Vary' => 'Brief,Prefer', + ), $server->httpResponse->headers); + + + $check = array( + '/d:multistatus', + '/d:multistatus/d:response' => 2, + '/d:multistatus/d:response/d:href' => 2, + '/d:multistatus/d:response/d:propstat' => 4, + '/d:multistatus/d:response/d:propstat/d:prop' => 4, + '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 2, + '/d:multistatus/d:response/d:propstat/d:prop/d:getcontentlength' => 2, + '/d:multistatus/d:response/d:propstat/d:status' => 4, + ); + + $xml = simplexml_load_string($server->httpResponse->body); + $xml->registerXPathNamespace('d','DAV:'); + foreach($check as $v1=>$v2) { + + $xpath = is_int($v1)?$v2:$v1; + + $result = $xml->xpath($xpath); + + $count = 1; + if (!is_int($v1)) $count = $v2; + + $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body); + + } + + } + function testWrongUri() { + + $xml = '<?xml version="1.0"?> +<d:principal-property-search xmlns:d="DAV:"> + <d:property-search> + <d:prop> + <d:displayname /> + </d:prop> + <d:match>user</d:match> + </d:property-search> + <d:prop> + <d:displayname /> + <d:getcontentlength /> + </d:prop> +</d:principal-property-search>'; + + $serverVars = array( + 'REQUEST_METHOD' => 'REPORT', + 'HTTP_DEPTH' => '0', + 'REQUEST_URI' => '/', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($xml); + + $server = $this->getServer(); + $server->httpRequest = $request; + + $server->exec(); + + $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status, $server->httpResponse->body); + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + 'Vary' => 'Brief,Prefer', + ), $server->httpResponse->headers); + + + $check = array( + '/d:multistatus', + '/d:multistatus/d:response' => 0, + ); + + $xml = simplexml_load_string($server->httpResponse->body); + $xml->registerXPathNamespace('d','DAV:'); + foreach($check as $v1=>$v2) { + + $xpath = is_int($v1)?$v2:$v1; + + $result = $xml->xpath($xpath); + + $count = 1; + if (!is_int($v1)) $count = $v2; + + $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body); + + } + + } +} + +class MockPlugin extends Plugin { + + function getCurrentUserPrivilegeSet($node) { + + return array( + '{DAV:}read', + '{DAV:}write', + ); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php new file mode 100644 index 000000000..412389e8b --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php @@ -0,0 +1,135 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class PrincipalSearchPropertySetTest extends \PHPUnit_Framework_TestCase { + + function getServer() { + + $backend = new PrincipalBackend\Mock(); + + $dir = new DAV\SimpleCollection('root'); + $principals = new PrincipalCollection($backend); + $dir->addChild($principals); + + $fakeServer = new DAV\Server(new DAV\ObjectTree($dir)); + $fakeServer->httpResponse = new HTTP\ResponseMock(); + $plugin = new Plugin($backend,'realm'); + $this->assertTrue($plugin instanceof Plugin); + $fakeServer->addPlugin($plugin); + $this->assertEquals($plugin, $fakeServer->getPlugin('acl')); + + return $fakeServer; + + } + + function testDepth1() { + + $xml = '<?xml version="1.0"?> +<d:principal-search-property-set xmlns:d="DAV:" />'; + + $serverVars = array( + 'REQUEST_METHOD' => 'REPORT', + 'HTTP_DEPTH' => '1', + 'REQUEST_URI' => '/principals', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($xml); + + $server = $this->getServer(); + $server->httpRequest = $request; + + $server->exec(); + + $this->assertEquals('HTTP/1.1 400 Bad request', $server->httpResponse->status); + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), $server->httpResponse->headers); + + } + + function testDepthIncorrectXML() { + + $xml = '<?xml version="1.0"?> +<d:principal-search-property-set xmlns:d="DAV:"><d:ohell /></d:principal-search-property-set>'; + + $serverVars = array( + 'REQUEST_METHOD' => 'REPORT', + 'HTTP_DEPTH' => '0', + 'REQUEST_URI' => '/principals', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($xml); + + $server = $this->getServer(); + $server->httpRequest = $request; + + $server->exec(); + + $this->assertEquals('HTTP/1.1 400 Bad request', $server->httpResponse->status, $server->httpResponse->body); + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), $server->httpResponse->headers); + + } + + function testCorrect() { + + $xml = '<?xml version="1.0"?> +<d:principal-search-property-set xmlns:d="DAV:"/>'; + + $serverVars = array( + 'REQUEST_METHOD' => 'REPORT', + 'HTTP_DEPTH' => '0', + 'REQUEST_URI' => '/principals', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody($xml); + + $server = $this->getServer(); + $server->httpRequest = $request; + + $server->exec(); + + $this->assertEquals('HTTP/1.1 200 OK', $server->httpResponse->status, $server->httpResponse->body); + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), $server->httpResponse->headers); + + + $check = array( + '/d:principal-search-property-set', + '/d:principal-search-property-set/d:principal-search-property' => 2, + '/d:principal-search-property-set/d:principal-search-property/d:prop' => 2, + '/d:principal-search-property-set/d:principal-search-property/d:prop/d:displayname' => 1, + '/d:principal-search-property-set/d:principal-search-property/d:prop/s:email-address' => 1, + '/d:principal-search-property-set/d:principal-search-property/d:description' => 2, + ); + + $xml = simplexml_load_string($server->httpResponse->body); + $xml->registerXPathNamespace('d','DAV:'); + $xml->registerXPathNamespace('s','http://sabredav.org/ns'); + foreach($check as $v1=>$v2) { + + $xpath = is_int($v1)?$v2:$v1; + + $result = $xml->xpath($xpath); + + $count = 1; + if (!is_int($v1)) $count = $v2; + + $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body); + + } + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php new file mode 100644 index 000000000..2d4371138 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php @@ -0,0 +1,204 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + +class PrincipalTest extends \PHPUnit_Framework_TestCase { + + public function testConstruct() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $this->assertTrue($principal instanceof Principal); + + } + + /** + * @expectedException Sabre\DAV\Exception + */ + public function testConstructNoUri() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array()); + + } + + public function testGetName() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $this->assertEquals('admin',$principal->getName()); + + } + + public function testGetDisplayName() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $this->assertEquals('admin',$principal->getDisplayname()); + + $principal = new Principal($principalBackend, array( + 'uri' => 'principals/admin', + '{DAV:}displayname' => 'Mr. Admin' + )); + $this->assertEquals('Mr. Admin',$principal->getDisplayname()); + + } + + public function testGetProperties() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array( + 'uri' => 'principals/admin', + '{DAV:}displayname' => 'Mr. Admin', + '{http://www.example.org/custom}custom' => 'Custom', + '{http://sabredav.org/ns}email-address' => 'admin@example.org', + )); + + $keys = array( + '{DAV:}displayname', + '{http://www.example.org/custom}custom', + '{http://sabredav.org/ns}email-address', + ); + $props = $principal->getProperties($keys); + + foreach($keys as $key) $this->assertArrayHasKey($key,$props); + + $this->assertEquals('Mr. Admin',$props['{DAV:}displayname']); + + $this->assertEquals('admin@example.org', $props['{http://sabredav.org/ns}email-address']); + } + + public function testUpdateProperties() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $result = $principal->updateProperties(array('{DAV:}yourmom'=>'test')); + $this->assertEquals(true,$result); + + } + + public function testGetPrincipalUrl() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $this->assertEquals('principals/admin',$principal->getPrincipalUrl()); + + } + + public function testGetAlternateUriSet() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array( + 'uri' => 'principals/admin', + '{DAV:}displayname' => 'Mr. Admin', + '{http://www.example.org/custom}custom' => 'Custom', + '{http://sabredav.org/ns}email-address' => 'admin@example.org', + '{DAV:}alternate-URI-set' => array( + 'mailto:admin+1@example.org', + 'mailto:admin+2@example.org', + 'mailto:admin@example.org', + ), + )); + + $expected = array( + 'mailto:admin+1@example.org', + 'mailto:admin+2@example.org', + 'mailto:admin@example.org', + ); + + $this->assertEquals($expected,$principal->getAlternateUriSet()); + + } + public function testGetAlternateUriSetEmpty() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array( + 'uri' => 'principals/admin', + )); + + $expected = array(); + + $this->assertEquals($expected,$principal->getAlternateUriSet()); + + } + + public function testGetGroupMemberSet() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $this->assertEquals(array(),$principal->getGroupMemberSet()); + + } + public function testGetGroupMembership() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $this->assertEquals(array(),$principal->getGroupMembership()); + + } + + public function testSetGroupMemberSet() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $principal->setGroupMemberSet(array('principals/foo')); + + $this->assertEquals(array( + 'principals/admin' => array('principals/foo'), + ), $principalBackend->groupMembers); + + } + + public function testGetOwner() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $this->assertEquals('principals/admin',$principal->getOwner()); + + } + + public function testGetGroup() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $this->assertNull($principal->getGroup()); + + } + + public function testGetACl() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $this->assertEquals(array( + array( + 'privilege' => '{DAV:}read', + 'principal' => 'principals/admin', + 'protected' => true, + ) + ),$principal->getACL()); + + } + + /** + * @expectedException Sabre\DAV\Exception\MethodNotAllowed + */ + public function testSetACl() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $principal->setACL(array()); + + } + + public function testGetSupportedPrivilegeSet() { + + $principalBackend = new PrincipalBackend\Mock(); + $principal = new Principal($principalBackend, array('uri' => 'principals/admin')); + $this->assertNull($principal->getSupportedPrivilegeSet()); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLRestrictionsTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLRestrictionsTest.php new file mode 100644 index 000000000..72a2f36a4 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLRestrictionsTest.php @@ -0,0 +1,35 @@ +<?php + +namespace Sabre\DAVACL\Property; + +use Sabre\DAV; +use Sabre\HTTP; + +class ACLRestrictionsTest extends \PHPUnit_Framework_TestCase { + + function testConstruct() { + + $prop = new AclRestrictions(); + + } + + function testSerializeEmpty() { + + $dom = new \DOMDocument('1.0'); + $root = $dom->createElementNS('DAV:','d:root'); + + $dom->appendChild($root); + + $acl = new AclRestrictions(); + $acl->serialize(new DAV\Server(), $root); + + $xml = $dom->saveXML(); + $expected = '<?xml version="1.0"?> +<d:root xmlns:d="DAV:"><d:grant-only/><d:no-invert/></d:root> +'; + $this->assertEquals($expected, $xml); + + } + + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLTest.php new file mode 100644 index 000000000..7f2014df3 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLTest.php @@ -0,0 +1,335 @@ +<?php + +namespace Sabre\DAVACL\Property; + +use Sabre\DAV; +use Sabre\HTTP; + + +class ACLTest extends \PHPUnit_Framework_TestCase { + + function testConstruct() { + + $acl = new Acl(array()); + + } + + function testSerializeEmpty() { + + $dom = new \DOMDocument('1.0'); + $root = $dom->createElementNS('DAV:','d:root'); + + $dom->appendChild($root); + + $acl = new Acl(array()); + $acl->serialize(new DAV\Server(), $root); + + $xml = $dom->saveXML(); + $expected = '<?xml version="1.0"?> +<d:root xmlns:d="DAV:"/> +'; + $this->assertEquals($expected, $xml); + + } + + function testSerialize() { + + $dom = new \DOMDocument('1.0'); + $root = $dom->createElementNS('DAV:','d:root'); + + $dom->appendChild($root); + + $privileges = array( + array( + 'principal' => 'principals/evert', + 'privilege' => '{DAV:}write', + 'uri' => 'articles', + ), + array( + 'principal' => 'principals/foo', + 'privilege' => '{DAV:}read', + 'uri' => 'articles', + 'protected' => true, + ), + ); + + $acl = new Acl($privileges); + $acl->serialize(new DAV\Server(), $root); + + $dom->formatOutput = true; + + $xml = $dom->saveXML(); + $expected = '<?xml version="1.0"?> +<d:root xmlns:d="DAV:"> + <d:ace> + <d:principal> + <d:href>/principals/evert/</d:href> + </d:principal> + <d:grant> + <d:privilege> + <d:write/> + </d:privilege> + </d:grant> + </d:ace> + <d:ace> + <d:principal> + <d:href>/principals/foo/</d:href> + </d:principal> + <d:grant> + <d:privilege> + <d:read/> + </d:privilege> + </d:grant> + <d:protected/> + </d:ace> +</d:root> +'; + $this->assertEquals($expected, $xml); + + } + + function testSerializeSpecialPrincipals() { + + $dom = new \DOMDocument('1.0'); + $root = $dom->createElementNS('DAV:','d:root'); + + $dom->appendChild($root); + + $privileges = array( + array( + 'principal' => '{DAV:}authenticated', + 'privilege' => '{DAV:}write', + 'uri' => 'articles', + ), + array( + 'principal' => '{DAV:}unauthenticated', + 'privilege' => '{DAV:}write', + 'uri' => 'articles', + ), + array( + 'principal' => '{DAV:}all', + 'privilege' => '{DAV:}write', + 'uri' => 'articles', + ), + + ); + + $acl = new Acl($privileges); + $acl->serialize(new DAV\Server(), $root); + + $dom->formatOutput = true; + + $xml = $dom->saveXML(); + $expected = '<?xml version="1.0"?> +<d:root xmlns:d="DAV:"> + <d:ace> + <d:principal> + <d:authenticated/> + </d:principal> + <d:grant> + <d:privilege> + <d:write/> + </d:privilege> + </d:grant> + </d:ace> + <d:ace> + <d:principal> + <d:unauthenticated/> + </d:principal> + <d:grant> + <d:privilege> + <d:write/> + </d:privilege> + </d:grant> + </d:ace> + <d:ace> + <d:principal> + <d:all/> + </d:principal> + <d:grant> + <d:privilege> + <d:write/> + </d:privilege> + </d:grant> + </d:ace> +</d:root> +'; + $this->assertEquals($expected, $xml); + + } + + function testUnserialize() { + + $source = '<?xml version="1.0"?> +<d:root xmlns:d="DAV:"> + <d:ace> + <d:principal> + <d:href>/principals/evert/</d:href> + </d:principal> + <d:grant> + <d:privilege> + <d:write/> + </d:privilege> + </d:grant> + </d:ace> + <d:ace> + <d:principal> + <d:href>/principals/foo/</d:href> + </d:principal> + <d:grant> + <d:privilege> + <d:read/> + </d:privilege> + </d:grant> + <d:protected/> + </d:ace> +</d:root> +'; + + $dom = DAV\XMLUtil::loadDOMDocument($source); + $result = Acl::unserialize($dom->firstChild); + + $this->assertInstanceOf('Sabre\\DAVACL\\Property\\ACL', $result); + + $expected = array( + array( + 'principal' => '/principals/evert/', + 'protected' => false, + 'privilege' => '{DAV:}write', + ), + array( + 'principal' => '/principals/foo/', + 'protected' => true, + 'privilege' => '{DAV:}read', + ), + ); + + $this->assertEquals($expected, $result->getPrivileges()); + + + } + + /** + * @expectedException Sabre\DAV\Exception\BadRequest + */ + function testUnserializeNoPrincipal() { + + $source = '<?xml version="1.0"?> +<d:root xmlns:d="DAV:"> + <d:ace> + <d:grant> + <d:privilege> + <d:write/> + </d:privilege> + </d:grant> + </d:ace> +</d:root> +'; + + $dom = DAV\XMLUtil::loadDOMDocument($source); + Acl::unserialize($dom->firstChild); + + } + + function testUnserializeOtherPrincipal() { + + $source = '<?xml version="1.0"?> +<d:root xmlns:d="DAV:"> + <d:ace> + <d:grant> + <d:privilege> + <d:write/> + </d:privilege> + </d:grant> + <d:principal><d:authenticated /></d:principal> + </d:ace> + <d:ace> + <d:grant> + <d:privilege> + <d:write/> + </d:privilege> + </d:grant> + <d:principal><d:unauthenticated /></d:principal> + </d:ace> + <d:ace> + <d:grant> + <d:privilege> + <d:write/> + </d:privilege> + </d:grant> + <d:principal><d:all /></d:principal> + </d:ace> +</d:root> +'; + + $dom = DAV\XMLUtil::loadDOMDocument($source); + $result = Acl::unserialize($dom->firstChild); + + $this->assertInstanceOf('Sabre\\DAVACL\\Property\\Acl', $result); + + $expected = array( + array( + 'principal' => '{DAV:}authenticated', + 'protected' => false, + 'privilege' => '{DAV:}write', + ), + array( + 'principal' => '{DAV:}unauthenticated', + 'protected' => false, + 'privilege' => '{DAV:}write', + ), + array( + 'principal' => '{DAV:}all', + 'protected' => false, + 'privilege' => '{DAV:}write', + ), + ); + + $this->assertEquals($expected, $result->getPrivileges()); + + + } + + /** + * @expectedException Sabre\DAV\Exception\NotImplemented + */ + function testUnserializeDeny() { + + $source = '<?xml version="1.0"?> +<d:root xmlns:d="DAV:"> + <d:ace> + <d:deny> + <d:privilege> + <d:write/> + </d:privilege> + </d:deny> + <d:principal><d:href>/principals/evert</d:href></d:principal> + </d:ace> +</d:root> +'; + + $dom = DAV\XMLUtil::loadDOMDocument($source); + Acl::unserialize($dom->firstChild); + } + + /** + * @expectedException Sabre\DAV\Exception\BadRequest + */ + function testUnserializeMissingPriv() { + + $source = '<?xml version="1.0"?> +<d:root xmlns:d="DAV:"> + <d:ace> + <d:grant> + <d:privilege /> + </d:grant> + <d:principal><d:href>/principals/evert</d:href></d:principal> + </d:ace> +</d:root> +'; + + $dom = DAV\XMLUtil::loadDOMDocument($source); + Acl::unserialize($dom->firstChild); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Property/CurrentUserPrivilegeSetTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/CurrentUserPrivilegeSetTest.php new file mode 100644 index 000000000..e71addb65 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/CurrentUserPrivilegeSetTest.php @@ -0,0 +1,68 @@ +<?php + +namespace Sabre\DAVACL\Property; + +use Sabre\DAV; +use Sabre\HTTP; + + +class CurrentUserPrivilegeSetTest extends \PHPUnit_Framework_TestCase { + + function testSerialize() { + + $privileges = array( + '{DAV:}read', + '{DAV:}write', + ); + $prop = new CurrentUserPrivilegeSet($privileges); + + $server = new DAV\Server(); + $dom = new \DOMDocument('1.0','utf-8'); + $root = $dom->createElementNS('DAV:','d:root'); + $dom->appendChild($root); + + $prop->serialize($server, $root); + + $xpaths = array( + '/d:root' => 1, + '/d:root/d:privilege' => 2, + '/d:root/d:privilege/d:read' => 1, + '/d:root/d:privilege/d:write' => 1, + ); + + // Reloading because PHP DOM sucks + $dom2 = new \DOMDocument('1.0', 'utf-8'); + $dom2->loadXML($dom->saveXML()); + + $dxpath = new \DOMXPath($dom2); + $dxpath->registerNamespace('d','DAV:'); + foreach($xpaths as $xpath=>$count) { + + $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count); + + } + + } + + function testUnserialize() { + + $source = '<?xml version="1.0"?> +<d:root xmlns:d="DAV:"> + <d:privilege> + <d:write-properties /> + </d:privilege> + <d:privilege> + <d:read /> + </d:privilege> +</d:root> +'; + + $dom = DAV\XMLUtil::loadDOMDocument($source); + $result = CurrentUserPrivilegeSet::unserialize($dom->firstChild, array()); + $this->assertTrue($result->has('{DAV:}read')); + $this->assertTrue($result->has('{DAV:}write-properties')); + $this->assertFalse($result->has('{DAV:}bind')); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Property/PrincipalTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/PrincipalTest.php new file mode 100644 index 000000000..be12c79ee --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/PrincipalTest.php @@ -0,0 +1,181 @@ +<?php + +namespace Sabre\DAVACL\Property; + +use Sabre\DAV; +use Sabre\HTTP; + +class PrincipalTest extends \PHPUnit_Framework_TestCase { + + function testSimple() { + + $principal = new Principal(Principal::UNAUTHENTICATED); + $this->assertEquals(Principal::UNAUTHENTICATED, $principal->getType()); + $this->assertNull($principal->getHref()); + + $principal = new Principal(Principal::AUTHENTICATED); + $this->assertEquals(Principal::AUTHENTICATED, $principal->getType()); + $this->assertNull($principal->getHref()); + + $principal = new Principal(Principal::HREF,'admin'); + $this->assertEquals(Principal::HREF, $principal->getType()); + $this->assertEquals('admin',$principal->getHref()); + + } + + /** + * @depends testSimple + * @expectedException Sabre\DAV\Exception + */ + function testNoHref() { + + $principal = new Principal(Principal::HREF); + + } + + /** + * @depends testSimple + */ + function testSerializeUnAuthenticated() { + + $prin = new Principal(Principal::UNAUTHENTICATED); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:principal'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $objectTree = new DAV\ObjectTree(new DAV\SimpleCollection('rootdir')); + $server = new DAV\Server($objectTree); + + $prin->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<d:principal xmlns:d="DAV:">' . +'<d:unauthenticated/>' . +'</d:principal> +', $xml); + + } + + + /** + * @depends testSerializeUnAuthenticated + */ + function testSerializeAuthenticated() { + + $prin = new Principal(Principal::AUTHENTICATED); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:principal'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $objectTree = new DAV\ObjectTree(new DAV\SimpleCollection('rootdir')); + $server = new DAV\Server($objectTree); + + $prin->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<d:principal xmlns:d="DAV:">' . +'<d:authenticated/>' . +'</d:principal> +', $xml); + + } + + + /** + * @depends testSerializeUnAuthenticated + */ + function testSerializeHref() { + + $prin = new Principal(Principal::HREF,'principals/admin'); + + $doc = new \DOMDocument(); + $root = $doc->createElement('d:principal'); + $root->setAttribute('xmlns:d','DAV:'); + + $doc->appendChild($root); + $objectTree = new DAV\ObjectTree(new DAV\SimpleCollection('rootdir')); + $server = new DAV\Server($objectTree); + + $prin->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<d:principal xmlns:d="DAV:">' . +'<d:href>/principals/admin</d:href>' . +'</d:principal> +', $xml); + + } + + function testUnserializeHref() { + + $xml = '<?xml version="1.0"?> +<d:principal xmlns:d="DAV:">' . +'<d:href>/principals/admin</d:href>' . +'</d:principal>'; + + $dom = DAV\XMLUtil::loadDOMDocument($xml); + + $principal = Principal::unserialize($dom->firstChild); + $this->assertEquals(Principal::HREF, $principal->getType()); + $this->assertEquals('/principals/admin', $principal->getHref()); + + } + + function testUnserializeAuthenticated() { + + $xml = '<?xml version="1.0"?> +<d:principal xmlns:d="DAV:">' . +' <d:authenticated />' . +'</d:principal>'; + + $dom = DAV\XMLUtil::loadDOMDocument($xml); + + $principal = Principal::unserialize($dom->firstChild); + $this->assertEquals(Principal::AUTHENTICATED, $principal->getType()); + + } + + function testUnserializeUnauthenticated() { + + $xml = '<?xml version="1.0"?> +<d:principal xmlns:d="DAV:">' . +' <d:unauthenticated />' . +'</d:principal>'; + + $dom = DAV\XMLUtil::loadDOMDocument($xml); + + $principal = Principal::unserialize($dom->firstChild); + $this->assertEquals(Principal::UNAUTHENTICATED, $principal->getType()); + + } + + /** + * @expectedException Sabre\DAV\Exception\BadRequest + */ + function testUnserializeUnknown() { + + $xml = '<?xml version="1.0"?> +<d:principal xmlns:d="DAV:">' . +' <d:foo />' . +'</d:principal>'; + + $dom = DAV\XMLUtil::loadDOMDocument($xml); + + Principal::unserialize($dom->firstChild); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Property/SupportedPrivilegeSetTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/SupportedPrivilegeSetTest.php new file mode 100644 index 000000000..943316331 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/SupportedPrivilegeSetTest.php @@ -0,0 +1,106 @@ +<?php + +namespace Sabre\DAVACL\Property; + +use Sabre\DAV; +use Sabre\HTTP; + + + +class SupportedPrivilegeSetTest extends \PHPUnit_Framework_TestCase { + + function testSimple() { + + $prop = new SupportedPrivilegeSet(array( + 'privilege' => '{DAV:}all', + )); + + } + + + /** + * @depends testSimple + */ + function testSerializeSimple() { + + $prop = new SupportedPrivilegeSet(array( + 'privilege' => '{DAV:}all', + )); + + $doc = new \DOMDocument(); + $root = $doc->createElementNS('DAV:', 'd:supported-privilege-set'); + + $doc->appendChild($root); + + $server = new DAV\Server(); + $prop->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<d:supported-privilege-set xmlns:d="DAV:">' . +'<d:supported-privilege>' . +'<d:privilege>' . +'<d:all/>' . +'</d:privilege>' . +'</d:supported-privilege>' . +'</d:supported-privilege-set> +', $xml); + + } + + /** + * @depends testSimple + */ + function testSerializeAggregate() { + + $prop = new SupportedPrivilegeSet(array( + 'privilege' => '{DAV:}all', + 'abstract' => true, + 'aggregates' => array( + array( + 'privilege' => '{DAV:}read', + ), + array( + 'privilege' => '{DAV:}write', + 'description' => 'booh', + ), + ), + )); + + $doc = new \DOMDocument(); + $root = $doc->createElementNS('DAV:', 'd:supported-privilege-set'); + + $doc->appendChild($root); + + $server = new DAV\Server(); + $prop->serialize($server, $root); + + $xml = $doc->saveXML(); + + $this->assertEquals( +'<?xml version="1.0"?> +<d:supported-privilege-set xmlns:d="DAV:">' . +'<d:supported-privilege>' . +'<d:privilege>' . +'<d:all/>' . +'</d:privilege>' . +'<d:abstract/>' . +'<d:supported-privilege>' . +'<d:privilege>' . +'<d:read/>' . +'</d:privilege>' . +'</d:supported-privilege>' . +'<d:supported-privilege>' . +'<d:privilege>' . +'<d:write/>' . +'</d:privilege>' . +'<d:description>booh</d:description>' . +'</d:supported-privilege>' . +'</d:supported-privilege>' . +'</d:supported-privilege-set> +', $xml); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php new file mode 100644 index 000000000..04ed5c330 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php @@ -0,0 +1,322 @@ +<?php + +namespace Sabre\DAVACL; + +use Sabre\DAV; +use Sabre\HTTP; + + +require_once 'Sabre/DAVACL/MockPrincipal.php'; +require_once 'Sabre/DAVACL/MockACLNode.php'; + +class SimplePluginTest extends \PHPUnit_Framework_TestCase { + + function testValues() { + + $aclPlugin = new Plugin(); + $this->assertEquals('acl',$aclPlugin->getPluginName()); + $this->assertEquals( + array('access-control', 'calendarserver-principal-property-search'), + $aclPlugin->getFeatures() + ); + + $this->assertEquals( + array( + '{DAV:}expand-property', + '{DAV:}principal-property-search', + '{DAV:}principal-search-property-set' + ), + $aclPlugin->getSupportedReportSet('')); + + $this->assertEquals(array('ACL'), $aclPlugin->getMethods('')); + + } + + function testGetFlatPrivilegeSet() { + + $expected = array( + '{DAV:}all' => array( + 'privilege' => '{DAV:}all', + 'abstract' => true, + 'aggregates' => array( + '{DAV:}read', + '{DAV:}write', + ), + 'concrete' => null, + ), + '{DAV:}read' => array( + 'privilege' => '{DAV:}read', + 'abstract' => false, + 'aggregates' => array( + '{DAV:}read-acl', + '{DAV:}read-current-user-privilege-set', + ), + 'concrete' => '{DAV:}read', + ), + '{DAV:}read-acl' => array( + 'privilege' => '{DAV:}read-acl', + 'abstract' => true, + 'aggregates' => array(), + 'concrete' => '{DAV:}read', + ), + '{DAV:}read-current-user-privilege-set' => array( + 'privilege' => '{DAV:}read-current-user-privilege-set', + 'abstract' => true, + 'aggregates' => array(), + 'concrete' => '{DAV:}read', + ), + '{DAV:}write' => array( + 'privilege' => '{DAV:}write', + 'abstract' => false, + 'aggregates' => array( + '{DAV:}write-acl', + '{DAV:}write-properties', + '{DAV:}write-content', + '{DAV:}bind', + '{DAV:}unbind', + '{DAV:}unlock', + ), + 'concrete' => '{DAV:}write', + ), + '{DAV:}write-acl' => array( + 'privilege' => '{DAV:}write-acl', + 'abstract' => true, + 'aggregates' => array(), + 'concrete' => '{DAV:}write', + ), + '{DAV:}write-properties' => array( + 'privilege' => '{DAV:}write-properties', + 'abstract' => true, + 'aggregates' => array(), + 'concrete' => '{DAV:}write', + ), + '{DAV:}write-content' => array( + 'privilege' => '{DAV:}write-content', + 'abstract' => true, + 'aggregates' => array(), + 'concrete' => '{DAV:}write', + ), + '{DAV:}unlock' => array( + 'privilege' => '{DAV:}unlock', + 'abstract' => true, + 'aggregates' => array(), + 'concrete' => '{DAV:}write', + ), + '{DAV:}bind' => array( + 'privilege' => '{DAV:}bind', + 'abstract' => true, + 'aggregates' => array(), + 'concrete' => '{DAV:}write', + ), + '{DAV:}unbind' => array( + 'privilege' => '{DAV:}unbind', + 'abstract' => true, + 'aggregates' => array(), + 'concrete' => '{DAV:}write', + ), + + ); + + $plugin = new Plugin(); + $server = new DAV\Server(); + $server->addPlugin($plugin); + $this->assertEquals($expected, $plugin->getFlatPrivilegeSet('')); + + } + + function testCurrentUserPrincipalsNotLoggedIn() { + + $acl = new Plugin(); + $server = new DAV\Server(); + $server->addPlugin($acl); + + $this->assertEquals(array(),$acl->getCurrentUserPrincipals()); + + } + + function testCurrentUserPrincipalsSimple() { + + $tree = array( + + new DAV\SimpleCollection('principals', array( + new MockPrincipal('admin','principals/admin'), + )) + + ); + + $acl = new Plugin(); + $server = new DAV\Server($tree); + $server->addPlugin($acl); + + $auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'SabreDAV'); + $server->addPlugin($auth); + + //forcing login + $auth->beforeMethod('GET','/'); + + $this->assertEquals(array('principals/admin'),$acl->getCurrentUserPrincipals()); + + } + + function testCurrentUserPrincipalsGroups() { + + $tree = array( + + new DAV\SimpleCollection('principals', array( + new MockPrincipal('admin','principals/admin',array('principals/administrators', 'principals/everyone')), + new MockPrincipal('administrators','principals/administrators',array('principals/groups'), array('principals/admin')), + new MockPrincipal('everyone','principals/everyone',array(), array('principals/admin')), + new MockPrincipal('groups','principals/groups',array(), array('principals/administrators')), + )) + + ); + + $acl = new Plugin(); + $server = new DAV\Server($tree); + $server->addPlugin($acl); + + $auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'SabreDAV'); + $server->addPlugin($auth); + + //forcing login + $auth->beforeMethod('GET','/'); + + $expected = array( + 'principals/admin', + 'principals/administrators', + 'principals/everyone', + 'principals/groups', + ); + + $this->assertEquals($expected,$acl->getCurrentUserPrincipals()); + + // The second one should trigger the cache and be identical + $this->assertEquals($expected,$acl->getCurrentUserPrincipals()); + + } + + function testGetACL() { + + $acl = array( + array( + 'principal' => 'principals/admin', + 'privilege' => '{DAV:}read', + ), + array( + 'principal' => 'principals/admin', + 'privilege' => '{DAV:}write', + ), + ); + + + $tree = array( + new MockACLNode('foo',$acl), + ); + + $server = new DAV\Server($tree); + $aclPlugin = new Plugin(); + $server->addPlugin($aclPlugin); + + $this->assertEquals($acl,$aclPlugin->getACL('foo')); + + } + + function testGetCurrentUserPrivilegeSet() { + + $acl = array( + array( + 'principal' => 'principals/admin', + 'privilege' => '{DAV:}read', + ), + array( + 'principal' => 'principals/user1', + 'privilege' => '{DAV:}read', + ), + array( + 'principal' => 'principals/admin', + 'privilege' => '{DAV:}write', + ), + ); + + + $tree = array( + new MockACLNode('foo',$acl), + + new DAV\SimpleCollection('principals', array( + new MockPrincipal('admin','principals/admin'), + )), + + ); + + $server = new DAV\Server($tree); + $aclPlugin = new Plugin(); + $server->addPlugin($aclPlugin); + + $auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'SabreDAV'); + $server->addPlugin($auth); + + //forcing login + $auth->beforeMethod('GET','/'); + + $expected = array( + '{DAV:}write', + '{DAV:}write-acl', + '{DAV:}write-properties', + '{DAV:}write-content', + '{DAV:}bind', + '{DAV:}unbind', + '{DAV:}unlock', + '{DAV:}read', + '{DAV:}read-acl', + '{DAV:}read-current-user-privilege-set', + ); + + $this->assertEquals($expected,$aclPlugin->getCurrentUserPrivilegeSet('foo')); + + } + + function testCheckPrivileges() { + + $acl = array( + array( + 'principal' => 'principals/admin', + 'privilege' => '{DAV:}read', + ), + array( + 'principal' => 'principals/user1', + 'privilege' => '{DAV:}read', + ), + array( + 'principal' => 'principals/admin', + 'privilege' => '{DAV:}write', + ), + ); + + + $tree = array( + new MockACLNode('foo',$acl), + + new DAV\SimpleCollection('principals', array( + new MockPrincipal('admin','principals/admin'), + )), + + ); + + $server = new DAV\Server($tree); + $aclPlugin = new Plugin(); + $server->addPlugin($aclPlugin); + + $auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'SabreDAV'); + $server->addPlugin($auth); + + //forcing login + //$auth->beforeMethod('GET','/'); + + $this->assertFalse($aclPlugin->checkPrivileges('foo', array('{DAV:}read'), Plugin::R_PARENT, false)); + + } +} + + + + diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/VersionTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/VersionTest.php new file mode 100644 index 000000000..c432527dc --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVACL/VersionTest.php @@ -0,0 +1,17 @@ +<?php + +namespace Sabre\DAVACL; + +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'); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/DAVServerTest.php b/vendor/sabre/dav/tests/Sabre/DAVServerTest.php new file mode 100644 index 000000000..5dc72fda0 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAVServerTest.php @@ -0,0 +1,179 @@ +<?php + +namespace Sabre; + +require_once 'Sabre/HTTP/ResponseMock.php'; +require_once 'Sabre/CalDAV/Backend/Mock.php'; +require_once 'Sabre/CardDAV/Backend/Mock.php'; +require_once 'Sabre/DAVACL/PrincipalBackend/Mock.php'; +require_once 'Sabre/DAV/Auth/Backend/Mock.php'; + +/** + * This class may be used as a basis for other webdav-related unittests. + * + * This class is supposed to provide a reasonably big framework to quickly get + * a testing environment running. + * + * @package Sabre + * @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 + */ +abstract class DAVServerTest extends \PHPUnit_Framework_TestCase { + + protected $setupCalDAV = false; + protected $setupCardDAV = false; + protected $setupACL = false; + protected $setupCalDAVSharing = false; + + protected $caldavCalendars = array(); + protected $caldavCalendarObjects = array(); + + protected $carddavAddressBooks = array(); + protected $carddavCards = array(); + + /** + * @var Sabre\DAV\Server + */ + protected $server; + protected $tree = array(); + + protected $caldavBackend; + protected $carddavBackend; + protected $principalBackend; + + /** + * @var Sabre\CalDAV\Plugin + */ + protected $caldavPlugin; + + /** + * @var Sabre\CardDAV\Plugin + */ + protected $carddavPlugin; + + /** + * @var Sabre\DAVACL\Plugin + */ + protected $aclPlugin; + + /** + * @var Sabre\CalDAV\SharingPlugin + */ + protected $caldavSharingPlugin; + + /** + * @var Sabre\DAV\Auth\Plugin + */ + protected $authPlugin; + + /** + * If this string is set, we will automatically log in the user with this + * name. + */ + protected $autoLogin = null; + + function setUp() { + + $this->setUpBackends(); + $this->setUpTree(); + + $this->server = new DAV\Server($this->tree); + $this->server->debugExceptions = true; + + if ($this->setupCalDAV) { + $this->caldavPlugin = new CalDAV\Plugin(); + $this->server->addPlugin($this->caldavPlugin); + } + if ($this->setupCalDAVSharing) { + $this->caldavSharingPlugin = new CalDAV\SharingPlugin(); + $this->server->addPlugin($this->caldavSharingPlugin); + } + if ($this->setupCardDAV) { + $this->carddavPlugin = new CardDAV\Plugin(); + $this->server->addPlugin($this->carddavPlugin); + } + if ($this->setupACL) { + $this->aclPlugin = new DAVACL\Plugin(); + $this->server->addPlugin($this->aclPlugin); + } + if ($this->autoLogin) { + $authBackend = new DAV\Auth\Backend\Mock(); + $authBackend->defaultUser = $this->autoLogin; + $this->authPlugin = new DAV\Auth\Plugin($authBackend, 'SabreDAV'); + $this->server->addPlugin($this->authPlugin); + + // This will trigger the actual login procedure + $this->authPlugin->beforeMethod('OPTIONS','/'); + } + + } + + /** + * Makes a request, and returns a response object. + * + * You can either pass an instance of Sabre\HTTP\Request, or an array, + * which will then be used as the _SERVER array. + * + * @param array|\Sabre\HTTP\Request $request + * @return \Sabre\HTTP\Response + */ + function request($request) { + + if (is_array($request)) { + $request = new HTTP\Request($request); + } + $this->server->httpRequest = $request; + $this->server->httpResponse = new HTTP\ResponseMock(); + $this->server->exec(); + + return $this->server->httpResponse; + + } + + function setUpTree() { + + if ($this->setupCalDAV) { + $this->tree[] = new CalDAV\CalendarRootNode( + $this->principalBackend, + $this->caldavBackend + ); + } + if ($this->setupCardDAV) { + $this->tree[] = new CardDAV\AddressBookRoot( + $this->principalBackend, + $this->carddavBackend + ); + } + + if ($this->setupCardDAV || $this->setupCalDAV) { + $this->tree[] = new DAVACL\PrincipalCollection( + $this->principalBackend + ); + } + + } + + function setUpBackends() { + + if ($this->setupCalDAV && is_null($this->caldavBackend)) { + $this->caldavBackend = new CalDAV\Backend\Mock($this->caldavCalendars, $this->caldavCalendarObjects); + } + if ($this->setupCardDAV && is_null($this->carddavBackend)) { + $this->carddavBackend = new CardDAV\Backend\Mock($this->carddavAddressBooks, $this->carddavCards); + } + if ($this->setupCardDAV || $this->setupCalDAV) { + $this->principalBackend = new DAVACL\PrincipalBackend\Mock(); + } + + } + + + function assertHTTPStatus($expectedStatus, HTTP\Request $req) { + + $resp = $this->request($req); + $this->assertEquals($resp->getStatusMessage($expectedStatus), $resp->status,'Incorrect HTTP status received: ' . $resp->body); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/AWSAuthTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/AWSAuthTest.php new file mode 100644 index 000000000..569ec2e7d --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/HTTP/AWSAuthTest.php @@ -0,0 +1,242 @@ +<?php + +namespace Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class AWSAuthTest extends \PHPUnit_Framework_TestCase { + + /** + * @var Sabre\HTTP\ResponseMock + */ + private $response; + /** + * @var Sabre\HTTP\AWSAuth + */ + private $auth; + + const REALM = 'SabreDAV unittest'; + + public function setUp() { + + $this->response = new ResponseMock(); + $this->auth = new AWSAuth(); + $this->auth->setRealm(self::REALM); + $this->auth->setHTTPResponse($this->response); + + } + + public function testNoHeader() { + + $request = new Request(array( + 'REQUEST_METHOD' => 'GET', + )); + + $this->auth->setHTTPRequest($request); + + $result = $this->auth->init(); + + $this->assertFalse($result,'No AWS Authorization header was supplied, so we should have gotten false'); + $this->assertEquals(AWSAuth::ERR_NOAWSHEADER,$this->auth->errorCode); + + } + + public function testIncorrectContentMD5() { + + $accessKey = 'accessKey'; + $secretKey = 'secretKey'; + + $request = new Request(array( + 'REQUEST_METHOD' => 'GET', + 'HTTP_AUTHORIZATION' => "AWS $accessKey:sig", + 'HTTP_CONTENT_MD5' => 'garbage', + 'REQUEST_URI' => '/', + )); + + $this->auth->setHTTPRequest($request); + $this->auth->init(); + $result = $this->auth->validate($secretKey); + + $this->assertFalse($result); + $this->assertEquals(AWSAuth::ERR_MD5CHECKSUMWRONG,$this->auth->errorCode); + + } + + public function testNoDate() { + + $accessKey = 'accessKey'; + $secretKey = 'secretKey'; + $content = 'thisisthebody'; + $contentMD5 = base64_encode(md5($content,true)); + + + $request = new Request(array( + 'REQUEST_METHOD' => 'POST', + 'HTTP_AUTHORIZATION' => "AWS $accessKey:sig", + 'HTTP_CONTENT_MD5' => $contentMD5, + )); + + $request->setBody($content); + + $this->auth->setHTTPRequest($request); + $this->auth->init(); + $result = $this->auth->validate($secretKey); + + $this->assertFalse($result); + $this->assertEquals(AWSAuth::ERR_INVALIDDATEFORMAT,$this->auth->errorCode); + + } + + public function testFutureDate() { + + $accessKey = 'accessKey'; + $secretKey = 'secretKey'; + $content = 'thisisthebody'; + $contentMD5 = base64_encode(md5($content,true)); + + $date = new \DateTime('@' . (time() + (60*20))); + $date->setTimeZone(new \DateTimeZone('GMT')); + $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); + + $request = new Request(array( + 'REQUEST_METHOD' => 'POST', + 'HTTP_AUTHORIZATION' => "AWS $accessKey:sig", + 'HTTP_CONTENT_MD5' => $contentMD5, + 'HTTP_DATE' => $date, + )); + + $request->setBody($content); + + $this->auth->setHTTPRequest($request); + $this->auth->init(); + $result = $this->auth->validate($secretKey); + + $this->assertFalse($result); + $this->assertEquals(AWSAuth::ERR_REQUESTTIMESKEWED,$this->auth->errorCode); + + } + + public function testPastDate() { + + $accessKey = 'accessKey'; + $secretKey = 'secretKey'; + $content = 'thisisthebody'; + $contentMD5 = base64_encode(md5($content,true)); + + $date = new \DateTime('@' . (time() - (60*20))); + $date->setTimeZone(new \DateTimeZone('GMT')); + $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); + + $request = new Request(array( + 'REQUEST_METHOD' => 'POST', + 'HTTP_AUTHORIZATION' => "AWS $accessKey:sig", + 'HTTP_CONTENT_MD5' => $contentMD5, + 'HTTP_X_AMZ_DATE' => $date, + )); + + $request->setBody($content); + + $this->auth->setHTTPRequest($request); + $this->auth->init(); + $result = $this->auth->validate($secretKey); + + $this->assertFalse($result); + $this->assertEquals(AWSAuth::ERR_REQUESTTIMESKEWED,$this->auth->errorCode); + + } + + public function testIncorrectSignature() { + + $accessKey = 'accessKey'; + $secretKey = 'secretKey'; + $content = 'thisisthebody'; + + $contentMD5 = base64_encode(md5($content,true)); + + $date = new \DateTime('now'); + $date->setTimeZone(new \DateTimeZone('GMT')); + $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); + + $request = new Request(array( + 'REQUEST_METHOD' => 'POST', + 'HTTP_AUTHORIZATION' => "AWS $accessKey:sig", + 'HTTP_CONTENT_MD5' => $contentMD5, + 'HTTP_X_AMZ_DATE' => $date, + 'REQUEST_URI' => '/', + )); + + $request->setBody($content); + + $this->auth->setHTTPRequest($request); + $this->auth->init(); + $result = $this->auth->validate($secretKey); + + $this->assertFalse($result); + $this->assertEquals(AWSAuth::ERR_INVALIDSIGNATURE,$this->auth->errorCode); + + } + + public function testValidRequest() { + + $accessKey = 'accessKey'; + $secretKey = 'secretKey'; + $content = 'thisisthebody'; + $contentMD5 = base64_encode(md5($content,true)); + + $date = new \DateTime('now'); + $date->setTimeZone(new \DateTimeZone('GMT')); + $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); + + + $sig = base64_encode($this->hmacsha1($secretKey, + "POST\n$contentMD5\n\n$date\nx-amz-date:$date\n/evert" + )); + + $request = new Request(array( + 'REQUEST_METHOD' => 'POST', + 'HTTP_AUTHORIZATION' => "AWS $accessKey:$sig", + 'HTTP_CONTENT_MD5' => $contentMD5, + 'HTTP_X_AMZ_DATE' => $date, + 'REQUEST_URI' => '/evert', + )); + + $request->setBody($content); + + $this->auth->setHTTPRequest($request); + $this->auth->init(); + $result = $this->auth->validate($secretKey); + + $this->assertTrue($result,'Signature did not validate, got errorcode ' . $this->auth->errorCode); + $this->assertEquals($accessKey,$this->auth->getAccessKey()); + + } + + public function test401() { + + $this->auth->requireLogin(); + $test = preg_match('/^AWS$/',$this->response->headers['WWW-Authenticate'],$matches); + $this->assertTrue($test==true,'The WWW-Authenticate response didn\'t match our pattern'); + + } + + /** + * Generates an HMAC-SHA1 signature + * + * @param string $key + * @param string $message + * @return string + */ + private function hmacsha1($key, $message) { + + $blocksize=64; + if (strlen($key)>$blocksize) + $key=pack('H*', sha1($key)); + $key=str_pad($key,$blocksize,chr(0x00)); + $ipad=str_repeat(chr(0x36),$blocksize); + $opad=str_repeat(chr(0x5c),$blocksize); + $hmac = pack('H*',sha1(($key^$opad).pack('H*',sha1(($key^$ipad).$message)))); + return $hmac; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/BasicAuthTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/BasicAuthTest.php new file mode 100644 index 000000000..77c5c7179 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/HTTP/BasicAuthTest.php @@ -0,0 +1,132 @@ +<?php + +namespace Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class BasicAuthTest extends \PHPUnit_Framework_TestCase { + + /** + * @var Sabre\HTTP\ResponseMock + */ + private $response; + /** + * @var Sabre\HTTP\BasicAuth + */ + private $basicAuth; + + function setUp() { + + $this->response = new ResponseMock(); + $this->basicAuth = new BasicAuth(); + $this->basicAuth->setHTTPResponse($this->response); + + } + + function testGetUserPassApache() { + + $server = array( + 'PHP_AUTH_USER' => 'admin', + 'PHP_AUTH_PW' => '1234', + ); + + $request = new Request($server); + $this->basicAuth->setHTTPRequest($request); + + $userPass = $this->basicAuth->getUserPass(); + + $this->assertEquals( + array('admin','1234'), + $userPass, + 'We did not get the username and password we expected' + ); + + } + + function testGetUserPassIIS() { + + $server = array( + 'HTTP_AUTHORIZATION' => 'Basic ' . base64_encode('admin:1234'), + ); + + $request = new Request($server); + $this->basicAuth->setHTTPRequest($request); + + $userPass = $this->basicAuth->getUserPass(); + + $this->assertEquals( + array('admin','1234'), + $userPass, + 'We did not get the username and password we expected' + ); + + } + + function testGetUserPassWithColon() { + + $server = array( + 'HTTP_AUTHORIZATION' => 'Basic ' . base64_encode('admin:1234:5678'), + ); + + $request = new Request($server); + $this->basicAuth->setHTTPRequest($request); + + $userPass = $this->basicAuth->getUserPass(); + + $this->assertEquals( + array('admin','1234:5678'), + $userPass, + 'We did not get the username and password we expected' + ); + + } + + function testGetUserPassApacheEdgeCase() { + + $server = array( + 'REDIRECT_HTTP_AUTHORIZATION' => 'Basic ' . base64_encode('admin:1234'), + ); + + $request = new Request($server); + $this->basicAuth->setHTTPRequest($request); + + $userPass = $this->basicAuth->getUserPass(); + + $this->assertEquals( + array('admin','1234'), + $userPass, + 'We did not get the username and password we expected' + ); + + } + + function testGetUserPassNothing() { + + $this->assertEquals( + false, + $this->basicAuth->getUserPass() + ); + + } + + function testRequireLogin() { + + $this->basicAuth->requireLogin(); + $this->assertEquals('SabreDAV',$this->basicAuth->getRealm()); + $this->assertEquals( + 'HTTP/1.1 401 Unauthorized', + $this->response->status, + 'We expected a 401 status to be set' + ); + + $this->assertEquals( + 'Basic realm="SabreDAV"', + $this->response->headers['WWW-Authenticate'], + 'The WWW-Autenticate header was not set!' + ); + + + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/DigestAuthTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/DigestAuthTest.php new file mode 100644 index 000000000..576a00d4a --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/HTTP/DigestAuthTest.php @@ -0,0 +1,228 @@ +<?php + +namespace Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class DigestAuthTest extends \PHPUnit_Framework_TestCase { + + /** + * @var Sabre\HTTP\ResponseMock + */ + private $response; + /** + * @var Sabre\HTTP\DigestAuth + */ + private $auth; + + const REALM = 'SabreDAV unittest'; + + public function setUp() { + + $this->response = new ResponseMock(); + $this->auth = new DigestAuth(); + $this->auth->setRealm(self::REALM); + $this->auth->setHTTPResponse($this->response); + + } + + public function testDigest() { + + list($nonce,$opaque) = $this->getServerTokens(); + + $username = 'admin'; + $password = 12345; + $nc = '00002'; + $cnonce = uniqid(); + + $digestHash = md5( + md5($username . ':' . self::REALM . ':' . $password) . ':' . + $nonce . ':' . + $nc . ':' . + $cnonce . ':' . + 'auth:' . + md5('GET' . ':' . '/') + ); + + $request = new Request(array( + 'REQUEST_METHOD' => 'GET', + 'PHP_AUTH_DIGEST' => 'username="'.$username.'", realm="' . self::REALM . '", nonce="' . $nonce . '", uri="/", response="' . $digestHash . '", opaque="' . $opaque . '", qop=auth,nc='.$nc.',cnonce="' . $cnonce . '"', + )); + + $this->auth->setHTTPRequest($request); + $this->auth->init(); + + $this->assertEquals($username,$this->auth->getUserName()); + $this->assertEquals(self::REALM,$this->auth->getRealm()); + $this->assertTrue($this->auth->validateA1(md5($username . ':' . self::REALM . ':' . $password)),'Authentication is deemed invalid through validateA1'); + $this->assertTrue($this->auth->validatePassword($password),'Authentication is deemed invalid through validatePassword'); + + } + + public function testDigestCGIFormat() { + + list($nonce,$opaque) = $this->getServerTokens(); + + $username = 'admin'; + $password = 12345; + $nc = '00002'; + $cnonce = uniqid(); + + $digestHash = md5( + md5($username . ':' . self::REALM . ':' . $password) . ':' . + $nonce . ':' . + $nc . ':' . + $cnonce . ':' . + 'auth:' . + md5('GET' . ':' . '/') + ); + + $request = new Request(array( + 'REQUEST_METHOD' => 'GET', + 'HTTP_AUTHORIZATION' => 'Digest username="'.$username.'", realm="' . self::REALM . '", nonce="' . $nonce . '", uri="/", response="' . $digestHash . '", opaque="' . $opaque . '", qop=auth,nc='.$nc.',cnonce="' . $cnonce . '"', + )); + + $this->auth->setHTTPRequest($request); + $this->auth->init(); + + $this->assertTrue($this->auth->validateA1(md5($username . ':' . self::REALM . ':' . $password)),'Authentication is deemed invalid through validateA1'); + $this->assertTrue($this->auth->validatePassword($password),'Authentication is deemed invalid through validatePassword'); + + } + + public function testDigestApacheEdgeCase() { + + list($nonce,$opaque) = $this->getServerTokens(); + + $username = 'admin'; + $password = 12345; + $nc = '00002'; + $cnonce = uniqid(); + + $digestHash = md5( + md5($username . ':' . self::REALM . ':' . $password) . ':' . + $nonce . ':' . + $nc . ':' . + $cnonce . ':' . + 'auth:' . + md5('GET' . ':' . '/') + ); + + $request = new Request(array( + 'REQUEST_METHOD' => 'GET', + 'REDIRECT_HTTP_AUTHORIZATION' => 'Digest username="'.$username.'", realm="' . self::REALM . '", nonce="' . $nonce . '", uri="/", response="' . $digestHash . '", opaque="' . $opaque . '", qop=auth,nc='.$nc.',cnonce="' . $cnonce . '"', + )); + + $this->auth->setHTTPRequest($request); + $this->auth->init(); + + $this->assertTrue($this->auth->validateA1(md5($username . ':' . self::REALM . ':' . $password)),'Authentication is deemed invalid through validateA1'); + $this->assertTrue($this->auth->validatePassword($password),'Authentication is deemed invalid through validatePassword'); + + } + + public function testInvalidDigest() { + + list($nonce,$opaque) = $this->getServerTokens(); + + $username = 'admin'; + $password = 12345; + $nc = '00002'; + $cnonce = uniqid(); + + $digestHash = md5( + md5($username . ':' . self::REALM . ':' . $password) . ':' . + $nonce . ':' . + $nc . ':' . + $cnonce . ':' . + 'auth:' . + md5('GET' . ':' . '/') + ); + + $request = new Request(array( + 'REQUEST_METHOD' => 'GET', + 'PHP_AUTH_DIGEST' => 'username="'.$username.'", realm="' . self::REALM . '", nonce="' . $nonce . '", uri="/", response="' . $digestHash . '", opaque="' . $opaque . '", qop=auth,nc='.$nc.',cnonce="' . $cnonce . '"', + )); + + $this->auth->setHTTPRequest($request); + $this->auth->init(); + + $this->assertFalse($this->auth->validateA1(md5($username . ':' . self::REALM . ':' . ($password . 'randomness'))),'Authentication is deemed invalid through validateA1'); + + } + + public function testInvalidDigest2() { + + $request = new Request(array( + 'REQUEST_METHOD' => 'GET', + 'HTTP_AUTHORIZATION' => 'basic blablabla', + )); + + $this->auth->setHTTPRequest($request); + $this->auth->init(); + + $this->assertFalse($this->auth->validateA1(md5('user:realm:password'))); + + } + + + public function testDigestAuthInt() { + + $this->auth->setQOP(DigestAuth::QOP_AUTHINT | DigestAuth::QOP_AUTH); + list($nonce,$opaque) = $this->getServerTokens(DigestAuth::QOP_AUTHINT| DigestAuth::QOP_AUTH); + + $username = 'admin'; + $password = 12345; + $nc = '00003'; + $cnonce = uniqid(); + + $digestHash = md5( + md5($username . ':' . self::REALM . ':' . $password) . ':' . + $nonce . ':' . + $nc . ':' . + $cnonce . ':' . + 'auth-int:' . + md5('POST' . ':' . '/' . ':' . md5('body')) + ); + + $request = new Request(array( + 'REQUEST_METHOD' => 'POST', + 'PHP_AUTH_DIGEST' => 'username="'.$username.'", realm="' . self::REALM . '", nonce="' . $nonce . '", uri="/", response="' . $digestHash . '", opaque="' . $opaque . '", qop=auth-int,nc='.$nc.',cnonce="' . $cnonce . '"', + )); + $request->setBody('body'); + + $this->auth->setHTTPRequest($request); + + $this->auth->init(); + + $this->assertTrue($this->auth->validateA1(md5($username . ':' . self::REALM . ':' . $password)),'Authentication is deemed invalid through validateA1'); + + } + + private function getServerTokens($qop = DigestAuth::QOP_AUTH) { + + $this->auth->requireLogin(); + + switch($qop) { + case DigestAuth::QOP_AUTH : $qopstr='auth'; break; + case DigestAuth::QOP_AUTHINT : $qopstr='auth-int'; break; + default : $qopstr='auth,auth-int'; break; + } + + $test = preg_match('/Digest realm="'.self::REALM.'",qop="'.$qopstr.'",nonce="([0-9a-f]*)",opaque="([0-9a-f]*)"/', + $this->response->headers['WWW-Authenticate'],$matches); + + $this->assertTrue($test==true,'The WWW-Authenticate response didn\'t match our pattern. We received: ' . $this->response->headers['WWW-Authenticate']); + + $nonce = $matches[1]; + $opaque = $matches[2]; + + // Reset our environment + $this->setUp(); + $this->auth->setQOP($qop); + + return array($nonce,$opaque); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/RequestTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/RequestTest.php new file mode 100644 index 000000000..c52ce351d --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/HTTP/RequestTest.php @@ -0,0 +1,150 @@ +<?php + +namespace Sabre\HTTP; + +/** + * @covers Sabre\HTTP\Request + */ +class RequestTest extends \PHPUnit_Framework_TestCase { + + /** + * @var Sabre\HTTP\Request + */ + private $request; + + function setUp() { + + $server = array( + 'HTTP_HOST' => 'www.example.org', + 'REQUEST_METHOD' => 'PUT', + 'REQUEST_URI' => '/testuri/', + 'CONTENT_TYPE' => 'text/xml', + ); + + $this->request = new Request($server); + + } + + function testGetHeader() { + + $this->assertEquals('www.example.org', $this->request->getHeader('Host')); + $this->assertEquals('text/xml', $this->request->getHeader('Content-Type')); + + } + + function testGetNonExistantHeader() { + + $this->assertNull($this->request->getHeader('doesntexist')); + $this->assertNull($this->request->getHeader('Content-Length')); + + } + + function testGetHeaders() { + + $expected = array( + 'host' => 'www.example.org', + 'content-type' => 'text/xml', + ); + + $this->assertEquals($expected, $this->request->getHeaders()); + + } + + function testGetMethod() { + + $this->assertEquals('PUT', $this->request->getMethod(), 'It seems as if we didn\'t get a valid HTTP Request method back'); + + } + + function testGetUri() { + + $this->assertEquals('/testuri/', $this->request->getUri(), 'We got an invalid uri back'); + + } + + function testSetGetBody() { + + $h = fopen('php://memory','r+'); + fwrite($h,'testing'); + rewind($h); + $this->request->setBody($h); + $this->assertEquals('testing',$this->request->getBody(true),'We didn\'t get our testbody back'); + + } + + function testSetGetBodyStream() { + + $h = fopen('php://memory','r+'); + fwrite($h,'testing'); + rewind($h); + $this->request->setBody($h); + $this->assertEquals('testing',stream_get_contents($this->request->getBody()),'We didn\'t get our testbody back'); + + } + + + function testDefaultInputStream() { + + $h = fopen('php://memory','r+'); + fwrite($h,'testing'); + rewind($h); + + $previousValue = Request::$defaultInputStream; + Request::$defaultInputStream = $h; + + $this->assertEquals('testing',$this->request->getBody(true),'We didn\'t get our testbody back'); + Request::$defaultInputStream = $previousValue; + + } + + function testGetAbsoluteUri() { + + $s = array( + 'HTTP_HOST' => 'sabredav.org', + 'REQUEST_URI' => '/foo' + ); + + $r = new Request($s); + + $this->assertEquals('http://sabredav.org/foo', $r->getAbsoluteUri()); + + $s = array( + 'HTTP_HOST' => 'sabredav.org', + 'REQUEST_URI' => '/foo', + 'HTTPS' => 'on', + ); + + $r = new Request($s); + + $this->assertEquals('https://sabredav.org/foo', $r->getAbsoluteUri()); + + } + + function testGetQueryString() { + + $s = array( + 'QUERY_STRING' => 'bla', + ); + + $r = new Request($s); + $this->assertEquals('bla', $r->getQueryString()); + + $s = array(); + + $r = new Request($s); + $this->assertEquals('', $r->getQueryString()); + + } + + function testGetPostVars() { + + $post = array( + 'bla' => 'foo', + ); + $r = new Request(array(),$post); + $this->assertEquals($post, $r->getPostVars('bla')); + + } + + +} diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php b/vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php new file mode 100644 index 000000000..16c034099 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php @@ -0,0 +1,29 @@ +<?php + +namespace Sabre\HTTP; + +class ResponseMock extends Response { + + public $headers = array(); + public $status = ''; + public $body = ''; + + function setHeader($name,$value,$overwrite = true) { + + $this->headers[$name] = $value; + + } + + function sendStatus($code) { + + $this->status = $this->getStatusMessage($code, $this->defaultHttpVersion); + + } + + function sendBody($body) { + + $this->body = $body; + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/ResponseTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/ResponseTest.php new file mode 100644 index 000000000..f5302c993 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/HTTP/ResponseTest.php @@ -0,0 +1,70 @@ +<?php + +namespace Sabre\HTTP; + +require_once 'Sabre/HTTP/ResponseMock.php'; + +class ResponseTest extends \PHPUnit_Framework_TestCase { + + /** + * @var Sabre\HTTP\ResponseMock + */ + private $response; + + function setUp() { + + $this->response = new ResponseMock(); + + } + + function testGetStatusMessage() { + + $msg = $this->response->getStatusMessage(200); + $this->assertEquals('HTTP/1.1 200 OK',$msg); + + } + + function testSetHeader() { + + $this->response->setHeader('Content-Type','text/html'); + $this->assertEquals('text/html', $this->response->headers['Content-Type']); + + + } + function testSetHeaders() { + + $this->response->setHeaders(array('Content-Type'=>'text/html')); + $this->assertEquals('text/html', $this->response->headers['Content-Type']); + + + } + + function testSendStatus() { + + $this->response->sendStatus(404); + $this->assertEquals('HTTP/1.1 404 Not Found', $this->response->status); + + } + + function testSendBody() { + + ob_start(); + $response = new Response(); + $response->sendBody('hello'); + $this->assertEquals('hello',ob_get_clean()); + + } + + function testSendBodyStream() { + + ob_start(); + $stream = fopen('php://memory','r+'); + fwrite($stream,'hello'); + rewind($stream); + $response = new Response(); + $response->sendBody($stream); + $this->assertEquals('hello',ob_get_clean()); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/UtilTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/UtilTest.php new file mode 100644 index 000000000..47a7b98bd --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/HTTP/UtilTest.php @@ -0,0 +1,78 @@ +<?php + +namespace Sabre\HTTP; + +class UtilTest extends \PHPUnit_Framework_TestCase { + + function testParseHTTPDate() { + + $times = array( + 'Wed, 13 Oct 2010 10:26:00 GMT', + 'Wednesday, 13-Oct-10 10:26:00 GMT', + 'Wed Oct 13 10:26:00 2010', + ); + + $expected = 1286965560; + + foreach($times as $time) { + $result = Util::parseHTTPDate($time); + $this->assertEquals($expected, $result->format('U')); + } + + $result = Util::parseHTTPDate('Wed Oct 6 10:26:00 2010'); + $this->assertEquals(1286360760, $result->format('U')); + + } + + function testParseHTTPDateFail() { + + $times = array( + //random string + 'NOW', + // not-GMT timezone + 'Wednesday, 13-Oct-10 10:26:00 UTC', + // No space before the 6 + 'Wed Oct 6 10:26:00 2010', + ); + + foreach($times as $time) { + $this->assertFalse(Util::parseHTTPDate($time), 'We used the string: ' . $time); + } + + } + + function testTimezones() { + + $default = date_default_timezone_get(); + date_default_timezone_set('Europe/Amsterdam'); + + $this->testParseHTTPDate(); + + date_default_timezone_set($default); + + } + + function testToHTTPDate() { + + $dt = new \DateTime('2011-12-10 12:00:00 +0200'); + + $this->assertEquals( + 'Sat, 10 Dec 2011 10:00:00 GMT', + Util::toHTTPDate($dt) + ); + + } + + function testStrtotimeFail() { + + // Strtotime may return -1 when the date cannot be parsed. + // We are simulating this situation by testing a date that actually + // results in -1. (because I have found no other way to break this + // code) + + $time = 'Wed, 13 Oct 1960 10:26:00 GMT'; + + $this->assertNull(Util::parseHTTPDate($time)); + + } +} diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/VersionTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/VersionTest.php new file mode 100644 index 000000000..c7094b3bc --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/HTTP/VersionTest.php @@ -0,0 +1,17 @@ +<?php + +namespace Sabre\HTTP; + +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'); + + } + +} diff --git a/vendor/sabre/dav/tests/Sabre/TestUtil.php b/vendor/sabre/dav/tests/Sabre/TestUtil.php new file mode 100644 index 000000000..5a9062498 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/TestUtil.php @@ -0,0 +1,51 @@ +<?php + +namespace Sabre; + +class TestUtil { + + /** + * This function deletes all the contents of the temporary directory. + * + * @return void + */ + static function clearTempDir() { + + self::deleteTree(SABRE_TEMPDIR,false); + + } + + + static private function deleteTree($path,$deleteRoot = true) { + + foreach(scandir($path) as $node) { + + if ($node=='.' || $node=='..') continue; + $myPath = $path.'/'. $node; + if (is_file($myPath)) { + unlink($myPath); + } else { + self::deleteTree($myPath); + } + + } + if ($deleteRoot) { + rmdir($path); + } + + } + + static function getMySQLDB() { + + try { + $pdo = new \PDO(SABRE_MYSQLDSN,SABRE_MYSQLUSER,SABRE_MYSQLPASS); + $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION); + return $pdo; + } catch (\PDOException $e) { + return null; + } + + } + + +} |