Initial Release of the calendar plugin

This commit is contained in:
Tobias Hößl 2012-06-03 18:19:28 +00:00
parent 45cc9885fc
commit 7115197a33
561 changed files with 189494 additions and 0 deletions

View file

@ -0,0 +1,511 @@
<?php
abstract class Sabre_CalDAV_Backend_AbstractPDOTest extends PHPUnit_Framework_TestCase {
protected $pdo;
function testConstruct() {
$backend = new Sabre_CalDAV_Backend_PDO($this->pdo);
$this->assertTrue($backend instanceof Sabre_CalDAV_Backend_PDO);
}
/**
* @depends testConstruct
*/
function testGetCalendarsForUserNoCalendars() {
$backend = new Sabre_CalDAV_Backend_PDO($this->pdo);
$calendars = $backend->getCalendarsForUser('principals/user2');
$this->assertEquals(array(),$calendars);
}
/**
* @depends testConstruct
*/
function testCreateCalendarAndFetch() {
$backend = new Sabre_CalDAV_Backend_PDO($this->pdo);
$returnedId = $backend->createCalendar('principals/user2','somerandomid',array(
'{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Sabre_CalDAV_Property_SupportedCalendarComponentSet(array('VEVENT')),
'{DAV:}displayname' => 'Hello!',
));
$calendars = $backend->getCalendarsForUser('principals/user2');
$elementCheck = array(
'id' => $returnedId,
'uri' => 'somerandomid',
'{DAV:}displayname' => 'Hello!',
'{urn:ietf:params:xml:ns:caldav}calendar-description' => '',
);
$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 Sabre_CalDAV_Backend_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',
));
// 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',
);
$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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_PDO($this->pdo);
$returnedId = $backend->createCalendar('principals/user2','somerandomid',array(
'{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Sabre_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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(Sabre_CalDAV_Backend_PDO::MAX_DATE),
'componenttype' => 'VEVENT',
), $result->fetch(PDO::FETCH_ASSOC));
}
/**
* @depends testCreateCalendarObject
*/
function testCreateCalendarObjectEndingReccurence() {
$backend = new Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_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('20120103'),
'end' => new DateTime('20120104'),
),
),
),
'prop-filters' => array(),
'is-not-defined' => false,
'time-range' => null,
);
$this->assertEquals(array(
"event2",
), $backend->calendarQuery(1, $filters));
}
}

View file

@ -0,0 +1,86 @@
<?php
class Sabre_CalDAV_Backend_AbstractTest extends PHPUnit_Framework_TestCase {
function testUpdateCalendar() {
$abstract = new Sabre_CalDAV_Backend_AbstractMock();
$this->assertEquals(false, $abstract->updateCalendar('randomid', array('{DAV:}displayname' => 'anything')));
}
function testCalendarQuery() {
$abstract = new Sabre_CalDAV_Backend_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 Sabre_CalDAV_Backend_AbstractMock extends Sabre_CalDAV_Backend_Abstract {
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) { }
}

View file

@ -0,0 +1,230 @@
<?php
class Sabre_CalDAV_Backend_Mock extends Sabre_CalDAV_Backend_Abstract {
private $calendarData;
private $calendars;
function __construct(array $calendars, array $calendarData) {
$this->calendars = $calendars;
$this->calendarData = $calendarData;
}
/**
* 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) {
throw new Exception('Not implemented');
}
/**
* 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) {
throw new Exception('Not implemented');
}
/**
* 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 Sabre_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');
}
}

View file

@ -0,0 +1,37 @@
<?php
require_once 'Sabre/TestUtil.php';
require_once 'Sabre/CalDAV/TestUtil.php';
require_once 'Sabre/CalDAV/Backend/AbstractPDOTest.php';
class Sabre_CalDAV_Backend_PDOMySQLTest extends Sabre_CalDAV_Backend_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;
}
}

View file

@ -0,0 +1,21 @@
<?php
require_once 'Sabre/CalDAV/Backend/AbstractPDOTest.php';
class Sabre_CalDAV_Backend_PDOSQLiteTest extends Sabre_CalDAV_Backend_AbstractPDOTest {
function setup() {
if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
$this->pdo = Sabre_CalDAV_TestUtil::getSQLiteDB();
}
function teardown() {
$this->pdo = null;
unlink(SABRE_TEMPDIR . '/testdb.sqlite');
}
}

View file

@ -0,0 +1,360 @@
<?php
require_once 'Sabre/CalDAV/TestUtil.php';
require_once 'Sabre/DAV/Auth/MockBackend.php';
require_once 'Sabre/DAVACL/MockPrincipalBackend.php';
require_once 'Sabre/CalDAV/Backend/Mock.php';
class Sabre_CalDAV_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 = Sabre_CalDAV_TestUtil::getBackend();
$this->principalBackend = new Sabre_DAVACL_MockPrincipalBackend;
$calendars = $this->backend->getCalendarsForUser('principals/user1');
$this->assertEquals(2,count($calendars));
$this->calendar = new Sabre_CalDAV_Calendar($this->principalBackend,$this->backend, $calendars[0]);
}
function teardown() {
unset($this->calendar);
unset($this->backend);
}
function testSetup() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof Sabre_CalDAV_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 Sabre_CalDAV_CalendarObject(
new Sabre_CalDAV_Backend_Mock(array(),array()),
array(),
array()
);
}
/**
* @expectedException InvalidArgumentException
*/
function testInvalidArg2() {
$obj = new Sabre_CalDAV_CalendarObject(
new Sabre_CalDAV_Backend_Mock(array(),array()),
array(),
array('calendarid' => '1')
);
}
/**
* @depends testSetup
*/
function testPut() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof Sabre_CalDAV_CalendarObject);
$newData = Sabre_CalDAV_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 Sabre_CalDAV_CalendarObject);
$newData = Sabre_CalDAV_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 Sabre_CalDAV_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 Sabre_CalDAV_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 Sabre_CalDAV_CalendarObject);
$obj = $children[0];
$size = $obj->getSize();
$this->assertInternalType('int', $size);
}
function testGetOwner() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof Sabre_CalDAV_CalendarObject);
$obj = $children[0];
$this->assertEquals('principals/user1', $obj->getOwner());
}
function testGetGroup() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof Sabre_CalDAV_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 Sabre_CalDAV_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 Sabre_CalDAV_CalendarObject);
$obj = $children[0];
$obj->setACL(array());
}
function testGet() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof Sabre_CalDAV_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 Sabre_CalDAV_Backend_Mock(array(), array(
1 => array(
'foo' => array(
'calendardata' => 'foo',
'uri' => 'foo'
),
)
));
$obj = new Sabre_CalDAV_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 Sabre_CalDAV_Backend_Mock(array(), array());
$obj = new Sabre_CalDAV_CalendarObject($backend, array(), $objectInfo);
$this->assertEquals('bar', $obj->getETag());
}
function testGetEtag2() {
$objectInfo = array(
'calendardata' => 'foo',
'uri' => 'foo',
'calendarid' => 1
);
$backend = new Sabre_CalDAV_Backend_Mock(array(), array());
$obj = new Sabre_CalDAV_CalendarObject($backend, array(), $objectInfo);
$this->assertEquals('"' . md5('foo') . '"', $obj->getETag());
}
function testGetSupportedPrivilegesSet() {
$objectInfo = array(
'calendardata' => 'foo',
'uri' => 'foo',
'calendarid' => 1
);
$backend = new Sabre_CalDAV_Backend_Mock(array(), array());
$obj = new Sabre_CalDAV_CalendarObject($backend, array(), $objectInfo);
$this->assertNull($obj->getSupportedPrivilegeSet());
}
function testGetSize1() {
$objectInfo = array(
'calendardata' => 'foo',
'uri' => 'foo',
'calendarid' => 1
);
$backend = new Sabre_CalDAV_Backend_Mock(array(), array());
$obj = new Sabre_CalDAV_CalendarObject($backend, array(), $objectInfo);
$this->assertEquals(3, $obj->getSize());
}
function testGetSize2() {
$objectInfo = array(
'uri' => 'foo',
'calendarid' => 1,
'size' => 4,
);
$backend = new Sabre_CalDAV_Backend_Mock(array(), array());
$obj = new Sabre_CalDAV_CalendarObject($backend, array(), $objectInfo);
$this->assertEquals(4, $obj->getSize());
}
}

View file

@ -0,0 +1,537 @@
<?php
class Sabre_CalDAV_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 = Sabre_DAV_XMLUtil::loadDOMDocument($xml);
$q = new Sabre_CalDAV_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 = Sabre_DAV_XMLUtil::loadDOMDocument($body);
$q = new Sabre_CalDAV_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 = Sabre_DAV_XMLUtil::loadDOMDocument($xml);
$q = new Sabre_CalDAV_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 = Sabre_DAV_XMLUtil::loadDOMDocument($xml);
$q = new Sabre_CalDAV_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 = Sabre_DAV_XMLUtil::loadDOMDocument($xml);
$q = new Sabre_CalDAV_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 = Sabre_DAV_XMLUtil::loadDOMDocument($xml);
$q = new Sabre_CalDAV_CalendarQueryParser($dom);
$q->parse();
}
}

View file

@ -0,0 +1,115 @@
<?php
class Sabre_CalDAV_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() {
$vevent = Sabre_VObject_Component::create('VEVENT');
$vevent->RRULE = 'FREQ=MONTHLY';
$vevent->DTSTART = '20120101T120000Z';
$vevent->UID = 'bla';
$valarm = Sabre_VObject_Component::create('VALARM');
$valarm->TRIGGER = '-P15D';
$vevent->add($valarm);
$vcalendar = Sabre_VObject_Component::create('VCALENDAR');
$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 Sabre_CalDAV_CalendarQueryValidator();
$this->assertTrue($validator->validate($vcalendar, $filter));
// A limited recurrence rule, should return false
$vevent = Sabre_VObject_Component::create('VEVENT');
$vevent->RRULE = 'FREQ=MONTHLY;COUNT=1';
$vevent->DTSTART = '20120101T120000Z';
$vevent->UID = 'bla';
$valarm = Sabre_VObject_Component::create('VALARM');
$valarm->TRIGGER = '-P15D';
$vevent->add($valarm);
$vcalendar = Sabre_VObject_Component::create('VCALENDAR');
$vcalendar->add($vevent);
$this->assertFalse($validator->validate($vcalendar, $filter));
}
function testAlarmWayBefore() {
$vevent = Sabre_VObject_Component::create('VEVENT');
$vevent->DTSTART = '20120101T120000Z';
$vevent->UID = 'bla';
$valarm = Sabre_VObject_Component::create('VALARM');
$valarm->TRIGGER = '-P2W1D';
$vevent->add($valarm);
$vcalendar = Sabre_VObject_Component::create('VCALENDAR');
$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 Sabre_CalDAV_CalendarQueryValidator();
$this->assertTrue($validator->validate($vcalendar, $filter));
}
}

View file

@ -0,0 +1,748 @@
<?php
class Sabre_CalDAV_CalendarQueryValidatorTest extends PHPUnit_Framework_TestCase {
/**
* @dataProvider provider
*/
function testValid($icalObject, $filters, $outcome) {
$validator = new Sabre_CalDAV_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 = Sabre_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 (Sabre_DAV_Exception $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;
$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,
);
// Time-range with RRULE
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),
);
}
}

View file

