summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Müller <thomas.mueller@tmit.eu>2015-08-12 10:07:20 +0200
committerThomas Müller <thomas.mueller@tmit.eu>2015-08-12 10:07:20 +0200
commiteb13cb8d75634c0423dbcde4b0f55239c0dfb1e7 (patch)
tree552c2467ab6a2b94f8b6ec1310866562f1e5a781
parent24e45d5954c202c9c9cf4e59f0e41b0b37068e38 (diff)
parentb7cbff23d93a24f391b39682fc7581c85d8e0017 (diff)
downloadnextcloud-server-eb13cb8d75634c0423dbcde4b0f55239c0dfb1e7.tar.gz
nextcloud-server-eb13cb8d75634c0423dbcde4b0f55239c0dfb1e7.zip
Merge pull request #18127 from owncloud/dav-request-tests
add test framework for doing full request webdav tests
-rw-r--r--apps/files/appinfo/remote.php56
-rw-r--r--apps/files_sharing/publicwebdav.php42
-rw-r--r--lib/private/connector/sabre/exceptionloggerplugin.php2
-rw-r--r--lib/private/connector/sabre/file.php2
-rw-r--r--lib/private/connector/sabre/objecttree.php6
-rw-r--r--lib/private/connector/sabre/serverfactory.php107
-rw-r--r--tests/lib/connector/sabre/requesttest/auth.php69
-rw-r--r--tests/lib/connector/sabre/requesttest/exceptionplugin.php32
-rw-r--r--tests/lib/connector/sabre/requesttest/requesttest.php163
-rw-r--r--tests/lib/connector/sabre/requesttest/sapi.php53
-rw-r--r--tests/lib/connector/sabre/requesttest/uploadtest.php88
11 files changed, 543 insertions, 77 deletions
diff --git a/apps/files/appinfo/remote.php b/apps/files/appinfo/remote.php
index fff3332ef49..36479ae13d0 100644
--- a/apps/files/appinfo/remote.php
+++ b/apps/files/appinfo/remote.php
@@ -33,51 +33,23 @@ set_time_limit(0);
// Turn off output buffering to prevent memory problems
\OC_Util::obEnd();
+$serverFactory = new \OC\Connector\Sabre\ServerFactory(
+ \OC::$server->getConfig(),
+ \OC::$server->getLogger(),
+ \OC::$server->getDatabaseConnection(),
+ \OC::$server->getUserSession(),
+ \OC::$server->getMountManager(),
+ \OC::$server->getTagManager()
+);
+
// Backends
$authBackend = new \OC\Connector\Sabre\Auth();
+$requestUri = \OC::$server->getRequest()->getRequestUri();
-// Fire up server
-$objectTree = new \OC\Connector\Sabre\ObjectTree();
-$server = new \OC\Connector\Sabre\Server($objectTree);
-// Set URL explicitly due to reverse-proxy situations
-$server->httpRequest->setUrl(\OC::$server->getRequest()->getRequestUri());
-$server->setBaseUri($baseuri);
-
-// Load plugins
-$defaults = new OC_Defaults();
-$server->addPlugin(new \OC\Connector\Sabre\BlockLegacyClientPlugin(\OC::$server->getConfig()));
-$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, $defaults->getName()));
-// FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
-$server->addPlugin(new \OC\Connector\Sabre\DummyGetResponsePlugin());
-$server->addPlugin(new \OC\Connector\Sabre\FilesPlugin($objectTree));
-$server->addPlugin(new \OC\Connector\Sabre\MaintenancePlugin(\OC::$server->getConfig()));
-$server->addPlugin(new \OC\Connector\Sabre\ExceptionLoggerPlugin('webdav', \OC::$server->getLogger()));
-
-// wait with registering these until auth is handled and the filesystem is setup
-$server->on('beforeMethod', function () use ($server, $objectTree) {
- $view = \OC\Files\Filesystem::getView();
- $rootInfo = $view->getFileInfo('');
-
- // Create ownCloud Dir
- $mountManager = \OC\Files\Filesystem::getMountManager();
- $rootDir = new \OC\Connector\Sabre\Directory($view, $rootInfo);
- $objectTree->init($rootDir, $view, $mountManager);
-
- $server->addPlugin(new \OC\Connector\Sabre\TagsPlugin($objectTree, \OC::$server->getTagManager()));
- $server->addPlugin(new \OC\Connector\Sabre\QuotaPlugin($view));
-
- // custom properties plugin must be the last one
- $server->addPlugin(
- new \Sabre\DAV\PropertyStorage\Plugin(
- new \OC\Connector\Sabre\CustomPropertiesBackend(
- $objectTree,
- \OC::$server->getDatabaseConnection(),
- \OC::$server->getUserSession()->getUser()
- )
- )
- );
- $server->addPlugin(new \OC\Connector\Sabre\CopyEtagHeaderPlugin());
-}, 30); // priority 30: after auth (10) and acl(20), before lock(50) and handling the request
+$server = $serverFactory->createServer($baseuri, $requestUri, $authBackend, function() {
+ // use the view for the logged in user
+ return \OC\Files\Filesystem::getView();
+});
// And off we go!
$server->exec();
diff --git a/apps/files_sharing/publicwebdav.php b/apps/files_sharing/publicwebdav.php
index 5bde908109d..eec158dd4b6 100644
--- a/apps/files_sharing/publicwebdav.php
+++ b/apps/files_sharing/publicwebdav.php
@@ -33,24 +33,18 @@ OC_Util::obEnd();
// Backends
$authBackend = new OCA\Files_Sharing\Connector\PublicAuth(\OC::$server->getConfig());
-// Fire up server
-$objectTree = new \OC\Connector\Sabre\ObjectTree();
-$server = new \OC\Connector\Sabre\Server($objectTree);
-// Set URL explicitly due to reverse-proxy situations
-$server->httpRequest->setUrl(\OC::$server->getRequest()->getRequestUri());
-$server->setBaseUri($baseuri);
+$serverFactory = new \OC\Connector\Sabre\ServerFactory(
+ \OC::$server->getConfig(),
+ \OC::$server->getLogger(),
+ \OC::$server->getDatabaseConnection(),
+ \OC::$server->getUserSession(),
+ \OC::$server->getMountManager(),
+ \OC::$server->getTagManager()
+);
-// Load plugins
-$defaults = new OC_Defaults();
-$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, $defaults->getName()));
-// FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
-$server->addPlugin(new \OC\Connector\Sabre\DummyGetResponsePlugin());
-$server->addPlugin(new \OC\Connector\Sabre\FilesPlugin($objectTree, true));
-$server->addPlugin(new \OC\Connector\Sabre\MaintenancePlugin(\OC::$server->getConfig()));
-$server->addPlugin(new \OC\Connector\Sabre\ExceptionLoggerPlugin('webdav', \OC::$server->getLogger()));
+$requestUri = \OC::$server->getRequest()->getRequestUri();
-// wait with registering these until auth is handled and the filesystem is setup
-$server->on('beforeMethod', function () use ($server, $objectTree, $authBackend) {
+$server = $serverFactory->createServer($baseuri, $requestUri, $authBackend, function () use ($authBackend) {
if (OCA\Files_Sharing\Helper::isOutgoingServer2serverShareEnabled() === false) {
// this is what is thrown when trying to access a non-existing share
throw new \Sabre\DAV\Exception\NotAuthenticated();
@@ -72,20 +66,8 @@ $server->on('beforeMethod', function () use ($server, $objectTree, $authBackend)
$ownerView = \OC\Files\Filesystem::getView();
$path = $ownerView->getPath($fileId);
- $view = new \OC\Files\View($ownerView->getAbsolutePath($path));
- $rootInfo = $view->getFileInfo('');
-
- // Create ownCloud Dir
- if ($rootInfo->getType() === 'dir') {
- $root = new \OC\Connector\Sabre\Directory($view, $rootInfo);
- } else {
- $root = new \OC\Connector\Sabre\File($view, $rootInfo);
- }
- $mountManager = \OC\Files\Filesystem::getMountManager();
- $objectTree->init($root, $view, $mountManager);
-
- $server->addPlugin(new \OC\Connector\Sabre\QuotaPlugin($view));
-}, 30); // priority 30: after auth (10) and acl(20), before lock(50) and handling the request
+ return new \OC\Files\View($ownerView->getAbsolutePath($path));
+});
// And off we go!
$server->exec();
diff --git a/lib/private/connector/sabre/exceptionloggerplugin.php b/lib/private/connector/sabre/exceptionloggerplugin.php
index 741ba4d3e05..53a1f738ea6 100644
--- a/lib/private/connector/sabre/exceptionloggerplugin.php
+++ b/lib/private/connector/sabre/exceptionloggerplugin.php
@@ -28,7 +28,7 @@ use Sabre\DAV\Exception;
use Sabre\HTTP\Response;
class ExceptionLoggerPlugin extends \Sabre\DAV\ServerPlugin {
- private $nonFatalExceptions = array(
+ protected $nonFatalExceptions = array(
'Sabre\DAV\Exception\NotAuthenticated' => true,
// the sync client uses this to find out whether files exist,
// so it is not always an error, log it as debug
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index fa2f5ce18d7..b7d0c547f24 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -332,7 +332,7 @@ class File extends Node implements IFile {
$info = \OC_FileChunking::decodeName($name);
if (empty($info)) {
- throw new NotImplemented();
+ throw new NotImplemented('Invalid chunk name');
}
$chunk_handler = new \OC_FileChunking($info);
$bytesWritten = $chunk_handler->store($info['index'], $data);
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index 1e9b9ba59e2..18d3c1dcf23 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -41,7 +41,7 @@ class ObjectTree extends \Sabre\DAV\Tree {
protected $fileView;
/**
- * @var \OC\Files\Mount\Manager
+ * @var \OCP\Files\Mount\IMountManager
*/
protected $mountManager;
@@ -54,9 +54,9 @@ class ObjectTree extends \Sabre\DAV\Tree {
/**
* @param \Sabre\DAV\INode $rootNode
* @param \OC\Files\View $view
- * @param \OC\Files\Mount\Manager $mountManager
+ * @param \OCP\Files\Mount\IMountManager $mountManager
*/
- public function init(\Sabre\DAV\INode $rootNode, \OC\Files\View $view, \OC\Files\Mount\Manager $mountManager) {
+ public function init(\Sabre\DAV\INode $rootNode, \OC\Files\View $view, \OCP\Files\Mount\IMountManager $mountManager) {
$this->rootNode = $rootNode;
$this->fileView = $view;
$this->mountManager = $mountManager;
diff --git a/lib/private/connector/sabre/serverfactory.php b/lib/private/connector/sabre/serverfactory.php
new file mode 100644
index 00000000000..525ff0104cd
--- /dev/null
+++ b/lib/private/connector/sabre/serverfactory.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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/>
+ *
+ */
+
+namespace OC\Connector\Sabre;
+
+use OCP\Files\Mount\IMountManager;
+use OCP\IConfig;
+use OCP\IDBConnection;
+use OCP\ILogger;
+use OCP\ITagManager;
+use OCP\IUserSession;
+use Sabre\DAV\Auth\Backend\BackendInterface;
+
+class ServerFactory {
+ public function __construct(
+ IConfig $config,
+ ILogger $logger,
+ IDBConnection $databaseConnection,
+ IUserSession $userSession,
+ IMountManager $mountManager,
+ ITagManager $tagManager
+ ) {
+ $this->config = $config;
+ $this->logger = $logger;
+ $this->databaseConnection = $databaseConnection;
+ $this->userSession = $userSession;
+ $this->mountManager = $mountManager;
+ $this->tagManager = $tagManager;
+ }
+
+ /**
+ * @param string $baseUri
+ * @param string $requestUri
+ * @param BackendInterface $authBackend
+ * @param callable $viewCallBack callback that should return the view for the dav endpoint
+ * @return Server
+ */
+ public function createServer($baseUri, $requestUri, BackendInterface $authBackend, callable $viewCallBack) {
+ // Fire up server
+ $objectTree = new \OC\Connector\Sabre\ObjectTree();
+ $server = new \OC\Connector\Sabre\Server($objectTree);
+ // Set URL explicitly due to reverse-proxy situations
+ $server->httpRequest->setUrl($requestUri);
+ $server->setBaseUri($baseUri);
+
+ // Load plugins
+ $defaults = new \OC_Defaults();
+ $server->addPlugin(new \OC\Connector\Sabre\BlockLegacyClientPlugin($this->config));
+ $server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, $defaults->getName()));
+ // FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
+ $server->addPlugin(new \OC\Connector\Sabre\DummyGetResponsePlugin());
+ $server->addPlugin(new \OC\Connector\Sabre\FilesPlugin($objectTree));
+ $server->addPlugin(new \OC\Connector\Sabre\MaintenancePlugin($this->config));
+ $server->addPlugin(new \OC\Connector\Sabre\ExceptionLoggerPlugin('webdav', $this->logger));
+
+ // wait with registering these until auth is handled and the filesystem is setup
+ $server->on('beforeMethod', function () use ($server, $objectTree, $viewCallBack) {
+ /** @var \OC\Files\View $view */
+ $view = $viewCallBack();
+ $rootInfo = $view->getFileInfo('');
+
+ // Create ownCloud Dir
+ if ($rootInfo->getType() === 'dir') {
+ $root = new \OC\Connector\Sabre\Directory($view, $rootInfo);
+ } else {
+ $root = new \OC\Connector\Sabre\File($view, $rootInfo);
+ }
+ $objectTree->init($root, $view, $this->mountManager);
+
+ $server->addPlugin(new \OC\Connector\Sabre\QuotaPlugin($view));
+
+ if($this->userSession->isLoggedIn()) {
+ $server->addPlugin(new \OC\Connector\Sabre\TagsPlugin($objectTree, $this->tagManager));
+ // custom properties plugin must be the last one
+ $server->addPlugin(
+ new \Sabre\DAV\PropertyStorage\Plugin(
+ new \OC\Connector\Sabre\CustomPropertiesBackend(
+ $objectTree,
+ $this->databaseConnection,
+ $this->userSession->getUser()
+ )
+ )
+ );
+ }
+ $server->addPlugin(new \OC\Connector\Sabre\CopyEtagHeaderPlugin());
+ }, 30); // priority 30: after auth (10) and acl(20), before lock(50) and handling the request
+ return $server;
+ }
+}
diff --git a/tests/lib/connector/sabre/requesttest/auth.php b/tests/lib/connector/sabre/requesttest/auth.php
new file mode 100644
index 00000000000..7cab4da5264
--- /dev/null
+++ b/tests/lib/connector/sabre/requesttest/auth.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Connector\Sabre\RequestTest;
+
+use Sabre\DAV\Auth\Backend\BackendInterface;
+
+class Auth implements BackendInterface {
+ /**
+ * @var string
+ */
+ private $user;
+
+ /**
+ * @var string
+ */
+ private $password;
+
+ /**
+ * Auth constructor.
+ *
+ * @param string $user
+ * @param string $password
+ */
+ public function __construct($user, $password) {
+ $this->user = $user;
+ $this->password = $password;
+ }
+
+
+ /**
+ * Authenticates the user based on the current request.
+ *
+ * If authentication is successful, true must be returned.
+ * If authentication fails, an exception must be thrown.
+ *
+ * @param \Sabre\DAV\Server $server
+ * @param string $realm
+ * @return bool
+ */
+ function authenticate(\Sabre\DAV\Server $server, $realm) {
+ $userSession = \OC::$server->getUserSession();
+ $result = $userSession->login($this->user, $this->password);
+ if ($result) {
+ //we need to pass the user name, which may differ from login name
+ $user = $userSession->getUser()->getUID();
+ \OC_Util::setupFS($user);
+ //trigger creation of user home and /files folder
+ \OC::$server->getUserFolder($user);
+ }
+ return $result;
+ }
+
+ /**
+ * Returns information about the currently logged in username.
+ *
+ * If nobody is currently logged in, this method should return null.
+ *
+ * @return string|null
+ */
+ function getCurrentUser() {
+ return $this->user;
+ }
+}
diff --git a/tests/lib/connector/sabre/requesttest/exceptionplugin.php b/tests/lib/connector/sabre/requesttest/exceptionplugin.php
new file mode 100644
index 00000000000..2b9e5d6d46d
--- /dev/null
+++ b/tests/lib/connector/sabre/requesttest/exceptionplugin.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Connector\Sabre\RequestTest;
+
+use Sabre\DAV\Exception;
+
+class ExceptionPlugin extends \OC\Connector\Sabre\ExceptionLoggerPlugin {
+ /**
+ * @var \Exception[]
+ */
+ protected $exceptions = [];
+
+ public function logException(\Exception $ex) {
+ $exceptionClass = get_class($ex);
+ if (!isset($this->nonFatalExceptions[$exceptionClass])) {
+ $this->exceptions[] = $ex;
+ }
+ }
+
+ /**
+ * @return \Exception[]
+ */
+ public function getExceptions() {
+ return $this->exceptions;
+ }
+}
diff --git a/tests/lib/connector/sabre/requesttest/requesttest.php b/tests/lib/connector/sabre/requesttest/requesttest.php
new file mode 100644
index 00000000000..c7739aefcd7
--- /dev/null
+++ b/tests/lib/connector/sabre/requesttest/requesttest.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Connector\Sabre\RequestTest;
+
+use OC\Connector\Sabre\Server;
+use OC\Connector\Sabre\ServerFactory;
+use OC\Files\Mount\MountPoint;
+use OC\Files\Storage\Temporary;
+use OC\Files\View;
+use OCP\IUser;
+use Sabre\HTTP\Request;
+use Test\TestCase;
+
+abstract class RequestTest extends TestCase {
+ /**
+ * @var \OC_User_Dummy
+ */
+ protected $userBackend;
+
+ /**
+ * @var \OCP\Files\Config\IMountProvider[]
+ */
+ protected $mountProviders;
+
+ /**
+ * @var \OC\Connector\Sabre\ServerFactory
+ */
+ protected $serverFactory;
+
+ protected function getStream($string) {
+ $stream = fopen('php://temp', 'r+');
+ fwrite($stream, $string);
+ fseek($stream, 0);
+ return $stream;
+ }
+
+ /**
+ * @param $userId
+ * @param $storages
+ * @return \OCP\Files\Config\IMountProvider
+ */
+ protected function getMountProvider($userId, $storages) {
+ $mounts = [];
+ foreach ($storages as $mountPoint => $storage) {
+ $mounts[] = new MountPoint($storage, $mountPoint);
+ }
+ $provider = $this->getMock('\OCP\Files\Config\IMountProvider');
+ $provider->expects($this->any())
+ ->method('getMountsForUser')
+ ->will($this->returnCallback(function (IUser $user) use ($userId, $mounts) {
+ if ($user->getUID() === $userId) {
+ return $mounts;
+ } else {
+ return [];
+ }
+ }));
+ return $provider;
+ }
+
+ protected function setUp() {
+ parent::setUp();
+ $this->userBackend = new \OC_User_Dummy();
+ \OC::$server->getUserManager()->registerBackend($this->userBackend);
+
+ $this->serverFactory = new ServerFactory(
+ \OC::$server->getConfig(),
+ \OC::$server->getLogger(),
+ \OC::$server->getDatabaseConnection(),
+ \OC::$server->getUserSession(),
+ \OC::$server->getMountManager(),
+ \OC::$server->getTagManager()
+ );
+ }
+
+ protected function tearDown() {
+ parent::tearDown();
+ \OC::$server->getUserManager()->removeBackend($this->userBackend);
+ }
+
+ protected function setupUser($name, $password) {
+ $this->userBackend->createUser($name, $password);
+ \OC::$server->getMountProviderCollection()->registerProvider($this->getMountProvider($name, [
+ '/' . $name => new Temporary()
+ ]));
+ $this->loginAsUser($name);
+ return new View('/' . $name . '/files');
+ }
+
+ /**
+ * @param \OC\Files\View $view the view to run the webdav server against
+ * @param string $user
+ * @param string $password
+ * @param string $method
+ * @param string $url
+ * @param resource|string|null $body
+ * @param array|null $headers
+ * @return \Sabre\HTTP\Response
+ */
+ protected function request($view, $user, $password, $method, $url, $body = null, $headers = null) {
+ if (is_string($body)) {
+ $body = $this->getStream($body);
+ }
+ $this->logout();
+ $exceptionPlugin = new ExceptionPlugin('webdav', null);
+ $server = $this->getSabreServer($view, $user, $password, $exceptionPlugin);
+ $request = new Request($method, $url, $headers, $body);
+
+ // since sabre catches all exceptions we need to save them and throw them from outside the sabre server
+
+ $originalServer = $_SERVER;
+
+ if (is_array($headers)) {
+ foreach ($headers as $header => $value) {
+ $_SERVER['HTTP_' . strtoupper(str_replace('-', '_', $header))] = $value;
+ }
+ }
+
+ $result = $this->makeRequest($server, $request);
+
+ foreach ($exceptionPlugin->getExceptions() as $exception) {
+ throw $exception;
+ }
+ $_SERVER = $originalServer;
+ return $result;
+ }
+
+ /**
+ * @param Server $server
+ * @param Request $request
+ * @return \Sabre\HTTP\Response
+ */
+ protected function makeRequest(Server $server, Request $request) {
+ $sapi = new Sapi($request);
+ $server->sapi = $sapi;
+ $server->httpRequest = $request;
+ $server->exec();
+ return $sapi->getResponse();
+ }
+
+ /**
+ * @param View $view
+ * @param string $user
+ * @param string $password
+ * @param ExceptionPlugin $exceptionPlugin
+ * @return Server
+ */
+ protected function getSabreServer(View $view, $user, $password, ExceptionPlugin $exceptionPlugin) {
+ $authBackend = new Auth($user, $password);
+
+ $server = $this->serverFactory->createServer('/', 'dummy', $authBackend, function () use ($view) {
+ return $view;
+ });
+ $server->addPlugin($exceptionPlugin);
+
+ return $server;
+ }
+}
diff --git a/tests/lib/connector/sabre/requesttest/sapi.php b/tests/lib/connector/sabre/requesttest/sapi.php
new file mode 100644
index 00000000000..7072b8bd286
--- /dev/null
+++ b/tests/lib/connector/sabre/requesttest/sapi.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Connector\Sabre\RequestTest;
+
+use Sabre\HTTP\Request;
+use Sabre\HTTP\Response;
+
+class Sapi {
+ /**
+ * @var \Sabre\HTTP\Request
+ */
+ private $request;
+
+ /**
+ * @var \Sabre\HTTP\Response
+ */
+ private $response;
+
+ /**
+ * This static method will create a new Request object, based on the
+ * current PHP request.
+ *
+ * @return \Sabre\HTTP\Request
+ */
+ public function getRequest() {
+ return $this->request;
+ }
+
+ public function __construct(Request $request) {
+ $this->request = $request;
+ }
+
+ /**
+ * @param \Sabre\HTTP\Response $response
+ * @return void
+ */
+ public function sendResponse(Response $response) {
+ $this->response = $response;
+ }
+
+ /**
+ * @return \Sabre\HTTP\Response
+ */
+ public function getResponse() {
+ return $this->response;
+ }
+}
diff --git a/tests/lib/connector/sabre/requesttest/uploadtest.php b/tests/lib/connector/sabre/requesttest/uploadtest.php
new file mode 100644
index 00000000000..2cc912d07f2
--- /dev/null
+++ b/tests/lib/connector/sabre/requesttest/uploadtest.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Connector\Sabre\RequestTest;
+
+class UploadTest extends RequestTest {
+ public function testBasicUpload() {
+ $user = $this->getUniqueID();
+ $view = $this->setupUser($user, 'pass');
+
+ $this->assertFalse($view->file_exists('foo.txt'));
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt', 'asd');
+
+ $this->assertEquals(201, $response->getStatus());
+ $this->assertTrue($view->file_exists('foo.txt'));
+ $this->assertEquals('asd', $view->file_get_contents('foo.txt'));
+ }
+
+ public function testUploadOverWrite() {
+ $user = $this->getUniqueID();
+ $view = $this->setupUser($user, 'pass');
+
+ $view->file_put_contents('foo.txt', 'bar');
+
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt', 'asd');
+
+ $this->assertEquals(204, $response->getStatus());
+ $this->assertEquals('asd', $view->file_get_contents('foo.txt'));
+ }
+
+ public function testChunkedUpload() {
+ $user = $this->getUniqueID();
+ $view = $this->setupUser($user, 'pass');
+
+ $this->assertFalse($view->file_exists('foo.txt'));
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt-chunking-123-2-0', 'asd', ['OC-Chunked' => '1']);
+
+ $this->assertEquals(201, $response->getStatus());
+ $this->assertFalse($view->file_exists('foo.txt'));
+
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt-chunking-123-2-1', 'bar', ['OC-Chunked' => '1']);
+
+ $this->assertEquals(201, $response->getStatus());
+ $this->assertTrue($view->file_exists('foo.txt'));
+
+ $this->assertEquals('asdbar', $view->file_get_contents('foo.txt'));
+ }
+
+ public function testChunkedUploadOverWrite() {
+ $user = $this->getUniqueID();
+ $view = $this->setupUser($user, 'pass');
+
+ $view->file_put_contents('foo.txt', 'bar');
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt-chunking-123-2-0', 'asd', ['OC-Chunked' => '1']);
+
+ $this->assertEquals(201, $response->getStatus());
+ $this->assertEquals('bar', $view->file_get_contents('foo.txt'));
+
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt-chunking-123-2-1', 'bar', ['OC-Chunked' => '1']);
+
+ $this->assertEquals(201, $response->getStatus());
+
+ $this->assertEquals('asdbar', $view->file_get_contents('foo.txt'));
+ }
+
+ public function testChunkedUploadOutOfOrder() {
+ $user = $this->getUniqueID();
+ $view = $this->setupUser($user, 'pass');
+
+ $this->assertFalse($view->file_exists('foo.txt'));
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt-chunking-123-2-1', 'bar', ['OC-Chunked' => '1']);
+
+ $this->assertEquals(201, $response->getStatus());
+ $this->assertFalse($view->file_exists('foo.txt'));
+
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt-chunking-123-2-0', 'asd', ['OC-Chunked' => '1']);
+
+ $this->assertEquals(201, $response->getStatus());
+ $this->assertTrue($view->file_exists('foo.txt'));
+
+ $this->assertEquals('asdbar', $view->file_get_contents('foo.txt'));
+ }
+}