Merge remote-tracking branch 'origin/support/2.7' into support/3.0

# Conflicts:
#	tests/manual-visual-tests/Backoffice/RenderAllUiBlocks.php
#	tests/php-unit-tests/ItopDataTestCase.php
#	tests/php-unit-tests/ItopTestCase.php
#	tests/php-unit-tests/integration-tests/dictionaries-test/fr.dictionary.itop.core.KO.wrong_php
#	tests/php-unit-tests/integration-tests/dictionaries-test/fr.dictionary.itop.core.OK.php
#	tests/php-unit-tests/integration-tests/iTopModulesPhpVersionChecklistTest.php
#	tests/php-unit-tests/integration-tests/iTopXmlVersionChecklistTest.php
#	tests/php-unit-tests/phpunit.xml.dist
#	tests/php-unit-tests/unitary-tests/application/SCSSCompilationTest.php
#	tests/php-unit-tests/unitary-tests/application/Session/SessionTest.php
#	tests/php-unit-tests/unitary-tests/application/ThemeHandlerTest.php
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/DO_NOT_CHANGE.css-variables.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/DO_NOT_CHANGE.light-grey.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/README.md
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/_included_file3.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/cross_reference1.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/cross_reference2.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/feature1/_feature1.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/included_file1.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/included_scss/included_file2.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/included_scss/included_file4.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/multi_imports.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/shortcut.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/shortcut2.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/simple_import.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/simple_import2.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/typography.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css/ui-lightness/DO_NOT_CHANGE.jqueryui.scss
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/css/ui-lightness/images/ui-icons_1c94c4_256x240.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/css/ui-lightness/images/ui-icons_222222_256x240.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/css/ui-lightness/images/ui-icons_E87C1E_256x240.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/css/ui-lightness/images/ui-icons_F26522_256x240.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/css/ui-lightness/images/ui-icons_ffd27a_256x240.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/css/ui-lightness/images/ui-icons_ffffff_256x240.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/ac-background.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/actions_right.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/bg.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/breadcrumb-separator.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/calendar.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/delete.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/desc.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/error.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/eye-closed-555.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/eye-closed-fff.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/eye-open-555.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/eye-open-fff.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/full-screen.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/green-header.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/green-square.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/indicator.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/info-mini.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/minus.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/ok.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/orange-header.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/plus.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/red-header.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/truncated.png
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/tv-collapsable-last.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/tv-collapsable.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/tv-expandable-last.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/tv-expandable.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/tv-item-last.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/images/tv-item.gif
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main.css
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_imagemodified.css
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_importmodified.css
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_stylesheet.css
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_testcompilethemes.css
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_varchanged.css
#	tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/theme-parameters.json
#	tests/php-unit-tests/unitary-tests/application/theme-handler/getimages/expected-getimages.json
#	tests/php-unit-tests/unitary-tests/application/theme-handler/getimages/test-getimages.scss
#	tests/php-unit-tests/unitary-tests/core/ActionEmailTest.php
#	tests/php-unit-tests/unitary-tests/core/AttributeDefTest.inc.php
#	tests/php-unit-tests/unitary-tests/core/AttributeURLDefaultPattern.php
#	tests/php-unit-tests/unitary-tests/core/AttributeURLTest.php
#	tests/php-unit-tests/unitary-tests/core/BulkChangeTest.inc.php
#	tests/php-unit-tests/unitary-tests/core/CSVParserTest.php
#	tests/php-unit-tests/unitary-tests/core/DBObjectTest.php
#	tests/php-unit-tests/unitary-tests/core/DBSearchAddConditionPointingTo.php
#	tests/php-unit-tests/unitary-tests/core/ExpressionEvaluateTest.php
#	tests/php-unit-tests/unitary-tests/core/GetSelectFilterTest.php
#	tests/php-unit-tests/unitary-tests/core/InlineImageTest.php
#	tests/php-unit-tests/unitary-tests/core/Log/ExceptionLogTest.php
#	tests/php-unit-tests/unitary-tests/core/Log/ExceptionLogTest/Exceptions.php
#	tests/php-unit-tests/unitary-tests/core/Log/LogAPITest.php
#	tests/php-unit-tests/unitary-tests/core/Log/LogFileNameBuilderTest.php
#	tests/php-unit-tests/unitary-tests/core/LogAPITest.php
#	tests/php-unit-tests/unitary-tests/core/LogFileNameBuilderTest.php
#	tests/php-unit-tests/unitary-tests/core/MetaModelTest.php
#	tests/php-unit-tests/unitary-tests/core/OQLTest.php
#	tests/php-unit-tests/unitary-tests/core/UniquenessConstraintTest.php
#	tests/php-unit-tests/unitary-tests/core/XMLDataLoaderTest.php
#	tests/php-unit-tests/unitary-tests/core/dictApcuTest.php
#	tests/php-unit-tests/unitary-tests/core/dictTest.php
#	tests/php-unit-tests/unitary-tests/core/ormCaseLogTest.php
#	tests/php-unit-tests/unitary-tests/core/ormPasswordTest.php
#	tests/php-unit-tests/unitary-tests/core/ormStyleTest.php
#	tests/php-unit-tests/unitary-tests/setup/MFCompilerTest.php
#	tests/php-unit-tests/unitary-tests/setup/SubMFCompiler.php
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/1.7_to_1.6.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/1.6_to_1.7_2.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/1.6_to_1.7_2.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/1.7.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/1.7_to_1.6.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/1.7_to_1.6.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/1.7_to_1.6_2.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/1.7_to_1.6_2.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/1.7_to_3.0.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/1.7_to_3.0.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/3.0_to_1.7.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/3.0_to_1.7.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/Bug_4569.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/Bug_4569.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_deleted_to_deleted.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_deleted_to_deleted.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_deleted_to_in-definition.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_deleted_to_in-definition.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_deleted_to_not-in-definition.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_deleted_to_not-in-definition.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_in-definition_to_deleted.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_in-definition_to_deleted.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_in-definition_to_in-definition.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_in-definition_to_in-definition.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_in-definition_to_not-in-definition.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_in-definition_to_not-in-definition.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_not-in-definition_to_deleted.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_not-in-definition_to_deleted.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_not-in-definition_to_in-definition.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_not-in-definition_to_in-definition.input.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_not-in-definition_to_not-in-definition.expected.xml
#	tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/MoveNode-samples/from_not-in-definition_to_not-in-definition.input.xml
#	tests/php-unit-tests/unitary-tests/setup/ressources/datamodels/datamodel-branding.xml
#	tests/php-unit-tests/unitary-tests/sources/application/Helper/WebResourcesHelperTest.php
#	tests/php-unit-tests/unitary-tests/sources/application/status/StatusIncTest.php
#	tests/php-unit-tests/unitary-tests/sources/application/status/status.php
#	tests/php-unit-tests/unitary-tests/synchro/DataSynchroTest.php
This commit is contained in:
Molkobain
2023-01-10 14:05:32 +01:00
242 changed files with 1249 additions and 584 deletions

View File

