From 49cf33fe177fb3ebe455205a7dfe7517cfcaa994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 30 Oct 2018 12:57:45 +0100 Subject: [PATCH] No max version check for apps when using release channel git or daily --- lib/base.php | 3 +- lib/private/App/AppManager.php | 33 +--- lib/private/App/DependencyAnalyzer.php | 10 +- lib/private/App/Platform.php | 23 +-- lib/private/Installer.php | 3 +- lib/private/Repair/Apps.php | 4 +- lib/private/Server.php | 4 +- lib/private/legacy/app.php | 92 +++++----- .../Controller/AppSettingsControllerTest.php | 1 + tests/lib/App/DependencyAnalyzerTest.php | 48 ++--- tests/lib/App/ManagerTest.php | 167 ++++++++---------- tests/lib/AppTest.php | 23 +-- 12 files changed, 188 insertions(+), 223 deletions(-) diff --git a/lib/base.php b/lib/base.php index 60c2746128a0..d98d60fee109 100644 --- a/lib/base.php +++ b/lib/base.php @@ -400,8 +400,7 @@ private static function printUpgradePage() { $tmpl->assign('isAppsOnlyUpgrade', $isAppsOnlyUpgrade); // get third party apps - $ocVersion = \OCP\Util::getVersion(); - $tmpl->assign('appsToUpgrade', $appManager->getAppsNeedingUpgrade($ocVersion)); + $tmpl->assign('appsToUpgrade', $appManager->getAppsNeedingUpgrade()); $tmpl->assign('productName', 'ownCloud'); // for now $tmpl->assign('oldTheme', $oldTheme); $tmpl->printPage(); diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php index 1c0a2ff545f9..98fff366c11c 100644 --- a/lib/private/App/AppManager.php +++ b/lib/private/App/AppManager.php @@ -86,6 +86,8 @@ class AppManager implements IAppManager { * @var string[][] */ private $appDirs = []; + /** @var Platform */ + private $platform; /** * @param IUserSession $userSession @@ -94,19 +96,22 @@ class AppManager implements IAppManager { * @param ICacheFactory $memCacheFactory * @param EventDispatcherInterface $dispatcher * @param IConfig $config + * @param Platform $platform */ public function __construct(IUserSession $userSession = null, IAppConfig $appConfig = null, IGroupManager $groupManager = null, ICacheFactory $memCacheFactory, EventDispatcherInterface $dispatcher, - IConfig $config) { + IConfig $config, + Platform $platform) { $this->userSession = $userSession; $this->appConfig = $appConfig; $this->groupManager = $groupManager; $this->memCacheFactory = $memCacheFactory; $this->dispatcher = $dispatcher; $this->config = $config; + $this->platform = $platform; } /** @@ -339,12 +344,11 @@ public function clearAppsCache() { /** * Returns a list of apps that need upgrade * - * @param array $ocVersion ownCloud version as array of version components * @return array list of app info from apps that need an upgrade * * @internal */ - public function getAppsNeedingUpgrade($ocVersion) { + public function getAppsNeedingUpgrade() { $appsToUpgrade = []; $apps = $this->getInstalledApps(); foreach ($apps as $appId) { @@ -353,7 +357,7 @@ public function getAppsNeedingUpgrade($ocVersion) { if ($appDbVersion && isset($appInfo['version']) && \version_compare($appInfo['version'], $appDbVersion, '>') - && \OC_App::isAppCompatible($ocVersion, $appInfo) + && \OC_App::isAppCompatible($this->platform, $appInfo) ) { $appsToUpgrade[] = $appInfo; } @@ -383,27 +387,6 @@ public function getAppInfo($appId) { return $appInfo; } - /** - * Returns a list of apps incompatible with the given version - * - * @param array $version ownCloud version as array of version components - * - * @return array list of app info from incompatible apps - * - * @internal - */ - public function getIncompatibleApps($version) { - $apps = $this->getInstalledApps(); - $incompatibleApps = []; - foreach ($apps as $appId) { - $info = $this->getAppInfo($appId); - if (!\OC_App::isAppCompatible($version, $info)) { - $incompatibleApps[] = $info; - } - } - return $incompatibleApps; - } - /** * @inheritdoc */ diff --git a/lib/private/App/DependencyAnalyzer.php b/lib/private/App/DependencyAnalyzer.php index 75937056c3e9..f25599d060fa 100644 --- a/lib/private/App/DependencyAnalyzer.php +++ b/lib/private/App/DependencyAnalyzer.php @@ -176,8 +176,8 @@ private function analyzeDatabases(array $dependencies) { return $this->getValue($db); }, $supportedDatabases); $currentDatabase = $this->platform->getDatabase(); - if (!\in_array($currentDatabase, $supportedDatabases)) { - $missing[] = (string)$this->l->t('Following databases are supported: %s', \join(', ', $supportedDatabases)); + if (!\in_array($currentDatabase, $supportedDatabases, true)) { + $missing[] = (string)$this->l->t('Following databases are supported: %s', \implode(', ', $supportedDatabases)); } return $missing; } @@ -279,8 +279,8 @@ private function analyzeOS(array $dependencies) { $oss = [$oss]; } $currentOS = $this->platform->getOS(); - if (!\in_array($currentOS, $oss)) { - $missing[] = (string)$this->l->t('Following platforms are supported: %s', \join(', ', $oss)); + if (!\in_array($currentOS, $oss, true)) { + $missing[] = (string)$this->l->t('Following platforms are supported: %s', \implode(', ', $oss)); } return $missing; } @@ -312,7 +312,7 @@ private function analyzeOC(array $dependencies, array $appInfo) { $missing[] = (string)$this->l->t('ownCloud %s or higher is required.', $minVersion); } } - if ($maxVersion !== null) { + if ($maxVersion !== null && !\in_array($this->platform->getOcChannel(), ['git', 'daily'], true)) { if ($this->compareBigger($this->platform->getOcVersion(), $maxVersion)) { $missing[] = (string)$this->l->t('ownCloud %s or lower is required.', $maxVersion); } diff --git a/lib/private/App/Platform.php b/lib/private/App/Platform.php index 1ef9268ab443..98f735c4966b 100644 --- a/lib/private/App/Platform.php +++ b/lib/private/App/Platform.php @@ -46,29 +46,29 @@ public function __construct(IConfig $config) { /** * @return string */ - public function getPhpVersion() { + public function getPhpVersion(): string { return \phpversion(); } /** * @return int */ - public function getIntSize() { + public function getIntSize(): int { return PHP_INT_SIZE; } /** * @return string */ - public function getOcVersion() { + public function getOcVersion(): string { $v = \OCP\Util::getVersion(); - return \join('.', $v); + return \implode('.', $v); } /** * @return string */ - public function getDatabase() { + public function getDatabase(): string { $dbType = $this->config->getSystemValue('dbtype', 'sqlite'); if ($dbType === 'sqlite3') { $dbType = 'sqlite'; @@ -80,7 +80,7 @@ public function getDatabase() { /** * @return string */ - public function getOS() { + public function getOS(): string { return \php_uname('s'); } @@ -88,14 +88,17 @@ public function getOS() { * @param $command * @return bool */ - public function isCommandKnown($command) { + public function isCommandKnown($command): bool { $path = \OC_Helper::findBinaryPath($command); return ($path !== null); } - public function getLibraryVersion($name) { + public function getLibraryVersion($name): ?string { $repo = new PlatformRepository(); - $lib = $repo->findLibrary($name); - return $lib; + return $repo->findLibrary($name); + } + + public function getOcChannel(): string { + return \OCP\Util::getChannel(); } } diff --git a/lib/private/Installer.php b/lib/private/Installer.php index 883bd38e5814..27372855eab0 100644 --- a/lib/private/Installer.php +++ b/lib/private/Installer.php @@ -39,6 +39,7 @@ namespace OC; use Doctrine\DBAL\Exception\TableExistsException; +use OC\App\Platform; use OC\DB\MigrationService; use OC_App; use OC_DB; @@ -372,7 +373,7 @@ public static function checkAppsIntegrity($data, $extractDir, $path, $isShipped } // check if the app is compatible with this version of ownCloud - if (!OC_App::isAppCompatible(\OCP\Util::getVersion(), $info)) { + if (!OC_App::isAppCompatible(new Platform(\OC::$server->getConfig()), $info)) { OC_Helper::rmdirr($extractDir); throw new \Exception($l->t("App can't be installed because it is not compatible with this version of ownCloud")); } diff --git a/lib/private/Repair/Apps.php b/lib/private/Repair/Apps.php index 6a5e1eede602..1b03263447d9 100644 --- a/lib/private/Repair/Apps.php +++ b/lib/private/Repair/Apps.php @@ -23,6 +23,7 @@ use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Types\Type; +use OC\App\Platform; use OC\RepairException; use OC_App; use OCP\App\AppAlreadyInstalledException; @@ -265,8 +266,7 @@ protected function getAppsToUpgrade() { $appsToUpgrade[self::KEY_MISSING][] = $appId; continue; } - $version = Util::getVersion(); - $key = (\OC_App::isAppCompatible($version, $info)) ? self::KEY_COMPATIBLE : self::KEY_INCOMPATIBLE; + $key = (\OC_App::isAppCompatible(new Platform($this->config), $info)) ? self::KEY_COMPATIBLE : self::KEY_INCOMPATIBLE; $appsToUpgrade[$key][] = $appId; } return $appsToUpgrade; diff --git a/lib/private/Server.php b/lib/private/Server.php index 983040bc861c..63bd09256cde 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -41,6 +41,7 @@ namespace OC; use bantu\IniGetWrapper\IniGetWrapper; +use OC\App\Platform; use OC\AppFramework\Http\Request; use OC\AppFramework\Db\Db; use OC\AppFramework\Utility\TimeFactory; @@ -594,7 +595,8 @@ public function __construct($webRoot, \OC\Config $config) { $groupManager, $c->getMemCacheFactory(), $c->getEventDispatcher(), - $c->getConfig() + $c->getConfig(), + new Platform($c->getConfig()) ); }); $this->registerService('DateTimeZone', function (Server $c) { diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php index 877c66094a4f..30b4c275bfad 100644 --- a/lib/private/legacy/app.php +++ b/lib/private/legacy/app.php @@ -98,6 +98,9 @@ public static function isAppLoaded($app) { * exists. * * if $types is set, only apps of those types will be loaded + * @throws \OC\HintException + * @throws \OC\NeedsUpdateException + * @throws \OC\ServerNotAvailableException */ public static function loadApps($types = null) { if (\is_array($types) && !\array_diff($types, self::$loadedTypes)) { @@ -123,7 +126,7 @@ public static function loadApps($types = null) { // prevent app.php from printing output \ob_start(); foreach ($apps as $app) { - if (($types === null or self::isType($app, $types)) && !\in_array($app, self::$loadedApps)) { + if (($types === null or self::isType($app, $types)) && !\in_array($app, self::$loadedApps, true)) { self::loadApp($app); } } @@ -175,7 +178,9 @@ public static function loadApp($app, $checkUpgrade = true) { /** * Enables the app as a theme if it has the type "theme" + * * @param string $app + * @throws \OCP\AppFramework\QueryException */ private static function enableThemeIfApplicable($app) { if (self::isType($app, 'theme')) { @@ -206,6 +211,7 @@ public static function registerAutoloading($app, $path) { * Load app.php from the given app * * @param string $app app name + * @throws Exception */ private static function requireAppFile($app) { try { @@ -239,7 +245,7 @@ public static function isType($app, $types) { } $appTypes = self::getAppTypes($app); foreach ($types as $type) { - if (\array_search($type, $appTypes) !== false) { + if (\array_search($type, $appTypes, true)) { return true; } } @@ -260,9 +266,9 @@ private static function getAppTypes($app) { if (isset(self::$appTypes[$app])) { return \explode(',', self::$appTypes[$app]); - } else { - return []; } + + return []; } /** @@ -388,6 +394,7 @@ public static function enable($app, $groups = null) { /** * @param string $app * @return bool + * @throws \OCP\App\AppAlreadyInstalledException */ public static function removeApp($app) { if (self::isShipped($app)) { @@ -413,9 +420,9 @@ public static function disable($app) { self::$enabledAppsCache = []; // run uninstall steps - $appData = OC_App::getAppInfo($app); + $appData = self::getAppInfo($app); if ($appData !== null) { - OC_App::executeRepairSteps($app, $appData['repair-steps']['uninstall']); + self::executeRepairSteps($app, $appData['repair-steps']['uninstall']); } // emit disable hook - needed anymore ? @@ -445,11 +452,11 @@ public static function getSettingsNavigation() { ) { $settings = [ [ - "id" => "help", - "order" => 1000, - "href" => $urlGenerator->linkToRoute('settings_help'), - "name" => $l->t("Help"), - "icon" => $urlGenerator->imagePath("settings", "help.svg") + 'id' => 'help', + 'order' => 1000, + 'href' => $urlGenerator->linkToRoute('settings_help'), + 'name' => $l->t('Help'), + 'icon' => $urlGenerator->imagePath('settings', 'help.svg') ] ]; } @@ -458,11 +465,11 @@ public static function getSettingsNavigation() { if (OC_User::isLoggedIn()) { // personal menu $settings[] = [ - "id" => "settings", - "order" => 1, - "href" => $urlGenerator->linkToRoute('settings.SettingsPage.getPersonal'), - "name" => $l->t("Settings"), - "icon" => $urlGenerator->imagePath("settings", "admin.svg") + 'id' => 'settings', + 'order' => 1, + 'href' => $urlGenerator->linkToRoute('settings.SettingsPage.getPersonal'), + 'name' => $l->t('Settings'), + 'icon' => $urlGenerator->imagePath('settings', 'admin.svg') ]; } @@ -482,11 +489,11 @@ private static function proceedNavigation($list) { unset($navEntry); \usort($list, function ($a, $b) { - if ($a["order"] == $b["order"]) { + if ($a['order'] == $b['order']) { return 0; } - if ($a["order"] < $b["order"]) { + if ($a['order'] < $b['order']) { return -1; } @@ -566,6 +573,7 @@ public static function getAppVersion($appId) { * * @param string $path * @return string + * @throws Exception */ public static function getAppVersionByPath($path) { $infoFile = $path . '/appinfo/info.xml'; @@ -579,6 +587,7 @@ public static function getAppVersionByPath($path) { * @param string $appId id of the app or the path of the info.xml file * @param boolean $path (optional) * @return array|null + * @throws Exception * @note all data is read from info.xml, not just pre-defined fields */ public static function getAppInfo($appId, $path = false) { @@ -604,7 +613,7 @@ public static function getAppInfo($appId, $path = false) { } if (\is_array($data)) { - $data = OC_App::parseAppInfo($data); + $data = self::parseAppInfo($data); } if (isset($data['ocsid'])) { $storedId = \OC::$server->getConfig()->getAppValue($appId, 'ocsid'); @@ -637,6 +646,7 @@ public static function getNavigation() { * get the id of loaded app * * @return string + * @throws Exception */ public static function getCurrentApp() { $request = \OC::$server->getRequest(); @@ -651,9 +661,9 @@ public static function getCurrentApp() { if ($topFolder == 'apps') { $length = \strlen($topFolder); return \substr($script, $length + 1, \strpos($script, '/', $length + 1) - $length - 1); - } else { - return $topFolder; } + + return $topFolder; } /** @@ -754,13 +764,11 @@ public static function getAllApps() { /** * List all apps, this is used in apps.php * - * @param bool $onlyLocal - * @param bool $includeUpdateInfo Should we check whether there is an update - * in the app store? * @return array + * @throws Exception */ public static function listAllApps() { - $installedApps = OC_App::getAllApps(); + $installedApps = self::getAllApps(); //TODO which apps do we want to blacklist and how do we integrate // blacklisting with the multi apps folder feature? @@ -771,8 +779,8 @@ public static function listAllApps() { $urlGenerator = \OC::$server->getURLGenerator(); foreach ($installedApps as $app) { - if (\array_search($app, $blacklist) === false) { - $info = OC_App::getAppInfo($app); + if (!\in_array($app, $blacklist)) { + $info = self::getAppInfo($app); if (!\is_array($info)) { \OCP\Util::writeLog('core', 'Could not read app info file for app "' . $app . '"', \OCP\Util::ERROR); continue; @@ -838,7 +846,7 @@ public static function listAllApps() { } } - $info['version'] = OC_App::getAppVersion($app); + $info['version'] = self::getAppVersion($app); $appList[] = $info; } } @@ -854,8 +862,8 @@ public static function listAllApps() { public static function getInternalAppIdByOcs($ocsID) { if (\is_numeric($ocsID)) { $idArray = \OC::$server->getAppConfig()->getValues(false, 'ocsid'); - if (\array_search($ocsID, $idArray)) { - return \array_search($ocsID, $idArray); + if (\array_search($ocsID, $idArray, true)) { + return \array_search($ocsID, $idArray, true); } } return false; @@ -903,12 +911,12 @@ private static function adjustVersionParts($version1, $version2) { * This means that it's possible to specify "requiremin" => 6 * and "requiremax" => 6 and it will still match ownCloud 6.0.3. * - * @param string|array $ocVersion ownCloud version to check against + * @param Platform $platform * @param array $appInfo app info (from xml) * * @return boolean true if compatible, otherwise false */ - public static function isAppCompatible($ocVersion, $appInfo) { + public static function isAppCompatible(Platform $platform, $appInfo) { $requireMin = ''; $requireMax = ''; if (isset($appInfo['dependencies']['owncloud']['@attributes']['min-version'])) { @@ -925,10 +933,7 @@ public static function isAppCompatible($ocVersion, $appInfo) { $requireMax = $appInfo['requiremax']; } - if (\is_array($ocVersion)) { - $ocVersion = \implode('.', $ocVersion); - } - + $ocVersion = $platform->getOcVersion(); if (!empty($requireMin) && \version_compare(self::adjustVersionParts($ocVersion, $requireMin), $requireMin, '<') ) { @@ -936,6 +941,7 @@ public static function isAppCompatible($ocVersion, $appInfo) { } if (!empty($requireMax) + && !\in_array($platform->getOcChannel(), ['git', 'daily'], true) && \version_compare(self::adjustVersionParts($ocVersion, $requireMax), $requireMax, '>') ) { return false; @@ -962,6 +968,7 @@ public static function getAppVersions() { * * @param string $appId * @return bool + * @throws \OC\NeedsUpdateException */ public static function updateApp($appId) { $appPath = self::getAppPath($appId); @@ -1003,7 +1010,7 @@ public static function updateApp($appId) { self::setAppTypes($appId); - $version = \OC_App::getAppVersion($appId); + $version = self::getAppVersion($appId); \OC::$server->getAppConfig()->setValue($appId, 'installed_version', $version); return true; @@ -1060,19 +1067,20 @@ private static function setupLiveMigrations($appId, array $steps) { /** * @param string $appId * @return \OC\Files\View|false + * @throws Exception */ public static function getStorage($appId) { - if (OC_App::isEnabled($appId)) { //sanity check + if (self::isEnabled($appId)) { //sanity check if (OC_User::isLoggedIn()) { $view = new \OC\Files\View('/' . OC_User::getUser()); if (!$view->file_exists($appId)) { $view->mkdir($appId); } return new \OC\Files\View('/' . OC_User::getUser() . '/' . $appId); - } else { - \OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ', user not logged in', \OCP\Util::ERROR); - return false; } + + \OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ', user not logged in', \OCP\Util::ERROR); + return false; } else { \OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ' not enabled', \OCP\Util::ERROR); return false; @@ -1125,7 +1133,7 @@ protected static function checkAppDependencies($config, $l, $info) { $dependencyAnalyzer = new DependencyAnalyzer(new Platform($config), $l); $missing = $dependencyAnalyzer->analyze($info); if (!empty($missing)) { - $missingMsg = \join(PHP_EOL, $missing); + $missingMsg = \implode(PHP_EOL, $missing); throw new \Exception( $l->t('App "%s" cannot be installed because the following dependencies are not fulfilled: %s', [$info['name'], $missingMsg] diff --git a/tests/Settings/Controller/AppSettingsControllerTest.php b/tests/Settings/Controller/AppSettingsControllerTest.php index 254200242662..756d8a744eda 100644 --- a/tests/Settings/Controller/AppSettingsControllerTest.php +++ b/tests/Settings/Controller/AppSettingsControllerTest.php @@ -60,6 +60,7 @@ public function setUp() { $this->appManager = $this->getMockBuilder(IAppManager::class) ->disableOriginalConstructor()->getMock(); + $this->config->method('getSystemValue')->willReturnArgument(1); $this->appSettingsController = new AppSettingsController( 'settings', $this->request, diff --git a/tests/lib/App/DependencyAnalyzerTest.php b/tests/lib/App/DependencyAnalyzerTest.php index 863b4a3de3a0..415ffcc42ae9 100644 --- a/tests/lib/App/DependencyAnalyzerTest.php +++ b/tests/lib/App/DependencyAnalyzerTest.php @@ -29,39 +29,43 @@ public function setUp() { $this->platformMock = $this->getMockBuilder(Platform::class) ->disableOriginalConstructor() ->getMock(); - $this->platformMock->expects($this->any()) + $this->platformMock ->method('getPhpVersion') ->will($this->returnValue('5.4.3')); - $this->platformMock->expects($this->any()) + $this->platformMock ->method('getIntSize') ->will($this->returnValue('4')); - $this->platformMock->expects($this->any()) + $this->platformMock ->method('getDatabase') ->will($this->returnValue('mysql')); - $this->platformMock->expects($this->any()) + $this->platformMock ->method('getOS') ->will($this->returnValue('Linux')); - $this->platformMock->expects($this->any()) + $this->platformMock ->method('isCommandKnown') ->will($this->returnCallback(function ($command) { return ($command === 'grep'); })); - $this->platformMock->expects($this->any()) + $this->platformMock ->method('getLibraryVersion') ->will($this->returnCallback(function ($lib) { if ($lib === 'curl') { - return "2.3.4"; + return '2.3.4'; } return null; })); - $this->platformMock->expects($this->any()) + $this->platformMock ->method('getOcVersion') ->will($this->returnValue('8.0.2')); - $this->l10nMock = $this->getMockBuilder('\OCP\IL10N') + $this->platformMock + ->method('getOcChannel') + ->will($this->returnValue('production')); + + $this->l10nMock = $this->getMockBuilder(IL10N::class) ->disableOriginalConstructor() ->getMock(); - $this->l10nMock->expects($this->any()) + $this->l10nMock ->method('t') ->will($this->returnCallback(function ($text, $parameters = []) { return \vsprintf($text, $parameters); @@ -78,7 +82,7 @@ public function setUp() { * @param string $maxVersion * @param string $intSize */ - public function testPhpVersion($expectedMissing, $minVersion, $maxVersion, $intSize) { + public function testPhpVersion($expectedMissing, $minVersion, $maxVersion, $intSize): void { $app = [ 'dependencies' => [ 'php' => [] @@ -104,7 +108,7 @@ public function testPhpVersion($expectedMissing, $minVersion, $maxVersion, $intS * @param $expectedMissing * @param $databases */ - public function testDatabases($expectedMissing, $databases) { + public function testDatabases($expectedMissing, $databases): void { $app = [ 'dependencies' => [ ] @@ -124,7 +128,7 @@ public function testDatabases($expectedMissing, $databases) { * @param string $expectedMissing * @param string|null $commands */ - public function testCommand($expectedMissing, $commands) { + public function testCommand($expectedMissing, $commands): void { $app = [ 'dependencies' => [ ] @@ -143,7 +147,7 @@ public function testCommand($expectedMissing, $commands) { * @param $expectedMissing * @param $libs */ - public function testLibs($expectedMissing, $libs) { + public function testLibs($expectedMissing, $libs): void { $app = [ 'dependencies' => [ ] @@ -163,7 +167,7 @@ public function testLibs($expectedMissing, $libs) { * @param $expectedMissing * @param $oss */ - public function testOS($expectedMissing, $oss) { + public function testOS($expectedMissing, $oss): void { $app = [ 'dependencies' => [] ]; @@ -182,7 +186,7 @@ public function testOS($expectedMissing, $oss) { * @param $expectedMissing * @param $oc */ - public function testOC($expectedMissing, $oc) { + public function testOC($expectedMissing, $oc): void { $app = [ 'dependencies' => [] ]; @@ -199,7 +203,7 @@ public function testOC($expectedMissing, $oc) { /** * @return array */ - public function providesOC() { + public function providesOC(): array { return [ // no version -> no missing dependency [[], null], @@ -215,7 +219,7 @@ public function providesOC() { /** * @return array */ - public function providesOS() { + public function providesOS(): array { return [ [[], null], [[], []], @@ -227,7 +231,7 @@ public function providesOS() { /** * @return array */ - public function providesLibs() { + public function providesLibs(): array { return [ // we expect curl to exist [[], 'curl'], @@ -257,7 +261,7 @@ public function providesLibs() { /** * @return array */ - public function providesCommands() { + public function providesCommands(): array { return [ [[], null], // grep is known on linux @@ -275,7 +279,7 @@ public function providesCommands() { /** * @return array */ - public function providesDatabases() { + public function providesDatabases(): array { return [ // non BC - in case on databases are defined -> all are supported [[], null], @@ -288,7 +292,7 @@ public function providesDatabases() { /** * @return array */ - public function providesPhpVersion() { + public function providesPhpVersion(): array { return [ [[], null, null, null], [[], '5.4', null, null], diff --git a/tests/lib/App/ManagerTest.php b/tests/lib/App/ManagerTest.php index 4cca6f48c95b..7c3b19ee2972 100644 --- a/tests/lib/App/ManagerTest.php +++ b/tests/lib/App/ManagerTest.php @@ -10,6 +10,7 @@ namespace Test\App; use OC\App\AppManager; +use OC\App\Platform; use OC\Group\Group; use OCP\App\IAppManager; use OCP\IAppConfig; @@ -47,6 +48,8 @@ class ManagerTest extends TestCase { protected $eventDispatcher; /** @var IConfig | \PHPUnit_Framework_MockObject_MockObject */ private $config; + /** @var Platform | \PHPUnit_Framework_MockObject_MockObject */ + private $platform; /** * @return IAppConfig | \PHPUnit_Framework_MockObject_MockObject @@ -57,12 +60,12 @@ protected function getAppConfig() { ->disableOriginalConstructor() ->getMock(); - $config->expects($this->any()) + $config ->method('getValue') ->will($this->returnCallback(function ($app, $key, $default) use (&$appConfig) { return (isset($appConfig[$app]) and isset($appConfig[$app][$key])) ? $appConfig[$app][$key] : $default; })); - $config->expects($this->any()) + $config ->method('setValue') ->will($this->returnCallback(function ($app, $key, $value) use (&$appConfig) { if (!isset($appConfig[$app])) { @@ -70,20 +73,20 @@ protected function getAppConfig() { } $appConfig[$app][$key] = $value; })); - $config->expects($this->any()) + $config ->method('getValues') ->will($this->returnCallback(function ($app, $key) use (&$appConfig) { if ($app) { return $appConfig[$app]; - } else { - $values = []; - foreach ($appConfig as $app => $appData) { - if (isset($appData[$key])) { - $values[$app] = $appData[$key]; - } + } + + $values = []; + foreach ($appConfig as $appId => $appData) { + if (isset($appData[$key])) { + $values[$appId] = $appData[$key]; } - return $values; } + return $values; })); return $config; @@ -99,22 +102,23 @@ protected function setUp() { $this->cacheFactory = $this->createMock(ICacheFactory::class); $this->cache = $this->createMock(ICache::class); $this->eventDispatcher = $this->createMock(EventDispatcherInterface::class); - $this->cacheFactory->expects($this->any()) + $this->cacheFactory ->method('create') ->with('settings') ->willReturn($this->cache); + $this->platform = $this->createMock(Platform::class); $this->manager = new AppManager($this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, - $this->config); + $this->config, $this->platform); } - protected function expectClearCache() { + protected function expectClearCache(): void { $this->cache->expects($this->once()) ->method('clear') ->with('listApps'); } - public function testEnableApp() { + public function testEnableApp(): void { $this->expectClearCache(); // making sure "files_trashbin" is disabled if ($this->manager->isEnabledForUser('files_trashbin')) { @@ -127,13 +131,14 @@ public function testEnableApp() { /** * @expectedException \OCP\App\AppManagerException */ - public function testEnableSecondAppTheme() { + public function testEnableSecondAppTheme(): void { $appThemeName = 'theme-one'; + /** @var AppManager | \PHPUnit_Framework_MockObject_MockObject $manager */ $manager = $this->getMockBuilder(AppManager::class) ->setMethods(['isTheme', 'getAppInfo', 'getAppPath']) ->setConstructorArgs([$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, - $this->config]) + $this->config, $this->platform]) ->getMock(); $manager->expects($this->once()) @@ -152,13 +157,13 @@ public function testEnableSecondAppTheme() { $manager->enableApp($appThemeName); } - public function testEnableTheSameThemeTwice() { + public function testEnableTheSameThemeTwice(): void { $appThemeName = 'theme-one'; $manager = $this->getMockBuilder(AppManager::class) ->setMethods(['isTheme', 'getAppInfo', 'getAppPath', 'getInstalledApps']) ->setConstructorArgs([$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, - $this->config]) + $this->config, $this->platform]) ->getMock(); $manager->expects($this->once()) @@ -168,7 +173,7 @@ public function testEnableTheSameThemeTwice() { ->method('getAppInfo') ->willReturn(['types'=>['theme']]); - $manager->expects($this->any()) + $manager ->method('isTheme') ->will( $this->returnCallback( @@ -186,7 +191,7 @@ function ($appId) use ($appThemeName) { $manager->enableApp($appThemeName); } - public function testDisableApp() { + public function testDisableApp(): void { $this->expectClearCache(); $this->manager->disableApp('files_trashbin'); $this->assertEquals('no', $this->appConfig->getValue('files_trashbin', 'enabled', 'no')); @@ -195,14 +200,14 @@ public function testDisableApp() { /** * @expectedException \Exception */ - public function testNotEnableIfNotInstalled() { + public function testNotEnableIfNotInstalled(): void { $this->manager->enableApp('some_random_name_which_i_hope_is_not_an_app'); $this->assertEquals('no', $this->appConfig->getValue( 'some_random_name_which_i_hope_is_not_an_app', 'enabled', 'no' )); } - public function testEnableAppForGroups() { + public function testEnableAppForGroups(): void { $groups = [ new Group('group1', [], null, $this->eventDispatcher), new Group('group2', [], null, $this->eventDispatcher) @@ -212,7 +217,7 @@ public function testEnableAppForGroups() { $this->assertEquals('["group1","group2"]', $this->appConfig->getValue('test', 'enabled', 'no')); } - public function dataEnableAppForGroupsAllowedTypes() { + public function dataEnableAppForGroupsAllowedTypes(): array { return [ [[]], [[ @@ -228,8 +233,9 @@ public function dataEnableAppForGroupsAllowedTypes() { * @dataProvider dataEnableAppForGroupsAllowedTypes * * @param array $appInfo + * @throws \Exception */ - public function testEnableAppForGroupsAllowedTypes(array $appInfo) { + public function testEnableAppForGroupsAllowedTypes(array $appInfo): void { $groups = [ new Group('group1', [], null, $this->eventDispatcher), new Group('group2', [], null, $this->eventDispatcher) @@ -237,10 +243,11 @@ public function testEnableAppForGroupsAllowedTypes(array $appInfo) { $this->expectClearCache(); /** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */ - $manager = $this->getMockBuilder('OC\App\AppManager') + $manager = $this->getMockBuilder(AppManager::class) ->setConstructorArgs([ $this->userSession, $this->appConfig, $this->groupManager, - $this->cacheFactory, $this->eventDispatcher, $this->config + $this->cacheFactory, $this->eventDispatcher, $this->config, + $this->platform ]) ->setMethods([ 'getAppInfo' @@ -256,7 +263,7 @@ public function testEnableAppForGroupsAllowedTypes(array $appInfo) { $this->assertEquals('["group1","group2"]', $this->appConfig->getValue('test', 'enabled', 'no')); } - public function dataEnableAppForGroupsForbiddenTypes() { + public function dataEnableAppForGroupsForbiddenTypes(): array { return [ ['filesystem'], ['prelogin'], @@ -274,17 +281,18 @@ public function dataEnableAppForGroupsForbiddenTypes() { * @expectedException \Exception * @expectedExceptionMessage test can't be enabled for groups. */ - public function testEnableAppForGroupsForbiddenTypes($type) { + public function testEnableAppForGroupsForbiddenTypes($type): void { $groups = [ new Group('group1', [], null, $this->eventDispatcher), new Group('group2', [], null, $this->eventDispatcher) ]; /** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */ - $manager = $this->getMockBuilder('OC\App\AppManager') + $manager = $this->getMockBuilder(AppManager::class) ->setConstructorArgs([ $this->userSession, $this->appConfig, $this->groupManager, - $this->cacheFactory, $this->eventDispatcher, $this->config + $this->cacheFactory, $this->eventDispatcher, $this->config, + $this->platform ]) ->setMethods([ 'getAppInfo' @@ -301,34 +309,34 @@ public function testEnableAppForGroupsForbiddenTypes($type) { $manager->enableAppForGroups('test', $groups); } - public function testIsInstalledEnabled() { + public function testIsInstalledEnabled(): void { $this->appConfig->setValue('test', 'enabled', 'yes'); $this->assertTrue($this->manager->isInstalled('test')); } - public function testIsInstalledDisabled() { + public function testIsInstalledDisabled(): void { $this->appConfig->setValue('test', 'enabled', 'no'); $this->assertFalse($this->manager->isInstalled('test')); } - public function testIsInstalledEnabledForGroups() { + public function testIsInstalledEnabledForGroups(): void { $this->appConfig->setValue('test', 'enabled', '["foo"]'); $this->assertTrue($this->manager->isInstalled('test')); } - public function testIsEnabledForUserEnabled() { + public function testIsEnabledForUserEnabled(): void { $this->appConfig->setValue('test', 'enabled', 'yes'); $user = $this->createMock(IUser::class); $this->assertTrue($this->manager->isEnabledForUser('test', $user)); } - public function testIsEnabledForUserDisabled() { + public function testIsEnabledForUserDisabled(): void { $this->appConfig->setValue('test', 'enabled', 'no'); $user = $this->createMock(IUser::class); $this->assertFalse($this->manager->isEnabledForUser('test', $user)); } - public function testIsEnabledForUserEnabledForGroup() { + public function testIsEnabledForUserEnabledForGroup(): void { $user = $this->createMock(IUser::class); $this->groupManager->expects($this->once()) ->method('getUserGroupIds') @@ -339,7 +347,7 @@ public function testIsEnabledForUserEnabledForGroup() { $this->assertTrue($this->manager->isEnabledForUser('test', $user)); } - public function testIsEnabledForUserDisabledForGroup() { + public function testIsEnabledForUserDisabledForGroup(): void { $user = $this->createMock(IUser::class); $this->groupManager->expects($this->once()) ->method('getUserGroupIds') @@ -350,12 +358,12 @@ public function testIsEnabledForUserDisabledForGroup() { $this->assertFalse($this->manager->isEnabledForUser('test', $user)); } - public function testIsEnabledForUserLoggedOut() { + public function testIsEnabledForUserLoggedOut(): void { $this->appConfig->setValue('test', 'enabled', '["foo"]'); - $this->assertFalse($this->manager->IsEnabledForUser('test')); + $this->assertFalse($this->manager->isEnabledForUser('test')); } - public function testIsEnabledForUserLoggedIn() { + public function testIsEnabledForUserLoggedIn(): void { $user = $this->createMock(IUser::class); $this->userSession->expects($this->once()) @@ -370,7 +378,7 @@ public function testIsEnabledForUserLoggedIn() { $this->assertTrue($this->manager->isEnabledForUser('test')); } - public function testGetInstalledApps() { + public function testGetInstalledApps(): void { $this->appConfig->setValue('test1', 'enabled', 'yes'); $this->appConfig->setValue('test2', 'enabled', 'no'); $this->appConfig->setValue('test3', 'enabled', '["foo"]'); @@ -384,9 +392,9 @@ public function testGetInstalledApps() { ], $this->manager->getInstalledApps()); } - public function testGetAppsForUser() { + public function testGetAppsForUser(): void { $user = $this->createMock(IUser::class); - $this->groupManager->expects($this->any()) + $this->groupManager ->method('getUserGroupIds') ->with($user) ->will($this->returnValue(['foo', 'bar'])); @@ -405,10 +413,12 @@ public function testGetAppsForUser() { ], $this->manager->getEnabledAppsForUser($user)); } - public function testGetAppsNeedingUpgrade() { - $this->manager = $this->getMockBuilder('\OC\App\AppManager') + public function testGetAppsNeedingUpgrade(): void { + $this->platform->method('getOcVersion')->willReturn('8.2.0'); + $this->manager = $this->getMockBuilder(AppManager::class) ->setConstructorArgs([$this->userSession, $this->appConfig, - $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->config]) + $this->groupManager, $this->cacheFactory, $this->eventDispatcher, + $this->config, $this->platform]) ->setMethods(['getAppInfo']) ->getMock(); @@ -424,7 +434,7 @@ public function testGetAppsNeedingUpgrade() { 'testnoversion' => ['id' => 'testnoversion', 'requiremin' => '8.2.0'], ]; - $this->manager->expects($this->any()) + $this->manager ->method('getAppInfo') ->will($this->returnCallback( function ($appId) use ($appInfos) { @@ -441,61 +451,24 @@ function ($appId) use ($appInfos) { $this->appConfig->setValue('test4', 'enabled', 'yes'); $this->appConfig->setValue('test4', 'installed_version', '2.4.0'); - $apps = $this->manager->getAppsNeedingUpgrade('8.2.0'); + $apps = $this->manager->getAppsNeedingUpgrade(); $this->assertCount(2, $apps); $this->assertEquals('test1', $apps[0]['id']); $this->assertEquals('test4', $apps[1]['id']); } - public function testGetIncompatibleApps() { - $this->manager = $this->getMockBuilder('\OC\App\AppManager') - ->setConstructorArgs([$this->userSession, $this->appConfig, - $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->config]) - ->setMethods(['getAppInfo']) - ->getMock(); - - $appInfos = [ - 'dav' => ['id' => 'dav'], - 'files' => ['id' => 'files'], - 'files_external' => ['id' => 'files_external'], - 'federatedfilesharing' => ['id' => 'federatedfilesharing'], - 'test1' => ['id' => 'test1', 'version' => '1.0.1', 'requiremax' => '8.0.0'], - 'test2' => ['id' => 'test2', 'version' => '1.0.0', 'requiremin' => '8.2.0'], - 'test3' => ['id' => 'test3', 'version' => '1.2.4', 'requiremin' => '9.0.0'], - 'testnoversion' => ['id' => 'testnoversion', 'requiremin' => '8.2.0'], - ]; - - $this->manager->expects($this->any()) - ->method('getAppInfo') - ->will($this->returnCallback( - function ($appId) use ($appInfos) { - return $appInfos[$appId]; - } - )); - - $this->appConfig->setValue('test1', 'enabled', 'yes'); - $this->appConfig->setValue('test2', 'enabled', 'yes'); - $this->appConfig->setValue('test3', 'enabled', 'yes'); - - $apps = $this->manager->getIncompatibleApps('8.2.0'); - - $this->assertCount(2, $apps); - $this->assertEquals('test1', $apps[0]['id']); - $this->assertEquals('test3', $apps[1]['id']); - } - /** * @dataProvider providesDataForCanInstall * @param bool $canInstall * @param string $opsMode */ - public function testCanInstall($canInstall, $opsMode) { + public function testCanInstall($canInstall, $opsMode): void { $this->config->expects($this->once())->method('getSystemValue')->willReturn($opsMode); $this->assertEquals($canInstall, $this->manager->canInstall()); } - public function providesDataForCanInstall() { + public function providesDataForCanInstall(): array { return [ [true, 'single-instance'], [false, 'clustered-instance'], @@ -509,7 +482,7 @@ public function providesDataForCanInstall() { * @param string $secondDirVersion * @param bool $isFirstWinner */ - public function testTheMostRecentAppIsFound($firstDirVersion, $secondDirVersion, $isFirstWinner) { + public function testTheMostRecentAppIsFound($firstDirVersion, $secondDirVersion, $isFirstWinner): void { $appId = 'bogusapp'; $appsParentDir = vfsStream::setup(); $firstAppDir = vfsStream::newDirectory('apps')->at($appsParentDir); @@ -522,7 +495,7 @@ public function testTheMostRecentAppIsFound($firstDirVersion, $secondDirVersion, ->disableOriginalConstructor() ->getMock(); - $appManager->expects($this->any()) + $appManager ->method('getAppRoots') ->willReturn([ [ @@ -535,7 +508,7 @@ public function testTheMostRecentAppIsFound($firstDirVersion, $secondDirVersion, ] ]); - $appManager->expects($this->any()) + $appManager ->method('getAppVersionByPath') ->will($this->onConsecutiveCalls($firstDirVersion, $secondDirVersion)); @@ -544,14 +517,14 @@ public function testTheMostRecentAppIsFound($firstDirVersion, $secondDirVersion, $this->assertEquals($expected, $appPath); } - public function appInfoDataProvider() { + public function appInfoDataProvider(): array { return [ [ '1.2.3', '3.2.4', false ], [ '2.2.3', '2.2.1', true ] ]; } - public function testPathIsNotCachedForNotFoundApp() { + public function testPathIsNotCachedForNotFoundApp(): void { $appId = 'notexistingapp'; $appManager = $this->getMockBuilder(AppManager::class) @@ -559,7 +532,7 @@ public function testPathIsNotCachedForNotFoundApp() { ->disableOriginalConstructor() ->getMock(); - $appManager->expects($this->any()) + $appManager ->method('getAppRoots') ->willReturn([]); @@ -578,7 +551,7 @@ public function testPathIsNotCachedForNotFoundApp() { * @param string $expectedAppWebPath */ public function testAppWebRootAboveOcWebRoot($ocWebRoot, $appData, - $expectedAppWebPath) { + $expectedAppWebPath): void { $appId = 'notexistingapp'; $appManager = $this->getMockBuilder(AppManager::class) @@ -586,11 +559,11 @@ public function testAppWebRootAboveOcWebRoot($ocWebRoot, $appData, ->disableOriginalConstructor() ->getMock(); - $appManager->expects($this->any()) + $appManager ->method('getOcWebRoot') ->willReturn($ocWebRoot); - $appManager->expects($this->any()) + $appManager ->method('findAppInDirectories') ->with($appId) ->willReturn($appData); @@ -599,7 +572,7 @@ public function testAppWebRootAboveOcWebRoot($ocWebRoot, $appData, $this->assertEquals($expectedAppWebPath, $appWebPath); } - public function appAboveWebRootDataProvider() { + public function appAboveWebRootDataProvider(): array { return [ [ '/some/host/path', diff --git a/tests/lib/AppTest.php b/tests/lib/AppTest.php index f709b21affde..c45bcad62e47 100644 --- a/tests/lib/AppTest.php +++ b/tests/lib/AppTest.php @@ -8,6 +8,7 @@ */ namespace Test; +use OC\App\Platform; use OCP\IAppConfig; use Test\Traits\UserTrait; @@ -272,20 +273,10 @@ public function appVersionsProvider() { * @dataProvider appVersionsProvider */ public function testIsAppCompatible($ocVersion, $appInfo, $expectedResult) { - $this->assertEquals($expectedResult, \OC_App::isAppCompatible($ocVersion, $appInfo)); - } - - /** - * Test that the isAppCompatible method also supports passing an array - * as $ocVersion - */ - public function testIsAppCompatibleWithArray() { - $ocVersion = [6]; - $appInfo = [ - 'requiremin' => '6', - 'requiremax' => '6', - ]; - $this->assertTrue(\OC_App::isAppCompatible($ocVersion, $appInfo)); + $platform = $this->createMock(Platform::class); + $platform->method('getOcChannel')->willReturn('production'); + $platform->method('getOcVersion')->willReturn($ocVersion); + $this->assertEquals($expectedResult, \OC_App::isAppCompatible($platform, $appInfo)); } /** @@ -507,7 +498,7 @@ private function registerAppConfig(IAppConfig $appConfig) { \OC::$server->registerService('AppManager', function (\OC\Server $c) use ($appConfig) { return new \OC\App\AppManager($c->getUserSession(), $appConfig, $c->getGroupManager(), $c->getMemCacheFactory(), - $c->getEventDispatcher(), $c->getConfig()); + $c->getEventDispatcher(), $c->getConfig(), new Platform($c->getConfig())); }); } @@ -521,7 +512,7 @@ private function restoreAppConfig() { \OC::$server->registerService('AppManager', function (\OC\Server $c) { return new \OC\App\AppManager($c->getUserSession(), $c->getAppConfig(), $c->getGroupManager(), $c->getMemCacheFactory(), - $c->getEventDispatcher(), $c->getConfig()); + $c->getEventDispatcher(), $c->getConfig(), new Platform($c->getConfig())); }); // Remove the cache of the mocked apps list with a forceRefresh