N°8796 - Add PHP code style validation in iTop and extensions - format whole code base

This commit is contained in:
odain
2025-11-07 20:39:38 +01:00
parent 7681c157ec
commit b0a792afab
369 changed files with 22041 additions and 26866 deletions

View File

@@ -6,7 +6,7 @@ echo $APPROOT;
$finder = PhpCsFixer\Finder::create()
->in($APPROOT)
->exclude(['oql', 'data', 'extensions'])
->notPath(['/env-*/', '/cache-*/', 'lib', 'vendor', 'node_modules', 'config-itop', 'php-static-analysis'])
->notPath(['/env-*/', '/cache-*/', 'lib', 'vendor', 'node_modules', 'config-itop', 'php-static-analysis', 'module.__MODULE__.php'])
;
$config = new PhpCsFixer\Config();

View File

@@ -1,10 +1,10 @@
<?php
/**
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
/**
* Copyright (C) 2013-2024 Combodo SAS
*
@@ -37,36 +37,33 @@ function ShowExamples($oP, $sExpression)
{
$bUsingExample = false;
$aExamples = array(
'Pedagogic examples' => array(
$aExamples = [
'Pedagogic examples' => [
"Web applications" => "SELECT WebApplication",
"Person having an 'A' in their name" => "SELECT Person AS B WHERE B.name LIKE '%A%'",
"Servers having a name like dbserver1.demo.com or dbserver023.foo.fr" => "SELECT Server WHERE name REGEXP '^dbserver[0-9]+\\\\..+\\\\.[a-z]{2,3}$'",
"Changes planned on new year's day" => "SELECT Change AS ch WHERE ch.start_date >= '2009-12-31' AND ch.end_date <= '2010-01-01'",
"IPs in a range" => "SELECT DatacenterDevice AS dev WHERE INET_ATON(dev.managementip) > INET_ATON('10.22.32.224') AND INET_ATON(dev.managementip) < INET_ATON('10.22.32.255')",
"Persons below a given root organization" => "SELECT Person AS P JOIN Organization AS Node ON P.org_id = Node.id JOIN Organization AS Root ON Node.parent_id BELOW Root.id WHERE Root.id=1",
),
'Usefull examples' => array(
],
'Usefull examples' => [
"NW interfaces of equipment in production for customer 'Demo'" => "SELECT PhysicalInterface AS if JOIN DatacenterDevice AS dev ON if.connectableci_id = dev.id WHERE dev.status = 'production' AND dev.organization_name = 'Demo'",
"My tickets" => "SELECT Ticket AS t WHERE t.agent_id = :current_contact_id",
"People being owner of an active ticket" => "SELECT Person AS p JOIN UserRequest AS u ON u.agent_id = p.id WHERE u.status != 'closed'",
"Contracts terminating in the next thirty days" => "SELECT Contract AS c WHERE c.end_date > NOW() AND c.end_date < DATE_ADD(NOW(), INTERVAL 30 DAY)",
"Orphan tickets (opened one hour ago, still not assigned)" => "SELECT UserRequest AS u WHERE u.start_date < DATE_SUB(NOW(), INTERVAL 60 MINUTE) AND u.status = 'new'",
"Long lasting incidents (duration > 8 hours)" => "SELECT UserRequest AS u WHERE u.close_date > DATE_ADD(u.start_date, INTERVAL 8 HOUR)",
),
);
],
];
$aDisplayData = array();
$aDisplayData = [];
$oAppContext = new ApplicationContext();
$sContext = $oAppContext->GetForForm();
foreach ($aExamples as $sTopic => $aQueries)
{
foreach ($aQueries as $sDescription => $sOql)
{
foreach ($aExamples as $sTopic => $aQueries) {
foreach ($aQueries as $sDescription => $sOql) {
$sHighlight = '';
$sDisable = '';
if ($sOql == $sExpression)
{
if ($sOql == $sExpression) {
// this one is currently being tested, highlight it
$sHighlight = "background-color:yellow;";
$sDisable = 'disabled';
@@ -74,20 +71,19 @@ function ShowExamples($oP, $sExpression)
$bUsingExample = true;
}
//$aDisplayData[$sTopic][] = array(
$aDisplayData[Dict::S('UI:RunQuery:QueryExamples')][] = array(
$aDisplayData[Dict::S('UI:RunQuery:QueryExamples')][] = [
'desc' => "<div style=\"$sHighlight\">".utils::EscapeHtml($sDescription)."</div>",
'oql' => "<div style=\"$sHighlight\">".utils::EscapeHtml($sOql)."</div>",
'go' => "<form method=\"get\"><input type=\"hidden\" name=\"expression\" value=\"$sOql\"><input type=\"submit\" value=\"".Dict::S('UI:Button:Test')."\" $sDisable>$sContext</form>\n",
);
];
}
}
$aDisplayConfig = array();
$aDisplayConfig['desc'] = array('label' => Dict::S('UI:RunQuery:HeaderPurpose'), 'description' => Dict::S('UI:RunQuery:HeaderPurpose+'));
$aDisplayConfig['oql'] = array('label' => Dict::S('UI:RunQuery:HeaderOQLExpression'), 'description' => Dict::S('UI:RunQuery:HeaderOQLExpression+'));
$aDisplayConfig['go'] = array('label' => '', 'description' => '');
$aDisplayConfig = [];
$aDisplayConfig['desc'] = ['label' => Dict::S('UI:RunQuery:HeaderPurpose'), 'description' => Dict::S('UI:RunQuery:HeaderPurpose+')];
$aDisplayConfig['oql'] = ['label' => Dict::S('UI:RunQuery:HeaderOQLExpression'), 'description' => Dict::S('UI:RunQuery:HeaderOQLExpression+')];
$aDisplayConfig['go'] = ['label' => '', 'description' => ''];
foreach ($aDisplayData as $sTopic => $aQueriesDisplayData)
{
foreach ($aDisplayData as $sTopic => $aQueriesDisplayData) {
$bShowOpened = $bUsingExample;
$oP->StartCollapsibleSection($sTopic, $bShowOpened);
$oP->table($aDisplayConfig, $aQueriesDisplayData);
@@ -107,10 +103,8 @@ $sEncoding = utils::ReadParam('encoding', 'oql');
ShowExamples($oP, $sExpression);
try
{
if ($sEncoding == 'crypted')
{
try {
if ($sEncoding == 'crypted') {
// Translate $sExpression into a oql expression
$sClearText = base64_decode($sExpression);
echo "<strong>FYI: '$sClearText'</strong><br/>\n";
@@ -119,37 +113,27 @@ try
}
$oFilter = null;
$aArgs = array();
$aArgs = [];
$sSyntaxError = null;
if (!empty($sExpression))
{
try
{
if (!empty($sExpression)) {
try {
$oFilter = DBObjectSearch::FromOQL($sExpression);
} catch (Exception $e)
{
if ($e instanceof OqlException)
{
} catch (Exception $e) {
if ($e instanceof OqlException) {
$sSyntaxError = $e->getHtmlDesc();
}
else
{
} else {
$sSyntaxError = $e->getMessage();
}
}
if ($oFilter)
{
$aArgs = array();
foreach ($oFilter->GetQueryParams() as $sParam => $foo)
{
if ($oFilter) {
$aArgs = [];
foreach ($oFilter->GetQueryParams() as $sParam => $foo) {
$value = utils::ReadParam('arg_'.$sParam, null, true, 'raw_data');
if (!is_null($value))
{
if (!is_null($value)) {
$aArgs[$sParam] = $value;
}
else {
} else {
$aArgs[$sParam] = '';
}
}
@@ -160,7 +144,8 @@ try
$oP->add("<form method=\"post\">\n");
$oP->add(Dict::S('UI:RunQuery:ExpressionToEvaluate')."<br/>\n");
$oP->add("<textarea cols=\"120\" rows=\"8\" id=\"expression\" name=\"expression\">".utils::EscapeHtml($sExpression)."</textarea>\n");
$oP->add_ready_script(<<<JS
$oP->add_ready_script(
<<<JS
$("#expression").trigger('select');
$("#expression").on('keyup', function (oEvent) {
if ((oEvent.ctrlKey || oEvent.metaKey) && oEvent.key === 'Enter') {
@@ -170,12 +155,10 @@ $("#expression").on('keyup', function (oEvent) {
JS
);
if (count($aArgs) > 0)
{
if (count($aArgs) > 0) {
$oP->add("<div class=\"wizContainer\">\n");
$oP->add("<h3>Query arguments</h3>\n");
foreach ($aArgs as $sParam => $sValue)
{
foreach ($aArgs as $sParam => $sValue) {
$oP->p("$sParam: <input type=\"string\" name=\"arg_$sParam\" value=\"$sValue\">\n");
}
$oP->add("</div>\n");
@@ -185,9 +168,7 @@ JS
$oP->add($oAppContext->GetForForm());
$oP->add("</form>\n");
if ($oFilter)
{
if ($oFilter) {
$oP->add("<h3>Query results</h3>\n");
$oResultBlock = new DisplayBlock($oFilter, 'list', false);
@@ -197,19 +178,14 @@ JS
//$iCount = $oResultBlock->GetDisplayedCount();
$sPageId = "ui-search-".$oFilter->GetClass();
$sLabel = MetaModel::GetName($oFilter->GetClass());
$aArgs = array();
foreach (array_merge($_POST, $_GET) as $sKey => $value)
{
if (is_array($value))
{
$aItems = array();
foreach ($value as $sItemKey => $sItemValue)
{
$aArgs = [];
foreach (array_merge($_POST, $_GET) as $sKey => $value) {
if (is_array($value)) {
$aItems = [];
foreach ($value as $sItemKey => $sItemValue) {
$aArgs[] = $sKey.'['.$sItemKey.']='.urlencode($sItemValue);
}
}
else
{
} else {
$aArgs[] = $sKey.'='.urlencode($value);
}
}
@@ -233,25 +209,21 @@ JS
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($oFilter);
$oBuild = new QueryBuilderContext($oFilter, $aModifierProperties);
$oSQLQueryCount = $oSQLObjectQueryBuilder->BuildSQLQueryStruct(null, true, $aModifierProperties);
$oP->p('<pre>'.$oSQLQueryCount->RenderSelect(array(), array(), 0, 0, true, true).'</pre>');
$oP->p('<pre>'.$oSQLQueryCount->RenderSelect([], [], 0, 0, true, true).'</pre>');
$oP->EndCollapsibleSection();
$oP->StartCollapsibleSection('SQL');
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($oFilter);
$oBuild = new QueryBuilderContext($oFilter, $aModifierProperties);
$oSQLQuery = $oSQLObjectQueryBuilder->BuildSQLQueryStruct(null, false, $aModifierProperties);
$oP->p('<pre>'.$oSQLQuery->RenderSelect(array(), array(), 10, 0, false, true).'</pre>');
$oP->p('<pre>'.$oSQLQuery->RenderSelect([], [], 10, 0, false, true).'</pre>');
$oP->EndCollapsibleSection();
}
elseif ($sSyntaxError)
{
if ($e instanceof OqlException)
{
} elseif ($sSyntaxError) {
if ($e instanceof OqlException) {
$sWrongWord = $e->GetWrongWord();
$aSuggestedWords = $e->GetSuggestions();
if (count($aSuggestedWords) > 0)
{
if (count($aSuggestedWords) > 0) {
$sSuggestedWord = OqlException::FindClosestString($sWrongWord, $aSuggestedWords);
if (strlen($sSuggestedWord) > 0) {
@@ -262,26 +234,18 @@ JS
$sFixedExpressionHtml = $sBefore.'<span style="background-color:yellow">'.$sSuggestedWord.'</span>'.$sAfter;
$oP->p("Suggesting: $sFixedExpressionHtml");
$oP->add('<button onClick="$(\'textarea[name=expression]\').val(\''.utils::EscapeHtml(addslashes($sFixedExpression)).'\');">Use this query</button>');
}
else
{
} else {
$oP->p('<b>'.Dict::Format('UI:RunQuery:Error', $e->getHtmlDesc()).'</b>');
}
}
else
{
} else {
$oP->p('<b>'.Dict::Format('UI:RunQuery:Error', $e->getHtmlDesc()).'</b>');
}
}
else
{
} else {
$oP->p('<b>'.Dict::Format('UI:RunQuery:Error', $e->getMessage()).'</b>');
}
}
} catch (Exception $e)
{
} catch (Exception $e) {
$oP->p('<b>'.Dict::Format('UI:RunQuery:Error', $e->getMessage()).'</b>');
}
$oP->output();

View File

@@ -27,15 +27,11 @@ function LogResult($sString)
function LogBenchmarkCSV()
{
$aValues = array();
foreach (func_get_args() as $arg)
{
if (is_string($arg))
{
$aValues = [];
foreach (func_get_args() as $arg) {
if (is_string($arg)) {
$aValues[] = '"'.str_replace('"', '""', $arg).'"';
}
else
{
} else {
$aValues[] = (string) $arg;
}
}
@@ -47,18 +43,17 @@ class QueryLogEntry
{
public function __construct($aLogEntryId, $aLogEntryData)
{
$this->aErrors = array();
$this->aErrors = [];
$this->sSql = '';
$this->MakeDuration = 0;
$this->fExecDuration = 0;
$this->iTableCount = 0;
$this->aRows = array();
$this->aRows = [];
$this->sLogId = $aLogEntryId;
$this->sOql = $aLogEntryData['oql'];
$this->sOqlHtml = htmlentities($this->sOql, ENT_QUOTES, 'UTF-8');
$aQueryData = unserialize($aLogEntryData['data']);
$this->oFilter = $aQueryData['filter'];
$this->sClass = $this->oFilter->GetClass();
@@ -66,8 +61,7 @@ class QueryLogEntry
$iRepeat = utils::ReadParam('repeat', 3);
if ($aQueryData['type'] == 'select')
{
if ($aQueryData['type'] == 'select') {
$this->aOrderBy = $aQueryData['order_by'];
$this->aAttToLoad = $aQueryData['att_to_load'];
$this->aExtendedDataSpec = $aQueryData['extended_data_spec'];
@@ -75,68 +69,50 @@ class QueryLogEntry
$this->iLimitStart = $aQueryData['limit_start'];
$this->bGetCount = $aQueryData['is_count'];
if ($this->bGetCount)
{
if ($this->bGetCount) {
$this->sQueryType = 'COUNT';
$this->sQueryDesc = '';
}
else
{
} else {
$this->sQueryType = 'LIST';
$this->sQueryDesc = "limit count: $this->iLimitCount";
$this->sQueryDesc .= "; limit start: $this->iLimitStart";
if (count($this->aOrderBy) > 0)
{
if (count($this->aOrderBy) > 0) {
$this->sQueryDesc .= "; order by: ".implode(',', array_keys($this->aOrderBy));
}
if (is_array($this->aAttToLoad))
{
if (is_array($this->aAttToLoad)) {
$this->sQueryDesc .= "; attributes: ".implode(',', array_keys($this->aAttToLoad));
}
}
$fRefTime = MyHelpers::getmicrotime();
try
{
for($i = 0 ; $i < $iRepeat ; $i++)
{
try {
for ($i = 0 ; $i < $iRepeat ; $i++) {
$this->sSql = $this->oFilter->MakeSelectQuery($this->aOrderBy, $this->aArgs, $this->aAttToLoad, $this->aExtendedDataSpec, $this->iLimitCount, $this->iLimitStart, $this->bGetCount);
}
}
catch(Exception $e)
{
} catch (Exception $e) {
$this->aErrors[] = "Failed to create the SQL:".$e->getMessage();
}
$this->fMakeDuration = (MyHelpers::getmicrotime() - $fRefTime) / $iRepeat;
}
elseif ($aQueryData['type'] == 'group_by')
{
} elseif ($aQueryData['type'] == 'group_by') {
$this->aGroupByExpr = $aQueryData['group_by_expr'];
$this->sQueryType = 'GROUP BY';
$aGroupedBy = array();
foreach ($this->aGroupByExpr as $oExpr)
{
$aGroupedBy = [];
foreach ($this->aGroupByExpr as $oExpr) {
$aGroupedBy[] = $oExpr->RenderExpression();
}
$this->sQueryDesc = implode(', ', $aGroupedBy);
$fRefTime = MyHelpers::getmicrotime();
try
{
for($i = 0 ; $i < $iRepeat ; $i++)
{
try {
for ($i = 0 ; $i < $iRepeat ; $i++) {
$this->sSql = $this->oFilter->MakeGroupByQuery($this->aArgs, $this->aGroupByExpr);
}
}
catch(Exception $e)
{
} catch (Exception $e) {
$this->aErrors[] = "Failed to create the SQL:".$e->getMessage();
}
$this->fMakeDuration = (MyHelpers::getmicrotime() - $fRefTime) / $iRepeat;
}
else
{
} else {
// unsupported
$this->sQueryType = 'ERROR';
$this->sQueryDesc = "Unkown type of query: ".$aQueryData['type'];
@@ -145,44 +121,34 @@ class QueryLogEntry
public function Exec()
{
if ($this->sSql != '')
{
if ($this->sSql != '') {
$iRepeat = utils::ReadParam('repeat', 3);
try
{
try {
$resQuery = null;
$fRefTime = MyHelpers::getmicrotime();
for($i = 0 ; $i < $iRepeat ; $i++)
{
for ($i = 0 ; $i < $iRepeat ; $i++) {
$resQuery = CMDBSource::Query($this->sSql);
}
$this->fExecDuration = (MyHelpers::getmicrotime() - $fRefTime) / $iRepeat;
// This is not relevant...
if (preg_match_all('|\s*JOIN\s*\(\s*`|', $this->sSql, $aMatches)) // JOIN (`mytable...
{
// This is not relevant...
if (preg_match_all('|\s*JOIN\s*\(\s*`|', $this->sSql, $aMatches)) { // JOIN (`mytable...
$this->iTableCount = 1 + count($aMatches[0]);
}
else
{
} else {
$this->iTableCount = 1;
}
}
catch (Exception $e)
{
} catch (Exception $e) {
$this->aErrors[] = "Failed to execute the SQL:".$e->getMessage();
}
if ($resQuery)
{
while ($aRow = CMDBSource::FetchArray($resQuery))
{
if ($resQuery) {
while ($aRow = CMDBSource::FetchArray($resQuery)) {
$this->aRows[] = $aRow;
}
CMDBSource::FreeResult($resQuery);
}
}
}
public function HasErrors()
{
return (count($this->aErrors) > 0);
@@ -193,8 +159,7 @@ class QueryLogEntry
$oP->p($this->sOqlHtml);
$oP->p($this->sQueryType);
$oP->p($this->sQueryDesc);
foreach ($this->aErrors as $sError)
{
foreach ($this->aErrors as $sError) {
$oP->p($sError);
}
}
@@ -217,7 +182,6 @@ LoginWebPage::DoLogin(); // Check user rights and prompt if needed
$oP = new WebPage('Replay queries.log');
ini_set('memory_limit', '512M');
require_once(APPROOT.'/data/queries.log');
@@ -226,131 +190,113 @@ $oP->p("Nombre de requêtes: ".$iCount);
$sOperation = utils::ReadParam('operation', '');
switch ($sOperation)
{
case '':
default:
$oP->add("<ol>\n");
foreach ($aQueriesLog as $sQueryId => $aOqlData)
{
$sOql = $aOqlData['oql'];
$sOqlHtml = htmlentities($sOql, ENT_QUOTES, 'UTF-8');
$oP->add("<li>$sOqlHtml <a href=\"?operation=zoom&query=$sQueryId\">zoom</a></li>\n");
}
$oP->add("</ol>\n");
$oP->add("<form action=\"?operation=benchmark&repeat=3\" method=\"post\">\n");
$oP->add("<input type=\"submit\" value=\"Benchmark (3 repeats)!\">\n");
$oP->add("</form>\n");
$oP->add("<form action=\"?operation=check\" method=\"post\">\n");
$oP->add("<input type=\"submit\" value=\"Check!\">\n");
$oP->add("</form>\n");
break;
case 'zoom':
$sQueryId = utils::ReadParam('query', '', false, 'raw_data');
$oP->add("<h2>Zoom on query</h2>\n");
$oQuery = new QueryLogEntry($sQueryId, $aQueriesLog[$sQueryId]);
$oQuery->Exec();
$oQuery->Display($oP);
$oP->add("<pre>$oQuery->sSql</pre>\n");
$oP->p("Tables: $oQuery->iTableCount");
if (strlen($oQuery->sSql) > 0)
{
$aExplain = CMDBSource::ExplainQuery($oQuery->sSql);
$oP->add("<h4>Explain</h4>\n");
$oP->add("<table style=\"border=1px;\">\n");
foreach ($aExplain as $aRow)
{
$oP->add(" <tr>\n");
$oP->add(" <td>".implode('</td><td>', $aRow)."</td>\n");
$oP->add(" </tr>\n");
switch ($sOperation) {
case '':
default:
$oP->add("<ol>\n");
foreach ($aQueriesLog as $sQueryId => $aOqlData) {
$sOql = $aOqlData['oql'];
$sOqlHtml = htmlentities($sOql, ENT_QUOTES, 'UTF-8');
$oP->add("<li>$sOqlHtml <a href=\"?operation=zoom&query=$sQueryId\">zoom</a></li>\n");
}
$oP->add("</table>\n");
}
if (count($oQuery->aRows))
{
$oP->add("<h4>Values</h4>\n");
$oP->add("<table style=\"border=1px;\">\n");
foreach ($oQuery->aRows as $iRow => $aRow)
{
$oP->add(" <tr>\n");
$oP->add(" <td>".implode('</td><td>', $aRow)."</td>\n");
$oP->add(" </tr>\n");
}
$oP->add("</table>\n");
}
else
{
$oP->p("No data");
}
break;
$oP->add("</ol>\n");
$oP->add("<form action=\"?operation=benchmark&repeat=3\" method=\"post\">\n");
$oP->add("<input type=\"submit\" value=\"Benchmark (3 repeats)!\">\n");
$oP->add("</form>\n");
case 'check':
$oP->add("<h2>List queries in error</h2>\n");
foreach ($aQueriesLog as $sQueryId => $aOqlData)
{
$oQuery = new QueryLogEntry($sQueryId, $aOqlData);
$oP->add("<form action=\"?operation=check\" method=\"post\">\n");
$oP->add("<input type=\"submit\" value=\"Check!\">\n");
$oP->add("</form>\n");
break;
case 'zoom':
$sQueryId = utils::ReadParam('query', '', false, 'raw_data');
$oP->add("<h2>Zoom on query</h2>\n");
$oQuery = new QueryLogEntry($sQueryId, $aQueriesLog[$sQueryId]);
$oQuery->Exec();
if ($oQuery->HasErrors())
{
$oQuery->Display($oP);
$oP->p("<a href=\"?operation=zoom&query=$sQueryId\">zoom</a>");
$oQuery->Display($oP);
$oP->add("<pre>$oQuery->sSql</pre>\n");
$oP->p("Tables: $oQuery->iTableCount");
if (strlen($oQuery->sSql) > 0) {
$aExplain = CMDBSource::ExplainQuery($oQuery->sSql);
$oP->add("<h4>Explain</h4>\n");
$oP->add("<table style=\"border=1px;\">\n");
foreach ($aExplain as $aRow) {
$oP->add(" <tr>\n");
$oP->add(" <td>".implode('</td><td>', $aRow)."</td>\n");
$oP->add(" </tr>\n");
}
$oP->add("</table>\n");
}
}
break;
case 'benchmark':
$oP->add("<h2>Create data/queries.xxx reports</h2>\n");
// Reset the log contents
file_put_contents(utils::GetDataPath().'queries.results.log', date('Y-m-d H:i:s')."\n");
file_put_contents(utils::GetDataPath().'queries.benchmark.csv', '');
LogBenchmarkCSV('type', 'properties', 'make duration', 'class', 'tables', 'query length', 'exec duration', 'rows', 'oql');
$iErrors = 0;
foreach ($aQueriesLog as $sQueryId => $aOqlData)
{
$oQuery = new QueryLogEntry($sQueryId, $aOqlData);
$oQuery->Exec();
LogResult('-----------------------------------------------------------');
LogResult($oQuery->sOql);
LogResult($oQuery->sQueryType);
if (strlen($oQuery->sQueryDesc) > 0)
{
LogResult($oQuery->sQueryDesc);
if (count($oQuery->aRows)) {
$oP->add("<h4>Values</h4>\n");
$oP->add("<table style=\"border=1px;\">\n");
foreach ($oQuery->aRows as $iRow => $aRow) {
$oP->add(" <tr>\n");
$oP->add(" <td>".implode('</td><td>', $aRow)."</td>\n");
$oP->add(" </tr>\n");
}
$oP->add("</table>\n");
} else {
$oP->p("No data");
}
if ($oQuery->HasErrors())
{
foreach($oQuery->aErrors as $sError)
{
LogResult($sError);
$iErrors++;
break;
case 'check':
$oP->add("<h2>List queries in error</h2>\n");
foreach ($aQueriesLog as $sQueryId => $aOqlData) {
$oQuery = new QueryLogEntry($sQueryId, $aOqlData);
$oQuery->Exec();
if ($oQuery->HasErrors()) {
$oQuery->Display($oP);
$oP->p("<a href=\"?operation=zoom&query=$sQueryId\">zoom</a>");
}
}
else
{
LogResult("row count = ".count($oQuery->aRows));
foreach($oQuery->aRows as $iRow => $aRow)
{
LogResult("row: ".serialize($aRow));
if ($iRow > 100) break;
break;
case 'benchmark':
$oP->add("<h2>Create data/queries.xxx reports</h2>\n");
// Reset the log contents
file_put_contents(utils::GetDataPath().'queries.results.log', date('Y-m-d H:i:s')."\n");
file_put_contents(utils::GetDataPath().'queries.benchmark.csv', '');
LogBenchmarkCSV('type', 'properties', 'make duration', 'class', 'tables', 'query length', 'exec duration', 'rows', 'oql');
$iErrors = 0;
foreach ($aQueriesLog as $sQueryId => $aOqlData) {
$oQuery = new QueryLogEntry($sQueryId, $aOqlData);
$oQuery->Exec();
LogResult('-----------------------------------------------------------');
LogResult($oQuery->sOql);
LogResult($oQuery->sQueryType);
if (strlen($oQuery->sQueryDesc) > 0) {
LogResult($oQuery->sQueryDesc);
}
if ($oQuery->HasErrors()) {
foreach ($oQuery->aErrors as $sError) {
LogResult($sError);
$iErrors++;
}
} else {
LogResult("row count = ".count($oQuery->aRows));
foreach ($oQuery->aRows as $iRow => $aRow) {
LogResult("row: ".serialize($aRow));
if ($iRow > 100) {
break;
}
}
LogBenchmarkCSV($oQuery->sQueryType, $oQuery->sQueryDesc, sprintf('%1.3f', round($oQuery->fMakeDuration, 3)), $oQuery->sClass, $oQuery->iTableCount, strlen($oQuery->sSql), sprintf('%1.4f', round($oQuery->fExecDuration, 4)), count($oQuery->aRows), $oQuery->sOql);
}
LogBenchmarkCSV($oQuery->sQueryType, $oQuery->sQueryDesc, sprintf('%1.3f', round($oQuery->fMakeDuration, 3)), $oQuery->sClass, $oQuery->iTableCount, strlen($oQuery->sSql), sprintf('%1.4f', round($oQuery->fExecDuration, 4)), count($oQuery->aRows), $oQuery->sOql);
}
}
}
$oP->output();
?>

View File

@@ -1,4 +1,5 @@
<?php
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
@@ -48,7 +49,6 @@ use VirtualHost;
use VirtualMachine;
use XMLDataLoader;
/** @see \Combodo\iTop\Test\UnitTest\ItopDataTestCase::CreateObjectWithTagSet() */
define('TAG_CLASS', 'FAQ');
define('TAG_ATTCODE', 'domains');
@@ -80,9 +80,9 @@ abstract class ItopDataTestCase extends ItopTestCase
/**
* @var string Default environment to use for test cases
*/
const DEFAULT_TEST_ENVIRONMENT = 'production';
const USE_TRANSACTION = true;
const CREATE_TEST_ORG = false;
public const DEFAULT_TEST_ENVIRONMENT = 'production';
public const USE_TRANSACTION = true;
public const CREATE_TEST_ORG = false;
protected static $aURP_Profiles = [
'Administrator' => 1,
@@ -126,15 +126,13 @@ abstract class ItopDataTestCase extends ItopTestCase
$this->PrepareEnvironment();
if (static::USE_TRANSACTION)
{
if (static::USE_TRANSACTION) {
CMDBSource::Query('START TRANSACTION');
}
if (static::CREATE_TEST_ORG)
{
if (static::CREATE_TEST_ORG) {
// Create a specific organization for the tests
$this->iTestOrgId = $this->GivenObjectInDB('Organization', [
'name' => 'UnitTestOrganization',
'name' => 'UnitTestOrganization',
]);
}
@@ -166,17 +164,14 @@ abstract class ItopDataTestCase extends ItopTestCase
} else {
$this->debug("");
$this->aCreatedObjects = array_reverse($this->aCreatedObjects);
foreach ($this->aCreatedObjects as $oObject)
{
foreach ($this->aCreatedObjects as $oObject) {
/** @var DBObject $oObject */
try
{
try {
$sClass = get_class($oObject);
$iKey = $oObject->GetKey();
$this->debug("Removing $sClass::$iKey");
$oObject->DBDelete();
}
catch (Exception $e) {
} catch (Exception $e) {
$this->debug("Error when removing created objects: $sClass::$iKey. Exception message: ".$e->getMessage());
}
}
@@ -201,7 +196,8 @@ abstract class ItopDataTestCase extends ItopTestCase
/**
* Helper to reset the metamodel cache : for a class and a key it will contain the SQL query, that could include silo filter
*/
protected function ResetMetaModelQueyCacheGetObject() {
protected function ResetMetaModelQueyCacheGetObject()
{
$this->SetNonPublicStaticProperty(MetaModel::class, 'aQueryCacheGetObject', []);
}
@@ -316,8 +312,7 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function createObject($sClass, $aParams)
{
$oMyObj = MetaModel::NewObject($sClass);
foreach ($aParams as $sAttCode => $oValue)
{
foreach ($aParams as $sAttCode => $oValue) {
$oMyObj->Set($sAttCode, $oValue);
}
$oMyObj->DBInsert();
@@ -341,8 +336,7 @@ abstract class ItopDataTestCase extends ItopTestCase
protected static function updateObject($sClass, $iKey, $aParams)
{
$oMyObj = MetaModel::GetObject($sClass, $iKey);
foreach ($aParams as $sAttCode => $oValue)
{
foreach ($aParams as $sAttCode => $oValue) {
$oMyObj->Set($sAttCode, $oValue);
}
$oMyObj->DBUpdate();
@@ -361,9 +355,9 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function CreateOrganization($sName)
{
/** @var \Organization $oObj */
$oObj = $this->createObject('Organization', array(
$oObj = $this->createObject('Organization', [
'name' => $sName,
));
]);
$this->debug("Created Organization {$oObj->Get('name')}");
return $oObj;
@@ -380,13 +374,13 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function CreateTicket($iNum)
{
/** @var Ticket $oTicket */
$oTicket = $this->createObject('UserRequest', array(
$oTicket = $this->createObject('UserRequest', [
'ref' => 'Ticket_'.$iNum,
'title' => 'TICKET_'.$iNum,
//'request_type' => 'incident',
'description' => 'Created for unit tests.',
'org_id' => $this->getTestOrgId(),
));
]);
$this->debug("Created {$oTicket->Get('title')} ({$oTicket->Get('ref')})");
return $oTicket;
@@ -412,13 +406,13 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function CreateTagData($sClass, $sAttCode, $sTagCode, $sTagLabel, $sTagDescription = '')
{
$sTagClass = TagSetFieldData::GetTagDataClassName($sClass, $sAttCode);
$oTagData = $this->createObject($sTagClass, array(
$oTagData = $this->createObject($sTagClass, [
'code' => $sTagCode,
'label' => $sTagLabel,
'obj_class' => $sClass,
'obj_attcode' => $sAttCode,
'description' => $sTagDescription,
));
]);
$this->debug("Created {$oTagData->Get('code')} ({$oTagData->Get('label')})");
/** @var \TagSetFieldData $oTagData */
@@ -451,7 +445,7 @@ abstract class ItopDataTestCase extends ItopTestCase
private function RemoveObjects($sClass, $sOQL)
{
$oFilter = DBSearch::FromOQL($sOQL);
$aRes = $oFilter->ToDataArray(array('id'));
$aRes = $oFilter->ToDataArray(['id']);
foreach ($aRes as $aRow) {
$this->debug($aRow);
$iKey = $aRow['id'];
@@ -462,7 +456,8 @@ abstract class ItopDataTestCase extends ItopTestCase
}
}
protected function GetUserRequestParams($iNum) {
protected function GetUserRequestParams($iNum)
{
return [
'ref' => 'Ticket_'.$iNum,
'title' => 'BUG 1161_'.$iNum,
@@ -488,7 +483,8 @@ abstract class ItopDataTestCase extends ItopTestCase
* @uses \array_merge()
* @uses createObject
*/
protected function CreateUserRequest($iNum, $aUserRequestCustomParams = []) {
protected function CreateUserRequest($iNum, $aUserRequestCustomParams = [])
{
$aUserRequestDefaultParams = $this->GetUserRequestParams($iNum);
$aUserRequestParams = array_merge($aUserRequestDefaultParams, $aUserRequestCustomParams);
@@ -512,11 +508,11 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function CreateServer($iNum, $iRackUnit = null)
{
/** @var Server $oServer */
$oServer = $this->createObject('Server', array(
$oServer = $this->createObject('Server', [
'name' => 'Server_'.$iNum,
'org_id' => $this->getTestOrgId(),
'nb_u' => $iRackUnit,
));
]);
$this->debug("Created {$oServer->GetName()} ({$oServer->GetKey()})");
return $oServer;
@@ -534,11 +530,11 @@ abstract class ItopDataTestCase extends ItopTestCase
*/
protected function CreatePhysicalInterface($iNum, $iSpeed, $iConnectableCiId)
{
$oObj = $this->createObject('PhysicalInterface', array(
$oObj = $this->createObject('PhysicalInterface', [
'name' => "$iNum",
'speed' => $iSpeed,
'connectableci_id' => $iConnectableCiId,
));
]);
$this->debug("Created {$oObj->GetName()} ({$oObj->GetKey()})");
return $oObj;
@@ -556,11 +552,11 @@ abstract class ItopDataTestCase extends ItopTestCase
*/
protected function CreateFiberChannelInterface($iNum, $iSpeed, $iConnectableCiId)
{
$oObj = $this->createObject('FiberChannelInterface', array(
$oObj = $this->createObject('FiberChannelInterface', [
'name' => "$iNum",
'speed' => $iSpeed,
'datacenterdevice_id' => $iConnectableCiId,
));
]);
$this->debug("Created {$oObj->GetName()} ({$oObj->GetKey()})");
return $oObj;
@@ -578,11 +574,11 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function CreatePerson($iNum, $iOrgId = 0)
{
/** @var Person $oPerson */
$oPerson = $this->createObject('Person', array(
$oPerson = $this->createObject('Person', [
'name' => 'Person_'.$iNum,
'first_name' => 'Test',
'org_id' => ($iOrgId == 0 ? $this->getTestOrgId() : $iOrgId),
));
]);
$this->debug("Created {$oPerson->GetName()} ({$oPerson->GetKey()})");
return $oPerson;
@@ -595,7 +591,7 @@ abstract class ItopDataTestCase extends ItopTestCase
* @return \UserLocal
* @throws Exception
*/
protected function CreateUser($sLogin, $iProfileId, $sPassword=null, $iContactid=2)
protected function CreateUser($sLogin, $iProfileId, $sPassword = null, $iContactid = 2)
{
$oUser = $this->CreateContactlessUser($sLogin, $iProfileId, $sPassword);
$oUser->Set('contactid', $iContactid);
@@ -610,9 +606,9 @@ abstract class ItopDataTestCase extends ItopTestCase
* @return \UserLocal
* @throws Exception
*/
protected function CreateContactlessUser($sLogin, $iProfileId, $sPassword=null)
protected function CreateContactlessUser($sLogin, $iProfileId, $sPassword = null)
{
if (empty($sPassword)){
if (empty($sPassword)) {
$sPassword = $sLogin;
}
@@ -620,12 +616,12 @@ abstract class ItopDataTestCase extends ItopTestCase
$oSet->AddItem(MetaModel::NewObject('URP_UserProfile', ['profileid' => $iProfileId, 'reason' => 'UNIT Tests']));
/** @var \UserLocal $oUser */
$oUser = $this->createObject('UserLocal', array(
$oUser = $this->createObject('UserLocal', [
'login' => $sLogin,
'password' => $sPassword,
'language' => 'EN US',
'profile_list' => $oSet,
));
]);
$this->debug("Created {$oUser->GetName()} ({$oUser->GetKey()})");
return $oUser;
@@ -646,15 +642,14 @@ abstract class ItopDataTestCase extends ItopTestCase
/** @var \ormLinkSet $oSet */
$oSet = $oUser->Get('profile_list');
$oSet->AddItem($oUserProfile);
$oUser = $this->updateObject(User::class, $oUser->GetKey(), array(
$oUser = $this->updateObject(User::class, $oUser->GetKey(), [
'profile_list' => $oSet,
));
]);
$this->debug("Updated {$oUser->GetName()} ({$oUser->GetKey()})");
return $oUser;
}
/**
* Create a Hypervisor in database
*
@@ -668,18 +663,15 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function CreateHypervisor($iNum, $oServer, $oFarm = null)
{
/** @var Hypervisor $oHypervisor */
$oHypervisor = $this->createObject('Hypervisor', array(
$oHypervisor = $this->createObject('Hypervisor', [
'name' => 'Hypervisor_'.$iNum,
'org_id' => $this->getTestOrgId(),
'server_id' => $oServer->GetKey(),
'farm_id' => is_null($oFarm) ? 0 : $oFarm->GetKey(),
));
if (is_null($oFarm))
{
]);
if (is_null($oFarm)) {
$this->debug("Created {$oHypervisor->GetName()} ({$oHypervisor->GetKey()}) on {$oServer->GetName()}");
}
else
{
} else {
$this->debug("Created {$oHypervisor->GetName()} ({$oHypervisor->GetKey()}) on {$oServer->GetName()} part of {$oFarm->GetName()}");
}
@@ -698,11 +690,11 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function CreateFarm($iNum, $sRedundancy = '1')
{
/** @var Farm $oFarm */
$oFarm = $this->createObject('Farm', array(
$oFarm = $this->createObject('Farm', [
'name' => 'Farm_'.$iNum,
'org_id' => $this->getTestOrgId(),
'redundancy' => $sRedundancy,
));
]);
$this->debug("Created {$oFarm->GetName()} ({$oFarm->GetKey()}) redundancy $sRedundancy");
return $oFarm;
@@ -720,11 +712,11 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function CreateVirtualMachine($iNum, $oVirtualHost)
{
/** @var VirtualMachine $oVirtualMachine */
$oVirtualMachine = $this->createObject('VirtualMachine', array(
$oVirtualMachine = $this->createObject('VirtualMachine', [
'name' => 'VirtualMachine_'.$iNum,
'org_id' => $this->getTestOrgId(),
'virtualhost_id' => $oVirtualHost->GetKey(),
));
]);
$this->debug("Created {$oVirtualMachine->GetName()} ({$oVirtualMachine->GetKey()}) on {$oVirtualHost->GetName()}");
return $oVirtualMachine;
@@ -733,24 +725,22 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function CreateObjectWithTagSet()
{
$oFaqCategory = MetaModel::GetObject('FAQCategory', 1, false);
if (empty($oFaqCategory))
{
$oFaqCategory = $this->createObject('FAQCategory', array(
if (empty($oFaqCategory)) {
$oFaqCategory = $this->createObject('FAQCategory', [
'name' => 'FAQCategory_phpunit',
));
]);
}
/** @var \FAQ $oFaq */
$oFaq = $this->createObject('FAQ', array(
$oFaq = $this->createObject('FAQ', [
'category_id' => $oFaqCategory->GetKey(),
'title' => 'FAQ_phpunit',
));
]);
$this->debug("Created {$oFaq->GetName()}");
return $oFaq;
}
/**
* Add a link between a contact and a CI.
* The database is not updated.
@@ -786,10 +776,8 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function RemoveContactFromCI($oContact, $oCI)
{
$oContacts = $oCI->Get('contacts_list');
foreach ($oContacts as $oLnk)
{
if ($oLnk->Get('contact_id') == $oContact->GetKey())
{
foreach ($oContacts as $oLnk) {
if ($oLnk->Get('contact_id') == $oContact->GetKey()) {
$oContacts->RemoveItem($oLnk->GetKey());
$oCI->Set('contacts_list', $oContacts);
$this->debug("Removed {$oContact->GetName()} from {$oCI->Get('name')}");
@@ -821,7 +809,7 @@ abstract class ItopDataTestCase extends ItopTestCase
$this->debug("Added {$oCI->GetName()} to {$oTicket->Get('ref')} with {$sImpactCode}");
return array($oCI->GetKey() => $sImpactCode);
return [$oCI->GetKey() => $sImpactCode];
}
/**
@@ -836,10 +824,8 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function RemoveCIFromTicket($oCI, $oTicket)
{
$oCIs = $oTicket->Get('functionalcis_list');
foreach ($oCIs as $oLnk)
{
if ($oLnk->Get('functionalci_id') == $oCI->GetKey())
{
foreach ($oCIs as $oLnk) {
if ($oLnk->Get('functionalci_id') == $oCI->GetKey()) {
$sImpactCode = $oLnk->Get('impact_code');
$oCIs->RemoveItem($oLnk->GetKey());
$oTicket->Set('functionalcis_list', $oCIs);
@@ -864,13 +850,12 @@ abstract class ItopDataTestCase extends ItopTestCase
* @return array
* @throws Exception
*/
protected function AddContactToTicket($oContact, $oTicket, $sRoleCode, $aParams = array())
protected function AddContactToTicket($oContact, $oTicket, $sRoleCode, $aParams = [])
{
$oNewLink = new lnkContactToTicket();
$oNewLink->Set('contact_id', $oContact->GetKey());
$oNewLink->Set('role_code', $sRoleCode);
foreach ($aParams as $sAttCode => $oValue)
{
foreach ($aParams as $sAttCode => $oValue) {
$oNewLink->Set($sAttCode, $oValue);
}
$oCIs = $oTicket->Get('contacts_list');
@@ -879,7 +864,7 @@ abstract class ItopDataTestCase extends ItopTestCase
$this->debug("Added {$oContact->GetName()} to {$oTicket->Get('ref')} with {$sRoleCode}");
return array($oContact->GetKey() => $sRoleCode);
return [$oContact->GetKey() => $sRoleCode];
}
/**
@@ -894,10 +879,8 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function RemoveContactFromTicket($oContact, $oTicket)
{
$oContacts = $oTicket->Get('contacts_list');
foreach ($oContacts as $oLnk)
{
if ($oLnk->Get('contact_id') == $oContact->GetKey())
{
foreach ($oContacts as $oLnk) {
if ($oLnk->Get('contact_id') == $oContact->GetKey()) {
$sRoleCode = $oLnk->Get('role_code');
$oContacts->RemoveItem($oLnk->GetKey());
$oTicket->Set('contacts_list', $oContacts);
@@ -948,18 +931,14 @@ abstract class ItopDataTestCase extends ItopTestCase
$oFunction();
$iFinalCount = (int) CMDBSource::QueryToScalar("SHOW SESSION STATUS LIKE 'Queries'", 1);
$iCount = $iFinalCount - 1 - $iInitialCount;
if ($iCount != $iExpectedCount)
{
if ($iCount != $iExpectedCount) {
if ($sMessage === '') {
$sMessage = "Expected $iExpectedCount queries. $iCount have been executed.";
}
else {
} else {
$sMessage .= " - Expected $iExpectedCount queries. $iCount have been executed.";
}
$this->fail($sMessage);
}
else
{
} else {
// Otherwise, PHP Unit will consider that no assertion has been made
$this->assertTrue(true);
}
@@ -1001,8 +980,6 @@ abstract class ItopDataTestCase extends ItopTestCase
$this->assertStringContainsString($sNeedle, $aLastLines[0], $sMessage);
}
/**
* Import a set of XML files describing a consistent set of iTop objects
* @param string[] $aFiles
@@ -1014,8 +991,7 @@ abstract class ItopDataTestCase extends ItopTestCase
{
$oLoader = new XMLDataLoader();
$oLoader->StartSession(CMDBObject::GetCurrentChange());
foreach($aFiles as $sFilePath)
{
foreach ($aFiles as $sFilePath) {
$oLoader->LoadFile($sFilePath, false, $bSearch);
}
$oLoader->EndSession();
@@ -1042,7 +1018,6 @@ abstract class ItopDataTestCase extends ItopTestCase
return $ret;
}
protected function DBInsertSingleTable($sTableClass, $aValues, $iKey = 0)
{
$sTable = MetaModel::DBGetTable($sTableClass);
@@ -1052,8 +1027,8 @@ abstract class ItopDataTestCase extends ItopTestCase
}
// fields in first array, values in the second
$aFieldsToWrite = array();
$aValuesToWrite = array();
$aFieldsToWrite = [];
$aValuesToWrite = [];
if (!empty($iKey) && ($iKey >= 0)) {
// Add it to the list of fields to write
@@ -1061,7 +1036,7 @@ abstract class ItopDataTestCase extends ItopTestCase
$aValuesToWrite[] = CMDBSource::Quote($iKey);
}
$aHierarchicalKeys = array();
$aHierarchicalKeys = [];
foreach (MetaModel::ListAttributeDefs($sTableClass) as $sAttCode => $oAttDef) {
// Skip this attribute if not defined in this table
@@ -1118,8 +1093,7 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function GivenObject(string $sClass, array $aParams): DBObject
{
$oMyObj = MetaModel::NewObject($sClass);
foreach ($aParams as $sAttCode => $oValue)
{
foreach ($aParams as $sAttCode => $oValue) {
$oMyObj->Set($sAttCode, $oValue);
}
@@ -1374,16 +1348,14 @@ abstract class ItopDataTestCase extends ItopTestCase
$this->debug("Added CI $sCIId to {$oTicket->Get('ref')} with {$sImpactCode}");
return array($sCIId => $sImpactCode);
return [$sCIId => $sImpactCode];
}
protected function RemoveLnkFunctionalCIToTicketObject($sCIId, $oTicket)
{
$oCIs = $oTicket->Get('functionalcis_list');
foreach ($oCIs as $oLnk)
{
if ($oLnk->Get('functionalci_id') == $sCIId)
{
foreach ($oCIs as $oLnk) {
if ($oLnk->Get('functionalci_id') == $sCIId) {
$sImpactCode = $oLnk->Get('impact_code');
$oCIs->RemoveItem($oLnk->GetKey());
$oTicket->Set('functionalcis_list', $oCIs);
@@ -1396,7 +1368,7 @@ abstract class ItopDataTestCase extends ItopTestCase
$this->assertTrue(false);
}
protected function AddLnkContactToTicketObject($sContactId, $oTicket, $sRoleCode, $aParams = array()): array
protected function AddLnkContactToTicketObject($sContactId, $oTicket, $sRoleCode, $aParams = []): array
{
$aParams['contact_id'] = $sContactId;
$aParams['role_code'] = $sRoleCode;
@@ -1408,16 +1380,14 @@ abstract class ItopDataTestCase extends ItopTestCase
$this->debug("Added contact $sContactId to {$oTicket->Get('ref')} with {$sRoleCode}");
return array($sContactId => $sRoleCode);
return [$sContactId => $sRoleCode];
}
protected function RemoveLnkContactToTicketObject($sContactId, $oTicket)
{
$oContacts = $oTicket->Get('contacts_list');
foreach ($oContacts as $oLnk)
{
if ($oLnk->Get('contact_id') == $sContactId)
{
foreach ($oContacts as $oLnk) {
if ($oLnk->Get('contact_id') == $sContactId) {
$sRoleCode = $oLnk->Get('role_code');
$oContacts->RemoveItem($oLnk->GetKey());
$oTicket->Set('contacts_list', $oContacts);
@@ -1436,10 +1406,10 @@ abstract class ItopDataTestCase extends ItopTestCase
'password' => 'tagada-Secret,007',
'language' => 'EN US',
'profile_list' => [
'profileid:'.$sProfileId
'profileid:'.$sProfileId,
],
'allowed_org_list' => [
'allowed_org_id:'.$iOrganization
'allowed_org_id:'.$iOrganization,
],
]);
return $sLogin;
@@ -1456,7 +1426,7 @@ abstract class ItopDataTestCase extends ItopTestCase
{
$sLogin = 'demo_test_'.uniqid(__CLASS__, true);
$aProfileList = array_map(function($sProfileId) {
$aProfileList = array_map(function ($sProfileId) {
return 'profileid:'.self::$aURP_Profiles[$sProfileId];
}, $aProfiles);
@@ -1495,16 +1465,14 @@ abstract class ItopDataTestCase extends ItopTestCase
protected function AssertUniqueObjectInDB(string $sClass, array $aCriteria, string $sMessage = ''): void
{
$oSearch = new \DBObjectSearch($sClass);
foreach($aCriteria as $sAttCode => $value)
{
foreach ($aCriteria as $sAttCode => $value) {
$oSearch->AddCondition($sAttCode, $value);
}
$oSet = new DBObjectSet($oSearch);
$this->assertEquals(1, $oSet->Count(), $sMessage);
}
static protected function StartStopwatchInThePast(DBObject $oObject, string $sStopwatchAttCode, int $iDelayInSecond)
protected static function StartStopwatchInThePast(DBObject $oObject, string $sStopwatchAttCode, int $iDelayInSecond)
{
$iStartDate = time() - $iDelayInSecond;
/** @var \ormStopWatch $oStopwatch */
@@ -1515,8 +1483,7 @@ abstract class ItopDataTestCase extends ItopTestCase
$oObject->Set($sStopwatchAttCode, $oStopwatch);
}
static protected function StopStopwatchInTheFuture(DBObject $oObject, string $sStopwatchAttCode, int $iDelayInSecond)
protected static function StopStopwatchInTheFuture(DBObject $oObject, string $sStopwatchAttCode, int $iDelayInSecond)
{
$iEndDate = time() + $iDelayInSecond;
/** @var \ormStopWatch $oStopwatch */

View File

@@ -524,8 +524,8 @@ abstract class ItopTestCase extends KernelTestCase
sort($aActual);
sort($aExpected);
$sExpected = var_export($aExpected, true);
$sActual = var_export($aActual, true);
$sExpected = var_export($aExpected, true);
$sActual = var_export($aActual, true);
if ($sExpected === $sActual) {
$this->assertTrue(true);
return;

View File

@@ -71,14 +71,15 @@ class NavigationMenuTest extends ItopDataTestCase
/**
* test GetHyperlink return empty for TemplateMenuNode and ShortcutContainerMenuNode only
*/
public function testGetHyperlink(){
public function testGetHyperlink()
{
ApplicationMenu::LoadAdditionalMenus();
foreach (ApplicationMenu::$aMenusIndex as $sMenuId => $aMenu) {
//echo ' **** '. get_class($aMenu['node']);
if(in_array(get_class($aMenu['node']), ['TemplateMenuNode','ShortcutContainerMenuNode']) ){
if (in_array(get_class($aMenu['node']), ['TemplateMenuNode','ShortcutContainerMenuNode'])) {
$this->assertEquals('', $aMenu['node']->GetHyperlink([]), 'Menu node '.$sMenuId.' is a TemplateMenuNode. It should have empty hyperlink');
} else {
$this->assertNotEquals('', $aMenu['node']->GetHyperlink([]),'Menu node '.$sMenuId.' is a '.get_class($aMenu['node']).'. It should have not empty hyperlink');
$this->assertNotEquals('', $aMenu['node']->GetHyperlink([]), 'Menu node '.$sMenuId.' is a '.get_class($aMenu['node']).'. It should have not empty hyperlink');
}
}
}

View File

@@ -1,4 +1,5 @@
<?php
/*
* @copyright Copyright (C) 2010-2025 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
@@ -15,71 +16,71 @@ use utils;
*/
class utilsTestWithDataModel extends ItopDataTestCase
{
const USE_TRANSACTION = false;
public const USE_TRANSACTION = false;
/**
* @dataProvider GetMentionedObjectsFromTextProvider
* @covers utils::GetMentionedObjectsFromText
*
* @throws \Exception
*/
public function testGetMentionedObjectsFromText($sInput, $aExceptedMentionedObjects)
{
MetaModel::GetConfig()->Set('mentions.allowed_classes', ['@' => 'Person', '😊#' => 'Team']);
// Emulate the "Case provider mechanism" (reason: the data provider requires utils constants not available before the application startup)
$aTestedMentionedObjects = utils::GetMentionedObjectsFromText($sInput);
/**
* @dataProvider GetMentionedObjectsFromTextProvider
* @covers utils::GetMentionedObjectsFromText
*
* @throws \Exception
*/
public function testGetMentionedObjectsFromText($sInput, $aExceptedMentionedObjects)
{
MetaModel::GetConfig()->Set('mentions.allowed_classes', ['@' => 'Person', '😊#' => 'Team']);
// Emulate the "Case provider mechanism" (reason: the data provider requires utils constants not available before the application startup)
$aTestedMentionedObjects = utils::GetMentionedObjectsFromText($sInput);
$this->AssertArraysHaveSameItems($aExceptedMentionedObjects, $aTestedMentionedObjects);
}
$this->AssertArraysHaveSameItems($aExceptedMentionedObjects, $aTestedMentionedObjects);
}
/**
* @since 3.0.0
*/
public function GetMentionedObjectsFromTextProvider(): array
{
$sAbsUrlAppRoot = 'https://myitop.com/itop/';
/**
* @since 3.0.0
*/
public function GetMentionedObjectsFromTextProvider(): array
{
$sAbsUrlAppRoot = 'https://myitop.com/itop/';
return [
'No object' => [
"Begining
return [
'No object' => [
"Begining
Second line
End",
[],
],
'1 Object' => [
<<<HTML
[],
],
'1 Object' => [
<<<HTML
<p>Beginning</p><p>Before link <a data-role="object-mention" data-object-class="Person" data-object-key="12345" data-object-id="#Test Person" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=Person&id=12345">@Test Person</a>After link</p><p>End</p>
HTML,
[
'Person' => ['12345'],
],
],
'Should not match 1 Object if the mention prefix is missing' => [
<<<HTML
[
'Person' => ['12345'],
],
],
'Should not match 1 Object if the mention prefix is missing' => [
<<<HTML
<div class="ibo-activity-entry--main-information-content"><p>Beginning</p><p>Before link <a data-role="object-mention" data-object-class="Person" data-object-key="12345" data-object-id="#Test Person 1" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=Person&id=12345">#Test Ticket</a> After link</p></div>
HTML,
[],
],
'Should return 2 Objects' => [
<<<HTML
[],
],
'Should return 2 Objects' => [
<<<HTML
<div class="ibo-activity-entry--main-information-content"><div class="ibo-activity-entry--main-information-content"><p>Beginning</p><p>Before link <a data-role="object-mention" data-object-class="Person" data-object-key="12345" data-object-id="#Test Person" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=UserRequest&id=12345">@Test Person</a> After link</p><p>And <a data-role="object-mention" data-object-class="Person" data-object-id="@Agatha Christie" data-object-key="3" data-object-id="@Agatha Christie" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=Person&id=3">@Agatha Christie</a></p><p>End</p></div></div>
HTML,
[
'Person' => ['12345', '3'],
],
],
'Should process objects of different classes' => [
<<<HTML
[
'Person' => ['12345', '3'],
],
],
'Should process objects of different classes' => [
<<<HTML
Begining
Before link <a data-object-class="Team" data-object-key="12345" href=\"$sAbsUrlAppRoot/pages/UI.php&operation=details&class=Team&id=12345&foo=bar\">😊#R-012345</a> After link
And <a data-object-class="Person" data-object-key="3" href=\"$sAbsUrlAppRoot/pages/UI.php&operation=details&class=Person&id=3&foo=bar\">@Claude Monet</a>
End
HTML,
[
'Team' => ['12345'],
'Person' => ['3'],
],
],
];
}
[
'Team' => ['12345'],
'Person' => ['3'],
],
],
];
}
}

View File

@@ -1,4 +1,5 @@
<?php
// Copyright (c) 2010-2024 Combodo SAS
//
// This file is part of iTop.
@@ -31,21 +32,21 @@ use MissingQueryArgument;
use MySQLException;
use MySQLHasGoneAwayException;
class ActionNewsroomTest extends ItopDataTestCase
{
const CREATE_TEST_ORG = true;
public const CREATE_TEST_ORG = true;
private int $iTrigger;
private int $iRecipientId;
protected function setUp(): void
{
parent::setUp();
$this->iTrigger = $this->GivenObjectInDB('TriggerOnObjectCreate',
array(
$this->iTrigger = $this->GivenObjectInDB(
'TriggerOnObjectCreate',
[
'description' => '[TEST] TriggerOnObjectCreate',
'target_class' => 'UserRequest',
)
]
);
$this->iRecipientId = $this->GivenPersonInDB(1);
}
@@ -54,7 +55,7 @@ class ActionNewsroomTest extends ItopDataTestCase
{
return [
'With Sync ActionNewsroom' => ['bIsAsynchronous' => false],
'With Async ActionNewsroom' => ['bIsAsynchronous' => true]
'With Async ActionNewsroom' => ['bIsAsynchronous' => true],
];
}
@@ -71,7 +72,8 @@ class ActionNewsroomTest extends ItopDataTestCase
{
$iActionNewsroomId = $this->GivenActionNewsroomInDB(false, 'Body of the notification');
$this->CreateUserRequest(1,
$this->CreateUserRequest(
1,
[
'title' => '[TEST] ActionNewsroom',
'org_id' => $this->getTestOrgId(),
@@ -85,7 +87,7 @@ class ActionNewsroomTest extends ItopDataTestCase
[
'action_id' => $iActionNewsroomId,
'message' => 'Body of the notification',
'title' => 'Title'
'title' => 'Title',
]
);
}
@@ -99,13 +101,14 @@ class ActionNewsroomTest extends ItopDataTestCase
{
$iActionNewsroomId = $this->GivenActionNewsroomInDB($bIsAsynchronous, '$this->service_name$');
$this->CreateUserRequest(1,
$this->CreateUserRequest(
1,
[
'title' => '[TEST] ActionNewsroom',
'org_id' => $this->getTestOrgId(),
'caller_id' => $this->iRecipientId,
'description' => 'PHPUnit Test',
'service_id' => 0
'service_id' => 0,
]
);
@@ -114,7 +117,7 @@ class ActionNewsroomTest extends ItopDataTestCase
[
'action_id' => $iActionNewsroomId,
'title' => 'Notification not sent',
'message' => 'An error occurred while saving the notification'
'message' => 'An error occurred while saving the notification',
]
);
}
@@ -129,7 +132,7 @@ class ActionNewsroomTest extends ItopDataTestCase
'password' => 'admin_123',
'language' => 'EN US',
'profile_list' => ['profileid:'.self::$aURP_Profiles['Administrator']],
'contactid' => $this->iRecipientId
'contactid' => $this->iRecipientId,
]);
return $this->GivenObjectInDB('ActionNewsroom', [
@@ -141,7 +144,7 @@ class ActionNewsroomTest extends ItopDataTestCase
'recipients' => "SELECT Person WHERE id = $this->iRecipientId",
'asynchronous' => $bIsAsynchronous ? 'yes' : 'no',
'trigger_list' => [
"trigger_id:$this->iTrigger"
"trigger_id:$this->iTrigger",
],
]);
}
@@ -151,10 +154,12 @@ class ActionNewsroomTest extends ItopDataTestCase
*/
private function GivenService(string $sName): int
{
return $this->GivenObjectInDB('Service', [
return $this->GivenObjectInDB(
'Service',
[
'name' => $sName,
'org_id' => $this->getTestOrgId()
'org_id' => $this->getTestOrgId(),
]
);
}
}
}

View File

@@ -8,7 +8,7 @@ use MetaModel;
class BulkChangeTest extends ItopDataTestCase
{
const CREATE_TEST_ORG = true;
public const CREATE_TEST_ORG = true;
protected function setUp(): void
{
@@ -18,17 +18,18 @@ class BulkChangeTest extends ItopDataTestCase
}
//bug 2888: csv import / data synchro issue with password validation
public function testPasswordBulkChangeIssue() {
public function testPasswordBulkChangeIssue()
{
/** @var Person $oPerson */
$oPerson = $this->createObject('Person', array(
$oPerson = $this->createObject('Person', [
'first_name' => 'isaac',
'name' => 'asimov',
'email' => 'isaac.asimov@fundation.org',
'org_id' => $this->getTestOrgId(),
));
]);
$aData = array(
array(
$aData = [
[
$oPerson->Get("first_name"),
$oPerson->Get("name"),
$oPerson->Get("email"),
@@ -36,19 +37,19 @@ class BulkChangeTest extends ItopDataTestCase
"iasimov",
"harryseldon",
"profileid->name:Administrator",
),
);
$aAttributes = array("language" => 3, "login" => 4, "password" => 5, "profile_list" => 6);
$aExtKeys = array(
],
];
$aAttributes = ["language" => 3, "login" => 4, "password" => 5, "profile_list" => 6];
$aExtKeys = [
"contactid" =>
array("first_name" => 0, "name" => 1, "email" => 2),
);
["first_name" => 0, "name" => 1, "email" => 2],
];
$oBulk = new BulkChange(
"UserLocal",
$aData,
$aAttributes,
$aExtKeys,
array("login"),
["login"],
null,
null,
"Y-m-d H:i:s", // date format
@@ -61,13 +62,14 @@ class BulkChangeTest extends ItopDataTestCase
foreach ($aRes as $aRow) {
if (array_key_exists('__STATUS__', $aRow)) {
$sStatus = $aRow['__STATUS__'];
$this->assertFalse(strstr($sStatus->GetDescription(), "CoreCannotSaveObjectException"),
"CSVimport/Datasynchro: Password validation failed with: ".$sStatus->GetDescription());
$this->assertFalse(
strstr($sStatus->GetDescription(), "CoreCannotSaveObjectException"),
"CSVimport/Datasynchro: Password validation failed with: ".$sStatus->GetDescription()
);
}
}
}
/**
* test $oBulk->Process with server 1 from demo datas
*
@@ -78,7 +80,8 @@ class BulkChangeTest extends ItopDataTestCase
* @param $aExtKeys
* @param $aReconcilKeys
*/
public function testBulkChangeWithoutInitData($aCSVData, $aAttributes, $aExtKeys, $aReconcilKeys, $aResult, array $aResultHTML = null) {
public function testBulkChangeWithoutInitData($aCSVData, $aAttributes, $aExtKeys, $aReconcilKeys, $aResult, array $aResultHTML = null)
{
$this->debug("aReconcilKeys:".$aReconcilKeys[0]);
$oBulk = new BulkChange(
"Server",
@@ -106,9 +109,9 @@ class BulkChangeTest extends ItopDataTestCase
$this->debug("i:".$i);
$this->debug('GetCLIValue:'.$oCell->GetCLIValue());
$this->debug("aResult:".$aResult[$i]);
$this->assertEquals($aResult[$i], $oCell->GetCLIValue(), "Unexpected CLI result for cell " . $i);
$this->assertEquals($aResult[$i], $oCell->GetCLIValue(), "Unexpected CLI result for cell ".$i);
if (null !== $aResultHTML) {
$this->assertEquals($aResultHTML[$i], $oCell->GetHTMLValue(), "Unexpected HTML result for cell " . $i);
$this->assertEquals($aResultHTML[$i], $oCell->GetHTMLValue(), "Unexpected HTML result for cell ".$i);
}
}
}
@@ -116,74 +119,75 @@ class BulkChangeTest extends ItopDataTestCase
}
}
public function bulkChangeWithoutInitDataProvider() {
public function bulkChangeWithoutInitDataProvider()
{
return [
"Case 3, 5 et 8 : unchanged" => [
"csvData" =>
[["Demo", "Server1", "1", "production", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconciliation Keys"=>
"reconciliation Keys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[0 => "Demo", "org_id" => "3", 1 => "Server1", 2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "unchanged"],
"expectedResultHTML"=>
"expectedResultHTML" =>
[0 => "Demo", "org_id" => "3", 1 => "Server1", 2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "unchanged"],
],
"Case 9 : wrong date format" => [
"csvData" =>
[["Demo", "Server1", "1", "production", "<date"]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconciliation Keys"=>
"reconciliation Keys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ 0 => "Demo", "org_id" => "n/a", 1 => "Server1", 2 => "1", 3 => "production", 4 => "'<date' is an invalid value", "id" => 1, "__STATUS__" => "Issue: wrong date format"],
"expectedResultHTML"=>
"expectedResultHTML" =>
[ 0 => "Demo", "org_id" => "n/a", 1 => "Server1", 2 => "1", 3 => "production", 4 => "'&lt;date' is an invalid value", "id" => 1, "__STATUS__" => "Issue: wrong date format"],
],
"Case 1 : no match" => [
"csvData" =>
[["<Bad", "Server1", "1", "production", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconciliation Keys"=>
"reconciliation Keys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[0 => '<Bad', "org_id" => "No match for value '<Bad'",1 => "Server1",2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)"],
"expectedResultHTML"=>
"expectedResultHTML" =>
[0 => '&lt;Bad', "org_id" => "No match for value &apos;&lt;Bad&apos;",1 => "Server1",2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)"],
],
"Case 10 : Missing mandatory value" => [
"csvData" =>
[["", "Server1", "1", "production", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconciliation Keys"=>
"reconciliation Keys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[0 => null, "org_id" => "Invalid value for attribute", 1 => "Server1", 2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)"],
"expectedResultHTML"=>
"expectedResultHTML" =>
[0 => null, "org_id" => "Invalid value for attribute", 1 => "Server1", 2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)"],
],
"Case 6 : Unexpected value" => [
"csvData" =>
[["Demo", "Server1", "1", "<svg onclick\"alert(1)\">", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconciliation Keys"=>
"reconciliation Keys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[
0 => "Demo",
"org_id" => "3",
@@ -193,9 +197,9 @@ class BulkChangeTest extends ItopDataTestCase
4 => "",
"id" => 1,
"__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Unexpected value for attribute 'status': no match found, check spelling"
"__ERRORS__" => "Unexpected value for attribute 'status': no match found, check spelling",
],
"expectedResultHTML"=>
"expectedResultHTML" =>
[
0 => "Demo",
"org_id" => "3",
@@ -205,7 +209,7 @@ class BulkChangeTest extends ItopDataTestCase
4 => "",
"id" => 1,
"__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Unexpected value for attribute 'status': no match found, check spelling"
"__ERRORS__" => "Unexpected value for attribute 'status': no match found, check spelling",
],
],
];
@@ -222,21 +226,21 @@ class BulkChangeTest extends ItopDataTestCase
* @param $aExtKeys
* @param $aReconcilKeys
*/
public function testBulkChangeWithExistingData($aInitData, $aCsvData, $aAttributes, $aExtKeys, $aReconcilKeys, $aResult, $aResultHTML= null ) {
public function testBulkChangeWithExistingData($aInitData, $aCsvData, $aAttributes, $aExtKeys, $aReconcilKeys, $aResult, $aResultHTML = null)
{
//change value during the test
$db_core_transactions_enabled=MetaModel::GetConfig()->Get('db_core_transactions_enabled');
MetaModel::GetConfig()->Set('db_core_transactions_enabled',false);
$db_core_transactions_enabled = MetaModel::GetConfig()->Get('db_core_transactions_enabled');
MetaModel::GetConfig()->Set('db_core_transactions_enabled', false);
if (is_array($aInitData) && sizeof($aInitData) != 0) {
/** @var Server $oServer */
$oServer = $this->createObject('Server', array(
$oServer = $this->createObject('Server', [
'name' => $aInitData[1],
'status' => $aInitData[2],
'org_id' => $aInitData[0],
'purchase_date' => $aInitData[3],
));
if(array_key_exists('id', $aAttributes)) {
]);
if (array_key_exists('id', $aAttributes)) {
$iColumnForId = $aAttributes['id'];
$aCsvData[0][$iColumnForId] = $oServer->GetKey();
$aResult[$iColumnForId] = $oServer->GetKey();
@@ -253,7 +257,7 @@ class BulkChangeTest extends ItopDataTestCase
$iNBFields = count($aAttributes);
foreach ($aExtKeys as $aListFields) {
$iNBFields += count($aListFields);
$iNBFields += count($aListFields);
}
$oBulk = new BulkChange(
"Server",
@@ -279,38 +283,39 @@ class BulkChangeTest extends ItopDataTestCase
$this->debug("i:".$i);
$this->debug('GetCLIValue:'.$oCell->GetCLIValue());
$this->debug("aResult:".$aResult[$i]);
$this->assertEquals( $aResult[$i], $oCell->GetCLIValue(), "failure on " . get_class($oCell) . ' cell type for cell number ' . $i );
$this->assertEquals($aResult[$i], $oCell->GetCLIValue(), "failure on ".get_class($oCell).' cell type for cell number '.$i);
if (null !== $aResultHTML && array_key_exists($i, $aResultHTML)) {
$this->assertEquals($aResultHTML[$i], $oCell->GetHTMLValue(), "failure on " . get_class($oCell) . ' cell type for cell number ' . $i);
$this->assertEquals($aResultHTML[$i], $oCell->GetHTMLValue(), "failure on ".get_class($oCell).' cell type for cell number '.$i);
}
} else if ($i === "__ERRORS__") {
} elseif ($i === "__ERRORS__") {
$sErrors = array_key_exists("__ERRORS__", $aResult) ? $aResult["__ERRORS__"] : "";
$this->assertEquals( $sErrors, $oCell->GetDescription());
$this->assertEquals($sErrors, $oCell->GetDescription());
}
}
$this->assertEquals( $aResult[0], $aRow[0]->GetCLIValue());
$this->assertEquals($aResult[0], $aRow[0]->GetCLIValue());
if (null !== $aResultHTML) {
$this->assertEquals($aResultHTML[0], $aRow[0]->GetHTMLValue());
}
}
}
MetaModel::GetConfig()->Set('db_core_transactions_enabled',$db_core_transactions_enabled);
MetaModel::GetConfig()->Set('db_core_transactions_enabled', $db_core_transactions_enabled);
}
public function bulkChangeWithExistingDataProvider() {
public function bulkChangeWithExistingDataProvider()
{
return [
"Ambigous case on reconciliation" => [
"initData"=>
"initData" =>
["1", "Server1", "production", ""],
"csvData" =>
[[">Demo", "Server1"]],
"attributes"=>
"attributes" =>
["name" => 1],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["name"],
"expectedResult"=>
"expectedResult" =>
[
0 => ">Demo",
"org_id" => "n/a",
@@ -320,7 +325,7 @@ class BulkChangeTest extends ItopDataTestCase
"__STATUS__" => "Issue: ambiguous reconciliation",
"__ERRORS__" => "Object not found",
],
"expectedResultHTML"=>
"expectedResultHTML" =>
[
0 => "&gt;Demo",
"org_id" => "n/a",
@@ -332,17 +337,17 @@ class BulkChangeTest extends ItopDataTestCase
],
],
"Case 6 - 1 : Unexpected value (update)" => [
"initData"=>
"initData" =>
["1", ">ServerTest", "production", ""],
"csvData"=>
"csvData" =>
[["Demo", ">ServerTest", "key - will be automatically overwritten by test", ">BadValue", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[
"id" => "{Id of the server created by the test}",
0 => "Demo",
@@ -354,31 +359,31 @@ class BulkChangeTest extends ItopDataTestCase
"__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Allowed 'status' value(s): stock,implementation,production,obsolete",
],
"expectedResultHTML"=>
[
"id" => "{Id of the server created by the test}",
0 => "Demo",
"org_id" => "3",
1 => "&gt;ServerTest",
2 => "1",
3 => "'&gt;BadValue' is an invalid value",
4 => "",
"__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Allowed 'status' value(s): stock,implementation,production,obsolete",
],
"expectedResultHTML" =>
[
"id" => "{Id of the server created by the test}",
0 => "Demo",
"org_id" => "3",
1 => "&gt;ServerTest",
2 => "1",
3 => "'&gt;BadValue' is an invalid value",
4 => "",
"__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Allowed 'status' value(s): stock,implementation,production,obsolete",
],
],
"Case 6 - 2 : Unexpected value (update)" => [
"initData"=>
"initData" =>
["1", ">ServerTest", "production", ""],
"csvData"=>
"csvData" =>
[["Demo", ">ServerTest", "key", "<svg onclick\"alert(1)\">", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[
"id" => "{Id of the server created by the test}",
0 => "Demo",
@@ -390,7 +395,7 @@ class BulkChangeTest extends ItopDataTestCase
"__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Allowed 'status' value(s): stock,implementation,production,obsolete",
],
"expectedResultHTML"=>
"expectedResultHTML" =>
[
"id" => "{Id of the server created by the test}",
0 => "Demo",
@@ -404,17 +409,17 @@ class BulkChangeTest extends ItopDataTestCase
],
],
"Case 6 - 3 : Unexpected value (creation)" => [
"initData"=>
"initData" =>
[],
"csvData"=>
"csvData" =>
[["Demo", ">ServerTest", "<svg onclick\"alert(1)\">", 1]],
"attributes"=>
["name" => 1, "status" => 2, 'id'=> 3],
"extKeys"=>
"attributes" =>
["name" => 1, "status" => 2, 'id' => 3],
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["name"],
"expectedResult"=>
"expectedResult" =>
[
"id" => "{Id of the server created by the test}",
0 => "Demo",
@@ -425,7 +430,7 @@ class BulkChangeTest extends ItopDataTestCase
"__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Allowed 'status' value(s): stock,implementation,production,obsolete",
],
"expectedResultHTML"=>
"expectedResultHTML" =>
[
"id" => "{Id of the server created by the test}",
0 => "Demo",
@@ -438,219 +443,218 @@ class BulkChangeTest extends ItopDataTestCase
],
],
"Case 8 : unchanged name" => [
"initData"=>
"initData" =>
["1", "<svg onclick\"alert(1)\">", "production", ""],
"csvData"=>
"csvData" =>
[["Demo", "<svg onclick\"alert(1)\">", "key", "production", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ "id" => "{Id of the server created by the test}",
0 => "Demo", "org_id" => "3", 1 => '<svg onclick"alert(1)">', 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "updated 1 cols"],
"expectedResultHTML"=>
0 => "Demo", "org_id" => "3", 1 => '<svg onclick"alert(1)">', 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "updated 1 cols"],
"expectedResultHTML" =>
[ "id" => "{Id of the server created by the test}",
0 => "Demo", "org_id" => "3", 1 => '&lt;svg onclick&quot;alert(1)&quot;&gt;', 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "updated 1 cols"],
0 => "Demo", "org_id" => "3", 1 => '&lt;svg onclick&quot;alert(1)&quot;&gt;', 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "updated 1 cols"],
],
"Case 3, 5 et 8 : unchanged 2" => [
"initData"=>
"initData" =>
["1", ">ServerTest", "production", ""],
"csvData"=>
"csvData" =>
[["Demo", ">ServerTest", "1", "production", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ "id" => "{Id of the server created by the test}",
0 => "Demo", "org_id" => "3", 1 => ">ServerTest", 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "updated 1 cols"],
"expectedResultHTML"=>
0 => "Demo", "org_id" => "3", 1 => ">ServerTest", 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "updated 1 cols"],
"expectedResultHTML" =>
[ "id" => "{Id of the server created by the test}",
0 => "Demo", "org_id" => "3", 1 => "&gt;ServerTest", 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "updated 1 cols"],
0 => "Demo", "org_id" => "3", 1 => "&gt;ServerTest", 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "updated 1 cols"],
],
"Case 9 - 1: wrong date format" => [
"initData"=>
"initData" =>
["1", ">ServerTest", "production", ""],
"csvData"=>
"csvData" =>
[["Demo", ">ServerTest", "1", "production", "date>"]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ "id" => "{Id of the server created by the test}",
0 => "Demo", "org_id" => "n/a", 1 => ">ServerTest", 2 => "1", 3 => "production", 4 => "'date>' is an invalid value", "__STATUS__" => "Issue: wrong date format"],
"expectedResultHTML"=>
0 => "Demo", "org_id" => "n/a", 1 => ">ServerTest", 2 => "1", 3 => "production", 4 => "'date>' is an invalid value", "__STATUS__" => "Issue: wrong date format"],
"expectedResultHTML" =>
[ "id" => "{Id of the server created by the test}",
0 => "Demo", "org_id" => "n/a", 1 => "&gt;ServerTest", 2 => "1", 3 => "production", 4 => "'date&gt;' is an invalid value", "__STATUS__" => "Issue: wrong date format"],
0 => "Demo", "org_id" => "n/a", 1 => "&gt;ServerTest", 2 => "1", 3 => "production", 4 => "'date&gt;' is an invalid value", "__STATUS__" => "Issue: wrong date format"],
],
"Case 9 - 2: wrong date format" => [
"initData"=>
"initData" =>
["1", ">ServerTest", "production", ""],
"csvData"=>
"csvData" =>
[["Demo", ">ServerTest", "1", "production", "<svg onclick\"alert(1)\">"]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ "id" => "{Id of the server created by the test}",
0 => "Demo", "org_id" => "n/a", 1 => ">ServerTest", 2 => "1", 3 => "production", 4 => '\'<svg onclick"alert(1)">\' is an invalid value',"__STATUS__" => "Issue: wrong date format"],
"expectedResultHTML"=>
0 => "Demo", "org_id" => "n/a", 1 => ">ServerTest", 2 => "1", 3 => "production", 4 => '\'<svg onclick"alert(1)">\' is an invalid value',"__STATUS__" => "Issue: wrong date format"],
"expectedResultHTML" =>
[ "id" => "{Id of the server created by the test}",
0 => "Demo", "org_id" => "n/a", 1 => "&gt;ServerTest", 2 => "1", 3 => "production", 4 => '\'&lt;svg onclick&quot;alert(1)&quot;&gt;\' is an invalid value',"__STATUS__" => "Issue: wrong date format"],
0 => "Demo", "org_id" => "n/a", 1 => "&gt;ServerTest", 2 => "1", 3 => "production", 4 => '\'&lt;svg onclick&quot;alert(1)&quot;&gt;\' is an invalid value',"__STATUS__" => "Issue: wrong date format"],
],
"Case 1 - 1 : no match" => [
"initData"=>
"initData" =>
["1", ">ServerTest", "production", ""],
"csvData"=>
"csvData" =>
[[">Bad", ">ServerTest", "1", "production", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ "id" => "{Id of the server created by the test}",
0 => ">Bad", "org_id" => "No match for value '>Bad'",1 => ">ServerTest",2 => "1", 3 => "production", 4 => "", "__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Object not found",
0 => ">Bad", "org_id" => "No match for value '>Bad'",1 => ">ServerTest",2 => "1", 3 => "production", 4 => "", "__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Object not found",
],
"expectedResultHTML"=>
"expectedResultHTML" =>
[ "id" => "{Id of the server created by the test}",
0 => "&gt;Bad", "org_id" => "No match for value &apos;&gt;Bad&apos;",1 => "&gt;ServerTest",2 => "1", 3 => "production", 4 => "", "__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Object not found",
0 => "&gt;Bad", "org_id" => "No match for value &apos;&gt;Bad&apos;",1 => "&gt;ServerTest",2 => "1", 3 => "production", 4 => "", "__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Object not found",
],
],
"Case 1 - 2 : no match" => [
"initData"=>
"initData" =>
["1", ">ServerTest", "production", ""],
"csvData"=>
"csvData" =>
[["<svg onclick\"alert(1)\">", ">ServerTest", "1", "production", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ "id" => "{Id of the server created by the test}",
0 => '<svg onclick"alert(1)">', "org_id" => "No match for value '<svg onclick\"alert(1)\">'",1 => ">ServerTest",2 => "1", 3 => "production", 4 => "", "__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Object not found",
0 => '<svg onclick"alert(1)">', "org_id" => "No match for value '<svg onclick\"alert(1)\">'",1 => ">ServerTest",2 => "1", 3 => "production", 4 => "", "__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Object not found",
],
"expectedResultHTML"=>
"expectedResultHTML" =>
[ "id" => "{Id of the server created by the test}",
0 => '&lt;svg onclick&quot;alert(1)&quot;&gt;', "org_id" => "No match for value &apos;&lt;svg onclick&quot;alert(1)&quot;&gt;&apos;",1 => "&gt;ServerTest",2 => "1", 3 => "production", 4 => "", "__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Object not found",
0 => '&lt;svg onclick&quot;alert(1)&quot;&gt;', "org_id" => "No match for value &apos;&lt;svg onclick&quot;alert(1)&quot;&gt;&apos;",1 => "&gt;ServerTest",2 => "1", 3 => "production", 4 => "", "__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Object not found",
],
],
"Case 10 : Missing mandatory value" => [
"initData"=>
"initData" =>
["1", ">ServerTest", "production", ""],
"csvData"=>
"csvData" =>
[["", ">ServerTest", "1", "production", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ "id" => "{Id of the server created by the test}",
0 => "", "org_id" => "Invalid value for attribute", 1 => ">ServerTest", 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Null not allowed",
0 => "", "org_id" => "Invalid value for attribute", 1 => ">ServerTest", 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Null not allowed",
],
"expectedResultHTML"=>
"expectedResultHTML" =>
[ "id" => "{Id of the server created by the test}",
0 => "", "org_id" => "Invalid value for attribute", 1 => "&gt;ServerTest", 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Null not allowed",
0 => "", "org_id" => "Invalid value for attribute", 1 => "&gt;ServerTest", 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => "Null not allowed",
],
],
"Case 0 : Date format ok but incorrect date" => [
"initData"=>
"initData" =>
["1", ">ServerTest", "production", "2020-02-01"],
"csvData"=>
"csvData" =>
[["Demo", ">ServerTest", "1", "production", "2020-20-03"]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ "id" => "{Id of the server created by the test}",
0 => "Demo", "org_id" => "n/a", 1 => ">ServerTest", 2 => "1", 3 => "production", 4 => "'2020-20-03' is an invalid value", "id" => 1, "__STATUS__" => "Issue: wrong date format"],
0 => "Demo", "org_id" => "n/a", 1 => ">ServerTest", 2 => "1", 3 => "production", 4 => "'2020-20-03' is an invalid value", "id" => 1, "__STATUS__" => "Issue: wrong date format"],
],
"Case 11 : Missing AttributeDateTime cell should issue an error" => [
"initData"=>
"initData" =>
["1", "ServerTest", "production", "2020-02-01"],
"csvData"=>
"csvData" =>
[["1"]],
"attributes"=>
"attributes" =>
["id" => 0,"purchase_date" => 1],
"extKeys"=>
"extKeys" =>
[],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ 1 => "'' is an invalid value", "id" => 1, "__STATUS__" => 'Issue: Not the expected number of columns (found: 1, expected: 2)'],
],
"Case 12 : Missing AttributeEnum cell should issue an error" => [
"initData"=>
"initData" =>
["1", "ServerTest", "production", "2020-02-01"],
"csvData"=>
"csvData" =>
[[ "1"]], // missing status
"attributes"=>
"attributes" =>
[ "id" => 0, "status" => 1],
"extKeys"=>
"extKeys" =>
[],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ 1 => "'' is an invalid value", "id" => 1, "__STATUS__" => 'Issue: Not the expected number of columns (found: 1, expected: 2)'],
],
"Case 13 : Missing AttributeExternalKey cell should issue an error" => [
"initData"=>
"initData" =>
["1", "ServerTest", "production", "2020-02-01"],
"csvData"=>
"csvData" =>
[[ "1"]], // missing org_id
"attributes"=>
"attributes" =>
[ "id" => 0],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 1]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ 1 => "'' is an invalid value", "id" => 1, "__STATUS__" => 'Issue: Not the expected number of columns (found: 1, expected: 2)'],
],
"Case 14 : Missing 1 of 2 AttributeExternalKey need 2 cells for reconciliation cell should issue an error" => [
"initData"=>
"initData" =>
["1", "ServerTest", "production", "2020-02-01"],
"csvData"=>
"csvData" =>
[[ "1", "Demo"]], // missing org_code
"attributes"=>
"attributes" =>
[ "id" => 0],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 1, "code" => 2]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[ 1 => 'Demo', "id" => 1, "__STATUS__" => 'Issue: Not the expected number of columns (found: 2, expected: 3)'],
],
];
}
/**
* test $oBulk->Process with new server and new organization datas
*
@@ -662,35 +666,36 @@ class BulkChangeTest extends ItopDataTestCase
* @param $aExtKeys
* @param $aReconcilKeys
*/
public function testBulkChangeWithExistingDataAndSpecificOrg($aInitData, $aCsvData, $aAttributes, $aExtKeys, $aReconcilKeys, $aResult, $aResultHTML = null) {
public function testBulkChangeWithExistingDataAndSpecificOrg($aInitData, $aCsvData, $aAttributes, $aExtKeys, $aReconcilKeys, $aResult, $aResultHTML = null)
{
//change value during the test
$db_core_transactions_enabled=MetaModel::GetConfig()->Get('db_core_transactions_enabled');
MetaModel::GetConfig()->Set('db_core_transactions_enabled',false);
$db_core_transactions_enabled = MetaModel::GetConfig()->Get('db_core_transactions_enabled');
MetaModel::GetConfig()->Set('db_core_transactions_enabled', false);
if (is_array($aInitData) && sizeof($aInitData) != 0) {
/** @var Server $oServer */
$oOrganisation = $this->createObject('Organization', array(
'name' => $aInitData["orgName"]
));
if ($aResult["org_id"]==="{org id of the server created by the test}"){
$oOrganisation = $this->createObject('Organization', [
'name' => $aInitData["orgName"],
]);
if ($aResult["org_id"] === "{org id of the server created by the test}") {
$aResult["org_id"] = $oOrganisation->GetKey();
if ($aResultHTML!==null){
$aResultHTML["org_id"]=$oOrganisation->GetKey();
if ($aResultHTML !== null) {
$aResultHTML["org_id"] = $oOrganisation->GetKey();
}
}
$oServer = $this->createObject('Server', array(
$oServer = $this->createObject('Server', [
'name' => $aInitData["serverName"],
'status' => $aInitData["serverStatus"],
'org_id' => $oOrganisation->GetKey(),
'purchase_date' => $aInitData["serverPurchaseDate"],
));
]);
$aCsvData[0][2] = $oServer->GetKey();
$aResult[2]=$oServer->GetKey();
if ($aResult["id"]==="{Id of the server created by the test}") {
$aResult["id"]=$oServer->GetKey();
if ($aResultHTML!==null){
$aResultHTML[2]=$oServer->GetKey();
$aResultHTML["id"]=$oServer->GetKey();
$aResult[2] = $oServer->GetKey();
if ($aResult["id"] === "{Id of the server created by the test}") {
$aResult["id"] = $oServer->GetKey();
if ($aResultHTML !== null) {
$aResultHTML[2] = $oServer->GetKey();
$aResultHTML["id"] = $oServer->GetKey();
}
}
}
@@ -720,9 +725,9 @@ class BulkChangeTest extends ItopDataTestCase
} elseif ($i === "__STATUS__") {
$sStatus = $aRow['__STATUS__'];
$this->assertEquals($aResult["__STATUS__"], $sStatus->GetDescription());
} else if ($i === "__ERRORS__") {
} elseif ($i === "__ERRORS__") {
$sErrors = array_key_exists("__ERRORS__", $aResult) ? $aResult["__ERRORS__"] : "";
$this->assertEquals( $sErrors, $oCell->GetDescription());
$this->assertEquals($sErrors, $oCell->GetDescription());
}
}
$this->assertEquals($aResult[0], $aRow[0]->GetCLIValue());
@@ -730,23 +735,24 @@ class BulkChangeTest extends ItopDataTestCase
$this->assertEquals($aResultHTML[0], $aRow[0]->GetHTMLValue());
}
}
MetaModel::GetConfig()->Set('db_core_transactions_enabled',$db_core_transactions_enabled);
MetaModel::GetConfig()->Set('db_core_transactions_enabled', $db_core_transactions_enabled);
}
public function bulkChangeWithExistingDataAndSpecificOrgProvider() {
public function bulkChangeWithExistingDataAndSpecificOrgProvider()
{
return [
"Ambigous case " => [
"initData"=>
["orgName" => "Demo", "serverName" => ">ServerYO", "serverStatus" => "production", "serverPurchaseDate" =>""],
"initData" =>
["orgName" => "Demo", "serverName" => ">ServerYO", "serverStatus" => "production", "serverPurchaseDate" => ""],
"csvData" =>
[["Demo", ">Server1"]],
"attributes"=>
"attributes" =>
["name" => 1,"id" => 2],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["org_id"],
"expectedResult"=>
"expectedResult" =>
[
0 => "Demo",
"org_id" => "Invalid value for attribute",
@@ -755,7 +761,7 @@ class BulkChangeTest extends ItopDataTestCase
"__STATUS__" => "Issue: failed to reconcile",
"__ERRORS__" => "Allowed 'status' value(s): stock,implemfentation,production,obsolete",
],
"expectedResultHTML"=>
"expectedResultHTML" =>
[
0 => "Demo",
"org_id" => "Invalid value for attribute",
@@ -766,67 +772,67 @@ class BulkChangeTest extends ItopDataTestCase
],
],
"Case 3 : unchanged name" => [
"initData"=>
["orgName" => ">dodo", "serverName" => ">ServerYO", "serverStatus" => "production", "serverPurchaseDate" =>""],
"csvData"=>
"initData" =>
["orgName" => ">dodo", "serverName" => ">ServerYO", "serverStatus" => "production", "serverPurchaseDate" => ""],
"csvData" =>
[[">dodo", ">ServerYO", "key will be set by the test", "production", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[0 => ">dodo", "org_id" => "{org id of the server created by the test}", 1 => ">ServerYO", 2 => "1", 3 => "production", 4 => "", "id" => "{Id of the server created by the test}", "__STATUS__" => "unchanged"],
"expectedResultHTML"=>
"expectedResultHTML" =>
[0 => "&gt;dodo", "org_id" => "{org id of the server created by the test}", 1 => "&gt;ServerYO", 2 => "1", 3 => "production", 4 => "", "id" => "{Id of the server created by the test}", "__STATUS__" => "unchanged"],
],
"Case 3 bis : unchanged name" => [
"initData"=>
["orgName" =>"<svg >", "serverName" => ">ServerYO", "serverStatus" => "production", "serverPurchaseDate" =>""],
"csvData"=>
"initData" =>
["orgName" => "<svg >", "serverName" => ">ServerYO", "serverStatus" => "production", "serverPurchaseDate" => ""],
"csvData" =>
[["<svg >", ">ServerYO", "key", "production", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[0 => "<svg >", "org_id" => "{org id of the server created by the test}", 1 => ">ServerYO", 2 => "1", 3 => "production", 4 => "", "id" => "{Id of the server created by the test}", "__STATUS__" => "unchanged"],
"expectedResultHTML"=>
"expectedResultHTML" =>
[0 => "&lt;svg &gt;", "org_id" => "{org id of the server created by the test}", 1 => "&gt;ServerYO", 2 => "1", 3 => "production", 4 => "", "id" => "{Id of the server created by the test}", "__STATUS__" => "unchanged"],
],
"Case 3 ter : unchanged name" => [
"initData"=>
["orgName" => "<svg onclick\"alert(1)\" >", "serverName" => ">ServerYO", "serverStatus" => "production", "serverPurchaseDate" =>""],
"csvData"=>
"initData" =>
["orgName" => "<svg onclick\"alert(1)\" >", "serverName" => ">ServerYO", "serverStatus" => "production", "serverPurchaseDate" => ""],
"csvData" =>
[["<svg onclick\"alert(1)\" >", ">ServerYO", "key", "production", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["id"],
"expectedResult"=>
"expectedResult" =>
[0 => '<svg onclick"alert(1)" >', "org_id" => "{org id of the server created by the test}", 1 => ">ServerYO", 2 => "1", 3 => "production", 4 => "", "id" => "{Id of the server created by the test}", "__STATUS__" => "unchanged"],
"expectedResultHTML"=>
"expectedResultHTML" =>
[0 => '&lt;svg onclick&quot;alert(1)&quot; &gt;', "org_id" => "{org id of the server created by the test}", 1 => "&gt;ServerYO", 2 => "1", 3 => "production", 4 => "", "id" => "{Id of the server created by the test}", "__STATUS__" => "unchanged"],
],
"Case reconciliation on external key" => [
"initData"=>
["orgName" => "<svg onclick\"alert(1)\" >", "serverName" => ">ServerYO", "serverStatus" => "production", "serverPurchaseDate" =>""],
"csvData"=>
"initData" =>
["orgName" => "<svg onclick\"alert(1)\" >", "serverName" => ">ServerYO", "serverStatus" => "production", "serverPurchaseDate" => ""],
"csvData" =>
[["<svg onclick\"alert(1)\" >", ">ServerYO", "key", "production", ""]],
"attributes"=>
"attributes" =>
["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4],
"extKeys"=>
"extKeys" =>
["org_id" => ["name" => 0]],
"reconcilKeys"=>
"reconcilKeys" =>
["org_id", "name"],
"expectedResult"=>
"expectedResult" =>
[0 => '<svg onclick"alert(1)" >', "org_id" => "{org id of the server created by the test}", 1 => ">ServerYO", 2 => "1", 3 => "production", 4 => "", "id" => "{Id of the server created by the test}", "__STATUS__" => "unchanged"],
"expectedResultHTML"=>
"expectedResultHTML" =>
[0 => '&lt;svg onclick&quot;alert(1)&quot; &gt;', "org_id" => "{org id of the server created by the test}", 1 => "&gt;ServerYO", 2 => "1", 3 => "production", 4 => "", "id" => "{Id of the server created by the test}", "__STATUS__" => "unchanged"],
],
];

View File

@@ -1424,7 +1424,7 @@ class DBObjectTest extends ItopDataTestCase
$iUserRequest = $this->GivenObjectInDB('UserRequest', [
'ref' => 'UR1', 'title' => 'UR1', 'description' => 'UR1', 'caller_id' => 3, 'org_id' => 3, 'service_id' => 1,
'functionalcis_list' => [
"functionalci_id:$iServer"
"functionalci_id:$iServer",
],
]);
$oUserRequest = MetaModel::GetObject('UserRequest', $iUserRequest);

View File

@@ -90,8 +90,9 @@ class DBSearchCommitTest extends ItopDataTestCase
/**
* @covers N°8511 - Enhance DBObjectSet to be able to order by id
*/
public function testDbObjectSetFetchMethodWorksWithOptimizeColumnLoadOrderedById(){
$sUID=uniqid();
public function testDbObjectSetFetchMethodWorksWithOptimizeColumnLoadOrderedById()
{
$sUID = uniqid();
$oOrg1 = $this->CreateOrganization($sUID);
$oOrg2 = $this->CreateOrganization($sUID);

View File

@@ -68,7 +68,7 @@ class ExceptionLogTest extends ItopDataTestCase
$sExpectedFile = __FILE__;
// @formatter:off
$oException = new $aExceptions[$i]("Iteration number $i");
$sExpectedLine = __LINE__-1; //Both should remain on the same line
$sExpectedLine = __LINE__ - 1; //Both should remain on the same line
// @formatter:on
$iExpectedWriteNumber = $aExpectedWriteNumber[$i];

View File

@@ -9,7 +9,6 @@
namespace Combodo\iTop\Test\UnitTest\Core;
use CMDBSource;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
use DBObjectSearch;
@@ -25,7 +24,6 @@ use utils;
class OQLTest extends ItopDataTestCase
{
/**
* @doesNotPerformAssertions
*
@@ -63,244 +61,236 @@ class OQLTest extends ItopDataTestCase
public function NestedQueryProvider()
{
return array(
array("SELECT User AS U JOIN Person AS P ON U.contactid = P.id WHERE U.status='enabled' AND U.id NOT IN (SELECT User AS U JOIN Person AS P ON U.contactid=P.id JOIN URP_UserOrg AS L ON L.userid = U.id WHERE U.status='enabled' AND L.allowed_org_id = P.org_id UNION SELECT User AS U WHERE U.status='enabled' AND U.id NOT IN ( SELECT User AS U JOIN URP_UserOrg AS L ON L.userid = U.id WHERE U.status='enabled'))"),
array('SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE `UserRequest`.org_id IN (SELECT `Organization` FROM Organization AS `Organization` JOIN Organization AS `Organization1` ON `Organization`.parent_id BELOW `Organization1`.id WHERE (`Organization1`.`id` = \'3\'))'),
array('SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`org_id` IN (SELECT `Organization` FROM Organization AS `Organization` WHERE `Organization`.`id`=`UserRequest`.`org_id`))'),
array("SELECT UserRequest AS Ur WHERE Ur.id NOT IN (SELECT UserRequest AS Ur JOIN lnkFunctionalCIToTicket AS lnk ON lnk.ticket_id = Ur.id)"),
array("SELECT Ticket AS T WHERE T. finalclass IN ('userrequest' , 'change') AND T.id NOT IN (SELECT UserRequest AS Ur JOIN lnkFunctionalCIToTicket AS lnk ON lnk.ticket_id = Ur.id UNION SELECT Change AS C JOIN lnkFunctionalCIToTicket AS lnk ON lnk.ticket_id = C.id)"),
array("SELECT PhysicalDevice WHERE status='production' AND id NOT IN (SELECT PhysicalDevice AS p JOIN lnkFunctionalCIToProviderContract AS l ON l.functionalci_id=p.id)"),
array("SELECT Team WHERE id NOT IN (SELECT Team AS t JOIN lnkPersonToTeam AS l ON l.team_id=t.id WHERE 1)"),
);
return [
["SELECT User AS U JOIN Person AS P ON U.contactid = P.id WHERE U.status='enabled' AND U.id NOT IN (SELECT User AS U JOIN Person AS P ON U.contactid=P.id JOIN URP_UserOrg AS L ON L.userid = U.id WHERE U.status='enabled' AND L.allowed_org_id = P.org_id UNION SELECT User AS U WHERE U.status='enabled' AND U.id NOT IN ( SELECT User AS U JOIN URP_UserOrg AS L ON L.userid = U.id WHERE U.status='enabled'))"],
['SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE `UserRequest`.org_id IN (SELECT `Organization` FROM Organization AS `Organization` JOIN Organization AS `Organization1` ON `Organization`.parent_id BELOW `Organization1`.id WHERE (`Organization1`.`id` = \'3\'))'],
['SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`org_id` IN (SELECT `Organization` FROM Organization AS `Organization` WHERE `Organization`.`id`=`UserRequest`.`org_id`))'],
["SELECT UserRequest AS Ur WHERE Ur.id NOT IN (SELECT UserRequest AS Ur JOIN lnkFunctionalCIToTicket AS lnk ON lnk.ticket_id = Ur.id)"],
["SELECT Ticket AS T WHERE T. finalclass IN ('userrequest' , 'change') AND T.id NOT IN (SELECT UserRequest AS Ur JOIN lnkFunctionalCIToTicket AS lnk ON lnk.ticket_id = Ur.id UNION SELECT Change AS C JOIN lnkFunctionalCIToTicket AS lnk ON lnk.ticket_id = C.id)"],
["SELECT PhysicalDevice WHERE status='production' AND id NOT IN (SELECT PhysicalDevice AS p JOIN lnkFunctionalCIToProviderContract AS l ON l.functionalci_id=p.id)"],
["SELECT Team WHERE id NOT IN (SELECT Team AS t JOIN lnkPersonToTeam AS l ON l.team_id=t.id WHERE 1)"],
];
}
/**
* @dataProvider GoodQueryProvider
* @depends testOQLSetup
*
* @param $sQuery
*
* @throws \OQLException
*/
public function testGoodQueryParser($sQuery)
{
$this->debug($sQuery);
$oOql = new OqlInterpreter($sQuery);
$oQuery = $oOql->ParseQuery();
static::assertInstanceOf('OqlQuery', $oQuery);
}
/**
* @dataProvider GoodQueryProvider
* @depends testOQLSetup
*
* @param $sQuery
*
* @throws \OQLException
*/
public function testGoodQueryParser($sQuery)
{
$this->debug($sQuery);
$oOql = new OqlInterpreter($sQuery);
$oQuery = $oOql->ParseQuery();
static::assertInstanceOf('OqlQuery', $oQuery);
}
public function GoodQueryProvider()
{
return array(
array('SELECT toto'),
array('SELECT toto WHERE toto.a = 1'),
array('SELECT toto WHERE toto.a = -1'),
array('SELECT toto WHERE toto.a = (1-1)'),
array('SELECT toto WHERE toto.a = (-1+3)'),
array('SELECT toto WHERE toto.a = (3+-1)'),
array('SELECT toto WHERE toto.a = (3--1)'),
array('SELECT toto WHERE toto.a = 0xC'),
array('SELECT toto WHERE toto.a = \'AXDVFS0xCZ32\''),
array('SELECT toto WHERE toto.a = :myparameter'),
array('SELECT toto WHERE toto.a IN (:param1)'),
array('SELECT toto WHERE toto.a IN (:param1, :param2)'),
array('SELECT toto WHERE toto.a=1'),
array('SELECT toto WHERE toto.a = "1"'),
array('SELECT toto WHERE toto.a & 1'),
array('SELECT toto WHERE toto.a | 1'),
array('SELECT toto WHERE toto.a ^ 1'),
array('SELECT toto WHERE toto.a << 1'),
array('SELECT toto WHERE toto.a >> 1'),
array('SELECT toto WHERE toto.a NOT LIKE "That\'s it"'),
array('SELECT toto WHERE toto.a NOT LIKE "That\'s \\"it\\""'),
array('SELECT toto WHERE toto.a NOT LIKE \'That"s it\''),
array('SELECT toto WHERE toto.a NOT LIKE \'That\\\'s it\''),
array('SELECT toto WHERE toto.a NOT LIKE "blah \\\\ truc"'),
array('SELECT toto WHERE toto.a NOT LIKE \'blah \\\\ truc\''),
array('SELECT toto WHERE toto.a NOT LIKE "\\\\"'),
array('SELECT toto WHERE toto.a NOT LIKE "\\""'),
array('SELECT toto WHERE toto.a NOT LIKE "\\"\\\\"'),
array('SELECT toto WHERE toto.a NOT LIKE "\\\\\\""'),
array('SELECT toto WHERE toto.a NOT LIKE ""'),
array('SELECT toto WHERE toto.a NOT LIKE "blah" AND toto.b LIKE "foo"'),
array('SELECT toto WHERE toto.a = 1 AND toto.b LIKE "x" AND toto.f >= 12345'),
array('SELECT Device JOIN Site ON Device.site = Site.id'),
array('SELECT Device JOIN Site ON Device.site = Site.id JOIN Country ON Site.location = Country.id'),
array('SELECT UserRightsMatrixClassGrant WHERE UserRightsMatrixClassGrant.class = \'lnkContactRealObject\' AND UserRightsMatrixClassGrant.action = \'modify\' AND UserRightsMatrixClassGrant.login = \'Denis\''),
array('SELECT A WHERE A.col1 = \'lit1\' AND A.col2 = \'lit2\' AND A.col3 = \'lit3\''),
array('SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 = 123 AND B.col1 = \'aa\') OR (A.col3 = \'zzz\' AND B.col4 > 100)'),
array('SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 = B.col2 AND B.col1 = A.col2) OR (A.col3 = \'\' AND B.col4 > 100)'),
array('SELECT A JOIN B ON A.myB = B.id WHERE A.col1 + B.col2 * B.col1 = A.col2'),
array('SELECT A JOIN B ON A.myB = B.id WHERE A.col1 + (B.col2 * B.col1) = A.col2'),
array('SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 + B.col2) * B.col1 = A.col2'),
array('SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 & B.col2) = A.col2'),
array('SELECT Device AS D_ JOIN Site AS S_ ON D_.site = S_.id WHERE S_.country = "Francia"'),
array('SELECT A FROM A'),
array('SELECT A JOIN B ON A.myB = B.id WHERE A.col1 = 2'),
array('SELECT A FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2'),
array('SELECT B FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2'),
array('SELECT A,B FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2'),
array('SELECT A, B FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2'),
array('SELECT B,A FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2'),
array('SELECT A, B,C FROM A JOIN B ON A.myB = B.id'),
array('SELECT C FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2'),
array('SELECT A JOIN B ON A.myB BELOW B.id WHERE A.col1 = 2'),
array('SELECT A JOIN B ON B.myA BELOW A.id WHERE A.col1 = 2'),
array('SELECT A JOIN B ON A.myB = B.id JOIN C ON C.parent_id BELOW B.id WHERE A.col1 = 2 AND B.id = 3'),
array('SELECT A JOIN B ON A.myB = B.id JOIN C ON C.parent_id BELOW STRICT B.id WHERE A.col1 = 2 AND B.id = 3'),
array('SELECT A JOIN B ON A.myB = B.id JOIN C ON C.parent_id NOT BELOW B.id WHERE A.col1 = 2 AND B.id = 3'),
array('SELECT A JOIN B ON A.myB = B.id JOIN C ON C.parent_id NOT BELOW STRICT B.id WHERE A.col1 = 2 AND B.id = 3'),
array('SELECT A UNION SELECT B'),
array('SELECT A WHERE A.b = "sdf" UNION SELECT B WHERE B.a = "sfde"'),
array('SELECT A UNION SELECT B UNION SELECT C'),
array('SELECT A UNION SELECT B UNION SELECT C UNION SELECT D'),
array('SELECT A JOIN B ON A.myB = B.id JOIN C ON C.parent_id NOT BELOW B.id WHERE A.col1 = 2 AND B.id = 3 UNION SELECT Device JOIN Site ON Device.site = Site.id JOIN Country ON Site.location = Country.id'),
array('SELECT Person AS B WHERE B.name LIKE \'%A%\''),
array('SELECT Server WHERE name REGEXP \'dbserver[0-9]+\''),
array('SELECT Server WHERE name REGEXP \'^dbserver[0-9]+\\\\..+\\\\.[a-z]{2,3}$\''),
array('SELECT Change AS ch WHERE ch.start_date >= \'2009-12-31\' AND ch.end_date <= \'2010-01-01\''),
array('SELECT DatacenterDevice AS dev WHERE INET_ATON(dev.managementip) > INET_ATON(\'10.22.32.224\') AND INET_ATON(dev.managementip) < INET_ATON(\'10.22.32.255\')'),
array('SELECT Person AS P JOIN Organization AS Node ON P.org_id = Node.id JOIN Organization AS Root ON Node.parent_id BELOW Root.id WHERE Root.id=1'),
array('SELECT PhysicalInterface AS if JOIN DatacenterDevice AS dev ON if.connectableci_id = dev.id WHERE dev.status = \'production\' AND dev.organization_name = \'Demo\''),
array('SELECT Ticket AS t WHERE t.agent_id = :current_contact_id'),
array('SELECT Person AS p JOIN UserRequest AS u ON u.agent_id = p.id WHERE u.status != \'closed\''),
array('SELECT Contract AS c WHERE c.end_date > NOW() AND c.end_date < DATE_ADD(NOW(), INTERVAL 30 DAY)'),
array('SELECT UserRequest AS u WHERE u.start_date < DATE_SUB(NOW(), INTERVAL 60 MINUTE) AND u.status = \'new\''),
array('SELECT UserRequest AS u WHERE u.close_date > DATE_ADD(u.start_date, INTERVAL 8 HOUR)'),
array('SELECT Ticket WHERE tagfield MATCHES \'salad\''),
);
}
public function GoodQueryProvider()
{
return [
['SELECT toto'],
['SELECT toto WHERE toto.a = 1'],
['SELECT toto WHERE toto.a = -1'],
['SELECT toto WHERE toto.a = (1-1)'],
['SELECT toto WHERE toto.a = (-1+3)'],
['SELECT toto WHERE toto.a = (3+-1)'],
['SELECT toto WHERE toto.a = (3--1)'],
['SELECT toto WHERE toto.a = 0xC'],
['SELECT toto WHERE toto.a = \'AXDVFS0xCZ32\''],
['SELECT toto WHERE toto.a = :myparameter'],
['SELECT toto WHERE toto.a IN (:param1)'],
['SELECT toto WHERE toto.a IN (:param1, :param2)'],
['SELECT toto WHERE toto.a=1'],
['SELECT toto WHERE toto.a = "1"'],
['SELECT toto WHERE toto.a & 1'],
['SELECT toto WHERE toto.a | 1'],
['SELECT toto WHERE toto.a ^ 1'],
['SELECT toto WHERE toto.a << 1'],
['SELECT toto WHERE toto.a >> 1'],
['SELECT toto WHERE toto.a NOT LIKE "That\'s it"'],
['SELECT toto WHERE toto.a NOT LIKE "That\'s \\"it\\""'],
['SELECT toto WHERE toto.a NOT LIKE \'That"s it\''],
['SELECT toto WHERE toto.a NOT LIKE \'That\\\'s it\''],
['SELECT toto WHERE toto.a NOT LIKE "blah \\\\ truc"'],
['SELECT toto WHERE toto.a NOT LIKE \'blah \\\\ truc\''],
['SELECT toto WHERE toto.a NOT LIKE "\\\\"'],
['SELECT toto WHERE toto.a NOT LIKE "\\""'],
['SELECT toto WHERE toto.a NOT LIKE "\\"\\\\"'],
['SELECT toto WHERE toto.a NOT LIKE "\\\\\\""'],
['SELECT toto WHERE toto.a NOT LIKE ""'],
['SELECT toto WHERE toto.a NOT LIKE "blah" AND toto.b LIKE "foo"'],
['SELECT toto WHERE toto.a = 1 AND toto.b LIKE "x" AND toto.f >= 12345'],
['SELECT Device JOIN Site ON Device.site = Site.id'],
['SELECT Device JOIN Site ON Device.site = Site.id JOIN Country ON Site.location = Country.id'],
['SELECT UserRightsMatrixClassGrant WHERE UserRightsMatrixClassGrant.class = \'lnkContactRealObject\' AND UserRightsMatrixClassGrant.action = \'modify\' AND UserRightsMatrixClassGrant.login = \'Denis\''],
['SELECT A WHERE A.col1 = \'lit1\' AND A.col2 = \'lit2\' AND A.col3 = \'lit3\''],
['SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 = 123 AND B.col1 = \'aa\') OR (A.col3 = \'zzz\' AND B.col4 > 100)'],
['SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 = B.col2 AND B.col1 = A.col2) OR (A.col3 = \'\' AND B.col4 > 100)'],
['SELECT A JOIN B ON A.myB = B.id WHERE A.col1 + B.col2 * B.col1 = A.col2'],
['SELECT A JOIN B ON A.myB = B.id WHERE A.col1 + (B.col2 * B.col1) = A.col2'],
['SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 + B.col2) * B.col1 = A.col2'],
['SELECT A JOIN B ON A.myB = B.id WHERE (A.col1 & B.col2) = A.col2'],
['SELECT Device AS D_ JOIN Site AS S_ ON D_.site = S_.id WHERE S_.country = "Francia"'],
['SELECT A FROM A'],
['SELECT A JOIN B ON A.myB = B.id WHERE A.col1 = 2'],
['SELECT A FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2'],
['SELECT B FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2'],
['SELECT A,B FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2'],
['SELECT A, B FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2'],
['SELECT B,A FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2'],
['SELECT A, B,C FROM A JOIN B ON A.myB = B.id'],
['SELECT C FROM A JOIN B ON A.myB = B.id WHERE A.col1 = 2'],
['SELECT A JOIN B ON A.myB BELOW B.id WHERE A.col1 = 2'],
['SELECT A JOIN B ON B.myA BELOW A.id WHERE A.col1 = 2'],
['SELECT A JOIN B ON A.myB = B.id JOIN C ON C.parent_id BELOW B.id WHERE A.col1 = 2 AND B.id = 3'],
['SELECT A JOIN B ON A.myB = B.id JOIN C ON C.parent_id BELOW STRICT B.id WHERE A.col1 = 2 AND B.id = 3'],
['SELECT A JOIN B ON A.myB = B.id JOIN C ON C.parent_id NOT BELOW B.id WHERE A.col1 = 2 AND B.id = 3'],
['SELECT A JOIN B ON A.myB = B.id JOIN C ON C.parent_id NOT BELOW STRICT B.id WHERE A.col1 = 2 AND B.id = 3'],
['SELECT A UNION SELECT B'],
['SELECT A WHERE A.b = "sdf" UNION SELECT B WHERE B.a = "sfde"'],
['SELECT A UNION SELECT B UNION SELECT C'],
['SELECT A UNION SELECT B UNION SELECT C UNION SELECT D'],
['SELECT A JOIN B ON A.myB = B.id JOIN C ON C.parent_id NOT BELOW B.id WHERE A.col1 = 2 AND B.id = 3 UNION SELECT Device JOIN Site ON Device.site = Site.id JOIN Country ON Site.location = Country.id'],
['SELECT Person AS B WHERE B.name LIKE \'%A%\''],
['SELECT Server WHERE name REGEXP \'dbserver[0-9]+\''],
['SELECT Server WHERE name REGEXP \'^dbserver[0-9]+\\\\..+\\\\.[a-z]{2,3}$\''],
['SELECT Change AS ch WHERE ch.start_date >= \'2009-12-31\' AND ch.end_date <= \'2010-01-01\''],
['SELECT DatacenterDevice AS dev WHERE INET_ATON(dev.managementip) > INET_ATON(\'10.22.32.224\') AND INET_ATON(dev.managementip) < INET_ATON(\'10.22.32.255\')'],
['SELECT Person AS P JOIN Organization AS Node ON P.org_id = Node.id JOIN Organization AS Root ON Node.parent_id BELOW Root.id WHERE Root.id=1'],
['SELECT PhysicalInterface AS if JOIN DatacenterDevice AS dev ON if.connectableci_id = dev.id WHERE dev.status = \'production\' AND dev.organization_name = \'Demo\''],
['SELECT Ticket AS t WHERE t.agent_id = :current_contact_id'],
['SELECT Person AS p JOIN UserRequest AS u ON u.agent_id = p.id WHERE u.status != \'closed\''],
['SELECT Contract AS c WHERE c.end_date > NOW() AND c.end_date < DATE_ADD(NOW(), INTERVAL 30 DAY)'],
['SELECT UserRequest AS u WHERE u.start_date < DATE_SUB(NOW(), INTERVAL 60 MINUTE) AND u.status = \'new\''],
['SELECT UserRequest AS u WHERE u.close_date > DATE_ADD(u.start_date, INTERVAL 8 HOUR)'],
['SELECT Ticket WHERE tagfield MATCHES \'salad\''],
];
}
/**
* @dataProvider BadQueryProvider
* @depends testOQLSetup
*
* @param $sQuery
* @param $sExpectedExceptionClass
*
*/
public function testBadQueryParser($sQuery, $sExpectedExceptionClass)
{
$this->debug($sQuery);
$oOql = new OqlInterpreter($sQuery);
$sExceptionClass = '';
try
{
$oOql->ParseQuery();
}
catch (Exception $e)
{
$sExceptionClass = get_class($e);
}
/**
* @dataProvider BadQueryProvider
* @depends testOQLSetup
*
* @param $sQuery
* @param $sExpectedExceptionClass
*
*/
public function testBadQueryParser($sQuery, $sExpectedExceptionClass)
{
$this->debug($sQuery);
$oOql = new OqlInterpreter($sQuery);
$sExceptionClass = '';
try {
$oOql->ParseQuery();
} catch (Exception $e) {
$sExceptionClass = get_class($e);
}
static::assertEquals($sExpectedExceptionClass, $sExceptionClass);
}
static::assertEquals($sExpectedExceptionClass, $sExceptionClass);
}
public function BadQueryProvider()
{
return array(
array('SELECT toto WHERE toto.a = (3++1)', 'OQLParserSyntaxErrorException'),
array('SELECT toto WHHHERE toto.a = "1"', 'OQLParserSyntaxErrorException'),
array('SELECT toto WHERE toto.a == "1"', 'OQLParserSyntaxErrorException'),
array('SELECT toto WHERE toto.a % 1', 'Exception'),
array('SELECT toto WHERE toto.a like \'arg\'', 'OQLParserSyntaxErrorException'),
array('SELECT toto WHERE toto.a NOT LIKE "That\'s "it""', 'OQLParserSyntaxErrorException'),
array('SELECT toto WHERE toto.a NOT LIKE \'That\'s it\'', 'OQLParserSyntaxErrorException'),
array('SELECT toto WHERE toto.a NOT LIKE "blah \\ truc"', 'Exception'),
array('SELECT toto WHERE toto.a NOT LIKE \'blah \\ truc\'', 'Exception'),
array('SELECT A JOIN B ON A.myB = B.id JOIN C ON C.parent_id = B.id WHERE A.col1 BELOW 2 AND B.id = 3', 'OQLParserSyntaxErrorException'),
);
}
public function BadQueryProvider()
{
return [
['SELECT toto WHERE toto.a = (3++1)', 'OQLParserSyntaxErrorException'],
['SELECT toto WHHHERE toto.a = "1"', 'OQLParserSyntaxErrorException'],
['SELECT toto WHERE toto.a == "1"', 'OQLParserSyntaxErrorException'],
['SELECT toto WHERE toto.a % 1', 'Exception'],
['SELECT toto WHERE toto.a like \'arg\'', 'OQLParserSyntaxErrorException'],
['SELECT toto WHERE toto.a NOT LIKE "That\'s "it""', 'OQLParserSyntaxErrorException'],
['SELECT toto WHERE toto.a NOT LIKE \'That\'s it\'', 'OQLParserSyntaxErrorException'],
['SELECT toto WHERE toto.a NOT LIKE "blah \\ truc"', 'Exception'],
['SELECT toto WHERE toto.a NOT LIKE \'blah \\ truc\'', 'Exception'],
['SELECT A JOIN B ON A.myB = B.id JOIN C ON C.parent_id = B.id WHERE A.col1 BELOW 2 AND B.id = 3', 'OQLParserSyntaxErrorException'],
];
}
/**
* Needs actual datamodel
* @depends testOQLSetup
*
* @dataProvider QueryNormalizationProvider
*
* @param $sQuery
* @param $sExpectedExceptionClass
*
*/
public function testQueryNormalization($sQuery, $sExpectedExceptionClass)
{
$this->debug($sQuery);
$sExceptionClass = '';
try
{
$oSearch = DBObjectSearch::FromOQL($sQuery);
static::assertInstanceOf('DBObjectSearch', $oSearch);
}
catch (Exception $e)
{
$sExceptionClass = get_class($e);
}
/**
* Needs actual datamodel
* @depends testOQLSetup
*
* @dataProvider QueryNormalizationProvider
*
* @param $sQuery
* @param $sExpectedExceptionClass
*
*/
public function testQueryNormalization($sQuery, $sExpectedExceptionClass)
{
$this->debug($sQuery);
$sExceptionClass = '';
try {
$oSearch = DBObjectSearch::FromOQL($sQuery);
static::assertInstanceOf('DBObjectSearch', $oSearch);
} catch (Exception $e) {
$sExceptionClass = get_class($e);
}
static::assertEquals($sExpectedExceptionClass, $sExceptionClass);
}
static::assertEquals($sExpectedExceptionClass, $sExceptionClass);
}
public function QueryNormalizationProvider()
{
return [
['SELECT Contact', ''],
['SELECT Contact WHERE nom_de_famille = "foo"', 'OqlNormalizeException'],
['SELECT Contact AS c WHERE name = "foo"', ''],
['SELECT Contact AS c WHERE nom_de_famille = "foo"', 'OqlNormalizeException'],
['SELECT Contact AS c WHERE c.name = "foo"', ''],
['SELECT Contact AS c WHERE Contact.name = "foo"', 'OqlNormalizeException'],
['SELECT Contact AS c WHERE x.name = "foo"', 'OqlNormalizeException'],
public function QueryNormalizationProvider()
{
return array(
array('SELECT Contact', ''),
array('SELECT Contact WHERE nom_de_famille = "foo"', 'OqlNormalizeException'),
array('SELECT Contact AS c WHERE name = "foo"', ''),
array('SELECT Contact AS c WHERE nom_de_famille = "foo"', 'OqlNormalizeException'),
array('SELECT Contact AS c WHERE c.name = "foo"', ''),
array('SELECT Contact AS c WHERE Contact.name = "foo"', 'OqlNormalizeException'),
array('SELECT Contact AS c WHERE x.name = "foo"', 'OqlNormalizeException'),
['SELECT Organization AS child JOIN Organization AS root ON child.parent_id BELOW root.id', ''],
['SELECT Organization AS root JOIN Organization AS child ON child.parent_id BELOW root.id', ''],
array('SELECT Organization AS child JOIN Organization AS root ON child.parent_id BELOW root.id', ''),
array('SELECT Organization AS root JOIN Organization AS child ON child.parent_id BELOW root.id', ''),
['SELECT RelationProfessionnelle', 'UnknownClassOqlException'],
['SELECT RelationProfessionnelle AS c WHERE name = "foo"', 'UnknownClassOqlException'],
array('SELECT RelationProfessionnelle', 'UnknownClassOqlException'),
array('SELECT RelationProfessionnelle AS c WHERE name = "foo"', 'UnknownClassOqlException'),
// The first query is the base query altered only in one place in the subsequent queries
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.id WHERE p.name LIKE "foo"', ''],
['SELECT Person AS p JOIN lnkXXXXXXXXXXXX AS lnk ON lnk.person_id = p.id WHERE p.name LIKE "foo"', 'UnknownClassOqlException'],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON p.person_id = p.id WHERE p.name LIKE "foo"', 'OqlNormalizeException'],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON person_id = p.id WHERE p.name LIKE "foo"', 'OqlNormalizeException'],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = id WHERE p.name LIKE "foo"', 'OqlNormalizeException'],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.role = p.id WHERE p.name LIKE "foo"', 'OqlNormalizeException'],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.team_id = p.id WHERE p.name LIKE "foo"', 'OqlNormalizeException'],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id BELOW p.id WHERE p.name LIKE "bar"', ''],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.org_id WHERE p.name LIKE "foo"', 'OqlNormalizeException'],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON p.id = lnk.person_id WHERE p.name LIKE "foo"', 'OqlNormalizeException'], // inverted the JOIN spec
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.id WHERE name LIKE "foo"', ''],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.id WHERE x.name LIKE "foo"', 'OqlNormalizeException'],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.id WHERE p.eman LIKE "foo"', 'OqlNormalizeException'],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.id WHERE eman LIKE "foo"', 'OqlNormalizeException'],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.id WHERE id = 1', 'OqlNormalizeException'],
['SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON p.id = lnk.person_id WHERE p.name LIKE "foo"', 'OqlNormalizeException'],
// The first query is the base query altered only in one place in the subsequent queries
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.id WHERE p.name LIKE "foo"', ''),
array('SELECT Person AS p JOIN lnkXXXXXXXXXXXX AS lnk ON lnk.person_id = p.id WHERE p.name LIKE "foo"', 'UnknownClassOqlException'),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON p.person_id = p.id WHERE p.name LIKE "foo"', 'OqlNormalizeException'),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON person_id = p.id WHERE p.name LIKE "foo"', 'OqlNormalizeException'),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = id WHERE p.name LIKE "foo"', 'OqlNormalizeException'),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.role = p.id WHERE p.name LIKE "foo"', 'OqlNormalizeException'),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.team_id = p.id WHERE p.name LIKE "foo"', 'OqlNormalizeException'),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id BELOW p.id WHERE p.name LIKE "bar"', ''),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.org_id WHERE p.name LIKE "foo"', 'OqlNormalizeException'),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON p.id = lnk.person_id WHERE p.name LIKE "foo"', 'OqlNormalizeException'), // inverted the JOIN spec
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.id WHERE name LIKE "foo"', ''),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.id WHERE x.name LIKE "foo"', 'OqlNormalizeException'),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.id WHERE p.eman LIKE "foo"', 'OqlNormalizeException'),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.id WHERE eman LIKE "foo"', 'OqlNormalizeException'),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON lnk.person_id = p.id WHERE id = 1', 'OqlNormalizeException'),
array('SELECT Person AS p JOIN lnkPersonToTeam AS lnk ON p.id = lnk.person_id WHERE p.name LIKE "foo"', 'OqlNormalizeException'),
['SELECT Person AS p JOIN Organization AS o ON p.org_id = o.id WHERE p.name LIKE "foo" AND o.name LIKE "land"', ''],
['SELECT Person AS p JOIN Organization AS o ON p.location_id = o.id WHERE p.name LIKE "foo" AND o.name LIKE "land"', 'OqlNormalizeException'],
['SELECT Person AS p JOIN Organization AS o ON p.name = o.id WHERE p.name LIKE "foo" AND o.name LIKE "land"', 'OqlNormalizeException'],
array('SELECT Person AS p JOIN Organization AS o ON p.org_id = o.id WHERE p.name LIKE "foo" AND o.name LIKE "land"', ''),
array('SELECT Person AS p JOIN Organization AS o ON p.location_id = o.id WHERE p.name LIKE "foo" AND o.name LIKE "land"', 'OqlNormalizeException'),
array('SELECT Person AS p JOIN Organization AS o ON p.name = o.id WHERE p.name LIKE "foo" AND o.name LIKE "land"', 'OqlNormalizeException'),
['SELECT Person AS p JOIN Organization AS o ON p.org_id = o.id JOIN Person AS p ON p.org_id = o.id', 'OqlNormalizeException'],
['SELECT Person JOIN Organization AS o ON Person.org_id = o.id JOIN Person ON Person.org_id = o.id', 'OqlNormalizeException'],
array('SELECT Person AS p JOIN Organization AS o ON p.org_id = o.id JOIN Person AS p ON p.org_id = o.id', 'OqlNormalizeException'),
array('SELECT Person JOIN Organization AS o ON Person.org_id = o.id JOIN Person ON Person.org_id = o.id', 'OqlNormalizeException'),
['SELECT Person AS p JOIN Location AS l ON p.location_id = l.id', ''],
['SELECT Person AS p JOIN Location AS l ON p.location_id BELOW l.id', 'OqlNormalizeException'],
array('SELECT Person AS p JOIN Location AS l ON p.location_id = l.id', ''),
array('SELECT Person AS p JOIN Location AS l ON p.location_id BELOW l.id', 'OqlNormalizeException'),
array('SELECT Person FROM Person JOIN Location ON Person.location_id = Location.id', ''),
array('SELECT p FROM Person AS p JOIN Location AS l ON p.location_id = l.id', ''),
array('SELECT l FROM Person AS p JOIN Location AS l ON p.location_id = l.id', ''),
array('SELECT l, p FROM Person AS p JOIN Location AS l ON p.location_id = l.id', ''),
array('SELECT p, l FROM Person AS p JOIN Location AS l ON p.location_id = l.id', ''),
array('SELECT foo FROM Person AS p JOIN Location AS l ON p.location_id = l.id', 'OqlNormalizeException'),
array('SELECT p, foo FROM Person AS p JOIN Location AS l ON p.location_id = l.id', 'OqlNormalizeException'),
// Joins based on AttributeObjectKey
//
array('SELECT Attachment AS a JOIN UserRequest AS r ON a.item_id = r.id', ''),
array('SELECT UserRequest AS r JOIN Attachment AS a ON a.item_id = r.id', ''),
);
}
['SELECT Person FROM Person JOIN Location ON Person.location_id = Location.id', ''],
['SELECT p FROM Person AS p JOIN Location AS l ON p.location_id = l.id', ''],
['SELECT l FROM Person AS p JOIN Location AS l ON p.location_id = l.id', ''],
['SELECT l, p FROM Person AS p JOIN Location AS l ON p.location_id = l.id', ''],
['SELECT p, l FROM Person AS p JOIN Location AS l ON p.location_id = l.id', ''],
['SELECT foo FROM Person AS p JOIN Location AS l ON p.location_id = l.id', 'OqlNormalizeException'],
['SELECT p, foo FROM Person AS p JOIN Location AS l ON p.location_id = l.id', 'OqlNormalizeException'],
// Joins based on AttributeObjectKey
//
['SELECT Attachment AS a JOIN UserRequest AS r ON a.item_id = r.id', ''],
['SELECT UserRequest AS r JOIN Attachment AS a ON a.item_id = r.id', ''],
];
}
/**
* @depends testOQLSetup
@@ -331,7 +321,7 @@ class OQLTest extends ItopDataTestCase
public function OQLIntersectProvider()
{
return array(
return [
// Wrong result:
/*
SELECT `SSC`
@@ -349,17 +339,17 @@ class OQLTest extends ItopDataTestCase
// "SELECT ServiceSubcategory AS ssc JOIN Service AS s ON ssc.service_id=s.id JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = :current_contact->org_id AND ssc.status != 'obsolete'",
// "SELECT `SSC` FROM ServiceSubcategory AS `SSC` JOIN Service AS `S` ON `SSC`.service_id = `S`.id JOIN lnkCustomerContractToService AS `l11` ON `l11`.service_id = `S`.id JOIN CustomerContract AS `cc` ON `l11`.customercontract_id = `cc`.id JOIN lnkGRTypeToServiceSubcategory AS `l1` ON `l1`.servicesubcategory_id = `SSC`.id JOIN GRType AS `GRT` ON `l1`.grtype_id = `GRT`.id WHERE ((`GRT`.`id` = :grtype_id) AND ((`cc`.`org_id` = :current_contact->org_id) AND (`SSC`.`status` != 'obsolete')))"
// ),
'Person' => array(
'Person' => [
"SELECT P FROM Person AS P JOIN lnkPersonToTeam AS l1 ON l1.person_id = P.id JOIN Team AS T ON l1.team_id = T.id WHERE T.id = 3",
"SELECT p FROM Person AS p JOIN Person AS mgr ON p.manager_id = mgr.id JOIN lnkContactToTicket AS l1 ON l1.contact_id = mgr.id JOIN Ticket AS T ON l1.ticket_id = T.id WHERE T.id = 4 AND p.id = 3",
"SELECT `P` FROM Person AS `P` JOIN Person AS `mgr` ON `P`.manager_id = `mgr`.id JOIN lnkContactToTicket AS `l11` ON `l11`.contact_id = `mgr`.id JOIN Ticket AS `T1` ON `l11`.ticket_id = `T1`.id JOIN lnkPersonToTeam AS `l1` ON `l1`.person_id = `P`.id JOIN Team AS `T` ON `l1`.team_id = `T`.id WHERE ((`T`.`id` = 3) AND ((`T1`.`id` = 4) AND (`P`.`id` = 3)))"
),
'Person2' => array(
"SELECT `P` FROM Person AS `P` JOIN Person AS `mgr` ON `P`.manager_id = `mgr`.id JOIN lnkContactToTicket AS `l11` ON `l11`.contact_id = `mgr`.id JOIN Ticket AS `T1` ON `l11`.ticket_id = `T1`.id JOIN lnkPersonToTeam AS `l1` ON `l1`.person_id = `P`.id JOIN Team AS `T` ON `l1`.team_id = `T`.id WHERE ((`T`.`id` = 3) AND ((`T1`.`id` = 4) AND (`P`.`id` = 3)))",
],
'Person2' => [
"SELECT P FROM Person AS P JOIN lnkPersonToTeam AS l1 ON l1.person_id = P.id JOIN Team AS T ON l1.team_id = T.id JOIN Person AS MGR ON P.manager_id = MGR.id WHERE T.id = 3",
"SELECT p FROM Person AS p JOIN Person AS mgr ON p.manager_id = mgr.id JOIN lnkContactToTicket AS l1 ON l1.contact_id = mgr.id JOIN Ticket AS T ON l1.ticket_id = T.id WHERE T.id = 4 AND p.id = 3",
"SELECT `P` FROM Person AS `P` JOIN Person AS `MGR` ON `P`.manager_id = `MGR`.id JOIN lnkContactToTicket AS `l11` ON `l11`.contact_id = `MGR`.id JOIN Ticket AS `T1` ON `l11`.ticket_id = `T1`.id JOIN lnkPersonToTeam AS `l1` ON `l1`.person_id = `P`.id JOIN Team AS `T` ON `l1`.team_id = `T`.id WHERE ((`T`.`id` = 3) AND ((`T1`.`id` = 4) AND (`P`.`id` = 3)))"
),
);
"SELECT `P` FROM Person AS `P` JOIN Person AS `MGR` ON `P`.manager_id = `MGR`.id JOIN lnkContactToTicket AS `l11` ON `l11`.contact_id = `MGR`.id JOIN Ticket AS `T1` ON `l11`.ticket_id = `T1`.id JOIN lnkPersonToTeam AS `l1` ON `l1`.person_id = `P`.id JOIN Team AS `T` ON `l1`.team_id = `T`.id WHERE ((`T`.`id` = 3) AND ((`T1`.`id` = 4) AND (`P`.`id` = 3)))",
],
];
}
/**
@@ -370,13 +360,10 @@ class OQLTest extends ItopDataTestCase
public function testMakeSelectQuery($sOQL, $sExpectedExceptionClass = '')
{
$sExceptionClass = '';
try
{
try {
$oSearch = DBSearch::FromOQL($sOQL);
CMDBSource::TestQuery($oSearch->MakeSelectQuery());
}
catch (Exception $e)
{
} catch (Exception $e) {
$this->debug($e->getMessage());
$sExceptionClass = get_class($e);
}
@@ -386,22 +373,21 @@ class OQLTest extends ItopDataTestCase
public function MakeSelectQueryProvider()
{
return array(
array("SELECT `UserRequest` FROM UserRequest AS `UserRequest` JOIN Person AS `P` ON `UserRequest`.agent_id = `P`.id JOIN Organization AS `Organization` ON `P`.org_id = `Organization`.id WHERE (`UserRequest`.`org_id` IN (SELECT `Organization` FROM Organization AS `Organization` WHERE (`Organization`.`id` = `Toto`.`org_id`)))", 'OqlNormalizeException'),
array("SELECT `UserRequest` FROM UserRequest AS `UserRequest` JOIN Person AS `P` ON `UserRequest`.agent_id = `P`.id JOIN Organization AS `Organization` ON `P`.org_id = `Organization`.id WHERE (`UserRequest`.`org_id` IN (SELECT `Organization` FROM Organization AS `Organization` WHERE (`Organization`.`id` = `UserRequest`.`org_id`)))"),
array("SELECT `U` FROM User AS `U` JOIN Person AS `P` ON `U`.contactid = `P`.id WHERE ((`U`.`status` = 'enabled') AND (`U`.`id` NOT IN (SELECT `U` FROM User AS `U` JOIN Person AS `P` ON `U`.contactid = `P`.id JOIN URP_UserOrg AS `L` ON `L`.userid = `U`.id WHERE ((`U`.`status` = 'enabled') AND (`L`.`allowed_org_id` = `P`.`org_id`)) UNION SELECT `U` FROM User AS `U` WHERE ((`U`.`status` = 'enabled') AND (`U`.`id` NOT IN (SELECT `U` FROM User AS `U` JOIN URP_UserOrg AS `L` ON `L`.userid = `U`.id WHERE (`U`.`status` = 'enabled')))))))"),
array("SELECT `Ur` FROM UserRequest AS `Ur` WHERE (`Ur`.`id` NOT IN (SELECT `Ur` FROM UserRequest AS `Ur` JOIN lnkFunctionalCIToTicket AS `lnk` ON `lnk`.ticket_id = `Ur`.id WHERE 1))"),
array("SELECT `T` FROM Ticket AS `T` WHERE ((`T`.`finalclass` IN ('userrequest', 'change')) AND (`T`.`id` NOT IN (SELECT `Ur` FROM UserRequest AS `Ur` JOIN lnkFunctionalCIToTicket AS `lnk` ON `lnk`.ticket_id = `Ur`.id WHERE 1 UNION SELECT `C` FROM Change AS `C` JOIN lnkFunctionalCIToTicket AS `lnk` ON `lnk`.ticket_id = `C`.id WHERE 1)))"),
array("SELECT `PhysicalDevice` FROM PhysicalDevice AS `PhysicalDevice` WHERE ((`PhysicalDevice`.`status` = 'production') AND (`PhysicalDevice`.`id` NOT IN (SELECT `p` FROM PhysicalDevice AS `p` JOIN lnkFunctionalCIToProviderContract AS `l` ON `l`.functionalci_id = `p`.id WHERE 1)))"),
array("SELECT `U` FROM User AS `U` JOIN Person AS `P` ON `U`.contactid = `P`.id WHERE ((`U`.`status` = 'enabled') AND (`U`.`id` NOT IN (SELECT `U` FROM User AS `U` JOIN Person AS `P` ON `U`.contactid = `P`.id JOIN URP_UserOrg AS `L` ON `L`.userid = `U`.id WHERE ((`U1`.`status` = 'enabled') AND (`L`.`allowed_org_id` = `P`.`org_id`)) UNION SELECT `U` FROM User AS `U` WHERE ((`U`.`status` = 'enabled') AND (`U`.`id` NOT IN (SELECT `U` FROM User AS `U` JOIN URP_UserOrg AS `L` ON `L`.userid = `U`.id WHERE (`U`.`status` = 'enabled')))))))", "OqlNormalizeException"),
array("SELECT Team WHERE id NOT IN (SELECT Team AS t JOIN lnkPersonToTeam AS l ON l.team_id=t.id WHERE 1)"),
array("SELECT UserRequest WHERE id NOT IN (SELECT UserRequest AS u JOIN lnkFunctionalCIToTicket AS l ON l.ticket_id=u.id JOIN PhysicalDevice AS f ON l.functionalci_id=f.id WHERE f.status='production')"),
array("SELECT UserRequest WHERE id NOT IN (SELECT UserRequest AS u JOIN lnkFunctionalCIToTicket AS l ON l.ticket_id=u.id JOIN PhysicalDevice AS f ON l.functionalci_id=f.id WHERE f.status='production' UNION SELECT UserRequest AS u JOIN lnkFunctionalCIToTicket AS l ON l.ticket_id=u.id JOIN ApplicationSolution AS f ON l.functionalci_id=f.id WHERE f.status='active')"),
array("SELECT Person WHERE status='active' AND id NOT IN (SELECT Person AS p JOIN User AS u ON u.contactid=p.id WHERE u.status='enabled')"),
);
return [
["SELECT `UserRequest` FROM UserRequest AS `UserRequest` JOIN Person AS `P` ON `UserRequest`.agent_id = `P`.id JOIN Organization AS `Organization` ON `P`.org_id = `Organization`.id WHERE (`UserRequest`.`org_id` IN (SELECT `Organization` FROM Organization AS `Organization` WHERE (`Organization`.`id` = `Toto`.`org_id`)))", 'OqlNormalizeException'],
["SELECT `UserRequest` FROM UserRequest AS `UserRequest` JOIN Person AS `P` ON `UserRequest`.agent_id = `P`.id JOIN Organization AS `Organization` ON `P`.org_id = `Organization`.id WHERE (`UserRequest`.`org_id` IN (SELECT `Organization` FROM Organization AS `Organization` WHERE (`Organization`.`id` = `UserRequest`.`org_id`)))"],
["SELECT `U` FROM User AS `U` JOIN Person AS `P` ON `U`.contactid = `P`.id WHERE ((`U`.`status` = 'enabled') AND (`U`.`id` NOT IN (SELECT `U` FROM User AS `U` JOIN Person AS `P` ON `U`.contactid = `P`.id JOIN URP_UserOrg AS `L` ON `L`.userid = `U`.id WHERE ((`U`.`status` = 'enabled') AND (`L`.`allowed_org_id` = `P`.`org_id`)) UNION SELECT `U` FROM User AS `U` WHERE ((`U`.`status` = 'enabled') AND (`U`.`id` NOT IN (SELECT `U` FROM User AS `U` JOIN URP_UserOrg AS `L` ON `L`.userid = `U`.id WHERE (`U`.`status` = 'enabled')))))))"],
["SELECT `Ur` FROM UserRequest AS `Ur` WHERE (`Ur`.`id` NOT IN (SELECT `Ur` FROM UserRequest AS `Ur` JOIN lnkFunctionalCIToTicket AS `lnk` ON `lnk`.ticket_id = `Ur`.id WHERE 1))"],
["SELECT `T` FROM Ticket AS `T` WHERE ((`T`.`finalclass` IN ('userrequest', 'change')) AND (`T`.`id` NOT IN (SELECT `Ur` FROM UserRequest AS `Ur` JOIN lnkFunctionalCIToTicket AS `lnk` ON `lnk`.ticket_id = `Ur`.id WHERE 1 UNION SELECT `C` FROM Change AS `C` JOIN lnkFunctionalCIToTicket AS `lnk` ON `lnk`.ticket_id = `C`.id WHERE 1)))"],
["SELECT `PhysicalDevice` FROM PhysicalDevice AS `PhysicalDevice` WHERE ((`PhysicalDevice`.`status` = 'production') AND (`PhysicalDevice`.`id` NOT IN (SELECT `p` FROM PhysicalDevice AS `p` JOIN lnkFunctionalCIToProviderContract AS `l` ON `l`.functionalci_id = `p`.id WHERE 1)))"],
["SELECT `U` FROM User AS `U` JOIN Person AS `P` ON `U`.contactid = `P`.id WHERE ((`U`.`status` = 'enabled') AND (`U`.`id` NOT IN (SELECT `U` FROM User AS `U` JOIN Person AS `P` ON `U`.contactid = `P`.id JOIN URP_UserOrg AS `L` ON `L`.userid = `U`.id WHERE ((`U1`.`status` = 'enabled') AND (`L`.`allowed_org_id` = `P`.`org_id`)) UNION SELECT `U` FROM User AS `U` WHERE ((`U`.`status` = 'enabled') AND (`U`.`id` NOT IN (SELECT `U` FROM User AS `U` JOIN URP_UserOrg AS `L` ON `L`.userid = `U`.id WHERE (`U`.`status` = 'enabled')))))))", "OqlNormalizeException"],
["SELECT Team WHERE id NOT IN (SELECT Team AS t JOIN lnkPersonToTeam AS l ON l.team_id=t.id WHERE 1)"],
["SELECT UserRequest WHERE id NOT IN (SELECT UserRequest AS u JOIN lnkFunctionalCIToTicket AS l ON l.ticket_id=u.id JOIN PhysicalDevice AS f ON l.functionalci_id=f.id WHERE f.status='production')"],
["SELECT UserRequest WHERE id NOT IN (SELECT UserRequest AS u JOIN lnkFunctionalCIToTicket AS l ON l.ticket_id=u.id JOIN PhysicalDevice AS f ON l.functionalci_id=f.id WHERE f.status='production' UNION SELECT UserRequest AS u JOIN lnkFunctionalCIToTicket AS l ON l.ticket_id=u.id JOIN ApplicationSolution AS f ON l.functionalci_id=f.id WHERE f.status='active')"],
["SELECT Person WHERE status='active' AND id NOT IN (SELECT Person AS p JOIN User AS u ON u.contactid=p.id WHERE u.status='enabled')"],
];
}
/**
* @dataProvider GetOQLClassTreeProvider
* @param $sOQL
@@ -410,13 +396,11 @@ class OQLTest extends ItopDataTestCase
public function testGetOQLClassTree($sOQL, $sExpectedOQL)
{
$oFilter = DBSearch::FromOQL($sOQL);
$aCountAttToLoad = array();
$aCountAttToLoad = [];
$sMainClass = null;
foreach ($oFilter->GetSelectedClasses() as $sClassAlias => $sClass)
{
$aCountAttToLoad[$sClassAlias] = array();
if (empty($sMainClass))
{
foreach ($oFilter->GetSelectedClasses() as $sClassAlias => $sClass) {
$aCountAttToLoad[$sClassAlias] = [];
if (empty($sMainClass)) {
$sMainClass = $sClass;
}
}
@@ -462,10 +446,10 @@ class OQLTest extends ItopDataTestCase
{
$oFilter = DBSearch::FromOQL($sOQL);
// Avoid adding all the fields for counts or "group by" requests
$aCountAttToLoad = array();
$aCountAttToLoad = [];
$sMainClass = null;
foreach ($oFilter->GetSelectedClasses() as $sClassAlias => $sClass) {
$aCountAttToLoad[$sClassAlias] = array();
$aCountAttToLoad[$sClassAlias] = [];
if (empty($sMainClass)) {
$sMainClass = $sClass;
}

View File

@@ -140,8 +140,6 @@ class ormDocumentTest extends ItopDataTestCase
];
}
public function testResizeImageToFitShouldResizeImageWhenImageIsTooBig()
{
$sImageData = base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAoAAAAICAIAAABPmPnhAAAAe0lEQVQI132OMQoCMRRE3/9Z3M126V0kB9BCvICnziXs7QIWlttqpWMRFQT1VcMbGMb4xPoQ18uWL4eTxxglSaq1Au8OwM1TSi3nnLGnzxKA4fM8N1VKQVyPZ6Br6s4Xhj7st9OwcNy61yUsGEK3Nmu+mUawcbfiN85fHsBoHdXt5HATAAAAAElFTkSuQmCC');
@@ -159,9 +157,9 @@ class ormDocumentTest extends ItopDataTestCase
'height' => $aRealDimensions[1],
];
$this->assertNotSame( $oDoc, $oResult, 'ResizeImageToFit should return a new object when there have been some modifications');
$this->assertIsArray( $aDimensions, 'ResizeImageToFit should fill aDimension with the dimensions of the new image when there are no issues');
$this->assertEquals( $aDimensions, $aActualDimensions, 'The returned dimensions should match the real dimensions of the image');
$this->assertNotSame($oDoc, $oResult, 'ResizeImageToFit should return a new object when there have been some modifications');
$this->assertIsArray($aDimensions, 'ResizeImageToFit should fill aDimension with the dimensions of the new image when there are no issues');
$this->assertEquals($aDimensions, $aActualDimensions, 'The returned dimensions should match the real dimensions of the image');
$this->assertLessThanOrEqual($iMawWidth, $aActualDimensions['width'], 'The new width should be less than or equal to max width');
$this->assertLessThanOrEqual($iMaxHeight, $aActualDimensions['height'], 'The new height should be less than or equal to max height');
}
@@ -177,8 +175,8 @@ class ormDocumentTest extends ItopDataTestCase
$oResult = $oDoc->ResizeImageToFit($iMawWidth, $iMaxHeight, $aDimensions);
$this->assertSame( $oDoc, $oResult, 'ResizeImageToFit should return the same object when there have been no modifications');
$this->assertIsArray( $aDimensions, 'ResizeImageToFit should fill aDimension with the dimensions of the image when there are no issues');
$this->assertSame($oDoc, $oResult, 'ResizeImageToFit should return the same object when there have been no modifications');
$this->assertIsArray($aDimensions, 'ResizeImageToFit should fill aDimension with the dimensions of the image when there are no issues');
}
public function testResizeImageToFitShouldDoNothingWhenItCannotReadTheImage()
@@ -192,8 +190,8 @@ class ormDocumentTest extends ItopDataTestCase
$oResult = $oDoc->ResizeImageToFit($iMawWidth, $iMaxHeight, $aDimensions);
$this->assertSame( $oDoc, $oResult, 'ResizeImageToFit should return the same object when there have been no modifications');
$this->assertNull( $aDimensions, 'ResizeImageToFit should fill aDimension with null when there are issues');
$this->assertSame($oDoc, $oResult, 'ResizeImageToFit should return the same object when there have been no modifications');
$this->assertNull($aDimensions, 'ResizeImageToFit should fill aDimension with null when there are issues');
}
public function testResizeImageToFitShouldDoNothingWhenItDoesNotHandleTheMimeType()
@@ -207,8 +205,8 @@ class ormDocumentTest extends ItopDataTestCase
$oResult = $oDoc->ResizeImageToFit($iMawWidth, $iMaxHeight, $aDimensions);
$this->assertSame( $oDoc, $oResult, 'ResizeImageToFit should return the same object when there have been no modifications');
$this->assertNull( $aDimensions, 'ResizeImageToFit should fill aDimension with null when there are issues');
$this->assertSame($oDoc, $oResult, 'ResizeImageToFit should return the same object when there have been no modifications');
$this->assertNull($aDimensions, 'ResizeImageToFit should fill aDimension with null when there are issues');
}
public function testResizeImageToFitShouldNotResizeWhenMaximumIs0()
@@ -222,8 +220,8 @@ class ormDocumentTest extends ItopDataTestCase
$oResult = $oDoc->ResizeImageToFit($iMawWidth, $iMaxHeight, $aDimensions);
$this->assertSame( $oDoc, $oResult, 'ResizeImageToFit should return the same object when there have been no modifications');
$this->assertIsArray( $aDimensions, 'ResizeImageToFit should fill aDimension with the dimensions of the image when there are no issues');
$this->assertSame($oDoc, $oResult, 'ResizeImageToFit should return the same object when there have been no modifications');
$this->assertIsArray($aDimensions, 'ResizeImageToFit should fill aDimension with the dimensions of the image when there are no issues');
}
public function testResizeImageToFitShouldIgnoreMaximum0Axis()
@@ -243,9 +241,9 @@ class ormDocumentTest extends ItopDataTestCase
'height' => $aRealDimensions[1],
];
$this->assertNotSame( $oDoc, $oResult, 'ResizeImageToFit should return a new object when there have been some modifications');
$this->assertIsArray( $aDimensions, 'ResizeImageToFit should fill aDimension with the dimensions of the new image when there are no issues');
$this->assertEquals( $aDimensions, $aActualDimensions, 'The returned dimensions should match the real dimensions of the image');
$this->assertNotSame($oDoc, $oResult, 'ResizeImageToFit should return a new object when there have been some modifications');
$this->assertIsArray($aDimensions, 'ResizeImageToFit should fill aDimension with the dimensions of the new image when there are no issues');
$this->assertEquals($aDimensions, $aActualDimensions, 'The returned dimensions should match the real dimensions of the image');
$this->assertEquals($iMawWidth, $aActualDimensions['width'], 'The new width should be exactly the max width');
$this->assertGreaterThanOrEqual($iMaxHeight, $aActualDimensions['height'], 'The new height should not be 0');
}

View File

@@ -6,7 +6,6 @@ use CMDBSource;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
use MetaModel;
/**
* created a dedicated test for external keys imports.
*
@@ -14,28 +13,31 @@ use MetaModel;
*
* @package Combodo\iTop\Test\UnitTest\Core
*/
class BulkChangeExtKeyTest extends ItopDataTestCase {
const CREATE_TEST_ORG = true;
class BulkChangeExtKeyTest extends ItopDataTestCase
{
public const CREATE_TEST_ORG = true;
/**
* this test may delete Person objects to cover all usecases
* DO NOT CHANGE USE_TRANSACTION value to avoid any DB loss!
*/
const USE_TRANSACTION = true;
public const USE_TRANSACTION = true;
private $sUid;
protected function setUp() : void {
protected function setUp(): void
{
parent::setUp();
require_once(APPROOT.'core/bulkchange.class.inc.php');
}
private function deleteAllRacks(){
private function deleteAllRacks()
{
$oSearch = \DBSearch::FromOQL("SELECT Rack");
$oSet = new \DBObjectSet($oSearch);
$iCount = $oSet->Count();
if ($iCount != 0){
while ($oRack = $oSet->Fetch()){
if ($iCount != 0) {
while ($oRack = $oSet->Fetch()) {
$oRack->DBDelete();
}
}
@@ -44,7 +46,8 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
/**
* @dataProvider ReconciliationKeyProvider
*/
public function testExternalFieldIssueImportFail_NoObjectAtAll($bIsRackReconKey){
public function testExternalFieldIssueImportFail_NoObjectAtAll($bIsRackReconKey)
{
$this->deleteAllRacks();
$this->performBulkChangeTest(
@@ -55,7 +58,8 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
);
}
public function createRackObjects($aRackDict) {
public function createRackObjects($aRackDict)
{
foreach ($aRackDict as $iOrgId => $aRackNames) {
foreach ($aRackNames as $sRackName) {
$this->createObject('Rack', ['name' => $sRackName, 'description' => "{$sRackName}Desc", 'org_id' => $iOrgId]);
@@ -63,9 +67,10 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
}
}
private function createAnotherUserInAnotherOrg() {
private function createAnotherUserInAnotherOrg()
{
$oOrg2 = $this->CreateOrganization('UnitTestOrganization2');
$oProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => 'Configuration Manager'), true);
$oProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", ['name' => 'Configuration Manager'], true);
$sUid = $this->GetUid();
@@ -73,13 +78,13 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
$oSet->AddItem(MetaModel::NewObject('URP_UserProfile', ['profileid' => $oProfile->GetKey(), 'reason' => 'UNIT Tests']));
$oPerson = $this->CreatePerson('666', $oOrg2->GetKey());
$oUser = $this->createObject('UserLocal', array(
$oUser = $this->createObject('UserLocal', [
'contactid' => $oPerson->GetKey(),
'login' => $sUid,
'password' => "ABCdef$sUid@12345",
'language' => 'EN US',
'profile_list' => $oSet,
));
]);
$oAllowedOrgList = $oUser->Get('allowed_org_list');
/** @var \URP_UserOrg $oUserOrg */
@@ -90,22 +95,23 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
return [$oOrg2, $oUser];
}
public function ReconciliationKeyProvider(){
public function ReconciliationKeyProvider()
{
return [
'rack_id NOT a reconcilication key' => [ false ],
'rack_id reconcilication key' => [ true ],
];
}
/**
* @dataProvider ReconciliationKeyProvider
*/
public function testExternalFieldIssueImportFail_NoObjectVisibleByCurrentUser($bIsRackReconKey){
public function testExternalFieldIssueImportFail_NoObjectVisibleByCurrentUser($bIsRackReconKey)
{
$this->deleteAllRacks();
$this->createRackObjects(
[
$this->getTestOrgId() => ['RackTest1', 'RackTest2', 'RackTest3', 'RackTest4']
$this->getTestOrgId() => ['RackTest1', 'RackTest2', 'RackTest3', 'RackTest4'],
]
);
@@ -123,7 +129,8 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
/**
* @dataProvider ReconciliationKeyProvider
*/
public function testExternalFieldIssueImportFail_SomeObjectVisibleByCurrentUser($bIsRackReconKey){
public function testExternalFieldIssueImportFail_SomeObjectVisibleByCurrentUser($bIsRackReconKey)
{
$this->deleteAllRacks();
[$oOrg2, $oUser] = $this->createAnotherUserInAnotherOrg();
$this->createRackObjects(
@@ -146,11 +153,12 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
/**
* @dataProvider ReconciliationKeyProvider
*/
public function testExternalFieldIssueImportFail_AllObjectsVisibleByCurrentUser($bIsRackReconKey){
public function testExternalFieldIssueImportFail_AllObjectsVisibleByCurrentUser($bIsRackReconKey)
{
$this->deleteAllRacks();
$this->createRackObjects(
[
$this->getTestOrgId() => ['RackTest1', 'RackTest2', 'RackTest3', 'RackTest4']
$this->getTestOrgId() => ['RackTest1', 'RackTest2', 'RackTest3', 'RackTest4'],
]
);
@@ -165,11 +173,12 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
/**
* @dataProvider ReconciliationKeyProvider
*/
public function testExternalFieldIssueImportFail_AllObjectsVisibleByCurrentUser_AmbigousMatch($bIsRackReconKey){
public function testExternalFieldIssueImportFail_AllObjectsVisibleByCurrentUser_AmbigousMatch($bIsRackReconKey)
{
$this->deleteAllRacks();
$this->createRackObjects(
[
$this->getTestOrgId() => ['UnexistingRack', 'UnexistingRack']
$this->getTestOrgId() => ['UnexistingRack', 'UnexistingRack'],
]
);
@@ -189,11 +198,12 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
/**
* @dataProvider ReconciliationKeyProvider
*/
public function testExternalFieldIssueImportFail_AllObjectsVisibleByCurrentUser_FurtherExtKeyForRack($bIsRackReconKey){
public function testExternalFieldIssueImportFail_AllObjectsVisibleByCurrentUser_FurtherExtKeyForRack($bIsRackReconKey)
{
$this->deleteAllRacks();
$this->createRackObjects(
[
$this->getTestOrgId() => ['RackTest1', 'RackTest2', 'RackTest3', 'RackTest4']
$this->getTestOrgId() => ['RackTest1', 'RackTest2', 'RackTest3', 'RackTest4'],
]
);
@@ -213,24 +223,33 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
);
}
private function GetUid(){
if (is_null($this->sUid)){
private function GetUid()
{
if (is_null($this->sUid)) {
$this->sUid = uniqid('test');
}
return $this->sUid;
}
public function performBulkChangeTest($sExpectedDisplayableValue, $sExpectedDescription, $oOrg, $bIsRackReconKey,
$aAdditionalCsvData=null, $aAdditionalAttributes=null, $aExtKeys=null, $sSearchLinkUrl=null, $sError="Object not found") {
if ($sSearchLinkUrl===null){
public function performBulkChangeTest(
$sExpectedDisplayableValue,
$sExpectedDescription,
$oOrg,
$bIsRackReconKey,
$aAdditionalCsvData = null,
$aAdditionalAttributes = null,
$aExtKeys = null,
$sSearchLinkUrl = null,
$sError = "Object not found"
) {
if ($sSearchLinkUrl === null) {
$sSearchLinkUrl = 'UI.php?operation=search&filter='.rawurlencode('%5B%22SELECT+%60Rack%60+FROM+Rack+AS+%60Rack%60+WHERE+%28%60Rack%60.%60name%60+%3D+%3Aname%29%22%2C%7B%22name%22%3A%22UnexistingRack%22%7D%2C%5B%5D%5D');
}
if (is_null($oOrg)){
if (is_null($oOrg)) {
$iOrgId = $this->getTestOrgId();
$sOrgName = "UnitTestOrganization";
}else{
} else {
$iOrgId = $oOrg->GetKey();
$sOrgName = $oOrg->Get('name');
}
@@ -238,18 +257,18 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
$sUid = $this->GetUid();
$aCsvData = [[$sOrgName, "UnexistingRack", "$sUid"]];
if ($aAdditionalCsvData !== null){
foreach ($aAdditionalCsvData as $i => $aData){
foreach ($aData as $sData){
if ($aAdditionalCsvData !== null) {
foreach ($aAdditionalCsvData as $i => $aData) {
foreach ($aData as $sData) {
$aCsvData[$i][] = $sData;
}
}
}
$aAttributes = ["name" => 2];
if ($aAdditionalAttributes !== null){
if ($aAdditionalAttributes !== null) {
$aAttributes = array_merge($aAttributes, $aAdditionalAttributes);
}
if ($aExtKeys == null){
if ($aExtKeys == null) {
$aExtKeys = ["org_id" => ["name" => 0], "rack_id" => ["name" => 1]];
}
$aReconcilKeys = [ "name" ];
@@ -261,19 +280,18 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
2 => "\"$sUid\"",
"rack_id" => [
$sExpectedDisplayableValue,
$sExpectedDescription
$sExpectedDescription,
],
"__STATUS__" => "Issue: Unexpected attribute value(s)",
"__ERRORS__" => $sError,
];
if ($bIsRackReconKey){
if ($bIsRackReconKey) {
$aReconcilKeys[] = "rack_id";
$aResult[2] = $sUid;
$aResult["__STATUS__"] = "Issue: failed to reconcile";
}
CMDBSource::Query('START TRANSACTION');
try {
@@ -281,8 +299,8 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
$db_core_transactions_enabled = MetaModel::GetConfig()->Get('db_core_transactions_enabled');
MetaModel::GetConfig()->Set('db_core_transactions_enabled', false);
$this->debug("aCsvData:" . json_encode($aCsvData[0]));
$this->debug("aReconcilKeys:" . var_export($aReconcilKeys));
$this->debug("aCsvData:".json_encode($aCsvData[0]));
$this->debug("aReconcilKeys:".var_export($aReconcilKeys));
$oBulk = new \BulkChange(
"Server",
$aCsvData,
@@ -304,24 +322,33 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
foreach ($aRes as $aRow) {
if (array_key_exists('__STATUS__', $aRow)) {
$sStatus = $aRow['__STATUS__'];
$this->debug("sStatus:" . $sStatus->GetDescription());
$this->debug("sStatus:".$sStatus->GetDescription());
$this->assertEquals($aResult["__STATUS__"], $sStatus->GetDescription());
foreach ($aRow as $i => $oCell) {
if ($i != "finalclass" && $i != "__STATUS__" && $i != "__ERRORS__") {
$this->debug("i:" . $i);
$this->debug("i:".$i);
if (array_key_exists($i, $aResult)) {
$this->debug("aResult:" . var_export($aResult[$i]));
$this->debug("aResult:".var_export($aResult[$i]));
if ($oCell instanceof \CellStatus_SearchIssue ||
$oCell instanceof \CellStatus_Ambiguous) {
$this->assertEquals($aResult[$i][0], $oCell->GetCLIValue(),
"failure on " . get_class($oCell) . ' cell type');
$this->assertEquals($sSearchLinkUrl, $oCell->GetSearchLinkUrl(),
"failure on " . get_class($oCell) . ' cell type');
$this->assertEquals($aResult[$i][1], $oCell->GetDescription(),
"failure on " . get_class($oCell) . ' cell type');
$this->assertEquals(
$aResult[$i][0],
$oCell->GetCLIValue(),
"failure on ".get_class($oCell).' cell type'
);
$this->assertEquals(
$sSearchLinkUrl,
$oCell->GetSearchLinkUrl(),
"failure on ".get_class($oCell).' cell type'
);
$this->assertEquals(
$aResult[$i][1],
$oCell->GetDescription(),
"failure on ".get_class($oCell).' cell type'
);
}
}
} else if ($i === "__ERRORS__") {
} elseif ($i === "__ERRORS__") {
$sErrors = array_key_exists("__ERRORS__", $aResult) ? $aResult["__ERRORS__"] : "";
$this->assertEquals($sErrors, $oCell->GetDescription());
}

View File

@@ -75,8 +75,6 @@ class UpdateImpactedItemsTest extends ItopDataTestCase
]);
}
public function testImpactShouldBePropagatedInOneWayOnly()
{
/**
@@ -140,7 +138,7 @@ class UpdateImpactedItemsTest extends ItopDataTestCase
ApplicationSolution_12 <-> ApplicationSolution_13
EOF);
$oTicket = $this->GivenTicketWithCIsOrPersons([
'ApplicationSolution_0' => 'manual'
'ApplicationSolution_0' => 'manual',
]);
$oTicket->UpdateImpactedItems(); // impact analysis
@@ -487,8 +485,7 @@ class UpdateImpactedItemsTest extends ItopDataTestCase
list($sCI, $sPerson) = explode('<->', $sLine);
$sPersonId = $this->GivenCIOrPersonInDB(trim($sPerson));
$sCIId = $this->GivenCIOrPersonInDB(trim($sCI));
if (str_starts_with(trim($sPerson),'ApplicationSolution'))
{
if (str_starts_with(trim($sPerson), 'ApplicationSolution')) {
$this->GivenLnkApplicationSolutionToFunctionalCIInDB($sPersonId, $sCIId);
} else {
$this->GivenLnkContactToFunctionalCIInDB($sPersonId, $sCIId);
@@ -575,4 +572,3 @@ class UpdateImpactedItemsTest extends ItopDataTestCase
$this->ResetMetaModelQueyCacheGetObject();
}
}

View File

@@ -30,12 +30,12 @@ class ModuleFileReaderTest extends ItopDataTestCase
public static function ReadModuleFileConfigurationFileNameProvider()
{
$aUsecases=[];
foreach (glob(__DIR__.'/resources/*.php') as $sModuleFilePath){
if (false !== strpos($sModuleFilePath, "module.__MODULE__.php")){
$aUsecases = [];
foreach (glob(__DIR__.'/resources/*.php') as $sModuleFilePath) {
if (false !== strpos($sModuleFilePath, "module.__MODULE__.php")) {
continue;
}
$aUsecases[basename($sModuleFilePath)]=[$sModuleFilePath];
$aUsecases[basename($sModuleFilePath)] = [$sModuleFilePath];
}
return $aUsecases;
@@ -46,8 +46,8 @@ class ModuleFileReaderTest extends ItopDataTestCase
*/
public function testReadModuleFileConfigurationVsLegacyMethod(string $sModuleFilePath)
{
$_SERVER=[
'SERVER_NAME' => 'titi'
$_SERVER = [
'SERVER_NAME' => 'titi',
];
$aRes = ModuleFileReader::GetInstance()->ReadModuleFileInformation($sModuleFilePath);
@@ -75,8 +75,7 @@ class ModuleFileReaderTest extends ItopDataTestCase
file_put_contents($this->sTempModuleFilePath, $sPHpCode);
try {
return ModuleFileReader::GetInstance()->ReadModuleFileInformation($this->sTempModuleFilePath);
}
finally {
} finally {
@unlink($this->sTempModuleFilePath);
}
}
@@ -198,7 +197,7 @@ PHP;
public function testGetAndCheckModuleInstallerClass()
{
$sModuleInstallerClass = "TicketsInstaller" . uniqid();
$sModuleInstallerClass = "TicketsInstaller".uniqid();
$sPHpCode = file_get_contents(__DIR__.'/resources/module.itop-tickets.php');
$sPHpCode = str_replace("TicketsInstaller", $sModuleInstallerClass, $sPHpCode);
$this->sTempModuleFilePath = tempnam(__DIR__, "test");
@@ -211,11 +210,10 @@ PHP;
$this->assertFalse(class_exists($sModuleInstallerClass));
$this->assertEquals($sModuleInstallerClass, ModuleFileReader::GetInstance()->GetAndCheckModuleInstallerClass($aModuleInfo[2]));
}
finally {
} finally {
@unlink($this->sTempModuleFilePath);
}
$this->assertTrue(class_exists($sModuleInstallerClass));
}
}
}

View File

@@ -1,80 +1,78 @@
<?php
// Until we develop a mean to adress this within the setup, let's check that this instance
// of PHP has the php_ldap extension
//
if (function_exists('ldap_connect'))
{
if (function_exists('ldap_connect')) {
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'authent-ldap/3.3.0',
array(
// Identification
//
'label' => 'User authentication based on LDAP',
'category' => 'authentication',
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'authent-ldap/3.3.0',
[
// Identification
//
'label' => 'User authentication based on LDAP',
'category' => 'authentication',
// Setup
//
'dependencies' => array(
),
'mandatory' => false,
'visible' => true,
'installer' => 'AuthentLDAPInstaller',
// Setup
//
'dependencies' => [
],
'mandatory' => false,
'visible' => true,
'installer' => 'AuthentLDAPInstaller',
// Components
//
'datamodel' => array(
),
'data.struct' => array(
//'data.struct.authent-ldap.xml',
),
'data.sample' => array(
//'data.sample.authent-ldap.xml',
),
// Components
//
'datamodel' => [
],
'data.struct' => [
//'data.struct.authent-ldap.xml',
],
'data.sample' => [
//'data.sample.authent-ldap.xml',
],
// Documentation
//
'doc.manual_setup' => '',
'doc.more_information' => '',
// Documentation
//
'doc.manual_setup' => '',
'doc.more_information' => '',
// Default settings
//
'settings' => array(
'uri' => 'ldap://localhost', // URI with host or IP address of your LDAP server
'default_user' => '', // User and password used for initial "Anonymous" bind to LDAP
'default_pwd' => '', // Leave both blank, if anonymous (read-only) bind is allowed
'base_dn' => 'dc=yourcompany,dc=com', // Base DN for User queries, adjust it to your LDAP schema
'user_query' => '(&(uid=%1$s)(inetuserstatus=ACTIVE))', // Query used to retrieve each user %1$s => iTop login
// For Windows AD use (samaccountname=%1$s) or (userprincipalname=%1$s)
// Default settings
//
'settings' => [
'uri' => 'ldap://localhost', // URI with host or IP address of your LDAP server
'default_user' => '', // User and password used for initial "Anonymous" bind to LDAP
'default_pwd' => '', // Leave both blank, if anonymous (read-only) bind is allowed
'base_dn' => 'dc=yourcompany,dc=com', // Base DN for User queries, adjust it to your LDAP schema
'user_query' => '(&(uid=%1$s)(inetuserstatus=ACTIVE))', // Query used to retrieve each user %1$s => iTop login
// For Windows AD use (samaccountname=%1$s) or (userprincipalname=%1$s)
// Some extra LDAP options, refer to: http://www.php.net/manual/en/function.ldap-set-option.php for more info
'options' => array(
LDAP_OPT_PROTOCOL_VERSION => 3,
LDAP_OPT_REFERRALS => 0,
),
'start_tls' => false,
'debug' => false,
'servers' => array(),
),
)
);
// Some extra LDAP options, refer to: http://www.php.net/manual/en/function.ldap-set-option.php for more info
'options' => [
LDAP_OPT_PROTOCOL_VERSION => 3,
LDAP_OPT_REFERRALS => 0,
],
'start_tls' => false,
'debug' => false,
'servers' => [],
],
]
);
// Module installation handler
//
class AuthentLDAPInstaller extends ModuleInstallerAPI
{
public static function AfterDataLoad(Config $oConfiguration, $sPreviousVersion, $sCurrentVersion)
// Module installation handler
//
class AuthentLDAPInstaller extends ModuleInstallerAPI
{
public static function AfterDataLoad(Config $oConfiguration, $sPreviousVersion, $sCurrentVersion)
{
}
public static function BeforeWritingConfig(Config $oConfiguration)
{
}
}
public static function BeforeWritingConfig(Config $oConfiguration)
{
}
}
} // if (function_exists('ldap_connect'))

View File

@@ -3,32 +3,32 @@
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'combodo-email-synchro/3.8.2',
array(
[
// Identification
'label' => 'Tickets synchronization via e-mail',
'category' => 'business',
// Setup
'dependencies' => array(
'itop-profiles-itil/3.0.0',
),
'dependencies' => [
'itop-profiles-itil/3.0.0',
],
'mandatory' => false,
'visible' => true,
'installer' => 'EmailSynchroInstaller',
// Components
'datamodel' => array(
'datamodel' => [
'classes/autoload.php',
'model.combodo-email-synchro.php',
),
'dictionary' => array(),
'data.struct' => array(
),
'data.sample' => array(
),
],
'dictionary' => [],
'data.struct' => [
],
'data.sample' => [
],
// Documentation
'doc.manual_setup' => '', // No manual installation required
'doc.more_information' => '', // None
// Default settings
'settings' => array(
'settings' => [
'notify_errors_to' => '', // mandatory to track errors not handled by the email processing module
'notify_errors_from' => '', // mandatory as well (can be set at the same value as notify_errors_to)
'debug' => false, // Set to true to turn on debugging
@@ -36,44 +36,42 @@ SetupWebPage::AddModule(
'retention_period' => 1, // number of hour we keep the replica
'body_parts_order' => 'text/html,text/plain', // Order in which to read the parts of the incoming emails
'pop3_auth_option' => 'USER',
'imap_options' => array('imap'),
'imap_open_options' => array(),
'imap_options' => ['imap'],
'imap_open_options' => [],
'maximum_email_size' => '10M', // Maximum allowed size for incoming emails
'big_files_dir' => '',
'exclude_attachment_types' => array('application/exe'), // Example: 'application/exe', 'application/x-winexe', 'application/msdos-windows'
'exclude_attachment_types' => ['application/exe'], // Example: 'application/exe', 'application/x-winexe', 'application/msdos-windows'
// Lines to be removed just above the 'new part' in a reply-to message... add your own patterns below
'introductory-patterns' => array(
'introductory-patterns' => [
'/^le .+ a écrit :$/i', // Thunderbird French
'/^on .+ wrote:$/i', // Thunderbird English
'|^[0-9]{4}/[0-9]{1,2}/[0-9]{1,2} .+:$|', // Gmail style
),
],
// Some patterns which delimit the previous message in case of a Reply
// The "new" part of the message is the text before the pattern
// Add your own multi-line patterns (use \\R for a line break)
// These patterns depend on the mail client/server used... feel free to add your own discoveries to the list
'multiline-delimiter-patterns' => array(
'multiline-delimiter-patterns' => [
'/\\RFrom: .+\\RSent: .+\\R/m', // Outlook English
'/\\R_+\\R/m', // A whole line made only of underscore characters
'/\\RDe : .+\\R\\R?Envoyé : /m', // Outlook French, HTML and rich text
'/\\RDe : .+\\RDate d\'envoi : .+\\R/m', // Outlook French, plain text
'/\\R-----Message d\'origine-----\\R/m',
),
],
'use_message_id_as_uid' => false, // Do NOT change this unless you known what you are doing!!
'images_minimum_size' => '100x20', // Images smaller that these dimensions will be ignored (signatures...)
'images_maximum_size' => '', // Images bigger that these dimensions will be resized before uploading into iTop
'recommended_max_allowed_packet' => 10*1024*1024, // MySQL parameter for attachments
),
)
'recommended_max_allowed_packet' => 10 * 1024 * 1024, // MySQL parameter for attachments
],
]
);
if (!class_exists('EmailSynchroInstaller'))
{
if (!class_exists('EmailSynchroInstaller')) {
// Module installation handler
//
class EmailSynchroInstaller extends ModuleInstallerAPI
{
/**
* Handler called after the creation/update of the database schema
*
@@ -109,10 +107,9 @@ if (!class_exists('EmailSynchroInstaller'))
// Looping on inboxes to update
$oSet = new DBObjectSet($oSearch);
while ($oInbox = $oSet->Fetch())
{
$sUpdateQuery = "UPDATE $sTableName SET $sMailboxColName = " . CMDBSource::Quote($oInbox->Get('mailbox')) . " WHERE $sUidlColName LIKE " . CMDBSource::Quote($oInbox->Get('login') . '_%') . " AND $sMailboxColName IS NULL";
SetupLog::Info("Executing query: " . $sUpdateQuery);
while ($oInbox = $oSet->Fetch()) {
$sUpdateQuery = "UPDATE $sTableName SET $sMailboxColName = ".CMDBSource::Quote($oInbox->Get('mailbox'))." WHERE $sUidlColName LIKE ".CMDBSource::Quote($oInbox->Get('login').'_%')." AND $sMailboxColName IS NULL";
SetupLog::Info("Executing query: ".$sUpdateQuery);
$iRet = CMDBSource::Query($sUpdateQuery); // Throws an exception in case of error
SetupLog::Info("Updated $iRet rows.");
}

View File

@@ -1,51 +1,52 @@
<?php
//
// iTop module definition file
//
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'itop-admin-delegation-profiles-bridge-for-combodo-email-synchro/1.0.0',
array(
// Identification
//
'label' => 'Profiles per admin fonction: Mail inboxes and messages',
'category' => 'Datamodel',
'itop-admin-delegation-profiles-bridge-for-combodo-email-synchro/1.0.0',
[
// Identification
//
'label' => 'Profiles per admin fonction: Mail inboxes and messages',
'category' => 'Datamodel',
// Setup
//
'dependencies' => array(
'itop-admin-delegation-profiles/1.0.0',
'itop-admin-delegation-profiles/1.0.0 || combodo-email-synchro/3.7.2 || itop-oauth-client/2.7.7', // Optional dependency to silence the setup to not display a warning if the other module is not present
),
// Setup
//
'dependencies' => [
'itop-admin-delegation-profiles/1.0.0',
'itop-admin-delegation-profiles/1.0.0 || combodo-email-synchro/3.7.2 || itop-oauth-client/2.7.7', // Optional dependency to silence the setup to not display a warning if the other module is not present
],
'mandatory' => false,
'visible' => false,
'auto_select' => 'SetupInfo::ModuleIsSelected("itop-admin-delegation-profiles") && SetupInfo::ModuleIsSelected("combodo-email-synchro") && SetupInfo::ModuleIsSelected("itop-oauth-client")',
// Components
//
'datamodel' => array(
'model.itop-admin-delegation-profiles-bridge-for-combodo-email-synchro.php'
),
'webservice' => array(
),
'data.struct' => array(
'datamodel' => [
'model.itop-admin-delegation-profiles-bridge-for-combodo-email-synchro.php',
],
'webservice' => [
],
'data.struct' => [
// add your 'structure' definition XML files here,
),
'data.sample' => array(
],
'data.sample' => [
// add your sample data XML files here,
),
],
// Documentation
//
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
'doc.more_information' => '', // hyperlink to more information, if any
'doc.more_information' => '', // hyperlink to more information, if any
// Default settings
//
'settings' => array(
'settings' => [
// Module specific settings go here, if any
),
)
],
]
);

View File

@@ -1,52 +1,53 @@
<?php
//
// iTop module definition file
//
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'itop-admin-delegation-profiles/1.2.1',
array(
// Identification
//
'label' => 'Profiles per admin fonction',
'category' => 'Datamodel',
'itop-admin-delegation-profiles/1.2.1',
[
// Identification
//
'label' => 'Profiles per admin fonction',
'category' => 'Datamodel',
// Setup
//
'dependencies' => array(
'itop-config-mgmt/2.7.0' || 'itop-structure/3.0.0',
// itop-profiles-itil is here to ensure that the /itop_design/groups/group[@id="History"] alteration comes after those from that module.
// This allows to define the missing "History" group in iTop 2.7 / 3.0, while merging smoothly with iTop 3.1+
'itop-profiles-itil/2.7.0',
),
// Setup
//
'dependencies' => [
'itop-config-mgmt/2.7.0' || 'itop-structure/3.0.0',
// itop-profiles-itil is here to ensure that the /itop_design/groups/group[@id="History"] alteration comes after those from that module.
// This allows to define the missing "History" group in iTop 2.7 / 3.0, while merging smoothly with iTop 3.1+
'itop-profiles-itil/2.7.0',
],
'mandatory' => false,
'visible' => true,
// Components
//
'datamodel' => array(
'model.itop-admin-delegation-profiles.php'
),
'webservice' => array(
),
'data.struct' => array(
'datamodel' => [
'model.itop-admin-delegation-profiles.php',
],
'webservice' => [
],
'data.struct' => [
// add your 'structure' definition XML files here,
),
'data.sample' => array(
],
'data.sample' => [
// add your sample data XML files here,
),
],
// Documentation
//
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
'doc.more_information' => '', // hyperlink to more information, if any
'doc.more_information' => '', // hyperlink to more information, if any
// Default settings
//
'settings' => array(
'settings' => [
// Module specific settings go here, if any
),
)
],
]
);

View File

@@ -7,35 +7,35 @@
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'itop-full-itil/3.3.0',
array(
[
// Identification
//
'label' => 'Bridge - Request management ITIL + Incident management ITIL',
'category' => 'business',
// Setup
//
'dependencies' => array(
'dependencies' => [
'itop-request-mgmt-itil/2.3.0',
'itop-incident-mgmt-itil/2.3.0',
),
],
'mandatory' => false,
'visible' => false,
'auto_select' => 'SetupInfo::ModuleIsSelected("itop-request-mgmt-itil") && SetupInfo::ModuleIsSelected("itop-incident-mgmt-itil")',
// Components
//
'datamodel' => array(),
'webservice' => array(),
'data.struct' => array(// add your 'structure' definition XML files here,
),
'data.sample' => array(// add your sample data XML files here,
),
'datamodel' => [],
'webservice' => [],
'data.struct' => [// add your 'structure' definition XML files here,
],
'data.sample' => [// add your sample data XML files here,
],
// Documentation
//
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
'doc.more_information' => '', // hyperlink to more information, if any
// Default settings
//
'settings' => array(// Module specific settings go here, if any
),
)
'settings' => [// Module specific settings go here, if any
],
]
);

View File

@@ -11,7 +11,7 @@
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'itop-global-requests-mgmt/1.6.3',
array(
[
// Identification
//
'label' => 'iTop Global Requests Management',
@@ -19,23 +19,23 @@ SetupWebPage::AddModule(
// Setup
//
'dependencies' => array(
'dependencies' => [
'itop-portal-base/3.2.0',
),
],
'mandatory' => false,
'visible' => true,
'installer' => GlobalRequestInstaller::class,
// Components
//
'datamodel' => array(
'datamodel' => [
'vendor/autoload.php',
),
'webservice' => array(),
'data.struct' => array(// add your 'structure' definition XML files here,
),
'data.sample' => array(// add your sample data XML files here,
),
],
'webservice' => [],
'data.struct' => [// add your 'structure' definition XML files here,
],
'data.sample' => [// add your sample data XML files here,
],
// Documentation
//
@@ -44,15 +44,14 @@ SetupWebPage::AddModule(
// Default settings
//
'settings' => array(
'settings' => [
'target_state' => 'new',
'bypass_profiles' => 'Administrator, Service Manager',
'reuse_previous_answers' => true,
),
)
],
]
);
class GlobalRequestInstaller extends ModuleInstallerAPI
{
/**
@@ -71,5 +70,3 @@ class GlobalRequestInstaller extends ModuleInstallerAPI
//code
}
}

View File

@@ -1,10 +1,9 @@
<?php
SetupWebPage::AddModule(
__FILE__,
'itop-tickets/3.3.0',
array(
[
// Identification
//
'label' => 'Tickets Management',
@@ -12,24 +11,24 @@ SetupWebPage::AddModule(
// Setup
//
'dependencies' => array(
'dependencies' => [
'itop-structure/2.7.1',
),
],
'mandatory' => false,
'visible' => true,
'installer' => 'TicketsInstaller',
// Components
//
'datamodel' => array(
'datamodel' => [
'main.itop-tickets.php',
),
'data.struct' => array(
],
'data.struct' => [
// 'data.struct.ta-actions.xml',
),
'data.sample' => array(
),
],
'data.sample' => [
],
// Documentation
//
'doc.manual_setup' => '',
@@ -37,9 +36,9 @@ SetupWebPage::AddModule(
// Default settings
//
'settings' => array(
),
)
'settings' => [
],
]
);
// Module installation handler
@@ -52,17 +51,12 @@ class TicketsInstaller extends ModuleInstallerAPI
CMDBObject::SetTrackInfo('Uninstallation');
$oSearch = new DBObjectSearch('TriggerOnObject');
$oSet = new DBObjectSet($oSearch);
while($oTrigger = $oSet->Fetch())
{
try
{
if (!MetaModel::IsValidClass($oTrigger->Get('target_class')))
{
while ($oTrigger = $oSet->Fetch()) {
try {
if (!MetaModel::IsValidClass($oTrigger->Get('target_class'))) {
$oTrigger->DBDelete();
}
}
catch(Exception $e)
{
} catch (Exception $e) {
utils::EnrichRaisedException($oTrigger, $e);
}
}

View File

@@ -1,79 +1,80 @@
<?php
//
// iTop module definition file
//
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'servername-ticket/2.6.2',
array(
// Identification
//
'label' => 'I3S Datamodel tickets',
'category' => 'business',
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'servername-ticket/2.6.2',
[
// Identification
//
'label' => 'I3S Datamodel tickets',
'category' => 'business',
// Setup
//
'dependencies' => array(
'itop-attachments/2.5.0',
),
'mandatory' => false,
'visible' => true,
// Setup
//
'dependencies' => [
'itop-attachments/2.5.0',
],
'mandatory' => false,
'visible' => true,
// Components
//
'datamodel' => array(
'model.servername-datamodel-ticket.php',
'main.servername-datamodel-ticket.php'
),
'webservice' => array(
// Components
//
'datamodel' => [
'model.servername-datamodel-ticket.php',
'main.servername-datamodel-ticket.php',
],
'webservice' => [
),
'data.struct' => array(
// add your 'structure' definition XML files here,
),
'data.sample' => array(
// add your sample data XML files here,
),
],
'data.struct' => [
// add your 'structure' definition XML files here,
],
'data.sample' => [
// add your sample data XML files here,
],
// Documentation
//
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
'doc.more_information' => '', // hyperlink to more information, if any
// Documentation
//
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
'doc.more_information' => '', // hyperlink to more information, if any
// Default settings
//
'settings' => array(
// url d'accès au répertoire des traces applicatives liées aux tickets
'traces_base_url' => 'file://'.$_SERVER['SERVER_NAME'].'/traces',
// répertoire des faqi liées aux tickets
'traces_base_dir_faqi' => '/data/i3s-gsit-tt/faqi',
// url d'accès au répertoire des faqi liées aux tickets
// ce serveur est-il le serveur de consolidation ?
'consolidation_server' => false,
// restriction des franchissements
'max_allowed_transitions' => array(
// Les noms des transitions sont visibles dans Outils d'admin => Modèle de données => Incident => Cycle de vie
// Les transitions qui ne sont pas présentes dans ce tableau sont considérées comme étant à 0
/* 'nom technique de la transition' => nombre maximal autorisé */
'ev_askinfo' => 0, // Demander des informations (au demandeur)
'ev_assign' => 0, // Assigner
'ev_cancel_by_user' => 0, // Annuler (par le demandeur)
'ev_cancel' => 0, // Annuler
'ev_close' => 0, // Clore
'ev_escalate' => 0, // Escalader
'ev_giveinfo' => 0, // Envoyer les informations
'ev_monitor' => 0, // Surveiller
'ev_pending' => 0, // En attente
'ev_reassign' => 0, // Ré-assigner
'ev_refuse_reject' => 0, // Refuser le rejet
'ev_refuse_solution' => 0, // Refuser la solution
'ev_reject' => 0, // Rejeter
'ev_resolve' => 0, // Marquer comme résolu
'ev_suspend' => 0, // Suspendre
'ev_terminate' => 0, // Solder
'ev_verify' => 0, // Accepter la solution / Confirmer la résolution
),
),
)
// Default settings
//
'settings' => [
// url d'accès au répertoire des traces applicatives liées aux tickets
'traces_base_url' => 'file://'.$_SERVER['SERVER_NAME'].'/traces',
// répertoire des faqi liées aux tickets
'traces_base_dir_faqi' => '/data/i3s-gsit-tt/faqi',
// url d'accès au répertoire des faqi liées aux tickets
// ce serveur est-il le serveur de consolidation ?
'consolidation_server' => false,
// restriction des franchissements
'max_allowed_transitions' => [
// Les noms des transitions sont visibles dans Outils d'admin => Modèle de données => Incident => Cycle de vie
// Les transitions qui ne sont pas présentes dans ce tableau sont considérées comme étant à 0
/* 'nom technique de la transition' => nombre maximal autorisé */
'ev_askinfo' => 0, // Demander des informations (au demandeur)
'ev_assign' => 0, // Assigner
'ev_cancel_by_user' => 0, // Annuler (par le demandeur)
'ev_cancel' => 0, // Annuler
'ev_close' => 0, // Clore
'ev_escalate' => 0, // Escalader
'ev_giveinfo' => 0, // Envoyer les informations
'ev_monitor' => 0, // Surveiller
'ev_pending' => 0, // En attente
'ev_reassign' => 0, // Ré-assigner
'ev_refuse_reject' => 0, // Refuser le rejet
'ev_refuse_solution' => 0, // Refuser la solution
'ev_reject' => 0, // Rejeter
'ev_resolve' => 0, // Marquer comme résolu
'ev_suspend' => 0, // Suspendre
'ev_terminate' => 0, // Solder
'ev_verify' => 0, // Accepter la solution / Confirmer la résolution
],
],
]
);

View File

@@ -38,10 +38,10 @@ class QuickCreateHelperTest extends ItopDataTestCase
{
$aRecentClasses = [];
// User preferences will be reset during the rollback
foreach($aGivenClasses as $sClass) {
$aRecentClasses[] = array(
foreach ($aGivenClasses as $sClass) {
$aRecentClasses[] = [
'class' => $sClass,
);
];
}
appUserPreferences::SetPref(QuickCreateHelper::USER_PREF_CODE, $aRecentClasses);
@@ -50,11 +50,11 @@ class QuickCreateHelperTest extends ItopDataTestCase
private function AssertPopularClassesMatches(array $aExpectedClasses, array $aPopularClasses, string $sMessage = '')
{
$aFoundClasses = [];
foreach($aPopularClasses as $aClassData) {
foreach ($aPopularClasses as $aClassData) {
$aFoundClasses[] = $aClassData['class'];
}
sort($aFoundClasses);
sort($aExpectedClasses);
$this->assertEquals($aExpectedClasses, $aFoundClasses, $sMessage);
}
}
}

View File

@@ -7,7 +7,8 @@ use Combodo\iTop\Setup\ModuleDiscovery\ModuleFileReader;
use Combodo\iTop\Setup\ModuleDiscovery\ModuleFileReaderException;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
class PhpExpressionEvaluatorTest extends ItopDataTestCase {
class PhpExpressionEvaluatorTest extends ItopDataTestCase
{
public static $STATIC_PROPERTY = 123;
private static $PRIVATE_STATIC_PROPERTY = 123;
private const PRIVATE_CONSTANT = 123;
@@ -17,7 +18,8 @@ class PhpExpressionEvaluatorTest extends ItopDataTestCase {
parent::tearDown();
}
public static function EvaluateExpressionProvider() {
public static function EvaluateExpressionProvider()
{
return [
'Array: [1000 => "a"]' => ['sExpression' => '[1000 => "a"]'],
'Array: ["a"]' => ['sExpression' => '["a"]'],
@@ -97,18 +99,18 @@ class PhpExpressionEvaluatorTest extends ItopDataTestCase {
/**
* @dataProvider EvaluateExpressionProvider
*/
public function testEvaluateExpression($sExpression, $forced_expected="NOTPROVIDED")
public function testEvaluateExpression($sExpression, $forced_expected = "NOTPROVIDED")
{
global $oGlobalNonNullVar;
$oGlobalNonNullVar="a";
$oGlobalNonNullVar = "a";
global $oGlobalNullVar;
$oGlobalNullVar=null;
$oGlobalNullVar = null;
$oNonNullVar="a";
$oNonNullVar = "a";
$oNullVar=null;
$_SERVER=[
$oNullVar = null;
$_SERVER = [
'toto' => 'titi',
];
@@ -117,7 +119,7 @@ class PhpExpressionEvaluatorTest extends ItopDataTestCase {
$oPhpExpressionEvaluator = new PhpExpressionEvaluator(ModuleFileReader::FUNC_CALL_WHITELIST, ModuleFileReader::STATIC_CALLWHITELIST);
$res = $oPhpExpressionEvaluator->ParseAndEvaluateExpression($sExpression);
if ($forced_expected === "NOTPROVIDED"){
if ($forced_expected === "NOTPROVIDED") {
$this->assertEquals($this->UnprotectedComputeExpression($sExpression), $res, $sExpression);
} else {
$this->assertEquals($forced_expected, $res, $sExpression);
@@ -148,15 +150,15 @@ class PhpExpressionEvaluatorTest extends ItopDataTestCase {
public function testEvaluateExpressionThrowsException($sExpression)
{
global $oGlobalNonNullVar;
$oGlobalNonNullVar="a";
$oGlobalNonNullVar = "a";
global $oGlobalNullVar;
$oGlobalNullVar=null;
$oGlobalNullVar = null;
$oNonNullVar="a";
$oNonNullVar = "a";
$oNullVar=null;
$_SERVER=[
$oNullVar = null;
$_SERVER = [
'toto' => 'titi',
];
@@ -168,21 +170,20 @@ class PhpExpressionEvaluatorTest extends ItopDataTestCase {
$oPhpExpressionEvaluator->ParseAndEvaluateExpression($sExpression);
}
/**
* @param string $sBooleanExpr
*
* @return mixed
* @throws ModuleFileReaderException
*/
private function UnprotectedComputeExpression(string $sExpr) : mixed
private function UnprotectedComputeExpression(string $sExpr): mixed
{
try {
$bResult = null;
@eval('$bResult = '.$sExpr.';');
return $bResult;
} catch (\Throwable $t){
} catch (\Throwable $t) {
return null;
}
}
@@ -217,15 +218,17 @@ class PhpExpressionEvaluatorTest extends ItopDataTestCase {
/**
* @dataProvider ParseAndEvaluateBooleanExpression_AutoselectProvider
*/
public function testEvaluateBooleanExpression_Autoselect(string $sBooleanExpression, bool $expected){
public function testEvaluateBooleanExpression_Autoselect(string $sBooleanExpression, bool $expected)
{
\SetupInfo::SetSelectedModules(["itop-storage-mgmt" => "123"]);
$oPhpExpressionEvaluator = new PhpExpressionEvaluator([], ["SetupInfo::ModuleIsSelected"]);
$this->assertEquals($expected, $oPhpExpressionEvaluator->ParseAndEvaluateBooleanExpression($sBooleanExpression), $sBooleanExpression);
}
}
class EvaluationFakeClass {
public string $iIsOk="IsOkValue";
class EvaluationFakeClass
{
public string $iIsOk = "IsOkValue";
public function GetName()
{
@@ -234,11 +237,11 @@ class EvaluationFakeClass {
public function GetLongName($suffix)
{
return "gabuzomeu_" . $suffix;
return "gabuzomeu_".$suffix;
}
public function __toString(): string
{
return "toString";
}
}
}