@@ -0,0 +1,87 @@
<?php
namespace Combodo\iTop\Test\UnitTest\Core;
use CMDBSource;
use Combodo\iTop\Test\UnitTest\ItopTestCase;
use DBBackup;
use utils;
/**
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
* @backupGlobals disabled
*/
class DBBackupTest extends ItopTestCase
{
/**
* @throws \CoreException
* @throws \MySQLException
* @throws \ConfigException
*/
protected function setUp(): void
{
parent::setUp();
$this->RequireOnceItopFile('setup/backup.class.inc.php');
// We need a connection to the DB, so let's open it !
// We are using the default config file... as the server might not be configured for all the combination we are testing
// For example dev env and ci env won't accept TLS connection
$oConfigOnDisk = utils::GetConfig();
CMDBSource::InitFromConfig($oConfigOnDisk);
}
/**
* No TLS connection = no additional CLI args !
*
* @throws \CoreException
* @throws \ConfigException
* @throws \MySQLException
*/
public function testGetMysqlCliTlsOptionsNoTls()
{
$oConfigToTest = utils::GetConfig();
$oConfigToTest->Set('db_tls.enabled', false);
$sCliArgsNoTls = DBBackup::GetMysqlCliTlsOptions($oConfigToTest);
$this->assertEmpty($sCliArgsNoTls);
}
/**
* TLS connection configured = we need one CLI arg
*
* @return void
* @throws \ConfigException
* @throws \CoreException
*/
public function testGetMysqlCliTlsOptionsWithTlsNoCa()
{
$oConfigToTest = utils::GetConfig();
$oConfigToTest->Set('db_tls.enabled', true);
$sCliArgsMinCfg = DBBackup::GetMysqlCliTlsOptions($oConfigToTest);
// depending on the MySQL version, we would have `--ssl` or `--ssl-mode=VERIFY_CA`
$this->assertStringStartsWith(' --ssl', $sCliArgsMinCfg);
}
/**
* TLS connection configured + CA option = we need multiple CLI args
*
* @return void
* @throws \ConfigException
* @throws \CoreException
*/
public function testGetMysqlCliTlsOptionsWithTlsAndCa()
{
$oConfigToTest = utils::GetConfig();
$sTestCa = 'my_test_ca';
$oConfigToTest->Set('db_tls.enabled', true);
$oConfigToTest->Set('db_tls.ca', $sTestCa);
$sCliArgsCapathCfg = DBBackup::GetMysqlCliTlsOptions($oConfigToTest);
$this->assertStringStartsWith(' --ssl', $sCliArgsCapathCfg);
$this->assertStringEndsWith('--ssl-ca='.DBBackup::EscapeShellArg($sTestCa), $sCliArgsCapathCfg);
}
}

View File

