From 31148e25cf6d800851064813689f8fba6340fb5c Mon Sep 17 00:00:00 2001 From: Philipp Holzer Date: Sat, 6 Oct 2018 16:27:20 +0200 Subject: [PATCH] Changing Friendica\App\Mode from static methods to public methods - Changing from static methods to public methods - Adding dev-composer-dependency Mockery for static method mocking (f.e. Config, DBA) - Adding ModeTest with Mocking - removing bootstrap from phpunit.xml because of double loading tests\bootstrap.php --- bin/auth_ejabberd.php | 4 +- bin/daemon.php | 2 +- composer.json | 3 +- composer.lock | 203 +++++++++++++++++++- index.php | 14 +- phpunit.xml | 1 - src/App.php | 30 ++- src/App/Mode.php | 58 ++++-- src/Core/Config.php | 10 +- src/Core/Console/ArchiveContact.php | 4 +- src/Core/Console/Cache.php | 2 +- src/Core/Console/Config.php | 4 +- src/Core/Console/GlobalCommunityBlock.php | 2 +- src/Core/Console/GlobalCommunitySilence.php | 2 +- src/Core/Console/Maintenance.php | 4 +- src/Core/Console/NewPassword.php | 2 +- src/Core/Console/PostUpdate.php | 4 +- src/Core/PConfig.php | 14 +- tests/Util/VFSTrait.php | 52 +++++ tests/src/App/ModeTest.php | 139 ++++++++++++++ tests/src/Core/Console/ConsoleTest.php | 50 +---- 21 files changed, 498 insertions(+), 106 deletions(-) create mode 100644 tests/Util/VFSTrait.php create mode 100644 tests/src/App/ModeTest.php diff --git a/bin/auth_ejabberd.php b/bin/auth_ejabberd.php index 55917bf6d9..1f03b94af9 100755 --- a/bin/auth_ejabberd.php +++ b/bin/auth_ejabberd.php @@ -54,7 +54,7 @@ require_once "include/dba.php"; $a = new App(dirname(__DIR__)); -if (App\Mode::isNormal()) { +if ($a->getMode()->isNormal()) { $oAuth = new ExAuth(); $oAuth->readStdin(); -} \ No newline at end of file +} diff --git a/bin/daemon.php b/bin/daemon.php index e2bad90df5..f0f5826d92 100755 --- a/bin/daemon.php +++ b/bin/daemon.php @@ -34,7 +34,7 @@ require_once "include/dba.php"; $a = new App(dirname(__DIR__)); -if (App\Mode::isInstall()) { +if ($a->getMode()->isInstall()) { die("Friendica isn't properly installed yet.\n"); } diff --git a/composer.json b/composer.json index a37010a9ef..5df9a5355b 100644 --- a/composer.json +++ b/composer.json @@ -75,7 +75,8 @@ "phpunit/dbunit": "^2.0", "phpdocumentor/reflection-docblock": "^3.0.2", "phpunit/php-token-stream": "^1.4.2", - "mikey179/vfsStream": "^1.6" + "mikey179/vfsStream": "^1.6", + "mockery/mockery": "^1.2" }, "scripts": { "test": "phpunit" diff --git a/composer.lock b/composer.lock index a07d56e692..7973167762 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c2306df3b19ec46d53bb16ac2cffa51a", + "content-hash": "9f0dbeccbae197460a0ce74a940177cd", "packages": [ { "name": "asika/simple-console", @@ -818,6 +818,28 @@ "reference": null, "shasum": "30dc7a7ce872155b23a33bd10ad4c76c0d613f55" }, + "require-dev": { + "npm-asset/babel-core": ">=6.26.0,<7.0.0", + "npm-asset/babel-plugin-external-helpers": ">=6.22.0,<7.0.0", + "npm-asset/babel-preset-env": ">=1.6.1,<2.0.0", + "npm-asset/cpy-cli": ">=1.0.1,<2.0.0", + "npm-asset/cssnano": ">=3.10.0,<4.0.0", + "npm-asset/del-cli": ">=1.1.0,<2.0.0", + "npm-asset/eslint": ">=4.14.0,<5.0.0", + "npm-asset/eslint-config-airbnb-base": ">=12.1.0,<13.0.0", + "npm-asset/eslint-plugin-import": ">=2.8.0,<3.0.0", + "npm-asset/node-qunit-phantomjs": ">=2.0.0,<3.0.0", + "npm-asset/npm-run-all": ">=4.1.2,<5.0.0", + "npm-asset/postcss-cli": ">=4.1.1,<5.0.0", + "npm-asset/postcss-cssnext": ">=3.0.2,<4.0.0", + "npm-asset/postcss-header": ">=1.0.0,<2.0.0", + "npm-asset/postcss-url": ">=7.3.0,<8.0.0", + "npm-asset/rollup": ">=0.53.3,<0.54.0", + "npm-asset/rollup-plugin-babel": ">=3.0.3,<4.0.0", + "npm-asset/rollup-watch": ">=4.3.1,<5.0.0", + "npm-asset/stylefmt": ">=6.0.0,<7.0.0", + "npm-asset/uglify-js": ">=3.3.4,<4.0.0" + }, "type": "npm-asset-library", "extra": { "npm-asset-bugs": { @@ -997,6 +1019,22 @@ "require": { "npm-asset/ev-emitter": ">=1.0.0,<2.0.0" }, + "require-dev": { + "npm-asset/chalk": ">=1.1.1,<2.0.0", + "npm-asset/cheerio": ">=0.19.0,<0.20.0", + "npm-asset/gulp": ">=3.9.0,<4.0.0", + "npm-asset/gulp-jshint": ">=1.11.2,<2.0.0", + "npm-asset/gulp-json-lint": ">=0.1.0,<0.2.0", + "npm-asset/gulp-rename": ">=1.2.2,<2.0.0", + "npm-asset/gulp-replace": ">=0.5.4,<0.6.0", + "npm-asset/gulp-requirejs-optimize": "dev-github:metafizzy/gulp-requirejs-optimize", + "npm-asset/gulp-uglify": ">=1.4.2,<2.0.0", + "npm-asset/gulp-util": ">=3.0.7,<4.0.0", + "npm-asset/highlight.js": ">=8.9.1,<9.0.0", + "npm-asset/marked": ">=0.3.5,<0.4.0", + "npm-asset/minimist": ">=1.2.0,<2.0.0", + "npm-asset/transfob": ">=1.0.0,<2.0.0" + }, "type": "npm-asset-library", "extra": { "npm-asset-bugs": { @@ -1042,6 +1080,14 @@ "reference": null, "shasum": "2736e332aaee73ccf0a14a5f0066391a0a13f4a3" }, + "require-dev": { + "npm-asset/grunt": "~0.4.2", + "npm-asset/grunt-contrib-cssmin": "~0.9.0", + "npm-asset/grunt-contrib-jshint": "~0.6.3", + "npm-asset/grunt-contrib-less": "~0.11.0", + "npm-asset/grunt-contrib-uglify": "~0.4.0", + "npm-asset/grunt-contrib-watch": "~0.6.1" + }, "type": "npm-asset-library", "extra": { "npm-asset-bugs": { @@ -1075,6 +1121,32 @@ "reference": null, "shasum": "2c89d6889b5eac522a7eea32c14521559c6cbf02" }, + "require-dev": { + "npm-asset/commitplease": "2.0.0", + "npm-asset/core-js": "0.9.17", + "npm-asset/grunt": "0.4.5", + "npm-asset/grunt-babel": "5.0.1", + "npm-asset/grunt-cli": "0.1.13", + "npm-asset/grunt-compare-size": "0.4.0", + "npm-asset/grunt-contrib-jshint": "0.11.2", + "npm-asset/grunt-contrib-uglify": "0.9.2", + "npm-asset/grunt-contrib-watch": "0.6.1", + "npm-asset/grunt-git-authors": "2.0.1", + "npm-asset/grunt-jscs": "2.1.0", + "npm-asset/grunt-jsonlint": "1.0.4", + "npm-asset/grunt-npmcopy": "0.1.0", + "npm-asset/gzip-js": "0.3.2", + "npm-asset/jsdom": "5.6.1", + "npm-asset/load-grunt-tasks": "1.0.0", + "npm-asset/qunit-assert-step": "1.0.3", + "npm-asset/qunitjs": "1.17.1", + "npm-asset/requirejs": "2.1.17", + "npm-asset/sinon": "1.10.3", + "npm-asset/sizzle": "2.2.1", + "npm-asset/strip-json-comments": "1.0.3", + "npm-asset/testswarm": "1.1.0", + "npm-asset/win-spawn": "2.0.0" + }, "type": "npm-asset-library", "extra": { "npm-asset-bugs": { @@ -1225,6 +1297,12 @@ "reference": null, "shasum": "06f0335f16e353a695e7206bf50503cb523a6ee5" }, + "require-dev": { + "npm-asset/grunt": "~0.4.1", + "npm-asset/grunt-contrib-connect": "~0.5.0", + "npm-asset/grunt-contrib-jshint": "~0.7.1", + "npm-asset/grunt-contrib-uglify": "~0.2.7" + }, "type": "npm-asset-library", "extra": { "npm-asset-bugs": { @@ -1933,6 +2011,54 @@ ], "time": "2015-06-14T21:17:01+00:00" }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/776503d3a8e85d4f9a1148614f95b7a608b046ad", + "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "1.3.3", + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "time": "2016-01-20T08:20:44+00:00" + }, { "name": "mikey179/vfsStream", "version": "v1.6.5", @@ -1979,6 +2105,71 @@ "homepage": "http://vfs.bovigo.org/", "time": "2017-08-01T08:02:14+00:00" }, + { + "name": "mockery/mockery", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "100633629bf76d57430b86b7098cd6beb996a35a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/100633629bf76d57430b86b7098cd6beb996a35a", + "reference": "100633629bf76d57430b86b7098cd6beb996a35a", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "~2.0", + "lib-pcre": ">=7.0", + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "~5.7.10|~6.5|~7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "time": "2018-10-02T21:52:37+00:00" + }, { "name": "myclabs/deep-copy", "version": "1.7.0", @@ -2779,7 +2970,7 @@ } ], "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", + "homepage": "https://github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", @@ -2881,7 +3072,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -2949,7 +3140,7 @@ } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "homepage": "https://github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" @@ -3001,7 +3192,7 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], @@ -3103,7 +3294,7 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "time": "2016-11-19T07:33:16+00:00" }, { diff --git a/index.php b/index.php index f34b79867c..19b85b9356 100644 --- a/index.php +++ b/index.php @@ -36,7 +36,7 @@ $a->backend = false; require_once "include/dba.php"; // Missing DB connection: ERROR -if (App\Mode::has(App\Mode::LOCALCONFIGPRESENT) && !App\Mode::has(App\Mode::DBAVAILABLE)) { +if ($a->getMode()->has(App\Mode::LOCALCONFIGPRESENT) && !$a->getMode()->has(App\Mode::DBAVAILABLE)) { System::httpExit(500, ['title' => 'Error 500 - Internal Server Error', 'description' => 'Apologies but the website is unavailable at the moment.']); } @@ -48,7 +48,7 @@ if ($a->isMaxProcessesReached() || $a->isMaxLoadReached()) { System::httpExit(503, ['title' => 'Error 503 - Service Temporarily Unavailable', 'description' => 'System is currently overloaded. Please try again later.']); } -if (!App\Mode::isInstall()) { +if (!$a->getMode()->isInstall()) { if (Config::get('system', 'force_ssl') && ($a->get_scheme() == "http") && (intval(Config::get('system', 'ssl_policy')) == SSL_POLICY_FULL) && (substr(System::baseUrl(), 0, 8) == "https://") @@ -107,7 +107,7 @@ if (!empty($_SESSION['language']) && $_SESSION['language'] !== $lang) { L10n::loadTranslationTable($lang); } -if (!empty($_GET['zrl']) && App\Mode::isNormal()) { +if (!empty($_GET['zrl']) && $a->getMode()->isNormal()) { $a->query_string = Profile::stripZrls($a->query_string); if (!local_user()) { // Only continue when the given profile link seems valid @@ -130,7 +130,7 @@ if (!empty($_GET['zrl']) && App\Mode::isNormal()) { } } -if (!empty($_GET['owt']) && App\Mode::isNormal()) { +if (!empty($_GET['owt']) && $a->getMode()->isNormal()) { $token = $_GET['owt']; $a->query_string = Profile::stripQueryParam($a->query_string, 'owt'); Profile::openWebAuthInit($token); @@ -165,9 +165,9 @@ $_SESSION['last_updated'] = defaults($_SESSION, 'last_updated', []); // in install mode, any url loads install module // but we need "view" module for stylesheet -if (App\Mode::isInstall() && $a->module != 'view') { +if ($a->getMode()->isInstall() && $a->module != 'view') { $a->module = 'install'; -} elseif (!App\Mode::has(App\Mode::MAINTENANCEDISABLED) && $a->module != 'view') { +} elseif (!$a->getMode()->has(App\Mode::MAINTENANCEDISABLED) && $a->module != 'view') { $a->module = 'maintenance'; } else { check_url($a); @@ -320,7 +320,7 @@ if (file_exists($theme_info_file)) { /* initialise content region */ -if (App\Mode::isNormal()) { +if ($a->getMode()->isNormal()) { Addon::callHooks('page_content_top', $a->page['content']); } diff --git a/phpunit.xml b/phpunit.xml index 9ed293b631..0494b4dcb4 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,6 +1,5 @@ diff --git a/src/App.php b/src/App.php index 9a09bcfce0..61d7335f1a 100644 --- a/src/App.php +++ b/src/App.php @@ -11,6 +11,7 @@ use Friendica\Core\L10n; use Friendica\Core\PConfig; use Friendica\Core\System; use Friendica\Database\DBA; +use Friendica\Network\HTTPException\InternalServerErrorException; require_once 'boot.php'; require_once 'include/dba.php'; @@ -83,6 +84,11 @@ class App public $stylesheets = []; public $footerScripts = []; + /** + * @var App\Mode The Mode of the Application + */ + private $mode; + /** * Register a stylesheet file path to be included in the tag of every page. * Inclusion is done in App->initHead(). @@ -193,6 +199,8 @@ class App $this->callstack['rendering'] = []; $this->callstack['parser'] = []; + $this->mode = new App\Mode($basepath); + $this->reload(); set_time_limit(0); @@ -300,6 +308,22 @@ class App $this->register_template_engine('Friendica\Render\FriendicaSmartyEngine'); } + /** + * Returns the Mode of the Application + * + * @return App\Mode The Application Mode + * + * @throws InternalServerErrorException when the mode isn't created + */ + public function getMode() + { + if (empty($this->mode)) { + throw new InternalServerErrorException('Mode of the Application is not defined'); + } + + return $this->mode; + } + /** * Reloads the whole app instance */ @@ -310,13 +334,13 @@ class App $this->loadDatabase(); - App\Mode::determine($this->basepath); + $this->getMode()->determine($this->basepath); $this->determineUrlPath(); Config::load(); - if (App\Mode::has(App\Mode::DBAVAILABLE)) { + if ($this->getMode()->has(App\Mode::DBAVAILABLE)) { Core\Addon::loadHooks(); $this->loadAddonConfig(); @@ -1402,7 +1426,7 @@ class App */ public function getCurrentTheme() { - if (App\Mode::isInstall()) { + if ($this->getMode()->isInstall()) { return ''; } diff --git a/src/App/Mode.php b/src/App/Mode.php index 189573e378..10f1092a89 100644 --- a/src/App/Mode.php +++ b/src/App/Mode.php @@ -20,9 +20,19 @@ class Mode /*** * @var int the mode of this Application * - * Default is 0 (= not set) */ - private static $mode = 0; + private $mode; + + /** + * @var string the basepath of the application + */ + private $basepath; + + public function __construct($basepath = '') + { + $this->basepath = $basepath; + $this->mode = 0; + } /** * Sets the App mode @@ -34,34 +44,38 @@ class Mode * @param string $basepath the Basepath of the Application * */ - public static function determine($basepath) + public function determine($basepath = null) { - self::$mode = 0; + if (!empty($basepath)) { + $this->basepath = $basepath; + } - if (!file_exists($basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php') - && !file_exists($basepath . DIRECTORY_SEPARATOR . '.htconfig.php')) { + $this->mode = 0; + + if (!file_exists($this->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php') + && !file_exists($this->basepath . DIRECTORY_SEPARATOR . '.htconfig.php')) { return; } - self::$mode |= Mode::LOCALCONFIGPRESENT; + $this->mode |= Mode::LOCALCONFIGPRESENT; if (!DBA::connected()) { return; } - self::$mode |= Mode::DBAVAILABLE; + $this->mode |= Mode::DBAVAILABLE; if (DBA::fetchFirst("SHOW TABLES LIKE 'config'") === false) { return; } - self::$mode |= Mode::DBCONFIGAVAILABLE; + $this->mode |= Mode::DBCONFIGAVAILABLE; if (Config::get('system', 'maintenance')) { return; } - self::$mode |= Mode::MAINTENANCEDISABLED; + $this->mode |= Mode::MAINTENANCEDISABLED; } /** @@ -71,9 +85,13 @@ class Mode * * @return bool returns true, if the mode is set */ - public static function has($mode) + public function has($mode) { - return self::$mode & $mode; + echo "mode: " . $this->mode . " with " . $mode; + + echo "value: " . ($this->mode & $mode); + + return ($this->mode & $mode) > 0; } @@ -82,10 +100,10 @@ class Mode * * @return bool */ - public static function isInstall() + public function isInstall() { - return !self::has(Mode::LOCALCONFIGPRESENT) || - !self::has(MODE::DBCONFIGAVAILABLE); + return !$this->has(Mode::LOCALCONFIGPRESENT) || + !$this->has(MODE::DBCONFIGAVAILABLE); } /** @@ -93,11 +111,11 @@ class Mode * * @return bool */ - public static function isNormal() + public function isNormal() { - return self::has(Mode::LOCALCONFIGPRESENT) && - self::has(Mode::DBAVAILABLE) && - self::has(Mode::DBCONFIGAVAILABLE) && - self::has(Mode::MAINTENANCEDISABLED); + return $this->has(Mode::LOCALCONFIGPRESENT) && + $this->has(Mode::DBAVAILABLE) && + $this->has(Mode::DBCONFIGAVAILABLE) && + $this->has(Mode::MAINTENANCEDISABLED); } } diff --git a/src/Core/Config.php b/src/Core/Config.php index f2b0d12ab0..a07bbd31c9 100644 --- a/src/Core/Config.php +++ b/src/Core/Config.php @@ -31,7 +31,7 @@ class Config extends BaseObject public static function init() { // Database isn't ready or populated yet - if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { return; } @@ -55,7 +55,7 @@ class Config extends BaseObject public static function load($family = "config") { // Database isn't ready or populated yet - if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { return; } @@ -88,7 +88,7 @@ class Config extends BaseObject public static function get($family, $key, $default_value = null, $refresh = false) { // Database isn't ready or populated yet, fallback to file config - if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { return self::getApp()->getConfigValue($family, $key, $default_value); } @@ -116,7 +116,7 @@ class Config extends BaseObject public static function set($family, $key, $value) { // Database isn't ready or populated yet - if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { return false; } @@ -141,7 +141,7 @@ class Config extends BaseObject public static function delete($family, $key) { // Database isn't ready or populated yet - if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { return false; } diff --git a/src/Core/Console/ArchiveContact.php b/src/Core/Console/ArchiveContact.php index 8a6bc1f7bf..481037a5f6 100644 --- a/src/Core/Console/ArchiveContact.php +++ b/src/Core/Console/ArchiveContact.php @@ -39,7 +39,7 @@ HELP; protected function doExecute() { - $a = get_app(); + $a = \Friendica\BaseObject::getApp(); if ($this->getOption('v')) { $this->out('Class: ' . __CLASS__); @@ -56,7 +56,7 @@ HELP; throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments'); } - if (App\Mode::isInstall()) { + if ($a->getMode()->isInstall()) { throw new RuntimeException('Friendica isn\'t properly installed yet.'); } diff --git a/src/Core/Console/Cache.php b/src/Core/Console/Cache.php index 2d3508894a..af0d771307 100644 --- a/src/Core/Console/Cache.php +++ b/src/Core/Console/Cache.php @@ -65,7 +65,7 @@ HELP; $this->out('Options: ' . var_export($this->options, true)); } - if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if ($a->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { $this->out('Database isn\'t ready or populated yet, database cache won\'t be available'); } diff --git a/src/Core/Console/Config.php b/src/Core/Console/Config.php index d67f6cbb96..3b92d5a784 100644 --- a/src/Core/Console/Config.php +++ b/src/Core/Console/Config.php @@ -84,7 +84,7 @@ HELP; throw new CommandArgsException('Too many arguments'); } - if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if (!$a->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { $this->out('Database isn\'t ready or populated yet, showing file config only'); } @@ -143,7 +143,7 @@ HELP; if (count($this->args) == 0) { Core\Config::load(); - if (Core\Config::get('system', 'config_adapter') == 'jit' && App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if (Core\Config::get('system', 'config_adapter') == 'jit' && $a->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { $this->out('Warning: The JIT (Just In Time) Config adapter doesn\'t support loading the entire configuration, showing file config only'); } diff --git a/src/Core/Console/GlobalCommunityBlock.php b/src/Core/Console/GlobalCommunityBlock.php index dbab4ff02c..2a19a9e7f3 100644 --- a/src/Core/Console/GlobalCommunityBlock.php +++ b/src/Core/Console/GlobalCommunityBlock.php @@ -56,7 +56,7 @@ HELP; throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments'); } - if (App\Mode::isInstall()) { + if ($a->getMode()->isInstall()) { throw new \RuntimeException('Database isn\'t ready or populated yet'); } diff --git a/src/Core/Console/GlobalCommunitySilence.php b/src/Core/Console/GlobalCommunitySilence.php index 0dce00a7b1..3ea6b41554 100644 --- a/src/Core/Console/GlobalCommunitySilence.php +++ b/src/Core/Console/GlobalCommunitySilence.php @@ -65,7 +65,7 @@ HELP; throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments'); } - if (App\Mode::isInstall()) { + if ($a->getMode()->isInstall()) { throw new RuntimeException('Database isn\'t ready or populated yet'); } diff --git a/src/Core/Console/Maintenance.php b/src/Core/Console/Maintenance.php index d693cb6e89..212edabcc1 100644 --- a/src/Core/Console/Maintenance.php +++ b/src/Core/Console/Maintenance.php @@ -47,7 +47,7 @@ HELP; protected function doExecute() { - $a = get_app(); + $a = \Friendica\BaseObject::getApp(); if ($this->getOption('v')) { $this->out('Class: ' . __CLASS__); @@ -64,7 +64,7 @@ HELP; throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments'); } - if (App\Mode::isInstall()) { + if ($a->getMode()->isInstall()) { throw new \RuntimeException('Database isn\'t ready or populated yet'); } diff --git a/src/Core/Console/NewPassword.php b/src/Core/Console/NewPassword.php index 56f3ae7c98..54d10af207 100644 --- a/src/Core/Console/NewPassword.php +++ b/src/Core/Console/NewPassword.php @@ -57,7 +57,7 @@ HELP; throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments'); } - if (App\Mode::isInstall()) { + if ($a->getMode()->isInstall()) { throw new RuntimeException('Database isn\'t ready or populated yet'); } diff --git a/src/Core/Console/PostUpdate.php b/src/Core/Console/PostUpdate.php index a77aae39de..1215591a20 100644 --- a/src/Core/Console/PostUpdate.php +++ b/src/Core/Console/PostUpdate.php @@ -33,7 +33,7 @@ HELP; protected function doExecute() { - $a = get_app(); + $a = \Friendica\BaseObject::getApp(); if ($this->getOption($this->helpOptions)) { $this->out($this->getHelp()); @@ -50,7 +50,7 @@ HELP; return 0; } - if (App\Mode::isInstall()) { + if ($a->getMode()->isInstall()) { throw new \RuntimeException('Database isn\'t ready or populated yet'); } diff --git a/src/Core/PConfig.php b/src/Core/PConfig.php index 3c48a568cb..2080f716ce 100644 --- a/src/Core/PConfig.php +++ b/src/Core/PConfig.php @@ -29,12 +29,14 @@ class PConfig extends BaseObject public static function init($uid) { + $a = self::getApp(); + // Database isn't ready or populated yet - if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if (!$a->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { return; } - if (self::getApp()->getConfigValue('system', 'config_adapter') == 'preload') { + if ($a->getConfigValue('system', 'config_adapter') == 'preload') { self::$adapter = new Config\PreloadPConfigAdapter($uid); } else { self::$adapter = new Config\JITPConfigAdapter($uid); @@ -55,7 +57,7 @@ class PConfig extends BaseObject public static function load($uid, $family) { // Database isn't ready or populated yet - if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { return; } @@ -84,7 +86,7 @@ class PConfig extends BaseObject public static function get($uid, $family, $key, $default_value = null, $refresh = false) { // Database isn't ready or populated yet - if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { return; } @@ -113,7 +115,7 @@ class PConfig extends BaseObject public static function set($uid, $family, $key, $value) { // Database isn't ready or populated yet - if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { return false; } @@ -139,7 +141,7 @@ class PConfig extends BaseObject public static function delete($uid, $family, $key) { // Database isn't ready or populated yet - if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) { + if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) { return false; } diff --git a/tests/Util/VFSTrait.php b/tests/Util/VFSTrait.php new file mode 100644 index 0000000000..b0e7a3a604 --- /dev/null +++ b/tests/Util/VFSTrait.php @@ -0,0 +1,52 @@ + [], + 'bin' => [] + ]; + + // create a virtual directory and copy all needed files and folders to it + $this->root = vfsStream::setup('friendica', null, $structure); + + $this->setConfigFile('config.ini.php'); + $this->setConfigFile('settings.ini.php'); + $this->setConfigFile('local.ini.php'); + $this->setConfigFile('dbstructure.json'); + } + + protected function setConfigFile($filename) + { + $file = dirname(__DIR__) . DIRECTORY_SEPARATOR . + '..' . DIRECTORY_SEPARATOR . + 'config' . DIRECTORY_SEPARATOR . + $filename; + + if (file_exists($file)) { + vfsStream::newFile($filename) + ->at($this->root->getChild('config')) + ->setContent(file_get_contents($file)); + } + } + + protected function delConfigFile($filename) + { + if ($this->root->hasChild('config/' . $filename)) { + $this->root->removeChild('config/' . $filename); + } + } +} diff --git a/tests/src/App/ModeTest.php b/tests/src/App/ModeTest.php new file mode 100644 index 0000000000..bac553eb8c --- /dev/null +++ b/tests/src/App/ModeTest.php @@ -0,0 +1,139 @@ +setUpVfsDir(); + } + + public function testItEmpty() + { + $mode = new Mode($this->root->url()); + $this->assertTrue($mode->isInstall()); + $this->assertFalse($mode->isNormal()); + } + + public function testWithoutConfig() + { + $mode = new Mode($this->root->url()); + + $this->assertTrue($this->root->hasChild('config/local.ini.php')); + + $this->delConfigFile('local.ini.php'); + + $this->assertFalse($this->root->hasChild('config/local.ini.php')); + + $mode->determine(); + + $this->assertTrue($mode->isInstall()); + $this->assertFalse($mode->isNormal()); + + $this->assertFalse($mode->has(Mode::LOCALCONFIGPRESENT)); + } + + public function testWithoutDatabase() + { + $dba = \Mockery::mock('alias:Friendica\Database\DBA'); + $dba + ->shouldReceive('connected') + ->andReturn(false); + + $mode = new Mode($this->root->url()); + $mode->determine(); + + $this->assertFalse($mode->isNormal()); + $this->assertTrue($mode->isInstall()); + + $this->assertTrue($mode->has(Mode::LOCALCONFIGPRESENT)); + $this->assertFalse($mode->has(Mode::DBAVAILABLE)); + } + + public function testWithoutDatabaseSetup() + { + $dba = \Mockery::mock('alias:Friendica\Database\DBA'); + $dba + ->shouldReceive('connected') + ->andReturn(true); + $dba + ->shouldReceive('fetchFirst') + ->with('SHOW TABLES LIKE \'config\'') + ->andReturn(false); + + $mode = new Mode($this->root->url()); + $mode->determine(); + + $this->assertFalse($mode->isNormal()); + $this->assertTrue($mode->isInstall()); + + $this->assertTrue($mode->has(Mode::LOCALCONFIGPRESENT)); + } + + public function testWithMaintenanceMode() + { + $dba = \Mockery::mock('alias:Friendica\Database\DBA'); + $dba + ->shouldReceive('connected') + ->andReturn(true); + $dba + ->shouldReceive('fetchFirst') + ->with('SHOW TABLES LIKE \'config\'') + ->andReturn(true); + + $conf = \Mockery::mock('alias:Friendica\Core\Config'); + $conf + ->shouldReceive('get') + ->with('system', 'maintenance') + ->andReturn(true); + + $mode = new Mode($this->root->url()); + $mode->determine(); + + $this->assertFalse($mode->isNormal()); + $this->assertFalse($mode->isInstall()); + + $this->assertTrue($mode->has(Mode::DBCONFIGAVAILABLE)); + $this->assertFalse($mode->has(Mode::MAINTENANCEDISABLED)); + } + + public function testNormalMode() + { + $dba = \Mockery::mock('alias:Friendica\Database\DBA'); + $dba + ->shouldReceive('connected') + ->andReturn(true); + $dba + ->shouldReceive('fetchFirst') + ->with('SHOW TABLES LIKE \'config\'') + ->andReturn(true); + + $conf = \Mockery::mock('alias:Friendica\Core\Config'); + $conf + ->shouldReceive('get') + ->with('system', 'maintenance') + ->andReturn(false); + + $mode = new Mode($this->root->url()); + $mode->determine(); + + $this->assertTrue($mode->isNormal()); + $this->assertFalse($mode->isInstall()); + + $this->assertTrue($mode->has(Mode::DBCONFIGAVAILABLE)); + $this->assertTrue($mode->has(Mode::MAINTENANCEDISABLED)); + } +} diff --git a/tests/src/Core/Console/ConsoleTest.php b/tests/src/Core/Console/ConsoleTest.php index 0cc5c63359..40f864e3b9 100644 --- a/tests/src/Core/Console/ConsoleTest.php +++ b/tests/src/Core/Console/ConsoleTest.php @@ -6,12 +6,15 @@ use Friendica\App; use Friendica\BaseObject; use Friendica\Database\DBA; use Friendica\Test\Util\Intercept; +use Friendica\Test\Util\VFSTrait; use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStreamDirectory; use PHPUnit\Framework\TestCase; abstract class ConsoleTest extends TestCase { + use VFSTrait; + /** * @var MultiUseConsole Extension of the basic Friendica Console for testing purpose */ @@ -21,11 +24,6 @@ abstract class ConsoleTest extends TestCase */ protected $app; - /** - * @var vfsStreamDirectory The Stream Directory - */ - protected $root; - protected $stdout; protected function setUp() @@ -40,6 +38,11 @@ abstract class ConsoleTest extends TestCase $this->setUpVfsDir(); + // fake console.php for setting an executable + vfsStream::newFile('console.php') + ->at($this->root->getChild('bin')) + ->setContent('app = new App($this->root->url()); BaseObject::setApp($this->app); @@ -67,41 +70,4 @@ abstract class ConsoleTest extends TestCase protected function getExecutablePath() { return $this->root->getChild('bin' . DIRECTORY_SEPARATOR . 'console.php')->url(); } - - private function setUpVfsDir() { - // the used directories inside the App class - $structure = [ - 'config' => [], - 'bin' => [] - ]; - - // create a virtual directory and copy all needed files and folders to it - $this->root = vfsStream::setup('friendica', null, $structure); - - $this->setConfigFile('config.ini.php'); - $this->setConfigFile('settings.ini.php'); - $this->setConfigFile('local.ini.php'); - $this->setConfigFile('dbstructure.json'); - - // fake console.php for setting an executable - vfsStream::newFile('console.php') - ->at($this->root->getChild('bin')) - ->setContent('at($this->root->getChild('config')) - ->setContent(file_get_contents($file)); - } - } }