Merge branch 'support/3.2' into develop

This commit is contained in:
odain
2025-11-07 20:33:14 +01:00
1837 changed files with 33034 additions and 34549 deletions

View File

@@ -18,11 +18,9 @@ class DBBackupDataTest extends ItopDataTestCase
$sTmpDir = sys_get_temp_dir().'/testPrepareFilesToBackup-'.time();
$oBackup = new DBBackup(MetaModel::GetConfig());
MetaModel::GetConfig()->SetModuleSetting('itop-backup', 'extra_files', array_keys($aExtraFiles));
foreach($aExtraFiles as $sExtraFile => $bExists)
{
if ($bExists)
{
foreach ($aExtraFiles as $sExtraFile => $bExists) {
if ($bExists) {
@mkdir(dirname(APPROOT.'/'.$sExtraFile), 0755, true);
file_put_contents(APPROOT.'/'.$sExtraFile, 'Hello World!');
}
@@ -32,29 +30,29 @@ class DBBackupDataTest extends ItopDataTestCase
if ($bUnsafeFileException) {
$this->expectExceptionMessage("Backup: Aborting, resource '$sExtraFile'. Considered as UNSAFE because not inside the iTop directory.");
}
$aFiles = $this->InvokeNonPublicMethod('DBBackup', 'PrepareFilesToBackup', $oBackup, [APPROOT . '/conf/'.$this->GetTestEnvironment().'/config-itop.php', $sTmpDir, true]);
$aFiles = $this->InvokeNonPublicMethod('DBBackup', 'PrepareFilesToBackup', $oBackup, [APPROOT.'/conf/'.$this->GetTestEnvironment().'/config-itop.php', $sTmpDir, true]);
SetupUtils::rrmdir($sTmpDir);
$aExpectedFiles = [
$sTmpDir . '/config-itop.php',
$sTmpDir.'/config-itop.php',
];
if (file_exists(APPROOT.'/data/'.$this->GetTestEnvironment().'.delta.xml')) {
$aExpectedFiles[] = $sTmpDir . '/' . 'delta.xml';
$aExpectedFiles[] = $sTmpDir.'/'.'delta.xml';
}
if (file_exists(APPROOT.'/data/'.$this->GetTestEnvironment().'-modules')) {
$aExpectedFiles[] = $sTmpDir . '/' . $this->GetTestEnvironment() . '-modules';
$aExpectedFiles[] = $sTmpDir.'/'.$this->GetTestEnvironment().'-modules';
}
foreach ($aExtraFiles as $sRelFile => $bExists) {
if ($bExists) {
$aExpectedFiles[] = $sTmpDir . '/' . $sRelFile;
$aExpectedFiles[] = $sTmpDir.'/'.$sRelFile;
}
}
} finally {
// Cleanup
foreach ($aExtraFiles as $sExtraFile => $bExists) {
if ($bExists) {
unlink(APPROOT . '/' . $sExtraFile);
$folderPath = dirname(APPROOT . '/' . $sExtraFile);
if (is_dir($folderPath) && count(glob($folderPath . '/*')) === 0) {
unlink(APPROOT.'/'.$sExtraFile);
$folderPath = dirname(APPROOT.'/'.$sExtraFile);
if (is_dir($folderPath) && count(glob($folderPath.'/*')) === 0) {
rmdir($folderPath);
}
}
@@ -65,8 +63,8 @@ class DBBackupDataTest extends ItopDataTestCase
sort($aExpectedFiles);
$this->assertEquals($aExpectedFiles, $aFiles);
}
function prepareFilesToBackupProvider()
public function prepareFilesToBackupProvider()
{
return [
'no_extra_file' => ['aExtraFiles' => [], false],
@@ -80,43 +78,39 @@ class DBBackupDataTest extends ItopDataTestCase
/**
* @dataProvider restoreListExtraFilesProvider
*/
function testRestoreListExtraFiles($aFilesToCreate, $aExpectedRelativeExtraFiles)
public function testRestoreListExtraFiles($aFilesToCreate, $aExpectedRelativeExtraFiles)
{
require_once(APPROOT.'/env-production/itop-backup/dbrestore.class.inc.php');
$sTmpDir = sys_get_temp_dir().'/testRestoreListExtraFiles-'.time();
foreach($aFilesToCreate as $sRelativeName)
{
foreach ($aFilesToCreate as $sRelativeName) {
$sDir = $sTmpDir.'/'.dirname($sRelativeName);
if(!is_dir($sDir))
{
if (!is_dir($sDir)) {
mkdir($sDir, 0755, true);
}
file_put_contents($sTmpDir.'/'.$sRelativeName, 'Hello world.');
}
$aExpectedExtraFiles = [];
foreach($aExpectedRelativeExtraFiles as $sRelativeName)
{
foreach ($aExpectedRelativeExtraFiles as $sRelativeName) {
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$sRelativeName = str_replace('/', '\\', $sRelativeName);
$aExpectedExtraFiles[$sTmpDir.'\\'.$sRelativeName] = APPROOT.'\\'.$sRelativeName;
}
else {
} else {
$aExpectedExtraFiles[$sTmpDir.'/'.$sRelativeName] = APPROOT.'/'.$sRelativeName;
}
}
$oRestore = new DBRestore(MetaModel::GetConfig());
$aExtraFiles = $this->InvokeNonPublicMethod('DBRestore', 'ListExtraFiles', $oRestore, [$sTmpDir]);
asort($aExtraFiles);
asort($aExpectedExtraFiles);
$this->assertEquals($aExpectedExtraFiles, $aExtraFiles);
SetupUtils::rrmdir($sTmpDir);
}
function restoreListExtraFilesProvider()
public function restoreListExtraFilesProvider()
{
return [
'no extra file' => ['aFilesToCreate' => ['config-itop.php', 'itop-dump.sql', 'delta.xml'], 'aExpectedExtraFiles' => []],
@@ -124,5 +118,5 @@ class DBBackupDataTest extends ItopDataTestCase
'one extra file' => ['aFilesToCreate' => ['config-itop.php', 'itop-dump.sql', 'delta.xml', 'production-modules/test/module.test.php', 'collectors/ldap/conf/params.local.xml'], 'aExpectedExtraFiles' => ['collectors/ldap/conf/params.local.xml']],
];
}
}

View File

@@ -62,12 +62,9 @@ class DBBackupTest extends ItopTestCase
$sCliArgsMinCfg = DBBackup::GetMysqlCliTlsOptions($oConfigToTest);
// depending on the MySQL vendor, we would have `--ssl` or `--ssl-mode=REQUIRED`
if (CMDBSource::IsSslModeDBVersion())
{
if (CMDBSource::IsSslModeDBVersion()) {
$this->assertStringStartsWith(' --ssl-mode=REQUIRED', $sCliArgsMinCfg);
}
else
{
} else {
$this->assertStringStartsWith(' --ssl', $sCliArgsMinCfg);
$this->assertStringNotContainsString('--ssl-mode', $sCliArgsMinCfg);
}
@@ -90,12 +87,9 @@ class DBBackupTest extends ItopTestCase
$sCliArgsCapathCfg = DBBackup::GetMysqlCliTlsOptions($oConfigToTest);
// depending on the MySQL vendor, we would have `--ssl` or `--ssl-mode=VERIFY_CA`
if (CMDBSource::IsSslModeDBVersion())
{
if (CMDBSource::IsSslModeDBVersion()) {
$this->assertStringStartsWith(' --ssl-mode=VERIFY_CA', $sCliArgsCapathCfg);
}
else
{
} else {
$this->assertStringStartsWith(' --ssl', $sCliArgsCapathCfg);
$this->assertStringNotContainsString('--ssl-mode', $sCliArgsCapathCfg);
@@ -113,11 +107,11 @@ class DBBackupTest extends ItopTestCase
$sExpectedPortCliOption = '';
} else {
$sEscapedPortValue = \DBBackup::EscapeShellArg($iExpectedPortValue);
$sExpectedPortCliOption = ' --port=' . $sEscapedPortValue;
$sExpectedPortCliOption = ' --port='.$sEscapedPortValue;
}
$sActualCliOptions = $this->InvokeNonPublicStaticMethod(DBBackup::class, 'GetMysqlCliPortAndTransportOptions', [$sDbHost, $iPort]);
$this->assertEquals($sExpectedPortCliOption . $sExpectedProtocolCliOption, $sActualCliOptions);
$this->assertEquals($sExpectedPortCliOption.$sExpectedProtocolCliOption, $sActualCliOptions);
}
public function GetMysqlCliPortAndTransportOptionsProvider()

View File

@@ -11,10 +11,11 @@ use utils;
/**
* @covers \MFCompiler::UseLatestPrecompiledFile
*/
class MFCompilerTest extends ItopTestCase {
class MFCompilerTest extends ItopTestCase
{
/** @var array */
private static $aFoldersToCleanup;
/** @var array */
private static $aRessources;
@@ -23,7 +24,8 @@ class MFCompilerTest extends ItopTestCase {
private $sTmpDir;
public function setUp(): void {
public function setUp(): void
{
parent::setUp();
$this->RequireOnceItopFile('setup/compiler.class.inc.php');
$this->RequireOnceItopFile('setup/modelfactory.class.inc.php');
@@ -33,26 +35,34 @@ class MFCompilerTest extends ItopTestCase {
$this->oMFCompiler = new SubMFCompiler($this->createMock(\ModelFactory::class), '');
}
public function tearDown(): void {
public function tearDown(): void
{
parent::tearDown();
$this->RecurseRmdir($this->sTmpDir);
}
public static function Init(){
if (!is_null(self::$aFoldersToCleanup)){
public static function Init()
{
if (!is_null(self::$aFoldersToCleanup)) {
return;
}
clearstatcache();
$sPrefix = 'scsstest_';
$sAppRootForProvider = dirname(dirname(dirname(dirname(dirname(__FILE__))))) . DIRECTORY_SEPARATOR;
$sTempTargetDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'UseLatestPrecompiledFileProvider';
$sExtensionTargetDir = $sAppRootForProvider . 'extensions/UseLatestPrecompiledFileProvider';
$sSourceDir = $sAppRootForProvider . 'datamodels' . DIRECTORY_SEPARATOR . '2.x';
$sDatamodel2xTargetDir = $sSourceDir . DIRECTORY_SEPARATOR . '/UseLatestPrecompiledFileProvider';
$sAppRootForProvider = dirname(dirname(dirname(dirname(dirname(__FILE__))))).DIRECTORY_SEPARATOR;
$sTempTargetDir = sys_get_temp_dir().DIRECTORY_SEPARATOR.'UseLatestPrecompiledFileProvider';
$sExtensionTargetDir = $sAppRootForProvider.'extensions/UseLatestPrecompiledFileProvider';
$sSourceDir = $sAppRootForProvider.'datamodels'.DIRECTORY_SEPARATOR.'2.x';
$sDatamodel2xTargetDir = $sSourceDir.DIRECTORY_SEPARATOR.'/UseLatestPrecompiledFileProvider';
if (!is_dir($sTempTargetDir)) mkdir($sTempTargetDir);
if (!is_dir($sExtensionTargetDir)) @mkdir($sExtensionTargetDir);
if (!is_dir($sDatamodel2xTargetDir)) @mkdir($sDatamodel2xTargetDir);
if (!is_dir($sTempTargetDir)) {
mkdir($sTempTargetDir);
}
if (!is_dir($sExtensionTargetDir)) {
@mkdir($sExtensionTargetDir);
}
if (!is_dir($sDatamodel2xTargetDir)) {
@mkdir($sDatamodel2xTargetDir);
}
self::$aFoldersToCleanup = [ $sTempTargetDir, $sExtensionTargetDir, $sDatamodel2xTargetDir ];
@@ -60,27 +70,27 @@ class MFCompilerTest extends ItopTestCase {
$iTimeStart = time() - 100;
self::$aRessources['sPostCompilation1'] = tempnam($sTempTargetDir, $sPrefix);
touch(self::$aRessources['sPostCompilation1'], $iTimeStart+=2);
touch(self::$aRessources['sPostCompilation1'], $iTimeStart += 2);
//datamodel XML file in extension folder
self::$aRessources['sPrecompiledInExtensionFile1'] = tempnam($sExtensionTargetDir, $sPrefix);
touch(self::$aRessources['sPrecompiledInExtensionFile1'], $iTimeStart+=2);
self::$aRessources['sPrecompiledInExtensionFileUri1'] = "UseLatestPrecompiledFileProvider" . DIRECTORY_SEPARATOR . basename(self::$aRessources['sPrecompiledInExtensionFile1']);
touch(self::$aRessources['sPrecompiledInExtensionFile1'], $iTimeStart += 2);
self::$aRessources['sPrecompiledInExtensionFileUri1'] = "UseLatestPrecompiledFileProvider".DIRECTORY_SEPARATOR.basename(self::$aRessources['sPrecompiledInExtensionFile1']);
//datamodel XML file in source dir /datamodels/2.x folder
self::$aRessources['sPrecompiledInDataModelXXFile1'] = tempnam($sDatamodel2xTargetDir, $sPrefix);
touch(self::$aRessources['sPrecompiledInDataModelXXFile1'], $iTimeStart+=2);
self::$aRessources['sPrecompiledInDataModelXXFileUri1'] = "UseLatestPrecompiledFileProvider" . DIRECTORY_SEPARATOR . basename(self::$aRessources['sPrecompiledInDataModelXXFile1']);
touch(self::$aRessources['sPrecompiledInDataModelXXFile1'], $iTimeStart += 2);
self::$aRessources['sPrecompiledInDataModelXXFileUri1'] = "UseLatestPrecompiledFileProvider".DIRECTORY_SEPARATOR.basename(self::$aRessources['sPrecompiledInDataModelXXFile1']);
//generate ressources from a previous setup: called postcompiled
self::$aRessources['sPostCompilation2'] = tempnam($sTempTargetDir, $sPrefix);
touch(self::$aRessources['sPostCompilation2'], $iTimeStart+=2);
touch(self::$aRessources['sPostCompilation2'], $iTimeStart += 2);
//simulate copy of /data/models.2.x or extensions ressources during setup in a temp directory
self::$aRessources['sCopiedExtensionFile1'] = $sTempTargetDir . DIRECTORY_SEPARATOR . basename(self::$aRessources['sPrecompiledInExtensionFile1']);
self::$aRessources['sCopiedExtensionFile1'] = $sTempTargetDir.DIRECTORY_SEPARATOR.basename(self::$aRessources['sPrecompiledInExtensionFile1']);
copy(self::$aRessources['sPrecompiledInExtensionFile1'], self::$aRessources['sCopiedExtensionFile1']);
self::$aRessources['sCopiedDataModelXXFile1'] = $sTempTargetDir . DIRECTORY_SEPARATOR . basename(self::$aRessources['sPrecompiledInDataModelXXFile1']);
self::$aRessources['sCopiedDataModelXXFile1'] = $sTempTargetDir.DIRECTORY_SEPARATOR.basename(self::$aRessources['sPrecompiledInDataModelXXFile1']);
copy(self::$aRessources['sPrecompiledInDataModelXXFile1'], self::$aRessources['sCopiedDataModelXXFile1']);
self::$aRessources['sMissingFile'] = tempnam($sTempTargetDir, $sPrefix);
@@ -95,13 +105,13 @@ class MFCompilerTest extends ItopTestCase {
public static function tearDownAfterClass(): void
{
if (is_null(self::$aFoldersToCleanup)){
if (is_null(self::$aFoldersToCleanup)) {
return;
}
foreach (self::$aFoldersToCleanup as $sFolder){
if (is_dir($sFolder)){
foreach (glob("$sFolder/**") as $sFile){
foreach (self::$aFoldersToCleanup as $sFolder) {
if (is_dir($sFolder)) {
foreach (glob("$sFolder/**") as $sFile) {
unlink($sFile);
}
rmdir($sFolder);
@@ -118,40 +128,44 @@ class MFCompilerTest extends ItopTestCase {
* @param string $sThemeDir
* @param ?string $sExpectedReturn
*/
public function testUseLatestPrecompiledFile(string $sTempTargetDir, string $sPrecompiledFileUri, string $sPostCompilationLatestPrecompiledFile, string $sThemeDir, ?string $sExpectedReturn, bool $bDisableThemePrecompilationViaConf = false){
public function testUseLatestPrecompiledFile(string $sTempTargetDir, string $sPrecompiledFileUri, string $sPostCompilationLatestPrecompiledFile, string $sThemeDir, ?string $sExpectedReturn, bool $bDisableThemePrecompilationViaConf = false)
{
// Enable or disable precompilation depending on the test case
utils::GetConfig()->Set('theme.enable_precompilation', !$bDisableThemePrecompilationViaConf);
$sRes = $this->oMFCompiler->UseLatestPrecompiledFile($sTempTargetDir, $sPrecompiledFileUri, $sPostCompilationLatestPrecompiledFile, $sThemeDir);
$this->assertEquals($sExpectedReturn, $sRes);
}
public function UseLatestPrecompiledFileProvider(){
public function UseLatestPrecompiledFileProvider()
{
self::init();
return [
'no precompiled file at all' => $this->BuildProviderUseCaseArray('', self::$aRessources['sMissingFile'], null),
'deactivate precompilation via conf' => $this->BuildProviderUseCaseArray('', self::$aRessources['sPostCompilation1'], null, true),
'no precompiled file configured in precompiled_stylesheet XM section' => $this->BuildProviderUseCaseArray('', self::$aRessources['sPostCompilation1'], self::$aRessources['sPostCompilation1']),
'missing precompiled file in precompiled_stylesheet section' => $this->BuildProviderUseCaseArray(self::$aRessources['sMissingFile'], self::$aRessources['sPostCompilation1'], self::$aRessources['sPostCompilation1'] ),
'no precompiled file generated in previous setup in /data/precompiled_styles' => $this->BuildProviderUseCaseArray(self::$aRessources['sPrecompiledInExtensionFileUri1'], self::$aRessources['sMissingFile'], self::$aRessources['sCopiedExtensionFile1'] ),
'(extensions) XML precompiled_stylesheet file older than last post setup generated file in /data/precompiled_styles' => $this->BuildProviderUseCaseArray(self::$aRessources['sPrecompiledInExtensionFileUri1'], self::$aRessources['sPostCompilation2'], self::$aRessources['sPostCompilation2'] ),
'last post setup generated file in /data/precompiled_styles older than (extensions) XML precompiled_stylesheet file' => $this->BuildProviderUseCaseArray(self::$aRessources['sPrecompiledInExtensionFileUri1'], self::$aRessources['sPostCompilation1'], self::$aRessources['sCopiedExtensionFile1'] ),
'(datamodels/N.x) XML precompiled_stylesheet file older than last post setup generated file in /data/precompiled_styles' => $this->BuildProviderUseCaseArray(self::$aRessources['sPrecompiledInDataModelXXFileUri1'], self::$aRessources['sPostCompilation2'], self::$aRessources['sPostCompilation2'] ),
'(datamodels/N.x) last post setup generated file in /data/precompiled_styles older than (extensions) XML precompiled_stylesheet file' => $this->BuildProviderUseCaseArray(self::$aRessources['sPrecompiledInDataModelXXFileUri1'], self::$aRessources['sPostCompilation1'], self::$aRessources['sCopiedDataModelXXFile1'] ),
'missing precompiled file in precompiled_stylesheet section' => $this->BuildProviderUseCaseArray(self::$aRessources['sMissingFile'], self::$aRessources['sPostCompilation1'], self::$aRessources['sPostCompilation1']),
'no precompiled file generated in previous setup in /data/precompiled_styles' => $this->BuildProviderUseCaseArray(self::$aRessources['sPrecompiledInExtensionFileUri1'], self::$aRessources['sMissingFile'], self::$aRessources['sCopiedExtensionFile1']),
'(extensions) XML precompiled_stylesheet file older than last post setup generated file in /data/precompiled_styles' => $this->BuildProviderUseCaseArray(self::$aRessources['sPrecompiledInExtensionFileUri1'], self::$aRessources['sPostCompilation2'], self::$aRessources['sPostCompilation2']),
'last post setup generated file in /data/precompiled_styles older than (extensions) XML precompiled_stylesheet file' => $this->BuildProviderUseCaseArray(self::$aRessources['sPrecompiledInExtensionFileUri1'], self::$aRessources['sPostCompilation1'], self::$aRessources['sCopiedExtensionFile1']),
'(datamodels/N.x) XML precompiled_stylesheet file older than last post setup generated file in /data/precompiled_styles' => $this->BuildProviderUseCaseArray(self::$aRessources['sPrecompiledInDataModelXXFileUri1'], self::$aRessources['sPostCompilation2'], self::$aRessources['sPostCompilation2']),
'(datamodels/N.x) last post setup generated file in /data/precompiled_styles older than (extensions) XML precompiled_stylesheet file' => $this->BuildProviderUseCaseArray(self::$aRessources['sPrecompiledInDataModelXXFileUri1'], self::$aRessources['sPostCompilation1'], self::$aRessources['sCopiedDataModelXXFile1']),
];
}
private function BuildProviderUseCaseArray(string $sPrecompiledFileUri, string $sPostCompilationLatestPrecompiledFile, $sExpectedReturn, $bDisableThemePrecompilationViaConf = false) : array{
private function BuildProviderUseCaseArray(string $sPrecompiledFileUri, string $sPostCompilationLatestPrecompiledFile, $sExpectedReturn, $bDisableThemePrecompilationViaConf = false): array
{
return [
"sTempTargetDir" => sys_get_temp_dir(),
"sPrecompiledFileUri" => $sPrecompiledFileUri,
"sPostCompilationLatestPrecompiledFile" => $sPostCompilationLatestPrecompiledFile,
"sThemeDir" => "test",
"sExpectedReturn" => $sExpectedReturn,
"bDisableThemePrecompilationViaConf" => $bDisableThemePrecompilationViaConf
"bDisableThemePrecompilationViaConf" => $bDisableThemePrecompilationViaConf,
];
}
public function testCompileThemes(){
public function testCompileThemes()
{
$sFullmoonThemeCompiledFolder = $this->sTmpDir.DIRECTORY_SEPARATOR.'branding'.DIRECTORY_SEPARATOR.'themes'.DIRECTORY_SEPARATOR.'fullmoon'.DIRECTORY_SEPARATOR;
$sXmlDataCustoFilePath = realpath(__DIR__.'/ressources/datamodels/datamodel-branding.xml');
@@ -164,12 +178,11 @@ class MFCompilerTest extends ItopTestCase {
$this->RecurseMkdir($sFullmoonThemeCompiledFolder);
file_put_contents($sFullmoonThemeCompiledFolder.'main.css', "");
$aImportsPaths = array(
$aImportsPaths = [
APPROOT.'css/',
APPROOT.'css/backoffice/main.scss',
$this->sTmpDir.'//',
);
];
$aThemeParameters = [
'variables' => [
@@ -189,8 +202,7 @@ class MFCompilerTest extends ItopTestCase {
$oThemeHandlerService = $this->createMock(\ThemeHandlerService::class);
$oThemeHandlerService->expects($this->exactly(1))
->method("CompileTheme")
->with("fullmoon", true, $this->oMFCompiler->GetCompilationTimeStamp(), $aThemeParameters, $aImportsPaths, $this->sTmpDir . '/');
->with("fullmoon", true, $this->oMFCompiler->GetCompilationTimeStamp(), $aThemeParameters, $aImportsPaths, $this->sTmpDir.'/');
//CompileTheme($sThemeId, $bSetup = false, $sSetupCompilationTimestamp="", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null)
MFCompiler::SetThemeHandlerService($oThemeHandlerService);

View File

@@ -10,7 +10,6 @@ use MFElement;
use ModelFactory;
use PHPUnit\Framework\ExpectationFailedException;
/**
* Class ModelFactoryTest
*
@@ -681,8 +680,7 @@ class ModelFactoryTest extends ItopTestCase
$oDeltaRoot = $oDocument->firstChild;
try {
$oFactory->LoadDelta($oDeltaRoot, $oFactoryDocument);
}
catch (\Exception $e) {
} catch (\Exception $e) {
$this->assertNull($sExpectedXML, 'LoadDelta() should not have failed with exception: '.$e->getMessage());
$this->assertEquals($sExpectedXMLOrErrorMessage, $e->getMessage());
return;
@@ -2224,7 +2222,9 @@ XML
*/
public function AlterationAPIsProvider()
{
define('CASE_NO_FLAG', <<<XML
define(
'CASE_NO_FLAG',
<<<XML
<root_tag>
<container_tag>
<target_tag/>
@@ -2232,7 +2232,9 @@ XML
</root_tag>
XML
);
define('CASE_ABOVE_A_FLAG', <<<XML
define(
'CASE_ABOVE_A_FLAG',
<<<XML
<root_tag>
<container_tag>
<target_tag>
@@ -2242,7 +2244,9 @@ XML
</root_tag>
XML
);
define('CASE_IN_A_DEFINITION', <<<XML
define(
'CASE_IN_A_DEFINITION',
<<<XML
<root_tag>
<container_tag _alteration="added">
<target_tag>
@@ -2252,7 +2256,9 @@ XML
</root_tag>
XML
);
define('CASE_FLAG_ON_TARGET_define', <<<XML
define(
'CASE_FLAG_ON_TARGET_define',
<<<XML
<root_tag>
<container_tag>
<target_tag _alteration="added"/>
@@ -2260,7 +2266,9 @@ XML
</root_tag>
XML
);
define('CASE_FLAG_ON_TARGET_redefine', <<<XML
define(
'CASE_FLAG_ON_TARGET_redefine',
<<<XML
<root_tag>
<container_tag>
<target_tag _alteration="replaced"/>
@@ -2268,7 +2276,9 @@ XML
</root_tag>
XML
);
define('CASE_FLAG_ON_TARGET_needed', <<<XML
define(
'CASE_FLAG_ON_TARGET_needed',
<<<XML
<root_tag>
<container_tag>
<target_tag _alteration="needed"/>
@@ -2276,7 +2286,9 @@ XML
</root_tag>
XML
);
define('CASE_FLAG_ON_TARGET_forced', <<<XML
define(
'CASE_FLAG_ON_TARGET_forced',
<<<XML
<root_tag>
<container_tag>
<target_tag _alteration="forced"/>
@@ -2284,7 +2296,9 @@ XML
</root_tag>
XML
);
define('CASE_FLAG_ON_TARGET_removed', <<<XML
define(
'CASE_FLAG_ON_TARGET_removed',
<<<XML
<root_tag>
<container_tag>
<target_tag _alteration="removed"/>
@@ -2292,7 +2306,9 @@ XML
</root_tag>
XML
);
define('CASE_FLAG_ON_TARGET_old_id', <<<XML
define(
'CASE_FLAG_ON_TARGET_old_id',
<<<XML
<root_tag>
<container_tag>
<target_tag id="fraise" _old_id="tagada"/>
@@ -2300,7 +2316,9 @@ XML
</root_tag>
XML
);
define('CASE_MISSING_TARGET', <<<XML
define(
'CASE_MISSING_TARGET',
<<<XML
<root_tag>
<container_tag/>
</root_tag>
@@ -3088,7 +3106,7 @@ XML
$oNode->setAttribute('id', $sClassName);
$oNode->setAttribute('_created_in', $sModuleName);
$oDoc = $oNode->ownerDocument;
foreach (array('properties', 'fields', 'methods', 'presentation') as $sElementName) {
foreach (['properties', 'fields', 'methods', 'presentation'] as $sElementName) {
$oElement = $oDoc->createElement($sElementName);
$oNode->appendChild($oElement);
}
@@ -3203,7 +3221,6 @@ XML
$this->assertCount(0, $aDiff);
}
/**
* @test
* @dataProvider AddClassProvider
@@ -3445,11 +3462,9 @@ XML
$oFactory->LoadDelta($oDeltaRoot, $oFactoryDocument, ModelFactory::LOAD_DELTA_MODE_LAX);
$this->assertNotNull($sExpectedXML, "LoadDelta(lax) should have failed with exception: $sExpectedXMLInLaxMode");
$this->AssertEqualModels($sExpectedXML, $oFactory, 'LoadDelta(lax) did not produce the expected result');
}
catch (ExpectationFailedException $e) {
} catch (ExpectationFailedException $e) {
throw $e;
}
catch (\Exception $e) {
} catch (\Exception $e) {
$this->assertNull($sExpectedXML, 'LoadDelta(lax) should not have failed with exception: '.$e->getMessage());
$this->assertEquals($sExpectedXMLInLaxMode, $e->getMessage());
}
@@ -3470,11 +3485,9 @@ XML
$oFactory->LoadDelta($oDeltaRoot, $oFactoryDocument, ModelFactory::LOAD_DELTA_MODE_STRICT);
$this->assertNotNull($sExpectedXML, "LoadDelta(lax) should have failed with exception: $sExpectedXMLInStrictMode");
$this->AssertEqualModels($sExpectedXML, $oFactory, 'LoadDelta(strict) did not produce the expected result');
}
catch (ExpectationFailedException $e) {
} catch (ExpectationFailedException $e) {
throw $e;
}
catch (\Exception $e) {
} catch (\Exception $e) {
$this->assertNull($sExpectedXML, 'LoadDelta(strict) should not have failed with exception: '.$e->getMessage());
$this->assertEquals($sExpectedXMLInStrictMode, $e->getMessage());
}
@@ -3694,10 +3707,12 @@ XML
];
}
public function testDictEntryIsIntegratedIntoMF() {
public function testDictEntryIsIntegratedIntoMF()
{
$oFactory = new ModelFactory([]);
$sLanguageCode = 'RU URSS';
$oFactory->IntegrateDictEntriesIntoXML($sLanguageCode,
$oFactory->IntegrateDictEntriesIntoXML(
$sLanguageCode,
[
'english_description' => 'Russian',
'localized_description' => 'URSS',
@@ -3708,7 +3723,8 @@ XML
);
$this->assertDictEntryUniqueAndEquals($oFactory, $sLanguageCode, 'key1', 'Label 1', 'New entry in new language should be present in XML');
$oFactory->IntegrateDictEntriesIntoXML($sLanguageCode,
$oFactory->IntegrateDictEntriesIntoXML(
$sLanguageCode,
[
'english_description' => 'Russian',
'localized_description' => 'URSS',

View File

@@ -7,7 +7,6 @@ use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
use MetaModel;
use ModuleInstallerAPI;
/**
* Class ModuleInstallerAPITest
*
@@ -38,7 +37,6 @@ class ModuleInstallerAPITest extends ItopDataTestCase
parent::tearDown();
}
/**
* @param string $sTable
* @param string $sAttCode
@@ -52,7 +50,7 @@ class ModuleInstallerAPITest extends ItopDataTestCase
$oOrigAttDef = MetaModel::GetAttributeDef($sTable, $sAttCode);
$sOrigColName = array_key_first($oOrigAttDef->GetSQLColumns());
return array($sOrigTable, $sOrigColName);
return [$sOrigTable, $sOrigColName];
}
/**
@@ -68,8 +66,8 @@ class ModuleInstallerAPITest extends ItopDataTestCase
{
// Create a table with the same structure as the original table(s)
// - Create a SQL query to get all the ids from the original tables
if(is_array($aOrigTables)) {
$sOrigDataQuery = implode(" UNION ", array_map(fn($sTable) => "SELECT id FROM `{$sTable}`", $aOrigTables));
if (is_array($aOrigTables)) {
$sOrigDataQuery = implode(" UNION ", array_map(fn ($sTable) => "SELECT id FROM `{$sTable}`", $aOrigTables));
}
CMDBSource::Query(
@@ -179,18 +177,18 @@ SQL
// Create 2 objects, so we know the ids for one of each class
$oPerson = $this->createObject('Person', ['first_name' => 'John', 'name' => 'Doe', 'org_id' => 1]);
$oTeam = $this->createObject('Team', ['name' => 'La tcheam', 'org_id' => 1]);
// Info from the original tables (we don't need real data, just the ids)
$sOrigClass = "Person";
[$sOrigTable, $sOrigColName] = $this->GetInfoFromTable($sOrigClass, "first_name");
$sOrigClass2 = "Team";
[$sOrigTable2, $sOrigColName2] = $this->GetInfoFromTable($sOrigClass2, "friendlyname");
// Info for the destination table
$sDstTable = static::$sWorkTable3;
$sDstColName = "existing_column";
// Insert our ids into similar work tables
// Then insert data into their respective columns to be moved
$sOrigWorkTable = static::$sWorkTable;
@@ -202,7 +200,7 @@ SQL
WHERE 1
SQL
);
$sOrigWorkTable2 = static::$sWorkTable2;
$this->CreateDestinationTable($sOrigWorkTable2, [$sOrigTable2], $sDstColName);
CMDBSource::Query(
@@ -212,23 +210,23 @@ SQL
WHERE 1
SQL
);
// Create our destination table
$this->CreateDestinationTable($sDstTable, [$sOrigTable, $sOrigTable2], $sDstColName);
// Try to move data from both tables into the same column
ModuleInstallerAPI::MoveColumnInDB($sOrigWorkTable, $sDstColName, $sDstTable, $sDstColName, true);
ModuleInstallerAPI::MoveColumnInDB($sOrigWorkTable2, $sDstColName, $sDstTable, $sDstColName, true);
// Check if data was actually moved by getting the value from the destination table for the ids we stored earlier
$iPersonId = $oPerson->GetKey();
$iPersonId = $oPerson->GetKey();
$sFromTable1Data = CMDBSource::QueryToScalar(
<<<SQL
SELECT `{$sDstColName}` FROM `{$sDstTable}` WHERE `id` = {$iPersonId}
LIMIT 1
SQL
);
$iTeamId = $oTeam->GetKey();
$sFromTable2Data = CMDBSource::QueryToScalar(
<<<SQL
@@ -236,7 +234,7 @@ SQL
LIMIT 1
SQL
);
$this->assertEquals('from table 1', $sFromTable1Data, "Data was not moved as expected");
$this->assertEquals('from table 2', $sFromTable2Data, "Data was not moved as expected");
}

View File

@@ -1,12 +1,10 @@
<?php
namespace Combodo\iTop\Test\UnitTest\Setup;
use Combodo\iTop\Test\UnitTest\ItopTestCase;
use SetupUtils;
/**
* Class SetupUtilsTest
*
@@ -17,10 +15,10 @@ use SetupUtils;
*/
class SetupUtilsTest extends ItopTestCase
{
const ERROR = 0;
const WARNING = 1;
const INFO = 2;
const TRACE = 3; // for log purposes : replace old SetupLog::Log calls
public const ERROR = 0;
public const WARNING = 1;
public const INFO = 2;
public const TRACE = 3; // for log purposes : replace old SetupLog::Log calls
protected function setUp(): void
{
@@ -33,7 +31,8 @@ class SetupUtilsTest extends ItopTestCase
/**
* @dataProvider CheckGraphvizProvider
*/
public function testCheckGraphviz($sScriptPath, $iSeverity, $sLabel){
public function testCheckGraphviz($sScriptPath, $iSeverity, $sLabel)
{
/** @var \CheckResult $oCheck */
$aCheck = SetupUtils::CheckGraphviz($sScriptPath);
$bLabelFound = false;
@@ -46,7 +45,8 @@ class SetupUtilsTest extends ItopTestCase
$this->assertTrue($bLabelFound, "label '$sLabel' not found");
}
public function CheckGraphvizProvider() {
public function CheckGraphvizProvider()
{
if (substr(PHP_OS, 0, 3) === 'WIN') {
return [];
}
@@ -139,8 +139,11 @@ class SetupUtilsTest extends ItopTestCase
$this->assertEquals($sPHPMinVersion, $oComposerConfig->config->platform->php, "SetupUtils::PHP_MIN_VERSION ($sPHPMinVersion) is not equals composer.json > config > platform ($sComposerPlatformPhp)");
// Require/PHP must be set to the supported PHP versions range in order to keep our package constraints up-to-date
$sComposerRequirePhp = $oComposerConfig->require->php;
$this->assertEquals(">=$sPHPMinVersion <$sPHPNotValidatedVersion", $oComposerConfig->require->php,
"SetupUtils::PHP_MIN_VERSION ($sPHPMinVersion) and SetupUtils::PHP_NOT_VALIDATED_VERSION ($sPHPNotValidatedVersion) is not equals composer.json > require > php ($sComposerRequirePhp)");
$this->assertEquals(
">=$sPHPMinVersion <$sPHPNotValidatedVersion",
$oComposerConfig->require->php,
"SetupUtils::PHP_MIN_VERSION ($sPHPMinVersion) and SetupUtils::PHP_NOT_VALIDATED_VERSION ($sPHPNotValidatedVersion) is not equals composer.json > require > php ($sComposerRequirePhp)"
);
}
}
}

View File

@@ -3,12 +3,15 @@
/**
* Class SubMFCompiler: used to call a protected method for testing purpose
*/
class SubMFCompiler extends MFCompiler {
public function CompileThemes($oBrandingNode, $sTempTargetDir) {
class SubMFCompiler extends MFCompiler
{
public function CompileThemes($oBrandingNode, $sTempTargetDir)
{
return parent::CompileThemes($oBrandingNode, $sTempTargetDir);
}
public function GetCompilationTimeStamp(){
public function GetCompilationTimeStamp()
{
return $this->sCompilationTimeStamp;
}
}
}

View File

@@ -9,7 +9,6 @@ use iTopDesignFormat;
use ReflectionException;
use utils;
/**
* @covers iTopDesignFormat
*
@@ -18,7 +17,7 @@ use utils;
*/
class iTopDesignFormatTest extends ItopTestCase
{
const SAMPLES_DIR_PATH = 'Convert-samples/';
public const SAMPLES_DIR_PATH = 'Convert-samples/';
protected function setUp(): void
{
@@ -61,8 +60,11 @@ class iTopDesignFormatTest extends ItopTestCase
$bResult = $oInputDesignFormat->Convert($sTargetVersion);
$aErrors = $oInputDesignFormat->GetErrors();
$this->assertCount($iExpectedErrors, $aErrors,
'errors in input format: '.var_export($aErrors, true));
$this->assertCount(
$iExpectedErrors,
$aErrors,
'errors in input format: '.var_export($aErrors, true)
);
if ($iExpectedErrors > 0) {
$this->assertFalse($bResult);
$this->assertEquals($sFirstErrorMessage, $aErrors[0]);
@@ -111,8 +113,10 @@ class iTopDesignFormatTest extends ItopTestCase
$oExpectedDesignFormat->GetITopDesignNode()->setAttribute('version', $sExpectedPreviousVersion);
$bConversionResult = $oExpectedDesignFormat->Convert($sExpectedVersion);
$this->assertTrue($bConversionResult,
'There were conversion errors: '.var_export($oExpectedDesignFormat->GetErrors(), true));
$this->assertTrue(
$bConversionResult,
'There were conversion errors: '.var_export($oExpectedDesignFormat->GetErrors(), true)
);
/** @noinspection PhpRedundantOptionalArgumentInspection We REALLY want those options so specifying it anyway */
$sConvertedXml = $oExpectedDesignFormat->GetXmlAsString(null, true, false);
@@ -246,24 +250,24 @@ class iTopDesignFormatTest extends ItopTestCase
public function MoveNodeProvider()
{
return array(
'From deleted to deleted' => array('from_deleted_to_deleted'),
'From deleted to in definition' => array('from_deleted_to_in-definition'),
'From deleted to not in definition' => array('from_deleted_to_not-in-definition'),
'From in definition to deleted' => array('from_in-definition_to_deleted'),
'From in definition to in definition' => array('from_in-definition_to_in-definition'),
'From in definition to not in definition' => array('from_in-definition_to_not-in-definition'),
'From not in definition to deleted' => array('from_not-in-definition_to_deleted'),
'From not in definition to in definition' => array('from_not-in-definition_to_in-definition'),
'From not in definition to not in definition' => array('from_not-in-definition_to_not-in-definition'),
);
return [
'From deleted to deleted' => ['from_deleted_to_deleted'],
'From deleted to in definition' => ['from_deleted_to_in-definition'],
'From deleted to not in definition' => ['from_deleted_to_not-in-definition'],
'From in definition to deleted' => ['from_in-definition_to_deleted'],
'From in definition to in definition' => ['from_in-definition_to_in-definition'],
'From in definition to not in definition' => ['from_in-definition_to_not-in-definition'],
'From not in definition to deleted' => ['from_not-in-definition_to_deleted'],
'From not in definition to in definition' => ['from_not-in-definition_to_in-definition'],
'From not in definition to not in definition' => ['from_not-in-definition_to_not-in-definition'],
];
}
private function GetFileContent($sFileName)
{
$sCurrentPath = __DIR__;
return file_get_contents($sCurrentPath . DIRECTORY_SEPARATOR . $sFileName . '.xml');
return file_get_contents($sCurrentPath.DIRECTORY_SEPARATOR.$sFileName.'.xml');
}
/**
@@ -288,7 +292,7 @@ class iTopDesignFormatTest extends ItopTestCase
continue;
}
if (false === \array_key_exists($aXmlVersionData[$sXmlVersionPointingToKey], iTopDesignFormat::$aVersions)) {
$aAVersionsErrors[] = "$sXmlVersion version: invalid value for `$sXmlVersionPointingToKey` key ! Value=" . $aXmlVersionData[$sXmlVersionPointingToKey];
$aAVersionsErrors[] = "$sXmlVersion version: invalid value for `$sXmlVersionPointingToKey` key ! Value=".$aXmlVersionData[$sXmlVersionPointingToKey];
}
}
@@ -310,6 +314,6 @@ class iTopDesignFormatTest extends ItopTestCase
}
}
$this->assertCount(0, $aAVersionsErrors, 'There were errors detected in iTopDesignFormat::$aVersions : ' . var_export($aAVersionsErrors, true));
$this->assertCount(0, $aAVersionsErrors, 'There were errors detected in iTopDesignFormat::$aVersions : '.var_export($aAVersionsErrors, true));
}
}
}

View File

@@ -9,24 +9,29 @@ use RunTimeEnvironment;
use InstallationFileService;
use ModuleDiscovery;
class InstallationFileServiceTest extends ItopTestCase {
protected function setUp(): void {
class InstallationFileServiceTest extends ItopTestCase
{
protected function setUp(): void
{
parent::setUp();
$this->RequireOnceItopFile('/setup/unattended-install/InstallationFileService.php');
ModuleDiscovery::ResetCache();
}
protected function tearDown(): void {
protected function tearDown(): void
{
parent::tearDown();
}
private function GetInstallationPath() : string {
return realpath(__DIR__ . '/resources/installation.xml');
private function GetInstallationPath(): string
{
return realpath(__DIR__.'/resources/installation.xml');
}
private function GetModuleData($sCategory, bool $bIsVisible, bool $bIsAutoSelect, bool $bProductionModulesInRootDir=false) : array {
$sRootDir = str_replace('//', '/', $bProductionModulesInRootDir ? $this->GetAppRoot() .'data/production-modules/' : '');
private function GetModuleData($sCategory, bool $bIsVisible, bool $bIsAutoSelect, bool $bProductionModulesInRootDir = false): array
{
$sRootDir = str_replace('//', '/', $bProductionModulesInRootDir ? $this->GetAppRoot().'data/production-modules/' : '');
var_dump($sRootDir);
@@ -36,14 +41,15 @@ class InstallationFileServiceTest extends ItopTestCase {
'root_dir' => $sRootDir,
];
if ($bIsAutoSelect){
if ($bIsAutoSelect) {
$aModuleData['auto_select'] = true;
}
return $aModuleData;
}
public function ProcessDefaultModulesProvider() {
public function ProcessDefaultModulesProvider()
{
return [
'root module' => [
'aAllFoundModules' => [
@@ -75,28 +81,28 @@ class InstallationFileServiceTest extends ItopTestCase {
],
'autoselect/invisible/in-root-dir module' => [
'aAllFoundModules' => [
'autoselect-only' => $this->GetModuleData('mycategory', false, true , true),
'autoselect-only' => $this->GetModuleData('mycategory', false, true, true),
],
'aExpectedSelectedModules' => [],
'aExpectedAutoSelectModules' => ['autoselect-only'],
],
'visible/authent module' => [
'aAllFoundModules' => [
'authent-module' => $this->GetModuleData('authentication', true, false , false),
'authent-module' => $this->GetModuleData('authentication', true, false, false),
],
'aExpectedSelectedModules' => ['authent-module'],
'aExpectedAutoSelectModules' => [],
],
'invisible module' => [
'aAllFoundModules' => [
'visible-module' => $this->GetModuleData('mycategory', false, false , false),
'visible-module' => $this->GetModuleData('mycategory', false, false, false),
],
'aExpectedSelectedModules' => ['visible-module'],
'aExpectedAutoSelectModules' => [],
],
'in-root-dir module' => [
'aAllFoundModules' => [
'in-root-dir-module' => $this->GetModuleData('mycategory', true, false , true),
'in-root-dir-module' => $this->GetModuleData('mycategory', true, false, true),
],
'aExpectedSelectedModules' => ['in-root-dir-module'],
'aExpectedAutoSelectModules' => [],
@@ -106,7 +112,8 @@ class InstallationFileServiceTest extends ItopTestCase {
/**
* @dataProvider ProcessDefaultModulesProvider
*/
public function testProcessDefaultModules(array $aAllFoundModules, array $aExpectedSelectedModules, array $aExpectedAutoSelectModules) {
public function testProcessDefaultModules(array $aAllFoundModules, array $aExpectedSelectedModules, array $aExpectedAutoSelectModules)
{
$oInstallationFileService = new InstallationFileService('', 'production', [], true);
$oProductionEnv = $this->createMock(RunTimeEnvironment::class);
@@ -128,7 +135,8 @@ class InstallationFileServiceTest extends ItopTestCase {
$this->assertEquals($aExpectedAutoSelectModules, $aAutoSelectModules);
}
public function ProcessInstallationChoicesProvider() {
public function ProcessInstallationChoicesProvider()
{
return [
'all checked' => [ true ],
'only defaut + mandatory' => [ false ],
@@ -138,7 +146,8 @@ class InstallationFileServiceTest extends ItopTestCase {
/**
* @dataProvider ProcessInstallationChoicesProvider
*/
public function testProcessInstallationChoices($bInstallationOptionalChoicesChecked) {
public function testProcessInstallationChoices($bInstallationOptionalChoicesChecked)
{
$sPath = $this->GetInstallationPath();
$oInstallationFileService = new InstallationFileService($sPath, 'production', [], $bInstallationOptionalChoicesChecked);
$oProductionEnv = $this->createMock(RunTimeEnvironment::class);
@@ -176,12 +185,12 @@ class InstallationFileServiceTest extends ItopTestCase {
'itop-service-mgmt-provider',
];
if ($bInstallationOptionalChoicesChecked){
$aExpectedModules []= "itop-problem-mgmt";
$aExpectedModules []= "itop-knownerror-mgmt";
if ($bInstallationOptionalChoicesChecked) {
$aExpectedModules [] = "itop-problem-mgmt";
$aExpectedModules [] = "itop-knownerror-mgmt";
} else {
$aExpectedUnselectedModules []= "itop-problem-mgmt";
$aExpectedUnselectedModules []= "itop-knownerror-mgmt";
$aExpectedUnselectedModules [] = "itop-problem-mgmt";
$aExpectedUnselectedModules [] = "itop-knownerror-mgmt";
}
sort($aExpectedModules);
@@ -199,18 +208,18 @@ class InstallationFileServiceTest extends ItopTestCase {
sort($aGetAfterComputationSelectedExtensions);
$aExpectedExtensions = [
'itop-change-mgmt-simple',
'itop-config-mgmt-core',
'itop-config-mgmt-datacenter',
'itop-config-mgmt-end-user',
'itop-config-mgmt-storage',
'itop-config-mgmt-virtualization',
'itop-service-mgmt-enterprise',
'itop-ticket-mgmt-simple-ticket',
'itop-config-mgmt-core',
'itop-config-mgmt-datacenter',
'itop-config-mgmt-end-user',
'itop-config-mgmt-storage',
'itop-config-mgmt-virtualization',
'itop-service-mgmt-enterprise',
'itop-ticket-mgmt-simple-ticket',
'itop-ticket-mgmt-simple-ticket-enhanced-portal',
];
if ($bInstallationOptionalChoicesChecked){
$aExpectedExtensions []= "itop-problem-mgmt";
$aExpectedExtensions []= 'itop-kown-error-mgmt';
if ($bInstallationOptionalChoicesChecked) {
$aExpectedExtensions [] = "itop-problem-mgmt";
$aExpectedExtensions [] = 'itop-kown-error-mgmt';
}
sort($aExpectedExtensions);
$this->assertEquals($aExpectedExtensions, $aGetAfterComputationSelectedExtensions);
@@ -221,7 +230,8 @@ class InstallationFileServiceTest extends ItopTestCase {
/**
* @dataProvider ItilExtensionProvider
*/
public function testProcessInstallationChoicesWithItilChoices(array $aSelectedExtensions, bool $bKnownMgtSelected, bool $bCoreMgtSelected) {
public function testProcessInstallationChoicesWithItilChoices(array $aSelectedExtensions, bool $bKnownMgtSelected, bool $bCoreMgtSelected)
{
$sPath = $this->GetInstallationPath();
$oInstallationFileService = new InstallationFileService($sPath, 'production', $aSelectedExtensions, false);
$oProductionEnv = $this->createMock(RunTimeEnvironment::class);
@@ -253,8 +263,8 @@ class InstallationFileServiceTest extends ItopTestCase {
"itop-portal-base",
"itop-change-mgmt-itil",
];
if ($bKnownMgtSelected){
$aExpectedInstallationModules []= "itop-knownerror-mgmt";
if ($bKnownMgtSelected) {
$aExpectedInstallationModules [] = "itop-knownerror-mgmt";
}
sort($aExpectedInstallationModules);
@@ -269,8 +279,8 @@ class InstallationFileServiceTest extends ItopTestCase {
'itop-request-mgmt',
'itop-service-mgmt-provider',
];
if (!$bKnownMgtSelected){
$aExpectedUnselectedModules[]='itop-knownerror-mgmt';
if (!$bKnownMgtSelected) {
$aExpectedUnselectedModules[] = 'itop-knownerror-mgmt';
}
$aUnselectedModules = array_keys($oInstallationFileService->GetUnSelectedModules());
sort($aExpectedUnselectedModules);
@@ -280,23 +290,26 @@ class InstallationFileServiceTest extends ItopTestCase {
$this->ValidateItilExtensionComputation($oInstallationFileService, $bKnownMgtSelected, $bCoreMgtSelected);
}
public function GetDefaultModulesProvider() {
public function GetDefaultModulesProvider()
{
return [
'check all possible modules' => [true],
'only minimum defaul/mandatory from installation.xml' => [false],
];
}
private function GetMockListOfFoundModules() : array {
$sJsonContent = file_get_contents(realpath(__DIR__ . '/resources/AnalyzeInstallation.json'));
private function GetMockListOfFoundModules(): array
{
$sJsonContent = file_get_contents(realpath(__DIR__.'/resources/AnalyzeInstallation.json'));
$sJsonContent = str_replace('ROOTDIR_TOREPLACE', addslashes(APPROOT), $sJsonContent);
return json_decode($sJsonContent, true);
return json_decode($sJsonContent, true);
}
/**
* @dataProvider GetDefaultModulesProvider
*/
public function testGetAllSelectedModules($bInstallationOptionalChoicesChecked=false) {
public function testGetAllSelectedModules($bInstallationOptionalChoicesChecked = false)
{
$sPath = $this->GetInstallationPath();
$oInstallationFileService = new InstallationFileService($sPath, 'production', [], $bInstallationOptionalChoicesChecked);
@@ -344,9 +357,9 @@ class InstallationFileServiceTest extends ItopTestCase {
'itop-bridge-virtualization-storage',
];
if ($bInstallationOptionalChoicesChecked){
$aExpectedInstallationModules []= "itop-problem-mgmt";
$aExpectedInstallationModules []= "itop-knownerror-mgmt";
if ($bInstallationOptionalChoicesChecked) {
$aExpectedInstallationModules [] = "itop-problem-mgmt";
$aExpectedInstallationModules [] = "itop-knownerror-mgmt";
}
sort($aExpectedInstallationModules);
@@ -358,7 +371,8 @@ class InstallationFileServiceTest extends ItopTestCase {
$this->ValidateNonItilExtensionComputation($oInstallationFileService, $bInstallationOptionalChoicesChecked);
}
private function ValidateNonItilExtensionComputation($oInstallationFileService, bool $bInstallationOptionalChoicesChecked, array $aAdditionalExtensions=[]) {
private function ValidateNonItilExtensionComputation($oInstallationFileService, bool $bInstallationOptionalChoicesChecked, array $aAdditionalExtensions = [])
{
$aGetAfterComputationSelectedExtensions = $oInstallationFileService->GetAfterComputationSelectedExtensions();
sort($aGetAfterComputationSelectedExtensions);
$aExpectedExtensions = array_merge($aAdditionalExtensions, [
@@ -372,15 +386,16 @@ class InstallationFileServiceTest extends ItopTestCase {
'itop-ticket-mgmt-simple-ticket',
'itop-ticket-mgmt-simple-ticket-enhanced-portal',
]);
if ($bInstallationOptionalChoicesChecked){
$aExpectedExtensions []= "itop-problem-mgmt";
$aExpectedExtensions []= 'itop-kown-error-mgmt';
if ($bInstallationOptionalChoicesChecked) {
$aExpectedExtensions [] = "itop-problem-mgmt";
$aExpectedExtensions [] = 'itop-kown-error-mgmt';
}
sort($aExpectedExtensions);
$this->assertEquals($aExpectedExtensions, $aGetAfterComputationSelectedExtensions);
}
private function ValidateItilExtensionComputation($oInstallationFileService, bool $bKnownMgtSelected, bool $bCoreMgtSelected) {
private function ValidateItilExtensionComputation($oInstallationFileService, bool $bKnownMgtSelected, bool $bCoreMgtSelected)
{
$aGetAfterComputationSelectedExtensions = $oInstallationFileService->GetAfterComputationSelectedExtensions();
sort($aGetAfterComputationSelectedExtensions);
$aExpectedExtensions = [
@@ -395,17 +410,18 @@ class InstallationFileServiceTest extends ItopTestCase {
'itop-ticket-mgmt-itil-incident',
'itop-ticket-mgmt-itil-user-request',
];
if ($bCoreMgtSelected){
$aExpectedExtensions []= 'itop-config-mgmt-core';
if ($bCoreMgtSelected) {
$aExpectedExtensions [] = 'itop-config-mgmt-core';
}
if ($bKnownMgtSelected){
$aExpectedExtensions []= 'itop-kown-error-mgmt';
if ($bKnownMgtSelected) {
$aExpectedExtensions [] = 'itop-kown-error-mgmt';
}
sort($aExpectedExtensions);
$this->assertEquals($aExpectedExtensions, $aGetAfterComputationSelectedExtensions);
}
private function GetSelectedItilExtensions(bool $coreExtensionIncluded, bool $bKnownMgtIncluded) : array {
private function GetSelectedItilExtensions(bool $coreExtensionIncluded, bool $bKnownMgtIncluded): array
{
$aExtensions = [
'itop-config-mgmt-datacenter',
'itop-config-mgmt-end-user',
@@ -419,19 +435,20 @@ class InstallationFileServiceTest extends ItopTestCase {
'itop-change-mgmt-itil',
];
if ($coreExtensionIncluded){
$aExtensions[]= 'itop-config-mgmt-core';
if ($coreExtensionIncluded) {
$aExtensions[] = 'itop-config-mgmt-core';
}
if ($bKnownMgtIncluded){
$aExtensions[]= 'itop-kown-error-mgmt';
if ($bKnownMgtIncluded) {
$aExtensions[] = 'itop-kown-error-mgmt';
}
return $aExtensions;
}
public function ItilExtensionProvider() {
public function ItilExtensionProvider()
{
return [
'all itil extensions + INCLUDING known-error-mgt' => [
'aSelectedExtensions' => $this->GetSelectedItilExtensions(true, true),
@@ -459,7 +476,8 @@ class InstallationFileServiceTest extends ItopTestCase {
/**
* @dataProvider ItilExtensionProvider
*/
public function testGetAllSelectedModules_withItilExtensions(array $aSelectedExtensions, bool $bKnownMgtSelected, bool $bCoreMgtSelected) {
public function testGetAllSelectedModules_withItilExtensions(array $aSelectedExtensions, bool $bKnownMgtSelected, bool $bCoreMgtSelected)
{
$sPath = $this->GetInstallationPath();
$oInstallationFileService = new InstallationFileService($sPath, 'production', $aSelectedExtensions);
@@ -509,8 +527,8 @@ class InstallationFileServiceTest extends ItopTestCase {
'itop-sla-computation',
'itop-bridge-virtualization-storage',
];
if ($bKnownMgtSelected){
$aExpectedInstallationModules []= "itop-knownerror-mgmt";
if ($bKnownMgtSelected) {
$aExpectedInstallationModules [] = "itop-knownerror-mgmt";
}
sort($aExpectedInstallationModules);
@@ -520,7 +538,8 @@ class InstallationFileServiceTest extends ItopTestCase {
$this->ValidateItilExtensionComputation($oInstallationFileService, $bKnownMgtSelected, $bCoreMgtSelected);
}
private function CreateItopExtension(string $sSource, string $sCode, array $aModules, array $aMissingDependencies, bool $bIsVisible) : iTopExtension{
private function CreateItopExtension(string $sSource, string $sCode, array $aModules, array $aMissingDependencies, bool $bIsVisible): iTopExtension
{
$oExtension = new iTopExtension();
$oExtension->sCode = $sCode;
$oExtension->sSource = $sSource;
@@ -530,31 +549,32 @@ class InstallationFileServiceTest extends ItopTestCase {
return $oExtension;
}
public function CanChooseUnpackageExtensionProvider() {
public function CanChooseUnpackageExtensionProvider()
{
return [
'extension in SOURCE_REMOTE' => [
'sCode' => "extension-from-designer",
'bInstallationOptionalChoicesChecked' => false,
'sSource' => 'data',
'bExpectedRes' => true
'bExpectedRes' => true,
],
'extension in SOURCE_WIZARD' => [
'sCode' => 'extension-from-package',
'bInstallationOptionalChoicesChecked' => true,
'sSource' => 'datamodels',
'bExpectedRes' => false
'bExpectedRes' => false,
],
'extension in SOURCE_MANUAL + optional OK' => [
'sCode' => 'extension-from-package',
'bInstallationOptionalChoicesChecked' => true,
'sSource' => 'extensions',
'bExpectedRes' => true
'bExpectedRes' => true,
],
'extension in SOURCE_MANUAL + optional NOT OK' => [
'sCode' => 'extension-from-package',
'bInstallationOptionalChoicesChecked' => false,
'sSource' => 'extensions',
'bExpectedRes' => false
'bExpectedRes' => false,
],
];
}
@@ -562,7 +582,8 @@ class InstallationFileServiceTest extends ItopTestCase {
/**
* @dataProvider CanChooseUnpackageExtensionProvider
*/
public function testCanChooseUnpackageExtension(string $sCode, bool $bInstallationOptionalChoicesChecked, string $sSource, bool $bExpectedRes) {
public function testCanChooseUnpackageExtension(string $sCode, bool $bInstallationOptionalChoicesChecked, string $sSource, bool $bExpectedRes)
{
$sPath = $this->GetInstallationPath();
$oInstallationFileService = new InstallationFileService($sPath, 'production', [], $bInstallationOptionalChoicesChecked);
@@ -570,7 +591,8 @@ class InstallationFileServiceTest extends ItopTestCase {
$this->assertEquals($bExpectedRes, $oInstallationFileService->CanChooseUnpackageExtension($oItopExtension));
}
public function ProcessExtensionModulesNotSpecifiedInChoicesProvider() {
public function ProcessExtensionModulesNotSpecifiedInChoicesProvider()
{
return [
'extensions to install OK' => [
'aExtensionData' => [
@@ -583,17 +605,17 @@ class InstallationFileServiceTest extends ItopTestCase {
//'itop-incident-mgmt-itil', //unselected
'combodo-monitoring2',
'itop-attachments', //already selected
]
],
],
'bExtensionCanBeChoosen' => true,
'aMissingDependencies' => [],
'bIsVisible' => true,
'bExpectedAdditionalExtensions' => [
'extension1', 'extension2'
'extension1', 'extension2',
],
'bExpectedAdditionalModules' => [
'combodo-monitoring', 'combodo-monitoring2'
]
'combodo-monitoring', 'combodo-monitoring2',
],
],
'extensions to install cannot be choose,' => [
'aExtensionData' => [
@@ -602,13 +624,13 @@ class InstallationFileServiceTest extends ItopTestCase {
],
'extension2' => [
'combodo-monitoring2',
]
],
],
'bExtensionCanBeChoosen' => false,
'aMissingDependencies' => [],
'bIsVisible' => true,
'bExpectedAdditionalExtensions' => [],
'bExpectedAdditionalModules' => []
'bExpectedAdditionalModules' => [],
],
'extensions to install not visible' => [
'aExtensionData' => [
@@ -617,13 +639,13 @@ class InstallationFileServiceTest extends ItopTestCase {
],
'extension2' => [
'combodo-monitoring2',
]
],
],
'bExtensionCanBeChoosen' => true,
'aMissingDependencies' => [],
'bIsVisible' => false,
'bExpectedAdditionalExtensions' => [],
'bExpectedAdditionalModules' => []
'bExpectedAdditionalModules' => [],
],
'extensions to install with missing dependencies' => [
'aExtensionData' => [
@@ -632,13 +654,13 @@ class InstallationFileServiceTest extends ItopTestCase {
],
'extension2' => [
'combodo-monitoring2',
]
],
],
'bExtensionCanBeChoosen' => true,
'aMissingDependencies' => ['missing-module'],
'bIsVisible' => true,
'bExpectedAdditionalExtensions' => [],
'bExpectedAdditionalModules' => []
'bExpectedAdditionalModules' => [],
],
'extensions to install with unselectable ITIL module' => [
'aExtensionData' => [
@@ -649,13 +671,13 @@ class InstallationFileServiceTest extends ItopTestCase {
'extension2' => [
'itop-incident-mgmt-itil', //unselected
'combodo-monitoring2',
]
],
],
'bExtensionCanBeChoosen' => true,
'aMissingDependencies' => [],
'bIsVisible' => true,
'bExpectedAdditionalExtensions' => [],
'bExpectedAdditionalModules' => []
'bExpectedAdditionalModules' => [],
],
'extensions already processed' => [
'aExtensionData' => [
@@ -669,7 +691,7 @@ class InstallationFileServiceTest extends ItopTestCase {
'bExpectedAdditionalExtensions' => [
],
'bExpectedAdditionalModules' => [
]
],
],
];
}
@@ -677,8 +699,14 @@ class InstallationFileServiceTest extends ItopTestCase {
/**
* @dataProvider ProcessExtensionModulesNotSpecifiedInChoicesProvider
*/
public function testProcessExtensionModulesNotSpecifiedInChoices(array $aExtensionData, bool $bExtensionCanBeChoosen,
array $aMissingDependencies, bool $bIsVisible, array $bExpectedAdditionalExtensions, array $bExpectedAdditionalModules) {
public function testProcessExtensionModulesNotSpecifiedInChoices(
array $aExtensionData,
bool $bExtensionCanBeChoosen,
array $aMissingDependencies,
bool $bIsVisible,
array $bExpectedAdditionalExtensions,
array $bExpectedAdditionalModules
) {
$sPath = $this->GetInstallationPath();
$oInstallationFileService = new InstallationFileService($sPath, 'production', [], true);
@@ -692,8 +720,8 @@ class InstallationFileServiceTest extends ItopTestCase {
$aItopExtensionMap = [];
$sSource = $bExtensionCanBeChoosen ? iTopExtension::SOURCE_REMOTE : iTopExtension::SOURCE_WIZARD;
foreach ($aExtensionData as $sExtensionCode => $aModules){
$aItopExtensionMap[]= $this->CreateItopExtension($sSource, $sExtensionCode, $aModules, $aMissingDependencies, $bIsVisible);
foreach ($aExtensionData as $sExtensionCode => $aModules) {
$aItopExtensionMap[] = $this->CreateItopExtension($sSource, $sExtensionCode, $aModules, $aMissingDependencies, $bIsVisible);
}
$oItopExtensionsMap->expects($this->once())
->method('GetAllExtensions')
@@ -742,5 +770,4 @@ class InstallationFileServiceTest extends ItopTestCase {
$this->ValidateNonItilExtensionComputation($oInstallationFileService, true, $bExpectedAdditionalExtensions);
}
}

View File

@@ -6,10 +6,10 @@ use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
class UnattendedInstallTest extends ItopDataTestCase
{
protected function setUp(): void
{
parent::setUp();
}
protected function setUp(): void
{
parent::setUp();
}
protected function tearDown(): void
{
parent::tearDown();
@@ -17,15 +17,16 @@ class UnattendedInstallTest extends ItopDataTestCase
'web.config',
'.htaccess',
];
foreach ($aFiles as $sFile){
foreach ($aFiles as $sFile) {
$sPath = APPROOT."setup/unattended-install/$sFile";
if (is_file("$sPath.back")){
if (is_file("$sPath.back")) {
rename("$sPath.back", $sPath);
}
}
}
private function callUnattendedFromHttp() : string {
private function callUnattendedFromHttp(): string
{
$ch = curl_init();
$sUrl = \MetaModel::GetConfig()->Get('app_root_url');
@@ -38,18 +39,19 @@ class UnattendedInstallTest extends ItopDataTestCase
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$sJson = curl_exec($ch);
curl_close ($ch);
curl_close($ch);
return $sJson;
}
public function testCallUnattendedInstallFromHttp(){
public function testCallUnattendedInstallFromHttp()
{
$sJson = $this->callUnattendedFromHttp();
if (false !== strpos($sJson, "403 Forbidden")){
if (false !== strpos($sJson, "403 Forbidden")) {
//.htaccess / webconfig effect
$aFiles = [
'web.config',
'.htaccess',
];
foreach ($aFiles as $sFile){
foreach ($aFiles as $sFile) {
$sPath = APPROOT."setup/unattended-install/$sFile";
if (is_file("$sPath")) {
rename($sPath, "$sPath.back");
@@ -62,19 +64,20 @@ class UnattendedInstallTest extends ItopDataTestCase
$this->assertEquals("Mode CLI only", $sJson, "even without HTTP protection, script should NOT be called directly by HTTP");
}
public function testCallUnattendedInstallFromCLI() {
public function testCallUnattendedInstallFromCLI()
{
$sCliPath = realpath(APPROOT."/setup/unattended-install/unattended-install.php");
exec(sprintf("%s %s", PHP_BINARY, $sCliPath), $aOutput, $iCode);
$sOutput = implode('\n', $aOutput);
var_dump($sOutput);
$this->assertStringContainsString("Missing mandatory argument `--param-file`", $sOutput);
if (DIRECTORY_SEPARATOR === '\\') {
// Windows
$this->assertEquals(-1, $iCode);
} else {
// Linux
$this->assertEquals(255, $iCode);
}
if (DIRECTORY_SEPARATOR === '\\') {
// Windows
$this->assertEquals(-1, $iCode);
} else {
// Linux
$this->assertEquals(255, $iCode);
}
}
}