@@ -0,0 +1,195 @@
<?php
use Combodo\iTop\Test\UnitTest\ItopTestCase;
/**
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
* @backupGlobals disabled
* @covers \MFCompiler::UseLatestPrecompiledFile
*/
class MFCompilerTest extends ItopTestCase {
/** @var array */
private static $aFoldersToCleanup;
/** @var array */
private static $aRessources;
/** @var \MFCompiler */
private $oMFCompiler;
private $sTmpDir;
public function setUp(): void {
parent::setUp();
$this->RequireOnceItopFile('setup/compiler.class.inc.php');
$this->RequireOnceItopFile('setup/modelfactory.class.inc.php');
$this->RequireOnceUnitTestFile('./SubMFCompiler.php');
$this->sTmpDir = $this->CreateTmpdir();
$this->oMFCompiler = new SubMFCompiler($this->createMock(\ModelFactory::class), '');
}
public function tearDown(): void {
parent::tearDown();
$this->RecurseRmdir($this->sTmpDir);
}
public static function Init(){
if (!is_null(self::$aFoldersToCleanup)){
return;
}
clearstatcache();
$sPrefix = 'scsstest_';
$sAppRootForProvider = 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';
mkdir($sTempTargetDir);
mkdir($sExtensionTargetDir);
mkdir($sDatamodel2xTargetDir);
self::$aFoldersToCleanup = [ $sTempTargetDir, $sExtensionTargetDir, $sDatamodel2xTargetDir ];
self::$aRessources['sPostCompilation1'] = tempnam($sTempTargetDir, $sPrefix);
sleep(1);
//datamodel XML file in extension folder
self::$aRessources['sPrecompiledInExtensionFile1'] = tempnam($sExtensionTargetDir, $sPrefix);
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);
self::$aRessources['sPrecompiledInDataModelXXFileUri1'] = "UseLatestPrecompiledFileProvider" . DIRECTORY_SEPARATOR . basename(self::$aRessources['sPrecompiledInDataModelXXFile1']);
sleep(1);
//generate ressources from a previous setup: called postcompiled
self::$aRessources['sPostCompilation2'] = tempnam($sTempTargetDir, $sPrefix);
sleep(1);
//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']);
copy(self::$aRessources['sPrecompiledInExtensionFile1'], self::$aRessources['sCopiedExtensionFile1']);
self::$aRessources['sCopiedDataModelXXFile1'] = $sTempTargetDir . DIRECTORY_SEPARATOR . basename(self::$aRessources['sPrecompiledInDataModelXXFile1']);
copy(self::$aRessources['sPrecompiledInDataModelXXFile1'], self::$aRessources['sCopiedDataModelXXFile1']);
self::$aRessources['sMissingFile'] = tempnam($sTempTargetDir, $sPrefix);
unlink(self::$aRessources['sMissingFile']);
/*foreach (self::$aRessources as $sKey => $sRessource){
if (is_file($sRessource)) {
var_dump("$sKey $sRessource:" . filemtime($sRessource));
}
}*/
}
public static function tearDownAfterClass(): void
{
if (is_null(self::$aFoldersToCleanup)){
return;
}
foreach (self::$aFoldersToCleanup as $sFolder){
if (is_dir($sFolder)){
foreach (glob("$sFolder/**") as $sFile){
unlink($sFile);
}
rmdir($sFolder);
}
}
}
/**
* @dataProvider UseLatestPrecompiledFileProvider
*
* @param string $sTempTargetDir
* @param string $sPrecompiledFileUri
* @param string $sPostCompilationLatestPrecompiledFile
* @param string $sThemeDir
* @param ?string $sExpectedReturn
*/
public function testUseLatestPrecompiledFile(string $sTempTargetDir, string $sPrecompiledFileUri, string $sPostCompilationLatestPrecompiledFile, string $sThemeDir, ?string $sExpectedReturn, bool $bDisableThemePrecompilationViaConf = false){
if ($bDisableThemePrecompilationViaConf){
utils::GetConfig()->Set('theme.enable_precompilation', false);
}
$sRes = $this->oMFCompiler->UseLatestPrecompiledFile($sTempTargetDir, $sPrecompiledFileUri, $sPostCompilationLatestPrecompiledFile, $sThemeDir);
$this->assertEquals($sExpectedReturn, $sRes);
}
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'] ),
];
}
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
];
}
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');
$oDom = new MFDocument();
$oDom->load($sXmlDataCustoFilePath);
/** @var \MFElement $oBrandingNode */
$oBrandingNode = $oDom->GetNodes('branding')->item(0);
$this->RecurseMkdir($sFullmoonThemeCompiledFolder);
file_put_contents($sFullmoonThemeCompiledFolder.'main.css', "");
$aImportsPaths = array(
APPROOT.'css/',
APPROOT.'css/backoffice/main.scss',
$this->sTmpDir.'//',
);
$aThemeParameters = [
'variables' => [
'ibo-page-banner--background-color' => '$ibo-color-red-600',
'ibo-page-banner--text-color' => '$ibo-color-red-100',
'ibo-page-banner--text-content' => '"THIS IS A TEST INSTANCE"',
],
'variable_imports' => ['ok-because-xsi-type-variables' => 'ok-because-xsi-type-variables.scss'],
'utility_imports' => ['ok-because-xsi-type-utilities' => 'ok-because-xsi-type-utilities.scss'],
'stylesheets' => [
"fullmoon" => '../css/backoffice/main.scss',
"environment-banner" => '../css/backoffice/themes/page-banner.scss',
"datamodel-compiled-scss-rules" => 'branding/themes/datamodel-compiled-scss-rules.scss',
],
];
$oThemeHandlerService = $this->createMock(\ThemeHandlerService::class);
$oThemeHandlerService->expects($this->exactly(1))
->method("CompileTheme")
->with("fullmoon", true, $this->oMFCompiler->GetCompilationTimeStamp(), $aThemeParameters, $aImportsPaths, $this->sTmpDir . '/');
//CompileTheme($sThemeId, $bSetup = false, $sSetupCompilationTimestamp="", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null)
MFCompiler::SetThemeHandlerService($oThemeHandlerService);
$this->InvokeNonPublicMethod(MFCompiler::class, 'CompileThemes', $this->oMFCompiler, [$oBrandingNode, $this->sTmpDir]);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,143 @@
<?php
namespace Combodo\iTop\Test\UnitTest\Setup;
use Combodo\iTop\Test\UnitTest\ItopTestCase;
use SetupUtils;
/**
* Class SetupUtilsTest
*
* @covers SetupUtils
*
* @since 2.7.4 N°3412
* @package Combodo\iTop\Test\UnitTest\Setup
*/
class SetupUtilsTest extends ItopTestCase
{
const ERROR = 0;
const WARNING = 1;
const INFO = 2;
const TRACE = 3; // for log purposes : replace old SetupLog::Log calls
protected function setUp(): void
{
parent::setUp();
$this->RequireOnceItopFile('setup/setuputils.class.inc.php');
$this->RequireOnceItopFile('setup/setuppage.class.inc.php');
}
/**
* @dataProvider CheckGraphvizProvider
*/
public function testCheckGraphviz($sScriptPath, $iSeverity, $sLabel){
/** @var \CheckResult $oCheck */
$aCheck = SetupUtils::CheckGraphviz($sScriptPath);
$bLabelFound = false;
foreach ($aCheck as $oCheck) {
$this->assertGreaterThanOrEqual($iSeverity, $oCheck->iSeverity);
if (!$bLabelFound && (empty($sLabel) || strpos($oCheck->sLabel, $sLabel) !== false)) {
$bLabelFound = true;
}
}
$this->assertTrue($bLabelFound, "label '$sLabel' not found");
}
public function CheckGraphvizProvider(){
if (substr(PHP_OS,0,3) === 'WIN'){
return [];
}
return [
"bash injection" => [
"touch /tmp/toto",
self::WARNING,
"could not be executed: Please make sure it is installed and in the path",
],
"command ok" => [
"/usr/bin/whereis",
self::INFO,
"",
],
"empty command => dot by default" => [
"",
self::INFO,
"",
],
"command failed" => [
"/bin/ls",
self::WARNING,
"dot could not be executed (retcode=2): Please make sure it is installed and in the path",
]
];
}
/**
* @dataProvider HumanReadableSizeProvider
*/
public function testHumanReadableSize($fBytes, $sExpected)
{
$sOutput = SetupUtils::HumanReadableSize($fBytes);
$this->assertEquals($sExpected, $sOutput);
}
public function HumanReadableSizeProvider(): array
{
return [
'10 bytes' => [
10,
'10 bytes',
],
'10 kilobytes' => [
10 * 1024,
'10.24 KB',
],
'10 megabytes' => [
10 * 1024 * 1024,
'10.49 MB',
],
'10 gigabytes' => [
10 * 1024 * 1024 * 1024,
'10.74 GB',
],
'10 terabytes' => [
10 * 1024 * 1024 * 1024 * 1024,
'11.00 TB',
],
'10 petabytes' => [
10 * 1024 * 1024 * 1024 * 1024 * 1024,
'11.26 PB',
],
'10 heptabytes' => [
10 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024,
'11.53 HB',
],
];
}
/**
* @covers SetupUtils::PHP_MIN_VERSION
* @covers SetupUtils::PHP_NOT_VALIDATED_VERSION
* @covers composer.json
* @group composerJson
*/
public function testPhpMinVersionConsistency()
{
$sPHPMinVersion = SetupUtils::PHP_MIN_VERSION;
$sPHPNotValidatedVersion = SetupUtils::PHP_NOT_VALIDATED_VERSION;
// Ensure that not validated version is greater than min. supported version
$this->assertTrue(version_compare($sPHPMinVersion, $sPHPNotValidatedVersion, '<'), "SetupUtils::PHP_MIN_VERSION ($sPHPMinVersion) is not strictly lower than SetupUtils::PHP_NOT_VALIDATED_VERSION ($sPHPNotValidatedVersion)");
if (file_exists(APPROOT.'composer.json')) {
$oComposerConfig = json_decode(file_get_contents(APPROOT.'composer.json'));
// Platform/PHP must be set to the minimum to ensure dependancies are compatible with the min. version
$this->assertEquals($sPHPMinVersion, $oComposerConfig->config->platform->php, "Composer/Platform/PHP");
// Require/PHP must be set to the supported PHP versions range in order to keep our package constraints up-to-date
$this->assertEquals(">=$sPHPMinVersion <$sPHPNotValidatedVersion", $oComposerConfig->require->php, "Composer/Require/PHP");
}
}
}