@ -0,0 +1,253 @@
<?php
require_once 'Sabre/CalDAV/TestUtil.php';
require_once 'Sabre/DAVACL/MockPrincipalBackend.php';
class Sabre_CalDAV_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 = Sabre_CalDAV_TestUtil::getBackend();
$this->principalBackend = new Sabre_DAVACL_MockPrincipalBackend();
$this->calendars = $this->backend->getCalendarsForUser('principals/user1');
$this->assertEquals(2, count($this->calendars));
$this->calendar = new Sabre_CalDAV_Calendar($this->principalBackend, $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(
'{DAV:}owner',
'{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',
);
$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 Sabre_CalDAV_Property_SupportedCollationSet);
$this->assertTrue($result['{DAV:}owner'] instanceof Sabre_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 Sabre_CalDAV_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,Sabre_CalDAV_TestUtil::getTestCalendarData());
rewind($file);
$this->calendar->createFile('hello',$file);
$file = $this->calendar->getChild('hello');
$this->assertTrue($file instanceof Sabre_CalDAV_CalendarObject);
}
function testCreateFileNoSupportedComponents() {
$file = fopen('php://memory','r+');
fwrite($file,Sabre_CalDAV_TestUtil::getTestCalendarData());
rewind($file);
$calendar = new Sabre_CalDAV_Calendar($this->principalBackend, $this->backend, $this->calendars[1]);
$calendar->createFile('hello',$file);
$file = $calendar->getChild('hello');
$this->assertTrue($file instanceof Sabre_CalDAV_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' => '{' . Sabre_CalDAV_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(
'{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}read-free-busy',
$result['aggregates'][0]['aggregates'][2]['privilege']
);
}
}

View file

@ -0,0 +1,106 @@
<?php
/**
* This unittests is created to find out why recurring events have wrong DTSTART value
*
*
* @copyright Copyright (C) 2007-2012 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 Sabre_CalDAV_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 Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
));
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120205T230000Z" end="20120212T225959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20120205T230000Z" end="20120212T225959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;','',$body);
$vObject = Sabre_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->value, array('20120207T171500Z', '20120208T171500Z', '20120209T171500Z'), 'DTSTART is not a valid value: '.$child->value);
} elseif ($child->name == 'DTEND') {
// DTEND has to be one of three valid values
$this->assertContains($child->value, array('20120207T181500Z', '20120208T181500Z', '20120209T181500Z'), 'DTEND is not a valid value: '.$child->value);
}
}
}
}
}

View file

@ -0,0 +1,100 @@
<?php
/**
* This unittests is created to find out why recurring events have wrong DTSTART value
*
*
* @copyright Copyright (C) 2007-2012 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 Sabre_CalDAV_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 Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
));
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120210T230000Z" end="20120217T225959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20120210T230000Z" end="20120217T225959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;','',$body);
$vObject = Sabre_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->value, array('20120214T171500Z', '20120216T171500Z'), 'DTSTART is not a valid value: '.$child->value);
} elseif ($child->name == 'DTEND') {
// DTEND has to be one of two valid values
$this->assertContains($child->value, array('20120214T181500Z', '20120216T181500Z'), 'DTEND is not a valid value: '.$child->value);
}
}
}
}
}

View file

@ -0,0 +1,99 @@
<?php
/**
* 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-2012 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 Sabre_CalDAV_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 Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
));
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120205T230000Z" end="20120212T225959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20120205T230000Z" end="20120212T225959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;','',$body);
$vObject = Sabre_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']));
}
}

View file

@ -0,0 +1,155 @@
<?php
require_once 'Sabre/CalDAV/Backend/Mock.php';
require_once 'Sabre/DAVACL/MockPrincipalBackend.php';
require_once 'Sabre/HTTP/ResponseMock.php';
class Sabre_CalDAV_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 Sabre_CalDAV_Backend_Mock(array(), $calendarData);
$principalBackend = new Sabre_DAVACL_MockPrincipalBackend();
$calendar = new Sabre_CalDAV_Calendar($principalBackend,$caldavBackend, array(
'id' => 1,
'uri' => 'calendar',
'principaluri' => 'principals/user1',
));
$this->server = new Sabre_DAV_Server(array($calendar));
$request = new Sabre_HTTP_Request(array(
'REQUEST_URI' => '/calendar',
));
$this->server->httpRequest = $request;
$this->server->httpResponse = new Sabre_HTTP_ResponseMock();
$this->plugin = new Sabre_CalDAV_Plugin();
$this->server->addPlugin($this->plugin);
$this->server->addPlugin(new Sabre_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 = Sabre_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 = Sabre_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 Sabre_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 = Sabre_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 Sabre_DAV_Server();
$this->plugin = new Sabre_CalDAV_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 = Sabre_DAV_XMLUtil::loadDOMDocument($reportXML);
$this->plugin->report('{urn:ietf:params:xml:ns:caldav}free-busy-query', $dom);
}
}

View file

@ -0,0 +1,93 @@
<?php
/**
* This unittest is created to check if queries for time-range include the start timestamp or not
*
*
* @copyright Copyright (C) 2007-2012 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 Sabre_CalDAV_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 Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
));
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120226T230000Z" end="20120228T225959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20120226T230000Z" end="20120228T225959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
if (strpos($response->body, 'BEGIN:VCALENDAR') === false) {
$this->fail('Got no events instead of 1. Output: '.$response->body);
}
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;','',$body);
$vObject = Sabre_VObject_Reader::read($body);
// We expect 1 event
$this->assertEquals(1, count($vObject->VEVENT), 'We got 0 events instead of 1. Output: ' . $body);
}
}

View file

@ -0,0 +1,174 @@
<?php
require_once 'Sabre/CalDAV/TestUtil.php';
require_once 'Sabre/DAV/Auth/MockBackend.php';
require_once 'Sabre/HTTP/ResponseMock.php';
class Sabre_CalDAV_ICSExportPluginTest extends PHPUnit_Framework_TestCase {
function testInit() {
$p = new Sabre_CalDAV_ICSExportPlugin();
$s = new Sabre_DAV_Server();
$s->addPlugin($p);
}
function testBeforeMethod() {
if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
$cbackend = Sabre_CalDAV_TestUtil::getBackend();
$pbackend = new Sabre_DAVACL_MockPrincipalBackend();
$props = array(
'uri'=>'UUID-123467',
'principaluri' => 'admin',
'id' => 1,
);
$tree = array(
new Sabre_CalDAV_Calendar($pbackend,$cbackend,$props),
);
$p = new Sabre_CalDAV_ICSExportPlugin();
$s = new Sabre_DAV_Server($tree);
$s->addPlugin($p);
$s->addPlugin(new Sabre_CalDAV_Plugin());
$h = new Sabre_HTTP_Request(array(
'QUERY_STRING' => 'export',
));
$s->httpRequest = $h;
$s->httpResponse = new Sabre_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 = Sabre_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));
}
function testBeforeMethodNoGET() {
$p = new Sabre_CalDAV_ICSExportPlugin();
$s = new Sabre_DAV_Server();
$s->addPlugin($p);
$this->assertNull($p->beforeMethod('POST','UUID-123467?export'));
}
function testBeforeMethodNoExport() {
$p = new Sabre_CalDAV_ICSExportPlugin();
$s = new Sabre_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 = Sabre_CalDAV_TestUtil::getBackend();
$pbackend = new Sabre_DAVACL_MockPrincipalBackend();
$props = array(
'uri'=>'UUID-123467',
'principaluri' => 'admin',
'id' => 1,
);
$tree = array(
new Sabre_CalDAV_Calendar($pbackend,$cbackend,$props),
);
$p = new Sabre_CalDAV_ICSExportPlugin();
$s = new Sabre_DAV_Server($tree);
$s->addPlugin($p);
$s->addPlugin(new Sabre_CalDAV_Plugin());
$s->addPlugin(new Sabre_DAVACL_Plugin());
$h = new Sabre_HTTP_Request(array(
'QUERY_STRING' => 'export',
));
$s->httpRequest = $h;
$s->httpResponse = new Sabre_HTTP_ResponseMock();
$p->beforeMethod('GET','UUID-123467?export');
}
function testACLIntegrationNotBlocked() {
if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
$cbackend = Sabre_CalDAV_TestUtil::getBackend();
$pbackend = new Sabre_DAVACL_MockPrincipalBackend();
$props = array(
'uri'=>'UUID-123467',
'principaluri' => 'admin',
'id' => 1,
);
$tree = array(
new Sabre_CalDAV_Calendar($pbackend,$cbackend,$props),
new Sabre_DAVACL_PrincipalCollection($pbackend),
);
$p = new Sabre_CalDAV_ICSExportPlugin();
$s = new Sabre_DAV_Server($tree);
$s->addPlugin($p);
$s->addPlugin(new Sabre_CalDAV_Plugin());
$s->addPlugin(new Sabre_DAVACL_Plugin());
$s->addPlugin(new Sabre_DAV_Auth_Plugin(new Sabre_DAV_Auth_MockBackend(),'SabreDAV'));
// Forcing login
$s->getPlugin('acl')->adminPrincipals = array('principals/admin');
$h = new Sabre_HTTP_Request(array(
'QUERY_STRING' => 'export',
'REQUEST_URI' => '/UUID-123467',
'REQUEST_METHOD' => 'GET',
));
$s->httpRequest = $h;
$s->httpResponse = new Sabre_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 = Sabre_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));
}
}

View file

@ -0,0 +1,59 @@
<?php
class Sabre_CalDAV_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 Sabre_CalDAV_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 = Sabre_VObject_Reader::read($input);
$this->assertTrue($validator->validate($input,$filters));
}
}

View file

@ -0,0 +1,131 @@
<?php
class Sabre_CalDAV_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 Sabre_CalDAV_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 = Sabre_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 Sabre_CalDAV_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 = Sabre_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 Sabre_CalDAV_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 = Sabre_VObject_Reader::read($input);
$this->assertTrue($validator->validate($input,$filters));
}
}

View file

@ -0,0 +1,135 @@
<?php
/**
* This unittest is created to find out why an overwritten DAILY event has wrong DTSTART, DTEND, SUMMARY and RECURRENCEID
*
*
* @copyright Copyright (C) 2007-2012 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 Sabre_CalDAV_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 Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
));
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120325T220000Z" end="20120401T215959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20120325T220000Z" end="20120401T215959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;','',$body);
$vObject = Sabre_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->value) {
continue 2;
}
}
}
$matching = true;
break;
}
$this->assertTrue($matching, 'Did not find the following event in the response: '.var_export($expectedEvent, true));
}
}
}

View file

@ -0,0 +1,94 @@
<?php
/**
* This unittest is created to check if a VALARM TRIGGER of PT0S is supported
*
*
* @copyright Copyright (C) 2007-2012 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 Sabre_CalDAV_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 Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
));
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120325T220000Z" end="20120401T215959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:comp-filter name="VALARM">
<C:time-range start="20120325T220000Z" end="20120401T215959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
$this->assertFalse(strpos($response->body, '<s:exception>Exception</s:exception>'), 'Exception occurred: ' . $response->body);
$this->assertFalse(strpos($response->body, 'Unknown or bad format'), 'DateTime unknown format Exception: ' . $response->body);
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;','',$body);
$vObject = Sabre_VObject_Reader::read($body);
$this->assertEquals(1, count($vObject->VEVENT));
}
}

View file

@ -0,0 +1,86 @@
<?php
/**
* This unittest is created to check for an endless loop in Sabre_CalDAV_CalendarQueryValidator
*
*
* @copyright Copyright (C) 2007-2012 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 Sabre_CalDAV_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 Sabre_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));
}
}

View file

@ -0,0 +1,321 @@
<?php
require_once 'Sabre/DAVServerTest.php';
require_once 'Sabre/CalDAV/Schedule/IMip/Mock.php';
class Sabre_CalDAV_OutboxPostTest extends Sabre_DAVServerTest {
protected $setupCalDAV = true;
function testPostPassThruNotFound() {
$req = new Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/notfound',
));
$this->assertHTTPStatus(501, $req);
}
function testPostPassThruNoOutBox() {
$req = new Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars',
));
$this->assertHTTPStatus(501, $req);
}
function testNoOriginator() {
$req = new Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/admin/outbox',
));
$this->assertHTTPStatus(400, $req);
}
function testNoRecipient() {
$req = new Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/admin/outbox',
'HTTP_ORIGINATOR' => 'mailto:orig@example.org',
));
$this->assertHTTPStatus(400, $req);
}
function testBadOriginator() {
$req = new Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/admin/outbox',
'HTTP_ORIGINATOR' => 'nomailto:orig@example.org',
'HTTP_RECIPIENT' => 'mailto:user1@example.org',
));
$this->assertHTTPStatus(400, $req);
}
function testBadRecipient() {
$req = new Sabre_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',
));
$this->assertHTTPStatus(400, $req);
}
function testIncorrectOriginator() {
$req = new Sabre_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',
));
$this->assertHTTPStatus(403, $req);
}
function testInvalidIcalBody() {
$req = new Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
'HTTP_RECIPIENT' => 'mailto:user2@example.org',
));
$req->setBody('foo');
$this->assertHTTPStatus(400, $req);
}
function testNoVEVENT() {
$req = new Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
'HTTP_RECIPIENT' => 'mailto:user2@example.org',
));
$body = array(
'BEGIN:VCALENDAR',
'BEGIN:VTIMEZONE',
'END:VTIMEZONE',
'END:VCALENDAR',
);
$req->setBody(implode("\r\n",$body));
$this->assertHTTPStatus(400, $req);
}
function testNoMETHOD() {
$req = new Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
'HTTP_RECIPIENT' => 'mailto:user2@example.org',
));
$body = array(
'BEGIN:VCALENDAR',
'BEGIN:VEVENT',
'END:VEVENT',
'END:VCALENDAR',
);
$req->setBody(implode("\r\n",$body));
$this->assertHTTPStatus(400, $req);
}
function testUnsupportedMethod() {
$req = new Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
'HTTP_RECIPIENT' => 'mailto:user2@example.org',
));
$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 Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
'HTTP_RECIPIENT' => 'mailto:user2@example.org',
));
$body = array(
'BEGIN:VCALENDAR',
'METHOD:REQUEST',
'BEGIN:VEVENT',
'END:VEVENT',
'END:VCALENDAR',
);
$req->setBody(implode("\r\n",$body));
$this->assertHTTPStatus(501, $req);
}
function testSuccessRequest() {
$req = new Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
'HTTP_RECIPIENT' => 'mailto:user2@example.org',
));
$body = array(
'BEGIN:VCALENDAR',
'METHOD:REQUEST',
'BEGIN:VEVENT',
'SUMMARY:An invitation',
'END:VEVENT',
'END:VCALENDAR',
);
$req->setBody(implode("\r\n",$body));
$handler = new Sabre_CalDAV_Schedule_IMip_Mock('server@example.org');
$this->caldavPlugin->setIMIPhandler($handler);
$this->assertHTTPStatus(200, $req);
$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: ' . Sabre_DAV_Version::VERSION . '-' . Sabre_DAV_Version::STABILITY,
),
)
), $handler->getSentEmails());
}
function testSuccessReply() {
$req = new Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
'HTTP_RECIPIENT' => 'mailto:user2@example.org',
));
$body = array(
'BEGIN:VCALENDAR',
'METHOD:REPLY',
'BEGIN:VEVENT',
'SUMMARY:An invitation',
'END:VEVENT',
'END:VCALENDAR',
);
$req->setBody(implode("\r\n",$body));
$handler = new Sabre_CalDAV_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: ' . Sabre_DAV_Version::VERSION . '-' . Sabre_DAV_Version::STABILITY,
),
)
), $handler->getSentEmails());
}
function testSuccessCancel() {
$req = new Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
'HTTP_RECIPIENT' => 'mailto:user2@example.org',
));
$body = array(
'BEGIN:VCALENDAR',
'METHOD:CANCEL',
'BEGIN:VEVENT',
'SUMMARY:An invitation',
'END:VEVENT',
'END:VCALENDAR',
);
$req->setBody(implode("\r\n",$body));
$handler = new Sabre_CalDAV_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: ' . Sabre_DAV_Version::VERSION . '-' . Sabre_DAV_Version::STABILITY,
),
)
), $handler->getSentEmails());
}
}

View file

@ -0,0 +1,994 @@
<?php
require_once 'Sabre/HTTP/ResponseMock.php';
require_once 'Sabre/DAV/Auth/MockBackend.php';
require_once 'Sabre/CalDAV/TestUtil.php';
require_once 'Sabre/DAVACL/MockPrincipalBackend.php';
class Sabre_CalDAV_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() {
if (!SABRE_HASSQLITE) $this->markTestSkipped('No PDO SQLite support');
$this->caldavBackend = Sabre_CalDAV_TestUtil::getBackend();
$principalBackend = new Sabre_DAVACL_MockPrincipalBackend();
$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 Sabre_CalDAV_CalendarRootNode($principalBackend,$this->caldavBackend);
$principals = new Sabre_CalDAV_Principal_Collection($principalBackend);
$root = new Sabre_DAV_SimpleCollection('root');
$root->addChild($calendars);
$root->addChild($principals);
$objectTree = new Sabre_DAV_ObjectTree($root);
$this->server = new Sabre_DAV_Server($objectTree);
$this->server->debugExceptions = true;
$this->server->setBaseUri('/');
$this->plugin = new Sabre_CalDAV_Plugin();
$this->server->addPlugin($this->plugin);
$this->response = new Sabre_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 Sabre_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 Sabre_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 501 Not Implemented', $this->response->status);
}
function testMkCalendarBadLocation() {
$request = new Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_CalDAV_Property_SupportedCalendarComponentSet);
$this->assertEquals(array('VEVENT'),$newCalendar[$sccs]->getValue());
}
function testMkCalendarEmptyBodySucceed() {
$request = new Sabre_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 Sabre_CalDAV_Property_SupportedCalendarComponentSet);
$this->assertEquals(array('VEVENT','VTODO'),$newCalendar[$sccs]->getValue());
}
function testPrincipalProperties() {
$httpRequest = new Sabre_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',
'{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}calendar-proxy-read-for',
'{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}calendar-proxy-write-for',
));
$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 Sabre_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 Sabre_DAV_Property_Href);
$this->assertEquals('calendars/user1/outbox',$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 Sabre_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->assertTrue($prop instanceof Sabre_DAV_Property_SupportedReportSet);
$value = array(
);
$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',
);
$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 Sabre_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(Sabre_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 Sabre_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(Sabre_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 Sabre_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(Sabre_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 Sabre_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(Sabre_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 Sabre_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 Sabre_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(Sabre_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 Sabre_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(Sabre_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 Sabre_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 Sabre_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 Sabre_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);
}
}

View file

@ -0,0 +1,18 @@
<?php
require_once 'Sabre/DAVACL/MockPrincipalBackend.php';
class Sabre_CalDAV_Principal_CollectionTest extends PHPUnit_Framework_TestCase {
function testGetChildForPrincipal() {
$back = new Sabre_DAVACL_MockPrincipalBackend();
$col = new Sabre_CalDAV_Principal_Collection($back);
$r = $col->getChildForPrincipal(array(
'uri' => 'principals/admin',
));
$this->assertInstanceOf('Sabre_CalDAV_Principal_User', $r);
}
}

View file

@ -0,0 +1,98 @@
<?php
class Sabre_CalDAV_Principal_ProxyReadTest extends PHPUnit_Framework_TestCase {
protected $backend;
function getInstance() {
$backend = new Sabre_DAVACL_MockPrincipalBackend();
$principal = new Sabre_CalDAV_Principal_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);
}
}

View file

@ -0,0 +1,36 @@
<?php
class Sabre_CalDAV_Principal_ProxyWriteTest extends Sabre_CalDAV_Principal_ProxyReadTest {
function getInstance() {
$backend = new Sabre_DAVACL_MockPrincipalBackend();
$principal = new Sabre_CalDAV_Principal_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());
}
}

View file

@ -0,0 +1,123 @@
<?php
class Sabre_CalDAV_Principal_UserTest extends PHPUnit_Framework_TestCase {
function getInstance() {
$backend = new Sabre_DAVACL_MockPrincipalBackend();
$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 Sabre_CalDAV_Principal_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());
}
}

View file

@ -0,0 +1,66 @@
<?php
class Sabre_CalDAV_Property_SupportedCalendarComponentSetTest extends PHPUnit_Framework_TestCase {
function testSimple() {
$sccs = new Sabre_CalDAV_Property_SupportedCalendarComponentSet(array('VEVENT'));
$this->assertEquals(array('VEVENT'), $sccs->getValue());
}
/**
* @depends testSimple
*/
function testSerialize() {
$property = new Sabre_CalDAV_Property_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);
$objectTree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('rootdir'));
$server = new Sabre_DAV_Server($objectTree);
$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 = Sabre_CalDAV_Property_SupportedCalendarComponentSet::unserialize($dom->firstChild);
$this->assertTrue($property instanceof Sabre_CalDAV_Property_SupportedCalendarComponentSet);
$this->assertEquals(array(
'VEVENT',
'VJOURNAL',
),
$property->getValue());
}
}

