aboutsummaryrefslogtreecommitdiffstats
path: root/build/integration/features/bootstrap
diff options
context:
space:
mode:
Diffstat (limited to 'build/integration/features/bootstrap')
-rw-r--r--build/integration/features/bootstrap/BasicStructure.php312
-rw-r--r--build/integration/features/bootstrap/FeatureContext.php244
-rw-r--r--build/integration/features/bootstrap/FederationContext.php54
-rw-r--r--build/integration/features/bootstrap/Provisioning.php656
-rw-r--r--build/integration/features/bootstrap/Sharing.php498
-rw-r--r--build/integration/features/bootstrap/WebDav.php508
6 files changed, 2033 insertions, 239 deletions
diff --git a/build/integration/features/bootstrap/BasicStructure.php b/build/integration/features/bootstrap/BasicStructure.php
new file mode 100644
index 00000000000..f693a242e17
--- /dev/null
+++ b/build/integration/features/bootstrap/BasicStructure.php
@@ -0,0 +1,312 @@
+<?php
+
+use GuzzleHttp\Client;
+use GuzzleHttp\Message\ResponseInterface;
+
+require __DIR__ . '/../../vendor/autoload.php';
+
+trait BasicStructure {
+
+ /** @var string */
+ private $currentUser = '';
+
+ /** @var string */
+ private $currentServer = '';
+
+ /** @var string */
+ private $baseUrl = '';
+
+ /** @var int */
+ private $apiVersion = 1;
+
+ /** @var ResponseInterface */
+ private $response = null;
+
+ /** @var \GuzzleHttp\Cookie\CookieJar */
+ private $cookieJar;
+
+ /** @var string */
+ private $requestToken;
+
+ public function __construct($baseUrl, $admin, $regular_user_password) {
+
+ // Initialize your context here
+ $this->baseUrl = $baseUrl;
+ $this->adminUser = $admin;
+ $this->regularUser = $regular_user_password;
+ $this->localBaseUrl = $this->baseUrl;
+ $this->remoteBaseUrl = $this->baseUrl;
+ $this->currentServer = 'LOCAL';
+ $this->cookieJar = new \GuzzleHttp\Cookie\CookieJar();
+
+ // in case of ci deployment we take the server url from the environment
+ $testServerUrl = getenv('TEST_SERVER_URL');
+ if ($testServerUrl !== false) {
+ $this->baseUrl = $testServerUrl;
+ $this->localBaseUrl = $testServerUrl;
+ }
+
+ // federated server url from the environment
+ $testRemoteServerUrl = getenv('TEST_SERVER_FED_URL');
+ if ($testRemoteServerUrl !== false) {
+ $this->remoteBaseUrl = $testRemoteServerUrl;
+ }
+ }
+
+ /**
+ * @Given /^using api version "([^"]*)"$/
+ * @param string $version
+ */
+ public function usingApiVersion($version) {
+ $this->apiVersion = $version;
+ }
+
+ /**
+ * @Given /^As an "([^"]*)"$/
+ * @param string $user
+ */
+ public function asAn($user) {
+ $this->currentUser = $user;
+ }
+
+ /**
+ * @Given /^Using server "(LOCAL|REMOTE)"$/
+ * @param string $server
+ * @return string Previous used server
+ */
+ public function usingServer($server) {
+ $previousServer = $this->currentServer;
+ if ($server === 'LOCAL'){
+ $this->baseUrl = $this->localBaseUrl;
+ $this->currentServer = 'LOCAL';
+ return $previousServer;
+ } else {
+ $this->baseUrl = $this->remoteBaseUrl;
+ $this->currentServer = 'REMOTE';
+ return $previousServer;
+ }
+ }
+
+ /**
+ * @When /^sending "([^"]*)" to "([^"]*)"$/
+ * @param string $verb
+ * @param string $url
+ */
+ public function sendingTo($verb, $url) {
+ $this->sendingToWith($verb, $url, null);
+ }
+
+ /**
+ * Parses the xml answer to get ocs response which doesn't match with
+ * http one in v1 of the api.
+ * @param ResponseInterface $response
+ * @return string
+ */
+ public function getOCSResponse($response) {
+ return $response->xml()->meta[0]->statuscode;
+ }
+
+ /**
+ * This function is needed to use a vertical fashion in the gherkin tables.
+ * @param array $arrayOfArrays
+ * @return array
+ */
+ public function simplifyArray($arrayOfArrays){
+ $a = array_map(function($subArray) { return $subArray[0]; }, $arrayOfArrays);
+ return $a;
+ }
+
+ /**
+ * @When /^sending "([^"]*)" to "([^"]*)" with$/
+ * @param string $verb
+ * @param string $url
+ * @param \Behat\Gherkin\Node\TableNode $body
+ */
+ public function sendingToWith($verb, $url, $body) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php" . $url;
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ } else {
+ $options['auth'] = [$this->currentUser, $this->regularUser];
+ }
+ if ($body instanceof \Behat\Gherkin\Node\TableNode) {
+ $fd = $body->getRowsHash();
+ $options['body'] = $fd;
+ }
+
+ try {
+ $this->response = $client->send($client->createRequest($verb, $fullUrl, $options));
+ } catch (\GuzzleHttp\Exception\ClientException $ex) {
+ $this->response = $ex->getResponse();
+ }
+ }
+
+ public function isExpectedUrl($possibleUrl, $finalPart){
+ $baseUrlChopped = substr($this->baseUrl, 0, -4);
+ $endCharacter = strlen($baseUrlChopped) + strlen($finalPart);
+ return (substr($possibleUrl,0,$endCharacter) == "$baseUrlChopped" . "$finalPart");
+ }
+
+ /**
+ * @Then /^the OCS status code should be "([^"]*)"$/
+ * @param int $statusCode
+ */
+ public function theOCSStatusCodeShouldBe($statusCode) {
+ PHPUnit_Framework_Assert::assertEquals($statusCode, $this->getOCSResponse($this->response));
+ }
+
+ /**
+ * @Then /^the HTTP status code should be "([^"]*)"$/
+ * @param int $statusCode
+ */
+ public function theHTTPStatusCodeShouldBe($statusCode) {
+ PHPUnit_Framework_Assert::assertEquals($statusCode, $this->response->getStatusCode());
+ }
+
+ /**
+ * @param ResponseInterface $response
+ */
+ private function extracRequestTokenFromResponse(ResponseInterface $response) {
+ $this->requestToken = substr(preg_replace('/(.*)data-requesttoken="(.*)">(.*)/sm', '\2', $response->getBody()->getContents()), 0, 89);
+ }
+
+ /**
+ * @Given Logging in using web as :user
+ * @param string $user
+ */
+ public function loggingInUsingWebAs($user) {
+ $loginUrl = substr($this->baseUrl, 0, -5) . '/login';
+ // Request a new session and extract CSRF token
+ $client = new Client();
+ $response = $client->get(
+ $loginUrl,
+ [
+ 'cookies' => $this->cookieJar,
+ ]
+ );
+ $this->extracRequestTokenFromResponse($response);
+
+ // Login and extract new token
+ $password = ($user === 'admin') ? 'admin' : '123456';
+ $client = new Client();
+ $response = $client->post(
+ $loginUrl,
+ [
+ 'body' => [
+ 'user' => $user,
+ 'password' => $password,
+ 'requesttoken' => $this->requestToken,
+ ],
+ 'cookies' => $this->cookieJar,
+ ]
+ );
+ $this->extracRequestTokenFromResponse($response);
+ }
+
+ /**
+ * @When Sending a :method to :url with requesttoken
+ * @param string $method
+ * @param string $url
+ */
+ public function sendingAToWithRequesttoken($method, $url) {
+ $baseUrl = substr($this->baseUrl, 0, -5);
+
+ $client = new Client();
+ $request = $client->createRequest(
+ $method,
+ $baseUrl . $url,
+ [
+ 'cookies' => $this->cookieJar,
+ ]
+ );
+ $request->addHeader('requesttoken', $this->requestToken);
+ try {
+ $this->response = $client->send($request);
+ } catch (\GuzzleHttp\Exception\ClientException $e) {
+ $this->response = $e->getResponse();
+ }
+ }
+
+ /**
+ * @When Sending a :method to :url without requesttoken
+ * @param string $method
+ * @param string $url
+ */
+ public function sendingAToWithoutRequesttoken($method, $url) {
+ $baseUrl = substr($this->baseUrl, 0, -5);
+
+ $client = new Client();
+ $request = $client->createRequest(
+ $method,
+ $baseUrl . $url,
+ [
+ 'cookies' => $this->cookieJar,
+ ]
+ );
+ try {
+ $this->response = $client->send($request);
+ } catch (\GuzzleHttp\Exception\ClientException $e) {
+ $this->response = $e->getResponse();
+ }
+ }
+
+ public static function removeFile($path, $filename){
+ if (file_exists("$path" . "$filename")) {
+ unlink("$path" . "$filename");
+ }
+ }
+
+ /**
+ * @Given User :user modifies text of :filename with text :text
+ * @param string $user
+ * @param string $filename
+ * @param string $text
+ */
+ public function modifyTextOfFile($user, $filename, $text) {
+ self::removeFile("../../data/$user/files", "$filename");
+ file_put_contents("../../data/$user/files" . "$filename", "$text");
+ }
+
+ /**
+ * @BeforeSuite
+ */
+ public static function addFilesToSkeleton(){
+ for ($i=0; $i<5; $i++){
+ file_put_contents("../../core/skeleton/" . "textfile" . "$i" . ".txt", "ownCloud test text file\n");
+ }
+ if (!file_exists("../../core/skeleton/FOLDER")) {
+ mkdir("../../core/skeleton/FOLDER", 0777, true);
+ }
+ if (!file_exists("../../core/skeleton/PARENT")) {
+ mkdir("../../core/skeleton/PARENT", 0777, true);
+ }
+ file_put_contents("../../core/skeleton/PARENT/" . "parent.txt", "ownCloud test text file\n");
+ if (!file_exists("../../core/skeleton/PARENT/CHILD")) {
+ mkdir("../../core/skeleton/PARENT/CHILD", 0777, true);
+ }
+ file_put_contents("../../core/skeleton/PARENT/CHILD/" . "child.txt", "ownCloud test text file\n");
+ }
+
+ /**
+ * @AfterSuite
+ */
+ public static function removeFilesFromSkeleton(){
+ for ($i=0; $i<5; $i++){
+ self::removeFile("../../core/skeleton/", "textfile" . "$i" . ".txt");
+ }
+ if (is_dir("../../core/skeleton/FOLDER")) {
+ rmdir("../../core/skeleton/FOLDER");
+ }
+ self::removeFile("../../core/skeleton/PARENT/CHILD/", "child.txt");
+ if (is_dir("../../core/skeleton/PARENT/CHILD")) {
+ rmdir("../../core/skeleton/PARENT/CHILD");
+ }
+ self::removeFile("../../core/skeleton/PARENT/", "parent.txt");
+ if (is_dir("../../core/skeleton/PARENT")) {
+ rmdir("../../core/skeleton/PARENT");
+ }
+ }
+}
+
diff --git a/build/integration/features/bootstrap/FeatureContext.php b/build/integration/features/bootstrap/FeatureContext.php
index caff517a16d..21ca8d87295 100644
--- a/build/integration/features/bootstrap/FeatureContext.php
+++ b/build/integration/features/bootstrap/FeatureContext.php
@@ -1,248 +1,14 @@
<?php
-use Behat\Behat\Context\BehatContext;
-use GuzzleHttp\Client;
-use GuzzleHttp\Message\ResponseInterface;
+use Behat\Behat\Context\Context;
+use Behat\Behat\Context\SnippetAcceptingContext;
require __DIR__ . '/../../vendor/autoload.php';
+
/**
* Features context.
*/
-class FeatureContext extends BehatContext {
-
- /** @var string */
- private $baseUrl = '';
-
- /** @var ResponseInterface */
- private $response = null;
-
- /** @var string */
- private $currentUser = '';
-
- /** @var int */
- private $apiVersion = 1;
-
- /**
- * Initializes context.
- * Every scenario gets it's own context object.
- *
- * @param array $parameters context parameters (set them up through behat.yml)
- */
- public function __construct(array $parameters) {
-
- // Initialize your context here
- $this->baseUrl = $parameters['baseUrl'];
- $this->adminUser = $parameters['admin'];
-
- // in case of ci deployment we take the server url from the environment
- $testServerUrl = getenv('TEST_SERVER_URL');
- if ($testServerUrl !== false) {
- $this->baseUrl = $testServerUrl;
- }
- }
-
- /**
- * @When /^sending "([^"]*)" to "([^"]*)"$/
- */
- public function sendingTo($verb, $url) {
- $this->sendingToWith($verb, $url, null);
- }
-
- /**
- * Parses the xml answer to get ocs response which doesn't match with
- * http one in v1 of the api.
- */
- public function getOCSResponse($response) {
- return $response->xml()->meta[0]->statuscode;
- }
-
- /**
- * Parses the xml answer to get the array of users returned.
- */
- public function getArrayOfUsersResponded($resp) {
- $listCheckedElements = $resp->xml()->data[0]->users[0]->element;
- $extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
- return $extractedElementsArray;
- }
-
- /**
- * Parses the xml answer to get the array of groups returned.
- */
- public function getArrayOfGroupsResponded($resp) {
- $listCheckedElements = $resp->xml()->data[0]->groups[0]->element;
- $extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
- return $extractedElementsArray;
- }
-
- /**
- * @Then /^users returned are$/
- * @param \Behat\Gherkin\Node\TableNode|null $formData
- */
- public function theUsersShouldBe($usersList) {
- if ($usersList instanceof \Behat\Gherkin\Node\TableNode) {
- $users = $usersList->getRows()[0];
- $respondedArray = $this->getArrayOfUsersResponded($this->response);
- PHPUnit_Framework_Assert::assertEquals(asort($users), asort($respondedArray));
- }
-
- }
-
- /**
- * @Then /^groups returned are$/
- * @param \Behat\Gherkin\Node\TableNode|null $formData
- */
- public function theGroupsShouldBe($groupsList) {
- if ($groupsList instanceof \Behat\Gherkin\Node\TableNode) {
- $groups = $groupsList->getRows()[0];
- $respondedArray = $this->getArrayOfGroupsResponded($this->response);
- PHPUnit_Framework_Assert::assertEquals(asort($groups), asort($respondedArray));
- }
-
- }
-
- /**
- * @Then /^the OCS status code should be "([^"]*)"$/
- */
- public function theOCSStatusCodeShouldBe($statusCode) {
- PHPUnit_Framework_Assert::assertEquals($statusCode, $this->getOCSResponse($this->response));
- }
-
- /**
- * @Then /^the HTTP status code should be "([^"]*)"$/
- */
- public function theHTTPStatusCodeShouldBe($statusCode) {
- PHPUnit_Framework_Assert::assertEquals($statusCode, $this->response->getStatusCode());
- }
-
- /**
- * @Given /^As an "([^"]*)"$/
- */
- public function asAn($user) {
- $this->currentUser = $user;
- }
-
- /**
- * @Given /^using api version "([^"]*)"$/
- */
- public function usingApiVersion($version) {
- $this->apiVersion = $version;
- }
-
- /**
- * @Given /^user "([^"]*)" exists$/
- */
- public function userExists($user) {
- $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user";
- $client = new Client();
- $options = [];
- if ($this->currentUser === 'admin') {
- $options['auth'] = $this->adminUser;
- }
-
- $this->response = $client->get($fullUrl, $options);
- PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
- }
-
- /**
- * @Given /^user "([^"]*)" does not exist$/
- */
- public function userDoesNotExist($user) {
- try {
- $this->userExists($user);
- PHPUnit_Framework_Assert::fail('The user "' . $user . '" exists');
- } catch (\GuzzleHttp\Exception\ClientException $ex) {
- $this->response = $ex->getResponse();
- PHPUnit_Framework_Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
- }
- }
-
- /**
- * @When /^creating the user "([^"]*)r"$/
- */
- public function creatingTheUser($user) {
- $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
- $client = new Client();
- $options = [];
- if ($this->currentUser === 'admin') {
- $options['auth'] = $this->adminUser;
- }
-
- $this->response = $client->post($fullUrl, [
- 'form_params' => [
- 'userid' => $user,
- 'password' => '123456'
- ]
- ]);
-
- }
-
- /**
- * @When /^creating the group "([^"]*)r"$/
- */
- public function creatingTheGroup($group) {
- $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups/addgroup";
- $client = new Client();
- $options = [];
- if ($this->currentUser === 'admin') {
- $options['auth'] = $this->adminUser;
- }
-
- $this->response = $client->post($fullUrl, [
- 'form_params' => [
- 'groupid' => $user
- ]
- ]);
- }
-
- /**
- * @Given /^group "([^"]*)" exists$/
- */
- public function groupExists($group) {
- $fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group";
- $client = new Client();
- $options = [];
- if ($this->currentUser === 'admin') {
- $options['auth'] = $this->adminUser;
- }
-
- $this->response = $client->get($fullUrl, $options);
- PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
- }
-
- /**
- * @Given /^group "([^"]*)" does not exist$/
- */
- public function groupDoesNotExist($group) {
- try {
- $this->groupExists($group);
- PHPUnit_Framework_Assert::fail('The group "' . $group . '" exists');
- } catch (\GuzzleHttp\Exception\ClientException $ex) {
- $this->response = $ex->getResponse();
- PHPUnit_Framework_Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
- }
- }
-
- /**
- * @When /^sending "([^"]*)" to "([^"]*)" with$/
- * @param \Behat\Gherkin\Node\TableNode|null $formData
- */
- public function sendingToWith($verb, $url, $body) {
- $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php" . $url;
- $client = new Client();
- $options = [];
- if ($this->currentUser === 'admin') {
- $options['auth'] = $this->adminUser;
- }
- if ($body instanceof \Behat\Gherkin\Node\TableNode) {
- $fd = $body->getRowsHash();
- $options['body'] = $fd;
- }
-
- try {
- $this->response = $client->send($client->createRequest($verb, $fullUrl, $options));
- } catch (\GuzzleHttp\Exception\ClientException $ex) {
- $this->response = $ex->getResponse();
- }
- }
+class FeatureContext implements Context, SnippetAcceptingContext {
+ use WebDav;
}
diff --git a/build/integration/features/bootstrap/FederationContext.php b/build/integration/features/bootstrap/FederationContext.php
new file mode 100644
index 00000000000..55f3a55da0d
--- /dev/null
+++ b/build/integration/features/bootstrap/FederationContext.php
@@ -0,0 +1,54 @@
+<?php
+
+use Behat\Behat\Context\Context;
+use Behat\Behat\Context\SnippetAcceptingContext;
+use GuzzleHttp\Client;
+use GuzzleHttp\Message\ResponseInterface;
+
+require __DIR__ . '/../../vendor/autoload.php';
+
+/**
+ * Federation context.
+ */
+class FederationContext implements Context, SnippetAcceptingContext {
+
+ use WebDav;
+
+ /**
+ * @Given /^User "([^"]*)" from server "(LOCAL|REMOTE)" shares "([^"]*)" with user "([^"]*)" from server "(LOCAL|REMOTE)"$/
+ *
+ * @param string $sharerUser
+ * @param string $sharerServer "LOCAL" or "REMOTE"
+ * @param string $sharerPath
+ * @param string $shareeUser
+ * @param string $shareeServer "LOCAL" or "REMOTE"
+ */
+ public function federateSharing($sharerUser, $sharerServer, $sharerPath, $shareeUser, $shareeServer){
+ if ($shareeServer == "REMOTE"){
+ $shareWith = "$shareeUser@" . substr($this->remoteBaseUrl, 0, -4);
+ } else {
+ $shareWith = "$shareeUser@" . substr($this->localBaseUrl, 0, -4);
+ }
+ $previous = $this->usingServer($sharerServer);
+ $this->createShare($sharerUser, $sharerPath, 6, $shareWith, null, null, null);
+ $this->usingServer($previous);
+ }
+
+ /**
+ * @When /^User "([^"]*)" from server "(LOCAL|REMOTE)" accepts last pending share$/
+ * @param string $user
+ * @param string $server
+ */
+ public function acceptLastPendingShare($user, $server){
+ $previous = $this->usingServer($server);
+ $this->asAn($user);
+ $this->sendingToWith('GET', "/apps/files_sharing/api/v1/remote_shares/pending", null);
+ $this->theHTTPStatusCodeShouldBe('200');
+ $this->theOCSStatusCodeShouldBe('100');
+ $share_id = $this->response->xml()->data[0]->element[0]->id;
+ $this->sendingToWith('POST', "/apps/files_sharing/api/v1/remote_shares/pending/{$share_id}", null);
+ $this->theHTTPStatusCodeShouldBe('200');
+ $this->theOCSStatusCodeShouldBe('100');
+ $this->usingServer($previous);
+ }
+}
diff --git a/build/integration/features/bootstrap/Provisioning.php b/build/integration/features/bootstrap/Provisioning.php
new file mode 100644
index 00000000000..6cf57514483
--- /dev/null
+++ b/build/integration/features/bootstrap/Provisioning.php
@@ -0,0 +1,656 @@
+<?php
+
+use GuzzleHttp\Client;
+use GuzzleHttp\Message\ResponseInterface;
+
+require __DIR__ . '/../../vendor/autoload.php';
+
+trait Provisioning {
+ use BasicStructure;
+
+ /** @var array */
+ private $createdUsers = [];
+
+ /** @var array */
+ private $createdRemoteUsers = [];
+
+ /** @var array */
+ private $createdRemoteGroups = [];
+
+ /** @var array */
+ private $createdGroups = [];
+
+ /**
+ * @Given /^user "([^"]*)" exists$/
+ * @param string $user
+ */
+ public function assureUserExists($user) {
+ try {
+ $this->userExists($user);
+ } catch (\GuzzleHttp\Exception\ClientException $ex) {
+ $previous_user = $this->currentUser;
+ $this->currentUser = "admin";
+ $this->creatingTheUser($user);
+ $this->currentUser = $previous_user;
+ }
+ $this->userExists($user);
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ /**
+ * @Given /^user "([^"]*)" does not exist$/
+ * @param string $user
+ */
+ public function userDoesNotExist($user) {
+ try {
+ $this->userExists($user);
+ } catch (\GuzzleHttp\Exception\ClientException $ex) {
+ $this->response = $ex->getResponse();
+ PHPUnit_Framework_Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
+ return;
+ }
+ $previous_user = $this->currentUser;
+ $this->currentUser = "admin";
+ $this->deletingTheUser($user);
+ $this->currentUser = $previous_user;
+ try {
+ $this->userExists($user);
+ } catch (\GuzzleHttp\Exception\ClientException $ex) {
+ $this->response = $ex->getResponse();
+ PHPUnit_Framework_Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
+ }
+ }
+
+ public function creatingTheUser($user) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $options['body'] = [
+ 'userid' => $user,
+ 'password' => '123456'
+ ];
+
+ $this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
+ if ($this->currentServer === 'LOCAL'){
+ $this->createdUsers[$user] = $user;
+ } elseif ($this->currentServer === 'REMOTE') {
+ $this->createdRemoteUsers[$user] = $user;
+ }
+
+ //Quick hack to login once with the current user
+ $options2 = [
+ 'auth' => [$user, '123456'],
+ ];
+ $url = $fullUrl.'/'.$user;
+ $client->send($client->createRequest('GET', $url, $options2));
+ }
+
+ public function createUser($user) {
+ $previous_user = $this->currentUser;
+ $this->currentUser = "admin";
+ $this->creatingTheUser($user);
+ $this->userExists($user);
+ $this->currentUser = $previous_user;
+ }
+
+ public function deleteUser($user) {
+ $previous_user = $this->currentUser;
+ $this->currentUser = "admin";
+ $this->deletingTheUser($user);
+ $this->userDoesNotExist($user);
+ $this->currentUser = $previous_user;
+ }
+
+ public function createGroup($group) {
+ $previous_user = $this->currentUser;
+ $this->currentUser = "admin";
+ $this->creatingTheGroup($group);
+ $this->groupExists($group);
+ $this->currentUser = $previous_user;
+ }
+
+ public function deleteGroup($group) {
+ $previous_user = $this->currentUser;
+ $this->currentUser = "admin";
+ $this->deletingTheGroup($group);
+ $this->groupDoesNotExist($group);
+ $this->currentUser = $previous_user;
+ }
+
+ public function userExists($user){
+ $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user";
+ $client = new Client();
+ $options = [];
+ $options['auth'] = $this->adminUser;
+
+ $this->response = $client->get($fullUrl, $options);
+ }
+
+ /**
+ * @Then /^check that user "([^"]*)" belongs to group "([^"]*)"$/
+ * @param string $user
+ * @param string $group
+ */
+ public function checkThatUserBelongsToGroup($user, $group) {
+ $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ $respondedArray = $this->getArrayOfGroupsResponded($this->response);
+ sort($respondedArray);
+ PHPUnit_Framework_Assert::assertContains($group, $respondedArray);
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ public function userBelongsToGroup($user, $group) {
+ $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ $respondedArray = $this->getArrayOfGroupsResponded($this->response);
+
+ if (array_key_exists($group, $respondedArray)) {
+ return True;
+ } else{
+ return False;
+ }
+ }
+
+ /**
+ * @Given /^user "([^"]*)" belongs to group "([^"]*)"$/
+ * @param string $user
+ * @param string $group
+ */
+ public function assureUserBelongsToGroup($user, $group){
+ $previous_user = $this->currentUser;
+ $this->currentUser = "admin";
+
+ if (!$this->userBelongsToGroup($user, $group)){
+ $this->addingUserToGroup($user, $group);
+ }
+
+ $this->checkThatUserBelongsToGroup($user, $group);
+ $this->currentUser = $previous_user;
+ }
+
+ /**
+ * @Given /^user "([^"]*)" does not belong to group "([^"]*)"$/
+ * @param string $user
+ * @param string $group
+ */
+ public function userDoesNotBelongToGroup($user, $group) {
+ $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ $groups = array($group);
+ $respondedArray = $this->getArrayOfGroupsResponded($this->response);
+ PHPUnit_Framework_Assert::assertNotEquals($groups, $respondedArray, "", 0.0, 10, true);
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ /**
+ * @When /^creating the group "([^"]*)"$/
+ * @param string $group
+ */
+ public function creatingTheGroup($group) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $options['body'] = [
+ 'groupid' => $group,
+ ];
+
+ $this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
+ if ($this->currentServer === 'LOCAL'){
+ $this->createdGroups[$group] = $group;
+ } elseif ($this->currentServer === 'REMOTE') {
+ $this->createdRemoteGroups[$group] = $group;
+ }
+ }
+
+ /**
+ * @When /^assure user "([^"]*)" is disabled$/
+ */
+ public function assureUserIsDisabled($user) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/disable";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->send($client->createRequest("PUT", $fullUrl, $options));
+ }
+
+ /**
+ * @When /^Deleting the user "([^"]*)"$/
+ * @param string $user
+ */
+ public function deletingTheUser($user) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->send($client->createRequest("DELETE", $fullUrl, $options));
+ }
+
+ /**
+ * @When /^Deleting the group "([^"]*)"$/
+ * @param string $group
+ */
+ public function deletingTheGroup($group) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups/$group";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->send($client->createRequest("DELETE", $fullUrl, $options));
+ }
+
+ /**
+ * @Given /^Add user "([^"]*)" to the group "([^"]*)"$/
+ * @param string $user
+ * @param string $group
+ */
+ public function addUserToGroup($user, $group) {
+ $this->userExists($user);
+ $this->groupExists($group);
+ $this->addingUserToGroup($user, $group);
+
+ }
+
+ /**
+ * @When /^User "([^"]*)" is added to the group "([^"]*)"$/
+ * @param string $user
+ * @param string $group
+ */
+ public function addingUserToGroup($user, $group) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/groups";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $options['body'] = [
+ 'groupid' => $group,
+ ];
+
+ $this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
+ }
+
+
+ public function groupExists($group) {
+ $fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group";
+ $client = new Client();
+ $options = [];
+ $options['auth'] = $this->adminUser;
+
+ $this->response = $client->get($fullUrl, $options);
+ }
+
+ /**
+ * @Given /^group "([^"]*)" exists$/
+ * @param string $group
+ */
+ public function assureGroupExists($group) {
+ try {
+ $this->groupExists($group);
+ } catch (\GuzzleHttp\Exception\ClientException $ex) {
+ $previous_user = $this->currentUser;
+ $this->currentUser = "admin";
+ $this->creatingTheGroup($group);
+ $this->currentUser = $previous_user;
+ }
+ $this->groupExists($group);
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ /**
+ * @Given /^group "([^"]*)" does not exist$/
+ * @param string $group
+ */
+ public function groupDoesNotExist($group) {
+ try {
+ $this->groupExists($group);
+ } catch (\GuzzleHttp\Exception\ClientException $ex) {
+ $this->response = $ex->getResponse();
+ PHPUnit_Framework_Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
+ return;
+ }
+ $previous_user = $this->currentUser;
+ $this->currentUser = "admin";
+ $this->deletingTheGroup($group);
+ $this->currentUser = $previous_user;
+ try {
+ $this->groupExists($group);
+ } catch (\GuzzleHttp\Exception\ClientException $ex) {
+ $this->response = $ex->getResponse();
+ PHPUnit_Framework_Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
+ }
+ }
+
+ /**
+ * @Given /^user "([^"]*)" is subadmin of group "([^"]*)"$/
+ * @param string $user
+ * @param string $group
+ */
+ public function userIsSubadminOfGroup($user, $group) {
+ $fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group/subadmins";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ $respondedArray = $this->getArrayOfSubadminsResponded($this->response);
+ sort($respondedArray);
+ PHPUnit_Framework_Assert::assertContains($user, $respondedArray);
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ /**
+ * @Given /^Assure user "([^"]*)" is subadmin of group "([^"]*)"$/
+ * @param string $user
+ * @param string $group
+ */
+ public function assureUserIsSubadminOfGroup($user, $group) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/subadmins";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+ $options['body'] = [
+ 'groupid' => $group
+ ];
+ $this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ /**
+ * @Given /^user "([^"]*)" is not a subadmin of group "([^"]*)"$/
+ * @param string $user
+ * @param string $group
+ */
+ public function userIsNotSubadminOfGroup($user, $group) {
+ $fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group/subadmins";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ $respondedArray = $this->getArrayOfSubadminsResponded($this->response);
+ sort($respondedArray);
+ PHPUnit_Framework_Assert::assertNotContains($user, $respondedArray);
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ /**
+ * @Then /^users returned are$/
+ * @param \Behat\Gherkin\Node\TableNode|null $usersList
+ */
+ public function theUsersShouldBe($usersList) {
+ if ($usersList instanceof \Behat\Gherkin\Node\TableNode) {
+ $users = $usersList->getRows();
+ $usersSimplified = $this->simplifyArray($users);
+ $respondedArray = $this->getArrayOfUsersResponded($this->response);
+ PHPUnit_Framework_Assert::assertEquals($usersSimplified, $respondedArray, "", 0.0, 10, true);
+ }
+
+ }
+
+ /**
+ * @Then /^groups returned are$/
+ * @param \Behat\Gherkin\Node\TableNode|null $groupsList
+ */
+ public function theGroupsShouldBe($groupsList) {
+ if ($groupsList instanceof \Behat\Gherkin\Node\TableNode) {
+ $groups = $groupsList->getRows();
+ $groupsSimplified = $this->simplifyArray($groups);
+ $respondedArray = $this->getArrayOfGroupsResponded($this->response);
+ PHPUnit_Framework_Assert::assertEquals($groupsSimplified, $respondedArray, "", 0.0, 10, true);
+ }
+
+ }
+
+ /**
+ * @Then /^subadmin groups returned are$/
+ * @param \Behat\Gherkin\Node\TableNode|null $groupsList
+ */
+ public function theSubadminGroupsShouldBe($groupsList) {
+ if ($groupsList instanceof \Behat\Gherkin\Node\TableNode) {
+ $groups = $groupsList->getRows();
+ $groupsSimplified = $this->simplifyArray($groups);
+ $respondedArray = $this->getArrayOfSubadminsResponded($this->response);
+ PHPUnit_Framework_Assert::assertEquals($groupsSimplified, $respondedArray, "", 0.0, 10, true);
+ }
+
+ }
+
+ /**
+ * @Then /^apps returned are$/
+ * @param \Behat\Gherkin\Node\TableNode|null $appList
+ */
+ public function theAppsShouldBe($appList) {
+ if ($appList instanceof \Behat\Gherkin\Node\TableNode) {
+ $apps = $appList->getRows();
+ $appsSimplified = $this->simplifyArray($apps);
+ $respondedArray = $this->getArrayOfAppsResponded($this->response);
+ PHPUnit_Framework_Assert::assertEquals($appsSimplified, $respondedArray, "", 0.0, 10, true);
+ }
+
+ }
+
+ /**
+ * @Then /^subadmin users returned are$/
+ * @param \Behat\Gherkin\Node\TableNode|null $groupsList
+ */
+ public function theSubadminUsersShouldBe($groupsList) {
+ $this->theSubadminGroupsShouldBe($groupsList);
+ }
+
+ /**
+ * Parses the xml answer to get the array of users returned.
+ * @param ResponseInterface $resp
+ * @return array
+ */
+ public function getArrayOfUsersResponded($resp) {
+ $listCheckedElements = $resp->xml()->data[0]->users[0]->element;
+ $extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
+ return $extractedElementsArray;
+ }
+
+ /**
+ * Parses the xml answer to get the array of groups returned.
+ * @param ResponseInterface $resp
+ * @return array
+ */
+ public function getArrayOfGroupsResponded($resp) {
+ $listCheckedElements = $resp->xml()->data[0]->groups[0]->element;
+ $extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
+ return $extractedElementsArray;
+ }
+
+ /**
+ * Parses the xml answer to get the array of apps returned.
+ * @param ResponseInterface $resp
+ * @return array
+ */
+ public function getArrayOfAppsResponded($resp) {
+ $listCheckedElements = $resp->xml()->data[0]->apps[0]->element;
+ $extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
+ return $extractedElementsArray;
+ }
+
+ /**
+ * Parses the xml answer to get the array of subadmins returned.
+ * @param ResponseInterface $resp
+ * @return array
+ */
+ public function getArrayOfSubadminsResponded($resp) {
+ $listCheckedElements = $resp->xml()->data[0]->element;
+ $extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
+ return $extractedElementsArray;
+ }
+
+
+ /**
+ * @Given /^app "([^"]*)" is disabled$/
+ * @param string $app
+ */
+ public function appIsDisabled($app) {
+ $fullUrl = $this->baseUrl . "v2.php/cloud/apps?filter=disabled";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ $respondedArray = $this->getArrayOfAppsResponded($this->response);
+ PHPUnit_Framework_Assert::assertContains($app, $respondedArray);
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ /**
+ * @Given /^app "([^"]*)" is enabled$/
+ * @param string $app
+ */
+ public function appIsEnabled($app) {
+ $fullUrl = $this->baseUrl . "v2.php/cloud/apps?filter=enabled";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ $respondedArray = $this->getArrayOfAppsResponded($this->response);
+ PHPUnit_Framework_Assert::assertContains($app, $respondedArray);
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ /**
+ * @Then /^user "([^"]*)" is disabled$/
+ * @param string $user
+ */
+ public function userIsDisabled($user) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ PHPUnit_Framework_Assert::assertEquals("false", $this->response->xml()->data[0]->enabled);
+ }
+
+ /**
+ * @Then /^user "([^"]*)" is enabled$/
+ * @param string $user
+ */
+ public function userIsEnabled($user) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ PHPUnit_Framework_Assert::assertEquals("true", $this->response->xml()->data[0]->enabled);
+ }
+
+ /**
+ * @Given user :user has a quota of :quota
+ * @param string $user
+ * @param string $quota
+ */
+ public function userHasAQuotaOf($user, $quota)
+ {
+ $body = new \Behat\Gherkin\Node\TableNode([
+ 0 => ['key', 'quota'],
+ 1 => ['value', $quota],
+ ]);
+
+ // method used from BasicStructure trait
+ $this->sendingToWith("PUT", "/cloud/users/" . $user, $body);
+ }
+
+ /**
+ * @Given user :user has unlimited quota
+ * @param string $user
+ */
+ public function userHasUnlimitedQuota($user)
+ {
+ $this->userHasAQuotaOf($user, 'none');
+ }
+
+ /**
+ * @BeforeScenario
+ * @AfterScenario
+ */
+ public function cleanupUsers()
+ {
+ $previousServer = $this->currentServer;
+ $this->usingServer('LOCAL');
+ foreach($this->createdUsers as $user) {
+ $this->deleteUser($user);
+ }
+ $this->usingServer('REMOTE');
+ foreach($this->createdRemoteUsers as $remoteUser) {
+ $this->deleteUser($remoteUser);
+ }
+ $this->usingServer($previousServer);
+ }
+
+ /**
+ * @BeforeScenario
+ * @AfterScenario
+ */
+ public function cleanupGroups()
+ {
+ $previousServer = $this->currentServer;
+ $this->usingServer('LOCAL');
+ foreach($this->createdGroups as $group) {
+ $this->deleteGroup($group);
+ }
+ $this->usingServer('REMOTE');
+ foreach($this->createdRemoteGroups as $remoteGroup) {
+ $this->deleteUser($remoteGroup);
+ }
+ $this->usingServer($previousServer);
+ }
+
+}
diff --git a/build/integration/features/bootstrap/Sharing.php b/build/integration/features/bootstrap/Sharing.php
new file mode 100644
index 00000000000..39ec4397bab
--- /dev/null
+++ b/build/integration/features/bootstrap/Sharing.php
@@ -0,0 +1,498 @@
+<?php
+
+use GuzzleHttp\Client;
+use GuzzleHttp\Message\ResponseInterface;
+
+require __DIR__ . '/../../vendor/autoload.php';
+
+
+
+trait Sharing {
+ use Provisioning;
+
+ /** @var int */
+ private $sharingApiVersion = 1;
+
+ /** @var SimpleXMLElement */
+ private $lastShareData = null;
+
+ /** @var int */
+ private $savedShareId = null;
+
+ /**
+ * @Given /^as "([^"]*)" creating a share with$/
+ * @param string $user
+ * @param \Behat\Gherkin\Node\TableNode|null $body
+ */
+ public function asCreatingAShareWith($user, $body) {
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares";
+ $client = new Client();
+ $options = [];
+ if ($user === 'admin') {
+ $options['auth'] = $this->adminUser;
+ } else {
+ $options['auth'] = [$user, $this->regularUser];
+ }
+
+ if ($body instanceof \Behat\Gherkin\Node\TableNode) {
+ $fd = $body->getRowsHash();
+ if (array_key_exists('expireDate', $fd)){
+ $dateModification = $fd['expireDate'];
+ $fd['expireDate'] = date('Y-m-d', strtotime($dateModification));
+ }
+ $options['body'] = $fd;
+ }
+
+ try {
+ $this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
+ } catch (\GuzzleHttp\Exception\ClientException $ex) {
+ $this->response = $ex->getResponse();
+ }
+
+ $this->lastShareData = $this->response->xml();
+ }
+
+ /**
+ * @When /^creating a share with$/
+ * @param \Behat\Gherkin\Node\TableNode|null $body
+ */
+ public function creatingShare($body) {
+ $this->asCreatingAShareWith($this->currentUser, $body);
+ }
+
+ /**
+ * @Then /^Public shared file "([^"]*)" can be downloaded$/
+ */
+ public function checkPublicSharedFile($filename) {
+ $client = new Client();
+ $options = [];
+ if (count($this->lastShareData->data->element) > 0){
+ $url = $this->lastShareData->data[0]->url;
+ }
+ else{
+ $url = $this->lastShareData->data->url;
+ }
+ $fullUrl = $url . "/download";
+ $options['save_to'] = "./$filename";
+ $this->response = $client->get($fullUrl, $options);
+ $finfo = new finfo;
+ $fileinfo = $finfo->file("./$filename", FILEINFO_MIME_TYPE);
+ PHPUnit_Framework_Assert::assertEquals($fileinfo, "text/plain");
+ if (file_exists("./$filename")) {
+ unlink("./$filename");
+ }
+ }
+
+ /**
+ * @Then /^Public shared file "([^"]*)" with password "([^"]*)" can be downloaded$/
+ */
+ public function checkPublicSharedFileWithPassword($filename, $password) {
+ $client = new Client();
+ $options = [];
+ if (count($this->lastShareData->data->element) > 0){
+ $token = $this->lastShareData->data[0]->token;
+ }
+ else{
+ $token = $this->lastShareData->data->token;
+ }
+
+ $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/webdav";
+ $options['auth'] = [$token, $password];
+ $options['save_to'] = "./$filename";
+ $this->response = $client->get($fullUrl, $options);
+ $finfo = new finfo;
+ $fileinfo = $finfo->file("./$filename", FILEINFO_MIME_TYPE);
+ PHPUnit_Framework_Assert::assertEquals($fileinfo, "text/plain");
+ if (file_exists("./$filename")) {
+ unlink("./$filename");
+ }
+ }
+
+ /**
+ * @When /^Adding expiration date to last share$/
+ */
+ public function addingExpirationDate() {
+ $share_id = (string) $this->lastShareData->data[0]->id;
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares/$share_id";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ } else {
+ $options['auth'] = [$this->currentUser, $this->regularUser];
+ }
+ $date = date('Y-m-d', strtotime("+3 days"));
+ $options['body'] = ['expireDate' => $date];
+ $this->response = $client->send($client->createRequest("PUT", $fullUrl, $options));
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ /**
+ * @When /^Updating last share with$/
+ * @param \Behat\Gherkin\Node\TableNode|null $body
+ */
+ public function updatingLastShare($body) {
+ $share_id = (string) $this->lastShareData->data[0]->id;
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares/$share_id";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ } else {
+ $options['auth'] = [$this->currentUser, $this->regularUser];
+ }
+
+ if ($body instanceof \Behat\Gherkin\Node\TableNode) {
+ $fd = $body->getRowsHash();
+ if (array_key_exists('expireDate', $fd)){
+ $dateModification = $fd['expireDate'];
+ $fd['expireDate'] = date('Y-m-d', strtotime($dateModification));
+ }
+ $options['body'] = $fd;
+ }
+
+ try {
+ $this->response = $client->send($client->createRequest("PUT", $fullUrl, $options));
+ } catch (\GuzzleHttp\Exception\ClientException $ex) {
+ $this->response = $ex->getResponse();
+ }
+
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ public function createShare($user,
+ $path = null,
+ $shareType = null,
+ $shareWith = null,
+ $publicUpload = null,
+ $password = null,
+ $permissions = null){
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares";
+ $client = new Client();
+ $options = [];
+
+ if ($user === 'admin') {
+ $options['auth'] = $this->adminUser;
+ } else {
+ $options['auth'] = [$user, $this->regularUser];
+ }
+ $fd = [];
+ if (!is_null($path)){
+ $fd['path'] = $path;
+ }
+ if (!is_null($shareType)){
+ $fd['shareType'] = $shareType;
+ }
+ if (!is_null($shareWith)){
+ $fd['shareWith'] = $shareWith;
+ }
+ if (!is_null($publicUpload)){
+ $fd['publicUpload'] = $publicUpload;
+ }
+ if (!is_null($password)){
+ $fd['password'] = $password;
+ }
+ if (!is_null($permissions)){
+ $fd['permissions'] = $permissions;
+ }
+
+ $options['body'] = $fd;
+
+ try {
+ $this->response = $client->send($client->createRequest("POST", $fullUrl, $options));
+ $this->lastShareData = $this->response->xml();
+ } catch (\GuzzleHttp\Exception\ClientException $ex) {
+ $this->response = $ex->getResponse();
+ }
+ }
+
+ public function isFieldInResponse($field, $contentExpected){
+ $data = $this->response->xml()->data[0];
+ if ((string)$field == 'expiration'){
+ $contentExpected = date('Y-m-d', strtotime($contentExpected)) . " 00:00:00";
+ }
+
+ if (count($data->element) > 0){
+ foreach($data as $element) {
+ if ($contentExpected == "A_TOKEN"){
+ return (strlen((string)$element->$field) == 15);
+ }
+ elseif ($contentExpected == "A_NUMBER"){
+ return is_numeric((string)$element->$field);
+ }
+ elseif($contentExpected == "AN_URL"){
+ return $this->isExpectedUrl((string)$element->$field, "index.php/s/");
+ }
+ elseif ((string)$element->$field == $contentExpected){
+ return True;
+ }
+ else{
+ print($element->$field);
+ }
+ }
+
+ return False;
+ } else {
+ if ($contentExpected == "A_TOKEN"){
+ return (strlen((string)$data->$field) == 15);
+ }
+ elseif ($contentExpected == "A_NUMBER"){
+ return is_numeric((string)$data->$field);
+ }
+ elseif($contentExpected == "AN_URL"){
+ return $this->isExpectedUrl((string)$data->$field, "index.php/s/");
+ }
+ elseif ($data->$field == $contentExpected){
+ return True;
+ }
+ return False;
+ }
+ }
+
+ /**
+ * @Then /^File "([^"]*)" should be included in the response$/
+ *
+ * @param string $filename
+ */
+ public function checkSharedFileInResponse($filename){
+ PHPUnit_Framework_Assert::assertEquals(True, $this->isFieldInResponse('file_target', "/$filename"));
+ }
+
+ /**
+ * @Then /^File "([^"]*)" should not be included in the response$/
+ *
+ * @param string $filename
+ */
+ public function checkSharedFileNotInResponse($filename){
+ PHPUnit_Framework_Assert::assertEquals(False, $this->isFieldInResponse('file_target', "/$filename"));
+ }
+
+ /**
+ * @Then /^User "([^"]*)" should be included in the response$/
+ *
+ * @param string $user
+ */
+ public function checkSharedUserInResponse($user){
+ PHPUnit_Framework_Assert::assertEquals(True, $this->isFieldInResponse('share_with', "$user"));
+ }
+
+ /**
+ * @Then /^User "([^"]*)" should not be included in the response$/
+ *
+ * @param string $user
+ */
+ public function checkSharedUserNotInResponse($user){
+ PHPUnit_Framework_Assert::assertEquals(False, $this->isFieldInResponse('share_with', "$user"));
+ }
+
+ public function isUserOrGroupInSharedData($userOrGroup){
+ $data = $this->response->xml()->data[0];
+ foreach($data as $element) {
+ if ($element->share_with == $userOrGroup){
+ return True;
+ }
+ }
+ return False;
+ }
+
+ /**
+ * @Given /^file "([^"]*)" of user "([^"]*)" is shared with user "([^"]*)"$/
+ *
+ * @param string $filepath
+ * @param string $user1
+ * @param string $user2
+ */
+ public function assureFileIsShared($filepath, $user1, $user2){
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares" . "?path=$filepath";
+ $client = new Client();
+ $options = [];
+ if ($user1 === 'admin') {
+ $options['auth'] = $this->adminUser;
+ } else {
+ $options['auth'] = [$user1, $this->regularUser];
+ }
+ $this->response = $client->get($fullUrl, $options);
+ if ($this->isUserOrGroupInSharedData($user2)){
+ return;
+ } else {
+ $this->createShare($user1, $filepath, 0, $user2, null, null, null);
+ }
+ $this->response = $client->get($fullUrl, $options);
+ PHPUnit_Framework_Assert::assertEquals(True, $this->isUserOrGroupInSharedData($user2));
+ }
+
+ /**
+ * @Given /^file "([^"]*)" of user "([^"]*)" is shared with group "([^"]*)"$/
+ *
+ * @param string $filepath
+ * @param string $user
+ * @param string $group
+ */
+ public function assureFileIsSharedWithGroup($filepath, $user, $group){
+ $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares" . "?path=$filepath";
+ $client = new Client();
+ $options = [];
+ if ($user === 'admin') {
+ $options['auth'] = $this->adminUser;
+ } else {
+ $options['auth'] = [$user, $this->regularUser];
+ }
+ $this->response = $client->get($fullUrl, $options);
+ if ($this->isUserOrGroupInSharedData($group)){
+ return;
+ } else {
+ $this->createShare($user, $filepath, 1, $group, null, null, null);
+ }
+ $this->response = $client->get($fullUrl, $options);
+ PHPUnit_Framework_Assert::assertEquals(True, $this->isUserOrGroupInSharedData($group));
+ }
+
+ /**
+ * @When /^Deleting last share$/
+ */
+ public function deletingLastShare(){
+ $share_id = $this->lastShareData->data[0]->id;
+ $url = "/apps/files_sharing/api/v{$this->sharingApiVersion}/shares/$share_id";
+ $this->sendingToWith("DELETE", $url, null);
+ }
+
+ /**
+ * @When /^Getting info of last share$/
+ */
+ public function gettingInfoOfLastShare(){
+ $share_id = $this->lastShareData->data[0]->id;
+ $url = "/apps/files_sharing/api/v{$this->sharingApiVersion}/shares/$share_id";
+ $this->sendingToWith("GET", $url, null);
+ }
+
+ /**
+ * @Then /^last share_id is included in the answer$/
+ */
+ public function checkingLastShareIDIsIncluded(){
+ $share_id = $this->lastShareData->data[0]->id;
+ if (!$this->isFieldInResponse('id', $share_id)){
+ PHPUnit_Framework_Assert::fail("Share id $share_id not found in response");
+ }
+ }
+
+ /**
+ * @Then /^last share_id is included in the answer as parent$/
+ */
+ public function checkingLastShareIDIsIncludedAsParent(){
+ $share_id = $this->lastShareData->data[0]->id;
+ //This is a problem before 9.0, setupFS is called with every api call so a new share id is created
+ //we just need to check the parent id to match with the returned id.
+ if (!$this->isFieldInResponse('parent', $share_id)){
+ PHPUnit_Framework_Assert::fail("Share id $share_id not found in response as parent");
+ }
+ }
+
+ /**
+ * @Then /^last share_id is not included in the answer$/
+ */
+ public function checkingLastShareIDIsNotIncluded(){
+ $share_id = $this->lastShareData->data[0]->id;
+ if ($this->isFieldInResponse('id', $share_id)){
+ PHPUnit_Framework_Assert::fail("Share id $share_id has been found in response");
+ }
+ }
+
+ /**
+ * @Then /^last share_id is not included in the answer as parent$/
+ */
+ public function checkingLastShareIDIsNotIncludedAsParent(){
+ $share_id = $this->lastShareData->data[0]->id;
+ //This is a problem before 9.0, setupFS is called with every api call so a new share id is created
+ //we just need to check the parent id to match with the returned id.
+ if ($this->isFieldInResponse('parent', $share_id)){
+ PHPUnit_Framework_Assert::fail("Share id $share_id has been found in response as parent");
+ }
+ }
+
+ /**
+ * @Then /^Share fields of last share match with$/
+ * @param \Behat\Gherkin\Node\TableNode|null $body
+ */
+ public function checkShareFields($body){
+ if ($body instanceof \Behat\Gherkin\Node\TableNode) {
+ $fd = $body->getRowsHash();
+
+ foreach($fd as $field => $value) {
+ if (substr($field, 0, 10 ) === "share_with"){
+ $value = str_replace("REMOTE", substr($this->remoteBaseUrl, 0, -5), $value);
+ $value = str_replace("LOCAL", substr($this->localBaseUrl, 0, -5), $value);
+ }
+ if (substr($field, 0, 6 ) === "remote"){
+ $value = str_replace("REMOTE", substr($this->remoteBaseUrl, 0, -4), $value);
+ $value = str_replace("LOCAL", substr($this->localBaseUrl, 0, -4), $value);
+ }
+ if (!$this->isFieldInResponse($field, $value)){
+ PHPUnit_Framework_Assert::fail("$field" . " doesn't have value " . "$value");
+ }
+ }
+ }
+ }
+
+ /**
+ * @Then As :user remove all shares from the file named :fileName
+ */
+ public function asRemoveAllSharesFromTheFileNamed($user, $fileName) {
+ $url = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares?format=json";
+ $client = new \GuzzleHttp\Client();
+ $res = $client->get(
+ $url,
+ [
+ 'auth' => [
+ $user,
+ '123456',
+ ],
+ 'headers' => [
+ 'Content-Type' => 'application/json',
+ ],
+ ]
+ );
+ $json = json_decode($res->getBody()->getContents(), true);
+ $deleted = false;
+ foreach($json['ocs']['data'] as $data) {
+ if (stripslashes($data['path']) === $fileName) {
+ $id = $data['id'];
+ $client->delete(
+ $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares/{$id}",
+ [
+ 'auth' => [
+ $user,
+ '123456',
+ ],
+ 'headers' => [
+ 'Content-Type' => 'application/json',
+ ],
+ ]
+ );
+ $deleted = true;
+ }
+ }
+
+ if($deleted === false) {
+ throw new \Exception("Could not delete file $fileName");
+ }
+ }
+
+ /**
+ * @When save last share id
+ */
+ public function saveLastShareId()
+ {
+ $this->savedShareId = $this->lastShareData['data']['id'];
+ }
+
+ /**
+ * @Then share ids should match
+ */
+ public function shareIdsShouldMatch()
+ {
+ if ($this->savedShareId !== $this->lastShareData['data']['id']) {
+ throw new \Exception('Expected the same link share to be returned');
+ }
+ }
+}
+
diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php
new file mode 100644
index 00000000000..3df37db72bb
--- /dev/null
+++ b/build/integration/features/bootstrap/WebDav.php
@@ -0,0 +1,508 @@
+<?php
+
+use GuzzleHttp\Client as GClient;
+use GuzzleHttp\Message\ResponseInterface;
+use Sabre\DAV\Client as SClient;
+
+require __DIR__ . '/../../vendor/autoload.php';
+
+
+trait WebDav {
+ use Sharing;
+
+ /** @var string*/
+ private $davPath = "remote.php/webdav";
+ /** @var ResponseInterface */
+ private $response;
+
+ /**
+ * @Given /^using dav path "([^"]*)"$/
+ */
+ public function usingDavPath($davPath) {
+ $this->davPath = $davPath;
+ }
+
+ public function makeDavRequest($user, $method, $path, $headers, $body = null){
+ $fullUrl = substr($this->baseUrl, 0, -4) . $this->davPath . "$path";
+ $client = new GClient();
+ $options = [];
+ if ($user === 'admin') {
+ $options['auth'] = $this->adminUser;
+ } else {
+ $options['auth'] = [$user, $this->regularUser];
+ }
+ $request = $client->createRequest($method, $fullUrl, $options);
+ if (!is_null($headers)){
+ foreach ($headers as $key => $value) {
+ $request->addHeader($key, $value);
+ }
+ }
+
+ if (!is_null($body)) {
+ $request->setBody($body);
+ }
+
+ return $client->send($request);
+ }
+
+ /**
+ * @Given /^User "([^"]*)" moved file "([^"]*)" to "([^"]*)"$/
+ * @param string $user
+ * @param string $fileSource
+ * @param string $fileDestination
+ */
+ public function userMovedFile($user, $fileSource, $fileDestination){
+ $fullUrl = substr($this->baseUrl, 0, -4) . $this->davPath;
+ $headers['Destination'] = $fullUrl . $fileDestination;
+ $this->response = $this->makeDavRequest($user, "MOVE", $fileSource, $headers);
+ PHPUnit_Framework_Assert::assertEquals(201, $this->response->getStatusCode());
+ }
+
+ /**
+ * @When /^User "([^"]*)" moves file "([^"]*)" to "([^"]*)"$/
+ * @param string $user
+ * @param string $fileSource
+ * @param string $fileDestination
+ */
+ public function userMovesFile($user, $fileSource, $fileDestination){
+ $fullUrl = substr($this->baseUrl, 0, -4) . $this->davPath;
+ $headers['Destination'] = $fullUrl . $fileDestination;
+ try {
+ $this->response = $this->makeDavRequest($user, "MOVE", $fileSource, $headers);
+ } catch (\GuzzleHttp\Exception\ClientException $e) {
+ $this->response = $e->getResponse();
+ }
+ }
+
+ /**
+ * @When /^User "([^"]*)" copies file "([^"]*)" to "([^"]*)"$/
+ * @param string $user
+ * @param string $fileSource
+ * @param string $fileDestination
+ */
+ public function userCopiesFile($user, $fileSource, $fileDestination){
+ $fullUrl = substr($this->baseUrl, 0, -4) . $this->davPath;
+ $headers['Destination'] = $fullUrl . $fileDestination;
+ try {
+ $this->response = $this->makeDavRequest($user, "COPY", $fileSource, $headers);
+ } catch (\GuzzleHttp\Exception\ClientException $e) {
+ $this->response = $e->getResponse();
+ }
+ }
+
+ /**
+ * @When /^Downloading file "([^"]*)" with range "([^"]*)"$/
+ * @param string $fileSource
+ * @param string $range
+ */
+ public function downloadFileWithRange($fileSource, $range){
+ $headers['Range'] = $range;
+ $this->response = $this->makeDavRequest($this->currentUser, "GET", $fileSource, $headers);
+ }
+
+ /**
+ * @When /^Downloading last public shared file with range "([^"]*)"$/
+ * @param string $range
+ */
+ public function downloadPublicFileWithRange($range){
+ $token = $this->lastShareData->data->token;
+ $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/webdav";
+ $headers['Range'] = $range;
+
+ $client = new GClient();
+ $options = [];
+ $options['auth'] = [$token, ""];
+
+ $request = $client->createRequest("GET", $fullUrl, $options);
+ $request->addHeader('Range', $range);
+
+ $this->response = $client->send($request);
+ }
+
+ /**
+ * @When /^Downloading last public shared file inside a folder "([^"]*)" with range "([^"]*)"$/
+ * @param string $range
+ */
+ public function downloadPublicFileInsideAFolderWithRange($path, $range){
+ $token = $this->lastShareData->data->token;
+ $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/webdav" . "$path";
+ $headers['Range'] = $range;
+
+ $client = new GClient();
+ $options = [];
+ $options['auth'] = [$token, ""];
+
+ $request = $client->createRequest("GET", $fullUrl, $options);
+ $request->addHeader('Range', $range);
+
+ $this->response = $client->send($request);
+ }
+
+ /**
+ * @Then /^Downloaded content should be "([^"]*)"$/
+ * @param string $content
+ */
+ public function downloadedContentShouldBe($content){
+ PHPUnit_Framework_Assert::assertEquals($content, (string)$this->response->getBody());
+ }
+
+ /**
+ * @Then /^Downloaded content when downloading file "([^"]*)" with range "([^"]*)" should be "([^"]*)"$/
+ * @param string $fileSource
+ * @param string $range
+ * @param string $content
+ */
+ public function downloadedContentWhenDownloadindShouldBe($fileSource, $range, $content){
+ $this->downloadFileWithRange($fileSource, $range);
+ $this->downloadedContentShouldBe($content);
+ }
+
+ /**
+ * @When Downloading file :fileName
+ * @param string $fileName
+ */
+ public function downloadingFile($fileName) {
+ try {
+ $this->response = $this->makeDavRequest($this->currentUser, 'GET', $fileName, []);
+ } catch (\GuzzleHttp\Exception\ClientException $e) {
+ $this->response = $e->getResponse();
+ }
+ }
+
+ /**
+ * @Then The following headers should be set
+ * @param \Behat\Gherkin\Node\TableNode $table
+ * @throws \Exception
+ */
+ public function theFollowingHeadersShouldBeSet(\Behat\Gherkin\Node\TableNode $table) {
+ foreach($table->getTable() as $header) {
+ $headerName = $header[0];
+ $expectedHeaderValue = $header[1];
+ $returnedHeader = $this->response->getHeader($headerName);
+ if($returnedHeader !== $expectedHeaderValue) {
+ throw new \Exception(
+ sprintf(
+ "Expected value '%s' for header '%s', got '%s'",
+ $expectedHeaderValue,
+ $headerName,
+ $returnedHeader
+ )
+ );
+ }
+ }
+ }
+
+ /**
+ * @Then Downloaded content should start with :start
+ * @param int $start
+ * @throws \Exception
+ */
+ public function downloadedContentShouldStartWith($start) {
+ if(strpos($this->response->getBody()->getContents(), $start) !== 0) {
+ throw new \Exception(
+ sprintf(
+ "Expected '%s', got '%s'",
+ $start,
+ $this->response->getBody()->getContents()
+ )
+ );
+ }
+ }
+
+ /**
+ * @Then /^as "([^"]*)" gets properties of folder "([^"]*)" with$/
+ * @param string $user
+ * @param string $path
+ * @param \Behat\Gherkin\Node\TableNode|null $propertiesTable
+ */
+ public function asGetsPropertiesOfFolderWith($user, $path, $propertiesTable) {
+ $properties = null;
+ if ($propertiesTable instanceof \Behat\Gherkin\Node\TableNode) {
+ foreach ($propertiesTable->getRows() as $row) {
+ $properties[] = $row[0];
+ }
+ }
+ $this->response = $this->listFolder($user, $path, 0, $properties);
+ }
+
+ /**
+ * @Then the single response should contain a property :key with value :value
+ * @param string $key
+ * @param string $expectedValue
+ * @throws \Exception
+ */
+ public function theSingleResponseShouldContainAPropertyWithValue($key, $expectedValue) {
+ $keys = $this->response;
+ if (!array_key_exists($key, $keys)) {
+ throw new \Exception("Cannot find property \"$key\" with \"$expectedValue\"");
+ }
+
+ $value = $keys[$key];
+ if ($value != $expectedValue) {
+ throw new \Exception("Property \"$key\" found with value \"$value\", expected \"$expectedValue\"");
+ }
+ }
+
+ /**
+ * @Then the response should contain a share-types property with
+ */
+ public function theResponseShouldContainAShareTypesPropertyWith($table)
+ {
+ $keys = $this->response;
+ if (!array_key_exists('{http://owncloud.org/ns}share-types', $keys)) {
+ throw new \Exception("Cannot find property \"{http://owncloud.org/ns}share-types\"");
+ }
+
+ $foundTypes = [];
+ $data = $keys['{http://owncloud.org/ns}share-types'];
+ foreach ($data as $item) {
+ if ($item['name'] !== '{http://owncloud.org/ns}share-type') {
+ throw new \Exception('Invalid property found: "' . $item['name'] . '"');
+ }
+
+ $foundTypes[] = $item['value'];
+ }
+
+ foreach ($table->getRows() as $row) {
+ $key = array_search($row[0], $foundTypes);
+ if ($key === false) {
+ throw new \Exception('Expected type ' . $row[0] . ' not found');
+ }
+
+ unset($foundTypes[$key]);
+ }
+
+ if ($foundTypes !== []) {
+ throw new \Exception('Found more share types then specified: ' . $foundTypes);
+ }
+ }
+
+ /**
+ * @Then the response should contain an empty property :property
+ * @param string $property
+ * @throws \Exception
+ */
+ public function theResponseShouldContainAnEmptyProperty($property) {
+ $properties = $this->response;
+ if (!array_key_exists($property, $properties)) {
+ throw new \Exception("Cannot find property \"$property\"");
+ }
+
+ if ($properties[$property] !== null) {
+ throw new \Exception("Property \"$property\" is not empty");
+ }
+ }
+
+
+ /*Returns the elements of a propfind, $folderDepth requires 1 to see elements without children*/
+ public function listFolder($user, $path, $folderDepth, $properties = null){
+ $fullUrl = substr($this->baseUrl, 0, -4);
+
+ $settings = array(
+ 'baseUri' => $fullUrl,
+ 'userName' => $user,
+ );
+
+ if ($user === 'admin') {
+ $settings['password'] = $this->adminUser[1];
+ } else {
+ $settings['password'] = $this->regularUser;
+ }
+
+ $client = new SClient($settings);
+
+ if (!$properties) {
+ $properties = [
+ '{DAV:}getetag'
+ ];
+ }
+
+ $response = $client->propfind($this->davPath . '/' . ltrim($path, '/'), $properties, $folderDepth);
+
+ return $response;
+ }
+
+ /**
+ * @Then /^user "([^"]*)" should see following elements$/
+ * @param string $user
+ * @param \Behat\Gherkin\Node\TableNode|null $expectedElements
+ */
+ public function checkElementList($user, $expectedElements){
+ $elementList = $this->listFolder($user, '/', 3);
+ if ($expectedElements instanceof \Behat\Gherkin\Node\TableNode) {
+ $elementRows = $expectedElements->getRows();
+ $elementsSimplified = $this->simplifyArray($elementRows);
+ foreach($elementsSimplified as $expectedElement) {
+ $webdavPath = "/" . $this->davPath . $expectedElement;
+ if (!array_key_exists($webdavPath,$elementList)){
+ PHPUnit_Framework_Assert::fail("$webdavPath" . " is not in propfind answer");
+ }
+ }
+ }
+ }
+
+ /**
+ * @When User :user uploads file :source to :destination
+ * @param string $user
+ * @param string $source
+ * @param string $destination
+ */
+ public function userUploadsAFileTo($user, $source, $destination)
+ {
+ $file = \GuzzleHttp\Stream\Stream::factory(fopen($source, 'r'));
+ try {
+ $this->response = $this->makeDavRequest($user, "PUT", $destination, [], $file);
+ } catch (\GuzzleHttp\Exception\ServerException $e) {
+ // 4xx and 5xx responses cause an exception
+ $this->response = $e->getResponse();
+ }
+ }
+
+ /**
+ * @When User :user uploads file with content :content to :destination
+ */
+ public function userUploadsAFileWithContentTo($user, $content, $destination)
+ {
+ $file = \GuzzleHttp\Stream\Stream::factory($content);
+ try {
+ $this->response = $this->makeDavRequest($user, "PUT", $destination, [], $file);
+ } catch (\GuzzleHttp\Exception\ServerException $e) {
+ // 4xx and 5xx responses cause an exception
+ $this->response = $e->getResponse();
+ }
+ }
+
+ /**
+ * @When User :user deletes file :file
+ * @param string $user
+ * @param string $file
+ */
+ public function userDeletesFile($user, $file) {
+ try {
+ $this->response = $this->makeDavRequest($user, 'DELETE', $file, []);
+ } catch (\GuzzleHttp\Exception\ServerException $e) {
+ // 4xx and 5xx responses cause an exception
+ $this->response = $e->getResponse();
+ }
+ }
+
+ /**
+ * @Given User :user created a folder :destination
+ * @param string $user
+ * @param string $destination
+ */
+ public function userCreatedAFolder($user, $destination){
+ try {
+ $this->response = $this->makeDavRequest($user, "MKCOL", $destination, []);
+ } catch (\GuzzleHttp\Exception\ServerException $e) {
+ // 4xx and 5xx responses cause an exception
+ $this->response = $e->getResponse();
+ }
+ }
+
+ /**
+ * @Given user :user uploads chunk file :num of :total with :data to :destination
+ * @param string $user
+ * @param int $num
+ * @param int $total
+ * @param string $data
+ * @param string $destination
+ */
+ public function userUploadsChunkFileOfWithToWithChecksum($user, $num, $total, $data, $destination)
+ {
+ $num -= 1;
+ $data = \GuzzleHttp\Stream\Stream::factory($data);
+ $file = $destination . '-chunking-42-'.$total.'-'.$num;
+ $this->makeDavRequest($user, 'PUT', $file, ['OC-Chunked' => '1'], $data);
+ }
+
+ /**
+ * @Given user :user creates a new chunking upload with id :id
+ */
+ public function userCreatesANewChunkingUploadWithId($user, $id)
+ {
+ $destination = '/uploads/'.$user.'/'.$id;
+ $this->makeDavRequest($user, 'MKCOL', $destination, []);
+ }
+
+ /**
+ * @Given user :user uploads new chunk file :num with :data to id :id
+ */
+ public function userUploadsNewChunkFileOfWithToId($user, $num, $data, $id)
+ {
+ $data = \GuzzleHttp\Stream\Stream::factory($data);
+ $destination = '/uploads/'.$user.'/'.$id.'/'.$num;
+ $this->makeDavRequest($user, 'PUT', $destination, [], $data);
+ }
+
+ /**
+ * @Given user :user moves new chunk file with id :id to :dest
+ */
+ public function userMovesNewChunkFileWithIdToMychunkedfile($user, $id, $dest)
+ {
+ $source = '/uploads/'.$user.'/'.$id.'/.file';
+ $destination = substr($this->baseUrl, 0, -4) . $this->davPath . '/files/'.$user.$dest;
+ $this->makeDavRequest($user, 'MOVE', $source, [
+ 'Destination' => $destination
+ ]);
+ }
+
+
+ /**
+ * @Given /^Downloading file "([^"]*)" as "([^"]*)"$/
+ */
+ public function downloadingFileAs($fileName, $user) {
+ try {
+ $this->response = $this->makeDavRequest($user, 'GET', $fileName, []);
+ } catch (\GuzzleHttp\Exception\ServerException $ex) {
+ $this->response = $ex->getResponse();
+ }
+ }
+
+ /**
+ * @When user :user favorites element :path
+ */
+ public function userFavoritesElement($user, $path){
+ $this->response = $this->changeFavStateOfAnElement($user, $path, 1, 0, null);
+ }
+
+ /**
+ * @When user :user unfavorites element :path
+ */
+ public function userUnfavoritesElement($user, $path){
+ $this->response = $this->changeFavStateOfAnElement($user, $path, 0, 0, null);
+ }
+
+ /*Set the elements of a proppatch, $folderDepth requires 1 to see elements without children*/
+ public function changeFavStateOfAnElement($user, $path, $favOrUnfav, $folderDepth, $properties = null){
+ $fullUrl = substr($this->baseUrl, 0, -4);
+ $settings = array(
+ 'baseUri' => $fullUrl,
+ 'userName' => $user,
+ );
+ if ($user === 'admin') {
+ $settings['password'] = $this->adminUser[1];
+ } else {
+ $settings['password'] = $this->regularUser;
+ }
+ $client = new SClient($settings);
+ if (!$properties) {
+ $properties = [
+ '{http://owncloud.org/ns}favorite' => $favOrUnfav
+ ];
+ }
+
+ $response = $client->proppatch($this->davPath . '/' . ltrim($path, '/'), $properties, $folderDepth);
+ return $response;
+ }
+
+ /**
+ * @Then /^as "([^"]*)" gets properties of file "([^"]*)" with$/
+ * @param string $user
+ * @param string $path
+ * @param \Behat\Gherkin\Node\TableNode|null $propertiesTable
+ */
+ public function asGetsPropertiesOfFileWith($user, $path, $propertiesTable) {
+ $this->asGetsPropertiesOfFolderWith($user, $path, $propertiesTable);
+ }
+}