View File

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

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.6">
<menus>
<menu id="WelcomeMenuLink1" xsi:type="WebPageMenuNode" _delta="define">
<rank>100</rank>
<parent>WelcomeMenu</parent>
<url>$$http://fr.wikipedia.org/</url>
</menu>
<menu id="WelcomeMenuLink2" xsi:type="WebPageMenuNode" _delta="define">
<rank>100</rank>
<parent>WelcomeMenu</parent>
<url>$$http://fr.wikipedia.org/</url>
</menu>
</menus>
</itop_design>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<menus>
<menu id="WelcomeMenuLink1" xsi:type="WebPageMenuNode" _delta="define">
<rank>100</rank>
<parent>WelcomeMenu</parent>
<url>$$http://fr.wikipedia.org/</url>
<in_new_window>true</in_new_window>
</menu>
<menu id="WelcomeMenuLink2" xsi:type="WebPageMenuNode" _delta="define">
<rank>100</rank>
<parent>WelcomeMenu</parent>
<url>$$http://fr.wikipedia.org/</url>
</menu>
</menus>
</itop_design>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<branding _revision_id="180">
<main_logo _revision_id="53" _delta="define">
<fileref ref="smile_portal_logo_7417a491754f12f744ac6311525e4db3" _revision_id="116"/>
</main_logo>
<login_logo _revision_id="53" _delta="define">
<fileref ref="smile_portal_logo_7417a491754f12f744ac6311525e4db3" _revision_id="116"/>
</login_logo>
<portal_logo _revision_id="53" _delta="define">
<fileref ref="smile_portal_logo_7417a491754f12f744ac6311525e4db3" _revision_id="116"/>
</portal_logo>
</branding>
<constants>
<constant id="RESPONSE_TICKET_SLT_QUERY" xsi:type="string" _created_in="itop-tickets" _revision_id="19" _delta="redefine"><![CDATA[SELECT slt FROM Organization AS child JOIN Organization AS root ON child.parent_id BELOW root.id JOIN CustomerContract AS cc ON cc.org_id=root.id JOIN lnkCustomerContractToService AS l1 ON l1.customercontract_id=cc.id JOIN SLA AS sla ON l1.sla_id=sla.id JOIN lnkSLAToSLT AS l2 ON l2.sla_id=sla.id JOIN SLT AS slt ON l2.slt_id=slt.id WHERE slt.metric = :metric AND l1.service_id = :this->service_id AND child.id= :this->org_id AND slt.request_type = :request_type AND slt.priority = :this->priority]]></constant>
</constants>
</itop_design>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.6">
<branding _revision_id="180">
<main_logo _revision_id="53" _delta="define">
<fileref ref="smile_portal_logo_7417a491754f12f744ac6311525e4db3" _revision_id="116"/>
</main_logo>
<login_logo _revision_id="53" _delta="define">
<fileref ref="smile_portal_logo_7417a491754f12f744ac6311525e4db3" _revision_id="116"/>
</login_logo>
<portal_logo _revision_id="53" _delta="define">
<fileref ref="smile_portal_logo_7417a491754f12f744ac6311525e4db3" _revision_id="116"/>
</portal_logo>
</branding>
<constants>
<constant id="RESPONSE_TICKET_SLT_QUERY" xsi:type="string" _created_in="itop-tickets" _revision_id="19" _delta="redefine"><![CDATA[SELECT slt FROM Organization AS child JOIN Organization AS root ON child.parent_id BELOW root.id JOIN CustomerContract AS cc ON cc.org_id=root.id JOIN lnkCustomerContractToService AS l1 ON l1.customercontract_id=cc.id JOIN SLA AS sla ON l1.sla_id=sla.id JOIN lnkSLAToSLT AS l2 ON l2.sla_id=sla.id JOIN SLT AS slt ON l2.slt_id=slt.id WHERE slt.metric = :metric AND l1.service_id = :this->service_id AND child.id= :this->org_id AND slt.request_type = :request_type AND slt.priority = :this->priority]]></constant>
<constant id="PORTAL_SERVICECATEGORY_QUERY" xsi:type="string" _created_in="itop-tickets" _revision_id="19" _delta="redefine"><![CDATA[SELECT s FROM Organization AS child JOIN Organization AS root ON child.parent_id BELOW root.id JOIN CustomerContract AS cc ON cc.org_id = root.id JOIN lnkCustomerContractToService AS l1 ON l1.customercontract_id=cc.id JOIN Service AS s ON l1.service_id=s.id WHERE child.id = :org_id AND s.status != 'obsolete' UNION SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = :org_id AND s.status != 'obsolete']]></constant>
<constant id="PORTAL_VALIDATE_SERVICECATEGORY_QUERY" xsi:type="string" _created_in="itop-tickets" _revision_id="19" _delta="redefine"><![CDATA[SELECT s FROM Organization AS child JOIN Organization AS root ON child.parent_id BELOW root.id JOIN CustomerContract AS cc ON cc.org_id = root.id JOIN lnkCustomerContractToService AS l1 ON l1.customercontract_id=cc.id JOIN Service AS s ON l1.service_id=s.id WHERE child.id = :org_id AND s.id = :id AND s.status != 'obsolete' UNION SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = :org_id AND s.id = :id AND s.status != 'obsolete']]></constant>
</constants>
</itop_design>

