mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
introduce dependency analyzer to take care of app dependencies
some more unit tests on xml info parser
This commit is contained in:
parent
f74d568bda
commit
b469e9f6fb
8 changed files with 227 additions and 9 deletions
58
lib/private/app/dependencyanalyzer.php
Normal file
58
lib/private/app/dependencyanalyzer.php
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Müller
|
||||
* @copyright 2014 Thomas Müller deepdiver@owncloud.com
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\App;
|
||||
|
||||
class DependencyAnalyzer {
|
||||
|
||||
/**
|
||||
* @param array $app
|
||||
* @param Platform $system
|
||||
* @param \OCP\IL10N $l
|
||||
*/
|
||||
function __construct(array $app, $system, $l) {
|
||||
$this->system = $system;
|
||||
$this->l = $l;
|
||||
$this->missing = array();
|
||||
$this->dependencies = array();
|
||||
if (array_key_exists('dependencies', $app)) {
|
||||
$this->dependencies = $app['dependencies'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $app
|
||||
* @returns array of missing dependencies
|
||||
*/
|
||||
public function analyze() {
|
||||
$this->analysePhpVersion();
|
||||
return $this->missing;
|
||||
}
|
||||
|
||||
private function analysePhpVersion() {
|
||||
if (!array_key_exists('php', $this->dependencies)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (array_key_exists('min-version', $this->dependencies['php'])) {
|
||||
$minVersion = $this->dependencies['php']['min-version'];
|
||||
if (version_compare($this->system->getPhpVersion(), $minVersion, '<')) {
|
||||
$this->missing[] = (string)$this->l->t('PHP %s or higher is required.', $minVersion);
|
||||
}
|
||||
}
|
||||
if (array_key_exists('max-version', $this->dependencies['php'])) {
|
||||
$maxVersion = $this->dependencies['php']['max-version'];
|
||||
if (version_compare($this->system->getPhpVersion(), $maxVersion, '>')) {
|
||||
$this->missing[] = (string)$this->l->t('PHP with a version less then %s is required.', $maxVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ class InfoParser {
|
|||
$array['types'] = array();
|
||||
}
|
||||
|
||||
if (array_key_exists('documentation', $array)) {
|
||||
if (array_key_exists('documentation', $array) && is_array($array['documentation'])) {
|
||||
foreach ($array['documentation'] as $key => $url) {
|
||||
// If it is not an absolute URL we assume it is a key
|
||||
// i.e. admin-ldap will get converted to go.php?to=admin-ldap
|
||||
|
|
@ -78,7 +78,9 @@ class InfoParser {
|
|||
if (array_key_exists('types', $array)) {
|
||||
foreach ($array['types'] as $type => $v) {
|
||||
unset($array['types'][$type]);
|
||||
$array['types'][] = $type;
|
||||
if (is_string($type)) {
|
||||
$array['types'][] = $type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
17
lib/private/app/platform.php
Normal file
17
lib/private/app/platform.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Müller
|
||||
* @copyright 2014 Thomas Müller deepdiver@owncloud.com
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\App;
|
||||
|
||||
class Platform {
|
||||
public function getPhpVersion() {
|
||||
return phpversion();
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
namespace OC\Settings\Controller;
|
||||
|
||||
use OC\App\DependencyAnalyzer;
|
||||
use OC\App\Platform;
|
||||
use \OCP\AppFramework\Controller;
|
||||
use OCP\IRequest;
|
||||
use OCP\IL10N;
|
||||
|
|
@ -123,10 +125,16 @@ class AppSettingsController extends Controller {
|
|||
}
|
||||
$app['groups'] = $groups;
|
||||
$app['canUnInstall'] = !$app['active'] && $app['removable'];
|
||||
|
||||
// analyse dependencies
|
||||
$dependencyAnalyzer = new DependencyAnalyzer($app, new Platform(), $this->l10n);
|
||||
$missing = $dependencyAnalyzer->analyze();
|
||||
|
||||
$app['canInstall'] = empty($missing);
|
||||
$app['missingDependencies'] = $missing;
|
||||
return $app;
|
||||
}, $apps);
|
||||
|
||||
return array('apps' => $apps, 'status' => 'success');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
24
tests/data/app/strange-types-info.json
Normal file
24
tests/data/app/strange-types-info.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"info": [],
|
||||
"remote": [],
|
||||
"public": [],
|
||||
"id": "files_encryption",
|
||||
"name": "Server-side Encryption",
|
||||
"description": "\n\tThis application encrypts all files accessed by ownCloud at rest, wherever they are stored. As an example, with this application enabled, external cloud based Amazon S3 storage will be encrypted, protecting this data on storage outside of the control of the Admin. When this application is enabled for the first time, all files are encrypted as users log in and are prompted for their password. The recommended recovery key option enables recovery of files in case the key is lost. \n\tNote that this app encrypts all files that are touched by ownCloud, so external storage providers and applications such as SharePoint will see new files encrypted when they are accessed. Encryption is based on AES 128 or 256 bit keys. More information is available in the Encryption documentation \n\t",
|
||||
"licence": "AGPL",
|
||||
"author": "Sam Tuke, Bjoern Schiessle, Florin Peter",
|
||||
"requiremin": "4",
|
||||
"shipped": "true",
|
||||
"documentation": {
|
||||
"user": "https://docs.example.com/server/go.php?to=user-encryption",
|
||||
"admin": "https://docs.example.com/server/go.php?to=admin-encryption"
|
||||
},
|
||||
"rememberlogin": "false",
|
||||
"types": [],
|
||||
"ocsid": "166047",
|
||||
"dependencies": {
|
||||
"php": {
|
||||
"min-version": 5.4
|
||||
}
|
||||
}
|
||||
}
|
||||
23
tests/data/app/strange-types-info.xml
Normal file
23
tests/data/app/strange-types-info.xml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0"?>
|
||||
<info>
|
||||
<id>files_encryption</id>
|
||||
<name>Server-side Encryption</name>
|
||||
<description>
|
||||
This application encrypts all files accessed by ownCloud at rest, wherever they are stored. As an example, with this application enabled, external cloud based Amazon S3 storage will be encrypted, protecting this data on storage outside of the control of the Admin. When this application is enabled for the first time, all files are encrypted as users log in and are prompted for their password. The recommended recovery key option enables recovery of files in case the key is lost.
|
||||
Note that this app encrypts all files that are touched by ownCloud, so external storage providers and applications such as SharePoint will see new files encrypted when they are accessed. Encryption is based on AES 128 or 256 bit keys. More information is available in the Encryption documentation
|
||||
</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Sam Tuke, Bjoern Schiessle, Florin Peter</author>
|
||||
<requiremin>4</requiremin>
|
||||
<shipped>true</shipped>
|
||||
<documentation>
|
||||
<user>user-encryption</user>
|
||||
<admin>admin-encryption</admin>
|
||||
</documentation>
|
||||
<rememberlogin>false</rememberlogin>
|
||||
<types><base/></types>
|
||||
<ocsid>166047</ocsid>
|
||||
<dependencies>
|
||||
<php><min-version>5.4</min-version></php>
|
||||
</dependencies>
|
||||
</info>
|
||||
77
tests/lib/app/dependencyanalyzer.php
Normal file
77
tests/lib/app/dependencyanalyzer.php
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @author Thomas Müller
|
||||
* @copyright 2014 Thomas Müller deepdiver@owncloud.com
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace Test\App;
|
||||
|
||||
use OC;
|
||||
use OC\App\Platform;
|
||||
use OCP\IL10N;
|
||||
|
||||
class DependencyAnalyzer extends \PHPUnit_Framework_TestCase {
|
||||
|
||||
/**
|
||||
* @var Platform
|
||||
*/
|
||||
private $platformMock;
|
||||
|
||||
/**
|
||||
* @var IL10N
|
||||
*/
|
||||
private $l10nMock;
|
||||
|
||||
public function setUp() {
|
||||
$this->platformMock = $this->getMockBuilder('\OC\App\Platform')
|
||||
->getMock();
|
||||
$this->platformMock->expects($this->any())
|
||||
->method('getPhpVersion')
|
||||
->will( $this->returnValue('5.4.3'));
|
||||
$this->l10nMock = $this->getMockBuilder('\OCP\IL10N')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->l10nMock->expects($this->any())
|
||||
->method('t')
|
||||
->will($this->returnCallback(function($text, $parameters = array()) {
|
||||
return vsprintf($text, $parameters);
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providesPhpVersion
|
||||
*/
|
||||
public function testPhpVersion($expectedMissing, $minVersion, $maxVersion) {
|
||||
$app = array(
|
||||
'dependencies' => array(
|
||||
'php' => array()
|
||||
)
|
||||
);
|
||||
if (!is_null($minVersion)) {
|
||||
$app['dependencies']['php']['min-version'] = $minVersion;
|
||||
}
|
||||
if (!is_null($maxVersion)) {
|
||||
$app['dependencies']['php']['max-version'] = $maxVersion;
|
||||
}
|
||||
$analyser = new \OC\App\DependencyAnalyzer($app, $this->platformMock, $this->l10nMock);
|
||||
$missing = $analyser->analyze();
|
||||
|
||||
$this->assertTrue(is_array($missing));
|
||||
$this->assertEquals(count($expectedMissing), count($missing));
|
||||
$this->assertEquals($expectedMissing, $missing);
|
||||
}
|
||||
|
||||
function providesPhpVersion() {
|
||||
return array(
|
||||
array(array(), null, null),
|
||||
array(array(), '5.4', null),
|
||||
array(array(), null, '5.5'),
|
||||
array(array(), '5.4', '5.5'),
|
||||
array(array('PHP 5.4.4 or higher is required.'), '5.4.4', null),
|
||||
array(array('PHP with a version less then 5.4.2 is required.'), null, '5.4.2'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -39,15 +39,24 @@ class InfoParser extends \PHPUnit_Framework_TestCase {
|
|||
$this->parser = new \OC\App\InfoParser($httpHelper, $urlGenerator);
|
||||
}
|
||||
|
||||
public function testParsingValidXml() {
|
||||
$expectedData = json_decode(file_get_contents(OC::$SERVERROOT.'/tests/data/app/expected-info.json'), true);
|
||||
$data = $this->parser->parse(OC::$SERVERROOT.'/tests/data/app/valid-info.xml');
|
||||
/**
|
||||
* @dataProvider providesInfoXml
|
||||
*/
|
||||
public function testParsingValidXml($expectedJson, $xmlFile) {
|
||||
$expectedData = null;
|
||||
if (!is_null($expectedJson)) {
|
||||
$expectedData = json_decode(file_get_contents(OC::$SERVERROOT . "/tests/data/app/$expectedJson"), true);
|
||||
}
|
||||
$data = $this->parser->parse(OC::$SERVERROOT. "/tests/data/app/$xmlFile");
|
||||
|
||||
$this->assertEquals($expectedData, $data);
|
||||
}
|
||||
|
||||
public function testParsingInvalidXml() {
|
||||
$data = $this->parser->parse(OC::$SERVERROOT.'/tests/data/app/invalid-info.xml');
|
||||
$this->assertNull($data);
|
||||
function providesInfoXml() {
|
||||
return array(
|
||||
array('expected-info.json', 'valid-info.xml'),
|
||||
array('strange-types-info.json', 'strange-types-info.xml'),
|
||||
array(null, 'invalid-info.xml'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue