'principals/user1', 'uri' => 'cal', ], [ 'principaluri' => 'principals/user2', 'uri' => 'cal', ], ]; function setUp() { $this->calendarObjectUri = '/calendars/user1/cal/object.ics'; parent::setUp(); } function testNewInvite() { $newObject = <<deliver(null, $newObject); $this->assertItemsInInbox('user2', 1); $expected = <<assertVObjEquals( $expected, $newObject ); } function testNewOnWrongCollection() { $newObject = <<calendarObjectUri = '/calendars/user1/object.ics'; $this->deliver(null, $newObject); $this->assertItemsInInbox('user2', 0); } function testNewInviteSchedulingDisabled() { $newObject = <<deliver(null, $newObject, true); $this->assertItemsInInbox('user2', 0); } function testUpdatedInvite() { $newObject = <<deliver($oldObject, $newObject); $this->assertItemsInInbox('user2', 1); $expected = <<assertVObjEquals( $expected, $newObject ); } function testUpdatedInviteSchedulingDisabled() { $newObject = <<deliver($oldObject, $newObject, true); $this->assertItemsInInbox('user2', 0); } function testUpdatedInviteWrongPath() { $newObject = <<calendarObjectUri = '/calendars/user1/inbox/foo.ics'; $this->deliver($oldObject, $newObject); $this->assertItemsInInbox('user2', 0); } function testDeletedInvite() { $newObject = null; $oldObject = <<deliver($oldObject, $newObject); $this->assertItemsInInbox('user2', 1); } function testDeletedInviteSchedulingDisabled() { $newObject = null; $oldObject = <<deliver($oldObject, $newObject, true); $this->assertItemsInInbox('user2', 0); } /** * A MOVE request will trigger an unbind on a scheduling resource. * * However, we must not treat it as a cancellation, it just got moved to a * different calendar. */ function testUnbindIgnoredOnMove() { $newObject = null; $oldObject = <<server->httpRequest->setMethod('MOVE'); $this->deliver($oldObject, $newObject); $this->assertItemsInInbox('user2', 0); } function testDeletedInviteWrongUrl() { $newObject = null; $oldObject = <<calendarObjectUri = '/calendars/user1/inbox/foo.ics'; $this->deliver($oldObject, $newObject); $this->assertItemsInInbox('user2', 0); } function testReply() { $oldObject = <<putPath('calendars/user2/cal/foo.ics', $oldObject); $this->deliver($oldObject, $newObject); $this->assertItemsInInbox('user2', 1); $this->assertItemsInInbox('user1', 0); $expected = <<assertVObjEquals( $expected, $newObject ); } function testInviteUnknownUser() { $newObject = <<deliver(null, $newObject); $expected = <<assertVObjEquals( $expected, $newObject ); } function testInviteNoInboxUrl() { $newObject = <<server->on('propFind', function($propFind) { $propFind->set('{' . Plugin::NS_CALDAV . '}schedule-inbox-URL', null, 403); }); $this->deliver(null, $newObject); $expected = <<assertVObjEquals( $expected, $newObject ); } function testInviteNoCalendarHomeSet() { $newObject = <<server->on('propFind', function($propFind) { $propFind->set('{' . Plugin::NS_CALDAV . '}calendar-home-set', null, 403); }); $this->deliver(null, $newObject); $expected = <<assertVObjEquals( $expected, $newObject ); } function testInviteNoDefaultCalendar() { $newObject = <<server->on('propFind', function($propFind) { $propFind->set('{' . Plugin::NS_CALDAV . '}schedule-default-calendar-URL', null, 403); }); $this->deliver(null, $newObject); $expected = <<assertVObjEquals( $expected, $newObject ); } function testInviteNoScheduler() { $newObject = <<server->removeAllListeners('schedule'); $this->deliver(null, $newObject); $expected = <<assertVObjEquals( $expected, $newObject ); } function testInviteNoACLPlugin() { $this->setupACL = false; parent::setUp(); $newObject = <<deliver(null, $newObject); $expected = <<assertVObjEquals( $expected, $newObject ); } protected $calendarObjectUri; function deliver($oldObject, &$newObject, $disableScheduling = false) { $this->server->httpRequest->setUrl($this->calendarObjectUri); if ($disableScheduling) { $this->server->httpRequest->setHeader('Schedule-Reply','F'); } if ($oldObject && $newObject) { // update $this->putPath($this->calendarObjectUri, $oldObject); $stream = fopen('php://memory','r+'); fwrite($stream, $newObject); rewind($stream); $modified = false; $this->server->emit('beforeWriteContent', [ $this->calendarObjectUri, $this->server->tree->getNodeForPath($this->calendarObjectUri), &$stream, &$modified ]); if ($modified) { $newObject = $stream; } } elseif ($oldObject && !$newObject) { // delete $this->putPath($this->calendarObjectUri, $oldObject); $this->caldavSchedulePlugin->beforeUnbind( $this->calendarObjectUri ); } else { // create $stream = fopen('php://memory','r+'); fwrite($stream, $newObject); rewind($stream); $modified = false; $this->server->emit('beforeCreateFile', [ $this->calendarObjectUri, &$stream, $this->server->tree->getNodeForPath(dirname($this->calendarObjectUri)), &$modified ]); if ($modified) { $newObject = $stream; } } } /** * Creates or updates a node at the specified path. * * This circumvents sabredav's internal server apis, so all events and * access control is skipped. * * @param string $path * @param string $data * @return void */ function putPath($path, $data) { list($parent, $base) = \Sabre\HTTP\UrlUtil::splitPath($path); $parentNode = $this->server->tree->getNodeForPath($parent); /* if ($parentNode->childExists($base)) { $childNode = $parentNode->getChild($base); $childNode->put($data); } else {*/ $parentNode->createFile($base, $data); //} } function assertItemsInInbox($user, $count) { $inboxNode = $this->server->tree->getNodeForPath('calendars/'.$user.'/inbox'); $this->assertEquals($count, count($inboxNode->getChildren())); } function assertVObjEquals($expected, $actual) { $format = function($data) { $data = trim($data, "\r\n"); $data = str_replace("\r","", $data); // Unfolding lines. $data = str_replace("\n ", "", $data); return $data; }; $this->assertEquals( $format($expected), $format($actual) ); } }