Add transfer ownership integration tests (#26543)
* Add transfer ownership integration tests * Added more transfer ownership tests and OCC checks Signed-off-by: Lukas Reschke <lukas@statuscode.ch>pull/2719/head
parent
9b71ee27ff
commit
55bf9e3f71
@ -0,0 +1,167 @@ |
||||
<?php |
||||
/** |
||||
* @author Vincent Petry <pvince81@owncloud.com> |
||||
* |
||||
* @copyright Copyright (c) 2016, ownCloud, Inc. |
||||
* @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/> |
||||
* |
||||
*/ |
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php'; |
||||
|
||||
trait CommandLine { |
||||
/** @var int return code of last command */ |
||||
private $lastCode; |
||||
/** @var string stdout of last command */ |
||||
private $lastStdOut; |
||||
/** @var string stderr of last command */ |
||||
private $lastStdErr; |
||||
|
||||
/** @var string */ |
||||
protected $ocPath = '../..'; |
||||
|
||||
/** |
||||
* Invokes an OCC command |
||||
* |
||||
* @param string OCC command, the part behind "occ". For example: "files:transfer-ownership" |
||||
* @return int exit code |
||||
*/ |
||||
public function runOcc($args = []) { |
||||
$args = array_map(function($arg) { |
||||
return escapeshellarg($arg); |
||||
}, $args); |
||||
$args[] = '--no-ansi'; |
||||
$args = implode(' ', $args); |
||||
|
||||
$descriptor = [ |
||||
0 => ['pipe', 'r'], |
||||
1 => ['pipe', 'w'], |
||||
2 => ['pipe', 'w'], |
||||
]; |
||||
$process = proc_open('php console.php ' . $args, $descriptor, $pipes, $this->ocPath); |
||||
$this->lastStdOut = stream_get_contents($pipes[1]); |
||||
$this->lastStdErr = stream_get_contents($pipes[2]); |
||||
$this->lastCode = proc_close($process); |
||||
return $this->lastCode; |
||||
} |
||||
|
||||
/** |
||||
* @Given /^invoking occ with "([^"]*)"$/ |
||||
*/ |
||||
public function invokingTheCommand($cmd) { |
||||
$args = explode(' ', $cmd); |
||||
$this->runOcc($args); |
||||
} |
||||
|
||||
/** |
||||
* Find exception texts in stderr |
||||
*/ |
||||
public function findExceptions() { |
||||
$exceptions = []; |
||||
$captureNext = false; |
||||
// the exception text usually appears after an "[Exception"] row |
||||
foreach (explode("\n", $this->lastStdErr) as $line) { |
||||
if (preg_match('/\[Exception\]/', $line)) { |
||||
$captureNext = true; |
||||
continue; |
||||
} |
||||
if ($captureNext) { |
||||
$exceptions[] = trim($line); |
||||
$captureNext = false; |
||||
} |
||||
} |
||||
|
||||
return $exceptions; |
||||
} |
||||
|
||||
/** |
||||
* Finds all lines containing the given text |
||||
* |
||||
* @param string $input stdout or stderr output |
||||
* @param string $text text to search for |
||||
* @return array array of lines that matched |
||||
*/ |
||||
public function findLines($input, $text) { |
||||
$results = []; |
||||
// the exception text usually appears after an "[Exception"] row |
||||
foreach (explode("\n", $input) as $line) { |
||||
if (strpos($line, $text) >= 0) { |
||||
$results[] = $line; |
||||
} |
||||
} |
||||
|
||||
return $results; |
||||
} |
||||
|
||||
/** |
||||
* @Then /^the command was successful$/ |
||||
*/ |
||||
public function theCommandWasSuccessful() { |
||||
$exceptions = $this->findExceptions(); |
||||
if ($this->lastCode !== 0) { |
||||
$msg = 'The command was not successful, exit code was ' . $this->lastCode . '.'; |
||||
if (!empty($exceptions)) { |
||||
$msg .= ' Exceptions: ' . implode(', ', $exceptions); |
||||
} |
||||
throw new \Exception($msg); |
||||
} else if (!empty($exceptions)) { |
||||
$msg = 'The command was successful but triggered exceptions: ' . implode(', ', $exceptions); |
||||
throw new \Exception($msg); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @Then /^the command failed with exit code ([0-9]+)$/ |
||||
*/ |
||||
public function theCommandFailedWithExitCode($exitCode) { |
||||
if ($this->lastCode !== (int)$exitCode) { |
||||
throw new \Exception('The command was expected to fail with exit code ' . $exitCode . ' but got ' . $this->lastCode); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @Then /^the command failed with exception text "([^"]*)"$/ |
||||
*/ |
||||
public function theCommandFailedWithException($exceptionText) { |
||||
$exceptions = $this->findExceptions(); |
||||
if (empty($exceptions)) { |
||||
throw new \Exception('The command did not throw any exceptions'); |
||||
} |
||||
|
||||
if (!in_array($exceptionText, $exceptions)) { |
||||
throw new \Exception('The command did not throw any exception with the text "' . $exceptionText . '"'); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @Then /^the command output contains the text "([^"]*)"$/ |
||||
*/ |
||||
public function theCommandOutputContainsTheText($text) { |
||||
$lines = $this->findLines($this->lastStdOut, $text); |
||||
if (empty($lines)) { |
||||
throw new \Exception('The command did not output the expected text on stdout "' . $exceptionText . '"'); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @Then /^the command error output contains the text "([^"]*)"$/ |
||||
*/ |
||||
public function theCommandErrorOutputContainsTheText($text) { |
||||
$lines = $this->findLines($this->lastStdErr, $text); |
||||
if (empty($lines)) { |
||||
throw new \Exception('The command did not output the expected text on stderr "' . $exceptionText . '"'); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,99 @@ |
||||
<?php |
||||
/** |
||||
* @author Vincent Petry <pvince81@owncloud.com> |
||||
* |
||||
* @copyright Copyright (c) 2016, ownCloud, Inc. |
||||
* @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/> |
||||
* |
||||
*/ |
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php'; |
||||
|
||||
use Behat\Behat\Hook\Scope\BeforeScenarioScope; |
||||
|
||||
class CommandLineContext implements \Behat\Behat\Context\Context { |
||||
use CommandLine; |
||||
|
||||
private $lastTransferPath; |
||||
|
||||
private $featureContext; |
||||
|
||||
public function __construct($ocPath, $baseUrl) { |
||||
$this->ocPath = rtrim($ocPath, '/') . '/'; |
||||
$this->localBaseUrl = $baseUrl; |
||||
$this->remoteBaseUrl = $baseUrl; |
||||
} |
||||
|
||||
/** @BeforeScenario */ |
||||
public function gatherContexts(BeforeScenarioScope $scope) { |
||||
$environment = $scope->getEnvironment(); |
||||
// this should really be "WebDavContext" ... |
||||
$this->featureContext = $environment->getContext('FeatureContext'); |
||||
} |
||||
|
||||
private function findLastTransferFolderForUser($sourceUser, $targetUser) { |
||||
$foundPaths = []; |
||||
$results = $this->featureContext->listFolder($targetUser, '', 1); |
||||
foreach ($results as $path => $data) { |
||||
$path = rawurldecode($path); |
||||
$parts = explode(' ', $path); |
||||
if (basename($parts[0]) !== 'transferred') { |
||||
continue; |
||||
} |
||||
if (isset($parts[2]) && $parts[2] === $sourceUser) { |
||||
// store timestamp as key |
||||
$foundPaths[] = [ |
||||
'date' => strtotime(dirname($parts[4])), |
||||
'path' => $path, |
||||
]; |
||||
} |
||||
} |
||||
|
||||
if (empty($foundPaths)) { |
||||
return null; |
||||
} |
||||
|
||||
usort($foundPaths, function($a, $b) { |
||||
return $a['date'] - $b['date']; |
||||
}); |
||||
|
||||
$davPath = rtrim($this->featureContext->getDavFilesPath($targetUser), '/'); |
||||
|
||||
$foundPath = end($foundPaths)['path']; |
||||
// strip dav path |
||||
return substr($foundPath, strlen($davPath) + 1); |
||||
} |
||||
|
||||
/** |
||||
* @When /^transfering ownership from "([^"]+)" to "([^"]+)"/ |
||||
*/ |
||||
public function transferingOwnership($user1, $user2) { |
||||
if ($this->runOcc(['files:transfer-ownership', $user1, $user2]) === 0) { |
||||
$this->lastTransferPath = $this->findLastTransferFolderForUser($user1, $user2); |
||||
} else { |
||||
// failure |
||||
$this->lastTransferPath = null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @When /^using received transfer folder of "([^"]+)" as dav path$/ |
||||
*/ |
||||
public function usingTransferFolderAsDavPath($user) { |
||||
$davPath = $this->featureContext->getDavFilesPath($user); |
||||
$davPath = rtrim($davPath, '/') . $this->lastTransferPath; |
||||
$this->featureContext->usingDavPath($davPath); |
||||
} |
||||
} |
||||
@ -0,0 +1,119 @@ |
||||
Feature: transfer-ownership |
||||
|
||||
Scenario: transfering ownership of a file |
||||
Given user "user0" exists |
||||
And user "user1" exists |
||||
And User "user0" uploads file "data/textfile.txt" to "/somefile.txt" |
||||
When transfering ownership from "user0" to "user1" |
||||
And the command was successful |
||||
And As an "user1" |
||||
And using received transfer folder of "user1" as dav path |
||||
Then Downloaded content when downloading file "/somefile.txt" with range "bytes=0-6" should be "This is" |
||||
|
||||
Scenario: transfering ownership of a folder |
||||
Given user "user0" exists |
||||
And user "user1" exists |
||||
And User "user0" created a folder "/test" |
||||
And User "user0" uploads file "data/textfile.txt" to "/test/somefile.txt" |
||||
When transfering ownership from "user0" to "user1" |
||||
And the command was successful |
||||
And As an "user1" |
||||
And using received transfer folder of "user1" as dav path |
||||
Then Downloaded content when downloading file "/test/somefile.txt" with range "bytes=0-6" should be "This is" |
||||
|
||||
Scenario: transfering ownership of file shares |
||||
Given user "user0" exists |
||||
And user "user1" exists |
||||
And user "user2" exists |
||||
And User "user0" uploads file "data/textfile.txt" to "/somefile.txt" |
||||
And file "/somefile.txt" of user "user0" is shared with user "user2" with permissions 19 |
||||
When transfering ownership from "user0" to "user1" |
||||
And the command was successful |
||||
And As an "user2" |
||||
Then Downloaded content when downloading file "/somefile.txt" with range "bytes=0-6" should be "This is" |
||||
|
||||
Scenario: transfering ownership of folder shared with third user |
||||
Given user "user0" exists |
||||
And user "user1" exists |
||||
And user "user2" exists |
||||
And User "user0" created a folder "/test" |
||||
And User "user0" uploads file "data/textfile.txt" to "/test/somefile.txt" |
||||
And folder "/test" of user "user0" is shared with user "user2" with permissions 31 |
||||
When transfering ownership from "user0" to "user1" |
||||
And the command was successful |
||||
And As an "user2" |
||||
Then Downloaded content when downloading file "/test/somefile.txt" with range "bytes=0-6" should be "This is" |
||||
|
||||
Scenario: transfering ownership of folder shared with transfer recipient |
||||
Given user "user0" exists |
||||
And user "user1" exists |
||||
And User "user0" created a folder "/test" |
||||
And User "user0" uploads file "data/textfile.txt" to "/test/somefile.txt" |
||||
And folder "/test" of user "user0" is shared with user "user1" with permissions 31 |
||||
When transfering ownership from "user0" to "user1" |
||||
And the command was successful |
||||
And As an "user1" |
||||
Then as "user1" the folder "/test" does not exist |
||||
And using received transfer folder of "user1" as dav path |
||||
And Downloaded content when downloading file "/test/somefile.txt" with range "bytes=0-6" should be "This is" |
||||
|
||||
Scenario: transfering ownership of folder doubly shared with third user |
||||
Given group "group1" exists |
||||
And user "user0" exists |
||||
And user "user1" exists |
||||
And user "user2" exists |
||||
And user "user2" belongs to group "group1" |
||||
And User "user0" created a folder "/test" |
||||
And User "user0" uploads file "data/textfile.txt" to "/test/somefile.txt" |
||||
And folder "/test" of user "user0" is shared with group "group1" with permissions 31 |
||||
And folder "/test" of user "user0" is shared with user "user2" with permissions 31 |
||||
When transfering ownership from "user0" to "user1" |
||||
And the command was successful |
||||
And As an "user2" |
||||
Then Downloaded content when downloading file "/test/somefile.txt" with range "bytes=0-6" should be "This is" |
||||
|
||||
Scenario: transfering ownership does not transfer received shares |
||||
Given user "user0" exists |
||||
And user "user1" exists |
||||
And user "user2" exists |
||||
And User "user2" created a folder "/test" |
||||
And folder "/test" of user "user2" is shared with user "user0" with permissions 31 |
||||
When transfering ownership from "user0" to "user1" |
||||
And the command was successful |
||||
And As an "user1" |
||||
And using received transfer folder of "user1" as dav path |
||||
Then as "user1" the folder "/test" does not exist |
||||
|
||||
@local_storage |
||||
Scenario: transfering ownership does not transfer external storage |
||||
Given user "user0" exists |
||||
And user "user1" exists |
||||
When transfering ownership from "user0" to "user1" |
||||
And the command was successful |
||||
And As an "user1" |
||||
And using received transfer folder of "user1" as dav path |
||||
Then as "user1" the folder "/local_storage" does not exist |
||||
|
||||
Scenario: transfering ownership does not fail with shared trashed files |
||||
Given user "user0" exists |
||||
And user "user1" exists |
||||
And user "user2" exists |
||||
And User "user0" created a folder "/sub" |
||||
And User "user0" created a folder "/sub/test" |
||||
And folder "/sub/test" of user "user0" is shared with user "user2" with permissions 31 |
||||
And User "user0" deletes folder "/sub" |
||||
When transfering ownership from "user0" to "user1" |
||||
Then the command was successful |
||||
|
||||
Scenario: transfering ownership fails with invalid source user |
||||
Given user "user0" exists |
||||
When transfering ownership from "invalid_user" to "user0" |
||||
Then the command error output contains the text "Unknown source user" |
||||
And the command failed with exit code 1 |
||||
|
||||
Scenario: transfering ownership fails with invalid target user |
||||
Given user "user0" exists |
||||
When transfering ownership from "user0" to "invalid_user" |
||||
Then the command error output contains the text "Unknown target user" |
||||
And the command failed with exit code 1 |
||||
|
||||
Loading…
Reference in new issue