mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
✅ ♻️ iTopDesignFormatTest : get version directly from expected content
This commit is contained in:
10
application/exceptions/iTopXmlException.php
Normal file
10
application/exceptions/iTopXmlException.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class iTopXmlException extends CoreException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -191,6 +191,7 @@ class iTopDesignFormat
|
||||
$aErrors[] = $aLogEntry['msg'];
|
||||
}
|
||||
}
|
||||
|
||||
return $aErrors;
|
||||
}
|
||||
|
||||
@@ -202,15 +203,49 @@ class iTopDesignFormat
|
||||
return $this->aLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \iTopXmlException if root node not found
|
||||
*/
|
||||
public function GetITopDesignNode(): DOMNode
|
||||
{
|
||||
$oXPath = new DOMXPath($this->oDocument);
|
||||
// Retrieve the version number
|
||||
$oNodeList = $oXPath->query('/itop_design');
|
||||
if ($oNodeList->length === 0) {
|
||||
throw new iTopXmlException('File format: no root <itop_design> tag found');
|
||||
}
|
||||
|
||||
return $oNodeList->item(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \iTopXmlException
|
||||
*/
|
||||
public function GetVersion()
|
||||
{
|
||||
$oITopDesignNode = $this->GetITopDesignNode();
|
||||
|
||||
$sVersion = $oITopDesignNode->getAttribute('version');
|
||||
if (utils::IsNullOrEmptyString($sVersion)) {
|
||||
// Originally, the information was missing: default to 1.0
|
||||
$sVersion = '1.0';
|
||||
}
|
||||
|
||||
return $sVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* An alternative to getNodePath, that gives the id of nodes instead of the position within the children
|
||||
*
|
||||
* @param $oNode
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function GetItopNodePath($oNode)
|
||||
{
|
||||
if ($oNode instanceof DOMDocument) return '';
|
||||
|
||||
|
||||
$sId = $oNode->getAttribute('id');
|
||||
$sNodeDesc = ($sId != '') ? $oNode->nodeName.'['.$sId.']' : $oNode->nodeName;
|
||||
return self::GetItopNodePath($oNode->parentNode).'/'.$sNodeDesc;
|
||||
@@ -247,30 +282,24 @@ class iTopDesignFormat
|
||||
$this->aLog = array();
|
||||
$this->bStatus = true;
|
||||
|
||||
$oXPath = new DOMXPath($this->oDocument);
|
||||
// Retrieve the version number
|
||||
$oNodeList = $oXPath->query('/itop_design');
|
||||
if ($oNodeList->length == 0)
|
||||
{
|
||||
// Hmm, not an iTop Data Model file...
|
||||
$this->LogError('File format, no root <itop_design> tag found');
|
||||
try {
|
||||
$sVersion = $this->GetVersion();
|
||||
}
|
||||
else
|
||||
{
|
||||
$sVersion = $oNodeList->item(0)->getAttribute('version');
|
||||
if ($sVersion == '')
|
||||
{
|
||||
// Originaly, the information was missing: default to 1.0
|
||||
$sVersion = '1.0';
|
||||
}
|
||||
$this->LogInfo("Converting from $sVersion to $sTargetVersion");
|
||||
$this->DoConvert($sVersion, $sTargetVersion, $oFactory);
|
||||
if ($this->bStatus)
|
||||
{
|
||||
// Update the version number
|
||||
$oNodeList->item(0)->setAttribute('version', $sTargetVersion);
|
||||
}
|
||||
catch (iTopXmlException $e) {
|
||||
$this->LogError($e->getMessage());
|
||||
|
||||
return $this->bStatus;
|
||||
}
|
||||
|
||||
$this->LogInfo("Converting from $sVersion to $sTargetVersion");
|
||||
$this->DoConvert($sVersion, $sTargetVersion, $oFactory);
|
||||
if ($this->bStatus) {
|
||||
/** @noinspection PhpUnhandledExceptionInspection already called earlier so should not crash */
|
||||
$oITopDesignNode = $this->GetITopDesignNode();
|
||||
// Update the version number
|
||||
$oITopDesignNode->setAttribute('version', $sTargetVersion);
|
||||
}
|
||||
|
||||
return $this->bStatus;
|
||||
}
|
||||
|
||||
@@ -318,22 +347,39 @@ class iTopDesignFormat
|
||||
}
|
||||
// Transform to the intermediate format
|
||||
$aCallSpec = array($this, $sTransform);
|
||||
try
|
||||
{
|
||||
try {
|
||||
call_user_func($aCallSpec, $oFactory);
|
||||
|
||||
// Recurse
|
||||
$this->DoConvert($sIntermediate, $sTo, $oFactory);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
catch (Exception $e) {
|
||||
$this->LogError($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMNode|null $node
|
||||
* @param bool $bFormatOutput
|
||||
* @param bool $bPreserveWhiteSpace
|
||||
*
|
||||
* @return false|string
|
||||
*
|
||||
* @uses \DOMDocument::saveXML()
|
||||
*/
|
||||
public function GetXmlAsString($node = null, $bFormatOutput = true, $bPreserveWhiteSpace = false)
|
||||
{
|
||||
$this->oDocument->formatOutput = $bFormatOutput;
|
||||
$this->oDocument->preserveWhiteSpace = $bPreserveWhiteSpace;
|
||||
|
||||
return $this->oDocument->saveXML($node = null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade the format from version 1.0 to 1.1
|
||||
*
|
||||
* @param \ModelFactory $oFactory
|
||||
*
|
||||
* @return void (Errors are logged)
|
||||
*/
|
||||
protected function From10To11($oFactory)
|
||||
|
||||
@@ -28,47 +28,57 @@ class iTopDesignFormatTest extends ItopTestCase
|
||||
* @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 = '')
|
||||
public function testConvert($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();
|
||||
$sExpectedXml = $this->GetFileContent($sSamplesRelDirPath.$sXmlFileName.'.expected');
|
||||
$oExpectedDesignFormat = static::GetItopFormatFromString($sExpectedXml);
|
||||
$sTargetVersion = $oExpectedDesignFormat->GetVersion();
|
||||
|
||||
$sInputXml = $this->GetFileContent($sSamplesRelDirPath.$sXmlFileName.'.input');
|
||||
$oInputDesignFormat = static::GetItopFormatFromString($sInputXml);
|
||||
$bResult = $oInputDesignFormat->Convert($sTargetVersion);
|
||||
$aErrors = $oInputDesignFormat->GetErrors();
|
||||
$this->assertCount($iExpectedErrors, $aErrors);
|
||||
if ($iExpectedErrors > 0) {
|
||||
$this->assertFalse($bResult);
|
||||
$this->assertEquals($sFirstErrorMessage, $aErrors[0]);
|
||||
}
|
||||
|
||||
$sConvertedXml = $oInputDocument->saveXML();
|
||||
/** @noinspection PhpRedundantOptionalArgumentInspection We REALLY want those options so specifying it anyway */
|
||||
$sConvertedXml = $oInputDesignFormat->GetXmlAsString(null, true, false);
|
||||
// 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);
|
||||
}
|
||||
|
||||
private static function GetItopFormatFromString(string $sFileContent): iTopDesignFormat
|
||||
{
|
||||
$oInputDocument = new DOMDocument();
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
libxml_clear_errors();
|
||||
$oInputDocument->formatOutput = true;
|
||||
$oInputDocument->preserveWhiteSpace = false;
|
||||
$oInputDocument->loadXML($sFileContent);
|
||||
|
||||
return new iTopDesignFormat($oInputDocument);
|
||||
}
|
||||
|
||||
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'],
|
||||
'1.6 to 1.7 2' => ['sXmlFileName' => '1.6_to_1.7_2'],
|
||||
'1.7 to 1.6' => ['sXmlFileName' => '1.7_to_1.6'],
|
||||
'1.7 to 1.6 2' => ['sXmlFileName' => '1.7_to_1.6_2'],
|
||||
'1.7 to 3.0' => ['sXmlFileName' => '1.7_to_3.0'],
|
||||
'3.0 to 1.7' => ['sXmlFileName' => '3.0_to_1.7'],
|
||||
'Bug_4569' => ['sXmlFileName' => 'Bug_4569'],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user