Merge pull request #4054 from owncloud/searchInProjectSpace

ApiTest. search entity from project space and shares jail
This commit is contained in:
Phil Davis
2022-06-30 15:27:37 +05:45
committed by GitHub
6 changed files with 204 additions and 151 deletions

View File

@@ -1,5 +1,5 @@
# The test runner source for API tests
CORE_COMMITID=ca4294642f8391dd3f294e0bfd8277fa0ca478f5
CORE_COMMITID=7e9caa446346426de197b475e03be19dfe367a54
CORE_BRANCH=master
# The test runner source for UI tests

View File

@@ -41,6 +41,7 @@ default:
- FilesVersionsContext:
- OCSContext:
- PublicWebDavContext:
- SearchContext:
- TrashbinContext:
- WebDavPropertiesContext:
- TusContext:

View File

@@ -19,3 +19,5 @@ The expected failures in this file are from features in the owncloud/ocis repo.
- [apiArchiver/downloadById.feature:134](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadById.feature#L134)
- [apiArchiver/downloadById.feature:135](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadById.feature#L135)
### [Search by shares jail works incorrect](https://github.com/owncloud/ocis/issues/4014)
- [apiSpaces/search.feature:43](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/search.feature#L43)

View File

@@ -0,0 +1,54 @@
@api @skipOnOcV10
Feature: Search
It is possible to search files in the shares jail and the project space
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 new DAV path
And the administrator has given "Alice" the role "Admin" using the settings api
And user "Alice" has created a space "find data" with the default quota using the GraphApi
And user "Alice" has created a folder "folder/SubFolder1/subFOLDER2" in space "find data"
And user "Alice" has uploaded a file inside space "find data" with content "some content" to "folder/SubFolder1/subFOLDER2/insideTheFolder.txt"
Scenario: Alice can find data from the project space
When user "Alice" searches for "fol" using the WebDAV API
Then the HTTP status code should be "207"
And the search result should contain "4" entries
And the search result of user "Alice" should contain these entries:
| /folder |
| /folder/SubFolder1 |
| /folder/SubFolder1/subFOLDER2 |
| /folder/SubFolder1/subFOLDER2/insideTheFolder.txt |
Scenario: Alice can find data from the project space
When user "Alice" searches for "SUB" using the WebDAV API
Then the HTTP status code should be "207"
And the search result should contain "2" entries
And the search result of user "Alice" should contain these entries:
| /folder/SubFolder1 |
| /folder/SubFolder1/subFOLDER2 |
But the search result of user "Alice" should not contain these entries:
| /folder |
| /folder/SubFolder1/subFOLDER2/insideTheFolder.txt |
Scenario: Brian can find data from the shares jail
Given user "Alice" shares the following entity "folder" inside of space "find data" with user "Brian" with role "viewer"
And user "Brian" has accepted share "/folder" offered by user "Alice"
When user "Brian" searches for "folder" using the WebDAV API
Then the HTTP status code should be "207"
And the search result should contain "4" entries
And the search result of user "Brian" should contain these entries:
| /folder |
| /folder/SubFolder1 |
| /folder/SubFolder1/subFOLDER2 |
| /folder/SubFolder1/subFOLDER2/insideTheFolder.txt |

View File

@@ -316,13 +316,15 @@ class SpacesContext implements Context {
* @throws Exception|GuzzleException
*/
public function getUserIdByUserName(string $userName): string {
$this->featureContext->setResponse(GraphHelper::getUser(
$this->featureContext->getBaseUrl(),
$this->featureContext->getStepLineRef(),
$this->featureContext->getAdminUsername(),
$this->featureContext->getAdminPassword(),
$userName
));
$this->featureContext->setResponse(
GraphHelper::getUser(
$this->featureContext->getBaseUrl(),
$this->featureContext->getStepLineRef(),
$this->featureContext->getAdminUsername(),
$this->featureContext->getAdminPassword(),
$userName
)
);
if ($this->featureContext->getResponse()) {
$rawBody = $this->featureContext->getResponse()->getBody()->getContents();
$response = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR);
@@ -369,21 +371,20 @@ class SpacesContext implements Context {
*
* @throws Exception|GuzzleException
*/
public function cleanDataAfterTests(): void
{
public function cleanDataAfterTests(): void {
$this->deleteAllSpacesOfTheType('project');
}
/**
* The method first disables and then deletes spaces
*
* @param string $driveType
*
* @return void
*
* @throws Exception|GuzzleException
*/
public function deleteAllSpacesOfTheType(string $driveType): void
{
public function deleteAllSpacesOfTheType(string $driveType): void {
$query = "\$filter=driveType eq $driveType";
$userAdmin = $this->featureContext->getAdminUsername();
@@ -401,7 +402,7 @@ class SpacesContext implements Context {
if (!empty($drives)) {
foreach ($drives as $value) {
if (!array_key_exists("deleted", $value["root"])) {
if (!\array_key_exists("deleted", $value["root"])) {
$this->sendDisableSpaceRequest($userAdmin, $value["name"]);
} else {
$this->sendDeleteSpaceRequest($userAdmin, $value["name"]);
@@ -744,13 +745,15 @@ class SpacesContext implements Context {
}
Assert::assertNotEmpty($roleToAssign, "The selected role $role could not be found");
$this->featureContext->setResponse(GraphHelper::getUser(
$this->featureContext->getBaseUrl(),
$this->featureContext->getStepLineRef(),
$this->featureContext->getAdminUsername(),
$this->featureContext->getAdminPassword(),
$user
));
$this->featureContext->setResponse(
GraphHelper::getUser(
$this->featureContext->getBaseUrl(),
$this->featureContext->getStepLineRef(),
$this->featureContext->getAdminUsername(),
$this->featureContext->getAdminPassword(),
$user
)
);
if ($this->featureContext->getResponse()) {
$rawBody = $this->featureContext->getResponse()->getBody()->getContents();
if (isset(\json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["id"])) {
@@ -2228,6 +2231,7 @@ class SpacesContext implements Context {
/**
* User downloads a preview of the file inside the project space
*
* @When /^user "([^"]*)" downloads the preview of "([^"]*)" of the space "([^"]*)" with width "([^"]*)" and height "([^"]*)" using the WebDAV API$/
*
* @param string $user
@@ -2273,7 +2277,7 @@ class SpacesContext implements Context {
* @When /^user "([^"]*)" downloads the file "([^"]*)" of the space "([^"]*)" using the WebDAV API$/
*
* @param string $user
* @param string $fileName
* @param string $fileName
* @param string $spaceName
*
* @throws GuzzleException
@@ -2282,7 +2286,7 @@ class SpacesContext implements Context {
string $user,
string $fileName,
string $spaceName
): void {
): void {
$space = $this->getSpaceByName($user, $spaceName);
$fullUrl = $this->baseUrl . $this->davSpacesUrl . $space['id'] . '/' . $fileName;
@@ -2303,7 +2307,7 @@ class SpacesContext implements Context {
* @When /^user "([^"]*)" downloads version of the file "([^"]*)" with the index "([^"]*)" of the space "([^"]*)" using the WebDAV API$/
*
* @param string $user
* @param string $fileName
* @param string $fileName
* @param string $index
* @param string $spaceName
*
@@ -2314,14 +2318,14 @@ class SpacesContext implements Context {
string $fileName,
string $index,
string $spaceName
): void {
): void {
$fileVersion = $this->listFileVersion($user, $fileName, $spaceName);
if (!isset($fileVersion[$index])) {
Assert::fail(
'could not find version of file "' . $fileName . '" with index "' . $index . '"'
);
}
$url = $this->baseUrl . $fileVersion[$index][0];
$url = $this->baseUrl . $fileVersion[$index][0];
$this->featureContext->setResponse(
HttpRequestHelper::sendRequest(
@@ -2337,12 +2341,11 @@ class SpacesContext implements Context {
}
/**
* Method returns an array with url values from the propfind request
* Method returns an array with url values from the propfind request
* like: /remote.php/dav/meta/spaceUuid%fileUuid/v/fileUuid.REV.2022-05-17T10:39:49.672285951Z
*
*
* @param string $user
* @param string $fileName
* @param string $fileName
* @param string $spaceName
*
* @return array
@@ -2352,8 +2355,7 @@ class SpacesContext implements Context {
string $user,
string $fileName,
string $spaceName
): array {
): array {
$fileId = $this->getFileId($user, $spaceName, $fileName);
$fullUrl = $this->baseUrl . '/remote.php/dav/meta/' . $fileId . '/v';

View File

@@ -18,137 +18,131 @@ require_once 'bootstrap.php';
/**
* Context for the TUS-specific steps using the Graph API
*/
class TusContext implements Context
{
class TusContext implements Context {
/**
* @var FeatureContext
*/
private FeatureContext $featureContext;
/**
* @var FeatureContext
*/
private FeatureContext $featureContext;
/**
* @var SpacesContext
*/
private SpacesContext $spacesContext;
/**
* @var SpacesContext
*/
private SpacesContext $spacesContext;
/**
* @var string
*/
private string $baseUrl;
/**
* @var string
*/
private string $baseUrl;
/**
* @return string
*/
public function acceptanceTestsDirLocation(): string
{
return \dirname(__FILE__) . "/../../filesForUpload/";
}
/**
* @return string
*/
public function acceptanceTestsDirLocation(): string {
return \dirname(__FILE__) . "/../../filesForUpload/";
}
/**
* 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');
$this->baseUrl = \trim($this->featureContext->getBaseUrl(), "/");
}
/**
* 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');
$this->baseUrl = \trim($this->featureContext->getBaseUrl(), "/");
}
/**
* @Given /^user "([^"]*)" has uploaded a file "([^"]*)" via TUS inside of the space "([^"]*)" using the WebDAV API$/
*
* @param string $user
* @param string $resource
* @param string $spaceName
*
* @return void
*
* @throws Exception
* @throws GuzzleException
*/
public function uploadFileViaTus(string $user, string $resource, string $spaceName): void
{
$resourceLocation = $this->getResourceLocation($user, $resource, $spaceName);
$file = \fopen($this->acceptanceTestsDirLocation() . $resource, 'r');
/**
* @Given /^user "([^"]*)" has uploaded a file "([^"]*)" via TUS inside of the space "([^"]*)" using the WebDAV API$/
*
* @param string $user
* @param string $resource
* @param string $spaceName
*
* @return void
*
* @throws Exception
* @throws GuzzleException
*/
public function uploadFileViaTus(string $user, string $resource, string $spaceName): void {
$resourceLocation = $this->getResourceLocation($user, $resource, $spaceName);
$file = \fopen($this->acceptanceTestsDirLocation() . $resource, 'r');
$this->featureContext->setResponse(
HttpRequestHelper::sendRequest(
$resourceLocation,
"",
'HEAD',
$user,
$this->featureContext->getPasswordForUser($user),
[],
""
)
);
$this->featureContext->theHTTPStatusCodeShouldBe(200, "Expected response status code should be 200");
$this->featureContext->setResponse(
HttpRequestHelper::sendRequest(
$resourceLocation,
"",
'HEAD',
$user,
$this->featureContext->getPasswordForUser($user),
[],
""
)
);
$this->featureContext->theHTTPStatusCodeShouldBe(200, "Expected response status code should be 200");
$this->featureContext->setResponse(
HttpRequestHelper::sendRequest(
$resourceLocation,
"",
'PATCH',
$user,
$this->featureContext->getPasswordForUser($user),
["Tus-Resumable" => "1.0.0", "Upload-Offset" => 0, 'Content-Type' => 'application/offset+octet-stream'],
$file
)
);
$this->featureContext->theHTTPStatusCodeShouldBe(204, "Expected response status code should be 204");
}
$this->featureContext->setResponse(
HttpRequestHelper::sendRequest(
$resourceLocation,
"",
'PATCH',
$user,
$this->featureContext->getPasswordForUser($user),
["Tus-Resumable" => "1.0.0", "Upload-Offset" => 0, 'Content-Type' => 'application/offset+octet-stream'],
$file
)
);
$this->featureContext->theHTTPStatusCodeShouldBe(204, "Expected response status code should be 204");
}
/**
* send POST and return the url of the resource location in the response header
*
* @param string $user
* @param string $resource
* @param string $spaceName
*
* @return string
* @throws Exception|GuzzleException
*/
public function getResourceLocation(string $user, string $resource, string $spaceName): string {
$space = $this->spacesContext->getSpaceByName($user, $spaceName);
$fullUrl = $this->baseUrl . "/remote.php/dav/spaces/" . $space["id"];
/**
* send POST and return the url of the resource location in the response header
*
* @param string $user
* @param string $resource
* @param string $spaceName
*
* @return string
* @throws Exception|GuzzleException
*/
public function getResourceLocation(string $user, string $resource, string $spaceName): string
{
$space = $this->spacesContext->getSpaceByName($user, $spaceName);
$fullUrl = $this->baseUrl . "/remote.php/dav/spaces/" . $space["id"];
$tusEndpoint = "tusEndpoint " . base64_encode(str_replace("$", "%", $fullUrl));
$fileName = "filename " . base64_encode($resource);
$tusEndpoint = "tusEndpoint " . base64_encode(str_replace("$", "%", $fullUrl));
$fileName = "filename " . base64_encode($resource);
$headers = [
"Tus-Resumable" => "1.0.0",
"Upload-Metadata" => $tusEndpoint . ',' . $fileName,
"Upload-Length" => filesize($this->acceptanceTestsDirLocation() . $resource)
];
$headers = [
"Tus-Resumable" => "1.0.0",
"Upload-Metadata" => $tusEndpoint . ',' . $fileName,
"Upload-Length" => filesize($this->acceptanceTestsDirLocation() . $resource)
];
$this->featureContext->setResponse(
HttpRequestHelper::post(
$fullUrl,
"",
$this->featureContext->getActualUsername($user),
$this->featureContext->getUserPassword($user),
$headers,
''
)
);
$this->featureContext->theHTTPStatusCodeShouldBe(201, "Expected response status code should be 201");
$this->featureContext->setResponse(
HttpRequestHelper::post(
$fullUrl,
"",
$this->featureContext->getActualUsername($user),
$this->featureContext->getUserPassword($user),
$headers,
''
)
);
$this->featureContext->theHTTPStatusCodeShouldBe(201, "Expected response status code should be 201");
$locationHeader = $this->featureContext->getResponse()->getHeader('Location');
if (\sizeof($locationHeader) > 0) {
return $locationHeader[0];
}
throw new \Exception(__METHOD__ . " Location header could not be found");
}
$locationHeader = $this->featureContext->getResponse()->getHeader('Location');
if (\sizeof($locationHeader) > 0) {
return $locationHeader[0];
}
throw new \Exception(__METHOD__ . " Location header could not be found");
}
}