View file

@ -0,0 +1,40 @@
<?php
class Sabre_CalDAV_Property_SupportedCalendarDataTest extends PHPUnit_Framework_TestCase {
function testSimple() {
$sccs = new Sabre_CalDAV_Property_SupportedCalendarData();
}
/**
* @depends testSimple
*/
function testSerialize() {
$property = new Sabre_CalDAV_Property_SupportedCalendarData();
$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);
$objectTree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('rootdir'));
$server = new Sabre_DAV_Server($objectTree);
$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:calendar-data content-type="text/calendar" version="2.0"/>' .
'</d:root>
', $xml);
}
}

View file

@ -0,0 +1,42 @@
<?php
class Sabre_CalDAV_Property_SupportedCollationSetTest extends PHPUnit_Framework_TestCase {
function testSimple() {
$scs = new Sabre_CalDAV_Property_SupportedCollationSet();
}
/**
* @depends testSimple
*/
function testSerialize() {
$property = new Sabre_CalDAV_Property_SupportedCollationSet();
$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);
$objectTree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('rootdir'));
$server = new Sabre_DAV_Server($objectTree);
$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: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);
}
}

View file

@ -0,0 +1,50 @@
<?php
/**
* 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-2012 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 Sabre_CalDAV_Schedule_IMip_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;
}
}

View file

@ -0,0 +1,58 @@
<?php
class Sabre_CalDAV_Schedule_OutboxTest extends PHPUnit_Framework_TestCase {
function testSetup() {
$outbox = new Sabre_CalDAV_Schedule_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' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-query-freebusy',
'principal' => 'principals/user1',
'protected' => true,
),
array(
'privilege' => '{DAV:}read',
'principal' => 'principals/user1',
'protected' => true,
),
), $outbox->getACL());
$ok = false;
try {
$outbox->setACL(array());
} catch (Sabre_DAV_Exception_MethodNotAllowed $e) {
$ok = true;
}
if (!$ok) {
$this->fail('Exception was not emitted');
}
}
function testGetSupportedPrivilegeSet() {
$outbox = new Sabre_CalDAV_Schedule_Outbox('principals/user1');
$r = $outbox->getSupportedPrivilegeSet();
$ok = false;
foreach($r['aggregates'] as $priv) {
if ($priv['privilege'] == '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-query-freebusy') {
$ok = true;
}
}
if (!$ok) {
$this->fail('{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-query-freebusy was not found as a supported privilege');
}
}
}

View file

@ -0,0 +1,31 @@
<?php
require_once 'Sabre/CalDAV/TestUtil.php';
class Sabre_CalDAV_ServerTest extends PHPUnit_Framework_TestCase {
/**
* The CalDAV server is a simple script that just composes a
* Sabre_DAV_Server. All we really have to do is check if the setup
* is done correctly.
*/
function testSetup() {
if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
$pdo = Sabre_CalDAV_TestUtil::getSQLiteDB();
$server = new Sabre_CalDAV_Server($pdo);
$authPlugin = $server->getPlugin('auth');
$this->assertTrue($authPlugin instanceof Sabre_DAV_Auth_Plugin);
$caldavPlugin = $server->getPlugin('caldav');
$this->assertTrue($caldavPlugin instanceof Sabre_CalDAV_Plugin);
$node = $server->tree->getNodeForPath('');
$this->assertTrue($node instanceof Sabre_DAV_SimpleCollection);
$this->assertEquals('root', $node->getName());
}
}

