aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/sabre/dav/tests
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sabre/dav/tests')
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php550
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractTest.php88
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php400
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php39
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php25
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php359
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryParserTest.php540
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php122
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php804
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php255
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php110
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php103
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php104
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php159
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyRequestTest.php282
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php96
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php227
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php63
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php135
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue203Test.php139
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php97
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php89
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php99
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php78
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php90
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php101
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteReplyTest.php134
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteTest.php230
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/SystemStatusTest.php61
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/OutboxPostTest.php545
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php1126
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php19
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php101
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php39
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php126
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Property/AllowedSharingModesTest.php46
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Property/InviteTest.php196
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Property/ScheduleCalendarTranspTest.php99
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarComponentSetTest.php67
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarDataTest.php44
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCollationSetTest.php46
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/IMip/Mock.php50
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php68
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ShareableCalendarTest.php62
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php122
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php391
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php208
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsSharedCalendarsTest.php93
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsTest.php207
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php250
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/VersionTest.php17
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php41
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryParserTest.php329
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php192
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookRootTest.php31
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php162
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php249
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php130
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php60
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php69
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php184
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php30
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php55
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php149
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/Property/SupportedAddressDataTest.php44
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php43
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/TestUtil.php68
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/UserAddressBooksTest.php162
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php75
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php204
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php155
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/VersionTest.php17
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php64
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php91
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php149
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php35
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php45
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php42
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php37
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php31
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php28
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php84
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php234
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php68
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php44
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php114
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php32
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php949
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php68
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Exception/PaymentRequiredTest.php14
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php30
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php95
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/FSExt/NodeTest.php178
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php224
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/HTTPPreferParsingTest.php200
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php105
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php196
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FSTest.php31
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FileTest.php24
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php32
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php29
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/GetIfConditionsTest.php375
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php123
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php966
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php58
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php100
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php79
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/PluginTest.php130
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Property/GetLastModifiedTest.php75
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Property/HrefListTest.php91
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Property/HrefTest.php119
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Property/ResourceTypeTest.php111
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseListTest.php19
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseTest.php230
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Property/SupportedReportSetTest.php128
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerCopyMoveTest.php268
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php76
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerFinderBlockTest.php53
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php371
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php98
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerPreconditionTest.php395
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerPropsTest.php413
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerRangeTest.php274
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php767
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php130
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php19
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php122
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php252
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php34
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Tree/FilesystemTest.php88
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php175
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/URLUtilTest.php131
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/UUIDUtilTest.php25
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/XMLUtilTest.php284
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php331
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php139
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php190
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php39
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php49
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php39
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php39
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php39
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php358
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php56
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php66
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php83
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php407
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php127
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php178
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/Mock.php184
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php45
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php42
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php52
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php246
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php135
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php204
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLRestrictionsTest.php35
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLTest.php335
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Property/CurrentUserPrivilegeSetTest.php68
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Property/PrincipalTest.php181
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Property/SupportedPrivilegeSetTest.php106
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php322
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/VersionTest.php17
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVServerTest.php178
-rw-r--r--vendor/sabre/dav/tests/Sabre/HTTP/AWSAuthTest.php242
-rw-r--r--vendor/sabre/dav/tests/Sabre/HTTP/BasicAuthTest.php132
-rw-r--r--vendor/sabre/dav/tests/Sabre/HTTP/DigestAuthTest.php228
-rw-r--r--vendor/sabre/dav/tests/Sabre/HTTP/RequestTest.php150
-rw-r--r--vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php29
-rw-r--r--vendor/sabre/dav/tests/Sabre/HTTP/ResponseTest.php70
-rw-r--r--vendor/sabre/dav/tests/Sabre/HTTP/UtilTest.php78
-rw-r--r--vendor/sabre/dav/tests/Sabre/HTTP/VersionTest.php17
-rw-r--r--vendor/sabre/dav/tests/Sabre/TestUtil.php51
-rw-r--r--vendor/sabre/dav/tests/bootstrap.php22
-rw-r--r--vendor/sabre/dav/tests/phpunit.xml29
175 files changed, 27140 insertions, 0 deletions
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php
new file mode 100644
index 000000000..2224f0b63
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php
@@ -0,0 +1,550 @@
+<?php
+
+namespace Sabre\CalDAV\Backend;
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
+
+ protected $pdo;
+
+ function testConstruct() {
+
+ $backend = new PDO($this->pdo);
+ $this->assertTrue($backend instanceof PDO);
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testGetCalendarsForUserNoCalendars() {
+
+ $backend = new PDO($this->pdo);
+ $calendars = $backend->getCalendarsForUser('principals/user2');
+ $this->assertEquals(array(),$calendars);
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testCreateCalendarAndFetch() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array(
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Property\SupportedCalendarComponentSet(array('VEVENT')),
+ '{DAV:}displayname' => 'Hello!',
+ '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Property\ScheduleCalendarTransp('transparent'),
+ ));
+ $calendars = $backend->getCalendarsForUser('principals/user2');
+
+ $elementCheck = array(
+ 'id' => $returnedId,
+ 'uri' => 'somerandomid',
+ '{DAV:}displayname' => 'Hello!',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => '',
+ '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Property\ScheduleCalendarTransp('transparent'),
+ );
+
+ $this->assertInternalType('array',$calendars);
+ $this->assertEquals(1,count($calendars));
+
+ foreach($elementCheck as $name=>$value) {
+
+ $this->assertArrayHasKey($name, $calendars[0]);
+ $this->assertEquals($value,$calendars[0][$name]);
+
+ }
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testUpdateCalendarAndFetch() {
+
+ $backend = new PDO($this->pdo);
+
+ //Creating a new calendar
+ $newId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ // Updating the calendar
+ $result = $backend->updateCalendar($newId,array(
+ '{DAV:}displayname' => 'myCalendar',
+ '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Property\ScheduleCalendarTransp('transparent'),
+ ));
+
+ // Verifying the result of the update
+ $this->assertEquals(true, $result);
+
+ // Fetching all calendars from this user
+ $calendars = $backend->getCalendarsForUser('principals/user2');
+
+ // Checking if all the information is still correct
+ $elementCheck = array(
+ 'id' => $newId,
+ 'uri' => 'somerandomid',
+ '{DAV:}displayname' => 'myCalendar',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => '',
+ '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => '',
+ '{http://calendarserver.org/ns/}getctag' => '2',
+ '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Property\ScheduleCalendarTransp('transparent'),
+ );
+
+ $this->assertInternalType('array',$calendars);
+ $this->assertEquals(1,count($calendars));
+
+ foreach($elementCheck as $name=>$value) {
+
+ $this->assertArrayHasKey($name, $calendars[0]);
+ $this->assertEquals($value,$calendars[0][$name]);
+
+ }
+
+ }
+
+ /**
+ * @depends testUpdateCalendarAndFetch
+ */
+ function testUpdateCalendarUnknownProperty() {
+
+ $backend = new PDO($this->pdo);
+
+ //Creating a new calendar
+ $newId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ // Updating the calendar
+ $result = $backend->updateCalendar($newId,array(
+ '{DAV:}displayname' => 'myCalendar',
+ '{DAV:}yourmom' => 'wittycomment',
+ ));
+
+ // Verifying the result of the update
+ $this->assertEquals(array(
+ '403' => array('{DAV:}yourmom' => null),
+ '424' => array('{DAV:}displayname' => null),
+ ), $result);
+
+ }
+
+ /**
+ * @depends testCreateCalendarAndFetch
+ */
+ function testDeleteCalendar() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array(
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Property\SupportedCalendarComponentSet(array('VEVENT')),
+ '{DAV:}displayname' => 'Hello!',
+ ));
+
+ $backend->deleteCalendar($returnedId);
+
+ $calendars = $backend->getCalendarsForUser('principals/user2');
+ $this->assertEquals(array(),$calendars);
+
+ }
+
+ /**
+ * @depends testCreateCalendarAndFetch
+ * @expectedException \Sabre\DAV\Exception
+ */
+ function testCreateCalendarIncorrectComponentSet() {;
+
+ $backend = new PDO($this->pdo);
+
+ //Creating a new calendar
+ $newId = $backend->createCalendar('principals/user2','somerandomid',array(
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => 'blabla',
+ ));
+
+ }
+
+ function testCreateCalendarObject() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $this->assertEquals(array(
+ 'etag' => md5($object),
+ 'size' => strlen($object),
+ 'calendardata' => $object,
+ 'firstoccurence' => strtotime('20120101'),
+ 'lastoccurence' => strtotime('20120101')+(3600*24),
+ 'componenttype' => 'VEVENT',
+ ), $result->fetch(\PDO::FETCH_ASSOC));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ * @depends testCreateCalendarObject
+ */
+ function testCreateCalendarObjectNoComponent() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testCreateCalendarObjectDuration() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nDURATION:P2D\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $this->assertEquals(array(
+ 'etag' => md5($object),
+ 'size' => strlen($object),
+ 'calendardata' => $object,
+ 'firstoccurence' => strtotime('20120101'),
+ 'lastoccurence' => strtotime('20120101')+(3600*48),
+ 'componenttype' => 'VEVENT',
+ ), $result->fetch(\PDO::FETCH_ASSOC));
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testCreateCalendarObjectNoDTEND() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $this->assertEquals(array(
+ 'etag' => md5($object),
+ 'size' => strlen($object),
+ 'calendardata' => $object,
+ 'firstoccurence' => strtotime('2012-01-01 10:00:00'),
+ 'lastoccurence' => strtotime('2012-01-01 10:00:00'),
+ 'componenttype' => 'VEVENT',
+ ), $result->fetch(\PDO::FETCH_ASSOC));
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testCreateCalendarObjectInfiniteReccurence() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nRRULE:FREQ=DAILY\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $this->assertEquals(array(
+ 'etag' => md5($object),
+ 'size' => strlen($object),
+ 'calendardata' => $object,
+ 'firstoccurence' => strtotime('2012-01-01 10:00:00'),
+ 'lastoccurence' => strtotime(PDO::MAX_DATE),
+ 'componenttype' => 'VEVENT',
+ ), $result->fetch(\PDO::FETCH_ASSOC));
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testCreateCalendarObjectEndingReccurence() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nDTEND;VALUE=DATE-TIME:20120101T110000Z\r\nRRULE:FREQ=DAILY;COUNT=1000\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $this->assertEquals(array(
+ 'etag' => md5($object),
+ 'size' => strlen($object),
+ 'calendardata' => $object,
+ 'firstoccurence' => strtotime('2012-01-01 10:00:00'),
+ 'lastoccurence' => strtotime('2012-01-01 11:00:00') + (3600 * 24 * 999),
+ 'componenttype' => 'VEVENT',
+ ), $result->fetch(\PDO::FETCH_ASSOC));
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testCreateCalendarObjectTask() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nDUE;VALUE=DATE-TIME:20120101T100000Z\r\nEND:VTODO\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $this->assertEquals(array(
+ 'etag' => md5($object),
+ 'size' => strlen($object),
+ 'calendardata' => $object,
+ 'firstoccurence' => null,
+ 'lastoccurence' => null,
+ 'componenttype' => 'VTODO',
+ ), $result->fetch(\PDO::FETCH_ASSOC));
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testGetCalendarObjects() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+
+ $data = $backend->getCalendarObjects($returnedId,'random-id');
+
+ $this->assertEquals(1, count($data));
+ $data = $data[0];
+
+ $this->assertEquals($returnedId, $data['calendarid']);
+ $this->assertEquals('random-id', $data['uri']);
+ $this->assertEquals(strlen($object),$data['size']);
+
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testUpdateCalendarObject() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+ $object2 = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20130101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+ $backend->updateCalendarObject($returnedId, 'random-id', $object2);
+
+ $data = $backend->getCalendarObject($returnedId,'random-id');
+
+ $this->assertEquals($object2, $data['calendardata']);
+ $this->assertEquals($returnedId, $data['calendarid']);
+ $this->assertEquals('random-id', $data['uri']);
+
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ */
+ function testDeleteCalendarObject() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2','somerandomid',array());
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+ $backend->deleteCalendarObject($returnedId, 'random-id');
+
+ $data = $backend->getCalendarObject($returnedId,'random-id');
+ $this->assertNull($data);
+
+ }
+
+ function testCalendarQueryNoResult() {
+
+ $abstract = new PDO($this->pdo);
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VJOURNAL',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $this->assertEquals(array(
+ ), $abstract->calendarQuery(1, $filters));
+
+ }
+
+ function testCalendarQueryTodo() {
+
+ $backend = new PDO($this->pdo);
+ $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VTODO',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $this->assertEquals(array(
+ "todo",
+ ), $backend->calendarQuery(1, $filters));
+
+ }
+ function testCalendarQueryTodoNotMatch() {
+
+ $backend = new PDO($this->pdo);
+ $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VTODO',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(
+ array(
+ 'name' => 'summary',
+ 'text-match' => null,
+ 'time-range' => null,
+ 'param-filters' => array(),
+ 'is-not-defined' => false,
+ ),
+ ),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $this->assertEquals(array(
+ ), $backend->calendarQuery(1, $filters));
+
+ }
+
+ function testCalendarQueryNoFilter() {
+
+ $backend = new PDO($this->pdo);
+ $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $result = $backend->calendarQuery(1, $filters);
+ $this->assertTrue(in_array('todo', $result));
+ $this->assertTrue(in_array('event', $result));
+
+ }
+
+ function testCalendarQueryTimeRange() {
+
+ $backend = new PDO($this->pdo);
+ $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event2", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('20120103'),
+ 'end' => new \DateTime('20120104'),
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $this->assertEquals(array(
+ "event2",
+ ), $backend->calendarQuery(1, $filters));
+
+ }
+ function testCalendarQueryTimeRangeNoEnd() {
+
+ $backend = new PDO($this->pdo);
+ $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject(1, "event2", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('20120102'),
+ 'end' => null,
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $this->assertEquals(array(
+ "event2",
+ ), $backend->calendarQuery(1, $filters));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractTest.php
new file mode 100644
index 000000000..04fb16df5
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractTest.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Sabre\CalDAV\Backend;
+
+class AbstractTest extends \PHPUnit_Framework_TestCase {
+
+ function testUpdateCalendar() {
+
+ $abstract = new AbstractMock();
+ $this->assertEquals(false, $abstract->updateCalendar('randomid', array('{DAV:}displayname' => 'anything')));
+
+ }
+
+ function testCalendarQuery() {
+
+ $abstract = new AbstractMock();
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $this->assertEquals(array(
+ 'event1.ics',
+ ), $abstract->calendarQuery(1, $filters));
+
+ }
+
+}
+
+class AbstractMock extends AbstractBackend {
+
+ function getCalendarsForUser($principalUri) { }
+ function createCalendar($principalUri,$calendarUri,array $properties) { }
+ function deleteCalendar($calendarId) { }
+ function getCalendarObjects($calendarId) {
+
+ return array(
+ array(
+ 'id' => 1,
+ 'calendarid' => 1,
+ 'uri' => 'event1.ics',
+ ),
+ array(
+ 'id' => 2,
+ 'calendarid' => 1,
+ 'uri' => 'task1.ics',
+ ),
+ );
+
+ }
+ function getCalendarObject($calendarId,$objectUri) {
+
+ switch($objectUri) {
+
+ case 'event1.ics' :
+ return array(
+ 'id' => 1,
+ 'calendarid' => 1,
+ 'uri' => 'event1.ics',
+ 'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
+ );
+ case 'task1.ics' :
+ return array(
+ 'id' => 1,
+ 'calendarid' => 1,
+ 'uri' => 'event1.ics',
+ 'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n",
+ );
+
+ }
+
+ }
+ function createCalendarObject($calendarId,$objectUri,$calendarData) { }
+ function updateCalendarObject($calendarId,$objectUri,$calendarData) { }
+ function deleteCalendarObject($calendarId,$objectUri) { }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php
new file mode 100644
index 000000000..d196297f7
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php
@@ -0,0 +1,400 @@
+<?php
+
+namespace Sabre\CalDAV\Backend;
+use Sabre\DAV;
+use Sabre\CalDAV;
+
+class Mock extends AbstractBackend implements NotificationSupport, SharingSupport {
+
+ private $calendarData;
+ private $calendars;
+ private $notifications;
+ private $shares = array();
+
+ function __construct(array $calendars, array $calendarData, array $notifications = array()) {
+
+ $this->calendars = $calendars;
+ $this->calendarData = $calendarData;
+ $this->notifications = $notifications;
+
+ }
+
+ /**
+ * Returns a list of calendars for a principal.
+ *
+ * Every project is an array with the following keys:
+ * * id, a unique id that will be used by other functions to modify the
+ * calendar. This can be the same as the uri or a database key.
+ * * uri, which the basename of the uri with which the calendar is
+ * accessed.
+ * * principalUri. The owner of the calendar. Almost always the same as
+ * principalUri passed to this method.
+ *
+ * Furthermore it can contain webdav properties in clark notation. A very
+ * common one is '{DAV:}displayname'.
+ *
+ * @param string $principalUri
+ * @return array
+ */
+ function getCalendarsForUser($principalUri) {
+
+ $r = array();
+ foreach($this->calendars as $row) {
+ if ($row['principaluri'] == $principalUri) {
+ $r[] = $row;
+ }
+ }
+
+ return $r;
+
+ }
+
+ /**
+ * Creates a new calendar for a principal.
+ *
+ * If the creation was a success, an id must be returned that can be used to reference
+ * this calendar in other methods, such as updateCalendar.
+ *
+ * This function must return a server-wide unique id that can be used
+ * later to reference the calendar.
+ *
+ * @param string $principalUri
+ * @param string $calendarUri
+ * @param array $properties
+ * @return string|int
+ */
+ function createCalendar($principalUri,$calendarUri,array $properties) {
+
+ $id = DAV\UUIDUtil::getUUID();
+ $this->calendars[] = array_merge(array(
+ 'id' => $id,
+ 'principaluri' => $principalUri,
+ 'uri' => $calendarUri,
+ '{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Property\SupportedCalendarComponentSet(array('VEVENT','VTODO')),
+ ), $properties);
+
+ return $id;
+
+ }
+
+ /**
+ * Updates properties on this node,
+ *
+ * The properties array uses the propertyName in clark-notation as key,
+ * and the array value for the property value. In the case a property
+ * should be deleted, the property value will be null.
+ *
+ * This method must be atomic. If one property cannot be changed, the
+ * entire operation must fail.
+ *
+ * If the operation was successful, true can be returned.
+ * If the operation failed, false can be returned.
+ *
+ * Deletion of a non-existent property is always successful.
+ *
+ * Lastly, it is optional to return detailed information about any
+ * failures. In this case an array should be returned with the following
+ * structure:
+ *
+ * array(
+ * 403 => array(
+ * '{DAV:}displayname' => null,
+ * ),
+ * 424 => array(
+ * '{DAV:}owner' => null,
+ * )
+ * )
+ *
+ * In this example it was forbidden to update {DAV:}displayname.
+ * (403 Forbidden), which in turn also caused {DAV:}owner to fail
+ * (424 Failed Dependency) because the request needs to be atomic.
+ *
+ * @param string $calendarId
+ * @param array $properties
+ * @return bool|array
+ */
+ public function updateCalendar($calendarId, array $properties) {
+
+ return false;
+
+ }
+
+ /**
+ * Delete a calendar and all it's objects
+ *
+ * @param string $calendarId
+ * @return void
+ */
+ public function deleteCalendar($calendarId) {
+
+ foreach($this->calendars as $k=>$calendar) {
+ if ($calendar['id'] === $calendarId) {
+ unset($this->calendars[$k]);
+ }
+ }
+
+ }
+
+ /**
+ * Returns all calendar objects within a calendar object.
+ *
+ * Every item contains an array with the following keys:
+ * * id - unique identifier which will be used for subsequent updates
+ * * calendardata - The iCalendar-compatible calendar data
+ * * uri - a unique key which will be used to construct the uri. This can be any arbitrary string.
+ * * lastmodified - a timestamp of the last modification time
+ * * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
+ * ' "abcdef"')
+ * * calendarid - The calendarid as it was passed to this function.
+ *
+ * Note that the etag is optional, but it's highly encouraged to return for
+ * speed reasons.
+ *
+ * The calendardata is also optional. If it's not returned
+ * 'getCalendarObject' will be called later, which *is* expected to return
+ * calendardata.
+ *
+ * @param string $calendarId
+ * @return array
+ */
+ public function getCalendarObjects($calendarId) {
+
+ if (!isset($this->calendarData[$calendarId]))
+ return array();
+
+ $objects = $this->calendarData[$calendarId];
+
+ foreach($objects as $uri => &$object) {
+ $object['calendarid'] = $calendarId;
+ $object['uri'] = $uri;
+
+ }
+ return $objects;
+
+ }
+
+ /**
+ * Returns information from a single calendar object, based on it's object
+ * uri.
+ *
+ * The returned array must have the same keys as getCalendarObjects. The
+ * 'calendardata' object is required here though, while it's not required
+ * for getCalendarObjects.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @return array
+ */
+ function getCalendarObject($calendarId,$objectUri) {
+
+ if (!isset($this->calendarData[$calendarId][$objectUri])) {
+ throw new DAV\Exception\NotFound('Object could not be found');
+ }
+ $object = $this->calendarData[$calendarId][$objectUri];
+ $object['calendarid'] = $calendarId;
+ $object['uri'] = $objectUri;
+ return $object;
+
+ }
+
+ /**
+ * Creates a new calendar object.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @param string $calendarData
+ * @return void
+ */
+ function createCalendarObject($calendarId,$objectUri,$calendarData) {
+
+ $this->calendarData[$calendarId][$objectUri] = array(
+ 'calendardata' => $calendarData,
+ 'calendarid' => $calendarId,
+ 'uri' => $objectUri,
+ );
+
+ }
+
+ /**
+ * Updates an existing calendarobject, based on it's uri.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @param string $calendarData
+ * @return void
+ */
+ function updateCalendarObject($calendarId,$objectUri,$calendarData) {
+
+ $this->calendarData[$calendarId][$objectUri] = array(
+ 'calendardata' => $calendarData,
+ 'calendarid' => $calendarId,
+ 'uri' => $objectUri,
+ );
+
+ }
+
+ /**
+ * Deletes an existing calendar object.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @return void
+ */
+ function deleteCalendarObject($calendarId,$objectUri) {
+
+ throw new Exception('Not implemented');
+
+
+ }
+
+ /**
+ * Returns a list of notifications for a given principal url.
+ *
+ * The returned array should only consist of implementations of
+ * Sabre\CalDAV\Notifications\INotificationType.
+ *
+ * @param string $principalUri
+ * @return array
+ */
+ public function getNotificationsForPrincipal($principalUri) {
+
+ if (isset($this->notifications[$principalUri])) {
+ return $this->notifications[$principalUri];
+ }
+ return array();
+
+ }
+
+ /**
+ * This deletes a specific notifcation.
+ *
+ * This may be called by a client once it deems a notification handled.
+ *
+ * @param string $principalUri
+ * @param Sabre\CalDAV\Notifications\INotificationType $notification
+ * @return void
+ */
+ public function deleteNotification($principalUri, CalDAV\Notifications\INotificationType $notification) {
+
+ foreach($this->notifications[$principalUri] as $key=>$value) {
+ if ($notification === $value) {
+ unset($this->notifications[$principalUri][$key]);
+ }
+ }
+
+ }
+
+ /**
+ * Updates the list of shares.
+ *
+ * The first array is a list of people that are to be added to the
+ * calendar.
+ *
+ * Every element in the add array has the following properties:
+ * * href - A url. Usually a mailto: address
+ * * commonName - Usually a first and last name, or false
+ * * summary - A description of the share, can also be false
+ * * readOnly - A boolean value
+ *
+ * Every element in the remove array is just the address string.
+ *
+ * Note that if the calendar is currently marked as 'not shared' by and
+ * this method is called, the calendar should be 'upgraded' to a shared
+ * calendar.
+ *
+ * @param mixed $calendarId
+ * @param array $add
+ * @param array $remove
+ * @return void
+ */
+ public function updateShares($calendarId, array $add, array $remove) {
+
+ if (!isset($this->shares[$calendarId])) {
+ $this->shares[$calendarId] = array();
+ }
+
+ foreach($add as $val) {
+ $val['status'] = CalDAV\SharingPlugin::STATUS_NORESPONSE;
+ $this->shares[$calendarId][] = $val;
+ }
+
+ foreach($this->shares[$calendarId] as $k=>$share) {
+
+ if (in_array($share['href'], $remove)) {
+ unset($this->shares[$calendarId][$k]);
+ }
+
+ }
+
+ // Re-numbering keys
+ $this->shares[$calendarId] = array_values($this->shares[$calendarId]);
+
+ }
+
+ /**
+ * Returns the list of people whom this calendar is shared with.
+ *
+ * Every element in this array should have the following properties:
+ * * href - Often a mailto: address
+ * * commonName - Optional, for example a first + last name
+ * * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
+ * * readOnly - boolean
+ * * summary - Optional, a description for the share
+ *
+ * @param mixed $calendarId
+ * @return array
+ */
+ public function getShares($calendarId) {
+
+ if (!isset($this->shares[$calendarId])) {
+ return array();
+ }
+
+ return $this->shares[$calendarId];
+
+ }
+
+ /**
+ * This method is called when a user replied to a request to share.
+ *
+ * @param string href The sharee who is replying (often a mailto: address)
+ * @param int status One of the SharingPlugin::STATUS_* constants
+ * @param string $calendarUri The url to the calendar thats being shared
+ * @param string $inReplyTo The unique id this message is a response to
+ * @param string $summary A description of the reply
+ * @return void
+ */
+ public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null) {
+
+ // This operation basically doesn't do anything yet
+ if ($status === CalDAV\SharingPlugin::STATUS_ACCEPTED) {
+ return 'calendars/blabla/calendar';
+ }
+
+ }
+
+ /**
+ * Publishes a calendar
+ *
+ * @param mixed $calendarId
+ * @param bool $value
+ * @return void
+ */
+ public function setPublishStatus($calendarId, $value) {
+
+ foreach($this->calendars as $k=>$cal) {
+ if ($cal['id'] === $calendarId) {
+ if (!$value) {
+ unset($cal['{http://calendarserver.org/ns/}publish-url']);
+ } else {
+ $cal['{http://calendarserver.org/ns/}publish-url'] = 'http://example.org/public/ ' . $calendarId . '.ics';
+ }
+ return;
+ }
+ }
+
+ throw new DAV\Exception('Calendar with id "' . $calendarId . '" not found');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php
new file mode 100644
index 000000000..15c1d91fd
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Sabre\CalDAV\Backend;
+
+require_once 'Sabre/TestUtil.php';
+require_once 'Sabre/CalDAV/TestUtil.php';
+require_once 'Sabre/CalDAV/Backend/AbstractPDOTest.php';
+
+class PDOMySQLTest extends AbstractPDOTest {
+
+ function setup() {
+
+ if (!SABRE_HASMYSQL) $this->markTestSkipped('MySQL driver is not available, or not properly configured');
+ $pdo = \Sabre\TestUtil::getMySQLDB();
+ if (!$pdo) $this->markTestSkipped('Could not connect to mysql database');
+
+ $pdo->query('DROP TABLE IF EXISTS calendarobjects, calendars');
+
+ $queries = explode(
+ ';',
+ file_get_contents(__DIR__ . '/../../../../examples/sql/mysql.calendars.sql')
+ );
+
+ foreach($queries as $query) {
+ $query = trim($query," \r\n\t");
+ if ($query)
+ $pdo->exec($query);
+ }
+ $this->pdo = $pdo;
+
+ }
+
+ function teardown() {
+
+ $this->pdo = null;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php
new file mode 100644
index 000000000..c50f06986
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Sabre\CalDAV\Backend;
+
+use Sabre\CalDAV;
+
+require_once 'Sabre/CalDAV/Backend/AbstractPDOTest.php';
+
+class PDOSQLiteTest extends AbstractPDOTest {
+
+ function setup() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $this->pdo = CalDAV\TestUtil::getSQLiteDB();
+
+ }
+
+ function teardown() {
+
+ $this->pdo = null;
+ unlink(SABRE_TEMPDIR . '/testdb.sqlite');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php
new file mode 100644
index 000000000..eab10eae7
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php
@@ -0,0 +1,359 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\DAVACL;
+
+require_once 'Sabre/CalDAV/TestUtil.php';
+
+class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\CalDAV\Backend_PDO
+ */
+ protected $backend;
+ /**
+ * @var Sabre\CalDAV\Calendar
+ */
+ protected $calendar;
+ protected $principalBackend;
+
+ function setup() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $this->backend = TestUtil::getBackend();
+
+ $calendars = $this->backend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(2,count($calendars));
+ $this->calendar = new Calendar($this->backend, $calendars[0]);
+
+ }
+
+ function teardown() {
+
+ unset($this->calendar);
+ unset($this->backend);
+
+ }
+
+ function testSetup() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $this->assertInternalType('string',$children[0]->getName());
+ $this->assertInternalType('string',$children[0]->get());
+ $this->assertInternalType('string',$children[0]->getETag());
+ $this->assertEquals('text/calendar; charset=utf-8', $children[0]->getContentType());
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testInvalidArg1() {
+
+ $obj = new CalendarObject(
+ new Backend\Mock(array(),array()),
+ array(),
+ array()
+ );
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testInvalidArg2() {
+
+ $obj = new CalendarObject(
+ new Backend\Mock(array(),array()),
+ array(),
+ array('calendarid' => '1')
+ );
+
+ }
+
+ /**
+ * @depends testSetup
+ */
+ function testPut() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+ $newData = TestUtil::getTestCalendarData();
+
+ $children[0]->put($newData);
+ $this->assertEquals($newData, $children[0]->get());
+
+ }
+
+ /**
+ * @depends testSetup
+ */
+ function testPutStream() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+ $newData = TestUtil::getTestCalendarData();
+
+ $stream = fopen('php://temp','r+');
+ fwrite($stream, $newData);
+ rewind($stream);
+ $children[0]->put($stream);
+ $this->assertEquals($newData, $children[0]->get());
+
+ }
+
+
+ /**
+ * @depends testSetup
+ */
+ function testDelete() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+ $obj->delete();
+
+ $children2 = $this->calendar->getChildren();
+ $this->assertEquals(count($children)-1, count($children2));
+
+ }
+
+ /**
+ * @depends testSetup
+ */
+ function testGetLastModified() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+
+ $lastMod = $obj->getLastModified();
+ $this->assertTrue(is_int($lastMod) || ctype_digit($lastMod));
+
+ }
+
+ /**
+ * @depends testSetup
+ */
+ function testGetSize() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+
+ $size = $obj->getSize();
+ $this->assertInternalType('int', $size);
+
+ }
+
+ function testGetOwner() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+ $this->assertEquals('principals/user1', $obj->getOwner());
+
+ }
+
+ function testGetGroup() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+ $this->assertNull($obj->getGroup());
+
+ }
+
+ function testGetACL() {
+
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1/calendar-proxy-read',
+ 'protected' => true,
+ ),
+ );
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+ $this->assertEquals($expected, $obj->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetACL() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+ $obj->setACL(array());
+
+ }
+
+ function testGet() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ $obj = $children[0];
+
+ $expected = "BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:Asia/Seoul
+BEGIN:DAYLIGHT
+TZOFFSETFROM:+0900
+RRULE:FREQ=YEARLY;UNTIL=19880507T150000Z;BYMONTH=5;BYDAY=2SU
+DTSTART:19870510T000000
+TZNAME:GMT+09:00
+TZOFFSETTO:+1000
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:+1000
+DTSTART:19881009T000000
+TZNAME:GMT+09:00
+TZOFFSETTO:+0900
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20100225T154229Z
+UID:39A6B5ED-DD51-4AFE-A683-C35EE3749627
+TRANSP:TRANSPARENT
+SUMMARY:Something here
+DTSTAMP:20100228T130202Z
+DTSTART;TZID=Asia/Seoul:20100223T060000
+DTEND;TZID=Asia/Seoul:20100223T070000
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR";
+
+
+
+ $this->assertEquals($expected, $obj->get());
+
+ }
+
+ function testGetRefetch() {
+
+ $backend = new Backend\Mock(array(), array(
+ 1 => array(
+ 'foo' => array(
+ 'calendardata' => 'foo',
+ 'uri' => 'foo'
+ ),
+ )
+ ));
+ $obj = new CalendarObject($backend, array(), array('calendarid' => 1, 'uri' => 'foo'));
+
+ $this->assertEquals('foo', $obj->get());
+
+ }
+
+ function testGetEtag1() {
+
+ $objectInfo = array(
+ 'calendardata' => 'foo',
+ 'uri' => 'foo',
+ 'etag' => 'bar',
+ 'calendarid' => 1
+ );
+
+ $backend = new Backend\Mock(array(), array());
+ $obj = new CalendarObject($backend, array(), $objectInfo);
+
+ $this->assertEquals('bar', $obj->getETag());
+
+ }
+
+ function testGetEtag2() {
+
+ $objectInfo = array(
+ 'calendardata' => 'foo',
+ 'uri' => 'foo',
+ 'calendarid' => 1
+ );
+
+ $backend = new Backend\Mock(array(), array());
+ $obj = new CalendarObject($backend, array(), $objectInfo);
+
+ $this->assertEquals('"' . md5('foo') . '"', $obj->getETag());
+
+ }
+
+ function testGetSupportedPrivilegesSet() {
+
+ $objectInfo = array(
+ 'calendardata' => 'foo',
+ 'uri' => 'foo',
+ 'calendarid' => 1
+ );
+
+ $backend = new Backend\Mock(array(), array());
+ $obj = new CalendarObject($backend, array(), $objectInfo);
+ $this->assertNull($obj->getSupportedPrivilegeSet());
+
+ }
+
+ function testGetSize1() {
+
+ $objectInfo = array(
+ 'calendardata' => 'foo',
+ 'uri' => 'foo',
+ 'calendarid' => 1
+ );
+
+ $backend = new Backend\Mock(array(), array());
+ $obj = new CalendarObject($backend, array(), $objectInfo);
+ $this->assertEquals(3, $obj->getSize());
+
+ }
+
+ function testGetSize2() {
+
+ $objectInfo = array(
+ 'uri' => 'foo',
+ 'calendarid' => 1,
+ 'size' => 4,
+ );
+
+ $backend = new Backend\Mock(array(), array());
+ $obj = new CalendarObject($backend, array(), $objectInfo);
+ $this->assertEquals(4, $obj->getSize());
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryParserTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryParserTest.php
new file mode 100644
index 000000000..fdfe4de89
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryParserTest.php
@@ -0,0 +1,540 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\DAV;
+
+class CalendarQueryParserTest extends \PHPUnit_Framework_TestCase {
+
+ function parse($xml) {
+
+ $xml =
+'<?xml version="1.0"?>
+<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
+' . implode("\n", $xml) . '
+</c:calendar-query>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $q = new CalendarQueryParser($dom);
+ $q->parse();
+ return $q->filters;
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testNoFilter() {
+
+ $xml = array();
+ $this->parse($xml);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testTwoCompFilter() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VEVENT" />',
+ ' <c:comp-filter name="VEVENT" />',
+ '</c:filter>'
+ );
+ $this->parse($xml);
+
+ }
+
+ function testBasicFilter() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR" />',
+ '</c:filter>'
+ );
+ $result = $this->parse($xml);
+
+ $expected = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => false
+ );
+
+ $this->assertEquals(
+ $expected,
+ $result
+ );
+
+ }
+
+ function testCompIsNotDefined() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR">',
+ ' <c:comp-filter name="VEVENT">',
+ ' <c:is-not-defined/>',
+ ' </c:comp-filter>',
+ ' </c:comp-filter>',
+ '</c:filter>'
+ );
+ $result = $this->parse($xml);
+
+ $expected = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => true,
+ 'time-range' => false
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => false
+ );
+
+ $this->assertEquals(
+ $expected,
+ $result
+ );
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testCompTimeRangeOnVCALENDAR() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR">',
+ ' <c:time-range start="20110101T000000Z" end="20111231T235959Z" />',
+ ' </c:comp-filter>',
+ '</c:filter>'
+ );
+ $result = $this->parse($xml);
+
+ }
+
+ function testCompTimeRange() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR">',
+ ' <c:comp-filter name="VEVENT">',
+ ' <c:time-range start="20110101T000000Z" end="20111231T235959Z" />',
+ ' </c:comp-filter>',
+ ' <c:comp-filter name="VTODO">',
+ ' <c:time-range start="20110101T000000Z" />',
+ ' </c:comp-filter>',
+ ' <c:comp-filter name="VJOURNAL">',
+ ' <c:time-range end="20111231T235959Z" />',
+ ' </c:comp-filter>',
+ ' </c:comp-filter>',
+ '</c:filter>'
+ );
+ $result = $this->parse($xml);
+
+ $expected = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 00:00:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-12-31 23:59:59', new \DateTimeZone('GMT')),
+ ),
+ ),
+ array(
+ 'name' => 'VTODO',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 00:00:00', new \DateTimeZone('GMT')),
+ 'end' => null,
+ ),
+ ),
+ array(
+ 'name' => 'VJOURNAL',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => null,
+ 'end' => new \DateTime('2011-12-31 23:59:59', new \DateTimeZone('GMT')),
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => false
+ );
+
+ $this->assertEquals(
+ $expected,
+ $result
+ );
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testCompTimeRangeBadRange() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR">',
+ ' <c:comp-filter name="VEVENT">',
+ ' <c:time-range start="20110101T000000Z" end="20100101T000000Z" />',
+ ' </c:comp-filter>',
+ ' </c:comp-filter>',
+ '</c:filter>'
+ );
+ $this->parse($xml);
+
+ }
+
+ function testProp() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR">',
+ ' <c:comp-filter name="VEVENT">',
+ ' <c:prop-filter name="SUMMARY">',
+ ' <c:text-match>vacation</c:text-match>',
+ ' </c:prop-filter>',
+ ' </c:comp-filter>',
+ ' </c:comp-filter>',
+ '</c:filter>'
+ );
+ $result = $this->parse($xml);
+
+ $expected = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'is-not-defined' => false,
+ 'comp-filters' => array(),
+ 'prop-filters' => array(
+ array(
+ 'name' => 'SUMMARY',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'text-match' => array(
+ 'negate-condition' => false,
+ 'collation' => 'i;ascii-casemap',
+ 'value' => 'vacation',
+ ),
+ 'time-range' => null,
+ ),
+ ),
+ 'time-range' => null,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => false
+ );
+
+ $this->assertEquals(
+ $expected,
+ $result
+ );
+
+ }
+
+ function testComplex() {
+
+ $xml = array(
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR">',
+ ' <c:comp-filter name="VEVENT">',
+ ' <c:prop-filter name="SUMMARY">',
+ ' <c:text-match collation="i;unicode-casemap">vacation</c:text-match>',
+ ' </c:prop-filter>',
+ ' <c:prop-filter name="DTSTAMP">',
+ ' <c:time-range start="20110704T000000Z" />',
+ ' </c:prop-filter>',
+ ' <c:prop-filter name="ORGANIZER">',
+ ' <c:is-not-defined />',
+ ' </c:prop-filter>',
+ ' <c:prop-filter name="DTSTART">',
+ ' <c:param-filter name="VALUE">',
+ ' <c:text-match negate-condition="yes">DATE</c:text-match>',
+ ' </c:param-filter>',
+ ' </c:prop-filter>',
+ ' </c:comp-filter>',
+ ' </c:comp-filter>',
+ '</c:filter>'
+ );
+ $result = $this->parse($xml);
+
+ $expected = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'is-not-defined' => false,
+ 'comp-filters' => array(),
+ 'prop-filters' => array(
+ array(
+ 'name' => 'SUMMARY',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'text-match' => array(
+ 'negate-condition' => false,
+ 'collation' => 'i;unicode-casemap',
+ 'value' => 'vacation',
+ ),
+ 'time-range' => null,
+ ),
+ array(
+ 'name' => 'DTSTAMP',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'text-match' => null,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-07-04 00:00:00', new \DateTimeZone('GMT')),
+ 'end' => null,
+ ),
+ ),
+ array(
+ 'name' => 'ORGANIZER',
+ 'is-not-defined' => true,
+ 'param-filters' => array(),
+ 'text-match' => null,
+ 'time-range' => null,
+ ),
+ array(
+ 'name' => 'DTSTART',
+ 'is-not-defined' => false,
+ 'param-filters' => array(
+ array(
+ 'name' => 'VALUE',
+ 'is-not-defined' => false,
+ 'text-match' => array(
+ 'negate-condition' => true,
+ 'value' => 'DATE',
+ 'collation' => 'i;ascii-casemap',
+ ),
+ ),
+ ),
+ 'text-match' => null,
+ 'time-range' => null,
+ ),
+ ),
+ 'time-range' => null,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => false
+ );
+
+ $this->assertEquals(
+ $expected,
+ $result
+ );
+
+ }
+
+ function testOther1() {
+
+ // This body was exactly sent to us from the sabredav mailing list. Checking if this parses correctly.
+
+ $body = <<<BLA
+<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:"
+xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data/>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20090101T000000Z" end="20121202T000000Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>
+BLA;
+
+ $dom = DAV\XMLUtil::loadDOMDocument($body);
+
+ $q = new CalendarQueryParser($dom);
+ $q->parse();
+
+ $this->assertEquals(array(
+ '{urn:ietf:params:xml:ns:caldav}calendar-data',
+ '{DAV:}getetag',
+ ), $q->requestedProperties);
+
+ $expectedFilters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'time-range' => array(
+ 'start' => new \DateTime('2009-01-01 00:00:00', new \DateTimeZone('UTC')),
+ 'end' => new \DateTime('2012-12-02 00:00:00', new \DateTimeZone('UTC')),
+ ),
+ 'is-not-defined' => false,
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'time-range' => null,
+ 'is-not-defined' => false,
+ );
+
+ $this->assertEquals($expectedFilters, $q->filters);
+
+ }
+
+ function testExpand() {
+
+ $xml = array(
+ '<d:prop>',
+ ' <c:calendar-data>',
+ ' <c:expand start="20110101T000000Z" end="20120101T000000Z"/>',
+ ' </c:calendar-data>',
+ '</d:prop>',
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR" />',
+ '</c:filter>'
+ );
+
+ $xml =
+'<?xml version="1.0"?>
+<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
+' . implode("\n", $xml) . '
+</c:calendar-query>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+ $q = new CalendarQueryParser($dom);
+ $q->parse();
+
+
+ $expected = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => false
+ );
+
+ $this->assertEquals(
+ $expected,
+ $q->filters
+ );
+
+ $this->assertEquals(array(
+ '{urn:ietf:params:xml:ns:caldav}calendar-data',
+ ), $q->requestedProperties);
+
+ $this->assertEquals(
+ array(
+ 'start' => new \DateTime('2011-01-01 00:00:00', new \DateTimeZone('UTC')),
+ 'end' => new \DateTime('2012-01-01 00:00:00', new \DateTimeZone('UTC')),
+ ),
+ $q->expand
+ );
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testExpandNoStart() {
+
+ $xml = array(
+ '<d:prop>',
+ ' <c:calendar-data>',
+ ' <c:expand end="20120101T000000Z"/>',
+ ' </c:calendar-data>',
+ '</d:prop>',
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR" />',
+ '</c:filter>'
+ );
+
+ $xml =
+'<?xml version="1.0"?>
+<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
+' . implode("\n", $xml) . '
+</c:calendar-query>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+ $q = new CalendarQueryParser($dom);
+ $q->parse();
+
+ }
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testExpandNoEnd() {
+
+ $xml = array(
+ '<d:prop>',
+ ' <c:calendar-data>',
+ ' <c:expand start="20120101T000000Z"/>',
+ ' </c:calendar-data>',
+ '</d:prop>',
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR" />',
+ '</c:filter>'
+ );
+
+ $xml =
+'<?xml version="1.0"?>
+<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
+' . implode("\n", $xml) . '
+</c:calendar-query>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+ $q = new CalendarQueryParser($dom);
+ $q->parse();
+
+ }
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testExpandBadTimes() {
+
+ $xml = array(
+ '<d:prop>',
+ ' <c:calendar-data>',
+ ' <c:expand start="20120101T000000Z" end="19980101T000000Z"/>',
+ ' </c:calendar-data>',
+ '</d:prop>',
+ '<c:filter>',
+ ' <c:comp-filter name="VCALENDAR" />',
+ '</c:filter>'
+ );
+
+ $xml =
+'<?xml version="1.0"?>
+<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
+' . implode("\n", $xml) . '
+</c:calendar-query>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+ $q = new CalendarQueryParser($dom);
+ $q->parse();
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php
new file mode 100644
index 000000000..9de24d3aa
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\VObject;
+
+class CalendarQueryVAlarmTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * This test is specifically for a time-range query on a VALARM, contained
+ * in a VEVENT that's recurring
+ */
+ function testValarm() {
+
+ $vcalendar = new VObject\Component\VCalendar();
+
+ $vevent = $vcalendar->createComponent('VEVENT');
+ $vevent->RRULE = 'FREQ=MONTHLY';
+ $vevent->DTSTART = '20120101T120000Z';
+ $vevent->UID = 'bla';
+
+ $valarm = $vcalendar->createComponent('VALARM');
+ $valarm->TRIGGER = '-P15D';
+ $vevent->add($valarm);
+
+
+ $vcalendar->add($vevent);
+
+ $filter = array(
+ 'name' => 'VCALENDAR',
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ 'prop-filters' => array(),
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ 'prop-filters' => array(),
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VALARM',
+ 'is-not-defined' => false,
+ 'prop-filters' => array(),
+ 'comp-filters' => array(),
+ 'time-range' => array(
+ 'start' => new \DateTime('2012-05-10'),
+ 'end' => new \DateTime('2012-05-20'),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $validator = new CalendarQueryValidator();
+ $this->assertTrue($validator->validate($vcalendar, $filter));
+
+ $vcalendar = new VObject\Component\VCalendar();
+
+ // A limited recurrence rule, should return false
+ $vevent = $vcalendar->createComponent('VEVENT');
+ $vevent->RRULE = 'FREQ=MONTHLY;COUNT=1';
+ $vevent->DTSTART = '20120101T120000Z';
+ $vevent->UID = 'bla';
+
+ $valarm = $vcalendar->createComponent('VALARM');
+ $valarm->TRIGGER = '-P15D';
+ $vevent->add($valarm);
+
+ $vcalendar->add($vevent);
+
+ $this->assertFalse($validator->validate($vcalendar, $filter));
+ }
+
+ function testAlarmWayBefore() {
+
+ $vcalendar = new VObject\Component\VCalendar();
+
+ $vevent = $vcalendar->createComponent('VEVENT');
+ $vevent->DTSTART = '20120101T120000Z';
+ $vevent->UID = 'bla';
+
+ $valarm = $vcalendar->createComponent('VALARM');
+ $valarm->TRIGGER = '-P2W1D';
+ $vevent->add($valarm);
+
+ $vcalendar->add($vevent);
+
+ $filter = array(
+ 'name' => 'VCALENDAR',
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ 'prop-filters' => array(),
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ 'prop-filters' => array(),
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VALARM',
+ 'is-not-defined' => false,
+ 'prop-filters' => array(),
+ 'comp-filters' => array(),
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-12-10'),
+ 'end' => new \DateTime('2011-12-20'),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $validator = new CalendarQueryValidator();
+ $this->assertTrue($validator->validate($vcalendar, $filter));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php
new file mode 100644
index 000000000..deb70d205
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php
@@ -0,0 +1,804 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\VObject;
+use Sabre\DAV;
+
+class CalendarQueryValidatorTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @dataProvider provider
+ */
+ function testValid($icalObject, $filters, $outcome) {
+
+ $validator = new CalendarQueryValidator();
+
+ // Wrapping filter in a VCALENDAR component filter, as this is always
+ // there anyway.
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array($filters),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $vObject = VObject\Reader::read($icalObject);
+
+ switch($outcome) {
+ case 0 :
+ $this->assertFalse($validator->validate($vObject, $filters));
+ break;
+ case 1 :
+ $this->assertTrue($validator->validate($vObject, $filters));
+ break;
+ case -1 :
+ try {
+ $validator->validate($vObject, $filters);
+ } catch (DAV\Exception $e) {
+ // Success
+ } catch (\LogicException $e) {
+ // Success
+ }
+ break;
+
+ }
+
+ }
+
+ function provider() {
+
+ $blob1 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+SUMMARY:hi
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob2 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+SUMMARY:hi
+BEGIN:VALARM
+ACTION:DISPLAY
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob3 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+SUMMARY:hi
+DTSTART;VALUE=DATE:20110704
+END:VEVENT
+END:VCALENDAR
+yow;
+ $blob4 = <<<yow
+BEGIN:VCARD
+VERSION:3.0
+FN:Evert
+END:VCARD
+yow;
+
+ $blob5 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DTEND:20110102T120000Z
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob6 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DURATION:PT5H
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob7 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20110101
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob8 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob9 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+DTSTART:20110101T120000Z
+DURATION:PT1H
+END:VTODO
+END:VCALENDAR
+yow;
+ $blob10 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+DTSTART:20110101T120000Z
+DUE:20110101T130000Z
+END:VTODO
+END:VCALENDAR
+yow;
+ $blob11 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+DTSTART:20110101T120000Z
+END:VTODO
+END:VCALENDAR
+yow;
+
+ $blob12 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+DUE:20110101T130000Z
+END:VTODO
+END:VCALENDAR
+yow;
+
+ $blob13 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+COMPLETED:20110101T130000Z
+CREATED:20110101T110000Z
+END:VTODO
+END:VCALENDAR
+yow;
+
+ $blob14 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+COMPLETED:20110101T130000Z
+END:VTODO
+END:VCALENDAR
+yow;
+
+ $blob15 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+CREATED:20110101T110000Z
+END:VTODO
+END:VCALENDAR
+yow;
+
+
+ $blob16 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+END:VTODO
+END:VCALENDAR
+yow;
+
+ $blob17 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VJOURNAL
+END:VJOURNAL
+END:VCALENDAR
+yow;
+
+ $blob18 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VJOURNAL
+DTSTART:20110101T120000Z
+END:VJOURNAL
+END:VCALENDAR
+yow;
+
+ $blob19 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VJOURNAL
+DTSTART;VALUE=DATE:20110101
+END:VJOURNAL
+END:VCALENDAR
+yow;
+
+ $blob20 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VFREEBUSY
+END:VFREEBUSY
+END:VCALENDAR
+yow;
+
+ $blob21 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+BEGIN:VALARM
+TRIGGER:-PT1H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob22 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION:-PT1H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob23 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION;RELATED=END:-PT1H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob24 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DTEND:20110101T130000Z
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION;RELATED=END:-PT2H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob25 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DURATION:PT1H
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION;RELATED=END:-PT2H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob26 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DURATION:PT1H
+BEGIN:VALARM
+TRIGGER;VALUE=DATE-TIME:20110101T110000Z
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+
+ $blob27 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VTODO
+DTSTART:20110101T120000Z
+DUE:20110101T130000Z
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION;RELATED=END:-PT2H
+END:VALARM
+END:VTODO
+END:VCALENDAR
+yow;
+
+ $blob28 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VJOURNAL
+DTSTART:20110101T120000Z
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION;RELATED=END:-PT2H
+END:VALARM
+END:VJOURNAL
+END:VCALENDAR
+yow;
+
+ $blob29 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DURATION:PT1H
+BEGIN:VALARM
+TRIGGER;VALUE=DATE-TIME:20110101T090000Z
+REPEAT:2
+DURATION:PT1H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob30 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DURATION:PT1H
+BEGIN:VALARM
+TRIGGER;VALUE=DATE-TIME:20110101T090000Z
+DURATION:PT1H
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob31 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20080101T120000Z
+DURATION:PT1H
+RRULE:FREQ=YEARLY
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $blob32 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20080102T120000Z
+DURATION:PT1H
+RRULE:FREQ=YEARLY
+END:VEVENT
+END:VCALENDAR
+yow;
+ $blob33 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20120628
+RRULE:FREQ=DAILY
+END:VEVENT
+END:VCALENDAR
+yow;
+ $blob34 = <<<yow
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20120628
+RRULE:FREQ=DAILY
+BEGIN:VALARM
+TRIGGER:P52W
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+yow;
+
+ $filter1 = array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+ $filter2 = $filter1;
+ $filter2['name'] = 'VTODO';
+
+ $filter3 = $filter1;
+ $filter3['is-not-defined'] = true;
+
+ $filter4 = $filter1;
+ $filter4['name'] = 'VTODO';
+ $filter4['is-not-defined'] = true;
+
+ $filter5 = $filter1;
+ $filter5['comp-filters'] = array(
+ array(
+ 'name' => 'VALARM',
+ 'is-not-defined' => false,
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'time-range' => null,
+ ),
+ );
+ $filter6 = $filter1;
+ $filter6['prop-filters'] = array(
+ array(
+ 'name' => 'SUMMARY',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'time-range' => null,
+ 'text-match' => null,
+ ),
+ );
+ $filter7 = $filter6;
+ $filter7['prop-filters'][0]['name'] = 'DESCRIPTION';
+
+ $filter8 = $filter6;
+ $filter8['prop-filters'][0]['is-not-defined'] = true;
+
+ $filter9 = $filter7;
+ $filter9['prop-filters'][0]['is-not-defined'] = true;
+
+ $filter10 = $filter5;
+ $filter10['prop-filters'] = $filter6['prop-filters'];
+
+ // Param filters
+ $filter11 = $filter1;
+ $filter11['prop-filters'] = array(
+ array(
+ 'name' => 'DTSTART',
+ 'is-not-defined' => false,
+ 'param-filters' => array(
+ array(
+ 'name' => 'VALUE',
+ 'is-not-defined' => false,
+ 'text-match' => null,
+ ),
+ ),
+ 'time-range' => null,
+ 'text-match' => null,
+ ),
+ );
+
+ $filter12 = $filter11;
+ $filter12['prop-filters'][0]['param-filters'][0]['name'] = 'TZID';
+
+ $filter13 = $filter11;
+ $filter13['prop-filters'][0]['param-filters'][0]['is-not-defined'] = true;
+
+ $filter14 = $filter12;
+ $filter14['prop-filters'][0]['param-filters'][0]['is-not-defined'] = true;
+
+ // Param text filter
+ $filter15 = $filter11;
+ $filter15['prop-filters'][0]['param-filters'][0]['text-match'] = array(
+ 'collation' => 'i;ascii-casemap',
+ 'value' => 'dAtE',
+ 'negate-condition' => false,
+ );
+ $filter16 = $filter15;
+ $filter16['prop-filters'][0]['param-filters'][0]['text-match']['collation'] = 'i;octet';
+
+ $filter17 = $filter15;
+ $filter17['prop-filters'][0]['param-filters'][0]['text-match']['negate-condition'] = true;
+
+ $filter18 = $filter15;
+ $filter18['prop-filters'][0]['param-filters'][0]['text-match']['negate-condition'] = true;
+ $filter18['prop-filters'][0]['param-filters'][0]['text-match']['collation'] = 'i;octet';
+
+ // prop + text
+ $filter19 = $filter5;
+ $filter19['comp-filters'][0]['prop-filters'] = array(
+ array(
+ 'name' => 'action',
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ 'param-filters' => array(),
+ 'text-match' => array(
+ 'collation' => 'i;ascii-casemap',
+ 'value' => 'display',
+ 'negate-condition' => false,
+ ),
+ ),
+ );
+
+ // Time range
+ $filter20 = array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
+ ),
+ );
+ // Time range, no end date
+ $filter21 = $filter20;
+ $filter21['time-range']['end'] = null;
+
+ // Time range, no start date
+ $filter22 = $filter20;
+ $filter22['time-range']['start'] = null;
+
+ // Time range, other dates
+ $filter23 = $filter20;
+ $filter23['time-range'] = array(
+ 'start' => new \DateTime('2011-02-01 10:00:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-02-01 13:00:00', new \DateTimeZone('GMT')),
+ );
+ // Time range
+ $filter24 = array(
+ 'name' => 'VTODO',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
+ ),
+ );
+ // Time range, other dates (1 month in the future)
+ $filter25 = $filter24;
+ $filter25['time-range'] = array(
+ 'start' => new \DateTime('2011-02-01 10:00:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-02-01 13:00:00', new \DateTimeZone('GMT')),
+ );
+ $filter26 = $filter24;
+ $filter26['time-range'] = array(
+ 'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
+ );
+
+ // Time range for VJOURNAL
+ $filter27 = array(
+ 'name' => 'VJOURNAL',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
+ ),
+ );
+ $filter28 = $filter27;
+ $filter28['time-range'] = array(
+ 'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
+ );
+ // Time range for VFREEBUSY
+ $filter29 = array(
+ 'name' => 'VFREEBUSY',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
+ ),
+ );
+ // Time range filter on property
+ $filter30 = array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(
+ array(
+ 'name' => 'DTSTART',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
+ ),
+ 'text-match' => null,
+ ),
+ ),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ // Time range for alarm
+ $filter31 = array(
+ 'name' => 'VEVENT',
+ 'prop-filters' => array(),
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VALARM',
+ 'is-not-defined' => false,
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 10:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 11:15:00', new \DateTimeZone('GMT')),
+ ),
+ 'text-match' => null,
+ ),
+ ),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+ $filter32 = $filter31;
+ $filter32['comp-filters'][0]['time-range'] = array(
+ 'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
+ );
+
+ $filter33 = $filter31;
+ $filter33['name'] = 'VTODO';
+ $filter34 = $filter32;
+ $filter34['name'] = 'VTODO';
+ $filter35 = $filter31;
+ $filter35['name'] = 'VJOURNAL';
+ $filter36 = $filter32;
+ $filter36['name'] = 'VJOURNAL';
+
+ // Time range filter on non-datetime property
+ $filter37 = array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(
+ array(
+ 'name' => 'SUMMARY',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')),
+ 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
+ ),
+ 'text-match' => null,
+ ),
+ ),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ $filter38 = array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2012-07-01 00:00:00', new \DateTimeZone('UTC')),
+ 'end' => new \DateTime('2012-08-01 00:00:00', new \DateTimeZone('UTC')),
+ )
+ );
+ $filter39 = array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VALARM',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2012-09-01 00:00:00', new \DateTimeZone('UTC')),
+ 'end' => new \DateTime('2012-10-01 00:00:00', new \DateTimeZone('UTC')),
+ )
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+
+ return array(
+
+ // Component check
+
+ array($blob1, $filter1, 1),
+ array($blob1, $filter2, 0),
+ array($blob1, $filter3, 0),
+ array($blob1, $filter4, 1),
+
+ // Subcomponent check
+ array($blob1, $filter5, 0),
+ array($blob2, $filter5, 1),
+
+ // Property check
+ array($blob1, $filter6, 1),
+ array($blob1, $filter7, 0),
+ array($blob1, $filter8, 0),
+ array($blob1, $filter9, 1),
+
+ // Subcomponent + property
+ array($blob2, $filter10, 1),
+
+ // Param filter
+ array($blob3, $filter11, 1),
+ array($blob3, $filter12, 0),
+ array($blob3, $filter13, 0),
+ array($blob3, $filter14, 1),
+
+ // Param + text
+ array($blob3, $filter15, 1),
+ array($blob3, $filter16, 0),
+ array($blob3, $filter17, 0),
+ array($blob3, $filter18, 1),
+
+ // Prop + text
+ array($blob2, $filter19, 1),
+
+ // Incorrect object (vcard)
+ array($blob4, $filter1, -1),
+
+ // Time-range for event
+ array($blob5, $filter20, 1),
+ array($blob6, $filter20, 1),
+ array($blob7, $filter20, 1),
+ array($blob8, $filter20, 1),
+
+ array($blob5, $filter21, 1),
+ array($blob5, $filter22, 1),
+
+ array($blob5, $filter23, 0),
+ array($blob6, $filter23, 0),
+ array($blob7, $filter23, 0),
+ array($blob8, $filter23, 0),
+
+ // Time-range for todo
+ array($blob9, $filter24, 1),
+ array($blob9, $filter25, 0),
+ array($blob9, $filter26, 1),
+ array($blob10, $filter24, 1),
+ array($blob10, $filter25, 0),
+ array($blob10, $filter26, 1),
+
+ array($blob11, $filter24, 0),
+ array($blob11, $filter25, 0),
+ array($blob11, $filter26, 1),
+
+ array($blob12, $filter24, 1),
+ array($blob12, $filter25, 0),
+ array($blob12, $filter26, 0),
+
+ array($blob13, $filter24, 1),
+ array($blob13, $filter25, 0),
+ array($blob13, $filter26, 1),
+
+ array($blob14, $filter24, 1),
+ array($blob14, $filter25, 0),
+ array($blob14, $filter26, 0),
+
+ array($blob15, $filter24, 1),
+ array($blob15, $filter25, 1),
+ array($blob15, $filter26, 1),
+
+ array($blob16, $filter24, 1),
+ array($blob16, $filter25, 1),
+ array($blob16, $filter26, 1),
+
+ // Time-range for journals
+ array($blob17, $filter27, 0),
+ array($blob17, $filter28, 0),
+ array($blob18, $filter27, 0),
+ array($blob18, $filter28, 1),
+ array($blob19, $filter27, 1),
+ array($blob19, $filter28, 1),
+
+ // Time-range for free-busy
+ array($blob20, $filter29, -1),
+
+ // Time-range on property
+ array($blob5, $filter30, 1),
+ array($blob3, $filter37, -1),
+ array($blob3, $filter30, 0),
+
+ // Time-range on alarm in vevent
+ array($blob21, $filter31, 1),
+ array($blob21, $filter32, 0),
+ array($blob22, $filter31, 1),
+ array($blob22, $filter32, 0),
+ array($blob23, $filter31, 1),
+ array($blob23, $filter32, 0),
+ array($blob24, $filter31, 1),
+ array($blob24, $filter32, 0),
+ array($blob25, $filter31, 1),
+ array($blob25, $filter32, 0),
+ array($blob26, $filter31, 1),
+ array($blob26, $filter32, 0),
+
+ // Time-range on alarm for vtodo
+ array($blob27, $filter33, 1),
+ array($blob27, $filter34, 0),
+
+ // Time-range on alarm for vjournal
+ array($blob28, $filter35, -1),
+ array($blob28, $filter36, -1),
+
+ // Time-range on alarm with duration
+ array($blob29, $filter31, 1),
+ array($blob29, $filter32, 0),
+ array($blob30, $filter31, 0),
+ array($blob30, $filter32, 0),
+
+ // Time-range with RRULE
+ array($blob31, $filter20, 1),
+ array($blob32, $filter20, 0),
+
+ // Bug reported on mailing list, related to all-day events.
+ array($blob33, $filter38, 1),
+
+ // Event in timerange, but filtered alarm is in the far future.
+ array($blob34, $filter39, 0),
+ );
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php
new file mode 100644
index 000000000..2b2690d42
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php
@@ -0,0 +1,255 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\DAVACL;
+
+require_once 'Sabre/CalDAV/TestUtil.php';
+
+class CalendarTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\CalDAV\Backend_PDO
+ */
+ protected $backend;
+ protected $principalBackend;
+ /**
+ * @var Sabre\CalDAV\Calendar
+ */
+ protected $calendar;
+ /**
+ * @var array
+ */
+ protected $calendars;
+
+ function setup() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+
+ $this->backend = TestUtil::getBackend();
+
+ $this->calendars = $this->backend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(2, count($this->calendars));
+ $this->calendar = new Calendar($this->backend, $this->calendars[0]);
+
+
+ }
+
+ function teardown() {
+
+ unset($this->backend);
+
+ }
+
+ function testSimple() {
+
+ $this->assertEquals($this->calendars[0]['uri'], $this->calendar->getName());
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testUpdateProperties() {
+
+ $result = $this->calendar->updateProperties(array(
+ '{DAV:}displayname' => 'NewName',
+ ));
+
+ $this->assertEquals(true, $result);
+
+ $calendars2 = $this->backend->getCalendarsForUser('principals/user1');
+ $this->assertEquals('NewName',$calendars2[0]['{DAV:}displayname']);
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testGetProperties() {
+
+ $question = array(
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-data',
+ '{urn:ietf:params:xml:ns:caldav}supported-collation-set',
+ '{DAV:}owner',
+ );
+
+ $result = $this->calendar->getProperties($question);
+
+ foreach($question as $q) $this->assertArrayHasKey($q,$result);
+
+ $this->assertEquals(array('VEVENT','VTODO'), $result['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']->getValue());
+
+ $this->assertTrue($result['{urn:ietf:params:xml:ns:caldav}supported-collation-set'] instanceof Property\SupportedCollationSet);
+
+ $this->assertTrue($result['{DAV:}owner'] instanceof DAVACL\Property\Principal);
+ $this->assertEquals('principals/user1', $result['{DAV:}owner']->getHref());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotFound
+ * @depends testSimple
+ */
+ function testGetChildNotFound() {
+
+ $this->calendar->getChild('randomname');
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testGetChildren() {
+
+ $children = $this->calendar->getChildren();
+ $this->assertEquals(1,count($children));
+
+ $this->assertTrue($children[0] instanceof CalendarObject);
+
+ }
+
+ /**
+ * @depends testGetChildren
+ */
+ function testChildExists() {
+
+ $this->assertFalse($this->calendar->childExists('foo'));
+
+ $children = $this->calendar->getChildren();
+ $this->assertTrue($this->calendar->childExists($children[0]->getName()));
+ }
+
+
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testCreateDirectory() {
+
+ $this->calendar->createDirectory('hello');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetName() {
+
+ $this->calendar->setName('hello');
+
+ }
+
+ function testGetLastModified() {
+
+ $this->assertNull($this->calendar->getLastModified());
+
+ }
+
+ function testCreateFile() {
+
+ $file = fopen('php://memory','r+');
+ fwrite($file,TestUtil::getTestCalendarData());
+ rewind($file);
+
+ $this->calendar->createFile('hello',$file);
+
+ $file = $this->calendar->getChild('hello');
+ $this->assertTrue($file instanceof CalendarObject);
+
+ }
+
+ function testCreateFileNoSupportedComponents() {
+
+ $file = fopen('php://memory','r+');
+ fwrite($file,TestUtil::getTestCalendarData());
+ rewind($file);
+
+ $calendar = new Calendar($this->backend, $this->calendars[1]);
+ $calendar->createFile('hello',$file);
+
+ $file = $calendar->getChild('hello');
+ $this->assertTrue($file instanceof CalendarObject);
+
+ }
+
+ function testDelete() {
+
+ $this->calendar->delete();
+
+ $calendars = $this->backend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(1, count($calendars));
+ }
+
+ function testGetOwner() {
+
+ $this->assertEquals('principals/user1',$this->calendar->getOwner());
+
+ }
+
+ function testGetGroup() {
+
+ $this->assertNull($this->calendar->getGroup());
+
+ }
+
+ function testGetACL() {
+
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1/calendar-proxy-read',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
+ 'principal' => '{DAV:}authenticated',
+ 'protected' => true,
+ ),
+ );
+ $this->assertEquals($expected, $this->calendar->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetACL() {
+
+ $this->calendar->setACL(array());
+
+ }
+
+ function testGetSupportedPrivilegesSet() {
+
+ $result = $this->calendar->getSupportedPrivilegeSet();
+
+ $this->assertEquals(
+ '{' . Plugin::NS_CALDAV . '}read-free-busy',
+ $result['aggregates'][0]['aggregates'][2]['privilege']
+ );
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php
new file mode 100644
index 000000000..511288480
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php
@@ -0,0 +1,110 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittests is created to find out why recurring events have wrong DTSTART value
+ *
+ *
+ * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class ExpandEventsDTSTARTandDTENDTest extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:foobar
+DTEND;TZID=Europe/Berlin:20120207T191500
+RRULE:FREQ=DAILY;INTERVAL=1;COUNT=3
+SUMMARY:RecurringEvents 3 times
+DTSTART;TZID=Europe/Berlin:20120207T181500
+END:VEVENT
+BEGIN:VEVENT
+CREATED:20120207T111900Z
+UID:foobar
+DTEND;TZID=Europe/Berlin:20120208T191500
+SUMMARY:RecurringEvents 3 times OVERWRITTEN
+DTSTART;TZID=Europe/Berlin:20120208T181500
+RECURRENCE-ID;TZID=Europe/Berlin:20120208T181500
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testExpand() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120205T230000Z" end="20120212T225959Z"/>
+ </C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20120205T230000Z" end="20120212T225959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ // Everts super awesome xml parser.
+ $body = substr(
+ $response->body,
+ $start = strpos($response->body, 'BEGIN:VCALENDAR'),
+ strpos($response->body, 'END:VCALENDAR') - $start + 13
+ );
+ $body = str_replace('&#13;','',$body);
+
+ $vObject = VObject\Reader::read($body);
+
+ // check if DTSTARTs and DTENDs are correct
+ foreach ($vObject->VEVENT as $vevent) {
+ /** @var $vevent Sabre\VObject\Component\VEvent */
+ foreach ($vevent->children as $child) {
+ /** @var $child Sabre\VObject\Property */
+
+ if ($child->name == 'DTSTART') {
+ // DTSTART has to be one of three valid values
+ $this->assertContains($child->getValue(), array('20120207T171500Z', '20120208T171500Z', '20120209T171500Z'), 'DTSTART is not a valid value: '.$child->getValue());
+ } elseif ($child->name == 'DTEND') {
+ // DTEND has to be one of three valid values
+ $this->assertContains($child->getValue(), array('20120207T181500Z', '20120208T181500Z', '20120209T181500Z'), 'DTEND is not a valid value: '.$child->getValue());
+ }
+ }
+ }
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php
new file mode 100644
index 000000000..d5e9ff5ab
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittests is created to find out why recurring events have wrong DTSTART value
+ *
+ * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class ExpandEventsDTSTARTandDTENDbyDayTest extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:foobar
+DTEND;TZID=Europe/Berlin:20120207T191500
+RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,TH
+SUMMARY:RecurringEvents on tuesday and thursday
+DTSTART;TZID=Europe/Berlin:20120207T181500
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testExpandRecurringByDayEvent() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120210T230000Z" end="20120217T225959Z"/>
+ </C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20120210T230000Z" end="20120217T225959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ // Everts super awesome xml parser.
+ $body = substr(
+ $response->body,
+ $start = strpos($response->body, 'BEGIN:VCALENDAR'),
+ strpos($response->body, 'END:VCALENDAR') - $start + 13
+ );
+ $body = str_replace('&#13;','',$body);
+
+ $vObject = VObject\Reader::read($body);
+
+ $this->assertEquals(2, count($vObject->VEVENT));
+
+ // check if DTSTARTs and DTENDs are correct
+ foreach ($vObject->VEVENT as $vevent) {
+ /** @var $vevent Sabre\VObject\Component\VEvent */
+ foreach ($vevent->children as $child) {
+ /** @var $child Sabre\VObject\Property */
+
+ if ($child->name == 'DTSTART') {
+ // DTSTART has to be one of two valid values
+ $this->assertContains($child->getValue(), array('20120214T171500Z', '20120216T171500Z'), 'DTSTART is not a valid value: '.$child->getValue());
+ } elseif ($child->name == 'DTEND') {
+ // DTEND has to be one of two valid values
+ $this->assertContains($child->getValue(), array('20120214T181500Z', '20120216T181500Z'), 'DTEND is not a valid value: '.$child->getValue());
+ }
+ }
+ }
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php
new file mode 100644
index 000000000..e5a13f77b
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php
@@ -0,0 +1,104 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittests is created to find out why certain events show up twice.
+ *
+ * Hopefully, by the time I'm done with this, I've both found the problem, and
+ * fixed it :)
+ *
+ * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class ExpandEventsDoubleEventsTest extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:foobar
+DTEND;TZID=Europe/Berlin:20120207T191500
+RRULE:FREQ=DAILY;INTERVAL=1;COUNT=3
+SUMMARY:RecurringEvents 3 times
+DTSTART;TZID=Europe/Berlin:20120207T181500
+END:VEVENT
+BEGIN:VEVENT
+CREATED:20120207T111900Z
+UID:foobar
+DTEND;TZID=Europe/Berlin:20120208T191500
+SUMMARY:RecurringEvents 3 times OVERWRITTEN
+DTSTART;TZID=Europe/Berlin:20120208T181500
+RECURRENCE-ID;TZID=Europe/Berlin:20120208T181500
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testExpand() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120205T230000Z" end="20120212T225959Z"/>
+ </C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20120205T230000Z" end="20120212T225959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ // Everts super awesome xml parser.
+ $body = substr(
+ $response->body,
+ $start = strpos($response->body, 'BEGIN:VCALENDAR'),
+ strpos($response->body, 'END:VCALENDAR') - $start + 13
+ );
+ $body = str_replace('&#13;','',$body);
+
+ $vObject = VObject\Reader::read($body);
+
+ // We only expect 3 events
+ $this->assertEquals(3, count($vObject->VEVENT),'We got 6 events instead of 3. Output: ' . $body);
+
+ // TZID should be gone
+ $this->assertFalse(isset($vObject->VEVENT->DTSTART['TZID']));
+
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php
new file mode 100644
index 000000000..93eca9ee9
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php
@@ -0,0 +1,159 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAV;
+use Sabre\DAVACL;
+use Sabre\HTTP;
+
+require_once 'Sabre/CalDAV/Backend/Mock.php';
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class FreeBusyReportTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\CalDAV\Plugin
+ */
+ protected $plugin;
+ /**
+ * @var Sabre\DAV\Server
+ */
+ protected $server;
+
+ function setUp() {
+
+ $obj1 = <<<ics
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20111005T120000Z
+DURATION:PT1H
+END:VEVENT
+END:VCALENDAR
+ics;
+ $obj2 = fopen('php://memory','r+');
+ fwrite($obj2,<<<ics
+BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20121005T120000Z
+DURATION:PT1H
+END:VEVENT
+END:VCALENDAR
+ics
+ );
+ rewind($obj2);
+
+ $calendarData = array(
+ 1 => array(
+ 'obj1' => array(
+ 'calendarid' => 1,
+ 'uri' => 'event1.ics',
+ 'calendardata' => $obj1,
+ ),
+ 'obj2' => array(
+ 'calendarid' => 1,
+ 'uri' => 'event2.ics',
+ 'calendardata' => $obj2
+ )
+ ),
+ );
+
+
+ $caldavBackend = new Backend\Mock(array(), $calendarData);
+
+ $calendar = new Calendar($caldavBackend, array(
+ 'id' => 1,
+ 'uri' => 'calendar',
+ 'principaluri' => 'principals/user1',
+ ));
+
+ $this->server = new DAV\Server(array($calendar));
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_URI' => '/calendar',
+ ));
+ $this->server->httpRequest = $request;
+ $this->server->httpResponse = new HTTP\ResponseMock();
+
+ $this->plugin = new Plugin();
+ $this->server->addPlugin($this->plugin);
+ $this->server->addPlugin(new DAVACL\Plugin());
+
+ }
+
+ function testFreeBusyReport() {
+
+ $reportXML = <<<XML
+<?xml version="1.0"?>
+<c:free-busy-query xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <c:time-range start="20111001T000000Z" end="20111101T000000Z" />
+</c:free-busy-query>
+XML;
+
+ $dom = DAV\XMLUtil::loadDOMDocument($reportXML);
+ $this->plugin->report('{urn:ietf:params:xml:ns:caldav}free-busy-query', $dom);
+
+ $this->assertEquals('HTTP/1.1 200 OK', $this->server->httpResponse->status);
+ $this->assertEquals('text/calendar', $this->server->httpResponse->headers['Content-Type']);
+ $this->assertTrue(strpos($this->server->httpResponse->body,'BEGIN:VFREEBUSY')!==false);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testFreeBusyReportNoTimeRange() {
+
+ $reportXML = <<<XML
+<?xml version="1.0"?>
+<c:free-busy-query xmlns:c="urn:ietf:params:xml:ns:caldav">
+</c:free-busy-query>
+XML;
+
+ $dom = DAV\XMLUtil::loadDOMDocument($reportXML);
+ $this->plugin->report('{urn:ietf:params:xml:ns:caldav}free-busy-query', $dom);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotImplemented
+ */
+ function testFreeBusyReportWrongNode() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_URI' => '/',
+ ));
+ $this->server->httpRequest = $request;
+
+ $reportXML = <<<XML
+<?xml version="1.0"?>
+<c:free-busy-query xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <c:time-range start="20111001T000000Z" end="20111101T000000Z" />
+</c:free-busy-query>
+XML;
+
+ $dom = DAV\XMLUtil::loadDOMDocument($reportXML);
+ $this->plugin->report('{urn:ietf:params:xml:ns:caldav}free-busy-query', $dom);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ */
+ function testFreeBusyReportNoACLPlugin() {
+
+ $this->server = new DAV\Server();
+ $this->plugin = new Plugin();
+ $this->server->addPlugin($this->plugin);
+
+ $reportXML = <<<XML
+<?xml version="1.0"?>
+<c:free-busy-query xmlns:c="urn:ietf:params:xml:ns:caldav">
+ <c:time-range start="20111001T000000Z" end="20111101T000000Z" />
+</c:free-busy-query>
+XML;
+
+ $dom = DAV\XMLUtil::loadDOMDocument($reportXML);
+ $this->plugin->report('{urn:ietf:params:xml:ns:caldav}free-busy-query', $dom);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyRequestTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyRequestTest.php
new file mode 100644
index 000000000..62252e6a1
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyRequestTest.php
@@ -0,0 +1,282 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAV;
+use Sabre\DAVACL;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class FreeBusyRequestTest extends \PHPUnit_Framework_TestCase {
+
+ protected $plugin;
+ protected $server;
+ protected $aclPlugin;
+ protected $request;
+ protected $authPlugin;
+
+ function setUp() {
+
+ $calendars = array(
+ array(
+ 'principaluri' => 'principals/user2',
+ 'id' => 1,
+ 'uri' => 'calendar1',
+ ),
+ );
+ $calendarobjects = array(
+ 1 => array( '1.ics' => array(
+ 'uri' => '1.ics',
+ 'calendardata' => 'BEGIN:VCALENDAR
+BEGIN:VEVENT
+DTSTART:20110101T130000
+DURATION:PT1H
+END:VEVENT
+END:VCALENDAR',
+ 'calendarid' => 1,
+ ))
+
+ );
+
+ $principalBackend = new DAVACL\PrincipalBackend\Mock();
+ $caldavBackend = new Backend\Mock($calendars, $calendarobjects);
+
+ $tree = array(
+ new DAVACL\PrincipalCollection($principalBackend),
+ new CalendarRootNode($principalBackend, $caldavBackend),
+ );
+
+ $this->request = new HTTP\Request(array(
+ 'CONTENT_TYPE' => 'text/calendar',
+ ));
+ $this->response = new HTTP\ResponseMock();
+
+ $this->server = new DAV\Server($tree);
+ $this->server->httpRequest = $this->request;
+ $this->server->httpResponse = $this->response;
+
+ $this->aclPlugin = new DAVACL\Plugin();
+ $this->server->addPlugin($this->aclPlugin);
+
+ $authBackend = new DAV\Auth\Backend\Mock();
+ $authBackend->setCurrentUser('user1');
+ $this->authPlugin = new DAV\Auth\Plugin($authBackend,'SabreDAV');
+ $this->server->addPlugin($this->authPlugin);
+
+ $this->plugin = new Plugin();
+ $this->server->addPlugin($this->plugin);
+
+ }
+
+ function testWrongMethod() {
+
+ $this->assertNull(
+ $this->plugin->unknownMethod('PUT','calendars/user1/outbox')
+ );
+
+ }
+
+ function testWrongContentType() {
+
+ $this->server->httpRequest = new HTTP\Request(array(
+ 'CONTENT_TYPE' => 'text/plain',
+ ));
+
+ $this->assertNull(
+ $this->plugin->unknownMethod('POST','calendars/user1/outbox')
+ );
+
+ }
+
+ function testNotFound() {
+
+ $this->assertNull(
+ $this->plugin->unknownMethod('POST','calendars/user1/blabla')
+ );
+
+ }
+
+ function testNotOutbox() {
+
+ $this->assertNull(
+ $this->plugin->unknownMethod('POST','calendars/user1/inbox')
+ );
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testNoItipMethod() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+BEGIN:VFREEBUSY
+END:VFREEBUSY
+END:VCALENDAR
+ICS;
+
+ $this->request->setBody($body);
+ $this->plugin->unknownMethod('POST','calendars/user1/outbox');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testNoVFreeBusy() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+METHOD:REQUEST
+BEGIN:VEVENT
+END:VEVENT
+END:VCALENDAR
+ICS;
+
+ $this->request->setBody($body);
+ $this->plugin->unknownMethod('POST','calendars/user1/outbox');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ function testIncorrectOrganizer() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+METHOD:REQUEST
+BEGIN:VFREEBUSY
+ORGANIZER:mailto:john@wayne.org
+END:VFREEBUSY
+END:VCALENDAR
+ICS;
+
+ $this->request->setBody($body);
+ $this->plugin->unknownMethod('POST','calendars/user1/outbox');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testNoAttendees() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+METHOD:REQUEST
+BEGIN:VFREEBUSY
+ORGANIZER:mailto:user1.sabredav@sabredav.org
+END:VFREEBUSY
+END:VCALENDAR
+ICS;
+
+ $this->request->setBody($body);
+ $this->plugin->unknownMethod('POST','calendars/user1/outbox');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testNoDTStart() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+METHOD:REQUEST
+BEGIN:VFREEBUSY
+ORGANIZER:mailto:user1.sabredav@sabredav.org
+ATTENDEE:mailto:user2.sabredav@sabredav.org
+END:VFREEBUSY
+END:VCALENDAR
+ICS;
+
+ $this->request->setBody($body);
+ $this->plugin->unknownMethod('POST','calendars/user1/outbox');
+
+ }
+
+ function testSucceed() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+METHOD:REQUEST
+BEGIN:VFREEBUSY
+ORGANIZER:mailto:user1.sabredav@sabredav.org
+ATTENDEE:mailto:user2.sabredav@sabredav.org
+ATTENDEE:mailto:user3.sabredav@sabredav.org
+DTSTART:20110101T080000Z
+DTEND:20110101T180000Z
+END:VFREEBUSY
+END:VCALENDAR
+ICS;
+
+ // Lazily making the current principal an admin.
+ $this->aclPlugin->adminPrincipals[] = 'principals/user1';
+
+ $this->request->setBody($body);
+ $this->assertFalse($this->plugin->unknownMethod('POST','calendars/user1/outbox'));
+
+ $this->assertEquals('HTTP/1.1 200 OK' , $this->response->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ ), $this->response->headers);
+
+ $strings = array(
+ '<d:href>mailto:user2.sabredav@sabredav.org</d:href>',
+ '<d:href>mailto:user3.sabredav@sabredav.org</d:href>',
+ '<cal:request-status>2.0;Success</cal:request-status>',
+ '<cal:request-status>3.7;Could not find principal</cal:request-status>',
+ 'FREEBUSY;FBTYPE=BUSY:20110101T130000Z/20110101T140000Z',
+ );
+
+ foreach($strings as $string) {
+ $this->assertTrue(
+ strpos($this->response->body, $string)!==false,
+ 'The response body did not contain: ' . $string .'Full response: ' . $this->response->body
+ );
+ }
+
+
+ }
+
+ function testNoPrivilege() {
+
+ $body = <<<ICS
+BEGIN:VCALENDAR
+METHOD:REQUEST
+BEGIN:VFREEBUSY
+ORGANIZER:mailto:user1.sabredav@sabredav.org
+ATTENDEE:mailto:user2.sabredav@sabredav.org
+DTSTART:20110101T080000Z
+DTEND:20110101T180000Z
+END:VFREEBUSY
+END:VCALENDAR
+ICS;
+
+ $this->request->setBody($body);
+ $this->assertFalse($this->plugin->unknownMethod('POST','calendars/user1/outbox'));
+
+ $this->assertEquals('HTTP/1.1 200 OK' , $this->response->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ ), $this->response->headers);
+
+ $strings = array(
+ '<d:href>mailto:user2.sabredav@sabredav.org</d:href>',
+ '<cal:request-status>3.7;No calendar-home-set property found</cal:request-status>',
+ );
+
+ foreach($strings as $string) {
+ $this->assertTrue(
+ strpos($this->response->body, $string)!==false,
+ 'The response body did not contain: ' . $string .'Full response: ' . $this->response->body
+ );
+ }
+
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php
new file mode 100644
index 000000000..e473cdeb1
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittest is created to check if queries for time-range include the start timestamp or not
+ *
+ * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class GetEventsByTimerangeTest extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+CREATED:20120313T142342Z
+UID:171EBEFC-C951-499D-B234-7BA7D677B45D
+DTEND;TZID=Europe/Berlin:20120227T000000
+TRANSP:OPAQUE
+SUMMARY:Monday 0h
+DTSTART;TZID=Europe/Berlin:20120227T000000
+DTSTAMP:20120313T142416Z
+SEQUENCE:4
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testQueryTimerange() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120226T230000Z" end="20120228T225959Z"/>
+ </C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20120226T230000Z" end="20120228T225959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ if (strpos($response->body, 'BEGIN:VCALENDAR') === false) {
+ $this->fail('Got no events instead of 1. Output: '.$response->body);
+ }
+
+ // Everts super awesome xml parser.
+ $body = substr(
+ $response->body,
+ $start = strpos($response->body, 'BEGIN:VCALENDAR'),
+ strpos($response->body, 'END:VCALENDAR') - $start + 13
+ );
+ $body = str_replace('&#13;','',$body);
+
+ $vObject = VObject\Reader::read($body);
+
+ // We expect 1 event
+ $this->assertEquals(1, count($vObject->VEVENT), 'We got 0 events instead of 1. Output: ' . $body);
+
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php
new file mode 100644
index 000000000..be21796dd
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php
@@ -0,0 +1,227 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+use Sabre\DAVACL;
+
+require_once 'Sabre/CalDAV/TestUtil.php';
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class ICSExportPluginTest extends \PHPUnit_Framework_TestCase {
+
+ function testInit() {
+
+ $p = new ICSExportPlugin();
+ $s = new DAV\Server();
+ $s->addPlugin($p);
+
+ }
+
+ function testBeforeMethod() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $cbackend = TestUtil::getBackend();
+
+ $props = array(
+ 'uri'=>'UUID-123467',
+ 'principaluri' => 'admin',
+ 'id' => 1,
+ );
+ $tree = array(
+ new Calendar($cbackend,$props),
+ );
+
+ $p = new ICSExportPlugin();
+
+ $s = new DAV\Server($tree);
+ $s->addPlugin($p);
+ $s->addPlugin(new Plugin());
+
+ $h = new HTTP\Request(array(
+ 'QUERY_STRING' => 'export',
+ ));
+
+ $s->httpRequest = $h;
+ $s->httpResponse = new HTTP\ResponseMock();
+
+ $this->assertFalse($p->beforeMethod('GET','UUID-123467?export'));
+
+ $this->assertEquals('HTTP/1.1 200 OK',$s->httpResponse->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'text/calendar',
+ ), $s->httpResponse->headers);
+
+ $obj = VObject\Reader::read($s->httpResponse->body);
+
+ $this->assertEquals(5,count($obj->children()));
+ $this->assertEquals(1,count($obj->VERSION));
+ $this->assertEquals(1,count($obj->CALSCALE));
+ $this->assertEquals(1,count($obj->PRODID));
+ $this->assertTrue(strpos((string)$obj->PRODID, DAV\Version::VERSION)!==false);
+ $this->assertEquals(1,count($obj->VTIMEZONE));
+ $this->assertEquals(1,count($obj->VEVENT));
+
+ }
+ function testBeforeMethodNoVersion() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $cbackend = TestUtil::getBackend();
+
+ $props = array(
+ 'uri'=>'UUID-123467',
+ 'principaluri' => 'admin',
+ 'id' => 1,
+ );
+ $tree = array(
+ new Calendar($cbackend,$props),
+ );
+
+ $p = new ICSExportPlugin();
+
+ $s = new DAV\Server($tree);
+
+ $s->addPlugin($p);
+ $s->addPlugin(new Plugin());
+
+ $h = new HTTP\Request(array(
+ 'QUERY_STRING' => 'export',
+ ));
+
+ $s->httpRequest = $h;
+ $s->httpResponse = new HTTP\ResponseMock();
+
+ DAV\Server::$exposeVersion = false;
+ $this->assertFalse($p->beforeMethod('GET','UUID-123467?export'));
+ DAV\Server::$exposeVersion = true;
+
+ $this->assertEquals('HTTP/1.1 200 OK',$s->httpResponse->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'text/calendar',
+ ), $s->httpResponse->headers);
+
+ $obj = VObject\Reader::read($s->httpResponse->body);
+
+ $this->assertEquals(5,count($obj->children()));
+ $this->assertEquals(1,count($obj->VERSION));
+ $this->assertEquals(1,count($obj->CALSCALE));
+ $this->assertEquals(1,count($obj->PRODID));
+ $this->assertFalse(strpos((string)$obj->PRODID, DAV\Version::VERSION)!==false);
+ $this->assertEquals(1,count($obj->VTIMEZONE));
+ $this->assertEquals(1,count($obj->VEVENT));
+
+ }
+
+ function testBeforeMethodNoGET() {
+
+ $p = new ICSExportPlugin();
+
+ $s = new DAV\Server();
+ $s->addPlugin($p);
+
+ $this->assertNull($p->beforeMethod('POST','UUID-123467?export'));
+
+ }
+
+ function testBeforeMethodNoExport() {
+
+ $p = new ICSExportPlugin();
+
+ $s = new DAV\Server();
+ $s->addPlugin($p);
+
+ $this->assertNull($p->beforeMethod('GET','UUID-123467'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testACLIntegrationBlocked() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $cbackend = TestUtil::getBackend();
+
+ $props = array(
+ 'uri'=>'UUID-123467',
+ 'principaluri' => 'admin',
+ 'id' => 1,
+ );
+ $tree = array(
+ new Calendar($cbackend,$props),
+ );
+
+ $p = new ICSExportPlugin();
+
+ $s = new DAV\Server($tree);
+ $s->addPlugin($p);
+ $s->addPlugin(new Plugin());
+ $s->addPlugin(new DAVACL\Plugin());
+
+ $h = new HTTP\Request(array(
+ 'QUERY_STRING' => 'export',
+ ));
+
+ $s->httpRequest = $h;
+ $s->httpResponse = new HTTP\ResponseMock();
+
+ $p->beforeMethod('GET','UUID-123467?export');
+
+ }
+
+ function testACLIntegrationNotBlocked() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $cbackend = TestUtil::getBackend();
+ $pbackend = new DAVACL\PrincipalBackend\Mock();
+
+ $props = array(
+ 'uri'=>'UUID-123467',
+ 'principaluri' => 'admin',
+ 'id' => 1,
+ );
+ $tree = array(
+ new Calendar($cbackend,$props),
+ new DAVACL\PrincipalCollection($pbackend),
+ );
+
+ $p = new ICSExportPlugin();
+
+ $s = new DAV\Server($tree);
+ $s->addPlugin($p);
+ $s->addPlugin(new Plugin());
+ $s->addPlugin(new DAVACL\Plugin());
+ $s->addPlugin(new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'SabreDAV'));
+
+ // Forcing login
+ $s->getPlugin('acl')->adminPrincipals = array('principals/admin');
+
+ $h = new HTTP\Request(array(
+ 'QUERY_STRING' => 'export',
+ 'REQUEST_URI' => '/UUID-123467',
+ 'REQUEST_METHOD' => 'GET',
+ ));
+
+ $s->httpRequest = $h;
+ $s->httpResponse = new HTTP\ResponseMock();
+
+ $s->exec();
+
+ $this->assertEquals('HTTP/1.1 200 OK',$s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
+ $this->assertEquals(array(
+ 'Content-Type' => 'text/calendar',
+ ), $s->httpResponse->headers);
+
+ $obj = VObject\Reader::read($s->httpResponse->body);
+
+ $this->assertEquals(5,count($obj->children()));
+ $this->assertEquals(1,count($obj->VERSION));
+ $this->assertEquals(1,count($obj->CALSCALE));
+ $this->assertEquals(1,count($obj->PRODID));
+ $this->assertEquals(1,count($obj->VTIMEZONE));
+ $this->assertEquals(1,count($obj->VEVENT));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php
new file mode 100644
index 000000000..f925224f2
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\VObject;
+use Sabre\DAV;
+
+class Issue166Test extends \PHPUnit_Framework_TestCase {
+
+ function testFlaw() {
+
+ $input = <<<HI
+BEGIN:VCALENDAR
+PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+TZID:Asia/Pyongyang
+X-LIC-LOCATION:Asia/Pyongyang
+BEGIN:STANDARD
+TZOFFSETFROM:+0900
+TZOFFSETTO:+0900
+TZNAME:KST
+DTSTART:19700101T000000
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20111118T010857Z
+LAST-MODIFIED:20111118T010937Z
+DTSTAMP:20111118T010937Z
+UID:a03245b3-9947-9a48-a088-863c74e0fdd8
+SUMMARY:New Event
+RRULE:FREQ=YEARLY
+DTSTART;TZID=Asia/Pyongyang:19960102T111500
+DTEND;TZID=Asia/Pyongyang:19960102T121500
+END:VEVENT
+END:VCALENDAR
+HI;
+
+ $validator = new CalendarQueryValidator();
+
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2011-12-01'),
+ 'end' => new \DateTime('2012-02-01'),
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ );
+ $input = VObject\Reader::read($input);
+ $this->assertTrue($validator->validate($input,$filters));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php
new file mode 100644
index 000000000..ce6d364f6
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\VObject;
+use Sabre\DAV;
+
+class Issue172Test extends \PHPUnit_Framework_TestCase {
+
+ // DateTimeZone() native name: America/Los_Angeles (GMT-8 in January)
+ function testBuiltInTimezoneName() {
+ $input = <<<HI
+BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+DTSTART;TZID=America/Los_Angeles:20120118T204500
+DTEND;TZID=America/Los_Angeles:20120118T214500
+END:VEVENT
+END:VCALENDAR
+HI;
+ $validator = new CalendarQueryValidator();
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2012-01-18 21:00:00 GMT-08:00'),
+ 'end' => new \DateTime('2012-01-18 21:00:00 GMT-08:00'),
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ );
+ $input = VObject\Reader::read($input);
+ $this->assertTrue($validator->validate($input,$filters));
+ }
+
+ // Pacific Standard Time, translates to America/Los_Angeles (GMT-8 in January)
+ function testOutlookTimezoneName() {
+ $input = <<<HI
+BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VTIMEZONE
+TZID:Pacific Standard Time
+BEGIN:STANDARD
+DTSTART:16010101T030000
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0100
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:16010101T020000
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0200
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTART;TZID=Pacific Standard Time:20120113T100000
+DTEND;TZID=Pacific Standard Time:20120113T110000
+END:VEVENT
+END:VCALENDAR
+HI;
+ $validator = new CalendarQueryValidator();
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
+ 'end' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ );
+ $input = VObject\Reader::read($input);
+ $this->assertTrue($validator->validate($input,$filters));
+ }
+
+ // X-LIC-LOCATION, translates to America/Los_Angeles (GMT-8 in January)
+ function testLibICalLocationName() {
+ $input = <<<HI
+BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VTIMEZONE
+TZID:My own timezone name
+X-LIC-LOCATION:America/Los_Angeles
+BEGIN:STANDARD
+DTSTART:16010101T030000
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0100
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:16010101T020000
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0200
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTART;TZID=My own timezone name:20120113T100000
+DTEND;TZID=My own timezone name:20120113T110000
+END:VEVENT
+END:VCALENDAR
+HI;
+ $validator = new CalendarQueryValidator();
+ $filters = array(
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => array(
+ array(
+ 'name' => 'VEVENT',
+ 'comp-filters' => array(),
+ 'prop-filters' => array(),
+ 'is-not-defined' => false,
+ 'time-range' => array(
+ 'start' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
+ 'end' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
+ ),
+ ),
+ ),
+ 'prop-filters' => array(),
+ );
+ $input = VObject\Reader::read($input);
+ $this->assertTrue($validator->validate($input,$filters));
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue203Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue203Test.php
new file mode 100644
index 000000000..a27e3a9e5
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue203Test.php
@@ -0,0 +1,139 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittest is created to find out why an overwritten DAILY event has wrong DTSTART, DTEND, SUMMARY and RECURRENCEID
+ *
+ *
+ * @copyright Copyright (C) 2007-2014 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Issue203Test extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:20120330T155305CEST-6585fBUVgV
+DTSTAMP:20120330T135305Z
+DTSTART;TZID=Europe/Berlin:20120326T155200
+DTEND;TZID=Europe/Berlin:20120326T165200
+RRULE:FREQ=DAILY;COUNT=2;INTERVAL=1
+SUMMARY:original summary
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+UID:20120330T155305CEST-6585fBUVgV
+DTSTAMP:20120330T135352Z
+DESCRIPTION:
+DTSTART;TZID=Europe/Berlin:20120328T155200
+DTEND;TZID=Europe/Berlin:20120328T165200
+RECURRENCE-ID;TZID=Europe/Berlin:20120327T155200
+SEQUENCE:1
+SUMMARY:overwritten summary
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testIssue203() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120325T220000Z" end="20120401T215959Z"/>
+ </C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20120325T220000Z" end="20120401T215959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ // Everts super awesome xml parser.
+ $body = substr(
+ $response->body,
+ $start = strpos($response->body, 'BEGIN:VCALENDAR'),
+ strpos($response->body, 'END:VCALENDAR') - $start + 13
+ );
+ $body = str_replace('&#13;','',$body);
+
+ $vObject = VObject\Reader::read($body);
+
+ $this->assertEquals(2, count($vObject->VEVENT));
+
+
+ $expectedEvents = array(
+ array(
+ 'DTSTART' => '20120326T135200Z',
+ 'DTEND' => '20120326T145200Z',
+ 'SUMMARY' => 'original summary',
+ ),
+ array(
+ 'DTSTART' => '20120328T135200Z',
+ 'DTEND' => '20120328T145200Z',
+ 'SUMMARY' => 'overwritten summary',
+ 'RECURRENCE-ID' => '20120327T135200Z',
+ )
+ );
+
+ // try to match agains $expectedEvents array
+ foreach ($expectedEvents as $expectedEvent) {
+
+ $matching = false;
+
+ foreach ($vObject->VEVENT as $vevent) {
+ /** @var $vevent Sabre\VObject\Component\VEvent */
+
+ foreach ($vevent->children as $child) {
+ /** @var $child Sabre\VObject\Property */
+
+ if (isset($expectedEvent[$child->name])) {
+ if ($expectedEvent[$child->name] != $child->getValue()) {
+ continue 2;
+ }
+ }
+ }
+
+ $matching = true;
+ break;
+ }
+
+ $this->assertTrue($matching, 'Did not find the following event in the response: '.var_export($expectedEvent, true));
+ }
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php
new file mode 100644
index 000000000..d9998ef44
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittest is created to check if a VALARM TRIGGER of PT0S is supported
+ *
+ * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Issue205Test extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:20120330T155305CEST-6585fBUVgV
+DTSTAMP:20120330T135305Z
+DTSTART;TZID=Europe/Berlin:20120326T155200
+DTEND;TZID=Europe/Berlin:20120326T165200
+SUMMARY:original summary
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:AUDIO
+ATTACH;VALUE=URI:Basso
+TRIGGER:PT0S
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testIssue205() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120325T220000Z" end="20120401T215959Z"/>
+ </C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:comp-filter name="VALARM">
+ <C:time-range start="20120325T220000Z" end="20120401T215959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ $this->assertFalse(strpos($response->body, '<s:exception>Exception</s:exception>'), 'Exception occurred: ' . $response->body);
+ $this->assertFalse(strpos($response->body, 'Unknown or bad format'), 'DateTime unknown format Exception: ' . $response->body);
+
+ // Everts super awesome xml parser.
+ $body = substr(
+ $response->body,
+ $start = strpos($response->body, 'BEGIN:VCALENDAR'),
+ strpos($response->body, 'END:VCALENDAR') - $start + 13
+ );
+ $body = str_replace('&#13;','',$body);
+
+ $vObject = VObject\Reader::read($body);
+
+ $this->assertEquals(1, count($vObject->VEVENT));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php
new file mode 100644
index 000000000..d149a3984
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+
+/**
+ * This unittest is created to check for an endless loop in Sabre\CalDAV\CalendarQueryValidator
+ *
+ * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Issue211Test extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:20120418T172519CEST-3510gh1hVw
+DTSTAMP:20120418T152519Z
+DTSTART;VALUE=DATE:20120330
+DTEND;VALUE=DATE:20120531
+EXDATE;TZID=Europe/Berlin:20120330T000000
+RRULE:FREQ=YEARLY;INTERVAL=1
+SEQUENCE:1
+SUMMARY:Birthday
+TRANSP:TRANSPARENT
+BEGIN:VALARM
+ACTION:EMAIL
+ATTENDEE:MAILTO:xxx@domain.de
+DESCRIPTION:Dies ist eine Kalender Erinnerung
+SUMMARY:Kalender Alarm Erinnerung
+TRIGGER;VALUE=DATE-TIME:20120329T060000Z
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testIssue211() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data/>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:comp-filter name="VALARM">
+ <C:time-range start="20120426T220000Z" end="20120427T215959Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ // if this assert is reached, the endless loop is gone
+ // There should be no matching events
+ $this->assertFalse(strpos('BEGIN:VEVENT', $response->body));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php
new file mode 100644
index 000000000..e97cbc4a6
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\HTTP;
+
+/**
+ * This unittest is created to check for an endless loop in CalendarQueryValidator
+ *
+ * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Issue220Test extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+DTSTART;TZID=Europe/Berlin:20120601T180000
+SUMMARY:Brot backen
+RRULE:FREQ=DAILY;INTERVAL=1;WKST=MO
+TRANSP:OPAQUE
+DURATION:PT20M
+LAST-MODIFIED:20120601T064634Z
+CREATED:20120601T064634Z
+DTSTAMP:20120601T064634Z
+UID:b64f14c5-dccc-4eda-947f-bdb1f763fbcd
+BEGIN:VALARM
+TRIGGER;VALUE=DURATION:-PT5M
+ACTION:DISPLAY
+DESCRIPTION:Default Event Notification
+X-WR-ALARMUID:cd952c1b-b3d6-41fb-b0a6-ec3a1a5bdd58
+END:VALARM
+END:VEVENT
+BEGIN:VEVENT
+DTSTART;TZID=Europe/Berlin:20120606T180000
+SUMMARY:Brot backen
+TRANSP:OPAQUE
+STATUS:CANCELLED
+DTEND;TZID=Europe/Berlin:20120606T182000
+LAST-MODIFIED:20120605T094310Z
+SEQUENCE:1
+RECURRENCE-ID:20120606T160000Z
+UID:b64f14c5-dccc-4eda-947f-bdb1f763fbcd
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testIssue220() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data/>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:comp-filter name="VALARM">
+ <C:time-range start="20120607T161646Z" end="20120612T161646Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ $this->assertFalse(strpos($response->body, '<s:exception>PHPUnit_Framework_Error_Warning</s:exception>'), 'Error Warning occurred: ' . $response->body);
+ $this->assertFalse(strpos($response->body, 'Invalid argument supplied for foreach()'), 'Invalid argument supplied for foreach(): ' . $response->body);
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status);
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php
new file mode 100644
index 000000000..9345bdcb2
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php
@@ -0,0 +1,78 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+
+/**
+ * This unittest is created to check if the time-range filter is working correctly with all-day-events
+ *
+ * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Issue228Test extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ protected $caldavCalendars = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Calendar',
+ 'principaluri' => 'principals/user1',
+ 'uri' => 'calendar1',
+ )
+ );
+
+ protected $caldavCalendarObjects = array(
+ 1 => array(
+ 'event.ics' => array(
+ 'calendardata' => 'BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:20120730T113415CEST-6804EGphkd@xxxxxx.de
+DTSTAMP:20120730T093415Z
+DTSTART;VALUE=DATE:20120729
+DTEND;VALUE=DATE:20120730
+SUMMARY:sunday event
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
+',
+ ),
+ ),
+ );
+
+ function testIssue228() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody('<?xml version="1.0" encoding="utf-8" ?>
+<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:prop>
+ <C:calendar-data>
+ <C:expand start="20120730T095609Z"
+ end="20120813T095609Z"/>
+</C:calendar-data>
+ <D:getetag/>
+ </D:prop>
+ <C:filter>
+ <C:comp-filter name="VCALENDAR">
+ <C:comp-filter name="VEVENT">
+ <C:time-range start="20120730T095609Z" end="20120813T095609Z"/>
+ </C:comp-filter>
+ </C:comp-filter>
+ </C:filter>
+</C:calendar-query>');
+
+ $response = $this->request($request);
+
+ // We must check if absolutely nothing was returned from this query.
+ $this->assertFalse(strpos($response->body, 'BEGIN:VCALENDAR'));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php
new file mode 100644
index 000000000..eaed4f503
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php
@@ -0,0 +1,90 @@
+<?php
+
+namespace Sabre\CalDAV\Notifications;
+
+use Sabre\CalDAV;
+
+class CollectionTest extends \PHPUnit_Framework_TestCase {
+
+ protected $caldavBackend;
+ protected $principalUri;
+ protected $notification;
+
+ function getInstance() {
+
+ $this->principalUri = 'principals/user1';
+
+ $this->notification = new Notification\SystemStatus(1,'"1"');
+
+ $this->caldavBackend = new CalDAV\Backend\Mock(array(),array(), array(
+ 'principals/user1' => array(
+ $this->notification
+ )
+ ));
+
+ return new Collection($this->caldavBackend, $this->principalUri);
+
+ }
+
+ function testGetChildren() {
+
+ $col = $this->getInstance();
+ $this->assertEquals('notifications', $col->getName());
+
+ $this->assertEquals(array(
+ new Node($this->caldavBackend, $this->principalUri, $this->notification)
+ ), $col->getChildren());
+
+ }
+
+ function testGetOwner() {
+
+ $col = $this->getInstance();
+ $this->assertEquals('principals/user1', $col->getOwner());
+
+ }
+
+ function testGetGroup() {
+
+ $col = $this->getInstance();
+ $this->assertNull($col->getGroup());
+
+ }
+
+ function testGetACL() {
+
+ $col = $this->getInstance();
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->principalUri,
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => $this->principalUri,
+ 'protected' => true,
+ ),
+ );
+
+ $this->assertEquals($expected, $col->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotImplemented
+ */
+ function testSetACL() {
+
+ $col = $this->getInstance();
+ $col->setACL(array());
+
+ }
+
+ function testGetSupportedPrivilegeSet() {
+
+ $col = $this->getInstance();
+ $this->assertNull($col->getSupportedPrivilegeSet());
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php
new file mode 100644
index 000000000..28e43ce08
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php
@@ -0,0 +1,101 @@
+<?php
+
+namespace Sabre\CalDAV\Notifications;
+
+use Sabre\CalDAV;
+
+class NodeTest extends \PHPUnit_Framework_TestCase {
+
+ protected $systemStatus;
+ protected $caldavBackend;
+
+ function getInstance() {
+
+ $principalUri = 'principals/user1';
+
+ $this->systemStatus = new Notification\SystemStatus(1,'"1"');
+
+ $this->caldavBackend = new CalDAV\Backend\Mock(array(),array(), array(
+ 'principals/user1' => array(
+ $this->systemStatus
+ )
+ ));
+
+ $node = new Node($this->caldavBackend, 'principals/user1', $this->systemStatus);
+ return $node;
+
+ }
+
+ function testGetId() {
+
+ $node = $this->getInstance();
+ $this->assertEquals($this->systemStatus->getId() . '.xml', $node->getName());
+
+ }
+
+ function testGetEtag() {
+
+ $node = $this->getInstance();
+ $this->assertEquals('"1"', $node->getETag());
+
+ }
+
+ function testGetNotificationType() {
+
+ $node = $this->getInstance();
+ $this->assertEquals($this->systemStatus, $node->getNotificationType());
+
+ }
+
+ function testDelete() {
+
+ $node = $this->getInstance();
+ $node->delete();
+ $this->assertEquals(array(), $this->caldavBackend->getNotificationsForPrincipal('principals/user1'));
+
+ }
+
+ function testGetGroup() {
+
+ $node = $this->getInstance();
+ $this->assertNull($node->getGroup());
+
+ }
+
+ function testGetACL() {
+
+ $node = $this->getInstance();
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ );
+
+ $this->assertEquals($expected, $node->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotImplemented
+ */
+ function testSetACL() {
+
+ $node = $this->getInstance();
+ $node->setACL(array());
+
+ }
+
+ function testGetSupportedPrivilegeSet() {
+
+ $node = $this->getInstance();
+ $this->assertNull($node->getSupportedPrivilegeSet());
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteReplyTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteReplyTest.php
new file mode 100644
index 000000000..c53f68cee
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteReplyTest.php
@@ -0,0 +1,134 @@
+<?php
+
+namespace Sabre\CalDAV\Notifications\Notification;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class InviteReplyTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @dataProvider dataProvider
+ */
+ function testSerializers($notification, $expected) {
+
+ $notification = new InviteReply($notification);
+
+ $this->assertEquals('foo', $notification->getId());
+ $this->assertEquals('"1"', $notification->getETag());
+
+ $simpleExpected = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:invite-reply/></cs:root>' . "\n";
+
+ $dom = new \DOMDocument('1.0','UTF-8');
+ $elem = $dom->createElement('cs:root');
+ $elem->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+ $dom->appendChild($elem);
+ $notification->serialize(new DAV\Server(), $elem);
+ $this->assertEquals($simpleExpected, $dom->saveXML());
+
+ $dom = new \DOMDocument('1.0','UTF-8');
+ $dom->formatOutput = true;
+ $elem = $dom->createElement('cs:root');
+ $elem->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+ $elem->setAttribute('xmlns:d','DAV:');
+ $dom->appendChild($elem);
+ $notification->serializeBody(new DAV\Server(), $elem);
+ $this->assertEquals($expected, $dom->saveXML());
+
+
+ }
+
+ function dataProvider() {
+
+ $dtStamp = new \DateTime('2012-01-01 00:00:00 GMT');
+ return array(
+ array(
+ array(
+ 'id' => 'foo',
+ 'dtStamp' => $dtStamp,
+ 'etag' => '"1"',
+ 'inReplyTo' => 'bar',
+ 'href' => 'mailto:foo@example.org',
+ 'type' => CalDAV\SharingPlugin::STATUS_ACCEPTED,
+ 'hostUrl' => 'calendar'
+ ),
+<<<FOO
+<?xml version="1.0" encoding="UTF-8"?>
+<cs:root xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:">
+ <cs:dtstamp>20120101T000000Z</cs:dtstamp>
+ <cs:invite-reply>
+ <cs:uid>foo</cs:uid>
+ <cs:in-reply-to>bar</cs:in-reply-to>
+ <d:href>mailto:foo@example.org</d:href>
+ <cs:invite-accepted/>
+ <cs:hosturl>
+ <d:href>/calendar</d:href>
+ </cs:hosturl>
+ </cs:invite-reply>
+</cs:root>
+
+FOO
+ ),
+ array(
+ array(
+ 'id' => 'foo',
+ 'dtStamp' => $dtStamp,
+ 'etag' => '"1"',
+ 'inReplyTo' => 'bar',
+ 'href' => 'mailto:foo@example.org',
+ 'type' => CalDAV\SharingPlugin::STATUS_DECLINED,
+ 'hostUrl' => 'calendar',
+ 'summary' => 'Summary!'
+ ),
+<<<FOO
+<?xml version="1.0" encoding="UTF-8"?>
+<cs:root xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:">
+ <cs:dtstamp>20120101T000000Z</cs:dtstamp>
+ <cs:invite-reply>
+ <cs:uid>foo</cs:uid>
+ <cs:in-reply-to>bar</cs:in-reply-to>
+ <d:href>mailto:foo@example.org</d:href>
+ <cs:invite-declined/>
+ <cs:hosturl>
+ <d:href>/calendar</d:href>
+ </cs:hosturl>
+ <cs:summary>Summary!</cs:summary>
+ </cs:invite-reply>
+</cs:root>
+
+FOO
+ ),
+
+ );
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testMissingArg() {
+
+ new InviteReply(array());
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testUnknownArg() {
+
+ new InviteReply(array(
+ 'foo-i-will-break' => true,
+
+ 'id' => 1,
+ 'etag' => '"bla"',
+ 'href' => 'abc',
+ 'dtStamp' => 'def',
+ 'inReplyTo' => 'qrs',
+ 'type' => 'ghi',
+ 'hostUrl' => 'jkl',
+ ));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteTest.php
new file mode 100644
index 000000000..d2c114f4c
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/InviteTest.php
@@ -0,0 +1,230 @@
+<?php
+
+namespace Sabre\CalDAV\Notifications\Notification;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class InviteTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @dataProvider dataProvider
+ */
+ function testSerializers($notification, $expected) {
+
+ $notification = new Invite($notification);
+
+ $this->assertEquals('foo', $notification->getId());
+ $this->assertEquals('"1"', $notification->getETag());
+
+ $simpleExpected = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:invite-notification/></cs:root>' . "\n";
+
+ $dom = new \DOMDocument('1.0','UTF-8');
+ $elem = $dom->createElement('cs:root');
+ $elem->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+ $dom->appendChild($elem);
+ $notification->serialize(new DAV\Server(), $elem);
+ $this->assertEquals($simpleExpected, $dom->saveXML());
+
+ $dom = new \DOMDocument('1.0','UTF-8');
+ $dom->formatOutput = true;
+ $elem = $dom->createElement('cs:root');
+ $elem->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+ $elem->setAttribute('xmlns:d','DAV:');
+ $elem->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+ $dom->appendChild($elem);
+ $notification->serializeBody(new DAV\Server(), $elem);
+ $this->assertEquals($expected, $dom->saveXML());
+
+
+ }
+
+ function dataProvider() {
+
+ $dtStamp = new \DateTime('2012-01-01 00:00:00', new \DateTimeZone('GMT'));
+ return array(
+ array(
+ array(
+ 'id' => 'foo',
+ 'dtStamp' => $dtStamp,
+ 'etag' => '"1"',
+ 'href' => 'mailto:foo@example.org',
+ 'type' => CalDAV\SharingPlugin::STATUS_ACCEPTED,
+ 'readOnly' => true,
+ 'hostUrl' => 'calendar',
+ 'organizer' => 'principal/user1',
+ 'commonName' => 'John Doe',
+ 'summary' => 'Awesome stuff!'
+ ),
+<<<FOO
+<?xml version="1.0" encoding="UTF-8"?>
+<cs:root xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:cal="urn:ietf:params:xml:ns:caldav">
+ <cs:dtstamp>20120101T000000Z</cs:dtstamp>
+ <cs:invite-notification>
+ <cs:uid>foo</cs:uid>
+ <d:href>mailto:foo@example.org</d:href>
+ <cs:invite-accepted/>
+ <cs:hosturl>
+ <d:href>/calendar</d:href>
+ </cs:hosturl>
+ <cs:access>
+ <cs:read/>
+ </cs:access>
+ <cs:organizer-cn>John Doe</cs:organizer-cn>
+ <cs:organizer>
+ <d:href>/principal/user1</d:href>
+ <cs:common-name>John Doe</cs:common-name>
+ </cs:organizer>
+ <cs:summary>Awesome stuff!</cs:summary>
+ </cs:invite-notification>
+</cs:root>
+
+FOO
+ ),
+ array(
+ array(
+ 'id' => 'foo',
+ 'dtStamp' => $dtStamp,
+ 'etag' => '"1"',
+ 'href' => 'mailto:foo@example.org',
+ 'type' => CalDAV\SharingPlugin::STATUS_DECLINED,
+ 'readOnly' => true,
+ 'hostUrl' => 'calendar',
+ 'organizer' => 'principal/user1',
+ 'commonName' => 'John Doe',
+ ),
+<<<FOO
+<?xml version="1.0" encoding="UTF-8"?>
+<cs:root xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:cal="urn:ietf:params:xml:ns:caldav">
+ <cs:dtstamp>20120101T000000Z</cs:dtstamp>
+ <cs:invite-notification>
+ <cs:uid>foo</cs:uid>
+ <d:href>mailto:foo@example.org</d:href>
+ <cs:invite-declined/>
+ <cs:hosturl>
+ <d:href>/calendar</d:href>
+ </cs:hosturl>
+ <cs:access>
+ <cs:read/>
+ </cs:access>
+ <cs:organizer-cn>John Doe</cs:organizer-cn>
+ <cs:organizer>
+ <d:href>/principal/user1</d:href>
+ <cs:common-name>John Doe</cs:common-name>
+ </cs:organizer>
+ </cs:invite-notification>
+</cs:root>
+
+FOO
+ ),
+ array(
+ array(
+ 'id' => 'foo',
+ 'dtStamp' => $dtStamp,
+ 'etag' => '"1"',
+ 'href' => 'mailto:foo@example.org',
+ 'type' => CalDAV\SharingPlugin::STATUS_NORESPONSE,
+ 'readOnly' => true,
+ 'hostUrl' => 'calendar',
+ 'organizer' => 'principal/user1',
+ 'firstName' => 'Foo',
+ 'lastName' => 'Bar',
+ ),
+<<<FOO
+<?xml version="1.0" encoding="UTF-8"?>
+<cs:root xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:cal="urn:ietf:params:xml:ns:caldav">
+ <cs:dtstamp>20120101T000000Z</cs:dtstamp>
+ <cs:invite-notification>
+ <cs:uid>foo</cs:uid>
+ <d:href>mailto:foo@example.org</d:href>
+ <cs:invite-noresponse/>
+ <cs:hosturl>
+ <d:href>/calendar</d:href>
+ </cs:hosturl>
+ <cs:access>
+ <cs:read/>
+ </cs:access>
+ <cs:organizer-first>Foo</cs:organizer-first>
+ <cs:organizer-last>Bar</cs:organizer-last>
+ <cs:organizer>
+ <d:href>/principal/user1</d:href>
+ <cs:first-name>Foo</cs:first-name>
+ <cs:last-name>Bar</cs:last-name>
+ </cs:organizer>
+ </cs:invite-notification>
+</cs:root>
+
+FOO
+ ),
+ array(
+ array(
+ 'id' => 'foo',
+ 'dtStamp' => $dtStamp,
+ 'etag' => '"1"',
+ 'href' => 'mailto:foo@example.org',
+ 'type' => CalDAV\SharingPlugin::STATUS_DELETED,
+ 'readOnly' => false,
+ 'hostUrl' => 'calendar',
+ 'organizer' => 'mailto:user1@fruux.com',
+ 'supportedComponents' => new CalDAV\Property\SupportedCalendarComponentSet(array('VEVENT','VTODO')),
+ ),
+<<<FOO
+<?xml version="1.0" encoding="UTF-8"?>
+<cs:root xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:" xmlns:cal="urn:ietf:params:xml:ns:caldav">
+ <cs:dtstamp>20120101T000000Z</cs:dtstamp>
+ <cs:invite-notification>
+ <cs:uid>foo</cs:uid>
+ <d:href>mailto:foo@example.org</d:href>
+ <cs:invite-deleted/>
+ <cs:hosturl>
+ <d:href>/calendar</d:href>
+ </cs:hosturl>
+ <cs:access>
+ <cs:read-write/>
+ </cs:access>
+ <cs:organizer>
+ <d:href>mailto:user1@fruux.com</d:href>
+ </cs:organizer>
+ <cal:supported-calendar-component-set>
+ <cal:comp name="VEVENT"/>
+ <cal:comp name="VTODO"/>
+ </cal:supported-calendar-component-set>
+ </cs:invite-notification>
+</cs:root>
+
+FOO
+ ),
+
+ );
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testMissingArg() {
+
+ new Invite(array());
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testUnknownArg() {
+
+ new Invite(array(
+ 'foo-i-will-break' => true,
+
+ 'id' => 1,
+ 'etag' => '"bla"',
+ 'href' => 'abc',
+ 'dtStamp' => 'def',
+ 'type' => 'ghi',
+ 'readOnly' => true,
+ 'hostUrl' => 'jkl',
+ 'organizer' => 'mno',
+ ));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/SystemStatusTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/SystemStatusTest.php
new file mode 100644
index 000000000..8dc494932
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/Notification/SystemStatusTest.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Sabre\CalDAV\Notifications\Notification;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class SystemStatusTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @dataProvider dataProvider
+ */
+ function testSerializers($notification, $expected1, $expected2) {
+
+ $this->assertEquals('foo', $notification->getId());
+ $this->assertEquals('"1"', $notification->getETag());
+
+
+ $dom = new \DOMDocument('1.0','UTF-8');
+ $elem = $dom->createElement('cs:root');
+ $elem->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+ $dom->appendChild($elem);
+ $notification->serialize(new DAV\Server(), $elem);
+ $this->assertEquals($expected1, $dom->saveXML());
+
+ $dom = new \DOMDocument('1.0','UTF-8');
+ $elem = $dom->createElement('cs:root');
+ $elem->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+ $dom->appendChild($elem);
+ $notification->serializeBody(new DAV\Server(), $elem);
+ $this->assertEquals($expected2, $dom->saveXML());
+
+
+ }
+
+ function dataProvider() {
+
+ return array(
+
+ array(
+ new SystemStatus('foo', '"1"'),
+ '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:systemstatus type="high"/></cs:root>' . "\n",
+ '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:systemstatus type="high"/></cs:root>' . "\n",
+ ),
+
+ array(
+ new SystemStatus('foo', '"1"', SystemStatus::TYPE_MEDIUM,'bar'),
+ '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:systemstatus type="medium"/></cs:root>' . "\n",
+ '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:systemstatus type="medium"><cs:description>bar</cs:description></cs:systemstatus></cs:root>' . "\n",
+ ),
+
+ array(
+ new SystemStatus('foo', '"1"', SystemStatus::TYPE_LOW,null,'http://example.org/'),
+ '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:systemstatus type="low"/></cs:root>' . "\n",
+ '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<cs:root xmlns:cs="http://calendarserver.org/ns/"><cs:systemstatus type="low"><d:href>http://example.org/</d:href></cs:systemstatus></cs:root>' . "\n",
+ )
+ );
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/OutboxPostTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/OutboxPostTest.php
new file mode 100644
index 000000000..5a5a4e75c
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/OutboxPostTest.php
@@ -0,0 +1,545 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\HTTP;
+use Sabre\VObject;
+use Sabre\DAV;
+
+require_once 'Sabre/DAVServerTest.php';
+require_once 'Sabre/CalDAV/Schedule/IMip/Mock.php';
+
+class OutboxPostTest extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+
+ function testPostPassThruNotFound() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/notfound',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $this->assertHTTPStatus(501, $req);
+
+ }
+
+ function testPostPassThruNotTextCalendar() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/admin/outbox',
+ ));
+
+ $this->assertHTTPStatus(501, $req);
+
+ }
+
+ function testPostPassThruNoOutBox() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $this->assertHTTPStatus(501, $req);
+
+ }
+
+ function testNoOriginator() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/admin/outbox',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(400, $req);
+
+ }
+
+ function testNoRecipient() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/admin/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:orig@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(400, $req);
+
+ }
+
+ function testBadOriginator() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/admin/outbox',
+ 'HTTP_ORIGINATOR' => 'nomailto:orig@example.org',
+ 'HTTP_RECIPIENT' => 'mailto:user1@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(403, $req);
+
+ }
+
+ function testBadRecipient() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/admin/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:orig@example.org',
+ 'HTTP_RECIPIENT' => 'http://user1@example.org, mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(400, $req);
+
+ }
+
+ function testIncorrectOriginator() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/admin/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:orig@example.org',
+ 'HTTP_RECIPIENT' => 'mailto:user1@example.org, mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(403, $req);
+
+ }
+
+ function testInvalidIcalBody() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+ $req->setBody('foo');
+
+ $this->assertHTTPStatus(400, $req);
+
+ }
+
+ function testNoVEVENT() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'BEGIN:VTIMEZONE',
+ 'END:VTIMEZONE',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(400, $req);
+
+ }
+
+ function testNoMETHOD() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(400, $req);
+
+ }
+
+ function testUnsupportedMethod() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:PUBLISH',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $this->assertHTTPStatus(501, $req);
+
+ }
+
+ function testNoIMIPHandler() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+
+ $response = $this->request($req);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ ), $response->headers);
+
+ // Lazily checking the body for a few expected values.
+ $this->assertTrue(strpos($response->body, '5.2;')!==false);
+ $this->assertTrue(strpos($response->body,'user2@example.org')!==false);
+
+
+ }
+
+ function testSuccessRequest() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'SUMMARY:An invitation',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $handler = new Schedule\IMip\Mock('server@example.org');
+
+ $this->caldavPlugin->setIMIPhandler($handler);
+
+ $response = $this->request($req);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ ), $response->headers);
+
+ // Lazily checking the body for a few expected values.
+ $this->assertTrue(strpos($response->body, '2.0;')!==false);
+ $this->assertTrue(strpos($response->body,'user2@example.org')!==false);
+
+ $this->assertEquals(array(
+ array(
+ 'to' => 'user2@example.org',
+ 'subject' => 'Invitation for: An invitation',
+ 'body' => implode("\r\n", $body) . "\r\n",
+ 'headers' => array(
+ 'Reply-To: user1.sabredav@sabredav.org',
+ 'From: server@example.org',
+ 'Content-Type: text/calendar; method=REQUEST; charset=utf-8',
+ 'X-Sabre-Version: ' . DAV\Version::VERSION . '-' . DAV\Version::STABILITY,
+ ),
+ )
+ ), $handler->getSentEmails());
+
+ }
+
+ function testSuccessRequestUseRelativePrincipal() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => '/principals/user1/',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'SUMMARY:An invitation',
+ 'ORGANIZER:mailto:user1.sabredav@sabredav.org',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $handler = new Schedule\IMip\Mock('server@example.org');
+
+ $this->caldavPlugin->setIMIPhandler($handler);
+
+ $response = $this->request($req);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status, 'Full body: ' . $response->body);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ ), $response->headers);
+
+ // Lazily checking the body for a few expected values.
+ $this->assertTrue(strpos($response->body, '2.0;')!==false);
+ $this->assertTrue(strpos($response->body,'user2@example.org')!==false);
+
+ $this->assertEquals(array(
+ array(
+ 'to' => 'user2@example.org',
+ 'subject' => 'Invitation for: An invitation',
+ 'body' => implode("\r\n", $body) . "\r\n",
+ 'headers' => array(
+ 'Reply-To: user1.sabredav@sabredav.org',
+ 'From: server@example.org',
+ 'Content-Type: text/calendar; method=REQUEST; charset=utf-8',
+ 'X-Sabre-Version: ' . DAV\Version::VERSION . '-' . DAV\Version::STABILITY,
+ ),
+ )
+ ), $handler->getSentEmails());
+
+ }
+
+ function testSuccessRequestUpperCased() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'MAILTO:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'MAILTO:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'SUMMARY:An invitation',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $handler = new Schedule\IMip\Mock('server@example.org');
+
+ $this->caldavPlugin->setIMIPhandler($handler);
+
+ $response = $this->request($req);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ ), $response->headers);
+
+ // Lazily checking the body for a few expected values.
+ $this->assertTrue(strpos($response->body, '2.0;')!==false);
+ $this->assertTrue(strpos($response->body,'user2@example.org')!==false);
+
+ $this->assertEquals(array(
+ array(
+ 'to' => 'user2@example.org',
+ 'subject' => 'Invitation for: An invitation',
+ 'body' => implode("\r\n", $body) . "\r\n",
+ 'headers' => array(
+ 'Reply-To: user1.sabredav@sabredav.org',
+ 'From: server@example.org',
+ 'Content-Type: text/calendar; method=REQUEST; charset=utf-8',
+ 'X-Sabre-Version: ' . DAV\Version::VERSION . '-' . DAV\Version::STABILITY,
+ ),
+ )
+ ), $handler->getSentEmails());
+
+ }
+
+ function testSuccessReply() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REPLY',
+ 'BEGIN:VEVENT',
+ 'SUMMARY:An invitation',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $handler = new Schedule\IMip\Mock('server@example.org');
+
+ $this->caldavPlugin->setIMIPhandler($handler);
+ $this->assertHTTPStatus(200, $req);
+
+ $this->assertEquals(array(
+ array(
+ 'to' => 'user2@example.org',
+ 'subject' => 'Response for: An invitation',
+ 'body' => implode("\r\n", $body) . "\r\n",
+ 'headers' => array(
+ 'Reply-To: user1.sabredav@sabredav.org',
+ 'From: server@example.org',
+ 'Content-Type: text/calendar; method=REPLY; charset=utf-8',
+ 'X-Sabre-Version: ' . DAV\Version::VERSION . '-' . DAV\Version::STABILITY,
+ ),
+ )
+ ), $handler->getSentEmails());
+
+ }
+
+ function testSuccessCancel() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:CANCEL',
+ 'BEGIN:VEVENT',
+ 'SUMMARY:An invitation',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $handler = new Schedule\IMip\Mock('server@example.org');
+
+ $this->caldavPlugin->setIMIPhandler($handler);
+ $this->assertHTTPStatus(200, $req);
+
+ $this->assertEquals(array(
+ array(
+ 'to' => 'user2@example.org',
+ 'subject' => 'Cancelled event: An invitation',
+ 'body' => implode("\r\n", $body) . "\r\n",
+ 'headers' => array(
+ 'Reply-To: user1.sabredav@sabredav.org',
+ 'From: server@example.org',
+ 'Content-Type: text/calendar; method=CANCEL; charset=utf-8',
+ 'X-Sabre-Version: ' . DAV\Version::VERSION . '-' . DAV\Version::STABILITY,
+ ),
+ )
+ ), $handler->getSentEmails());
+
+
+ }
+
+ function testUseRelativePrincipalNoFallback() {
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/outbox',
+ 'HTTP_ORIGINATOR' => '/principals/user1/',
+ 'HTTP_RECIPIENT' => 'mailto:user2@example.org',
+ 'HTTP_CONTENT_TYPE' => 'text/calendar',
+ ));
+
+ $body = array(
+ 'BEGIN:VCALENDAR',
+ 'METHOD:REQUEST',
+ 'BEGIN:VEVENT',
+ 'SUMMARY:An invitation',
+ 'ORGANIZER:rrrrrr',
+ 'END:VEVENT',
+ 'END:VCALENDAR',
+ );
+
+ $req->setBody(implode("\r\n",$body));
+
+ $handler = new Schedule\IMip\Mock('server@example.org');
+
+ $this->caldavPlugin->setIMIPhandler($handler);
+
+ $response = $this->request($req);
+ $this->assertEquals('HTTP/1.1 403 Forbidden', $response->status, 'Full body: ' . $response->body);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php
new file mode 100644
index 000000000..fb7dc316a
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php
@@ -0,0 +1,1126 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\DAVACL;
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+require_once 'Sabre/CalDAV/TestUtil.php';
+
+class PluginTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\DAV\Server
+ */
+ protected $server;
+ /**
+ * @var Sabre\CalDAV\Plugin
+ */
+ protected $plugin;
+ protected $response;
+ /**
+ * @var Sabre\CalDAV\Backend\PDO
+ */
+ protected $caldavBackend;
+
+ function setup() {
+
+ $this->caldavBackend = new Backend\Mock(array(
+ array(
+ 'id' => 1,
+ 'uri' => 'UUID-123467',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'user1 calendar',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar description',
+ '{http://apple.com/ns/ical/}calendar-order' => '1',
+ '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Property\SupportedCalendarComponentSet(array('VEVENT','VTODO')),
+ ),
+ array(
+ 'id' => 2,
+ 'uri' => 'UUID-123468',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'user1 calendar2',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar description',
+ '{http://apple.com/ns/ical/}calendar-order' => '1',
+ '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Property\SupportedCalendarComponentSet(array('VEVENT','VTODO')),
+ )
+ ), array(
+ 1 => array(
+ 'UUID-2345' => array(
+ 'calendardata' => TestUtil::getTestCalendarData(),
+ )
+ )
+ ));
+ $principalBackend = new DAVACL\PrincipalBackend\Mock();
+ $principalBackend->setGroupMemberSet('principals/admin/calendar-proxy-read',array('principals/user1'));
+ $principalBackend->setGroupMemberSet('principals/admin/calendar-proxy-write',array('principals/user1'));
+ $principalBackend->addPrincipal(array(
+ 'uri' => 'principals/admin/calendar-proxy-read',
+ ));
+ $principalBackend->addPrincipal(array(
+ 'uri' => 'principals/admin/calendar-proxy-write',
+ ));
+
+ $calendars = new CalendarRootNode($principalBackend,$this->caldavBackend);
+ $principals = new Principal\Collection($principalBackend);
+
+ $root = new DAV\SimpleCollection('root');
+ $root->addChild($calendars);
+ $root->addChild($principals);
+
+ $objectTree = new DAV\ObjectTree($root);
+ $this->server = new DAV\Server($objectTree);
+ $this->server->debugExceptions = true;
+ $this->server->setBaseUri('/');
+ $this->plugin = new Plugin();
+ $this->server->addPlugin($this->plugin);
+
+ // Adding ACL plugin
+ $this->server->addPlugin(new DAVACL\Plugin());
+
+ // Adding Auth plugin, and ensuring that we are logged in.
+ $authBackend = new DAV\Auth\Backend\Mock();
+ $authBackend->defaultUser = 'user1';
+ $authPlugin = new DAV\Auth\Plugin($authBackend, 'SabreDAV');
+ $this->server->addPlugin($authPlugin);
+
+ $authPlugin->beforeMethod('GET', '/');
+
+ $this->response = new HTTP\ResponseMock();
+ $this->server->httpResponse = $this->response;
+
+ }
+
+ function testSimple() {
+
+ $this->assertEquals(array('MKCALENDAR'), $this->plugin->getHTTPMethods('calendars/user1/randomnewcalendar'));
+ $this->assertEquals(array('calendar-access','calendar-proxy'), $this->plugin->getFeatures());
+ $this->assertArrayHasKey('urn:ietf:params:xml:ns:caldav', $this->server->xmlNamespaces);
+
+ }
+
+ function testUnknownMethodPassThrough() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'MKBREAKFAST',
+ 'REQUEST_URI' => '/',
+ ));
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $this->response->status,'Incorrect status returned. Full response body:' . $this->response->body);
+
+ }
+
+ function testReportPassThrough() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/',
+ ));
+ $request->setBody('<?xml version="1.0"?><s:somereport xmlns:s="http://www.rooftopsolutions.nl/NS/example" />');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden', $this->response->status);
+
+ }
+
+ function testMkCalendarBadLocation() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'MKCALENDAR',
+ 'REQUEST_URI' => '/blabla',
+ ));
+
+ $body = '<?xml version="1.0" encoding="utf-8" ?>
+ <C:mkcalendar xmlns:D="DAV:"
+ xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:set>
+ <D:prop>
+ <D:displayname>Lisa\'s Events</D:displayname>
+ <C:calendar-description xml:lang="en"
+ >Calendar restricted to events.</C:calendar-description>
+ <C:supported-calendar-component-set>
+ <C:comp name="VEVENT"/>
+ </C:supported-calendar-component-set>
+ <C:calendar-timezone><![CDATA[BEGIN:VCALENDAR
+ PRODID:-//Example Corp.//CalDAV Client//EN
+ VERSION:2.0
+ BEGIN:VTIMEZONE
+ TZID:US-Eastern
+ LAST-MODIFIED:19870101T000000Z
+ BEGIN:STANDARD
+ DTSTART:19671029T020000
+ RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+ TZOFFSETFROM:-0400
+ TZOFFSETTO:-0500
+ TZNAME:Eastern Standard Time (US & Canada)
+ END:STANDARD
+ BEGIN:DAYLIGHT
+ DTSTART:19870405T020000
+ RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+ TZOFFSETFROM:-0500
+ TZOFFSETTO:-0400
+ TZNAME:Eastern Daylight Time (US & Canada)
+ END:DAYLIGHT
+ END:VTIMEZONE
+ END:VCALENDAR
+ ]]></C:calendar-timezone>
+ </D:prop>
+ </D:set>
+ </C:mkcalendar>';
+
+ $request->setBody($body);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden', $this->response->status);
+
+ }
+
+ function testMkCalendarNoParentNode() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'MKCALENDAR',
+ 'REQUEST_URI' => '/doesntexist/calendar',
+ ));
+
+ $body = '<?xml version="1.0" encoding="utf-8" ?>
+ <C:mkcalendar xmlns:D="DAV:"
+ xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:set>
+ <D:prop>
+ <D:displayname>Lisa\'s Events</D:displayname>
+ <C:calendar-description xml:lang="en"
+ >Calendar restricted to events.</C:calendar-description>
+ <C:supported-calendar-component-set>
+ <C:comp name="VEVENT"/>
+ </C:supported-calendar-component-set>
+ <C:calendar-timezone><![CDATA[BEGIN:VCALENDAR
+ PRODID:-//Example Corp.//CalDAV Client//EN
+ VERSION:2.0
+ BEGIN:VTIMEZONE
+ TZID:US-Eastern
+ LAST-MODIFIED:19870101T000000Z
+ BEGIN:STANDARD
+ DTSTART:19671029T020000
+ RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+ TZOFFSETFROM:-0400
+ TZOFFSETTO:-0500
+ TZNAME:Eastern Standard Time (US & Canada)
+ END:STANDARD
+ BEGIN:DAYLIGHT
+ DTSTART:19870405T020000
+ RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+ TZOFFSETFROM:-0500
+ TZOFFSETTO:-0400
+ TZNAME:Eastern Daylight Time (US & Canada)
+ END:DAYLIGHT
+ END:VTIMEZONE
+ END:VCALENDAR
+ ]]></C:calendar-timezone>
+ </D:prop>
+ </D:set>
+ </C:mkcalendar>';
+
+ $request->setBody($body);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 409 Conflict', $this->response->status);
+
+ }
+
+ function testMkCalendarExistingCalendar() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'MKCALENDAR',
+ 'REQUEST_URI' => '/calendars/user1/UUID-123467',
+ ));
+
+ $body = '<?xml version="1.0" encoding="utf-8" ?>
+ <C:mkcalendar xmlns:D="DAV:"
+ xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:set>
+ <D:prop>
+ <D:displayname>Lisa\'s Events</D:displayname>
+ <C:calendar-description xml:lang="en"
+ >Calendar restricted to events.</C:calendar-description>
+ <C:supported-calendar-component-set>
+ <C:comp name="VEVENT"/>
+ </C:supported-calendar-component-set>
+ <C:calendar-timezone><![CDATA[BEGIN:VCALENDAR
+ PRODID:-//Example Corp.//CalDAV Client//EN
+ VERSION:2.0
+ BEGIN:VTIMEZONE
+ TZID:US-Eastern
+ LAST-MODIFIED:19870101T000000Z
+ BEGIN:STANDARD
+ DTSTART:19671029T020000
+ RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+ TZOFFSETFROM:-0400
+ TZOFFSETTO:-0500
+ TZNAME:Eastern Standard Time (US & Canada)
+ END:STANDARD
+ BEGIN:DAYLIGHT
+ DTSTART:19870405T020000
+ RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+ TZOFFSETFROM:-0500
+ TZOFFSETTO:-0400
+ TZNAME:Eastern Daylight Time (US & Canada)
+ END:DAYLIGHT
+ END:VTIMEZONE
+ END:VCALENDAR
+ ]]></C:calendar-timezone>
+ </D:prop>
+ </D:set>
+ </C:mkcalendar>';
+
+ $request->setBody($body);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 405 Method Not Allowed', $this->response->status);
+
+ }
+
+ function testMkCalendarSucceed() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'MKCALENDAR',
+ 'REQUEST_URI' => '/calendars/user1/NEWCALENDAR',
+ ));
+
+ $timezone = 'BEGIN:VCALENDAR
+PRODID:-//Example Corp.//CalDAV Client//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+TZID:US-Eastern
+LAST-MODIFIED:19870101T000000Z
+BEGIN:STANDARD
+DTSTART:19671029T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+TZNAME:Eastern Standard Time (US & Canada)
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:19870405T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+TZNAME:Eastern Daylight Time (US & Canada)
+END:DAYLIGHT
+END:VTIMEZONE
+END:VCALENDAR';
+
+ $body = '<?xml version="1.0" encoding="utf-8" ?>
+ <C:mkcalendar xmlns:D="DAV:"
+ xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:set>
+ <D:prop>
+ <D:displayname>Lisa\'s Events</D:displayname>
+ <C:calendar-description xml:lang="en"
+ >Calendar restricted to events.</C:calendar-description>
+ <C:supported-calendar-component-set>
+ <C:comp name="VEVENT"/>
+ </C:supported-calendar-component-set>
+ <C:calendar-timezone><![CDATA[' . $timezone . ']]></C:calendar-timezone>
+ </D:prop>
+ </D:set>
+ </C:mkcalendar>';
+
+ $request->setBody($body);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 201 Created', $this->response->status,'Invalid response code received. Full response body: ' .$this->response->body);
+
+ $calendars = $this->caldavBackend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(3, count($calendars));
+
+ $newCalendar = null;
+ foreach($calendars as $calendar) {
+ if ($calendar['uri'] === 'NEWCALENDAR') {
+ $newCalendar = $calendar;
+ break;
+ }
+ }
+
+ $this->assertInternalType('array',$newCalendar);
+
+ $keys = array(
+ 'uri' => 'NEWCALENDAR',
+ 'id' => null,
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar restricted to events.',
+ '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => $timezone,
+ '{DAV:}displayname' => 'Lisa\'s Events',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => null,
+ );
+
+ foreach($keys as $key=>$value) {
+
+ $this->assertArrayHasKey($key, $newCalendar);
+
+ if (is_null($value)) continue;
+ $this->assertEquals($value, $newCalendar[$key]);
+
+ }
+ $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
+ $this->assertTrue($newCalendar[$sccs] instanceof Property\SupportedCalendarComponentSet);
+ $this->assertEquals(array('VEVENT'),$newCalendar[$sccs]->getValue());
+
+ }
+
+ function testMkCalendarEmptyBodySucceed() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'MKCALENDAR',
+ 'REQUEST_URI' => '/calendars/user1/NEWCALENDAR',
+ ));
+
+ $request->setBody('');
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 201 Created', $this->response->status,'Invalid response code received. Full response body: ' .$this->response->body);
+
+ $calendars = $this->caldavBackend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(3, count($calendars));
+
+ $newCalendar = null;
+ foreach($calendars as $calendar) {
+ if ($calendar['uri'] === 'NEWCALENDAR') {
+ $newCalendar = $calendar;
+ break;
+ }
+ }
+
+ $this->assertInternalType('array',$newCalendar);
+
+ $keys = array(
+ 'uri' => 'NEWCALENDAR',
+ 'id' => null,
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => null,
+ );
+
+ foreach($keys as $key=>$value) {
+
+ $this->assertArrayHasKey($key, $newCalendar);
+
+ if (is_null($value)) continue;
+ $this->assertEquals($value, $newCalendar[$key]);
+
+ }
+ $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
+ $this->assertTrue($newCalendar[$sccs] instanceof Property\SupportedCalendarComponentSet);
+ $this->assertEquals(array('VEVENT','VTODO'),$newCalendar[$sccs]->getValue());
+
+ }
+
+ function testPrincipalProperties() {
+
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_HOST' => 'sabredav.org',
+ ));
+ $this->server->httpRequest = $httpRequest;
+
+ $props = $this->server->getPropertiesForPath('/principals/user1',array(
+ '{urn:ietf:params:xml:ns:caldav}calendar-home-set',
+ '{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL',
+ '{urn:ietf:params:xml:ns:caldav}calendar-user-address-set',
+ '{' . Plugin::NS_CALENDARSERVER . '}calendar-proxy-read-for',
+ '{' . Plugin::NS_CALENDARSERVER . '}calendar-proxy-write-for',
+ '{' . Plugin::NS_CALENDARSERVER . '}notification-URL',
+ ));
+
+ $this->assertArrayHasKey(0,$props);
+ $this->assertArrayHasKey(200,$props[0]);
+
+
+ $this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}calendar-home-set',$props[0][200]);
+ $prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}calendar-home-set'];
+ $this->assertTrue($prop instanceof DAV\Property\Href);
+ $this->assertEquals('calendars/user1/',$prop->getHref());
+
+ $this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL',$props[0][200]);
+ $prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL'];
+ $this->assertTrue($prop instanceof DAV\Property\Href);
+ $this->assertEquals('calendars/user1/outbox',$prop->getHref());
+
+ $this->assertArrayHasKey('{'.Plugin::NS_CALENDARSERVER .'}notification-URL',$props[0][200]);
+ $prop = $props[0][200]['{'.Plugin::NS_CALENDARSERVER .'}notification-URL'];
+ $this->assertTrue($prop instanceof DAV\Property\Href);
+ $this->assertEquals('calendars/user1/notifications/',$prop->getHref());
+
+
+ $this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}calendar-user-address-set',$props[0][200]);
+ $prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}calendar-user-address-set'];
+ $this->assertTrue($prop instanceof DAV\Property\HrefList);
+ $this->assertEquals(array('mailto:user1.sabredav@sabredav.org','/principals/user1/'),$prop->getHrefs());
+
+ $this->assertArrayHasKey('{http://calendarserver.org/ns/}calendar-proxy-read-for', $props[0][200]);
+ $prop = $props[0][200]['{http://calendarserver.org/ns/}calendar-proxy-read-for'];
+ $this->assertInstanceOf('Sabre\\DAV\\Property\\HrefList', $prop);
+ $this->assertEquals(array('principals/admin'), $prop->getHrefs());
+
+ $this->assertArrayHasKey('{http://calendarserver.org/ns/}calendar-proxy-write-for', $props[0][200]);
+ $prop = $props[0][200]['{http://calendarserver.org/ns/}calendar-proxy-write-for'];
+ $this->assertInstanceOf('Sabre\\DAV\\Property\\HrefList', $prop);
+ $this->assertEquals(array('principals/admin'), $prop->getHrefs());
+
+
+ }
+
+ function testSupportedReportSetPropertyNonCalendar() {
+
+ $props = $this->server->getPropertiesForPath('/calendars/user1',array(
+ '{DAV:}supported-report-set',
+ ));
+
+ $this->assertArrayHasKey(0,$props);
+ $this->assertArrayHasKey(200,$props[0]);
+ $this->assertArrayHasKey('{DAV:}supported-report-set',$props[0][200]);
+
+ $prop = $props[0][200]['{DAV:}supported-report-set'];
+
+ $this->assertInstanceOf('\\Sabre\\DAV\\Property\\SupportedReportSet', $prop);
+ $value = array(
+ '{DAV:}expand-property',
+ '{DAV:}principal-property-search',
+ '{DAV:}principal-search-property-set'
+ );
+ $this->assertEquals($value,$prop->getValue());
+
+ }
+
+ /**
+ * @depends testSupportedReportSetPropertyNonCalendar
+ */
+ function testSupportedReportSetProperty() {
+
+ $props = $this->server->getPropertiesForPath('/calendars/user1/UUID-123467',array(
+ '{DAV:}supported-report-set',
+ ));
+
+ $this->assertArrayHasKey(0,$props);
+ $this->assertArrayHasKey(200,$props[0]);
+ $this->assertArrayHasKey('{DAV:}supported-report-set',$props[0][200]);
+
+ $prop = $props[0][200]['{DAV:}supported-report-set'];
+
+ $this->assertTrue($prop instanceof \Sabre\DAV\Property\SupportedReportSet);
+ $value = array(
+ '{urn:ietf:params:xml:ns:caldav}calendar-multiget',
+ '{urn:ietf:params:xml:ns:caldav}calendar-query',
+ '{urn:ietf:params:xml:ns:caldav}free-busy-query',
+ '{DAV:}expand-property',
+ '{DAV:}principal-property-search',
+ '{DAV:}principal-search-property-set'
+ );
+ $this->assertEquals($value,$prop->getValue());
+
+ }
+
+ /**
+ * @depends testSupportedReportSetProperty
+ */
+ function testCalendarMultiGetReport() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data />' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>' .
+ '</c:calendar-multiget>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body);
+
+ $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($this->response->body));
+
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:href',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getetag',
+ '/d:multistatus/d:response/d:propstat/d:prop/c:calendar-data',
+ '/d:multistatus/d:response/d:propstat/d:status' => 'HTTP/1.1 200 OK',
+ );
+
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result));
+
+ if (!is_int($v1)) $this->assertEquals($v2,(string)$result[0]);
+
+ }
+
+ // The response object should have a reference to the Asia/Seoul
+ // timezone.
+ $this->assertTrue(strpos($this->response->body,'Asia/Seoul')!==false);
+
+ }
+
+ /**
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarMultiGetReportExpand() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data>' .
+ ' <c:expand start="20110101T000000Z" end="20111231T235959Z" />' .
+ ' </c:calendar-data>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>' .
+ '</c:calendar-multiget>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body);
+
+ $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($this->response->body));
+
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:href',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getetag',
+ '/d:multistatus/d:response/d:propstat/d:prop/c:calendar-data',
+ '/d:multistatus/d:response/d:propstat/d:status' => 'HTTP/1.1 200 OK',
+ );
+
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result));
+
+ if (!is_int($v1)) $this->assertEquals($v2,(string)$result[0]);
+
+ }
+ // The response object should no longer hold references to timezones.
+ $this->assertTrue(strpos($this->response->body,'Asia/Seoul')===false);
+
+ }
+
+ /**
+ * @depends testSupportedReportSetProperty
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarQueryReport() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data>' .
+ ' <c:expand start="20000101T000000Z" end="20101231T235959Z" />' .
+ ' </c:calendar-data>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<c:filter>' .
+ ' <c:comp-filter name="VCALENDAR">' .
+ ' <c:comp-filter name="VEVENT" />' .
+ ' </c:comp-filter>' .
+ '</c:filter>' .
+ '</c:calendar-query>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1/UUID-123467',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
+
+ $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($this->response->body));
+
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:href',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getetag',
+ '/d:multistatus/d:response/d:propstat/d:prop/c:calendar-data',
+ '/d:multistatus/d:response/d:propstat/d:status' => 'HTTP/1.1 200 OK',
+ );
+
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result), 'We expected 1 ' . $xpath . ' elements. We\'ve found ' . count($result) . '. Full result: ' . $this->response->body);
+
+ if (!is_int($v1)) $this->assertEquals($v2,(string)$result[0]);
+
+ }
+
+ }
+
+ /**
+ * @depends testCalendarQueryReport
+ */
+ function testCalendarQueryReportNoCalData() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<c:filter>' .
+ ' <c:comp-filter name="VCALENDAR">' .
+ ' <c:comp-filter name="VEVENT" />' .
+ ' </c:comp-filter>' .
+ '</c:filter>' .
+ '</c:calendar-query>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1//UUID-123467',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
+
+ $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($this->response->body));
+
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:href',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getetag',
+ '/d:multistatus/d:response/d:propstat/d:status' => 'HTTP/1.1 200 OK',
+ );
+
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result), 'We expected 1 ' . $xpath . ' elements. We\'ve found ' . count($result) . '. Full result: ' . $this->response->body);
+
+ if (!is_int($v1)) $this->assertEquals($v2,(string)$result[0]);
+
+ }
+
+ }
+
+ /**
+ * @depends testCalendarQueryReport
+ */
+ function testCalendarQueryReportNoFilters() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data />' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '</c:calendar-query>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1//UUID-123467',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
+
+ }
+
+ /**
+ * @depends testSupportedReportSetProperty
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarQueryReport1Object() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data>' .
+ ' <c:expand start="20000101T000000Z" end="20101231T235959Z" />' .
+ ' </c:calendar-data>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<c:filter>' .
+ ' <c:comp-filter name="VCALENDAR">' .
+ ' <c:comp-filter name="VEVENT" />' .
+ ' </c:comp-filter>' .
+ '</c:filter>' .
+ '</c:calendar-query>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1/UUID-123467/UUID-2345',
+ 'HTTP_DEPTH' => '0',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
+
+ $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($this->response->body));
+
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:href',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getetag',
+ '/d:multistatus/d:response/d:propstat/d:prop/c:calendar-data',
+ '/d:multistatus/d:response/d:propstat/d:status' => 'HTTP/1.1 200 OK',
+ );
+
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result), 'We expected 1 ' . $xpath . ' elements. We\'ve found ' . count($result) . '. Full result: ' . $this->response->body);
+
+ if (!is_int($v1)) $this->assertEquals($v2,(string)$result[0]);
+
+ }
+
+ }
+
+ /**
+ * @depends testSupportedReportSetProperty
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarQueryReport1ObjectNoCalData() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<c:filter>' .
+ ' <c:comp-filter name="VCALENDAR">' .
+ ' <c:comp-filter name="VEVENT" />' .
+ ' </c:comp-filter>' .
+ '</c:filter>' .
+ '</c:calendar-query>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1/UUID-123467/UUID-2345',
+ 'HTTP_DEPTH' => '0',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
+
+ $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($this->response->body));
+
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:href',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getetag',
+ '/d:multistatus/d:response/d:propstat/d:status' => 'HTTP/1.1 200 OK',
+ );
+
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result), 'We expected 1 ' . $xpath . ' elements. We\'ve found ' . count($result) . '. Full result: ' . $this->response->body);
+
+ if (!is_int($v1)) $this->assertEquals($v2,(string)$result[0]);
+
+ }
+
+ }
+
+ function testHTMLActionsPanel() {
+
+ $output = '';
+ $r = $this->server->broadcastEvent('onHTMLActionsPanel', array($this->server->tree->getNodeForPath('calendars/user1'), &$output));
+ $this->assertFalse($r);
+
+ $this->assertTrue(!!strpos($output,'Display name'));
+
+ }
+
+ function testBrowserPostAction() {
+
+ $r = $this->server->broadcastEvent('onBrowserPostAction', array('calendars/user1', 'mkcalendar', array(
+ 'name' => 'NEWCALENDAR',
+ '{DAV:}displayname' => 'foo',
+ )));
+ $this->assertFalse($r);
+
+ $calendars = $this->caldavBackend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(3, count($calendars));
+
+ $newCalendar = null;
+ foreach($calendars as $calendar) {
+ if ($calendar['uri'] === 'NEWCALENDAR') {
+ $newCalendar = $calendar;
+ break;
+ }
+ }
+ if (!$newCalendar)
+ $this->fail('Could not find newly created calendar');
+
+
+ }
+
+ /**
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarMultiGetReportNoEnd() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data>' .
+ ' <c:expand start="20110101T000000Z" />' .
+ ' </c:calendar-data>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>' .
+ '</c:calendar-multiget>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body);
+
+ }
+
+ /**
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarMultiGetReportNoStart() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data>' .
+ ' <c:expand end="20110101T000000Z" />' .
+ ' </c:calendar-data>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>' .
+ '</c:calendar-multiget>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body);
+
+ }
+
+ /**
+ * @depends testCalendarMultiGetReport
+ */
+ function testCalendarMultiGetReportEndBeforeStart() {
+
+ $body =
+ '<?xml version="1.0"?>' .
+ '<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">' .
+ '<d:prop>' .
+ ' <c:calendar-data>' .
+ ' <c:expand start="20200101T000000Z" end="20110101T000000Z" />' .
+ ' </c:calendar-data>' .
+ ' <d:getetag />' .
+ '</d:prop>' .
+ '<d:href>/calendars/user1/UUID-123467/UUID-2345</d:href>' .
+ '</c:calendar-multiget>';
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'HTTP_DEPTH' => '1',
+ ));
+ $request->setBody($body);
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body);
+
+ }
+
+ function testNotificationProperties() {
+
+ $request = array(
+ '{' . Plugin::NS_CALENDARSERVER . '}notificationtype',
+ );
+ $result = array();
+ $notification = new Notifications\Node(
+ $this->caldavBackend,
+ 'principals/user1',
+ new Notifications\Notification\SystemStatus('foo','"1"')
+ );
+ $this->plugin->beforeGetProperties('foo', $notification, $request, $result);
+
+ $this->assertEquals(
+ array(
+ 200 => array(
+ '{' . Plugin::NS_CALENDARSERVER . '}notificationtype' => $notification->getNotificationType()
+ )
+ ), $result);
+
+ }
+
+ function testNotificationGet() {
+
+ $notification = new Notifications\Node(
+ $this->caldavBackend,
+ 'principals/user1',
+ new Notifications\Notification\SystemStatus('foo','"1"')
+ );
+
+ $server = new DAV\Server(array($notification));
+ $caldav = new Plugin();
+
+ $server->httpRequest = new HTTP\Request(array(
+ 'REQUEST_URI' => '/foo.xml',
+ ));
+ $httpResponse = new HTTP\ResponseMock();
+ $server->httpResponse = $httpResponse;
+
+ $server->addPlugin($caldav);
+
+ $caldav->beforeMethod('GET','foo.xml');
+
+ $this->assertEquals('HTTP/1.1 200 OK', $httpResponse->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml',
+ 'ETag' => '"1"',
+ ), $httpResponse->headers);
+
+ $expected =
+'<?xml version="1.0" encoding="UTF-8"?>
+<cs:notification xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">
+ <cs:systemstatus type="high"/>
+</cs:notification>
+';
+
+ $this->assertEquals($expected, $httpResponse->body);
+
+ }
+
+ function testGETPassthrough() {
+
+ $server = new DAV\Server();
+ $caldav = new Plugin();
+
+ $httpResponse = new HTTP\ResponseMock();
+ $server->httpResponse = $httpResponse;
+
+ $server->addPlugin($caldav);
+
+ $caldav->beforeMethod('GET','foo');
+
+ $this->assertNull($caldav->beforeMethod('GET','foozz'));
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php
new file mode 100644
index 000000000..625f64211
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Sabre\CalDAV\Principal;
+use Sabre\DAVACL;
+
+class CollectionTest extends \PHPUnit_Framework_TestCase {
+
+ function testGetChildForPrincipal() {
+
+ $back = new DAVACL\PrincipalBackend\Mock();
+ $col = new Collection($back);
+ $r = $col->getChildForPrincipal(array(
+ 'uri' => 'principals/admin',
+ ));
+ $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\User', $r);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php
new file mode 100644
index 000000000..1ee999a92
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php
@@ -0,0 +1,101 @@
+<?php
+
+namespace Sabre\CalDAV\Principal;
+use Sabre\DAVACL;
+
+class ProxyReadTest extends \PHPUnit_Framework_TestCase {
+
+ protected $backend;
+
+ function getInstance() {
+
+ $backend = new DAVACL\PrincipalBackend\Mock();
+ $principal = new ProxyRead($backend, array(
+ 'uri' => 'principal/user',
+ ));
+ $this->backend = $backend;
+ return $principal;
+
+ }
+
+ function testGetName() {
+
+ $i = $this->getInstance();
+ $this->assertEquals('calendar-proxy-read', $i->getName());
+
+ }
+ function testGetDisplayName() {
+
+ $i = $this->getInstance();
+ $this->assertEquals('calendar-proxy-read', $i->getDisplayName());
+
+ }
+
+ function testGetLastModified() {
+
+ $i = $this->getInstance();
+ $this->assertNull($i->getLastModified());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ function testDelete() {
+
+ $i = $this->getInstance();
+ $i->delete();
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ function testSetName() {
+
+ $i = $this->getInstance();
+ $i->setName('foo');
+
+ }
+
+ function testGetAlternateUriSet() {
+
+ $i = $this->getInstance();
+ $this->assertEquals(array(), $i->getAlternateUriSet());
+
+ }
+
+ function testGetPrincipalUri() {
+
+ $i = $this->getInstance();
+ $this->assertEquals('principal/user/calendar-proxy-read', $i->getPrincipalUrl());
+
+ }
+
+ function testGetGroupMemberSet() {
+
+ $i = $this->getInstance();
+ $this->assertEquals(array(), $i->getGroupMemberSet());
+
+ }
+
+ function testGetGroupMembership() {
+
+ $i = $this->getInstance();
+ $this->assertEquals(array(), $i->getGroupMembership());
+
+ }
+
+ function testSetGroupMemberSet() {
+
+ $i = $this->getInstance();
+ $i->setGroupMemberSet(array('principals/foo'));
+
+ $expected = array(
+ $i->getPrincipalUrl() => array('principals/foo')
+ );
+
+ $this->assertEquals($expected, $this->backend->groupMembers);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php
new file mode 100644
index 000000000..c0186ff0d
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Sabre\CalDAV\Principal;
+use Sabre\DAVACL;
+
+class ProxyWriteTest extends ProxyReadTest {
+
+ function getInstance() {
+
+ $backend = new DAVACL\PrincipalBackend\Mock();
+ $principal = new ProxyWrite($backend, array(
+ 'uri' => 'principal/user',
+ ));
+ $this->backend = $backend;
+ return $principal;
+
+ }
+
+ function testGetName() {
+
+ $i = $this->getInstance();
+ $this->assertEquals('calendar-proxy-write', $i->getName());
+
+ }
+ function testGetDisplayName() {
+
+ $i = $this->getInstance();
+ $this->assertEquals('calendar-proxy-write', $i->getDisplayName());
+
+ }
+
+ function testGetPrincipalUri() {
+
+ $i = $this->getInstance();
+ $this->assertEquals('principal/user/calendar-proxy-write', $i->getPrincipalUrl());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php
new file mode 100644
index 000000000..d41692f2a
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php
@@ -0,0 +1,126 @@
+<?php
+
+namespace Sabre\CalDAV\Principal;
+use Sabre\DAVACL;
+
+class UserTest extends \PHPUnit_Framework_TestCase {
+
+ function getInstance() {
+
+ $backend = new DAVACL\PrincipalBackend\Mock();
+ $backend->addPrincipal(array(
+ 'uri' => 'principals/user/calendar-proxy-read',
+ ));
+ $backend->addPrincipal(array(
+ 'uri' => 'principals/user/calendar-proxy-write',
+ ));
+ $backend->addPrincipal(array(
+ 'uri' => 'principals/user/random',
+ ));
+ return new User($backend, array(
+ 'uri' => 'principals/user',
+ ));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ function testCreateFile() {
+
+ $u = $this->getInstance();
+ $u->createFile('test');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ function testCreateDirectory() {
+
+ $u = $this->getInstance();
+ $u->createDirectory('test');
+
+ }
+
+ function testGetChildProxyRead() {
+
+ $u = $this->getInstance();
+ $child = $u->getChild('calendar-proxy-read');
+ $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyRead', $child);
+
+ }
+
+ function testGetChildProxyWrite() {
+
+ $u = $this->getInstance();
+ $child = $u->getChild('calendar-proxy-write');
+ $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyWrite', $child);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotFound
+ */
+ function testGetChildNotFound() {
+
+ $u = $this->getInstance();
+ $child = $u->getChild('foo');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotFound
+ */
+ function testGetChildNotFound2() {
+
+ $u = $this->getInstance();
+ $child = $u->getChild('random');
+
+ }
+
+ function testGetChildren() {
+
+ $u = $this->getInstance();
+ $children = $u->getChildren();
+ $this->assertEquals(2, count($children));
+ $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyRead', $children[0]);
+ $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyWrite', $children[1]);
+
+ }
+
+ function testChildExist() {
+
+ $u = $this->getInstance();
+ $this->assertTrue($u->childExists('calendar-proxy-read'));
+ $this->assertTrue($u->childExists('calendar-proxy-write'));
+ $this->assertFalse($u->childExists('foo'));
+
+ }
+
+ function testGetACL() {
+
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user/calendar-proxy-read',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ );
+
+ $u = $this->getInstance();
+ $this->assertEquals($expected, $u->getACL());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Property/AllowedSharingModesTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/AllowedSharingModesTest.php
new file mode 100644
index 000000000..733ea1108
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/AllowedSharingModesTest.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Sabre\CalDAV\Property;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class AllowedSharingModesTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $sccs = new AllowedSharingModes(true,true);
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerialize() {
+
+ $property = new AllowedSharingModes(true,true);
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+ $root->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '" xmlns:cs="' . CalDAV\Plugin::NS_CALENDARSERVER . '">' .
+'<cs:can-be-shared/>' .
+'<cs:can-be-published/>' .
+'</d:root>
+', $xml);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Property/InviteTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/InviteTest.php
new file mode 100644
index 000000000..349a6e080
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/InviteTest.php
@@ -0,0 +1,196 @@
+<?php
+
+namespace Sabre\CalDAV\Property;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class InviteTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $sccs = new Invite(array());
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerialize() {
+
+ $property = new Invite(array(
+ array(
+ 'href' => 'mailto:user1@example.org',
+ 'status' => CalDAV\SharingPlugin::STATUS_ACCEPTED,
+ 'readOnly' => false,
+ ),
+ array(
+ 'href' => 'mailto:user2@example.org',
+ 'commonName' => 'John Doe',
+ 'status' => CalDAV\SharingPlugin::STATUS_DECLINED,
+ 'readOnly' => true,
+ ),
+ array(
+ 'href' => 'mailto:user3@example.org',
+ 'commonName' => 'Joe Shmoe',
+ 'status' => CalDAV\SharingPlugin::STATUS_NORESPONSE,
+ 'readOnly' => true,
+ 'summary' => 'Something, something',
+ ),
+ array(
+ 'href' => 'mailto:user4@example.org',
+ 'commonName' => 'Hoe Boe',
+ 'status' => CalDAV\SharingPlugin::STATUS_INVALID,
+ 'readOnly' => true,
+ ),
+ ), array(
+ 'href' => 'mailto:thedoctor@example.org',
+ 'commonName' => 'The Doctor',
+ 'firstName' => 'The',
+ 'lastName' => 'Doctor',
+ ));
+
+ $doc = new \DOMDocument();
+ $doc->formatOutput = true;
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+ $root->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '" xmlns:cs="' . CalDAV\Plugin::NS_CALENDARSERVER . '">
+ <cs:organizer>
+ <d:href>mailto:thedoctor@example.org</d:href>
+ <cs:common-name>The Doctor</cs:common-name>
+ <cs:first-name>The</cs:first-name>
+ <cs:last-name>Doctor</cs:last-name>
+ </cs:organizer>
+ <cs:user>
+ <d:href>mailto:user1@example.org</d:href>
+ <cs:invite-accepted/>
+ <cs:access>
+ <cs:read-write/>
+ </cs:access>
+ </cs:user>
+ <cs:user>
+ <d:href>mailto:user2@example.org</d:href>
+ <cs:common-name>John Doe</cs:common-name>
+ <cs:invite-declined/>
+ <cs:access>
+ <cs:read/>
+ </cs:access>
+ </cs:user>
+ <cs:user>
+ <d:href>mailto:user3@example.org</d:href>
+ <cs:common-name>Joe Shmoe</cs:common-name>
+ <cs:invite-noresponse/>
+ <cs:access>
+ <cs:read/>
+ </cs:access>
+ <cs:summary>Something, something</cs:summary>
+ </cs:user>
+ <cs:user>
+ <d:href>mailto:user4@example.org</d:href>
+ <cs:common-name>Hoe Boe</cs:common-name>
+ <cs:invite-invalid/>
+ <cs:access>
+ <cs:read/>
+ </cs:access>
+ </cs:user>
+</d:root>
+', $xml);
+
+ }
+
+ /**
+ * @depends testSerialize
+ */
+ public function testUnserialize() {
+
+ $input = array(
+ array(
+ 'href' => 'mailto:user1@example.org',
+ 'status' => CalDAV\SharingPlugin::STATUS_ACCEPTED,
+ 'readOnly' => false,
+ 'commonName' => '',
+ 'summary' => '',
+ ),
+ array(
+ 'href' => 'mailto:user2@example.org',
+ 'commonName' => 'John Doe',
+ 'status' => CalDAV\SharingPlugin::STATUS_DECLINED,
+ 'readOnly' => true,
+ 'summary' => '',
+ ),
+ array(
+ 'href' => 'mailto:user3@example.org',
+ 'commonName' => 'Joe Shmoe',
+ 'status' => CalDAV\SharingPlugin::STATUS_NORESPONSE,
+ 'readOnly' => true,
+ 'summary' => 'Something, something',
+ ),
+ array(
+ 'href' => 'mailto:user4@example.org',
+ 'commonName' => 'Hoe Boe',
+ 'status' => CalDAV\SharingPlugin::STATUS_INVALID,
+ 'readOnly' => true,
+ 'summary' => '',
+ ),
+ );
+
+ // Creating the xml
+ $doc = new \DOMDocument();
+ $doc->formatOutput = true;
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+ $root->setAttribute('xmlns:cs',CalDAV\Plugin::NS_CALENDARSERVER);
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $inputProperty = new Invite($input);
+ $inputProperty->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ // Parsing it again
+
+ $doc2 = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $outputProperty = Invite::unserialize($doc2->firstChild);
+
+ $this->assertEquals($input, $outputProperty->getValue());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ */
+ function testUnserializeNoStatus() {
+
+$xml = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '" xmlns:cs="' . CalDAV\Plugin::NS_CALENDARSERVER . '">
+ <cs:user>
+ <d:href>mailto:user1@example.org</d:href>
+ <!-- <cs:invite-accepted/> -->
+ <cs:access>
+ <cs:read-write/>
+ </cs:access>
+ </cs:user>
+</d:root>';
+
+ $doc2 = DAV\XMLUtil::loadDOMDocument($xml);
+ $outputProperty = Invite::unserialize($doc2->firstChild);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Property/ScheduleCalendarTranspTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/ScheduleCalendarTranspTest.php
new file mode 100644
index 000000000..1ace0b18f
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/ScheduleCalendarTranspTest.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace Sabre\CalDAV\Property;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class ScheduleCalendarTranspTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $sccs = new ScheduleCalendarTransp('transparent');
+ $this->assertEquals('transparent', $sccs->getValue());
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testBadArg() {
+
+ $sccs = new ScheduleCalendarTransp('foo');
+
+ }
+
+ function values() {
+
+ return array(
+ array('transparent'),
+ array('opaque'),
+ );
+
+ }
+
+ /**
+ * @depends testSimple
+ * @dataProvider values
+ */
+ function testSerialize($value) {
+
+ $property = new ScheduleCalendarTransp($value);
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:' . $value . '/>' .
+'</d:root>
+', $xml);
+
+ }
+
+ /**
+ * @depends testSimple
+ * @dataProvider values
+ */
+ function testUnserializer($value) {
+
+ $xml = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:'.$value.'/>' .
+'</d:root>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $property = ScheduleCalendarTransp::unserialize($dom->firstChild);
+
+ $this->assertTrue($property instanceof ScheduleCalendarTransp);
+ $this->assertEquals($value, $property->getValue());
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testUnserializerBadData() {
+
+ $xml = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:foo/>' .
+'</d:root>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $this->assertNull(ScheduleCalendarTransp::unserialize($dom->firstChild));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarComponentSetTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarComponentSetTest.php
new file mode 100644
index 000000000..3e5d5f5fc
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarComponentSetTest.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Sabre\CalDAV\Property;
+
+class SupportedCalendarComponentSetTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $sccs = new SupportedCalendarComponentSet(array('VEVENT'));
+ $this->assertEquals(array('VEVENT'), $sccs->getValue());
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerialize() {
+
+ $property = new SupportedCalendarComponentSet(array('VEVENT','VJOURNAL'));
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',\Sabre\CalDAV\Plugin::NS_CALDAV);
+
+ $doc->appendChild($root);
+ $server = new \Sabre\DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . \Sabre\CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:comp name="VEVENT"/>' .
+'<cal:comp name="VJOURNAL"/>' .
+'</d:root>
+', $xml);
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testUnserializer() {
+
+ $xml = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . \Sabre\CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:comp name="VEVENT"/>' .
+'<cal:comp name="VJOURNAL"/>' .
+'</d:root>';
+
+ $dom = \Sabre\DAV\XMLUtil::loadDOMDocument($xml);
+
+ $property = SupportedCalendarComponentSet::unserialize($dom->firstChild);
+
+ $this->assertTrue($property instanceof SupportedCalendarComponentSet);
+ $this->assertEquals(array(
+ 'VEVENT',
+ 'VJOURNAL',
+ ),
+ $property->getValue());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarDataTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarDataTest.php
new file mode 100644
index 000000000..3e016368c
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCalendarDataTest.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Sabre\CalDAV\Property;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class SupportedCalendarDataTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $sccs = new SupportedCalendarData();
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerialize() {
+
+ $property = new SupportedCalendarData();
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:calendar-data content-type="text/calendar" version="2.0"/>' .
+'</d:root>
+', $xml);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCollationSetTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCollationSetTest.php
new file mode 100644
index 000000000..669e31553
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Property/SupportedCollationSetTest.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Sabre\CalDAV\Property;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class SupportedCollationSetTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $scs = new SupportedCollationSet();
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerialize() {
+
+ $property = new SupportedCollationSet();
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:cal',CalDAV\Plugin::NS_CALDAV);
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:" xmlns:cal="' . CalDAV\Plugin::NS_CALDAV . '">' .
+'<cal:supported-collation>i;ascii-casemap</cal:supported-collation>' .
+'<cal:supported-collation>i;octet</cal:supported-collation>' .
+'<cal:supported-collation>i;unicode-casemap</cal:supported-collation>' .
+'</d:root>
+', $xml);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/IMip/Mock.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/IMip/Mock.php
new file mode 100644
index 000000000..a97eb3bdd
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/IMip/Mock.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Sabre\CalDAV\Schedule\IMip;
+
+/**
+ * iMIP handler.
+ *
+ * This class is responsible for sending out iMIP messages. iMIP is the
+ * email-based transport for iTIP. iTIP deals with scheduling operations for
+ * iCalendar objects.
+ *
+ * If you want to customize the email that gets sent out, you can do so by
+ * extending this class and overriding the sendMessage method.
+ *
+ * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Mock extends \Sabre\CalDAV\Schedule\IMip {
+
+ protected $emails = array();
+
+ /**
+ * This function is reponsible for sending the actual email.
+ *
+ * @param string $to Recipient email address
+ * @param string $subject Subject of the email
+ * @param string $body iCalendar body
+ * @param array $headers List of headers
+ * @return void
+ */
+ protected function mail($to, $subject, $body, array $headers) {
+
+ $this->emails[] = array(
+ 'to' => $to,
+ 'subject' => $subject,
+ 'body' => $body,
+ 'headers' => $headers,
+ );
+
+ }
+
+ public function getSentEmails() {
+
+ return $this->emails;
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php
new file mode 100644
index 000000000..60ce9a2ad
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Sabre\CalDAV\Schedule;
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+class OutboxTest extends \PHPUnit_Framework_TestCase {
+
+ function testSetup() {
+
+ $outbox = new Outbox('principals/user1');
+ $this->assertEquals('outbox', $outbox->getName());
+ $this->assertEquals(array(), $outbox->getChildren());
+ $this->assertEquals('principals/user1', $outbox->getOwner());
+ $this->assertEquals(null, $outbox->getGroup());
+
+ $this->assertEquals(array(
+ array(
+ 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-query-freebusy',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-post-vevent',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ ), $outbox->getACL());
+
+ $ok = false;
+ try {
+ $outbox->setACL(array());
+ } catch (DAV\Exception\MethodNotAllowed $e) {
+ $ok = true;
+ }
+ if (!$ok) {
+ $this->fail('Exception was not emitted');
+ }
+
+ }
+
+ function testGetSupportedPrivilegeSet() {
+
+ $outbox = new Outbox('principals/user1');
+ $r = $outbox->getSupportedPrivilegeSet();
+
+ $ok = 0;
+ foreach($r['aggregates'] as $priv) {
+
+ if ($priv['privilege'] == '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-query-freebusy') {
+ $ok++;
+ }
+ if ($priv['privilege'] == '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-post-vevent') {
+ $ok++;
+ }
+ }
+
+ $this->assertEquals(2, $ok, "We're missing one or more privileges");
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ShareableCalendarTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ShareableCalendarTest.php
new file mode 100644
index 000000000..2f79351f1
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ShareableCalendarTest.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAVACL;
+
+class ShareableCalendarTest extends \PHPUnit_Framework_TestCase {
+
+ protected $backend;
+ protected $instance;
+
+ function setUp() {
+
+ $props = array(
+ 'id' => 1,
+ );
+
+ $this->backend = new Backend\Mock(
+ array($props),
+ array(),
+ array()
+ );
+ $this->backend->updateShares(1, array(
+ array(
+ 'href' => 'mailto:removeme@example.org',
+ 'commonName' => 'To be removed',
+ 'readOnly' => true,
+ ),
+ ), array());
+
+ $this->instance = new ShareableCalendar($this->backend, $props);
+
+ }
+
+ function testUpdateShares() {
+
+ $this->instance->updateShares(array(
+ array(
+ 'href' => 'mailto:test@example.org',
+ 'commonName' => 'Foo Bar',
+ 'summary' => 'Booh',
+ 'readOnly' => false,
+ ),
+ ), array('mailto:removeme@example.org'));
+
+ $this->assertEquals(array(array(
+ 'href' => 'mailto:test@example.org',
+ 'commonName' => 'Foo Bar',
+ 'summary' => 'Booh',
+ 'readOnly' => false,
+ 'status' => SharingPlugin::STATUS_NORESPONSE,
+ )), $this->instance->getShares());
+
+ }
+
+ function testPublish() {
+
+ $this->instance->setPublishStatus(true);
+ $this->instance->setPublishStatus(false);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php
new file mode 100644
index 000000000..955831917
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAVACL;
+
+class SharedCalendarTest extends \PHPUnit_Framework_TestCase {
+
+ protected $backend;
+
+ function getInstance(array $props = null) {
+
+ if (is_null($props)) {
+ $props = array(
+ 'id' => 1,
+ '{http://calendarserver.org/ns/}shared-url' => 'calendars/owner/original',
+ '{http://sabredav.org/ns}owner-principal' => 'principals/owner',
+ '{http://sabredav.org/ns}read-only' => false,
+ 'principaluri' => 'principals/sharee',
+ );
+ }
+
+ $this->backend = new Backend\Mock(
+ array($props),
+ array(),
+ array()
+ );
+ $this->backend->updateShares(1, array(
+ array(
+ 'href' => 'mailto:removeme@example.org',
+ 'commonName' => 'To be removed',
+ 'readOnly' => true,
+ ),
+ ), array());
+
+ return new SharedCalendar($this->backend, $props);
+
+ }
+
+ function testGetSharedUrl() {
+ $this->assertEquals('calendars/owner/original', $this->getInstance()->getSharedUrl());
+ }
+
+ function testGetShares() {
+
+ $this->assertEquals(array(array(
+ 'href' => 'mailto:removeme@example.org',
+ 'commonName' => 'To be removed',
+ 'readOnly' => true,
+ 'status' => SharingPlugin::STATUS_NORESPONSE,
+ )), $this->getInstance()->getShares());
+
+ }
+
+ function testGetOwner() {
+ $this->assertEquals('principals/owner', $this->getInstance()->getOwner());
+ }
+
+ function testGetACL() {
+
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/owner',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/owner',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/owner/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/owner/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/owner/calendar-proxy-read',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
+ 'principal' => '{DAV:}authenticated',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/sharee',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/sharee',
+ 'protected' => true,
+ ),
+ );
+
+ $this->assertEquals($expected, $this->getInstance()->getACL());
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testCreateInstanceMissingArg() {
+
+ $this->getInstance(array(
+ 'id' => 1,
+ '{http://calendarserver.org/ns/}shared-url' => 'calendars/owner/original',
+ '{http://sabredav.org/ns}read-only' => false,
+ 'principaluri' => 'principals/sharee',
+ ));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php
new file mode 100644
index 000000000..60a71fd7f
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php
@@ -0,0 +1,391 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+class SharingPluginTest extends \Sabre\DAVServerTest {
+
+ protected $setupCalDAV = true;
+ protected $setupCalDAVSharing = true;
+ protected $setupACL = true;
+ protected $autoLogin = 'user1';
+
+ function setUp() {
+
+ $this->caldavCalendars = array(
+ array(
+ 'principaluri' => 'principals/user1',
+ 'id' => 1,
+ 'uri' => 'cal1',
+ ),
+ array(
+ 'principaluri' => 'principals/user1',
+ 'id' => 2,
+ 'uri' => 'cal2',
+ '{' . Plugin::NS_CALENDARSERVER . '}shared-url' => 'calendars/user1/cal2',
+ '{http://sabredav.org/ns}owner-principal' => 'principals/user2',
+ '{http://sabredav.org/ns}read-only' => 'true',
+ ),
+ array(
+ 'principaluri' => 'principals/user1',
+ 'id' => 3,
+ 'uri' => 'cal3',
+ ),
+ );
+
+ parent::setUp();
+
+ // Making the logged in user an admin, for full access:
+ $this->aclPlugin->adminPrincipals[] = 'principals/user1';
+ $this->aclPlugin->adminPrincipals[] = 'principals/user2';
+
+ }
+
+ function testSimple() {
+
+ $this->assertInstanceOf('Sabre\\CalDAV\\SharingPlugin', $this->server->getPlugin('caldav-sharing'));
+
+ }
+
+ function testGetFeatures() {
+
+ $this->assertEquals(array('calendarserver-sharing'), $this->caldavSharingPlugin->getFeatures());
+
+ }
+
+ function testBeforeGetShareableCalendar() {
+
+ // Forcing the server to authenticate:
+ $this->authPlugin->beforeMethod('GET','');
+ $props = $this->server->getProperties('calendars/user1/cal1', array(
+ '{' . Plugin::NS_CALENDARSERVER . '}invite',
+ '{' . Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes',
+ ));
+
+ $this->assertInstanceOf('Sabre\\CalDAV\\Property\\Invite', $props['{' . Plugin::NS_CALENDARSERVER . '}invite']);
+ $this->assertInstanceOf('Sabre\\CalDAV\\Property\\AllowedSharingModes', $props['{' . Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes']);
+
+ }
+
+ function testBeforeGetSharedCalendar() {
+
+ $props = $this->server->getProperties('calendars/user1/cal2', array(
+ '{' . Plugin::NS_CALENDARSERVER . '}shared-url',
+ '{' . Plugin::NS_CALENDARSERVER . '}invite',
+ ));
+
+ $this->assertInstanceOf('Sabre\\CalDAV\\Property\\Invite', $props['{' . Plugin::NS_CALENDARSERVER . '}invite']);
+ $this->assertInstanceOf('Sabre\\DAV\\Property\\IHref', $props['{' . Plugin::NS_CALENDARSERVER . '}shared-url']);
+
+ }
+
+ function testUpdateProperties() {
+
+ $this->caldavBackend->updateShares(1,
+ array(
+ array(
+ 'href' => 'mailto:joe@example.org',
+ ),
+ ),
+ array()
+ );
+ $result = $this->server->updateProperties('calendars/user1/cal1', array(
+ '{DAV:}resourcetype' => new DAV\Property\ResourceType(array('{DAV:}collection'))
+ ));
+
+ $this->assertEquals(array(
+ 200 => array(
+ '{DAV:}resourcetype' => null,
+ ),
+ 'href' => 'calendars/user1/cal1',
+ ), $result);
+
+ $this->assertEquals(0, count($this->caldavBackend->getShares(1)));
+
+ }
+
+ function testUpdatePropertiesPassThru() {
+
+ $result = $this->server->updateProperties('calendars/user1/cal3', array(
+ '{DAV:}foo' => 'bar',
+ ));
+
+ $this->assertEquals(array(
+ 403 => array(
+ '{DAV:}foo' => null,
+ ),
+ 'href' => 'calendars/user1/cal3',
+ ), $result);
+
+ }
+
+ function testUnknownMethodNoPOST() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PATCH',
+ 'REQUEST_URI' => '/',
+ ));
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+
+ function testUnknownMethodNoXML() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/',
+ 'CONTENT_TYPE' => 'text/plain',
+ ));
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+
+ function testUnknownMethodNoNode() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/foo',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+
+ function testShareRequest() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal1',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = <<<RRR
+<?xml version="1.0"?>
+<cs:share xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:">
+ <cs:set>
+ <d:href>mailto:joe@example.org</d:href>
+ <cs:common-name>Joe Shmoe</cs:common-name>
+ <cs:read-write />
+ </cs:set>
+ <cs:remove>
+ <d:href>mailto:nancy@example.org</d:href>
+ </cs:remove>
+</cs:share>
+RRR;
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status, $response->body);
+
+ $this->assertEquals(array(array(
+ 'href' => 'mailto:joe@example.org',
+ 'commonName' => 'Joe Shmoe',
+ 'readOnly' => false,
+ 'status' => SharingPlugin::STATUS_NORESPONSE,
+ 'summary' => '',
+ )), $this->caldavBackend->getShares(1));
+
+ // Verifying that the calendar is now marked shared.
+ $props = $this->server->getProperties('calendars/user1/cal1', array('{DAV:}resourcetype'));
+ $this->assertTrue(
+ $props['{DAV:}resourcetype']->is('{http://calendarserver.org/ns/}shared-owner')
+ );
+
+ }
+
+ function testShareRequestNoShareableCalendar() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal2',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:share xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
+ <cs:set>
+ <d:href>mailto:joe@example.org</d:href>
+ <cs:common-name>Joe Shmoe</cs:common-name>
+ <cs:read-write />
+ </cs:set>
+ <cs:remove>
+ <d:href>mailto:nancy@example.org</d:href>
+ </cs:remove>
+</cs:share>
+';
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+
+ function testInviteReply() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:invite-reply xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
+ <cs:hosturl><d:href>/principals/owner</d:href></cs:hosturl>
+ <cs:invite-accepted />
+</cs:invite-reply>
+';
+
+ $request->setBody($xml);
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status, $response->body);
+
+ }
+
+ function testInviteBadXML() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:invite-reply xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
+</cs:invite-reply>
+';
+ $request->setBody($xml);
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, $response->body);
+
+ }
+
+ function testInviteWrongUrl() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal1',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:invite-reply xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
+ <cs:hosturl><d:href>/principals/owner</d:href></cs:hosturl>
+</cs:invite-reply>
+';
+ $request->setBody($xml);
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ // If the plugin did not handle this request, it must ensure that the
+ // body is still accessible by other plugins.
+ $this->assertEquals($xml, $request->getBody(true));
+
+ }
+
+ function testPublish() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal1',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:publish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
+';
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 202 Accepted', $response->status, $response->body);
+
+ }
+
+ function testUnpublish() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal1',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:unpublish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
+';
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status, $response->body);
+
+ }
+
+ function testPublishWrongUrl() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal2',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:publish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
+';
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+
+ function testUnpublishWrongUrl() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal2',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:unpublish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
+';
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+
+ function testUnknownXmlDoc() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'REQUEST_URI' => '/calendars/user1/cal2',
+ 'CONTENT_TYPE' => 'text/xml',
+ ));
+
+ $xml = '<?xml version="1.0"?>
+<cs:foo-bar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />';
+
+ $request->setBody($xml);
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $response->status, $response->body);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php b/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php
new file mode 100644
index 000000000..19acea200
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php
@@ -0,0 +1,208 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+class TestUtil {
+
+ static function getBackend() {
+
+ $backend = new Backend\PDO(self::getSQLiteDB());
+ return $backend;
+
+ }
+
+ static function getSQLiteDB() {
+
+ if (file_exists(SABRE_TEMPDIR . '/testdb.sqlite'))
+ unlink(SABRE_TEMPDIR . '/testdb.sqlite');
+
+ $pdo = new \PDO('sqlite:' . SABRE_TEMPDIR . '/testdb.sqlite');
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
+
+ // Yup this is definitely not 'fool proof', but good enough for now.
+ $queries = explode(';', file_get_contents(__DIR__ . '/../../../examples/sql/sqlite.calendars.sql'));
+ foreach($queries as $query) {
+ $pdo->exec($query);
+ }
+ // Inserting events through a backend class.
+ $backend = new Backend\PDO($pdo);
+ $calendarId = $backend->createCalendar(
+ 'principals/user1',
+ 'UUID-123467',
+ array(
+ '{DAV:}displayname' => 'user1 calendar',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar description',
+ '{http://apple.com/ns/ical/}calendar-order' => '1',
+ '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
+ )
+ );
+ $backend->createCalendar(
+ 'principals/user1',
+ 'UUID-123468',
+ array(
+ '{DAV:}displayname' => 'user1 calendar2',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar description',
+ '{http://apple.com/ns/ical/}calendar-order' => '1',
+ '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
+ )
+ );
+ $backend->createCalendarObject($calendarId, 'UUID-2345', self::getTestCalendarData());
+ return $pdo;
+
+ }
+
+ static function getTestCalendarData($type = 1) {
+
+ $calendarData = 'BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:Asia/Seoul
+BEGIN:DAYLIGHT
+TZOFFSETFROM:+0900
+RRULE:FREQ=YEARLY;UNTIL=19880507T150000Z;BYMONTH=5;BYDAY=2SU
+DTSTART:19870510T000000
+TZNAME:GMT+09:00
+TZOFFSETTO:+1000
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:+1000
+DTSTART:19881009T000000
+TZNAME:GMT+09:00
+TZOFFSETTO:+0900
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20100225T154229Z
+UID:39A6B5ED-DD51-4AFE-A683-C35EE3749627
+TRANSP:TRANSPARENT
+SUMMARY:Something here
+DTSTAMP:20100228T130202Z';
+
+ switch($type) {
+ case 1 :
+ $calendarData.="\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDTEND;TZID=Asia/Seoul:20100223T070000\n";
+ break;
+ case 2 :
+ $calendarData.="\nDTSTART:20100223T060000\nDTEND:20100223T070000\n";
+ break;
+ case 3 :
+ $calendarData.="\nDTSTART;VALUE=DATE:20100223\nDTEND;VALUE=DATE:20100223\n";
+ break;
+ case 4 :
+ $calendarData.="\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDURATION:PT1H\n";
+ break;
+ case 5 :
+ $calendarData.="\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDURATION:-P5D\n";
+ break;
+ case 6 :
+ $calendarData.="\nDTSTART;VALUE=DATE:20100223\n";
+ break;
+ case 7 :
+ $calendarData.="\nDTSTART;VALUE=DATETIME:20100223T060000\n";
+ break;
+
+ // No DTSTART, so intentionally broken
+ case 'X' :
+ $calendarData.="\n";
+ break;
+ }
+
+
+ $calendarData.='ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR';
+
+ return $calendarData;
+
+ }
+
+ static function getTestTODO($type = 'due') {
+
+ switch($type) {
+
+ case 'due' :
+ $extra = "DUE:20100104T000000Z";
+ break;
+ case 'due2' :
+ $extra = "DUE:20060104T000000Z";
+ break;
+ case 'due_date' :
+ $extra = "DUE;VALUE=DATE:20060104";
+ break;
+ case 'due_tz' :
+ $extra = "DUE;TZID=Asia/Seoul:20060104T000000Z";
+ break;
+ case 'due_dtstart' :
+ $extra = "DTSTART:20050223T060000Z\nDUE:20060104T000000Z";
+ break;
+ case 'due_dtstart2' :
+ $extra = "DTSTART:20090223T060000Z\nDUE:20100104T000000Z";
+ break;
+ case 'dtstart' :
+ $extra = 'DTSTART:20100223T060000Z';
+ break;
+ case 'dtstart2' :
+ $extra = 'DTSTART:20060223T060000Z';
+ break;
+ case 'dtstart_date' :
+ $extra = 'DTSTART;VALUE=DATE:20100223';
+ break;
+ case 'dtstart_tz' :
+ $extra = 'DTSTART;TZID=Asia/Seoul:20100223T060000Z';
+ break;
+ case 'dtstart_duration' :
+ $extra = "DTSTART:20061023T060000Z\nDURATION:PT1H";
+ break;
+ case 'dtstart_duration2' :
+ $extra = "DTSTART:20101023T060000Z\nDURATION:PT1H";
+ break;
+ case 'completed' :
+ $extra = 'COMPLETED:20060601T000000Z';
+ break;
+ case 'completed2' :
+ $extra = 'COMPLETED:20090601T000000Z';
+ break;
+ case 'created' :
+ $extra = 'CREATED:20060601T000000Z';
+ break;
+ case 'created2' :
+ $extra = 'CREATED:20090601T000000Z';
+ break;
+ case 'completedcreated' :
+ $extra = "CREATED:20060601T000000Z\nCOMPLETED:20070101T000000Z";
+ break;
+ case 'completedcreated2' :
+ $extra = "CREATED:20090601T000000Z\nCOMPLETED:20100101T000000Z";
+ break;
+ case 'notime' :
+ $extra = 'X-FILLER:oh hello';
+ break;
+ default :
+ throw new Exception('Unknown type: ' . $type);
+
+ }
+
+ $todo = 'BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Corp.//CalDAV Client//EN
+BEGIN:VTODO
+DTSTAMP:20060205T235335Z
+' . $extra . '
+STATUS:NEEDS-ACTION
+SUMMARY:Task #1
+UID:DDDEEB7915FA61233B861457@example.com
+BEGIN:VALARM
+ACTION:AUDIO
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+END:VTODO
+END:VCALENDAR';
+
+ return $todo;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsSharedCalendarsTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsSharedCalendarsTest.php
new file mode 100644
index 000000000..4c3bae3a4
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsSharedCalendarsTest.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAVACL;
+
+require_once 'Sabre/CalDAV/TestUtil.php';
+
+/**
+ * @covers Sabre\CalDAV\UserCalendars
+ */
+class UserCalendarsSharedCalendarsTest extends \PHPUnit_Framework_TestCase {
+
+ protected $backend;
+
+ function getInstance() {
+
+ $calendars = array(
+ array(
+ 'id' => 1,
+ 'principaluri' => 'principals/user1',
+ ),
+ array(
+ 'id' => 2,
+ '{http://calendarserver.org/ns/}shared-url' => 'calendars/owner/cal1',
+ '{http://sabredav.org/ns}owner-principal' => 'principal/owner',
+ '{http://sabredav.org/ns}read-only' => false,
+ 'principaluri' => 'principals/user1',
+ ),
+ );
+
+ $this->backend = new Backend\Mock(
+ $calendars,
+ array(),
+ array()
+ );
+
+ return new UserCalendars($this->backend, array(
+ 'uri' => 'principals/user1'
+ ));
+
+ }
+
+ function testSimple() {
+
+ $instance = $this->getInstance();
+ $this->assertEquals('user1', $instance->getName());
+
+ }
+
+ function testGetChildren() {
+
+ $instance = $this->getInstance();
+ $children = $instance->getChildren();
+ $this->assertEquals(4, count($children));
+
+ // Testing if we got all the objects back.
+ $hasShareable = false;
+ $hasShared = false;
+ $hasOutbox = false;
+ $hasNotifications = false;
+
+ foreach($children as $child) {
+
+ if ($child instanceof IShareableCalendar) {
+ $hasShareable = true;
+ }
+ if ($child instanceof ISharedCalendar) {
+ $hasShared = true;
+ }
+ if ($child instanceof Schedule\IOutbox) {
+ $hasOutbox = true;
+ }
+ if ($child instanceof Notifications\ICollection) {
+ $hasNotifications = true;
+ }
+
+ }
+ if (!$hasShareable) $this->fail('Missing node!');
+ if (!$hasShared) $this->fail('Missing node!');
+ if (!$hasOutbox) $this->fail('Missing node!');
+ if (!$hasNotifications) $this->fail('Missing node!');
+
+ }
+
+ function testShareReply() {
+
+ $instance = $this->getInstance();
+ $instance->shareReply('uri', SharingPlugin::STATUS_DECLINED, 'curi', '1');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsTest.php
new file mode 100644
index 000000000..453c872e5
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/UserCalendarsTest.php
@@ -0,0 +1,207 @@
+<?php
+
+namespace Sabre\CalDAV;
+use Sabre\DAVACL;
+use Sabre\DAV;
+
+require_once 'Sabre/CalDAV/TestUtil.php';
+
+/**
+ * @covers Sabre\CalDAV\UserCalendars
+ */
+class UserCalendarsTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\CalDAV\UserCalendars
+ */
+ protected $usercalendars;
+ /**
+ * @var Sabre\CalDAV\Backend\PDO
+ */
+ protected $backend;
+
+ function setup() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $this->backend = TestUtil::getBackend();
+ $this->usercalendars = new UserCalendars($this->backend, array(
+ 'uri' => 'principals/user1'
+ ));
+
+ }
+
+ function testSimple() {
+
+ $this->assertEquals('user1',$this->usercalendars->getName());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotFound
+ * @depends testSimple
+ */
+ function testGetChildNotFound() {
+
+ $this->usercalendars->getChild('randomname');
+
+ }
+
+ function testChildExists() {
+
+ $this->assertFalse($this->usercalendars->childExists('foo'));
+ $this->assertTrue($this->usercalendars->childExists('UUID-123467'));
+
+ }
+
+ function testGetOwner() {
+
+ $this->assertEquals('principals/user1', $this->usercalendars->getOwner());
+
+ }
+
+ function testGetGroup() {
+
+ $this->assertNull($this->usercalendars->getGroup());
+
+ }
+
+ function testGetACL() {
+
+ $expected = array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1/calendar-proxy-write',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1/calendar-proxy-read',
+ 'protected' => true,
+ ),
+ );
+ $this->assertEquals($expected, $this->usercalendars->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetACL() {
+
+ $this->usercalendars->setACL(array());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ * @depends testSimple
+ */
+ function testSetName() {
+
+ $this->usercalendars->setName('bla');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ * @depends testSimple
+ */
+ function testDelete() {
+
+ $this->usercalendars->delete();
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testGetLastModified() {
+
+ $this->assertNull($this->usercalendars->getLastModified());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ * @depends testSimple
+ */
+ function testCreateFile() {
+
+ $this->usercalendars->createFile('bla');
+
+ }
+
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ * @depends testSimple
+ */
+ function testCreateDirectory() {
+
+ $this->usercalendars->createDirectory('bla');
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testCreateExtendedCollection() {
+
+ $result = $this->usercalendars->createExtendedCollection('newcalendar', array('{DAV:}collection', '{urn:ietf:params:xml:ns:caldav}calendar'), array());
+ $this->assertNull($result);
+ $cals = $this->backend->getCalendarsForUser('principals/user1');
+ $this->assertEquals(3,count($cals));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\InvalidResourceType
+ * @depends testSimple
+ */
+ function testCreateExtendedCollectionBadResourceType() {
+
+ $this->usercalendars->createExtendedCollection('newcalendar', array('{DAV:}collection','{DAV:}blabla'), array());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\InvalidResourceType
+ * @depends testSimple
+ */
+ function testCreateExtendedCollectionNotACalendar() {
+
+ $this->usercalendars->createExtendedCollection('newcalendar', array('{DAV:}collection'), array());
+
+ }
+
+ function testGetSupportedPrivilegesSet() {
+
+ $this->assertNull($this->usercalendars->getSupportedPrivilegeSet());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotImplemented
+ */
+ function testShareReplyFail() {
+
+ $this->usercalendars->shareReply('uri', SharingPlugin::STATUS_DECLINED, 'curi', '1');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php
new file mode 100644
index 000000000..6634b9c3b
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php
@@ -0,0 +1,250 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+use Sabre\DAV;
+use Sabre\DAVACL;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class ValidateICalTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\DAV\Server
+ */
+ protected $server;
+ /**
+ * @var Sabre\CalDAV\Backend\Mock
+ */
+ protected $calBackend;
+
+ function setUp() {
+
+ $calendars = array(
+ array(
+ 'id' => 'calendar1',
+ 'principaluri' => 'principals/admin',
+ 'uri' => 'calendar1',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Property\SupportedCalendarComponentSet( array('VEVENT','VTODO','VJOURNAL') ),
+ ),
+ array(
+ 'id' => 'calendar2',
+ 'principaluri' => 'principals/admin',
+ 'uri' => 'calendar2',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Property\SupportedCalendarComponentSet( array('VTODO','VJOURNAL') ),
+ )
+ );
+
+ $this->calBackend = new Backend\Mock($calendars,array());
+ $principalBackend = new DAVACL\PrincipalBackend\Mock();
+
+ $tree = array(
+ new CalendarRootNode($principalBackend, $this->calBackend),
+ );
+
+ $this->server = new DAV\Server($tree);
+ $this->server->debugExceptions = true;
+
+ $plugin = new Plugin();
+ $this->server->addPlugin($plugin);
+
+ $response = new HTTP\ResponseMock();
+ $this->server->httpResponse = $response;
+
+ }
+
+ function request(HTTP\Request $request) {
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ return $this->server->httpResponse;
+
+ }
+
+ function testCreateFile() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 415 Unsupported Media Type', $response->status);
+
+ }
+
+ function testCreateFileValid() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 201 Created', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+ $expected = array(
+ 'uri' => 'blabla.ics',
+ 'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
+ 'calendarid' => 'calendar1',
+ );
+
+ $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1','blabla.ics'));
+
+ }
+
+ function testCreateFileNoComponents() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testCreateFileNoUID() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testCreateFileVCard() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCARD\r\nEND:VCARD\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 415 Unsupported Media Type', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testCreateFile2Components() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nBEGIN:VJOURNAL\r\nUID:foo\r\nEND:VJOURNAL\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testCreateFile2UIDS() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nBEGIN:VEVENT\r\nUID:bar\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testCreateFileWrongComponent() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VFREEBUSY\r\nUID:foo\r\nEND:VFREEBUSY\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testUpdateFile() {
+
+ $this->calBackend->createCalendarObject('calendar1','blabla.ics','foo');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 415 Unsupported Media Type', $response->status);
+
+ }
+
+ function testUpdateFileParsableBody() {
+
+ $this->calBackend->createCalendarObject('calendar1','blabla.ics','foo');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ));
+ $body = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+ $request->setBody($body);
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 204 No Content', $response->status);
+
+ $expected = array(
+ 'uri' => 'blabla.ics',
+ 'calendardata' => $body,
+ 'calendarid' => 'calendar1',
+ );
+
+ $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1','blabla.ics'));
+
+ }
+
+ function testCreateFileInvalidComponent() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar2/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testUpdateFileInvalidComponent() {
+
+ $this->calBackend->createCalendarObject('calendar2','blabla.ics','foo');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/calendars/admin/calendar2/blabla.ics',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/VersionTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/VersionTest.php
new file mode 100644
index 000000000..a4e093e35
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/VersionTest.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace Sabre\CalDAV;
+
+class VersionTest extends \PHPUnit_Framework_TestCase {
+
+ function testString() {
+
+ $v = Version::VERSION;
+ $this->assertEquals(-1, version_compare('1.0.0',$v));
+
+ $s = Version::STABILITY;
+ $this->assertTrue($s == 'alpha' || $s == 'beta' || $s =='stable');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php
new file mode 100644
index 000000000..94081fc8b
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+use Sabre\DAV;
+use Sabre\DAVACL;
+
+abstract class AbstractPluginTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\CardDAV\Plugin
+ */
+ protected $plugin;
+ /**
+ * @var Sabre\DAV\Server
+ */
+ protected $server;
+ /**
+ * @var Sabre\CardDAV\Backend\Mock;
+ */
+ protected $backend;
+
+ function setUp() {
+
+ $this->backend = new Backend\Mock();
+ $principalBackend = new DAVACL\PrincipalBackend\Mock();
+
+ $tree = array(
+ new AddressBookRoot($principalBackend, $this->backend),
+ new DAVACL\PrincipalCollection($principalBackend)
+ );
+
+ $this->plugin = new Plugin();
+ $this->plugin->directories = array('directory');
+ $this->server = new DAV\Server($tree);
+ $this->server->addPlugin($this->plugin);
+ $this->server->debugExceptions = true;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryParserTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryParserTest.php
new file mode 100644
index 000000000..51bea6c6c
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryParserTest.php
@@ -0,0 +1,329 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+use Sabre\DAV;
+
+class AddressBookQueryParserTest extends \PHPUnit_Framework_TestCase {
+
+ function parse($xml) {
+
+ $xml = implode("\n", $xml);
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $q = new AddressBookQueryParser($dom);
+ $q->parse();
+ return $q;
+
+ }
+
+ function testFilterBasic() {
+
+ $xml = array(
+ '<?xml version="1.0"?>',
+ '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">',
+ ' <d:prop>',
+ ' <d:foo />',
+ ' </d:prop>',
+ ' <c:filter>',
+ ' <c:prop-filter name="NICKNAME" />',
+ ' </c:filter>',
+ '</c:addressbook-query>'
+ );
+
+ $q = $this->parse($xml);
+
+ $this->assertEquals(
+ array('{DAV:}foo'),
+ $q->requestedProperties
+ );
+
+ $this->assertEquals(
+ array(
+ array(
+ 'name' => 'NICKNAME',
+ 'test' => 'anyof',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'text-matches' => array(),
+ ),
+ ),
+ $q->filters
+ );
+
+ $this->assertNull($q->limit);
+ $this->assertEquals('anyof', $q->test);
+
+ }
+
+ function testNoFilter() {
+
+ // This is non-standard, but helps working around a KDE bug
+ $xml = array(
+ '<?xml version="1.0"?>',
+ '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">',
+ ' <d:prop>',
+ ' <d:foo />',
+ ' </d:prop>',
+ '</c:addressbook-query>'
+ );
+
+ $q = $this->parse($xml);
+
+ $this->assertEquals(
+ array('{DAV:}foo'),
+ $q->requestedProperties
+ );
+
+ $this->assertEquals(
+ array(),
+ $q->filters
+ );
+
+ $this->assertNull($q->limit);
+ $this->assertEquals('anyof', $q->test);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testFilterDoubleFilter() {
+
+ $xml = array(
+ '<?xml version="1.0"?>',
+ '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">',
+ ' <d:prop>',
+ ' <d:foo />',
+ ' </d:prop>',
+ ' <c:filter>',
+ ' <c:prop-filter name="NICKNAME" />',
+ ' </c:filter>',
+ ' <c:filter>',
+ ' <c:prop-filter name="NICKNAME" />',
+ ' </c:filter>',
+ '</c:addressbook-query>'
+ );
+
+ $q = $this->parse($xml);
+
+ }
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testFilterCorruptTest() {
+
+ $xml = array(
+ '<?xml version="1.0"?>',
+ '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">',
+ ' <d:prop>',
+ ' <d:foo />',
+ ' </d:prop>',
+ ' <c:filter test="foo">',
+ ' <c:prop-filter name="NICKNAME" />',
+ ' </c:filter>',
+ '</c:addressbook-query>'
+ );
+
+ $q = $this->parse($xml);
+
+ }
+
+ function testPropFilter() {
+
+ $xml = array(
+ '<?xml version="1.0"?>',
+ '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">',
+ ' <d:prop>',
+ ' <d:foo />',
+ ' </d:prop>',
+ ' <c:filter test="allof">',
+ ' <c:prop-filter name="NICKNAME" />',
+ ' <c:prop-filter name="EMAIL" test="allof" />',
+ ' <c:prop-filter name="FN">',
+ ' <c:is-not-defined />',
+ ' </c:prop-filter>',
+ ' </c:filter>',
+ ' <c:limit><c:nresults>4</c:nresults></c:limit>',
+ '</c:addressbook-query>'
+ );
+
+ $q = $this->parse($xml);
+
+ $this->assertEquals(
+ array(
+ array(
+ 'name' => 'NICKNAME',
+ 'test' => 'anyof',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'text-matches' => array(),
+ ),
+ array(
+ 'name' => 'EMAIL',
+ 'test' => 'allof',
+ 'is-not-defined' => false,
+ 'param-filters' => array(),
+ 'text-matches' => array(),
+ ),
+ array(
+ 'name' => 'FN',
+ 'test' => 'anyof',
+ 'is-not-defined' => true,
+ 'param-filters' => array(),
+ 'text-matches' => array(),
+ ),
+ ),
+ $q->filters
+ );
+
+ $this->assertEquals(4,$q->limit);
+ $this->assertEquals('allof', $q->test);
+
+ }
+
+ function testParamFilter() {
+
+ $xml = array(
+ '<?xml version="1.0"?>',
+ '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">',
+ ' <d:prop>',
+ ' <d:foo />',
+ ' </d:prop>',
+ ' <c:filter>',
+ ' <c:prop-filter name="NICKNAME">',
+ ' <c:param-filter name="BLA" />',
+ ' <c:param-filter name="BLA2">',
+ ' <c:is-not-defined />',
+ ' </c:param-filter>',
+ ' </c:prop-filter>',
+ ' </c:filter>',
+ '</c:addressbook-query>'
+ );
+
+ $q = $this->parse($xml);
+
+ $this->assertEquals(
+ array(
+ array(
+ 'name' => 'NICKNAME',
+ 'test' => 'anyof',
+ 'is-not-defined' => false,
+ 'param-filters' => array(
+ array(
+ 'name' => 'BLA',
+ 'is-not-defined' => false,
+ 'text-match' => null
+ ),
+ array(
+ 'name' => 'BLA2',
+ 'is-not-defined' => true,
+ 'text-match' => null
+ ),
+ ),
+ 'text-matches' => array(),
+ ),
+ ),
+ $q->filters
+ );
+
+ }
+
+ function testTextMatch() {
+
+ $xml = array(
+ '<?xml version="1.0"?>',
+ '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">',
+ ' <d:prop>',
+ ' <d:foo />',
+ ' </d:prop>',
+ ' <c:filter>',
+ ' <c:prop-filter name="NICKNAME">',
+ ' <c:text-match>evert</c:text-match>',
+ ' <c:text-match collation="i;octet">evert</c:text-match>',
+ ' <c:text-match negate-condition="yes">rene</c:text-match>',
+ ' <c:text-match match-type="starts-with">e</c:text-match>',
+ ' <c:param-filter name="BLA">',
+ ' <c:text-match>foo</c:text-match>',
+ ' </c:param-filter>',
+ ' </c:prop-filter>',
+ ' </c:filter>',
+ '</c:addressbook-query>'
+ );
+
+ $q = $this->parse($xml);
+
+ $this->assertEquals(
+ array(
+ array(
+ 'name' => 'NICKNAME',
+ 'test' => 'anyof',
+ 'is-not-defined' => false,
+ 'param-filters' => array(
+ array(
+ 'name' => 'BLA',
+ 'is-not-defined' => false,
+ 'text-match' => array(
+ 'negate-condition' => false,
+ 'collation' => 'i;unicode-casemap',
+ 'match-type' => 'contains',
+ 'value' => 'foo',
+ ),
+ ),
+ ),
+ 'text-matches' => array(
+ array(
+ 'negate-condition' => false,
+ 'collation' => 'i;unicode-casemap',
+ 'match-type' => 'contains',
+ 'value' => 'evert',
+ ),
+ array(
+ 'negate-condition' => false,
+ 'collation' => 'i;octet',
+ 'match-type' => 'contains',
+ 'value' => 'evert',
+ ),
+ array(
+ 'negate-condition' => true,
+ 'collation' => 'i;unicode-casemap',
+ 'match-type' => 'contains',
+ 'value' => 'rene',
+ ),
+ array(
+ 'negate-condition' => false,
+ 'collation' => 'i;unicode-casemap',
+ 'match-type' => 'starts-with',
+ 'value' => 'e',
+ ),
+ ),
+ ),
+ ),
+ $q->filters
+ );
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testBadTextMatch() {
+
+ $xml = array(
+ '<?xml version="1.0"?>',
+ '<c:addressbook-query xmlns:c="urn:ietf:params:xml:ns:carddav" xmlns:d="DAV:">',
+ ' <d:prop>',
+ ' <d:foo />',
+ ' </d:prop>',
+ ' <c:filter>',
+ ' <c:prop-filter name="NICKNAME">',
+ ' <c:text-match match-type="foo">evert</c:text-match>',
+ ' </c:prop-filter>',
+ ' </c:filter>',
+ '</c:addressbook-query>'
+ );
+
+ $q = $this->parse($xml);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php
new file mode 100644
index 000000000..c79f7e877
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php
@@ -0,0 +1,192 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+use Sabre\HTTP;
+use Sabre\DAV;
+
+require_once 'Sabre/CardDAV/AbstractPluginTest.php';
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class AddressBookQueryTest extends AbstractPluginTest {
+
+ function testQuery() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/addressbooks/user1/book1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody(
+'<?xml version="1.0"?>
+<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
+ <d:prop>
+ <d:getetag />
+ </d:prop>
+ <c:filter>
+ <c:prop-filter name="uid" />
+ </c:filter>
+</c:addressbook-query>'
+ );
+
+ $response = new HTTP\ResponseMock();
+
+ $this->server->httpRequest = $request;
+ $this->server->httpResponse = $response;
+
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status, 'Incorrect status code. Full response body:' . $response->body);
+
+ // using the client for parsing
+ $client = new DAV\Client(array('baseUri'=>'/'));
+
+ $result = $client->parseMultiStatus($response->body);
+
+ $this->assertEquals(array(
+ '/addressbooks/user1/book1/card1' => array(
+ 200 => array(
+ '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
+ ),
+ ),
+ '/addressbooks/user1/book1/card2' => array(
+ 404 => array(
+ '{DAV:}getetag' => null,
+ ),
+ )
+ ), $result);
+
+
+ }
+
+ function testQueryDepth0() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/addressbooks/user1/book1/card1',
+ 'HTTP_DEPTH' => '0',
+ ));
+
+ $request->setBody(
+'<?xml version="1.0"?>
+<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
+ <d:prop>
+ <d:getetag />
+ </d:prop>
+ <c:filter>
+ <c:prop-filter name="uid" />
+ </c:filter>
+</c:addressbook-query>'
+ );
+
+ $response = new HTTP\ResponseMock();
+
+ $this->server->httpRequest = $request;
+ $this->server->httpResponse = $response;
+
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status, 'Incorrect status code. Full response body:' . $response->body);
+
+ // using the client for parsing
+ $client = new DAV\Client(array('baseUri'=>'/'));
+
+ $result = $client->parseMultiStatus($response->body);
+
+ $this->assertEquals(array(
+ '/addressbooks/user1/book1/card1' => array(
+ 200 => array(
+ '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
+ ),
+ ),
+ ), $result);
+
+
+ }
+
+ function testQueryNoMatch() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/addressbooks/user1/book1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody(
+'<?xml version="1.0"?>
+<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
+ <d:prop>
+ <d:getetag />
+ </d:prop>
+ <c:filter>
+ <c:prop-filter name="email" />
+ </c:filter>
+</c:addressbook-query>'
+ );
+
+ $response = new HTTP\ResponseMock();
+
+ $this->server->httpRequest = $request;
+ $this->server->httpResponse = $response;
+
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status, 'Incorrect status code. Full response body:' . $response->body);
+
+ // using the client for parsing
+ $client = new DAV\Client(array('baseUri'=>'/'));
+
+ $result = $client->parseMultiStatus($response->body);
+
+ $this->assertEquals(array(), $result);
+
+ }
+
+ function testQueryLimit() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/addressbooks/user1/book1',
+ 'HTTP_DEPTH' => '1',
+ ));
+
+ $request->setBody(
+'<?xml version="1.0"?>
+<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
+ <d:prop>
+ <d:getetag />
+ </d:prop>
+ <c:filter>
+ <c:prop-filter name="uid" />
+ </c:filter>
+ <c:limit><c:nresults>1</c:nresults></c:limit>
+</c:addressbook-query>'
+ );
+
+ $response = new HTTP\ResponseMock();
+
+ $this->server->httpRequest = $request;
+ $this->server->httpResponse = $response;
+
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status, 'Incorrect status code. Full response body:' . $response->body);
+
+ // using the client for parsing
+ $client = new DAV\Client(array('baseUri'=>'/'));
+
+ $result = $client->parseMultiStatus($response->body);
+
+ $this->assertEquals(array(
+ '/addressbooks/user1/book1/card1' => array(
+ 200 => array(
+ '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD"). '"',
+ ),
+ ),
+ ), $result);
+
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookRootTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookRootTest.php
new file mode 100644
index 000000000..6eaff5db0
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookRootTest.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+use Sabre\DAVACL;
+
+class AddressBookRootTest extends \PHPUnit_Framework_TestCase {
+
+ function testGetName() {
+
+ $pBackend = new DAVACL\PrincipalBackend\Mock();
+ $cBackend = new Backend\Mock();
+ $root = new AddressBookRoot($pBackend, $cBackend);
+ $this->assertEquals('addressbooks', $root->getName());
+
+ }
+
+ function testGetChildForPrincipal() {
+
+ $pBackend = new DAVACL\PrincipalBackend\Mock();
+ $cBackend = new Backend\Mock();
+ $root = new AddressBookRoot($pBackend, $cBackend);
+
+ $children = $root->getChildren();
+ $this->assertEquals(3, count($children));
+
+ $this->assertInstanceOf('Sabre\\CardDAV\\UserAddressBooks', $children[0]);
+ $this->assertEquals('user1', $children[0]->getName());
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php
new file mode 100644
index 000000000..aac749b37
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php
@@ -0,0 +1,162 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+
+require_once 'Sabre/CardDAV/Backend/Mock.php';
+
+class AddressBookTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\CardDAV\AddressBook
+ */
+ protected $ab;
+ protected $backend;
+
+ function setUp() {
+
+ $this->backend = new Backend\Mock();
+ $this->ab = new AddressBook(
+ $this->backend,
+ array(
+ 'uri' => 'book1',
+ 'id' => 'foo',
+ '{DAV:}displayname' => 'd-name',
+ 'principaluri' => 'principals/user1',
+ )
+ );
+
+ }
+
+ function testGetName() {
+
+ $this->assertEquals('book1', $this->ab->getName());
+
+ }
+
+ function testGetChild() {
+
+ $card = $this->ab->getChild('card1');
+ $this->assertInstanceOf('Sabre\\CardDAV\\Card', $card);
+ $this->assertEquals('card1', $card->getName());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotFound
+ */
+ function testGetChildNotFound() {
+
+ $card = $this->ab->getChild('card3');
+
+ }
+
+ function testGetChildren() {
+
+ $cards = $this->ab->getChildren();
+ $this->assertEquals(2, count($cards));
+
+ $this->assertEquals('card1', $cards[0]->getName());
+ $this->assertEquals('card2', $cards[1]->getName());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testCreateDirectory() {
+
+ $this->ab->createDirectory('name');
+
+ }
+
+ function testCreateFile() {
+
+ $file = fopen('php://memory','r+');
+ fwrite($file,'foo');
+ rewind($file);
+ $this->ab->createFile('card2',$file);
+
+ $this->assertEquals('foo', $this->backend->cards['foo']['card2']);
+
+ }
+
+ function testDelete() {
+
+ $this->ab->delete();
+ $this->assertEquals(array(), $this->backend->addressBooks);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetName() {
+
+ $this->ab->setName('foo');
+
+ }
+
+ function testGetLastModified() {
+
+ $this->assertNull($this->ab->getLastModified());
+
+ }
+
+ function testUpdateProperties() {
+
+ $this->assertTrue(
+ $this->ab->updateProperties(array('{DAV:}displayname' => 'barrr'))
+ );
+
+ $this->assertEquals('barrr', $this->backend->addressBooks[0]['{DAV:}displayname']);
+
+ }
+
+ function testGetProperties() {
+
+ $props = $this->ab->getProperties(array('{DAV:}displayname'));
+ $this->assertEquals(array(
+ '{DAV:}displayname' => 'd-name',
+ ), $props);
+
+ }
+
+ function testACLMethods() {
+
+ $this->assertEquals('principals/user1', $this->ab->getOwner());
+ $this->assertNull($this->ab->getGroup());
+ $this->assertEquals(array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ ), $this->ab->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetACL() {
+
+ $this->ab->setACL(array());
+
+ }
+
+ function testGetSupportedPrivilegeSet() {
+
+ $this->assertNull(
+ $this->ab->getSupportedPrivilegeSet()
+ );
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php
new file mode 100644
index 000000000..623188d32
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php
@@ -0,0 +1,249 @@
+<?php
+
+namespace Sabre\CardDAV\Backend;
+
+use Sabre\CardDAV;
+
+abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var CardDAV\Backend\PDO
+ */
+ protected $backend;
+
+ /**
+ * @abstract
+ * @return PDO
+ */
+ abstract function getPDO();
+
+ public function setUp() {
+
+ $this->backend = new PDO($this->getPDO());
+
+ }
+
+ public function testGetAddressBooksForUser() {
+
+ $result = $this->backend->getAddressBooksForUser('principals/user1');
+
+ $expected = array(
+ array(
+ 'id' => 1,
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'book1',
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1',
+ '{http://calendarserver.org/ns/}getctag' => 1,
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}supported-address-data' => new CardDAV\Property\SupportedAddressData(),
+ )
+ );
+
+ $this->assertEquals($expected, $result);
+
+ }
+
+ public function testUpdateAddressBookInvalidProp() {
+
+ $result = $this->backend->updateAddressBook(1, array(
+ '{DAV:}displayname' => 'updated',
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'updated',
+ '{DAV:}foo' => 'bar',
+ ));
+
+ $this->assertFalse($result);
+
+ $result = $this->backend->getAddressBooksForUser('principals/user1');
+
+ $expected = array(
+ array(
+ 'id' => 1,
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'book1',
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1',
+ '{http://calendarserver.org/ns/}getctag' => 1,
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}supported-address-data' => new CardDAV\Property\SupportedAddressData(),
+ )
+ );
+
+ $this->assertEquals($expected, $result);
+
+ }
+
+ public function testUpdateAddressBookNoProps() {
+
+ $result = $this->backend->updateAddressBook(1, array());
+
+ $this->assertFalse($result);
+
+ $result = $this->backend->getAddressBooksForUser('principals/user1');
+
+ $expected = array(
+ array(
+ 'id' => 1,
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'book1',
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1',
+ '{http://calendarserver.org/ns/}getctag' => 1,
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}supported-address-data' => new CardDAV\Property\SupportedAddressData(),
+ )
+ );
+
+ $this->assertEquals($expected, $result);
+
+
+ }
+
+ public function testUpdateAddressBookSuccess() {
+
+ $result = $this->backend->updateAddressBook(1, array(
+ '{DAV:}displayname' => 'updated',
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'updated',
+ ));
+
+ $this->assertTrue($result);
+
+ $result = $this->backend->getAddressBooksForUser('principals/user1');
+
+ $expected = array(
+ array(
+ 'id' => 1,
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'updated',
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'updated',
+ '{http://calendarserver.org/ns/}getctag' => 2,
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}supported-address-data' => new CardDAV\Property\SupportedAddressData(),
+ )
+ );
+
+ $this->assertEquals($expected, $result);
+
+
+ }
+
+ public function testDeleteAddressBook() {
+
+ $this->backend->deleteAddressBook(1);
+
+ $this->assertEquals(array(), $this->backend->getAddressBooksForUser('principals/user1'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ public function testCreateAddressBookUnsupportedProp() {
+
+ $this->backend->createAddressBook('principals/user1','book2', array(
+ '{DAV:}foo' => 'bar',
+ ));
+
+ }
+
+ public function testCreateAddressBookSuccess() {
+
+ $this->backend->createAddressBook('principals/user1','book2', array(
+ '{DAV:}displayname' => 'book2',
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 2',
+ ));
+
+ $expected = array(
+ array(
+ 'id' => 1,
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'book1',
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1',
+ '{http://calendarserver.org/ns/}getctag' => 1,
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}supported-address-data' => new CardDAV\Property\SupportedAddressData(),
+ ),
+ array(
+ 'id' => 2,
+ 'uri' => 'book2',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'book2',
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 2',
+ '{http://calendarserver.org/ns/}getctag' => 1,
+ '{' . CardDAV\Plugin::NS_CARDDAV . '}supported-address-data' => new CardDAV\Property\SupportedAddressData(),
+ )
+ );
+ $result = $this->backend->getAddressBooksForUser('principals/user1');
+ $this->assertEquals($expected, $result);
+
+ }
+
+ public function testGetCards() {
+
+ $result = $this->backend->getCards(1);
+
+ $expected = array(
+ array(
+ 'id' => 1,
+ 'uri' => 'card1',
+ 'carddata' => 'card1',
+ 'lastmodified' => 0,
+ )
+ );
+
+ $this->assertEquals($expected, $result);
+
+ }
+
+ public function testGetCard() {
+
+ $result = $this->backend->getCard(1,'card1');
+
+ $expected = array(
+ 'id' => 1,
+ 'uri' => 'card1',
+ 'carddata' => 'card1',
+ 'lastmodified' => 0,
+ );
+
+ $this->assertEquals($expected, $result);
+
+ }
+
+ /**
+ * @depends testGetCard
+ */
+ public function testCreateCard() {
+
+ $result = $this->backend->createCard(1, 'card2', 'data2');
+ $this->assertEquals('"' . md5('data2') . '"', $result);
+ $result = $this->backend->getCard(1,'card2');
+ $this->assertEquals(2, $result['id']);
+ $this->assertEquals('card2', $result['uri']);
+ $this->assertEquals('data2', $result['carddata']);
+
+ }
+
+ /**
+ * @depends testGetCard
+ */
+ public function testUpdateCard() {
+
+ $result = $this->backend->updateCard(1, 'card1', 'newdata');
+ $this->assertEquals('"' . md5('newdata') . '"', $result);
+
+ $result = $this->backend->getCard(1,'card1');
+ $this->assertEquals(1, $result['id']);
+ $this->assertEquals('newdata', $result['carddata']);
+
+ }
+
+ /**
+ * @depends testGetCard
+ */
+ public function testDeleteCard() {
+
+ $this->backend->deleteCard(1, 'card1');
+ $result = $this->backend->getCard(1,'card1');
+ $this->assertFalse($result);
+
+ }
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php
new file mode 100644
index 000000000..ab7ac4e6a
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php
@@ -0,0 +1,130 @@
+<?php
+
+namespace Sabre\CardDAV\Backend;
+
+class Mock extends AbstractBackend {
+
+ public $addressBooks;
+ public $cards;
+
+ function __construct($addressBooks = null, $cards = null) {
+
+ $this->addressBooks = $addressBooks;
+ $this->cards = $cards;
+
+ if (is_null($this->addressBooks)) {
+ $this->addressBooks = array(
+ array(
+ 'id' => 'foo',
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'd-name',
+ ),
+ );
+
+ $card2 = fopen('php://memory','r+');
+ fwrite($card2,"BEGIN:VCARD\nVERSION:3.0\nUID:45678\nEND:VCARD");
+ rewind($card2);
+ $this->cards = array(
+ 'foo' => array(
+ 'card1' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD",
+ 'card2' => $card2,
+ ),
+ );
+ }
+
+ }
+
+
+ function getAddressBooksForUser($principalUri) {
+
+ $books = array();
+ foreach($this->addressBooks as $book) {
+ if ($book['principaluri'] === $principalUri) {
+ $books[] = $book;
+ }
+ }
+ return $books;
+
+ }
+
+ function updateAddressBook($addressBookId, array $mutations) {
+
+ foreach($this->addressBooks as &$book) {
+ if ($book['id'] !== $addressBookId)
+ continue;
+
+ foreach($mutations as $key=>$value) {
+ $book[$key] = $value;
+ }
+ return true;
+ }
+ return false;
+
+ }
+
+ function createAddressBook($principalUri, $url, array $properties) {
+
+ $this->addressBooks[] = array_merge($properties, array(
+ 'id' => $url,
+ 'uri' => $url,
+ 'principaluri' => $principalUri,
+ ));
+
+ }
+
+ function deleteAddressBook($addressBookId) {
+
+ foreach($this->addressBooks as $key=>$value) {
+ if ($value['id'] === $addressBookId)
+ unset($this->addressBooks[$key]);
+ }
+ unset($this->cards[$addressBookId]);
+
+ }
+
+ function getCards($addressBookId) {
+
+ $cards = array();
+ foreach($this->cards[$addressBookId] as $uri=>$data) {
+ $cards[] = array(
+ 'uri' => $uri,
+ 'carddata' => $data,
+ );
+ }
+ return $cards;
+
+ }
+
+ function getCard($addressBookId, $cardUri) {
+
+ if (!isset($this->cards[$addressBookId][$cardUri])) {
+ return false;
+ }
+
+ return array(
+ 'uri' => $cardUri,
+ 'carddata' => $this->cards[$addressBookId][$cardUri],
+ );
+
+ }
+
+ function createCard($addressBookId, $cardUri, $cardData) {
+
+ $this->cards[$addressBookId][$cardUri] = $cardData;
+
+ }
+
+ function updateCard($addressBookId, $cardUri, $cardData) {
+
+ $this->cards[$addressBookId][$cardUri] = $cardData;
+
+ }
+
+ function deleteCard($addressBookId, $cardUri) {
+
+ unset($this->cards[$addressBookId][$cardUri]);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php
new file mode 100644
index 000000000..b2f871f6e
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Sabre\CardDAV\Backend;
+
+require_once 'Sabre/TestUtil.php';
+
+class PDOMySQLTest extends AbstractPDOTest {
+
+ /**
+ * @return PDO
+ */
+ public function getPDO() {
+
+ if (!SABRE_HASMYSQL) $this->markTestSkipped('MySQL driver is not available, or not properly configured');
+
+ $pdo = \Sabre\TestUtil::getMySQLDB();
+ if (!$pdo) $this->markTestSkipped('Could not connect to MySQL database');
+
+ $pdo->query("DROP TABLE IF EXISTS addressbooks");
+ $pdo->query("DROP TABLE IF EXISTS cards");
+ $pdo->query("
+CREATE TABLE addressbooks (
+ id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ principaluri VARCHAR(255),
+ displayname VARCHAR(255),
+ uri VARCHAR(100),
+ description TEXT,
+ ctag INT(11) UNSIGNED NOT NULL DEFAULT '1'
+);
+");
+
+ $pdo->query("
+INSERT INTO addressbooks
+ (principaluri, displayname, uri, description, ctag)
+VALUES
+ ('principals/user1', 'book1', 'book1', 'addressbook 1', 1);
+");
+
+ $pdo->query("
+CREATE TABLE cards (
+ id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ addressbookid INT(11) UNSIGNED NOT NULL,
+ carddata TEXT,
+ uri VARCHAR(100),
+ lastmodified INT(11) UNSIGNED
+);
+");
+
+ $pdo->query("
+INSERT INTO cards
+ (addressbookid, carddata, uri, lastmodified)
+VALUES
+ (1, 'card1', 'card1', 0);
+");
+ return $pdo;
+
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php
new file mode 100644
index 000000000..a9bbb0bd1
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace Sabre\CardDAV\Backend;
+
+require_once 'Sabre/TestUtil.php';
+
+class PDOSqliteTest extends AbstractPDOTest {
+
+ function tearDown() {
+
+ if (file_exists(SABRE_TEMPDIR . '/pdobackend')) unlink(SABRE_TEMPDIR . '/pdobackend');
+ if (file_exists(SABRE_TEMPDIR . '/pdobackend2')) unlink(SABRE_TEMPDIR . '/pdobackend2');
+
+ }
+
+ /**
+ * @return PDO
+ */
+ function getPDO() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $pdo = new \PDO('sqlite:'.SABRE_TEMPDIR.'/pdobackend');
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
+
+ $pdo->query("DROP TABLE IF EXISTS addressbooks");
+ $pdo->query("DROP TABLE IF EXISTS cards");
+ $pdo->query("
+CREATE TABLE addressbooks (
+ id integer primary key asc,
+ principaluri text,
+ displayname text,
+ uri text,
+ description text,
+ ctag integer
+);
+
+");
+
+ $pdo->query("
+INSERT INTO addressbooks
+ (principaluri, displayname, uri, description, ctag)
+VALUES
+ ('principals/user1', 'book1', 'book1', 'addressbook 1', 1);
+");
+
+ $pdo->query("
+
+CREATE TABLE cards (
+ id integer primary key asc,
+ addressbookid integer,
+ carddata text,
+ uri text,
+ lastmodified integer
+);
+
+");
+ $pdo->query("
+INSERT INTO cards
+ (addressbookid, carddata, uri, lastmodified)
+VALUES
+ (1, 'card1', 'card1', 0);
+");
+
+ return $pdo;
+
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php
new file mode 100644
index 000000000..438bd2ea5
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php
@@ -0,0 +1,184 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+class CardTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\CardDAV\Card
+ */
+ protected $card;
+ /**
+ * @var Sabre\CardDAV\MockBackend
+ */
+ protected $backend;
+
+ function setUp() {
+
+ $this->backend = new Backend\Mock();
+ $this->card = new Card(
+ $this->backend,
+ array(
+ 'uri' => 'book1',
+ 'id' => 'foo',
+ 'principaluri' => 'principals/user1',
+ ),
+ array(
+ 'uri' => 'card1',
+ 'addressbookid' => 'foo',
+ 'carddata' => 'card',
+ )
+ );
+
+ }
+
+ function testGet() {
+
+ $result = $this->card->get();
+ $this->assertEquals('card', $result);
+
+ }
+ function testGet2() {
+
+ $this->card = new Card(
+ $this->backend,
+ array(
+ 'uri' => 'book1',
+ 'id' => 'foo',
+ 'principaluri' => 'principals/user1',
+ ),
+ array(
+ 'uri' => 'card1',
+ 'addressbookid' => 'foo',
+ )
+ );
+ $result = $this->card->get();
+ $this->assertEquals("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD", $result);
+
+ }
+
+
+ /**
+ * @depends testGet
+ */
+ function testPut() {
+
+ $file = fopen('php://memory','r+');
+ fwrite($file, 'newdata');
+ rewind($file);
+ $this->card->put($file);
+ $result = $this->card->get();
+ $this->assertEquals('newdata', $result);
+
+ }
+
+
+ function testDelete() {
+
+ $this->card->delete();
+ $this->assertEquals(1, count($this->backend->cards['foo']));
+
+ }
+
+ function testGetContentType() {
+
+ $this->assertEquals('text/x-vcard; charset=utf-8', $this->card->getContentType());
+
+ }
+
+ function testGetETag() {
+
+ $this->assertEquals('"' . md5('card') . '"' , $this->card->getETag());
+
+ }
+
+ function testGetETag2() {
+
+ $card = new Card(
+ $this->backend,
+ array(
+ 'uri' => 'book1',
+ 'id' => 'foo',
+ 'principaluri' => 'principals/user1',
+ ),
+ array(
+ 'uri' => 'card1',
+ 'addressbookid' => 'foo',
+ 'carddata' => 'card',
+ 'etag' => '"blabla"',
+ )
+ );
+ $this->assertEquals('"blabla"' , $card->getETag());
+
+ }
+
+ function testGetLastModified() {
+
+ $this->assertEquals(null, $this->card->getLastModified());
+
+ }
+
+ function testGetSize() {
+
+ $this->assertEquals(4, $this->card->getSize());
+ $this->assertEquals(4, $this->card->getSize());
+
+ }
+
+ function testGetSize2() {
+
+ $card = new Card(
+ $this->backend,
+ array(
+ 'uri' => 'book1',
+ 'id' => 'foo',
+ 'principaluri' => 'principals/user1',
+ ),
+ array(
+ 'uri' => 'card1',
+ 'addressbookid' => 'foo',
+ 'etag' => '"blabla"',
+ 'size' => 4,
+ )
+ );
+ $this->assertEquals(4, $card->getSize());
+
+ }
+
+ function testACLMethods() {
+
+ $this->assertEquals('principals/user1', $this->card->getOwner());
+ $this->assertNull($this->card->getGroup());
+ $this->assertEquals(array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ ), $this->card->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetACL() {
+
+ $this->card->setACL(array());
+
+ }
+
+ function testGetSupportedPrivilegeSet() {
+
+ $this->assertNull(
+ $this->card->getSupportedPrivilegeSet()
+ );
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php
new file mode 100644
index 000000000..431cd2524
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+use Sabre\DAV;
+
+class IDirectoryTest extends \PHPUnit_Framework_TestCase {
+
+ function testResourceType() {
+
+ $tree = array(
+ new DirectoryMock('directory')
+ );
+
+ $server = new DAV\Server($tree);
+ $plugin = new Plugin();
+ $server->addPlugin($plugin);
+
+ $props = $server->getProperties('directory', array('{DAV:}resourcetype'));
+ $this->assertTrue($props['{DAV:}resourcetype']->is('{' . Plugin::NS_CARDDAV . '}directory'));
+
+ }
+
+}
+
+class DirectoryMock extends DAV\SimpleCollection implements IDirectory {
+
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php
new file mode 100644
index 000000000..12922c6fd
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+use Sabre\HTTP;
+use Sabre\DAV;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class MultiGetTest extends AbstractPluginTest {
+
+ function testMultiGet() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_URI' => '/addressbooks/user1/book1',
+ ));
+
+ $request->setBody(
+'<?xml version="1.0"?>
+<c:addressbook-multiget xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
+ <d:prop>
+ <d:getetag />
+ <c:address-data />
+ </d:prop>
+ <d:href>/addressbooks/user1/book1/card1</d:href>
+</c:addressbook-multiget>'
+ );
+
+ $response = new HTTP\ResponseMock();
+
+ $this->server->httpRequest = $request;
+ $this->server->httpResponse = $response;
+
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status, 'Incorrect status code. Full response body:' . $response->body);
+
+ // using the client for parsing
+ $client = new DAV\Client(array('baseUri'=>'/'));
+
+ $result = $client->parseMultiStatus($response->body);
+
+ $this->assertEquals(array(
+ '/addressbooks/user1/book1/card1' => array(
+ 200 => array(
+ '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
+ '{urn:ietf:params:xml:ns:carddav}address-data' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD",
+ )
+ )
+ ), $result);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php
new file mode 100644
index 000000000..297ebf496
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php
@@ -0,0 +1,149 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+use Sabre\DAV;
+
+require_once 'Sabre/CardDAV/AbstractPluginTest.php';
+
+class PluginTest extends AbstractPluginTest {
+
+ function testConstruct() {
+
+ $this->assertEquals('card', $this->server->xmlNamespaces[Plugin::NS_CARDDAV]);
+ $this->assertEquals('{' . Plugin::NS_CARDDAV . '}addressbook', $this->server->resourceTypeMapping['Sabre\\CardDAV\\IAddressBook']);
+
+ $this->assertTrue(in_array('addressbook', $this->plugin->getFeatures()));
+
+ }
+
+ function testSupportedReportSet() {
+
+ $this->assertEquals(array(
+ '{' . Plugin::NS_CARDDAV . '}addressbook-multiget',
+ '{' . Plugin::NS_CARDDAV . '}addressbook-query',
+ ), $this->plugin->getSupportedReportSet('addressbooks/user1/book1'));
+
+ }
+
+ function testSupportedReportSetEmpty() {
+
+ $this->assertEquals(array(
+ ), $this->plugin->getSupportedReportSet(''));
+
+ }
+
+ function testAddressBookHomeSet() {
+
+ $result = $this->server->getProperties('principals/user1', array('{' . Plugin::NS_CARDDAV . '}addressbook-home-set'));
+
+ $this->assertEquals(1, count($result));
+ $this->assertTrue(isset($result['{' . Plugin::NS_CARDDAV . '}addressbook-home-set']));
+ $this->assertEquals('addressbooks/user1/', $result['{' . Plugin::NS_CARDDAV . '}addressbook-home-set']->getHref());
+
+ }
+
+ function testMeCardTest() {
+
+ $result = $this->server->getProperties(
+ 'addressbooks/user1',
+ array(
+ '{http://calendarserver.org/ns/}me-card',
+ )
+ );
+
+ $this->assertEquals(
+ array(
+ '{http://calendarserver.org/ns/}me-card' =>
+ new DAV\Property\Href('addressbooks/user1/book1/vcard1.vcf')
+ ),
+ $result
+ );
+
+ }
+
+ function testDirectoryGateway() {
+
+ $result = $this->server->getProperties('principals/user1', array('{' . Plugin::NS_CARDDAV . '}directory-gateway'));
+
+ $this->assertEquals(1, count($result));
+ $this->assertTrue(isset($result['{' . Plugin::NS_CARDDAV . '}directory-gateway']));
+ $this->assertEquals(array('directory'), $result['{' . Plugin::NS_CARDDAV . '}directory-gateway']->getHrefs());
+
+ }
+
+ function testReportPassThrough() {
+
+ $this->assertNull($this->plugin->report('{DAV:}foo', new \DomDocument()));
+
+ }
+
+ function testHTMLActionsPanel() {
+
+ $output = '';
+ $r = $this->server->broadcastEvent('onHTMLActionsPanel', array($this->server->tree->getNodeForPath('addressbooks/user1'), &$output));
+ $this->assertFalse($r);
+
+ $this->assertTrue(!!strpos($output,'Display name'));
+
+ }
+
+ function testBrowserPostAction() {
+
+ $r = $this->server->broadcastEvent('onBrowserPostAction', array('addressbooks/user1', 'mkaddressbook', array(
+ 'name' => 'NEWADDRESSBOOK',
+ '{DAV:}displayname' => 'foo',
+ )));
+ $this->assertFalse($r);
+
+ $addressbooks = $this->backend->getAddressBooksforUser('principals/user1');
+ $this->assertEquals(2, count($addressbooks));
+
+ $newAddressBook = null;
+ foreach($addressbooks as $addressbook) {
+ if ($addressbook['uri'] === 'NEWADDRESSBOOK') {
+ $newAddressBook = $addressbook;
+ break;
+ }
+ }
+ if (!$newAddressBook)
+ $this->fail('Could not find newly created addressbook');
+
+ }
+
+ function testUpdatePropertiesMeCard() {
+
+ $result = $this->server->updateProperties('addressbooks/user1', array(
+ '{http://calendarserver.org/ns/}me-card' => new DAV\Property\Href('/addressbooks/user1/book1/vcard2',true),
+ ));
+
+ $this->assertEquals(
+ array(
+ 'href' => 'addressbooks/user1',
+ 200 => array(
+ '{http://calendarserver.org/ns/}me-card' => null,
+ ),
+ ),
+ $result
+ );
+
+ }
+
+ function testUpdatePropertiesMeCardBadValue() {
+
+ $result = $this->server->updateProperties('addressbooks/user1', array(
+ '{http://calendarserver.org/ns/}me-card' => new DAV\Property\HrefList(array()),
+ ));
+
+ $this->assertEquals(
+ array(
+ 'href' => 'addressbooks/user1',
+ 400 => array(
+ '{http://calendarserver.org/ns/}me-card' => null,
+ ),
+ ),
+ $result
+ );
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Property/SupportedAddressDataTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Property/SupportedAddressDataTest.php
new file mode 100644
index 000000000..a0e4130d5
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Property/SupportedAddressDataTest.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Sabre\CardDAV\Property;
+
+use Sabre\CardDAV;
+use Sabre\DAV;
+
+class SupportedAddressDataDataTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $property = new SupportedAddressData();
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerialize() {
+
+ $property = new SupportedAddressData();
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElementNS(CardDAV\Plugin::NS_CARDDAV, 'card:root');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<card:root xmlns:card="' . CardDAV\Plugin::NS_CARDDAV . '" xmlns:d="DAV:">' .
+'<card:address-data-type content-type="text/vcard" version="3.0"/>' .
+//'<card:address-data-type content-type="text/vcard" version="4.0"/>' .
+'</card:root>
+', $xml);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php
new file mode 100644
index 000000000..2a62bd2f9
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+use Sabre\HTTP;
+
+class SogoStripContentType extends \Sabre\DAVServerTest {
+
+ protected $setupCardDAV = true;
+ protected $carddavAddressBooks = array(
+ array(
+ 'id' => 1,
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ ),
+ );
+ protected $carddavCards = array(
+ 1 => array(
+ 'card1.vcf' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD",
+ ),
+ );
+
+ function testDontStrip() {
+
+ $result = $this->server->getProperties('addressbooks/user1/book1/card1.vcf',array('{DAV:}getcontenttype'));
+ $this->assertEquals(array(
+ '{DAV:}getcontenttype' => 'text/x-vcard; charset=utf-8'
+ ), $result);
+
+ }
+ function testStrip() {
+
+ $this->server->httpRequest = new HTTP\Request(array(
+ 'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2 Lightning/1.2.1',
+ ));
+ $result = $this->server->getProperties('addressbooks/user1/book1/card1.vcf',array('{DAV:}getcontenttype'));
+ $this->assertEquals(array(
+ '{DAV:}getcontenttype' => 'text/x-vcard'
+ ), $result);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/TestUtil.php b/vendor/sabre/dav/tests/Sabre/CardDAV/TestUtil.php
new file mode 100644
index 000000000..9f84566af
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/TestUtil.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+use PDO;
+
+class TestUtil {
+
+ static function getBackend() {
+
+ $backend = new Backend\PDO(self::getSQLiteDB());
+ return $backend;
+
+ }
+
+ static function getSQLiteDB() {
+
+ if (file_exists(SABRE_TEMPDIR . '/testdb.sqlite'))
+ unlink(SABRE_TEMPDIR . '/testdb.sqlite');
+
+ $pdo = new PDO('sqlite:' . SABRE_TEMPDIR . '/testdb.sqlite');
+ $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
+
+ // Yup this is definitely not 'fool proof', but good enough for now.
+ $queries = explode(';', file_get_contents(__DIR__ . '/../../../examples/sql/sqlite.addressbooks.sql'));
+ foreach($queries as $query) {
+ $pdo->exec($query);
+ }
+ // Inserting events through a backend class.
+ $backend = new Backend\PDO($pdo);
+ $addressbookId = $backend->createAddressBook(
+ 'principals/user1',
+ 'UUID-123467',
+ array(
+ '{DAV:}displayname' => 'user1 addressbook',
+ '{urn:ietf:params:xml:ns:carddav}addressbook-description' => 'AddressBook description',
+ )
+ );
+ $backend->createAddressBook(
+ 'principals/user1',
+ 'UUID-123468',
+ array(
+ '{DAV:}displayname' => 'user1 addressbook2',
+ '{urn:ietf:params:xml:ns:carddav}addressbook-description' => 'AddressBook description',
+ )
+ );
+ $backend->createCard($addressbookId, 'UUID-2345', self::getTestCardData());
+ return $pdo;
+
+ }
+
+ static function getTestCardData($type = 1) {
+
+ $addressbookData = 'BEGIN:VCARD
+VERSION:3.0
+PRODID:-//Acme Inc.//RoadRunner 1.0//EN
+FN:Wile E. Coyote
+N:Coyote;Wile;Erroll;;
+ORG:Acme Inc.
+UID:39A6B5ED-DD51-4AFE-A683-C35EE3749627
+REV:2012-06-20T07:00:39+00:00
+END:VCARD';
+
+ return $addressbookData;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/UserAddressBooksTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/UserAddressBooksTest.php
new file mode 100644
index 000000000..a6ecf3e47
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/UserAddressBooksTest.php
@@ -0,0 +1,162 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+class UserAddressBooksTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\CardDAV\UserAddressBooks
+ */
+ protected $s;
+ protected $backend;
+
+ function setUp() {
+
+ $this->backend = new Backend\Mock();
+ $this->s = new UserAddressBooks(
+ $this->backend,
+ 'principals/user1'
+ );
+
+ }
+
+ function testGetName() {
+
+ $this->assertEquals('user1', $this->s->getName());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetName() {
+
+ $this->s->setName('user2');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testDelete() {
+
+ $this->s->delete();
+
+ }
+
+ function testGetLastModified() {
+
+ $this->assertNull($this->s->getLastModified());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testCreateFile() {
+
+ $this->s->createFile('bla');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testCreateDirectory() {
+
+ $this->s->createDirectory('bla');
+
+ }
+
+ function testGetChild() {
+
+ $child = $this->s->getChild('book1');
+ $this->assertInstanceOf('Sabre\\CardDAV\\AddressBook', $child);
+ $this->assertEquals('book1', $child->getName());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotFound
+ */
+ function testGetChild404() {
+
+ $this->s->getChild('book2');
+
+ }
+
+ function testGetChildren() {
+
+ $children = $this->s->getChildren();
+ $this->assertEquals(1, count($children));
+ $this->assertInstanceOf('Sabre\\CardDAV\\AddressBook', $children[0]);
+ $this->assertEquals('book1', $children[0]->getName());
+
+ }
+
+ function testCreateExtendedCollection() {
+
+ $resourceType = array(
+ '{' . Plugin::NS_CARDDAV . '}addressbook',
+ '{DAV:}collection',
+ );
+ $this->s->createExtendedCollection('book2', $resourceType, array('{DAV:}displayname' => 'a-book 2'));
+
+ $this->assertEquals(array(
+ 'id' => 'book2',
+ 'uri' => 'book2',
+ '{DAV:}displayname' => 'a-book 2',
+ 'principaluri' => 'principals/user1',
+ ), $this->backend->addressBooks[1]);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\InvalidResourceType
+ */
+ function testCreateExtendedCollectionInvalid() {
+
+ $resourceType = array(
+ '{DAV:}collection',
+ );
+ $this->s->createExtendedCollection('book2', $resourceType, array('{DAV:}displayname' => 'a-book 2'));
+
+ }
+
+
+ function testACLMethods() {
+
+ $this->assertEquals('principals/user1', $this->s->getOwner());
+ $this->assertNull($this->s->getGroup());
+ $this->assertEquals(array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/user1',
+ 'protected' => true,
+ ),
+ ), $this->s->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testSetACL() {
+
+ $this->s->setACL(array());
+
+ }
+
+ function testGetSupportedPrivilegeSet() {
+
+ $this->assertNull(
+ $this->s->getSupportedPrivilegeSet()
+ );
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php
new file mode 100644
index 000000000..84da59311
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+use Sabre\HTTP;
+
+class VCFExportTest extends \Sabre\DAVServerTest {
+
+ protected $setupCardDAV = true;
+ protected $autoLogin = 'user1';
+ protected $setupACL = true;
+
+ protected $carddavAddressBooks = array(
+ array(
+ 'id' => 'book1',
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ )
+ );
+ protected $carddavCards = array(
+ 'book1' => array(
+ "card1" => "BEGIN:VCARD\r\nFN:Person1\r\nEND:VCARD\r\n",
+ "card2" => "BEGIN:VCARD\r\nFN:Person2\r\nEND:VCARD",
+ "card3" => "BEGIN:VCARD\r\nFN:Person3\r\nEND:VCARD\r\n",
+ "card4" => "BEGIN:VCARD\nFN:Person4\nEND:VCARD\n",
+ )
+ );
+
+ function setUp() {
+
+ parent::setUp();
+ $this->server->addPlugin(
+ new VCFExportPlugin()
+ );
+
+ }
+
+ function testSimple() {
+
+ $this->assertInstanceOf('Sabre\\CardDAV\\VCFExportPlugin', $this->server->getPlugin('Sabre\\CardDAV\\VCFExportPlugin'));
+
+ }
+
+ function testExport() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_URI' => '/addressbooks/user1/book1?export',
+ 'QUERY_STRING' => 'export',
+ 'REQUEST_METHOD' => 'GET',
+ ));
+
+ $response = $this->request($request);
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status, $response->body);
+
+ $expected = "BEGIN:VCARD
+FN:Person1
+END:VCARD
+BEGIN:VCARD
+FN:Person2
+END:VCARD
+BEGIN:VCARD
+FN:Person3
+END:VCARD
+BEGIN:VCARD
+FN:Person4
+END:VCARD
+";
+ // We actually expected windows line endings
+ $expected = str_replace("\n","\r\n", $expected);
+
+ $this->assertEquals($expected, $response->body);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php
new file mode 100644
index 000000000..c87716c10
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php
@@ -0,0 +1,204 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+require_once 'Sabre/CardDAV/AbstractPluginTest.php';
+
+class ValidateFilterTest extends AbstractPluginTest {
+
+ /**
+ * @dataProvider data
+ */
+ function testFilter($input, $filters, $test, $result, $message = null) {
+
+ if ($result) {
+ $this->assertTrue($this->plugin->validateFilters($input, $filters, $test), $message);
+ } else {
+ $this->assertFalse($this->plugin->validateFilters($input, $filters, $test), $message);
+ }
+
+ }
+
+ function data() {
+
+ $body1 = <<<HELLO
+BEGIN:VCARD
+VERSION:3.0
+ORG:Company;
+TITLE:Title
+TEL;TYPE=IPHONE;TYPE=pref:(222) 22 22 22
+TEL;TYPE=HOME:(33) 333 66 66
+TEL;TYPE=WORK:(444) 44 44 44
+TEL;TYPE=MAIN:(55) 555 55 55
+ITEM4.TEL:(111) 11 11 11
+ITEM5.TEL:(6) 66 66 66 66
+ITEM6.TEL:(77) 777 77 77
+UID:3151DE6A-BC35-4612-B340-B53A034A2B27
+ITEM1.EMAIL:1111@111.com
+ITEM2.EMAIL:bbbbb@bbbb.com
+ITEM3.EMAIL:ccccc@ccccc.com
+FN:First Last
+N:Last;First;Middle;Dr
+BDAY:1985-07-20
+ADR;TYPE=HOME:;;Street;City;;3556;Montenegro
+ADR;TYPE=WORK:;;Street\\nStreet2;Harkema;;35444;Australia
+URL:http://google.com
+END:VCARD
+HELLO;
+
+ // Check if TITLE is defined
+ $filter1 =
+ array('name' => 'title', 'is-not-defined' => false, 'param-filters' => array(), 'text-matches' => array());
+
+ // Check if FOO is defined
+ $filter2 =
+ array('name' => 'foo', 'is-not-defined' => false, 'param-filters' => array(), 'text-matches' => array());
+
+ // Check if TITLE is not defined
+ $filter3 =
+ array('name' => 'title', 'is-not-defined' => true, 'param-filters' => array(), 'text-matches' => array());
+
+ // Check if FOO is not defined
+ $filter4 =
+ array('name' => 'foo', 'is-not-defined' => true, 'param-filters' => array(), 'text-matches' => array());
+
+ // Check if TEL[TYPE] is defined
+ $filter5 =
+ array(
+ 'name' => 'tel',
+ 'is-not-defined' => false,
+ 'test' => 'anyof',
+ 'param-filters' => array(
+ array(
+ 'name' => 'type',
+ 'is-not-defined' => false,
+ 'text-match' => null
+ ),
+ ),
+ 'text-matches' => array(),
+ );
+
+ // Check if TEL[FOO] is defined
+ $filter6 = $filter5;
+ $filter6['param-filters'][0]['name'] = 'FOO';
+
+ // Check if TEL[TYPE] is not defined
+ $filter7 = $filter5;
+ $filter7['param-filters'][0]['is-not-defined'] = true;
+
+ // Check if TEL[FOO] is not defined
+ $filter8 = $filter5;
+ $filter8['param-filters'][0]['name'] = 'FOO';
+ $filter8['param-filters'][0]['is-not-defined'] = true;
+
+ // Combining property filters
+ $filter9 = $filter5;
+ $filter9['param-filters'][] = $filter6['param-filters'][0];
+
+ $filter10 = $filter5;
+ $filter10['param-filters'][] = $filter6['param-filters'][0];
+ $filter10['test'] = 'allof';
+
+ // Check if URL contains 'google'
+ $filter11 =
+ array(
+ 'name' => 'url',
+ 'is-not-defined' => false,
+ 'test' => 'anyof',
+ 'param-filters' => array(),
+ 'text-matches' => array(
+ array(
+ 'match-type' => 'contains',
+ 'value' => 'google',
+ 'negate-condition' => false,
+ 'collation' => 'i;octet',
+ ),
+ ),
+ );
+
+ // Check if URL contains 'bing'
+ $filter12 = $filter11;
+ $filter12['text-matches'][0]['value'] = 'bing';
+
+ // Check if URL does not contain 'google'
+ $filter13 = $filter11;
+ $filter13['text-matches'][0]['negate-condition'] = true;
+
+ // Check if URL does not contain 'bing'
+ $filter14 = $filter11;
+ $filter14['text-matches'][0]['value'] = 'bing';
+ $filter14['text-matches'][0]['negate-condition'] = true;
+
+ // Param filter with text
+ $filter15 = $filter5;
+ $filter15['param-filters'][0]['text-match'] = array(
+ 'match-type' => 'contains',
+ 'value' => 'WORK',
+ 'collation' => 'i;octet',
+ 'negate-condition' => false,
+ );
+ $filter16 = $filter15;
+ $filter16['param-filters'][0]['text-match']['negate-condition'] = true;
+
+
+ // Param filter + text filter
+ $filter17 = $filter5;
+ $filter17['test'] = 'anyof';
+ $filter17['text-matches'][] = array(
+ 'match-type' => 'contains',
+ 'value' => '444',
+ 'collation' => 'i;octet',
+ 'negate-condition' => false,
+ );
+
+ $filter18 = $filter17;
+ $filter18['text-matches'][0]['negate-condition'] = true;
+
+ $filter18['test'] = 'allof';
+
+ return array(
+
+ // Basic filters
+ array($body1, array($filter1), 'anyof',true),
+ array($body1, array($filter2), 'anyof',false),
+ array($body1, array($filter3), 'anyof',false),
+ array($body1, array($filter4), 'anyof',true),
+
+ // Combinations
+ array($body1, array($filter1, $filter2), 'anyof',true),
+ array($body1, array($filter1, $filter2), 'allof',false),
+ array($body1, array($filter1, $filter4), 'anyof',true),
+ array($body1, array($filter1, $filter4), 'allof',true),
+ array($body1, array($filter2, $filter3), 'anyof',false),
+ array($body1, array($filter2, $filter3), 'allof',false),
+
+ // Basic parameters
+ array($body1, array($filter5), 'anyof', true, 'TEL;TYPE is defined, so this should return true'),
+ array($body1, array($filter6), 'anyof', false, 'TEL;FOO is not defined, so this should return false'),
+
+ array($body1, array($filter7), 'anyof', false, 'TEL;TYPE is defined, so this should return false'),
+ array($body1, array($filter8), 'anyof', true, 'TEL;TYPE is not defined, so this should return true'),
+
+ // Combined parameters
+ array($body1, array($filter9), 'anyof', true),
+ array($body1, array($filter10), 'anyof', false),
+
+ // Text-filters
+ array($body1, array($filter11), 'anyof', true),
+ array($body1, array($filter12), 'anyof', false),
+ array($body1, array($filter13), 'anyof', false),
+ array($body1, array($filter14), 'anyof', true),
+
+ // Param filter with text-match
+ array($body1, array($filter15), 'anyof', true),
+ array($body1, array($filter16), 'anyof', false),
+
+ // Param filter + text filter
+ array($body1, array($filter17), 'anyof', true),
+ array($body1, array($filter18), 'anyof', false),
+ array($body1, array($filter18), 'anyof', false),
+ );
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php
new file mode 100644
index 000000000..1f52f30a7
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php
@@ -0,0 +1,155 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+use Sabre\DAVACL;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class ValidateVCardTest extends \PHPUnit_Framework_TestCase {
+
+ protected $server;
+ protected $cardBackend;
+
+ function setUp() {
+
+ $addressbooks = array(
+ array(
+ 'id' => 'addressbook1',
+ 'principaluri' => 'principals/admin',
+ 'uri' => 'addressbook1',
+ )
+ );
+
+ $this->cardBackend = new Backend\Mock($addressbooks,array());
+ $principalBackend = new DAVACL\PrincipalBackend\Mock();
+
+ $tree = array(
+ new AddressBookRoot($principalBackend, $this->cardBackend),
+ );
+
+ $this->server = new DAV\Server($tree);
+ $this->server->debugExceptions = true;
+
+ $plugin = new Plugin();
+ $this->server->addPlugin($plugin);
+
+ $response = new HTTP\ResponseMock();
+ $this->server->httpResponse = $response;
+
+ }
+
+ function request(HTTP\Request $request) {
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ return $this->server->httpResponse;
+
+ }
+
+ function testCreateFile() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
+ ));
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 415 Unsupported Media Type', $response->status);
+
+ }
+
+ function testCreateFileValid() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
+ ));
+ $request->setBody("BEGIN:VCARD\r\nUID:foo\r\nEND:VCARD\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 201 Created', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+ $expected = array(
+ 'uri' => 'blabla.vcf',
+ 'carddata' => "BEGIN:VCARD\r\nUID:foo\r\nEND:VCARD\r\n",
+ );
+
+ $this->assertEquals($expected, $this->cardBackend->getCard('addressbook1','blabla.vcf'));
+
+ }
+
+ function testCreateFileNoUID() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
+ ));
+ $request->setBody("BEGIN:VCARD\r\nEND:VCARD\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 201 Created', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ $foo = $this->cardBackend->getCard('addressbook1','blabla.vcf');
+ $this->assertTrue(strpos($foo['carddata'],'UID')!==false);
+ }
+
+
+ function testCreateFileVCalendar() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
+ ));
+ $request->setBody("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n");
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 415 Unsupported Media Type', $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+
+ }
+
+ function testUpdateFile() {
+
+ $this->cardBackend->createCard('addressbook1','blabla.vcf','foo');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
+ ));
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 415 Unsupported Media Type', $response->status);
+
+ }
+
+ function testUpdateFileParsableBody() {
+
+ $this->cardBackend->createCard('addressbook1','blabla.vcf','foo');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
+ ));
+ $body = "BEGIN:VCARD\r\nUID:foo\r\nEND:VCARD\r\n";
+ $request->setBody($body);
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 204 No Content', $response->status);
+
+ $expected = array(
+ 'uri' => 'blabla.vcf',
+ 'carddata' => $body,
+ );
+
+ $this->assertEquals($expected, $this->cardBackend->getCard('addressbook1','blabla.vcf'));
+
+ }
+}
+
+?>
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/VersionTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/VersionTest.php
new file mode 100644
index 000000000..02943b2d3
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/VersionTest.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace Sabre\CardDAV;
+
+class VersionTest extends \PHPUnit_Framework_TestCase {
+
+ function testString() {
+
+ $v = Version::VERSION;
+ $this->assertEquals(-1, version_compare('0.1',$v));
+
+ $s = Version::STABILITY;
+ $this->assertTrue($s == 'alpha' || $s == 'beta' || $s =='stable');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php b/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php
new file mode 100644
index 000000000..357675686
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace Sabre\DAV;
+
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+abstract class AbstractServer extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\HTTP\ResponseMock
+ */
+ protected $response;
+ protected $request;
+ /**
+ * @var Sabre\DAV\Server
+ */
+ protected $server;
+ protected $tempDir = SABRE_TEMPDIR;
+
+ function setUp() {
+
+ $this->response = new HTTP\ResponseMock();
+ $this->server = new Server($this->getRootNode());
+ $this->server->httpResponse = $this->response;
+ $this->server->debugExceptions = true;
+ file_put_contents(SABRE_TEMPDIR . '/test.txt', 'Test contents');
+ mkdir(SABRE_TEMPDIR . '/dir');
+ file_put_contents(SABRE_TEMPDIR . '/dir/child.txt', 'Child contents');
+
+
+ }
+
+ function tearDown() {
+
+ $this->deleteTree(SABRE_TEMPDIR,false);
+
+ }
+
+ protected function getRootNode() {
+
+ return new FS\Directory(SABRE_TEMPDIR);
+
+ }
+
+ private function deleteTree($path,$deleteRoot = true) {
+
+ foreach(scandir($path) as $node) {
+
+ if ($node=='.' || $node=='.svn' || $node=='..') continue;
+ $myPath = $path.'/'. $node;
+ if (is_file($myPath)) {
+ unlink($myPath);
+ } else {
+ $this->deleteTree($myPath);
+ }
+
+ }
+ if ($deleteRoot) rmdir($path);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php
new file mode 100644
index 000000000..36d23c5c0
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php
@@ -0,0 +1,91 @@
+<?php
+
+namespace Sabre\DAV\Auth\Backend;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class AbstractBasicTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotAuthenticated
+ */
+ public function testAuthenticateNoHeaders() {
+
+ $response = new HTTP\ResponseMock();
+ $server = new DAV\Server();
+ $server->httpResponse = $response;
+
+ $backend = new AbstractBasicMock();
+ $backend->authenticate($server,'myRealm');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotAuthenticated
+ */
+ public function testAuthenticateUnknownUser() {
+
+ $response = new HTTP\ResponseMock();
+ $tree = new DAV\ObjectTree(new DAV\SimpleCollection('bla'));
+ $server = new DAV\Server($tree);
+ $server->httpResponse = $response;
+
+ $request = new HTTP\Request(array(
+ 'PHP_AUTH_USER' => 'username',
+ 'PHP_AUTH_PW' => 'wrongpassword',
+ ));
+ $server->httpRequest = $request;
+
+ $backend = new AbstractBasicMock();
+ $backend->authenticate($server,'myRealm');
+
+ }
+
+ public function testAuthenticate() {
+
+ $response = new HTTP\ResponseMock();
+ $tree = new DAV\ObjectTree(new DAV\SimpleCollection('bla'));
+ $server = new DAV\Server($tree);
+ $server->httpResponse = $response;
+
+ $request = new HTTP\Request(array(
+ 'PHP_AUTH_USER' => 'username',
+ 'PHP_AUTH_PW' => 'password',
+ ));
+ $server->httpRequest = $request;
+
+ $backend = new AbstractBasicMock();
+ $this->assertTrue($backend->authenticate($server,'myRealm'));
+
+ $result = $backend->getCurrentUser();
+
+ $this->assertEquals('username', $result);
+
+ }
+
+
+}
+
+
+class AbstractBasicMock extends AbstractBasic {
+
+ /**
+ * Validates a username and password
+ *
+ * This method should return true or false depending on if login
+ * succeeded.
+ *
+ * @param string $username
+ * @param string $password
+ * @return bool
+ */
+ function validateUserPass($username, $password) {
+
+ return ($username == 'username' && $password == 'password');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php
new file mode 100644
index 000000000..495690c4e
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php
@@ -0,0 +1,149 @@
+<?php
+
+namespace Sabre\DAV\Auth\Backend;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class AbstractDigestTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotAuthenticated
+ */
+ public function testAuthenticateNoHeaders() {
+
+ $response = new HTTP\ResponseMock();
+ $server = new DAV\Server();
+ $server->httpResponse = $response;
+
+ $backend = new AbstractDigestMock();
+ $backend->authenticate($server,'myRealm');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ */
+ public function testAuthenticateBadGetUserInfoResponse() {
+
+ $response = new HTTP\ResponseMock();
+ $server = new DAV\Server();
+ $server->httpResponse = $response;
+
+ $header = 'username=null, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1';
+ $request = new HTTP\Request(array(
+ 'PHP_AUTH_DIGEST' => $header,
+ ));
+ $server->httpRequest = $request;
+
+ $backend = new AbstractDigestMock();
+ $backend->authenticate($server,'myRealm');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ */
+ public function testAuthenticateBadGetUserInfoResponse2() {
+
+ $response = new HTTP\ResponseMock();
+ $server = new DAV\Server();
+ $server->httpResponse = $response;
+
+ $header = 'username=array, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1';
+ $request = new HTTP\Request(array(
+ 'PHP_AUTH_DIGEST' => $header,
+ ));
+ $server->httpRequest = $request;
+
+ $backend = new AbstractDigestMock();
+ $backend->authenticate($server,'myRealm');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotAuthenticated
+ */
+ public function testAuthenticateUnknownUser() {
+
+ $response = new HTTP\ResponseMock();
+ $server = new DAV\Server();
+ $server->httpResponse = $response;
+
+ $header = 'username=false, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1';
+ $request = new HTTP\Request(array(
+ 'PHP_AUTH_DIGEST' => $header,
+ ));
+ $server->httpRequest = $request;
+
+ $backend = new AbstractDigestMock();
+ $backend->authenticate($server,'myRealm');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotAuthenticated
+ */
+ public function testAuthenticateBadPassword() {
+
+ $response = new HTTP\ResponseMock();
+ $server = new DAV\Server();
+ $server->httpResponse = $response;
+
+ $header = 'username=user, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1';
+ $request = new HTTP\Request(array(
+ 'PHP_AUTH_DIGEST' => $header,
+ 'REQUEST_METHOD' => 'PUT',
+ ));
+ $server->httpRequest = $request;
+
+ $backend = new AbstractDigestMock();
+ $backend->authenticate($server,'myRealm');
+
+ }
+
+ public function testAuthenticate() {
+
+ $response = new HTTP\ResponseMock();
+ $server = new DAV\Server();
+ $server->httpResponse = $response;
+
+ $digestHash = md5('HELLO:12345:1:1:auth:' . md5('GET:/'));
+ $header = 'username=user, realm=myRealm, nonce=12345, uri=/, response='.$digestHash.', opaque=1, qop=auth, nc=1, cnonce=1';
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'GET',
+ 'PHP_AUTH_DIGEST' => $header,
+ 'REQUEST_URI' => '/',
+ ));
+ $server->httpRequest = $request;
+
+ $backend = new AbstractDigestMock();
+ $this->assertTrue($backend->authenticate($server,'myRealm'));
+
+ $result = $backend->getCurrentUser();
+
+ $this->assertEquals('user', $result);
+ $this->assertEquals('HELLO', $backend->getDigestHash('myRealm', $result));
+
+ }
+
+
+}
+
+
+class AbstractDigestMock extends AbstractDigest {
+
+ function getDigestHash($realm, $userName) {
+
+ switch($userName) {
+ case 'null' : return null;
+ case 'false' : return false;
+ case 'array' : return array();
+ case 'user' : return 'HELLO';
+ }
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php
new file mode 100644
index 000000000..d22923d51
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Sabre\DAV\Auth\Backend;
+
+use Sabre\DAV;
+
+abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
+
+ abstract function getPDO();
+
+ function testConstruct() {
+
+ $pdo = $this->getPDO();
+ $backend = new PDO($pdo);
+ $this->assertTrue($backend instanceof PDO);
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testUserInfo() {
+
+ $pdo = $this->getPDO();
+ $backend = new PDO($pdo);
+
+ $this->assertNull($backend->getDigestHash('realm','blabla'));
+
+ $expected = 'hash';
+
+ $this->assertEquals($expected, $backend->getDigestHash('realm','user'));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php
new file mode 100644
index 000000000..b1ed555d4
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Sabre\DAV\Auth\Backend;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+class ApacheTest extends \PHPUnit_Framework_TestCase {
+
+ function testConstruct() {
+
+ $backend = new Apache();
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ */
+ function testNoHeader() {
+
+ $server = new DAV\Server();
+ $backend = new Apache();
+ $backend->authenticate($server,'Realm');
+
+ }
+
+ function testRemoteUser() {
+
+ $backend = new Apache();
+
+ $server = new DAV\Server();
+ $request = new HTTP\Request(array(
+ 'REMOTE_USER' => 'username',
+ ));
+ $server->httpRequest = $request;
+
+ $this->assertTrue($backend->authenticate($server, 'Realm'));
+
+ $userInfo = 'username';
+
+ $this->assertEquals($userInfo, $backend->getCurrentUser());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php
new file mode 100644
index 000000000..72f150ab6
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Sabre\DAV\Auth\Backend;
+
+class FileTest extends \PHPUnit_Framework_TestCase {
+
+ function tearDown() {
+
+ if (file_exists(SABRE_TEMPDIR . '/filebackend')) unlink(SABRE_TEMPDIR .'/filebackend');
+
+ }
+
+ function testConstruct() {
+
+ $file = new File();
+ $this->assertTrue($file instanceof File);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ */
+ function testLoadFileBroken() {
+
+ file_put_contents(SABRE_TEMPDIR . '/backend','user:realm:hash');
+ $file = new File();
+ $file->loadFile(SABRE_TEMPDIR .'/backend');
+
+ }
+
+ function testLoadFile() {
+
+ file_put_contents(SABRE_TEMPDIR . '/backend','user:realm:' . md5('user:realm:password'));
+ $file = new File();
+ $file->loadFile(SABRE_TEMPDIR . '/backend');
+
+ $this->assertFalse($file->getDigestHash('realm','blabla'));
+ $this->assertEquals(md5('user:realm:password'), $file->getDigesthash('realm','user'));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php
new file mode 100644
index 000000000..fdad8a605
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Sabre\DAV\Auth\Backend;
+
+use Sabre\DAV;
+
+class Mock implements BackendInterface {
+
+ protected $currentUser;
+
+ public $defaultUser = 'admin';
+
+ /**
+ * @param Sabre\DAV\Server $server
+ * @param string $realm
+ * @throws Sabre\DAV\Exception\NotAuthenticated
+ */
+ function authenticate(DAV\Server $server, $realm) {
+
+ if ($realm=='failme') throw new DAV\Exception\NotAuthenticated('deliberate fail');
+ $this->currentUser = $this->defaultUser;
+
+ }
+
+ function setCurrentUser($user) {
+
+ $this->currentUser = $user;
+
+ }
+
+ function getCurrentUser() {
+
+ return $this->currentUser;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php
new file mode 100644
index 000000000..ede432de2
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Sabre\DAV\Auth\Backend;
+
+require_once 'Sabre/TestUtil.php';
+
+class PDOMySQLTest extends AbstractPDOTest {
+
+ function getPDO() {
+
+ if (!SABRE_HASMYSQL) $this->markTestSkipped('MySQL driver is not available, or not properly configured');
+ $pdo = \Sabre\TestUtil::getMySQLDB();
+ if (!$pdo) $this->markTestSkipped('Could not connect to MySQL database');
+ $pdo->query("DROP TABLE IF EXISTS users");
+ $pdo->query("
+create table users (
+ id integer unsigned not null primary key auto_increment,
+ username varchar(50),
+ digesta1 varchar(32),
+ email varchar(80),
+ displayname varchar(80),
+ unique(username)
+);");
+
+ $pdo->query("INSERT INTO users (username,digesta1,email,displayname) VALUES ('user','hash','user@example.org','User')");
+
+ return $pdo;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php
new file mode 100644
index 000000000..abfb031bb
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Sabre\DAV\Auth\Backend;
+
+require_once 'Sabre/DAV/Auth/Backend/AbstractPDOTest.php';
+
+class PDOSQLiteTest extends AbstractPDOTest {
+
+ function tearDown() {
+
+ if (file_exists(SABRE_TEMPDIR . '/pdobackend')) unlink(SABRE_TEMPDIR . '/pdobackend');
+ if (file_exists(SABRE_TEMPDIR . '/pdobackend2')) unlink(SABRE_TEMPDIR . '/pdobackend2');
+
+ }
+
+ function getPDO() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $pdo = new \PDO('sqlite:'.SABRE_TEMPDIR.'/pdobackend');
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
+ $pdo->query('CREATE TABLE users (username TEXT, digesta1 TEXT, email VARCHAR(80), displayname VARCHAR(80))');
+ $pdo->query('INSERT INTO users VALUES ("user","hash","user@example.org","User")');
+
+ return $pdo;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php
new file mode 100644
index 000000000..2096a04d7
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace Sabre\DAV\Auth;
+
+use Sabre\HTTP;
+use Sabre\DAV;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class PluginTest extends \PHPUnit_Framework_TestCase {
+
+ function testInit() {
+
+ $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla'));
+ $plugin = new Plugin(new Backend\Mock(),'realm');
+ $this->assertTrue($plugin instanceof Plugin);
+ $fakeServer->addPlugin($plugin);
+ $this->assertEquals($plugin, $fakeServer->getPlugin('auth'));
+
+ }
+
+ /**
+ * @depends testInit
+ */
+ function testAuthenticate() {
+
+ $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla'));
+ $plugin = new Plugin(new Backend\Mock(),'realm');
+ $fakeServer->addPlugin($plugin);
+ $fakeServer->broadCastEvent('beforeMethod',array('GET','/'));
+
+ }
+
+
+
+ /**
+ * @depends testInit
+ * @expectedException Sabre\DAV\Exception\NotAuthenticated
+ */
+ function testAuthenticateFail() {
+
+ $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla'));
+ $plugin = new Plugin(new Backend\Mock(),'failme');
+ $fakeServer->addPlugin($plugin);
+ $fakeServer->broadCastEvent('beforeMethod',array('GET','/'));
+
+ }
+
+ function testReportPassThrough() {
+
+ $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla'));
+ $plugin = new Plugin(new Backend\Mock(),'realm');
+ $fakeServer->addPlugin($plugin);
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'REQUEST_URI' => '/',
+ ));
+ $request->setBody('<?xml version="1.0"?><s:somereport xmlns:s="http://www.rooftopsolutions.nl/NS/example" />');
+
+ $fakeServer->httpRequest = $request;
+ $fakeServer->httpResponse = new HTTP\ResponseMock();
+ $fakeServer->exec();
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden', $fakeServer->httpResponse->status);
+
+ }
+
+ /**
+ * @depends testInit
+ */
+ function testGetCurrentUserPrincipal() {
+
+ $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla'));
+ $plugin = new Plugin(new Backend\Mock(),'realm');
+ $fakeServer->addPlugin($plugin);
+ $fakeServer->broadCastEvent('beforeMethod',array('GET','/'));
+ $this->assertEquals('admin', $plugin->getCurrentUser());
+
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php
new file mode 100644
index 000000000..fdc2403db
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php
@@ -0,0 +1,234 @@
+<?php
+
+namespace Sabre\DAV;
+
+class BasicNodeTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ public function testPut() {
+
+ $file = new FileMock();
+ $file->put('hi');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ public function testGet() {
+
+ $file = new FileMock();
+ $file->get();
+
+ }
+
+ public function testGetSize() {
+
+ $file = new FileMock();
+ $this->assertEquals(0,$file->getSize());
+
+ }
+
+
+ public function testGetETag() {
+
+ $file = new FileMock();
+ $this->assertNull($file->getETag());
+
+ }
+
+ public function testGetContentType() {
+
+ $file = new FileMock();
+ $this->assertNull($file->getContentType());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ public function testDelete() {
+
+ $file = new FileMock();
+ $file->delete();
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ public function testSetName() {
+
+ $file = new FileMock();
+ $file->setName('hi');
+
+ }
+
+ public function testGetLastModified() {
+
+ $file = new FileMock();
+ // checking if lastmod is within the range of a few seconds
+ $lastMod = $file->getLastModified();
+ $compareTime = ($lastMod + 1)-time();
+ $this->assertTrue($compareTime < 3);
+
+ }
+
+ public function testGetChild() {
+
+ $dir = new DirectoryMock();
+ $file = $dir->getChild('mockfile');
+ $this->assertTrue($file instanceof FileMock);
+
+ }
+
+ public function testChildExists() {
+
+ $dir = new DirectoryMock();
+ $this->assertTrue($dir->childExists('mockfile'));
+
+ }
+
+ public function testChildExistsFalse() {
+
+ $dir = new DirectoryMock();
+ $this->assertFalse($dir->childExists('mockfile2'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotFound
+ */
+ public function testGetChild404() {
+
+ $dir = new DirectoryMock();
+ $file = $dir->getChild('blabla');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ public function testCreateFile() {
+
+ $dir = new DirectoryMock();
+ $dir->createFile('hello','data');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\Forbidden
+ */
+ public function testCreateDirectory() {
+
+ $dir = new DirectoryMock();
+ $dir->createDirectory('hello');
+
+ }
+
+ public function testSimpleDirectoryConstruct() {
+
+ $dir = new SimpleCollection('simpledir',array());
+
+ }
+
+ /**
+ * @depends testSimpleDirectoryConstruct
+ */
+ public function testSimpleDirectoryConstructChild() {
+
+ $file = new FileMock();
+ $dir = new SimpleCollection('simpledir',array($file));
+ $file2 = $dir->getChild('mockfile');
+
+ $this->assertEquals($file,$file2);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ * @depends testSimpleDirectoryConstruct
+ */
+ public function testSimpleDirectoryBadParam() {
+
+ $dir = new SimpleCollection('simpledir',array('string shouldn\'t be here'));
+
+ }
+
+ /**
+ * @depends testSimpleDirectoryConstruct
+ */
+ public function testSimpleDirectoryAddChild() {
+
+ $file = new FileMock();
+ $dir = new SimpleCollection('simpledir');
+ $dir->addChild($file);
+ $file2 = $dir->getChild('mockfile');
+
+ $this->assertEquals($file,$file2);
+
+ }
+
+ /**
+ * @depends testSimpleDirectoryConstruct
+ * @depends testSimpleDirectoryAddChild
+ */
+ public function testSimpleDirectoryGetChildren() {
+
+ $file = new FileMock();
+ $dir = new SimpleCollection('simpledir');
+ $dir->addChild($file);
+
+ $this->assertEquals(array($file),$dir->getChildren());
+
+ }
+
+ /*
+ * @depends testSimpleDirectoryConstruct
+ */
+ public function testSimpleDirectoryGetName() {
+
+ $dir = new SimpleCollection('simpledir');
+ $this->assertEquals('simpledir',$dir->getName());
+
+ }
+
+ /**
+ * @depends testSimpleDirectoryConstruct
+ * @expectedException Sabre\DAV\Exception\NotFound
+ */
+ public function testSimpleDirectoryGetChild404() {
+
+ $dir = new SimpleCollection('simpledir');
+ $dir->getChild('blabla');
+
+ }
+}
+
+class DirectoryMock extends Collection {
+
+ function getName() {
+
+ return 'mockdir';
+
+ }
+
+ function getChildren() {
+
+ return array(new FileMock());
+
+ }
+
+}
+
+class FileMock extends File {
+
+ function getName() {
+
+ return 'mockfile';
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php
new file mode 100644
index 000000000..6fc65f9e8
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Sabre\DAV\Browser;
+
+use Sabre\DAV;
+
+require_once 'Sabre/DAV/AbstractServer.php';
+class GuessContentTypeTest extends DAV\AbstractServer {
+
+ function setUp() {
+
+ parent::setUp();
+ file_put_contents(SABRE_TEMPDIR . '/somefile.jpg','blabla');
+ file_put_contents(SABRE_TEMPDIR . '/somefile.hoi','blabla');
+
+ }
+
+ function tearDown() {
+
+ unlink(SABRE_TEMPDIR . '/somefile.jpg');
+ parent::tearDown();
+ }
+
+ function testGetProperties() {
+
+ $properties = array(
+ '{DAV:}getcontenttype',
+ );
+ $result = $this->server->getPropertiesForPath('/somefile.jpg',$properties);
+ $this->assertArrayHasKey(0,$result);
+ $this->assertArrayHasKey(404,$result[0]);
+ $this->assertArrayHasKey('{DAV:}getcontenttype',$result[0][404]);
+
+ }
+
+ /**
+ * @depends testGetProperties
+ */
+ function testGetPropertiesPluginEnabled() {
+
+ $this->server->addPlugin(new GuessContentType());
+ $properties = array(
+ '{DAV:}getcontenttype',
+ );
+ $result = $this->server->getPropertiesForPath('/somefile.jpg',$properties);
+ $this->assertArrayHasKey(0,$result);
+ $this->assertArrayHasKey(200,$result[0]);
+ $this->assertArrayHasKey('{DAV:}getcontenttype',$result[0][200]);
+ $this->assertEquals('image/jpeg',$result[0][200]['{DAV:}getcontenttype']);
+
+ }
+
+ /**
+ * @depends testGetPropertiesPluginEnabled
+ */
+ function testGetPropertiesUnknown() {
+
+ $this->server->addPlugin(new GuessContentType());
+ $properties = array(
+ '{DAV:}getcontenttype',
+ );
+ $result = $this->server->getPropertiesForPath('/somefile.hoi',$properties);
+ $this->assertArrayHasKey(0,$result);
+ $this->assertArrayHasKey(404,$result[0]);
+ $this->assertArrayHasKey('{DAV:}getcontenttype',$result[0][404]);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php
new file mode 100644
index 000000000..169675e7e
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Sabre\DAV\Browser;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/DAV/AbstractServer.php';
+
+class MapGetToPropFindTest extends DAV\AbstractServer {
+
+ function setUp() {
+
+ parent::setUp();
+ $this->server->addPlugin(new MapGetToPropFind());
+
+ }
+
+ function testCollectionGet() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'GET',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ 'DAV' => '1, 3, extended-mkcol',
+ 'Vary' => 'Brief,Prefer',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Incorrect status response received. Full response body: ' . $this->response->body);
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php
new file mode 100644
index 000000000..c3c4bdebb
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php
@@ -0,0 +1,114 @@
+<?php
+
+namespace Sabre\DAV\Browser;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/DAV/AbstractServer.php';
+
+class PluginTest extends DAV\AbstractServer{
+
+ function setUp() {
+
+ parent::setUp();
+ $this->server->addPlugin(new Plugin());
+
+ }
+
+ function testCollectionGet() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir',
+ 'REQUEST_METHOD' => 'GET',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'text/html; charset=utf-8',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertTrue(strpos($this->response->body, 'Index for dir/') !== false);
+ $this->assertTrue(strpos($this->response->body, '<a href="/dir/child.txt"><img src="/?sabreAction=asset&assetName=icons%2Ffile.png" alt="" width="24" />')!==false);
+
+ }
+
+ function testNotFound() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/random',
+ 'REQUEST_METHOD' => 'GET',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 404 Not Found',$this->response->status);
+
+ }
+
+ function testPostOtherContentType() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'POST',
+ 'CONTENT_TYPE' => 'text/xml',
+ );
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $this->response->status);
+
+ }
+
+ function testPostNoSabreAction() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'POST',
+ 'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
+ );
+ $postVars = array();
+
+ $request = new HTTP\Request($serverVars,$postVars);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented', $this->response->status);
+
+ }
+
+ function testPostMkCol() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'POST',
+ 'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
+ );
+ $postVars = array(
+ 'sabreAction' => 'mkcol',
+ 'name' => 'new_collection',
+ );
+
+ $request = new HTTP\Request($serverVars,$postVars);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 302 Found', $this->response->status);
+ $this->assertEquals(array(
+ 'Location' => '/',
+ ), $this->response->headers);
+
+ $this->assertTrue(is_dir(SABRE_TEMPDIR . '/new_collection'));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php b/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php
new file mode 100644
index 000000000..6e74e6ec0
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Sabre\DAV;
+
+class ClientMock extends Client {
+
+ public $response;
+
+ public $url;
+ public $curlSettings;
+
+ protected function curlRequest($url, $curlSettings) {
+
+ $this->url = $url;
+ $this->curlSettings = $curlSettings;
+ return $this->response;
+
+ }
+
+ /**
+ * Just making this method public
+ *
+ * @param string $url
+ * @return string
+ */
+ public function getAbsoluteUrl($url) {
+
+ return parent::getAbsoluteUrl($url);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php
new file mode 100644
index 000000000..9c3532a47
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php
@@ -0,0 +1,949 @@
+<?php
+
+namespace Sabre\DAV;
+
+require_once 'Sabre/DAV/ClientMock.php';
+
+class ClientTest extends \PHPUnit_Framework_TestCase {
+
+ function testConstruct() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => '/',
+ ));
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testConstructNoBaseUri() {
+
+ $client = new ClientMock(array());
+
+ }
+
+ function testRequest() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 45,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
+
+ $this->assertEquals('http://example.org/foo/bar/baz', $client->url);
+ $this->assertEquals(array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_CUSTOMREQUEST => 'POST',
+ CURLOPT_POSTFIELDS => 'sillybody',
+ CURLOPT_HEADER => true,
+ CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
+ ), $client->curlSettings);
+
+ $this->assertEquals(array(
+ 'statusCode' => 200,
+ 'headers' => array(
+ 'content-type' => 'text/plain',
+ ),
+ 'body' => 'Hello there!'
+ ), $result);
+
+
+ }
+
+
+ function testRequestProxy() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ 'proxy' => 'http://localhost:8000/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 45,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
+
+ $this->assertEquals('http://example.org/foo/bar/baz', $client->url);
+ $this->assertEquals(array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_CUSTOMREQUEST => 'POST',
+ CURLOPT_POSTFIELDS => 'sillybody',
+ CURLOPT_HEADER => true,
+ CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
+ CURLOPT_PROXY => 'http://localhost:8000/',
+ ), $client->curlSettings);
+
+ $this->assertEquals(array(
+ 'statusCode' => 200,
+ 'headers' => array(
+ 'content-type' => 'text/plain',
+ ),
+ 'body' => 'Hello there!'
+ ), $result);
+
+ }
+
+ function testRequestCAInfo() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 45,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $client->addTrustedCertificates('bla');
+
+ $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
+
+ $this->assertEquals('http://example.org/foo/bar/baz', $client->url);
+ $this->assertEquals(array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_CUSTOMREQUEST => 'POST',
+ CURLOPT_POSTFIELDS => 'sillybody',
+ CURLOPT_HEADER => true,
+ CURLOPT_CAINFO => 'bla',
+ CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
+ ), $client->curlSettings);
+
+ }
+
+ function testRequestSslPeer() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 45,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $client->setVerifyPeer(true);
+
+ $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
+
+ $this->assertEquals('http://example.org/foo/bar/baz', $client->url);
+ $this->assertEquals(array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_CUSTOMREQUEST => 'POST',
+ CURLOPT_POSTFIELDS => 'sillybody',
+ CURLOPT_HEADER => true,
+ CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
+ CURLOPT_SSL_VERIFYPEER => true
+ ), $client->curlSettings);
+
+ }
+
+ function testRequestAuth() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ 'userName' => 'user',
+ 'password' => 'password',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 45,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
+
+ $this->assertEquals('http://example.org/foo/bar/baz', $client->url);
+ $this->assertEquals(array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_CUSTOMREQUEST => 'POST',
+ CURLOPT_POSTFIELDS => 'sillybody',
+ CURLOPT_HEADER => true,
+ CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
+ CURLOPT_HTTPAUTH => CURLAUTH_BASIC | CURLAUTH_DIGEST,
+ CURLOPT_USERPWD => 'user:password'
+ ), $client->curlSettings);
+
+ $this->assertEquals(array(
+ 'statusCode' => 200,
+ 'headers' => array(
+ 'content-type' => 'text/plain',
+ ),
+ 'body' => 'Hello there!'
+ ), $result);
+
+ }
+
+ function testRequestAuthBasic() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ 'userName' => 'user',
+ 'password' => 'password',
+ 'authType' => Client::AUTH_BASIC,
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 45,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
+
+ $this->assertEquals('http://example.org/foo/bar/baz', $client->url);
+ $this->assertEquals(array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_CUSTOMREQUEST => 'POST',
+ CURLOPT_POSTFIELDS => 'sillybody',
+ CURLOPT_HEADER => true,
+ CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
+ CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
+ CURLOPT_USERPWD => 'user:password'
+ ), $client->curlSettings);
+
+ $this->assertEquals(array(
+ 'statusCode' => 200,
+ 'headers' => array(
+ 'content-type' => 'text/plain',
+ ),
+ 'body' => 'Hello there!'
+ ), $result);
+
+ }
+
+ function testRequestAuthDigest() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ 'userName' => 'user',
+ 'password' => 'password',
+ 'authType' => Client::AUTH_DIGEST,
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 45,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $result = $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
+
+ $this->assertEquals('http://example.org/foo/bar/baz', $client->url);
+ $this->assertEquals(array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_CUSTOMREQUEST => 'POST',
+ CURLOPT_POSTFIELDS => 'sillybody',
+ CURLOPT_HEADER => true,
+ CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
+ CURLOPT_HTTPAUTH => CURLAUTH_DIGEST,
+ CURLOPT_USERPWD => 'user:password'
+ ), $client->curlSettings);
+
+ $this->assertEquals(array(
+ 'statusCode' => 200,
+ 'headers' => array(
+ 'content-type' => 'text/plain',
+ ),
+ 'body' => 'Hello there!'
+ ), $result);
+
+ }
+ function testRequestError() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 45,
+ 'http_code' => 200,
+ ),
+ CURLE_COULDNT_CONNECT,
+ "Could not connect, or something"
+ );
+
+ $caught = false;
+ try {
+ $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
+ } catch (Exception $e) {
+ $caught = true;
+ }
+ if (!$caught) {
+ $this->markTestFailed('Exception was not thrown');
+ }
+
+ }
+
+ function testRequestHTTPError() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 400 Bad Request",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 45,
+ 'http_code' => 400,
+ ),
+ 0,
+ ""
+ );
+
+ $caught = false;
+ try {
+ $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
+ } catch (Exception $e) {
+ $caught = true;
+ }
+ if (!$caught) {
+ $this->fail('Exception was not thrown');
+ }
+
+ }
+
+ function testRequestHTTP404() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 404 Not Found",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 45,
+ 'http_code' => 404,
+ ),
+ 0,
+ ""
+ );
+
+ $caught = false;
+ try {
+ $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
+ } catch (Exception\NotFound $e) {
+ $caught = true;
+ }
+ if (!$caught) {
+ $this->fail('Exception was not thrown');
+ }
+
+ }
+
+ /**
+ * @dataProvider supportedHTTPCodes
+ */
+ function testSpecificHTTPErrors($error) {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 $error blabla",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 42,
+ 'http_code' => $error,
+ ),
+ 0,
+ ""
+ );
+
+ try {
+ $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
+ $this->fail('Exception was not thrown');
+ } catch (Exception $e) {
+ $this->assertEquals($e->getHTTPCode(), $error);
+ }
+
+
+ }
+
+ public function supportedHTTPCodes() {
+
+ return array(
+ array(400),
+ array(401),
+ array(402),
+ array(403),
+ array(404),
+ array(405),
+ array(409),
+ array(412),
+ array(416),
+ array(500),
+ array(501),
+ array(507),
+ );
+
+ }
+
+ function testUnsupportedHTTPError() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 580 blabla",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 42,
+ 'http_code' => "580"
+ ),
+ 0,
+ ""
+ );
+
+ try {
+ $client->request('POST', 'baz', 'sillybody', array('Content-Type' => 'text/plain'));
+ $this->fail('Exception was not thrown');
+ } catch (Exception $e) {
+ $this->assertEquals(500, $e->getHTTPCode());
+ }
+
+
+ }
+
+ function testGetAbsoluteUrl() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/',
+ ));
+
+ $this->assertEquals(
+ 'http://example.org/foo/bar',
+ $client->getAbsoluteUrl('bar')
+ );
+
+ $this->assertEquals(
+ 'http://example.org/bar',
+ $client->getAbsoluteUrl('/bar')
+ );
+
+ $this->assertEquals(
+ 'http://example.com/bar',
+ $client->getAbsoluteUrl('http://example.com/bar')
+ );
+
+ }
+
+ function testOptions() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "DAV: feature1, feature2",
+ "",
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 40,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $result = $client->options();
+ $this->assertEquals(
+ array('feature1', 'feature2'),
+ $result
+ );
+
+ }
+
+ function testOptionsNoDav() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "",
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 20,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $result = $client->options();
+ $this->assertEquals(
+ array(),
+ $result
+ );
+
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testPropFindNoXML() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "",
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 20,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $client->propfind('', array('{DAV:}foo','{DAV:}bar'));
+
+ }
+
+ function testPropFind() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "",
+ "<?xml version=\"1.0\"?>",
+ "<d:multistatus xmlns:d=\"DAV:\">",
+ " <d:response>",
+ " <d:href>/foo/bar/</d:href>",
+ " <d:propstat>",
+ " <d:prop>",
+ " <d:foo>hello</d:foo>",
+ " </d:prop>",
+ " <d:status>HTTP/1.1 200 OK</d:status>",
+ " </d:propstat>",
+ " <d:propstat>",
+ " <d:prop>",
+ " <d:bar />",
+ " </d:prop>",
+ " <d:status>HTTP/1.1 404 Not Found</d:status>",
+ " </d:propstat>",
+ " </d:response>",
+ "</d:multistatus>",
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 19,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $result = $client->propfind('', array('{DAV:}foo','{DAV:}bar'));
+
+ $this->assertEquals(array(
+ '{DAV:}foo' => 'hello',
+ ), $result);
+
+ $requestBody = array(
+ '<?xml version="1.0"?>',
+ '<d:propfind xmlns:d="DAV:">',
+ ' <d:prop>',
+ ' <d:foo />',
+ ' <d:bar />',
+ ' </d:prop>',
+ '</d:propfind>'
+ );
+ $requestBody = implode("\n", $requestBody);
+
+ $this->assertEquals($requestBody, $client->curlSettings[CURLOPT_POSTFIELDS]);
+
+ }
+
+ /**
+ * This was reported in Issue 235.
+ *
+ * If no '200 Ok' properties are returned, the client will throw an
+ * E_NOTICE.
+ */
+ function testPropFindNo200s() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "",
+ "<?xml version=\"1.0\"?>",
+ "<d:multistatus xmlns:d=\"DAV:\">",
+ " <d:response>",
+ " <d:href>/foo/bar/</d:href>",
+ " <d:propstat>",
+ " <d:prop>",
+ " <d:bar />",
+ " </d:prop>",
+ " <d:status>HTTP/1.1 404 Not Found</d:status>",
+ " </d:propstat>",
+ " </d:response>",
+ "</d:multistatus>",
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 19,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $result = $client->propfind('', array('{DAV:}foo','{DAV:}bar'));
+
+ $this->assertEquals(array(
+ ), $result);
+
+ }
+
+ function testPropFindDepth1CustomProp() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "",
+ "<?xml version=\"1.0\"?>",
+ "<d:multistatus xmlns:d=\"DAV:\" xmlns:x=\"urn:custom\">",
+ " <d:response>",
+ " <d:href>/foo/bar/</d:href>",
+ " <d:propstat>",
+ " <d:prop>",
+ " <d:foo>hello</d:foo>",
+ " <x:bar>world</x:bar>",
+ " </d:prop>",
+ " <d:status>HTTP/1.1 200 OK</d:status>",
+ " </d:propstat>",
+ " </d:response>",
+ "</d:multistatus>",
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 19,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $result = $client->propfind('', array('{DAV:}foo','{urn:custom}bar'),1);
+
+ $this->assertEquals(array(
+ "/foo/bar/" => array(
+ '{DAV:}foo' => 'hello',
+ '{urn:custom}bar' => 'world',
+ ),
+ ), $result);
+
+ $requestBody = array(
+ '<?xml version="1.0"?>',
+ '<d:propfind xmlns:d="DAV:">',
+ ' <d:prop>',
+ ' <d:foo />',
+ ' <x:bar xmlns:x="urn:custom"/>',
+ ' </d:prop>',
+ '</d:propfind>'
+ );
+ $requestBody = implode("\n", $requestBody);
+
+ $this->assertEquals($requestBody, $client->curlSettings[CURLOPT_POSTFIELDS]);
+
+ }
+
+ function testPropPatch() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "",
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 20,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $client->proppatch('', array(
+ '{DAV:}foo' => 'newvalue',
+ '{urn:custom}foo' => 'newvalue2',
+ '{DAV:}bar' => null,
+ '{urn:custom}bar' => null,
+ ));
+
+ $requestBody = array(
+ '<?xml version="1.0"?>',
+ '<d:propertyupdate xmlns:d="DAV:">',
+ '<d:set><d:prop>',
+ ' <d:foo>newvalue</d:foo>',
+ '</d:prop></d:set>',
+ '<d:set><d:prop>',
+ ' <x:foo xmlns:x="urn:custom">newvalue2</x:foo>',
+ '</d:prop></d:set>',
+ '<d:remove><d:prop>',
+ ' <d:bar />',
+ '</d:prop></d:remove>',
+ '<d:remove><d:prop>',
+ ' <x:bar xmlns:x="urn:custom"/>',
+ '</d:prop></d:remove>',
+ '</d:propertyupdate>'
+ );
+ $requestBody = implode("\n", $requestBody);
+
+ $this->assertEquals($requestBody, $client->curlSettings[CURLOPT_POSTFIELDS]);
+
+ }
+
+ function testHEADRequest() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 45,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $result = $client->request('HEAD', 'baz');
+
+ $this->assertEquals('http://example.org/foo/bar/baz', $client->url);
+ $this->assertEquals(array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_CUSTOMREQUEST => 'HEAD',
+ CURLOPT_NOBODY => true,
+ CURLOPT_HEADER => true,
+ CURLOPT_HTTPHEADER => array(),
+ CURLOPT_POSTFIELDS => null,
+ ), $client->curlSettings);
+
+ }
+
+ function testPUTRequest() {
+
+ $client = new ClientMock(array(
+ 'baseUri' => 'http://example.org/foo/bar/',
+ ));
+
+ $responseBlob = array(
+ "HTTP/1.1 200 OK",
+ "Content-Type: text/plain",
+ "",
+ "Hello there!"
+ );
+
+ $client->response = array(
+ implode("\r\n", $responseBlob),
+ array(
+ 'header_size' => 45,
+ 'http_code' => 200,
+ ),
+ 0,
+ ""
+ );
+
+ $result = $client->request('PUT', 'bar','newcontent');
+
+ $this->assertEquals('http://example.org/foo/bar/bar', $client->url);
+ $this->assertEquals(array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_CUSTOMREQUEST => "PUT",
+ CURLOPT_POSTFIELDS => 'newcontent',
+ CURLOPT_HEADER => true,
+ CURLOPT_HTTPHEADER => array(),
+ ), $client->curlSettings);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php
new file mode 100644
index 000000000..c06d6aa1f
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Sabre\DAV\Exception;
+
+use
+ Sabre\DAV,
+ DOMDocument;
+
+class LockedTest extends \PHPUnit_Framework_TestCase {
+
+ function testSerialize() {
+
+ $dom = new DOMDocument('1.0');
+ $dom->formatOutput = true;
+ $root = $dom->createElement('d:root');
+
+ $dom->appendChild($root);
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $lockInfo = new DAV\Locks\LockInfo();
+ $lockInfo->uri = '/foo';
+ $locked = new Locked($lockInfo);
+
+ $locked->serialize(new DAV\Server(), $root);
+
+ $output = $dom->saveXML();
+
+ $expected = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">
+ <d:lock-token-submitted xmlns:d="DAV:">
+ <d:href>/foo</d:href>
+ </d:lock-token-submitted>
+</d:root>
+';
+
+ $this->assertEquals($expected, $output);
+
+ }
+
+ function testSerializeAmpersand() {
+
+ $dom = new DOMDocument('1.0');
+ $dom->formatOutput = true;
+ $root = $dom->createElement('d:root');
+
+ $dom->appendChild($root);
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $lockInfo = new DAV\Locks\LockInfo();
+ $lockInfo->uri = '/foo&bar';
+ $locked = new Locked($lockInfo);
+
+ $locked->serialize(new DAV\Server(), $root);
+
+ $output = $dom->saveXML();
+
+ $expected = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">
+ <d:lock-token-submitted xmlns:d="DAV:">
+ <d:href>/foo&amp;bar</d:href>
+ </d:lock-token-submitted>
+</d:root>
+';
+
+ $this->assertEquals($expected, $output);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Exception/PaymentRequiredTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Exception/PaymentRequiredTest.php
new file mode 100644
index 000000000..7142937b4
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Exception/PaymentRequiredTest.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Sabre\DAV\Exception;
+
+class PaymentRequiredTest extends \PHPUnit_Framework_TestCase {
+
+ function testGetHTTPCode() {
+
+ $ex = new PaymentRequired();
+ $this->assertEquals(402, $ex->getHTTPCode());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php
new file mode 100644
index 000000000..6d6bf5668
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Sabre\DAV;
+
+class ExceptionTest extends \PHPUnit_Framework_TestCase {
+
+ function testStatus() {
+
+ $e = new Exception();
+ $this->assertEquals(500,$e->getHTTPCode());
+
+ }
+
+ function testExceptionStatuses() {
+
+ $c = array(
+ 'Sabre\\DAV\\Exception\\NotAuthenticated' => 401,
+ 'Sabre\\DAV\\Exception\\InsufficientStorage' => 507,
+ );
+
+ foreach($c as $class=>$status) {
+
+ $obj = new $class();
+ $this->assertEquals($status, $obj->getHTTPCode());
+
+ }
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php
new file mode 100644
index 000000000..265f9f1c1
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php
@@ -0,0 +1,95 @@
+<?php
+
+namespace Sabre\DAV\FSExt;
+
+use Sabre\DAV;
+
+require_once 'Sabre/TestUtil.php';
+
+class FileTest extends \PHPUnit_Framework_TestCase {
+
+ function setUp() {
+
+ file_put_contents(SABRE_TEMPDIR . '/file.txt', 'Contents');
+
+ }
+
+ function tearDown() {
+
+ \Sabre\TestUtil::clearTempDir();
+
+ }
+
+ function testPut() {
+
+ $file = new File(SABRE_TEMPDIR . '/file.txt');
+ $result = $file->put('New contents');
+
+ $this->assertEquals('New contents',file_get_contents(SABRE_TEMPDIR . '/file.txt'));
+ $this->assertEquals('"' . md5('New contents') . '"', $result);
+
+ }
+
+ function testRange() {
+
+ $file = new File(SABRE_TEMPDIR . '/file.txt');
+ $file->put('0000000');
+ $file->putRange('111',3);
+
+ $this->assertEquals('0011100',file_get_contents(SABRE_TEMPDIR . '/file.txt'));
+
+ }
+
+ function testRangeStream() {
+
+ $stream = fopen('php://memory','r+');
+ fwrite($stream, "222");
+ rewind($stream);
+
+ $file = new File(SABRE_TEMPDIR . '/file.txt');
+ $file->put('0000000');
+ $file->putRange($stream,3);
+
+ $this->assertEquals('0022200',file_get_contents(SABRE_TEMPDIR . '/file.txt'));
+
+ }
+
+
+ function testGet() {
+
+ $file = new File(SABRE_TEMPDIR . '/file.txt');
+ $this->assertEquals('Contents',stream_get_contents($file->get()));
+
+ }
+
+ function testDelete() {
+
+ $file = new File(SABRE_TEMPDIR . '/file.txt');
+ $file->delete();
+
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/file.txt'));
+
+ }
+
+ function testGetETag() {
+
+ $file = new File(SABRE_TEMPDIR . '/file.txt');
+ $this->assertEquals('"' . md5('Contents') . '"',$file->getETag());
+
+ }
+
+ function testGetContentType() {
+
+ $file = new File(SABRE_TEMPDIR . '/file.txt');
+ $this->assertNull($file->getContentType());
+
+ }
+
+ function testGetSize() {
+
+ $file = new File(SABRE_TEMPDIR . '/file.txt');
+ $this->assertEquals(8,$file->getSize());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/NodeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/NodeTest.php
new file mode 100644
index 000000000..275075b4c
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/NodeTest.php
@@ -0,0 +1,178 @@
+<?php
+
+namespace Sabre\DAV\FSExt;
+use Sabre\DAV;
+
+require_once 'Sabre/TestUtil.php';
+
+class NodeTest extends \PHPUnit_Framework_TestCase {
+
+ function setUp() {
+
+ mkdir(SABRE_TEMPDIR . '/dir');
+ file_put_contents(SABRE_TEMPDIR . '/dir/file.txt', 'Contents');
+ file_put_contents(SABRE_TEMPDIR . '/dir/file2.txt', 'Contents2');
+
+ }
+
+ function tearDown() {
+
+ \Sabre\TestUtil::clearTempDir();
+
+ }
+
+ function testUpdateProperties() {
+
+ $file = new File(SABRE_TEMPDIR . '/dir/file.txt');
+ $properties = array(
+ '{http://sabredav.org/NS/2010}test1' => 'foo',
+ '{http://sabredav.org/NS/2010}test2' => 'bar',
+ );
+
+ $result = $file->updateProperties($properties);
+ $expected = true;
+
+ $this->assertEquals($expected, $result);
+
+ $getProperties = $file->getProperties(array_keys($properties));
+
+ $this->assertEquals($properties, $getProperties);
+
+ }
+
+ /**
+ * @depends testUpdateProperties
+ */
+ function testUpdatePropertiesAgain() {
+
+ $file = new File(SABRE_TEMPDIR . '/dir/file.txt');
+ $mutations = array(
+ '{http://sabredav.org/NS/2010}test1' => 'foo',
+ '{http://sabredav.org/NS/2010}test2' => 'bar',
+ );
+
+ $result = $file->updateProperties($mutations);
+
+ $this->assertEquals(true, $result);
+
+ $mutations = array(
+ '{http://sabredav.org/NS/2010}test1' => 'foo',
+ '{http://sabredav.org/NS/2010}test3' => 'baz',
+ );
+
+ $result = $file->updateProperties($mutations);
+
+ $this->assertEquals(true, $result);
+ }
+
+ /**
+ * @depends testUpdateProperties
+ */
+ function testUpdatePropertiesDelete() {
+
+ $file = new File(SABRE_TEMPDIR . '/dir/file.txt');
+
+ $mutations = array(
+ '{http://sabredav.org/NS/2010}test1' => 'foo',
+ '{http://sabredav.org/NS/2010}test2' => 'bar',
+ );
+
+ $result = $file->updateProperties($mutations);
+
+ $this->assertEquals(true, $result);
+
+ $mutations = array(
+ '{http://sabredav.org/NS/2010}test1' => null,
+ '{http://sabredav.org/NS/2010}test3' => null
+ );
+
+ $result = $file->updateProperties($mutations);
+
+ $this->assertEquals(true, $result);
+
+ $properties = $file->getProperties(array('http://sabredav.org/NS/2010}test1','{http://sabredav.org/NS/2010}test2','{http://sabredav.org/NS/2010}test3'));
+
+ $this->assertEquals(array(
+ '{http://sabredav.org/NS/2010}test2' => 'bar',
+ ), $properties);
+ }
+
+ /**
+ * @depends testUpdateProperties
+ */
+ function testUpdatePropertiesMove() {
+
+ $file = new File(SABRE_TEMPDIR . '/dir/file.txt');
+
+ $mutations = array(
+ '{http://sabredav.org/NS/2010}test1' => 'foo',
+ '{http://sabredav.org/NS/2010}test2' => 'bar',
+ );
+
+ $result = $file->updateProperties($mutations);
+
+ $this->assertEquals(true, $result);
+
+ $properties = $file->getProperties(array('{http://sabredav.org/NS/2010}test1','{http://sabredav.org/NS/2010}test2','{http://sabredav.org/NS/2010}test3'));
+
+ $this->assertEquals(array(
+ '{http://sabredav.org/NS/2010}test1' => 'foo',
+ '{http://sabredav.org/NS/2010}test2' => 'bar',
+ ), $properties);
+
+ // Renaming
+ $file->setName('file3.txt');
+
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/dir/file.txt'));
+ $this->assertTrue(file_exists(SABRE_TEMPDIR . '/dir/file3.txt'));
+ $this->assertEquals('file3.txt',$file->getName());
+
+ $newFile = new File(SABRE_TEMPDIR . '/dir/file3.txt');
+ $this->assertEquals('file3.txt',$newFile->getName());
+
+ $properties = $newFile->getProperties(array('{http://sabredav.org/NS/2010}test1','{http://sabredav.org/NS/2010}test2','{http://sabredav.org/NS/2010}test3'));
+
+ $this->assertEquals(array(
+ '{http://sabredav.org/NS/2010}test1' => 'foo',
+ '{http://sabredav.org/NS/2010}test2' => 'bar',
+ ), $properties);
+ }
+
+ /**
+ * @depends testUpdatePropertiesMove
+ */
+ function testUpdatePropertiesDeleteBleed() {
+
+ $file = new File(SABRE_TEMPDIR . '/dir/file.txt');
+ $mutations = array(
+ '{http://sabredav.org/NS/2010}test1' => 'foo',
+ '{http://sabredav.org/NS/2010}test2' => 'bar',
+ );
+
+ $result = $file->updateProperties($mutations);
+
+ $this->assertEquals(true, $result);
+
+ $properties = $file->getProperties(array('{http://sabredav.org/NS/2010}test1','{http://sabredav.org/NS/2010}test2','{http://sabredav.org/NS/2010}test3'));
+
+ $this->assertEquals(array(
+ '{http://sabredav.org/NS/2010}test1' => 'foo',
+ '{http://sabredav.org/NS/2010}test2' => 'bar',
+ ), $properties);
+
+ // Deleting
+ $file->delete();
+
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/dir/file.txt'));
+
+ // Creating it again
+ file_put_contents(SABRE_TEMPDIR . '/dir/file.txt','New Contents');
+ $file = new File(SABRE_TEMPDIR . '/dir/file.txt');
+
+ $properties = $file->getProperties(array('http://sabredav.org/NS/2010}test1','{http://sabredav.org/NS/2010}test2','{http://sabredav.org/NS/2010}test3'));
+
+ $this->assertEquals(array(), $properties);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php
new file mode 100644
index 000000000..907ede40b
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php
@@ -0,0 +1,224 @@
+<?php
+
+namespace Sabre\DAV\FSExt;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/DAV/AbstractServer.php';
+
+class ServerTest extends DAV\AbstractServer{
+
+ protected function getRootNode() {
+
+ return new Directory($this->tempDir);
+
+ }
+
+ function testGet() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 13,
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ 'ETag' => '"' .md5_file($this->tempDir . '/test.txt') . '"',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals('Test contents', stream_get_contents($this->response->body));
+
+ }
+
+ function testHEAD() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'HEAD',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 13,
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ 'ETag' => '"' . md5_file($this->tempDir . '/test.txt') . '"',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+
+ }
+
+ function testPut() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testput.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing new file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Length' => 0,
+ 'ETag' => '"' . md5('Testing new file') . '"',
+ ), $this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+ $this->assertEquals('Testing new file',file_get_contents($this->tempDir . '/testput.txt'));
+
+ }
+
+ function testPutAlreadyExists() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ 'HTTP_IF_NONE_MATCH' => '*',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing new file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status);
+ $this->assertNotEquals('Testing new file',file_get_contents($this->tempDir . '/test.txt'));
+
+ }
+
+ function testMkcol() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody("");
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+ $this->assertTrue(is_dir($this->tempDir . '/testcol'));
+
+ }
+
+ function testPutUpdate() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing updated file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('0', $this->response->headers['Content-Length']);
+
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+ $this->assertEquals('Testing updated file',file_get_contents($this->tempDir . '/test.txt'));
+
+ }
+
+ function testDelete() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'DELETE',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+ $this->assertFalse(file_exists($this->tempDir . '/test.txt'));
+
+ }
+
+ function testDeleteDirectory() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'DELETE',
+ );
+
+ mkdir($this->tempDir.'/testcol');
+ file_put_contents($this->tempDir.'/testcol/test.txt','Hi! I\'m a file with a short lifespan');
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),$this->response->headers);
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+ $this->assertFalse(file_exists($this->tempDir . '/col'));
+
+ }
+
+ function testOptions() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'OPTIONS',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'DAV' => '1, 3, extended-mkcol',
+ 'MS-Author-Via' => 'DAV',
+ 'Allow' => 'OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT',
+ 'Accept-Ranges' => 'bytes',
+ 'Content-Length' => '0',
+ 'X-Sabre-Version'=> DAV\Version::VERSION,
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/HTTPPreferParsingTest.php b/vendor/sabre/dav/tests/Sabre/DAV/HTTPPreferParsingTest.php
new file mode 100644
index 000000000..45865b2a1
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/HTTPPreferParsingTest.php
@@ -0,0 +1,200 @@
+<?php
+
+namespace Sabre\DAV;
+
+use Sabre\HTTP;
+
+class HTTPPReferParsingTest extends \Sabre\DAVServerTest {
+
+ function testParseSimple() {
+
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_PREFER' => 'return-asynch',
+ ));
+
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $this->assertEquals(array(
+ 'return-asynch' => true,
+ 'return-minimal' => false,
+ 'return-representation' => false,
+ 'strict' => false,
+ 'lenient' => false,
+ 'wait' => null,
+ ), $server->getHTTPPrefer());
+
+ }
+
+ function testParseValue() {
+
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_PREFER' => 'wait=10',
+ ));
+
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $this->assertEquals(array(
+ 'return-asynch' => false,
+ 'return-minimal' => false,
+ 'return-representation' => false,
+ 'strict' => false,
+ 'lenient' => false,
+ 'wait' => 10,
+ ), $server->getHTTPPrefer());
+
+ }
+
+ function testParseMultiple() {
+
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_PREFER' => 'return-minimal, strict,lenient',
+ ));
+
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $this->assertEquals(array(
+ 'return-asynch' => false,
+ 'return-minimal' => true,
+ 'return-representation' => false,
+ 'strict' => true,
+ 'lenient' => true,
+ 'wait' => null,
+ ), $server->getHTTPPrefer());
+
+ }
+
+ function testParseWeirdValue() {
+
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_PREFER' => 'BOOOH',
+ ));
+
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $this->assertEquals(array(
+ 'strict' => false,
+ 'lenient' => false,
+ 'wait' => null,
+ 'return-asynch' => false,
+ 'return-minimal' => false,
+ 'return-representation' => false,
+ ), $server->getHTTPPrefer());
+
+ }
+
+ function testBrief() {
+
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_BRIEF' => 't',
+ ));
+
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $this->assertEquals(array(
+ 'strict' => false,
+ 'lenient' => false,
+ 'wait' => null,
+ 'return-asynch' => false,
+ 'return-minimal' => true,
+ 'return-representation' => false,
+ ), $server->getHTTPPrefer());
+
+ }
+
+ /**
+ * propfindMinimal
+ *
+ * @return void
+ */
+ function testpropfindMinimal() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PROPFIND',
+ 'REQUEST_URI' => '/',
+ 'HTTP_PREFER' => 'return-minimal',
+ ));
+ $request->setBody(<<<BLA
+<?xml version="1.0"?>
+<d:propfind xmlns:d="DAV:">
+ <d:prop>
+ <d:something />
+ <d:resourcetype />
+ </d:prop>
+</d:propfind>
+BLA
+ );
+
+ $response = $this->request($request);
+
+ $this->assertTrue(strpos($response->body, 'resourcetype')!==false);
+ $this->assertTrue(strpos($response->body, 'something')===false);
+
+ }
+
+ function testproppatchMinimal() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PROPPATCH',
+ 'REQUEST_URI' => '/',
+ 'HTTP_PREFER' => 'return-minimal',
+ ));
+ $request->setBody(<<<BLA
+<?xml version="1.0"?>
+<d:proppatch xmlns:d="DAV:">
+ <d:set>
+ <d:prop>
+ <d:something>nope!</d:something>
+ </d:prop>
+ </d:set>
+</d:proppatch>
+BLA
+ );
+
+ $this->server->subscribeEvent('updateProperties', function(&$props, &$result) {
+
+ if (isset($props['{DAV:}something'])) {
+ unset($props['{DAV:}something']);
+ $result[200]['{DAV:}something'] = null;
+ }
+
+ });
+
+ $response = $this->request($request);
+
+ $this->assertEquals(0, strlen($response->body), 'Expected empty body: ' . $response->body);
+ $this->assertEquals('HTTP/1.1 204 No Content', $response->status);
+
+ }
+
+ function testproppatchMinimalError() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PROPPATCH',
+ 'REQUEST_URI' => '/',
+ 'HTTP_PREFER' => 'return-minimal',
+ ));
+ $request->setBody(<<<BLA
+<?xml version="1.0"?>
+<d:proppatch xmlns:d="DAV:">
+ <d:set>
+ <d:prop>
+ <d:something>nope!</d:something>
+ </d:prop>
+ </d:set>
+</d:proppatch>
+BLA
+ );
+
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $response->status);
+ $this->assertTrue(strpos($response->body, 'something')!==false);
+ $this->assertTrue(strpos($response->body, 'HTTP/1.1 403 Forbidden')!==false);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php b/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php
new file mode 100644
index 000000000..c3fba4aae
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace Sabre\DAV;
+
+use Sabre\HTTP;
+
+require_once 'Sabre/TestUtil.php';
+
+class Issue33Test extends \PHPUnit_Framework_TestCase {
+
+ function setUp() {
+
+ \Sabre\TestUtil::clearTempDir();
+
+ }
+
+ function testCopyMoveInfo() {
+
+ $bar = new SimpleCollection('bar');
+ $root = new SimpleCollection('webdav',array($bar));
+
+ $server = new Server($root);
+ $server->setBaseUri('/webdav/');
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/webdav/bar',
+ 'HTTP_DESTINATION' => 'http://dev2.tribalos.com/webdav/%C3%A0fo%C3%B3',
+ 'HTTP_OVERWRITE' => 'F',
+ );
+
+ $request = new HTTP\Request($serverVars);
+
+ $server->httpRequest = $request;
+
+ $info = $server->getCopyAndMoveInfo();
+
+ $this->assertEquals('%C3%A0fo%C3%B3', urlencode($info['destination']));
+ $this->assertFalse($info['destinationExists']);
+ $this->assertFalse($info['destinationNode']);
+
+ }
+
+ function testTreeMove() {
+
+ mkdir(SABRE_TEMPDIR . '/issue33');
+ $dir = new FS\Directory(SABRE_TEMPDIR . '/issue33');
+
+ $dir->createDirectory('bar');
+
+ $tree = new ObjectTree($dir);
+ $tree->move('bar',urldecode('%C3%A0fo%C3%B3'));
+
+ $node = $tree->getNodeForPath(urldecode('%C3%A0fo%C3%B3'));
+ $this->assertEquals(urldecode('%C3%A0fo%C3%B3'),$node->getName());
+
+ }
+
+ function testDirName() {
+
+ $dirname1 = 'bar';
+ $dirname2 = urlencode('%C3%A0fo%C3%B3');;
+
+ $this->assertTrue(dirname($dirname1)==dirname($dirname2));
+
+ }
+
+ /**
+ * @depends testTreeMove
+ * @depends testCopyMoveInfo
+ */
+ function testEverything() {
+
+ // Request object
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'MOVE',
+ 'REQUEST_URI' => '/webdav/bar',
+ 'HTTP_DESTINATION' => 'http://dev2.tribalos.com/webdav/%C3%A0fo%C3%B3',
+ 'HTTP_OVERWRITE' => 'F',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('');
+
+ $response = new HTTP\ResponseMock();
+
+ // Server setup
+ mkdir(SABRE_TEMPDIR . '/issue33');
+ $dir = new FS\Directory(SABRE_TEMPDIR . '/issue33');
+
+ $dir->createDirectory('bar');
+
+ $tree = new ObjectTree($dir);
+
+ $server = new Server($tree);
+ $server->setBaseUri('/webdav/');
+
+ $server->httpRequest = $request;
+ $server->httpResponse = $response;
+ $server->exec();
+
+ $this->assertTrue(file_exists(SABRE_TEMPDIR . '/issue33/' . urldecode('%C3%A0fo%C3%B3')));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php
new file mode 100644
index 000000000..f39e9a036
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php
@@ -0,0 +1,196 @@
+<?php
+
+namespace Sabre\DAV\Locks\Backend;
+
+use Sabre\DAV;
+
+abstract class AbstractTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @abstract
+ * @return AbstractBackend
+ */
+ abstract function getBackend();
+
+ function testSetup() {
+
+ $backend = $this->getBackend();
+ $this->assertInstanceOf('Sabre\\DAV\\Locks\\Backend\\AbstractBackend', $backend);
+
+ }
+
+ /**
+ * @depends testSetup
+ */
+ function testGetLocks() {
+
+ $backend = $this->getBackend();
+
+ $lock = new DAV\Locks\LockInfo();
+ $lock->owner = 'Sinterklaas';
+ $lock->timeout = 60;
+ $lock->created = time();
+ $lock->token = 'MY-UNIQUE-TOKEN';
+ $lock->uri ='someuri';
+
+ $this->assertTrue($backend->lock('someuri', $lock));
+
+ $locks = $backend->getLocks('someuri', false);
+
+ $this->assertEquals(1,count($locks));
+ $this->assertEquals('Sinterklaas',$locks[0]->owner);
+ $this->assertEquals('someuri',$locks[0]->uri);
+
+ }
+
+ /**
+ * @depends testGetLocks
+ */
+ function testGetLocksParent() {
+
+ $backend = $this->getBackend();
+
+ $lock = new DAV\Locks\LockInfo();
+ $lock->owner = 'Sinterklaas';
+ $lock->timeout = 60;
+ $lock->created = time();
+ $lock->depth = DAV\Server::DEPTH_INFINITY;
+ $lock->token = 'MY-UNIQUE-TOKEN';
+
+ $this->assertTrue($backend->lock('someuri', $lock));
+
+ $locks = $backend->getLocks('someuri/child', false);
+
+ $this->assertEquals(1,count($locks));
+ $this->assertEquals('Sinterklaas',$locks[0]->owner);
+ $this->assertEquals('someuri',$locks[0]->uri);
+
+ }
+
+
+ /**
+ * @depends testGetLocks
+ */
+ function testGetLocksParentDepth0() {
+
+ $backend = $this->getBackend();
+
+ $lock = new DAV\Locks\LockInfo();
+ $lock->owner = 'Sinterklaas';
+ $lock->timeout = 60;
+ $lock->created = time();
+ $lock->depth = 0;
+ $lock->token = 'MY-UNIQUE-TOKEN';
+
+ $this->assertTrue($backend->lock('someuri', $lock));
+
+ $locks = $backend->getLocks('someuri/child', false);
+
+ $this->assertEquals(0,count($locks));
+
+ }
+
+ function testGetLocksChildren() {
+
+ $backend = $this->getBackend();
+
+ $lock = new DAV\Locks\LockInfo();
+ $lock->owner = 'Sinterklaas';
+ $lock->timeout = 60;
+ $lock->created = time();
+ $lock->depth = 0;
+ $lock->token = 'MY-UNIQUE-TOKEN';
+
+ $this->assertTrue($backend->lock('someuri/child', $lock));
+
+ $locks = $backend->getLocks('someuri/child', false);
+ $this->assertEquals(1,count($locks));
+
+ $locks = $backend->getLocks('someuri', false);
+ $this->assertEquals(0,count($locks));
+
+ $locks = $backend->getLocks('someuri', true);
+ $this->assertEquals(1,count($locks));
+
+ }
+
+ /**
+ * @depends testGetLocks
+ */
+ function testLockRefresh() {
+
+ $backend = $this->getBackend();
+
+ $lock = new DAV\Locks\LockInfo();
+ $lock->owner = 'Sinterklaas';
+ $lock->timeout = 60;
+ $lock->created = time();
+ $lock->token = 'MY-UNIQUE-TOKEN';
+
+ $this->assertTrue($backend->lock('someuri', $lock));
+ /* Second time */
+
+ $lock->owner = 'Santa Clause';
+ $this->assertTrue($backend->lock('someuri', $lock));
+
+ $locks = $backend->getLocks('someuri', false);
+
+ $this->assertEquals(1,count($locks));
+
+ $this->assertEquals('Santa Clause',$locks[0]->owner);
+ $this->assertEquals('someuri',$locks[0]->uri);
+
+ }
+
+ /**
+ * @depends testGetLocks
+ */
+ function testUnlock() {
+
+ $backend = $this->getBackend();
+
+ $lock = new DAV\Locks\LockInfo();
+ $lock->owner = 'Sinterklaas';
+ $lock->timeout = 60;
+ $lock->created = time();
+ $lock->token = 'MY-UNIQUE-TOKEN';
+
+ $this->assertTrue($backend->lock('someuri', $lock));
+
+ $locks = $backend->getLocks('someuri', false);
+ $this->assertEquals(1,count($locks));
+
+ $this->assertTrue($backend->unlock('someuri',$lock));
+
+ $locks = $backend->getLocks('someuri', false);
+ $this->assertEquals(0,count($locks));
+
+ }
+
+ /**
+ * @depends testUnlock
+ */
+ function testUnlockUnknownToken() {
+
+ $backend = $this->getBackend();
+
+ $lock = new DAV\Locks\LockInfo();
+ $lock->owner = 'Sinterklaas';
+ $lock->timeout = 60;
+ $lock->created = time();
+ $lock->token = 'MY-UNIQUE-TOKEN';
+
+ $this->assertTrue($backend->lock('someuri', $lock));
+
+ $locks = $backend->getLocks('someuri', false);
+ $this->assertEquals(1,count($locks));
+
+ $lock->token = 'SOME-OTHER-TOKEN';
+ $this->assertFalse($backend->unlock('someuri',$lock));
+
+ $locks = $backend->getLocks('someuri', false);
+ $this->assertEquals(1,count($locks));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FSTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FSTest.php
new file mode 100644
index 000000000..651abf786
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FSTest.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Sabre\DAV\Locks\Backend;
+
+require_once 'Sabre/TestUtil.php';
+
+class FSTest extends AbstractTest {
+
+ function getBackend() {
+
+ \Sabre\TestUtil::clearTempDir();
+ mkdir(SABRE_TEMPDIR . '/locks');
+ $backend = new FS(SABRE_TEMPDIR . '/locks/');
+ return $backend;
+
+ }
+
+ function tearDown() {
+
+ \Sabre\TestUtil::clearTempDir();
+
+ }
+
+ function testGetLocksChildren() {
+
+ // We're skipping this test. This doesn't work, and it will
+ // never. The class is deprecated anyway.
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FileTest.php
new file mode 100644
index 000000000..537996f3b
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FileTest.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Sabre\DAV\Locks\Backend;
+
+require_once 'Sabre/TestUtil.php';
+
+class FileTest extends AbstractTest {
+
+ function getBackend() {
+
+ \Sabre\TestUtil::clearTempDir();
+ $backend = new File(SABRE_TEMPDIR . '/lockdb');
+ return $backend;
+
+ }
+
+
+ function tearDown() {
+
+ \Sabre\TestUtil::clearTempDir();
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php
new file mode 100644
index 000000000..b6f06224c
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Sabre\DAV\Locks\Backend;
+
+require_once 'Sabre/TestUtil.php';
+
+class PDOMySQLTest extends AbstractTest {
+
+ function getBackend() {
+
+ if (!SABRE_HASMYSQL) $this->markTestSkipped('MySQL driver is not available, or it was not properly configured');
+ $pdo = \Sabre\TestUtil::getMySQLDB();
+ if (!$pdo) $this->markTestSkipped('Could not connect to MySQL database');
+ $pdo->query('DROP TABLE IF EXISTS locks;');
+ $pdo->query("
+CREATE TABLE locks (
+ id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ owner VARCHAR(100),
+ timeout INTEGER UNSIGNED,
+ created INTEGER,
+ token VARCHAR(100),
+ scope TINYINT,
+ depth TINYINT,
+ uri text
+);");
+
+ $backend = new PDO($pdo);
+ return $backend;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php
new file mode 100644
index 000000000..d6336c7b2
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Sabre\DAV\Locks\Backend;
+
+require_once 'Sabre/TestUtil.php';
+require_once 'Sabre/DAV/Locks/Backend/AbstractTest.php';
+
+class PDOTest extends AbstractTest {
+
+ function getBackend() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ \Sabre\TestUtil::clearTempDir();
+ mkdir(SABRE_TEMPDIR . '/pdolocks');
+ $pdo = new \PDO('sqlite:' . SABRE_TEMPDIR . '/pdolocks/db.sqlite');
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
+ $pdo->query('CREATE TABLE locks ( id integer primary key asc, owner text, timeout text, created integer, token text, scope integer, depth integer, uri text)');
+ $backend = new PDO($pdo);
+ return $backend;
+
+ }
+
+ function tearDown() {
+
+ \Sabre\TestUtil::clearTempDir();
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/GetIfConditionsTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/GetIfConditionsTest.php
new file mode 100644
index 000000000..7b2cd0db0
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/GetIfConditionsTest.php
@@ -0,0 +1,375 @@
+<?php
+
+namespace Sabre\DAV\Locks;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+require_once 'Sabre/DAV/AbstractServer.php';
+
+class GetIfConditionsTest extends DAV\AbstractServer {
+
+ /**
+ * @var Sabre\DAV\Locks\Plugin
+ */
+ protected $locksPlugin;
+
+ function setUp() {
+
+ parent::setUp();
+ $locksPlugin = new Plugin();
+ $this->server->addPlugin($locksPlugin);
+ $this->locksPlugin = $locksPlugin;
+
+ }
+
+ function testNoConditions() {
+
+ $serverVars = array(
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+
+ $conditions = $this->locksPlugin->getIfConditions();
+ $this->assertEquals(array(),$conditions);
+
+ }
+
+ function testLockToken() {
+
+ $serverVars = array(
+ 'HTTP_IF' => '(<opaquelocktoken:token1>)',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+
+ $conditions = $this->locksPlugin->getIfConditions();
+
+ $compare = array(
+
+ array(
+ 'uri' => '',
+ 'tokens' => array(
+ array(
+ 1,
+ 'opaquelocktoken:token1',
+ '',
+ ),
+ ),
+
+ ),
+
+ );
+
+ $this->assertEquals($compare,$conditions);
+
+ }
+
+ function testNotLockToken() {
+
+ $serverVars = array(
+ 'HTTP_IF' => '(Not <opaquelocktoken:token1>)',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+
+ $conditions = $this->locksPlugin->getIfConditions();
+
+ $compare = array(
+
+ array(
+ 'uri' => '',
+ 'tokens' => array(
+ array(
+ 0,
+ 'opaquelocktoken:token1',
+ '',
+ ),
+ ),
+
+ ),
+
+ );
+ $this->assertEquals($compare,$conditions);
+
+ }
+
+ function testLockTokenUrl() {
+
+ $serverVars = array(
+ 'HTTP_IF' => '<http://www.example.com/> (<opaquelocktoken:token1>)',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+
+ $conditions = $this->locksPlugin->getIfConditions();
+
+ $compare = array(
+
+ array(
+ 'uri' => 'http://www.example.com/',
+ 'tokens' => array(
+ array(
+ 1,
+ 'opaquelocktoken:token1',
+ '',
+ ),
+ ),
+
+ ),
+
+ );
+ $this->assertEquals($compare,$conditions);
+
+ }
+
+ function test2LockTokens() {
+
+ $serverVars = array(
+ 'HTTP_IF' => '(<opaquelocktoken:token1>) (Not <opaquelocktoken:token2>)',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+
+ $conditions = $this->locksPlugin->getIfConditions();
+
+ $compare = array(
+
+ array(
+ 'uri' => '',
+ 'tokens' => array(
+ array(
+ 1,
+ 'opaquelocktoken:token1',
+ '',
+ ),
+ array(
+ 0,
+ 'opaquelocktoken:token2',
+ '',
+ ),
+ ),
+
+ ),
+
+ );
+ $this->assertEquals($compare,$conditions);
+
+ }
+
+ function test2UriLockTokens() {
+
+ $serverVars = array(
+ 'HTTP_IF' => '<http://www.example.org/node1> (<opaquelocktoken:token1>) <http://www.example.org/node2> (Not <opaquelocktoken:token2>)',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+
+ $conditions = $this->locksPlugin->getIfConditions();
+
+ $compare = array(
+
+ array(
+ 'uri' => 'http://www.example.org/node1',
+ 'tokens' => array(
+ array(
+ 1,
+ 'opaquelocktoken:token1',
+ '',
+ ),
+ ),
+ ),
+ array(
+ 'uri' => 'http://www.example.org/node2',
+ 'tokens' => array(
+ array(
+ 0,
+ 'opaquelocktoken:token2',
+ '',
+ ),
+ ),
+
+ ),
+
+ );
+ $this->assertEquals($compare,$conditions);
+
+ }
+
+ function test2UriMultiLockTokens() {
+
+ $serverVars = array(
+ 'HTTP_IF' => '<http://www.example.org/node1> (<opaquelocktoken:token1>) (<opaquelocktoken:token2>) <http://www.example.org/node2> (Not <opaquelocktoken:token3>)',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+
+ $conditions = $this->locksPlugin->getIfConditions();
+
+ $compare = array(
+
+ array(
+ 'uri' => 'http://www.example.org/node1',
+ 'tokens' => array(
+ array(
+ 1,
+ 'opaquelocktoken:token1',
+ '',
+ ),
+ array(
+ 1,
+ 'opaquelocktoken:token2',
+ '',
+ ),
+ ),
+ ),
+ array(
+ 'uri' => 'http://www.example.org/node2',
+ 'tokens' => array(
+ array(
+ 0,
+ 'opaquelocktoken:token3',
+ '',
+ ),
+ ),
+
+ ),
+
+ );
+ $this->assertEquals($compare,$conditions);
+
+ }
+
+ function testEtag() {
+
+ $serverVars = array(
+ 'HTTP_IF' => '([etag1])',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+
+ $conditions = $this->locksPlugin->getIfConditions();
+
+ $compare = array(
+
+ array(
+ 'uri' => '',
+ 'tokens' => array(
+ array(
+ 1,
+ '',
+ 'etag1',
+ ),
+ ),
+ ),
+
+ );
+ $this->assertEquals($compare,$conditions);
+
+ }
+
+ function test2Etags() {
+
+ $serverVars = array(
+ 'HTTP_IF' => '<http://www.example.org/> ([etag1]) ([etag2])',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+
+ $conditions = $this->locksPlugin->getIfConditions();
+
+ $compare = array(
+
+ array(
+ 'uri' => 'http://www.example.org/',
+ 'tokens' => array(
+ array(
+ 1,
+ '',
+ 'etag1',
+ ),
+ array(
+ 1,
+ '',
+ 'etag2',
+ ),
+ ),
+ ),
+
+ );
+ $this->assertEquals($compare,$conditions);
+
+ }
+
+ function testComplexIf() {
+
+ $serverVars = array(
+ 'HTTP_IF' => '<http://www.example.org/node1> (<opaquelocktoken:token1> [etag1]) ' .
+ '(Not <opaquelocktoken:token2>) ([etag2]) <http://www.example.org/node2> ' .
+ '(<opaquelocktoken:token3>) (Not <opaquelocktoken:token4>) ([etag3])',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+
+ $conditions = $this->locksPlugin->getIfConditions();
+
+ $compare = array(
+
+ array(
+ 'uri' => 'http://www.example.org/node1',
+ 'tokens' => array(
+ array(
+ 1,
+ 'opaquelocktoken:token1',
+ 'etag1',
+ ),
+ array(
+ 0,
+ 'opaquelocktoken:token2',
+ '',
+ ),
+ array(
+ 1,
+ '',
+ 'etag2',
+ ),
+ ),
+ ),
+ array(
+ 'uri' => 'http://www.example.org/node2',
+ 'tokens' => array(
+ array(
+ 1,
+ 'opaquelocktoken:token3',
+ '',
+ ),
+ array(
+ 0,
+ 'opaquelocktoken:token4',
+ '',
+ ),
+ array(
+ 1,
+ '',
+ 'etag3',
+ ),
+ ),
+ ),
+
+ );
+ $this->assertEquals($compare,$conditions);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php
new file mode 100644
index 000000000..b3d7d447b
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php
@@ -0,0 +1,123 @@
+<?php
+
+namespace Sabre\DAV\Locks;
+
+use Sabre\HTTP;
+use Sabre\DAV;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+require_once 'Sabre/TestUtil.php';
+
+class MSWordTest extends \PHPUnit_Framework_TestCase {
+
+ function testLockEtc() {
+
+ mkdir(SABRE_TEMPDIR . '/mstest');
+ $tree = new DAV\FS\Directory(SABRE_TEMPDIR . '/mstest');
+
+ $server = new DAV\Server($tree);
+ $server->debugExceptions = true;
+ $locksBackend = new Backend\File(SABRE_TEMPDIR . '/locksdb');
+ $locksPlugin = new Plugin($locksBackend);
+ $server->addPlugin($locksPlugin);
+
+ $response1 = new HTTP\ResponseMock();
+
+ $server->httpRequest = $this->getLockRequest();
+ $server->httpResponse = $response1;
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 201 Created', $server->httpResponse->status);
+ $this->assertTrue(isset($server->httpResponse->headers['Lock-Token']));
+ $lockToken = $server->httpResponse->headers['Lock-Token'];
+
+ //sleep(10);
+
+ $response2 = new HTTP\ResponseMock();
+
+ $server->httpRequest = $this->getLockRequest2();
+ $server->httpResponse = $response2;
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 201 Created', $server->httpResponse->status);
+ $this->assertTrue(isset($server->httpResponse->headers['Lock-Token']));
+
+ //sleep(10);
+
+ $response3 = new HTTP\ResponseMock();
+ $server->httpRequest = $this->getPutRequest($lockToken);
+ $server->httpResponse = $response3;
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 204 No Content', $server->httpResponse->status);
+
+ }
+
+ function tearDown() {
+
+ \Sabre\TestUtil::clearTempDir();
+
+ }
+
+ function getLockRequest() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'LOCK',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'HTTP_TIMEOUT' => 'Second-3600',
+ 'REQUEST_URI' => '/Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx',
+ ));
+
+ $request->setBody('<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope>
+ <D:exclusive />
+ </D:lockscope>
+ <D:locktype>
+ <D:write />
+ </D:locktype>
+ <D:owner>
+ <D:href>PC-Vista\User</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ return $request;
+
+ }
+ function getLockRequest2() {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'LOCK',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ 'HTTP_TIMEOUT' => 'Second-3600',
+ 'REQUEST_URI' => '/~$Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx',
+ ));
+
+ $request->setBody('<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope>
+ <D:exclusive />
+ </D:lockscope>
+ <D:locktype>
+ <D:write />
+ </D:locktype>
+ <D:owner>
+ <D:href>PC-Vista\User</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ return $request;
+
+ }
+
+ function getPutRequest($lockToken) {
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx',
+ 'HTTP_IF' => 'If: ('.$lockToken.')',
+ ));
+ $request->setBody('FAKE BODY');
+ return $request;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php
new file mode 100644
index 000000000..a45dafdf1
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php
@@ -0,0 +1,966 @@
+<?php
+
+namespace Sabre\DAV\Locks;
+
+use Sabre\HTTP;
+use Sabre\DAV;
+
+require_once 'Sabre/DAV/AbstractServer.php';
+
+class PluginTest extends DAV\AbstractServer {
+
+ /**
+ * @var Sabre\DAV\Locks\Plugin
+ */
+ protected $locksPlugin;
+
+ function setUp() {
+
+ parent::setUp();
+ $locksBackend = new Backend\File(SABRE_TEMPDIR . '/locksdb');
+ $locksPlugin = new Plugin($locksBackend);
+ $this->server->addPlugin($locksPlugin);
+ $this->locksPlugin = $locksPlugin;
+
+ }
+
+ function testGetFeatures() {
+
+ $this->assertEquals(array(2),$this->locksPlugin->getFeatures());
+
+ }
+
+ function testGetHTTPMethods() {
+
+ $this->assertEquals(array('LOCK','UNLOCK'),$this->locksPlugin->getHTTPMethods(''));
+
+ }
+
+ function testGetHTTPMethodsNoBackend() {
+
+ $locksPlugin = new Plugin();
+ $this->server->addPlugin($locksPlugin);
+ $this->assertEquals(array(),$locksPlugin->getHTTPMethods(''));
+
+ }
+
+ function testUnknownMethodPassthough() {
+
+ $this->assertNull($this->locksPlugin->unknownMethod('BLA','/'));
+
+ }
+
+ function testLockNoBody() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status);
+
+ }
+
+ function testLock() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status,'Got an incorrect status back. Response body: ' . $this->response->body);
+
+ $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
+ $xml = simplexml_load_string($body);
+ $xml->registerXPathNamespace('d','urn:DAV');
+
+ $elements = array(
+ '/d:prop',
+ '/d:prop/d:lockdiscovery',
+ '/d:prop/d:lockdiscovery/d:activelock',
+ '/d:prop/d:lockdiscovery/d:activelock/d:locktype',
+ '/d:prop/d:lockdiscovery/d:activelock/d:lockroot',
+ '/d:prop/d:lockdiscovery/d:activelock/d:lockroot/d:href',
+ '/d:prop/d:lockdiscovery/d:activelock/d:locktype/d:write',
+ '/d:prop/d:lockdiscovery/d:activelock/d:lockscope',
+ '/d:prop/d:lockdiscovery/d:activelock/d:lockscope/d:exclusive',
+ '/d:prop/d:lockdiscovery/d:activelock/d:depth',
+ '/d:prop/d:lockdiscovery/d:activelock/d:owner',
+ '/d:prop/d:lockdiscovery/d:activelock/d:timeout',
+ '/d:prop/d:lockdiscovery/d:activelock/d:locktoken',
+ '/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href',
+ );
+
+ foreach($elements as $elem) {
+ $data = $xml->xpath($elem);
+ $this->assertEquals(1,count($data),'We expected 1 match for the xpath expression "' . $elem . '". ' . count($data) . ' were found. Full response body: ' . $this->response->body);
+ }
+
+ $depth = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:depth');
+ $this->assertEquals('infinity',(string)$depth[0]);
+
+ $token = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href');
+ $this->assertEquals($this->response->headers['Lock-Token'],'<' . (string)$token[0] . '>','Token in response body didn\'t match token in response header.');
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testDoubleLock() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->response = new HTTP\ResponseMock();
+ $this->server->httpResponse = $this->response;
+
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+
+ $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status);
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testLockRefresh() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $lockToken = $this->response->headers['Lock-Token'];
+
+ $this->response = new HTTP\ResponseMock();
+ $this->server->httpResponse = $this->response;
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ 'HTTP_IF' => '(' . $lockToken . ')',
+ );
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('');
+ $this->server->httpRequest = $request;
+
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status,'We received an incorrect status code. Full response body: ' . $this->response->body);
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testLockNoFile() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/notfound.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testUnlockNoToken() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'UNLOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status);
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testUnlockBadToken() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'UNLOCK',
+ 'HTTP_LOCK_TOKEN' => '<opaquelocktoken:blablabla>',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status,'Got an incorrect status code. Full response body: ' . $this->response->body);
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testLockPutNoToken() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('newbody');
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status);
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testUnlock() {
+
+ $request = new HTTP\Request(array());
+ $this->server->httpRequest = $request;
+
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->invokeMethod('LOCK','test.txt');
+ $lockToken = $this->server->httpResponse->headers['Lock-Token'];
+
+ $serverVars = array(
+ 'HTTP_LOCK_TOKEN' => $lockToken,
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->httpResponse = new HTTP\ResponseMock();
+ $this->server->invokeMethod('UNLOCK', 'test.txt');
+
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->server->httpResponse->status,'Got an incorrect status code. Full response body: ' . $this->response->body);
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),
+ $this->server->httpResponse->headers
+ );
+
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testUnlockWindowsBug() {
+
+ $request = new HTTP\Request(array());
+ $this->server->httpRequest = $request;
+
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->invokeMethod('LOCK','test.txt');
+ $lockToken = $this->server->httpResponse->headers['Lock-Token'];
+
+ // See Issue 123
+ $lockToken = trim($lockToken,'<>');
+
+ $serverVars = array(
+ 'HTTP_LOCK_TOKEN' => $lockToken,
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->httpResponse = new HTTP\ResponseMock();
+ $this->server->invokeMethod('UNLOCK', 'test.txt');
+
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->server->httpResponse->status,'Got an incorrect status code. Full response body: ' . $this->response->body);
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),
+ $this->server->httpResponse->headers
+ );
+
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testLockRetainOwner() {
+
+ $request = new HTTP\Request(array());
+ $this->server->httpRequest = $request;
+
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>Evert</D:owner>
+</D:lockinfo>');
+
+ $this->server->invokeMethod('LOCK','test.txt');
+ $lockToken = $this->server->httpResponse->headers['Lock-Token'];
+
+ $locks = $this->locksPlugin->getLocks('test.txt');
+ $this->assertEquals(1,count($locks));
+ $this->assertEquals('Evert',$locks[0]->owner);
+
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testLockPutBadToken() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ 'HTTP_IF' => '(<opaquelocktoken:token1>)',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('newbody');
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status);
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testLockDeleteParent() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir',
+ 'REQUEST_METHOD' => 'DELETE',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status);
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+
+ }
+ /**
+ * @depends testLock
+ */
+ function testLockDeleteSucceed() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'DELETE',
+ 'HTTP_IF' => '(' . $this->response->headers['Lock-Token'] . ')',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testLockCopyLockSource() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'COPY',
+ 'HTTP_DESTINATION' => '/dir/child2.txt',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'Copy must succeed if only the source is locked, but not the destination');
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+
+ }
+ /**
+ * @depends testLock
+ */
+ function testLockCopyLockDestination() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child2.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'COPY',
+ 'HTTP_DESTINATION' => '/dir/child2.txt',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status,'Copy must succeed if only the source is locked, but not the destination');
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testLockMoveLockSourceLocked() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'MOVE',
+ 'HTTP_DESTINATION' => '/dir/child2.txt',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status,'Copy must succeed if only the source is locked, but not the destination');
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testLockMoveLockSourceSucceed() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'MOVE',
+ 'HTTP_DESTINATION' => '/dir/child2.txt',
+ 'HTTP_IF' => '(' . $this->response->headers['Lock-Token'] . ')',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'A valid lock-token was provided for the source, so this MOVE operation must succeed. Full response body: ' . $this->response->body);
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testLockMoveLockDestination() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child2.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'MOVE',
+ 'HTTP_DESTINATION' => '/dir/child2.txt',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status,'Copy must succeed if only the source is locked, but not the destination');
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+
+ }
+ /**
+ * @depends testLock
+ */
+ function testLockMoveLockParent() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir',
+ 'REQUEST_METHOD' => 'LOCK',
+ 'HTTP_DEPTH' => 'infinite',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'MOVE',
+ 'HTTP_DESTINATION' => '/dir/child2.txt',
+ 'HTTP_IF' => '</dir> (' . $this->response->headers['Lock-Token'] . ')',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'We locked the parent of both the source and destination, but the move didn\'t succeed.');
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+
+ }
+
+ /**
+ * @depends testLock
+ */
+ function testLockPutGoodToken() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ 'HTTP_IF' => '('.$this->response->headers['Lock-Token'].')',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('newbody');
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
+
+ }
+
+ function testPutWithIncorrectETag() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ 'HTTP_IF' => '(["etag1"])',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('newbody');
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+ $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status);
+
+ }
+
+ /**
+ * @depends testPutWithIncorrectETag
+ */
+ function testPutWithCorrectETag() {
+
+ // We need an etag-enabled file node.
+ $tree = new DAV\ObjectTree(new DAV\FSExt\Directory(SABRE_TEMPDIR));
+ $this->server->tree = $tree;
+
+ $etag = md5(file_get_contents(SABRE_TEMPDIR . '/test.txt'));
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ 'HTTP_IF' => '(["'.$etag.'"])',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('newbody');
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status, 'Incorrect status received. Full response body:' . $this->response->body);
+
+ }
+
+ function testGetTimeoutHeader() {
+
+ $request = new HTTP\Request(array(
+ 'HTTP_TIMEOUT' => 'second-100',
+ ));
+
+ $this->server->httpRequest = $request;
+ $this->assertEquals(100, $this->locksPlugin->getTimeoutHeader());
+
+ }
+
+
+ function testGetTimeoutHeaderNotSet() {
+
+ $request = new HTTP\Request(array(
+ ));
+
+ $this->server->httpRequest = $request;
+ $this->assertEquals(0, $this->locksPlugin->getTimeoutHeader());
+
+ }
+
+
+ function testGetTimeoutHeaderInfinite() {
+
+ $request = new HTTP\Request(array(
+ 'HTTP_TIMEOUT' => 'infinite',
+ ));
+
+ $this->server->httpRequest = $request;
+ $this->assertEquals(LockInfo::TIMEOUT_INFINITE, $this->locksPlugin->getTimeoutHeader());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testGetTimeoutHeaderInvalid() {
+
+ $request = new HTTP\Request(array(
+ 'HTTP_TIMEOUT' => 'yourmom',
+ ));
+
+ $this->server->httpRequest = $request;
+ $this->locksPlugin->getTimeoutHeader();
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php
new file mode 100644
index 000000000..e818fe043
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Sabre\DAV\Mount;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/DAV/AbstractServer.php';
+
+class PluginTest extends DAV\AbstractServer {
+
+ function setUp() {
+
+ parent::setUp();
+ $this->server->addPlugin(new Plugin());
+
+ }
+
+ function testPassThrough() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'GET',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented',$this->response->status,'We expected GET to not be implemented for Directories. Response body: ' . $this->response->body);
+
+ }
+
+ function testMountResponse() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/?mount',
+ 'REQUEST_METHOD' => 'GET',
+ 'QUERY_STRING' => 'mount',
+ 'HTTP_HOST' => 'example.org',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+
+ $xml = simplexml_load_string($this->response->body);
+ $this->assertTrue($xml==true,'Response was not a valid xml document');
+
+ $xml->registerXPathNamespace('dm','http://purl.org/NET/webdav/mount');
+ $url = $xml->xpath('//dm:url');
+ $this->assertEquals('http://example.org/',(string)$url[0]);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php
new file mode 100644
index 000000000..330058b6d
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace Sabre\DAV;
+
+require_once 'Sabre/TestUtil.php';
+
+class ObjectTreeTest extends \PHPUnit_Framework_TestCase {
+
+ protected $tree;
+
+ function setup() {
+
+ \Sabre\TestUtil::clearTempDir();
+ mkdir(SABRE_TEMPDIR . '/root');
+ mkdir(SABRE_TEMPDIR . '/root/subdir');
+ file_put_contents(SABRE_TEMPDIR . '/root/file.txt','contents');
+ file_put_contents(SABRE_TEMPDIR . '/root/subdir/subfile.txt','subcontents');
+ $rootNode = new FSExt\Directory(SABRE_TEMPDIR . '/root');
+ $this->tree = new ObjectTree($rootNode);
+
+ }
+
+ function teardown() {
+
+ \Sabre\TestUtil::clearTempDir();
+
+ }
+
+ function testGetRootNode() {
+
+ $root = $this->tree->getNodeForPath('');
+ $this->assertInstanceOf('Sabre\\DAV\\FSExt\\Directory',$root);
+
+ }
+
+ function testGetSubDir() {
+
+ $root = $this->tree->getNodeForPath('subdir');
+ $this->assertInstanceOf('Sabre\\DAV\\FSExt\\Directory',$root);
+
+ }
+
+ function testCopyFile() {
+
+ $this->tree->copy('file.txt','file2.txt');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/file2.txt'));
+ $this->assertEquals('contents',file_get_contents(SABRE_TEMPDIR.'/root/file2.txt'));
+
+ }
+
+ /**
+ * @depends testCopyFile
+ */
+ function testCopyDirectory() {
+
+ $this->tree->copy('subdir','subdir2');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2'));
+ $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2/subfile.txt'));
+ $this->assertEquals('subcontents',file_get_contents(SABRE_TEMPDIR.'/root/subdir2/subfile.txt'));
+
+ }
+
+ /**
+ * @depends testCopyFile
+ */
+ function testMoveFile() {
+
+ $this->tree->move('file.txt','file2.txt');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/file2.txt'));
+ $this->assertFalse(file_exists(SABRE_TEMPDIR.'/root/file.txt'));
+ $this->assertEquals('contents',file_get_contents(SABRE_TEMPDIR.'/root/file2.txt'));
+
+ }
+
+ /**
+ * @depends testMoveFile
+ */
+ function testMoveFileNewParent() {
+
+ $this->tree->move('file.txt','subdir/file2.txt');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir/file2.txt'));
+ $this->assertFalse(file_exists(SABRE_TEMPDIR.'/root/file.txt'));
+ $this->assertEquals('contents',file_get_contents(SABRE_TEMPDIR.'/root/subdir/file2.txt'));
+
+ }
+
+ /**
+ * @depends testCopyDirectory
+ */
+ function testMoveDirectory() {
+
+ $this->tree->move('subdir','subdir2');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2'));
+ $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2/subfile.txt'));
+ $this->assertFalse(file_exists(SABRE_TEMPDIR.'/root/subdir'));
+ $this->assertEquals('subcontents',file_get_contents(SABRE_TEMPDIR.'/root/subdir2/subfile.txt'));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php
new file mode 100644
index 000000000..e8cdc1666
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Sabre\DAV\PartialUpdate;
+use Sabre\DAV;
+
+class FileMock implements IFile {
+
+ protected $data = '';
+
+ function put($str) {
+
+ if (is_resource($str)) {
+ $str = stream_get_contents($str);
+ }
+ $this->data = $str;
+
+ }
+
+ function putRange($str,$start) {
+
+ if (is_resource($str)) {
+ $str = stream_get_contents($str);
+ }
+ $this->data = substr($this->data, 0, $start) . $str . substr($this->data, $start + strlen($str));
+
+
+
+ }
+
+ function get() {
+
+ return $this->data;
+
+ }
+
+ function getContentType() {
+
+ return 'text/plain';
+
+ }
+
+ function getSize() {
+
+ return strlen($this->data);
+
+ }
+
+ function getETag() {
+
+ return '"' . $this->data . '"';
+
+ }
+
+ function delete() {
+
+ throw new DAV\Exception\MethodNotAllowed();
+
+ }
+
+ function setName($name) {
+
+ throw new DAV\Exception\MethodNotAllowed();
+
+ }
+
+ function getName() {
+
+ return 'partial';
+
+ }
+
+ function getLastModified() {
+
+ return null;
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/PluginTest.php
new file mode 100644
index 000000000..7b90429d4
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/PluginTest.php
@@ -0,0 +1,130 @@
+<?php
+
+namespace Sabre\DAV\PartialUpdate;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/DAV/PartialUpdate/FileMock.php';
+
+class PluginTest extends \Sabre\DAVServerTest {
+
+ protected $node;
+ protected $plugin;
+
+ public function setUp() {
+
+ $this->node = new FileMock();
+ $this->tree[] = $this->node;
+
+ parent::setUp();
+
+ $this->plugin = new Plugin();
+ $this->server->addPlugin($this->plugin);
+
+
+
+ }
+
+ public function testInit() {
+
+ $this->assertEquals('partialupdate', $this->plugin->getPluginName());
+ $this->assertEquals(array('sabredav-partialupdate'), $this->plugin->getFeatures());
+ $this->assertEquals(array(
+ 'PATCH'
+ ), $this->plugin->getHTTPMethods('partial'));
+ $this->assertEquals(array(
+ ), $this->plugin->getHTTPMethods(''));
+
+ $this->assertNull($this->plugin->unknownMethod('FOO','partial'));
+
+ }
+
+ public function testPatchNoRange() {
+
+ $this->node->put('00000000');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PATCH',
+ 'REQUEST_URI' => '/partial',
+ ));
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $response->status, 'Full response body:' . $response->body);
+
+ }
+
+ public function testPatchNotSupported() {
+
+ $this->node->put('00000000');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PATCH',
+ 'REQUEST_URI' => '/',
+ 'X_UPDATE_RANGE' => '3-4',
+
+ ));
+ $request->setBody(
+ '111'
+ );
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 405 Method Not Allowed', $response->status, 'Full response body:' . $response->body);
+
+ }
+
+ public function testPatchNoContentType() {
+
+ $this->node->put('00000000');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PATCH',
+ 'REQUEST_URI' => '/partial',
+ 'HTTP_X_UPDATE_RANGE' => 'bytes=3-4',
+
+ ));
+ $request->setBody(
+ '111'
+ );
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 415 Unsupported Media Type', $response->status, 'Full response body:' . $response->body);
+
+ }
+
+ public function testPatchBadRange() {
+
+ $this->node->put('00000000');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PATCH',
+ 'REQUEST_URI' => '/partial',
+ 'HTTP_X_UPDATE_RANGE' => 'bytes=3-4',
+ 'HTTP_CONTENT_TYPE' => 'application/x-sabredav-partialupdate',
+ ));
+ $request->setBody(
+ '111'
+ );
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 416 Requested Range Not Satisfiable', $response->status, 'Full response body:' . $response->body);
+
+ }
+
+ public function testPatchSuccess() {
+
+ $this->node->put('00000000');
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PATCH',
+ 'REQUEST_URI' => '/partial',
+ 'HTTP_X_UPDATE_RANGE' => 'bytes=3-5',
+ 'HTTP_CONTENT_TYPE' => 'application/x-sabredav-partialupdate',
+ 'HTTP_CONTENT_LENGTH' => 3,
+ ));
+ $request->setBody(
+ '111'
+ );
+ $response = $this->request($request);
+
+ $this->assertEquals('HTTP/1.1 204 No Content', $response->status, 'Full response body:' . $response->body);
+ $this->assertEquals('00111000', $this->node->get());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/GetLastModifiedTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/GetLastModifiedTest.php
new file mode 100644
index 000000000..de8ca1283
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/GetLastModifiedTest.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Sabre\DAV\Property;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+class GetLastModifiedTest extends \PHPUnit_Framework_TestCase {
+
+ function testConstructDateTime() {
+
+ $dt = new \DateTime('2010-03-14 16:35', new \DateTimeZone('UTC'));
+ $lastMod = new GetLastModified($dt);
+ $this->assertEquals($dt->format(\DateTime::ATOM), $lastMod->getTime()->format(\DateTime::ATOM));
+
+ }
+
+ function testConstructString() {
+
+ $dt = new \DateTime('2010-03-14 16:35', new \DateTimeZone('UTC'));
+ $lastMod = new GetLastModified('2010-03-14 16:35');
+ $this->assertEquals($dt->format(\DateTime::ATOM), $lastMod->getTime()->format(\DateTime::ATOM));
+
+ }
+
+ function testConstructInt() {
+
+ $dt = new \DateTime('2010-03-14 16:35', new \DateTimeZone('UTC'));
+ $lastMod = new GetLastModified((int)$dt->format('U'));
+ $this->assertEquals($dt->format(\DateTime::ATOM), $lastMod->getTime()->format(\DateTime::ATOM));
+
+ }
+
+ function testSerialize() {
+
+ $dt = new \DateTime('2010-03-14 16:35', new \DateTimeZone('UTC'));
+ $lastMod = new GetLastModified($dt);
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:getlastmodified');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $lastMod->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ /*
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:getlastmodified xmlns:d="DAV:" xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">' .
+HTTP\Util::toHTTPDate($dt) .
+'</d:getlastmodified>
+', $xml);
+ */
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:getlastmodified xmlns:d="DAV:">' .
+HTTP\Util::toHTTPDate($dt) .
+'</d:getlastmodified>
+', $xml);
+
+ $ok = false;
+ try {
+ GetLastModified::unserialize(DAV\XMLUtil::loadDOMDocument($xml)->firstChild);
+ } catch (DAV\Exception $e) {
+ $ok = true;
+ }
+ if (!$ok) $this->markTestFailed('Unserialize should not be supported');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/HrefListTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/HrefListTest.php
new file mode 100644
index 000000000..fe2bc81f9
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/HrefListTest.php
@@ -0,0 +1,91 @@
+<?php
+
+namespace Sabre\DAV\Property;
+use Sabre\DAV;
+
+class HrefListTest extends \PHPUnit_Framework_TestCase {
+
+ function testConstruct() {
+
+ $href = new HrefList(array('foo','bar'));
+ $this->assertEquals(array('foo','bar'),$href->getHrefs());
+
+ }
+
+ function testSerialize() {
+
+ $href = new HrefList(array('foo','bar'));
+ $this->assertEquals(array('foo','bar'),$href->getHrefs());
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:anything');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+ $server->setBaseUri('/bla/');
+
+ $href->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:anything xmlns:d="DAV:"><d:href>/bla/foo</d:href><d:href>/bla/bar</d:href></d:anything>
+', $xml);
+
+ }
+
+ function testSerializeNoPrefix() {
+
+ $href = new HrefList(array('foo','bar'), false);
+ $this->assertEquals(array('foo','bar'),$href->getHrefs());
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:anything');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+ $server->setBaseUri('/bla/');
+
+ $href->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:anything xmlns:d="DAV:"><d:href>foo</d:href><d:href>bar</d:href></d:anything>
+', $xml);
+
+ }
+
+ function testUnserialize() {
+
+ $xml = '<?xml version="1.0"?>
+<d:anything xmlns:d="urn:DAV"><d:href>/bla/foo</d:href><d:href>/bla/bar</d:href></d:anything>
+';
+
+ $dom = new \DOMDocument();
+ $dom->loadXML($xml);
+
+ $href = HrefList::unserialize($dom->firstChild);
+ $this->assertEquals(array('/bla/foo','/bla/bar'),$href->getHrefs());
+
+ }
+
+ function testUnserializeIncompatible() {
+
+ $xml = '<?xml version="1.0"?>
+<d:anything xmlns:d="urn:DAV"><d:href2>/bla/foo</d:href2></d:anything>
+';
+
+ $dom = new \DOMDocument();
+ $dom->loadXML($xml);
+
+ $href = HrefList::unserialize($dom->firstChild);
+ $this->assertEquals(array(), $href->getHrefs());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/HrefTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/HrefTest.php
new file mode 100644
index 000000000..e5607f51b
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/HrefTest.php
@@ -0,0 +1,119 @@
+<?php
+
+namespace Sabre\DAV\Property;
+
+use Sabre\DAV;
+
+class HrefTest extends \PHPUnit_Framework_TestCase {
+
+ function testConstruct() {
+
+ $href = new Href('path');
+ $this->assertEquals('path',$href->getHref());
+
+ }
+
+ function testSerialize() {
+
+ $href = new Href('path');
+ $this->assertEquals('path',$href->getHref());
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:anything');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+ $server->setBaseUri('/bla/');
+
+ $href->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:anything xmlns:d="DAV:"><d:href>/bla/path</d:href></d:anything>
+', $xml);
+
+ }
+
+ function testSerializeNoPrefix() {
+
+ $href = new Href('path',false);
+ $this->assertEquals('path',$href->getHref());
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:anything');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+ $server->setBaseUri('/bla/');
+
+ $href->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:anything xmlns:d="DAV:"><d:href>path</d:href></d:anything>
+', $xml);
+
+ }
+
+ function testUnserialize() {
+
+ $xml = '<?xml version="1.0"?>
+<d:anything xmlns:d="urn:DAV"><d:href>/bla/path</d:href></d:anything>
+';
+
+ $dom = new \DOMDocument();
+ $dom->loadXML($xml);
+
+ $href = Href::unserialize($dom->firstChild);
+ $this->assertEquals('/bla/path',$href->getHref());
+
+ }
+
+ function testUnserializeIncompatible() {
+
+ $xml = '<?xml version="1.0"?>
+<d:anything xmlns:d="urn:DAV"><d:href2>/bla/path</d:href2></d:anything>
+';
+
+ $dom = new \DOMDocument();
+ $dom->loadXML($xml);
+
+ $href = Href::unserialize($dom->firstChild);
+ $this->assertNull($href);
+
+ }
+
+ /**
+ * This method tests if hrefs containing & are correctly encoded.
+ */
+ function testSerializeEntity() {
+
+ $href = new Href('http://example.org/?a&b', false);
+ $this->assertEquals('http://example.org/?a&b',$href->getHref());
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:anything');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+ $server->setBaseUri('/bla/');
+
+ $href->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:anything xmlns:d="DAV:"><d:href>http://example.org/?a&amp;b</d:href></d:anything>
+', $xml);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/ResourceTypeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/ResourceTypeTest.php
new file mode 100644
index 000000000..8a579baec
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/ResourceTypeTest.php
@@ -0,0 +1,111 @@
+<?php
+
+namespace Sabre\DAV\Property;
+
+use Sabre\DAV;
+
+class ResourceTypeTest extends \PHPUnit_Framework_TestCase {
+
+ function testConstruct() {
+
+ $resourceType = new ResourceType(array('{DAV:}collection'));
+ $this->assertEquals(array('{DAV:}collection'),$resourceType->getValue());
+
+ $resourceType = new ResourceType(DAV\Server::NODE_FILE);
+ $this->assertEquals(array(),$resourceType->getValue());
+
+ $resourceType = new ResourceType(DAV\Server::NODE_DIRECTORY);
+ $this->assertEquals(array('{DAV:}collection'),$resourceType->getValue());
+
+ $resourceType = new ResourceType('{DAV:}principal');
+ $this->assertEquals(array('{DAV:}principal'),$resourceType->getValue());
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testSerialize() {
+
+ $resourceType = new ResourceType(array('{DAV:}collection','{DAV:}principal'));
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:anything');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+ $resourceType->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:anything xmlns:d="DAV:"><d:collection/><d:principal/></d:anything>
+', $xml);
+
+ }
+
+ /**
+ * @depends testSerialize
+ */
+ function testSerializeCustomNS() {
+
+ $resourceType = new ResourceType(array('{http://example.org/NS}article'));
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:anything');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+ $resourceType->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:anything xmlns:d="DAV:"><custom:article xmlns:custom="http://example.org/NS"/></d:anything>
+', $xml);
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testIs() {
+
+ $resourceType = new ResourceType(array('{DAV:}collection','{DAV:}principal'));
+ $this->assertTrue($resourceType->is('{DAV:}collection'));
+ $this->assertFalse($resourceType->is('{DAV:}blabla'));
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testAdd() {
+
+ $resourceType = new ResourceType(array('{DAV:}collection','{DAV:}principal'));
+ $resourceType->add('{DAV:}foo');
+ $this->assertEquals(array('{DAV:}collection','{DAV:}principal','{DAV:}foo'), $resourceType->getValue());
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testUnserialize() {
+
+ $xml ='<?xml version="1.0"?>
+<d:anything xmlns:d="DAV:"><d:collection/><d:principal/></d:anything>
+';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $resourceType = ResourceType::unserialize($dom->firstChild);
+ $this->assertEquals(array('{DAV:}collection','{DAV:}principal'),$resourceType->getValue());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseListTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseListTest.php
new file mode 100644
index 000000000..d13066b80
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseListTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Sabre\DAV\Property;
+
+class ResponseListTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * This was the only part not yet covered by other tests, so I'm going to
+ * be lazy and (for now) only test this case.
+ *
+ * @expectedException InvalidArgumentException
+ */
+ public function testInvalidArg() {
+
+ $response = new ResponseList(array(1,2));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseTest.php
new file mode 100644
index 000000000..073cbb2ce
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/ResponseTest.php
@@ -0,0 +1,230 @@
+<?php
+
+namespace Sabre\DAV\Property;
+
+use Sabre\DAV;
+
+class ResponseTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $innerProps = array(
+ 200 => array(
+ '{DAV:}displayname' => 'my file',
+ ),
+ 404 => array(
+ '{DAV:}owner' => null,
+ )
+ );
+
+ $property = new Response('uri',$innerProps);
+
+ $this->assertEquals('uri',$property->getHref());
+ $this->assertEquals($innerProps,$property->getResponseProperties());
+
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerialize() {
+
+ $innerProps = array(
+ 200 => array(
+ '{DAV:}displayname' => 'my file',
+ ),
+ 404 => array(
+ '{DAV:}owner' => null,
+ )
+ );
+
+ $property = new Response('uri',$innerProps);
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">' .
+'<d:response>' .
+'<d:href>/uri</d:href>' .
+'<d:propstat>' .
+'<d:prop>' .
+'<d:displayname>my file</d:displayname>' .
+'</d:prop>' .
+'<d:status>HTTP/1.1 200 OK</d:status>' .
+'</d:propstat>' .
+'<d:propstat>' .
+'<d:prop>' .
+'<d:owner/>' .
+'</d:prop>' .
+'<d:status>HTTP/1.1 404 Not Found</d:status>' .
+'</d:propstat>' .
+'</d:response>' .
+'</d:root>
+', $xml);
+
+ }
+
+ /**
+ * This one is specifically for testing properties with no namespaces, which is legal xml
+ *
+ * @depends testSerialize
+ */
+ function testSerializeEmptyNamespace() {
+
+ $innerProps = array(
+ 200 => array(
+ '{}propertyname' => 'value',
+ ),
+ );
+
+ $property = new Response('uri',$innerProps);
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">' .
+'<d:response>' .
+'<d:href>/uri</d:href>' .
+'<d:propstat>' .
+'<d:prop>' .
+'<propertyname xmlns="">value</propertyname>' .
+'</d:prop>' .
+'<d:status>HTTP/1.1 200 OK</d:status>' .
+'</d:propstat>' .
+'</d:response>' .
+'</d:root>
+', $xml);
+
+ }
+
+ /**
+ * This one is specifically for testing properties with no namespaces, which is legal xml
+ *
+ * @depends testSerialize
+ */
+ function testSerializeCustomNamespace() {
+
+ $innerProps = array(
+ 200 => array(
+ '{http://sabredav.org/NS/example}propertyname' => 'value',
+ ),
+ );
+
+ $property = new Response('uri',$innerProps);
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">' .
+'<d:response>' .
+'<d:href>/uri</d:href>' .
+'<d:propstat>' .
+'<d:prop>' .
+'<x2:propertyname xmlns:x2="http://sabredav.org/NS/example">value</x2:propertyname>' .
+'</d:prop>' .
+'<d:status>HTTP/1.1 200 OK</d:status>' .
+'</d:propstat>' .
+'</d:response>' .
+'</d:root>
+', $xml);
+
+ }
+
+ /**
+ * @depends testSerialize
+ */
+ function testSerializeComplexProperty() {
+
+ $innerProps = array(
+ 200 => array(
+ '{DAV:}link' => new Href('http://sabredav.org/', false)
+ ),
+ );
+
+ $property = new Response('uri',$innerProps);
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">' .
+'<d:response>' .
+'<d:href>/uri</d:href>' .
+'<d:propstat>' .
+'<d:prop>' .
+'<d:link><d:href>http://sabredav.org/</d:href></d:link>' .
+'</d:prop>' .
+'<d:status>HTTP/1.1 200 OK</d:status>' .
+'</d:propstat>' .
+'</d:response>' .
+'</d:root>
+', $xml);
+
+ }
+
+ /**
+ * @depends testSerialize
+ * @expectedException Sabre\DAV\Exception
+ */
+ function testSerializeBreak() {
+
+ $innerProps = array(
+ 200 => array(
+ '{DAV:}link' => new \STDClass()
+ ),
+ );
+
+ $property = new Response('uri',$innerProps);
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $server = new DAV\Server();
+
+ $property->serialize($server, $root);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Property/SupportedReportSetTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Property/SupportedReportSetTest.php
new file mode 100644
index 000000000..445e22ab3
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Property/SupportedReportSetTest.php
@@ -0,0 +1,128 @@
+<?php
+
+namespace Sabre\DAV\Property;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+require_once 'Sabre/DAV/AbstractServer.php';
+
+class SupportedReportSetTest extends DAV\AbstractServer {
+
+ public function sendPROPFIND($body) {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'PROPFIND',
+ 'HTTP_DEPTH' => '0',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($body);
+
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ }
+
+ /**
+ * @covers Sabre\DAV\Property\SupportedReportSet
+ */
+ function testNoReports() {
+
+ $xml = '<?xml version="1.0"?>
+<d:propfind xmlns:d="DAV:">
+ <d:prop>
+ <d:supported-report-set />
+ </d:prop>
+</d:propfind>';
+
+ $this->sendPROPFIND($xml);
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'We expected a multi-status response. Full response body: ' . $this->response->body);
+
+ $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
+ $xml = simplexml_load_string($body);
+ $xml->registerXPathNamespace('d','urn:DAV');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop');
+ $this->assertEquals(1,count($data),'We expected 1 \'d:prop\' element');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supported-report-set');
+ $this->assertEquals(1,count($data),'We expected 1 \'d:supported-report-set\' element');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:status');
+ $this->assertEquals(1,count($data),'We expected 1 \'d:status\' element');
+
+ $this->assertEquals('HTTP/1.1 200 OK',(string)$data[0],'The status for this property should have been 200');
+
+ }
+
+ /**
+ * @covers Sabre\DAV\Property\SupportedReportSet
+ * @depends testNoReports
+ */
+ function testCustomReport() {
+
+ // Intercepting the report property
+ $this->server->subscribeEvent('afterGetProperties',array($this,'addProp'));
+
+ $xml = '<?xml version="1.0"?>
+<d:propfind xmlns:d="DAV:">
+ <d:prop>
+ <d:supported-report-set />
+ </d:prop>
+</d:propfind>';
+
+ $this->sendPROPFIND($xml);
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'We expected a multi-status response. Full response body: ' . $this->response->body);
+
+ $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
+ $xml = simplexml_load_string($body);
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('x','http://www.rooftopsolutions.nl/testnamespace');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop');
+ $this->assertEquals(1,count($data),'We expected 1 \'d:prop\' element');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supported-report-set');
+ $this->assertEquals(1,count($data),'We expected 1 \'d:supported-report-set\' element');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supported-report-set/d:supported-report');
+ $this->assertEquals(2,count($data),'We expected 2 \'d:supported-report\' elements');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supported-report-set/d:supported-report/d:report');
+ $this->assertEquals(2,count($data),'We expected 2 \'d:report\' elements');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supported-report-set/d:supported-report/d:report/x:myreport');
+ $this->assertEquals(1,count($data),'We expected 1 \'x:myreport\' element. Full body: ' . $this->response->body);
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supported-report-set/d:supported-report/d:report/d:anotherreport');
+ $this->assertEquals(1,count($data),'We expected 1 \'d:anotherreport\' element. Full body: ' . $this->response->body);
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:status');
+ $this->assertEquals(1,count($data),'We expected 1 \'d:status\' element');
+
+ $this->assertEquals('HTTP/1.1 200 OK',(string)$data[0],'The status for this property should have been 200');
+
+ }
+
+ /**
+ * This method is used as a callback for afterGetProperties
+ */
+ function addProp($path, &$properties) {
+
+ if (isset($properties[200]['{DAV:}supported-report-set'])) {
+ $properties[200]['{DAV:}supported-report-set']->addReport('{http://www.rooftopsolutions.nl/testnamespace}myreport');
+ $properties[200]['{DAV:}supported-report-set']->addReport('{DAV:}anotherreport');
+ }
+
+ }
+
+
+
+}
+
+?>
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerCopyMoveTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerCopyMoveTest.php
new file mode 100644
index 000000000..88e107c19
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerCopyMoveTest.php
@@ -0,0 +1,268 @@
+<?php
+
+namespace Sabre\DAV;
+
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class ServerCopyMoveTest extends \PHPUnit_Framework_TestCase {
+
+ private $response;
+ /**
+ * @var Server
+ */
+ private $server;
+
+ function setUp() {
+
+ $this->response = new HTTP\ResponseMock();
+ $dir = new FS\Directory(SABRE_TEMPDIR);
+ $tree = new ObjectTree($dir);
+ $this->server = new Server($tree);
+ $this->server->debugExceptions = true;
+ $this->server->httpResponse = $this->response;
+ file_put_contents(SABRE_TEMPDIR . '/test.txt', 'Test contents');
+ file_put_contents(SABRE_TEMPDIR . '/test2.txt', 'Test contents2');
+ mkdir(SABRE_TEMPDIR . '/col');
+ file_put_contents(SABRE_TEMPDIR . 'col/test.txt', 'Test contents');
+
+ }
+
+ function tearDown() {
+
+ $cleanUp = array('test.txt','testput.txt','testcol','test2.txt','test3.txt','col/test.txt','col','col2/test.txt','col2');
+ foreach($cleanUp as $file) {
+ $tmpFile = SABRE_TEMPDIR . '/' . $file;
+ if (file_exists($tmpFile)) {
+
+ if (is_dir($tmpFile)) {
+ rmdir($tmpFile);
+ } else {
+ unlink($tmpFile);
+ }
+
+ }
+ }
+
+ }
+
+
+ function testCopyOverWrite() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'COPY',
+ 'HTTP_DESTINATION' => '/test2.txt',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status,'Received an incorrect HTTP status. Full body inspection: ' . $this->response->body);
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR. '/test2.txt'));
+
+ }
+
+ function testCopyToSelf() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'COPY',
+ 'HTTP_DESTINATION' => '/test.txt',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status,'Received an incorrect HTTP status. Full body inspection: ' . $this->response->body);
+ $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR. '/test.txt'));
+
+ }
+
+ function testMoveToSelf() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'MOVE',
+ 'HTTP_DESTINATION' => '/test.txt',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status,'Received an incorrect HTTP status. Full body inspection: ' . $this->response->body);
+ $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR. '/test.txt'));
+
+ }
+
+ function testMoveOverWrite() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'MOVE',
+ 'HTTP_DESTINATION' => '/test2.txt',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Length' => 0,
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
+ $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR . '/test2.txt'));
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/test.txt'),'The sourcefile test.txt should no longer exist at this point');
+
+ }
+
+ function testBlockedOverWrite() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'COPY',
+ 'HTTP_DESTINATION' => '/test2.txt',
+ 'HTTP_OVERWRITE' => 'F',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status);
+ $this->assertEquals('Test contents2',file_get_contents(SABRE_TEMPDIR . '/test2.txt'));
+
+
+ }
+
+ function testNonExistantParent() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'COPY',
+ 'HTTP_DESTINATION' => '/testcol2/test2.txt',
+ 'HTTP_OVERWRITE' => 'F',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status);
+
+ }
+
+ function testRandomOverwriteHeader() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'COPY',
+ 'HTTP_DESTINATION' => '/testcol2/test2.txt',
+ 'HTTP_OVERWRITE' => 'SURE!',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status);
+
+ }
+
+ function testCopyDirectory() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/col',
+ 'REQUEST_METHOD' => 'COPY',
+ 'HTTP_DESTINATION' => '/col2',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR . '/col2/test.txt'));
+
+ }
+
+ function testSimpleCopyFile() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'COPY',
+ 'HTTP_DESTINATION' => '/test3.txt',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR . '/test3.txt'));
+
+ }
+
+ function testSimpleCopyCollection() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/col',
+ 'REQUEST_METHOD' => 'COPY',
+ 'HTTP_DESTINATION' => '/col2',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'Incorrect status received. Full response body: ' . $this->response->body);
+
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),
+ $this->response->headers
+ );
+
+
+ $this->assertEquals('Test contents',file_get_contents(SABRE_TEMPDIR . '/col2/test.txt'));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php
new file mode 100644
index 000000000..2c7a074df
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/DAV/AbstractServer.php';
+
+class ServerEventsTest extends AbstractServer {
+
+ private $tempPath;
+
+ private $exception;
+
+ function testAfterBind() {
+
+ $this->server->subscribeEvent('afterBind',array($this,'afterBindHandler'));
+ $newPath = 'afterBind';
+
+ $this->tempPath = '';
+ $this->server->createFile($newPath,'body');
+ $this->assertEquals($newPath, $this->tempPath);
+
+ }
+
+ function afterBindHandler($path) {
+
+ $this->tempPath = $path;
+
+ }
+
+ function testBeforeBindCancel() {
+
+ $this->server->subscribeEvent('beforeBind', array($this,'beforeBindCancelHandler'));
+ $this->assertFalse($this->server->createFile('bla','body'));
+
+ // Also testing put()
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/barbar',
+ ));
+
+ $this->server->httpRequest = $req;
+ $this->server->exec();
+
+ $this->assertEquals('',$this->server->httpResponse->status);
+
+ }
+
+ function beforeBindCancelHandler() {
+
+ return false;
+
+ }
+
+ function testException() {
+
+ $this->server->subscribeEvent('exception', array($this, 'exceptionHandler'));
+
+ $req = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'GET',
+ 'REQUEST_URI' => '/not/exisitng',
+ ));
+ $this->server->httpRequest = $req;
+ $this->server->exec();
+
+ $this->assertInstanceOf('Sabre\\DAV\\Exception\\NotFound', $this->exception);
+
+ }
+
+ function exceptionHandler(Exception $exception) {
+
+ $this->exception = $exception;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerFinderBlockTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerFinderBlockTest.php
new file mode 100644
index 000000000..180f27b2a
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerFinderBlockTest.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace Sabre\DAV;
+
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+require_once 'Sabre/DAV/AbstractServer.php';
+
+class ServerFinderBlockTest extends AbstractServer{
+
+ function testPut() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testput.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ 'HTTP_X_EXPECTED_ENTITY_LENGTH' => '20',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing finder');
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('', $this->response->body);
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals('0', $this->response->headers['Content-Length']);
+
+ $this->assertEquals('Testing finder',file_get_contents(SABRE_TEMPDIR . '/testput.txt'));
+
+ }
+
+ function testPutFail() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testput.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ 'HTTP_X_EXPECTED_ENTITY_LENGTH' => '20',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('');
+ $this->server->httpRequest = $request;
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/testput.txt'));
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php
new file mode 100644
index 000000000..34b084dcd
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php
@@ -0,0 +1,371 @@
+<?php
+
+namespace Sabre\DAV;
+
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+require_once 'Sabre/DAV/AbstractServer.php';
+require_once 'Sabre/DAV/Exception.php';
+
+class ServerMKCOLTest extends AbstractServer {
+
+ function testMkcol() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody("");
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+ $this->assertTrue(is_dir($this->tempDir . '/testcol'));
+
+ }
+
+ /**
+ * @depends testMkcol
+ */
+ function testMKCOLUnknownBody() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody("Hello");
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 415 Unsupported Media Type',$this->response->status);
+
+ }
+
+ /**
+ * @depends testMkcol
+ */
+ function testMKCOLBrokenXML() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody("Hello");
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status);
+
+ }
+
+ /**
+ * @depends testMkcol
+ */
+ function testMKCOLUnknownXML() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?><html></html>');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 415 Unsupported Media Type',$this->response->status);
+
+ }
+
+ /**
+ * @depends testMkcol
+ */
+ function testMKCOLNoResourceType() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<mkcol xmlns="DAV:">
+ <set>
+ <prop>
+ <displayname>Evert</displayname>
+ </prop>
+ </set>
+</mkcol>');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body);
+
+ }
+
+ /**
+ * @depends testMKCOLNoResourceType
+ */
+ function testMKCOLIncorrectResourceType() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<mkcol xmlns="DAV:">
+ <set>
+ <prop>
+ <resourcetype><blabla /></resourcetype>
+ </prop>
+ </set>
+</mkcol>');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body);
+
+ }
+
+ /**
+ * @depends testMKCOLIncorrectResourceType
+ */
+ function testMKCOLIncorrectResourceType2() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<mkcol xmlns="DAV:">
+ <set>
+ <prop>
+ <resourcetype><collection /><blabla /></resourcetype>
+ </prop>
+ </set>
+</mkcol>');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body);
+
+ }
+
+ /**
+ * @depends testMKCOLIncorrectResourceType2
+ */
+ function testMKCOLSuccess() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<mkcol xmlns="DAV:">
+ <set>
+ <prop>
+ <resourcetype><collection /></resourcetype>
+ </prop>
+ </set>
+</mkcol>');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body);
+
+ }
+
+ /**
+ * @depends testMKCOLIncorrectResourceType2
+ */
+ function testMKCOLWhiteSpaceResourceType() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<mkcol xmlns="DAV:">
+ <set>
+ <prop>
+ <resourcetype>
+ <collection />
+ </resourcetype>
+ </prop>
+ </set>
+</mkcol>');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body);
+
+ }
+
+ /**
+ * @depends testMKCOLIncorrectResourceType2
+ */
+ function testMKCOLNoParent() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testnoparent/409me',
+ 'REQUEST_METHOD' => 'MKCOL',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('');
+
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body);
+
+ }
+
+ /**
+ * @depends testMKCOLIncorrectResourceType2
+ */
+ function testMKCOLParentIsNoCollection() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt/409me',
+ 'REQUEST_METHOD' => 'MKCOL',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('');
+
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body);
+
+ }
+
+ /**
+ * @depends testMKCOLIncorrectResourceType2
+ */
+ function testMKCOLAlreadyExists() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'MKCOL',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('');
+
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ 'Allow' => 'OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 405 Method Not Allowed',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body);
+
+ }
+
+ /**
+ * @depends testMKCOLSuccess
+ * @depends testMKCOLAlreadyExists
+ */
+ function testMKCOLAndProps() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
+ 'HTTP_CONTENT_TYPE' => 'application/xml',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('<?xml version="1.0"?>
+<mkcol xmlns="DAV:">
+ <set>
+ <prop>
+ <resourcetype><collection /></resourcetype>
+ <displayname>my new collection</displayname>
+ </prop>
+ </set>
+</mkcol>');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body);
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php
new file mode 100644
index 000000000..8f1451b49
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php
@@ -0,0 +1,98 @@
+<?php
+
+namespace Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/DAV/AbstractServer.php';
+require_once 'Sabre/DAV/TestPlugin.php';
+
+class ServerPluginTest extends AbstractServer {
+
+ /**
+ * @var Sabre\DAV\TestPlugin
+ */
+ protected $testPlugin;
+
+ function setUp() {
+
+ parent::setUp();
+
+ $testPlugin = new TestPlugin();
+ $this->server->addPlugin($testPlugin);
+ $this->testPlugin = $testPlugin;
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\ServerPlugin
+ */
+ function testBaseClass() {
+
+ $p = new ServerPluginMock();
+ $this->assertEquals(array(),$p->getFeatures());
+ $this->assertEquals(array(),$p->getHTTPMethods(''));
+
+ }
+
+ function testOptions() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'OPTIONS',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'DAV' => '1, 3, extended-mkcol, drinking',
+ 'MS-Author-Via' => 'DAV',
+ 'Allow' => 'OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT, BEER, WINE',
+ 'Accept-Ranges' => 'bytes',
+ 'Content-Length' => '0',
+ 'X-Sabre-Version' => Version::VERSION,
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+ $this->assertEquals('OPTIONS',$this->testPlugin->beforeMethod);
+
+
+ }
+
+ function testGetPlugin() {
+
+ $this->assertEquals($this->testPlugin,$this->server->getPlugin(get_class($this->testPlugin)));
+
+ }
+
+ function testUnknownPlugin() {
+
+ $this->assertNull($this->server->getPlugin('SomeRandomClassName'));
+
+ }
+
+ function testGetSupportedReportSet() {
+
+ $this->assertEquals(array(), $this->testPlugin->getSupportedReportSet('/'));
+
+ }
+
+ function testGetPlugins() {
+
+ $this->assertEquals(
+ array(get_class($this->testPlugin) => $this->testPlugin),
+ $this->server->getPlugins()
+ );
+
+ }
+
+
+}
+
+class ServerPluginMock extends ServerPlugin {
+
+ function initialize(Server $s) { }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerPreconditionTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerPreconditionTest.php
new file mode 100644
index 000000000..ea09852a7
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerPreconditionTest.php
@@ -0,0 +1,395 @@
+<?php
+
+namespace Sabre\DAV;
+
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @covers Sabre\DAV\Server::checkPreconditions
+ * @expectedException Sabre\DAV\Exception\PreconditionFailed
+ */
+ function testIfMatchNoNode() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_MATCH' => '*',
+ 'REQUEST_URI' => '/bar'
+ ));
+ $server->httpRequest = $httpRequest;
+
+ $server->checkPreconditions();
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ function testIfMatchHasNode() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_MATCH' => '*',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+
+ $this->assertTrue($server->checkPreconditions());
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ * @expectedException Sabre\DAV\Exception\PreconditionFailed
+ */
+ function testIfMatchWrongEtag() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_MATCH' => '1234',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+
+ $server->checkPreconditions();
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ function testIfMatchCorrectEtag() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_MATCH' => '"abc123"',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+
+ $this->assertTrue($server->checkPreconditions());
+
+ }
+
+ /**
+ * Evolution sometimes uses \" instead of " for If-Match headers.
+ *
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ * @depends testIfMatchCorrectEtag
+ */
+ function testIfMatchEvolutionEtag() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_MATCH' => '\\"abc123\\"',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+
+ $this->assertTrue($server->checkPreconditions());
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ function testIfMatchMultiple() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_MATCH' => '"hellothere", "abc123"',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+
+ $this->assertTrue($server->checkPreconditions());
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ function testIfNoneMatchNoNode() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_NONE_MATCH' => '*',
+ 'REQUEST_URI' => '/bar'
+ ));
+ $server->httpRequest = $httpRequest;
+
+ $this->assertTrue($server->checkPreconditions());
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ * @expectedException Sabre\DAV\Exception\PreconditionFailed
+ */
+ function testIfNoneMatchHasNode() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_NONE_MATCH' => '*',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+
+ $server->checkPreconditions();
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ function testIfNoneMatchWrongEtag() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_NONE_MATCH' => '"1234"',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+
+ $this->assertTrue($server->checkPreconditions());
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ function testIfNoneMatchWrongEtagMultiple() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_NONE_MATCH' => '"1234", "5678"',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+
+ $this->assertTrue($server->checkPreconditions());
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ * @expectedException Sabre\DAV\Exception\PreconditionFailed
+ */
+ public function testIfNoneMatchCorrectEtag() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_NONE_MATCH' => '"abc123"',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+
+ $server->checkPreconditions();
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ * @expectedException Sabre\DAV\Exception\PreconditionFailed
+ */
+ public function testIfNoneMatchCorrectEtagMultiple() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_NONE_MATCH' => '"1234", "abc123"',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+
+ $server->checkPreconditions();
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ public function testIfNoneMatchCorrectEtagAsGet() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_NONE_MATCH' => '"abc123"',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+ $server->httpResponse = new HTTP\ResponseMock();
+
+ $this->assertFalse($server->checkPreconditions(true));
+ $this->assertEquals('HTTP/1.1 304 Not Modified',$server->httpResponse->status);
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ public function testIfModifiedSinceUnModified() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_MODIFIED_SINCE' => 'Sun, 06 Nov 1994 08:49:37 GMT',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+ $server->httpResponse = new HTTP\ResponseMock();
+ $this->assertFalse($server->checkPreconditions());
+
+ $this->assertEquals('HTTP/1.1 304 Not Modified',$server->httpResponse->status);
+ $this->assertEquals(array(
+ 'Last-Modified' => 'Sat, 06 Apr 1985 23:30:00 GMT',
+ ), $server->httpResponse->headers);
+
+ }
+
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ public function testIfModifiedSinceModified() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_MODIFIED_SINCE' => 'Tue, 06 Nov 1984 08:49:37 GMT',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+ $server->httpResponse = new HTTP\ResponseMock();
+ $this->assertTrue($server->checkPreconditions());
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ public function testIfModifiedSinceInvalidDate() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_MODIFIED_SINCE' => 'Your mother',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+ $server->httpResponse = new HTTP\ResponseMock();
+
+ // Invalid dates must be ignored, so this should return true
+ $this->assertTrue($server->checkPreconditions());
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ public function testIfModifiedSinceInvalidDate2() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_MODIFIED_SINCE' => 'Sun, 06 Nov 1994 08:49:37 EST',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+ $server->httpResponse = new HTTP\ResponseMock();
+ $this->assertTrue($server->checkPreconditions());
+
+ }
+
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ public function testIfUnmodifiedSinceUnModified() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_UNMODIFIED_SINCE' => 'Sun, 06 Nov 1994 08:49:37 GMT',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+ $this->assertTrue($server->checkPreconditions());
+
+ }
+
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ * @expectedException Sabre\DAV\Exception\PreconditionFailed
+ */
+ public function testIfUnmodifiedSinceModified() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_UNMODIFIED_SINCE' => 'Tue, 06 Nov 1984 08:49:37 GMT',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+ $server->httpResponse = new HTTP\ResponseMock();
+ $server->checkPreconditions();
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::checkPreconditions
+ */
+ public function testIfUnmodifiedSinceInvalidDate() {
+
+ $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $server = new Server($root);
+ $httpRequest = new HTTP\Request(array(
+ 'HTTP_IF_UNMODIFIED_SINCE' => 'Sun, 06 Nov 1984 08:49:37 CET',
+ 'REQUEST_URI' => '/foo'
+ ));
+ $server->httpRequest = $httpRequest;
+ $server->httpResponse = new HTTP\ResponseMock();
+ $this->assertTrue($server->checkPreconditions());
+
+ }
+
+
+}
+
+class ServerPreconditionsNode extends File {
+
+ function getETag() {
+
+ return '"abc123"';
+
+ }
+
+ function getLastModified() {
+
+ /* my birthday & time, I believe */
+ return strtotime('1985-04-07 01:30 +02:00');
+
+ }
+
+ function getName() {
+
+ return 'foo';
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerPropsTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerPropsTest.php
new file mode 100644
index 000000000..859a91070
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerPropsTest.php
@@ -0,0 +1,413 @@
+<?php
+
+namespace Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+require_once 'Sabre/DAV/AbstractServer.php';
+
+class ServerPropsTest extends AbstractServer {
+
+ protected function getRootNode() {
+
+ return new FSExt\Directory(SABRE_TEMPDIR);
+
+ }
+
+ function setUp() {
+
+ if (file_exists(SABRE_TEMPDIR.'../.sabredav')) unlink(SABRE_TEMPDIR.'../.sabredav');
+ parent::setUp();
+ file_put_contents(SABRE_TEMPDIR . '/test2.txt', 'Test contents2');
+ mkdir(SABRE_TEMPDIR . '/col');
+ file_put_contents(SABRE_TEMPDIR . 'col/test.txt', 'Test contents');
+ $this->server->addPlugin(new Locks\Plugin(new Locks\Backend\File(SABRE_TEMPDIR . '/.locksdb')));
+
+ }
+
+ function tearDown() {
+
+ parent::tearDown();
+ if (file_exists(SABRE_TEMPDIR.'../.locksdb')) unlink(SABRE_TEMPDIR.'../.locksdb');
+
+ }
+
+ private function sendRequest($body) {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'PROPFIND',
+ 'HTTP_DEPTH' => '0',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($body);
+
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ }
+
+ public function testPropFindEmptyBody() {
+
+ $hasFired = false;
+
+ $self = $this;
+ // Also testing the beforeGetPropertiesForPath event.
+ $this->server->subscribeEvent('beforeGetPropertiesForPath', function($path, $properties, $depth) use ($self, &$hasFired) {
+
+ $hasFired = true;
+ $self->assertEquals('', $path);
+ $self->assertEquals(array(), $properties);
+ $self->assertEquals(0, $depth);
+
+ });
+
+ $this->sendRequest("");
+
+ $this->assertTrue($hasFired);
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status);
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ 'DAV' => '1, 3, extended-mkcol, 2',
+ 'Vary' => 'Brief,Prefer',
+ ),
+ $this->response->headers
+ );
+
+ $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
+ $xml = simplexml_load_string($body);
+ $xml->registerXPathNamespace('d','urn:DAV');
+
+ list($data) = $xml->xpath('/d:multistatus/d:response/d:href');
+ $this->assertEquals('/',(string)$data,'href element should have been /');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:resourcetype');
+ $this->assertEquals(1,count($data));
+
+ }
+
+ function testSupportedLocks() {
+
+ $xml = '<?xml version="1.0"?>
+<d:propfind xmlns:d="DAV:">
+ <d:prop>
+ <d:supportedlock />
+ </d:prop>
+</d:propfind>';
+
+ $this->sendRequest($xml);
+
+ $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
+ $xml = simplexml_load_string($body);
+ $xml->registerXPathNamespace('d','urn:DAV');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry');
+ $this->assertEquals(2,count($data),'We expected two \'d:lockentry\' tags');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:lockscope');
+ $this->assertEquals(2,count($data),'We expected two \'d:lockscope\' tags');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:locktype');
+ $this->assertEquals(2,count($data),'We expected two \'d:locktype\' tags');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:lockscope/d:shared');
+ $this->assertEquals(1,count($data),'We expected a \'d:shared\' tag');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:lockscope/d:exclusive');
+ $this->assertEquals(1,count($data),'We expected a \'d:exclusive\' tag');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:locktype/d:write');
+ $this->assertEquals(2,count($data),'We expected two \'d:write\' tags');
+ }
+
+ function testLockDiscovery() {
+
+ $xml = '<?xml version="1.0"?>
+<d:propfind xmlns:d="DAV:">
+ <d:prop>
+ <d:lockdiscovery />
+ </d:prop>
+</d:propfind>';
+
+ $this->sendRequest($xml);
+
+ $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
+ $xml = simplexml_load_string($body);
+ $xml->registerXPathNamespace('d','urn:DAV');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:lockdiscovery');
+ $this->assertEquals(1,count($data),'We expected a \'d:lockdiscovery\' tag');
+
+ }
+
+ function testUnknownProperty() {
+
+ $xml = '<?xml version="1.0"?>
+<d:propfind xmlns:d="DAV:">
+ <d:prop>
+ <d:macaroni />
+ </d:prop>
+</d:propfind>';
+
+ $this->sendRequest($xml);
+ $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
+ $xml = simplexml_load_string($body);
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $pathTests = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response',
+ '/d:multistatus/d:response/d:propstat',
+ '/d:multistatus/d:response/d:propstat/d:status',
+ '/d:multistatus/d:response/d:propstat/d:prop',
+ '/d:multistatus/d:response/d:propstat/d:prop/d:macaroni',
+ );
+ foreach($pathTests as $test) {
+ $this->assertTrue(count($xml->xpath($test))==true,'We expected the ' . $test . ' element to appear in the response, we got: ' . $body);
+ }
+
+ $val = $xml->xpath('/d:multistatus/d:response/d:propstat/d:status');
+ $this->assertEquals(1,count($val),$body);
+ $this->assertEquals('HTTP/1.1 404 Not Found',(string)$val[0]);
+
+ }
+
+ /**
+ * @covers Sabre\DAV\Server::parsePropPatchRequest
+ */
+ public function testParsePropPatchRequest() {
+
+ $body = '<?xml version="1.0"?>
+<d:propertyupdate xmlns:d="DAV:" xmlns:s="http://sabredav.org/NS/test">
+ <d:set><d:prop><s:someprop>somevalue</s:someprop></d:prop></d:set>
+ <d:remove><d:prop><s:someprop2 /></d:prop></d:remove>
+ <d:set><d:prop><s:someprop3>removeme</s:someprop3></d:prop></d:set>
+ <d:remove><d:prop><s:someprop3 /></d:prop></d:remove>
+</d:propertyupdate>';
+
+ $result = $this->server->parsePropPatchRequest($body);
+ $this->assertEquals(array(
+ '{http://sabredav.org/NS/test}someprop' => 'somevalue',
+ '{http://sabredav.org/NS/test}someprop2' => null,
+ '{http://sabredav.org/NS/test}someprop3' => null,
+ ), $result);
+
+ }
+
+ /**
+ * @covers Sabre\DAV\Server::updateProperties
+ */
+ public function testUpdateProperties() {
+
+ $props = array(
+ '{http://sabredav.org/NS/test}someprop' => 'somevalue',
+ );
+
+ $result = $this->server->updateProperties('/test2.txt',$props);
+
+ $this->assertEquals(array(
+ '200' => array('{http://sabredav.org/NS/test}someprop' => null),
+ 'href' => '/test2.txt',
+ ), $result);
+
+ }
+
+ /**
+ * @covers Sabre\DAV\Server::updateProperties
+ * @depends testUpdateProperties
+ */
+ public function testUpdatePropertiesProtected() {
+
+ $props = array(
+ '{http://sabredav.org/NS/test}someprop' => 'somevalue',
+ '{DAV:}getcontentlength' => 50,
+ );
+
+ $result = $this->server->updateProperties('/test2.txt',$props);
+
+ $this->assertEquals(array(
+ '424' => array('{http://sabredav.org/NS/test}someprop' => null),
+ '403' => array('{DAV:}getcontentlength' => null),
+ 'href' => '/test2.txt',
+ ), $result);
+
+ }
+
+ /**
+ * @covers Sabre\DAV\Server::updateProperties
+ * @depends testUpdateProperties
+ */
+ public function testUpdatePropertiesFail1() {
+
+ $dir = new PropTestDirMock('updatepropsfalse');
+ $objectTree = new ObjectTree($dir);
+ $this->server->tree = $objectTree;
+
+ $props = array(
+ '{http://sabredav.org/NS/test}someprop' => 'somevalue',
+ );
+
+ $result = $this->server->updateProperties('/',$props);
+
+ $this->assertEquals(array(
+ '403' => array('{http://sabredav.org/NS/test}someprop' => null),
+ 'href' => '/',
+ ), $result);
+
+ }
+
+ /**
+ * @covers Sabre\DAV\Server::updateProperties
+ * @depends testUpdateProperties
+ */
+ public function testUpdatePropertiesFail2() {
+
+ $dir = new PropTestDirMock('updatepropsarray');
+ $objectTree = new ObjectTree($dir);
+ $this->server->tree = $objectTree;
+
+ $props = array(
+ '{http://sabredav.org/NS/test}someprop' => 'somevalue',
+ );
+
+ $result = $this->server->updateProperties('/',$props);
+
+ $this->assertEquals(array(
+ '402' => array('{http://sabredav.org/NS/test}someprop' => null),
+ 'href' => '/',
+ ), $result);
+
+ }
+
+ /**
+ * @covers Sabre\DAV\Server::updateProperties
+ * @depends testUpdateProperties
+ * @expectedException Sabre\DAV\Exception
+ */
+ public function testUpdatePropertiesFail3() {
+
+ $dir = new PropTestDirMock('updatepropsobj');
+ $objectTree = new ObjectTree($dir);
+ $this->server->tree = $objectTree;
+
+ $props = array(
+ '{http://sabredav.org/NS/test}someprop' => 'somevalue',
+ );
+
+ $result = $this->server->updateProperties('/',$props);
+
+ }
+
+ /**
+ * @depends testParsePropPatchRequest
+ * @depends testUpdateProperties
+ * @covers Sabre\DAV\Server::httpPropPatch
+ */
+ public function testPropPatch() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'PROPPATCH',
+ );
+
+ $body = '<?xml version="1.0"?>
+<d:propertyupdate xmlns:d="DAV:" xmlns:s="http://www.rooftopsolutions.nl/testnamespace">
+ <d:set><d:prop><s:someprop>somevalue</s:someprop></d:prop></d:set>
+</d:propertyupdate>';
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($body);
+
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ 'Vary' => 'Brief,Prefer',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'We got the wrong status. Full XML response: ' . $this->response->body);
+
+ $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
+ $xml = simplexml_load_string($body);
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('bla','http://www.rooftopsolutions.nl/testnamespace');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop');
+ $this->assertEquals(1,count($data),'We expected one \'d:prop\' element. Response body: ' . $body);
+
+ $data = $xml->xpath('//bla:someprop');
+ $this->assertEquals(1,count($data),'We expected one \'s:someprop\' element. Response body: ' . $body);
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:status');
+ $this->assertEquals(1,count($data),'We expected one \'s:status\' element. Response body: ' . $body);
+
+ $this->assertEquals('HTTP/1.1 200 OK',(string)$data[0]);
+
+ }
+
+ /**
+ * @depends testPropPatch
+ */
+ public function testPropPatchAndFetch() {
+
+ $this->testPropPatch();
+ $xml = '<?xml version="1.0"?>
+<d:propfind xmlns:d="DAV:" xmlns:s="http://www.rooftopsolutions.nl/testnamespace">
+ <d:prop>
+ <s:someprop />
+ </d:prop>
+</d:propfind>';
+
+ $this->sendRequest($xml);
+
+ $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
+ $xml = simplexml_load_string($body);
+ $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('bla','http://www.rooftopsolutions.nl/testnamespace');
+
+ $xpath='//bla:someprop';
+ $result = $xml->xpath($xpath);
+ $this->assertEquals(1,count($result),'We couldn\'t find our new property in the response. Full response body:' . "\n" . $body);
+ $this->assertEquals('somevalue',(string)$result[0],'We couldn\'t find our new property in the response. Full response body:' . "\n" . $body);
+
+ }
+
+}
+
+class PropTestDirMock extends SimpleCollection implements IProperties {
+
+ public $type;
+
+ function __construct($type) {
+
+ $this->type =$type;
+ parent::__construct('root');
+
+ }
+
+ function updateProperties($updateProperties) {
+
+ switch($this->type) {
+ case 'updatepropsfalse' : return false;
+ case 'updatepropsarray' :
+ $r = array(402 => array());
+ foreach($updateProperties as $k=>$v) $r[402][$k] = null;
+ return $r;
+ case 'updatepropsobj' :
+ return new \STDClass();
+ }
+
+ }
+
+ function getProperties($requestedPropeties) {
+
+ return array();
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerRangeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerRangeTest.php
new file mode 100644
index 000000000..a06fcb0be
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerRangeTest.php
@@ -0,0 +1,274 @@
+<?php
+
+namespace Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/DAV/AbstractServer.php';
+
+class ServerRangeTest extends AbstractServer{
+
+ protected function getRootNode() {
+
+ return new FSExt\Directory(SABRE_TEMPDIR);
+
+ }
+
+ function testRange() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_RANGE' => 'bytes=2-5',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 4,
+ 'Content-Range' => 'bytes 2-5/13',
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')). '"',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 206 Partial Content',$this->response->status);
+ $this->assertEquals('st c', stream_get_contents($this->response->body));
+
+ }
+
+ /**
+ * @depends testRange
+ */
+ function testStartRange() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_RANGE' => 'bytes=2-',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 11,
+ 'Content-Range' => 'bytes 2-12/13',
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')) . '"',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 206 Partial Content',$this->response->status);
+ $this->assertEquals('st contents', stream_get_contents($this->response->body));
+
+ }
+
+ /**
+ * @depends testRange
+ */
+ function testEndRange() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_RANGE' => 'bytes=-8',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 8,
+ 'Content-Range' => 'bytes 5-12/13',
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')). '"',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 206 Partial Content',$this->response->status);
+ $this->assertEquals('contents', stream_get_contents($this->response->body));
+
+ }
+
+ /**
+ * @depends testRange
+ */
+ function testTooHighRange() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_RANGE' => 'bytes=100-200',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 416 Requested Range Not Satisfiable',$this->response->status);
+
+ }
+
+ /**
+ * @depends testRange
+ */
+ function testCrazyRange() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_RANGE' => 'bytes=8-4',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 416 Requested Range Not Satisfiable',$this->response->status);
+
+ }
+
+ /**
+ * @depends testRange
+ * @covers \Sabre\DAV\Server::httpGet
+ */
+ function testIfRangeEtag() {
+
+ $node = $this->server->tree->getNodeForPath('test.txt');
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_RANGE' => 'bytes=2-5',
+ 'HTTP_IF_RANGE' => $node->getETag(),
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 4,
+ 'Content-Range' => 'bytes 2-5/13',
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')) . '"',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 206 Partial Content',$this->response->status);
+ $this->assertEquals('st c', stream_get_contents($this->response->body));
+
+ }
+
+ /**
+ * @depends testRange
+ * @covers \Sabre\DAV\Server::httpGet
+ */
+ function testIfRangeEtagIncorrect() {
+
+ $node = $this->server->tree->getNodeForPath('test.txt');
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_RANGE' => 'bytes=2-5',
+ 'HTTP_IF_RANGE' => $node->getETag() . 'blabla',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 13,
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')) . '"',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals('Test contents', stream_get_contents($this->response->body));
+
+ }
+
+ /**
+ * @depends testRange
+ * @covers \Sabre\DAV\Server::httpGet
+ */
+ function testIfRangeModificationDate() {
+
+ $node = $this->server->tree->getNodeForPath('test.txt');
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_RANGE' => 'bytes=2-5',
+ 'HTTP_IF_RANGE' => 'tomorrow',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 4,
+ 'Content-Range' => 'bytes 2-5/13',
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')) . '"',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 206 Partial Content',$this->response->status);
+ $this->assertEquals('st c', stream_get_contents($this->response->body));
+
+ }
+
+ /**
+ * @depends testRange
+ * @covers \Sabre\DAV\Server::httpGet
+ */
+ function testIfRangeModificationDateModified() {
+
+ $node = $this->server->tree->getNodeForPath('test.txt');
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_RANGE' => 'bytes=2-5',
+ 'HTTP_IF_RANGE' => '-2 years',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 13,
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ 'ETag' => '"' . md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')) . '"',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals('Test contents', stream_get_contents($this->response->body));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php
new file mode 100644
index 000000000..afcd5c98f
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php
@@ -0,0 +1,767 @@
+<?php
+
+namespace Sabre\DAV;
+
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+require_once 'Sabre/DAV/AbstractServer.php';
+require_once 'Sabre/DAV/Exception.php';
+
+class ServerSimpleTest extends AbstractServer{
+
+ function testConstructArray() {
+
+ $nodes = array(
+ new SimpleCollection('hello')
+ );
+
+ $server = new Server($nodes);
+ $this->assertEquals($nodes[0], $server->tree->getNodeForPath('hello'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ */
+ function testConstructIncorrectObj() {
+
+ $nodes = array(
+ new SimpleCollection('hello'),
+ new \STDClass(),
+ );
+
+ $server = new Server($nodes);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ */
+ function testConstructInvalidArg() {
+
+ $server = new Server(1);
+
+ }
+
+ function testGet() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 13,
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals('Test contents', stream_get_contents($this->response->body));
+
+ }
+ function testGetHttp10() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ 'SERVER_PROTOCOL' => 'HTTP/1.0',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 13,
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.0 200 OK',$this->response->status);
+ $this->assertEquals('Test contents', stream_get_contents($this->response->body));
+
+ }
+
+ function testGetDoesntExist() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt_randomblbla',
+ 'REQUEST_METHOD' => 'GET',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+ $this->assertEquals('HTTP/1.1 404 Not Found',$this->response->status);
+
+ }
+
+ function testGetDoesntExist2() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt/randomblbla',
+ 'REQUEST_METHOD' => 'GET',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+ $this->assertEquals('HTTP/1.1 404 Not Found',$this->response->status);
+
+ }
+
+ /**
+ * This test should have the exact same result as testGet.
+ *
+ * The idea is that double slashes // are converted to single ones /
+ *
+ */
+ function testGetDoubleSlash() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '//test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 13,
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals('Test contents', stream_get_contents($this->response->body));
+
+ }
+
+
+ function testHEAD() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'HEAD',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 13,
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+
+ }
+
+ function testPut() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testput.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing new file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('', $this->response->body);
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals(array(
+ "Content-Length" => "0",
+ ), $this->response->headers);
+
+ $this->assertEquals('Testing new file',file_get_contents($this->tempDir . '/testput.txt'));
+
+ }
+
+ function testPutAlreadyExists() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ 'HTTP_IF_NONE_MATCH' => '*',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing new file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status);
+ $this->assertNotEquals('Testing new file',file_get_contents($this->tempDir . '/test.txt'));
+
+ }
+
+ function testPutUpdate() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing updated file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('0', $this->response->headers['Content-Length']);
+
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+ $this->assertEquals('Testing updated file',file_get_contents($this->tempDir . '/test.txt'));
+
+ }
+
+ function testPutNoParentCollection() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt/item.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing updated file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status);
+
+ }
+
+ function testPutContentRange() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testput.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ 'HTTP_CONTENT_RANGE' => 'bytes/100-200',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing new file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented',$this->response->status);
+
+ }
+
+
+ function testDelete() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_METHOD' => 'DELETE',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+ $this->assertFalse(file_exists($this->tempDir . '/test.txt'));
+
+ }
+
+ function testDeleteDirectory() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'DELETE',
+ );
+
+ mkdir($this->tempDir.'/testcol');
+ file_put_contents($this->tempDir.'/testcol/test.txt','Hi! I\'m a file with a short lifespan');
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Length' => '0',
+ ),$this->response->headers);
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+ $this->assertFalse(file_exists($this->tempDir . '/col'));
+
+ }
+
+ function testOptions() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'OPTIONS',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'DAV' => '1, 3, extended-mkcol',
+ 'MS-Author-Via' => 'DAV',
+ 'Allow' => 'OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT',
+ 'Accept-Ranges' => 'bytes',
+ 'Content-Length' => '0',
+ 'X-Sabre-Version' => Version::VERSION,
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals('', $this->response->body);
+
+
+ }
+ function testNonExistantMethod() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'BLABLA',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented',$this->response->status);
+
+
+ }
+
+ function testGETOnCollection() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'GET',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 501 Not Implemented',$this->response->status);
+
+ }
+
+ function testHEADOnCollection() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'HEAD',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+
+ }
+
+ function testBaseUri() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/blabla/test.txt',
+ 'REQUEST_METHOD' => 'GET',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->setBaseUri('/blabla/');
+ $this->assertEquals('/blabla/',$this->server->getBaseUri());
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Length' => 13,
+ 'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals('Test contents', stream_get_contents($this->response->body));
+
+ }
+
+ function testBaseUriAddSlash() {
+
+ $tests = array(
+ '/' => '/',
+ '/foo' => '/foo/',
+ '/foo/' => '/foo/',
+ '/foo/bar' => '/foo/bar/',
+ '/foo/bar/' => '/foo/bar/',
+ );
+
+ foreach($tests as $test=>$result) {
+ $this->server->setBaseUri($test);
+
+ $this->assertEquals($result, $this->server->getBaseUri());
+
+ }
+
+ }
+
+ function testCalculateUri() {
+
+ $uris = array(
+ 'http://www.example.org/root/somepath',
+ '/root/somepath',
+ '/root/somepath/',
+ );
+
+ $this->server->setBaseUri('/root/');
+
+ foreach($uris as $uri) {
+
+ $this->assertEquals('somepath',$this->server->calculateUri($uri));
+
+ }
+
+ $this->server->setBaseUri('/root');
+
+ foreach($uris as $uri) {
+
+ $this->assertEquals('somepath',$this->server->calculateUri($uri));
+
+ }
+
+ $this->assertEquals('', $this->server->calculateUri('/root'));
+
+ }
+
+ function testCalculateUriSpecialChars() {
+
+ $uris = array(
+ 'http://www.example.org/root/%C3%A0fo%C3%B3',
+ '/root/%C3%A0fo%C3%B3',
+ '/root/%C3%A0fo%C3%B3/'
+ );
+
+ $this->server->setBaseUri('/root/');
+
+ foreach($uris as $uri) {
+
+ $this->assertEquals("\xc3\xa0fo\xc3\xb3",$this->server->calculateUri($uri));
+
+ }
+
+ $this->server->setBaseUri('/root');
+
+ foreach($uris as $uri) {
+
+ $this->assertEquals("\xc3\xa0fo\xc3\xb3",$this->server->calculateUri($uri));
+
+ }
+
+ $this->server->setBaseUri('/');
+
+ foreach($uris as $uri) {
+
+ $this->assertEquals("root/\xc3\xa0fo\xc3\xb3",$this->server->calculateUri($uri));
+
+ }
+
+ }
+
+ function testBaseUriCheck() {
+
+ $uris = array(
+ 'http://www.example.org/root/somepath',
+ '/root/somepath',
+ '/root/somepath/'
+ );
+
+ try {
+
+ $this->server->setBaseUri('root/');
+ $this->server->calculateUri('/root/testuri');
+
+ $this->fail('Expected an exception');
+
+ } catch (Exception\Forbidden $e) {
+
+ // This was expected
+
+ }
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::guessBaseUri
+ */
+ function testGuessBaseUri() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/index.php/root',
+ 'PATH_INFO' => '/root',
+ );
+
+ $httpRequest = new HTTP\Request($serverVars);
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $this->assertEquals('/index.php/', $server->guessBaseUri());
+
+ }
+
+ /**
+ * @depends testGuessBaseUri
+ * @covers Sabre\DAV\Server::guessBaseUri
+ */
+ function testGuessBaseUriPercentEncoding() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/index.php/dir/path2/path%20with%20spaces',
+ 'PATH_INFO' => '/dir/path2/path with spaces',
+ );
+
+ $httpRequest = new HTTP\Request($serverVars);
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $this->assertEquals('/index.php/', $server->guessBaseUri());
+
+ }
+
+ /**
+ * @depends testGuessBaseUri
+ * @covers \Sabre\DAV\Server::guessBaseUri
+ */
+ /*
+ function testGuessBaseUriPercentEncoding2() {
+
+ $this->markTestIncomplete('This behaviour is not yet implemented');
+ $serverVars = array(
+ 'REQUEST_URI' => '/some%20directory+mixed/index.php/dir/path2/path%20with%20spaces',
+ 'PATH_INFO' => '/dir/path2/path with spaces',
+ );
+
+ $httpRequest = new HTTP\Request($serverVars);
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $this->assertEquals('/some%20directory+mixed/index.php/', $server->guessBaseUri());
+
+ }*/
+
+ function testGuessBaseUri2() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/index.php/root/',
+ 'PATH_INFO' => '/root/',
+ );
+
+ $httpRequest = new HTTP\Request($serverVars);
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $this->assertEquals('/index.php/', $server->guessBaseUri());
+
+ }
+
+ function testGuessBaseUriNoPathInfo() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/index.php/root',
+ );
+
+ $httpRequest = new HTTP\Request($serverVars);
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $this->assertEquals('/', $server->guessBaseUri());
+
+ }
+
+ function testGuessBaseUriNoPathInfo2() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/a/b/c/test.php',
+ );
+
+ $httpRequest = new HTTP\Request($serverVars);
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $this->assertEquals('/', $server->guessBaseUri());
+
+ }
+
+
+ /**
+ * @covers \Sabre\DAV\Server::guessBaseUri
+ * @depends testGuessBaseUri
+ */
+ function testGuessBaseUriQueryString() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/index.php/root?query_string=blabla',
+ 'PATH_INFO' => '/root',
+ );
+
+ $httpRequest = new HTTP\Request($serverVars);
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $this->assertEquals('/index.php/', $server->guessBaseUri());
+
+ }
+
+ /**
+ * @covers \Sabre\DAV\Server::guessBaseUri
+ * @depends testGuessBaseUri
+ * @expectedException \Sabre\DAV\Exception
+ */
+ function testGuessBaseUriBadConfig() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/index.php/root/heyyy',
+ 'PATH_INFO' => '/root',
+ );
+
+ $httpRequest = new HTTP\Request($serverVars);
+ $server = new Server();
+ $server->httpRequest = $httpRequest;
+
+ $server->guessBaseUri();
+
+ }
+
+ function testTriggerException() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'FOO',
+ );
+
+ $httpRequest = new HTTP\Request($serverVars);
+ $this->server->httpRequest = $httpRequest;
+ $this->server->subscribeEvent('beforeMethod',array($this,'exceptionTrigger'));
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $this->assertEquals('HTTP/1.1 500 Internal Server Error',$this->response->status);
+
+ }
+
+ function exceptionTrigger() {
+
+ throw new Exception('Hola');
+
+ }
+
+ function testReportNotFound() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'REPORT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->httpRequest->setBody('<?xml version="1.0"?><bla:myreport xmlns:bla="http://www.rooftopsolutions.nl/NS"></bla:myreport>');
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status,'We got an incorrect status back. Full response body follows: ' . $this->response->body);
+
+ }
+
+ function testReportIntercepted() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/',
+ 'REQUEST_METHOD' => 'REPORT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->httpRequest->setBody('<?xml version="1.0"?><bla:myreport xmlns:bla="http://www.rooftopsolutions.nl/NS"></bla:myreport>');
+ $this->server->subscribeEvent('report',array($this,'reportHandler'));
+ $this->server->exec();
+
+ $this->assertEquals(array(
+ 'testheader' => 'testvalue',
+ ),
+ $this->response->headers
+ );
+
+ $this->assertEquals('HTTP/1.1 418 I\'m a teapot',$this->response->status,'We got an incorrect status back. Full response body follows: ' . $this->response->body);
+
+ }
+
+ function reportHandler($reportName) {
+
+ if ($reportName=='{http://www.rooftopsolutions.nl/NS}myreport') {
+ $this->server->httpResponse->sendStatus(418);
+ $this->server->httpResponse->setHeader('testheader','testvalue');
+ return false;
+ }
+ else return;
+
+ }
+
+ function testGetPropertiesForChildren() {
+
+ $result = $this->server->getPropertiesForChildren('',array(
+ '{DAV:}getcontentlength',
+ ));
+
+ $expected = array(
+ 'test.txt' => array('{DAV:}getcontentlength' => 13),
+ 'dir/' => array(),
+ );
+
+ $this->assertEquals($expected,$result);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php
new file mode 100644
index 000000000..a73e8d13f
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php
@@ -0,0 +1,130 @@
+<?php
+
+namespace Sabre\DAV;
+use Sabre\HTTP;
+
+class ServerUpdatePropertiesTest extends \PHPUnit_Framework_TestCase {
+
+ function testUpdatePropertiesFail() {
+
+ $tree = array(
+ new SimpleCollection('foo'),
+ );
+ $server = new Server($tree);
+
+ $result = $server->updateProperties('foo', array(
+ '{DAV:}foo' => 'bar'
+ ));
+
+ $expected = array(
+ 'href' => 'foo',
+ '403' => array(
+ '{DAV:}foo' => null,
+ ),
+ );
+ $this->assertEquals($expected, $result);
+
+ }
+
+ function testUpdatePropertiesProtected() {
+
+ $tree = array(
+ new SimpleCollection('foo'),
+ );
+ $server = new Server($tree);
+
+ $result = $server->updateProperties('foo', array(
+ '{DAV:}getetag' => 'bla',
+ '{DAV:}foo' => 'bar'
+ ));
+
+ $expected = array(
+ 'href' => 'foo',
+ '403' => array(
+ '{DAV:}getetag' => null,
+ ),
+ '424' => array(
+ '{DAV:}foo' => null,
+ ),
+ );
+ $this->assertEquals($expected, $result);
+
+ }
+
+ function testUpdatePropertiesEventFail() {
+
+ $tree = array(
+ new SimpleCollection('foo'),
+ );
+ $server = new Server($tree);
+ $server->subscribeEvent('updateProperties', array($this,'updatepropfail'));
+
+ $result = $server->updateProperties('foo', array(
+ '{DAV:}foo' => 'bar',
+ '{DAV:}foo2' => 'bla',
+ ));
+
+ $expected = array(
+ 'href' => 'foo',
+ '404' => array(
+ '{DAV:}foo' => null,
+ ),
+ '424' => array(
+ '{DAV:}foo2' => null,
+ ),
+ );
+ $this->assertEquals($expected, $result);
+
+ }
+
+ function updatePropFail(&$propertyDelta, &$result, $node) {
+
+ $result[404] = array(
+ '{DAV:}foo' => null,
+ );
+ unset($propertyDelta['{DAV:}foo']);
+ return false;
+
+ }
+
+
+ function testUpdatePropertiesEventSuccess() {
+
+ $tree = array(
+ new SimpleCollection('foo'),
+ );
+ $server = new Server($tree);
+ $server->subscribeEvent('updateProperties', array($this,'updatepropsuccess'));
+
+ $result = $server->updateProperties('foo', array(
+ '{DAV:}foo' => 'bar',
+ '{DAV:}foo2' => 'bla',
+ ));
+
+ $expected = array(
+ 'href' => 'foo',
+ '200' => array(
+ '{DAV:}foo' => null,
+ ),
+ '201' => array(
+ '{DAV:}foo2' => null,
+ ),
+ );
+ $this->assertEquals($expected, $result);
+
+ }
+
+ function updatePropSuccess(&$propertyDelta, &$result, $node) {
+
+ $result[200] = array(
+ '{DAV:}foo' => null,
+ );
+ $result[201] = array(
+ '{DAV:}foo2' => null,
+ );
+ unset($propertyDelta['{DAV:}foo']);
+ unset($propertyDelta['{DAV:}foo2']);
+ return;
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php
new file mode 100644
index 000000000..de8b05734
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Sabre\DAV;
+
+class SimpleFileTest extends \PHPUnit_Framework_TestCase {
+
+ function testAll() {
+
+ $file = new SimpleFile('filename.txt','contents','text/plain');
+
+ $this->assertEquals('filename.txt', $file->getName());
+ $this->assertEquals('contents', $file->get());
+ $this->assertEquals('8', $file->getSize());
+ $this->assertEquals('"' . md5('contents') . '"', $file->getETag());
+ $this->assertEquals('text/plain', $file->getContentType());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php b/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php
new file mode 100644
index 000000000..941d1f913
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace Sabre\DAV;
+
+class StringUtilTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @dataProvider dataset
+ */
+ function testTextMatch($haystack, $needle, $collation, $matchType, $result) {
+
+ $this->assertEquals($result, StringUtil::textMatch($haystack, $needle, $collation, $matchType));
+
+ }
+
+ function dataset() {
+
+ return array(
+ array('FOOBAR', 'FOO', 'i;octet', 'contains', true),
+ array('FOOBAR', 'foo', 'i;octet', 'contains', false),
+ array('FÖÖBAR', 'FÖÖ', 'i;octet', 'contains', true),
+ array('FÖÖBAR', 'föö', 'i;octet', 'contains', false),
+ array('FOOBAR', 'FOOBAR', 'i;octet', 'equals', true),
+ array('FOOBAR', 'fooBAR', 'i;octet', 'equals', false),
+ array('FOOBAR', 'FOO', 'i;octet', 'starts-with', true),
+ array('FOOBAR', 'foo', 'i;octet', 'starts-with', false),
+ array('FOOBAR', 'BAR', 'i;octet', 'starts-with', false),
+ array('FOOBAR', 'bar', 'i;octet', 'starts-with', false),
+ array('FOOBAR', 'FOO', 'i;octet', 'ends-with', false),
+ array('FOOBAR', 'foo', 'i;octet', 'ends-with', false),
+ array('FOOBAR', 'BAR', 'i;octet', 'ends-with', true),
+ array('FOOBAR', 'bar', 'i;octet', 'ends-with', false),
+
+ array('FOOBAR', 'FOO', 'i;ascii-casemap', 'contains', true),
+ array('FOOBAR', 'foo', 'i;ascii-casemap', 'contains', true),
+ array('FÖÖBAR', 'FÖÖ', 'i;ascii-casemap', 'contains', true),
+ array('FÖÖBAR', 'föö', 'i;ascii-casemap', 'contains', false),
+ array('FOOBAR', 'FOOBAR', 'i;ascii-casemap', 'equals', true),
+ array('FOOBAR', 'fooBAR', 'i;ascii-casemap', 'equals', true),
+ array('FOOBAR', 'FOO', 'i;ascii-casemap', 'starts-with', true),
+ array('FOOBAR', 'foo', 'i;ascii-casemap', 'starts-with', true),
+ array('FOOBAR', 'BAR', 'i;ascii-casemap', 'starts-with', false),
+ array('FOOBAR', 'bar', 'i;ascii-casemap', 'starts-with', false),
+ array('FOOBAR', 'FOO', 'i;ascii-casemap', 'ends-with', false),
+ array('FOOBAR', 'foo', 'i;ascii-casemap', 'ends-with', false),
+ array('FOOBAR', 'BAR', 'i;ascii-casemap', 'ends-with', true),
+ array('FOOBAR', 'bar', 'i;ascii-casemap', 'ends-with', true),
+
+ array('FOOBAR', 'FOO', 'i;unicode-casemap', 'contains', true),
+ array('FOOBAR', 'foo', 'i;unicode-casemap', 'contains', true),
+ array('FÖÖBAR', 'FÖÖ', 'i;unicode-casemap', 'contains', true),
+ array('FÖÖBAR', 'föö', 'i;unicode-casemap', 'contains', true),
+ array('FOOBAR', 'FOOBAR', 'i;unicode-casemap', 'equals', true),
+ array('FOOBAR', 'fooBAR', 'i;unicode-casemap', 'equals', true),
+ array('FOOBAR', 'FOO', 'i;unicode-casemap', 'starts-with', true),
+ array('FOOBAR', 'foo', 'i;unicode-casemap', 'starts-with', true),
+ array('FOOBAR', 'BAR', 'i;unicode-casemap', 'starts-with', false),
+ array('FOOBAR', 'bar', 'i;unicode-casemap', 'starts-with', false),
+ array('FOOBAR', 'FOO', 'i;unicode-casemap', 'ends-with', false),
+ array('FOOBAR', 'foo', 'i;unicode-casemap', 'ends-with', false),
+ array('FOOBAR', 'BAR', 'i;unicode-casemap', 'ends-with', true),
+ array('FOOBAR', 'bar', 'i;unicode-casemap', 'ends-with', true),
+ );
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ public function testBadCollation() {
+
+ StringUtil::textMatch('foobar','foo','blabla','contains');
+
+ }
+
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ public function testBadMatchType() {
+
+ StringUtil::textMatch('foobar','foo','i;octet','booh');
+
+ }
+
+ public function testEnsureUTF8_ascii() {
+
+ $inputString = "harkema";
+ $outputString = "harkema";
+
+ $this->assertEquals(
+ $outputString,
+ StringUtil::ensureUTF8($inputString)
+ );
+
+ }
+
+ public function testEnsureUTF8_latin1() {
+
+ $inputString = "m\xfcnster";
+ $outputString = "münster";
+
+ $this->assertEquals(
+ $outputString,
+ StringUtil::ensureUTF8($inputString)
+ );
+
+ }
+
+ public function testEnsureUTF8_utf8() {
+
+ $inputString = "m\xc3\xbcnster";
+ $outputString = "münster";
+
+ $this->assertEquals(
+ $outputString,
+ StringUtil::ensureUTF8($inputString)
+ );
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php b/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php
new file mode 100644
index 000000000..d136eeb17
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php
@@ -0,0 +1,252 @@
+<?php
+
+namespace Sabre\DAV;
+
+use Sabre\HTTP;
+
+class TemporaryFileFilterTest extends AbstractServer {
+
+ function setUp() {
+
+ parent::setUp();
+ $plugin = new TemporaryFileFilterPlugin(SABRE_TEMPDIR . '/tff');
+ $this->server->addPlugin($plugin);
+
+ }
+
+ function testPutNormal() {
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/testput.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing new file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('', $this->response->body);
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals('0', $this->response->headers['Content-Length']);
+
+ $this->assertEquals('Testing new file',file_get_contents(SABRE_TEMPDIR . '/testput.txt'));
+
+ }
+
+ function testPutTemp() {
+
+ // mimicking an OS/X resource fork
+ $serverVars = array(
+ 'REQUEST_URI' => '/._testput.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing new file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('', $this->response->body);
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals(array(
+ 'X-Sabre-Temp' => 'true',
+ ),$this->response->headers);
+
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/._testput.txt'),'._testput.txt should not exist in the regular file structure.');
+
+ }
+
+ function testPutTempIfNoneMatch() {
+
+ // mimicking an OS/X resource fork
+ $serverVars = array(
+ 'REQUEST_URI' => '/._testput.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ 'HTTP_IF_NONE_MATCH' => '*',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing new file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('', $this->response->body);
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals(array(
+ 'X-Sabre-Temp' => 'true',
+ ),$this->response->headers);
+
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/._testput.txt'),'._testput.txt should not exist in the regular file structure.');
+
+
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status);
+ $this->assertEquals(array(
+ 'X-Sabre-Temp' => 'true',
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ }
+
+ function testPutGet() {
+
+ // mimicking an OS/X resource fork
+ $serverVars = array(
+ 'REQUEST_URI' => '/._testput.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing new file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('', $this->response->body);
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals(array(
+ 'X-Sabre-Temp' => 'true',
+ ),$this->response->headers);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/._testput.txt',
+ 'REQUEST_METHOD' => 'GET',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
+ $this->assertEquals(array(
+ 'X-Sabre-Temp' => 'true',
+ 'Content-Length' => 16,
+ 'Content-Type' => 'application/octet-stream',
+ ),$this->response->headers);
+
+ $this->assertEquals('Testing new file',stream_get_contents($this->response->body));
+
+ }
+
+ function testLockNonExistant() {
+
+ mkdir(SABRE_TEMPDIR . '/locksdir');
+ $locksBackend = new Locks\Backend\FS(SABRE_TEMPDIR . '/locksdir');
+ $locksPlugin = new Locks\Plugin($locksBackend);
+ $this->server->addPlugin($locksPlugin);
+
+ // mimicking an OS/X resource fork
+ $serverVars = array(
+ 'REQUEST_URI' => '/._testlock.txt',
+ 'REQUEST_METHOD' => 'LOCK',
+ );
+
+ $request = new HTTP\Request($serverVars);
+
+ $request->setBody('<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+ <D:lockscope><D:exclusive/></D:lockscope>
+ <D:locktype><D:write/></D:locktype>
+ <D:owner>
+ <D:href>http://example.org/~ejw/contact.html</D:href>
+ </D:owner>
+</D:lockinfo>');
+
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
+ $this->assertEquals('true',$this->response->headers['X-Sabre-Temp']);
+
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/._testlock.txt'),'._testlock.txt should not exist in the regular file structure.');
+
+ }
+
+ function testPutDelete() {
+
+ // mimicking an OS/X resource fork
+ $serverVars = array(
+ 'REQUEST_URI' => '/._testput.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing new file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('', $this->response->body);
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals(array(
+ 'X-Sabre-Temp' => 'true',
+ ),$this->response->headers);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/._testput.txt',
+ 'REQUEST_METHOD' => 'DELETE',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status, "Incorrect status code received. Full body:\n". $this->response->body);
+ $this->assertEquals(array(
+ 'X-Sabre-Temp' => 'true',
+ ),$this->response->headers);
+
+ $this->assertEquals('',$this->response->body);
+
+ }
+
+ function testPutPropfind() {
+
+ // mimicking an OS/X resource fork
+ $serverVars = array(
+ 'REQUEST_URI' => '/._testput.txt',
+ 'REQUEST_METHOD' => 'PUT',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('Testing new file');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('', $this->response->body);
+ $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
+ $this->assertEquals(array(
+ 'X-Sabre-Temp' => 'true',
+ ),$this->response->headers);
+
+ $serverVars = array(
+ 'REQUEST_URI' => '/._testput.txt',
+ 'REQUEST_METHOD' => 'PROPFIND',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody('');
+ $this->server->httpRequest = ($request);
+ $this->server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Incorrect status code returned. Body: ' . $this->response->body);
+ $this->assertEquals(array(
+ 'X-Sabre-Temp' => 'true',
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ),$this->response->headers);
+
+ $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
+ $xml = simplexml_load_string($body);
+ $xml->registerXPathNamespace('d','urn:DAV');
+
+ list($data) = $xml->xpath('/d:multistatus/d:response/d:href');
+ $this->assertEquals('/._testput.txt',(string)$data,'href element should have been /._testput.txt');
+
+ $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:resourcetype');
+ $this->assertEquals(1,count($data));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php b/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php
new file mode 100644
index 000000000..9cf5edbb0
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Sabre\DAV;
+
+class TestPlugin extends ServerPlugin {
+
+ public $beforeMethod;
+
+ function getFeatures() {
+
+ return array('drinking');
+
+ }
+
+ function getHTTPMethods($uri) {
+
+ return array('BEER','WINE');
+
+ }
+
+ function initialize(Server $server) {
+
+ $server->subscribeEvent('beforeMethod',array($this,'beforeMethod'));
+
+ }
+
+ function beforeMethod($method) {
+
+ $this->beforeMethod = $method;
+ return true;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Tree/FilesystemTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Tree/FilesystemTest.php
new file mode 100644
index 000000000..19b08460f
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Tree/FilesystemTest.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Sabre\DAV\Tree;
+
+use Sabre\DAV;
+
+/**
+ * @covers Sabre\DAV\Tree
+ * @covers Sabre\DAV\Tree\Filesystem
+ * @covers Sabre\DAV\FS\Node
+ * @covers Sabre\DAV\FS\File
+ * @covers Sabre\DAV\FS\Directory
+ */
+class FilesystemTest extends \PHPUnit_Framework_TestCase {
+
+ function setUp() {
+
+ \Sabre\TestUtil::clearTempDir();
+ file_put_contents(SABRE_TEMPDIR. '/file.txt','Body');
+ mkdir(SABRE_TEMPDIR.'/dir');
+ file_put_contents(SABRE_TEMPDIR.'/dir/subfile.txt','Body');
+
+ }
+
+ function tearDown() {
+
+ \Sabre\TestUtil::clearTempDir();
+
+ }
+
+ function testGetNodeForPath_File() {
+
+ $fs = new Filesystem(SABRE_TEMPDIR);
+ $node = $fs->getNodeForPath('file.txt');
+ $this->assertTrue($node instanceof DAV\FS\File);
+
+ }
+
+ /**
+ * @expectedException \Sabre\DAV\Exception\NotFound
+ */
+ function testGetNodeForPath_DoesntExist() {
+
+ $fs = new Filesystem(SABRE_TEMPDIR);
+ $node = $fs->getNodeForPath('whoop/file.txt');
+
+ }
+
+ function testGetNodeForPath_Directory() {
+
+ $fs = new Filesystem(SABRE_TEMPDIR);
+ $node = $fs->getNodeForPath('dir');
+ $this->assertTrue($node instanceof DAV\FS\Directory);
+ $this->assertEquals('dir', $node->getName());
+ $this->assertInternalType('array', $node->getChildren());
+
+ }
+
+ function testCopy() {
+
+ $fs = new Filesystem(SABRE_TEMPDIR);
+ $fs->copy('file.txt','file2.txt');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR . '/file2.txt'));
+ $this->assertEquals('Body',file_get_contents(SABRE_TEMPDIR . '/file2.txt'));
+
+ }
+
+ function testCopyDir() {
+
+ $fs = new Filesystem(SABRE_TEMPDIR);
+ $fs->copy('dir','dir2');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR . '/dir2'));
+ $this->assertEquals('Body',file_get_contents(SABRE_TEMPDIR . '/dir2/subfile.txt'));
+
+ }
+
+ function testMove() {
+
+ $fs = new Filesystem(SABRE_TEMPDIR);
+ $fs->move('file.txt','file2.txt');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR . '/file2.txt'));
+ $this->assertTrue(!file_exists(SABRE_TEMPDIR . '/file.txt'));
+ $this->assertEquals('Body',file_get_contents(SABRE_TEMPDIR . '/file2.txt'));
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php
new file mode 100644
index 000000000..90df6427e
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php
@@ -0,0 +1,175 @@
+<?php
+
+namespace Sabre\DAV;
+
+/**
+ * @covers \Sabre\DAV\Tree
+ */
+class TreeTest extends \PHPUnit_Framework_TestCase {
+
+ function testNodeExists() {
+
+ $tree = new TreeMock();
+
+ $this->assertTrue($tree->nodeExists('hi'));
+ $this->assertFalse($tree->nodeExists('hello'));
+
+ }
+
+ function testCopy() {
+
+ $tree = new TreeMock();
+ $tree->copy('hi','hi2');
+
+ $this->assertArrayHasKey('hi2', $tree->getNodeForPath('')->newDirectories);
+ $this->assertEquals('foobar', $tree->getNodeForPath('hi/file')->get());
+ $this->assertEquals(array('test1'=>'value'), $tree->getNodeForPath('hi/file')->getProperties(array()));
+
+ }
+
+ function testMove() {
+
+ $tree = new TreeMock();
+ $tree->move('hi','hi2');
+
+ $this->assertEquals('hi2', $tree->getNodeForPath('hi')->getName());
+ $this->assertTrue($tree->getNodeForPath('hi')->isRenamed);
+
+ }
+
+ function testDeepMove() {
+
+ $tree = new TreeMock();
+ $tree->move('hi/sub','hi2');
+
+ $this->assertArrayHasKey('hi2', $tree->getNodeForPath('')->newDirectories);
+ $this->assertTrue($tree->getNodeForPath('hi/sub')->isDeleted);
+
+ }
+
+ function testDelete() {
+
+ $tree = new TreeMock();
+ $tree->delete('hi');
+ $this->assertTrue($tree->getNodeForPath('hi')->isDeleted);
+
+ }
+
+ function testGetChildren() {
+
+ $tree = new TreeMock();
+ $children = $tree->getChildren('');
+ $this->assertEquals(1,count($children));
+ $this->assertEquals('hi', $children[0]->getName());
+
+ }
+
+}
+
+class TreeMock extends Tree {
+
+ private $nodes = array();
+
+ function __construct() {
+
+ $this->nodes['hi/sub'] = new TreeDirectoryTester('sub');
+ $this->nodes['hi/file'] = new TreeFileTester('file');
+ $this->nodes['hi/file']->properties = array('test1' => 'value');
+ $this->nodes['hi/file']->data = 'foobar';
+ $this->nodes['hi'] = new TreeDirectoryTester('hi',array($this->nodes['hi/sub'], $this->nodes['hi/file']));
+ $this->nodes[''] = new TreeDirectoryTester('hi', array($this->nodes['hi']));
+
+ }
+
+ function getNodeForPath($path) {
+
+ if (isset($this->nodes[$path])) return $this->nodes[$path];
+ throw new Exception\NotFound('item not found');
+
+ }
+
+}
+
+class TreeDirectoryTester extends SimpleCollection {
+
+ public $newDirectories = array();
+ public $newFiles = array();
+ public $isDeleted = false;
+ public $isRenamed = false;
+
+ function createDirectory($name) {
+
+ $this->newDirectories[$name] = true;
+
+ }
+
+ function createFile($name,$data = null) {
+
+ $this->newFiles[$name] = $data;
+
+ }
+
+ function getChild($name) {
+
+ if (isset($this->newDirectories[$name])) return new TreeDirectoryTester($name);
+ if (isset($this->newFiles[$name])) return new TreeFileTester($name, $this->newFiles[$name]);
+ return parent::getChild($name);
+
+ }
+
+ function delete() {
+
+ $this->isDeleted = true;
+
+ }
+
+ function setName($name) {
+
+ $this->isRenamed = true;
+ $this->name = $name;
+
+ }
+
+}
+
+class TreeFileTester extends File implements IProperties {
+
+ public $name;
+ public $data;
+ public $properties;
+
+ function __construct($name, $data = null) {
+
+ $this->name = $name;
+ if (is_null($data)) $data = 'bla';
+ $this->data = $data;
+
+ }
+
+ function getName() {
+
+ return $this->name;
+
+ }
+
+ function get() {
+
+ return $this->data;
+
+ }
+
+ function getProperties($properties) {
+
+ return $this->properties;
+
+ }
+
+ function updateProperties($properties) {
+
+ $this->properties = $properties;
+ return true;
+
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/URLUtilTest.php b/vendor/sabre/dav/tests/Sabre/DAV/URLUtilTest.php
new file mode 100644
index 000000000..5d1380865
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/URLUtilTest.php
@@ -0,0 +1,131 @@
+<?php
+
+namespace Sabre\DAV;
+
+class URLUtilTest extends \PHPUnit_Framework_TestCase{
+
+ function testEncodePath() {
+
+ $str = '';
+ for($i=0;$i<128;$i++) $str.=chr($i);
+
+ $newStr = URLUtil::encodePath($str);
+
+ $this->assertEquals(
+ '%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f'.
+ '%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f'.
+ '%20%21%22%23%24%25%26%27()%2a%2b%2c-./'.
+ '0123456789:%3b%3c%3d%3e%3f'.
+ '%40ABCDEFGHIJKLMNO' .
+ 'PQRSTUVWXYZ%5b%5c%5d%5e_' .
+ '%60abcdefghijklmno' .
+ 'pqrstuvwxyz%7b%7c%7d~%7f',
+ $newStr);
+
+ $this->assertEquals($str,URLUtil::decodePath($newStr));
+
+ }
+
+ function testEncodePathSegment() {
+
+ $str = '';
+ for($i=0;$i<128;$i++) $str.=chr($i);
+
+ $newStr = URLUtil::encodePathSegment($str);
+
+ // Note: almost exactly the same as the last test, with the
+ // exception of the encoding of / (ascii code 2f)
+ $this->assertEquals(
+ '%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f'.
+ '%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f'.
+ '%20%21%22%23%24%25%26%27()%2a%2b%2c-.%2f'.
+ '0123456789:%3b%3c%3d%3e%3f'.
+ '%40ABCDEFGHIJKLMNO' .
+ 'PQRSTUVWXYZ%5b%5c%5d%5e_' .
+ '%60abcdefghijklmno' .
+ 'pqrstuvwxyz%7b%7c%7d~%7f',
+ $newStr);
+
+ $this->assertEquals($str,URLUtil::decodePathSegment($newStr));
+
+ }
+
+ function testDecode() {
+
+ $str = 'Hello%20Test+Test2.txt';
+ $newStr = URLUtil::decodePath($str);
+ $this->assertEquals('Hello Test+Test2.txt',$newStr);
+
+ }
+
+ /**
+ * @depends testDecode
+ */
+ function testDecodeUmlaut() {
+
+ $str = 'Hello%C3%BC.txt';
+ $newStr = URLUtil::decodePath($str);
+ $this->assertEquals("Hello\xC3\xBC.txt",$newStr);
+
+ }
+
+ /**
+ * @depends testDecodeUmlaut
+ */
+ function testDecodeUmlautLatin1() {
+
+ $str = 'Hello%FC.txt';
+ $newStr = URLUtil::decodePath($str);
+ $this->assertEquals("Hello\xC3\xBC.txt",$newStr);
+
+ }
+
+ /**
+ * This testcase was sent by a bug reporter
+ *
+ * @depends testDecode
+ */
+ function testDecodeAccentsWindows7() {
+
+ $str = '/webdav/%C3%A0fo%C3%B3';
+ $newStr = URLUtil::decodePath($str);
+ $this->assertEquals(strtolower($str),URLUtil::encodePath($newStr));
+
+ }
+
+ function testSplitPath() {
+
+ $strings = array(
+
+ // input // expected result
+ '/foo/bar' => array('/foo','bar'),
+ '/foo/bar/' => array('/foo','bar'),
+ 'foo/bar/' => array('foo','bar'),
+ 'foo/bar' => array('foo','bar'),
+ 'foo/bar/baz' => array('foo/bar','baz'),
+ 'foo/bar/baz/' => array('foo/bar','baz'),
+ 'foo' => array('','foo'),
+ 'foo/' => array('','foo'),
+ '/foo/' => array('','foo'),
+ '/foo' => array('','foo'),
+ '' => array(null,null),
+
+ // UTF-8
+ "/\xC3\xA0fo\xC3\xB3/bar" => array("/\xC3\xA0fo\xC3\xB3",'bar'),
+ "/\xC3\xA0foo/b\xC3\xBCr/" => array("/\xC3\xA0foo","b\xC3\xBCr"),
+ "foo/\xC3\xA0\xC3\xBCr" => array("foo","\xC3\xA0\xC3\xBCr"),
+
+ );
+
+ foreach($strings as $input => $expected) {
+
+ $output = URLUtil::splitPath($input);
+ $this->assertEquals($expected, $output, 'The expected output for \'' . $input . '\' was incorrect');
+
+
+ }
+
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/UUIDUtilTest.php b/vendor/sabre/dav/tests/Sabre/DAV/UUIDUtilTest.php
new file mode 100644
index 000000000..f005ecc75
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/UUIDUtilTest.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Sabre\DAV;
+
+class UUIDUtilTest extends \PHPUnit_Framework_TestCase {
+
+ function testValidateUUID() {
+
+ $this->assertTrue(
+ UUIDUtil::validateUUID('11111111-2222-3333-4444-555555555555')
+ );
+ $this->assertFalse(
+ UUIDUtil::validateUUID(' 11111111-2222-3333-4444-555555555555')
+ );
+ $this->assertTrue(
+ UUIDUtil::validateUUID('ffffffff-2222-3333-4444-555555555555')
+ );
+ $this->assertFalse(
+ UUIDUtil::validateUUID('fffffffg-2222-3333-4444-555555555555')
+ );
+
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/XMLUtilTest.php b/vendor/sabre/dav/tests/Sabre/DAV/XMLUtilTest.php
new file mode 100644
index 000000000..1d2bfd133
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAV/XMLUtilTest.php
@@ -0,0 +1,284 @@
+<?php
+
+namespace Sabre\DAV;
+
+class XMLUtilTest extends \PHPUnit_Framework_TestCase {
+
+ function testToClarkNotation() {
+
+ $dom = new \DOMDocument();
+ $dom->loadXML('<?xml version="1.0"?><test1 xmlns="http://www.example.org/">Testdoc</test1>');
+
+ $this->assertEquals(
+ '{http://www.example.org/}test1',
+ XMLUtil::toClarkNotation($dom->firstChild)
+ );
+
+ }
+
+ function testToClarkNotation2() {
+
+ $dom = new \DOMDocument();
+ $dom->loadXML('<?xml version="1.0"?><s:test1 xmlns:s="http://www.example.org/">Testdoc</s:test1>');
+
+ $this->assertEquals(
+ '{http://www.example.org/}test1',
+ XMLUtil::toClarkNotation($dom->firstChild)
+ );
+
+ }
+
+ function testToClarkNotationDAVNamespace() {
+
+ $dom = new \DOMDocument();
+ $dom->loadXML('<?xml version="1.0"?><s:test1 xmlns:s="urn:DAV">Testdoc</s:test1>');
+
+ $this->assertEquals(
+ '{DAV:}test1',
+ XMLUtil::toClarkNotation($dom->firstChild)
+ );
+
+ }
+
+ function testToClarkNotationNoElem() {
+
+ $dom = new \DOMDocument();
+ $dom->loadXML('<?xml version="1.0"?><s:test1 xmlns:s="urn:DAV">Testdoc</s:test1>');
+
+ $this->assertNull(
+ XMLUtil::toClarkNotation($dom->firstChild->firstChild)
+ );
+
+ }
+
+ function testConvertDAVNamespace() {
+
+ $xml='<?xml version="1.0"?><document xmlns="DAV:">blablabla</document>';
+ $this->assertEquals(
+ '<?xml version="1.0"?><document xmlns="urn:DAV">blablabla</document>',
+ XMLUtil::convertDAVNamespace($xml)
+ );
+
+ }
+
+ function testConvertDAVNamespace2() {
+
+ $xml='<?xml version="1.0"?><s:document xmlns:s="DAV:">blablabla</s:document>';
+ $this->assertEquals(
+ '<?xml version="1.0"?><s:document xmlns:s="urn:DAV">blablabla</s:document>',
+ XMLUtil::convertDAVNamespace($xml)
+ );
+
+ }
+
+ function testConvertDAVNamespace3() {
+
+ $xml='<?xml version="1.0"?><s:document xmlns="http://bla" xmlns:s="DAV:" xmlns:z="http://othernamespace">blablabla</s:document>';
+ $this->assertEquals(
+ '<?xml version="1.0"?><s:document xmlns="http://bla" xmlns:s="urn:DAV" xmlns:z="http://othernamespace">blablabla</s:document>',
+ XMLUtil::convertDAVNamespace($xml)
+ );
+
+ }
+
+ function testConvertDAVNamespace4() {
+
+ $xml='<?xml version="1.0"?><document xmlns=\'DAV:\'>blablabla</document>';
+ $this->assertEquals(
+ '<?xml version="1.0"?><document xmlns=\'urn:DAV\'>blablabla</document>',
+ XMLUtil::convertDAVNamespace($xml)
+ );
+
+ }
+
+ function testConvertDAVNamespaceMixedQuotes() {
+
+ $xml='<?xml version="1.0"?><document xmlns=\'DAV:" xmlns="Another attribute\'>blablabla</document>';
+ $this->assertEquals(
+ $xml,
+ XMLUtil::convertDAVNamespace($xml)
+ );
+
+ }
+
+ /**
+ * @depends testConvertDAVNamespace
+ */
+ function testLoadDOMDocument() {
+
+ $xml='<?xml version="1.0"?><document></document>';
+ $dom = XMLUtil::loadDOMDocument($xml);
+ $this->assertTrue($dom instanceof \DOMDocument);
+
+ }
+
+ /**
+ * @depends testLoadDOMDocument
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testLoadDOMDocumentEmpty() {
+
+ XMLUtil::loadDOMDocument('');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ * @depends testConvertDAVNamespace
+ */
+ function testLoadDOMDocumentInvalid() {
+
+ $xml='<?xml version="1.0"?><document></docu';
+ $dom = XMLUtil::loadDOMDocument($xml);
+
+ }
+
+ /**
+ * @depends testLoadDOMDocument
+ */
+ function testLoadDOMDocumentUTF16() {
+
+ $xml='<?xml version="1.0" encoding="UTF-16"?><root xmlns="DAV:">blabla</root>';
+ $xml = iconv('UTF-8','UTF-16LE',$xml);
+ $dom = XMLUtil::loadDOMDocument($xml);
+ $this->assertEquals('blabla',$dom->firstChild->nodeValue);
+
+ }
+
+
+ function testParseProperties() {
+
+ $xml='<?xml version="1.0"?>
+<root xmlns="DAV:">
+ <prop>
+ <displayname>Calendars</displayname>
+ </prop>
+</root>';
+
+ $dom = XMLUtil::loadDOMDocument($xml);
+ $properties = XMLUtil::parseProperties($dom->firstChild);
+
+ $this->assertEquals(array(
+ '{DAV:}displayname' => 'Calendars',
+ ), $properties);
+
+
+
+ }
+
+ /**
+ * @depends testParseProperties
+ */
+ function testParsePropertiesEmpty() {
+
+ $xml='<?xml version="1.0"?>
+<root xmlns="DAV:" xmlns:s="http://www.rooftopsolutions.nl/example">
+ <prop>
+ <displayname>Calendars</displayname>
+ </prop>
+ <prop>
+ <s:example />
+ </prop>
+</root>';
+
+ $dom = XMLUtil::loadDOMDocument($xml);
+ $properties = XMLUtil::parseProperties($dom->firstChild);
+
+ $this->assertEquals(array(
+ '{DAV:}displayname' => 'Calendars',
+ '{http://www.rooftopsolutions.nl/example}example' => null
+ ), $properties);
+
+ }
+
+
+ /**
+ * @depends testParseProperties
+ */
+ function testParsePropertiesComplex() {
+
+ $xml='<?xml version="1.0"?>
+<root xmlns="DAV:">
+ <prop>
+ <displayname>Calendars</displayname>
+ </prop>
+ <prop>
+ <someprop>Complex value <b>right here</b></someprop>
+ </prop>
+</root>';
+
+ $dom = XMLUtil::loadDOMDocument($xml);
+ $properties = XMLUtil::parseProperties($dom->firstChild);
+
+ $this->assertEquals(array(
+ '{DAV:}displayname' => 'Calendars',
+ '{DAV:}someprop' => 'Complex value right here',
+ ), $properties);
+
+ }
+
+
+ /**
+ * @depends testParseProperties
+ */
+ function testParsePropertiesNoProperties() {
+
+ $xml='<?xml version="1.0"?>
+<root xmlns="DAV:">
+ <prop>
+ </prop>
+</root>';
+
+ $dom = XMLUtil::loadDOMDocument($xml);
+ $properties = XMLUtil::parseProperties($dom->firstChild);
+
+ $this->assertEquals(array(), $properties);
+
+ }
+
+ function testParsePropertiesMapHref() {
+
+ $xml='<?xml version="1.0"?>
+<root xmlns="DAV:">
+ <prop>
+ <displayname>Calendars</displayname>
+ </prop>
+ <prop>
+ <someprop><href>http://sabredav.org/</href></someprop>
+ </prop>
+</root>';
+
+ $dom = XMLUtil::loadDOMDocument($xml);
+ $properties = XMLUtil::parseProperties($dom->firstChild,array('{DAV:}someprop'=>'Sabre\\DAV\\Property\\Href'));
+
+ $this->assertEquals(array(
+ '{DAV:}displayname' => 'Calendars',
+ '{DAV:}someprop' => new Property\Href('http://sabredav.org/',false),
+ ), $properties);
+
+ }
+
+ function testParseClarkNotation() {
+
+ $this->assertEquals(array(
+ 'DAV:',
+ 'foo',
+ ), XMLUtil::parseClarkNotation('{DAV:}foo'));
+
+ $this->assertEquals(array(
+ 'http://example.org/ns/bla',
+ 'bar-soap',
+ ), XMLUtil::parseClarkNotation('{http://example.org/ns/bla}bar-soap'));
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ function testParseClarkNotationFail() {
+
+ XMLUtil::parseClarkNotation('}foo');
+
+ }
+
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php
new file mode 100644
index 000000000..9960180a3
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php
@@ -0,0 +1,331 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+class ACLMethodTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testCallback() {
+
+ $acl = new Plugin();
+ $server = new DAV\Server();
+ $server->addPlugin($acl);
+
+ $acl->unknownMethod('ACL','test');
+
+ }
+
+ function testCallbackPassthru() {
+
+ $acl = new Plugin();
+ $server = new DAV\Server();
+ $server->addPlugin($acl);
+
+ $this->assertNull($acl->unknownMethod('FOO','test'));
+
+ }
+
+ /**
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ function testNotSupportedByNode() {
+
+ $tree = array(
+ new DAV\SimpleCollection('test'),
+ );
+ $acl = new Plugin();
+ $server = new DAV\Server($tree);
+ $server->httpRequest = new HTTP\Request();
+ $body = '<?xml version="1.0"?>
+<d:acl xmlns:d="DAV:">
+</d:acl>';
+ $server->httpRequest->setBody($body);
+ $server->addPlugin($acl);
+
+ $acl->httpACL('test');
+
+ }
+
+ function testSuccessSimple() {
+
+ $tree = array(
+ new MockACLNode('test',array()),
+ );
+ $acl = new Plugin();
+ $server = new DAV\Server($tree);
+ $server->httpRequest = new HTTP\Request();
+ $body = '<?xml version="1.0"?>
+<d:acl xmlns:d="DAV:">
+</d:acl>';
+ $server->httpRequest->setBody($body);
+ $server->addPlugin($acl);
+
+ $this->assertNull($acl->httpACL('test'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NotRecognizedPrincipal
+ */
+ function testUnrecognizedPrincipal() {
+
+ $tree = array(
+ new MockACLNode('test',array()),
+ );
+ $acl = new Plugin();
+ $server = new DAV\Server($tree);
+ $server->httpRequest = new HTTP\Request();
+ $body = '<?xml version="1.0"?>
+<d:acl xmlns:d="DAV:">
+ <d:ace>
+ <d:grant><d:privilege><d:read /></d:privilege></d:grant>
+ <d:principal><d:href>/principals/notfound</d:href></d:principal>
+ </d:ace>
+</d:acl>';
+ $server->httpRequest->setBody($body);
+ $server->addPlugin($acl);
+
+ $acl->httpACL('test');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NotRecognizedPrincipal
+ */
+ function testUnrecognizedPrincipal2() {
+
+ $tree = array(
+ new MockACLNode('test',array()),
+ new DAV\SimpleCollection('principals',array(
+ new DAV\SimpleCollection('notaprincipal'),
+ )),
+ );
+ $acl = new Plugin();
+ $server = new DAV\Server($tree);
+ $server->httpRequest = new HTTP\Request();
+ $body = '<?xml version="1.0"?>
+<d:acl xmlns:d="DAV:">
+ <d:ace>
+ <d:grant><d:privilege><d:read /></d:privilege></d:grant>
+ <d:principal><d:href>/principals/notaprincipal</d:href></d:principal>
+ </d:ace>
+</d:acl>';
+ $server->httpRequest->setBody($body);
+ $server->addPlugin($acl);
+
+ $acl->httpACL('test');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NotSupportedPrivilege
+ */
+ function testUnknownPrivilege() {
+
+ $tree = array(
+ new MockACLNode('test',array()),
+ );
+ $acl = new Plugin();
+ $server = new DAV\Server($tree);
+ $server->httpRequest = new HTTP\Request();
+ $body = '<?xml version="1.0"?>
+<d:acl xmlns:d="DAV:">
+ <d:ace>
+ <d:grant><d:privilege><d:bananas /></d:privilege></d:grant>
+ <d:principal><d:href>/principals/notfound</d:href></d:principal>
+ </d:ace>
+</d:acl>';
+ $server->httpRequest->setBody($body);
+ $server->addPlugin($acl);
+
+ $acl->httpACL('test');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NoAbstract
+ */
+ function testAbstractPrivilege() {
+
+ $tree = array(
+ new MockACLNode('test',array()),
+ );
+ $acl = new Plugin();
+ $server = new DAV\Server($tree);
+ $server->httpRequest = new HTTP\Request();
+ $body = '<?xml version="1.0"?>
+<d:acl xmlns:d="DAV:">
+ <d:ace>
+ <d:grant><d:privilege><d:read-acl /></d:privilege></d:grant>
+ <d:principal><d:href>/principals/notfound</d:href></d:principal>
+ </d:ace>
+</d:acl>';
+ $server->httpRequest->setBody($body);
+ $server->addPlugin($acl);
+
+ $acl->httpACL('test');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\AceConflict
+ */
+ function testUpdateProtectedPrivilege() {
+
+ $oldACL = array(
+ array(
+ 'principal' => 'principals/notfound',
+ 'privilege' => '{DAV:}write',
+ 'protected' => true,
+ ),
+ );
+
+ $tree = array(
+ new MockACLNode('test',$oldACL),
+ );
+ $acl = new Plugin();
+ $server = new DAV\Server($tree);
+ $server->httpRequest = new HTTP\Request();
+ $body = '<?xml version="1.0"?>
+<d:acl xmlns:d="DAV:">
+ <d:ace>
+ <d:grant><d:privilege><d:read /></d:privilege></d:grant>
+ <d:principal><d:href>/principals/notfound</d:href></d:principal>
+ </d:ace>
+</d:acl>';
+ $server->httpRequest->setBody($body);
+ $server->addPlugin($acl);
+
+ $acl->httpACL('test');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\AceConflict
+ */
+ function testUpdateProtectedPrivilege2() {
+
+ $oldACL = array(
+ array(
+ 'principal' => 'principals/notfound',
+ 'privilege' => '{DAV:}write',
+ 'protected' => true,
+ ),
+ );
+
+ $tree = array(
+ new MockACLNode('test',$oldACL),
+ );
+ $acl = new Plugin();
+ $server = new DAV\Server($tree);
+ $server->httpRequest = new HTTP\Request();
+ $body = '<?xml version="1.0"?>
+<d:acl xmlns:d="DAV:">
+ <d:ace>
+ <d:grant><d:privilege><d:write /></d:privilege></d:grant>
+ <d:principal><d:href>/principals/foo</d:href></d:principal>
+ </d:ace>
+</d:acl>';
+ $server->httpRequest->setBody($body);
+ $server->addPlugin($acl);
+
+ $acl->httpACL('test');
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\AceConflict
+ */
+ function testUpdateProtectedPrivilege3() {
+
+ $oldACL = array(
+ array(
+ 'principal' => 'principals/notfound',
+ 'privilege' => '{DAV:}write',
+ 'protected' => true,
+ ),
+ );
+
+ $tree = array(
+ new MockACLNode('test',$oldACL),
+ );
+ $acl = new Plugin();
+ $server = new DAV\Server($tree);
+ $server->httpRequest = new HTTP\Request();
+ $body = '<?xml version="1.0"?>
+<d:acl xmlns:d="DAV:">
+ <d:ace>
+ <d:grant><d:privilege><d:write /></d:privilege></d:grant>
+ <d:principal><d:href>/principals/notfound</d:href></d:principal>
+ </d:ace>
+</d:acl>';
+ $server->httpRequest->setBody($body);
+ $server->addPlugin($acl);
+
+ $acl->httpACL('test');
+
+ }
+
+ function testSuccessComplex () {
+
+ $oldACL = array(
+ array(
+ 'principal' => 'principals/foo',
+ 'privilege' => '{DAV:}write',
+ 'protected' => true,
+ ),
+ array(
+ 'principal' => 'principals/bar',
+ 'privilege' => '{DAV:}read',
+ ),
+ );
+
+ $tree = array(
+ $node = new MockACLNode('test',$oldACL),
+ new DAV\SimpleCollection('principals', array(
+ new MockPrincipal('foo','principals/foo'),
+ new MockPrincipal('baz','principals/baz'),
+ )),
+ );
+ $acl = new Plugin();
+ $server = new DAV\Server($tree);
+ $server->httpRequest = new HTTP\Request();
+ $body = '<?xml version="1.0"?>
+<d:acl xmlns:d="DAV:">
+ <d:ace>
+ <d:grant><d:privilege><d:write /></d:privilege></d:grant>
+ <d:principal><d:href>/principals/foo</d:href></d:principal>
+ <d:protected />
+ </d:ace>
+ <d:ace>
+ <d:grant><d:privilege><d:write /></d:privilege></d:grant>
+ <d:principal><d:href>/principals/baz</d:href></d:principal>
+ </d:ace>
+</d:acl>';
+ $server->httpRequest->setBody($body);
+ $server->addPlugin($acl);
+
+ $this->assertFalse($acl->unknownMethod('ACL','test'));
+
+ $this->assertEquals(array(
+ array(
+ 'principal' => 'principals/foo',
+ 'privilege' => '{DAV:}write',
+ 'protected' => true,
+ ),
+ array(
+ 'principal' => 'principals/baz',
+ 'privilege' => '{DAV:}write',
+ 'protected' => false,
+ ),
+ ), $node->getACL());
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php
new file mode 100644
index 000000000..3a9b35b45
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php
@@ -0,0 +1,139 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+class AllowAccessTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var DAV\Server
+ */
+ protected $server;
+
+ function setUp() {
+
+ $nodes = array(
+ new DAV\SimpleCollection('testdir'),
+ );
+
+ $this->server = new DAV\Server($nodes);
+ $aclPlugin = new Plugin();
+ $aclPlugin->allowAccessToNodesWithoutACL = true;
+ $this->server->addPlugin($aclPlugin);
+
+ }
+
+ function testGet() {
+
+ $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('GET','testdir')));
+
+ }
+
+ function testGetDoesntExist() {
+
+ $r = $this->server->broadcastEvent('beforeMethod',array('GET','foo'));
+ $this->assertTrue($r);
+
+ }
+
+ function testHEAD() {
+
+ $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('HEAD','testdir')));
+
+ }
+
+ function testOPTIONS() {
+
+ $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('OPTIONS','testdir')));
+
+ }
+
+ function testPUT() {
+
+ $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('PUT','testdir')));
+
+ }
+
+ function testACL() {
+
+ $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('ACL','testdir')));
+
+ }
+
+ function testPROPPATCH() {
+
+ $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('PROPPATCH','testdir')));
+
+ }
+
+ function testCOPY() {
+
+ $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('COPY','testdir')));
+
+ }
+
+ function testMOVE() {
+
+ $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('MOVE','testdir')));
+
+ }
+
+ function testLOCK() {
+
+ $this->assertTrue($this->server->broadcastEvent('beforeMethod',array('LOCK','testdir')));
+
+ }
+
+ function testBeforeBind() {
+
+ $this->assertTrue($this->server->broadcastEvent('beforeBind',array('testdir/file')));
+
+ }
+
+
+ function testBeforeUnbind() {
+
+ $this->assertTrue($this->server->broadcastEvent('beforeUnbind',array('testdir')));
+
+ }
+
+ function testAfterGetProperties() {
+
+ $properties = array(
+ 'href' => 'foo',
+ '200' => array(
+ '{DAV:}displayname' => 'foo',
+ '{DAV:}getcontentlength' => 500,
+ ),
+ '404' => array(
+ '{DAV:}bar' => null,
+ ),
+ '403' => array(
+ '{DAV:}owner' => null,
+ ),
+ );
+
+ $expected = array(
+ 'href' => 'foo',
+ '200' => array(
+ '{DAV:}displayname' => 'foo',
+ '{DAV:}getcontentlength' => 500,
+ ),
+ '404' => array(
+ '{DAV:}bar' => null,
+ ),
+ '403' => array(
+ '{DAV:}owner' => null,
+ ),
+ );
+
+ $r = $this->server->broadcastEvent('afterGetProperties',array('testdir',&$properties));
+ $this->assertTrue($r);
+
+ $this->assertEquals($expected, $properties);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php
new file mode 100644
index 000000000..345d2cc5d
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php
@@ -0,0 +1,190 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+class BlockAccessTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var DAV\Server
+ */
+ protected $server;
+ protected $plugin;
+
+ function setUp() {
+
+ $nodes = array(
+ new DAV\SimpleCollection('testdir'),
+ );
+
+ $this->server = new DAV\Server($nodes);
+ $this->plugin = new Plugin();
+ $this->plugin->allowAccessToNodesWithoutACL = false;
+ $this->server->addPlugin($this->plugin);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testGet() {
+
+ $this->server->broadcastEvent('beforeMethod',array('GET','testdir'));
+
+ }
+
+ function testGetDoesntExist() {
+
+ $r = $this->server->broadcastEvent('beforeMethod',array('GET','foo'));
+ $this->assertTrue($r);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testHEAD() {
+
+ $this->server->broadcastEvent('beforeMethod',array('HEAD','testdir'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testOPTIONS() {
+
+ $this->server->broadcastEvent('beforeMethod',array('OPTIONS','testdir'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testPUT() {
+
+ $this->server->broadcastEvent('beforeMethod',array('PUT','testdir'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testPROPPATCH() {
+
+ $this->server->broadcastEvent('beforeMethod',array('PROPPATCH','testdir'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testCOPY() {
+
+ $this->server->broadcastEvent('beforeMethod',array('COPY','testdir'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testMOVE() {
+
+ $this->server->broadcastEvent('beforeMethod',array('MOVE','testdir'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testACL() {
+
+ $this->server->broadcastEvent('beforeMethod',array('ACL','testdir'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testLOCK() {
+
+ $this->server->broadcastEvent('beforeMethod',array('LOCK','testdir'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testBeforeBind() {
+
+ $this->server->broadcastEvent('beforeBind',array('testdir/file'));
+
+ }
+
+ /**
+ * @expectedException Sabre\DAVACL\Exception\NeedPrivileges
+ */
+ function testBeforeUnbind() {
+
+ $this->server->broadcastEvent('beforeUnbind',array('testdir'));
+
+ }
+
+ function testBeforeGetProperties() {
+
+ $requestedProperties = array(
+ '{DAV:}displayname',
+ '{DAV:}getcontentlength',
+ '{DAV:}bar',
+ '{DAV:}owner',
+ );
+ $returnedProperties = array();
+
+ $arguments = array(
+ 'testdir',
+ new DAV\SimpleCollection('testdir'),
+ &$requestedProperties,
+ &$returnedProperties
+ );
+ $r = $this->server->broadcastEvent('beforeGetProperties',$arguments);
+ $this->assertTrue($r);
+
+ $expected = array(
+ '403' => array(
+ '{DAV:}displayname' => null,
+ '{DAV:}getcontentlength' => null,
+ '{DAV:}bar' => null,
+ '{DAV:}owner' => null,
+ ),
+ );
+
+ $this->assertEquals($expected, $returnedProperties);
+ $this->assertEquals(array(), $requestedProperties);
+
+ }
+
+ function testBeforeGetPropertiesNoListing() {
+
+ $this->plugin->hideNodesFromListings = true;
+
+ $requestedProperties = array(
+ '{DAV:}displayname',
+ '{DAV:}getcontentlength',
+ '{DAV:}bar',
+ '{DAV:}owner',
+ );
+ $returnedProperties = array();
+
+ $arguments = array(
+ 'testdir',
+ new DAV\SimpleCollection('testdir'),
+ &$requestedProperties,
+ &$returnedProperties
+ );
+ $r = $this->server->broadcastEvent('beforeGetProperties',$arguments);
+ $this->assertFalse($r);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php
new file mode 100644
index 000000000..fc48af67f
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Sabre\DAVACL\Exception;
+
+use Sabre\DAV;
+
+class AceConflictTest extends \PHPUnit_Framework_TestCase {
+
+ function testSerialize() {
+
+ $ex = new AceConflict('message');
+
+ $server = new DAV\Server();
+ $dom = new \DOMDocument('1.0','utf-8');
+ $root = $dom->createElementNS('DAV:','d:root');
+ $dom->appendChild($root);
+
+ $ex->serialize($server, $root);
+
+ $xpaths = array(
+ '/d:root' => 1,
+ '/d:root/d:no-ace-conflict' => 1,
+ );
+
+ // Reloading because PHP DOM sucks
+ $dom2 = new \DOMDocument('1.0', 'utf-8');
+ $dom2->loadXML($dom->saveXML());
+
+ $dxpath = new \DOMXPath($dom2);
+ $dxpath->registerNamespace('d','DAV:');
+ foreach($xpaths as $xpath=>$count) {
+
+ $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count);
+
+ }
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php
new file mode 100644
index 000000000..7e66adab6
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Sabre\DAVACL\Exception;
+
+use Sabre\DAV;
+
+class NeedPrivilegesTest extends \PHPUnit_Framework_TestCase {
+
+ function testSerialize() {
+
+ $uri = 'foo';
+ $privileges = array(
+ '{DAV:}read',
+ '{DAV:}write',
+ );
+ $ex = new NeedPrivileges($uri, $privileges);
+
+ $server = new DAV\Server();
+ $dom = new \DOMDocument('1.0','utf-8');
+ $root = $dom->createElementNS('DAV:','d:root');
+ $dom->appendChild($root);
+
+ $ex->serialize($server, $root);
+
+ $xpaths = array(
+ '/d:root' => 1,
+ '/d:root/d:need-privileges' => 1,
+ '/d:root/d:need-privileges/d:resource' => 2,
+ '/d:root/d:need-privileges/d:resource/d:href' => 2,
+ '/d:root/d:need-privileges/d:resource/d:privilege' => 2,
+ '/d:root/d:need-privileges/d:resource/d:privilege/d:read' => 1,
+ '/d:root/d:need-privileges/d:resource/d:privilege/d:write' => 1,
+ );
+
+ // Reloading because PHP DOM sucks
+ $dom2 = new \DOMDocument('1.0', 'utf-8');
+ $dom2->loadXML($dom->saveXML());
+
+ $dxpath = new \DOMXPath($dom2);
+ $dxpath->registerNamespace('d','DAV:');
+ foreach($xpaths as $xpath=>$count) {
+
+ $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count);
+
+ }
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php
new file mode 100644
index 000000000..2406c1c38
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Sabre\DAVACL\Exception;
+
+use Sabre\DAV;
+
+class NoAbstractTest extends \PHPUnit_Framework_TestCase {
+
+ function testSerialize() {
+
+ $ex = new NoAbstract('message');
+
+ $server = new DAV\Server();
+ $dom = new \DOMDocument('1.0','utf-8');
+ $root = $dom->createElementNS('DAV:','d:root');
+ $dom->appendChild($root);
+
+ $ex->serialize($server, $root);
+
+ $xpaths = array(
+ '/d:root' => 1,
+ '/d:root/d:no-abstract' => 1,
+ );
+
+ // Reloading because PHP DOM sucks
+ $dom2 = new \DOMDocument('1.0', 'utf-8');
+ $dom2->loadXML($dom->saveXML());
+
+ $dxpath = new \DOMXPath($dom2);
+ $dxpath->registerNamespace('d','DAV:');
+ foreach($xpaths as $xpath=>$count) {
+
+ $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count);
+
+ }
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php
new file mode 100644
index 000000000..6077b0ba5
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Sabre\DAVACL\Exception;
+
+use Sabre\DAV;
+
+class NotRecognizedPrincipalTest extends \PHPUnit_Framework_TestCase {
+
+ function testSerialize() {
+
+ $ex = new NotRecognizedPrincipal('message');
+
+ $server = new DAV\Server();
+ $dom = new \DOMDocument('1.0','utf-8');
+ $root = $dom->createElementNS('DAV:','d:root');
+ $dom->appendChild($root);
+
+ $ex->serialize($server, $root);
+
+ $xpaths = array(
+ '/d:root' => 1,
+ '/d:root/d:recognized-principal' => 1,
+ );
+
+ // Reloading because PHP DOM sucks
+ $dom2 = new \DOMDocument('1.0', 'utf-8');
+ $dom2->loadXML($dom->saveXML());
+
+ $dxpath = new \DOMXPath($dom2);
+ $dxpath->registerNamespace('d','DAV:');
+ foreach($xpaths as $xpath=>$count) {
+
+ $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count);
+
+ }
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php
new file mode 100644
index 000000000..8e7b3685d
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Sabre\DAVACL\Exception;
+
+use Sabre\DAV;
+
+class NotSupportedPrivilegeTest extends \PHPUnit_Framework_TestCase {
+
+ function testSerialize() {
+
+ $ex = new NotSupportedPrivilege('message');
+
+ $server = new DAV\Server();
+ $dom = new \DOMDocument('1.0','utf-8');
+ $root = $dom->createElementNS('DAV:','d:root');
+ $dom->appendChild($root);
+
+ $ex->serialize($server, $root);
+
+ $xpaths = array(
+ '/d:root' => 1,
+ '/d:root/d:not-supported-privilege' => 1,
+ );
+
+ // Reloading because PHP DOM sucks
+ $dom2 = new \DOMDocument('1.0', 'utf-8');
+ $dom2->loadXML($dom->saveXML());
+
+ $dxpath = new \DOMXPath($dom2);
+ $dxpath->registerNamespace('d','DAV:');
+ foreach($xpaths as $xpath=>$count) {
+
+ $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count);
+
+ }
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php
new file mode 100644
index 000000000..324788d4a
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php
@@ -0,0 +1,358 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class ExpandPropertiesTest extends \PHPUnit_Framework_TestCase {
+
+ function getServer() {
+
+ $tree = array(
+ new MockPropertyNode('node1', array(
+ '{http://sabredav.org/ns}simple' => 'foo',
+ '{http://sabredav.org/ns}href' => new DAV\Property\Href('node2'),
+ '{DAV:}displayname' => 'Node 1',
+ )),
+ new MockPropertyNode('node2', array(
+ '{http://sabredav.org/ns}simple' => 'simple',
+ '{http://sabredav.org/ns}hreflist' => new DAV\Property\HrefList(array('node1','node3')),
+ '{DAV:}displayname' => 'Node 2',
+ )),
+ new MockPropertyNode('node3', array(
+ '{http://sabredav.org/ns}simple' => 'simple',
+ '{DAV:}displayname' => 'Node 3',
+ )),
+ );
+
+ $fakeServer = new DAV\Server($tree);
+ $fakeServer->debugExceptions = true;
+ $fakeServer->httpResponse = new HTTP\ResponseMock();
+ $plugin = new Plugin();
+ $plugin->allowAccessToNodesWithoutACL = true;
+
+ $this->assertTrue($plugin instanceof Plugin);
+ $fakeServer->addPlugin($plugin);
+ $this->assertEquals($plugin, $fakeServer->getPlugin('acl'));
+
+ return $fakeServer;
+
+ }
+
+ function testSimple() {
+
+ $xml = '<?xml version="1.0"?>
+<d:expand-property xmlns:d="DAV:">
+ <d:property name="displayname" />
+ <d:property name="foo" namespace="http://www.sabredav.org/NS/2010/nonexistant" />
+ <d:property name="simple" namespace="http://sabredav.org/ns" />
+ <d:property name="href" namespace="http://sabredav.org/ns" />
+</d:expand-property>';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '0',
+ 'REQUEST_URI' => '/node1',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status,'Incorrect status code received. Full body: ' . $server->httpResponse->body);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ), $server->httpResponse->headers);
+
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response' => 1,
+ '/d:multistatus/d:response/d:href' => 1,
+ '/d:multistatus/d:response/d:propstat' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:simple' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:href' => 1,
+ );
+
+ $xml = simplexml_load_string($server->httpResponse->body);
+ $xml->registerXPathNamespace('d','DAV:');
+ $xml->registerXPathNamespace('s','http://sabredav.org/ns');
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+
+ $count = 1;
+ if (!is_int($v1)) $count = $v2;
+
+ $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response: ' . $server->httpResponse->body);
+
+ }
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testExpand() {
+
+ $xml = '<?xml version="1.0"?>
+<d:expand-property xmlns:d="DAV:">
+ <d:property name="href" namespace="http://sabredav.org/ns">
+ <d:property name="displayname" />
+ </d:property>
+</d:expand-property>';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '0',
+ 'REQUEST_URI' => '/node1',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status, 'Incorrect response status received. Full response body: ' . $server->httpResponse->body);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ), $server->httpResponse->headers);
+
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response' => 1,
+ '/d:multistatus/d:response/d:href' => 1,
+ '/d:multistatus/d:response/d:propstat' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:href' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop/d:displayname' => 1,
+ );
+
+ $xml = simplexml_load_string($server->httpResponse->body);
+ $xml->registerXPathNamespace('d','DAV:');
+ $xml->registerXPathNamespace('s','http://sabredav.org/ns');
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+
+ $count = 1;
+ if (!is_int($v1)) $count = $v2;
+
+ $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result));
+
+ }
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testExpandHrefList() {
+
+ $xml = '<?xml version="1.0"?>
+<d:expand-property xmlns:d="DAV:">
+ <d:property name="hreflist" namespace="http://sabredav.org/ns">
+ <d:property name="displayname" />
+ </d:property>
+</d:expand-property>';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '0',
+ 'REQUEST_URI' => '/node2',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ), $server->httpResponse->headers);
+
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response' => 1,
+ '/d:multistatus/d:response/d:href' => 1,
+ '/d:multistatus/d:response/d:propstat' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:href' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/d:displayname' => 2,
+ );
+
+ $xml = simplexml_load_string($server->httpResponse->body);
+ $xml->registerXPathNamespace('d','DAV:');
+ $xml->registerXPathNamespace('s','http://sabredav.org/ns');
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+
+ $count = 1;
+ if (!is_int($v1)) $count = $v2;
+
+ $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result));
+
+ }
+
+ }
+
+ /**
+ * @depends testExpand
+ */
+ function testExpandDeep() {
+
+ $xml = '<?xml version="1.0"?>
+<d:expand-property xmlns:d="DAV:">
+ <d:property name="hreflist" namespace="http://sabredav.org/ns">
+ <d:property name="href" namespace="http://sabredav.org/ns">
+ <d:property name="displayname" />
+ </d:property>
+ <d:property name="displayname" />
+ </d:property>
+</d:expand-property>';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '0',
+ 'REQUEST_URI' => '/node2',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ), $server->httpResponse->headers);
+
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response' => 1,
+ '/d:multistatus/d:response/d:href' => 1,
+ '/d:multistatus/d:response/d:propstat' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:href' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat' => 3,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop' => 3,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/d:displayname' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:href' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop/d:displayname' => 1,
+ );
+
+ $xml = simplexml_load_string($server->httpResponse->body);
+ $xml->registerXPathNamespace('d','DAV:');
+ $xml->registerXPathNamespace('s','http://sabredav.org/ns');
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+
+ $count = 1;
+ if (!is_int($v1)) $count = $v2;
+
+ $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result));
+
+ }
+
+ }
+}
+class MockPropertyNode implements DAV\INode, DAV\IProperties {
+
+ function __construct($name, array $properties) {
+
+ $this->name = $name;
+ $this->properties = $properties;
+
+ }
+
+ function getName() {
+
+ return $this->name;
+
+ }
+
+ function getProperties($requestedProperties) {
+
+ $returnedProperties = array();
+ foreach($requestedProperties as $requestedProperty) {
+ if (isset($this->properties[$requestedProperty])) {
+ $returnedProperties[$requestedProperty] =
+ $this->properties[$requestedProperty];
+ }
+ }
+ return $returnedProperties;
+
+ }
+
+ function delete() {
+
+ throw new DAV\Exception('Not implemented');
+
+ }
+
+ function setName($name) {
+
+ throw new DAV\Exception('Not implemented');
+
+ }
+
+ function getLastModified() {
+
+ return null;
+
+ }
+
+ function updateProperties($properties) {
+
+ throw new DAV\Exception('Not implemented');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php b/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php
new file mode 100644
index 000000000..7b3e8fc12
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+class MockACLNode extends DAV\Node implements IACL {
+
+ public $name;
+ public $acl;
+
+ function __construct($name, array $acl = array()) {
+
+ $this->name = $name;
+ $this->acl = $acl;
+
+ }
+
+ function getName() {
+
+ return $this->name;
+
+ }
+
+ function getOwner() {
+
+ return null;
+
+ }
+
+ function getGroup() {
+
+ return null;
+
+ }
+
+ function getACL() {
+
+ return $this->acl;
+
+ }
+
+ function setACL(array $acl) {
+
+ $this->acl = $acl;
+
+ }
+
+ function getSupportedPrivilegeSet() {
+
+ return null;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php b/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php
new file mode 100644
index 000000000..dd8542b8d
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+class MockPrincipal extends DAV\Node implements IPrincipal {
+
+ public $name;
+ public $principalUrl;
+ public $groupMembership = array();
+ public $groupMemberSet = array();
+
+ function __construct($name,$principalUrl,array $groupMembership = array(), array $groupMemberSet = array()) {
+
+ $this->name = $name;
+ $this->principalUrl = $principalUrl;
+ $this->groupMembership = $groupMembership;
+ $this->groupMemberSet = $groupMemberSet;
+
+ }
+
+ function getName() {
+
+ return $this->name;
+
+ }
+
+ function getDisplayName() {
+
+ return $this->getName();
+
+ }
+
+ function getAlternateUriSet() {
+
+ return array();
+
+ }
+
+ function getPrincipalUrl() {
+
+ return $this->principalUrl;
+
+ }
+
+ function getGroupMemberSet() {
+
+ return $this->groupMemberSet;
+
+ }
+
+ function getGroupMemberShip() {
+
+ return $this->groupMembership;
+
+ }
+
+ function setGroupMemberSet(array $groupMemberSet) {
+
+ $this->groupMemberSet = $groupMemberSet;
+
+ }
+}
+
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php
new file mode 100644
index 000000000..23c4b6e85
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+
+require_once 'Sabre/DAVACL/MockACLNode.php';
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class PluginAdminTest extends \PHPUnit_Framework_TestCase {
+
+ function testNoAdminAccess() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+
+ $tree = array(
+ new MockACLNode('adminonly', array()),
+ new PrincipalCollection($principalBackend),
+ );
+
+ $fakeServer = new DAV\Server($tree);
+ $plugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'realm');
+ $fakeServer->addPlugin($plugin);
+ $plugin = new Plugin();
+ $fakeServer->addPlugin($plugin);
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'OPTIONS',
+ 'HTTP_DEPTH' => 1,
+ 'REQUEST_URI' => '/adminonly',
+ ));
+
+ $response = new HTTP\ResponseMock();
+
+ $fakeServer->httpRequest = $request;
+ $fakeServer->httpResponse = $response;
+
+ $fakeServer->exec();
+
+ $this->assertEquals('HTTP/1.1 403 Forbidden', $response->status);
+
+ }
+
+ /**
+ * @depends testNoAdminAccess
+ */
+ function testAdminAccess() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+
+ $tree = array(
+ new MockACLNode('adminonly', array()),
+ new PrincipalCollection($principalBackend),
+ );
+
+ $fakeServer = new DAV\Server($tree);
+ $plugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'realm');
+ $fakeServer->addPlugin($plugin);
+ $plugin = new Plugin();
+ $plugin->adminPrincipals = array(
+ 'principals/admin',
+ );
+ $fakeServer->addPlugin($plugin);
+
+ $request = new HTTP\Request(array(
+ 'REQUEST_METHOD' => 'OPTIONS',
+ 'HTTP_DEPTH' => 1,
+ 'REQUEST_URI' => '/adminonly',
+ ));
+
+ $response = new HTTP\ResponseMock();
+
+ $fakeServer->httpRequest = $request;
+ $fakeServer->httpResponse = $response;
+
+ $fakeServer->exec();
+
+ $this->assertEquals('HTTP/1.1 200 OK', $response->status);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php
new file mode 100644
index 000000000..8c0626e50
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php
@@ -0,0 +1,407 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+
+class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
+
+ function testPrincipalCollectionSet() {
+
+ $plugin = new Plugin();
+ $plugin->principalCollectionSet = array(
+ 'principals1',
+ 'principals2',
+ );
+
+ $requestedProperties = array(
+ '{DAV:}principal-collection-set',
+ );
+
+ $returnedProperties = array(
+ 200 => array(),
+ 404 => array(),
+ );
+
+ $server = new DAV\Server();
+ $server->addPlugin($plugin);
+
+ $this->assertNull($plugin->beforeGetProperties('', new DAV\SimpleCollection('root'), $requestedProperties, $returnedProperties));
+
+ $this->assertEquals(1,count($returnedProperties[200]));
+ $this->assertArrayHasKey('{DAV:}principal-collection-set',$returnedProperties[200]);
+ $this->assertInstanceOf('Sabre\\DAV\\Property\\HrefList', $returnedProperties[200]['{DAV:}principal-collection-set']);
+
+ $expected = array(
+ 'principals1/',
+ 'principals2/',
+ );
+
+
+ $this->assertEquals($expected, $returnedProperties[200]['{DAV:}principal-collection-set']->getHrefs());
+
+
+ }
+
+ function testCurrentUserPrincipal() {
+
+ $fakeServer = new DAV\Server();
+ $plugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'realm');
+ $fakeServer->addPlugin($plugin);
+ $plugin = new Plugin();
+ $fakeServer->addPlugin($plugin);
+
+
+ $requestedProperties = array(
+ '{DAV:}current-user-principal',
+ );
+
+ $returnedProperties = array(
+ 200 => array(),
+ 404 => array(),
+ );
+
+ $this->assertNull($plugin->beforeGetProperties('', new DAV\SimpleCollection('root'), $requestedProperties, $returnedProperties));
+
+ $this->assertEquals(1,count($returnedProperties[200]));
+ $this->assertArrayHasKey('{DAV:}current-user-principal',$returnedProperties[200]);
+ $this->assertInstanceOf('Sabre\DAVACL\Property\Principal', $returnedProperties[200]['{DAV:}current-user-principal']);
+ $this->assertEquals(Property\Principal::UNAUTHENTICATED, $returnedProperties[200]['{DAV:}current-user-principal']->getType());
+
+ // This will force the login
+ $fakeServer->broadCastEvent('beforeMethod',array('GET',''));
+
+
+ $requestedProperties = array(
+ '{DAV:}current-user-principal',
+ );
+
+ $returnedProperties = array(
+ 200 => array(),
+ 404 => array(),
+ );
+
+
+ $this->assertNull($plugin->beforeGetProperties('', new DAV\SimpleCollection('root'), $requestedProperties, $returnedProperties));
+
+
+ $this->assertEquals(1,count($returnedProperties[200]));
+ $this->assertArrayHasKey('{DAV:}current-user-principal',$returnedProperties[200]);
+ $this->assertInstanceOf('Sabre\DAVACL\Property\Principal', $returnedProperties[200]['{DAV:}current-user-principal']);
+ $this->assertEquals(Property\Principal::HREF, $returnedProperties[200]['{DAV:}current-user-principal']->getType());
+ $this->assertEquals('principals/admin/', $returnedProperties[200]['{DAV:}current-user-principal']->getHref());
+
+ }
+
+ function testSupportedPrivilegeSet() {
+
+ $plugin = new Plugin();
+ $server = new DAV\Server();
+ $server->addPlugin($plugin);
+
+ $requestedProperties = array(
+ '{DAV:}supported-privilege-set',
+ );
+
+ $returnedProperties = array(
+ 200 => array(),
+ 404 => array(),
+ );
+
+
+ $this->assertNull($plugin->beforeGetProperties('', new DAV\SimpleCollection('root'), $requestedProperties, $returnedProperties));
+
+ $this->assertEquals(1,count($returnedProperties[200]));
+ $this->assertArrayHasKey('{DAV:}supported-privilege-set',$returnedProperties[200]);
+ $this->assertInstanceOf('Sabre\\DAVACL\\Property\\SupportedPrivilegeSet', $returnedProperties[200]['{DAV:}supported-privilege-set']);
+
+ $server = new DAV\Server();
+ $prop = $returnedProperties[200]['{DAV:}supported-privilege-set'];
+
+ $dom = new \DOMDocument('1.0', 'utf-8');
+ $root = $dom->createElement('d:root');
+ $root->setAttribute('xmlns:d','DAV:');
+ $dom->appendChild($root);
+ $prop->serialize($server, $root);
+
+
+ $xpaths = array(
+ '/d:root' => 1,
+ '/d:root/d:supported-privilege' => 1,
+ '/d:root/d:supported-privilege/d:privilege' => 1,
+ '/d:root/d:supported-privilege/d:privilege/d:all' => 1,
+ '/d:root/d:supported-privilege/d:abstract' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege' => 2,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:privilege' => 2,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:privilege/d:read' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:privilege/d:write' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege' => 8,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege' => 8,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:read-acl' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:read-current-user-privilege-set' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-content' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-properties' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-acl' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:bind' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:unbind' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:unlock' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:abstract' => 8,
+ );
+
+
+ // reloading because php dom sucks
+ $dom2 = new \DOMDocument('1.0', 'utf-8');
+ $dom2->loadXML($dom->saveXML());
+
+ $dxpath = new \DOMXPath($dom2);
+ $dxpath->registerNamespace('d','DAV:');
+ foreach($xpaths as $xpath=>$count) {
+
+ $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count);
+
+ }
+
+ }
+
+ function testACL() {
+
+ $plugin = new Plugin();
+
+ $nodes = array(
+ new MockACLNode('foo', array(
+ array(
+ 'principal' => 'principals/admin',
+ 'privilege' => '{DAV:}read',
+ )
+ )),
+ new DAV\SimpleCollection('principals', array(
+ $principal = new MockPrincipal('admin','principals/admin'),
+ )),
+
+ );
+
+ $server = new DAV\Server($nodes);
+ $server->addPlugin($plugin);
+ $authPlugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'realm');
+ $server->addPlugin($authPlugin);
+
+ // Force login
+ $authPlugin->beforeMethod('BLA','foo');
+
+ $requestedProperties = array(
+ '{DAV:}acl',
+ );
+
+ $returnedProperties = array(
+ 200 => array(),
+ 404 => array(),
+ );
+
+
+ $this->assertNull($plugin->beforeGetProperties('foo', $nodes[0], $requestedProperties, $returnedProperties));
+
+ $this->assertEquals(1,count($returnedProperties[200]),'The {DAV:}acl property did not return from the list. Full list: ' . print_r($returnedProperties,true));
+ $this->assertArrayHasKey('{DAV:}acl',$returnedProperties[200]);
+ $this->assertInstanceOf('Sabre\\DAVACL\\Property\\ACL', $returnedProperties[200]['{DAV:}acl']);
+
+ }
+
+ function testACLRestrictions() {
+
+ $plugin = new Plugin();
+
+ $nodes = array(
+ new MockACLNode('foo', array(
+ array(
+ 'principal' => 'principals/admin',
+ 'privilege' => '{DAV:}read',
+ )
+ )),
+ new DAV\SimpleCollection('principals', array(
+ $principal = new MockPrincipal('admin','principals/admin'),
+ )),
+
+ );
+
+ $server = new DAV\Server($nodes);
+ $server->addPlugin($plugin);
+ $authPlugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'realm');
+ $server->addPlugin($authPlugin);
+
+ // Force login
+ $authPlugin->beforeMethod('BLA','foo');
+
+ $requestedProperties = array(
+ '{DAV:}acl-restrictions',
+ );
+
+ $returnedProperties = array(
+ 200 => array(),
+ 404 => array(),
+ );
+
+
+ $this->assertNull($plugin->beforeGetProperties('foo', $nodes[0], $requestedProperties, $returnedProperties));
+
+ $this->assertEquals(1,count($returnedProperties[200]),'The {DAV:}acl-restrictions property did not return from the list. Full list: ' . print_r($returnedProperties,true));
+ $this->assertArrayHasKey('{DAV:}acl-restrictions',$returnedProperties[200]);
+ $this->assertInstanceOf('Sabre\\DAVACL\\Property\\ACLRestrictions', $returnedProperties[200]['{DAV:}acl-restrictions']);
+
+ }
+
+ function testAlternateUriSet() {
+
+ $tree = array(
+ new DAV\SimpleCollection('principals', array(
+ $principal = new MockPrincipal('user','principals/user'),
+ )),
+ );
+
+ $fakeServer = new DAV\Server($tree);
+ //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend(),'realm');
+ //$fakeServer->addPlugin($plugin);
+ $plugin = new Plugin();
+ $fakeServer->addPlugin($plugin);
+
+ $requestedProperties = array(
+ '{DAV:}alternate-URI-set',
+ );
+ $returnedProperties = array();
+
+ $result = $plugin->beforeGetProperties('principals/user',$principal,$requestedProperties,$returnedProperties);
+
+ $this->assertNull($result);
+
+ $this->assertTrue(isset($returnedProperties[200]));
+ $this->assertTrue(isset($returnedProperties[200]['{DAV:}alternate-URI-set']));
+ $this->assertInstanceOf('Sabre\\DAV\\Property\\HrefList', $returnedProperties[200]['{DAV:}alternate-URI-set']);
+
+ $this->assertEquals(array(), $returnedProperties[200]['{DAV:}alternate-URI-set']->getHrefs());
+
+ }
+
+ function testPrincipalURL() {
+
+ $tree = array(
+ new DAV\SimpleCollection('principals', array(
+ $principal = new MockPrincipal('user','principals/user'),
+ )),
+ );
+
+ $fakeServer = new DAV\Server($tree);
+ //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend(),'realm');
+ //$fakeServer->addPlugin($plugin);
+ $plugin = new Plugin();
+ $fakeServer->addPlugin($plugin);
+
+ $requestedProperties = array(
+ '{DAV:}principal-URL',
+ );
+ $returnedProperties = array();
+
+ $result = $plugin->beforeGetProperties('principals/user',$principal,$requestedProperties,$returnedProperties);
+
+ $this->assertNull($result);
+
+ $this->assertTrue(isset($returnedProperties[200]));
+ $this->assertTrue(isset($returnedProperties[200]['{DAV:}principal-URL']));
+ $this->assertInstanceOf('Sabre\\DAV\\Property\\Href', $returnedProperties[200]['{DAV:}principal-URL']);
+
+ $this->assertEquals('principals/user/', $returnedProperties[200]['{DAV:}principal-URL']->getHref());
+
+ }
+
+ function testGroupMemberSet() {
+
+ $tree = array(
+ new DAV\SimpleCollection('principals', array(
+ $principal = new MockPrincipal('user','principals/user'),
+ )),
+ );
+
+ $fakeServer = new DAV\Server($tree);
+ //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend(),'realm');
+ //$fakeServer->addPlugin($plugin);
+ $plugin = new Plugin();
+ $fakeServer->addPlugin($plugin);
+
+ $requestedProperties = array(
+ '{DAV:}group-member-set',
+ );
+ $returnedProperties = array();
+
+ $result = $plugin->beforeGetProperties('principals/user',$principal,$requestedProperties,$returnedProperties);
+
+ $this->assertNull($result);
+
+ $this->assertTrue(isset($returnedProperties[200]));
+ $this->assertTrue(isset($returnedProperties[200]['{DAV:}group-member-set']));
+ $this->assertInstanceOf('Sabre\\DAV\\Property\\HrefList', $returnedProperties[200]['{DAV:}group-member-set']);
+
+ $this->assertEquals(array(), $returnedProperties[200]['{DAV:}group-member-set']->getHrefs());
+
+ }
+
+ function testGroupMemberShip() {
+
+ $tree = array(
+ new DAV\SimpleCollection('principals', array(
+ $principal = new MockPrincipal('user','principals/user'),
+ )),
+ );
+
+ $fakeServer = new DAV\Server($tree);
+ //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend(),'realm');
+ //$fakeServer->addPlugin($plugin);
+ $plugin = new Plugin();
+ $fakeServer->addPlugin($plugin);
+
+ $requestedProperties = array(
+ '{DAV:}group-membership',
+ );
+ $returnedProperties = array();
+
+ $result = $plugin->beforeGetProperties('principals/user',$principal,$requestedProperties,$returnedProperties);
+
+ $this->assertNull($result);
+
+ $this->assertTrue(isset($returnedProperties[200]));
+ $this->assertTrue(isset($returnedProperties[200]['{DAV:}group-membership']));
+ $this->assertInstanceOf('Sabre\\DAV\\Property\\HrefList', $returnedProperties[200]['{DAV:}group-membership']);
+
+ $this->assertEquals(array(), $returnedProperties[200]['{DAV:}group-membership']->getHrefs());
+
+ }
+
+ function testGetDisplayName() {
+
+ $tree = array(
+ new DAV\SimpleCollection('principals', array(
+ $principal = new MockPrincipal('user','principals/user'),
+ )),
+ );
+
+ $fakeServer = new DAV\Server($tree);
+ //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend(),'realm');
+ //$fakeServer->addPlugin($plugin);
+ $plugin = new Plugin();
+ $fakeServer->addPlugin($plugin);
+
+ $requestedProperties = array(
+ '{DAV:}displayname',
+ );
+ $returnedProperties = array();
+
+ $result = $plugin->beforeGetProperties('principals/user',$principal,$requestedProperties,$returnedProperties);
+
+ $this->assertNull($result);
+
+ $this->assertTrue(isset($returnedProperties[200]));
+ $this->assertTrue(isset($returnedProperties[200]['{DAV:}displayname']));
+
+ $this->assertEquals('user', $returnedProperties[200]['{DAV:}displayname']);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php
new file mode 100644
index 000000000..53568654f
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php
@@ -0,0 +1,127 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+
+require_once 'Sabre/DAVACL/MockPrincipal.php';
+
+class PluginUpdatePropertiesTest extends \PHPUnit_Framework_TestCase {
+
+ public function testUpdatePropertiesPassthrough() {
+
+ $tree = array(
+ new DAV\SimpleCollection('foo'),
+ );
+ $server = new DAV\Server($tree);
+ $server->addPlugin(new Plugin());
+
+ $result = $server->updateProperties('foo', array(
+ '{DAV:}foo' => 'bar',
+ ));
+
+ $expected = array(
+ 'href' => 'foo',
+ '403' => array(
+ '{DAV:}foo' => null,
+ ),
+ );
+
+ $this->assertEquals($expected, $result);
+
+ }
+
+ public function testRemoveGroupMembers() {
+
+ $tree = array(
+ new MockPrincipal('foo','foo'),
+ );
+ $server = new DAV\Server($tree);
+ $server->addPlugin(new Plugin());
+
+ $result = $server->updateProperties('foo', array(
+ '{DAV:}group-member-set' => null,
+ ));
+
+ $expected = array(
+ 'href' => 'foo',
+ '200' => array(
+ '{DAV:}group-member-set' => null,
+ ),
+ );
+
+ $this->assertEquals($expected, $result);
+ $this->assertEquals(array(),$tree[0]->getGroupMemberSet());
+
+ }
+
+ public function testSetGroupMembers() {
+
+ $tree = array(
+ new MockPrincipal('foo','foo'),
+ );
+ $server = new DAV\Server($tree);
+ $server->addPlugin(new Plugin());
+
+ $result = $server->updateProperties('foo', array(
+ '{DAV:}group-member-set' => new DAV\Property\HrefList(array('/bar','/baz'), true),
+ ));
+
+ $expected = array(
+ 'href' => 'foo',
+ '200' => array(
+ '{DAV:}group-member-set' => null,
+ ),
+ );
+
+ $this->assertEquals($expected, $result);
+ $this->assertEquals(array('bar','baz'),$tree[0]->getGroupMemberSet());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ */
+ public function testSetBadValue() {
+
+ $tree = array(
+ new MockPrincipal('foo','foo'),
+ );
+ $server = new DAV\Server($tree);
+ $server->addPlugin(new Plugin());
+
+ $result = $server->updateProperties('foo', array(
+ '{DAV:}group-member-set' => new \StdClass(),
+ ));
+
+ }
+
+ public function testSetBadNode() {
+
+ $tree = array(
+ new DAV\SimpleCollection('foo'),
+ );
+ $server = new DAV\Server($tree);
+ $server->addPlugin(new Plugin());
+
+ $result = $server->updateProperties('foo', array(
+ '{DAV:}group-member-set' => new DAV\Property\HrefList(array('/bar','/baz'),false),
+ '{DAV:}bar' => 'baz',
+ ));
+
+ $expected = array(
+ 'href' => 'foo',
+ '403' => array(
+ '{DAV:}group-member-set' => null,
+ ),
+ '424' => array(
+ '{DAV:}bar' => null,
+ ),
+ );
+
+ $this->assertEquals($expected, $result);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php
new file mode 100644
index 000000000..3fe75ca0e
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php
@@ -0,0 +1,178 @@
+<?php
+
+namespace Sabre\DAVACL\PrincipalBackend;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+
+abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
+
+ abstract function getPDO();
+
+ function testConstruct() {
+
+ $pdo = $this->getPDO();
+ $backend = new PDO($pdo);
+ $this->assertTrue($backend instanceof PDO);
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testGetPrincipalsByPrefix() {
+
+ $pdo = $this->getPDO();
+ $backend = new PDO($pdo);
+
+ $expected = array(
+ array(
+ 'uri' => 'principals/user',
+ '{http://sabredav.org/ns}email-address' => 'user@example.org',
+ '{DAV:}displayname' => 'User',
+ ),
+ array(
+ 'uri' => 'principals/group',
+ '{http://sabredav.org/ns}email-address' => 'group@example.org',
+ '{DAV:}displayname' => 'Group',
+ ),
+ );
+
+ $this->assertEquals($expected, $backend->getPrincipalsByPrefix('principals'));
+ $this->assertEquals(array(), $backend->getPrincipalsByPrefix('foo'));
+
+ }
+
+ /**
+ * @depends testConstruct
+ */
+ function testGetPrincipalByPath() {
+
+ $pdo = $this->getPDO();
+ $backend = new PDO($pdo);
+
+ $expected = array(
+ 'id' => 1,
+ 'uri' => 'principals/user',
+ '{http://sabredav.org/ns}email-address' => 'user@example.org',
+ '{DAV:}displayname' => 'User',
+ );
+
+ $this->assertEquals($expected, $backend->getPrincipalByPath('principals/user'));
+ $this->assertEquals(null, $backend->getPrincipalByPath('foo'));
+
+ }
+
+ function testGetGroupMemberSet() {
+
+ $pdo = $this->getPDO();
+ $backend = new PDO($pdo);
+ $expected = array('principals/user');
+
+ $this->assertEquals($expected,$backend->getGroupMemberSet('principals/group'));
+
+ }
+
+ function testGetGroupMembership() {
+
+ $pdo = $this->getPDO();
+ $backend = new PDO($pdo);
+ $expected = array('principals/group');
+
+ $this->assertEquals($expected,$backend->getGroupMembership('principals/user'));
+
+ }
+
+ function testSetGroupMemberSet() {
+
+ $pdo = $this->getPDO();
+
+ // Start situation
+ $backend = new PDO($pdo);
+ $this->assertEquals(array('principals/user'), $backend->getGroupMemberSet('principals/group'));
+
+ // Removing all principals
+ $backend->setGroupMemberSet('principals/group', array());
+ $this->assertEquals(array(), $backend->getGroupMemberSet('principals/group'));
+
+ // Adding principals again
+ $backend->setGroupMemberSet('principals/group', array('principals/user'));
+ $this->assertEquals(array('principals/user'), $backend->getGroupMemberSet('principals/group'));
+
+
+ }
+
+ function testSearchPrincipals() {
+
+ $pdo = $this->getPDO();
+
+ $backend = new PDO($pdo);
+
+ $result = $backend->searchPrincipals('principals', array('{DAV:}blabla' => 'foo'));
+ $this->assertEquals(array(), $result);
+
+ $result = $backend->searchPrincipals('principals', array('{DAV:}displayname' => 'ou'));
+ $this->assertEquals(array('principals/group'), $result);
+
+ $result = $backend->searchPrincipals('principals', array('{DAV:}displayname' => 'UsEr', '{http://sabredav.org/ns}email-address' => 'USER@EXAMPLE'));
+ $this->assertEquals(array('principals/user'), $result);
+
+ $result = $backend->searchPrincipals('mom', array('{DAV:}displayname' => 'UsEr', '{http://sabredav.org/ns}email-address' => 'USER@EXAMPLE'));
+ $this->assertEquals(array(), $result);
+
+ }
+
+ function testUpdatePrincipal() {
+
+ $pdo = $this->getPDO();
+ $backend = new PDO($pdo);
+
+ $result = $backend->updatePrincipal('principals/user', array(
+ '{DAV:}displayname' => 'pietje',
+ '{http://sabredav.org/ns}vcard-url' => 'blabla',
+ ));
+
+ $this->assertTrue($result);
+
+ $this->assertEquals(array(
+ 'id' => 1,
+ 'uri' => 'principals/user',
+ '{DAV:}displayname' => 'pietje',
+ '{http://sabredav.org/ns}vcard-url' => 'blabla',
+ '{http://sabredav.org/ns}email-address' => 'user@example.org',
+ ), $backend->getPrincipalByPath('principals/user'));
+
+ }
+
+ function testUpdatePrincipalUnknownField() {
+
+ $pdo = $this->getPDO();
+ $backend = new PDO($pdo);
+
+ $result = $backend->updatePrincipal('principals/user', array(
+ '{DAV:}displayname' => 'pietje',
+ '{http://sabredav.org/ns}vcard-url' => 'blabla',
+ '{DAV:}unknown' => 'foo',
+ ));
+
+ $this->assertEquals(array(
+ 424 => array(
+ '{DAV:}displayname' => null,
+ '{http://sabredav.org/ns}vcard-url' => null,
+ ),
+ 403 => array(
+ '{DAV:}unknown' => null,
+ ),
+ ), $result);
+
+ $this->assertEquals(array(
+ 'id' => '1',
+ 'uri' => 'principals/user',
+ '{DAV:}displayname' => 'User',
+ '{http://sabredav.org/ns}email-address' => 'user@example.org',
+ ), $backend->getPrincipalByPath('principals/user'));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/Mock.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/Mock.php
new file mode 100644
index 000000000..354446e34
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/Mock.php
@@ -0,0 +1,184 @@
+<?php
+
+namespace Sabre\DAVACL\PrincipalBackend;
+
+class Mock extends AbstractBackend {
+
+ public $groupMembers = array();
+ public $principals;
+
+ function __construct() {
+
+ $this->principals = array(
+ array(
+ 'uri' => 'principals/user1',
+ '{DAV:}displayname' => 'User 1',
+ '{http://sabredav.org/ns}email-address' => 'user1.sabredav@sabredav.org',
+ '{http://sabredav.org/ns}vcard-url' => 'addressbooks/user1/book1/vcard1.vcf',
+ ),
+ array(
+ 'uri' => 'principals/admin',
+ '{DAV:}displayname' => 'Admin',
+ ),
+ array(
+ 'uri' => 'principals/user2',
+ '{DAV:}displayname' => 'User 2',
+ '{http://sabredav.org/ns}email-address' => 'user2.sabredav@sabredav.org',
+ ),
+ );
+
+
+ }
+
+ function getPrincipalsByPrefix($prefix) {
+
+ $prefix = trim($prefix,'/') . '/';
+ $return = array();
+
+ foreach($this->principals as $principal) {
+
+ if (strpos($principal['uri'], $prefix)!==0) continue;
+
+ $return[] = $principal;
+
+ }
+
+ return $return;
+
+ }
+
+ function addPrincipal(array $principal) {
+
+ $this->principals[] = $principal;
+
+ }
+
+ function getPrincipalByPath($path) {
+
+ foreach($this->getPrincipalsByPrefix('principals') as $principal) {
+ if ($principal['uri'] === $path) return $principal;
+ }
+
+ }
+
+ function searchPrincipals($prefixPath, array $searchProperties) {
+
+ $matches = array();
+ foreach($this->getPrincipalsByPrefix($prefixPath) as $principal) {
+
+ foreach($searchProperties as $key=>$value) {
+
+ if (!isset($principal[$key])) {
+ continue 2;
+ }
+ if (mb_stripos($principal[$key],$value, 0, 'UTF-8')===false) {
+ continue 2;
+ }
+
+ }
+ $matches[] = $principal['uri'];
+
+ }
+ return $matches;
+
+ }
+
+ function getGroupMemberSet($path) {
+
+ return isset($this->groupMembers[$path]) ? $this->groupMembers[$path] : array();
+
+ }
+
+ function getGroupMembership($path) {
+
+ $membership = array();
+ foreach($this->groupMembers as $group=>$members) {
+ if (in_array($path, $members)) $membership[] = $group;
+ }
+ return $membership;
+
+ }
+
+ function setGroupMemberSet($path, array $members) {
+
+ $this->groupMembers[$path] = $members;
+
+ }
+
+ /**
+ * Updates one ore more webdav properties on a principal.
+ *
+ * The list of mutations is supplied as an array. Each key in the array is
+ * a propertyname, such as {DAV:}displayname.
+ *
+ * Each value is the actual value to be updated. If a value is null, it
+ * must be deleted.
+ *
+ * This method should be atomic. It must either completely succeed, or
+ * completely fail. Success and failure can simply be returned as 'true' or
+ * 'false'.
+ *
+ * It is also possible to return detailed failure information. In that case
+ * an array such as this should be returned:
+ *
+ * array(
+ * 200 => array(
+ * '{DAV:}prop1' => null,
+ * ),
+ * 201 => array(
+ * '{DAV:}prop2' => null,
+ * ),
+ * 403 => array(
+ * '{DAV:}prop3' => null,
+ * ),
+ * 424 => array(
+ * '{DAV:}prop4' => null,
+ * ),
+ * );
+ *
+ * In this previous example prop1 was successfully updated or deleted, and
+ * prop2 was succesfully created.
+ *
+ * prop3 failed to update due to '403 Forbidden' and because of this prop4
+ * also could not be updated with '424 Failed dependency'.
+ *
+ * This last example was actually incorrect. While 200 and 201 could appear
+ * in 1 response, if there's any error (403) the other properties should
+ * always fail with 423 (failed dependency).
+ *
+ * But anyway, if you don't want to scratch your head over this, just
+ * return true or false.
+ *
+ * @param string $path
+ * @param array $mutations
+ * @return array|bool
+ */
+ public function updatePrincipal($path, $mutations) {
+
+ $value = null;
+ foreach($this->principals as $principalIndex=>$value) {
+ if ($value['uri'] === $path) {
+ $principal = $value;
+ break;
+ }
+ }
+ if (!$principal) return false;
+
+ foreach($mutations as $prop=>$value) {
+
+ if (is_null($value) && isset($principal[$prop])) {
+ unset($principal[$prop]);
+ } else {
+ $principal[$prop] = $value;
+ }
+
+ }
+
+ $this->principals[$principalIndex] = $principal;
+
+ return true;
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php
new file mode 100644
index 000000000..84ba062ca
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Sabre\DAVACL\PrincipalBackend;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+
+require_once 'Sabre/TestUtil.php';
+
+class PDOMySQLTest extends AbstractPDOTest {
+
+ function getPDO() {
+
+ if (!SABRE_HASMYSQL) $this->markTestSkipped('MySQL driver is not available, or not properly configured');
+ $pdo = \Sabre\TestUtil::getMySQLDB();
+ if (!$pdo) $this->markTestSkipped('Could not connect to MySQL database');
+ $pdo->query("DROP TABLE IF EXISTS principals");
+ $pdo->query("
+create table principals (
+ id integer unsigned not null primary key auto_increment,
+ uri varchar(50),
+ email varchar(80),
+ displayname VARCHAR(80),
+ vcardurl VARCHAR(80),
+ unique(uri)
+);");
+
+ $pdo->query("INSERT INTO principals (uri,email,displayname) VALUES ('principals/user','user@example.org','User')");
+ $pdo->query("INSERT INTO principals (uri,email,displayname) VALUES ('principals/group','group@example.org','Group')");
+ $pdo->query("DROP TABLE IF EXISTS groupmembers");
+ $pdo->query("CREATE TABLE groupmembers (
+ id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ principal_id INTEGER UNSIGNED NOT NULL,
+ member_id INTEGER UNSIGNED NOT NULL,
+ UNIQUE(principal_id, member_id)
+ );");
+
+ $pdo->query("INSERT INTO groupmembers (principal_id,member_id) VALUES (2,1)");
+
+ return $pdo;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php
new file mode 100644
index 000000000..192e188f9
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Sabre\DAVACL\PrincipalBackend;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+
+require_once 'Sabre/DAV/Auth/Backend/AbstractPDOTest.php';
+
+class PDOSQLiteTest extends AbstractPDOTest {
+
+ function tearDown() {
+
+ if (file_exists(SABRE_TEMPDIR . '/pdobackend')) unlink(SABRE_TEMPDIR . '/pdobackend');
+ if (file_exists(SABRE_TEMPDIR . '/pdobackend2')) unlink(SABRE_TEMPDIR . '/pdobackend2');
+
+ }
+
+ function getPDO() {
+
+ if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ $pdo = new \PDO('sqlite:'.SABRE_TEMPDIR.'/pdobackend');
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
+ $pdo->query('CREATE TABLE principals (id INTEGER PRIMARY KEY ASC, uri TEXT, email VARCHAR(80), displayname VARCHAR(80), vcardurl VARCHAR(80))');
+ $pdo->query('INSERT INTO principals VALUES (1, "principals/user","user@example.org","User",null)');
+ $pdo->query('INSERT INTO principals VALUES (2, "principals/group","group@example.org","Group",null)');
+
+ $pdo->query("CREATE TABLE groupmembers (
+ id INTEGER PRIMARY KEY ASC,
+ principal_id INT,
+ member_id INT,
+ UNIQUE(principal_id, member_id)
+ );");
+
+ $pdo->query("INSERT INTO groupmembers (principal_id,member_id) VALUES (2,1)");
+
+ return $pdo;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php
new file mode 100644
index 000000000..10b0c04da
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+
+class PrincipalCollectionTest extends \PHPUnit_Framework_TestCase {
+
+ public function testBasic() {
+
+ $backend = new PrincipalBackend\Mock();
+ $pc = new PrincipalCollection($backend);
+ $this->assertTrue($pc instanceof PrincipalCollection);
+
+ $this->assertEquals('principals',$pc->getName());
+
+ }
+
+ /**
+ * @depends testBasic
+ */
+ public function testGetChildren() {
+
+ $backend = new PrincipalBackend\Mock();
+ $pc = new PrincipalCollection($backend);
+
+ $children = $pc->getChildren();
+ $this->assertTrue(is_array($children));
+
+ foreach($children as $child) {
+ $this->assertTrue($child instanceof IPrincipal);
+ }
+
+ }
+
+ /**
+ * @depends testBasic
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ public function testGetChildrenDisable() {
+
+ $backend = new PrincipalBackend\Mock();
+ $pc = new PrincipalCollection($backend);
+ $pc->disableListing = true;
+
+ $children = $pc->getChildren();
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php
new file mode 100644
index 000000000..9c3be4f9a
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php
@@ -0,0 +1,246 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
+
+ function getServer() {
+
+ $backend = new PrincipalBackend\Mock();
+
+ $dir = new DAV\SimpleCollection('root');
+ $principals = new PrincipalCollection($backend);
+ $dir->addChild($principals);
+
+ $fakeServer = new DAV\Server(new DAV\ObjectTree($dir));
+ $fakeServer->httpResponse = new HTTP\ResponseMock();
+ $fakeServer->debugExceptions = true;
+ $plugin = new MockPlugin($backend,'realm');
+ $plugin->allowAccessToNodesWithoutACL = true;
+
+ $this->assertTrue($plugin instanceof Plugin);
+ $fakeServer->addPlugin($plugin);
+ $this->assertEquals($plugin, $fakeServer->getPlugin('acl'));
+
+ return $fakeServer;
+
+ }
+
+ function testDepth1() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal-property-search xmlns:d="DAV:">
+ <d:property-search>
+ <d:prop>
+ <d:displayname />
+ </d:prop>
+ <d:match>user</d:match>
+ </d:property-search>
+ <d:prop>
+ <d:displayname />
+ <d:getcontentlength />
+ </d:prop>
+</d:principal-property-search>';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '1',
+ 'REQUEST_URI' => '/principals',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $server->httpResponse->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ), $server->httpResponse->headers);
+
+ }
+
+
+ function testUnknownSearchField() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal-property-search xmlns:d="DAV:">
+ <d:property-search>
+ <d:prop>
+ <d:yourmom />
+ </d:prop>
+ <d:match>user</d:match>
+ </d:property-search>
+ <d:prop>
+ <d:displayname />
+ <d:getcontentlength />
+ </d:prop>
+</d:principal-property-search>';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '0',
+ 'REQUEST_URI' => '/principals',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ 'Vary' => 'Brief,Prefer',
+ ), $server->httpResponse->headers);
+
+ }
+
+ function testCorrect() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal-property-search xmlns:d="DAV:">
+ <d:apply-to-principal-collection-set />
+ <d:property-search>
+ <d:prop>
+ <d:displayname />
+ </d:prop>
+ <d:match>user</d:match>
+ </d:property-search>
+ <d:prop>
+ <d:displayname />
+ <d:getcontentlength />
+ </d:prop>
+</d:principal-property-search>';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '0',
+ 'REQUEST_URI' => '/',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status, $server->httpResponse->body);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ 'Vary' => 'Brief,Prefer',
+ ), $server->httpResponse->headers);
+
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response' => 2,
+ '/d:multistatus/d:response/d:href' => 2,
+ '/d:multistatus/d:response/d:propstat' => 4,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 4,
+ '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getcontentlength' => 2,
+ '/d:multistatus/d:response/d:propstat/d:status' => 4,
+ );
+
+ $xml = simplexml_load_string($server->httpResponse->body);
+ $xml->registerXPathNamespace('d','DAV:');
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+
+ $count = 1;
+ if (!is_int($v1)) $count = $v2;
+
+ $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
+
+ }
+
+ }
+ function testWrongUri() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal-property-search xmlns:d="DAV:">
+ <d:property-search>
+ <d:prop>
+ <d:displayname />
+ </d:prop>
+ <d:match>user</d:match>
+ </d:property-search>
+ <d:prop>
+ <d:displayname />
+ <d:getcontentlength />
+ </d:prop>
+</d:principal-property-search>';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '0',
+ 'REQUEST_URI' => '/',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 207 Multi-Status', $server->httpResponse->status, $server->httpResponse->body);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ 'Vary' => 'Brief,Prefer',
+ ), $server->httpResponse->headers);
+
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response' => 0,
+ );
+
+ $xml = simplexml_load_string($server->httpResponse->body);
+ $xml->registerXPathNamespace('d','DAV:');
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+
+ $count = 1;
+ if (!is_int($v1)) $count = $v2;
+
+ $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
+
+ }
+
+ }
+}
+
+class MockPlugin extends Plugin {
+
+ function getCurrentUserPrivilegeSet($node) {
+
+ return array(
+ '{DAV:}read',
+ '{DAV:}write',
+ );
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php
new file mode 100644
index 000000000..412389e8b
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class PrincipalSearchPropertySetTest extends \PHPUnit_Framework_TestCase {
+
+ function getServer() {
+
+ $backend = new PrincipalBackend\Mock();
+
+ $dir = new DAV\SimpleCollection('root');
+ $principals = new PrincipalCollection($backend);
+ $dir->addChild($principals);
+
+ $fakeServer = new DAV\Server(new DAV\ObjectTree($dir));
+ $fakeServer->httpResponse = new HTTP\ResponseMock();
+ $plugin = new Plugin($backend,'realm');
+ $this->assertTrue($plugin instanceof Plugin);
+ $fakeServer->addPlugin($plugin);
+ $this->assertEquals($plugin, $fakeServer->getPlugin('acl'));
+
+ return $fakeServer;
+
+ }
+
+ function testDepth1() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal-search-property-set xmlns:d="DAV:" />';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '1',
+ 'REQUEST_URI' => '/principals',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $server->httpResponse->status);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ), $server->httpResponse->headers);
+
+ }
+
+ function testDepthIncorrectXML() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal-search-property-set xmlns:d="DAV:"><d:ohell /></d:principal-search-property-set>';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '0',
+ 'REQUEST_URI' => '/principals',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 400 Bad request', $server->httpResponse->status, $server->httpResponse->body);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ), $server->httpResponse->headers);
+
+ }
+
+ function testCorrect() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal-search-property-set xmlns:d="DAV:"/>';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '0',
+ 'REQUEST_URI' => '/principals',
+ );
+
+ $request = new HTTP\Request($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals('HTTP/1.1 200 OK', $server->httpResponse->status, $server->httpResponse->body);
+ $this->assertEquals(array(
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ ), $server->httpResponse->headers);
+
+
+ $check = array(
+ '/d:principal-search-property-set',
+ '/d:principal-search-property-set/d:principal-search-property' => 2,
+ '/d:principal-search-property-set/d:principal-search-property/d:prop' => 2,
+ '/d:principal-search-property-set/d:principal-search-property/d:prop/d:displayname' => 1,
+ '/d:principal-search-property-set/d:principal-search-property/d:prop/s:email-address' => 1,
+ '/d:principal-search-property-set/d:principal-search-property/d:description' => 2,
+ );
+
+ $xml = simplexml_load_string($server->httpResponse->body);
+ $xml->registerXPathNamespace('d','DAV:');
+ $xml->registerXPathNamespace('s','http://sabredav.org/ns');
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+
+ $count = 1;
+ if (!is_int($v1)) $count = $v2;
+
+ $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
+
+ }
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php
new file mode 100644
index 000000000..2d4371138
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php
@@ -0,0 +1,204 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+class PrincipalTest extends \PHPUnit_Framework_TestCase {
+
+ public function testConstruct() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $this->assertTrue($principal instanceof Principal);
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception
+ */
+ public function testConstructNoUri() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array());
+
+ }
+
+ public function testGetName() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $this->assertEquals('admin',$principal->getName());
+
+ }
+
+ public function testGetDisplayName() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $this->assertEquals('admin',$principal->getDisplayname());
+
+ $principal = new Principal($principalBackend, array(
+ 'uri' => 'principals/admin',
+ '{DAV:}displayname' => 'Mr. Admin'
+ ));
+ $this->assertEquals('Mr. Admin',$principal->getDisplayname());
+
+ }
+
+ public function testGetProperties() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array(
+ 'uri' => 'principals/admin',
+ '{DAV:}displayname' => 'Mr. Admin',
+ '{http://www.example.org/custom}custom' => 'Custom',
+ '{http://sabredav.org/ns}email-address' => 'admin@example.org',
+ ));
+
+ $keys = array(
+ '{DAV:}displayname',
+ '{http://www.example.org/custom}custom',
+ '{http://sabredav.org/ns}email-address',
+ );
+ $props = $principal->getProperties($keys);
+
+ foreach($keys as $key) $this->assertArrayHasKey($key,$props);
+
+ $this->assertEquals('Mr. Admin',$props['{DAV:}displayname']);
+
+ $this->assertEquals('admin@example.org', $props['{http://sabredav.org/ns}email-address']);
+ }
+
+ public function testUpdateProperties() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $result = $principal->updateProperties(array('{DAV:}yourmom'=>'test'));
+ $this->assertEquals(true,$result);
+
+ }
+
+ public function testGetPrincipalUrl() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $this->assertEquals('principals/admin',$principal->getPrincipalUrl());
+
+ }
+
+ public function testGetAlternateUriSet() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array(
+ 'uri' => 'principals/admin',
+ '{DAV:}displayname' => 'Mr. Admin',
+ '{http://www.example.org/custom}custom' => 'Custom',
+ '{http://sabredav.org/ns}email-address' => 'admin@example.org',
+ '{DAV:}alternate-URI-set' => array(
+ 'mailto:admin+1@example.org',
+ 'mailto:admin+2@example.org',
+ 'mailto:admin@example.org',
+ ),
+ ));
+
+ $expected = array(
+ 'mailto:admin+1@example.org',
+ 'mailto:admin+2@example.org',
+ 'mailto:admin@example.org',
+ );
+
+ $this->assertEquals($expected,$principal->getAlternateUriSet());
+
+ }
+ public function testGetAlternateUriSetEmpty() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array(
+ 'uri' => 'principals/admin',
+ ));
+
+ $expected = array();
+
+ $this->assertEquals($expected,$principal->getAlternateUriSet());
+
+ }
+
+ public function testGetGroupMemberSet() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $this->assertEquals(array(),$principal->getGroupMemberSet());
+
+ }
+ public function testGetGroupMembership() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $this->assertEquals(array(),$principal->getGroupMembership());
+
+ }
+
+ public function testSetGroupMemberSet() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $principal->setGroupMemberSet(array('principals/foo'));
+
+ $this->assertEquals(array(
+ 'principals/admin' => array('principals/foo'),
+ ), $principalBackend->groupMembers);
+
+ }
+
+ public function testGetOwner() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $this->assertEquals('principals/admin',$principal->getOwner());
+
+ }
+
+ public function testGetGroup() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $this->assertNull($principal->getGroup());
+
+ }
+
+ public function testGetACl() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $this->assertEquals(array(
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/admin',
+ 'protected' => true,
+ )
+ ),$principal->getACL());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ */
+ public function testSetACl() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $principal->setACL(array());
+
+ }
+
+ public function testGetSupportedPrivilegeSet() {
+
+ $principalBackend = new PrincipalBackend\Mock();
+ $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $this->assertNull($principal->getSupportedPrivilegeSet());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLRestrictionsTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLRestrictionsTest.php
new file mode 100644
index 000000000..72a2f36a4
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLRestrictionsTest.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Sabre\DAVACL\Property;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+class ACLRestrictionsTest extends \PHPUnit_Framework_TestCase {
+
+ function testConstruct() {
+
+ $prop = new AclRestrictions();
+
+ }
+
+ function testSerializeEmpty() {
+
+ $dom = new \DOMDocument('1.0');
+ $root = $dom->createElementNS('DAV:','d:root');
+
+ $dom->appendChild($root);
+
+ $acl = new AclRestrictions();
+ $acl->serialize(new DAV\Server(), $root);
+
+ $xml = $dom->saveXML();
+ $expected = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:"><d:grant-only/><d:no-invert/></d:root>
+';
+ $this->assertEquals($expected, $xml);
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLTest.php
new file mode 100644
index 000000000..7f2014df3
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/ACLTest.php
@@ -0,0 +1,335 @@
+<?php
+
+namespace Sabre\DAVACL\Property;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+
+class ACLTest extends \PHPUnit_Framework_TestCase {
+
+ function testConstruct() {
+
+ $acl = new Acl(array());
+
+ }
+
+ function testSerializeEmpty() {
+
+ $dom = new \DOMDocument('1.0');
+ $root = $dom->createElementNS('DAV:','d:root');
+
+ $dom->appendChild($root);
+
+ $acl = new Acl(array());
+ $acl->serialize(new DAV\Server(), $root);
+
+ $xml = $dom->saveXML();
+ $expected = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:"/>
+';
+ $this->assertEquals($expected, $xml);
+
+ }
+
+ function testSerialize() {
+
+ $dom = new \DOMDocument('1.0');
+ $root = $dom->createElementNS('DAV:','d:root');
+
+ $dom->appendChild($root);
+
+ $privileges = array(
+ array(
+ 'principal' => 'principals/evert',
+ 'privilege' => '{DAV:}write',
+ 'uri' => 'articles',
+ ),
+ array(
+ 'principal' => 'principals/foo',
+ 'privilege' => '{DAV:}read',
+ 'uri' => 'articles',
+ 'protected' => true,
+ ),
+ );
+
+ $acl = new Acl($privileges);
+ $acl->serialize(new DAV\Server(), $root);
+
+ $dom->formatOutput = true;
+
+ $xml = $dom->saveXML();
+ $expected = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">
+ <d:ace>
+ <d:principal>
+ <d:href>/principals/evert/</d:href>
+ </d:principal>
+ <d:grant>
+ <d:privilege>
+ <d:write/>
+ </d:privilege>
+ </d:grant>
+ </d:ace>
+ <d:ace>
+ <d:principal>
+ <d:href>/principals/foo/</d:href>
+ </d:principal>
+ <d:grant>
+ <d:privilege>
+ <d:read/>
+ </d:privilege>
+ </d:grant>
+ <d:protected/>
+ </d:ace>
+</d:root>
+';
+ $this->assertEquals($expected, $xml);
+
+ }
+
+ function testSerializeSpecialPrincipals() {
+
+ $dom = new \DOMDocument('1.0');
+ $root = $dom->createElementNS('DAV:','d:root');
+
+ $dom->appendChild($root);
+
+ $privileges = array(
+ array(
+ 'principal' => '{DAV:}authenticated',
+ 'privilege' => '{DAV:}write',
+ 'uri' => 'articles',
+ ),
+ array(
+ 'principal' => '{DAV:}unauthenticated',
+ 'privilege' => '{DAV:}write',
+ 'uri' => 'articles',
+ ),
+ array(
+ 'principal' => '{DAV:}all',
+ 'privilege' => '{DAV:}write',
+ 'uri' => 'articles',
+ ),
+
+ );
+
+ $acl = new Acl($privileges);
+ $acl->serialize(new DAV\Server(), $root);
+
+ $dom->formatOutput = true;
+
+ $xml = $dom->saveXML();
+ $expected = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">
+ <d:ace>
+ <d:principal>
+ <d:authenticated/>
+ </d:principal>
+ <d:grant>
+ <d:privilege>
+ <d:write/>
+ </d:privilege>
+ </d:grant>
+ </d:ace>
+ <d:ace>
+ <d:principal>
+ <d:unauthenticated/>
+ </d:principal>
+ <d:grant>
+ <d:privilege>
+ <d:write/>
+ </d:privilege>
+ </d:grant>
+ </d:ace>
+ <d:ace>
+ <d:principal>
+ <d:all/>
+ </d:principal>
+ <d:grant>
+ <d:privilege>
+ <d:write/>
+ </d:privilege>
+ </d:grant>
+ </d:ace>
+</d:root>
+';
+ $this->assertEquals($expected, $xml);
+
+ }
+
+ function testUnserialize() {
+
+ $source = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">
+ <d:ace>
+ <d:principal>
+ <d:href>/principals/evert/</d:href>
+ </d:principal>
+ <d:grant>
+ <d:privilege>
+ <d:write/>
+ </d:privilege>
+ </d:grant>
+ </d:ace>
+ <d:ace>
+ <d:principal>
+ <d:href>/principals/foo/</d:href>
+ </d:principal>
+ <d:grant>
+ <d:privilege>
+ <d:read/>
+ </d:privilege>
+ </d:grant>
+ <d:protected/>
+ </d:ace>
+</d:root>
+';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($source);
+ $result = Acl::unserialize($dom->firstChild);
+
+ $this->assertInstanceOf('Sabre\\DAVACL\\Property\\ACL', $result);
+
+ $expected = array(
+ array(
+ 'principal' => '/principals/evert/',
+ 'protected' => false,
+ 'privilege' => '{DAV:}write',
+ ),
+ array(
+ 'principal' => '/principals/foo/',
+ 'protected' => true,
+ 'privilege' => '{DAV:}read',
+ ),
+ );
+
+ $this->assertEquals($expected, $result->getPrivileges());
+
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testUnserializeNoPrincipal() {
+
+ $source = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">
+ <d:ace>
+ <d:grant>
+ <d:privilege>
+ <d:write/>
+ </d:privilege>
+ </d:grant>
+ </d:ace>
+</d:root>
+';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($source);
+ Acl::unserialize($dom->firstChild);
+
+ }
+
+ function testUnserializeOtherPrincipal() {
+
+ $source = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">
+ <d:ace>
+ <d:grant>
+ <d:privilege>
+ <d:write/>
+ </d:privilege>
+ </d:grant>
+ <d:principal><d:authenticated /></d:principal>
+ </d:ace>
+ <d:ace>
+ <d:grant>
+ <d:privilege>
+ <d:write/>
+ </d:privilege>
+ </d:grant>
+ <d:principal><d:unauthenticated /></d:principal>
+ </d:ace>
+ <d:ace>
+ <d:grant>
+ <d:privilege>
+ <d:write/>
+ </d:privilege>
+ </d:grant>
+ <d:principal><d:all /></d:principal>
+ </d:ace>
+</d:root>
+';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($source);
+ $result = Acl::unserialize($dom->firstChild);
+
+ $this->assertInstanceOf('Sabre\\DAVACL\\Property\\Acl', $result);
+
+ $expected = array(
+ array(
+ 'principal' => '{DAV:}authenticated',
+ 'protected' => false,
+ 'privilege' => '{DAV:}write',
+ ),
+ array(
+ 'principal' => '{DAV:}unauthenticated',
+ 'protected' => false,
+ 'privilege' => '{DAV:}write',
+ ),
+ array(
+ 'principal' => '{DAV:}all',
+ 'protected' => false,
+ 'privilege' => '{DAV:}write',
+ ),
+ );
+
+ $this->assertEquals($expected, $result->getPrivileges());
+
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\NotImplemented
+ */
+ function testUnserializeDeny() {
+
+ $source = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">
+ <d:ace>
+ <d:deny>
+ <d:privilege>
+ <d:write/>
+ </d:privilege>
+ </d:deny>
+ <d:principal><d:href>/principals/evert</d:href></d:principal>
+ </d:ace>
+</d:root>
+';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($source);
+ Acl::unserialize($dom->firstChild);
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testUnserializeMissingPriv() {
+
+ $source = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">
+ <d:ace>
+ <d:grant>
+ <d:privilege />
+ </d:grant>
+ <d:principal><d:href>/principals/evert</d:href></d:principal>
+ </d:ace>
+</d:root>
+';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($source);
+ Acl::unserialize($dom->firstChild);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Property/CurrentUserPrivilegeSetTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/CurrentUserPrivilegeSetTest.php
new file mode 100644
index 000000000..e71addb65
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/CurrentUserPrivilegeSetTest.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Sabre\DAVACL\Property;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+
+class CurrentUserPrivilegeSetTest extends \PHPUnit_Framework_TestCase {
+
+ function testSerialize() {
+
+ $privileges = array(
+ '{DAV:}read',
+ '{DAV:}write',
+ );
+ $prop = new CurrentUserPrivilegeSet($privileges);
+
+ $server = new DAV\Server();
+ $dom = new \DOMDocument('1.0','utf-8');
+ $root = $dom->createElementNS('DAV:','d:root');
+ $dom->appendChild($root);
+
+ $prop->serialize($server, $root);
+
+ $xpaths = array(
+ '/d:root' => 1,
+ '/d:root/d:privilege' => 2,
+ '/d:root/d:privilege/d:read' => 1,
+ '/d:root/d:privilege/d:write' => 1,
+ );
+
+ // Reloading because PHP DOM sucks
+ $dom2 = new \DOMDocument('1.0', 'utf-8');
+ $dom2->loadXML($dom->saveXML());
+
+ $dxpath = new \DOMXPath($dom2);
+ $dxpath->registerNamespace('d','DAV:');
+ foreach($xpaths as $xpath=>$count) {
+
+ $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count);
+
+ }
+
+ }
+
+ function testUnserialize() {
+
+ $source = '<?xml version="1.0"?>
+<d:root xmlns:d="DAV:">
+ <d:privilege>
+ <d:write-properties />
+ </d:privilege>
+ <d:privilege>
+ <d:read />
+ </d:privilege>
+</d:root>
+';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($source);
+ $result = CurrentUserPrivilegeSet::unserialize($dom->firstChild, array());
+ $this->assertTrue($result->has('{DAV:}read'));
+ $this->assertTrue($result->has('{DAV:}write-properties'));
+ $this->assertFalse($result->has('{DAV:}bind'));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Property/PrincipalTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/PrincipalTest.php
new file mode 100644
index 000000000..be12c79ee
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/PrincipalTest.php
@@ -0,0 +1,181 @@
+<?php
+
+namespace Sabre\DAVACL\Property;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+class PrincipalTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $principal = new Principal(Principal::UNAUTHENTICATED);
+ $this->assertEquals(Principal::UNAUTHENTICATED, $principal->getType());
+ $this->assertNull($principal->getHref());
+
+ $principal = new Principal(Principal::AUTHENTICATED);
+ $this->assertEquals(Principal::AUTHENTICATED, $principal->getType());
+ $this->assertNull($principal->getHref());
+
+ $principal = new Principal(Principal::HREF,'admin');
+ $this->assertEquals(Principal::HREF, $principal->getType());
+ $this->assertEquals('admin',$principal->getHref());
+
+ }
+
+ /**
+ * @depends testSimple
+ * @expectedException Sabre\DAV\Exception
+ */
+ function testNoHref() {
+
+ $principal = new Principal(Principal::HREF);
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerializeUnAuthenticated() {
+
+ $prin = new Principal(Principal::UNAUTHENTICATED);
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:principal');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $objectTree = new DAV\ObjectTree(new DAV\SimpleCollection('rootdir'));
+ $server = new DAV\Server($objectTree);
+
+ $prin->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:principal xmlns:d="DAV:">' .
+'<d:unauthenticated/>' .
+'</d:principal>
+', $xml);
+
+ }
+
+
+ /**
+ * @depends testSerializeUnAuthenticated
+ */
+ function testSerializeAuthenticated() {
+
+ $prin = new Principal(Principal::AUTHENTICATED);
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:principal');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $objectTree = new DAV\ObjectTree(new DAV\SimpleCollection('rootdir'));
+ $server = new DAV\Server($objectTree);
+
+ $prin->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:principal xmlns:d="DAV:">' .
+'<d:authenticated/>' .
+'</d:principal>
+', $xml);
+
+ }
+
+
+ /**
+ * @depends testSerializeUnAuthenticated
+ */
+ function testSerializeHref() {
+
+ $prin = new Principal(Principal::HREF,'principals/admin');
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElement('d:principal');
+ $root->setAttribute('xmlns:d','DAV:');
+
+ $doc->appendChild($root);
+ $objectTree = new DAV\ObjectTree(new DAV\SimpleCollection('rootdir'));
+ $server = new DAV\Server($objectTree);
+
+ $prin->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:principal xmlns:d="DAV:">' .
+'<d:href>/principals/admin</d:href>' .
+'</d:principal>
+', $xml);
+
+ }
+
+ function testUnserializeHref() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal xmlns:d="DAV:">' .
+'<d:href>/principals/admin</d:href>' .
+'</d:principal>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $principal = Principal::unserialize($dom->firstChild);
+ $this->assertEquals(Principal::HREF, $principal->getType());
+ $this->assertEquals('/principals/admin', $principal->getHref());
+
+ }
+
+ function testUnserializeAuthenticated() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal xmlns:d="DAV:">' .
+' <d:authenticated />' .
+'</d:principal>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $principal = Principal::unserialize($dom->firstChild);
+ $this->assertEquals(Principal::AUTHENTICATED, $principal->getType());
+
+ }
+
+ function testUnserializeUnauthenticated() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal xmlns:d="DAV:">' .
+' <d:unauthenticated />' .
+'</d:principal>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+
+ $principal = Principal::unserialize($dom->firstChild);
+ $this->assertEquals(Principal::UNAUTHENTICATED, $principal->getType());
+
+ }
+
+ /**
+ * @expectedException Sabre\DAV\Exception\BadRequest
+ */
+ function testUnserializeUnknown() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal xmlns:d="DAV:">' .
+' <d:foo />' .
+'</d:principal>';
+
+ $dom = DAV\XMLUtil::loadDOMDocument($xml);
+
+ Principal::unserialize($dom->firstChild);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Property/SupportedPrivilegeSetTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/SupportedPrivilegeSetTest.php
new file mode 100644
index 000000000..943316331
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Property/SupportedPrivilegeSetTest.php
@@ -0,0 +1,106 @@
+<?php
+
+namespace Sabre\DAVACL\Property;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+
+
+class SupportedPrivilegeSetTest extends \PHPUnit_Framework_TestCase {
+
+ function testSimple() {
+
+ $prop = new SupportedPrivilegeSet(array(
+ 'privilege' => '{DAV:}all',
+ ));
+
+ }
+
+
+ /**
+ * @depends testSimple
+ */
+ function testSerializeSimple() {
+
+ $prop = new SupportedPrivilegeSet(array(
+ 'privilege' => '{DAV:}all',
+ ));
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElementNS('DAV:', 'd:supported-privilege-set');
+
+ $doc->appendChild($root);
+
+ $server = new DAV\Server();
+ $prop->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:supported-privilege-set xmlns:d="DAV:">' .
+'<d:supported-privilege>' .
+'<d:privilege>' .
+'<d:all/>' .
+'</d:privilege>' .
+'</d:supported-privilege>' .
+'</d:supported-privilege-set>
+', $xml);
+
+ }
+
+ /**
+ * @depends testSimple
+ */
+ function testSerializeAggregate() {
+
+ $prop = new SupportedPrivilegeSet(array(
+ 'privilege' => '{DAV:}all',
+ 'abstract' => true,
+ 'aggregates' => array(
+ array(
+ 'privilege' => '{DAV:}read',
+ ),
+ array(
+ 'privilege' => '{DAV:}write',
+ 'description' => 'booh',
+ ),
+ ),
+ ));
+
+ $doc = new \DOMDocument();
+ $root = $doc->createElementNS('DAV:', 'd:supported-privilege-set');
+
+ $doc->appendChild($root);
+
+ $server = new DAV\Server();
+ $prop->serialize($server, $root);
+
+ $xml = $doc->saveXML();
+
+ $this->assertEquals(
+'<?xml version="1.0"?>
+<d:supported-privilege-set xmlns:d="DAV:">' .
+'<d:supported-privilege>' .
+'<d:privilege>' .
+'<d:all/>' .
+'</d:privilege>' .
+'<d:abstract/>' .
+'<d:supported-privilege>' .
+'<d:privilege>' .
+'<d:read/>' .
+'</d:privilege>' .
+'</d:supported-privilege>' .
+'<d:supported-privilege>' .
+'<d:privilege>' .
+'<d:write/>' .
+'</d:privilege>' .
+'<d:description>booh</d:description>' .
+'</d:supported-privilege>' .
+'</d:supported-privilege>' .
+'</d:supported-privilege-set>
+', $xml);
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php
new file mode 100644
index 000000000..04ed5c330
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php
@@ -0,0 +1,322 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+use Sabre\DAV;
+use Sabre\HTTP;
+
+
+require_once 'Sabre/DAVACL/MockPrincipal.php';
+require_once 'Sabre/DAVACL/MockACLNode.php';
+
+class SimplePluginTest extends \PHPUnit_Framework_TestCase {
+
+ function testValues() {
+
+ $aclPlugin = new Plugin();
+ $this->assertEquals('acl',$aclPlugin->getPluginName());
+ $this->assertEquals(
+ array('access-control', 'calendarserver-principal-property-search'),
+ $aclPlugin->getFeatures()
+ );
+
+ $this->assertEquals(
+ array(
+ '{DAV:}expand-property',
+ '{DAV:}principal-property-search',
+ '{DAV:}principal-search-property-set'
+ ),
+ $aclPlugin->getSupportedReportSet(''));
+
+ $this->assertEquals(array('ACL'), $aclPlugin->getMethods(''));
+
+ }
+
+ function testGetFlatPrivilegeSet() {
+
+ $expected = array(
+ '{DAV:}all' => array(
+ 'privilege' => '{DAV:}all',
+ 'abstract' => true,
+ 'aggregates' => array(
+ '{DAV:}read',
+ '{DAV:}write',
+ ),
+ 'concrete' => null,
+ ),
+ '{DAV:}read' => array(
+ 'privilege' => '{DAV:}read',
+ 'abstract' => false,
+ 'aggregates' => array(
+ '{DAV:}read-acl',
+ '{DAV:}read-current-user-privilege-set',
+ ),
+ 'concrete' => '{DAV:}read',
+ ),
+ '{DAV:}read-acl' => array(
+ 'privilege' => '{DAV:}read-acl',
+ 'abstract' => true,
+ 'aggregates' => array(),
+ 'concrete' => '{DAV:}read',
+ ),
+ '{DAV:}read-current-user-privilege-set' => array(
+ 'privilege' => '{DAV:}read-current-user-privilege-set',
+ 'abstract' => true,
+ 'aggregates' => array(),
+ 'concrete' => '{DAV:}read',
+ ),
+ '{DAV:}write' => array(
+ 'privilege' => '{DAV:}write',
+ 'abstract' => false,
+ 'aggregates' => array(
+ '{DAV:}write-acl',
+ '{DAV:}write-properties',
+ '{DAV:}write-content',
+ '{DAV:}bind',
+ '{DAV:}unbind',
+ '{DAV:}unlock',
+ ),
+ 'concrete' => '{DAV:}write',
+ ),
+ '{DAV:}write-acl' => array(
+ 'privilege' => '{DAV:}write-acl',
+ 'abstract' => true,
+ 'aggregates' => array(),
+ 'concrete' => '{DAV:}write',
+ ),
+ '{DAV:}write-properties' => array(
+ 'privilege' => '{DAV:}write-properties',
+ 'abstract' => true,
+ 'aggregates' => array(),
+ 'concrete' => '{DAV:}write',
+ ),
+ '{DAV:}write-content' => array(
+ 'privilege' => '{DAV:}write-content',
+ 'abstract' => true,
+ 'aggregates' => array(),
+ 'concrete' => '{DAV:}write',
+ ),
+ '{DAV:}unlock' => array(
+ 'privilege' => '{DAV:}unlock',
+ 'abstract' => true,
+ 'aggregates' => array(),
+ 'concrete' => '{DAV:}write',
+ ),
+ '{DAV:}bind' => array(
+ 'privilege' => '{DAV:}bind',
+ 'abstract' => true,
+ 'aggregates' => array(),
+ 'concrete' => '{DAV:}write',
+ ),
+ '{DAV:}unbind' => array(
+ 'privilege' => '{DAV:}unbind',
+ 'abstract' => true,
+ 'aggregates' => array(),
+ 'concrete' => '{DAV:}write',
+ ),
+
+ );
+
+ $plugin = new Plugin();
+ $server = new DAV\Server();
+ $server->addPlugin($plugin);
+ $this->assertEquals($expected, $plugin->getFlatPrivilegeSet(''));
+
+ }
+
+ function testCurrentUserPrincipalsNotLoggedIn() {
+
+ $acl = new Plugin();
+ $server = new DAV\Server();
+ $server->addPlugin($acl);
+
+ $this->assertEquals(array(),$acl->getCurrentUserPrincipals());
+
+ }
+
+ function testCurrentUserPrincipalsSimple() {
+
+ $tree = array(
+
+ new DAV\SimpleCollection('principals', array(
+ new MockPrincipal('admin','principals/admin'),
+ ))
+
+ );
+
+ $acl = new Plugin();
+ $server = new DAV\Server($tree);
+ $server->addPlugin($acl);
+
+ $auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'SabreDAV');
+ $server->addPlugin($auth);
+
+ //forcing login
+ $auth->beforeMethod('GET','/');
+
+ $this->assertEquals(array('principals/admin'),$acl->getCurrentUserPrincipals());
+
+ }
+
+ function testCurrentUserPrincipalsGroups() {
+
+ $tree = array(
+
+ new DAV\SimpleCollection('principals', array(
+ new MockPrincipal('admin','principals/admin',array('principals/administrators', 'principals/everyone')),
+ new MockPrincipal('administrators','principals/administrators',array('principals/groups'), array('principals/admin')),
+ new MockPrincipal('everyone','principals/everyone',array(), array('principals/admin')),
+ new MockPrincipal('groups','principals/groups',array(), array('principals/administrators')),
+ ))
+
+ );
+
+ $acl = new Plugin();
+ $server = new DAV\Server($tree);
+ $server->addPlugin($acl);
+
+ $auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'SabreDAV');
+ $server->addPlugin($auth);
+
+ //forcing login
+ $auth->beforeMethod('GET','/');
+
+ $expected = array(
+ 'principals/admin',
+ 'principals/administrators',
+ 'principals/everyone',
+ 'principals/groups',
+ );
+
+ $this->assertEquals($expected,$acl->getCurrentUserPrincipals());
+
+ // The second one should trigger the cache and be identical
+ $this->assertEquals($expected,$acl->getCurrentUserPrincipals());
+
+ }
+
+ function testGetACL() {
+
+ $acl = array(
+ array(
+ 'principal' => 'principals/admin',
+ 'privilege' => '{DAV:}read',
+ ),
+ array(
+ 'principal' => 'principals/admin',
+ 'privilege' => '{DAV:}write',
+ ),
+ );
+
+
+ $tree = array(
+ new MockACLNode('foo',$acl),
+ );
+
+ $server = new DAV\Server($tree);
+ $aclPlugin = new Plugin();
+ $server->addPlugin($aclPlugin);
+
+ $this->assertEquals($acl,$aclPlugin->getACL('foo'));
+
+ }
+
+ function testGetCurrentUserPrivilegeSet() {
+
+ $acl = array(
+ array(
+ 'principal' => 'principals/admin',
+ 'privilege' => '{DAV:}read',
+ ),
+ array(
+ 'principal' => 'principals/user1',
+ 'privilege' => '{DAV:}read',
+ ),
+ array(
+ 'principal' => 'principals/admin',
+ 'privilege' => '{DAV:}write',
+ ),
+ );
+
+
+ $tree = array(
+ new MockACLNode('foo',$acl),
+
+ new DAV\SimpleCollection('principals', array(
+ new MockPrincipal('admin','principals/admin'),
+ )),
+
+ );
+
+ $server = new DAV\Server($tree);
+ $aclPlugin = new Plugin();
+ $server->addPlugin($aclPlugin);
+
+ $auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'SabreDAV');
+ $server->addPlugin($auth);
+
+ //forcing login
+ $auth->beforeMethod('GET','/');
+
+ $expected = array(
+ '{DAV:}write',
+ '{DAV:}write-acl',
+ '{DAV:}write-properties',
+ '{DAV:}write-content',
+ '{DAV:}bind',
+ '{DAV:}unbind',
+ '{DAV:}unlock',
+ '{DAV:}read',
+ '{DAV:}read-acl',
+ '{DAV:}read-current-user-privilege-set',
+ );
+
+ $this->assertEquals($expected,$aclPlugin->getCurrentUserPrivilegeSet('foo'));
+
+ }
+
+ function testCheckPrivileges() {
+
+ $acl = array(
+ array(
+ 'principal' => 'principals/admin',
+ 'privilege' => '{DAV:}read',
+ ),
+ array(
+ 'principal' => 'principals/user1',
+ 'privilege' => '{DAV:}read',
+ ),
+ array(
+ 'principal' => 'principals/admin',
+ 'privilege' => '{DAV:}write',
+ ),
+ );
+
+
+ $tree = array(
+ new MockACLNode('foo',$acl),
+
+ new DAV\SimpleCollection('principals', array(
+ new MockPrincipal('admin','principals/admin'),
+ )),
+
+ );
+
+ $server = new DAV\Server($tree);
+ $aclPlugin = new Plugin();
+ $server->addPlugin($aclPlugin);
+
+ $auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'SabreDAV');
+ $server->addPlugin($auth);
+
+ //forcing login
+ //$auth->beforeMethod('GET','/');
+
+ $this->assertFalse($aclPlugin->checkPrivileges('foo', array('{DAV:}read'), Plugin::R_PARENT, false));
+
+ }
+}
+
+
+
+
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/VersionTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/VersionTest.php
new file mode 100644
index 000000000..c432527dc
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/VersionTest.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+class VersionTest extends \PHPUnit_Framework_TestCase {
+
+ function testString() {
+
+ $v = Version::VERSION;
+ $this->assertEquals(-1, version_compare('1.0.0',$v));
+
+ $s = Version::STABILITY;
+ $this->assertTrue($s == 'alpha' || $s == 'beta' || $s =='stable');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVServerTest.php b/vendor/sabre/dav/tests/Sabre/DAVServerTest.php
new file mode 100644
index 000000000..a92c7065a
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/DAVServerTest.php
@@ -0,0 +1,178 @@
+<?php
+
+namespace Sabre;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+require_once 'Sabre/CalDAV/Backend/Mock.php';
+require_once 'Sabre/CardDAV/Backend/Mock.php';
+require_once 'Sabre/DAVACL/PrincipalBackend/Mock.php';
+require_once 'Sabre/DAV/Auth/Backend/Mock.php';
+
+/**
+ * This class may be used as a basis for other webdav-related unittests.
+ *
+ * This class is supposed to provide a reasonably big framework to quickly get
+ * a testing environment running.
+ *
+ * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
+
+ protected $setupCalDAV = false;
+ protected $setupCardDAV = false;
+ protected $setupACL = false;
+ protected $setupCalDAVSharing = false;
+
+ protected $caldavCalendars = array();
+ protected $caldavCalendarObjects = array();
+
+ protected $carddavAddressBooks = array();
+ protected $carddavCards = array();
+
+ /**
+ * @var Sabre\DAV\Server
+ */
+ protected $server;
+ protected $tree = array();
+
+ protected $caldavBackend;
+ protected $carddavBackend;
+ protected $principalBackend;
+
+ /**
+ * @var Sabre\CalDAV\Plugin
+ */
+ protected $caldavPlugin;
+
+ /**
+ * @var Sabre\CardDAV\Plugin
+ */
+ protected $carddavPlugin;
+
+ /**
+ * @var Sabre\DAVACL\Plugin
+ */
+ protected $aclPlugin;
+
+ /**
+ * @var Sabre\CalDAV\SharingPlugin
+ */
+ protected $caldavSharingPlugin;
+
+ /**
+ * @var Sabre\DAV\Auth\Plugin
+ */
+ protected $authPlugin;
+
+ /**
+ * If this string is set, we will automatically log in the user with this
+ * name.
+ */
+ protected $autoLogin = null;
+
+ function setUp() {
+
+ $this->setUpBackends();
+ $this->setUpTree();
+
+ $this->server = new DAV\Server($this->tree);
+ $this->server->debugExceptions = true;
+
+ if ($this->setupCalDAV) {
+ $this->caldavPlugin = new CalDAV\Plugin();
+ $this->server->addPlugin($this->caldavPlugin);
+ }
+ if ($this->setupCalDAVSharing) {
+ $this->caldavSharingPlugin = new CalDAV\SharingPlugin();
+ $this->server->addPlugin($this->caldavSharingPlugin);
+ }
+ if ($this->setupCardDAV) {
+ $this->carddavPlugin = new CardDAV\Plugin();
+ $this->server->addPlugin($this->carddavPlugin);
+ }
+ if ($this->setupACL) {
+ $this->aclPlugin = new DAVACL\Plugin();
+ $this->server->addPlugin($this->aclPlugin);
+ }
+ if ($this->autoLogin) {
+ $authBackend = new DAV\Auth\Backend\Mock();
+ $authBackend->defaultUser = $this->autoLogin;
+ $this->authPlugin = new DAV\Auth\Plugin($authBackend, 'SabreDAV');
+ $this->server->addPlugin($this->authPlugin);
+
+ // This will trigger the actual login procedure
+ $this->authPlugin->beforeMethod('OPTIONS','/');
+ }
+
+ }
+
+ /**
+ * Makes a request, and returns a response object.
+ *
+ * You can either pass an instance of Sabre\HTTP\Request, or an array,
+ * which will then be used as the _SERVER array.
+ *
+ * @param array|\Sabre\HTTP\Request $request
+ * @return \Sabre\HTTP\Response
+ */
+ function request($request) {
+
+ if (is_array($request)) {
+ $request = new HTTP\Request($request);
+ }
+ $this->server->httpRequest = $request;
+ $this->server->httpResponse = new HTTP\ResponseMock();
+ $this->server->exec();
+
+ return $this->server->httpResponse;
+
+ }
+
+ function setUpTree() {
+
+ if ($this->setupCalDAV) {
+ $this->tree[] = new CalDAV\CalendarRootNode(
+ $this->principalBackend,
+ $this->caldavBackend
+ );
+ }
+ if ($this->setupCardDAV) {
+ $this->tree[] = new CardDAV\AddressBookRoot(
+ $this->principalBackend,
+ $this->carddavBackend
+ );
+ }
+
+ if ($this->setupCardDAV || $this->setupCalDAV) {
+ $this->tree[] = new DAVACL\PrincipalCollection(
+ $this->principalBackend
+ );
+ }
+
+ }
+
+ function setUpBackends() {
+
+ if ($this->setupCalDAV && is_null($this->caldavBackend)) {
+ $this->caldavBackend = new CalDAV\Backend\Mock($this->caldavCalendars, $this->caldavCalendarObjects);
+ }
+ if ($this->setupCardDAV && is_null($this->carddavBackend)) {
+ $this->carddavBackend = new CardDAV\Backend\Mock($this->carddavAddressBooks, $this->carddavCards);
+ }
+ if ($this->setupCardDAV || $this->setupCalDAV) {
+ $this->principalBackend = new DAVACL\PrincipalBackend\Mock();
+ }
+
+ }
+
+
+ function assertHTTPStatus($expectedStatus, HTTP\Request $req) {
+
+ $resp = $this->request($req);
+ $this->assertEquals($resp->getStatusMessage($expectedStatus), $resp->status,'Incorrect HTTP status received: ' . $resp->body);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/AWSAuthTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/AWSAuthTest.php
new file mode 100644
index 000000000..569ec2e7d
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/HTTP/AWSAuthTest.php
@@ -0,0 +1,242 @@
+<?php
+
+namespace Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class AWSAuthTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\HTTP\ResponseMock
+ */
+ private $response;
+ /**
+ * @var Sabre\HTTP\AWSAuth
+ */
+ private $auth;
+
+ const REALM = 'SabreDAV unittest';
+
+ public function setUp() {
+
+ $this->response = new ResponseMock();
+ $this->auth = new AWSAuth();
+ $this->auth->setRealm(self::REALM);
+ $this->auth->setHTTPResponse($this->response);
+
+ }
+
+ public function testNoHeader() {
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'GET',
+ ));
+
+ $this->auth->setHTTPRequest($request);
+
+ $result = $this->auth->init();
+
+ $this->assertFalse($result,'No AWS Authorization header was supplied, so we should have gotten false');
+ $this->assertEquals(AWSAuth::ERR_NOAWSHEADER,$this->auth->errorCode);
+
+ }
+
+ public function testIncorrectContentMD5() {
+
+ $accessKey = 'accessKey';
+ $secretKey = 'secretKey';
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_AUTHORIZATION' => "AWS $accessKey:sig",
+ 'HTTP_CONTENT_MD5' => 'garbage',
+ 'REQUEST_URI' => '/',
+ ));
+
+ $this->auth->setHTTPRequest($request);
+ $this->auth->init();
+ $result = $this->auth->validate($secretKey);
+
+ $this->assertFalse($result);
+ $this->assertEquals(AWSAuth::ERR_MD5CHECKSUMWRONG,$this->auth->errorCode);
+
+ }
+
+ public function testNoDate() {
+
+ $accessKey = 'accessKey';
+ $secretKey = 'secretKey';
+ $content = 'thisisthebody';
+ $contentMD5 = base64_encode(md5($content,true));
+
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'HTTP_AUTHORIZATION' => "AWS $accessKey:sig",
+ 'HTTP_CONTENT_MD5' => $contentMD5,
+ ));
+
+ $request->setBody($content);
+
+ $this->auth->setHTTPRequest($request);
+ $this->auth->init();
+ $result = $this->auth->validate($secretKey);
+
+ $this->assertFalse($result);
+ $this->assertEquals(AWSAuth::ERR_INVALIDDATEFORMAT,$this->auth->errorCode);
+
+ }
+
+ public function testFutureDate() {
+
+ $accessKey = 'accessKey';
+ $secretKey = 'secretKey';
+ $content = 'thisisthebody';
+ $contentMD5 = base64_encode(md5($content,true));
+
+ $date = new \DateTime('@' . (time() + (60*20)));
+ $date->setTimeZone(new \DateTimeZone('GMT'));
+ $date = $date->format('D, d M Y H:i:s \\G\\M\\T');
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'HTTP_AUTHORIZATION' => "AWS $accessKey:sig",
+ 'HTTP_CONTENT_MD5' => $contentMD5,
+ 'HTTP_DATE' => $date,
+ ));
+
+ $request->setBody($content);
+
+ $this->auth->setHTTPRequest($request);
+ $this->auth->init();
+ $result = $this->auth->validate($secretKey);
+
+ $this->assertFalse($result);
+ $this->assertEquals(AWSAuth::ERR_REQUESTTIMESKEWED,$this->auth->errorCode);
+
+ }
+
+ public function testPastDate() {
+
+ $accessKey = 'accessKey';
+ $secretKey = 'secretKey';
+ $content = 'thisisthebody';
+ $contentMD5 = base64_encode(md5($content,true));
+
+ $date = new \DateTime('@' . (time() - (60*20)));
+ $date->setTimeZone(new \DateTimeZone('GMT'));
+ $date = $date->format('D, d M Y H:i:s \\G\\M\\T');
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'HTTP_AUTHORIZATION' => "AWS $accessKey:sig",
+ 'HTTP_CONTENT_MD5' => $contentMD5,
+ 'HTTP_X_AMZ_DATE' => $date,
+ ));
+
+ $request->setBody($content);
+
+ $this->auth->setHTTPRequest($request);
+ $this->auth->init();
+ $result = $this->auth->validate($secretKey);
+
+ $this->assertFalse($result);
+ $this->assertEquals(AWSAuth::ERR_REQUESTTIMESKEWED,$this->auth->errorCode);
+
+ }
+
+ public function testIncorrectSignature() {
+
+ $accessKey = 'accessKey';
+ $secretKey = 'secretKey';
+ $content = 'thisisthebody';
+
+ $contentMD5 = base64_encode(md5($content,true));
+
+ $date = new \DateTime('now');
+ $date->setTimeZone(new \DateTimeZone('GMT'));
+ $date = $date->format('D, d M Y H:i:s \\G\\M\\T');
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'HTTP_AUTHORIZATION' => "AWS $accessKey:sig",
+ 'HTTP_CONTENT_MD5' => $contentMD5,
+ 'HTTP_X_AMZ_DATE' => $date,
+ 'REQUEST_URI' => '/',
+ ));
+
+ $request->setBody($content);
+
+ $this->auth->setHTTPRequest($request);
+ $this->auth->init();
+ $result = $this->auth->validate($secretKey);
+
+ $this->assertFalse($result);
+ $this->assertEquals(AWSAuth::ERR_INVALIDSIGNATURE,$this->auth->errorCode);
+
+ }
+
+ public function testValidRequest() {
+
+ $accessKey = 'accessKey';
+ $secretKey = 'secretKey';
+ $content = 'thisisthebody';
+ $contentMD5 = base64_encode(md5($content,true));
+
+ $date = new \DateTime('now');
+ $date->setTimeZone(new \DateTimeZone('GMT'));
+ $date = $date->format('D, d M Y H:i:s \\G\\M\\T');
+
+
+ $sig = base64_encode($this->hmacsha1($secretKey,
+ "POST\n$contentMD5\n\n$date\nx-amz-date:$date\n/evert"
+ ));
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'HTTP_AUTHORIZATION' => "AWS $accessKey:$sig",
+ 'HTTP_CONTENT_MD5' => $contentMD5,
+ 'HTTP_X_AMZ_DATE' => $date,
+ 'REQUEST_URI' => '/evert',
+ ));
+
+ $request->setBody($content);
+
+ $this->auth->setHTTPRequest($request);
+ $this->auth->init();
+ $result = $this->auth->validate($secretKey);
+
+ $this->assertTrue($result,'Signature did not validate, got errorcode ' . $this->auth->errorCode);
+ $this->assertEquals($accessKey,$this->auth->getAccessKey());
+
+ }
+
+ public function test401() {
+
+ $this->auth->requireLogin();
+ $test = preg_match('/^AWS$/',$this->response->headers['WWW-Authenticate'],$matches);
+ $this->assertTrue($test==true,'The WWW-Authenticate response didn\'t match our pattern');
+
+ }
+
+ /**
+ * Generates an HMAC-SHA1 signature
+ *
+ * @param string $key
+ * @param string $message
+ * @return string
+ */
+ private function hmacsha1($key, $message) {
+
+ $blocksize=64;
+ if (strlen($key)>$blocksize)
+ $key=pack('H*', sha1($key));
+ $key=str_pad($key,$blocksize,chr(0x00));
+ $ipad=str_repeat(chr(0x36),$blocksize);
+ $opad=str_repeat(chr(0x5c),$blocksize);
+ $hmac = pack('H*',sha1(($key^$opad).pack('H*',sha1(($key^$ipad).$message))));
+ return $hmac;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/BasicAuthTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/BasicAuthTest.php
new file mode 100644
index 000000000..77c5c7179
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/HTTP/BasicAuthTest.php
@@ -0,0 +1,132 @@
+<?php
+
+namespace Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class BasicAuthTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\HTTP\ResponseMock
+ */
+ private $response;
+ /**
+ * @var Sabre\HTTP\BasicAuth
+ */
+ private $basicAuth;
+
+ function setUp() {
+
+ $this->response = new ResponseMock();
+ $this->basicAuth = new BasicAuth();
+ $this->basicAuth->setHTTPResponse($this->response);
+
+ }
+
+ function testGetUserPassApache() {
+
+ $server = array(
+ 'PHP_AUTH_USER' => 'admin',
+ 'PHP_AUTH_PW' => '1234',
+ );
+
+ $request = new Request($server);
+ $this->basicAuth->setHTTPRequest($request);
+
+ $userPass = $this->basicAuth->getUserPass();
+
+ $this->assertEquals(
+ array('admin','1234'),
+ $userPass,
+ 'We did not get the username and password we expected'
+ );
+
+ }
+
+ function testGetUserPassIIS() {
+
+ $server = array(
+ 'HTTP_AUTHORIZATION' => 'Basic ' . base64_encode('admin:1234'),
+ );
+
+ $request = new Request($server);
+ $this->basicAuth->setHTTPRequest($request);
+
+ $userPass = $this->basicAuth->getUserPass();
+
+ $this->assertEquals(
+ array('admin','1234'),
+ $userPass,
+ 'We did not get the username and password we expected'
+ );
+
+ }
+
+ function testGetUserPassWithColon() {
+
+ $server = array(
+ 'HTTP_AUTHORIZATION' => 'Basic ' . base64_encode('admin:1234:5678'),
+ );
+
+ $request = new Request($server);
+ $this->basicAuth->setHTTPRequest($request);
+
+ $userPass = $this->basicAuth->getUserPass();
+
+ $this->assertEquals(
+ array('admin','1234:5678'),
+ $userPass,
+ 'We did not get the username and password we expected'
+ );
+
+ }
+
+ function testGetUserPassApacheEdgeCase() {
+
+ $server = array(
+ 'REDIRECT_HTTP_AUTHORIZATION' => 'Basic ' . base64_encode('admin:1234'),
+ );
+
+ $request = new Request($server);
+ $this->basicAuth->setHTTPRequest($request);
+
+ $userPass = $this->basicAuth->getUserPass();
+
+ $this->assertEquals(
+ array('admin','1234'),
+ $userPass,
+ 'We did not get the username and password we expected'
+ );
+
+ }
+
+ function testGetUserPassNothing() {
+
+ $this->assertEquals(
+ false,
+ $this->basicAuth->getUserPass()
+ );
+
+ }
+
+ function testRequireLogin() {
+
+ $this->basicAuth->requireLogin();
+ $this->assertEquals('SabreDAV',$this->basicAuth->getRealm());
+ $this->assertEquals(
+ 'HTTP/1.1 401 Unauthorized',
+ $this->response->status,
+ 'We expected a 401 status to be set'
+ );
+
+ $this->assertEquals(
+ 'Basic realm="SabreDAV"',
+ $this->response->headers['WWW-Authenticate'],
+ 'The WWW-Autenticate header was not set!'
+ );
+
+
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/DigestAuthTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/DigestAuthTest.php
new file mode 100644
index 000000000..576a00d4a
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/HTTP/DigestAuthTest.php
@@ -0,0 +1,228 @@
+<?php
+
+namespace Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class DigestAuthTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\HTTP\ResponseMock
+ */
+ private $response;
+ /**
+ * @var Sabre\HTTP\DigestAuth
+ */
+ private $auth;
+
+ const REALM = 'SabreDAV unittest';
+
+ public function setUp() {
+
+ $this->response = new ResponseMock();
+ $this->auth = new DigestAuth();
+ $this->auth->setRealm(self::REALM);
+ $this->auth->setHTTPResponse($this->response);
+
+ }
+
+ public function testDigest() {
+
+ list($nonce,$opaque) = $this->getServerTokens();
+
+ $username = 'admin';
+ $password = 12345;
+ $nc = '00002';
+ $cnonce = uniqid();
+
+ $digestHash = md5(
+ md5($username . ':' . self::REALM . ':' . $password) . ':' .
+ $nonce . ':' .
+ $nc . ':' .
+ $cnonce . ':' .
+ 'auth:' .
+ md5('GET' . ':' . '/')
+ );
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'GET',
+ 'PHP_AUTH_DIGEST' => 'username="'.$username.'", realm="' . self::REALM . '", nonce="' . $nonce . '", uri="/", response="' . $digestHash . '", opaque="' . $opaque . '", qop=auth,nc='.$nc.',cnonce="' . $cnonce . '"',
+ ));
+
+ $this->auth->setHTTPRequest($request);
+ $this->auth->init();
+
+ $this->assertEquals($username,$this->auth->getUserName());
+ $this->assertEquals(self::REALM,$this->auth->getRealm());
+ $this->assertTrue($this->auth->validateA1(md5($username . ':' . self::REALM . ':' . $password)),'Authentication is deemed invalid through validateA1');
+ $this->assertTrue($this->auth->validatePassword($password),'Authentication is deemed invalid through validatePassword');
+
+ }
+
+ public function testDigestCGIFormat() {
+
+ list($nonce,$opaque) = $this->getServerTokens();
+
+ $username = 'admin';
+ $password = 12345;
+ $nc = '00002';
+ $cnonce = uniqid();
+
+ $digestHash = md5(
+ md5($username . ':' . self::REALM . ':' . $password) . ':' .
+ $nonce . ':' .
+ $nc . ':' .
+ $cnonce . ':' .
+ 'auth:' .
+ md5('GET' . ':' . '/')
+ );
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_AUTHORIZATION' => 'Digest username="'.$username.'", realm="' . self::REALM . '", nonce="' . $nonce . '", uri="/", response="' . $digestHash . '", opaque="' . $opaque . '", qop=auth,nc='.$nc.',cnonce="' . $cnonce . '"',
+ ));
+
+ $this->auth->setHTTPRequest($request);
+ $this->auth->init();
+
+ $this->assertTrue($this->auth->validateA1(md5($username . ':' . self::REALM . ':' . $password)),'Authentication is deemed invalid through validateA1');
+ $this->assertTrue($this->auth->validatePassword($password),'Authentication is deemed invalid through validatePassword');
+
+ }
+
+ public function testDigestApacheEdgeCase() {
+
+ list($nonce,$opaque) = $this->getServerTokens();
+
+ $username = 'admin';
+ $password = 12345;
+ $nc = '00002';
+ $cnonce = uniqid();
+
+ $digestHash = md5(
+ md5($username . ':' . self::REALM . ':' . $password) . ':' .
+ $nonce . ':' .
+ $nc . ':' .
+ $cnonce . ':' .
+ 'auth:' .
+ md5('GET' . ':' . '/')
+ );
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'GET',
+ 'REDIRECT_HTTP_AUTHORIZATION' => 'Digest username="'.$username.'", realm="' . self::REALM . '", nonce="' . $nonce . '", uri="/", response="' . $digestHash . '", opaque="' . $opaque . '", qop=auth,nc='.$nc.',cnonce="' . $cnonce . '"',
+ ));
+
+ $this->auth->setHTTPRequest($request);
+ $this->auth->init();
+
+ $this->assertTrue($this->auth->validateA1(md5($username . ':' . self::REALM . ':' . $password)),'Authentication is deemed invalid through validateA1');
+ $this->assertTrue($this->auth->validatePassword($password),'Authentication is deemed invalid through validatePassword');
+
+ }
+
+ public function testInvalidDigest() {
+
+ list($nonce,$opaque) = $this->getServerTokens();
+
+ $username = 'admin';
+ $password = 12345;
+ $nc = '00002';
+ $cnonce = uniqid();
+
+ $digestHash = md5(
+ md5($username . ':' . self::REALM . ':' . $password) . ':' .
+ $nonce . ':' .
+ $nc . ':' .
+ $cnonce . ':' .
+ 'auth:' .
+ md5('GET' . ':' . '/')
+ );
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'GET',
+ 'PHP_AUTH_DIGEST' => 'username="'.$username.'", realm="' . self::REALM . '", nonce="' . $nonce . '", uri="/", response="' . $digestHash . '", opaque="' . $opaque . '", qop=auth,nc='.$nc.',cnonce="' . $cnonce . '"',
+ ));
+
+ $this->auth->setHTTPRequest($request);
+ $this->auth->init();
+
+ $this->assertFalse($this->auth->validateA1(md5($username . ':' . self::REALM . ':' . ($password . 'randomness'))),'Authentication is deemed invalid through validateA1');
+
+ }
+
+ public function testInvalidDigest2() {
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_AUTHORIZATION' => 'basic blablabla',
+ ));
+
+ $this->auth->setHTTPRequest($request);
+ $this->auth->init();
+
+ $this->assertFalse($this->auth->validateA1(md5('user:realm:password')));
+
+ }
+
+
+ public function testDigestAuthInt() {
+
+ $this->auth->setQOP(DigestAuth::QOP_AUTHINT | DigestAuth::QOP_AUTH);
+ list($nonce,$opaque) = $this->getServerTokens(DigestAuth::QOP_AUTHINT| DigestAuth::QOP_AUTH);
+
+ $username = 'admin';
+ $password = 12345;
+ $nc = '00003';
+ $cnonce = uniqid();
+
+ $digestHash = md5(
+ md5($username . ':' . self::REALM . ':' . $password) . ':' .
+ $nonce . ':' .
+ $nc . ':' .
+ $cnonce . ':' .
+ 'auth-int:' .
+ md5('POST' . ':' . '/' . ':' . md5('body'))
+ );
+
+ $request = new Request(array(
+ 'REQUEST_METHOD' => 'POST',
+ 'PHP_AUTH_DIGEST' => 'username="'.$username.'", realm="' . self::REALM . '", nonce="' . $nonce . '", uri="/", response="' . $digestHash . '", opaque="' . $opaque . '", qop=auth-int,nc='.$nc.',cnonce="' . $cnonce . '"',
+ ));
+ $request->setBody('body');
+
+ $this->auth->setHTTPRequest($request);
+
+ $this->auth->init();
+
+ $this->assertTrue($this->auth->validateA1(md5($username . ':' . self::REALM . ':' . $password)),'Authentication is deemed invalid through validateA1');
+
+ }
+
+ private function getServerTokens($qop = DigestAuth::QOP_AUTH) {
+
+ $this->auth->requireLogin();
+
+ switch($qop) {
+ case DigestAuth::QOP_AUTH : $qopstr='auth'; break;
+ case DigestAuth::QOP_AUTHINT : $qopstr='auth-int'; break;
+ default : $qopstr='auth,auth-int'; break;
+ }
+
+ $test = preg_match('/Digest realm="'.self::REALM.'",qop="'.$qopstr.'",nonce="([0-9a-f]*)",opaque="([0-9a-f]*)"/',
+ $this->response->headers['WWW-Authenticate'],$matches);
+
+ $this->assertTrue($test==true,'The WWW-Authenticate response didn\'t match our pattern. We received: ' . $this->response->headers['WWW-Authenticate']);
+
+ $nonce = $matches[1];
+ $opaque = $matches[2];
+
+ // Reset our environment
+ $this->setUp();
+ $this->auth->setQOP($qop);
+
+ return array($nonce,$opaque);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/RequestTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/RequestTest.php
new file mode 100644
index 000000000..c52ce351d
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/HTTP/RequestTest.php
@@ -0,0 +1,150 @@
+<?php
+
+namespace Sabre\HTTP;
+
+/**
+ * @covers Sabre\HTTP\Request
+ */
+class RequestTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\HTTP\Request
+ */
+ private $request;
+
+ function setUp() {
+
+ $server = array(
+ 'HTTP_HOST' => 'www.example.org',
+ 'REQUEST_METHOD' => 'PUT',
+ 'REQUEST_URI' => '/testuri/',
+ 'CONTENT_TYPE' => 'text/xml',
+ );
+
+ $this->request = new Request($server);
+
+ }
+
+ function testGetHeader() {
+
+ $this->assertEquals('www.example.org', $this->request->getHeader('Host'));
+ $this->assertEquals('text/xml', $this->request->getHeader('Content-Type'));
+
+ }
+
+ function testGetNonExistantHeader() {
+
+ $this->assertNull($this->request->getHeader('doesntexist'));
+ $this->assertNull($this->request->getHeader('Content-Length'));
+
+ }
+
+ function testGetHeaders() {
+
+ $expected = array(
+ 'host' => 'www.example.org',
+ 'content-type' => 'text/xml',
+ );
+
+ $this->assertEquals($expected, $this->request->getHeaders());
+
+ }
+
+ function testGetMethod() {
+
+ $this->assertEquals('PUT', $this->request->getMethod(), 'It seems as if we didn\'t get a valid HTTP Request method back');
+
+ }
+
+ function testGetUri() {
+
+ $this->assertEquals('/testuri/', $this->request->getUri(), 'We got an invalid uri back');
+
+ }
+
+ function testSetGetBody() {
+
+ $h = fopen('php://memory','r+');
+ fwrite($h,'testing');
+ rewind($h);
+ $this->request->setBody($h);
+ $this->assertEquals('testing',$this->request->getBody(true),'We didn\'t get our testbody back');
+
+ }
+
+ function testSetGetBodyStream() {
+
+ $h = fopen('php://memory','r+');
+ fwrite($h,'testing');
+ rewind($h);
+ $this->request->setBody($h);
+ $this->assertEquals('testing',stream_get_contents($this->request->getBody()),'We didn\'t get our testbody back');
+
+ }
+
+
+ function testDefaultInputStream() {
+
+ $h = fopen('php://memory','r+');
+ fwrite($h,'testing');
+ rewind($h);
+
+ $previousValue = Request::$defaultInputStream;
+ Request::$defaultInputStream = $h;
+
+ $this->assertEquals('testing',$this->request->getBody(true),'We didn\'t get our testbody back');
+ Request::$defaultInputStream = $previousValue;
+
+ }
+
+ function testGetAbsoluteUri() {
+
+ $s = array(
+ 'HTTP_HOST' => 'sabredav.org',
+ 'REQUEST_URI' => '/foo'
+ );
+
+ $r = new Request($s);
+
+ $this->assertEquals('http://sabredav.org/foo', $r->getAbsoluteUri());
+
+ $s = array(
+ 'HTTP_HOST' => 'sabredav.org',
+ 'REQUEST_URI' => '/foo',
+ 'HTTPS' => 'on',
+ );
+
+ $r = new Request($s);
+
+ $this->assertEquals('https://sabredav.org/foo', $r->getAbsoluteUri());
+
+ }
+
+ function testGetQueryString() {
+
+ $s = array(
+ 'QUERY_STRING' => 'bla',
+ );
+
+ $r = new Request($s);
+ $this->assertEquals('bla', $r->getQueryString());
+
+ $s = array();
+
+ $r = new Request($s);
+ $this->assertEquals('', $r->getQueryString());
+
+ }
+
+ function testGetPostVars() {
+
+ $post = array(
+ 'bla' => 'foo',
+ );
+ $r = new Request(array(),$post);
+ $this->assertEquals($post, $r->getPostVars('bla'));
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php b/vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php
new file mode 100644
index 000000000..16c034099
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Sabre\HTTP;
+
+class ResponseMock extends Response {
+
+ public $headers = array();
+ public $status = '';
+ public $body = '';
+
+ function setHeader($name,$value,$overwrite = true) {
+
+ $this->headers[$name] = $value;
+
+ }
+
+ function sendStatus($code) {
+
+ $this->status = $this->getStatusMessage($code, $this->defaultHttpVersion);
+
+ }
+
+ function sendBody($body) {
+
+ $this->body = $body;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/ResponseTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/ResponseTest.php
new file mode 100644
index 000000000..f5302c993
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/HTTP/ResponseTest.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace Sabre\HTTP;
+
+require_once 'Sabre/HTTP/ResponseMock.php';
+
+class ResponseTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @var Sabre\HTTP\ResponseMock
+ */
+ private $response;
+
+ function setUp() {
+
+ $this->response = new ResponseMock();
+
+ }
+
+ function testGetStatusMessage() {
+
+ $msg = $this->response->getStatusMessage(200);
+ $this->assertEquals('HTTP/1.1 200 OK',$msg);
+
+ }
+
+ function testSetHeader() {
+
+ $this->response->setHeader('Content-Type','text/html');
+ $this->assertEquals('text/html', $this->response->headers['Content-Type']);
+
+
+ }
+ function testSetHeaders() {
+
+ $this->response->setHeaders(array('Content-Type'=>'text/html'));
+ $this->assertEquals('text/html', $this->response->headers['Content-Type']);
+
+
+ }
+
+ function testSendStatus() {
+
+ $this->response->sendStatus(404);
+ $this->assertEquals('HTTP/1.1 404 Not Found', $this->response->status);
+
+ }
+
+ function testSendBody() {
+
+ ob_start();
+ $response = new Response();
+ $response->sendBody('hello');
+ $this->assertEquals('hello',ob_get_clean());
+
+ }
+
+ function testSendBodyStream() {
+
+ ob_start();
+ $stream = fopen('php://memory','r+');
+ fwrite($stream,'hello');
+ rewind($stream);
+ $response = new Response();
+ $response->sendBody($stream);
+ $this->assertEquals('hello',ob_get_clean());
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/UtilTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/UtilTest.php
new file mode 100644
index 000000000..47a7b98bd
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/HTTP/UtilTest.php
@@ -0,0 +1,78 @@
+<?php
+
+namespace Sabre\HTTP;
+
+class UtilTest extends \PHPUnit_Framework_TestCase {
+
+ function testParseHTTPDate() {
+
+ $times = array(
+ 'Wed, 13 Oct 2010 10:26:00 GMT',
+ 'Wednesday, 13-Oct-10 10:26:00 GMT',
+ 'Wed Oct 13 10:26:00 2010',
+ );
+
+ $expected = 1286965560;
+
+ foreach($times as $time) {
+ $result = Util::parseHTTPDate($time);
+ $this->assertEquals($expected, $result->format('U'));
+ }
+
+ $result = Util::parseHTTPDate('Wed Oct 6 10:26:00 2010');
+ $this->assertEquals(1286360760, $result->format('U'));
+
+ }
+
+ function testParseHTTPDateFail() {
+
+ $times = array(
+ //random string
+ 'NOW',
+ // not-GMT timezone
+ 'Wednesday, 13-Oct-10 10:26:00 UTC',
+ // No space before the 6
+ 'Wed Oct 6 10:26:00 2010',
+ );
+
+ foreach($times as $time) {
+ $this->assertFalse(Util::parseHTTPDate($time), 'We used the string: ' . $time);
+ }
+
+ }
+
+ function testTimezones() {
+
+ $default = date_default_timezone_get();
+ date_default_timezone_set('Europe/Amsterdam');
+
+ $this->testParseHTTPDate();
+
+ date_default_timezone_set($default);
+
+ }
+
+ function testToHTTPDate() {
+
+ $dt = new \DateTime('2011-12-10 12:00:00 +0200');
+
+ $this->assertEquals(
+ 'Sat, 10 Dec 2011 10:00:00 GMT',
+ Util::toHTTPDate($dt)
+ );
+
+ }
+
+ function testStrtotimeFail() {
+
+ // Strtotime may return -1 when the date cannot be parsed.
+ // We are simulating this situation by testing a date that actually
+ // results in -1. (because I have found no other way to break this
+ // code)
+
+ $time = 'Wed, 13 Oct 1960 10:26:00 GMT';
+
+ $this->assertNull(Util::parseHTTPDate($time));
+
+ }
+}
diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/VersionTest.php b/vendor/sabre/dav/tests/Sabre/HTTP/VersionTest.php
new file mode 100644
index 000000000..c7094b3bc
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/HTTP/VersionTest.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace Sabre\HTTP;
+
+class VersionTest extends \PHPUnit_Framework_TestCase {
+
+ function testString() {
+
+ $v = Version::VERSION;
+ $this->assertEquals(-1, version_compare('1.0.0',$v));
+
+ $s = Version::STABILITY;
+ $this->assertTrue($s == 'alpha' || $s == 'beta' || $s =='stable');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/TestUtil.php b/vendor/sabre/dav/tests/Sabre/TestUtil.php
new file mode 100644
index 000000000..5a9062498
--- /dev/null
+++ b/vendor/sabre/dav/tests/Sabre/TestUtil.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Sabre;
+
+class TestUtil {
+
+ /**
+ * This function deletes all the contents of the temporary directory.
+ *
+ * @return void
+ */
+ static function clearTempDir() {
+
+ self::deleteTree(SABRE_TEMPDIR,false);
+
+ }
+
+
+ static private function deleteTree($path,$deleteRoot = true) {
+
+ foreach(scandir($path) as $node) {
+
+ if ($node=='.' || $node=='..') continue;
+ $myPath = $path.'/'. $node;
+ if (is_file($myPath)) {
+ unlink($myPath);
+ } else {
+ self::deleteTree($myPath);
+ }
+
+ }
+ if ($deleteRoot) {
+ rmdir($path);
+ }
+
+ }
+
+ static function getMySQLDB() {
+
+ try {
+ $pdo = new \PDO(SABRE_MYSQLDSN,SABRE_MYSQLUSER,SABRE_MYSQLPASS);
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
+ return $pdo;
+ } catch (\PDOException $e) {
+ return null;
+ }
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/tests/bootstrap.php b/vendor/sabre/dav/tests/bootstrap.php
new file mode 100644
index 000000000..c3be7366c
--- /dev/null
+++ b/vendor/sabre/dav/tests/bootstrap.php
@@ -0,0 +1,22 @@
+<?php
+
+define('SABRE_MYSQLDSN','mysql:host=127.0.0.1;dbname=sabredav');
+define('SABRE_MYSQLUSER','root');
+define('SABRE_MYSQLPASS','');
+
+set_include_path(__DIR__ . '/../lib/' . PATH_SEPARATOR . __DIR__ . PATH_SEPARATOR . get_include_path());
+
+include __DIR__ . '/../vendor/autoload.php';
+include 'Sabre/DAVServerTest.php';
+
+date_default_timezone_set('GMT');
+
+define("SABRE_TEMPDIR",dirname(__FILE__) . '/temp/');
+
+// If sqlite is not available, this constant is used to skip the relevant
+// tests
+define('SABRE_HASSQLITE',in_array('sqlite',PDO::getAvailableDrivers()));
+define('SABRE_HASMYSQL', in_array('mysql',PDO::getAvailableDrivers()) && defined('SABRE_MYSQLDSN') && defined('SABRE_MYSQLUSER') && defined('SABRE_MYSQLPASS'));
+
+if (!file_exists(SABRE_TEMPDIR)) mkdir(SABRE_TEMPDIR);
+if (file_exists('.sabredav')) unlink('.sabredav');
diff --git a/vendor/sabre/dav/tests/phpunit.xml b/vendor/sabre/dav/tests/phpunit.xml
new file mode 100644
index 000000000..e93933049
--- /dev/null
+++ b/vendor/sabre/dav/tests/phpunit.xml
@@ -0,0 +1,29 @@
+<phpunit
+ colors="true"
+ bootstrap="bootstrap.php"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ >
+ <testsuite name="sabre-dav">
+ <directory>Sabre/</directory>
+ </testsuite>
+ <testsuite name="sabre-vobject">
+ <directory>../vendor/sabre/vobject/tests/Sabre/VObject</directory>
+ </testsuite>
+
+ <filter>
+ <whitelist addUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">../lib/</directory>
+ <exclude>
+ <file>../lib/Sabre/autoload.php</file>
+ <file>../lib/Sabre/CalDAV/includes.php</file>
+ <file>../lib/Sabre/CardDAV/includes.php</file>
+ <file>../lib/Sabre/DAVACL/includes.php</file>
+ <file>../lib/Sabre/HTTP/includes.php</file>
+ <file>../lib/Sabre/DAV/includes.php</file>
+ <file>../lib/Sabre/VObject/includes.php</file>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>