View File

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<branding>
<themes>
<theme id="test-red" _delta="define">
<variables>
<variable id="backoffice-environment-banner-background-color">#C53030</variable>
<variable id="var1">#C53030</variable>
</variables>
<imports>
<import id="scss-variables">../css/scss-variables.scss</import>
<import id="css-variables">../css/css-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="custom">../css/custom.scss</stylesheet>
<stylesheet id="jqueryui">../css/ui-lightness/jqueryui.scss</stylesheet>
<stylesheet id="main">../css/main.scss</stylesheet>
</stylesheets>
</theme>
<theme id="light-grey">
<variables/>
<imports>
<import id="css-variables">../css/css-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="jqueryui">../css/ui-lightness/jqueryui.scss</stylesheet>
<stylesheet id="main">../css/light-grey.scss</stylesheet>
</stylesheets>
</theme>
</themes>
</branding>
<classes>
<class id="ClassWithStateButNoLifecycle">
<properties>
<icon>images/class-with-lifecycle.png</icon>
</properties>
</class>
<class id="ClassWithStateAndLifecycle">
<properties>
<icon>images/class-with-lifecycle.png</icon>
</properties>
<lifecycle>
<attribute>foo</attribute>
</lifecycle>
</class>
<class id="ClassWithStateAndImage">
<properties>
<icon>images/class-with-lifecycle.png</icon>
</properties>
</class>
<class id="ClassWithImageOnly">
<properties>
<icon>images/class-with-lifecycle.png</icon>
</properties>
</class>
<class id="OtherClass">
<properties>
<icon revisionid="2" _delta="redefine">
<fileref ref="company_0faae3b9d86b7c382b2e4cdae570bc3c" revisionid="62"/>
</icon>
</properties>
<fields>
<field id="status" xsi:type="AttributeEnum">
<always_load_in_tables>true</always_load_in_tables>
<values>
<value id="new">new</value>
<value id="waiting_for_approval">waiting_for_approval</value>
</values>
</field>
<field id="operational_status" xsi:type="AttributeMetaEnum">
<values>
<value id="ongoing">ongoing</value>
<value id="resolved">resolved</value>
</values>
</field>
</fields>
</class>
</classes>
<menus>
<menu id="WelcomeMenuLink1" xsi:type="WebPageMenuNode" _delta="define">
<rank>100</rank>
<parent>WelcomeMenu</parent>
<url>$$http://fr.wikipedia.org/</url>
<in_new_window>true</in_new_window>
</menu>
<menu id="RequestManagement" xsi:type="MenuGroup" _delta="define">
<rank>30</rank>
<enable_stimulus/>
</menu>
</menus>
<branding>
<main_logo _delta="define">images/itop-logo.png</main_logo>
</branding>
</itop_design>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.6">
<menus>
<menu id="WelcomeMenuLink1" xsi:type="WebPageMenuNode" _delta="define">
<rank>100</rank>
<parent>WelcomeMenu</parent>
<url>$$http://fr.wikipedia.org/</url>
</menu>
<menu id="WelcomeMenuLink2" xsi:type="WebPageMenuNode" _delta="define">
<rank>100</rank>
<parent>WelcomeMenu</parent>
<url>$$http://fr.wikipedia.org/</url>
</menu>
</menus>
<branding/>
</itop_design>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<menus>
<menu id="WelcomeMenuLink1" xsi:type="WebPageMenuNode" _delta="define">
<rank>100</rank>
<parent>WelcomeMenu</parent>
<url>$$http://fr.wikipedia.org/</url>
<in_new_window>true</in_new_window>
</menu>
<menu id="WelcomeMenuLink2" xsi:type="WebPageMenuNode" _delta="define">
<rank>100</rank>
<parent>WelcomeMenu</parent>
<url>$$http://fr.wikipedia.org/</url>
</menu>
</menus>
<branding>
<themes>
<theme id="light-grey">
<variables>
<variable id="foo" _delta="define">bar</variable>
</variables>
</theme>
</themes>
</branding>
</itop_design>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.6">
<branding _revision_id="180">
<main_logo _revision_id="53" _delta="define">
<fileref ref="smile_portal_logo_7417a491754f12f744ac6311525e4db3" _revision_id="116"/>
</main_logo>
<login_logo _revision_id="53" _delta="define">
<fileref ref="smile_portal_logo_7417a491754f12f744ac6311525e4db3" _revision_id="116"/>
</login_logo>
<portal_logo _revision_id="53" _delta="define">
<fileref ref="smile_portal_logo_7417a491754f12f744ac6311525e4db3" _revision_id="116"/>
</portal_logo>
</branding>
<constants>
<constant id="RESPONSE_TICKET_SLT_QUERY" xsi:type="string" _created_in="itop-tickets" _revision_id="19" _delta="redefine"><![CDATA[SELECT slt FROM Organization AS child JOIN Organization AS root ON child.parent_id BELOW root.id JOIN CustomerContract AS cc ON cc.org_id=root.id JOIN lnkCustomerContractToService AS l1 ON l1.customercontract_id=cc.id JOIN SLA AS sla ON l1.sla_id=sla.id JOIN lnkSLAToSLT AS l2 ON l2.sla_id=sla.id JOIN SLT AS slt ON l2.slt_id=slt.id WHERE slt.metric = :metric AND l1.service_id = :this->service_id AND child.id= :this->org_id AND slt.request_type = :request_type AND slt.priority = :this->priority]]></constant>
</constants>
</itop_design>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<branding _revision_id="180">
<main_logo _revision_id="53" _delta="define">
<fileref ref="smile_portal_logo_7417a491754f12f744ac6311525e4db3" _revision_id="116"/>
</main_logo>
<login_logo _revision_id="53" _delta="define">
<fileref ref="smile_portal_logo_7417a491754f12f744ac6311525e4db3" _revision_id="116"/>
</login_logo>
<portal_logo _revision_id="53" _delta="define">
<fileref ref="smile_portal_logo_7417a491754f12f744ac6311525e4db3" _revision_id="116"/>
</portal_logo>
</branding>
<constants>
<constant id="RESPONSE_TICKET_SLT_QUERY" xsi:type="string" _created_in="itop-tickets" _revision_id="19" _delta="redefine"><![CDATA[SELECT slt FROM Organization AS child JOIN Organization AS root ON child.parent_id BELOW root.id JOIN CustomerContract AS cc ON cc.org_id=root.id JOIN lnkCustomerContractToService AS l1 ON l1.customercontract_id=cc.id JOIN SLA AS sla ON l1.sla_id=sla.id JOIN lnkSLAToSLT AS l2 ON l2.sla_id=sla.id JOIN SLT AS slt ON l2.slt_id=slt.id WHERE slt.metric = :metric AND l1.service_id = :this->service_id AND child.id= :this->org_id AND slt.request_type = :request_type AND slt.priority = :this->priority]]></constant>
</constants>
</itop_design>

View File

@@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0">
<branding>
<themes>
<theme id="test-red" _delta="define">
<variables>
<variable id="ibo-page-banner--background-color">#C53030</variable>
<variable id="var1">#C53030</variable>
</variables>
<imports>
<import id="css-variables" xsi:type="utilities">../css/css-variables.scss</import>
<import id="scss-variables" xsi:type="utilities">../css/scss-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="jqueryui">../css/ui-lightness/jqueryui.scss</stylesheet>
<stylesheet id="main">../css/main.scss</stylesheet>
<stylesheet id="custom">../css/custom.scss</stylesheet>
</stylesheets>
</theme>
<theme id="light-grey">
<variables/>
<imports>
<import id="css-variables" xsi:type="utilities">../css/css-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="jqueryui">../css/ui-lightness/jqueryui.scss</stylesheet>
<stylesheet id="main">../css/light-grey.scss</stylesheet>
</stylesheets>
</theme>
</themes>
</branding>
<classes>
<class id="ClassWithNewValueInFieldWhichHasNoXsiTypeDueToMustExistFlag" _delta="must_exist">
<fields>
<field id="status" _delta="must_exist">
<values>
<value id="test" _delta="define">
<code>test</code>
</value>
</values>
</field>
</fields>
</class>
<class id="ClassWithLifecycle">
<properties>
<fields_semantic>
<state_attribute>foo</state_attribute>
</fields_semantic>
<style>
<icon>images/class-with-lifecycle.png</icon>
</style>
</properties>
<lifecycle/>
</class>
<class id="ClassWithLifecycleNoProperties">
<lifecycle/>
<properties>
<fields_semantic>
<state_attribute>foo</state_attribute>
</fields_semantic>
</properties>
</class>
<class id="OtherClass">
<properties>
<style>
<icon revisionid="2" _delta="redefine">
<fileref ref="company_0faae3b9d86b7c382b2e4cdae570bc3c" revisionid="62"/>
</icon>
</style>
</properties>
<fields>
<field id="status" xsi:type="AttributeEnum">
<always_load_in_tables>true</always_load_in_tables>
<values>
<value id="new">
<code>new</code>
</value>
<value id="assigned">
<code>assigned</code>
</value>
</values>
<sql>status</sql>
<default_value>new</default_value>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="operational_status" xsi:type="AttributeMetaEnum">
<values>
<value id="ongoing">
<code>ongoing</code>
</value>
<value id="resolved">
<code>resolved</code>
</value>
<value id="closed">
<code>closed</code>
</value>
</values>
<sql>operational_status</sql>
<default_value>ongoing</default_value>
<mappings>
<mapping id="Ticket">
<attcode>status</attcode>
<metavalues>
<metavalue id="resolved">
<values>
<value id="resolved"/>
</values>
</metavalue>
<metavalue id="closed">
<values>
<value id="closed"/>
<value id="rejected"/>
</values>
</metavalue>
</metavalues>
</mapping>
</mappings>
</field>
</fields>
</class>
</classes>
</itop_design>