View file

@ -0,0 +1,206 @@
<?php
class Sabre_CalDAV_TestUtil {
static function getBackend() {
$backend = new Sabre_CalDAV_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 Sabre_CalDAV_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;
}
}

View file

@ -0,0 +1,185 @@
<?php
require_once 'Sabre/CalDAV/TestUtil.php';
require_once 'Sabre/DAVACL/MockPrincipalBackend.php';
/**
* @covers Sabre_CalDAV_UserCalendars
*/
class Sabre_CalDAV_UserCalendarsTest extends PHPUnit_Framework_TestCase {
/**
* @var Sabre_CalDAV_UserCalendars
*/
protected $usercalendars;
/**
* @var Sabre_CalDAV_Backend_PDO
*/
protected $backend;
protected $principalBackend;
function setup() {
if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
$this->backend = Sabre_CalDAV_TestUtil::getBackend();
$this->principalBackend = new Sabre_DAVACL_MockPrincipalBackend('realm');
$this->usercalendars = new Sabre_CalDAV_UserCalendars($this->principalBackend, $this->backend, '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());
}
function testGetSupportedPrivilegesSet() {
$this->assertNull($this->usercalendars->getSupportedPrivilegeSet());
}
}

View file

@ -0,0 +1,210 @@
<?php
require_once 'Sabre/CalDAV/Backend/Mock.php';
require_once 'Sabre/DAVACL/MockPrincipalBackend.php';
require_once 'Sabre/HTTP/ResponseMock.php';
class Sabre_CalDAV_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',
)
);
$this->calBackend = new Sabre_CalDAV_Backend_Mock($calendars,array());
$principalBackend = new Sabre_DAVACL_MockPrincipalBackend();
$tree = array(
new Sabre_CalDAV_CalendarRootNode($principalBackend, $this->calBackend),
);
$this->server = new Sabre_DAV_Server($tree);
$this->server->debugExceptions = true;
$plugin = new Sabre_CalDAV_Plugin();
$this->server->addPlugin($plugin);
$response = new Sabre_HTTP_ResponseMock();
$this->server->httpResponse = $response;
}
function request(Sabre_HTTP_Request $request) {
$this->server->httpRequest = $request;
$this->server->exec();
return $this->server->httpResponse;
}
function testCreateFile() {
$request = new Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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'));
}
}

View file

@ -0,0 +1,15 @@
<?php
class Sabre_CalDAV_VersionTest extends PHPUnit_Framework_TestCase {
function testString() {
$v = Sabre_CalDAV_Version::VERSION;
$this->assertEquals(-1, version_compare('1.0.0',$v));
$s = Sabre_CalDAV_Version::STABILITY;
$this->assertTrue($s == 'alpha' || $s == 'beta' || $s =='stable');
}
}

View file

@ -0,0 +1,39 @@
<?php
require_once 'Sabre/CardDAV/Backend/Mock.php';
require_once 'Sabre/DAVACL/MockPrincipalBackend.php';
abstract class Sabre_CardDAV_AbstractPluginTest extends PHPUnit_Framework_TestCase {
/**
* @var Sabre_CardDAV_Plugin
*/
protected $plugin;
/**
* @var Sabre_DAV_Server
*/
protected $server;
/**
* @var Sabre_CardDAV_MockBackend
*/
protected $backend;
function setUp() {
$this->backend = new Sabre_CardDAV_Backend_Mock();
$principalBackend = new Sabre_DAVACL_MockPrincipalBackend();
$tree = array(
new Sabre_CardDAV_AddressBookRoot($principalBackend, $this->backend),
new Sabre_DAVACL_PrincipalCollection($principalBackend)
);
$this->plugin = new Sabre_CardDAV_Plugin();
$this->plugin->directories = array('directory');
$this->server = new Sabre_DAV_Server($tree);
$this->server->addPlugin($this->plugin);
$this->server->debugExceptions = true;
}
}

View file

@ -0,0 +1,325 @@
<?php
class Sabre_CardDAV_AddressBookQueryParserTest extends PHPUnit_Framework_TestCase {
function parse($xml) {
$xml = implode("\n", $xml);
$dom = Sabre_DAV_XMLUtil::loadDOMDocument($xml);
$q = new Sabre_CardDAV_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);
}
}

View file

@ -0,0 +1,187 @@
<?php
require_once 'Sabre/CardDAV/AbstractPluginTest.php';
require_once 'Sabre/HTTP/ResponseMock.php';
class Sabre_CardDAV_AddressBookQueryTest extends Sabre_CardDAV_AbstractPluginTest {
function testQuery() {
$request = new Sabre_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 Sabre_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 Sabre_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(
200 => array(
'{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:45678\nEND:VCARD") . '"',
),
)
), $result);
}
function testQueryDepth0() {
$request = new Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_DAV_Client(array('baseUri'=>'/'));
$result = $client->parseMultiStatus($response->body);
$this->assertEquals(array(), $result);
}
function testQueryLimit() {
$request = new Sabre_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 Sabre_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 Sabre_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);
}
}

View file

@ -0,0 +1,27 @@
<?php
class Sabre_CardDAV_AddressBookRootTest extends PHPUnit_Framework_TestCase {
function testGetName() {
$pBackend = new Sabre_DAVACL_MockPrincipalBackend();
$cBackend = new Sabre_CardDAV_Backend_Mock();
$root = new Sabre_CardDAV_AddressBookRoot($pBackend, $cBackend);
$this->assertEquals('addressbooks', $root->getName());
}
function testGetChildForPrincipal() {
$pBackend = new Sabre_DAVACL_MockPrincipalBackend();
$cBackend = new Sabre_CardDAV_Backend_Mock();
$root = new Sabre_CardDAV_AddressBookRoot($pBackend, $cBackend);
$children = $root->getChildren();
$this->assertEquals(3, count($children));
$this->assertInstanceOf('Sabre_CardDAV_UserAddressBooks', $children[0]);
$this->assertEquals('user1', $children[0]->getName());
}
}

View file

@ -0,0 +1,159 @@
<?php
require_once 'Sabre/CardDAV/Backend/Mock.php';
class Sabre_CardDAV_AddressBookTest extends PHPUnit_Framework_TestCase {
/**
* @var Sabre_CardDAV_AddressBook
*/
protected $ab;
protected $backend;
function setUp() {
$this->backend = new Sabre_CardDAV_Backend_Mock();
$this->ab = new Sabre_CardDAV_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()
);
}
}

View file

@ -0,0 +1,245 @@
<?php
abstract class Sabre_CardDAV_Backend_AbstractPDOTest extends PHPUnit_Framework_TestCase {
/**
* @var Sabre_CardDAV_Backend_PDO
*/
protected $backend;
/**
* @abstract
* @return PDO
*/
abstract function getPDO();
public function setUp() {
$this->backend = new Sabre_CardDAV_Backend_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',
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1',
'{http://calendarserver.org/ns/}getctag' => 1,
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' => new Sabre_CardDAV_Property_SupportedAddressData(),
)
);
$this->assertEquals($expected, $result);
}
public function testUpdateAddressBookInvalidProp() {
$result = $this->backend->updateAddressBook(1, array(
'{DAV:}displayname' => 'updated',
'{' . Sabre_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',
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1',
'{http://calendarserver.org/ns/}getctag' => 1,
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' => new Sabre_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',
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1',
'{http://calendarserver.org/ns/}getctag' => 1,
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' => new Sabre_CardDAV_Property_SupportedAddressData(),
)
);
$this->assertEquals($expected, $result);
}
public function testUpdateAddressBookSuccess() {
$result = $this->backend->updateAddressBook(1, array(
'{DAV:}displayname' => 'updated',
'{' . Sabre_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',
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => 'updated',
'{http://calendarserver.org/ns/}getctag' => 2,
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' => new Sabre_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',
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 2',
));
$expected = array(
array(
'id' => 1,
'uri' => 'book1',
'principaluri' => 'principals/user1',
'{DAV:}displayname' => 'book1',
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1',
'{http://calendarserver.org/ns/}getctag' => 1,
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' => new Sabre_CardDAV_Property_SupportedAddressData(),
),
array(
'id' => 2,
'uri' => 'book2',
'principaluri' => 'principals/user1',
'{DAV:}displayname' => 'book2',
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 2',
'{http://calendarserver.org/ns/}getctag' => 1,
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' => new Sabre_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);
}
}

View file

@ -0,0 +1,125 @@
<?php
class Sabre_CardDAV_Backend_Mock extends Sabre_CardDAV_Backend_Abstract {
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',
),
);
$this->cards = array(
'foo' => array(
'card1' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD",
'card2' => "BEGIN:VCARD\nVERSION:3.0\nUID:45678\nEND:VCARD",
),
);
}
}
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]);
}
}

View file

@ -0,0 +1,58 @@
<?php
require_once 'Sabre/TestUtil.php';
class Sabre_CardDAV_Backend_PDOMySQLTest extends Sabre_CardDAV_Backend_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;
}
}

View file

@ -0,0 +1,67 @@
<?php
require_once 'Sabre/TestUtil.php';
class Sabre_CardDAV_Backend_PDOSqliteTest extends Sabre_CardDAV_Backend_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;
}
}

View file

@ -0,0 +1,182 @@
<?php
class Sabre_CardDAV_CardTest extends PHPUnit_Framework_TestCase {
/**
* @var Sabre_CardDAV_Card
*/
protected $card;
/**
* @var Sabre_CardDAV_MockBackend
*/
protected $backend;
function setUp() {
$this->backend = new Sabre_CardDAV_Backend_Mock();
$this->card = new Sabre_CardDAV_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 Sabre_CardDAV_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 Sabre_CardDAV_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 Sabre_CardDAV_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()
);
}
}

View file

@ -0,0 +1,25 @@
<?php
class Sabre_CardDAV_IDirectoryTest extends PHPUnit_Framework_TestCase {
function testResourceType() {
$tree = array(
new Sabre_CardDAV_DirectoryMock('directory')
);
$server = new Sabre_DAV_Server($tree);
$plugin = new Sabre_CardDAV_Plugin();
$server->addPlugin($plugin);
$props = $server->getProperties('directory', array('{DAV:}resourcetype'));
$this->assertTrue($props['{DAV:}resourcetype']->is('{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}directory'));
}
}
class Sabre_CardDAV_DirectoryMock extends Sabre_DAV_SimpleCollection implements Sabre_CardDAV_IDirectory {
}

View file

@ -0,0 +1,50 @@
<?php
require_once 'Sabre/HTTP/ResponseMock.php';
class Sabre_CardDAV_MultiGetTest extends Sabre_CardDAV_AbstractPluginTest {
function testMultiGet() {
$request = new Sabre_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 Sabre_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 Sabre_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);
}
}

View file

