From 158cede97f16f0f8e6fcf4169fd1b3dfa54c2033 Mon Sep 17 00:00:00 2001 From: Saw-jan Date: Fri, 4 Oct 2024 16:35:55 +0545 Subject: [PATCH 1/2] test: check file-parent id in shares propfind --- tests/acceptance/bootstrap/SpacesContext.php | 78 ++++++++++++++++--- .../apiSharingNg1/propfindShares.feature | 19 +++-- 2 files changed, 82 insertions(+), 15 deletions(-) diff --git a/tests/acceptance/bootstrap/SpacesContext.php b/tests/acceptance/bootstrap/SpacesContext.php index f83643cdf..ffca88577 100644 --- a/tests/acceptance/bootstrap/SpacesContext.php +++ b/tests/acceptance/bootstrap/SpacesContext.php @@ -4000,12 +4000,50 @@ class SpacesContext implements Context { } /** - * @param string $resource // can be resource name, space id or file id - * @param array $properties // ["key" => "value"] + * @param SimpleXMLElement $responseXmlObject + * @param array $xpaths + * @param string $message + * + * @return string + */ + public function buildXpathErrorMessage(SimpleXMLElement $responseXmlObject, array $xpaths, string $message): string { + return "Using xpaths:\n\t- " . \join("\n\t- ", $xpaths) + . "\n" + . $message + . "\n\t" + . "'" . \trim($responseXmlObject->asXML()) . "'"; + } + + /** + * @param SimpleXMLElement $responseXmlObject + * @param string $siblingXpath + * @param string $siblingToFind + * + * @return string + * @throws Exception + */ + public function getXpathSiblingValue(SimpleXMLElement $responseXmlObject, string $siblingXpath, string $siblingToFind): string { + $xpaths[] = $siblingXpath . "/preceding-sibling::$siblingToFind"; + $xpaths[] = $siblingXpath . "/following-sibling::$siblingToFind"; + + foreach ($xpaths as $key => $xpath) { + $foundSibling = $responseXmlObject->xpath($xpath); + if (\count($foundSibling)) { + break; + } + } + $errorMessage = $this->buildXpathErrorMessage($responseXmlObject, $xpaths, "Could not find sibling '<$siblingToFind>' element in the XML response"); + Assert::assertNotEmpty($foundSibling, $errorMessage); + return \preg_quote($foundSibling[0]->__toString(), "/"); + } + + /** + * @param string $resource // can be resource name, space id or file id + * @param array $properties // ["key" => "value"] * * @return void * @throws GuzzleException - * @throws JsonException + * @throws Exception */ public function theXMLResponseShouldContain(string $resource, array $properties): void { $responseXmlObject = HttpRequestHelper::getResponseXml($this->featureContext->getResponse(), __METHOD__); @@ -4056,17 +4094,39 @@ class SpacesContext implements Context { $xpaths[] = $xpath; } + Assert::assertCount( + 1, + $foundXmlItem, + $this->buildXpathErrorMessage($responseXmlObject, $xpaths, "Found multiple elements for '<$itemToFind>' in the XML response") + ); Assert::assertNotEmpty( $foundXmlItem, - // all these for the sake of a nice error message - "Using xpaths:\n\t- " . \join("\n\t- ", $xpaths) - . "\n" - . "Could not find '<$itemToFind>' element in the XML response\n\t" - . "'" . \trim($responseXmlObject->asXML()) . "'" + $this->buildXpathErrorMessage($responseXmlObject, $xpaths, "Could not find '<$itemToFind>' element in the XML response") ); $actualValue = $foundXmlItem[0]->__toString(); - $expectedValue = $this->featureContext->substituteInLineCodes($property['value']); + $expectedValue = $property['value']; + \preg_match_all("/%self::[a-z0-9-:]+?%/", $expectedValue, $selfMatches); + $substituteFunctions = []; + if (!empty($selfMatches[0])) { + $siblingXpath = $xpaths[\count($xpaths) - 1]; + foreach ($selfMatches[0] as $match) { + $siblingToFind = \ltrim($match, "/%self::/"); + $siblingToFind = \rtrim($siblingToFind, "/%/"); + $substituteFunctions[] = [ + "code" => $match, + "function" => + [$this, "getXpathSiblingValue"], + "parameter" => [$responseXmlObject, $siblingXpath, $siblingToFind] + ]; + } + } + $expectedValue = $this->featureContext->substituteInLineCodes( + $property['value'], + null, + [], + $substituteFunctions, + ); switch ($itemToFind) { case "oc:fileid": diff --git a/tests/acceptance/features/apiSharingNg1/propfindShares.feature b/tests/acceptance/features/apiSharingNg1/propfindShares.feature index 5e60d8e90..c24c3b027 100644 --- a/tests/acceptance/features/apiSharingNg1/propfindShares.feature +++ b/tests/acceptance/features/apiSharingNg1/propfindShares.feature @@ -123,18 +123,25 @@ Feature: propfind a shares When user "Brian" sends PROPFIND request from the space "Shares" to the resource "/" using the WebDAV API Then the HTTP status code should be "207" And as user "Brian" the PROPFIND response should contain a resource "folderToShare" with these key and value pairs: - | key | value | - | oc:fileid | | + | key | value | + | oc:fileid | | + | oc:file-parent | %self::oc:spaceid%!%uuidv4_pattern% | When user "Brian" sends PROPFIND request from the space "Shares" to the resource "folderToShare" using the WebDAV API Then the HTTP status code should be "207" And as user "Brian" the PROPFIND response should contain a resource "folderToShare" with these key and value pairs: - | key | value | - | oc:fileid | | + | key | value | + | oc:fileid | | + | oc:file-parent | %self::oc:spaceid%!%uuidv4_pattern% | + And as user "Brian" the PROPFIND response should contain a resource "folderToShare/textfile.txt" with these key and value pairs: + | key | value | + | oc:fileid | %file_id_pattern% | + | oc:file-parent | %self::oc:spaceid%!%uuidv4_pattern% | When user "Brian" sends PROPFIND request from the space "Shares" to the resource "folderToShare/textfile.txt" using the WebDAV API Then the HTTP status code should be "207" And as user "Brian" the PROPFIND response should contain a resource "folderToShare/textfile.txt" with these key and value pairs: - | key | value | - | oc:fileid | %file_id_pattern% | + | key | value | + | oc:fileid | %file_id_pattern% | + | oc:file-parent | %self::oc:spaceid%!%uuidv4_pattern% | Examples: | dav-path-version | pattern | | old | %file_id_pattern% | From 669a5eb2bc80738bff0dbe3466bae1f15d29a8dd Mon Sep 17 00:00:00 2001 From: Saw-jan Date: Wed, 11 Dec 2024 10:10:09 +0545 Subject: [PATCH 2/2] tests: add to expected-failure --- .../acceptance/expected-failures-localAPI-on-OCIS-storage.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md index b79f04bf3..3eea82cd2 100644 --- a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md @@ -318,5 +318,9 @@ The expected failures in this file are from features in the owncloud/ocis repo. - [apiSearchContent/contentSearch.feature:266](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSearchContent/contentSearch.feature#L266) - [apiSearchContent/contentSearch.feature:267](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSearchContent/contentSearch.feature#L267) +#### [Shares Jail PROPFIND returns different File IDs for the same item](https://github.com/owncloud/ocis/issues/9933) + +- [apiSharingNg1/propfindShares.feature:149](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSharingNg1/propfindShares.feature#L149) + Note: always have an empty line at the end of this file. The bash script that processes this file requires that the last line has a newline on the end.