diff options
author | Richard Steinmetz <richard@steinmetz.cloud> | 2024-02-21 22:29:09 +0100 |
---|---|---|
committer | Richard Steinmetz <richard@steinmetz.cloud> | 2024-02-28 14:51:10 +0100 |
commit | 53ef6c5f712bf910c2c976e1a1b6eb142349b5c2 (patch) | |
tree | 52887c3bf3971a86ad15bdf4d7284b476a6e4fe0 /build | |
parent | 7cc20468f13cddb433a35a58e048ce8c4ce43f1d (diff) | |
download | nextcloud-server-53ef6c5f712bf910c2c976e1a1b6eb142349b5c2.tar.gz nextcloud-server-53ef6c5f712bf910c2c976e1a1b6eb142349b5c2.zip |
feat(dav): update a principal's schedule-default-calendar-URL
Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
Diffstat (limited to 'build')
-rw-r--r-- | build/integration/dav_features/caldav.feature | 10 | ||||
-rw-r--r-- | build/integration/features/bootstrap/CalDavContext.php | 149 |
2 files changed, 159 insertions, 0 deletions
diff --git a/build/integration/dav_features/caldav.feature b/build/integration/dav_features/caldav.feature index fffdd89d367..f7baf76d4bc 100644 --- a/build/integration/dav_features/caldav.feature +++ b/build/integration/dav_features/caldav.feature @@ -75,3 +75,13 @@ Feature: caldav Then The CalDAV HTTP status code should be "404" And The exception is "Sabre\DAV\Exception\NotFound" And The error message is "Node with name 'admin' could not be found" + + Scenario: Update a principal's schedule-default-calendar-URL + Given user "user0" exists + And "user0" creates a calendar named "MyCalendar2" + When "user0" updates property "{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL" to href "/remote.php/dav/calendars/user0/MyCalendar2/" of principal "users/user0" on the endpoint "/remote.php/dav/principals/" + Then The CalDAV response should be multi status + And The CalDAV response should contain a property "{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL" + When "user0" requests principal "users/user0" on the endpoint "/remote.php/dav/principals/" + Then The CalDAV response should be multi status + And The CalDAV response should contain a property "{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL" with a href value "/remote.php/dav/calendars/user0/MyCalendar2/" diff --git a/build/integration/features/bootstrap/CalDavContext.php b/build/integration/features/bootstrap/CalDavContext.php index 936463b579e..bad0d915491 100644 --- a/build/integration/features/bootstrap/CalDavContext.php +++ b/build/integration/features/bootstrap/CalDavContext.php @@ -8,6 +8,7 @@ * @author Lukas Reschke <lukas@statuscode.ch> * @author Phil Davis <phil.davis@inf.org> * @author Robin Appelman <robin@icewind.nl> + * @author Richard Steinmetz <richard@steinmetz.cloud> * * @license AGPL-3.0 * @@ -106,6 +107,119 @@ class CalDavContext implements \Behat\Behat\Context\Context { } /** + * @When :user requests principal :principal on the endpoint :endpoint + */ + public function requestsPrincipal(string $user, string $principal, string $endpoint): void { + $davUrl = $this->baseUrl . $endpoint . $principal; + + $password = ($user === 'admin') ? 'admin' : '123456'; + try { + $this->response = $this->client->request( + 'PROPFIND', + $davUrl, + [ + 'headers' => [ + 'Content-Type' => 'application/xml; charset=UTF-8', + 'Depth' => 0, + ], + 'body' => '<x0:propfind xmlns:x0="DAV:"><x0:prop><x0:displayname/><x1:calendar-user-type xmlns:x1="urn:ietf:params:xml:ns:caldav"/><x1:calendar-user-address-set xmlns:x1="urn:ietf:params:xml:ns:caldav"/><x0:principal-URL/><x0:alternate-URI-set/><x2:email-address xmlns:x2="http://sabredav.org/ns"/><x3:language xmlns:x3="http://nextcloud.com/ns"/><x1:calendar-home-set xmlns:x1="urn:ietf:params:xml:ns:caldav"/><x1:schedule-inbox-URL xmlns:x1="urn:ietf:params:xml:ns:caldav"/><x1:schedule-outbox-URL xmlns:x1="urn:ietf:params:xml:ns:caldav"/><x1:schedule-default-calendar-URL xmlns:x1="urn:ietf:params:xml:ns:caldav"/><x3:resource-type xmlns:x3="http://nextcloud.com/ns"/><x3:resource-vehicle-type xmlns:x3="http://nextcloud.com/ns"/><x3:resource-vehicle-make xmlns:x3="http://nextcloud.com/ns"/><x3:resource-vehicle-model xmlns:x3="http://nextcloud.com/ns"/><x3:resource-vehicle-is-electric xmlns:x3="http://nextcloud.com/ns"/><x3:resource-vehicle-range xmlns:x3="http://nextcloud.com/ns"/><x3:resource-vehicle-seating-capacity xmlns:x3="http://nextcloud.com/ns"/><x3:resource-contact-person xmlns:x3="http://nextcloud.com/ns"/><x3:resource-contact-person-vcard xmlns:x3="http://nextcloud.com/ns"/><x3:room-type xmlns:x3="http://nextcloud.com/ns"/><x3:room-seating-capacity xmlns:x3="http://nextcloud.com/ns"/><x3:room-building-address xmlns:x3="http://nextcloud.com/ns"/><x3:room-building-story xmlns:x3="http://nextcloud.com/ns"/><x3:room-building-room-number xmlns:x3="http://nextcloud.com/ns"/><x3:room-features xmlns:x3="http://nextcloud.com/ns"/><x0:principal-collection-set/><x0:supported-report-set/></x0:prop></x0:propfind>', + 'auth' => [ + $user, + $password, + ], + ] + ); + } catch (\GuzzleHttp\Exception\ClientException $e) { + $this->response = $e->getResponse(); + } + } + + /** + * @Then The CalDAV response should contain a property :key + * @throws \Exception + */ + public function theCaldavResponseShouldContainAProperty(string $key): void { + /** @var \Sabre\DAV\Xml\Response\MultiStatus $multiStatus */ + $multiStatus = $this->responseXml['value']; + $responses = $multiStatus->getResponses()[0]->getResponseProperties(); + if (!isset($responses[200])) { + throw new \Exception( + sprintf( + 'Expected code 200 got [%s]', + implode(',', array_keys($responses)), + ) + ); + } + + $props = $responses[200]; + if (!array_key_exists($key, $props)) { + throw new \Exception( + sprintf( + 'Expected property %s in %s', + $key, + json_encode($props, JSON_PRETTY_PRINT), + ) + ); + } + } + + /** + * @Then The CalDAV response should contain a property :key with a href value :value + * @throws \Exception + */ + public function theCaldavResponseShouldContainAPropertyWithHrefValue( + string $key, + string $value, + ): void { + /** @var \Sabre\DAV\Xml\Response\MultiStatus $multiStatus */ + $multiStatus = $this->responseXml['value']; + $responses = $multiStatus->getResponses()[0]->getResponseProperties(); + if (!isset($responses[200])) { + throw new \Exception( + sprintf( + 'Expected code 200 got [%s]', + implode(',', array_keys($responses)), + ) + ); + } + + $props = $responses[200]; + if (!array_key_exists($key, $props)) { + throw new \Exception("Cannot find property \"$key\""); + } + + $actualValue = $props[$key]->getHref(); + if ($actualValue !== $value) { + throw new \Exception("Property \"$key\" found with value \"$actualValue\", expected \"$value\""); + } + } + + /** + * @Then The CalDAV response should be multi status + * @throws \Exception + */ + public function theCaldavResponseShouldBeMultiStatus(): void { + if (207 !== $this->response->getStatusCode()) { + throw new \Exception( + sprintf( + 'Expected code 207 got %s', + $this->response->getStatusCode() + ) + ); + } + + $body = $this->response->getBody()->getContents(); + if ($body && substr($body, 0, 1) === '<') { + $reader = new Sabre\Xml\Reader(); + $reader->xml($body); + $reader->elementMap['{DAV:}multistatus'] = \Sabre\DAV\Xml\Response\MultiStatus::class; + $reader->elementMap['{DAV:}response'] = \Sabre\DAV\Xml\Element\Response::class; + $reader->elementMap['{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL'] = \Sabre\DAV\Xml\Property\Href::class; + $this->responseXml = $reader->parse(); + } + } + + /** * @Then The CalDAV HTTP status code should be :code * @param int $code * @throws \Exception @@ -258,4 +372,39 @@ class CalDavContext implements \Behat\Behat\Context\Context { $this->response = $e->getResponse(); } } + + /** + * @Given :user updates property :key to href :value of principal :principal on the endpoint :endpoint + */ + public function updatesHrefPropertyOfPrincipal( + string $user, + string $key, + string $value, + string $principal, + string $endpoint, + ): void { + $davUrl = $this->baseUrl . $endpoint . $principal; + $password = ($user === 'admin') ? 'admin' : '123456'; + + $propPatch = new \Sabre\DAV\Xml\Request\PropPatch(); + $propPatch->properties = [$key => new \Sabre\DAV\Xml\Property\Href($value)]; + + $xml = new \Sabre\Xml\Service(); + $body = $xml->write('{DAV:}propertyupdate', $propPatch, '/'); + + $this->response = $this->client->request( + 'PROPPATCH', + $davUrl, + [ + 'headers' => [ + 'Content-Type' => 'application/xml; charset=UTF-8', + ], + 'body' => $body, + 'auth' => [ + $user, + $password, + ], + ] + ); + } } |