summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/private/app.php84
-rw-r--r--lib/private/installer.php5
-rw-r--r--tests/lib/app.php274
3 files changed, 272 insertions, 91 deletions
diff --git a/lib/private/app.php b/lib/private/app.php
index 575cc9f41af..50065197eb4 100644
--- a/lib/private/app.php
+++ b/lib/private/app.php
@@ -231,7 +231,7 @@ class OC_App{
// check if the app is compatible with this version of ownCloud
$info=OC_App::getAppInfo($app);
$version=OC_Util::getVersion();
- if(!isset($info['require']) or !self::isAppVersionCompatible($version, $info['require'])) {
+ if(!self::isAppCompatible($version, $info)) {
throw new \Exception(
$l->t("App \"%s\" can't be installed because it is not compatible with this version of ownCloud.",
array($info['name'])
@@ -898,7 +898,7 @@ class OC_App{
foreach($apps as $app) {
// check if the app is compatible with this version of ownCloud
$info = OC_App::getAppInfo($app);
- if(!isset($info['require']) or !self::isAppVersionCompatible($version, $info['require'])) {
+ if(!self::isAppCompatible($version, $info)) {
OC_Log::write('core',
'App "'.$info['name'].'" ('.$app.') can\'t be used because it is'
.' not compatible with this version of ownCloud',
@@ -909,38 +909,78 @@ class OC_App{
}
}
+ /**
+ * Ajust the number of version parts of $version1 to match
+ * the number of version parts of $version2.
+ *
+ * @param string $version1 version to adjust
+ * @param string $version2 version to take the number of parts from
+ * @return string shortened $version1
+ */
+ private static function adjustVersionParts($version1, $version2) {
+ $version1 = explode('.', $version1);
+ $version2 = explode('.', $version2);
+ // reduce $version1 to match the number of parts in $version2
+ while (count($version1) > count($version2)) {
+ array_pop($version1);
+ }
+ // if $version1 does not have enough parts, add some
+ while (count($version1) < count($version2)) {
+ $version1[] = '0';
+ }
+ return implode('.', $version1);
+ }
/**
- * Compares the app version with the owncloud version to see if the app
- * requires a newer version than the currently active one
- * @param array $owncloudVersions array with 3 entries: major minor bugfix
- * @param string $appRequired the required version from the xml
- * major.minor.bugfix
+ * Check whether the current ownCloud version matches the given
+ * application's version requirements.
+ *
+ * The comparison is made based on the number of parts that the
+ * app info version has. For example for ownCloud 6.0.3 if the
+ * app info version is expecting version 6.0, the comparison is
+ * made on the first two parts of the ownCloud version.
+ * This means that it's possible to specify "requiremin" => 6
+ * and "requiremax" => 6 and it will still match ownCloud 6.0.3.
+ *
+ * @param string $ocVersion ownCloud version to check against
+ * @param array $appInfo app info (from xml)
+ *
* @return boolean true if compatible, otherwise false
*/
- public static function isAppVersionCompatible($owncloudVersions, $appRequired){
- $appVersions = explode('.', $appRequired);
+ public static function isAppCompatible($ocVersion, $appInfo){
+ $requireMin = '';
+ $requireMax = '';
+ if (isset($appInfo['requiremin'])) {
+ $requireMin = $appInfo['requiremin'];
+ } else if (isset($appInfo['require'])) {
+ $requireMin = $appInfo['require'];
+ }
- for($i=0; $i<count($appVersions); $i++){
- $appVersion = (int) $appVersions[$i];
+ if (isset($appInfo['requiremax'])) {
+ $requireMax = $appInfo['requiremax'];
+ }
- if(isset($owncloudVersions[$i])){
- $owncloudVersion = $owncloudVersions[$i];
- } else {
- $owncloudVersion = 0;
- }
+ if (is_array($ocVersion)) {
+ $ocVersion = implode('.', $ocVersion);
+ }
- if($owncloudVersion < $appVersion){
- return false;
- } elseif ($owncloudVersion > $appVersion) {
- return true;
- }
+ if (!empty($requireMin)
+ && version_compare(self::adjustVersionParts($ocVersion, $requireMin), $requireMin, '<')
+ ) {
+
+ return false;
+ }
+
+ if (!empty($requireMax)
+ && version_compare(self::adjustVersionParts($ocVersion, $requireMax), $requireMax, '>')
+ ) {
+
+ return false;
}
return true;
}
-
/**
* get the installed version of all apps
*/
diff --git a/lib/private/installer.php b/lib/private/installer.php
index 667c05c9c16..3bddfa6a3b7 100644
--- a/lib/private/installer.php
+++ b/lib/private/installer.php
@@ -133,10 +133,7 @@ class OC_Installer{
}
// check if the app is compatible with this version of ownCloud
- if(
- !isset($info['require'])
- or !OC_App::isAppVersionCompatible(OC_Util::getVersion(), $info['require'])
- ) {
+ if(!OC_App::isAppCompatible(OC_Util::getVersion(), $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/tests/lib/app.php b/tests/lib/app.php
index 683820cabb6..e2b578fe6b9 100644
--- a/tests/lib/app.php
+++ b/tests/lib/app.php
@@ -1,6 +1,7 @@
<?php
/**
* Copyright (c) 2012 Bernhard Posselt <dev@bernhard-posselt.com>
+ * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
@@ -8,75 +9,218 @@
class Test_App extends PHPUnit_Framework_TestCase {
-
- public function testIsAppVersionCompatibleSingleOCNumber(){
- $oc = array(4);
- $app = '4.0';
-
- $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app));
- }
-
-
- public function testIsAppVersionCompatibleMultipleOCNumber(){
- $oc = array(4, 3, 1);
- $app = '4.3';
-
- $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app));
- }
-
-
- public function testIsAppVersionCompatibleSingleNumber(){
- $oc = array(4);
- $app = '4';
-
- $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app));
- }
-
-
- public function testIsAppVersionCompatibleSingleAppNumber(){
- $oc = array(4, 3);
- $app = '4';
-
- $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app));
- }
-
-
- public function testIsAppVersionCompatibleComplex(){
- $oc = array(5, 0, 0);
- $app = '4.5.1';
-
- $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app));
- }
-
-
- public function testIsAppVersionCompatibleShouldFail(){
- $oc = array(4, 3, 1);
- $app = '4.3.2';
-
- $this->assertFalse(OC_App::isAppVersionCompatible($oc, $app));
+ function appVersionsProvider() {
+ return array(
+ // exact match
+ array(
+ '6.0.0.0',
+ array(
+ 'requiremin' => '6.0',
+ 'requiremax' => '6.0',
+ ),
+ true
+ ),
+ // in-between match
+ array(
+ '6.0.0.0',
+ array(
+ 'requiremin' => '5.0',
+ 'requiremax' => '7.0',
+ ),
+ true
+ ),
+ // app too old
+ array(
+ '6.0.0.0',
+ array(
+ 'requiremin' => '5.0',
+ 'requiremax' => '5.0',
+ ),
+ false
+ ),
+ // app too new
+ array(
+ '5.0.0.0',
+ array(
+ 'requiremin' => '6.0',
+ 'requiremax' => '6.0',
+ ),
+ false
+ ),
+ // only min specified
+ array(
+ '6.0.0.0',
+ array(
+ 'requiremin' => '6.0',
+ ),
+ true
+ ),
+ // only min specified fail
+ array(
+ '5.0.0.0',
+ array(
+ 'requiremin' => '6.0',
+ ),
+ false
+ ),
+ // only min specified legacy
+ array(
+ '6.0.0.0',
+ array(
+ 'require' => '6.0',
+ ),
+ true
+ ),
+ // only min specified legacy fail
+ array(
+ '4.0.0.0',
+ array(
+ 'require' => '6.0',
+ ),
+ false
+ ),
+ // only max specified
+ array(
+ '5.0.0.0',
+ array(
+ 'requiremax' => '6.0',
+ ),
+ true
+ ),
+ // only max specified fail
+ array(
+ '7.0.0.0',
+ array(
+ 'requiremax' => '6.0',
+ ),
+ false
+ ),
+ // variations of versions
+ // single OC number
+ array(
+ '4',
+ array(
+ 'require' => '4.0',
+ ),
+ true
+ ),
+ // multiple OC number
+ array(
+ '4.3.1',
+ array(
+ 'require' => '4.3',
+ ),
+ true
+ ),
+ // single app number
+ array(
+ '4',
+ array(
+ 'require' => '4',
+ ),
+ true
+ ),
+ // single app number fail
+ array(
+ '4.3',
+ array(
+ 'require' => '5',
+ ),
+ false
+ ),
+ // complex
+ array(
+ '5.0.0',
+ array(
+ 'require' => '4.5.1',
+ ),
+ true
+ ),
+ // complex fail
+ array(
+ '4.3.1',
+ array(
+ 'require' => '4.3.2',
+ ),
+ false
+ ),
+ // two numbers
+ array(
+ '4.3.1',
+ array(
+ 'require' => '4.4',
+ ),
+ false
+ ),
+ // one number fail
+ array(
+ '4.3.1',
+ array(
+ 'require' => '5',
+ ),
+ false
+ ),
+ // pre-alpha app
+ array(
+ '5.0.3',
+ array(
+ 'require' => '4.93',
+ ),
+ true
+ ),
+ // pre-alpha OC
+ array(
+ '6.90.0.2',
+ array(
+ 'require' => '6.90',
+ ),
+ true
+ ),
+ // pre-alpha OC max
+ array(
+ '6.90.0.2',
+ array(
+ 'requiremax' => '7',
+ ),
+ true
+ ),
+ // expect same major number match
+ array(
+ '5.0.3',
+ array(
+ 'require' => '5',
+ ),
+ true
+ ),
+ // expect same major number match
+ array(
+ '5.0.3',
+ array(
+ 'requiremax' => '5',
+ ),
+ true
+ ),
+ );
}
- public function testIsAppVersionCompatibleShouldFailTwoVersionNumbers(){
- $oc = array(4, 3, 1);
- $app = '4.4';
-
- $this->assertFalse(OC_App::isAppVersionCompatible($oc, $app));
- }
-
-
- public function testIsAppVersionCompatibleShouldWorkForPreAlpha(){
- $oc = array(5, 0, 3);
- $app = '4.93';
-
- $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app));
+ /**
+ * @dataProvider appVersionsProvider
+ */
+ public function testIsAppCompatible($ocVersion, $appInfo, $expectedResult) {
+ $this->assertEquals($expectedResult, OC_App::isAppCompatible($ocVersion, $appInfo));
}
-
- public function testIsAppVersionCompatibleShouldFailOneVersionNumbers(){
- $oc = array(4, 3, 1);
- $app = '5';
-
- $this->assertFalse(OC_App::isAppVersionCompatible($oc, $app));
+ /**
+ * Test that the isAppCompatible method also supports passing an array
+ * as $ocVersion
+ */
+ public function testIsAppCompatibleWithArray() {
+ $ocVersion = array(6);
+ $appInfo = array(
+ 'requiremin' => '6',
+ 'requiremax' => '6',
+ );
+ $this->assertTrue(OC_App::isAppCompatible($ocVersion, $appInfo));
}
/**