[test-only] ApiTest. create tag (#5391)

* create tag

* split method

* fix after review
This commit is contained in:
Viktor Scharf
2023-01-17 12:41:56 +01:00
committed by GitHub
parent a2e26534ae
commit 7c9452768e
10 changed files with 333 additions and 2440 deletions
+92
View File
@@ -884,4 +884,96 @@ class GraphHelper {
\json_encode($payload)
);
}
/**
* @param string $baseUrl
* @param string $user
* @param string $password
* @param string $xRequestId
* @param array $body
* @param array $headers
*
* @return ResponseInterface
* @throws GuzzleException
*/
public static function getTags(
string $baseUrl,
string $user,
string $password,
string $xRequestId = '',
array $body = [],
array $headers = []
): ResponseInterface {
$url = self::getFullUrl($baseUrl, 'extensions/org.libregraph/tags');
return HttpRequestHelper::get($url, $xRequestId, $user, $password, $headers, $body);
}
/**
* @param string $baseUrl
* @param string $xRequestId
* @param string $user
* @param string $password
* @param string $resourceId
* @param array $tagName
*
* @return ResponseInterface
* @throws GuzzleException
*/
public static function createTags(
string $baseUrl,
string $xRequestId,
string $user,
string $password,
string $resourceId,
array $tagName
): ResponseInterface {
$url = self::getFullUrl($baseUrl, 'extensions/org.libregraph/tags');
$payload['resourceId'] = $resourceId;
$payload['tags'] = $tagName;
return HttpRequestHelper::sendRequest(
$url,
$xRequestId,
"PUT",
$user,
$password,
self::getRequestHeaders(),
\json_encode($payload)
);
}
/**
* @param string $baseUrl
* @param string $xRequestId
* @param string $user
* @param string $password
* @param string $resourceId
* @param array $tagName
*
* @return ResponseInterface
* @throws GuzzleException
*/
public static function deleteTags(
string $baseUrl,
string $xRequestId,
string $user,
string $password,
string $resourceId,
array $tagName
): ResponseInterface {
$url = self::getFullUrl($baseUrl, 'extensions/org.libregraph/tags');
$payload['resourceId'] = $resourceId;
$payload['tags'] = $tagName;
return HttpRequestHelper::sendRequest(
$url,
$xRequestId,
"DELETE",
$user,
$password,
self::getRequestHeaders(),
\json_encode($payload)
);
}
}
-352
View File
@@ -1,352 +0,0 @@
<?php declare(strict_types=1);
/**
* ownCloud
*
* @author Artur Neumann <artur@jankaritech.com>
* @copyright Copyright (c) 2017 Artur Neumann artur@jankaritech.com
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License,
* as published by the Free Software Foundation;
* either version 3 of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace TestHelpers;
use Psr\Http\Message\ResponseInterface;
use Exception;
use SimpleXMLElement;
/**
* Helper to administer Tags
*
* @author Artur Neumann <artur@jankaritech.com>
*
*/
class TagsHelper extends \PHPUnit\Framework\Assert {
/**
* tags a file
*
* @param string|null $baseUrl
* @param string|null $taggingUser
* @param string|null $password
* @param string|null $tagName
* @param string|null $fileName
* @param string|null $xRequestId
* @param string|null $fileOwner
* @param string|null $fileOwnerPassword
* @param int|null $davPathVersionToUse (1|2)
* @param string|null $adminUsername
* @param string|null $adminPassword
*
* @return ResponseInterface
* @throws Exception
*/
public static function tag(
?string $baseUrl,
?string $taggingUser,
?string $password,
?string $tagName,
?string $fileName,
?string $xRequestId = '',
?string $fileOwner = null,
?string $fileOwnerPassword = null,
?int $davPathVersionToUse = 2,
?string $adminUsername = null,
?string $adminPassword = null
):ResponseInterface {
if ($fileOwner === null) {
$fileOwner = $taggingUser;
}
if ($fileOwnerPassword === null) {
$fileOwnerPassword = $password;
}
$fileID = WebDavHelper::getFileIdForPath(
$baseUrl,
$fileOwner,
$fileOwnerPassword,
$fileName,
$xRequestId
);
try {
$tag = self::requestTagByDisplayName(
$baseUrl,
$taggingUser,
$password,
$tagName,
$xRequestId
);
} catch (Exception $e) {
//the tag might be not accessible by the user
//if we still want to find it, we need to try as admin
if ($adminUsername !== null && $adminPassword !== null) {
$tag = self::requestTagByDisplayName(
$baseUrl,
$adminUsername,
$adminPassword,
$tagName,
$xRequestId
);
} else {
throw $e;
}
}
$tagID = self::getTagIdFromTagData($tag);
$path = '/systemtags-relations/files/' . $fileID . '/' . $tagID;
$response = WebDavHelper::makeDavRequest(
$baseUrl,
$taggingUser,
$password,
"PUT",
$path,
null,
$xRequestId,
null,
$davPathVersionToUse,
"systemtags"
);
return $response;
}
/**
* @param SimpleXMLElement $tagData
*
* @return int
*/
public static function getTagIdFromTagData(SimpleXMLElement $tagData):int {
$tagID = $tagData->xpath(".//oc:id");
self::assertArrayHasKey(
0,
$tagID,
"cannot find id of tag"
);
return (int) $tagID[0]->__toString();
}
/**
* get all tags of a user
*
* @param string|null $baseUrl
* @param string|null $user
* @param string|null $password
* @param string|null $xRequestId
* @param bool $withGroups
*
* @return SimpleXMLElement
* @throws Exception
*/
public static function requestTagsForUser(
?string $baseUrl,
?string $user,
?string $password,
?string $xRequestId = '',
?bool $withGroups = false
):SimpleXMLElement {
$properties = [
'oc:id',
'oc:display-name',
'oc:user-visible',
'oc:user-assignable',
'oc:can-assign'
];
if ($withGroups) {
\array_push($properties, 'oc:groups');
}
$response = WebDavHelper::propfind(
$baseUrl,
$user,
$password,
'/systemtags/',
$properties,
$xRequestId,
'1',
"systemtags"
);
return HttpRequestHelper::getResponseXml($response, __METHOD__);
}
/**
* find a tag by its name
*
* @param string|null $baseUrl
* @param string|null $user
* @param string|null $password
* @param string|null $tagDisplayName
* @param string|null $xRequestId
* @param bool $withGroups
*
* @return SimpleXMLElement
* @throws Exception
*/
public static function requestTagByDisplayName(
?string $baseUrl,
?string $user,
?string $password,
?string $tagDisplayName,
?string $xRequestId = '',
?bool $withGroups = false
):SimpleXMLElement {
$tagList = self::requestTagsForUser(
$baseUrl,
$user,
$password,
$xRequestId,
$withGroups
);
$tagData = $tagList->xpath(
"//d:prop//oc:display-name[text() ='$tagDisplayName']/.."
);
self::assertArrayHasKey(
0,
$tagData,
"cannot find 'oc:display-name' property with text '$tagDisplayName'"
);
return $tagData[0];
}
/**
*
* @param string|null $baseUrl see: self::makeDavRequest()
* @param string|null $user
* @param string|null $password
* @param string|null $name
* @param string|null $xRequestId
* @param string|null $userVisible "true", "1" or "false", "0"
* @param string|null $userAssignable "true", "1" or "false", "0"
* @param string|null $userEditable "true", "1" or "false", "0"
* @param string|null $groups separated by "|"
* @param int|null $davPathVersionToUse (1|2)
*
* @return ResponseInterface
* @link self::makeDavRequest()
*/
public static function createTag(
?string $baseUrl,
?string $user,
?string $password,
?string $name,
?string $xRequestId = '',
?string $userVisible = "true",
?string $userAssignable = "true",
?string $userEditable = "false",
?string $groups = null,
?int $davPathVersionToUse = 2
):ResponseInterface {
$tagsPath = '/systemtags/';
$body = [
'name' => $name,
'userVisible' => $userVisible,
'userAssignable' => $userAssignable,
'userEditable' => $userEditable
];
if ($groups !== null) {
$body['groups'] = $groups;
}
return WebDavHelper::makeDavRequest(
$baseUrl,
$user,
$password,
"POST",
$tagsPath,
['Content-Type' => 'application/json',],
$xRequestId,
\json_encode($body),
$davPathVersionToUse,
"systemtags"
);
}
/**
*
* @param string|null $baseUrl
* @param string|null $user
* @param string|null $password
* @param int|null $tagID
* @param string|null $xRequestId
* @param int|null $davPathVersionToUse (1|2)
*
* @return ResponseInterface
*/
public static function deleteTag(
?string $baseUrl,
?string $user,
?string $password,
?int $tagID,
?string $xRequestId = '',
?int $davPathVersionToUse = 1
):ResponseInterface {
$tagsPath = '/systemtags/' . $tagID;
$response = WebDavHelper::makeDavRequest(
$baseUrl,
$user,
$password,
"DELETE",
$tagsPath,
[],
$xRequestId,
null,
$davPathVersionToUse,
"systemtags"
);
return $response;
}
/**
* Validate the keyword(s) used for the type of tag
* Tags can be "normal", "not user-assignable", "not user-visible" or "static"
* That determines the tag attributes which are set when creating the tag.
*
* When creating the tag, the attributes can be enabled/disabled by specifying
* either "true"/"false" or "1"/"0" in the request. Choose this "request style"
* by passing the $useTrueFalseStrings parameter.
*
* @param string|null $type
* @param boolean $useTrueFalseStrings use the strings "true"/"false" else "1"/"0"
*
* @return string[]
* @throws Exception
*/
public static function validateTypeOfTag(?string $type, ?bool $useTrueFalseStrings = true):array {
if ($useTrueFalseStrings) {
$trueValue = "true";
$falseValue = "false";
} else {
$trueValue = "1";
$falseValue = "0";
}
$userVisible = $trueValue;
$userAssignable = $trueValue;
$userEditable = $trueValue;
switch ($type) {
case 'normal':
break;
case 'not user-assignable':
$userAssignable = $falseValue;
break;
case 'not user-visible':
$userVisible = $falseValue;
break;
case 'static':
$userEditable = $falseValue;
break;
default:
throw new Exception('Unsupported type');
}
return [$userVisible, $userAssignable, $userEditable];
}
}
-1
View File
@@ -354,7 +354,6 @@ default:
- SearchContext:
- PublicWebDavContext:
- WebDavPropertiesContext:
- TagsContext:
- TrashbinContext:
coreApiWebdavPreviews:
+1
View File
@@ -48,6 +48,7 @@ default:
- OCSContext:
- PublicWebDavContext:
- SearchContext:
- TagContext:
- TrashbinContext:
- WebDavPropertiesContext:
- TUSContext:
@@ -844,12 +844,6 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
- [coreApiFavorites/favorites.feature:148](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiFavorites/favorites.feature#L148)
- [coreApiFavorites/favorites.feature:270](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiFavorites/favorites.feature#L270)
#### [could not create system tag](https://github.com/owncloud/ocis/issues/3092)
- [coreApiWebdavOperations/search.feature:274](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavOperations/search.feature#L274)
- [coreApiWebdavOperations/search.feature:291](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavOperations/search.feature#L291)
- [coreApiWebdavOperations/search.feature:317](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavOperations/search.feature#L317)
#### [Cannot disable the dav propfind depth infinity for resources](https://github.com/owncloud/ocis/issues/3720)
- [coreApiWebdavOperations/listFiles.feature:383](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavOperations/listFiles.feature#L383)
@@ -0,0 +1,80 @@
@api @skipOnOcV10
Feature: Tag
The user can add a tag to resources for sorting and quick search
Note - this feature is run in CI with ACCOUNTS_HASH_DIFFICULTY set to the default for production
See https://github.com/owncloud/ocis/issues/1542 and https://github.com/owncloud/ocis/pull/839
Background:
Given these users have been created with default attributes and without skeleton files:
| username |
| Alice |
| Brian |
And using spaces DAV path
And the administrator has given "Alice" the role "Space Admin" using the settings api
And user "Alice" has created a space "use-tag" with the default quota using the GraphApi
And user "Alice" has created a folder "folderMain" in space "use-tag"
And user "Alice" has uploaded a file inside space "use-tag" with content "some content" to "folderMain/insideTheFolder.txt"
Scenario: Alice creates tags for resources in the project space
Given user "Alice" has shared a space "use-tag" to user "Brian" with role "viewer"
When user "Alice" creates the following tags for folder "folderMain" of space "use-tag":
| tag level#1 |
| tag with symbols @^$#^%$@%!_+) |
Then the HTTP status code should be "200"
When user "Alice" sends PROPFIND request from the space "use-tag" to the resource "folderMain" using the WebDAV API
Then the HTTP status code should be "207"
And the "PROPFIND" response should contain a space "use-tag" with these key and value pairs:
| key | value |
| oc:tags | tag level#1,tag with symbols @^$#^%$@%!_+) |
When user "Alice" creates the following tags for file "folderMain/insideTheFolder.txt" of space "use-tag":
| fileTag |
Then the HTTP status code should be "200"
When user "Brian" sends PROPFIND request from the space "use-tag" to the resource "folderMain/insideTheFolder.txt" using the WebDAV API
Then the HTTP status code should be "207"
And the "PROPFIND" response should contain a space "use-tag" with these key and value pairs:
| key | value |
| oc:tags | fileTag |
When user "Alice" lists all available tags via the GraphApi
Then the HTTP status code should be "200"
And the response should contain following tags:
| tag level#1 |
| tag with symbols @^$#^%$@%!_+) |
| fileTag |
When user "Alice" lists all available tags via the GraphApi
Then the HTTP status code should be "200"
And the response should contain following tags:
| tag level#1 |
| tag with symbols @^$#^%$@%!_+) |
| fileTag |
Scenario: Alice creates tags for resources in the personal space
Given user "Alice" has created a folder "folderMain" in space "Alice Hansen"
And user "Alice" has uploaded a file inside space "Alice Hansen" with content "some content" to "file.txt"
When user "Alice" creates the following tags for folder "folderMain" of space "Alice Hansen":
| my tag |
| important |
Then the HTTP status code should be "200"
When user "Alice" creates the following tags for file "file.txt" of space "Alice Hansen":
| fileTag |
| tag with symbol @^$#^%$@%!_+) |
Then the HTTP status code should be "200"
When user "Alice" sends PROPFIND request from the space "Alice Hansen" to the resource "folderMain" using the WebDAV API
Then the HTTP status code should be "207"
And the "PROPFIND" response to user "Alice" should contain a mountpoint "Alice Hansen" with these key and value pairs:
| key | value |
| oc:tags | my tag,important |
When user "Alice" sends PROPFIND request from the space "Alice Hansen" to the resource "file.txt" using the WebDAV API
Then the HTTP status code should be "207"
And the "PROPFIND" response to user "Alice" should contain a mountpoint "Alice Hansen" with these key and value pairs:
| key | value |
| oc:tags | fileTag,tag with symbol @^$#^%$@%!_+) |
When user "Alice" lists all available tags via the GraphApi
Then the HTTP status code should be "200"
And the response should contain following tags:
| my tag |
| important |
| fileTag |
| tag with symbol @^$#^%$@%!_+) |
@@ -1651,7 +1651,7 @@ class SpacesContext implements Context {
*
* @param string $user
* @param string $fullUrl
* @param string $headers
* @param array $headers
*
* @return ResponseInterface
* @throws GuzzleException
@@ -1960,7 +1960,7 @@ class SpacesContext implements Context {
string $role
): void {
$response = $this->sendRequestForShareOfEntityInsideOfSpace($user, $entity, $spaceName, $userRecipient, $role);
Assert:assertEquals(
Assert::assertEquals(
$response->getStatusCode(),
200,
"Expected response status code should be 200"
@@ -2984,23 +2984,25 @@ class SpacesContext implements Context {
/**
* @When /^user "([^"]*)" sends PROPFIND request to space "([^"]*)" using the WebDAV API$/
* @When /^user "([^"]*)" sends PROPFIND request from the space "([^"]*)" to the resource "([^"]*)" using the WebDAV API$/
*
* @param string $user
* @param string $spaceName
* @param ?string $resource
*
* @throws GuzzleException
*
* @return void
*/
public function userSendsPropfindRequestToSpace(string $user, string $spaceName): void {
public function userSendsPropfindRequestToSpace(string $user, string $spaceName, ?string $resource = ""): void {
$this->setSpaceIDByName($user, $spaceName);
$properties = ['oc:permissions','oc:fileid','oc:share-types','oc:privatelink','d:resourcetype','oc:size','oc:name','d:getcontenttype'];
$properties = ['oc:permissions','oc:fileid','oc:share-types','oc:privatelink','d:resourcetype','oc:size','oc:name','d:getcontenttype', 'oc:tags'];
$this->featureContext->setResponse(
WebDavHelper::propfind(
$this->featureContext->getBaseUrl(),
$this->featureContext->getActualUsername($user),
$this->featureContext->getPasswordForUser($user),
"",
$resource,
$properties,
"",
"0",
@@ -0,0 +1,153 @@
<?php declare(strict_types=1);
/**
* @author Viktor Scharf <scharf.vi@gmail.com>
*
* @copyright Copyright (c) 2022, ownCloud GmbH
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
use Behat\Behat\Context\Context;
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Behat\Gherkin\Node\TableNode;
use PHPUnit\Framework\Assert;
use TestHelpers\GraphHelper;
require_once 'bootstrap.php';
/**
* Acceptance test steps related to testing tags features
*/
class TagContext implements Context {
/**
*
* @var FeatureContext
*/
private $featureContext;
/**
* @var SpacesContext
*/
private SpacesContext $spacesContext;
/**
* This will run before EVERY scenario.
* It will set the properties for this object.
*
* @BeforeScenario
*
* @param BeforeScenarioScope $scope
*
* @return void
*/
public function before(BeforeScenarioScope $scope): void {
// Get the environment
$environment = $scope->getEnvironment();
// Get all the contexts you need in this context from here
$this->featureContext = $environment->getContext('FeatureContext');
$this->spacesContext = $environment->getContext('SpacesContext');
}
/**
* @var array
*/
private $createdTags = [];
/**
* @When /^user "([^"]*)" creates the following tags for (folder|file)\s?"([^"]*)" of space "([^"]*)":$/
*
* @param string $user
* @param string $fileOrFolder (file|folder)
* @param string $resource
* @param string $space
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theUserCreatesFollowingTags(string $user, string $fileOrFolder, string $resource, string $space, TableNode $table):void {
$tagNameArray = [];
foreach ($table->getRows() as $value) {
array_push($tagNameArray, $value[0]);
}
if ($fileOrFolder === 'folder') {
$resourceId = $this->spacesContext->getFolderId($user, $space, $resource);
} else {
$resourceId = $this->spacesContext->getFileId($user, $space, $resource);
}
$response = GraphHelper::createTags(
$this->featureContext->getBaseUrl(),
$this->featureContext->getStepLineRef(),
$user,
$this->featureContext->getPasswordForUser($user),
$resourceId,
$tagNameArray
);
$this->featureContext->setResponse($response);
}
/**
* @Given /^user "([^"]*)" has created the following tags a (folder|file)\s?"([^"]*)" of the space "([^"]*)":$/
*
* @param string $user
* @param string $fileOrFolder (file|folder)
* @param string $resource
* @param string $space
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theUserHasCreatedFollowingTags(string $user, string $fileOrFolder, string $resource, string $space, TableNode $table):void {
$this->theUserCreatesFollowingTags($user, $fileOrFolder, $resource, $space, $table);
$this->featureContext->theHttpStatusCodeShouldBe(200);
}
/**
* @When user :user lists all available tag(s) via the GraphApi
*
* @param string $user
*
* @return void
* @throws Exception
*/
public function theUserGetsAllAvailableTags(string $user):void {
$this->featureContext->setResponse(
GraphHelper::getTags(
$this->featureContext->getBaseUrl(),
$user,
$this->featureContext->getPasswordForUser($user)
)
);
}
/**
* @Then the response should contain following tag(s):
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theFollowingTagsShouldExistForUser(TableNode $table):void {
$rows = $table->getRows();
foreach ($rows as $row) {
$responseArray = $this->featureContext->getJsonDecodedResponse($this->featureContext->getResponse())['value'];
Assert::assertTrue(\in_array($row[0], $responseArray), "the response does not contain the tag $row[0]");
}
}
}
File diff suppressed because it is too large Load Diff
@@ -269,69 +269,3 @@ Feature: Search
Examples:
| dav_version |
| spaces |
Scenario: search for entry by tags using REPORT method
Given user "Alice" has created a "normal" tag with name "JustARegularTag1"
And user "Alice" has created a "normal" tag with name "JustARegularTag2"
And user "Alice" has added tag "JustARegularTag1" to folder " näme"
And user "Alice" has added tag "JustARegularTag1" to file "upload.txt"
And user "Alice" has added tag "JustARegularTag2" to file "upload.txt"
When user "Alice" searches for resources tagged with tag "JustARegularTag1" using the webDAV API
Then the HTTP status code should be "207"
And the search result by tags for user "Alice" should contain these entries:
| näme |
| upload.txt |
When user "Alice" searches for resources tagged with tag "JustARegularTag2" using the webDAV API
Then the HTTP status code should be "207"
And the search result by tags for user "Alice" should contain these entries:
| upload.txt |
Scenario: share a tagged resource to another internal user and sharee searches for tag using REPORT method
Given user "Brian" has been created with default attributes and without skeleton files
And user "Alice" has created a "normal" tag with name "JustARegularTag1"
And user "Alice" has created a "normal" tag with name "JustARegularTag2"
And user "Alice" has added tag "JustARegularTag1" to folder " näme"
And user "Alice" has added tag "JustARegularTag1" to file "upload.txt"
And user "Alice" has added tag "JustARegularTag2" to file "upload.txt"
And user "Alice" has shared file " näme" with user "Brian"
And user "Alice" has shared file "upload.txt" with user "Brian"
When user "Brian" searches for resources tagged with tag "JustARegularTag1" using the webDAV API
Then the HTTP status code should be "207"
And the search result by tags for user "Brian" should contain these entries:
| näme |
| upload.txt |
When user "Brian" searches for resources tagged with tag "JustARegularTag2" using the webDAV API
Then the HTTP status code should be "207"
And the search result by tags for user "Brian" should contain these entries:
| upload.txt |
When user "Brian" searches for resources tagged with all of the following tags using the webDAV API
| JustARegularTag1 |
| JustARegularTag2 |
Then the HTTP status code should be "207"
And as user "Brian" the response should contain file "upload.txt"
And as user "Brian" the response should not contain file " näme"
Scenario: search for entries across various folders by tags using REPORT method
Given user "Alice" has created folder "/just-a-folder/inner-folder"
And user "Alice" has uploaded file with content "inner file" to "/just-a-folder/inner-folder/upload.txt"
And user "Alice" has created a "normal" tag with name "JustARegularTag1"
And user "Alice" has created a "normal" tag with name "JustARegularTag2"
And user "Alice" has added tag "JustARegularTag1" to folder "/just-a-folder/upload.txt"
And user "Alice" has added tag "JustARegularTag1" to file "/ näme/upload.txt"
And user "Alice" has added tag "JustARegularTag1" to file "/just-a-folder/inner-folder/upload.txt"
And user "Alice" has added tag "JustARegularTag2" to file "/upload😀 😁/upload,1.txt"
And user "Alice" has added tag "JustARegularTag2" to file "/upload.txt"
When user "Alice" searches for resources tagged with tag "JustARegularTag1" using the webDAV API
Then the HTTP status code should be "207"
And the search result by tags for user "Alice" should contain these entries:
| upload.txt |
| upload.txt |
| upload.txt |
When user "Alice" searches for resources tagged with tag "JustARegularTag2" using the webDAV API
Then the HTTP status code should be "207"
And the search result by tags for user "Alice" should contain these entries:
| upload,1.txt |
| upload.txt |