From bc49c6be04d78740d9b7cb100debcb6641559d39 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 26 Feb 2014 14:29:13 +0100 Subject: Manually triger the filecache update hooks before any other hook --- tests/lib/files/cache/updater.php | 5 ----- 1 file changed, 5 deletions(-) (limited to 'tests') diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index 48986149a73..1c4c965af0b 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -65,11 +65,6 @@ class Updater extends \PHPUnit_Framework_TestCase { Filesystem::mount($this->storage, array(), '/' . self::$user . '/files'); \OC_Hook::clear('OC_Filesystem'); - - \OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook'); - \OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook'); - \OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook'); - \OC_Hook::connect('OC_Filesystem', 'post_touch', '\OC\Files\Cache\Updater', 'touchHook'); } public function tearDown() { -- cgit v1.2.3 From bb8a7a2230ce1b13ab97e1558a56f54009064066 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 3 Mar 2014 16:48:06 +0100 Subject: Remove assert since the root size of the home storage is no longer calculated --- tests/lib/files/cache/homecache.php | 1 - 1 file changed, 1 deletion(-) (limited to 'tests') diff --git a/tests/lib/files/cache/homecache.php b/tests/lib/files/cache/homecache.php index dbcf6e9caa0..80dc54c9d19 100644 --- a/tests/lib/files/cache/homecache.php +++ b/tests/lib/files/cache/homecache.php @@ -90,7 +90,6 @@ class HomeCache extends \PHPUnit_Framework_TestCase { // check that files and root size ignored the unknown sizes $this->assertEquals(1000, $this->cache->calculateFolderSize('files')); - $this->assertEquals(1000, $this->cache->calculateFolderSize('')); // clean up $this->cache->remove(''); -- cgit v1.2.3 From c7e204bd3674b616faddbb0b88187f94638e5b01 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 5 Mar 2014 17:04:15 +0100 Subject: Added unit tests for serverHost and other related functions --- tests/lib/request.php | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) (limited to 'tests') diff --git a/tests/lib/request.php b/tests/lib/request.php index 1d77acc70ae..bff84e1b03f 100644 --- a/tests/lib/request.php +++ b/tests/lib/request.php @@ -135,4 +135,141 @@ class Test_Request extends PHPUnit_Framework_TestCase { ), ); } + + public function testInsecureServerHost() { + unset($_SERVER['HTTP_X_FORWARDED_HOST']); + unset($_SERVER['HTTP_HOST']); + unset($_SERVER['SERVER_NAME']); + $_SERVER['SERVER_NAME'] = 'from.server.name:8080'; + $host = OC_Request::insecureServerHost(); + $this->assertEquals('from.server.name:8080', $host); + + $_SERVER['HTTP_HOST'] = 'from.host.header:8080'; + $host = OC_Request::insecureServerHost(); + $this->assertEquals('from.host.header:8080', $host); + + $_SERVER['HTTP_X_FORWARDED_HOST'] = 'from.forwarded.host:8080'; + $host = OC_Request::insecureServerHost(); + $this->assertEquals('from.forwarded.host:8080', $host); + + $_SERVER['HTTP_X_FORWARDED_HOST'] = 'from.forwarded.host2:8080,another.one:9000'; + $host = OC_Request::insecureServerHost(); + $this->assertEquals('from.forwarded.host2:8080', $host); + + // clean up + unset($_SERVER['HTTP_X_FORWARDED_HOST']); + unset($_SERVER['HTTP_HOST']); + unset($_SERVER['SERVER_NAME']); + } + + public function testGetOverwriteHost() { + unset($_SERVER['REMOTE_ADDR']); + OC_Config::deleteKey('overwritecondaddr'); + OC_Config::deleteKey('overwritehost'); + $host = OC_Request::getOverwriteHost(); + $this->assertNull($host); + + OC_Config::setValue('overwritehost', ''); + $host = OC_Request::getOverwriteHost(); + $this->assertNull($host); + + OC_Config::setValue('overwritehost', 'host.one.test:8080'); + $host = OC_Request::getOverwriteHost(); + $this->assertEquals('host.one.test:8080', $host); + + $_SERVER['REMOTE_ADDR'] = 'somehost.test:8080'; + OC_Config::setValue('overwritecondaddr', '^somehost\..*$'); + $host = OC_Request::getOverwriteHost(); + $this->assertEquals('host.one.test:8080', $host); + + OC_Config::setValue('overwritecondaddr', '^somethingelse.*$'); + $host = OC_Request::getOverwriteHost(); + $this->assertNull($host); + + // clean up + unset($_SERVER['REMOTE_ADDR']); + OC_Config::deleteKey('overwritecondaddr'); + OC_Config::deleteKey('overwritehost'); + } + + /** + * @dataProvider trustedDomainDataProvider + */ + public function testIsTrustedDomain($trustedDomains, $testDomain, $result) { + OC_Config::deleteKey('trusted_domains'); + if ($trustedDomains !== null) { + OC_Config::setValue('trusted_domains', $trustedDomains); + } + + $this->assertEquals($result, OC_Request::isTrustedDomain($testDomain)); + + // clean up + OC_Config::deleteKey('trusted_domains'); + } + + public function trustedDomainDataProvider() { + $trustedHostTestList = array('host.one.test:8080', 'host.two.test:8080'); + return array( + // empty defaults to true + array(null, 'host.one.test:8080', true), + array('', 'host.one.test:8080', true), + array(array(), 'host.one.test:8080', true), + + // trust list when defined + array($trustedHostTestList, 'host.two.test:8080', true), + array($trustedHostTestList, 'host.two.test:9999', false), + array($trustedHostTestList, 'host.three.test:8080', false), + + // trust localhost regardless of trust list + array($trustedHostTestList, 'localhost', true), + array($trustedHostTestList, 'localhost:8080', true), + array($trustedHostTestList, '127.0.0.1', true), + array($trustedHostTestList, '127.0.0.1:8080', true), + + // do not trust invalid localhosts + array($trustedHostTestList, 'localhost:1:2', false), + array($trustedHostTestList, 'localhost: evil.host', false), + ); + } + + public function testServerHost() { + OC_Config::deleteKey('overwritecondaddr'); + OC_Config::setValue('overwritehost', 'overwritten.host:8080'); + OC_Config::setValue( + 'trusted_domains', + array( + 'trusted.host:8080', + 'second.trusted.host:8080' + ) + ); + $_SERVER['HTTP_HOST'] = 'trusted.host:8080'; + + // CLI always gives localhost + $oldCLI = OC::$CLI; + OC::$CLI = true; + $host = OC_Request::serverHost(); + $this->assertEquals('localhost', $host); + OC::$CLI = false; + + // overwritehost overrides trusted domain + $host = OC_Request::serverHost(); + $this->assertEquals('overwritten.host:8080', $host); + + // trusted domain returned when used + OC_Config::deleteKey('overwritehost'); + $host = OC_Request::serverHost(); + $this->assertEquals('trusted.host:8080', $host); + + // trusted domain returned when untrusted one in header + $_SERVER['HTTP_HOST'] = 'untrusted.host:8080'; + OC_Config::deleteKey('overwritehost'); + $host = OC_Request::serverHost(); + $this->assertEquals('trusted.host:8080', $host); + + // clean up + OC_Config::deleteKey('overwritecondaddr'); + OC_Config::deleteKey('overwritehost'); + unset($_SERVER['HTTP_HOST']); + OC::$CLI = $oldCLI; + } } -- cgit v1.2.3 From ada8d4e0c91a885ca21db6b2bf4ca5d5c932e51b Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Fri, 7 Mar 2014 02:44:34 +0100 Subject: Fix unit tests --- tests/lib/urlgenerator.php | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/lib/urlgenerator.php b/tests/lib/urlgenerator.php index 875a7f06580..8e605d88f32 100644 --- a/tests/lib/urlgenerator.php +++ b/tests/lib/urlgenerator.php @@ -12,17 +12,32 @@ class Test_Urlgenerator extends PHPUnit_Framework_TestCase { /** * @small * @brief test absolute URL construction - * @dataProvider provideURLs + * @dataProvider provideDocRootURLs */ - function testGetAbsoluteURL($url, $expectedResult) { + function testGetAbsoluteURLDocRoot($url, $expectedResult) { + \OC::$WEBROOT = ''; $urlGenerator = new \OC\URLGenerator(null); $result = $urlGenerator->getAbsoluteURL($url); $this->assertEquals($expectedResult, $result); } - public function provideURLs() { + /** + * @small + * @brief test absolute URL construction + * @dataProvider provideSubDirURLs + */ + function testGetAbsoluteURLSubDir($url, $expectedResult) { + + \OC::$WEBROOT = '/owncloud'; + $urlGenerator = new \OC\URLGenerator(null); + $result = $urlGenerator->getAbsoluteURL($url); + + $this->assertEquals($expectedResult, $result); + } + + public function provideDocRootURLs() { return array( array("index.php", "http://localhost/index.php"), array("/index.php", "http://localhost/index.php"), @@ -30,5 +45,14 @@ class Test_Urlgenerator extends PHPUnit_Framework_TestCase { array("apps/index.php", "http://localhost/apps/index.php"), ); } + + public function provideSubDirURLs() { + return array( + array("index.php", "http://localhost/owncloud/index.php"), + array("/index.php", "http://localhost/owncloud/index.php"), + array("/apps/index.php", "http://localhost/owncloud/apps/index.php"), + array("apps/index.php", "http://localhost/owncloud/apps/index.php"), + ); + } } -- cgit v1.2.3 From 48d63a6278078d164774fd182f03ebba5e3c77ad Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 7 Mar 2014 11:25:29 +0100 Subject: Return unencrypted_size of folder when queried This fixes the "used space" to be based on the unencrypted size, not encrypted size, to be consistent with how quota/space is handled when encryption is enabled --- apps/files_encryption/lib/proxy.php | 7 +++++++ apps/files_encryption/tests/proxy.php | 20 ++++++++++++++++++++ lib/private/files/storage/wrapper/quota.php | 5 +++++ tests/lib/files/storage/wrapper/quota.php | 16 ++++++++++++++++ 4 files changed, 48 insertions(+) (limited to 'tests') diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index a2d42c22c13..b7e1599c1fe 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -340,6 +340,13 @@ class Proxy extends \OC_FileProxy { // if path is a folder do nothing if ($view->is_dir($path)) { + $proxyState = \OC_FileProxy::$enabled; + \OC_FileProxy::$enabled = false; + $fileInfo = $view->getFileInfo($path); + \OC_FileProxy::$enabled = $proxyState; + if ($fileInfo['unencrypted_size'] > 0) { + return $fileInfo['unencrypted_size']; + } return $size; } diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php index 51cc0b795e3..647ee955eb1 100644 --- a/apps/files_encryption/tests/proxy.php +++ b/apps/files_encryption/tests/proxy.php @@ -112,4 +112,24 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase { } + function testPostFileSizeWithDirectory() { + + $this->view->file_put_contents($this->filename, $this->data); + + \OC_FileProxy::$enabled = false; + + // get root size, must match the file's unencrypted size + $unencryptedSize = $this->view->filesize(''); + + \OC_FileProxy::$enabled = true; + + $encryptedSize = $this->view->filesize(''); + + $this->assertTrue($encryptedSize !== $unencryptedSize); + + // cleanup + $this->view->unlink($this->filename); + + } + } diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php index 26c952e694a..ea612735477 100644 --- a/lib/private/files/storage/wrapper/quota.php +++ b/lib/private/files/storage/wrapper/quota.php @@ -36,6 +36,11 @@ class Quota extends Wrapper { $cache = $this->getCache(); $data = $cache->get($path); if (is_array($data) and isset($data['size'])) { + if (isset($data['unencrypted_size']) + && $data['unencrypted_size'] > 0 + ) { + return $data['unencrypted_size']; + } return $data['size']; } else { return \OC\Files\SPACE_NOT_COMPUTED; diff --git a/tests/lib/files/storage/wrapper/quota.php b/tests/lib/files/storage/wrapper/quota.php index 43eae78415d..bd2c69a7396 100644 --- a/tests/lib/files/storage/wrapper/quota.php +++ b/tests/lib/files/storage/wrapper/quota.php @@ -53,6 +53,22 @@ class Quota extends \Test\Files\Storage\Storage { $this->assertEquals(9, $instance->free_space('')); } + public function testFreeSpaceWithUsedSpace() { + $instance = $this->getLimitedStorage(9); + $instance->getCache()->put( + '', array('size' => 3, 'unencrypted_size' => 0) + ); + $this->assertEquals(6, $instance->free_space('')); + } + + public function testFreeSpaceWithUsedSpaceAndEncryption() { + $instance = $this->getLimitedStorage(9); + $instance->getCache()->put( + '', array('size' => 7, 'unencrypted_size' => 3) + ); + $this->assertEquals(6, $instance->free_space('')); + } + public function testFWriteNotEnoughSpace() { $instance = $this->getLimitedStorage(9); $stream = $instance->fopen('foo', 'w+'); -- cgit v1.2.3 From 8ab7d18a6a2b023527d2eef63099e2834c46ec97 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 10 Mar 2014 14:04:58 +0100 Subject: Move the router classes to a namespace and expose it with a public interface --- apps/files_sharing/appinfo/routes.php | 2 +- lib/base.php | 14 +- lib/private/appframework/routing/routeconfig.php | 7 +- lib/private/route.php | 124 -------------- lib/private/route/route.php | 132 +++++++++++++++ lib/private/route/router.php | 202 +++++++++++++++++++++++ lib/private/router.php | 161 ------------------ lib/private/server.php | 15 ++ lib/public/appframework/app.php | 2 +- lib/public/iservercontainer.php | 6 + lib/public/route/iroute.php | 79 +++++++++ lib/public/route/irouter.php | 71 ++++++++ tests/lib/appframework/routing/RoutingTest.php | 8 +- 13 files changed, 517 insertions(+), 306 deletions(-) delete mode 100644 lib/private/route.php create mode 100644 lib/private/route/route.php create mode 100644 lib/private/route/router.php delete mode 100644 lib/private/router.php create mode 100644 lib/public/route/iroute.php create mode 100644 lib/public/route/irouter.php (limited to 'tests') diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php index 9417a6eeb89..06e454b7d77 100644 --- a/apps/files_sharing/appinfo/routes.php +++ b/apps/files_sharing/appinfo/routes.php @@ -1,5 +1,5 @@ create('core_ajax_public_preview', '/publicpreview.png')->action( function() { require_once __DIR__ . '/../ajax/publicpreview.php'; diff --git a/lib/base.php b/lib/base.php index 86ee5349828..d49dd958310 100644 --- a/lib/base.php +++ b/lib/base.php @@ -73,11 +73,6 @@ class OC { */ public static $CLI = false; - /** - * @var OC_Router - */ - protected static $router = null; - /** * @var \OC\Session\Session */ @@ -388,15 +383,10 @@ class OC { } /** - * @return OC_Router + * @return \OCP\Route\IRouter */ public static function getRouter() { - if (!isset(OC::$router)) { - OC::$router = new OC_Router(); - OC::$router->loadRoutes(); - } - - return OC::$router; + return self::$server->getRouter(); } diff --git a/lib/private/appframework/routing/routeconfig.php b/lib/private/appframework/routing/routeconfig.php index 716358444a2..35bee75cc4d 100644 --- a/lib/private/appframework/routing/routeconfig.php +++ b/lib/private/appframework/routing/routeconfig.php @@ -23,6 +23,7 @@ namespace OC\AppFramework\routing; use OC\AppFramework\DependencyInjection\DIContainer; +use OCP\Route\IRouter; /** * Class RouteConfig @@ -36,10 +37,10 @@ class RouteConfig { /** * @param \OC\AppFramework\DependencyInjection\DIContainer $container - * @param \OC_Router $router + * @param \OCP\Route\IRouter $router * @internal param $appName */ - public function __construct(DIContainer $container, \OC_Router $router, $routes) { + public function __construct(DIContainer $container, IRouter $router, $routes) { $this->routes = $routes; $this->container = $container; $this->router = $router; @@ -47,7 +48,7 @@ class RouteConfig { } /** - * The routes and resource will be registered to the \OC_Router + * The routes and resource will be registered to the \OCP\Route\IRouter */ public function register() { diff --git a/lib/private/route.php b/lib/private/route.php deleted file mode 100644 index fb7da456b62..00000000000 --- a/lib/private/route.php +++ /dev/null @@ -1,124 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -use Symfony\Component\Routing\Route; - -class OC_Route extends Route { - /** - * Specify the method when this route is to be used - * - * @param string $method HTTP method (uppercase) - */ - public function method($method) { - $this->setRequirement('_method', strtoupper($method)); - return $this; - } - - /** - * Specify POST as the method to use with this route - */ - public function post() { - $this->method('POST'); - return $this; - } - - /** - * Specify GET as the method to use with this route - */ - public function get() { - $this->method('GET'); - return $this; - } - - /** - * Specify PUT as the method to use with this route - */ - public function put() { - $this->method('PUT'); - return $this; - } - - /** - * Specify DELETE as the method to use with this route - */ - public function delete() { - $this->method('DELETE'); - return $this; - } - - /** - * Specify PATCH as the method to use with this route - */ - public function patch() { - $this->method('PATCH'); - return $this; - } - - /** - * Defaults to use for this route - * - * @param array $defaults The defaults - */ - public function defaults($defaults) { - $action = $this->getDefault('action'); - $this->setDefaults($defaults); - if (isset($defaults['action'])) { - $action = $defaults['action']; - } - $this->action($action); - return $this; - } - - /** - * Requirements for this route - * - * @param array $requirements The requirements - */ - public function requirements($requirements) { - $method = $this->getRequirement('_method'); - $this->setRequirements($requirements); - if (isset($requirements['_method'])) { - $method = $requirements['_method']; - } - if ($method) { - $this->method($method); - } - return $this; - } - - /** - * The action to execute when this route matches - * @param string|callable $class the class or a callable - * @param string $function the function to use with the class - * - * This function is called with $class set to a callable or - * to the class with $function - */ - public function action($class, $function = null) { - $action = array($class, $function); - if (is_null($function)) { - $action = $class; - } - $this->setDefault('action', $action); - return $this; - } - - /** - * The action to execute when this route matches, includes a file like - * it is called directly - * @param $file - */ - public function actionInclude($file) { - $function = create_function('$param', - 'unset($param["_route"]);' - .'$_GET=array_merge($_GET, $param);' - .'unset($param);' - .'require_once "'.$file.'";'); - $this->action($function); - } -} diff --git a/lib/private/route/route.php b/lib/private/route/route.php new file mode 100644 index 00000000000..6ade9ec15f6 --- /dev/null +++ b/lib/private/route/route.php @@ -0,0 +1,132 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Route; + +use OCP\Route\IRoute; +use Symfony\Component\Routing\Route as SymfonyRoute; + +class Route extends SymfonyRoute implements IRoute { + /** + * Specify the method when this route is to be used + * + * @param string $method HTTP method (uppercase) + * @return \OC\Route\Route + */ + public function method($method) { + $this->setRequirement('_method', strtoupper($method)); + return $this; + } + + /** + * Specify POST as the method to use with this route + */ + public function post() { + $this->method('POST'); + return $this; + } + + /** + * Specify GET as the method to use with this route + */ + public function get() { + $this->method('GET'); + return $this; + } + + /** + * Specify PUT as the method to use with this route + */ + public function put() { + $this->method('PUT'); + return $this; + } + + /** + * Specify DELETE as the method to use with this route + */ + public function delete() { + $this->method('DELETE'); + return $this; + } + + /** + * Specify PATCH as the method to use with this route + */ + public function patch() { + $this->method('PATCH'); + return $this; + } + + /** + * Defaults to use for this route + * + * @param array $defaults The defaults + * @return \OC\Route\Route + */ + public function defaults($defaults) { + $action = $this->getDefault('action'); + $this->setDefaults($defaults); + if (isset($defaults['action'])) { + $action = $defaults['action']; + } + $this->action($action); + return $this; + } + + /** + * Requirements for this route + * + * @param array $requirements The requirements + * @return \OC\Route\Route + */ + public function requirements($requirements) { + $method = $this->getRequirement('_method'); + $this->setRequirements($requirements); + if (isset($requirements['_method'])) { + $method = $requirements['_method']; + } + if ($method) { + $this->method($method); + } + return $this; + } + + /** + * The action to execute when this route matches + * + * @param string|callable $class the class or a callable + * @param string $function the function to use with the class + * @return \OC\Route\Route + * + * This function is called with $class set to a callable or + * to the class with $function + */ + public function action($class, $function = null) { + $action = array($class, $function); + if (is_null($function)) { + $action = $class; + } + $this->setDefault('action', $action); + return $this; + } + + /** + * The action to execute when this route matches, includes a file like + * it is called directly + * @param $file + */ + public function actionInclude($file) { + $function = create_function('$param', + 'unset($param["_route"]);' + .'$_GET=array_merge($_GET, $param);' + .'unset($param);' + .'require_once "'.$file.'";'); + $this->action($function); + } +} diff --git a/lib/private/route/router.php b/lib/private/route/router.php new file mode 100644 index 00000000000..60ba5878401 --- /dev/null +++ b/lib/private/route/router.php @@ -0,0 +1,202 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Route; + +use OCP\Route\IRouter; +use Symfony\Component\Routing\Matcher\UrlMatcher; +use Symfony\Component\Routing\Generator\UrlGenerator; +use Symfony\Component\Routing\RequestContext; +use Symfony\Component\Routing\RouteCollection; + +class Router implements IRouter { + /** + * @var \Symfony\Component\Routing\RouteCollection[] + */ + protected $collections = array(); + + /** + * @var \Symfony\Component\Routing\RouteCollection + */ + protected $collection = null; + + /** + * @var \Symfony\Component\Routing\RouteCollection + */ + protected $root = null; + + /** + * @var \Symfony\Component\Routing\Generator\UrlGenerator + */ + protected $generator = null; + + /** + * @var string[] + */ + protected $routingFiles; + + /** + * @var string + */ + protected $cacheKey; + + protected $loaded = false; + + public function __construct() { + $baseUrl = \OC_Helper::linkTo('', 'index.php'); + if (!\OC::$CLI) { + $method = $_SERVER['REQUEST_METHOD']; + } else { + $method = 'GET'; + } + $host = \OC_Request::serverHost(); + $schema = \OC_Request::serverProtocol(); + $this->context = new RequestContext($baseUrl, $method, $host, $schema); + // TODO cache + $this->root = $this->getCollection('root'); + } + + /** + * Get the files to load the routes from + * + * @return string[] + */ + public function getRoutingFiles() { + if (!isset($this->routingFiles)) { + $this->routingFiles = array(); + foreach (\OC_APP::getEnabledApps() as $app) { + $file = \OC_App::getAppPath($app) . '/appinfo/routes.php'; + if (file_exists($file)) { + $this->routingFiles[$app] = $file; + } + } + } + return $this->routingFiles; + } + + public function getCacheKey() { + if (!isset($this->cacheKey)) { + $files = $this->getRoutingFiles(); + $files[] = 'settings/routes.php'; + $files[] = 'core/routes.php'; + $files[] = 'ocs/routes.php'; + $this->cacheKey = \OC_Cache::generateCacheKeyFromFiles($files); + } + return $this->cacheKey; + } + + /** + * loads the api routes + */ + public function loadRoutes() { + if ($this->loaded) { + return; + } + $this->loaded = true; + foreach ($this->getRoutingFiles() as $app => $file) { + $this->useCollection($app); + require_once $file; + $collection = $this->getCollection($app); + $collection->addPrefix('/apps/' . $app); + $this->root->addCollection($collection); + } + $this->useCollection('root'); + require_once 'settings/routes.php'; + require_once 'core/routes.php'; + + // include ocs routes + require_once 'ocs/routes.php'; + $collection = $this->getCollection('ocs'); + $collection->addPrefix('/ocs'); + $this->root->addCollection($collection); + } + + /** + * @param string $name + * @return \Symfony\Component\Routing\RouteCollection + */ + protected function getCollection($name) { + if (!isset($this->collections[$name])) { + $this->collections[$name] = new RouteCollection(); + } + return $this->collections[$name]; + } + + /** + * Sets the collection to use for adding routes + * + * @param string $name Name of the collection to use. + */ + public function useCollection($name) { + $this->collection = $this->getCollection($name); + } + + /** + * Create a \OC\Route\Route. + * + * @param string $name Name of the route to create. + * @param string $pattern The pattern to match + * @param array $defaults An array of default parameter values + * @param array $requirements An array of requirements for parameters (regexes) + * @return \OC\Route\Route + */ + public function create($name, $pattern, array $defaults = array(), array $requirements = array()) { + $route = new Route($pattern, $defaults, $requirements); + $this->collection->add($name, $route); + return $route; + } + + /** + * Find the route matching $url. + * + * @param string $url The url to find + * @throws \Exception + */ + public function match($url) { + $matcher = new UrlMatcher($this->root, $this->context); + $parameters = $matcher->match($url); + if (isset($parameters['action'])) { + $action = $parameters['action']; + if (!is_callable($action)) { + var_dump($action); + throw new \Exception('not a callable action'); + } + unset($parameters['action']); + call_user_func($action, $parameters); + } elseif (isset($parameters['file'])) { + include $parameters['file']; + } else { + throw new \Exception('no action available'); + } + } + + /** + * Get the url generator + * + */ + public function getGenerator() { + if (null !== $this->generator) { + return $this->generator; + } + + return $this->generator = new UrlGenerator($this->root, $this->context); + } + + /** + * Generate url based on $name and $parameters + * + * @param string $name Name of the route to use. + * @param array $parameters Parameters for the route + * @param bool $absolute + * @return string + */ + public function generate($name, $parameters = array(), $absolute = false) { + return $this->getGenerator()->generate($name, $parameters, $absolute); + } + +} diff --git a/lib/private/router.php b/lib/private/router.php deleted file mode 100644 index 918e3b13206..00000000000 --- a/lib/private/router.php +++ /dev/null @@ -1,161 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -use Symfony\Component\Routing\Matcher\UrlMatcher; -use Symfony\Component\Routing\Generator\UrlGenerator; -use Symfony\Component\Routing\RequestContext; -use Symfony\Component\Routing\RouteCollection; -//use Symfony\Component\Routing\Route; - -class OC_Router { - protected $collections = array(); - protected $collection = null; - protected $root = null; - - protected $generator = null; - protected $routing_files; - protected $cache_key; - - public function __construct() { - $baseUrl = OC_Helper::linkTo('', 'index.php'); - if ( !OC::$CLI) { - $method = $_SERVER['REQUEST_METHOD']; - }else{ - $method = 'GET'; - } - $host = OC_Request::serverHost(); - $schema = OC_Request::serverProtocol(); - $this->context = new RequestContext($baseUrl, $method, $host, $schema); - // TODO cache - $this->root = $this->getCollection('root'); - } - - public function getRoutingFiles() { - if (!isset($this->routing_files)) { - $this->routing_files = array(); - foreach(OC_APP::getEnabledApps() as $app) { - $file = OC_App::getAppPath($app).'/appinfo/routes.php'; - if(file_exists($file)) { - $this->routing_files[$app] = $file; - } - } - } - return $this->routing_files; - } - - public function getCacheKey() { - if (!isset($this->cache_key)) { - $files = $this->getRoutingFiles(); - $files[] = 'settings/routes.php'; - $files[] = 'core/routes.php'; - $files[] = 'ocs/routes.php'; - $this->cache_key = OC_Cache::generateCacheKeyFromFiles($files); - } - return $this->cache_key; - } - - /** - * loads the api routes - */ - public function loadRoutes() { - foreach($this->getRoutingFiles() as $app => $file) { - $this->useCollection($app); - require_once $file; - $collection = $this->getCollection($app); - $collection->addPrefix('/apps/'.$app); - $this->root->addCollection($collection); - } - $this->useCollection('root'); - require_once 'settings/routes.php'; - require_once 'core/routes.php'; - - // include ocs routes - require_once 'ocs/routes.php'; - $collection = $this->getCollection('ocs'); - $collection->addPrefix('/ocs'); - $this->root->addCollection($collection); - } - - protected function getCollection($name) { - if (!isset($this->collections[$name])) { - $this->collections[$name] = new RouteCollection(); - } - return $this->collections[$name]; - } - - /** - * Sets the collection to use for adding routes - * - * @param string $name Name of the colletion to use. - */ - public function useCollection($name) { - $this->collection = $this->getCollection($name); - } - - /** - * Create a OC_Route. - * - * @param string $name Name of the route to create. - * @param string $pattern The pattern to match - * @param array $defaults An array of default parameter values - * @param array $requirements An array of requirements for parameters (regexes) - */ - public function create($name, $pattern, array $defaults = array(), array $requirements = array()) { - $route = new OC_Route($pattern, $defaults, $requirements); - $this->collection->add($name, $route); - return $route; - } - - /** - * Find the route matching $url. - * - * @param string $url The url to find - */ - public function match($url) { - $matcher = new UrlMatcher($this->root, $this->context); - $parameters = $matcher->match($url); - if (isset($parameters['action'])) { - $action = $parameters['action']; - if (!is_callable($action)) { - var_dump($action); - throw new Exception('not a callable action'); - } - unset($parameters['action']); - call_user_func($action, $parameters); - } elseif (isset($parameters['file'])) { - include $parameters['file']; - } else { - throw new Exception('no action available'); - } - } - - /** - * Get the url generator - * - */ - public function getGenerator() - { - if (null !== $this->generator) { - return $this->generator; - } - - return $this->generator = new UrlGenerator($this->root, $this->context); - } - - /** - * Generate url based on $name and $parameters - * - * @param string $name Name of the route to use. - * @param array $parameters Parameters for the route - */ - public function generate($name, $parameters = array(), $absolute = false) - { - return $this->getGenerator()->generate($name, $parameters, $absolute); - } - -} diff --git a/lib/private/server.php b/lib/private/server.php index 7696fc207fd..8c9ea39c562 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -158,6 +158,10 @@ class Server extends SimpleContainer implements IServerContainer { $config = $c->getConfig(); return new \OC\BackgroundJob\JobList($c->getDatabaseConnection(), $config); }); + $this->registerService('Router', function ($c){ + $router = new \OC\Route\Router(); + return $router; + }); } /** @@ -364,4 +368,15 @@ class Server extends SimpleContainer implements IServerContainer { function getJobList(){ return $this->query('JobList'); } + + /** + * Returns a router for generating and matching urls + * + * @return \OCP\Route\IRouter + */ + function getRouter(){ + $router = $this->query('Router'); + $router->loadRoutes(); + return $router; + } } diff --git a/lib/public/appframework/app.php b/lib/public/appframework/app.php index 90150245c41..21612327879 100644 --- a/lib/public/appframework/app.php +++ b/lib/public/appframework/app.php @@ -67,7 +67,7 @@ class App { * $a = new TasksApp(); * $a->registerRoutes($this, $routes); * - * @param \OC_Router $router + * @param \OCP\Route\IRouter $router * @param array $routes */ public function registerRoutes($router, $routes) { diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index 5fb51f9ecd5..dc3aff663d4 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -190,4 +190,10 @@ interface IServerContainer { */ function getJobList(); + /** + * Returns a router for generating and matching urls + * + * @return \OCP\Route\IRouter + */ + function getRouter(); } diff --git a/lib/public/route/iroute.php b/lib/public/route/iroute.php new file mode 100644 index 00000000000..66fdb841821 --- /dev/null +++ b/lib/public/route/iroute.php @@ -0,0 +1,79 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +namespace OCP\Route; + +interface IRoute { + /** + * Specify PATCH as the method to use with this route + */ + public function patch(); + + /** + * Specify the method when this route is to be used + * + * @param string $method HTTP method (uppercase) + * @return \OCP\Route\IRoute + */ + public function method($method); + + /** + * The action to execute when this route matches, includes a file like + * it is called directly + * + * @param $file + */ + public function actionInclude($file); + + /** + * Specify GET as the method to use with this route + */ + public function get(); + + /** + * Specify POST as the method to use with this route + */ + public function post(); + + /** + * Specify DELETE as the method to use with this route + */ + public function delete(); + + /** + * The action to execute when this route matches + * + * @param string|callable $class the class or a callable + * @param string $function the function to use with the class + * @return \OCP\Route\IRoute + * + * This function is called with $class set to a callable or + * to the class with $function + */ + public function action($class, $function = null); + + /** + * Defaults to use for this route + * + * @param array $defaults The defaults + * @return \OCP\Route\IRoute + */ + public function defaults($defaults); + + /** + * Requirements for this route + * + * @param array $requirements The requirements + * @return \OCP\Route\IRoute + */ + public function requirements($requirements); + + /** + * Specify PUT as the method to use with this route + */ + public function put(); +} diff --git a/lib/public/route/irouter.php b/lib/public/route/irouter.php new file mode 100644 index 00000000000..deb01bca9b9 --- /dev/null +++ b/lib/public/route/irouter.php @@ -0,0 +1,71 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP\Route; + +interface IRouter { + + public function __construct(); + + /** + * Get the files to load the routes from + * + * @return string[] + */ + public function getRoutingFiles(); + + public function getCacheKey(); + + /** + * loads the api routes + */ + public function loadRoutes(); + + /** + * Sets the collection to use for adding routes + * + * @param string $name Name of the collection to use. + */ + public function useCollection($name); + + /** + * Create a \OCP\Route\IRoute. + * + * @param string $name Name of the route to create. + * @param string $pattern The pattern to match + * @param array $defaults An array of default parameter values + * @param array $requirements An array of requirements for parameters (regexes) + * @return \OCP\Route\IRoute + */ + public function create($name, $pattern, array $defaults = array(), array $requirements = array()); + + /** + * Find the route matching $url. + * + * @param string $url The url to find + * @throws \Exception + */ + public function match($url); + + /** + * Get the url generator + * + */ + public function getGenerator(); + + /** + * Generate url based on $name and $parameters + * + * @param string $name Name of the route to use. + * @param array $parameters Parameters for the route + * @param bool $absolute + * @return string + */ + public function generate($name, $parameters = array(), $absolute = false); + +} diff --git a/tests/lib/appframework/routing/RoutingTest.php b/tests/lib/appframework/routing/RoutingTest.php index d0244cf2511..9f2675bf0b4 100644 --- a/tests/lib/appframework/routing/RoutingTest.php +++ b/tests/lib/appframework/routing/RoutingTest.php @@ -46,7 +46,7 @@ class RouteConfigTest extends \PHPUnit_Framework_TestCase )); // router mock - $router = $this->getMock("\OC_Router", array('create')); + $router = $this->getMock("\OC\Route\Router", array('create')); // load route configuration $container = new DIContainer('app1'); @@ -91,7 +91,7 @@ class RouteConfigTest extends \PHPUnit_Framework_TestCase $route = $this->mockRoute($verb, $controllerName, $actionName); // router mock - $router = $this->getMock("\OC_Router", array('create')); + $router = $this->getMock("\OC\Route\Router", array('create')); // we expect create to be called once: $router @@ -116,7 +116,7 @@ class RouteConfigTest extends \PHPUnit_Framework_TestCase private function assertResource($yaml, $resourceName, $url, $controllerName, $paramName) { // router mock - $router = $this->getMock("\OC_Router", array('create')); + $router = $this->getMock("\OC\Route\Router", array('create')); // route mocks $indexRoute = $this->mockRoute('GET', $controllerName, 'index'); @@ -174,7 +174,7 @@ class RouteConfigTest extends \PHPUnit_Framework_TestCase private function mockRoute($verb, $controllerName, $actionName) { $container = new DIContainer('app1'); - $route = $this->getMock("\OC_Route", array('method', 'action'), array(), '', false); + $route = $this->getMock("\OC\Route\Route", array('method', 'action'), array(), '', false); $route ->expects($this->exactly(1)) ->method('method') -- cgit v1.2.3 From 010eef95c0c5cebd03b03645d29847638e064bd5 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 10 Mar 2014 15:19:18 +0100 Subject: Fixed total space display when data size exceeds quota The total space display in the personal page now shows the quota value instead of used space when used space exceeds the quota (soft quota). --- lib/private/files/storage/wrapper/quota.php | 7 ++ lib/private/helper.php | 11 ++- tests/lib/helperstorage.php | 113 ++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 tests/lib/helperstorage.php (limited to 'tests') diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php index 26c952e694a..0e0d5b13104 100644 --- a/lib/private/files/storage/wrapper/quota.php +++ b/lib/private/files/storage/wrapper/quota.php @@ -29,6 +29,13 @@ class Quota extends Wrapper { $this->sizeRoot = isset($parameters['root']) ? $parameters['root'] : ''; } + /** + * @return quota value + */ + public function getQuota() { + return $this->quota; + } + /** * @param string $path */ diff --git a/lib/private/helper.php b/lib/private/helper.php index b9956d5ec1c..0b1a26bbecd 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -914,13 +914,22 @@ class OC_Helper { if ($used < 0) { $used = 0; } - $free = \OC\Files\Filesystem::free_space($path); + $quota = 0; + // TODO: need a better way to get total space from storage + $storage = $rootInfo->getStorage(); + if ($storage instanceof \OC\Files\Storage\Wrapper\Quota) { + $quota = $storage->getQuota(); + } + $free = $storage->free_space(''); if ($free >= 0) { $total = $free + $used; } else { $total = $free; //either unknown or unlimited } if ($total > 0) { + if ($quota > 0 && $total > $quota) { + $total = $quota; + } // prevent division by zero or error codes (negative values) $relative = round(($used / $total) * 10000) / 100; } else { diff --git a/tests/lib/helperstorage.php b/tests/lib/helperstorage.php new file mode 100644 index 00000000000..010a54e3bb0 --- /dev/null +++ b/tests/lib/helperstorage.php @@ -0,0 +1,113 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +/** + * Test the storage functions of OC_Helper + */ +class Test_Helper_Storage extends PHPUnit_Framework_TestCase { + private $user; + private $storageMock; + + public function setUp() { + $this->user = 'user_' . uniqid(); + \OC\Files\Filesystem::tearDown(); + \OC\Files\Filesystem::init($this->user, '/' . $this->user . '/files'); + + $this->storageMock = $this->getMock( + '\OC\Files\Storage\Temporary', + array('free_space'), + array('') + ); + + \OC\Files\Filesystem::clearMounts(); + + $this->storageMock->expects($this->once()) + ->method('free_space') + ->will($this->returnValue(12)); + } + + public function tearDown() { + $this->user = null; + + $this->storageMock->getCache()->clear(); + \OC\Files\Filesystem::tearDown(); + } + + /** + * Test getting the storage info + */ + function testGetStorageInfo() { + \OC\Files\Filesystem::mount($this->storageMock, array(), '/' . $this->user . '/files'); + $this->storageMock->file_put_contents('test.txt', '01234'); + + $storageInfo = \OC_Helper::getStorageInfo(''); + $this->assertEquals(12, $storageInfo['free']); + $this->assertEquals(5, $storageInfo['used']); + $this->assertEquals(17, $storageInfo['total']); + } + + /** + * Test getting the storage info with quota enabled + */ + function testGetStorageInfoWithQuota() { + $this->storageMock->file_put_contents('test.txt', '01234'); + $this->storageMock = new \OC\Files\Storage\Wrapper\Quota( + array( + 'storage' => $this->storageMock, + 'quota' => 7 + ) + ); + \OC\Files\Filesystem::mount($this->storageMock, array(), '/' . $this->user . '/files'); + + $storageInfo = \OC_Helper::getStorageInfo(''); + $this->assertEquals(2, $storageInfo['free']); + $this->assertEquals(5, $storageInfo['used']); + $this->assertEquals(7, $storageInfo['total']); + } + + /** + * Test getting the storage info when data exceeds quota + */ + function testGetStorageInfoWhenSizeExceedsQuota() { + $this->storageMock->file_put_contents('test.txt', '0123456789'); + $this->storageMock = new \OC\Files\Storage\Wrapper\Quota( + array( + 'storage' => $this->storageMock, + 'quota' => 7 + ) + ); + \OC\Files\Filesystem::mount($this->storageMock, array(), '/' . $this->user . '/files'); + + $storageInfo = \OC_Helper::getStorageInfo(''); + $this->assertEquals(0, $storageInfo['free']); + $this->assertEquals(10, $storageInfo['used']); + // total = quota + $this->assertEquals(7, $storageInfo['total']); + } + + /** + * Test getting the storage info when the remaining + * free storage space is less than the quota + */ + function testGetStorageInfoWhenFreeSpaceLessThanQuota() { + $this->storageMock->file_put_contents('test.txt', '01234'); + $this->storageMock = new \OC\Files\Storage\Wrapper\Quota( + array( + 'storage' => $this->storageMock, + 'quota' => 18 + ) + ); + \OC\Files\Filesystem::mount($this->storageMock, array(), '/' . $this->user . '/files'); + + $storageInfo = \OC_Helper::getStorageInfo(''); + $this->assertEquals(12, $storageInfo['free']); + $this->assertEquals(5, $storageInfo['used']); + // total = free + used (because quota > total) + $this->assertEquals(17, $storageInfo['total']); + } +} -- cgit v1.2.3 From d798169037e666ab9b4165666193019d4dd18aaf Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 11 Mar 2014 21:01:16 +0100 Subject: Cleanup the fileproxy proxies on test bootstrap --- tests/bootstrap.php | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 581cfcff9f3..88f5de4b584 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -11,3 +11,4 @@ if(!class_exists('PHPUnit_Framework_TestCase')) { OC_Hook::clear(); OC_Log::$enabled = false; +OC_FileProxy::clearProxies(); -- cgit v1.2.3 From a8eb7a5092fad987b96f9dac947dc9bf4a2b0eaf Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 13 Mar 2014 13:33:09 +0100 Subject: Allow setting the config dir to use as enviroment variable for phpunit --- lib/base.php | 4 +++- tests/bootstrap.php | 9 +++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/lib/base.php b/lib/base.php index 86ee5349828..2d4a9f92764 100644 --- a/lib/base.php +++ b/lib/base.php @@ -103,7 +103,9 @@ class OC { get_include_path() ); - if(defined('PHPUNIT_RUN') and PHPUNIT_RUN and is_dir(OC::$SERVERROOT . '/tests/config/')) { + if(defined('PHPUNIT_CONFIG_DIR')) { + self::$configDir = OC::$SERVERROOT . '/' . PHPUNIT_CONFIG_DIR . '/'; + } elseif(defined('PHPUNIT_RUN') and PHPUNIT_RUN and is_dir(OC::$SERVERROOT . '/tests/config/')) { self::$configDir = OC::$SERVERROOT . '/tests/config/'; } else { self::$configDir = OC::$SERVERROOT . '/config/'; diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 581cfcff9f3..70de7cd1c44 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -3,9 +3,14 @@ define('PHPUNIT_RUN', 1); -require_once __DIR__.'/../lib/base.php'; +$configDir = getenv('CONFIG_DIR'); +if ($configDir) { + define('PHPUNIT_CONFIG_DIR', $configDir); +} + +require_once __DIR__ . '/../lib/base.php'; -if(!class_exists('PHPUnit_Framework_TestCase')) { +if (!class_exists('PHPUnit_Framework_TestCase')) { require_once('PHPUnit/Autoload.php'); } -- cgit v1.2.3 From fc697c729811e5644e2c7bc884bd54d3ff092ac8 Mon Sep 17 00:00:00 2001 From: Thomas Müller Date: Thu, 13 Mar 2014 16:19:17 +0100 Subject: adding StartSessionListener which initializes the session before each test case execution --- tests/phpunit-autotest.xml | 1 + tests/phpunit.xml.dist | 3 +++ tests/startsessionlistener.php | 45 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 tests/startsessionlistener.php (limited to 'tests') diff --git a/tests/phpunit-autotest.xml b/tests/phpunit-autotest.xml index 1a2ab35491b..872ff2c2596 100644 --- a/tests/phpunit-autotest.xml +++ b/tests/phpunit-autotest.xml @@ -36,6 +36,7 @@ + detail diff --git a/tests/phpunit.xml.dist b/tests/phpunit.xml.dist index 71a4ff2762c..21c63ea0469 100644 --- a/tests/phpunit.xml.dist +++ b/tests/phpunit.xml.dist @@ -29,4 +29,7 @@ + + + diff --git a/tests/startsessionlistener.php b/tests/startsessionlistener.php new file mode 100644 index 00000000000..fb7fa83e090 --- /dev/null +++ b/tests/startsessionlistener.php @@ -0,0 +1,45 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +/** + * Starts a new session before each test execution + */ +class StartSessionListener implements PHPUnit_Framework_TestListener { + + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) { + } + + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) { + } + + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) { + } + + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) { + } + + public function startTest(PHPUnit_Framework_Test $test) { + + // new session + \OC::$session = new \OC\Session\Memory(''); + + // load the version + OC_Util::getVersion(); + + } + + public function endTest(PHPUnit_Framework_Test $test, $time) { + } + + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) { + } + + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) { + } + +} -- cgit v1.2.3 From 3c46dcd7ddde403cdc89abdaabd3879fc71d39b9 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 14 Mar 2014 13:03:18 +0100 Subject: Added .ocdata file to check for data folder validity In environments where the data folder is mount from another partition, it is important to check that the data folder we see is actually the real one. If the mount failed for some reasons, this fix will make ownCloud temporarily unavailable instead of causing unpredictable behavior. --- lib/private/setup.php | 4 ++ lib/private/updater.php | 5 ++ lib/private/util.php | 32 +++++++++++-- tests/lib/utilcheckserver.php | 108 ++++++++++++++++++++++++++++++++++++++++++ tests/testcleanuplistener.php | 1 + 5 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 tests/lib/utilcheckserver.php (limited to 'tests') diff --git a/lib/private/setup.php b/lib/private/setup.php index 0d5bf424b33..b1061b3a25b 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -106,6 +106,10 @@ class OC_Setup { //guess what this does OC_Installer::installShippedApps(); + // create empty file in data dir, so we can later find + // out that this is indeed an ownCloud data directory + file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/.ocdata', ''); + //create htaccess files for apache hosts if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) { self::createHtaccess(); diff --git a/lib/private/updater.php b/lib/private/updater.php index fd2d46a1fac..2ca705193cc 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -105,6 +105,11 @@ class Updater extends BasicEmitter { } $this->emit('\OC\Updater', 'maintenanceStart'); + // create empty file in data dir, so we can later find + // out that this is indeed an ownCloud data directory + // (in case it didn't exist before) + file_put_contents(\OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', ''); + /* * START CONFIG CHANGES FOR OLDER VERSIONS */ diff --git a/lib/private/util.php b/lib/private/util.php index 920161949ae..75e1711b0de 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -290,13 +290,19 @@ class OC_Util { * @return array arrays with error messages and hints */ public static function checkServer() { + $errors = array(); + $CONFIG_DATADIRECTORY = OC_Config::getValue('datadirectory', OC::$SERVERROOT . '/data'); + + if (!\OC::needUpgrade() && OC_Config::getValue('installed', false)) { + // this check needs to be done every time + $errors = self::checkDataDirectoryValidity($CONFIG_DATADIRECTORY); + } + // Assume that if checkServer() succeeded before in this session, then all is fine. if(\OC::$session->exists('checkServer_suceeded') && \OC::$session->get('checkServer_suceeded')) { - return array(); + return $errors; } - $errors = array(); - $defaults = new \OC_Defaults(); $webServerRestart = false; @@ -341,7 +347,6 @@ class OC_Util { ); } } - $CONFIG_DATADIRECTORY = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ); // Create root dir. if(!is_dir($CONFIG_DATADIRECTORY)) { $success=@mkdir($CONFIG_DATADIRECTORY); @@ -540,6 +545,25 @@ class OC_Util { return $errors; } + /** + * Check that the data directory exists and is valid by + * checking the existence of the ".ocdata" file. + * + * @param string $dataDirectory data directory path + * @return bool true if the data directory is valid, false otherwise + */ + public static function checkDataDirectoryValidity($dataDirectory) { + $errors = array(); + if (!file_exists($dataDirectory.'/.ocdata')) { + $errors[] = array( + 'error' => 'Data directory (' . $dataDirectory . ') is invalid', + 'hint' => 'Please check that the data directory contains a file' . + ' ".ocdata" in its root.' + ); + } + return $errors; + } + /** * @return void */ diff --git a/tests/lib/utilcheckserver.php b/tests/lib/utilcheckserver.php new file mode 100644 index 00000000000..155d617c4ad --- /dev/null +++ b/tests/lib/utilcheckserver.php @@ -0,0 +1,108 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +/** + * Tests for server check functions + */ +class Test_Util_CheckServer extends PHPUnit_Framework_TestCase { + + private $datadir; + + public function setUp() { + $this->datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data'); + + file_put_contents($this->datadir . '/.ocdata', ''); + } + + public function tearDown() { + // clean up + @unlink($this->datadir . '/.ocdata'); + } + + /** + * Test that checkServer() returns no errors in the regular case. + */ + public function testCheckServer() { + $result = \OC_Util::checkServer(); + $this->assertEmpty($result); + } + + /** + * Test that checkServer() does not check the data dir validity + * when the server is not installed yet (else the setup cannot + * be run...) + */ + public function testCheckServerSkipDataDirValidityOnSetup() { + // simulate old version that didn't have it + unlink($this->datadir . '/.ocdata'); + + $session = \OC::$server->getSession(); + $oldInstalled = \OC_Config::getValue('installed', false); + + // simulate that the server isn't setup yet + \OC_Config::setValue('installed', false); + + // even though ".ocdata" is missing, the error isn't + // triggered to allow setup to run + $result = \OC_Util::checkServer(); + $this->assertEmpty($result); + + // restore config + \OC_Config::setValue('installed', $oldInstalled); + } + + /** + * Test that checkServer() does not check the data dir validity + * when an upgrade is required (else the upgrade cannot be + * performed...) + */ + public function testCheckServerSkipDataDirValidityOnUpgrade() { + // simulate old version that didn't have it + unlink($this->datadir . '/.ocdata'); + + $session = \OC::$server->getSession(); + $oldCurrentVersion = $session->get('OC_Version'); + $oldInstallVersion = \OC_Config::getValue('version', '0.0.0'); + + // upgrade condition to simulate needUpgrade() === true + $session->set('OC_Version', array(6, 0, 0, 2)); + \OC_Config::setValue('version', '6.0.0.1'); + + // even though ".ocdata" is missing, the error isn't + // triggered to allow for upgrade + $result = \OC_Util::checkServer(); + $this->assertEmpty($result); + + // restore versions + $session->set('OC_Version', $oldCurrentVersion); + \OC_Config::setValue('version', $oldInstallVersion); + } + + /** + * Test that checkDataDirectoryValidity returns no error + * when ".ocdata" is present. + */ + public function testCheckDataDirValidity() { + $result = \OC_Util::checkDataDirectoryValidity($this->datadir); + $this->assertEmpty($result); + } + + /** + * Test that checkDataDirectoryValidity and checkServer + * both return an error when ".ocdata" is missing. + */ + public function testCheckDataDirValidityWhenFileMissing() { + unlink($this->datadir . '/.ocdata'); + $result = \OC_Util::checkDataDirectoryValidity($this->datadir); + $this->assertEquals(1, count($result)); + + $result = \OC_Util::checkServer(); + $this->assertEquals(1, count($result)); + } + +} diff --git a/tests/testcleanuplistener.php b/tests/testcleanuplistener.php index 299a589ef4e..2083ffce67c 100644 --- a/tests/testcleanuplistener.php +++ b/tests/testcleanuplistener.php @@ -83,6 +83,7 @@ class TestCleanupListener implements PHPUnit_Framework_TestListener { $knownEntries = array( 'owncloud.log' => true, 'owncloud.db' => true, + '.ocdata' => true, '..' => true, '.' => true ); -- cgit v1.2.3 From fe05c0c81bba1e2203f6ec5c8fbe1007281e1d45 Mon Sep 17 00:00:00 2001 From: Thomas Müller Date: Fri, 14 Mar 2014 18:16:20 +0100 Subject: move session reset to endTest() - necessary because we need a valid session in the next unit tests setUp() call --- tests/startsessionlistener.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/startsessionlistener.php b/tests/startsessionlistener.php index fb7fa83e090..7559b8cff65 100644 --- a/tests/startsessionlistener.php +++ b/tests/startsessionlistener.php @@ -24,16 +24,14 @@ class StartSessionListener implements PHPUnit_Framework_TestListener { } public function startTest(PHPUnit_Framework_Test $test) { + } + public function endTest(PHPUnit_Framework_Test $test, $time) { // new session \OC::$session = new \OC\Session\Memory(''); // load the version OC_Util::getVersion(); - - } - - public function endTest(PHPUnit_Framework_Test $test, $time) { } public function startTestSuite(PHPUnit_Framework_TestSuite $suite) { -- cgit v1.2.3 From cd038604d396b7611353041cb8ed033f23fe305b Mon Sep 17 00:00:00 2001 From: Thomas Müller Date: Mon, 17 Mar 2014 08:40:59 +0100 Subject: unit tests for specific image type output added --- lib/private/image.php | 7 ++++++- tests/lib/image.php | 24 ++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/lib/private/image.php b/lib/private/image.php index dd041442ed6..c987ce92c3c 100644 --- a/lib/private/image.php +++ b/lib/private/image.php @@ -239,7 +239,12 @@ class OC_Image { $retVal = imagepng($this->resource, $filePath); break; case IMAGETYPE_XBM: - $retVal = imagexbm($this->resource, $filePath); + if (function_exists('imagexbm')) { + $retVal = imagexbm($this->resource, $filePath); + } else { + throw new Exception('\OC_Image::_output(): imagexbm() is not supported.'); + } + break; case IMAGETYPE_WBMP: $retVal = imagewbmp($this->resource, $filePath); diff --git a/tests/lib/image.php b/tests/lib/image.php index 4aba1b0bc61..131a9d86f3e 100644 --- a/tests/lib/image.php +++ b/tests/lib/image.php @@ -8,8 +8,8 @@ class Test_Image extends PHPUnit_Framework_TestCase { public static function tearDownAfterClass() { - unlink(OC::$SERVERROOT.'/tests/data/testimage2.png'); - unlink(OC::$SERVERROOT.'/tests/data/testimage2.jpg'); + @unlink(OC::$SERVERROOT.'/tests/data/testimage2.png'); + @unlink(OC::$SERVERROOT.'/tests/data/testimage2.jpg'); } public function testGetMimeTypeForFile() { @@ -236,4 +236,24 @@ class Test_Image extends PHPUnit_Framework_TestCase { $this->assertEquals(200, $img->width()); $this->assertEquals(200, $img->height()); } + + function convertDataProvider() { + return array( + array( 'image/gif'), + array( 'image/jpeg'), + array( 'image/png'), + ); + } + + /** + * @dataProvider convertDataProvider + */ + public function testConvert($mimeType) { + $img = new \OC_Image(OC::$SERVERROOT.'/tests/data/testimage.png'); + $tempFile = tempnam(sys_get_temp_dir(), 'img-test'); + + $img->save($tempFile, $mimeType); + $actualMimeType = \OC_Image::getMimeTypeForFile($tempFile); + $this->assertEquals($mimeType, $actualMimeType); + } } -- cgit v1.2.3 From 145db370d1e83978d0e575a60d7d61fbe1039cc4 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 17 Mar 2014 12:15:12 +0100 Subject: Correctly round bytes when converted from human readable format Instead of leave two decimal places which is confusing, round the byte values correctly to the closest byte. --- lib/private/helper.php | 4 ++-- tests/lib/helper.php | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/lib/private/helper.php b/lib/private/helper.php index 0b1a26bbecd..807fa849637 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -308,7 +308,7 @@ class OC_Helper { /** * @brief Make a computer file size - * @param string $str file size in a fancy format + * @param string $str file size in human readable format * @return int a file size in bytes * * Makes 2kB to 2048. @@ -338,7 +338,7 @@ class OC_Helper { $bytes *= $bytes_array[$matches[1]]; } - $bytes = round($bytes, 2); + $bytes = round($bytes); return $bytes; } diff --git a/tests/lib/helper.php b/tests/lib/helper.php index 4311215795c..0943e6bc1b9 100644 --- a/tests/lib/helper.php +++ b/tests/lib/helper.php @@ -23,6 +23,7 @@ class Test_Helper extends PHPUnit_Framework_TestCase { array('0 B', 0), array('1 kB', 1024), array('9.5 MB', 10000000), + array('1.3 GB', 1395864371), array('465.7 GB', 500000000000), array('454.7 TB', 500000000000000), array('444.1 PB', 500000000000000000), @@ -41,8 +42,9 @@ class Test_Helper extends PHPUnit_Framework_TestCase { return array( array(0.0, "0 B"), array(1024.0, "1 kB"), + array(1395864371.0, '1.3 GB'), array(9961472.0, "9.5 MB"), - array(500041567436.8, "465.7 GB"), + array(500041567437.0, "465.7 GB"), ); } -- cgit v1.2.3 From 6bbbf8536f6d5d21eed906c42da1e12118e4112e Mon Sep 17 00:00:00 2001 From: Thomas Müller Date: Mon, 17 Mar 2014 21:57:10 +0100 Subject: introduce reopen() method to be used for unit test execution only - right after a unit test has been executed the session will be reopened --- lib/private/session/memory.php | 7 +++++++ tests/startsessionlistener.php | 11 ++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/lib/private/session/memory.php b/lib/private/session/memory.php index 8434b6000e5..1497c0f8928 100644 --- a/lib/private/session/memory.php +++ b/lib/private/session/memory.php @@ -63,6 +63,13 @@ class Memory extends Session { $this->data = array(); } + /** + * Helper function for PHPUnit execution - don't use in non-test code + */ + public function reopen() { + $this->sessionClosed = false; + } + /** * In case the session has already been locked an exception will be thrown * diff --git a/tests/startsessionlistener.php b/tests/startsessionlistener.php index 7559b8cff65..808a2a2226f 100644 --- a/tests/startsessionlistener.php +++ b/tests/startsessionlistener.php @@ -27,11 +27,12 @@ class StartSessionListener implements PHPUnit_Framework_TestListener { } public function endTest(PHPUnit_Framework_Test $test, $time) { - // new session - \OC::$session = new \OC\Session\Memory(''); - - // load the version - OC_Util::getVersion(); + // reopen the session - only allowed for memory session + if (\OC::$session instanceof \OC\Session\Memory) { + /** @var $session \OC\Session\Memory */ + $session = \OC::$session; + $session->reopen(); + } } public function startTestSuite(PHPUnit_Framework_TestSuite $suite) { -- cgit v1.2.3 From 66bc0f0848846bce3680b79da4209d42620f1b8d Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 19 Mar 2014 19:07:11 +0100 Subject: Still return quota value when free space is unknown Fixed the quota storage wrapper to correctly return the quota value when the free space is not known (which usually happens when the disk_free_space function is disabled) --- lib/private/files/storage/wrapper/quota.php | 9 ++++++++- tests/lib/files/storage/wrapper/quota.php | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php index 32ceba8b196..a878b2c5cf6 100644 --- a/lib/private/files/storage/wrapper/quota.php +++ b/lib/private/files/storage/wrapper/quota.php @@ -69,7 +69,14 @@ class Quota extends Wrapper { return \OC\Files\SPACE_NOT_COMPUTED; } else { $free = $this->storage->free_space($path); - return min($free, (max($this->quota - $used, 0))); + $quotaFree = max($this->quota - $used, 0); + // if free space is known + if ($free >= 0) { + $free = min($free, $quotaFree); + } else { + $free = $quotaFree; + } + return $free; } } } diff --git a/tests/lib/files/storage/wrapper/quota.php b/tests/lib/files/storage/wrapper/quota.php index bd2c69a7396..777529fd85e 100644 --- a/tests/lib/files/storage/wrapper/quota.php +++ b/tests/lib/files/storage/wrapper/quota.php @@ -61,6 +61,24 @@ class Quota extends \Test\Files\Storage\Storage { $this->assertEquals(6, $instance->free_space('')); } + public function testFreeSpaceWithUnknownDiskSpace() { + $storage = $this->getMock( + '\OC\Files\Storage\Local', + array('free_space'), + array(array('datadir' => $this->tmpDir)) + ); + $storage->expects($this->any()) + ->method('free_space') + ->will($this->returnValue(-2)); + $storage->getScanner()->scan(''); + + $instance = new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => 9)); + $instance->getCache()->put( + '', array('size' => 3, 'unencrypted_size' => 0) + ); + $this->assertEquals(6, $instance->free_space('')); + } + public function testFreeSpaceWithUsedSpaceAndEncryption() { $instance = $this->getLimitedStorage(9); $instance->getCache()->put( -- cgit v1.2.3 From fffe330bbccee617cac6d84d1f4097133de82e44 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 20 Mar 2014 15:32:12 +0100 Subject: Fix parameter order for Storage\Local::hash --- lib/private/files/storage/local.php | 2 +- lib/private/files/storage/mappedlocal.php | 2 +- tests/lib/files/storage/storage.php | 47 +++++++++++++++++++++---------- 3 files changed, 34 insertions(+), 17 deletions(-) (limited to 'tests') diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index a62230bdba5..071b12ffbd5 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -256,7 +256,7 @@ if (\OC_Util::runningOnWindows()) { return 0; } - public function hash($path, $type, $raw = false) { + public function hash($type, $path, $raw = false) { return hash_file($type, $this->datadir . $path, $raw); } diff --git a/lib/private/files/storage/mappedlocal.php b/lib/private/files/storage/mappedlocal.php index 1bab3489a28..cb5ab6902e6 100644 --- a/lib/private/files/storage/mappedlocal.php +++ b/lib/private/files/storage/mappedlocal.php @@ -276,7 +276,7 @@ class MappedLocal extends \OC\Files\Storage\Common{ return 0; } - public function hash($path, $type, $raw=false) { + public function hash($type, $path, $raw=false) { return hash_file($type, $this->buildPath($path), $raw); } diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index f9291758606..f3bfba3feb8 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -64,17 +64,17 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { * @dataProvider directoryProvider */ public function testDirectories($directory) { - $this->assertFalse($this->instance->file_exists('/'.$directory)); + $this->assertFalse($this->instance->file_exists('/' . $directory)); - $this->assertTrue($this->instance->mkdir('/'.$directory)); + $this->assertTrue($this->instance->mkdir('/' . $directory)); - $this->assertTrue($this->instance->file_exists('/'.$directory)); - $this->assertTrue($this->instance->is_dir('/'.$directory)); - $this->assertFalse($this->instance->is_file('/'.$directory)); - $this->assertEquals('dir', $this->instance->filetype('/'.$directory)); - $this->assertEquals(0, $this->instance->filesize('/'.$directory)); - $this->assertTrue($this->instance->isReadable('/'.$directory)); - $this->assertTrue($this->instance->isUpdatable('/'.$directory)); + $this->assertTrue($this->instance->file_exists('/' . $directory)); + $this->assertTrue($this->instance->is_dir('/' . $directory)); + $this->assertFalse($this->instance->is_file('/' . $directory)); + $this->assertEquals('dir', $this->instance->filetype('/' . $directory)); + $this->assertEquals(0, $this->instance->filesize('/' . $directory)); + $this->assertTrue($this->instance->isReadable('/' . $directory)); + $this->assertTrue($this->instance->isUpdatable('/' . $directory)); $dh = $this->instance->opendir('/'); $content = array(); @@ -85,13 +85,13 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { } $this->assertEquals(array($directory), $content); - $this->assertFalse($this->instance->mkdir('/'.$directory)); //cant create existing folders - $this->assertTrue($this->instance->rmdir('/'.$directory)); + $this->assertFalse($this->instance->mkdir('/' . $directory)); //cant create existing folders + $this->assertTrue($this->instance->rmdir('/' . $directory)); $this->wait(); - $this->assertFalse($this->instance->file_exists('/'.$directory)); + $this->assertFalse($this->instance->file_exists('/' . $directory)); - $this->assertFalse($this->instance->rmdir('/'.$directory)); //cant remove non existing folders + $this->assertFalse($this->instance->rmdir('/' . $directory)); //cant remove non existing folders $dh = $this->instance->opendir('/'); $content = array(); @@ -103,8 +103,7 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertEquals(array(), $content); } - public function directoryProvider() - { + public function directoryProvider() { return array( array('folder'), array(' folder'), @@ -113,6 +112,7 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { array('spéciäl földer'), ); } + /** * test the various uses of file_get_contents and file_put_contents */ @@ -298,4 +298,21 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertFalse($this->instance->file_exists('folder/bar')); $this->assertFalse($this->instance->file_exists('folder')); } + + public function hashProvider(){ + return array( + array('Foobar', 'md5'), + array('Foobar', 'sha1'), + array('Foobar', 'sha256'), + ); + } + + /** + * @dataProvider hashProvider + */ + public function testHash($data, $type) { + $this->instance->file_put_contents('hash.txt', $data); + $this->assertEquals(hash($type, $data), $this->instance->hash($type, 'hash.txt')); + $this->assertEquals(hash($type, $data, true), $this->instance->hash($type, 'hash.txt', true)); + } } -- cgit v1.2.3 From fb7f3008d33cb123f8b6931f6edf8697913b355a Mon Sep 17 00:00:00 2001 From: Thomas Müller Date: Mon, 24 Mar 2014 13:46:31 +0100 Subject: idn have to be converted before being used --- lib/private/mail.php | 17 +++++++++++++++++ tests/lib/mail.php | 30 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 tests/lib/mail.php (limited to 'tests') diff --git a/lib/private/mail.php b/lib/private/mail.php index 9605290fe57..f691fda979d 100644 --- a/lib/private/mail.php +++ b/lib/private/mail.php @@ -73,6 +73,7 @@ class OC_Mail { $mailo->FromName = $fromname;; $mailo->Sender = $fromaddress; try { + $toaddress = self::buildAsciiEmail($toaddress); $mailo->AddAddress($toaddress, $toname); if($ccaddress<>'') $mailo->AddCC($ccaddress, $ccname); @@ -125,6 +126,22 @@ class OC_Mail { * @return bool */ public static function ValidateAddress($emailAddress) { + $emailAddress = self::buildAsciiEmail($emailAddress); return PHPMailer::ValidateAddress($emailAddress); } + + /** + * IDN domains will be properly converted to ascii domains. + * + * @param string $emailAddress + * @return string + */ + public static function buildAsciiEmail($emailAddress) { + + list($name, $domain) = explode('@', $emailAddress, 2); + $domain = idn_to_ascii($domain); + + return "$name@$domain"; + } + } diff --git a/tests/lib/mail.php b/tests/lib/mail.php new file mode 100644 index 00000000000..a88a9d797ae --- /dev/null +++ b/tests/lib/mail.php @@ -0,0 +1,30 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class Test_Mail extends PHPUnit_Framework_TestCase { + + /** + * @dataProvider buildAsciiEmailProvider + * @param $expected + * @param $address + */ + public function testBuildAsciiEmail($expected, $address) { + $actual = \OC_Mail::buildAsciiEmail($address); + $this->assertEquals($expected, $actual); + } + + function buildAsciiEmailProvider() { + return array( + array('info@example.com', 'info@example.com'), + array('info@xn--cjr6vy5ejyai80u.com', 'info@國際化域名.com'), + array('info@xn--mller-kva.de', 'info@müller.de'), + array('info@xn--mller-kva.xn--mller-kva.de', 'info@müller.müller.de'), + ); + } + +} -- cgit v1.2.3 From 1e39719926ea4b204a3b0a3e8aeba6a9a9ad5a96 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 24 Mar 2014 14:32:04 +0100 Subject: Added unit tests for external cache folder --- tests/lib/files/filesystem.php | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'tests') diff --git a/tests/lib/files/filesystem.php b/tests/lib/files/filesystem.php index 90f1dfe581b..53f528af793 100644 --- a/tests/lib/files/filesystem.php +++ b/tests/lib/files/filesystem.php @@ -226,4 +226,55 @@ class Filesystem extends \PHPUnit_Framework_TestCase { $path = $arguments['path']; $this->assertEquals($path, \OC\Files\Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized } + + /** + * Test that the default cache dir is part of the user's home + */ + public function testMountDefaultCacheDir() { + $userId = uniqid('user_'); + $oldCachePath = \OC_Config::getValue('cache_path', ''); + // no cache path configured + \OC_Config::setValue('cache_path', ''); + + \OC_User::createUser($userId, $userId); + \OC\Files\Filesystem::initMountPoints($userId); + + $this->assertEquals( + '/' . $userId . '/', + \OC\Files\Filesystem::getMountPoint('/' . $userId . '/cache') + ); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath('/' . $userId . '/cache'); + $this->assertInstanceOf('\OC\Files\Storage\Home', $storage); + $this->assertEquals('cache', $internalPath); + \OC_User::deleteUser($userId); + + \OC_Config::setValue('cache_path', $oldCachePath); + } + + /** + * Test that an external cache is mounted into + * the user's home + */ + public function testMountExternalCacheDir() { + $userId = uniqid('user_'); + + $oldCachePath = \OC_Config::getValue('cache_path', ''); + // set cache path to temp dir + $cachePath = \OC_Helper::tmpFolder() . '/extcache'; + \OC_Config::setValue('cache_path', $cachePath); + + \OC_User::createUser($userId, $userId); + \OC\Files\Filesystem::initMountPoints($userId); + + $this->assertEquals( + '/' . $userId . '/cache/', + \OC\Files\Filesystem::getMountPoint('/' . $userId . '/cache') + ); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath('/' . $userId . '/cache'); + $this->assertInstanceOf('\OC\Files\Storage\Local', $storage); + $this->assertEquals('', $internalPath); + \OC_User::deleteUser($userId); + + \OC_Config::setValue('cache_path', $oldCachePath); + } } -- cgit v1.2.3 From bc0292c16d5fa8e99727306ef703da1e018defa2 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 6 Mar 2014 14:00:12 +0100 Subject: always return an array --- lib/private/share/share.php | 15 ++++----------- tests/lib/share/share.php | 12 ++++++------ 2 files changed, 10 insertions(+), 17 deletions(-) (limited to 'tests') diff --git a/lib/private/share/share.php b/lib/private/share/share.php index f6f2ac8ccf8..b69f620646f 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -889,7 +889,7 @@ class Share extends \OC\Share\Constants { * @param bool Include collection item types (optional) * @param bool TODO (optional) * @prams bool check expire date - * @return mixed + * @return array * * See public functions getItem(s)... for parameter usage * @@ -898,11 +898,7 @@ class Share extends \OC\Share\Constants { $uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, $includeCollections = false, $itemShareWithBySource = false, $checkExpireDate = true) { if (!self::isEnabled()) { - if ($limit == 1 || (isset($uidOwner) && isset($item))) { - return false; - } else { - return array(); - } + return array(); } $backend = self::getBackend($itemType); $collectionTypes = false; @@ -1214,13 +1210,10 @@ class Share extends \OC\Share\Constants { if (!empty($collectionItems)) { $items = array_merge($items, $collectionItems); } - if (empty($items) && $limit == 1) { - return false; - } + return self::formatResult($items, $column, $backend, $format, $parameters); - } else if ($limit == 1 || (isset($uidOwner) && isset($item))) { - return false; } + return array(); } diff --git a/tests/lib/share/share.php b/tests/lib/share/share.php index b5cba9430aa..aae91fa1087 100644 --- a/tests/lib/share/share.php +++ b/tests/lib/share/share.php @@ -282,7 +282,7 @@ class Test_Share extends PHPUnit_Framework_TestCase { OC_User::setUserId($this->user2); $this->assertEquals(array(OCP\PERMISSION_READ), OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_PERMISSIONS)); OC_User::setUserId($this->user3); - $this->assertFalse(OCP\Share::getItemSharedWith('test', 'test.txt')); + $this->assertSame(array(), OCP\Share::getItemSharedWith('test', 'test.txt')); // Reshare again, and then have owner unshare OC_User::setUserId($this->user1); @@ -292,9 +292,9 @@ class Test_Share extends PHPUnit_Framework_TestCase { OC_User::setUserId($this->user1); $this->assertTrue(OCP\Share::unshare('test', 'test.txt', OCP\Share::SHARE_TYPE_USER, $this->user2)); OC_User::setUserId($this->user2); - $this->assertFalse(OCP\Share::getItemSharedWith('test', 'test.txt')); + $this->assertSame(array(), OCP\Share::getItemSharedWith('test', 'test.txt')); OC_User::setUserId($this->user3); - $this->assertFalse(OCP\Share::getItemSharedWith('test', 'test.txt')); + $this->assertSame(array(), OCP\Share::getItemSharedWith('test', 'test.txt')); // Attempt target conflict OC_User::setUserId($this->user1); @@ -325,7 +325,7 @@ class Test_Share extends PHPUnit_Framework_TestCase { ); OC_User::setUserId($this->user2); - $this->assertFalse( + $this->assertSame(array(), OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_SOURCE), 'Failed asserting that user 2 no longer has access to test.txt after expiration.' ); @@ -526,13 +526,13 @@ class Test_Share extends PHPUnit_Framework_TestCase { ); OC_User::setUserId($this->user2); - $this->assertFalse( + $this->assertSame(array(), OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_SOURCE), 'Failed asserting that user 2 no longer has access to test.txt after expiration.' ); OC_User::setUserId($this->user3); - $this->assertFalse( + $this->assertSame(array(), OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_SOURCE), 'Failed asserting that user 3 no longer has access to test.txt after expiration.' ); -- cgit v1.2.3