@ -0,0 +1,146 @@
<?php
require_once 'Sabre/DAVACL/MockPrincipalBackend.php';
require_once 'Sabre/CardDAV/AbstractPluginTest.php';
class Sabre_CardDAV_PluginTest extends Sabre_CardDAV_AbstractPluginTest {
function testConstruct() {
$this->assertEquals('card', $this->server->xmlNamespaces[Sabre_CardDAV_Plugin::NS_CARDDAV]);
$this->assertEquals('{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook', $this->server->resourceTypeMapping['Sabre_CardDAV_IAddressBook']);
$this->assertTrue(in_array('addressbook', $this->plugin->getFeatures()));
}
function testSupportedReportSet() {
$this->assertEquals(array(
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-multiget',
'{' . Sabre_CardDAV_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('{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-home-set'));
$this->assertEquals(1, count($result));
$this->assertTrue(isset($result['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-home-set']));
$this->assertEquals('addressbooks/user1/', $result['{' . Sabre_CardDAV_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 Sabre_DAV_Property_Href('addressbooks/user1/book1/vcard1.vcf')
),
$result
);
}
function testDirectoryGateway() {
$result = $this->server->getProperties('principals/user1', array('{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}directory-gateway'));
$this->assertEquals(1, count($result));
$this->assertTrue(isset($result['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}directory-gateway']));
$this->assertEquals(array('directory'), $result['{' . Sabre_CardDAV_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 Sabre_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 Sabre_DAV_Property_HrefList(array()),
));
$this->assertEquals(
array(
'href' => 'addressbooks/user1',
400 => array(
'{http://calendarserver.org/ns/}me-card' => null,
),
),
$result
);
}
}

View file

@ -0,0 +1,39 @@
<?php
class Sabre_CardDAV_Property_SupportedAddressDataDataTest extends PHPUnit_Framework_TestCase {
function testSimple() {
$property = new Sabre_CardDAV_Property_SupportedAddressData();
}
/**
* @depends testSimple
*/
function testSerialize() {
$property = new Sabre_CardDAV_Property_SupportedAddressData();
$doc = new DOMDocument();
$root = $doc->createElementNS(Sabre_CardDAV_Plugin::NS_CARDDAV, 'card:root');
$root->setAttribute('xmlns:d','DAV:');
$doc->appendChild($root);
$server = new Sabre_DAV_Server();
$property->serialize($server, $root);
$xml = $doc->saveXML();
$this->assertEquals(
'<?xml version="1.0"?>
<card:root xmlns:card="' . Sabre_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);
}
}

View file

@ -0,0 +1,39 @@
<?php
class Sabre_CardDAV_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 Sabre_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);
}
}

View file

@ -0,0 +1,160 @@
<?php
class Sabre_CardDAV_UserAddressBooksTest extends PHPUnit_Framework_TestCase {
/**
* @var Sabre_CardDAV_UserAddressBooks
*/
protected $s;
protected $backend;
function setUp() {
$this->backend = new Sabre_CardDAV_Backend_Mock();
$this->s = new Sabre_CardDAV_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(
'{' . Sabre_CardDAV_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()
);
}
}

View file

@ -0,0 +1,202 @@
<?php
require_once 'Sabre/CardDAV/AbstractPluginTest.php';
class Sabre_CardDAV_ValidateFilterTest extends Sabre_CardDAV_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),
);
}
}

View file

@ -0,0 +1,134 @@
<?php
require_once 'Sabre/CardDAV/Backend/Mock.php';
require_once 'Sabre/DAVACL/MockPrincipalBackend.php';
require_once 'Sabre/HTTP/ResponseMock.php';
class Sabre_CardDAV_ValidateVCardTest extends PHPUnit_Framework_TestCase {
protected $server;
protected $cardBackend;
function setUp() {
$addressbooks = array(
array(
'id' => 'addressbook1',
'principaluri' => 'principals/admin',
'uri' => 'addressbook1',
)
);
$this->cardBackend = new Sabre_CardDAV_Backend_Mock($addressbooks,array());
$principalBackend = new Sabre_DAVACL_MockPrincipalBackend();
$tree = array(
new Sabre_CardDAV_AddressBookRoot($principalBackend, $this->cardBackend),
);
$this->server = new Sabre_DAV_Server($tree);
$this->server->debugExceptions = true;
$plugin = new Sabre_CardDAV_Plugin();
$this->server->addPlugin($plugin);
$response = new Sabre_HTTP_ResponseMock();
$this->server->httpResponse = $response;
}
function request(Sabre_HTTP_Request $request) {
$this->server->httpRequest = $request;
$this->server->exec();
return $this->server->httpResponse;
}
function testCreateFile() {
$request = new Sabre_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 Sabre_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);
$expected = array(
'uri' => 'blabla.vcf',
'carddata' => "BEGIN:VCARD\r\nEND:VCARD\r\n",
);
$this->assertEquals($expected, $this->cardBackend->getCard('addressbook1','blabla.vcf'));
}
function testCreateFileVCalendar() {
$request = new Sabre_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 Sabre_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 Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'PUT',
'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
));
$body = "BEGIN:VCARD\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'));
}
}
?>

View file

@ -0,0 +1,15 @@
<?php
class Sabre_CardDAV_VersionTest extends PHPUnit_Framework_TestCase {
function testString() {
$v = Sabre_CardDAV_Version::VERSION;
$this->assertEquals(-1, version_compare('0.1',$v));
$s = Sabre_CardDAV_Version::STABILITY;
$this->assertTrue($s == 'alpha' || $s == 'beta' || $s =='stable');
}
}

View file

@ -0,0 +1,60 @@
<?php
require_once 'Sabre/HTTP/ResponseMock.php';
abstract class Sabre_DAV_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 Sabre_HTTP_ResponseMock();
$this->server = new Sabre_DAV_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 Sabre_DAV_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);
}
}

View file

@ -0,0 +1,87 @@
<?php
require_once 'Sabre/HTTP/ResponseMock.php';
class Sabre_DAV_Auth_Backend_AbstractBasicTest extends PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre_DAV_Exception_NotAuthenticated
*/
public function testAuthenticateNoHeaders() {
$response = new Sabre_HTTP_ResponseMock();
$tree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla'));
$server = new Sabre_DAV_Server($tree);
$server->httpResponse = $response;
$backend = new Sabre_DAV_Auth_Backend_AbstractBasicMock();
$backend->authenticate($server,'myRealm');
}
/**
* @expectedException Sabre_DAV_Exception_NotAuthenticated
*/
public function testAuthenticateUnknownUser() {
$response = new Sabre_HTTP_ResponseMock();
$tree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla'));
$server = new Sabre_DAV_Server($tree);
$server->httpResponse = $response;
$request = new Sabre_HTTP_Request(array(
'PHP_AUTH_USER' => 'username',
'PHP_AUTH_PW' => 'wrongpassword',
));
$server->httpRequest = $request;
$backend = new Sabre_DAV_Auth_Backend_AbstractBasicMock();
$backend->authenticate($server,'myRealm');
}
public function testAuthenticate() {
$response = new Sabre_HTTP_ResponseMock();
$tree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla'));
$server = new Sabre_DAV_Server($tree);
$server->httpResponse = $response;
$request = new Sabre_HTTP_Request(array(
'PHP_AUTH_USER' => 'username',
'PHP_AUTH_PW' => 'password',
));
$server->httpRequest = $request;
$backend = new Sabre_DAV_Auth_Backend_AbstractBasicMock();
$this->assertTrue($backend->authenticate($server,'myRealm'));
$result = $backend->getCurrentUser();
$this->assertEquals('username', $result);
}
}
class Sabre_DAV_Auth_Backend_AbstractBasicMock extends Sabre_DAV_Auth_Backend_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');
}
}

View file

@ -0,0 +1,150 @@
<?php
require_once 'Sabre/HTTP/ResponseMock.php';
class Sabre_DAV_Auth_Backend_AbstractDigestTest extends PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre_DAV_Exception_NotAuthenticated
*/
public function testAuthenticateNoHeaders() {
$response = new Sabre_HTTP_ResponseMock();
$tree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla'));
$server = new Sabre_DAV_Server($tree);
$server->httpResponse = $response;
$backend = new Sabre_DAV_Auth_Backend_AbstractDigestMock();
$backend->authenticate($server,'myRealm');
}
/**
* @expectedException Sabre_DAV_Exception
*/
public function testAuthenticateBadGetUserInfoResponse() {
$response = new Sabre_HTTP_ResponseMock();
$tree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla'));
$server = new Sabre_DAV_Server($tree);
$server->httpResponse = $response;
$header = 'username=null, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1';
$request = new Sabre_HTTP_Request(array(
'PHP_AUTH_DIGEST' => $header,
));
$server->httpRequest = $request;
$backend = new Sabre_DAV_Auth_Backend_AbstractDigestMock();
$backend->authenticate($server,'myRealm');
}
/**
* @expectedException Sabre_DAV_Exception
*/
public function testAuthenticateBadGetUserInfoResponse2() {
$response = new Sabre_HTTP_ResponseMock();
$tree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla'));
$server = new Sabre_DAV_Server($tree);
$server->httpResponse = $response;
$header = 'username=array, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1';
$request = new Sabre_HTTP_Request(array(
'PHP_AUTH_DIGEST' => $header,
));
$server->httpRequest = $request;
$backend = new Sabre_DAV_Auth_Backend_AbstractDigestMock();
$backend->authenticate($server,'myRealm');
}
/**
* @expectedException Sabre_DAV_Exception_NotAuthenticated
*/
public function testAuthenticateUnknownUser() {
$response = new Sabre_HTTP_ResponseMock();
$tree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla'));
$server = new Sabre_DAV_Server($tree);
$server->httpResponse = $response;
$header = 'username=false, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1';
$request = new Sabre_HTTP_Request(array(
'PHP_AUTH_DIGEST' => $header,
));
$server->httpRequest = $request;
$backend = new Sabre_DAV_Auth_Backend_AbstractDigestMock();
$backend->authenticate($server,'myRealm');
}
/**
* @expectedException Sabre_DAV_Exception_NotAuthenticated
*/
public function testAuthenticateBadPassword() {
$response = new Sabre_HTTP_ResponseMock();
$tree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla'));
$server = new Sabre_DAV_Server($tree);
$server->httpResponse = $response;
$header = 'username=user, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1';
$request = new Sabre_HTTP_Request(array(
'PHP_AUTH_DIGEST' => $header,
'REQUEST_METHOD' => 'PUT',
));
$server->httpRequest = $request;
$backend = new Sabre_DAV_Auth_Backend_AbstractDigestMock();
$backend->authenticate($server,'myRealm');
}
public function testAuthenticate() {
$response = new Sabre_HTTP_ResponseMock();
$tree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla'));
$server = new Sabre_DAV_Server($tree);
$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 Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'GET',
'PHP_AUTH_DIGEST' => $header,
'REQUEST_URI' => '/',
));
$server->httpRequest = $request;
$backend = new Sabre_DAV_Auth_Backend_AbstractDigestMock();
$this->assertTrue($backend->authenticate($server,'myRealm'));
$result = $backend->getCurrentUser();
$this->assertEquals('user', $result);
$this->assertEquals('HELLO', $backend->getDigestHash('myRealm', $result));
}
}
class Sabre_DAV_Auth_Backend_AbstractDigestMock extends Sabre_DAV_Auth_Backend_AbstractDigest {
function getDigestHash($realm, $userName) {
switch($userName) {
case 'null' : return null;
case 'false' : return false;
case 'array' : return array();
case 'user' : return 'HELLO';
}
}
}

View file

@ -0,0 +1,31 @@
<?php
abstract class Sabre_DAV_Auth_Backend_AbstractPDOTest extends PHPUnit_Framework_TestCase {
abstract function getPDO();
function testConstruct() {
$pdo = $this->getPDO();
$backend = new Sabre_DAV_Auth_Backend_PDO($pdo);
$this->assertTrue($backend instanceof Sabre_DAV_Auth_Backend_PDO);
}
/**
* @depends testConstruct
*/
function testUserInfo() {
$pdo = $this->getPDO();
$backend = new Sabre_DAV_Auth_Backend_PDO($pdo);
$this->assertNull($backend->getDigestHash('realm','blabla'));
$expected = 'hash';
$this->assertEquals($expected, $backend->getDigestHash('realm','user'));
}
}

View file