View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<branding>
<themes>
<theme id="test-red" _delta="define">
<variables>
<variable id="backoffice-environment-banner-background-color">#C53030</variable>
<variable id="var1">#C53030</variable>
</variables>
<imports>
<import id="css-variables">../css/css-variables.scss</import>
<import id="scss-variables">../css/scss-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="jqueryui">../css/ui-lightness/jqueryui.scss</stylesheet>
<stylesheet id="main">../css/main.scss</stylesheet>
<stylesheet id="custom">../css/custom.scss</stylesheet>
</stylesheets>
</theme>
<theme id="light-grey">
<variables/>
<imports>
<import id="css-variables">../css/css-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="jqueryui">../css/ui-lightness/jqueryui.scss</stylesheet>
<stylesheet id="main">../css/light-grey.scss</stylesheet>
</stylesheets>
</theme>
</themes>
</branding>
<classes>
<class id="ClassWithNewValueInFieldWhichHasNoXsiTypeDueToMustExistFlag" _delta="must_exist">
<fields>
<field id="status" _delta="must_exist">
<values>
<value id="test" _delta="define">test</value>
</values>
</field>
</fields>
</class>
<class id="ClassWithLifecycle">
<properties>
<icon>images/class-with-lifecycle.png</icon>
</properties>
<lifecycle>
<attribute>foo</attribute>
</lifecycle>
</class>
<class id="ClassWithLifecycleNoProperties">
<lifecycle>
<attribute>foo</attribute>
</lifecycle>
</class>
<class id="OtherClass">
<properties>
<icon revisionid="2" _delta="redefine">
<fileref ref="company_0faae3b9d86b7c382b2e4cdae570bc3c" revisionid="62"/>
</icon>
</properties>
<fields>
<field id="status" xsi:type="AttributeEnum">
<always_load_in_tables>true</always_load_in_tables>
<values>
<value id="new">new</value>
<value id="assigned">assigned</value>
</values>
<sql>status</sql>
<default_value>new</default_value>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="operational_status" xsi:type="AttributeMetaEnum">
<values>
<value id="ongoing">ongoing</value>
<value id="resolved">resolved</value>
<value id="closed">closed</value>
</values>
<sql>operational_status</sql>
<default_value>ongoing</default_value>
<mappings>
<mapping id="Ticket">
<attcode>status</attcode>
<metavalues>
<metavalue id="resolved">
<values>
<value id="resolved"/>
</values>
</metavalue>
<metavalue id="closed">
<values>
<value id="closed"/>
<value id="rejected"/>
</values>
</metavalue>
</metavalues>
</mapping>
</mappings>
</field>
</fields>
</class>
</classes>
</itop_design>

View File

@@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<branding>
<themes>
<theme id="test-red" _delta="define">
<variables>
<variable id="backoffice-environment-banner-background-color">#C53030</variable>
<variable id="var1">#C53030</variable>
</variables>
<imports>
<import id="scss-variables">../css/scss-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="custom">../css/custom.scss</stylesheet>
</stylesheets>
</theme>
</themes>
</branding>
<classes>
<class id="ClassWithStateButNoLifecycle">
<properties>
<icon>images/class-with-lifecycle.png</icon>
</properties>
</class>
<class id="ClassWithStateAndLifecycle">
<properties>
<icon>images/class-with-lifecycle.png</icon>
</properties>
<lifecycle>
<attribute>foo</attribute>
</lifecycle>
</class>
<class id="ClassWithStateAndImage">
<properties>
<icon>images/class-with-lifecycle.png</icon>
</properties>
</class>
<class id="ClassWithImageOnly">
<properties>
<icon>images/class-with-lifecycle.png</icon>
</properties>
</class>
<class id="OtherClass">
<properties>
<icon revisionid="2" _delta="redefine">
<fileref ref="company_0faae3b9d86b7c382b2e4cdae570bc3c" revisionid="62"/>
</icon>
</properties>
<fields>
<field id="status" xsi:type="AttributeEnum">
<always_load_in_tables>true</always_load_in_tables>
<values>
<value id="new">new</value>
<value id="waiting_for_approval">waiting_for_approval</value>
</values>
</field>
<field id="operational_status" xsi:type="AttributeMetaEnum">
<values>
<value id="ongoing">ongoing</value>
<value id="resolved">resolved</value>
</values>
</field>
</fields>
</class>
</classes>
<menus>
<menu id="WelcomeMenuLink1" xsi:type="WebPageMenuNode" _delta="define">
<rank>100</rank>
<parent>WelcomeMenu</parent>
<url>$$http://fr.wikipedia.org/</url>
<in_new_window>true</in_new_window>
</menu>
<menu id="RequestManagement" xsi:type="MenuGroup" _delta="define">
<rank>30</rank>
<enable_stimulus/>
</menu>
</menus>
<branding>
<main_logo _delta="define">images/itop-logo.png</main_logo>
</branding>
<meta>
<previous_versions>
<previous_version_1_7>
<trashed_nodes>
<trashed_node id="XXX">
<parent_xpath>/itop_design/branding/themes</parent_xpath>
<node_tree>
<theme id="light-grey">
<variables/>
<imports>
<import id="css-variables">../css/css-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="jqueryui">../css/ui-lightness/jqueryui.scss</stylesheet>
<stylesheet id="main">../css/light-grey.scss</stylesheet>
</stylesheets>
</theme>
</node_tree>
</trashed_node>
<trashed_node id="XXX">
<parent_xpath>/itop_design/branding/themes/theme[@id="test-red"]/imports</parent_xpath>
<node_tree>
<import id="css-variables">../css/css-variables.scss</import>
</node_tree>
</trashed_node>
<trashed_node id="XXX">
<parent_xpath>/itop_design/branding/themes/theme[@id="test-red"]/stylesheets</parent_xpath>
<node_tree>
<stylesheet id="jqueryui">../css/ui-lightness/jqueryui.scss</stylesheet>
</node_tree>
</trashed_node>
<trashed_node id="XXX">
<parent_xpath>/itop_design/branding/themes/theme[@id="test-red"]/stylesheets</parent_xpath>
<node_tree>
<stylesheet id="main">../css/main.scss</stylesheet>
</node_tree>
</trashed_node>
</trashed_nodes>
</previous_version_1_7>
</previous_versions>
</meta>
</itop_design>

View File

