mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-21 16:22:20 +02:00
N°9134 Validate extension codes before installation and refine progress message styling (#909)
* N°9134 Validate extension codes before installation and refine progress message styling * Add test for compile failure when extension code is missing
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -699,14 +699,10 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#progress_content {
|
#progress_content *:not(.message) + .message {
|
||||||
min-height: 200px;
|
|
||||||
overflow: auto;
|
|
||||||
text-align: center;
|
|
||||||
*:not(.message) + .message {
|
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#fresh_content{
|
#fresh_content{
|
||||||
border: 0;
|
border: 0;
|
||||||
min-height: 300px;
|
min-height: 300px;
|
||||||
|
|||||||
@@ -1467,6 +1467,14 @@ class RunTimeEnvironment
|
|||||||
// Removed modules are stored as static for FindModules()
|
// Removed modules are stored as static for FindModules()
|
||||||
$oExtensionsMap->DeclareExtensionAsRemoved($aRemovedExtensionCodes);
|
$oExtensionsMap->DeclareExtensionAsRemoved($aRemovedExtensionCodes);
|
||||||
|
|
||||||
|
// Check that all the extensions have a code
|
||||||
|
foreach ($oExtensionsMap->GetAllExtensions() as $oExtension) {
|
||||||
|
if (empty($oExtension->sCode)) {
|
||||||
|
$sExtensionLabel = !empty($oExtension->sLabel) ? $oExtension->sLabel : $oExtension->sSourceDir;
|
||||||
|
throw new Exception(sprintf('Extension "%s" cannot be installed: Missing extension code', $sExtensionLabel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$oFactory = new ModelFactory($aDirsToScan);
|
$oFactory = new ModelFactory($aDirsToScan);
|
||||||
|
|
||||||
$oDictModule = new MFDictModule('dictionaries', 'iTop Dictionaries', APPROOT.'dictionaries');
|
$oDictModule = new MFDictModule('dictionaries', 'iTop Dictionaries', APPROOT.'dictionaries');
|
||||||
@@ -1566,7 +1574,7 @@ class RunTimeEnvironment
|
|||||||
|
|
||||||
public function ExitMaintenanceMode(): void
|
public function ExitMaintenanceMode(): void
|
||||||
{
|
{
|
||||||
if (SetupUtils::IsInMaintenanceMode()){
|
if (SetupUtils::IsInMaintenanceMode()) {
|
||||||
SetupUtils::ExitMaintenanceMode();
|
SetupUtils::ExitMaintenanceMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Test\UnitTest\Setup;
|
||||||
|
|
||||||
|
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||||
|
use Exception;
|
||||||
|
use RunTimeEnvironment;
|
||||||
|
|
||||||
|
class RunTimeEnvironmentTest extends ItopTestCase
|
||||||
|
{
|
||||||
|
private ?string $sFixtureRootDir = null;
|
||||||
|
private ?string $sBuildDirToCleanup = null;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->RequireOnceItopFile('/setup/runtimeenv.class.inc.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown(): void
|
||||||
|
{
|
||||||
|
if (($this->sFixtureRootDir !== null) && is_dir($this->sFixtureRootDir)) {
|
||||||
|
self::RecurseRmdir($this->sFixtureRootDir);
|
||||||
|
}
|
||||||
|
if (($this->sBuildDirToCleanup !== null) && is_dir($this->sBuildDirToCleanup)) {
|
||||||
|
self::RecurseRmdir($this->sBuildDirToCleanup);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDoCompileThrowsWhenExtensionCodeIsMissing(): void
|
||||||
|
{
|
||||||
|
[$sToken, $sSourceDirRelative, $sExtensionsDirRelative] = $this->CreateFixtureContext('runtimeenv-missing-code-');
|
||||||
|
|
||||||
|
$sInvalidExtensionXml = <<<XML
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<extension format="1.0">
|
||||||
|
<label>Broken extension</label>
|
||||||
|
<description>Test extension without code</description>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<more_info_url></more_info_url>
|
||||||
|
</extension>
|
||||||
|
XML;
|
||||||
|
file_put_contents(APPROOT.$sExtensionsDirRelative.'/extension.xml', $sInvalidExtensionXml);
|
||||||
|
$oRunTimeEnvironment = $this->CreateRunTimeEnvironment($sToken);
|
||||||
|
|
||||||
|
$this->expectException(Exception::class);
|
||||||
|
$this->expectExceptionMessage('Extension "Broken extension" cannot be installed: Missing extension code');
|
||||||
|
|
||||||
|
$oRunTimeEnvironment->DoCompile([], [], $sSourceDirRelative, $sExtensionsDirRelative, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDoCompileThrowsWhenExtensionCodeAndLabelAreMissing(): void
|
||||||
|
{
|
||||||
|
[$sToken, $sSourceDirRelative, $sExtensionsDirRelative] = $this->CreateFixtureContext('runtimeenv-missing-label-');
|
||||||
|
|
||||||
|
$sInvalidExtensionXml = <<<XML
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<extension format="1.0">
|
||||||
|
<description>Test extension without code and label</description>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<more_info_url></more_info_url>
|
||||||
|
</extension>
|
||||||
|
XML;
|
||||||
|
$sExtensionsDirAbsolute = APPROOT.$sExtensionsDirRelative;
|
||||||
|
file_put_contents($sExtensionsDirAbsolute.'/extension.xml', $sInvalidExtensionXml);
|
||||||
|
$oRunTimeEnvironment = $this->CreateRunTimeEnvironment($sToken);
|
||||||
|
|
||||||
|
$this->expectException(Exception::class);
|
||||||
|
$this->expectExceptionMessage(sprintf('Extension "%s" cannot be installed: Missing extension code', $sExtensionsDirAbsolute));
|
||||||
|
|
||||||
|
$oRunTimeEnvironment->DoCompile([], [], $sSourceDirRelative, $sExtensionsDirRelative, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function CreateFixtureContext(string $sTokenPrefix): array
|
||||||
|
{
|
||||||
|
$sToken = str_replace('.', '-', uniqid($sTokenPrefix, true));
|
||||||
|
$this->sFixtureRootDir = APPROOT.'data/'.$sToken;
|
||||||
|
$sSourceDirRelative = 'data/'.$sToken.'/source';
|
||||||
|
$sExtensionsDirRelative = 'data/'.$sToken.'/extensions';
|
||||||
|
|
||||||
|
mkdir(APPROOT.$sSourceDirRelative, 0777, true);
|
||||||
|
mkdir(APPROOT.$sExtensionsDirRelative, 0777, true);
|
||||||
|
|
||||||
|
return [$sToken, $sSourceDirRelative, $sExtensionsDirRelative];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function CreateRunTimeEnvironment(string $sToken): RunTimeEnvironment
|
||||||
|
{
|
||||||
|
$oRunTimeEnvironment = new RunTimeEnvironment('test-'.$sToken, false);
|
||||||
|
$this->sBuildDirToCleanup = $oRunTimeEnvironment->GetBuildDir();
|
||||||
|
|
||||||
|
return $oRunTimeEnvironment;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user