@ -0,0 +1,40 @@
<?php
class Sabre_DAV_Auth_Backend_ApacheTest extends PHPUnit_Framework_TestCase {
function testConstruct() {
$backend = new Sabre_DAV_Auth_Backend_Apache();
}
/**
* @expectedException Sabre_DAV_Exception
*/
function testNoHeader() {
$server = new Sabre_DAV_Server();
$backend = new Sabre_DAV_Auth_Backend_Apache();
$backend->authenticate($server,'Realm');
}
function testRemoteUser() {
$backend = new Sabre_DAV_Auth_Backend_Apache();
$server = new Sabre_DAV_Server();
$request = new Sabre_HTTP_Request(array(
'REMOTE_USER' => 'username',
));
$server->httpRequest = $request;
$this->assertTrue($backend->authenticate($server, 'Realm'));
$userInfo = 'username';
$this->assertEquals($userInfo, $backend->getCurrentUser());
}
}

View file

@ -0,0 +1,40 @@
<?php
class Sabre_DAV_Auth_Backend_FileTest extends PHPUnit_Framework_TestCase {
function tearDown() {
if (file_exists(SABRE_TEMPDIR . '/filebackend')) unlink(SABRE_TEMPDIR .'/filebackend');
}
function testConstruct() {
$file = new Sabre_DAV_Auth_Backend_File();
$this->assertTrue($file instanceof Sabre_DAV_Auth_Backend_File);
}
/**
* @expectedException Sabre_DAV_Exception
*/
function testLoadFileBroken() {
file_put_contents(SABRE_TEMPDIR . '/backend','user:realm:hash');
$file = new Sabre_DAV_Auth_Backend_File();
$file->loadFile(SABRE_TEMPDIR .'/backend');
}
function testLoadFile() {
file_put_contents(SABRE_TEMPDIR . '/backend','user:realm:' . md5('user:realm:password'));
$file = new Sabre_DAV_Auth_Backend_File();
$file->loadFile(SABRE_TEMPDIR . '/backend');
$this->assertFalse($file->getDigestHash('realm','blabla'));
$this->assertEquals(md5('user:realm:password'), $file->getDigesthash('realm','user'));
}
}

View file

@ -0,0 +1,24 @@
<?php
class Sabre_DAV_Auth_Backend_PDOSQLiteTest extends Sabre_DAV_Auth_Backend_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)');
$pdo->query('INSERT INTO users VALUES ("user","hash")');
return $pdo;
}
}

View file

@ -0,0 +1,29 @@
<?php
require_once 'Sabre/TestUtil.php';
class Sabre_DAV_Auth_Backend_PDOMySQLTest extends Sabre_DAV_Auth_Backend_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;
}
}

View file

@ -0,0 +1,26 @@
<?php
require_once 'Sabre/DAV/Auth/Backend/AbstractPDOTest.php';
class Sabre_DAV_Auth_Backend_PDOSQLiteTest extends Sabre_DAV_Auth_Backend_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;
}
}

View file

@ -0,0 +1,32 @@
<?php
class Sabre_DAV_Auth_MockBackend implements Sabre_DAV_Auth_IBackend {
protected $currentUser;
/**
* @param Sabre_DAV_Server $server
* @param string $realm
* @throws Sabre_DAV_Exception_NotAuthenticated
*/
function authenticate(Sabre_DAV_Server $server, $realm) {
if ($realm=='failme') throw new Sabre_DAV_Exception_NotAuthenticated('deliberate fail');
$this->currentUser = 'admin';
}
function setCurrentUser($user) {
$this->currentUser = $user;
}
function getCurrentUser() {
return $this->currentUser;
}
}

View file

@ -0,0 +1,80 @@
<?php
require_once 'Sabre/DAV/Auth/MockBackend.php';
require_once 'Sabre/HTTP/ResponseMock.php';
class Sabre_DAV_Auth_PluginTest extends PHPUnit_Framework_TestCase {
function testInit() {
$fakeServer = new Sabre_DAV_Server(new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla')));
$plugin = new Sabre_DAV_Auth_Plugin(new Sabre_DAV_Auth_MockBackend(),'realm');
$this->assertTrue($plugin instanceof Sabre_DAV_Auth_Plugin);
$fakeServer->addPlugin($plugin);
$this->assertEquals($plugin, $fakeServer->getPlugin('auth'));
}
/**
* @depends testInit
*/
function testAuthenticate() {
$fakeServer = new Sabre_DAV_Server(new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla')));
$plugin = new Sabre_DAV_Auth_Plugin(new Sabre_DAV_Auth_MockBackend(),'realm');
$fakeServer->addPlugin($plugin);
$fakeServer->broadCastEvent('beforeMethod',array('GET','/'));
}
/**
* @depends testInit
* @expectedException Sabre_DAV_Exception_NotAuthenticated
*/
function testAuthenticateFail() {
$fakeServer = new Sabre_DAV_Server(new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla')));
$plugin = new Sabre_DAV_Auth_Plugin(new Sabre_DAV_Auth_MockBackend(),'failme');
$fakeServer->addPlugin($plugin);
$fakeServer->broadCastEvent('beforeMethod',array('GET','/'));
}
function testReportPassThrough() {
$fakeServer = new Sabre_DAV_Server(new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla')));
$plugin = new Sabre_DAV_Auth_Plugin(new Sabre_DAV_Auth_MockBackend(),'realm');
$fakeServer->addPlugin($plugin);
$request = new Sabre_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 Sabre_HTTP_ResponseMock();
$fakeServer->exec();
$this->assertEquals('HTTP/1.1 501 Not Implemented', $fakeServer->httpResponse->status);
}
/**
* @depends testInit
*/
function testGetCurrentUserPrincipal() {
$fakeServer = new Sabre_DAV_Server(new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('bla')));
$plugin = new Sabre_DAV_Auth_Plugin(new Sabre_DAV_Auth_MockBackend(),'realm');
$fakeServer->addPlugin($plugin);
$fakeServer->broadCastEvent('beforeMethod',array('GET','/'));
$this->assertEquals('admin', $plugin->getCurrentUser());
}
}

View file

@ -0,0 +1,232 @@
<?php
class Sabre_DAV_BasicNodeTest extends PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre_DAV_Exception_Forbidden
*/
public function testPut() {
$file = new Sabre_DAV_FileMock();
$file->put('hi');
}
/**
* @expectedException Sabre_DAV_Exception_Forbidden
*/
public function testGet() {
$file = new Sabre_DAV_FileMock();
$file->get();
}
public function testGetSize() {
$file = new Sabre_DAV_FileMock();
$this->assertEquals(0,$file->getSize());
}
public function testGetETag() {
$file = new Sabre_DAV_FileMock();
$this->assertNull($file->getETag());
}
public function testGetContentType() {
$file = new Sabre_DAV_FileMock();
$this->assertNull($file->getContentType());
}
/**
* @expectedException Sabre_DAV_Exception_Forbidden
*/
public function testDelete() {
$file = new Sabre_DAV_FileMock();
$file->delete();
}
/**
* @expectedException Sabre_DAV_Exception_Forbidden
*/
public function testSetName() {
$file = new Sabre_DAV_FileMock();
$file->setName('hi');
}
public function testGetLastModified() {
$file = new Sabre_DAV_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 Sabre_DAV_DirectoryMock();
$file = $dir->getChild('mockfile');
$this->assertTrue($file instanceof Sabre_DAV_FileMock);
}
public function testChildExists() {
$dir = new Sabre_DAV_DirectoryMock();
$this->assertTrue($dir->childExists('mockfile'));
}
public function testChildExistsFalse() {
$dir = new Sabre_DAV_DirectoryMock();
$this->assertFalse($dir->childExists('mockfile2'));
}
/**
* @expectedException Sabre_DAV_Exception_NotFound
*/
public function testGetChild404() {
$dir = new Sabre_DAV_DirectoryMock();
$file = $dir->getChild('blabla');
}
/**
* @expectedException Sabre_DAV_Exception_Forbidden
*/
public function testCreateFile() {
$dir = new Sabre_DAV_DirectoryMock();
$dir->createFile('hello','data');
}
/**
* @expectedException Sabre_DAV_Exception_Forbidden
*/
public function testCreateDirectory() {
$dir = new Sabre_DAV_DirectoryMock();
$dir->createDirectory('hello');
}
public function testSimpleDirectoryConstruct() {
$dir = new Sabre_DAV_SimpleCollection('simpledir',array());
}
/**
* @depends testSimpleDirectoryConstruct
*/
public function testSimpleDirectoryConstructChild() {
$file = new Sabre_DAV_FileMock();
$dir = new Sabre_DAV_SimpleCollection('simpledir',array($file));
$file2 = $dir->getChild('mockfile');
$this->assertEquals($file,$file2);
}
/**
* @expectedException Sabre_DAV_Exception
* @depends testSimpleDirectoryConstruct
*/
public function testSimpleDirectoryBadParam() {
$dir = new Sabre_DAV_SimpleCollection('simpledir',array('string shouldn\'t be here'));
}
/**
* @depends testSimpleDirectoryConstruct
*/
public function testSimpleDirectoryAddChild() {
$file = new Sabre_DAV_FileMock();
$dir = new Sabre_DAV_SimpleCollection('simpledir');
$dir->addChild($file);
$file2 = $dir->getChild('mockfile');
$this->assertEquals($file,$file2);
}
/**
* @depends testSimpleDirectoryConstruct
* @depends testSimpleDirectoryAddChild
*/
public function testSimpleDirectoryGetChildren() {
$file = new Sabre_DAV_FileMock();
$dir = new Sabre_DAV_SimpleCollection('simpledir');
$dir->addChild($file);
$this->assertEquals(array($file),$dir->getChildren());
}
/*
* @depends testSimpleDirectoryConstruct
*/
public function testSimpleDirectoryGetName() {
$dir = new Sabre_DAV_SimpleCollection('simpledir');
$this->assertEquals('simpledir',$dir->getName());
}
/**
* @depends testSimpleDirectoryConstruct
* @expectedException Sabre_DAV_Exception_NotFound
*/
public function testSimpleDirectoryGetChild404() {
$dir = new Sabre_DAV_SimpleCollection('simpledir');
$dir->getChild('blabla');
}
}
class Sabre_DAV_DirectoryMock extends Sabre_DAV_Collection {
function getName() {
return 'mockdir';
}
function getChildren() {
return array(new Sabre_DAV_FileMock());
}
}
class Sabre_DAV_FileMock extends Sabre_DAV_File {
function getName() {
return 'mockfile';
}
}

View file

@ -0,0 +1,64 @@
<?php
require_once 'Sabre/DAV/AbstractServer.php';
class Sabre_DAV_Browser_GuessContentTypeTest extends Sabre_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 Sabre_DAV_Browser_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 Sabre_DAV_Browser_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]);
}
}

View file

@ -0,0 +1,38 @@
<?php
require_once 'Sabre/DAV/AbstractServer.php';
class Sabre_DAV_Browser_MapGetToPropFindTest extends Sabre_DAV_AbstractServer {
function setUp() {
parent::setUp();
$this->server->addPlugin(new Sabre_DAV_Browser_MapGetToPropFind());
}
function testCollectionGet() {
$serverVars = array(
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'GET',
);
$request = new Sabre_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',
),
$this->response->headers
);
$this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Incorrect status response received. Full response body: ' . $this->response->body);
}
}

View file

@ -0,0 +1,108 @@
<?php
require_once 'Sabre/DAV/AbstractServer.php';
class Sabre_DAV_Browser_PluginTest extends Sabre_DAV_AbstractServer{
function setUp() {
parent::setUp();
$this->server->addPlugin(new Sabre_DAV_Browser_Plugin());
}
function testCollectionGet() {
$serverVars = array(
'REQUEST_URI' => '/dir',
'REQUEST_METHOD' => 'GET',
);
$request = new Sabre_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);
}
function testNotFound() {
$serverVars = array(
'REQUEST_URI' => '/random',
'REQUEST_METHOD' => 'GET',
);
$request = new Sabre_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 Sabre_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 Sabre_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 Sabre_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'));
}
}

View file

@ -0,0 +1,30 @@
<?php
class Sabre_DAV_ClientMock extends Sabre_DAV_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);
}
}

View file