@@ -0,0 +1,177 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0">
<branding>
<themes>
<theme id="test-red" _delta="define">
<variables>
<variable id="ibo-page-banner--background-color">#C53030</variable>
<variable id="var1">#C53030</variable>
</variables>
<imports>
<import id="scss-variables" xsi:type="utilities">../css/scss-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="custom">../css/custom.scss</stylesheet>
</stylesheets>
</theme>
</themes>
</branding>
<classes>
<class id="ClassWithStateButNoLifecycle">
<properties>
<style>
<icon>images/class-with-lifecycle.png</icon>
</style>
<fields_semantic>
<state_attribute>foo</state_attribute>
</fields_semantic>
</properties>
</class>
<class id="ClassWithStateAndLifecycle">
<properties>
<style>
<icon>images/class-with-lifecycle.png</icon>
</style>
<fields_semantic>
<state_attribute>foo</state_attribute>
</fields_semantic>
</properties>
<lifecycle/>
</class>
<class id="ClassWithStateAndImage">
<properties>
<style>
<icon>images/class-with-lifecycle.png</icon>
</style>
<fields_semantic>
<state_attribute>foo</state_attribute>
<image_attribute>bar</image_attribute>
</fields_semantic>
</properties>
</class>
<class id="ClassWithImageOnly">
<properties>
<style>
<icon>images/class-with-lifecycle.png</icon>
</style>
<fields_semantic>
<image_attribute>bar</image_attribute>
</fields_semantic>
</properties>
</class>
<class id="OtherClass">
<properties>
<style>
<icon revisionid="2" _delta="redefine">
<fileref ref="company_0faae3b9d86b7c382b2e4cdae570bc3c" revisionid="62"/>
</icon>
<main_color>#4E79A5</main_color>
<complementary_color>white</complementary_color>
</style>
</properties>
<fields>
<field id="status" xsi:type="AttributeEnum">
<always_load_in_tables>true</always_load_in_tables>
<values>
<value id="new">
<code>new</code>
<style>
<main_color>#2C5382</main_color>
<complementary_color>#FFFFFF</complementary_color>
<decoration_classes/>
</style>
</value>
<value id="waiting_for_approval">
<code>waiting_for_approval</code>
</value>
</values>
<default_style>
<main_color>#2B6CB0</main_color>
<complementary_color>#FFFFFF</complementary_color>
<decoration_classes/>
</default_style>
</field>
<field id="operational_status" xsi:type="AttributeMetaEnum">
<values>
<value id="ongoing">
<code>ongoing</code>
<style>
<main_color>#2C5382</main_color>
<complementary_color>#FFFFFF</complementary_color>
<decoration_classes/>
</style>
</value>
<value id="resolved">
<code>resolved</code>
</value>
</values>
<default_style>
<main_color>#2B6CB0</main_color>
<complementary_color>#FFFFFF</complementary_color>
<decoration_classes/>
</default_style>
</field>
</fields>
</class>
</classes>
<menus>
<menu id="WelcomeMenuLink1" xsi:type="WebPageMenuNode" _delta="define">
<rank>100</rank>
<parent>WelcomeMenu</parent>
<url>$$http://fr.wikipedia.org/</url>
<in_new_window>true</in_new_window>
</menu>
<menu id="RequestManagement" xsi:type="MenuGroup" _delta="define">
<rank>30</rank>
<enable_stimulus/>
<style>
<decoration_classes>fas fa-comment-alt</decoration_classes>
</style>
</menu>
</menus>
<branding>
<main_logo _delta="define">images/itop-logo.png</main_logo>
<main_logo_compact _delta="define">images/itop-logo-square.png</main_logo_compact>
</branding>
<meta>
<previous_versions>
<previous_version_1_7>
<trashed_nodes>
<trashed_node id="1">
<parent_xpath>/itop_design/branding/themes</parent_xpath>
<node_tree>
<theme id="light-grey">
<variables/>
<imports>
<import id="css-variables">../css/css-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="jqueryui">../css/ui-lightness/jqueryui.scss</stylesheet>
<stylesheet id="main">../css/light-grey.scss</stylesheet>
</stylesheets>
</theme>
</node_tree>
</trashed_node>
<trashed_node id="2">
<parent_xpath>/itop_design/branding/themes/theme[@id="test-red"]/imports</parent_xpath>
<node_tree>
<import id="css-variables">../css/css-variables.scss</import>
</node_tree>
</trashed_node>
<trashed_node id="3">
<parent_xpath>/itop_design/branding/themes/theme[@id="test-red"]/stylesheets</parent_xpath>
<node_tree>
<stylesheet id="jqueryui">../css/ui-lightness/jqueryui.scss</stylesheet>
</node_tree>
</trashed_node>
<trashed_node id="4">
<parent_xpath>/itop_design/branding/themes/theme[@id="test-red"]/stylesheets</parent_xpath>
<node_tree>
<stylesheet id="main">../css/main.scss</stylesheet>
</node_tree>
</trashed_node>
</trashed_nodes>
</previous_version_1_7>
</previous_versions>
</meta>
</itop_design>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b/>
<d _delta="delete"/>
<f _delta="delete">
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b>
<c _delta="delete">In self delete</c>
</b>
<d _delta="delete">
<e>In parent delete</e>
</d>
<f _delta="delete">
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b/>
<d _delta="delete"/>
<f _delta="define">
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b>
<c _delta="delete">In self delete</c>
</b>
<d _delta="delete">
<e>In parent delete</e>
</d>
<f _delta="define">
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b/>
<d _delta="delete"/>
<f>
<g>I'm a future sibling</g>
<c _delta="delete">In self delete</c>
<e>In parent delete</e>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b>
<c _delta="delete">In self delete</c>
</b>
<d _delta="delete">
<e>In parent delete</e>
</d>
<f>
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b/>
<d _delta="force"/>
<f _delta="delete">
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b>
<c _delta="define">In self definition</c>
</b>
<d _delta="force">
<e>In parent definition</e>
</d>
<f _delta="delete">
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b/>
<d _delta="force"/>
<f _delta="define">
<g>I'm a future sibling</g>
<c>In self definition</c>
<e>In parent definition</e>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b>
<c _delta="define">In self definition</c>
</b>
<d _delta="force">
<e>In parent definition</e>
</d>
<f _delta="define">
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b/>
<d _delta="force"/>
<f>
<g>I'm a future sibling</g>
<c _delta="define">In self definition</c>
<e _delta="force">In parent definition</e>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b>
<c _delta="define">In self definition</c>
</b>
<d _delta="force">
<e>In parent definition</e>
</d>
<f>
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b/>
<f _delta="delete">
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b>
<c>Not in definition</c>
</b>
<f _delta="delete">
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b/>
<f _delta="define">
<g>I'm a future sibling</g>
<c>Not in definition</c>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b>
<c>Not in definition</c>
</b>
<f _delta="define">
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b/>
<f>
<g>I'm a future sibling</g>
<c>Not in definition</c>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<a>
<b>
<c>Not in definition</c>
</b>
<f>
<g>I'm a future sibling</g>
</f>
</a>
</itop_design>

View File

@@ -0,0 +1,189 @@
<?php
namespace Combodo\iTop\Test\UnitTest\Setup;
use Combodo\iTop\Test\UnitTest\ItopTestCase;
use DOMDocument;
use DOMXPath;
use iTopDesignFormat;
/**
* @covers iTopDesignFormat
*
* @since 2.7.0 N°2586
* @package Combodo\iTop\Test\UnitTest\Setup
*/
class iTopDesignFormatTest extends ItopTestCase
{
protected function setUp(): void
{
parent::setUp();
$this->RequireOnceItopFile('setup/modelfactory.class.inc.php');
$this->RequireOnceItopFile('setup/itopdesignformat.class.inc.php');
}
/**
* @covers iTopDesignFormat::Convert
* @dataProvider ConvertProvider
*
* @param string $sTargetVersion
* @param string $sXmlFileName Corresponding files should exist in the `Convert-samples` dir with the `.expected` and `.input` suffixes
* Example "1.7_to_1.6" for `Convert-samples/1.7_to_1.6.expected.xml` and `Convert-samples/1.7_to_1.6.input.xml`
*
* @throws \Exception
*/
public function testConvert($sTargetVersion, $sXmlFileName, $iExpectedErrors = 0, $sFirstErrorMessage = '')
{
$sSamplesRelDirPath = 'Convert-samples/';
$sInputXml = $this->GetFileContent($sSamplesRelDirPath.$sXmlFileName.'.input');
$oInputDocument = new DOMDocument();
libxml_clear_errors();
$oInputDocument->preserveWhiteSpace = false;
$oInputDocument->loadXML($sInputXml);
$oInputDocument->formatOutput = true;
$oDesignFormat = new iTopDesignFormat($oInputDocument);
$bResult = $oDesignFormat->Convert($sTargetVersion);
$aErrors = $oDesignFormat->GetErrors();
$this->assertCount($iExpectedErrors, $aErrors);
if ($iExpectedErrors > 0) {
$this->assertFalse($bResult);
$this->assertEquals($sFirstErrorMessage, $aErrors[0]);
}
$sConvertedXml = $oInputDocument->saveXML();
// Erase dynamic values
$sConvertedXml = preg_replace('@<trashed_node id="\w+"@', '<trashed_node id="XXX"', $sConvertedXml);
$sExpectedXml = $this->GetFileContent($sSamplesRelDirPath.$sXmlFileName.'.expected');
$this->assertEquals($sExpectedXml, $sConvertedXml);
}
public function ConvertProvider()
{
return [
'1.6 to 1.7 2' => ['sTargetVersion' => '1.7', 'sXmlFileName' => '1.6_to_1.7_2'],
'1.7 to 1.6' => ['sTargetVersion' => '1.6', 'sXmlFileName' => '1.7_to_1.6'],
'1.7 to 1.6 2' => ['sTargetVersion' => '1.6', 'sXmlFileName' => '1.7_to_1.6_2'],
'1.7 to 3.0' => ['sTargetVersion' => '3.0', 'sXmlFileName' => '1.7_to_3.0'],
'3.0 to 1.7' => ['sTargetVersion' => '1.7', 'sXmlFileName' => '3.0_to_1.7'],
'Bug_4569' => ['sTargetVersion' => '1.7', 'sXmlFileName' => 'Bug_4569'],
];
}
/**
* @covers iTopDesignFormat::Convert
* @dataProvider ConvertBackAndForthProvider
*
* @param string $sTargetVersion
* @param string $sXmlFileName Example "1.7_to_1.6". Corresponding files should exist with the ".input" and ".Expected" suffix
*
* @throws \Exception
*/
public function testConvertBackAndForth($sTargetVersion, $sXmlFileName)
{
$sSamplesRelDirPath = 'Convert-samples/';
$sInputXml = $this->GetFileContent($sSamplesRelDirPath.$sXmlFileName.'.input');
$oInputDocument = new DOMDocument();
libxml_clear_errors();
$oInputDocument->preserveWhiteSpace = false;
$oInputDocument->loadXML($sInputXml);
$oXPath = new DOMXPath($oInputDocument);
$oItopDesignNode = $oXPath->query('/itop_design')->item(0);
if (!$oItopDesignNode) {
$this->fail('Bad XML format');
}
$sSourceVersion = $oItopDesignNode->getAttribute('version');
$oInputDocument->formatOutput = true;
$oDesignFormat = new iTopDesignFormat($oInputDocument);
$oDesignFormat->Convert($sTargetVersion);
$sConvertedXml = $oInputDocument->saveXML();
// Convert back
$oInputDocument = new DOMDocument();
libxml_clear_errors();
$oInputDocument->preserveWhiteSpace = false;
$oInputDocument->loadXML($sConvertedXml);
$oInputDocument->formatOutput = true;
$oDesignFormat = new iTopDesignFormat($oInputDocument);
$oDesignFormat->Convert($sSourceVersion);
$sConvertedXml = $oInputDocument->saveXML();
$this->assertEquals($sInputXml, $sConvertedXml);
}
public function ConvertBackAndForthProvider()
{
return [
'1.7 to 3.0' => ['3.0', '1.7'],
];
}
/**
* @covers iTopDesignFormat::MoveNode
* @dataProvider MoveNodeProvider
*
* @param string $sXmlFileName Example "from_deleted_to_not-in-definition"
*/
public function testMoveNode(string $sXmlFileName)
{
$sSamplesRelDirPath = 'MoveNode-samples/';
$sInputXml = $this->GetFileContent($sSamplesRelDirPath.$sXmlFileName.'.input');
$sExpectedXml = $this->GetFileContent($sSamplesRelDirPath.$sXmlFileName.'.expected');
// Prepare document
$oInputDocument = new DOMDocument();
libxml_clear_errors();
$oInputDocument->preserveWhiteSpace = false;
$oInputDocument->loadXML($sInputXml);
$oInputDocument->formatOutput = true;
$oDesignFormat = new iTopDesignFormat($oInputDocument);
$oXPath = new DOMXPath($oInputDocument);
// Move nodes
// Note: We could have pass the XPaths in the provider, but as for now they are the same for all cases, it's easier to read like this. Feel free to change it in the future if necessary.
$oFNode = $oXPath->query("//f")->item(0);
// - Self node
$oCNodeList = $oXPath->query("//c");
if ($oCNodeList->length > 0) {
$oCNode = $oCNodeList->item(0);
$this->InvokeNonPublicMethod('iTopDesignFormat', 'MoveNode', $oDesignFormat, [$oCNode, $oFNode]);
}
// - In parent node
$oENodeList = $oXPath->query("//e");
if ($oENodeList->length > 0) {
$oENode = $oENodeList->item(0);
$this->InvokeNonPublicMethod('iTopDesignFormat', 'MoveNode', $oDesignFormat, [$oENode, $oFNode]);
}
$sConvertedXml = $oInputDocument->saveXML();
$this->assertEquals($sExpectedXml, $sConvertedXml);
}
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'),
);
}
private function GetFileContent($sFileName)
{
$sCurrentPath = __DIR__;
return file_get_contents($sCurrentPath.DIRECTORY_SEPARATOR.$sFileName.'.xml');
}
}

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0">
<branding>
<themes>
<theme id="fullmoon" _delta="define">
<variables>
<variable id="ibo-page-banner--background-color">$ibo-color-red-600</variable>
<variable id="ibo-page-banner--text-color">$ibo-color-red-100</variable>
<variable id="ibo-page-banner--text-content">"THIS IS A TEST INSTANCE"</variable>
</variables>
<imports>
<import id="ignored-because-lack-xsi-type">ignored-because-lack-xsi-type.scss</import>
<import id="ok-because-xsi-type-variables" xsi:type="variables">ok-because-xsi-type-variables.scss</import>
<import id="ok-because-xsi-type-utilities" xsi:type="utilities">ok-because-xsi-type-utilities.scss</import>
</imports>
<stylesheets>
<stylesheet id="fullmoon">../css/backoffice/main.scss</stylesheet>
<stylesheet id="environment-banner">../css/backoffice/themes/page-banner.scss</stylesheet>
</stylesheets>
<precompiled_stylesheet>itop-structure/precompiled-themes/test-red/main.css</precompiled_stylesheet>
</theme>
</themes>
</branding>
</itop_design>