@ -0,0 +1,791 @@
<?php
require_once 'Sabre/DAV/ClientMock.php';
class Sabre_DAV_ClientTest extends PHPUnit_Framework_TestCase {
function testConstruct() {
$client = new Sabre_DAV_ClientMock(array(
'baseUri' => '/',
));
}
/**
* @expectedException InvalidArgumentException
*/
function testConstructNoBaseUri() {
$client = new Sabre_DAV_ClientMock(array());
}
function testRequest() {
$client = new Sabre_DAV_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 Sabre_DAV_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 testRequestAuth() {
$client = new Sabre_DAV_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 Sabre_DAV_ClientMock(array(
'baseUri' => 'http://example.org/foo/bar/',
'userName' => 'user',
'password' => 'password',
'authType' => Sabre_DAV_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 Sabre_DAV_ClientMock(array(
'baseUri' => 'http://example.org/foo/bar/',
'userName' => 'user',
'password' => 'password',
'authType' => Sabre_DAV_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 Sabre_DAV_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 (Sabre_DAV_Exception $e) {
$caught = true;
}
if (!$caught) {
$this->markTestFailed('Exception was not thrown');
}
}
function testRequestHTTPError() {
$client = new Sabre_DAV_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 (Sabre_DAV_Exception $e) {
$caught = true;
}
if (!$caught) {
$this->fail('Exception was not thrown');
}
}
function testRequestHTTP404() {
$client = new Sabre_DAV_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 (Sabre_DAV_Exception_NotFound $e) {
$caught = true;
}
if (!$caught) {
$this->fail('Exception was not thrown');
}
}
/**
* @dataProvider supportedHTTPCodes
*/
function testSpecificHTTPErrors($error) {
$client = new Sabre_DAV_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,
""
);
$caught = false;
try {
$client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
} catch (Sabre_DAV_Exception $e) {
$caught = true;
$this->assertEquals($e->getHTTPCode(), $error);
}
if (!$caught) {
$this->fail('Exception was not thrown');
}
}
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 testGetAbsoluteUrl() {
$client = new Sabre_DAV_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 Sabre_DAV_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 Sabre_DAV_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 Sabre_DAV_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 Sabre_DAV_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]);
}
function testPropFindDepth1CustomProp() {
$client = new Sabre_DAV_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 Sabre_DAV_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 Sabre_DAV_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 Sabre_DAV_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);
}
}

View file

@ -0,0 +1,12 @@
<?php
class Sabre_DAV_Exception_PaymentRequiredTest extends PHPUnit_Framework_TestCase {
function testGetHTTPCode() {
$ex = new Sabre_DAV_Exception_PaymentRequired();
$this->assertEquals(402, $ex->getHTTPCode());
}
}

View file

@ -0,0 +1,28 @@
<?php
class Sabre_DAV_ExceptionTest extends PHPUnit_Framework_TestCase {
function testStatus() {
$e = new Sabre_DAV_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());
}
}
}

View file

@ -0,0 +1,76 @@
<?php
require_once 'Sabre/TestUtil.php';
class Sabre_DAV_FSExt_FileTest extends PHPUnit_Framework_TestCase {
function setUp() {
file_put_contents(SABRE_TEMPDIR . '/file.txt', 'Contents');
}
function tearDown() {
Sabre_TestUtil::clearTempDir();
}
function testPut() {
$file = new Sabre_DAV_FSExt_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 Sabre_DAV_FSExt_File(SABRE_TEMPDIR . '/file.txt');
$file->put('0000000');
$file->putRange('111',3);
$this->assertEquals('0011100',file_get_contents(SABRE_TEMPDIR . '/file.txt'));
}
function testGet() {
$file = new Sabre_DAV_FSExt_File(SABRE_TEMPDIR . '/file.txt');
$this->assertEquals('Contents',stream_get_contents($file->get()));
}
function testDelete() {
$file = new Sabre_DAV_FSExt_File(SABRE_TEMPDIR . '/file.txt');
$file->delete();
$this->assertFalse(file_exists(SABRE_TEMPDIR . '/file.txt'));
}
function testGetETag() {
$file = new Sabre_DAV_FSExt_File(SABRE_TEMPDIR . '/file.txt');
$this->assertEquals('"' . md5('Contents') . '"',$file->getETag());
}
function testGetContentType() {
$file = new Sabre_DAV_FSExt_File(SABRE_TEMPDIR . '/file.txt');
$this->assertNull($file->getContentType());
}
function testGetSize() {
$file = new Sabre_DAV_FSExt_File(SABRE_TEMPDIR . '/file.txt');
$this->assertEquals(8,$file->getSize());
}
}

View file

@ -0,0 +1,175 @@
<?php
require_once 'Sabre/TestUtil.php';
class Sabre_DAV_FSExt_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 Sabre_DAV_FSExt_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 Sabre_DAV_FSExt_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 Sabre_DAV_FSExt_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 Sabre_DAV_FSExt_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 Sabre_DAV_FSExt_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 Sabre_DAV_FSExt_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 Sabre_DAV_FSExt_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);
}
}

View file

@ -0,0 +1,219 @@
<?php
require_once 'Sabre/DAV/AbstractServer.php';
class Sabre_DAV_FSExt_ServerTest extends Sabre_DAV_AbstractServer{
protected function getRootNode() {
return new Sabre_DAV_FSExt_Directory($this->tempDir);
}
function testGet() {
$serverVars = array(
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'GET',
);
$request = new Sabre_HTTP_Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals(array(
'Content-Type' => 'application/octet-stream',
'Content-Length' => 13,
'Last-Modified' => Sabre_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 Sabre_HTTP_Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals(array(
'Content-Type' => 'application/octet-stream',
'Content-Length' => 13,
'Last-Modified' => Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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'=> Sabre_DAV_Version::VERSION,
),$this->response->headers);
$this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
$this->assertEquals('', $this->response->body);
}
}

View file

@ -0,0 +1,102 @@
<?php
require_once 'Sabre/TestUtil.php';
class Sabre_DAV_Issue33Test extends PHPUnit_Framework_TestCase {
function setUp() {
Sabre_TestUtil::clearTempDir();
}
function testCopyMoveInfo() {
$foo = new Sabre_DAV_SimpleCollection('foo');
$root = new Sabre_DAV_SimpleCollection('webdav',array($foo));
$tree = new Sabre_DAV_ObjectTree($root);
$server = new Sabre_DAV_Server($tree);
$server->setBaseUri('/webdav/');
$serverVars = array(
'REQUEST_URI' => '/webdav/foo',
'HTTP_DESTINATION' => 'http://dev2.tribalos.com/webdav/%C3%A0fo%C3%B3',
'HTTP_OVERWRITE' => 'F',
);
$request = new Sabre_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 Sabre_DAV_FS_Directory(SABRE_TEMPDIR . '/issue33');
$dir->createDirectory('foo');
$tree = new Sabre_DAV_ObjectTree($dir);
$tree->move('foo',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 = 'foo';
$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/foo',
'HTTP_DESTINATION' => 'http://dev2.tribalos.com/webdav/%C3%A0fo%C3%B3',
'HTTP_OVERWRITE' => 'F',
);
$request = new Sabre_HTTP_Request($serverVars);
$request->setBody('');
$response = new Sabre_HTTP_ResponseMock();
// Server setup
mkdir(SABRE_TEMPDIR . '/issue33');
$dir = new Sabre_DAV_FS_Directory(SABRE_TEMPDIR . '/issue33');
$dir->createDirectory('foo');
$tree = new Sabre_DAV_ObjectTree($dir);
$server = new Sabre_DAV_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')));
}
}

View file

@ -0,0 +1,192 @@
<?php
abstract class Sabre_DAV_Locks_Backend_AbstractTest extends PHPUnit_Framework_TestCase {
/**
* @abstract
* @return Sabre_DAV_Locks_Backend_Abstract
*/
abstract function getBackend();
function testSetup() {
$backend = $this->getBackend();
$this->assertInstanceOf('Sabre_DAV_Locks_Backend_Abstract', $backend);
}
/**
* @depends testSetup
*/
function testGetLocks() {
$backend = $this->getBackend();
$lock = new Sabre_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 Sabre_DAV_Locks_LockInfo();
$lock->owner = 'Sinterklaas';
$lock->timeout = 60;
$lock->created = time();
$lock->depth = Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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));
}
}

View file

@ -0,0 +1,29 @@
<?php
require_once 'Sabre/TestUtil.php';
class Sabre_DAV_Locks_Backend_FSTest extends Sabre_DAV_Locks_Backend_AbstractTest {
function getBackend() {
Sabre_TestUtil::clearTempDir();
mkdir(SABRE_TEMPDIR . '/locks');
$backend = new Sabre_DAV_Locks_Backend_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.
}
}

View file

@ -0,0 +1,22 @@
<?php
require_once 'Sabre/TestUtil.php';
class Sabre_DAV_Locks_Backend_FileTest extends Sabre_DAV_Locks_Backend_AbstractTest {
function getBackend() {
Sabre_TestUtil::clearTempDir();
$backend = new Sabre_DAV_Locks_Backend_File(SABRE_TEMPDIR . '/lockdb');
return $backend;
}
function tearDown() {
Sabre_TestUtil::clearTempDir();
}
}

View file

@ -0,0 +1,30 @@
<?php
require_once 'Sabre/TestUtil.php';
class Sabre_DAV_Locks_Backend_PDOMySQLTest extends Sabre_DAV_Locks_Backend_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 Sabre_DAV_Locks_Backend_PDO($pdo);
return $backend;
}
}

View file

@ -0,0 +1,27 @@
<?php
require_once 'Sabre/TestUtil.php';
require_once 'Sabre/DAV/Locks/Backend/AbstractTest.php';
class Sabre_DAV_Locks_Backend_PDOTest extends Sabre_DAV_Locks_Backend_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 Sabre_DAV_Locks_Backend_PDO($pdo);
return $backend;
}
function tearDown() {
Sabre_TestUtil::clearTempDir();
}
}

View file

@ -0,0 +1,370 @@
<?php
require_once 'Sabre/HTTP/ResponseMock.php';
require_once 'Sabre/DAV/AbstractServer.php';
class Sabre_DAV_Locks_GetIfConditionsTest extends Sabre_DAV_AbstractServer {
/**
* @var Sabre_DAV_Locks_Plugin
*/
protected $locksPlugin;
function setUp() {
parent::setUp();
$locksPlugin = new Sabre_DAV_Locks_Plugin();
$this->server->addPlugin($locksPlugin);
$this->locksPlugin = $locksPlugin;
}
function testNoConditions() {
$serverVars = array(
);
$request = new Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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);
}
}

View file

@ -0,0 +1,118 @@
<?php
require_once 'Sabre/HTTP/ResponseMock.php';
require_once 'Sabre/TestUtil.php';
class Sabre_DAV_Locks_MSWordTest extends PHPUnit_Framework_TestCase {
function testLockEtc() {
mkdir(SABRE_TEMPDIR . '/mstest');
$tree = new Sabre_DAV_FS_Directory(SABRE_TEMPDIR . '/mstest');
$server = new Sabre_DAV_Server($tree);
$server->debugExceptions = true;
$locksBackend = new Sabre_DAV_Locks_Backend_File(SABRE_TEMPDIR . '/locksdb');
$locksPlugin = new Sabre_DAV_Locks_Plugin($locksBackend);
$server->addPlugin($locksPlugin);
$response1 = new Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'PUT',
'REQUEST_URI' => '/Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx',
'HTTP_IF' => 'If: ('.$lockToken.')',
));
$request->setBody('FAKE BODY');
return $request;
}
}

View file

@ -0,0 +1,961 @@
<?php
require_once 'Sabre/DAV/AbstractServer.php';
class Sabre_DAV_Locks_PluginTest extends Sabre_DAV_AbstractServer {
/**
* @var Sabre_DAV_Locks_Plugin
*/
protected $locksPlugin;
function setUp() {
parent::setUp();
$locksBackend = new Sabre_DAV_Locks_Backend_File(SABRE_TEMPDIR . '/locksdb');
$locksPlugin = new Sabre_DAV_Locks_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 Sabre_DAV_Locks_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_HTTP_ResponseMock();
$this->server->httpResponse = $this->response;
$serverVars = array(
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'LOCK',
'HTTP_IF' => '(' . $lockToken . ')',
);
$request = new Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_HTTP_Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->httpResponse = new Sabre_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 Sabre_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 Sabre_HTTP_Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->httpResponse = new Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_DAV_ObjectTree(new Sabre_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 Sabre_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 Sabre_HTTP_Request(array(
'HTTP_TIMEOUT' => 'second-100',
));
$this->server->httpRequest = $request;
$this->assertEquals(100, $this->locksPlugin->getTimeoutHeader());
}
function testGetTimeoutHeaderNotSet() {
$request = new Sabre_HTTP_Request(array(
));
$this->server->httpRequest = $request;
$this->assertEquals(0, $this->locksPlugin->getTimeoutHeader());
}
function testGetTimeoutHeaderInfinite() {
$request = new Sabre_HTTP_Request(array(
'HTTP_TIMEOUT' => 'infinite',
));
$this->server->httpRequest = $request;
$this->assertEquals(Sabre_DAV_Locks_LockInfo::TIMEOUT_INFINITE, $this->locksPlugin->getTimeoutHeader());
}
/**
* @expectedException Sabre_DAV_Exception_BadRequest
*/
function testGetTimeoutHeaderInvalid() {
$request = new Sabre_HTTP_Request(array(
'HTTP_TIMEOUT' => 'yourmom',
));
$this->server->httpRequest = $request;
$this->locksPlugin->getTimeoutHeader();
}
}

View file

@ -0,0 +1,53 @@
<?php
require_once 'Sabre/DAV/AbstractServer.php';
class Sabre_DAV_Mount_PluginTest extends Sabre_DAV_AbstractServer {
function setUp() {
parent::setUp();
$this->server->addPlugin(new Sabre_DAV_Mount_Plugin());
}
function testPassThrough() {
$serverVars = array(
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'GET',
);
$request = new Sabre_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 Sabre_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]);
}
}

View file

@ -0,0 +1,98 @@
<?php
require_once 'Sabre/TestUtil.php';
class Sabre_DAV_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 Sabre_DAV_FSExt_Directory(SABRE_TEMPDIR . '/root');
$this->tree = new Sabre_DAV_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'));
}
}

View file

@ -0,0 +1,76 @@
<?php
class Sabre_DAV_PartialUpdate_FileMock implements Sabre_DAV_PartialUpdate_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 Sabre_DAV_Exception_MethodNotAllowed();
}
function setName($name) {
throw new Sabre_DAV_Exception_MethodNotAllowed();
}
function getName() {
return 'partial';
}
function getLastModified() {
return null;
}
}

View file

@ -0,0 +1,125 @@
<?php
require_once 'Sabre/DAV/PartialUpdate/FileMock.php';
class Sabre_DAV_PartialUpdate_PluginTest extends Sabre_DAVServerTest {
protected $node;
protected $plugin;
public function setUp() {
$this->node = new Sabre_DAV_PartialUpdate_FileMock();
$this->tree[] = $this->node;
parent::setUp();
$this->plugin = new Sabre_DAV_PartialUpdate_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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());
}
}

View file

@ -0,0 +1,63 @@
<?php
class Sabre_DAV_Property_GetLastModifiedTest extends PHPUnit_Framework_TestCase {
function testConstructDateTime() {
$dt = new DateTime('2010-03-14 16:35', new DateTimeZone('UTC'));
$lastMod = new Sabre_DAV_Property_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 Sabre_DAV_Property_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 Sabre_DAV_Property_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 Sabre_DAV_Property_GetLastModified($dt);
$doc = new DOMDocument();
$root = $doc->createElement('d:getlastmodified');
$root->setAttribute('xmlns:d','DAV:');
$doc->appendChild($root);
$objectTree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('rootdir'));
$server = new Sabre_DAV_Server($objectTree);
$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">' .
Sabre_HTTP_Util::toHTTPDate($dt) .
'</d:getlastmodified>
', $xml);
$ok = false;
try {
Sabre_DAV_Property_GetLastModified::unserialize(Sabre_DAV_XMLUtil::loadDOMDocument($xml)->firstChild);
} catch (Sabre_DAV_Exception $e) {
$ok = true;
}
if (!$ok) $this->markTestFailed('Unserialize should not be supported');
}
}

View file

@ -0,0 +1,88 @@
<?php
class Sabre_DAV_Property_HrefListTest extends PHPUnit_Framework_TestCase {
function testConstruct() {
$href = new Sabre_DAV_Property_HrefList(array('foo','bar'));
$this->assertEquals(array('foo','bar'),$href->getHrefs());
}
function testSerialize() {
$href = new Sabre_DAV_Property_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 Sabre_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 Sabre_DAV_Property_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 Sabre_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 = Sabre_DAV_Property_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 = Sabre_DAV_Property_HrefList::unserialize($dom->firstChild);
$this->assertEquals(array(), $href->getHrefs());
}
}

View file

@ -0,0 +1,88 @@
<?php
class Sabre_DAV_Property_HrefTest extends PHPUnit_Framework_TestCase {
function testConstruct() {
$href = new Sabre_DAV_Property_Href('path');
$this->assertEquals('path',$href->getHref());
}
function testSerialize() {
$href = new Sabre_DAV_Property_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 Sabre_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 Sabre_DAV_Property_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 Sabre_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 = Sabre_DAV_Property_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 = Sabre_DAV_Property_Href::unserialize($dom->firstChild);
$this->assertNull($href);
}
}

View file

@ -0,0 +1,107 @@
<?php
class Sabre_DAV_Property_ResourceTypeTest extends PHPUnit_Framework_TestCase {
function testConstruct() {
$resourceType = new Sabre_DAV_Property_ResourceType(array('{DAV:}collection'));
$this->assertEquals(array('{DAV:}collection'),$resourceType->getValue());
$resourceType = new Sabre_DAV_Property_ResourceType(Sabre_DAV_Server::NODE_FILE);
$this->assertEquals(array(),$resourceType->getValue());
$resourceType = new Sabre_DAV_Property_ResourceType(Sabre_DAV_Server::NODE_DIRECTORY);
$this->assertEquals(array('{DAV:}collection'),$resourceType->getValue());
$resourceType = new Sabre_DAV_Property_ResourceType('{DAV:}principal');
$this->assertEquals(array('{DAV:}principal'),$resourceType->getValue());
}
/**
* @depends testConstruct
*/
function testSerialize() {
$resourceType = new Sabre_DAV_Property_ResourceType(array('{DAV:}collection','{DAV:}principal'));
$doc = new DOMDocument();
$root = $doc->createElement('d:anything');
$root->setAttribute('xmlns:d','DAV:');
$doc->appendChild($root);
$server = new Sabre_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 Sabre_DAV_Property_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 Sabre_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 Sabre_DAV_Property_ResourceType(array('{DAV:}collection','{DAV:}principal'));
$this->assertTrue($resourceType->is('{DAV:}collection'));
$this->assertFalse($resourceType->is('{DAV:}blabla'));
}
/**
* @depends testConstruct
*/
function testAdd() {
$resourceType = new Sabre_DAV_Property_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 = Sabre_DAV_XMLUtil::loadDOMDocument($xml);
$resourceType = Sabre_DAV_Property_ResourceType::unserialize($dom->firstChild);
$this->assertEquals(array('{DAV:}collection','{DAV:}principal'),$resourceType->getValue());
}
}

View file

@ -0,0 +1,231 @@
<?php
class Sabre_DAV_Property_ResponseTest extends PHPUnit_Framework_TestCase {
function testSimple() {
$innerProps = array(
200 => array(
'{DAV:}displayname' => 'my file',
),
404 => array(
'{DAV:}owner' => null,
)
);
$property = new Sabre_DAV_Property_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 Sabre_DAV_Property_Response('uri',$innerProps);
$doc = new DOMDocument();
$root = $doc->createElement('d:root');
$root->setAttribute('xmlns:d','DAV:');
$doc->appendChild($root);
$objectTree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('rootdir'));
$server = new Sabre_DAV_Server($objectTree);
$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 Sabre_DAV_Property_Response('uri',$innerProps);
$doc = new DOMDocument();
$root = $doc->createElement('d:root');
$root->setAttribute('xmlns:d','DAV:');
$doc->appendChild($root);
$objectTree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('rootdir'));
$server = new Sabre_DAV_Server($objectTree);
$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 Sabre_DAV_Property_Response('uri',$innerProps);
$doc = new DOMDocument();
$root = $doc->createElement('d:root');
$root->setAttribute('xmlns:d','DAV:');
$doc->appendChild($root);
$objectTree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('rootdir'));
$server = new Sabre_DAV_Server($objectTree);
$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 Sabre_DAV_Property_Href('http://sabredav.org/', false)
),
);
$property = new Sabre_DAV_Property_Response('uri',$innerProps);
$doc = new DOMDocument();
$root = $doc->createElement('d:root');
$root->setAttribute('xmlns:d','DAV:');
$doc->appendChild($root);
$objectTree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('rootdir'));
$server = new Sabre_DAV_Server($objectTree);
$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 Sabre_DAV_Property_Response('uri',$innerProps);
$doc = new DOMDocument();
$root = $doc->createElement('d:root');
$root->setAttribute('xmlns:d','DAV:');
$doc->appendChild($root);
$objectTree = new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleCollection('rootdir'));
$server = new Sabre_DAV_Server($objectTree);
$property->serialize($server, $root);
}
}

View file

@ -0,0 +1,123 @@
<?php
require_once 'Sabre/HTTP/ResponseMock.php';
require_once 'Sabre/DAV/AbstractServer.php';
class Sabre_DAV_Property_SupportedReportSetTest extends Sabre_DAV_AbstractServer {
public function sendPROPFIND($body) {
$serverVars = array(
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'PROPFIND',
'HTTP_DEPTH' => '0',
);
$request = new Sabre_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');
}
}
}
?>

View file

@ -0,0 +1,264 @@
<?php
require_once 'Sabre/HTTP/ResponseMock.php';
class Sabre_DAV_ServerCopyMoveTest extends PHPUnit_Framework_TestCase {
private $response;
/**
* @var Sabre_DAV_Server
*/
private $server;
function setUp() {
$this->response = new Sabre_HTTP_ResponseMock();
$dir = new Sabre_DAV_FS_Directory(SABRE_TEMPDIR);
$tree = new Sabre_DAV_ObjectTree($dir);
$this->server = new Sabre_DAV_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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 Sabre_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'));
}
}

View file

@ -0,0 +1,51 @@
<?php
require_once 'Sabre/DAV/AbstractServer.php';
class Sabre_DAV_ServerEventsTest extends Sabre_DAV_AbstractServer {
private $tempPath;
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 Sabre_HTTP_Request(array(
'REQUEST_METHOD' => 'PUT',
'REQUEST_URI' => '/foobar',
));
$this->server->httpRequest = $req;
$this->server->exec();
$this->assertEquals('',$this->server->httpResponse->status);
}
function beforeBindCancelHandler() {
return false;
}
}

View file

@ -0,0 +1,50 @@
<?php
require_once 'Sabre/HTTP/ResponseMock.php';
require_once 'Sabre/DAV/AbstractServer.php';
require_once 'Sabre/DAV/Exception.php';
class Sabre_DAV_ServerFinderBlockTest extends Sabre_DAV_AbstractServer{
function testPut() {
$serverVars = array(
'REQUEST_URI' => '/testput.txt',
'REQUEST_METHOD' => 'PUT',
'HTTP_X_EXPECTED_ENTITY_LENGTH' => '20',
);
$request = new Sabre_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 Sabre_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'));
}
}

Some files were not shown because too many files have changed in this diff Show more