mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
N°8796 - Add PHP code style validation in iTop and extensions - format whole code base
This commit is contained in:
@@ -56,7 +56,8 @@ $oPage = new iTopWebPage('Render all UI blocks');
|
||||
$oPageContentLayout = PageContentFactory::MakeStandardEmpty();
|
||||
$oPage->SetContentLayout($oPageContentLayout);
|
||||
|
||||
$oPage->add_style(<<<CSS
|
||||
$oPage->add_style(
|
||||
<<<CSS
|
||||
hr {
|
||||
background-color: var(--ibo-color-grey-950);
|
||||
}
|
||||
@@ -331,7 +332,6 @@ $oPage->AddUiBlock($oCollapsibleSectionSaveState);
|
||||
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Fieldset/field examples', 2));
|
||||
|
||||
|
||||
$oDashletFieldset1 = new FieldSet('Fieldset 1');
|
||||
$oDashletField1 = FieldUIBlockFactory::MakeStandard('Field A');
|
||||
$oDashletInput1 = InputUIBlockFactory::MakeStandard('text', 'input1', 'Input 1');
|
||||
@@ -360,13 +360,13 @@ $oDashletFieldset2->AddSubBlock($oDashletField6);
|
||||
// Code
|
||||
/////////
|
||||
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Code examples (MakeForCode)', 2 ));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Code examples (MakeForCode)', 2));
|
||||
$oCode1 = UIContentBlockUIBlockFactory::MakeForCode('function mean(int $a, int $b) {
|
||||
return ($a + $b)/2
|
||||
}');
|
||||
$oPage->AddUiBlock($oCode1);
|
||||
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Code examples (MakeForPreformatted)', 2 ));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Code examples (MakeForPreformatted)', 2));
|
||||
$oCode2 = UIContentBlockUIBlockFactory::MakeForPreformatted('function mean(int $a, int $b) {
|
||||
return ($a + $b)/2
|
||||
}');
|
||||
@@ -376,7 +376,7 @@ $oPage->AddUiBlock($oCode2);
|
||||
// Pill
|
||||
/////////
|
||||
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Pill examples', 2 ));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Pill examples', 2));
|
||||
|
||||
$oBlock = new UIContentBlockWithJSRefreshCallback(null, ["ibo-dashlet-header-dynamic--container"]);
|
||||
$oPage->AddUiBlock($oBlock);
|
||||
@@ -397,95 +397,97 @@ $oBlock->AddSubBlock($oPill6);
|
||||
// Title
|
||||
/////////
|
||||
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Title examples', 2 ));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Title example 1', 1 ));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Title example 2', 2 ));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Title example 3', 3 ));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Title example 4', 4 ));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Title example 5', 5 ));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Title examples', 2));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Title example 1', 1));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Title example 2', 2));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Title example 3', 3));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Title example 4', 4));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Title example 5', 5));
|
||||
|
||||
/////////
|
||||
// DataTable
|
||||
/////////
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Datatable examples', 2 ));
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Datatable examples', 2));
|
||||
|
||||
$oPage->AddUiBlock(DataTableUIBlockFactory::MakeForStaticData('Static datatable',
|
||||
array(
|
||||
'a' => array('label' => 'a'),
|
||||
'b' => array('label' => 'b'),
|
||||
'c' => array('label' => 'c'),
|
||||
'd' => array('label' => 'd')
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'a' => 'A1', 'b' => 'B1', 'c' => 'C1', 'd' => 'D1'
|
||||
), array(
|
||||
'a' => 'A2', 'b' => 'B2', 'c' => 'C2', 'd' => 'D2'
|
||||
), array(
|
||||
'a' => 'A3', 'b' => 'B3', 'c' => 'C3', 'd' => 'D3'
|
||||
), array(
|
||||
$oPage->AddUiBlock(DataTableUIBlockFactory::MakeForStaticData(
|
||||
'Static datatable',
|
||||
[
|
||||
'a' => ['label' => 'a'],
|
||||
'b' => ['label' => 'b'],
|
||||
'c' => ['label' => 'c'],
|
||||
'd' => ['label' => 'd'],
|
||||
],
|
||||
[
|
||||
[
|
||||
'a' => 'A1', 'b' => 'B1', 'c' => 'C1', 'd' => 'D1',
|
||||
], [
|
||||
'a' => 'A2', 'b' => 'B2', 'c' => 'C2', 'd' => 'D2',
|
||||
], [
|
||||
'a' => 'A3', 'b' => 'B3', 'c' => 'C3', 'd' => 'D3',
|
||||
], [
|
||||
'a' => 'A4',
|
||||
'b' => 'B4',
|
||||
'c' => 'C4',
|
||||
'd' => 'D4',
|
||||
),
|
||||
array(
|
||||
],
|
||||
[
|
||||
'@class' => 'ibo-is-red',
|
||||
'a' => 'A5 (Red highlighting)',
|
||||
'b' => 'B5',
|
||||
'c' => 'C5',
|
||||
'd' => 'D5',
|
||||
),
|
||||
array(
|
||||
],
|
||||
[
|
||||
'@class' => 'ibo-is-danger',
|
||||
'a' => 'A6 (Danger highlighting)',
|
||||
'b' => 'B6',
|
||||
'c' => 'C6',
|
||||
'd' => 'D6',
|
||||
),
|
||||
array(
|
||||
],
|
||||
[
|
||||
'@class' => 'ibo-is-orange',
|
||||
'a' => 'A7 (Orange highlighting)',
|
||||
'b' => 'B7',
|
||||
'c' => 'C7',
|
||||
'd' => 'D7',
|
||||
),
|
||||
array(
|
||||
],
|
||||
[
|
||||
'@class' => 'ibo-is-warning',
|
||||
'a' => 'A8 (Warning highlighting)',
|
||||
'b' => 'B8',
|
||||
'c' => 'C8',
|
||||
'd' => 'D8',
|
||||
),
|
||||
array(
|
||||
],
|
||||
[
|
||||
'@class' => 'ibo-is-blue',
|
||||
'a' => 'A9 (Blue highlighting)',
|
||||
'b' => 'B9',
|
||||
'c' => 'C9',
|
||||
'd' => 'D9',
|
||||
),
|
||||
array(
|
||||
],
|
||||
[
|
||||
'@class' => 'ibo-is-info',
|
||||
'a' => 'A10 (Info highlighting)',
|
||||
'b' => 'B10',
|
||||
'c' => 'C10',
|
||||
'd' => 'D10',
|
||||
),
|
||||
array(
|
||||
],
|
||||
[
|
||||
'@class' => 'ibo-is-green',
|
||||
'a' => 'A11 (Green highlighting)',
|
||||
'b' => 'B11',
|
||||
'c' => 'C11',
|
||||
'd' => 'D11',
|
||||
),
|
||||
array(
|
||||
],
|
||||
[
|
||||
'@class' => 'ibo-is-success',
|
||||
'a' => 'A12 (Success highlighting)',
|
||||
'b' => 'B12',
|
||||
'c' => 'C12',
|
||||
'd' => 'D12',
|
||||
),
|
||||
)));
|
||||
],
|
||||
]
|
||||
));
|
||||
|
||||
/////////
|
||||
// Set
|
||||
|
||||
@@ -7,7 +7,8 @@ require_once '../../approot.inc.php';
|
||||
|
||||
require_once(APPROOT.'/application\utils.inc.php');
|
||||
$index = 0;
|
||||
function testSanitize ($sValue, $sType, &$index ){
|
||||
function testSanitize($sValue, $sType, &$index)
|
||||
{
|
||||
$sDefaultVal = '!defaultVal!';
|
||||
$sValueEscapedJs = str_replace('"', '\"', $sValue);
|
||||
$sSanitizedValue = utils::Sanitize($sValue, $sDefaultVal, $sType);
|
||||
@@ -43,7 +44,7 @@ HTML;
|
||||
$index++;
|
||||
}
|
||||
|
||||
$aValues = array(
|
||||
$aValues = [
|
||||
"test",
|
||||
"t;e-s_t$",
|
||||
"123test",
|
||||
@@ -55,9 +56,9 @@ $aValues = array(
|
||||
"éèç",
|
||||
"q<div>è</div>=hcb test",
|
||||
// "<script>console.debug('((\'èé&');</script>q<div>è</div>=hcb test",
|
||||
);
|
||||
];
|
||||
|
||||
$aTypes = array(
|
||||
$aTypes = [
|
||||
utils::ENUM_SANITIZATION_FILTER_CONTEXT_PARAM,
|
||||
utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER,
|
||||
utils::ENUM_SANITIZATION_FILTER_FIELD_NAME,
|
||||
@@ -66,7 +67,7 @@ $aTypes = array(
|
||||
utils::ENUM_SANITIZATION_FILTER_STRING,
|
||||
utils::ENUM_SANITIZATION_FILTER_TRANSACTION_ID,
|
||||
utils::ENUM_SANITIZATION_FILTER_VARIABLE_NAME,
|
||||
);
|
||||
];
|
||||
|
||||
?>
|
||||
<!DOCTYPE>
|
||||
|
||||
@@ -13,14 +13,15 @@ namespace Combodo\iTop\Test\UnitTest;
|
||||
*/
|
||||
class runClassInSeparateProcessTest extends ItopDataTestCase
|
||||
{
|
||||
static public function setUpBeforeClass(): void
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
parent::setUpBeforeClass(); // TODO: Change the autogenerated stub
|
||||
|
||||
file_put_contents(
|
||||
dirname(__FILE__).'/pid.txt',
|
||||
getmypid().';'.static::class.';'.__METHOD__."\n",
|
||||
FILE_APPEND);
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
protected function LogPid()
|
||||
@@ -28,16 +29,17 @@ class runClassInSeparateProcessTest extends ItopDataTestCase
|
||||
file_put_contents(
|
||||
dirname(__FILE__).'/pid.txt',
|
||||
getmypid().';'.static::class.';'.$this->getName()."\n",
|
||||
FILE_APPEND);
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
function testA()
|
||||
public function testA()
|
||||
{
|
||||
$this->LogPid();
|
||||
static::assertTrue(true);
|
||||
}
|
||||
|
||||
function testB()
|
||||
public function testB()
|
||||
{
|
||||
$this->LogPid();
|
||||
static::assertTrue(true);
|
||||
@@ -46,13 +48,13 @@ class runClassInSeparateProcessTest extends ItopDataTestCase
|
||||
/**
|
||||
* @dataProvider CProvider
|
||||
*/
|
||||
function testC($i)
|
||||
public function testC($i)
|
||||
{
|
||||
$this->LogPid();
|
||||
static::assertTrue(true);
|
||||
}
|
||||
|
||||
function CProvider()
|
||||
public function CProvider()
|
||||
{
|
||||
return [
|
||||
[1],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
@@ -8,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
||||
*/
|
||||
class tearDownAfterFailureTest extends TestCase
|
||||
{
|
||||
static $bIsCorrectlyInitialized = true;
|
||||
public static $bIsCorrectlyInitialized = true;
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
@@ -16,7 +17,7 @@ class tearDownAfterFailureTest extends TestCase
|
||||
static::$bIsCorrectlyInitialized = true;
|
||||
}
|
||||
|
||||
function testIsInitializedAndChangeIt()
|
||||
public function testIsInitializedAndChangeIt()
|
||||
{
|
||||
static::assertTrue(static::$bIsCorrectlyInitialized);
|
||||
|
||||
@@ -26,18 +27,18 @@ class tearDownAfterFailureTest extends TestCase
|
||||
throw new \Exception('hello');
|
||||
}
|
||||
|
||||
function testIsStillInitialized()
|
||||
public function testIsStillInitialized()
|
||||
{
|
||||
static::assertTrue(static::$bIsCorrectlyInitialized);
|
||||
}
|
||||
|
||||
function testFailingDueToUnexpectedException()
|
||||
public function testFailingDueToUnexpectedException()
|
||||
{
|
||||
static::$bIsCorrectlyInitialized = false;
|
||||
This_Is_Not_A_Function_And_Causes_A_Fatal_Error();
|
||||
}
|
||||
|
||||
function testIsStillInitializedAnyway()
|
||||
public function testIsStillInitializedAnyway()
|
||||
{
|
||||
static::assertTrue(static::$bIsCorrectlyInitialized);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
* This file is part of iTop.
|
||||
@@ -17,6 +18,7 @@ namespace Combodo\iTop\Test\UnitTest\Integration;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use Dict;
|
||||
|
||||
use const APPROOT;
|
||||
|
||||
/**
|
||||
@@ -44,19 +46,19 @@ class CompiledDictionariesConsistencyTest extends ItopTestCase
|
||||
'UI:CSVReport-Value-NoMatch-SomeObjectNotVisibleForCurrentUser' => ['arg1'],
|
||||
];
|
||||
|
||||
$sCompiledLanguagesFilePath = APPROOT . 'env-' . \utils::GetCurrentEnvironment() . '/dictionaries/languages.php';
|
||||
$sCompiledLanguagesFilePath = APPROOT.'env-'.\utils::GetCurrentEnvironment().'/dictionaries/languages.php';
|
||||
$this->assertFileExists($sCompiledLanguagesFilePath, 'We must have an existing compiled language.php file in the current env !');
|
||||
require_once($sCompiledLanguagesFilePath);
|
||||
$this->assertNotEmpty(Dict::GetLanguages(), 'the languages.php file exists but didn\'t load any language');
|
||||
|
||||
foreach (glob(APPROOT . 'env-' . \utils::GetCurrentEnvironment() . '/dictionaries/*.dict.php') as $sDictFile) {
|
||||
foreach (glob(APPROOT.'env-'.\utils::GetCurrentEnvironment().'/dictionaries/*.dict.php') as $sDictFile) {
|
||||
if (preg_match('/.*\\/(.*).dict.php/', $sDictFile, $aMatches)) {
|
||||
$sLangCode = $aMatches[1];
|
||||
$sLanguageCode = strtoupper(str_replace('-', ' ', $sLangCode));
|
||||
Dict::SetUserLanguage($sLanguageCode);
|
||||
|
||||
foreach ($aLabelsToTest as $sLabelKey => $aLabelArgs) {
|
||||
echo "Testing $sDictFile, label $sLabelKey with " . \var_export($aLabelArgs, true) . "\n";
|
||||
echo "Testing $sDictFile, label $sLabelKey with ".\var_export($aLabelArgs, true)."\n";
|
||||
try {
|
||||
$sLabelValue = Dict::Format($sLabelKey, ...$aLabelArgs);
|
||||
//$this->debug($sLabelValue);
|
||||
@@ -71,7 +73,7 @@ class CompiledDictionariesConsistencyTest extends ItopTestCase
|
||||
]);
|
||||
}
|
||||
}
|
||||
$this->assertEquals([], $aFailedLabels, "$sDictFile : test fail for lang $sLangCode and labels (" . implode(", ", $aFailedLabels) . ')');
|
||||
$this->assertEquals([], $aFailedLabels, "$sDictFile : test fail for lang $sLangCode and labels (".implode(", ", $aFailedLabels).')');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class detectStaticPollutionTest extends TestCase
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function testDetectPolluters($sPattern, $sFix)
|
||||
public function testDetectPolluters($sPattern, $sFix)
|
||||
{
|
||||
$sScannedDir = dirname(__FILE__).'/../unitary-tests';
|
||||
|
||||
@@ -44,7 +44,7 @@ class detectStaticPollutionTest extends TestCase
|
||||
$Iterator = new RecursiveIteratorIterator($oDirectory);
|
||||
foreach (new RegexIterator($Iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH) as $aMatch) {
|
||||
$sFile = $aMatch[0];
|
||||
if(is_file($sFile)) {
|
||||
if (is_file($sFile)) {
|
||||
$sFileContents = file_get_contents($sFile);
|
||||
if (preg_match_all($sPattern, $sFileContents, $keys, PREG_PATTERN_ORDER)) {
|
||||
$aPolluters = array_merge($aPolluters, $this->FindMatches($sFile, $sFileContents, $sPattern));
|
||||
|
||||
@@ -16,7 +16,7 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase
|
||||
"Class:DatacenterDevice/Attribute:redundancy/count",
|
||||
"Class:DatacenterDevice/Attribute:redundancy/disabled",
|
||||
"Class:DatacenterDevice/Attribute:redundancy/percent",
|
||||
"Class:TriggerOnThresholdReached/Attribute:threshold_index+"
|
||||
"Class:TriggerOnThresholdReached/Attribute:threshold_index+",
|
||||
];
|
||||
|
||||
protected function setUp(): void
|
||||
@@ -33,7 +33,8 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase
|
||||
$this->SetNonPublicStaticProperty(\Dict::class, 'm_aData', $aDictEntriesByLanguage);
|
||||
}
|
||||
|
||||
public function FormatProvider(){
|
||||
public function FormatProvider()
|
||||
{
|
||||
return [
|
||||
'key does not exist in dictionnary' => [
|
||||
'sTemplate' => null,
|
||||
@@ -55,13 +56,14 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase
|
||||
* @since 2.7.10 N°5491 - Inconsistent dictionary entries regarding arguments to pass to Dict::Format
|
||||
* @dataProvider FormatProvider
|
||||
*/
|
||||
public function testFormatWithOneArgumentAndCustomKey(?string $sTemplate, $sExpectedTranslation){
|
||||
public function testFormatWithOneArgumentAndCustomKey(?string $sTemplate, $sExpectedTranslation)
|
||||
{
|
||||
//tricky way to mock GetLabelAndLangCode behavior via connected user language
|
||||
$sLangCode = \Dict::GetUserLanguage();
|
||||
$aDictByLang = $this->GetNonPublicStaticProperty(\Dict::class, 'm_aData');
|
||||
$sDictKey = 'ITOP::DICT:FORMAT:BROKEN:KEY';
|
||||
|
||||
if (! is_null($sTemplate)){
|
||||
if (! is_null($sTemplate)) {
|
||||
$aDictByLang[$sLangCode][$sDictKey] = $sTemplate;
|
||||
}
|
||||
|
||||
@@ -72,7 +74,8 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase
|
||||
|
||||
//test works after setup (no annotation @beforesetup)
|
||||
//even if it does not extend ItopDataTestCase
|
||||
private function ReadDictKeys($sLangCode) : array {
|
||||
private function ReadDictKeys($sLangCode): array
|
||||
{
|
||||
\Dict::InitLangIfNeeded($sLangCode);
|
||||
|
||||
$aDictEntries = $this->GetNonPublicStaticProperty(\Dict::class, 'm_aData');
|
||||
@@ -90,28 +93,30 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function GetKeyArgCountMap($aDictEntry) {
|
||||
private function GetKeyArgCountMap($aDictEntry)
|
||||
{
|
||||
$aKeyArgsCount = [];
|
||||
foreach ($aDictEntry as $sKey => $sValue){
|
||||
foreach ($aDictEntry as $sKey => $sValue) {
|
||||
$aKeyArgsCount[$sKey] = $this->countArg($sValue);
|
||||
}
|
||||
ksort($aKeyArgsCount);
|
||||
return $aKeyArgsCount;
|
||||
}
|
||||
|
||||
private function countArg($sLabel) {
|
||||
private function countArg($sLabel)
|
||||
{
|
||||
$iMaxIndex = 0;
|
||||
if (preg_match_all("/%(\d+)/", $sLabel, $aMatches)){
|
||||
if (preg_match_all("/%(\d+)/", $sLabel, $aMatches)) {
|
||||
$aSubMatches = $aMatches[1];
|
||||
if (is_array($aSubMatches)){
|
||||
foreach ($aSubMatches as $aCurrentMatch){
|
||||
if (is_array($aSubMatches)) {
|
||||
foreach ($aSubMatches as $aCurrentMatch) {
|
||||
$iIndex = $aCurrentMatch;
|
||||
$iMaxIndex = ($iMaxIndex < $iIndex) ? $iIndex : $iMaxIndex;
|
||||
}
|
||||
}
|
||||
} else if ((false !== strpos($sLabel, "%s"))
|
||||
} elseif ((false !== strpos($sLabel, "%s"))
|
||||
|| (false !== strpos($sLabel, "%d"))
|
||||
){
|
||||
) {
|
||||
$iMaxIndex = 1;
|
||||
}
|
||||
|
||||
@@ -122,7 +127,8 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase
|
||||
* Warning: hardcoded list of languages
|
||||
* It is hard to have it dynamically via Dict::GetLanguages as for each lang Dict::Init should be called first
|
||||
**/
|
||||
public function LangCodeProvider(){
|
||||
public function LangCodeProvider()
|
||||
{
|
||||
return [
|
||||
'cs' => [ 'CS CZ' ],
|
||||
'da' => [ 'DA DA' ],
|
||||
@@ -154,7 +160,6 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase
|
||||
|
||||
$aDictEntry = $this->ReadDictKeys($sLanguageCodeToTest);
|
||||
|
||||
|
||||
$aKeyArgsCountMap = [];
|
||||
$aKeyArgsCountMap[$sReferenceLangCode] = $this->GetKeyArgCountMap($aReferenceLangDictEntry);
|
||||
//$aKeyArgsCountMap[$sCode] = $this->GetKeyArgCountMap($aDictEntry);
|
||||
@@ -164,30 +169,30 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase
|
||||
|
||||
$aMismatchedKeys = [];
|
||||
|
||||
foreach ($aKeyArgsCountMap[$sReferenceLangCode] as $sKey => $iExpectedNbOfArgs){
|
||||
if (0 === $iExpectedNbOfArgs){
|
||||
//no arg needed in EN.
|
||||
foreach ($aKeyArgsCountMap[$sReferenceLangCode] as $sKey => $iExpectedNbOfArgs) {
|
||||
if (0 === $iExpectedNbOfArgs) {
|
||||
//no arg needed in EN.
|
||||
//let s assume job has been done correctly in EN to simplify
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($sKey, self::$aLabelCodeNotToCheck)){
|
||||
if (in_array($sKey, self::$aLabelCodeNotToCheck)) {
|
||||
//false positive: do not test
|
||||
continue;
|
||||
}
|
||||
|
||||
if (array_key_exists($sKey, $aDictEntry)){
|
||||
if (array_key_exists($sKey, $aDictEntry)) {
|
||||
$aPlaceHolders = [];
|
||||
for ($i=0; $i<$iExpectedNbOfArgs; $i++){
|
||||
$aPlaceHolders[]=$i;
|
||||
for ($i = 0; $i < $iExpectedNbOfArgs; $i++) {
|
||||
$aPlaceHolders[] = $i;
|
||||
}
|
||||
|
||||
$sLabelTemplate = $aDictEntry[$sKey];
|
||||
try{
|
||||
try {
|
||||
vsprintf($sLabelTemplate, $aPlaceHolders);
|
||||
} catch(\Throwable $e){
|
||||
} catch (\Throwable $e) {
|
||||
$sError = $e->getMessage();
|
||||
if (array_key_exists($sError, $aMismatchedKeys)){
|
||||
if (array_key_exists($sError, $aMismatchedKeys)) {
|
||||
$aMismatchedKeys[$sError][$sKey] = $iExpectedNbOfArgs;
|
||||
} else {
|
||||
$aMismatchedKeys[$sError] = [$sKey => $iExpectedNbOfArgs];
|
||||
@@ -197,7 +202,7 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase
|
||||
}
|
||||
|
||||
$iCount = 0;
|
||||
foreach ($aMismatchedKeys as $sError => $aKeys){
|
||||
foreach ($aMismatchedKeys as $sError => $aKeys) {
|
||||
var_dump($sError);
|
||||
foreach ($aKeys as $sKey => $iExpectedNbOfArgs) {
|
||||
$iCount++;
|
||||
@@ -222,7 +227,8 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase
|
||||
$this->assertEquals([], $aMismatchedKeys, $sErrorMsg);
|
||||
}
|
||||
|
||||
public function testEveryEnglishEntryShouldHaveItsFrenchCounterpart() {
|
||||
public function testEveryEnglishEntryShouldHaveItsFrenchCounterpart()
|
||||
{
|
||||
$sReferenceLangCode = 'EN US';
|
||||
$aReferenceLangDictEntries = $this->ReadDictKeys($sReferenceLangCode);
|
||||
|
||||
@@ -233,13 +239,14 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase
|
||||
$this->assertCount(0, $aMissingEntries, "The following entries are missing in french dictionaries : \n - ".implode("\n - ", $aMissingEntries));
|
||||
}
|
||||
|
||||
public function testEveryFrenchEntryShouldBeTranslated() {
|
||||
public function testEveryFrenchEntryShouldBeTranslated()
|
||||
{
|
||||
$sFrenchLangCode = 'FR FR';
|
||||
$aFrenchDictEntries = $this->ReadDictKeys($sFrenchLangCode);
|
||||
|
||||
$aUntranslatedEntries = [];
|
||||
foreach ($aFrenchDictEntries as $sKey => $sValue){
|
||||
if(mb_substr($sValue,-2) === '~~'){
|
||||
foreach ($aFrenchDictEntries as $sKey => $sValue) {
|
||||
if (mb_substr($sValue, -2) === '~~') {
|
||||
$aUntranslatedEntries[] = $sKey.' => '.var_export($sValue, true);
|
||||
}
|
||||
}
|
||||
@@ -247,7 +254,8 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase
|
||||
$this->assertCount(0, $aUntranslatedEntries, "The following french entries require translation : \n - ".implode("\n - ", $aUntranslatedEntries));
|
||||
}
|
||||
|
||||
public function VsprintfProvider(){
|
||||
public function VsprintfProvider()
|
||||
{
|
||||
return [
|
||||
'not enough args' => [
|
||||
"sLabelTemplate" => "$1%s",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
* This file is part of iTop.
|
||||
@@ -21,10 +22,10 @@ use Exception;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use RegexIterator;
|
||||
|
||||
use const ARRAY_FILTER_USE_BOTH;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper to load dictionary files without altering the main dictionary
|
||||
* Eval will be called within the current namespace (this is done by adding a "namespace" statement)
|
||||
@@ -49,7 +50,8 @@ class Dict
|
||||
|
||||
public static $sLastAddedLanguageCode = null;
|
||||
|
||||
public static function EnableLoadEntries(bool $bSaveKeyDuplicates = false) :void {
|
||||
public static function EnableLoadEntries(bool $bSaveKeyDuplicates = false): void
|
||||
{
|
||||
self::$sLastAddedLanguageCode = null;
|
||||
self::$m_aData = [];
|
||||
self::$aKeysDuplicate = [];
|
||||
@@ -84,8 +86,6 @@ class Dict
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* For tests on compiled dict files, see {@see CompiledDictionariesConsistencyTest}
|
||||
* @group beforeSetup
|
||||
@@ -126,20 +126,28 @@ class DictionariesConsistencyTest extends ItopTestCase
|
||||
static::assertTrue(true);
|
||||
}
|
||||
foreach ($aMatches[1] as $sLanguageCode) {
|
||||
static::assertSame($sExpectedLanguageCode, $sLanguageCode,
|
||||
"Unexpected language code for Dict::Add in dictionary $sDictFile");
|
||||
static::assertSame(
|
||||
$sExpectedLanguageCode,
|
||||
$sLanguageCode,
|
||||
"Unexpected language code for Dict::Add in dictionary $sDictFile"
|
||||
);
|
||||
}
|
||||
foreach ($aMatches[2] as $sEnglishLanguageDesc) {
|
||||
static::assertSame($sExpectedEnglishLanguageDesc, $sEnglishLanguageDesc,
|
||||
"Unexpected language description (english) for Dict::Add in dictionary $sDictFile");
|
||||
static::assertSame(
|
||||
$sExpectedEnglishLanguageDesc,
|
||||
$sEnglishLanguageDesc,
|
||||
"Unexpected language description (english) for Dict::Add in dictionary $sDictFile"
|
||||
);
|
||||
}
|
||||
foreach ($aMatches[3] as $sLocalizedLanguageDesc)
|
||||
{
|
||||
foreach ($aMatches[3] as $sLocalizedLanguageDesc) {
|
||||
if (false === is_array($aExpectedLocalizedLanguageDesc)) {
|
||||
$aExpectedLocalizedLanguageDesc = array($aExpectedLocalizedLanguageDesc);
|
||||
$aExpectedLocalizedLanguageDesc = [$aExpectedLocalizedLanguageDesc];
|
||||
}
|
||||
static::assertContains($sLocalizedLanguageDesc,$aExpectedLocalizedLanguageDesc,
|
||||
"Unexpected language description for Dict::Add in dictionary $sDictFile");
|
||||
static::assertContains(
|
||||
$sLocalizedLanguageDesc,
|
||||
$aExpectedLocalizedLanguageDesc,
|
||||
"Unexpected language description for Dict::Add in dictionary $sDictFile"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,18 +156,16 @@ class DictionariesConsistencyTest extends ItopTestCase
|
||||
$this->setUp();
|
||||
$sAppRoot = static::GetAppRoot();
|
||||
|
||||
|
||||
$aDictFilesCore = [];
|
||||
$sCoreDictionariesPath = realpath($sAppRoot.'dictionaries');
|
||||
$sDictFilePattern = '/^.+\.dict.*\.php$/i';
|
||||
$oDirIterator = new RecursiveDirectoryIterator($sCoreDictionariesPath, RecursiveDirectoryIterator::SKIP_DOTS);
|
||||
$oIterator = new RecursiveIteratorIterator($oDirIterator, RecursiveIteratorIterator::SELF_FIRST);
|
||||
$oRegexIterator = new RegexIterator($oIterator, $sDictFilePattern, RegexIterator::GET_MATCH);
|
||||
foreach($oRegexIterator as $file) {
|
||||
foreach ($oRegexIterator as $file) {
|
||||
$aDictFilesCore[] = $file[0];
|
||||
}
|
||||
|
||||
|
||||
$aDictFilesModules = array_merge(
|
||||
glob($sAppRoot.'datamodels/2.x/*/*.dict*.php'), // legacy form in modules
|
||||
glob($sAppRoot.'datamodels/2.x/*/dictionaries/*.dict*.php'), // modern form in modules
|
||||
@@ -170,15 +176,14 @@ class DictionariesConsistencyTest extends ItopTestCase
|
||||
);
|
||||
$this->RemoveModulesWithout7246Fixes($aDictFilesModules);
|
||||
|
||||
|
||||
$aDictFiles = array_merge($aDictFilesCore, $aDictFilesModules);
|
||||
|
||||
$aTestCases = array();
|
||||
$aTestCases = [];
|
||||
foreach ($aDictFiles as $sDictFile) {
|
||||
preg_match('/^(.*)\\.dict/', basename($sDictFile), $aMatches);
|
||||
$sDictFileLangPrefix = $aMatches[1];
|
||||
|
||||
$aTestCases[$sDictFile] = array('sDictFile' => $sDictFile, 'sLanguagePrefix' => $sDictFileLangPrefix);
|
||||
$aTestCases[$sDictFile] = ['sDictFile' => $sDictFile, 'sLanguagePrefix' => $sDictFileLangPrefix];
|
||||
}
|
||||
|
||||
return $aTestCases;
|
||||
@@ -189,11 +194,11 @@ class DictionariesConsistencyTest extends ItopTestCase
|
||||
*
|
||||
* @since 3.0.5 3.1.2 3.2.0 N°7246
|
||||
*/
|
||||
private function RemoveModulesWithout7246Fixes(array &$aDictFilesModules):void
|
||||
private function RemoveModulesWithout7246Fixes(array &$aDictFilesModules): void
|
||||
{
|
||||
require_once static::GetAppRoot() . 'approot.inc.php'; // mandatory for tearDownAfterClass to work, of not present will thow `Undefined constant "LINKSET_TRACKING_LIST"`
|
||||
require_once static::GetAppRoot().'approot.inc.php'; // mandatory for tearDownAfterClass to work, of not present will thow `Undefined constant "LINKSET_TRACKING_LIST"`
|
||||
$this->RequireOnceItopFile('core/config.class.inc.php'); // source of the ITOP_VERSION constant
|
||||
if (version_compare(ITOP_VERSION, '3.2.0', '>=')) {
|
||||
if (version_compare(ITOP_VERSION, '3.2.0', '>=')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -246,7 +251,8 @@ class DictionariesConsistencyTest extends ItopTestCase
|
||||
$this->CheckDictionarySyntax(__DIR__.'/dictionaries-test/fr.dictionary.itop.core.OK.php', true);
|
||||
}
|
||||
|
||||
private function GetPhpCodeFromDictFile(string $sDictFile) : string {
|
||||
private function GetPhpCodeFromDictFile(string $sDictFile): string
|
||||
{
|
||||
$sPHP = file_get_contents($sDictFile);
|
||||
// Strip php tag to allow "eval"
|
||||
$sPHP = substr(trim($sPHP), strlen('<?php'));
|
||||
@@ -281,14 +287,12 @@ class DictionariesConsistencyTest extends ItopTestCase
|
||||
if (!$bIsSyntaxValid) {
|
||||
$this->fail("Failed to detect syntax error in dictionary `{$sDictFile}` (which is known as being INCORRECT)");
|
||||
}
|
||||
}
|
||||
catch (Error $e) {
|
||||
} catch (Error $e) {
|
||||
if ($bIsSyntaxValid) {
|
||||
$iLine = $e->getLine() - $iLineShift;
|
||||
$this->fail("Invalid dictionary: {$e->getMessage()} in {$sDictFile}:{$iLine}");
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
if ($bIsSyntaxValid) {
|
||||
$iLine = $e->getLine() - $iLineShift;
|
||||
$sExceptionClass = get_class($e);
|
||||
@@ -303,7 +307,8 @@ class DictionariesConsistencyTest extends ItopTestCase
|
||||
*
|
||||
* @since 3.0.5 3.1.2 3.2.0 N°7143
|
||||
*/
|
||||
public function testNoDictFileInDatamodelsModuleRootDirectory():void {
|
||||
public function testNoDictFileInDatamodelsModuleRootDirectory(): void
|
||||
{
|
||||
$sAppRoot = static::GetAppRoot();
|
||||
$aDictFilesInDatamodelsModuleRootDir = glob($sAppRoot.'datamodels/2.x/*/*.dict*.php');
|
||||
$this->assertNotFalse($aDictFilesInDatamodelsModuleRootDir, 'Searching for files returned an error');
|
||||
@@ -311,7 +316,7 @@ class DictionariesConsistencyTest extends ItopTestCase
|
||||
$aExcludedModulesList = $this->GetLtsCompatibleModulesList();
|
||||
$aDictFilesInDatamodelsModuleRootDir = array_filter(
|
||||
$aDictFilesInDatamodelsModuleRootDir,
|
||||
function($sDictFileFullPath) use ($aExcludedModulesList) {
|
||||
function ($sDictFileFullPath) use ($aExcludedModulesList) {
|
||||
$sModuleFullPath = dirname($sDictFileFullPath);
|
||||
$sModuleDirectory = basename($sModuleFullPath);
|
||||
return !in_array($sModuleDirectory, $aExcludedModulesList);
|
||||
@@ -319,7 +324,9 @@ class DictionariesConsistencyTest extends ItopTestCase
|
||||
);
|
||||
|
||||
$sDictFilesInDatamodelsModuleRootDirList = var_export($aDictFilesInDatamodelsModuleRootDir, true);
|
||||
$this->assertCount(0, $aDictFilesInDatamodelsModuleRootDir,
|
||||
$this->assertCount(
|
||||
0,
|
||||
$aDictFilesInDatamodelsModuleRootDir,
|
||||
<<<EOF
|
||||
There are some files in datamodels module root dirs ! You must either:
|
||||
- add the module in the GetLtsCompatibleModulesList method (if the module needs to keep compatibility with iTop 2.7)
|
||||
@@ -336,7 +343,8 @@ EOF
|
||||
* Indeed multiple targets will add modules that must remain compatible with iTop 2.7 LTS, though with dict files in their root dir
|
||||
* The dictionaries directory in modules was added in 3.0.0 with N°2969
|
||||
*/
|
||||
private function GetLtsCompatibleModulesList(): array {
|
||||
private function GetLtsCompatibleModulesList(): array
|
||||
{
|
||||
return [
|
||||
'approval-base',
|
||||
'authent-token',
|
||||
@@ -385,7 +393,8 @@ EOF
|
||||
/**
|
||||
* @dataProvider DictionaryFileProvider
|
||||
*/
|
||||
public function testDictKeyDefinedOncePerFile(string $sDictFileToTestFullPath): void {
|
||||
public function testDictKeyDefinedOncePerFile(string $sDictFileToTestFullPath): void
|
||||
{
|
||||
Dict::EnableLoadEntries(true);
|
||||
|
||||
$sDictFileToTestPhp = $this->GetPhpCodeFromDictFile($sDictFileToTestFullPath);
|
||||
@@ -406,17 +415,18 @@ EOF
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDictKeyDefinedOnceForWholeProject(string $sLang): void {
|
||||
public function testDictKeyDefinedOnceForWholeProject(string $sLang): void
|
||||
{
|
||||
$this->markTestSkipped("Skip because duplicates exists in modules, while once is installed at setup. Possible solution : centralize common string in another dictionnary, and then enable this test.");
|
||||
|
||||
Dict::EnableLoadEntries(true);
|
||||
$aDictKeysDefinedMultipleTimes = [];
|
||||
|
||||
|
||||
foreach ($this->DictionaryFileProvider() as $aDictFile) {
|
||||
|
||||
if($aDictFile['sLanguagePrefix'] !== $sLang) continue;
|
||||
|
||||
if ($aDictFile['sLanguagePrefix'] !== $sLang) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Dict::ResetFileDuplicate();
|
||||
$sDictFileToTestFullPath = $aDictFile['sDictFile'];
|
||||
@@ -426,21 +436,20 @@ EOF
|
||||
|
||||
foreach (Dict::$aKeysDuplicate as $sDictKey => $iNumberOfDuplicates) {
|
||||
if (array_key_exists($sDictKey, $aDictKeysDefinedMultipleTimes)) {
|
||||
$aDictKeysDefinedMultipleTimes[$sDictKey]+= $iNumberOfDuplicates;
|
||||
$aDictKeysDefinedMultipleTimes[$sDictKey] += $iNumberOfDuplicates;
|
||||
} else {
|
||||
$aDictKeysDefinedMultipleTimes[$sDictKey] = $iNumberOfDuplicates;
|
||||
}
|
||||
}
|
||||
}
|
||||
$aDictKeysDefinedMoreThanOnce = array_filter($aDictKeysDefinedMultipleTimes, static function($iNumberOfDuplicates) {
|
||||
$aDictKeysDefinedMoreThanOnce = array_filter($aDictKeysDefinedMultipleTimes, static function ($iNumberOfDuplicates) {
|
||||
return $iNumberOfDuplicates > 0;
|
||||
});
|
||||
$this->assertEmpty($aDictKeysDefinedMoreThanOnce, "Some keys (". sizeof($aDictKeysDefinedMoreThanOnce).") are defined multiple times in the whole projectin lang $sLang: ".var_export($aDictKeysDefinedMoreThanOnce, true));
|
||||
$this->assertEmpty($aDictKeysDefinedMoreThanOnce, "Some keys (".sizeof($aDictKeysDefinedMoreThanOnce).") are defined multiple times in the whole projectin lang $sLang: ".var_export($aDictKeysDefinedMoreThanOnce, true));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* @dataProvider DictionaryFileProvider
|
||||
*/
|
||||
public function testNoRemainingTildesInTranslatedKeys(string $sDictFileToTestFullPath): void
|
||||
@@ -449,7 +458,6 @@ EOF
|
||||
$sReferenceLangCode = 'EN US';
|
||||
$sReferenceDictName = 'en';
|
||||
|
||||
|
||||
$sDictFileToTestPhp = $this->GetPhpCodeFromDictFile($sDictFileToTestFullPath);
|
||||
eval($sDictFileToTestPhp);
|
||||
|
||||
@@ -482,7 +490,6 @@ EOF
|
||||
$aLangToTestDictEntries = Dict::$m_aData[$sLanguageCodeToTest];
|
||||
$aReferenceLangDictEntries = Dict::$m_aData[$sReferenceLangCode];
|
||||
|
||||
|
||||
$this->assertGreaterThan(0, count($aLangToTestDictEntries), 'There should be at least one entry in the dictionary file to test');
|
||||
$aLangToTestDictEntriesNotEmptyValues = array_filter(
|
||||
$aLangToTestDictEntries,
|
||||
@@ -493,7 +500,6 @@ EOF
|
||||
);
|
||||
$this->assertNotEmpty($aLangToTestDictEntriesNotEmptyValues);
|
||||
|
||||
|
||||
$aTranslatedKeysWithTildes = [];
|
||||
foreach ($aReferenceLangDictEntries as $sDictKey => $sReferenceLangLabel) {
|
||||
if (false === array_key_exists($sDictKey, $aLangToTestDictEntries)) {
|
||||
@@ -522,13 +528,13 @@ EOF
|
||||
$sLanguageCodeToTest.'_file_location' => $this->MakeFilePathClickable($sDictFileToTestFullPath, $sDictKeyLineNumberInDictFileToTest),
|
||||
$sLanguageCodeToTest => $sTranslatedLabel,
|
||||
$sReferenceLangCode.'_file_location' => $this->MakeFilePathClickable($sDictFileReferenceFullPath, $sDictKeyLineNumberInDictFileReference),
|
||||
$sReferenceLangCode => $sReferenceLangLabel
|
||||
$sReferenceLangCode => $sReferenceLangLabel,
|
||||
];
|
||||
}
|
||||
|
||||
$sPathRoot = static::GetAppRoot();
|
||||
$sDictFileToTestRelativePath = str_replace($sPathRoot, '', $sDictFileToTestFullPath);
|
||||
$this->assertEmpty($aTranslatedKeysWithTildes, "In {$sDictFileToTestRelativePath} \n following keys are different from their '{$sReferenceDictName}' counterpart (translated ?) but have tildes at the end:\n" . var_export($aTranslatedKeysWithTildes, true));
|
||||
$this->assertEmpty($aTranslatedKeysWithTildes, "In {$sDictFileToTestRelativePath} \n following keys are different from their '{$sReferenceDictName}' counterpart (translated ?) but have tildes at the end:\n".var_export($aTranslatedKeysWithTildes, true));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -538,18 +544,19 @@ EOF
|
||||
* @return string a path that is clickable in PHPStorm 🤩
|
||||
* For this to happen we need full path with correct dir sep + line number
|
||||
* If it is not, check in File | Settings | Tools | Terminal the hyperlink option is checked
|
||||
*/
|
||||
private function MakeFilePathClickable(string $sFullPath, int $iLineNumber):string {
|
||||
return str_replace(array('//', '/'), array('/', DIRECTORY_SEPARATOR), $sFullPath).':'.$iLineNumber;
|
||||
*/
|
||||
private function MakeFilePathClickable(string $sFullPath, int $iLineNumber): string
|
||||
{
|
||||
return str_replace(['//', '/'], ['/', DIRECTORY_SEPARATOR], $sFullPath).':'.$iLineNumber;
|
||||
}
|
||||
|
||||
private function FindDictKeyLineNumberInContent(string $sFileContent, string $sDictKey): int
|
||||
{
|
||||
$aContentLines = explode("\n", $sFileContent);
|
||||
$aContentLines = explode("\n", $sFileContent);
|
||||
$sDictKeyToFind = "'{$sDictKey}'"; // adding string delimiters to match exact dict key (eg if not we would match 'Core:AttributeDateTime?SmartSearch' for 'Core:AttributeDateTime')
|
||||
|
||||
foreach($aContentLines as $iLineNumber => $line) {
|
||||
if(strpos($line, $sDictKeyToFind) !== false){
|
||||
foreach ($aContentLines as $iLineNumber => $line) {
|
||||
if (strpos($line, $sDictKeyToFind) !== false) {
|
||||
return $iLineNumber;
|
||||
}
|
||||
}
|
||||
@@ -576,7 +583,7 @@ EOF
|
||||
[
|
||||
'Español, Castellaño', // old value
|
||||
'Español, Castellano', // new value since N°3635
|
||||
]
|
||||
],
|
||||
],
|
||||
'fr' => ['FR FR', 'French', 'Français'],
|
||||
'hu' => ['HU HU', 'Hungarian', 'Magyar'],
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* @used-by \Combodo\iTop\Test\UnitTest\Integration\DictionariesConsistencyTest::testPlaygroundDictionariesPhpSyntax
|
||||
*/
|
||||
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'MyDictKey1' => 'l\'échappement : bon exemple 1'.ITOP_APPLICATION,
|
||||
'MyDictKey2' => 'l\'échappement : bon exemple 2',
|
||||
'MyDictKey3' => 'l\'échappement : bon exemple 3',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
* This file is part of iTop.
|
||||
@@ -19,18 +20,19 @@ use ApplicationException;
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use utils;
|
||||
|
||||
|
||||
/**
|
||||
* @package Combodo\iTop\Test\UnitTest\Setup
|
||||
* @group beforeSetup
|
||||
*/
|
||||
class iTopModulesPhpVersionIntegrationTest extends ItopTestCase {
|
||||
class iTopModulesPhpVersionIntegrationTest extends ItopTestCase
|
||||
{
|
||||
/**
|
||||
* @param string $sPhpFile iTop module file
|
||||
*
|
||||
* @return string module version
|
||||
*/
|
||||
private function GetItopModuleVersion(string $sPhpFile): ?string {
|
||||
private function GetItopModuleVersion(string $sPhpFile): ?string
|
||||
{
|
||||
$sModulePath = realpath($sPhpFile);
|
||||
$sModuleFileName = basename($sModulePath);
|
||||
$sModuleName = preg_replace('/[^.]+\.([^.]+)\.php/', '$1', $sModuleFileName);
|
||||
@@ -60,7 +62,8 @@ class iTopModulesPhpVersionIntegrationTest extends ItopTestCase {
|
||||
* @since 2.7.7 3.0.1 3.1.0 N°4714 uses new {@link ITOP_CORE_VERSION} constant
|
||||
* @since 3.0.3 3.1.0 move itop-community group in this method
|
||||
*/
|
||||
public function testITopModulesPhpVersion(): void {
|
||||
public function testITopModulesPhpVersion(): void
|
||||
{
|
||||
if (is_dir(APPROOT.'datamodels/2.x')) {
|
||||
$DatamodelsPath = APPROOT.'datamodels/2.x';
|
||||
} elseif (is_dir(APPROOT.'datamodels/1.x')) {
|
||||
@@ -79,8 +82,11 @@ class iTopModulesPhpVersionIntegrationTest extends ItopTestCase {
|
||||
foreach ($aPhpFiles as $sPhpFile) {
|
||||
$sActualVersion = $this->GetItopModuleVersion($sPhpFile);
|
||||
|
||||
$this->assertSame($sExpectedVersion, $sActualVersion,
|
||||
'Module desc file does not contain the same version as the core: '.$sPhpFile);
|
||||
$this->assertSame(
|
||||
$sExpectedVersion,
|
||||
$sActualVersion,
|
||||
'Module desc file does not contain the same version as the core: '.$sPhpFile
|
||||
);
|
||||
}
|
||||
|
||||
self::assertEquals([], $aModuleWithError, 'Some modules have wrong versions ! They should match '.$sExpectedVersion);
|
||||
@@ -90,11 +96,11 @@ class iTopModulesPhpVersionIntegrationTest extends ItopTestCase {
|
||||
* @dataProvider ItopWikiVersionProvider
|
||||
* @since 2.7.7 3.0.1 3.1.1 N°4714 new ITOP_CORE_VERSION constant
|
||||
*/
|
||||
public function testItopWikiVersion($sItopVersion, $sExpectedWikiVersion) {
|
||||
public function testItopWikiVersion($sItopVersion, $sExpectedWikiVersion)
|
||||
{
|
||||
try {
|
||||
$sActualWikiVersion = utils::GetItopVersionWikiSyntax($sItopVersion);
|
||||
}
|
||||
catch (ApplicationException $e) {
|
||||
} catch (ApplicationException $e) {
|
||||
self::fail('Cannot get wiki version : '.$e->getMessage());
|
||||
}
|
||||
self::assertSame($sExpectedWikiVersion, $sActualWikiVersion, 'Computed wiki version is wrong !');
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
* This file is part of iTop.
|
||||
@@ -19,7 +20,6 @@ use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use DOMDocument;
|
||||
use iTopDesignFormat;
|
||||
|
||||
|
||||
/**
|
||||
* @covers iTopDesignFormat
|
||||
*
|
||||
@@ -35,7 +35,6 @@ class iTopModulesXmlVersionIntegrationTest extends ItopTestCase
|
||||
$this->RequireOnceItopFile('setup/itopdesignformat.class.inc.php');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify if the `datamodels/2.x/datamodel.*.xml` files refer to the latest version of the design
|
||||
* This is an integration test
|
||||
@@ -61,8 +60,11 @@ class iTopModulesXmlVersionIntegrationTest extends ItopTestCase
|
||||
if ($oFormat->Convert()) {
|
||||
// Compare the original and new format
|
||||
$sExpectedXmlVersion = ITOP_DESIGN_LATEST_VERSION;
|
||||
$this->assertSame($oTransformedXml->saveXML(), $oOriginalXml->saveXML(),
|
||||
"Datamodel file $sXmlFile:2 not in the latest format ($sExpectedXmlVersion)");
|
||||
$this->assertSame(
|
||||
$oTransformedXml->saveXML(),
|
||||
$oOriginalXml->saveXML(),
|
||||
"Datamodel file $sXmlFile:2 not in the latest format ($sExpectedXmlVersion)"
|
||||
);
|
||||
} else {
|
||||
$this->fail("Failed to convert $sXmlFile into the latest format");
|
||||
}
|
||||
@@ -80,11 +82,11 @@ class iTopModulesXmlVersionIntegrationTest extends ItopTestCase
|
||||
$aXmlFiles[] = $sAppRoot.'core/datamodel.core.xml';
|
||||
$aXmlFiles[] = $sAppRoot.'application/datamodel.application.xml';
|
||||
|
||||
$aTestCases = array();
|
||||
$aTestCases = [];
|
||||
foreach ($aXmlFiles as $sXmlFile) {
|
||||
$aTestCases[$sXmlFile] = array(
|
||||
$aTestCases[$sXmlFile] = [
|
||||
'sXmlFile' => $sXmlFile,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
return $aTestCases;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
* This file is part of iTop.
|
||||
@@ -17,7 +18,6 @@ namespace Combodo\iTop\Test\UnitTest\Integration;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
|
||||
|
||||
/**
|
||||
* @package Combodo\iTop\Test\UnitTest\Setup
|
||||
* @group beforeSetup
|
||||
@@ -32,7 +32,6 @@ class iTopXmlVersionIntegrationTest extends ItopTestCase
|
||||
$this->RequireOnceItopFile('setup/itopdesignformat.class.inc.php');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify if the latest version of the XML datamodel is aligned with the app. core version
|
||||
* This is an integration test
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\HubConnector;
|
||||
|
||||
use Combodo\iTop\Application\Helper\Session;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use PHPUnit\Framework\SkippedTestCase;
|
||||
|
||||
class AjaxPageTest extends ItopDataTestCase {
|
||||
const USE_TRANSACTION = false;
|
||||
const AUTHENTICATION_TOKEN = '14b5da9d092f84044187421419a0347e7317bc8cd2b486fdda631be06b959269';
|
||||
const AUTHENTICATION_PASSWORD = "tagada-Secret,007";
|
||||
class AjaxPageTest extends ItopDataTestCase
|
||||
{
|
||||
public const USE_TRANSACTION = false;
|
||||
public const AUTHENTICATION_TOKEN = '14b5da9d092f84044187421419a0347e7317bc8cd2b486fdda631be06b959269';
|
||||
public const AUTHENTICATION_PASSWORD = "tagada-Secret,007";
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
@@ -38,12 +40,12 @@ class AjaxPageTest extends ItopDataTestCase {
|
||||
|
||||
// Then
|
||||
$aRes = json_decode($sOutput, true);
|
||||
$this->assertNotNull($aRes, "Response should be a valid json, found instead:" . PHP_EOL . $sOutput);
|
||||
$this->assertNotNull($aRes, "Response should be a valid json, found instead:".PHP_EOL.$sOutput);
|
||||
$this->assertEquals(
|
||||
[
|
||||
'code' => 0,
|
||||
'message' => 'Ok',
|
||||
'fields' => []
|
||||
'message' => 'Ok',
|
||||
'fields' => [],
|
||||
],
|
||||
$aRes
|
||||
);
|
||||
@@ -73,4 +75,4 @@ class AjaxPageTest extends ItopDataTestCase {
|
||||
|
||||
return $sOutput;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -19,25 +20,20 @@
|
||||
|
||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
|
||||
require_once ('../../../approot.inc.php');
|
||||
require_once('../../../approot.inc.php');
|
||||
require_once(APPROOT.'application/application.inc.php');
|
||||
require_once(APPROOT.'application/startup.inc.php');
|
||||
require_once(APPROOT.'application/loginwebpage.class.inc.php');
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Main program
|
||||
//
|
||||
LoginWebPage::DoLogin(true); // Check user rights and prompt if needed
|
||||
|
||||
|
||||
$sSubmit = utils::ReadParam('submit', '', false, 'raw_data');
|
||||
if ($sSubmit != 'Reset')
|
||||
{
|
||||
if ($sSubmit != 'Reset') {
|
||||
$sOQL = utils::ReadParam('OQL_Request', '', false, 'raw_data');
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sOQL = '';
|
||||
}
|
||||
$bError = false;
|
||||
@@ -46,20 +42,15 @@ $oP->set_base(utils::GetAbsoluteUrlAppRoot().'tests/');
|
||||
$oP->set_title('Grouping with functions');
|
||||
$oP->add('<div style="padding: 15px;"><h2>Grouping with functions</h2>');
|
||||
$oP->add('<div style="padding: 15px; background: #ddd;">');
|
||||
try
|
||||
{
|
||||
if (!empty($sOQL))
|
||||
{
|
||||
try {
|
||||
if (!empty($sOQL)) {
|
||||
// Getting class attributes
|
||||
$oSearch = DBSearch::FromOQL($sOQL);
|
||||
$aSearches = $oSearch->GetSearches();
|
||||
if ($oSearch instanceof DBUnionSearch)
|
||||
{
|
||||
if ($oSearch instanceof DBUnionSearch) {
|
||||
$sClass = $aSearches[0]->GetClassAlias();
|
||||
$sRealClass = $aSearches[0]->GetClass();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sClass = $oSearch->GetClassAlias();
|
||||
$sRealClass = $oSearch->GetClass();
|
||||
}
|
||||
@@ -74,22 +65,17 @@ try
|
||||
$sAttributesOptions3 = '';
|
||||
$sAttributesOptions4 = '';
|
||||
|
||||
foreach(array('_itop_sum_', '_itop_avg_', '_itop_min_', '_itop_max_', '_itop_count_', 'group1', 'group2') as $sAttCode)
|
||||
{
|
||||
foreach (['_itop_sum_', '_itop_avg_', '_itop_min_', '_itop_max_', '_itop_count_', 'group1', 'group2'] as $sAttCode) {
|
||||
$sAttributesOptions3 .= '<option value="'.$sAttCode.'" '.($sOrderBy1 == $sAttCode ? 'selected' : '').'>'.$sAttCode.'</option>';
|
||||
$sAttributesOptions4 .= '<option value="'.$sAttCode.'" '.($sOrderBy2 == $sAttCode ? 'selected' : '').'>'.$sAttCode.'</option>';
|
||||
}
|
||||
|
||||
foreach(MetaModel::ListAttributeDefs($sRealClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
foreach (MetaModel::ListAttributeDefs($sRealClass) as $sAttCode => $oAttDef) {
|
||||
// Skip this attribute if not defined in this table
|
||||
if ($oSearch instanceof DBUnionSearch)
|
||||
{
|
||||
foreach($aSearches as $oSubQuery)
|
||||
{
|
||||
if ($oSearch instanceof DBUnionSearch) {
|
||||
foreach ($aSearches as $oSubQuery) {
|
||||
$sSubClass = $oSubQuery->GetClass();
|
||||
if (!MetaModel::IsValidAttCode($sSubClass, $sAttCode))
|
||||
{
|
||||
if (!MetaModel::IsValidAttCode($sSubClass, $sAttCode)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
@@ -109,22 +95,17 @@ try
|
||||
$sFuncField = utils::ReadParam('funcfield', '');
|
||||
|
||||
$sFuncFieldOption = '';
|
||||
foreach(MetaModel::ListAttributeDefs($sRealClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
foreach (MetaModel::ListAttributeDefs($sRealClass) as $sAttCode => $oAttDef) {
|
||||
// Skip this attribute if not defined in this table
|
||||
if ($oSearch instanceof DBUnionSearch)
|
||||
{
|
||||
foreach($aSearches as $oSubQuery)
|
||||
{
|
||||
if ($oSearch instanceof DBUnionSearch) {
|
||||
foreach ($aSearches as $oSubQuery) {
|
||||
$sSubClass = $oSubQuery->GetClass();
|
||||
if (!MetaModel::IsValidAttCode($sSubClass, $sAttCode))
|
||||
{
|
||||
if (!MetaModel::IsValidAttCode($sSubClass, $sAttCode)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (get_class($oAttDef))
|
||||
{
|
||||
switch (get_class($oAttDef)) {
|
||||
case 'Integer':
|
||||
case 'AttributeDecimal':
|
||||
case 'AttributeDuration':
|
||||
@@ -135,9 +116,7 @@ try
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
$oP->p('<div class="header_message message_error">'.$e->getMessage().'</div>');
|
||||
$bError = true;
|
||||
}
|
||||
@@ -158,8 +137,7 @@ $oP->add(
|
||||
EOF
|
||||
);
|
||||
|
||||
if (!empty($sOQL) && !$bError)
|
||||
{
|
||||
if (!empty($sOQL) && !$bError) {
|
||||
$oP->add(
|
||||
<<<EOF
|
||||
<div>
|
||||
@@ -210,55 +188,46 @@ $oP->add("</form>");
|
||||
|
||||
$sSQL = '';
|
||||
|
||||
|
||||
if (empty($sOQL) || empty($sGroupBy1))
|
||||
{
|
||||
if (empty($sOQL) || empty($sGroupBy1)) {
|
||||
$oP->output();
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
try {
|
||||
$iLimitStart = 0;
|
||||
$aOrderBy = array();
|
||||
if (!empty($sOrderBy1))
|
||||
{
|
||||
$aOrderBy = [];
|
||||
if (!empty($sOrderBy1)) {
|
||||
$aOrderBy[$sOrderBy1] = ($sInvOrder1 != 'on');
|
||||
}
|
||||
if (!empty($sOrderBy2))
|
||||
{
|
||||
if (!empty($sOrderBy2)) {
|
||||
$aOrderBy[$sOrderBy2] = ($sInvOrder2 != 'on');
|
||||
}
|
||||
|
||||
$aGroupBy = array();
|
||||
$aGroupBy = [];
|
||||
$oExpr1 = Expression::FromOQL($sClass.'.'.$sGroupBy1);
|
||||
$aGroupBy["group1"] = $oExpr1;
|
||||
|
||||
if (!empty($sGroupBy2))
|
||||
{
|
||||
if (!empty($sGroupBy2)) {
|
||||
$oExpr2 = Expression::FromOQL($sClass.'.'.$sGroupBy2);
|
||||
$aGroupBy["group2"] = $oExpr2;
|
||||
}
|
||||
|
||||
$aArgs = array();
|
||||
$aArgs = [];
|
||||
|
||||
if (empty($sFuncField))
|
||||
{
|
||||
$aFunctions = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (empty($sFuncField)) {
|
||||
$aFunctions = [];
|
||||
} else {
|
||||
$oTimeExpr = Expression::FromOQL($sClass.'.'.$sFuncField);
|
||||
$oSumExpr = new FunctionExpression('SUM', array($oTimeExpr));
|
||||
$oAvgExpr = new FunctionExpression('AVG', array($oTimeExpr));
|
||||
$oMinExpr = new FunctionExpression('MIN', array($oTimeExpr));
|
||||
$oMaxExpr = new FunctionExpression('MAX', array($oTimeExpr));
|
||||
$oSumExpr = new FunctionExpression('SUM', [$oTimeExpr]);
|
||||
$oAvgExpr = new FunctionExpression('AVG', [$oTimeExpr]);
|
||||
$oMinExpr = new FunctionExpression('MIN', [$oTimeExpr]);
|
||||
$oMaxExpr = new FunctionExpression('MAX', [$oTimeExpr]);
|
||||
// Alias => Expression
|
||||
$aFunctions = array(
|
||||
$aFunctions = [
|
||||
'_itop_sum_' => $oSumExpr,
|
||||
'_itop_avg_' => $oAvgExpr,
|
||||
'_itop_min_' => $oMinExpr,
|
||||
'_itop_max_' => $oMaxExpr,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
$sSQL = $oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy, $iLimit, $iLimitStart);
|
||||
@@ -266,28 +235,23 @@ try
|
||||
$aRes = CMDBSource::QueryToArray($sSQL);
|
||||
|
||||
// Display results
|
||||
if (!empty($aRes))
|
||||
{
|
||||
if (!empty($aRes)) {
|
||||
$oP->add('<div>');
|
||||
$oP->add('<table class="listResults">');
|
||||
$aLine = $aRes[0];
|
||||
$aCols = array();
|
||||
$aCols = [];
|
||||
$oP->add('<tr>');
|
||||
foreach(array_keys($aLine) as $item)
|
||||
{
|
||||
if (!is_numeric($item))
|
||||
{
|
||||
foreach (array_keys($aLine) as $item) {
|
||||
if (!is_numeric($item)) {
|
||||
$aCols[] = $item;
|
||||
$oP->add("<th>$item</th>");
|
||||
}
|
||||
}
|
||||
$oP->add('</tr>');
|
||||
|
||||
foreach($aRes as $aLine)
|
||||
{
|
||||
foreach ($aRes as $aLine) {
|
||||
$oP->add('<tr>');
|
||||
foreach($aCols as $sCol)
|
||||
{
|
||||
foreach ($aCols as $sCol) {
|
||||
$oP->add("<td>".$aLine[$sCol]."</td>");
|
||||
}
|
||||
$oP->add('</tr>');
|
||||
@@ -295,14 +259,10 @@ try
|
||||
|
||||
$oP->add('</table>');
|
||||
$oP->add('</div>');
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oP->add("<p>No Result</p>\n");
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
$oP->p('<div class="header_message message_error">'.$e->getMessage().'</div>');
|
||||
$bError = true;
|
||||
}
|
||||
@@ -341,4 +301,4 @@ foreach($aClassSelection as $sClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -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").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();
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -29,17 +30,17 @@ require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||
|
||||
class BenchmarkDataCreation
|
||||
{
|
||||
var $m_iIfByServer;
|
||||
var $m_iIfByNWDevice;
|
||||
var $m_aRequested;
|
||||
var $m_aPlanned;
|
||||
var $m_aCreatedByClass = array();
|
||||
var $m_aCreatedByDesc = array();
|
||||
public $m_iIfByServer;
|
||||
public $m_iIfByNWDevice;
|
||||
public $m_aRequested;
|
||||
public $m_aPlanned;
|
||||
public $m_aCreatedByClass = [];
|
||||
public $m_aCreatedByDesc = [];
|
||||
|
||||
var $m_aStatsByClass = array();
|
||||
public $m_aStatsByClass = [];
|
||||
|
||||
/** @var \CMDBChange $m_oChange */
|
||||
var $m_oChange;
|
||||
public $m_oChange;
|
||||
public function __construct()
|
||||
{
|
||||
CMDBObject::SetTrackInfo('Benchmark setup');
|
||||
@@ -47,22 +48,22 @@ class BenchmarkDataCreation
|
||||
|
||||
public function PlanStructure($iPlannedContacts, $iPlannedContracts)
|
||||
{
|
||||
$this->m_aRequested = array(
|
||||
$this->m_aRequested = [
|
||||
'plannedcontacts' => $iPlannedContacts,
|
||||
'plannedcontracts' => $iPlannedContracts,
|
||||
);
|
||||
$this->m_aPlanned = array(
|
||||
];
|
||||
$this->m_aPlanned = [
|
||||
'Contacts' => $iPlannedContacts,
|
||||
'Contracts' => $iPlannedContracts,
|
||||
'Documents' => $iPlannedContracts * 2,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
public function PlanCis($iPlannedCIs)
|
||||
{
|
||||
$this->m_aRequested = array(
|
||||
$this->m_aRequested = [
|
||||
'plannedcis' => $iPlannedCIs,
|
||||
);
|
||||
];
|
||||
|
||||
$this->m_iIfByServer = 2;
|
||||
$this->m_iIfByNWDevice = 10;
|
||||
@@ -74,7 +75,7 @@ class BenchmarkDataCreation
|
||||
$iSolutions = ceil($iApplications / 2);
|
||||
$iProcesses = ceil($iSolutions / 2);
|
||||
|
||||
$this->m_aPlanned = array(
|
||||
$this->m_aPlanned = [
|
||||
'Network devices' => $iNWDevices,
|
||||
'Servers' => $iServers,
|
||||
'Interfaces' => $iInterfaces,
|
||||
@@ -82,45 +83,43 @@ class BenchmarkDataCreation
|
||||
'Applications' => $iApplications,
|
||||
'Solutions' => $iSolutions,
|
||||
'Processes' => $iProcesses,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
public function PlanTickets($iPlannedTickets, $iBigTicketCis)
|
||||
{
|
||||
$this->m_aRequested = array(
|
||||
$this->m_aRequested = [
|
||||
'plannedtickets' => $iPlannedTickets,
|
||||
'plannedbigticketcis' => $iBigTicketCis,
|
||||
);
|
||||
];
|
||||
|
||||
$this->m_aPlanned = array(
|
||||
$this->m_aPlanned = [
|
||||
'Incidents' => ceil($iPlannedTickets / 2),
|
||||
'Changes' => ceil($iPlannedTickets / 2),
|
||||
'Big ticket: CIs' => $iBigTicketCis,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
public function ShowPlans($oP)
|
||||
{
|
||||
$oP->add("<h2>Planned creations</h2>\n");
|
||||
$aPlanned = $this->m_aPlanned;
|
||||
$aForm = array();
|
||||
foreach ($aPlanned as $sKey => $iCount)
|
||||
{
|
||||
$aForm[] = array(
|
||||
$aForm = [];
|
||||
foreach ($aPlanned as $sKey => $iCount) {
|
||||
$aForm[] = [
|
||||
'label' => $sKey,
|
||||
'input' => $iCount,
|
||||
);
|
||||
];
|
||||
}
|
||||
$oP->form($aForm);
|
||||
}
|
||||
|
||||
|
||||
public function ShowForm($oP, $sNextOperation)
|
||||
{
|
||||
$aRequested = $this->m_aRequested;
|
||||
$oP->add("<form method=\"post\" onSubmit=\"return DoSubmit('Loading data...', 10)\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"operation\" value=\"$sNextOperation\">\n");
|
||||
foreach($this->m_aRequested as $sName => $sValue)
|
||||
{
|
||||
foreach ($this->m_aRequested as $sName => $sValue) {
|
||||
$oP->add("<input type=\"hidden\" name=\"$sName\" value=\"$sValue\">\n");
|
||||
}
|
||||
$oP->add("<button type=\"submit\">Next >></button>\n");
|
||||
@@ -132,10 +131,8 @@ class BenchmarkDataCreation
|
||||
$mu_t1 = MyHelpers::getmicrotime();
|
||||
|
||||
$oMyObject = MetaModel::NewObject($sClass);
|
||||
foreach($aData as $sProp => $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
foreach ($aData as $sProp => $value) {
|
||||
if (is_array($value)) {
|
||||
// transform into a link set
|
||||
$sCSVSpec = implode('|', $value);
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sProp);
|
||||
@@ -152,21 +149,19 @@ class BenchmarkDataCreation
|
||||
|
||||
$mu_t2 = MyHelpers::getmicrotime();
|
||||
$this->m_aStatsByClass[$sClass][] = $mu_t2 - $mu_t1;
|
||||
|
||||
|
||||
return $iId;
|
||||
}
|
||||
|
||||
static $m_aClassIdCache = array();
|
||||
public static $m_aClassIdCache = [];
|
||||
protected function GetClassIds($sClass)
|
||||
{
|
||||
if (!isset(self::$m_aClassIdCache[$sClass]))
|
||||
{
|
||||
if (!isset(self::$m_aClassIdCache[$sClass])) {
|
||||
// Load the cache now
|
||||
self::$m_aClassIdCache[$sClass] = array();
|
||||
|
||||
self::$m_aClassIdCache[$sClass] = [];
|
||||
|
||||
$oSet = new DBObjectSet(new DBObjectSearch($sClass));
|
||||
while($oObj = $oSet->Fetch())
|
||||
{
|
||||
while ($oObj = $oSet->Fetch()) {
|
||||
self::$m_aClassIdCache[$sClass][] = $oObj->GetKey();
|
||||
}
|
||||
}
|
||||
@@ -176,20 +171,18 @@ class BenchmarkDataCreation
|
||||
protected function RandomId($sClass, $sClassDesc = '')
|
||||
{
|
||||
$sClassId = "$sClass ($sClassDesc)";
|
||||
if (isset($this->m_aCreatedByDesc[$sClassId]))
|
||||
{
|
||||
if (isset($this->m_aCreatedByDesc[$sClassId])) {
|
||||
return $this->m_aCreatedByDesc[$sClassId][array_rand($this->m_aCreatedByDesc[$sClassId])];
|
||||
}
|
||||
|
||||
|
||||
$aIds = self::GetClassIds($sClass);
|
||||
return $aIds[array_rand($aIds)];
|
||||
}
|
||||
|
||||
static protected function FindId($sClass)
|
||||
protected static function FindId($sClass)
|
||||
{
|
||||
$oSet = new DBObjectSet(new DBObjectSearch($sClass));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
if ($oSet->Count() < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -197,11 +190,10 @@ class BenchmarkDataCreation
|
||||
return $oObj->GetKey();
|
||||
}
|
||||
|
||||
static protected function FindIdFromOQL($sOQL)
|
||||
protected static function FindIdFromOQL($sOQL)
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
if ($oSet->Count() < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -211,22 +203,15 @@ class BenchmarkDataCreation
|
||||
|
||||
protected function my_array_rand($aData, $iCount)
|
||||
{
|
||||
if ($iCount == 0)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
elseif ($iCount == 1)
|
||||
{
|
||||
if ($iCount == 0) {
|
||||
return [];
|
||||
} elseif ($iCount == 1) {
|
||||
// array_rand() for one item returns only the key
|
||||
$key = array_rand($aData);
|
||||
$aSample = array($key);
|
||||
}
|
||||
elseif ($iCount <= count($aData))
|
||||
{
|
||||
$aSample = [$key];
|
||||
} elseif ($iCount <= count($aData)) {
|
||||
$aSample = array_rand($aData, $iCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aSample = array_merge(array_keys($aData), self::my_array_rand($aData, $iCount - count($aData)));
|
||||
}
|
||||
return $aSample;
|
||||
@@ -240,12 +225,11 @@ class BenchmarkDataCreation
|
||||
$aTargets = self::GetClassIds($sToClass);
|
||||
$aSample = self::my_array_rand($aTargets, $iCount);
|
||||
|
||||
foreach($aSample as $key)
|
||||
{
|
||||
$aData = array(
|
||||
foreach ($aSample as $key) {
|
||||
$aData = [
|
||||
$sAttCodeFrom => $iFrom,
|
||||
$sAttCodeTo => $aTargets[$key],
|
||||
);
|
||||
];
|
||||
$this->CreateObject($sLinkClass, $aData);
|
||||
}
|
||||
}
|
||||
@@ -253,158 +237,153 @@ class BenchmarkDataCreation
|
||||
public function CreateStructure($oP)
|
||||
{
|
||||
$aClasses = MetaModel::GetClasses();
|
||||
$aActions = array('Read', 'Bulk Read', 'Delete', 'Bulk Delete', 'Modify', 'Bulk Modify');
|
||||
$aStdProfiles = array(2, 3, 4, 5, 6, 7, 8, 9);
|
||||
$aActions = ['Read', 'Bulk Read', 'Delete', 'Bulk Delete', 'Modify', 'Bulk Modify'];
|
||||
$aStdProfiles = [2, 3, 4, 5, 6, 7, 8, 9];
|
||||
|
||||
////////////////////////////////////////
|
||||
// New specific profile, giving access to everything
|
||||
//
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'name' => 'Data guru',
|
||||
'description' => 'Could do anything, because everything is granted',
|
||||
);
|
||||
];
|
||||
$iGuruProfile = $this->CreateObject('URP_Profiles', $aData);
|
||||
foreach($aClasses as $sClass)
|
||||
{
|
||||
foreach($aActions as $sAction)
|
||||
{
|
||||
$aData = array(
|
||||
foreach ($aClasses as $sClass) {
|
||||
foreach ($aActions as $sAction) {
|
||||
$aData = [
|
||||
'profileid' => $iGuruProfile,
|
||||
'class' => $sClass,
|
||||
'permission' => 'yes',
|
||||
'action' => $sAction,
|
||||
);
|
||||
];
|
||||
$this->CreateObject('URP_ActionGrant', $aData);
|
||||
}
|
||||
}
|
||||
|
||||
// User login with super access rights
|
||||
//
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'org_id' => self::FindId('Organization'),
|
||||
'location_id' => self::FindId('Location'),
|
||||
'first_name' => 'Jesus',
|
||||
'name' => 'Deus',
|
||||
'email' => 'guru@combodo.com',
|
||||
);
|
||||
];
|
||||
$iPerson = $this->CreateObject('Person', $aData);
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'contactid' => $iPerson,
|
||||
'login' => 'guru',
|
||||
'password' => 'guru',
|
||||
'language' => 'EN US',
|
||||
'profile_list' => array("profileid:$iGuruProfile;reason:he is the one"),
|
||||
);
|
||||
'profile_list' => ["profileid:$iGuruProfile;reason:he is the one"],
|
||||
];
|
||||
$iLogin = $this->CreateObject('UserLocal', $aData);
|
||||
|
||||
////////////////////////////////////////
|
||||
// User login having all std profiles
|
||||
//
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'org_id' => self::FindId('Organization'),
|
||||
'location_id' => self::FindId('Location'),
|
||||
'first_name' => 'Little ze',
|
||||
'name' => 'Foo',
|
||||
'email' => 'foo@combodo.com',
|
||||
);
|
||||
];
|
||||
$iPerson = $this->CreateObject('Person', $aData);
|
||||
|
||||
$aProfileSet = array();
|
||||
foreach($aStdProfiles as $iProfileId)
|
||||
{
|
||||
$aProfileSet = [];
|
||||
foreach ($aStdProfiles as $iProfileId) {
|
||||
$aProfileSet[] = "profileid:$iProfileId;reason:xxx";
|
||||
}
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'contactid' => $iPerson,
|
||||
'login' => 'foo',
|
||||
'password' => 'foo',
|
||||
'language' => 'EN US',
|
||||
'profile_list' => $aProfileSet,
|
||||
);
|
||||
];
|
||||
$iLogin = $this->CreateObject('UserLocal', $aData);
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
// Organizations
|
||||
//
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'name' => 'Benchmark',
|
||||
);
|
||||
];
|
||||
$iOrg = $this->CreateObject('Organization', $aData);
|
||||
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
// Locations
|
||||
//
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'name' => 'Rio de Janeiro',
|
||||
);
|
||||
];
|
||||
$iLoc = $this->CreateObject('Location', $aData);
|
||||
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
// Teams
|
||||
//
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'location_id' => $iLoc,
|
||||
'name' => 'Fluminense',
|
||||
'email' => 'fluminense@combodo.com',
|
||||
);
|
||||
];
|
||||
$iTeam = $this->CreateObject('Team', $aData);
|
||||
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
// Persons
|
||||
//
|
||||
for($i = 0 ; $i < $this->m_aPlanned['Contacts'] ; $i++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($i = 0 ; $i < $this->m_aPlanned['Contacts'] ; $i++) {
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'location_id' => $iLoc,
|
||||
'first_name' => 'Joaõ',
|
||||
'name' => 'Ningem #'.$i,
|
||||
'email' => 'foo'.$i.'@nowhere.fr',
|
||||
);
|
||||
];
|
||||
$iPerson = $this->CreateObject('Person', $aData);
|
||||
|
||||
// Contract/Infra
|
||||
//
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'contact_id' => $iPerson,
|
||||
'team_id' => $this->RandomId('Team'),
|
||||
);
|
||||
];
|
||||
$this->CreateObject('lnkTeamToContact', $aData);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
// Services
|
||||
//
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'name' => 'My Service',
|
||||
);
|
||||
];
|
||||
$iService = $this->CreateObject('Service', $aData);
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
// Service subcategories
|
||||
//
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'name' => 'My subcategory',
|
||||
'service_id' => $iService,
|
||||
);
|
||||
];
|
||||
$iOrg = $this->CreateObject('ServiceSubcategory', $aData);
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
// Contracts
|
||||
//
|
||||
for($i = 0 ; $i < $this->m_aPlanned['Contracts'] ; $i++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($i = 0 ; $i < $this->m_aPlanned['Contracts'] ; $i++) {
|
||||
$aData = [
|
||||
'name' => "Contract #$i",
|
||||
'description' => 'Created for benchmarking purposes',
|
||||
'org_id' => $this->RandomId('Organization'),
|
||||
@@ -412,19 +391,18 @@ class BenchmarkDataCreation
|
||||
'start_date' => '2009-12-25',
|
||||
'end_date' => '2019-08-01',
|
||||
'support_team_id' => $this->RandomId('Team'),
|
||||
);
|
||||
];
|
||||
$iContract = $this->CreateObject('CustomerContract', $aData);
|
||||
|
||||
// Contract/Contact (10% of contacts)
|
||||
//
|
||||
$iContactCount = ceil($this->m_aPlanned['Contracts'] / 10);
|
||||
for($iLinked = 0 ; $iLinked < $iContactCount ; $iLinked++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($iLinked = 0 ; $iLinked < $iContactCount ; $iLinked++) {
|
||||
$aData = [
|
||||
'contact_id' => $this->RandomId('Person'),
|
||||
'contract_id' => $iContract,
|
||||
'role' => 'role '.$iLinked,
|
||||
);
|
||||
];
|
||||
$this->CreateObject('lnkContractToContact', $aData);
|
||||
}
|
||||
}
|
||||
@@ -434,20 +412,18 @@ class BenchmarkDataCreation
|
||||
// Documents
|
||||
//
|
||||
$sMyDoc = '';
|
||||
for($i = 0 ; $i < 1000 ; $i++)
|
||||
{
|
||||
for ($i = 0 ; $i < 1000 ; $i++) {
|
||||
// 100 chars
|
||||
$sMyDoc .= "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678\n";
|
||||
}
|
||||
$oRefDoc = new ormDocument($sMyDoc, 'text/plain');
|
||||
|
||||
for($i = 0 ; $i < $this->m_aPlanned['Documents'] ; $i++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($i = 0 ; $i < $this->m_aPlanned['Documents'] ; $i++) {
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'name' => "document$i",
|
||||
'contents' => $oRefDoc,
|
||||
);
|
||||
];
|
||||
$this->CreateObject('FileDoc', $aData);
|
||||
}
|
||||
}
|
||||
@@ -461,29 +437,27 @@ class BenchmarkDataCreation
|
||||
//
|
||||
// Servers
|
||||
//
|
||||
for($i = 0 ; $i < $this->m_aPlanned['Servers'] ; $i++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($i = 0 ; $i < $this->m_aPlanned['Servers'] ; $i++) {
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'location_id' => $iLoc,
|
||||
'name' => 'server'.$i,
|
||||
'status' => 'production',
|
||||
);
|
||||
];
|
||||
$iServer = $this->CreateObject('Server', $aData);
|
||||
|
||||
// Contract/Infra
|
||||
$this->CreateLinks($iServer, 1, 'lnkContractToCI', 'ci_id', 'contract_id');
|
||||
|
||||
// Interfaces
|
||||
for($iLinked = 0 ; $iLinked < $this->m_iIfByServer ; $iLinked++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($iLinked = 0 ; $iLinked < $this->m_iIfByServer ; $iLinked++) {
|
||||
$aData = [
|
||||
'name' => "eth$iLinked",
|
||||
'status' => 'implementation',
|
||||
'org_id' => $iOrg,
|
||||
'device_id' => $iServer,
|
||||
'status' => 'production',
|
||||
);
|
||||
];
|
||||
$this->CreateObject('NetworkInterface', $aData, 'server if');
|
||||
}
|
||||
}
|
||||
@@ -492,14 +466,13 @@ class BenchmarkDataCreation
|
||||
//
|
||||
// Network devices
|
||||
//
|
||||
for($i = 0 ; $i < $this->m_aPlanned['Network devices'] ; $i++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($i = 0 ; $i < $this->m_aPlanned['Network devices'] ; $i++) {
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'location_id' => $iLoc,
|
||||
'name' => 'equipment #'.$i,
|
||||
'status' => 'production',
|
||||
);
|
||||
];
|
||||
$iNWDevice = $this->CreateObject('NetworkDevice', $aData);
|
||||
|
||||
// Contract/Infra
|
||||
@@ -507,16 +480,15 @@ class BenchmarkDataCreation
|
||||
|
||||
// Interfaces
|
||||
//
|
||||
for($iLinked = 0 ; $iLinked < $this->m_iIfByNWDevice ; $iLinked++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($iLinked = 0 ; $iLinked < $this->m_iIfByNWDevice ; $iLinked++) {
|
||||
$aData = [
|
||||
'name' => "eth$iLinked",
|
||||
'status' => 'implementation',
|
||||
'org_id' => $iOrg,
|
||||
'device_id' => $iNWDevice,
|
||||
'connected_if' => $this->RandomId('NetworkInterface', 'server if'),
|
||||
'status' => 'production',
|
||||
);
|
||||
];
|
||||
$this->CreateObject('NetworkInterface', $aData, 'equipment if');
|
||||
}
|
||||
}
|
||||
@@ -525,11 +497,10 @@ class BenchmarkDataCreation
|
||||
//
|
||||
// Application Software
|
||||
//
|
||||
for($i = 0 ; $i < $this->m_aPlanned['Application SW'] ; $i++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($i = 0 ; $i < $this->m_aPlanned['Application SW'] ; $i++) {
|
||||
$aData = [
|
||||
'name' => 'Software #'.$i,
|
||||
);
|
||||
];
|
||||
$iNWDevice = $this->CreateObject('Application', $aData);
|
||||
}
|
||||
|
||||
@@ -537,15 +508,14 @@ class BenchmarkDataCreation
|
||||
//
|
||||
// Applications
|
||||
//
|
||||
for($i = 0 ; $i < $this->m_aPlanned['Applications'] ; $i++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($i = 0 ; $i < $this->m_aPlanned['Applications'] ; $i++) {
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'device_id' => $this->RandomId('Server'),
|
||||
'software_id' => $this->RandomId('Application'),
|
||||
'name' => 'Application #'.$i,
|
||||
'status' => 'production',
|
||||
);
|
||||
];
|
||||
$iAppInstance = $this->CreateObject('ApplicationInstance', $aData);
|
||||
|
||||
// Contract/Infra
|
||||
@@ -556,13 +526,12 @@ class BenchmarkDataCreation
|
||||
//
|
||||
// Application Solution
|
||||
//
|
||||
for($i = 0 ; $i < $this->m_aPlanned['Solutions'] ; $i++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($i = 0 ; $i < $this->m_aPlanned['Solutions'] ; $i++) {
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'name' => 'Solution #'.$i,
|
||||
'status' => 'production',
|
||||
);
|
||||
];
|
||||
$iAppSolution = $this->CreateObject('ApplicationSolution', $aData);
|
||||
|
||||
// Contract/Infra
|
||||
@@ -573,13 +542,12 @@ class BenchmarkDataCreation
|
||||
//
|
||||
// Business Process
|
||||
//
|
||||
for($i = 0 ; $i < $this->m_aPlanned['Processes'] ; $i++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($i = 0 ; $i < $this->m_aPlanned['Processes'] ; $i++) {
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'name' => 'Process #'.$i,
|
||||
'status' => 'production',
|
||||
);
|
||||
];
|
||||
$iProcess = $this->CreateObject('BusinessProcess', $aData);
|
||||
|
||||
// Contract/Infra
|
||||
@@ -596,9 +564,8 @@ class BenchmarkDataCreation
|
||||
//
|
||||
// Incident Tickets
|
||||
//
|
||||
for($i = 0 ; $i < $this->m_aPlanned['Incidents'] ; $i++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($i = 0 ; $i < $this->m_aPlanned['Incidents'] ; $i++) {
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'caller_id' => $this->RandomId('Person'),
|
||||
'workgroup_id' => $this->RandomId('Team'),
|
||||
@@ -608,7 +575,7 @@ class BenchmarkDataCreation
|
||||
'title' => 'Incident #'.$i,
|
||||
'description' => 'O que aconteceu?',
|
||||
'ticket_log' => 'Testing...',
|
||||
);
|
||||
];
|
||||
$iTicket = $this->CreateObject('Incident', $aData);
|
||||
|
||||
// Incident/Infra
|
||||
@@ -624,7 +591,7 @@ class BenchmarkDataCreation
|
||||
//
|
||||
// Big Ticket
|
||||
//
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'caller_id' => $this->RandomId('Person'),
|
||||
'workgroup_id' => $this->RandomId('Team'),
|
||||
@@ -634,7 +601,7 @@ class BenchmarkDataCreation
|
||||
'title' => 'Big ticket',
|
||||
'description' => 'O que aconteceu?',
|
||||
'ticket_log' => 'Testing...',
|
||||
);
|
||||
];
|
||||
$iTicket = $this->CreateObject('Incident', $aData);
|
||||
|
||||
// Incident/Infra
|
||||
@@ -649,9 +616,8 @@ class BenchmarkDataCreation
|
||||
//
|
||||
// Change Tickets
|
||||
//
|
||||
for($i = 0 ; $i < $this->m_aPlanned['Changes'] ; $i++)
|
||||
{
|
||||
$aData = array(
|
||||
for ($i = 0 ; $i < $this->m_aPlanned['Changes'] ; $i++) {
|
||||
$aData = [
|
||||
'org_id' => $iOrg,
|
||||
'requestor_id' => $this->RandomId('Person'),
|
||||
'workgroup_id' => $this->RandomId('Team'),
|
||||
@@ -662,13 +628,13 @@ class BenchmarkDataCreation
|
||||
'manager_id' => $this->RandomId('Person'),
|
||||
'title' => 'change #'.$i,
|
||||
'description' => "Let's do something there",
|
||||
);
|
||||
];
|
||||
$iTicket = $this->CreateObject('NormalChange', $aData);
|
||||
|
||||
// Incident/Infra
|
||||
$iInfraCount = rand(1, 6);
|
||||
$this->CreateLinks($iTicket, $iInfraCount, 'lnkTicketToCI', 'ticket_id', 'ci_id');
|
||||
|
||||
|
||||
// Incident/Infra
|
||||
$iContactCount = rand(1, 6);
|
||||
$this->CreateLinks($iTicket, $iContactCount, 'lnkTicketToContact', 'ticket_id', 'contact_id');
|
||||
@@ -677,16 +643,15 @@ class BenchmarkDataCreation
|
||||
|
||||
public function MakeFeedback($oP)
|
||||
{
|
||||
foreach($this->m_aCreatedByClass as $sClass => $aClassIds)
|
||||
{
|
||||
foreach ($this->m_aCreatedByClass as $sClass => $aClassIds) {
|
||||
$iSample = reset($aClassIds);
|
||||
$sSample = "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=details&class=$sClass&id=$iSample\">sample</a>";
|
||||
|
||||
|
||||
$iDuration = number_format(array_sum($this->m_aStatsByClass[$sClass]), 3);
|
||||
$fDurationMin = number_format(min($this->m_aStatsByClass[$sClass]), 3);
|
||||
$fDurationMax = number_format(max($this->m_aStatsByClass[$sClass]), 3);
|
||||
$fDurationAverage = number_format(array_sum($this->m_aStatsByClass[$sClass]) / count($this->m_aStatsByClass[$sClass]), 3);
|
||||
|
||||
|
||||
$oP->add("<ul>");
|
||||
$oP->add("<li>");
|
||||
$oP->add("$sClass: ".count($this->m_aStatsByClass[$sClass])." - $sSample<br/>");
|
||||
@@ -699,7 +664,7 @@ class BenchmarkDataCreation
|
||||
|
||||
/**
|
||||
* Ask the user what are the settings for the data load
|
||||
*/
|
||||
*/
|
||||
function DisplayStep1(SetupPage $oP)
|
||||
{
|
||||
$sNextOperation = 'step2';
|
||||
@@ -707,17 +672,17 @@ function DisplayStep1(SetupPage $oP)
|
||||
|
||||
$oP->add("<form method=\"post\" onSubmit=\"return DoSubmit('Evaluating real plans...', 10)\">\n");
|
||||
$oP->add("<fieldset><legend>Data load configuration</legend>\n");
|
||||
$aForm = array();
|
||||
$aForm[] = array(
|
||||
$aForm = [];
|
||||
$aForm[] = [
|
||||
'label' => "Contacts:",
|
||||
'input' => "<input id=\"from\" type=\"text\" name=\"plannedcontacts\" value=\"100\">",
|
||||
'help' => '',
|
||||
);
|
||||
$aForm[] = array(
|
||||
];
|
||||
$aForm[] = [
|
||||
'label' => "Contracts:",
|
||||
'input' => "<input id=\"from\" type=\"text\" name=\"plannedcontracts\" value=\"10\">",
|
||||
'help' => '',
|
||||
);
|
||||
];
|
||||
$oP->form($aForm);
|
||||
$oP->add("</fieldset>\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"operation\" value=\"create_structure\">\n");
|
||||
@@ -726,12 +691,12 @@ function DisplayStep1(SetupPage $oP)
|
||||
|
||||
$oP->add("<form method=\"post\" onSubmit=\"return DoSubmit('Evaluating real plans...', 10)\">\n");
|
||||
$oP->add("<fieldset><legend>Data load configuration</legend>\n");
|
||||
$aForm = array();
|
||||
$aForm[] = array(
|
||||
$aForm = [];
|
||||
$aForm[] = [
|
||||
'label' => "Main CIs:",
|
||||
'input' => "<input id=\"to\" type=\"text\" name=\"plannedcis\" value=\"70\">",
|
||||
'help' => ' exclude interfaces, subnets or any other type of secondary CI',
|
||||
);
|
||||
];
|
||||
$oP->form($aForm);
|
||||
$oP->add("</fieldset>\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"operation\" value=\"create_cis\">\n");
|
||||
@@ -740,17 +705,17 @@ function DisplayStep1(SetupPage $oP)
|
||||
|
||||
$oP->add("<form method=\"post\" onSubmit=\"return DoSubmit('Evaluating real plans...', 10)\">\n");
|
||||
$oP->add("<fieldset><legend>Data load configuration</legend>\n");
|
||||
$aForm = array();
|
||||
$aForm[] = array(
|
||||
$aForm = [];
|
||||
$aForm[] = [
|
||||
'label' => "Tickets:",
|
||||
'input' => "<input id=\"to\" type=\"text\" name=\"plannedtickets\" value=\"200\">",
|
||||
'help' => ' 50% incidents, 50% changes',
|
||||
);
|
||||
$aForm[] = array(
|
||||
];
|
||||
$aForm[] = [
|
||||
'label' => "CIs for the big ticket:",
|
||||
'input' => "<input id=\"to\" type=\"text\" name=\"plannedbigticketcis\" value=\"200\">",
|
||||
'help' => 'Number of CI for the single big ticket',
|
||||
);
|
||||
];
|
||||
$oP->form($aForm);
|
||||
$oP->add("</fieldset>\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"operation\" value=\"create_tickets\">\n");
|
||||
@@ -758,7 +723,6 @@ function DisplayStep1(SetupPage $oP)
|
||||
$oP->add("</form>\n");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main program
|
||||
*/
|
||||
@@ -771,13 +735,11 @@ $oP = new SetupPage('iTop benchmark utility');
|
||||
ExecutionKPI::EnableDuration();
|
||||
$oKPI = new ExecutionKPI();
|
||||
|
||||
try
|
||||
{
|
||||
switch($sOperation)
|
||||
{
|
||||
try {
|
||||
switch ($sOperation) {
|
||||
case 'step1':
|
||||
DisplayStep1($oP);
|
||||
break;
|
||||
DisplayStep1($oP);
|
||||
break;
|
||||
|
||||
case 'create_structure':
|
||||
$oP->no_cache();
|
||||
@@ -792,71 +754,66 @@ try
|
||||
break;
|
||||
|
||||
case 'create_structure_go':
|
||||
$oP->no_cache();
|
||||
$iPlannedContacts = Utils::ReadParam('plannedcontacts');
|
||||
$iPlannedContracts = Utils::ReadParam('plannedcontracts');
|
||||
$oP->no_cache();
|
||||
$iPlannedContacts = Utils::ReadParam('plannedcontacts');
|
||||
$iPlannedContracts = Utils::ReadParam('plannedcontracts');
|
||||
|
||||
$oDataCreation = new BenchmarkDataCreation();
|
||||
$oDataCreation->PlanStructure($iPlannedContacts, $iPlannedContracts);
|
||||
$oDataCreation->CreateStructure($oP);
|
||||
$oDataCreation->MakeFeedback($oP);
|
||||
break;
|
||||
$oDataCreation = new BenchmarkDataCreation();
|
||||
$oDataCreation->PlanStructure($iPlannedContacts, $iPlannedContracts);
|
||||
$oDataCreation->CreateStructure($oP);
|
||||
$oDataCreation->MakeFeedback($oP);
|
||||
break;
|
||||
|
||||
case 'create_cis':
|
||||
$oP->no_cache();
|
||||
$iPlannedCIs = Utils::ReadParam('plannedcis');
|
||||
$oP->no_cache();
|
||||
$iPlannedCIs = Utils::ReadParam('plannedcis');
|
||||
|
||||
$oDataCreation = new BenchmarkDataCreation();
|
||||
$oDataCreation->PlanCis($iPlannedCIs);
|
||||
$oDataCreation->ShowPlans($oP);
|
||||
$oDataCreation->ShowForm($oP, 'create_cis_go');
|
||||
break;
|
||||
$oDataCreation = new BenchmarkDataCreation();
|
||||
$oDataCreation->PlanCis($iPlannedCIs);
|
||||
$oDataCreation->ShowPlans($oP);
|
||||
$oDataCreation->ShowForm($oP, 'create_cis_go');
|
||||
break;
|
||||
|
||||
case 'create_cis_go':
|
||||
$oP->no_cache();
|
||||
$iPlannedCIs = Utils::ReadParam('plannedcis');
|
||||
$oP->no_cache();
|
||||
$iPlannedCIs = Utils::ReadParam('plannedcis');
|
||||
|
||||
$oDataCreation = new BenchmarkDataCreation();
|
||||
$oDataCreation->PlanCis($iPlannedCIs);
|
||||
$oDataCreation->CreateCis($oP);
|
||||
$oDataCreation->MakeFeedback($oP);
|
||||
break;
|
||||
$oDataCreation = new BenchmarkDataCreation();
|
||||
$oDataCreation->PlanCis($iPlannedCIs);
|
||||
$oDataCreation->CreateCis($oP);
|
||||
$oDataCreation->MakeFeedback($oP);
|
||||
break;
|
||||
|
||||
case 'create_tickets':
|
||||
$oP->no_cache();
|
||||
$iPlannedTickets = Utils::ReadParam('plannedtickets');
|
||||
$iBigTicketCis = Utils::ReadParam('plannedbigticketcis');
|
||||
$oP->no_cache();
|
||||
$iPlannedTickets = Utils::ReadParam('plannedtickets');
|
||||
$iBigTicketCis = Utils::ReadParam('plannedbigticketcis');
|
||||
|
||||
$oDataCreation = new BenchmarkDataCreation();
|
||||
$oDataCreation->PlanTickets($iPlannedTickets, $iBigTicketCis);
|
||||
$oDataCreation->ShowPlans($oP);
|
||||
$oDataCreation->ShowForm($oP, 'create_tickets_go');
|
||||
break;
|
||||
$oDataCreation = new BenchmarkDataCreation();
|
||||
$oDataCreation->PlanTickets($iPlannedTickets, $iBigTicketCis);
|
||||
$oDataCreation->ShowPlans($oP);
|
||||
$oDataCreation->ShowForm($oP, 'create_tickets_go');
|
||||
break;
|
||||
|
||||
case 'create_tickets_go':
|
||||
$oP->no_cache();
|
||||
$iPlannedTickets = Utils::ReadParam('plannedtickets');
|
||||
$iBigTicketCis = Utils::ReadParam('plannedbigticketcis');
|
||||
$oP->no_cache();
|
||||
$iPlannedTickets = Utils::ReadParam('plannedtickets');
|
||||
$iBigTicketCis = Utils::ReadParam('plannedbigticketcis');
|
||||
|
||||
$oDataCreation = new BenchmarkDataCreation();
|
||||
$oDataCreation->PlanTickets($iPlannedTickets, $iBigTicketCis);
|
||||
$oDataCreation->CreateTickets($oP);
|
||||
$oDataCreation->MakeFeedback($oP);
|
||||
break;
|
||||
$oDataCreation = new BenchmarkDataCreation();
|
||||
$oDataCreation->PlanTickets($iPlannedTickets, $iBigTicketCis);
|
||||
$oDataCreation->CreateTickets($oP);
|
||||
$oDataCreation->MakeFeedback($oP);
|
||||
break;
|
||||
|
||||
default:
|
||||
$oP->error("Error: unsupported operation '$sOperation'");
|
||||
$oP->error("Error: unsupported operation '$sOperation'");
|
||||
}
|
||||
}
|
||||
catch(ZZException $e)
|
||||
{
|
||||
$oP->error("Error: '".$e->getMessage()."'");
|
||||
}
|
||||
catch(ZZCoreException $e)
|
||||
{
|
||||
$oP->error("Error: '".$e->getHtmlDesc()."'");
|
||||
} catch (ZZException $e) {
|
||||
$oP->error("Error: '".$e->getMessage()."'");
|
||||
} catch (ZZCoreException $e) {
|
||||
$oP->error("Error: '".$e->getHtmlDesc()."'");
|
||||
}
|
||||
$oKPI->ComputeAndReport('Total execution');
|
||||
//DBSearch::RecordQueryTrace();
|
||||
$oP->output();
|
||||
?>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
// Copyright (c) 2010-2024 Combodo SAS
|
||||
//
|
||||
// This file is part of iTop.
|
||||
@@ -21,7 +22,6 @@
|
||||
* Date: 06/10/2017
|
||||
*/
|
||||
|
||||
|
||||
require_once('../../../approot.inc.php');
|
||||
require_once(APPROOT.'application/startup.inc.php');
|
||||
|
||||
@@ -34,7 +34,7 @@ $oTestHandle = @fopen($sTestFile, "w");
|
||||
|
||||
@fwrite($oTestHandle, "<?php\n\n");
|
||||
|
||||
$aFoundOQLs = array();
|
||||
$aFoundOQLs = [];
|
||||
$iCount = 0;
|
||||
$iRead = 0;
|
||||
|
||||
@@ -47,7 +47,9 @@ if ($oOQLHandle) {
|
||||
$sOQL = $aRecord['oql'];
|
||||
|
||||
$sChecksum = md5($sBuffer);
|
||||
if (isset($aFoundOQLs[$sChecksum])) { continue; }
|
||||
if (isset($aFoundOQLs[$sChecksum])) {
|
||||
continue;
|
||||
}
|
||||
$aFoundOQLs[$sChecksum] = true;
|
||||
|
||||
$iCount++;
|
||||
@@ -72,10 +74,8 @@ if ($oOQLHandle) {
|
||||
|
||||
echo "File '$sTestFile' generated with $iCount entries (from $iRead captured OQL).\n";
|
||||
|
||||
|
||||
/// Group by
|
||||
|
||||
|
||||
$sOQLFile = APPROOT.'log/oql_group_by_records.txt';
|
||||
$sTestFile = APPROOT.'tests/core/oql_group_by_records.php';
|
||||
|
||||
@@ -83,7 +83,7 @@ $oTestHandle = @fopen($sTestFile, "w");
|
||||
|
||||
@fwrite($oTestHandle, "<?php\n\n");
|
||||
|
||||
$aFoundOQLs = array();
|
||||
$aFoundOQLs = [];
|
||||
$iCount = 1000;
|
||||
$iRead = 0;
|
||||
|
||||
@@ -96,19 +96,18 @@ if ($oOQLHandle) {
|
||||
$sOQL = $aRecord['oql'];
|
||||
|
||||
$sChecksum = md5($sBuffer);
|
||||
if (isset($aFoundOQLs[$sChecksum])) { continue; }
|
||||
if (isset($aFoundOQLs[$sChecksum])) {
|
||||
continue;
|
||||
}
|
||||
$aFoundOQLs[$sChecksum] = true;
|
||||
|
||||
$iCount++;
|
||||
$sOrderBy = ConvertArray($aRecord['order_by']);
|
||||
$sGroupByExpr = ConvertArray($aRecord['group_by_expr']);
|
||||
$sSelectExpr = ConvertArray($aRecord['select_expr']);
|
||||
if ($aRecord['exclude_null_values'])
|
||||
{
|
||||
if ($aRecord['exclude_null_values']) {
|
||||
$bExcludeNullValues = 'true';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$bExcludeNullValues = 'false';
|
||||
}
|
||||
$iLimitCount = $aRecord['limit_count'];
|
||||
@@ -128,19 +127,17 @@ if ($oOQLHandle) {
|
||||
|
||||
@fclose($oTestHandle);
|
||||
|
||||
echo "<br>File '$sTestFile' generated with ".($iCount-1000)." entries (from $iRead captured OQL).\n";
|
||||
echo "<br>File '$sTestFile' generated with ".($iCount - 1000)." entries (from $iRead captured OQL).\n";
|
||||
|
||||
function ConvertArray($aArray)
|
||||
{
|
||||
if (is_null($aArray))
|
||||
{
|
||||
if (is_null($aArray)) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
if (empty($aArray))
|
||||
{
|
||||
if (empty($aArray)) {
|
||||
return 'array()';
|
||||
}
|
||||
|
||||
return 'unserialize(\''.str_replace("'", "\\'",serialize($aArray)).'\')';
|
||||
return 'unserialize(\''.str_replace("'", "\\'", serialize($aArray)).'\')';
|
||||
}
|
||||
|
||||
@@ -8,31 +8,29 @@
|
||||
// The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
|
||||
//
|
||||
|
||||
$MySettings = array(
|
||||
$MySettings = [
|
||||
'db_host' => 'localhost',
|
||||
'db_user' => 'root',
|
||||
'db_pwd' => '',
|
||||
'db_name' => 'TestFarm',
|
||||
'db_subname' => '', // use it to differentiate two applications instances running on the same DB
|
||||
);
|
||||
];
|
||||
|
||||
// Modules: file names should be specified as a absolute paths
|
||||
|
||||
$MyModules = array(
|
||||
'application' => array (
|
||||
$MyModules = [
|
||||
'application' => [
|
||||
// '../core/event.class.inc.php',
|
||||
// '../core/action.class.inc.php',
|
||||
// '../core/trigger.class.inc.php',
|
||||
// to be continued...
|
||||
),
|
||||
'business' => array (
|
||||
],
|
||||
'business' => [
|
||||
'../business/test_farm.class.inc.php',
|
||||
// to be continued...
|
||||
),
|
||||
'addons' => array (
|
||||
],
|
||||
'addons' => [
|
||||
//'user rights' => '/addons/userrights/userrightsnull.class.inc.php', // or userrightsmatrix.class.inc.php
|
||||
// other modules to come later
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
],
|
||||
];
|
||||
|
||||
@@ -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(APPROOT.'data/queries.results.log', date('Y-m-d H:i:s')."\n");
|
||||
file_put_contents(APPROOT.'data/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(APPROOT.'data/queries.results.log', date('Y-m-d H:i:s')."\n");
|
||||
file_put_contents(APPROOT.'data/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();
|
||||
?>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?php
|
||||
|
||||
// Copyright (C) 2010-2024 Combodo SAS
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
@@ -23,7 +24,6 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
require_once(APPROOT.'/core/attributedef.class.inc.php');
|
||||
require_once(APPROOT.'/core/filterdef.class.inc.php');
|
||||
require_once(APPROOT.'/core/stimulus.class.inc.php');
|
||||
@@ -48,11 +48,10 @@ require_once(APPROOT.'/core/userrights.class.inc.php');
|
||||
|
||||
require_once(APPROOT.'/webservices/webservices.class.inc.php');
|
||||
|
||||
|
||||
// Just to differentiate programmatically triggered exceptions and other kind of errors (usefull?)
|
||||
class UnitTestException extends Exception
|
||||
{}
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Improved display of the backtrace
|
||||
@@ -69,7 +68,6 @@ class ExceptionFromError extends Exception
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test handler API and basic helpers
|
||||
*
|
||||
@@ -84,21 +82,33 @@ abstract class TestHandler
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->m_aSuccesses = array();
|
||||
$this->m_aWarnings = array();
|
||||
$this->m_aErrors = array();
|
||||
$this->m_aSuccesses = [];
|
||||
$this->m_aWarnings = [];
|
||||
$this->m_aErrors = [];
|
||||
}
|
||||
|
||||
static public function GetName() {return "fooname";}
|
||||
static public function GetDescription(){return "foodesc";}
|
||||
public static function GetName()
|
||||
{
|
||||
return "fooname";
|
||||
}
|
||||
public static function GetDescription()
|
||||
{
|
||||
return "foodesc";
|
||||
}
|
||||
|
||||
protected function DoPrepare() {return true;}
|
||||
protected function DoPrepare()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
abstract protected function DoExecute();
|
||||
protected function DoCleanup() {return true;}
|
||||
protected function DoCleanup()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static function DumpVariable($var)
|
||||
{
|
||||
echo "<pre class=\"vardump\">\n";
|
||||
echo "<pre class=\"vardump\">\n";
|
||||
print_r($var);
|
||||
echo "</pre>\n";
|
||||
}
|
||||
@@ -142,24 +152,25 @@ abstract class TestHandler
|
||||
{
|
||||
// Note: return false to call the default handler (stop the program if an error)
|
||||
|
||||
if ($errstr == 'assert()') $errno = E_USER_ERROR;
|
||||
if ($errstr == 'assert()') {
|
||||
$errno = E_USER_ERROR;
|
||||
}
|
||||
|
||||
switch ($errno)
|
||||
{
|
||||
case E_USER_ERROR:
|
||||
case E_WARNING: //(assertion failed)
|
||||
$this->ReportError("$errfile@$errline - $errstr");
|
||||
break;
|
||||
case E_USER_WARNING:
|
||||
$this->ReportWarning("$errfile@$errline - $errstr");
|
||||
break;
|
||||
case E_USER_NOTICE:
|
||||
$this->ReportWarning("$errfile@$errline - $errstr");
|
||||
break;
|
||||
default:
|
||||
$this->ReportWarning("$errfile@$errline - Unknown error type: [$errno] $errstr");
|
||||
echo "Unknown error type: [$errno] $errstr in $errfile at $errline<br />\n";
|
||||
break;
|
||||
switch ($errno) {
|
||||
case E_USER_ERROR:
|
||||
case E_WARNING: //(assertion failed)
|
||||
$this->ReportError("$errfile@$errline - $errstr");
|
||||
break;
|
||||
case E_USER_WARNING:
|
||||
$this->ReportWarning("$errfile@$errline - $errstr");
|
||||
break;
|
||||
case E_USER_NOTICE:
|
||||
$this->ReportWarning("$errfile@$errline - $errstr");
|
||||
break;
|
||||
default:
|
||||
$this->ReportWarning("$errfile@$errline - Unknown error type: [$errno] $errstr");
|
||||
echo "Unknown error type: [$errno] $errstr in $errfile at $errline<br />\n";
|
||||
break;
|
||||
}
|
||||
return true; // do not call the default handler
|
||||
}
|
||||
@@ -167,24 +178,17 @@ abstract class TestHandler
|
||||
public function Execute()
|
||||
{
|
||||
ob_start();
|
||||
set_error_handler(array($this, 'error_handler'));
|
||||
try
|
||||
{
|
||||
set_error_handler([$this, 'error_handler']);
|
||||
try {
|
||||
$this->DoPrepare();
|
||||
$this->DoExecute();
|
||||
}
|
||||
catch (ExceptionFromError $e)
|
||||
{
|
||||
} catch (ExceptionFromError $e) {
|
||||
$this->ReportError($e->getMessage().' - '.$e->getTraceAsHtml());
|
||||
}
|
||||
catch (CoreException $e)
|
||||
{
|
||||
} catch (CoreException $e) {
|
||||
//$this->ReportError($e->getMessage());
|
||||
//$this->ReportError($e->__tostring());
|
||||
$this->ReportError($e->getMessage().' - '.$e->getTraceAsHtml());
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
//$this->ReportError($e->getMessage());
|
||||
//$this->ReportError($e->__tostring());
|
||||
$this->ReportError('class '.get_class($e).' --- '.$e->getMessage().' - '.$e->getTraceAsString());
|
||||
@@ -194,10 +198,10 @@ abstract class TestHandler
|
||||
return (count($this->GetErrors()) == 0);
|
||||
}
|
||||
|
||||
static protected function DoPostRequestAuth($sRelativeUrl, $aData, $sLogin = 'admin', $sPassword = 'admin', $sOptionnalHeaders = null)
|
||||
protected static function DoPostRequestAuth($sRelativeUrl, $aData, $sLogin = 'admin', $sPassword = 'admin', $sOptionnalHeaders = null)
|
||||
{
|
||||
$aDataAndAuth = $aData;
|
||||
// To be changed to use basic authentication
|
||||
// To be changed to use basic authentication
|
||||
$aDataAndAuth['operation'] = 'login';
|
||||
$aDataAndAuth['auth_user'] = $sLogin;
|
||||
$aDataAndAuth['auth_pwd'] = $sPassword;
|
||||
@@ -212,50 +216,41 @@ abstract class TestHandler
|
||||
// Source: http://netevil.org/blog/2006/nov/http-post-from-php-without-curl
|
||||
// originaly named after do_post_request
|
||||
// Partially adapted to our coding conventions
|
||||
static protected function DoPostRequest($sUrl, $aData, $sOptionnalHeaders = null)
|
||||
protected static function DoPostRequest($sUrl, $aData, $sOptionnalHeaders = null)
|
||||
{
|
||||
// $sOptionnalHeaders is a string containing additional HTTP headers that you would like to send in your request.
|
||||
|
||||
$sData = http_build_query($aData);
|
||||
|
||||
$aParams = array('http' => array(
|
||||
$aParams = ['http' => [
|
||||
'method' => 'POST',
|
||||
'content' => $sData,
|
||||
'header'=> "Content-type: application/x-www-form-urlencoded\r\nContent-Length: ".strlen($sData)."\r\n",
|
||||
));
|
||||
if ($sOptionnalHeaders !== null)
|
||||
{
|
||||
'header' => "Content-type: application/x-www-form-urlencoded\r\nContent-Length: ".strlen($sData)."\r\n",
|
||||
]];
|
||||
if ($sOptionnalHeaders !== null) {
|
||||
$aParams['http']['header'] .= $sOptionnalHeaders;
|
||||
}
|
||||
$ctx = stream_context_create($aParams);
|
||||
|
||||
$fp = @fopen($sUrl, 'rb', false, $ctx);
|
||||
if (!$fp)
|
||||
{
|
||||
if (!$fp) {
|
||||
global $php_errormsg;
|
||||
if (isset($php_errormsg))
|
||||
{
|
||||
if (isset($php_errormsg)) {
|
||||
throw new Exception("Problem with $sUrl, $php_errormsg");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
throw new Exception("Problem with $sUrl");
|
||||
}
|
||||
}
|
||||
$response = @stream_get_contents($fp);
|
||||
if ($response === false)
|
||||
{
|
||||
if ($response === false) {
|
||||
throw new Exception("Problem reading data from $sUrl, $php_errormsg");
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test to execute a piece of code (checks if an error occurs)
|
||||
* Test to execute a piece of code (checks if an error occurs)
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
@@ -264,9 +259,8 @@ abstract class TestFunction extends TestHandler
|
||||
// simply overload DoExecute (temporary)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to execute a piece of code (checks if an error occurs)
|
||||
* Test to execute a piece of code (checks if an error occurs)
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
@@ -275,7 +269,7 @@ abstract class TestWebServices extends TestHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to execute a piece of code (checks if an error occurs)
|
||||
* Test to execute a piece of code (checks if an error occurs)
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
@@ -283,60 +277,52 @@ abstract class TestSoapWebService extends TestHandler
|
||||
{
|
||||
// simply overload DoExecute (temporary)
|
||||
|
||||
function __construct()
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to check that a function outputs some values depending on its input
|
||||
* Test to check that a function outputs some values depending on its input
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class TestFunctionInOut extends TestFunction
|
||||
{
|
||||
// abstract static public function GetCallSpec(); // parameters to call_user_func
|
||||
// abstract static public function GetInOut(); // array of input => output
|
||||
// abstract static public function GetCallSpec(); // parameters to call_user_func
|
||||
// abstract static public function GetInOut(); // array of input => output
|
||||
|
||||
protected function DoExecute()
|
||||
{
|
||||
$aTests = $this->GetInOut();
|
||||
if (is_array($aTests))
|
||||
{
|
||||
foreach ($aTests as $iTestId => $aTest)
|
||||
{
|
||||
if (is_array($aTests)) {
|
||||
foreach ($aTests as $iTestId => $aTest) {
|
||||
$ret = call_user_func_array($this->GetCallSpec(), $aTest['args']);
|
||||
if ($ret != $aTest['output'])
|
||||
{
|
||||
if ($ret != $aTest['output']) {
|
||||
// Note: to be improved to cope with non string parameters
|
||||
$this->ReportError("Found '$ret' while expecting '".$aTest['output']."'", $iTestId);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->ReportSuccess("Found the expected output '$ret'", $iTestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$ret = call_user_func($this->GetCallSpec());
|
||||
$this->ReportSuccess('Finished successfully');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to check an URL (Searches for Error/Warning/Etc keywords)
|
||||
* Test to check an URL (Searches for Error/Warning/Etc keywords)
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class TestUrl extends TestHandler
|
||||
{
|
||||
// abstract static public function GetUrl();
|
||||
// abstract static public function GetErrorKeywords();
|
||||
// abstract static public function GetWarningKeywords();
|
||||
// abstract static public function GetUrl();
|
||||
// abstract static public function GetErrorKeywords();
|
||||
// abstract static public function GetWarningKeywords();
|
||||
|
||||
protected function DoExecute()
|
||||
{
|
||||
@@ -344,9 +330,8 @@ abstract class TestUrl extends TestHandler
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to check a user management module
|
||||
* Test to check a user management module
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
@@ -358,7 +343,6 @@ abstract class TestUserRights extends TestHandler
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to execute a scenario on a given DB
|
||||
*
|
||||
@@ -366,10 +350,10 @@ abstract class TestUserRights extends TestHandler
|
||||
*/
|
||||
abstract class TestScenarioOnDB extends TestHandler
|
||||
{
|
||||
// abstract static public function GetDBHost();
|
||||
// abstract static public function GetDBUser();
|
||||
// abstract static public function GetDBPwd();
|
||||
// abstract static public function GetDBName();
|
||||
// abstract static public function GetDBHost();
|
||||
// abstract static public function GetDBUser();
|
||||
// abstract static public function GetDBPwd();
|
||||
// abstract static public function GetDBName();
|
||||
|
||||
protected function DoPrepare()
|
||||
{
|
||||
@@ -380,8 +364,7 @@ abstract class TestScenarioOnDB extends TestHandler
|
||||
|
||||
CMDBSource::Init($sDBHost, $sDBUser, $sDBPwd);
|
||||
CMDBSource::SetCharacterSet();
|
||||
if (CMDBSource::IsDB($sDBName))
|
||||
{
|
||||
if (CMDBSource::IsDB($sDBName)) {
|
||||
CMDBSource::DropDB($sDBName);
|
||||
}
|
||||
CMDBSource::CreateDB($sDBName);
|
||||
@@ -393,26 +376,28 @@ abstract class TestScenarioOnDB extends TestHandler
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to use a business model on a given DB
|
||||
* Test to use a business model on a given DB
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class TestBizModel extends TestHandler
|
||||
{
|
||||
// abstract static public function GetDBSubName();
|
||||
// abstract static public function GetBusinessModelFile();
|
||||
// abstract static public function GetConfigFile();
|
||||
// abstract static public function GetDBSubName();
|
||||
// abstract static public function GetBusinessModelFile();
|
||||
// abstract static public function GetConfigFile();
|
||||
|
||||
static public function GetConfigFile() {return 'conf/production/config-itop.php';}
|
||||
public static function GetConfigFile()
|
||||
{
|
||||
return 'conf/production/config-itop.php';
|
||||
}
|
||||
|
||||
protected function DoPrepare()
|
||||
{
|
||||
$sConfigFile = APPROOT.$this->GetConfigFile();
|
||||
MetaModel::Startup($sConfigFile);
|
||||
// #@# Temporary disabled by Romain
|
||||
// MetaModel::CheckDefinitions();
|
||||
// #@# Temporary disabled by Romain
|
||||
// MetaModel::CheckDefinitions();
|
||||
|
||||
// something here to create records... but that's another story
|
||||
}
|
||||
@@ -420,52 +405,45 @@ abstract class TestBizModel extends TestHandler
|
||||
protected $m_oChange;
|
||||
protected function GetCurrentChange()
|
||||
{
|
||||
if (!isset($this->m_oChange))
|
||||
{
|
||||
new CMDBChange();
|
||||
if (!isset($this->m_oChange)) {
|
||||
new CMDBChange();
|
||||
$oMyChange = MetaModel::NewObject("CMDBChange");
|
||||
$oMyChange->Set("date", time());
|
||||
$oMyChange->Set("userinfo", "Someone doing some tests");
|
||||
$iChangeId = $oMyChange->DBInsertNoReload();
|
||||
$this->m_oChange = $oMyChange;
|
||||
$this->m_oChange = $oMyChange;
|
||||
}
|
||||
return $this->m_oChange;
|
||||
}
|
||||
protected function ObjectToDB($oNew, $bReload = false)
|
||||
{
|
||||
if ($bReload)
|
||||
{
|
||||
if ($bReload) {
|
||||
$iId = $oNew->DBInsert();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$iId = $oNew->DBInsertNoReload();
|
||||
}
|
||||
return $iId;
|
||||
}
|
||||
|
||||
protected function UpdateObjectInDB($oObject)
|
||||
protected function UpdateObjectInDB($oObject)
|
||||
{
|
||||
$oObject->DBUpdate();
|
||||
}
|
||||
protected function ResetDB()
|
||||
{
|
||||
if (MetaModel::DBExists(false))
|
||||
{
|
||||
if (MetaModel::DBExists(false)) {
|
||||
MetaModel::DBDrop();
|
||||
}
|
||||
MetaModel::DBCreate();
|
||||
}
|
||||
|
||||
static protected function show_list($oObjectSet)
|
||||
protected static function show_list($oObjectSet)
|
||||
{
|
||||
$oObjectSet->Rewind();
|
||||
$aData = array();
|
||||
while ($oItem = $oObjectSet->Fetch())
|
||||
{
|
||||
$aValues = array();
|
||||
foreach(MetaModel::GetAttributesList(get_class($oItem)) as $sAttCode)
|
||||
{
|
||||
$aData = [];
|
||||
while ($oItem = $oObjectSet->Fetch()) {
|
||||
$aValues = [];
|
||||
foreach (MetaModel::GetAttributesList(get_class($oItem)) as $sAttCode) {
|
||||
$aValues[$sAttCode] = $oItem->GetAsHTML($sAttCode);
|
||||
}
|
||||
//echo $oItem->GetKey()." => ".implode(", ", $aValues)."</br>\n";
|
||||
@@ -474,22 +452,21 @@ abstract class TestBizModel extends TestHandler
|
||||
echo MyHelpers::make_table_from_assoc_array($aData);
|
||||
}
|
||||
|
||||
static protected function search_and_show_list(DBSearch $oMyFilter)
|
||||
protected static function search_and_show_list(DBSearch $oMyFilter)
|
||||
{
|
||||
$oObjSet = new CMDBObjectSet($oMyFilter);
|
||||
echo $oMyFilter->ToOQL()."' - Found ".$oObjSet->Count()." items.</br>\n";
|
||||
self::show_list($oObjSet);
|
||||
}
|
||||
|
||||
static protected function search_and_show_list_from_oql($sOQL)
|
||||
protected static function search_and_show_list_from_oql($sOQL)
|
||||
{
|
||||
echo $sOQL."...<br/>\n";
|
||||
echo $sOQL."...<br/>\n";
|
||||
$oNewFilter = DBObjectSearch::FromOQL($sOQL);
|
||||
self::search_and_show_list($oNewFilter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to execute a scenario common to any business model (tries to build all the possible queries, etc.)
|
||||
*
|
||||
@@ -497,12 +474,12 @@ abstract class TestBizModel extends TestHandler
|
||||
*/
|
||||
abstract class TestBizModelGeneric extends TestBizModel
|
||||
{
|
||||
static public function GetName()
|
||||
public static function GetName()
|
||||
{
|
||||
return 'Full test on a given business model';
|
||||
}
|
||||
|
||||
static public function GetDescription()
|
||||
public static function GetDescription()
|
||||
{
|
||||
return 'Systematic tests: gets each and every existing class and tries every attribute, search filters, etc.';
|
||||
}
|
||||
@@ -511,8 +488,7 @@ abstract class TestBizModelGeneric extends TestBizModel
|
||||
{
|
||||
parent::DoPrepare();
|
||||
|
||||
if (!MetaModel::DBExists(false))
|
||||
{
|
||||
if (!MetaModel::DBExists(false)) {
|
||||
MetaModel::DBCreate();
|
||||
}
|
||||
// something here to create records... but that's another story
|
||||
@@ -520,12 +496,13 @@ abstract class TestBizModelGeneric extends TestBizModel
|
||||
|
||||
protected function DoExecute()
|
||||
{
|
||||
foreach(MetaModel::GetClasses() as $sClassName)
|
||||
{
|
||||
if (MetaModel::HasTable($sClassName)) continue;
|
||||
foreach (MetaModel::GetClasses() as $sClassName) {
|
||||
if (MetaModel::HasTable($sClassName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oNobody = MetaModel::GetObject($sClassName, 123);
|
||||
$oBaby = new $sClassName;
|
||||
$oBaby = new $sClassName();
|
||||
$oFilter = new DBObjectSearch($sClassName);
|
||||
|
||||
// Challenge reversibility of OQL / filter object
|
||||
@@ -533,8 +510,7 @@ abstract class TestBizModelGeneric extends TestBizModel
|
||||
$sExpr1 = $oFilter->ToOQL();
|
||||
$oNewFilter = DBObjectSearch::FromOQL($sExpr1);
|
||||
$sExpr2 = $oNewFilter->ToOQL();
|
||||
if ($sExpr1 != $sExpr2)
|
||||
{
|
||||
if ($sExpr1 != $sExpr2) {
|
||||
$this->ReportError("Found two different OQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
|
||||
}
|
||||
|
||||
@@ -546,6 +522,3 @@ abstract class TestBizModelGeneric extends TestBizModel
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
@@ -33,8 +33,7 @@ line-height:100%;
|
||||
function ReadMandatoryParam($sName)
|
||||
{
|
||||
$value = utils::ReadParam($sName, null);
|
||||
if (is_null($value))
|
||||
{
|
||||
if (is_null($value)) {
|
||||
echo "<p>Missing mandatory argument <b>$sName</b></p>";
|
||||
exit;
|
||||
}
|
||||
@@ -45,12 +44,16 @@ function IsAValidTestClass($sClassName)
|
||||
{
|
||||
// Must be a child of TestHandler
|
||||
//
|
||||
if (!is_subclass_of($sClassName, 'TestHandler')) return false;
|
||||
if (!is_subclass_of($sClassName, 'TestHandler')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Must not be abstract
|
||||
//
|
||||
$oReflectionClass = new ReflectionClass($sClassName);
|
||||
if (!$oReflectionClass->isInstantiable()) return false;
|
||||
if (!$oReflectionClass->isInstantiable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -64,17 +67,13 @@ function GetTestClassLine($sClassName)
|
||||
function DisplayEvents($aEvents, $sTitle)
|
||||
{
|
||||
echo "<h4>$sTitle</h4>\n";
|
||||
if (count($aEvents) > 0)
|
||||
{
|
||||
if (count($aEvents) > 0) {
|
||||
echo "<ul>\n";
|
||||
foreach ($aEvents as $sEvent)
|
||||
{
|
||||
foreach ($aEvents as $sEvent) {
|
||||
echo "<li>$sEvent</li>\n";
|
||||
}
|
||||
echo "</ul>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
echo "<p>none</p>\n";
|
||||
}
|
||||
}
|
||||
@@ -92,36 +91,30 @@ require_once('./testlist.inc.php');
|
||||
|
||||
require_once(APPROOT.'/core/cmdbobject.class.inc.php');
|
||||
|
||||
|
||||
$sTodo = utils::ReadParam("todo", "");
|
||||
if ($sTodo == '')
|
||||
{
|
||||
if ($sTodo == '') {
|
||||
// Show the list of tests
|
||||
//
|
||||
echo "<h3>Existing tests</h3>\n";
|
||||
echo "<ul>\n";
|
||||
foreach (get_declared_classes() as $sClassName)
|
||||
{
|
||||
if (!IsAValidTestClass($sClassName)) continue;
|
||||
|
||||
$sName = call_user_func(array($sClassName, 'GetName'));
|
||||
$sDescription = call_user_func(array($sClassName, 'GetDescription'));
|
||||
foreach (get_declared_classes() as $sClassName) {
|
||||
if (!IsAValidTestClass($sClassName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sName = call_user_func([$sClassName, 'GetName']);
|
||||
$sDescription = call_user_func([$sClassName, 'GetDescription']);
|
||||
echo "<li><a href=\"?todo=exec&testid=$sClassName\">$sName</a> ($sDescription)</li>\n";
|
||||
}
|
||||
echo "</ul>\n";
|
||||
}
|
||||
else if ($sTodo == 'exec')
|
||||
{
|
||||
} elseif ($sTodo == 'exec') {
|
||||
// Execute a test
|
||||
//
|
||||
$sTestClass = ReadMandatoryParam("testid");
|
||||
|
||||
if (!IsAValidTestClass($sTestClass))
|
||||
{
|
||||
if (!IsAValidTestClass($sTestClass)) {
|
||||
echo "<p>Wrong value for testid, expecting a valid class name</p>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oTest = new $sTestClass();
|
||||
$iStartLine = GetTestClassLine($sTestClass);
|
||||
echo "<h3>Testing: ".$oTest->GetName()."</h3>\n";
|
||||
@@ -129,19 +122,16 @@ else if ($sTodo == 'exec')
|
||||
$bRes = $oTest->Execute();
|
||||
}
|
||||
|
||||
/*
|
||||
MyHelpers::var_dump_html($oTest->GetResults());
|
||||
MyHelpers::var_dump_html($oTest->GetWarnings());
|
||||
MyHelpers::var_dump_html($oTest->GetErrors());
|
||||
*/
|
||||
/*
|
||||
MyHelpers::var_dump_html($oTest->GetResults());
|
||||
MyHelpers::var_dump_html($oTest->GetWarnings());
|
||||
MyHelpers::var_dump_html($oTest->GetErrors());
|
||||
*/
|
||||
|
||||
if ($bRes)
|
||||
{
|
||||
if ($bRes) {
|
||||
echo "<p>Success :-)</p>\n";
|
||||
DisplayEvents($oTest->GetResults(), 'Results');
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
echo "<p>Failure :-(</p>\n";
|
||||
}
|
||||
DisplayEvents($oTest->GetErrors(), 'Errors');
|
||||
@@ -153,10 +143,7 @@ MyHelpers::var_dump_html($oTest->GetErrors());
|
||||
echo "<div style=\"border: dashed; background-color:light-grey;\">\n";
|
||||
echo $oTest->GetOutput();
|
||||
echo "</div>\n";
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2010-2024 Combodo SAS
|
||||
*
|
||||
@@ -25,7 +26,6 @@ use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use iTopDesignFormat;
|
||||
use utils;
|
||||
|
||||
|
||||
/**
|
||||
* Class SetupCssIntegrityChecklistTest
|
||||
*/
|
||||
@@ -35,19 +35,19 @@ class SetupCssIntegrityChecklistTest extends ItopTestCase
|
||||
{
|
||||
$sCssFileAbsPath = APPROOT."css/setup.css";
|
||||
|
||||
// First check if the compiled file exists
|
||||
$this->assertTrue(file_exists($sCssFileAbsPath));
|
||||
// First check if the compiled file exists
|
||||
$this->assertTrue(file_exists($sCssFileAbsPath));
|
||||
|
||||
// Then check that it is not empty
|
||||
$sVersionedCssFileContent = file_get_contents($sCssFileAbsPath);
|
||||
$this->assertGreaterThan(0, strlen($sVersionedCssFileContent), "Compiled setup.css file seems empty");
|
||||
// Then check that it is not empty
|
||||
$sVersionedCssFileContent = file_get_contents($sCssFileAbsPath);
|
||||
$this->assertGreaterThan(0, strlen($sVersionedCssFileContent), "Compiled setup.css file seems empty");
|
||||
|
||||
// Then check that the compiled file is up-to-date
|
||||
// Then check that the compiled file is up-to-date
|
||||
$sScssFileRelPath = "css/setup.scss";
|
||||
$sScssFileAbsPath = APPROOT . $sScssFileRelPath;
|
||||
touch($sScssFileAbsPath);
|
||||
utils::GetCSSFromSASS($sScssFileRelPath);
|
||||
$sCompiledCssFileContent = file_get_contents($sCssFileAbsPath);
|
||||
$this->assertSame($sCompiledCssFileContent, $sVersionedCssFileContent, "Compiled setup.css file does not seem up to date as the one compiled just now is different");
|
||||
$sScssFileAbsPath = APPROOT.$sScssFileRelPath;
|
||||
touch($sScssFileAbsPath);
|
||||
utils::GetCSSFromSASS($sScssFileRelPath);
|
||||
$sCompiledCssFileContent = file_get_contents($sCssFileAbsPath);
|
||||
$this->assertSame($sCompiledCssFileContent, $sVersionedCssFileContent, "Compiled setup.css file does not seem up to date as the one compiled just now is different");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use iTopDesignFormat;
|
||||
use PHPUnit\Exception;
|
||||
|
||||
|
||||
/**
|
||||
* Class iTopDesignFormatChecklistTest
|
||||
* Ticket 3053 - Check XML conversion methods
|
||||
@@ -31,19 +30,15 @@ class iTopDesignFormatChecklistTest extends ItopTestCase
|
||||
public function testCurrentVersion_DataModelConversionFunctions()
|
||||
{
|
||||
$aErrors = [];
|
||||
$aDatamodelCurrentVersions = array();
|
||||
$aDatamodelCurrentVersions = [];
|
||||
$aDataModelFiles = $this->GetDataModelFiles(APPROOT.'/datamodels');
|
||||
|
||||
//retrieve current XML version in datamoldels files
|
||||
foreach ($aDataModelFiles as $sDataModelFile)
|
||||
{
|
||||
if (preg_match('/itop_design .* version="([\d\.]*)"/', file_get_contents($sDataModelFile), $aMatches))
|
||||
{
|
||||
foreach ($aDataModelFiles as $sDataModelFile) {
|
||||
if (preg_match('/itop_design .* version="([\d\.]*)"/', file_get_contents($sDataModelFile), $aMatches)) {
|
||||
$sVersion = $aMatches[1];
|
||||
if (!array_key_exists($sVersion, $aDatamodelCurrentVersions))
|
||||
{
|
||||
if (trim($sVersion) === '')
|
||||
{
|
||||
if (!array_key_exists($sVersion, $aDatamodelCurrentVersions)) {
|
||||
if (trim($sVersion) === '') {
|
||||
$aErrors[] = "cannot retrieve itop_design datamodel version in $sDataModelFile:1";
|
||||
continue;
|
||||
}
|
||||
@@ -57,102 +52,99 @@ class iTopDesignFormatChecklistTest extends ItopTestCase
|
||||
$this->assertTrue(is_array($aDatamodelCurrentVersions));
|
||||
|
||||
$sFirstVersion = array_keys(iTopDesignFormat::$aVersions)[0];
|
||||
$sLatestVersion = array_keys(iTopDesignFormat::$aVersions)[count(iTopDesignFormat::$aVersions)-1];
|
||||
foreach ($aDatamodelCurrentVersions as $sCurrentVersion)
|
||||
{
|
||||
try{
|
||||
$sLatestVersion = array_keys(iTopDesignFormat::$aVersions)[count(iTopDesignFormat::$aVersions) - 1];
|
||||
foreach ($aDatamodelCurrentVersions as $sCurrentVersion) {
|
||||
try {
|
||||
//check we have migration function from current version to previous
|
||||
$this->CheckCondition(array_key_exists($sCurrentVersion, iTopDesignFormat::$aVersions), "Missing $sCurrentVersion conversion functions in iTopDesignFormat.");
|
||||
$aCurrentVersionInfo = iTopDesignFormat::$aVersions[$sCurrentVersion];
|
||||
$this->CheckCondition(is_array($aCurrentVersionInfo), "Wrong $sCurrentVersion config in iTopDesignFormat.");
|
||||
$this->CheckCondition(array_key_exists('previous', $aCurrentVersionInfo), "Missing previous for $sCurrentVersion config in iTopDesignFormat.");
|
||||
$this->TestDefinedFunction($aCurrentVersionInfo, 'go_to_next', $sCurrentVersion, ($sCurrentVersion=== $sLatestVersion));
|
||||
$this->TestDefinedFunction($aCurrentVersionInfo, 'go_to_previous', $sCurrentVersion, ($sCurrentVersion==='1.0'));
|
||||
$this->TestDefinedFunction($aCurrentVersionInfo, 'go_to_next', $sCurrentVersion, ($sCurrentVersion === $sLatestVersion));
|
||||
$this->TestDefinedFunction($aCurrentVersionInfo, 'go_to_previous', $sCurrentVersion, ($sCurrentVersion === '1.0'));
|
||||
|
||||
//check we have migration function from N-1 version to current one
|
||||
if (($sCurrentVersion!=='1.0')) {
|
||||
if (($sCurrentVersion !== '1.0')) {
|
||||
$sPreviousVersion = $aCurrentVersionInfo['previous'];
|
||||
$this->CheckCondition(array_key_exists($sPreviousVersion, iTopDesignFormat::$aVersions),
|
||||
"$sCurrentVersion: Missing $sPreviousVersion config in iTopDesignFormat.");
|
||||
$this->CheckCondition(
|
||||
array_key_exists($sPreviousVersion, iTopDesignFormat::$aVersions),
|
||||
"$sCurrentVersion: Missing $sPreviousVersion config in iTopDesignFormat."
|
||||
);
|
||||
$aPreviousVersionInfo = iTopDesignFormat::$aVersions[$sPreviousVersion];
|
||||
$this->CheckCondition(is_array($aPreviousVersionInfo),
|
||||
"$sCurrentVersion: wrong $sPreviousVersion config in iTopDesignFormat.");
|
||||
$this->CheckCondition(array_key_exists('previous', $aPreviousVersionInfo),
|
||||
"$sCurrentVersion: Missing previous for $sPreviousVersion config in iTopDesignFormat.");
|
||||
$this->CheckCondition(
|
||||
is_array($aPreviousVersionInfo),
|
||||
"$sCurrentVersion: wrong $sPreviousVersion config in iTopDesignFormat."
|
||||
);
|
||||
$this->CheckCondition(
|
||||
array_key_exists('previous', $aPreviousVersionInfo),
|
||||
"$sCurrentVersion: Missing previous for $sPreviousVersion config in iTopDesignFormat."
|
||||
);
|
||||
$this->TestDefinedFunction($aPreviousVersionInfo, 'go_to_previous', $sPreviousVersion, ($sPreviousVersion === '1.0'));
|
||||
$this->TestDefinedFunction($aPreviousVersionInfo, 'go_to_next', $sPreviousVersion, ($sPreviousVersion === $sLatestVersion));
|
||||
}
|
||||
|
||||
//check we have migration function from current version to next one
|
||||
if (($sCurrentVersion!== $sLatestVersion)) {
|
||||
if (($sCurrentVersion !== $sLatestVersion)) {
|
||||
$sNextVersion = $aCurrentVersionInfo['next'];
|
||||
$this->CheckCondition(array_key_exists($sNextVersion, iTopDesignFormat::$aVersions),
|
||||
"$sCurrentVersion: Missing $sNextVersion config in iTopDesignFormat.");
|
||||
$this->CheckCondition(
|
||||
array_key_exists($sNextVersion, iTopDesignFormat::$aVersions),
|
||||
"$sCurrentVersion: Missing $sNextVersion config in iTopDesignFormat."
|
||||
);
|
||||
$aNextVersionInfo = iTopDesignFormat::$aVersions[$sNextVersion];
|
||||
$this->CheckCondition(is_array($aNextVersionInfo),
|
||||
"$sCurrentVersion: wrong $sNextVersion config in iTopDesignFormat.");
|
||||
$this->CheckCondition(array_key_exists('previous', $aNextVersionInfo),
|
||||
"$sCurrentVersion: Missing previous for $sNextVersion config in iTopDesignFormat.");
|
||||
$this->CheckCondition(
|
||||
is_array($aNextVersionInfo),
|
||||
"$sCurrentVersion: wrong $sNextVersion config in iTopDesignFormat."
|
||||
);
|
||||
$this->CheckCondition(
|
||||
array_key_exists('previous', $aNextVersionInfo),
|
||||
"$sCurrentVersion: Missing previous for $sNextVersion config in iTopDesignFormat."
|
||||
);
|
||||
$this->TestDefinedFunction($aNextVersionInfo, 'go_to_previous', $sNextVersion, ($sNextVersion === '1.0'));
|
||||
$this->TestDefinedFunction($aNextVersionInfo, 'go_to_next', $sNextVersion, ($sNextVersion === $sLatestVersion));
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
$aErrors[] = $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
if (count($aErrors)!=0)
|
||||
{
|
||||
if (count($aErrors) != 0) {
|
||||
$sMsg = "Issue with conversion functions:\n";
|
||||
$sMsg .= implode("\n", $aErrors);
|
||||
$this->fail($sMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
private function CheckCondition($bCondition, $sMsg)
|
||||
{
|
||||
if ($bCondition === false)
|
||||
{
|
||||
if ($bCondition === false) {
|
||||
throw new \Exception($sMsg);
|
||||
}
|
||||
}
|
||||
|
||||
private function TestDefinedFunction($aCurrentVersionInfo, $sFunctionKey, $sVersion, $bNullFunction=false)
|
||||
private function TestDefinedFunction($aCurrentVersionInfo, $sFunctionKey, $sVersion, $bNullFunction = false)
|
||||
{
|
||||
$sInfo = json_encode($aCurrentVersionInfo, true);
|
||||
$this->CheckCondition(array_key_exists($sFunctionKey, $aCurrentVersionInfo), "Missing $sFunctionKey in $sVersion config in iTopDesignFormat: " . $sInfo);
|
||||
$this->CheckCondition(array_key_exists($sFunctionKey, $aCurrentVersionInfo), "Missing $sFunctionKey in $sVersion config in iTopDesignFormat: ".$sInfo);
|
||||
//echo $aCurrentVersionInfo[$sFunctionKey].'\n';
|
||||
if ($bNullFunction === false)
|
||||
{
|
||||
if ($bNullFunction === false) {
|
||||
$oReflectionClass = new \ReflectionClass(iTopDesignFormat::class);
|
||||
$this->CheckCondition($oReflectionClass->hasMethod($aCurrentVersionInfo[$sFunctionKey]), "wrong go_to_previous function '".$aCurrentVersionInfo[$sFunctionKey]."'' for $sVersion config in iTopDesignFormat." . $sInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->CheckCondition($oReflectionClass->hasMethod($aCurrentVersionInfo[$sFunctionKey]), "wrong go_to_previous function '".$aCurrentVersionInfo[$sFunctionKey]."'' for $sVersion config in iTopDesignFormat.".$sInfo);
|
||||
} else {
|
||||
$this->CheckCondition(is_null($aCurrentVersionInfo[$sFunctionKey]), "$sVersion $sFunctionKey function should be null");
|
||||
}
|
||||
}
|
||||
|
||||
public function GetDataModelFiles($sFolder)
|
||||
{
|
||||
$aDataModelFiles = array();
|
||||
if (is_dir($sFolder))
|
||||
{
|
||||
foreach (glob($sFolder."/*") as $sPath)
|
||||
{
|
||||
if (is_dir($sPath))
|
||||
{
|
||||
$aDataModelFiles = [];
|
||||
if (is_dir($sFolder)) {
|
||||
foreach (glob($sFolder."/*") as $sPath) {
|
||||
if (is_dir($sPath)) {
|
||||
/** @noinspection SlowArrayOperationsInLoopInspection */
|
||||
$aDataModelFiles = array_merge($aDataModelFiles, $this->GetDataModelFiles($sPath));
|
||||
}
|
||||
else if (preg_match("/datamodel\..*\.xml/", basename($sPath)))
|
||||
{
|
||||
} elseif (preg_match("/datamodel\..*\.xml/", basename($sPath))) {
|
||||
$aDataModelFiles[] = $sPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Combodo\iTop\Test\UnitTest\ReleaseChecklist;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
|
||||
|
||||
/**
|
||||
* @since 2.7.2 N°3060 / N°3061 Automatically check the installation.xml consistency
|
||||
*
|
||||
@@ -17,16 +16,14 @@ class iTopModuleXmlInstallationChecklistTest extends ItopTestCase
|
||||
*/
|
||||
public function testInstallationXmlFormat()
|
||||
{
|
||||
$sInstallationXmlPath = APPROOT . 'datamodels/2.x/installation.xml';
|
||||
$sInstallationXmlPath = APPROOT.'datamodels/2.x/installation.xml';
|
||||
$this->assertTrue(is_file($sInstallationXmlPath), "$sInstallationXmlPath does not exist");
|
||||
|
||||
$doc = new \DOMDocument();
|
||||
try{
|
||||
try {
|
||||
$doc->loadxml(file_get_contents($sInstallationXmlPath));
|
||||
}
|
||||
catch(\Exception $e)
|
||||
{
|
||||
$this->assertFalse(true, "$sInstallationXmlPath is not a valid XML content: " . $e->getMessage());
|
||||
} catch (\Exception $e) {
|
||||
$this->assertFalse(true, "$sInstallationXmlPath is not a valid XML content: ".$e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,32 +72,24 @@ class iTopModuleXmlInstallationChecklistTest extends ItopTestCase
|
||||
public function GetModulesNotAutoSelected($sFolder)
|
||||
{
|
||||
$aExcludedModules = ['authent-external', 'authent-ldap'];
|
||||
$aModules = array();
|
||||
if (is_dir($sFolder))
|
||||
{
|
||||
foreach (glob($sFolder."/*") as $sPath)
|
||||
{
|
||||
if (is_dir($sPath))
|
||||
{
|
||||
$aModules = [];
|
||||
if (is_dir($sFolder)) {
|
||||
foreach (glob($sFolder."/*") as $sPath) {
|
||||
if (is_dir($sPath)) {
|
||||
/** @noinspection SlowArrayOperationsInLoopInspection */
|
||||
$aModules = array_merge($aModules, $this->GetModulesNotAutoSelected($sPath));
|
||||
}
|
||||
else if (preg_match("/module\..*\.php/", basename($sPath)))
|
||||
{
|
||||
} elseif (preg_match("/module\..*\.php/", basename($sPath))) {
|
||||
$sModulePhpContent = file_get_contents($sPath);
|
||||
if (strpos($sModulePhpContent, "SetupWebPage::AddModule")!==false
|
||||
&& strpos($sModulePhpContent, "'mandatory' => true")===false)
|
||||
{
|
||||
if (strpos($sModulePhpContent, "SetupWebPage::AddModule") !== false
|
||||
&& strpos($sModulePhpContent, "'mandatory' => true") === false) {
|
||||
//filter modules autoselected due to below condition
|
||||
if (strpos($sModulePhpContent, "'mandatory' => false")!==false
|
||||
&& strpos($sModulePhpContent, "'visible' => false")!==false)
|
||||
{
|
||||
if (strpos($sModulePhpContent, "'mandatory' => false") !== false
|
||||
&& strpos($sModulePhpContent, "'visible' => false") !== false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sModule = basename(dirname($sPath));
|
||||
if (in_array($sModule, $aExcludedModules))// || $sModule === 'authent-ldap')
|
||||
{
|
||||
if (in_array($sModule, $aExcludedModules)) {// || $sModule === 'authent-ldap')
|
||||
//hardcode this condition to make sure test is OK (CI context) + added a ticket to work/investigate why it is failed for these 2 cases (itop dev context)
|
||||
continue;
|
||||
}
|
||||
@@ -115,21 +104,15 @@ class iTopModuleXmlInstallationChecklistTest extends ItopTestCase
|
||||
|
||||
public function GetAllModules($sFolder)
|
||||
{
|
||||
$aModules = array();
|
||||
if (is_dir($sFolder))
|
||||
{
|
||||
foreach (glob($sFolder."/*") as $sPath)
|
||||
{
|
||||
if (is_dir($sPath))
|
||||
{
|
||||
$aModules = [];
|
||||
if (is_dir($sFolder)) {
|
||||
foreach (glob($sFolder."/*") as $sPath) {
|
||||
if (is_dir($sPath)) {
|
||||
/** @noinspection SlowArrayOperationsInLoopInspection */
|
||||
$aModules = array_merge($aModules, $this->GetAllModules($sPath));
|
||||
}
|
||||
else if (preg_match("/module\..*\.php/", basename($sPath)))
|
||||
{
|
||||
} elseif (preg_match("/module\..*\.php/", basename($sPath))) {
|
||||
$sModulePhpContent = file_get_contents($sPath);
|
||||
if (strpos($sModulePhpContent, "SetupWebPage::AddModule")!==false)
|
||||
{
|
||||
if (strpos($sModulePhpContent, "SetupWebPage::AddModule") !== false) {
|
||||
$sModule = basename(dirname($sPath));
|
||||
$aModules[$sModule] = $sModule;
|
||||
}
|
||||
@@ -138,4 +121,4 @@ class iTopModuleXmlInstallationChecklistTest extends ItopTestCase
|
||||
}
|
||||
return $aModules;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -14,7 +15,6 @@ use MetaModel;
|
||||
use SetupUtils;
|
||||
use utils;
|
||||
|
||||
|
||||
/**
|
||||
* Class ItopCustomDatamodelTestCase
|
||||
*
|
||||
@@ -30,7 +30,7 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
|
||||
{
|
||||
/**
|
||||
* @var UnitTestRunTimeEnvironment
|
||||
*/
|
||||
*/
|
||||
protected $oEnvironment = null;
|
||||
|
||||
/**
|
||||
@@ -49,15 +49,15 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
|
||||
$this->setRunClassInSeparateProcess(true);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @return string Abs path to the XML delta to use for the tests of that class
|
||||
*/
|
||||
abstract public function GetDatamodelDeltaAbsPath(): string;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
static::LoadRequiredItopFiles();
|
||||
$this->oEnvironment = new UnitTestRunTimeEnvironment('production', $this->GetTestEnvironment());
|
||||
static::LoadRequiredItopFiles();
|
||||
$this->oEnvironment = new UnitTestRunTimeEnvironment('production', $this->GetTestEnvironment());
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
@@ -107,8 +107,8 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
|
||||
if (false === file_exists($this->GetTestEnvironmentFolderAbsPath())) {
|
||||
return false;
|
||||
}
|
||||
return $this->oEnvironment->IsUpToDate();
|
||||
}
|
||||
return $this->oEnvironment->IsUpToDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
@@ -124,10 +124,10 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
|
||||
// This requires XML deltas to be compatible, but it is a known and accepted trade-off. See PR #457
|
||||
if (false === $this->IsEnvironmentReady()) {
|
||||
|
||||
$this->debug("Preparing custom environment '$sTestEnv' with the following datamodel files:");
|
||||
foreach ($this->oEnvironment->GetCustomDatamodelFiles() as $sCustomDatamodelFile) {
|
||||
$this->debug(" - $sCustomDatamodelFile");
|
||||
}
|
||||
$this->debug("Preparing custom environment '$sTestEnv' with the following datamodel files:");
|
||||
foreach ($this->oEnvironment->GetCustomDatamodelFiles() as $sCustomDatamodelFile) {
|
||||
$this->debug(" - $sCustomDatamodelFile");
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
// Clear any previous "$sTestEnv" environment
|
||||
@@ -169,7 +169,7 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
|
||||
}
|
||||
CMDBSource::CreateDB($oTestConfig->Get('db_name'));
|
||||
MetaModel::Startup($sConfFile, false /* $bModelOnly */, true /* $bAllowCache */, false /* $bTraceSourceFiles */, $sTestEnv);
|
||||
// N°7446 For some reason we need to create the DB schema before starting the MM, then only we can create the tables.
|
||||
// N°7446 For some reason we need to create the DB schema before starting the MM, then only we can create the tables.
|
||||
MetaModel::DBCreate();
|
||||
|
||||
$this->debug("Custom environment '$sTestEnv' is ready!");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -43,7 +44,6 @@ use VirtualHost;
|
||||
use VirtualMachine;
|
||||
use XMLDataLoader;
|
||||
|
||||
|
||||
/** @see \Combodo\iTop\Test\UnitTest\ItopDataTestCase::CreateObjectWithTagSet() */
|
||||
define('TAG_CLASS', 'FAQ');
|
||||
define('TAG_ATTCODE', 'domains');
|
||||
@@ -75,9 +75,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,
|
||||
@@ -121,15 +121,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',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -161,17 +159,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());
|
||||
}
|
||||
}
|
||||
@@ -196,7 +191,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', []);
|
||||
}
|
||||
|
||||
@@ -311,8 +307,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();
|
||||
@@ -336,8 +331,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();
|
||||
@@ -356,9 +350,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;
|
||||
@@ -375,13 +369,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;
|
||||
@@ -407,13 +401,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 */
|
||||
@@ -446,7 +440,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'];
|
||||
@@ -457,7 +451,8 @@ abstract class ItopDataTestCase extends ItopTestCase
|
||||
}
|
||||
}
|
||||
|
||||
protected function GetUserRequestParams($iNum) {
|
||||
protected function GetUserRequestParams($iNum)
|
||||
{
|
||||
return [
|
||||
'ref' => 'Ticket_'.$iNum,
|
||||
'title' => 'BUG 1161_'.$iNum,
|
||||
@@ -483,7 +478,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);
|
||||
@@ -507,11 +503,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;
|
||||
@@ -529,11 +525,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;
|
||||
@@ -551,11 +547,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;
|
||||
@@ -573,11 +569,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;
|
||||
@@ -590,7 +586,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);
|
||||
@@ -605,9 +601,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;
|
||||
}
|
||||
|
||||
@@ -616,12 +612,12 @@ abstract class ItopDataTestCase extends ItopTestCase
|
||||
$oUserProfile->Set('reason', 'UNIT Tests');
|
||||
$oSet = DBObjectSet::FromObject($oUserProfile);
|
||||
/** @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;
|
||||
@@ -642,15 +638,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
|
||||
*
|
||||
@@ -664,18 +659,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()}");
|
||||
}
|
||||
|
||||
@@ -694,11 +686,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;
|
||||
@@ -716,11 +708,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;
|
||||
@@ -729,24 +721,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.
|
||||
@@ -782,10 +772,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')}");
|
||||
@@ -817,7 +805,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];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -832,10 +820,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);
|
||||
@@ -860,13 +846,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');
|
||||
@@ -875,7 +860,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];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -890,10 +875,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);
|
||||
@@ -944,18 +927,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);
|
||||
}
|
||||
@@ -993,8 +972,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
|
||||
@@ -1006,8 +983,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();
|
||||
@@ -1034,7 +1010,6 @@ abstract class ItopDataTestCase extends ItopTestCase
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
protected function DBInsertSingleTable($sTableClass, $aValues, $iKey = 0)
|
||||
{
|
||||
$sTable = MetaModel::DBGetTable($sTableClass);
|
||||
@@ -1044,8 +1019,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
|
||||
@@ -1053,7 +1028,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
|
||||
@@ -1110,8 +1085,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);
|
||||
}
|
||||
|
||||
@@ -1333,16 +1307,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);
|
||||
@@ -1355,7 +1327,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;
|
||||
@@ -1367,16 +1339,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);
|
||||
@@ -1395,10 +1365,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;
|
||||
@@ -1415,7 +1385,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);
|
||||
|
||||
@@ -1442,7 +1412,7 @@ abstract class ItopDataTestCase extends ItopTestCase
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
@@ -1453,8 +1423,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 */
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -13,6 +14,7 @@ use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
use ReflectionMethod;
|
||||
use SetupUtils;
|
||||
use Symfony\Component\HttpKernel\KernelInterface;
|
||||
|
||||
use const DEBUG_BACKTRACE_IGNORE_ARGS;
|
||||
|
||||
/**
|
||||
@@ -96,7 +98,6 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
* @param string $sExportFileName relative to log folder
|
||||
@@ -140,15 +141,16 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
}
|
||||
|
||||
$var_export = var_export($paramValues, true);
|
||||
file_put_contents(APPROOT.'/log/' .$sExportFileName, $var_export);
|
||||
file_put_contents(APPROOT.'/log/'.$sExportFileName, $var_export);
|
||||
return $var_export;
|
||||
}
|
||||
|
||||
protected function setUp(): void {
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
// Hack - Required the first time the Portal kernel is booted on a newly installed iTop
|
||||
$_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'] = __DIR__ . '/../../../../../env-production/itop-portal-base/portal/public/';
|
||||
$_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'] = __DIR__.'/../../../../../env-production/itop-portal-base/portal/public/';
|
||||
|
||||
$this->LoadRequiredItopFiles();
|
||||
$this->LoadRequiredTestFiles();
|
||||
@@ -187,22 +189,22 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
|
||||
$sAppRootPath = static::GetFirstDirUpContainingFile(__DIR__, 'approot.inc.php');
|
||||
|
||||
return $sAppRootPath . '/';
|
||||
return $sAppRootPath.'/';
|
||||
}
|
||||
|
||||
private static function GetFirstDirUpContainingFile(string $sSearchPath, string $sFileToFindGlobPattern): ?string
|
||||
{
|
||||
for ($iDepth = 0; $iDepth < 8; $iDepth++) {
|
||||
$aGlobFiles = glob($sSearchPath . '/' . $sFileToFindGlobPattern);
|
||||
$aGlobFiles = glob($sSearchPath.'/'.$sFileToFindGlobPattern);
|
||||
if (is_array($aGlobFiles) && (count($aGlobFiles) > 0)) {
|
||||
return $sSearchPath . '/';
|
||||
return $sSearchPath.'/';
|
||||
}
|
||||
$iOffsetSep = strrpos($sSearchPath, '/');
|
||||
if ($iOffsetSep === false) {
|
||||
$iOffsetSep = strrpos($sSearchPath, '\\');
|
||||
if ($iOffsetSep === false) {
|
||||
// Do not throw an exception here as PHPUnit will not show it clearly when determing the list of test to perform
|
||||
return 'Could not find the approot file in ' . $sSearchPath;
|
||||
return 'Could not find the approot file in '.$sSearchPath;
|
||||
}
|
||||
}
|
||||
$sSearchPath = substr($sSearchPath, 0, $iOffsetSep);
|
||||
@@ -210,7 +212,6 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overload this method to require necessary files through {@see \Combodo\iTop\Test\UnitTest\ItopTestCase::RequireOnceItopFile()}
|
||||
*
|
||||
@@ -221,7 +222,7 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
{
|
||||
// At least make sure that the autoloader will be loaded, and that the APPROOT constant is defined
|
||||
require_once __DIR__.'/../../../../approot.inc.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overload this method to require necessary files through {@see \Combodo\iTop\Test\UnitTest\ItopTestCase::RequireOnceUnitTestFile()}
|
||||
@@ -245,7 +246,7 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
*/
|
||||
protected function RequireOnceItopFile(string $sFileRelPath): void
|
||||
{
|
||||
require_once $this->GetAppRoot() . $sFileRelPath;
|
||||
require_once $this->GetAppRoot().$sFileRelPath;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,7 +263,7 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
$aStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
|
||||
$sCallerDirAbsPath = dirname($aStack[0]['file']);
|
||||
|
||||
require_once $sCallerDirAbsPath . DIRECTORY_SEPARATOR . $sFileRelPath;
|
||||
require_once $sCallerDirAbsPath.DIRECTORY_SEPARATOR.$sFileRelPath;
|
||||
}
|
||||
|
||||
protected function debug($sMsg)
|
||||
@@ -271,11 +272,11 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
if (is_string($sMsg)) {
|
||||
echo "$sMsg\n";
|
||||
} else {
|
||||
/** @noinspection ForgottenDebugOutputInspection */
|
||||
print_r($sMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
/** @noinspection ForgottenDebugOutputInspection */
|
||||
print_r($sMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function GetMicroTime()
|
||||
{
|
||||
@@ -286,8 +287,7 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
public function WriteToCsvHeader($sFilename, $aHeader)
|
||||
{
|
||||
$sResultFile = APPROOT.'log/'.$sFilename;
|
||||
if (is_file($sResultFile))
|
||||
{
|
||||
if (is_file($sResultFile)) {
|
||||
@unlink($sResultFile);
|
||||
}
|
||||
SetupUtils::builddir(dirname($sResultFile));
|
||||
@@ -378,7 +378,9 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
{
|
||||
$class = new \ReflectionClass($sClass);
|
||||
foreach ($class->getProperties() as $property) {
|
||||
if (!$property->isStatic()) continue;
|
||||
if (!$property->isStatic()) {
|
||||
continue;
|
||||
}
|
||||
$property->setAccessible(true);
|
||||
static::$aBackupStaticProperties[$sClass][$property->getName()] = $property->getValue();
|
||||
}
|
||||
@@ -396,7 +398,9 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
{
|
||||
$class = new \ReflectionClass($sClass);
|
||||
foreach ($class->getProperties() as $property) {
|
||||
if (!$property->isStatic()) continue;
|
||||
if (!$property->isStatic()) {
|
||||
continue;
|
||||
}
|
||||
$property->setAccessible(true);
|
||||
$property->setValue(null, static::$aBackupStaticProperties[$sClass][$property->getName()]);
|
||||
}
|
||||
@@ -414,7 +418,6 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
return $oProperty;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param object $oObject
|
||||
* @param string $sProperty
|
||||
@@ -454,38 +457,38 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
}
|
||||
}
|
||||
|
||||
public static function CreateTmpdir() {
|
||||
$sTmpDir=tempnam(sys_get_temp_dir(),'');
|
||||
if (file_exists($sTmpDir))
|
||||
{
|
||||
public static function CreateTmpdir()
|
||||
{
|
||||
$sTmpDir = tempnam(sys_get_temp_dir(), '');
|
||||
if (file_exists($sTmpDir)) {
|
||||
unlink($sTmpDir);
|
||||
}
|
||||
mkdir($sTmpDir);
|
||||
if (is_dir($sTmpDir))
|
||||
{
|
||||
if (is_dir($sTmpDir)) {
|
||||
return $sTmpDir;
|
||||
}
|
||||
|
||||
return sys_get_temp_dir();
|
||||
}
|
||||
|
||||
public static function RecurseMkdir($sDir){
|
||||
if (strpos($sDir, DIRECTORY_SEPARATOR) === 0){
|
||||
public static function RecurseMkdir($sDir)
|
||||
{
|
||||
if (strpos($sDir, DIRECTORY_SEPARATOR) === 0) {
|
||||
$sPath = DIRECTORY_SEPARATOR;
|
||||
} else {
|
||||
$sPath = "";
|
||||
}
|
||||
|
||||
foreach (explode(DIRECTORY_SEPARATOR, $sDir) as $sSubDir){
|
||||
foreach (explode(DIRECTORY_SEPARATOR, $sDir) as $sSubDir) {
|
||||
if (($sSubDir === '..')) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (( trim($sSubDir) === '' ) || ( $sSubDir === '.' )) {
|
||||
if ((trim($sSubDir) === '') || ($sSubDir === '.')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sPath .= $sSubDir . DIRECTORY_SEPARATOR;
|
||||
$sPath .= $sSubDir.DIRECTORY_SEPARATOR;
|
||||
if (!is_dir($sPath)) {
|
||||
var_dump($sPath);
|
||||
@mkdir($sPath);
|
||||
@@ -494,16 +497,16 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
|
||||
}
|
||||
|
||||
public static function RecurseCopy($src,$dst) {
|
||||
public static function RecurseCopy($src, $dst)
|
||||
{
|
||||
$dir = opendir($src);
|
||||
@mkdir($dst);
|
||||
while(false !== ( $file = readdir($dir)) ) {
|
||||
if (( $file != '.' ) && ( $file != '..' )) {
|
||||
if ( is_dir($src . '/' . $file) ) {
|
||||
static::RecurseCopy($src . DIRECTORY_SEPARATOR . $file,$dst . DIRECTORY_SEPARATOR . $file);
|
||||
}
|
||||
else {
|
||||
copy($src . DIRECTORY_SEPARATOR . $file,$dst . DIRECTORY_SEPARATOR . $file);
|
||||
while (false !== ($file = readdir($dir))) {
|
||||
if (($file != '.') && ($file != '..')) {
|
||||
if (is_dir($src.'/'.$file)) {
|
||||
static::RecurseCopy($src.DIRECTORY_SEPARATOR.$file, $dst.DIRECTORY_SEPARATOR.$file);
|
||||
} else {
|
||||
copy($src.DIRECTORY_SEPARATOR.$file, $dst.DIRECTORY_SEPARATOR.$file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -553,7 +556,7 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
/**
|
||||
* @since 3.2.1
|
||||
*/
|
||||
static protected function AssertDateEqualsNow($sActualDate, $sMessage = ''): void
|
||||
protected static function AssertDateEqualsNow($sActualDate, $sMessage = ''): void
|
||||
{
|
||||
$oActualDate = \DateTime::createFromFormat(\AttributeDate::GetInternalFormat(), $sActualDate);
|
||||
$oNow = new \DateTime();
|
||||
@@ -563,7 +566,7 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
/**
|
||||
* @since 3.2.1
|
||||
*/
|
||||
static protected function AssertDateTimeEqualsNow($sActualDate, $sMessage = ''): void
|
||||
protected static function AssertDateTimeEqualsNow($sActualDate, $sMessage = ''): void
|
||||
{
|
||||
$oActualDateTime = \DateTime::createFromFormat(\AttributeDateTime::GetInternalFormat(), $sActualDate);
|
||||
$oNow = new \DateTime();
|
||||
@@ -576,17 +579,17 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
*
|
||||
* @see static::bootKernel(), static::getContainer()
|
||||
* @see \Combodo\iTop\Kernel, \Combodo\iTop\Portal\Kernel
|
||||
*
|
||||
*
|
||||
* @param string $sKernelClass
|
||||
*
|
||||
* @since 3.2.1
|
||||
*/
|
||||
static protected function SetKernelClass(string $sKernelClass): void
|
||||
protected static function SetKernelClass(string $sKernelClass): void
|
||||
{
|
||||
$_SERVER['KERNEL_CLASS'] = $sKernelClass;
|
||||
}
|
||||
|
||||
static protected function bootKernel(array $options = []): KernelInterface
|
||||
protected static function bootKernel(array $options = []): KernelInterface
|
||||
{
|
||||
if (!array_key_exists('KERNEL_CLASS', $_SERVER)) {
|
||||
throw new \LogicException('static::SetKernelClass() must be called before booting the kernel.');
|
||||
@@ -599,31 +602,33 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
*
|
||||
* @since 3.2.1
|
||||
*/
|
||||
static protected function ReadTail($sFilename, $iLines = 1)
|
||||
protected static function ReadTail($sFilename, $iLines = 1)
|
||||
{
|
||||
$handle = fopen($sFilename, "r");
|
||||
$iLineCounter = $iLines;
|
||||
$iPos = -2;
|
||||
$bBeginning = false;
|
||||
$aLines = array();
|
||||
$aLines = [];
|
||||
while ($iLineCounter > 0) {
|
||||
$sChar = " ";
|
||||
while ($sChar != "\n") {
|
||||
if(fseek($handle, $iPos, SEEK_END) == -1) {
|
||||
if (fseek($handle, $iPos, SEEK_END) == -1) {
|
||||
$bBeginning = true;
|
||||
break;
|
||||
}
|
||||
$sChar = fgetc($handle);
|
||||
$iPos --;
|
||||
$iPos--;
|
||||
}
|
||||
$iLineCounter --;
|
||||
$iLineCounter--;
|
||||
if ($bBeginning) {
|
||||
rewind($handle);
|
||||
}
|
||||
$aLines[$iLines - $iLineCounter - 1] = fgets($handle);
|
||||
if ($bBeginning) break;
|
||||
if ($bBeginning) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose ($handle);
|
||||
fclose($handle);
|
||||
return array_reverse($aLines);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ use RunTimeEnvironment;
|
||||
use SetupUtils;
|
||||
use utils;
|
||||
|
||||
|
||||
/**
|
||||
* Class UnitTestRunTimeEnvironment
|
||||
*
|
||||
@@ -32,18 +31,18 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment
|
||||
*/
|
||||
protected $aCustomDatamodelFiles = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sSourceEnv;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sSourceEnv;
|
||||
|
||||
public function __construct($sSourceEnv, $sTargetEnv)
|
||||
{
|
||||
parent::__construct($sTargetEnv);
|
||||
$this->sSourceEnv = $sSourceEnv;
|
||||
}
|
||||
public function __construct($sSourceEnv, $sTargetEnv)
|
||||
{
|
||||
parent::__construct($sTargetEnv);
|
||||
$this->sSourceEnv = $sSourceEnv;
|
||||
}
|
||||
|
||||
public function GetEnvironment(): string
|
||||
public function GetEnvironment(): string
|
||||
{
|
||||
return $this->sFinalEnv;
|
||||
}
|
||||
@@ -60,19 +59,19 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment
|
||||
parent::CompileFrom($sSourceEnv, $bUseSymLinks);
|
||||
}
|
||||
|
||||
public function IsUpToDate()
|
||||
{
|
||||
clearstatcache();
|
||||
$fLastCompilationTime = filemtime(APPROOT.'env-'.$this->sFinalEnv);
|
||||
$aModifiedFiles = [];
|
||||
$this->FindFilesModifiedAfter($fLastCompilationTime, APPROOT.'datamodels/2.x', $aModifiedFiles);
|
||||
$this->FindFilesModifiedAfter($fLastCompilationTime, APPROOT.'extensions', $aModifiedFiles);
|
||||
$this->FindFilesModifiedAfter($fLastCompilationTime, APPROOT.'data/production-modules', $aModifiedFiles);
|
||||
foreach ($this->GetCustomDatamodelFiles() as $sCustomDatamodelFile) {
|
||||
if (filemtime($sCustomDatamodelFile) > $fLastCompilationTime) {
|
||||
$aModifiedFiles[] = $sCustomDatamodelFile;
|
||||
}
|
||||
}
|
||||
public function IsUpToDate()
|
||||
{
|
||||
clearstatcache();
|
||||
$fLastCompilationTime = filemtime(APPROOT.'env-'.$this->sFinalEnv);
|
||||
$aModifiedFiles = [];
|
||||
$this->FindFilesModifiedAfter($fLastCompilationTime, APPROOT.'datamodels/2.x', $aModifiedFiles);
|
||||
$this->FindFilesModifiedAfter($fLastCompilationTime, APPROOT.'extensions', $aModifiedFiles);
|
||||
$this->FindFilesModifiedAfter($fLastCompilationTime, APPROOT.'data/production-modules', $aModifiedFiles);
|
||||
foreach ($this->GetCustomDatamodelFiles() as $sCustomDatamodelFile) {
|
||||
if (filemtime($sCustomDatamodelFile) > $fLastCompilationTime) {
|
||||
$aModifiedFiles[] = $sCustomDatamodelFile;
|
||||
}
|
||||
}
|
||||
// Keep only xml files
|
||||
$aFilesToCompile = [];
|
||||
foreach ($aModifiedFiles as $sModifiedFile) {
|
||||
@@ -80,17 +79,17 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment
|
||||
$aFilesToCompile[] = $sModifiedFile;
|
||||
}
|
||||
}
|
||||
$aModifiedFiles = $aFilesToCompile;
|
||||
if (count($aModifiedFiles) > 0) {
|
||||
echo "The following files have been modified after the last compilation:\n";
|
||||
foreach ($aModifiedFiles as $sFile) {
|
||||
echo " - $sFile\n";
|
||||
}
|
||||
}
|
||||
return (count($aModifiedFiles) === 0);
|
||||
$aModifiedFiles = $aFilesToCompile;
|
||||
if (count($aModifiedFiles) > 0) {
|
||||
echo "The following files have been modified after the last compilation:\n";
|
||||
foreach ($aModifiedFiles as $sFile) {
|
||||
echo " - $sFile\n";
|
||||
}
|
||||
}
|
||||
return (count($aModifiedFiles) === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function GetMFModulesToCompile($sSourceEnv, $sSourceDir)
|
||||
@@ -99,8 +98,8 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment
|
||||
|
||||
foreach ($this->GetCustomDatamodelFiles() as $sDeltaFile) {
|
||||
$sDeltaId = preg_replace('/[^\d\w]/', '', $sDeltaFile);
|
||||
$sDeltaName = basename($sDeltaFile);
|
||||
$sDeltaDir = dirname($sDeltaFile);
|
||||
$sDeltaName = basename($sDeltaFile);
|
||||
$sDeltaDir = dirname($sDeltaFile);
|
||||
$oDelta = new MFCoreModule($sDeltaName, "$sDeltaDir/$sDeltaName", $sDeltaFile);
|
||||
$aRet[$sDeltaId] = $oDelta;
|
||||
}
|
||||
@@ -119,16 +118,16 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment
|
||||
// APPROOT, APPROOT/extensions/*, APPROOT/data/production-modules/*, APPROOT/data/production-modules/*/*
|
||||
|
||||
$aTestDirs = [];
|
||||
foreach(['', 'extensions/*/', 'data/production-modules/*/', 'data/production-modules/*/*/'] as $sRoot) {
|
||||
foreach (['', 'extensions/*/', 'data/production-modules/*/', 'data/production-modules/*/*/'] as $sRoot) {
|
||||
$aTestDirs = array_merge($aTestDirs, glob(APPROOT.$sRoot.'tests', GLOB_ONLYDIR));
|
||||
}
|
||||
|
||||
$aLoadedTestClasses = [];
|
||||
foreach($aTestDirs as $sTestDir) {
|
||||
foreach ($aTestDirs as $sTestDir) {
|
||||
// Iterate on all PHP files in subdirectories
|
||||
// Note: grep is not available on Windows, so we will use the PHP Reflection API
|
||||
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($sTestDir)) as $oFile) {
|
||||
if ($oFile->isDir()){
|
||||
if ($oFile->isDir()) {
|
||||
continue;
|
||||
}
|
||||
if (! utils::EndsWith($oFile->getFilename(), 'Test.php')) {
|
||||
@@ -154,16 +153,16 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment
|
||||
if (in_array($sClass, $aLoadedTestClasses)) {
|
||||
continue;
|
||||
}
|
||||
$aLoadedTestClasses[]=$sClass;
|
||||
require_once $sFile;
|
||||
$aLoadedTestClasses[] = $sClass;
|
||||
require_once $sFile;
|
||||
$oReflectionClass = new ReflectionClass($sClass);
|
||||
if ($oReflectionClass->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
// Check if the class extends ItopCustomDatamodelTestCase
|
||||
if (!$oReflectionClass->isSubclassOf(ItopCustomDatamodelTestCase::class)) {
|
||||
continue;
|
||||
}
|
||||
// Check if the class extends ItopCustomDatamodelTestCase
|
||||
if (!$oReflectionClass->isSubclassOf(ItopCustomDatamodelTestCase::class)) {
|
||||
continue;
|
||||
}
|
||||
/** @var \Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase $oTestClassInstance */
|
||||
$oTestClassInstance = new $sClass();
|
||||
if ($oTestClassInstance->GetTestEnvironment() !== $this->sFinalEnv) {
|
||||
@@ -182,18 +181,18 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment
|
||||
return $this->aCustomDatamodelFiles;
|
||||
}
|
||||
|
||||
private function FindFilesModifiedAfter(float $fReferenceTimestamp, string $sPathToScan, array &$aModifiedFiles)
|
||||
{
|
||||
if (!is_dir($sPathToScan)) {
|
||||
return;
|
||||
}
|
||||
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($sPathToScan)) as $oFile) {
|
||||
if ($oFile->isDir()) {
|
||||
continue;
|
||||
}
|
||||
if (filemtime($oFile->getPathname()) > $fReferenceTimestamp) {
|
||||
$aModifiedFiles[] = $oFile->getPathname();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private function FindFilesModifiedAfter(float $fReferenceTimestamp, string $sPathToScan, array &$aModifiedFiles)
|
||||
{
|
||||
if (!is_dir($sPathToScan)) {
|
||||
return;
|
||||
}
|
||||
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($sPathToScan)) as $oFile) {
|
||||
if ($oFile->isDir()) {
|
||||
continue;
|
||||
}
|
||||
if (filemtime($oFile->getPathname()) > $fReferenceTimestamp) {
|
||||
$aModifiedFiles[] = $oFile->getPathname();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Usage: php run_class_by_class.php
|
||||
*
|
||||
@@ -43,8 +44,7 @@ function RunTests($sFilterRegExp, $sUnitaryTestsDir = '', $bPassthru = false)
|
||||
///echo "executing <<<$sCommand>>>\n";
|
||||
if ($bPassthru) {
|
||||
passthru($sCommand, $iResultCode);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
exec($sCommand, $aTrashedOutput, $iResultCode);
|
||||
}
|
||||
$bTestSuccess = ($iResultCode == 0); // or 1 in case of a failing test
|
||||
@@ -61,4 +61,4 @@ foreach ($aTestClasses as $sTestClass) {
|
||||
$bSuccess = RunTests($sTestClass);
|
||||
$sDuration = round(microtime(true) - $fStarted, 3);
|
||||
echo "$sTestClass: ".($bSuccess ? 'Ok' : "FAILURE")." [$sDuration s]\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -6,7 +7,7 @@
|
||||
|
||||
class ApplicationObjectExtensionTest extends \Combodo\iTop\Test\UnitTest\ItopDataTestCase
|
||||
{
|
||||
const CREATE_TEST_ORG = true;
|
||||
public const CREATE_TEST_ORG = true;
|
||||
|
||||
// Count the calls by name
|
||||
private static array $aCalls = [];
|
||||
@@ -85,7 +86,6 @@ class ApplicationObjectExtensionTest extends \Combodo\iTop\Test\UnitTest\ItopDat
|
||||
$this->assertEquals(2, self::$iCalls);
|
||||
}
|
||||
|
||||
|
||||
public function testModificationsOnInsertWith2Extensions()
|
||||
{
|
||||
self::ResetCallCount();
|
||||
@@ -100,4 +100,4 @@ class ApplicationObjectExtensionTest extends \Combodo\iTop\Test\UnitTest\ItopDat
|
||||
$this->assertEquals(6, self::$iCalls);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -31,20 +32,20 @@ class DashboardLayoutTest extends ItopTestCase
|
||||
*/
|
||||
public function GetDashletCoordinatesProvider()
|
||||
{
|
||||
return array(
|
||||
'OneColLayout-Cell0' => array('DashboardLayoutOneCol', 0, array(0, 0)),
|
||||
'OneColLayout-Cell1' => array('DashboardLayoutOneCol', 1, array(0, 1)),
|
||||
'TwoColsLayout-Cell0' => array('DashboardLayoutTwoCols', 0, array(0, 0)),
|
||||
'TwoColsLayout-Cell1' => array('DashboardLayoutTwoCols', 1, array(1, 0)),
|
||||
'TwoColsLayout-Cell2' => array('DashboardLayoutTwoCols', 2, array(0, 1)),
|
||||
'TwoColsLayout-Cell3' => array('DashboardLayoutTwoCols', 3, array(1, 1)),
|
||||
'ThreeColsLayout-Cell0' => array('DashboardLayoutThreeCols', 0, array(0, 0)),
|
||||
'ThreeColsLayout-Cell1' => array('DashboardLayoutThreeCols', 1, array(1, 0)),
|
||||
'ThreeColsLayout-Cell2' => array('DashboardLayoutThreeCols', 2, array(2, 0)),
|
||||
'ThreeColsLayout-Cell3' => array('DashboardLayoutThreeCols', 3, array(0, 1)),
|
||||
'ThreeColsLayout-Cell4' => array('DashboardLayoutThreeCols', 4, array(1, 1)),
|
||||
'ThreeColsLayout-Cell5' => array('DashboardLayoutThreeCols', 5, array(2, 1)),
|
||||
);
|
||||
return [
|
||||
'OneColLayout-Cell0' => ['DashboardLayoutOneCol', 0, [0, 0]],
|
||||
'OneColLayout-Cell1' => ['DashboardLayoutOneCol', 1, [0, 1]],
|
||||
'TwoColsLayout-Cell0' => ['DashboardLayoutTwoCols', 0, [0, 0]],
|
||||
'TwoColsLayout-Cell1' => ['DashboardLayoutTwoCols', 1, [1, 0]],
|
||||
'TwoColsLayout-Cell2' => ['DashboardLayoutTwoCols', 2, [0, 1]],
|
||||
'TwoColsLayout-Cell3' => ['DashboardLayoutTwoCols', 3, [1, 1]],
|
||||
'ThreeColsLayout-Cell0' => ['DashboardLayoutThreeCols', 0, [0, 0]],
|
||||
'ThreeColsLayout-Cell1' => ['DashboardLayoutThreeCols', 1, [1, 0]],
|
||||
'ThreeColsLayout-Cell2' => ['DashboardLayoutThreeCols', 2, [2, 0]],
|
||||
'ThreeColsLayout-Cell3' => ['DashboardLayoutThreeCols', 3, [0, 1]],
|
||||
'ThreeColsLayout-Cell4' => ['DashboardLayoutThreeCols', 4, [1, 1]],
|
||||
'ThreeColsLayout-Cell5' => ['DashboardLayoutThreeCols', 5, [2, 1]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,6 +60,6 @@ class DashboardLayoutTest extends ItopTestCase
|
||||
$oDashboardLayout = new $sDashboardLayoutClass();
|
||||
$aDashletCoordinates = $oDashboardLayout->GetDashletCoordinates($iCellIdx);
|
||||
|
||||
$this->assertEquals($aExpectedCoordinates,$aDashletCoordinates);
|
||||
$this->assertEquals($aExpectedCoordinates, $aDashletCoordinates);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2018 Dennis Lassiter
|
||||
*
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -15,10 +16,10 @@ use UserRequest;
|
||||
|
||||
class DisplayBlockTest extends ItopCustomDatamodelTestCase
|
||||
{
|
||||
const CREATE_TEST_ORG = true;
|
||||
public const CREATE_TEST_ORG = true;
|
||||
public function GetDatamodelDeltaAbsPath(): string
|
||||
{
|
||||
return __DIR__ . '/Delta/add-enum-value-with-quote.xml';
|
||||
return __DIR__.'/Delta/add-enum-value-with-quote.xml';
|
||||
}
|
||||
|
||||
public function renderChartAjaxProvider(): array
|
||||
@@ -94,4 +95,4 @@ class DisplayBlockTest extends ItopCustomDatamodelTestCase
|
||||
$this->assertFalse(in_array($sNonExpected, $aJSNames));
|
||||
$this->assertTrue(in_array($sExpected, $aJSNames));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Application;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use MetaModel;
|
||||
|
||||
class LoginTest extends ItopDataTestCase {
|
||||
class LoginTest extends ItopDataTestCase
|
||||
{
|
||||
protected $sConfigTmpBackupFile;
|
||||
protected $sConfigPath;
|
||||
protected $sLoginMode;
|
||||
|
||||
protected function setUp(): void {
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
clearstatcache();
|
||||
@@ -29,8 +32,9 @@ class LoginTest extends ItopDataTestCase {
|
||||
@chmod($this->sConfigPath, 0444);
|
||||
}
|
||||
|
||||
protected function tearDown(): void {
|
||||
if (! is_null($this->sConfigTmpBackupFile) && is_file($this->sConfigTmpBackupFile)){
|
||||
protected function tearDown(): void
|
||||
{
|
||||
if (! is_null($this->sConfigTmpBackupFile) && is_file($this->sConfigTmpBackupFile)) {
|
||||
//put config back
|
||||
@chmod($this->sConfigPath, 0770);
|
||||
file_put_contents($this->sConfigPath, file_get_contents($this->sConfigTmpBackupFile));
|
||||
@@ -40,18 +44,19 @@ class LoginTest extends ItopDataTestCase {
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
protected function CallItopUrlByCurl($sUri, ?array $aPostFields=[]){
|
||||
protected function CallItopUrlByCurl($sUri, ?array $aPostFields = [])
|
||||
{
|
||||
$ch = curl_init();
|
||||
|
||||
$sUrl = MetaModel::GetConfig()->Get('app_root_url') . "/$sUri";
|
||||
$sUrl = MetaModel::GetConfig()->Get('app_root_url')."/$sUri";
|
||||
curl_setopt($ch, CURLOPT_URL, $sUrl);
|
||||
if (0 !== sizeof($aPostFields)){
|
||||
if (0 !== sizeof($aPostFields)) {
|
||||
curl_setopt($ch, CURLOPT_POST, 1);// set post data to true
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $aPostFields);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$sOutput = curl_exec($ch);
|
||||
curl_close ($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $sOutput;
|
||||
}
|
||||
|
||||
@@ -5,10 +5,12 @@ namespace Combodo\iTop\Test\UnitTest\Application;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
|
||||
class MenuNodeTest extends ItopDataTestCase {
|
||||
class MenuNodeTest extends ItopDataTestCase
|
||||
{
|
||||
private \UserRequest $oUR;
|
||||
|
||||
protected function setUp(): void {
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
clearstatcache();
|
||||
@@ -20,7 +22,6 @@ class MenuNodeTest extends ItopDataTestCase {
|
||||
$this->oUR = $this->CreateUserRequest(666, $aUserRequestCustomParams);
|
||||
}
|
||||
|
||||
|
||||
public function RenderOQLSearchProvider()
|
||||
{
|
||||
$aUseCases = [];
|
||||
@@ -66,16 +67,16 @@ OQL;
|
||||
SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (DATE_FORMAT(`UserRequest`.`ttr_escalation_deadline`, '%Y%v') != DATE_FORMAT(NOW(), '%Y%v'))
|
||||
OQL;
|
||||
|
||||
try{
|
||||
try {
|
||||
$sContent = $this->CallRenderOQLSearch(true, true, true, $sOql);
|
||||
$this->assertTrue(false !== strpos($sContent, $this->oUR->Get('title')), $sContent);
|
||||
} catch(\Exception $e){
|
||||
} catch (\Exception $e) {
|
||||
echo($e->getMessage());
|
||||
$this->fail('Without N°7750 fix Exception raised => TypeError : date(): Argument #2 ($timestamp) must be of type ?int, string given');
|
||||
}
|
||||
}
|
||||
|
||||
public function CallRenderOQLSearch(bool $bSearchPane, bool $bSearchOpen, bool $bAutoreload, string $sOql) : string
|
||||
public function CallRenderOQLSearch(bool $bSearchPane, bool $bSearchOpen, bool $bAutoreload, string $sOql): string
|
||||
{
|
||||
$sTitle = 'title';
|
||||
$oPage = new WebPage($sTitle);
|
||||
@@ -94,4 +95,3 @@ OQL;
|
||||
return $oResponse->getContent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -11,7 +12,6 @@ use utils;
|
||||
|
||||
class SCSSCompilationTest extends ItopTestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @dataProvider CompileDefaultThemesProvider
|
||||
* @doesNotPerformAssertions
|
||||
|
||||
@@ -85,7 +85,6 @@ class SessionTest extends ItopTestCase
|
||||
$this->assertEquals('OK', Session::Get('test'));
|
||||
}
|
||||
|
||||
|
||||
public function testIsSet()
|
||||
{
|
||||
$this->assertFalse(Session::IsSet('test'));
|
||||
|
||||
@@ -11,19 +11,18 @@ use ThemeHandler;
|
||||
*/
|
||||
class ThemeHandlerTest extends ItopTestCase
|
||||
{
|
||||
const PATTERN = '|\\\/var[^"]+testimages|';
|
||||
public const PATTERN = '|\\\/var[^"]+testimages|';
|
||||
|
||||
private $oCompileCSSServiceMock;
|
||||
private $sCompiledThemesDirAbsPath;
|
||||
private $sCssAbsPath;
|
||||
private $sDmCssAbsPath;
|
||||
private $sJsonThemeParamFile;
|
||||
static private $sTmpDir = null;
|
||||
static private $aDirsToCleanup = [];
|
||||
static private $sAbsoluteImagePath;
|
||||
private static $sTmpDir = null;
|
||||
private static $aDirsToCleanup = [];
|
||||
private static $sAbsoluteImagePath;
|
||||
|
||||
|
||||
static function setUpBeforeClass(): void
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
@@ -39,10 +38,9 @@ class ThemeHandlerTest extends ItopTestCase
|
||||
static::$aDirsToCleanup[] = dirname(static::$sAbsoluteImagePath);
|
||||
}
|
||||
|
||||
static function tearDownAfterClass(): void
|
||||
public static function tearDownAfterClass(): void
|
||||
{
|
||||
foreach (static::$aDirsToCleanup as $sDir)
|
||||
{
|
||||
foreach (static::$aDirsToCleanup as $sDir) {
|
||||
static::RecurseRmdir($sDir);
|
||||
}
|
||||
|
||||
@@ -73,35 +71,36 @@ class ThemeHandlerTest extends ItopTestCase
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
function KeepSignatureDiff($sSignature1, $sSignature2) : string {
|
||||
public function KeepSignatureDiff($sSignature1, $sSignature2): string
|
||||
{
|
||||
$aSignature1 = json_decode($sSignature1, true);
|
||||
$aSignature2 = json_decode($sSignature2, true);
|
||||
|
||||
$aDiffOuput = [];
|
||||
foreach ($aSignature1 as $sKey => $oVal1){
|
||||
if (is_array($oVal1) && ! empty($oVal1)){
|
||||
foreach ($aSignature1 as $sKey => $oVal1) {
|
||||
if (is_array($oVal1) && ! empty($oVal1)) {
|
||||
$aCurrentDiffVal = [];
|
||||
$oVal2 = $aSignature2[$sKey];
|
||||
if (0 != sizeof($oVal1)){
|
||||
foreach ($oVal1 as $sKey1 => $sVal1){
|
||||
if (! array_key_exists($sKey1, $oVal2)){
|
||||
if (0 != sizeof($oVal1)) {
|
||||
foreach ($oVal1 as $sKey1 => $sVal1) {
|
||||
if (! array_key_exists($sKey1, $oVal2)) {
|
||||
$aCurrentDiffVal[$sKey1] = "Missing";
|
||||
} else if ($sVal1 !== $oVal2[$sKey1]) {
|
||||
$aCurrentDiffVal[$sKey1] = "expected:$sVal1 | actual:" . $oVal2[$sKey1];
|
||||
} elseif ($sVal1 !== $oVal2[$sKey1]) {
|
||||
$aCurrentDiffVal[$sKey1] = "expected:$sVal1 | actual:".$oVal2[$sKey1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (! empty($oVal2)){
|
||||
foreach ($oVal2 as $sKey2 => $sVal2){
|
||||
if (! array_key_exists($sKey2, $oVal1)){
|
||||
if (! empty($oVal2)) {
|
||||
foreach ($oVal2 as $sKey2 => $sVal2) {
|
||||
if (! array_key_exists($sKey2, $oVal1)) {
|
||||
$aCurrentDiffVal[$sKey1] = "Missing";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (! empty($aCurrentDiffVal)){
|
||||
if (! empty($aCurrentDiffVal)) {
|
||||
$aDiffOuput[$sKey] = $aCurrentDiffVal;
|
||||
}
|
||||
} else if ($oVal1 !== $aSignature2[$sKey]){
|
||||
} elseif ($oVal1 !== $aSignature2[$sKey]) {
|
||||
$aDiffOuput[$sKey] = "expected:$oVal1 | actual:$aSignature2[$sKey]";
|
||||
}
|
||||
}
|
||||
@@ -111,14 +110,12 @@ class ThemeHandlerTest extends ItopTestCase
|
||||
|
||||
public static function RecurseMkdir($dir)
|
||||
{
|
||||
if (is_dir($dir))
|
||||
{
|
||||
if (is_dir($dir)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$sParentDir = dirname($dir);
|
||||
if (!static::RecurseMkdir($sParentDir))
|
||||
{
|
||||
if (!static::RecurseMkdir($sParentDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -128,28 +125,28 @@ class ThemeHandlerTest extends ItopTestCase
|
||||
public function testGetSignatureWithFileWithoutSignature()
|
||||
{
|
||||
$sTmpFile = tempnam(sys_get_temp_dir(), "sig");
|
||||
file_put_contents($sTmpFile,"ffff");
|
||||
$this->assertEquals("", ThemeHandler::GetSignature($sTmpFile));
|
||||
file_put_contents($sTmpFile, "ffff");
|
||||
$this->assertEquals("", ThemeHandler::GetSignature($sTmpFile));
|
||||
}
|
||||
|
||||
public function testGetSignature()
|
||||
{
|
||||
$sSig = ThemeHandler::GetSignature(APPROOT.'tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main.css');
|
||||
$sExpectedSig=<<<JSON
|
||||
$sExpectedSig = <<<JSON
|
||||
{"variables":"37c31105548fce44fecca5cb34e455c9","stylesheets":{"jqueryui":"78cfafc3524dac98e61fc2460918d4e5","main":"52d8a7c5530ceb3a4d777364fa4e1eea"},"variable_imports":{"css-variables":"3c3f5adf98b9dbf893658314436c4b93"},"images":{"css\/ui-lightness\/images\/ui-icons_222222_256x240.png":"3a3c5468f484f07ac4a320d9e22acb8c","css\/ui-lightness\/images\/ui-bg_diagonals-thick_20_666666_40x40.png":"4429d568c67d8dfeb9040273ea0fb8c4","css\/ui-lightness\/images\/ui-icons_E87C1E_256x240.png":"7003dd36cb2aa032c8ec871ce4d4e03d","css\/ui-lightness\/images\/ui-icons_1c94c4_256x240.png":"dbd693dc8e0ef04e90a2f7ac7b390086","css\/ui-lightness\/images\/ui-icons_F26522_256x240.png":"16278ec0c07270be571f4c2e97fcc10c","css\/ui-lightness\/images\/ui-bg_diagonals-thick_18_b81900_40x40.png":"e460a66d4b3e093fc651e62a236267cb","css\/ui-lightness\/images\/ui-icons_ffffff_256x240.png":"41612b0f4a034424f8321c9f824a94da","css\/ui-lightness\/images\/ui-icons_ffd27a_256x240.png":"dda1b6f694b0d196aefc66a1d6d758f6","images\/actions_right.png":"31c8906bd25d27b83a0a2466bf903462","images\/ac-background.gif":"76135f3697b41a15aed787cfd77776c7","images\/green-square.gif":"16ea9a497d72f5e66e4e8ea9ae08024e","images\/tv-item.gif":"719fe2d4566108e73162fb8868d3778c","images\/tv-collapsable.gif":"63a3351ea0d580797c9b8c386aa4f48b","images\/tv-expandable.gif":"a2d1af4128e4a798a7f3390b12a28574","images\/tv-item-last.gif":"2ae7e1d9972ce71e5caa65a086bc5b7e","images\/tv-collapsable-last.gif":"71acaa9d7c2616e9e8b7131a75ca65da","images\/tv-expandable-last.gif":"9d51036b3a8102742709da66789fd0f7","images\/red-header.gif":"c73b8765f0c8c3c183cb6a0c2bb0ec69","images\/green-header.gif":"0e22a09bb8051b2a274b3427ede62e82","images\/orange-header.gif":"ce1f93f0af64431771b4cbd6c99c567b","images\/calendar.png":"ab56e59af3c96ca661821257d376465e","images\/truncated.png":"c6f91108afe8159d417b4dc556cd3b2a","images\/plus.gif":"f00e1e6e1161f48608bb2bbc79b9948c","images\/minus.gif":"6d77c0c0c2f86b6995d1cdf78274eaab","images\/full-screen.png":"b541fadd3f1563856a4b44aeebd9d563","images\/indicator.gif":"03ce3dcc84af110e9da8699a841e5200","images\/delete.png":"93c047549c31a270a037840277cf59d3","images\/info-mini.png":"445c090ed777c5e6a08ac390fa896193","images\/ok.png":"f6973773335fd83d8d2875f9a3c925af","images\/error.png":"1af8a1041016f67669c5fd22dc88c82e","images\/eye-open-555.png":"9940f4e5b1248042c238e1924359fd5e","images\/eye-closed-555.png":"6ad3b0bae791bf61addc9d8ca80a642d","images\/eye-open-fff.png":"b7db2402d4d5c72314c25790a66150d4","images\/eye-closed-fff.png":"f9be7454dbb47b0e0bca3aa370ae7db5"},"utility_imports":[]}
|
||||
JSON;
|
||||
|
||||
$this->assertEquals($sExpectedSig, $sSig);
|
||||
$this->assertEquals($sExpectedSig, $sSig);
|
||||
}
|
||||
|
||||
public function testGetVarSignature()
|
||||
{
|
||||
$sSignature=<<<JSON
|
||||
$sSignature = <<<JSON
|
||||
{"variables":"37c31105548fce44fecca5cb34e455c9","stylesheets":{"css-variables":"934888ebb4991d4c76555be6b6d1d5cc","jqueryui":"78cfafc3524dac98e61fc2460918d4e5","main":"52d8a7c5530ceb3a4d777364fa4e1eea"},"variable_imports":[],"utility_imports":[]}
|
||||
JSON;
|
||||
$var_sig = ThemeHandler::GetVarSignature($sSignature);
|
||||
|
||||
$this->assertEquals("37c31105548fce44fecca5cb34e455c9",$var_sig);
|
||||
$this->assertEquals("37c31105548fce44fecca5cb34e455c9", $var_sig);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,19 +155,17 @@ JSON;
|
||||
* @throws \CoreException
|
||||
* @dataProvider CompileThemesProviderWithoutCss
|
||||
*/
|
||||
public function testCompileThemeWithoutCssFile_FocusOnParamAttribute($readFromParamAttributeFromJson=false)
|
||||
public function testCompileThemeWithoutCssFile_FocusOnParamAttribute($readFromParamAttributeFromJson = false)
|
||||
{
|
||||
static::InitCSSDirectory();
|
||||
|
||||
$sExpectJsonFilePath = APPROOT.'tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/theme-parameters.json';
|
||||
$sExpectedThemeParamJson = file_get_contents($sExpectJsonFilePath);
|
||||
$aThemeParameters = json_decode($sExpectedThemeParamJson, true);
|
||||
if (is_file($this->sJsonThemeParamFile))
|
||||
{
|
||||
if (is_file($this->sJsonThemeParamFile)) {
|
||||
unlink($this->sJsonThemeParamFile);
|
||||
}
|
||||
if (is_file($this->sCssAbsPath))
|
||||
{
|
||||
if (is_file($this->sCssAbsPath)) {
|
||||
unlink($this->sCssAbsPath);
|
||||
}
|
||||
|
||||
@@ -178,25 +173,22 @@ JSON;
|
||||
->method("CompileCSSFromSASS")
|
||||
->willReturn("====CSSCOMPILEDCONTENT====");
|
||||
|
||||
if($readFromParamAttributeFromJson)
|
||||
{
|
||||
if ($readFromParamAttributeFromJson) {
|
||||
copy($sExpectJsonFilePath, $this->sJsonThemeParamFile);
|
||||
$this->assertTrue(ThemeHandler::CompileTheme('basque-red', true, "COMPILATIONTIMESTAMP", null, [static::$sTmpDir.'/branding/themes/'], static::$sTmpDir));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->assertTrue(ThemeHandler::CompileTheme('basque-red', true, "COMPILATIONTIMESTAMP", $aThemeParameters, [static::$sTmpDir.'/branding/themes/'], static::$sTmpDir));
|
||||
}
|
||||
$this->assertTrue(is_file($this->sCssAbsPath));
|
||||
$this->assertEquals($sExpectedThemeParamJson, file_get_contents($this->sJsonThemeParamFile));
|
||||
$this->assertEquals(file_get_contents(APPROOT . 'tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main.css'), file_get_contents($this->sCssAbsPath));
|
||||
$this->assertEquals(file_get_contents(APPROOT.'tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main.css'), file_get_contents($this->sCssAbsPath));
|
||||
}
|
||||
|
||||
public function CompileThemesProviderWithoutCss()
|
||||
{
|
||||
return [
|
||||
"pass ParamAttributes and Save them in Json" => [false],
|
||||
"use them from saved json" => [true]
|
||||
"use them from saved json" => [true],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -208,23 +200,23 @@ JSON;
|
||||
* @throws \CoreException
|
||||
* @dataProvider CompileThemesProviderEmptyArray
|
||||
*/
|
||||
public function testCompileThemesEmptyArray($ThemeParametersJson, $CompileCount=0)
|
||||
public function testCompileThemesEmptyArray($ThemeParametersJson, $CompileCount = 0)
|
||||
{
|
||||
$sCssPath = static::$sTmpDir . '/branding/themes/basque-red/main.css';
|
||||
copy(APPROOT . 'tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main.css', $sCssPath);
|
||||
$sCssPath = static::$sTmpDir.'/branding/themes/basque-red/main.css';
|
||||
copy(APPROOT.'tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main.css', $sCssPath);
|
||||
|
||||
$this->oCompileCSSServiceMock->expects($this->exactly($CompileCount))
|
||||
->method("CompileCSSFromSASS")
|
||||
->willReturn("====CSSCOMPILEDCONTENT====");
|
||||
|
||||
$this->assertEquals($CompileCount!=0,ThemeHandler::CompileTheme('basque-red', true, "COMPILATIONTIMESTAMP", json_decode($ThemeParametersJson, true), [static::$sTmpDir.'/branding/themes/'], static::$sTmpDir));
|
||||
$this->assertEquals($CompileCount != 0, ThemeHandler::CompileTheme('basque-red', true, "COMPILATIONTIMESTAMP", json_decode($ThemeParametersJson, true), [static::$sTmpDir.'/branding/themes/'], static::$sTmpDir));
|
||||
}
|
||||
|
||||
public function CompileThemesProviderEmptyArray()
|
||||
{
|
||||
$aEmptyImports = '{"variables":{"brand-primary":"#C53030","hover-background-color":"#F6F6F6","icons-filter":"grayscale(1)","search-form-container-bg-color":"#4A5568"},"utility_imports":[],"variable_imports":[],"stylesheets":{"jqueryui":"..\/css\/ui-lightness\/DO_NOT_CHANGE.jqueryui.scss","main":"..\/css\/DO_NOT_CHANGE.light-grey.scss"}}';
|
||||
$aEmptyStyleSheets='{"variables":{"brand-primary":"#C53030","hover-background-color":"#F6F6F6","icons-filter":"grayscale(1)","search-form-container-bg-color":"#4A5568"},"utility_imports":{"css-variables":"..\/css\/DO_NOT_CHANGE.css-variables.scss"},"variable_imports":[],"stylesheets":[]}';
|
||||
$aEmptyVars='{"variables":[],"utility_imports":{"css-variables":"..\/css\/DO_NOT_CHANGE.css-variables.scss"},"variable_imports":[],"stylesheets":{"jqueryui":"..\/css\/ui-lightness\/DO_NOT_CHANGE.jqueryui.scss","main":"..\/css\/DO_NOT_CHANGE.light-grey.scss"}}';
|
||||
$aEmptyStyleSheets = '{"variables":{"brand-primary":"#C53030","hover-background-color":"#F6F6F6","icons-filter":"grayscale(1)","search-form-container-bg-color":"#4A5568"},"utility_imports":{"css-variables":"..\/css\/DO_NOT_CHANGE.css-variables.scss"},"variable_imports":[],"stylesheets":[]}';
|
||||
$aEmptyVars = '{"variables":[],"utility_imports":{"css-variables":"..\/css\/DO_NOT_CHANGE.css-variables.scss"},"variable_imports":[],"stylesheets":{"jqueryui":"..\/css\/ui-lightness\/DO_NOT_CHANGE.jqueryui.scss","main":"..\/css\/DO_NOT_CHANGE.light-grey.scss"}}';
|
||||
return [
|
||||
"empty imports" => [$aEmptyImports],
|
||||
"empty styles" => [$aEmptyStyleSheets],
|
||||
@@ -245,13 +237,13 @@ JSON;
|
||||
*/
|
||||
public function CompileThemesProvider()
|
||||
{
|
||||
$sModifiedVariableThemeParameterJson='{"variables":{"brand-primary1":"#C53030","hover-background-color":"#F6F6F6","icons-filter":"grayscale(1)","search-form-container-bg-color":"#4A5568"},"variable_imports":{"css-variables":"..\/css\/DO_NOT_CHANGE.css-variables.scss"},"stylesheets":{"jqueryui":"..\/css\/ui-lightness\/DO_NOT_CHANGE.jqueryui.scss","main":"..\/css\/DO_NOT_CHANGE.light-grey.scss"},"utility_imports":[]}';
|
||||
$sInitialThemeParamJson='{"variables":{"brand-primary":"#C53030","hover-background-color":"#F6F6F6","icons-filter":"grayscale(1)","search-form-container-bg-color":"#4A5568"},"variable_imports":{"css-variables":"..\/css\/DO_NOT_CHANGE.css-variables.scss"},"stylesheets":{"jqueryui":"..\/css\/ui-lightness\/DO_NOT_CHANGE.jqueryui.scss","main":"..\/css\/DO_NOT_CHANGE.light-grey.scss"},"utility_imports":[]}';
|
||||
$sModifiedVariableThemeParameterJson = '{"variables":{"brand-primary1":"#C53030","hover-background-color":"#F6F6F6","icons-filter":"grayscale(1)","search-form-container-bg-color":"#4A5568"},"variable_imports":{"css-variables":"..\/css\/DO_NOT_CHANGE.css-variables.scss"},"stylesheets":{"jqueryui":"..\/css\/ui-lightness\/DO_NOT_CHANGE.jqueryui.scss","main":"..\/css\/DO_NOT_CHANGE.light-grey.scss"},"utility_imports":[]}';
|
||||
$sInitialThemeParamJson = '{"variables":{"brand-primary":"#C53030","hover-background-color":"#F6F6F6","icons-filter":"grayscale(1)","search-form-container-bg-color":"#4A5568"},"variable_imports":{"css-variables":"..\/css\/DO_NOT_CHANGE.css-variables.scss"},"stylesheets":{"jqueryui":"..\/css\/ui-lightness\/DO_NOT_CHANGE.jqueryui.scss","main":"..\/css\/DO_NOT_CHANGE.light-grey.scss"},"utility_imports":[]}';
|
||||
$sImportFilePath = '/branding/css/DO_NOT_CHANGE.css-variables.scss';
|
||||
$sVarChangedMainCssPath="tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_varchanged.css";
|
||||
$sStylesheetMainCssPath="tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_stylesheet.css";
|
||||
$sImageMainCssPath="tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_imagemodified.css";
|
||||
$sImportModifiedMainCssPath="tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_importmodified.css";
|
||||
$sVarChangedMainCssPath = "tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_varchanged.css";
|
||||
$sStylesheetMainCssPath = "tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_stylesheet.css";
|
||||
$sImageMainCssPath = "tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_imagemodified.css";
|
||||
$sImportModifiedMainCssPath = "tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_importmodified.css";
|
||||
$sStylesheetFilePath = '/branding/css/DO_NOT_CHANGE.light-grey.scss';
|
||||
$sImageFilePath = 'tests/php-unit-tests/unitary-tests/application/theme-handler/copied/testimages/images/green-header.gif';
|
||||
return [
|
||||
@@ -273,7 +265,6 @@ JSON;
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $ThemeParametersJson
|
||||
* @param int $iCompileCSSFromSASSCount
|
||||
@@ -287,13 +278,12 @@ JSON;
|
||||
* @throws \CoreException
|
||||
* @dataProvider CompileThemesProvider
|
||||
*/
|
||||
public function testCompileThemes($ThemeParametersJson, $iCompileCSSFromSASSCount, $bMissingFile=false, $bFilesTouchedRecently=false, $bFileMd5sumModified=false, $sFileToTest=null, $sExpectedMainCssPath=null, $bSetup=true)
|
||||
public function testCompileThemes($ThemeParametersJson, $iCompileCSSFromSASSCount, $bMissingFile = false, $bFilesTouchedRecently = false, $bFileMd5sumModified = false, $sFileToTest = null, $sExpectedMainCssPath = null, $bSetup = true)
|
||||
{
|
||||
static::InitCSSDirectory();
|
||||
|
||||
$sAfterReplacementCssVariableMd5sum='';
|
||||
if (is_file(static::$sTmpDir.'/'.$sFileToTest))
|
||||
{
|
||||
$sAfterReplacementCssVariableMd5sum = '';
|
||||
if (is_file(static::$sTmpDir.'/'.$sFileToTest)) {
|
||||
$sFileToTest = static::$sTmpDir.'/'.$sFileToTest;
|
||||
} else {
|
||||
$sFileToTest = APPROOT.'/'.$sFileToTest;
|
||||
@@ -309,14 +299,12 @@ JSON;
|
||||
$sLine = '$approot-relative: "'.static::$sAbsoluteImagePath.'" !default;';
|
||||
$sCssVariableContent = preg_replace("/\\\$approot-relative: \"(.*)\"/", $sLine, $sCssVariableContent);
|
||||
file_put_contents($sCssVarPath, $sCssVariableContent);
|
||||
if ($bMissingFile)
|
||||
{
|
||||
if ($bMissingFile) {
|
||||
$sAfterReplacementCssVariableMd5sum = $sBeforeReplacementCssVariableMd5sum;
|
||||
unlink($sFileToTest);
|
||||
}
|
||||
|
||||
if (is_file($sCssVarPath))
|
||||
{
|
||||
if (is_file($sCssVarPath)) {
|
||||
$sAfterReplacementCssVariableMd5sum = md5_file($sCssVarPath);
|
||||
}
|
||||
|
||||
@@ -324,26 +312,23 @@ JSON;
|
||||
$sMainCssContent = file_get_contents(APPROOT."tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/main_testcompilethemes.css");
|
||||
$sMainCssContent = preg_replace('/MD5SUM/', $sAfterReplacementCssVariableMd5sum, $sMainCssContent);
|
||||
$sReplacement = rtrim(static::$sAbsoluteImagePath, '/');
|
||||
$sReplacement=preg_replace('|\/|', '\/', $sReplacement);
|
||||
$sMainCssContent = preg_replace(static::PATTERN, $sReplacement, $sMainCssContent);
|
||||
$cssPath = static::$sTmpDir . '/branding/themes/basque-red/main.css';
|
||||
$sReplacement = preg_replace('|\/|', '\/', $sReplacement);
|
||||
$sMainCssContent = preg_replace(static::PATTERN, $sReplacement, $sMainCssContent);
|
||||
$cssPath = static::$sTmpDir.'/branding/themes/basque-red/main.css';
|
||||
file_put_contents($cssPath, $sMainCssContent);
|
||||
|
||||
//should be after main.css modification to make sure precompilation check will be performed
|
||||
if ($bFilesTouchedRecently)
|
||||
{
|
||||
if ($bFilesTouchedRecently) {
|
||||
touch($sFileToTest, time() + 2, time() + 2);
|
||||
}
|
||||
|
||||
//same: it should be after main.css modification
|
||||
if ($bFileMd5sumModified)
|
||||
{
|
||||
if ($bFileMd5sumModified) {
|
||||
file_put_contents($sFileToTest, "###\n".file_get_contents($sFileToTest));
|
||||
touch($sFileToTest, time() + 2, time() + 2);
|
||||
}
|
||||
|
||||
if (is_file($sCssVarPath))
|
||||
{
|
||||
if (is_file($sCssVarPath)) {
|
||||
$sAfterReplacementCssVariableMd5sum = md5_file($sCssVarPath);
|
||||
}
|
||||
|
||||
@@ -352,10 +337,9 @@ JSON;
|
||||
->willReturn("====CSSCOMPILEDCONTENT====");
|
||||
|
||||
$aThemeParameters = json_decode($ThemeParametersJson, true);
|
||||
$this->assertEquals($iCompileCSSFromSASSCount!=0, ThemeHandler::CompileTheme('basque-red', $bSetup, "COMPILATIONTIMESTAMP", $aThemeParameters, [static::$sTmpDir.'/branding/themes/'], static::$sTmpDir));
|
||||
$this->assertEquals($iCompileCSSFromSASSCount != 0, ThemeHandler::CompileTheme('basque-red', $bSetup, "COMPILATIONTIMESTAMP", $aThemeParameters, [static::$sTmpDir.'/branding/themes/'], static::$sTmpDir));
|
||||
|
||||
if ($iCompileCSSFromSASSCount==1)
|
||||
{
|
||||
if ($iCompileCSSFromSASSCount == 1) {
|
||||
$sExpectedMainCssFile = APPROOT.$sExpectedMainCssPath;
|
||||
if (!is_file($sExpectedMainCssFile)) {
|
||||
$this->assertTrue(false, "Cannot find expected main css file $sExpectedMainCssFile");
|
||||
@@ -379,19 +363,18 @@ JSON;
|
||||
$sActualContent = file_get_contents($sActualCssFile);
|
||||
|
||||
//replace absolute path to fix it in any envt
|
||||
$sExpectedContent = preg_replace($aPatterns, $aReplacements, file_get_contents($sExpectedCssFile));
|
||||
$sExpectedContent = preg_replace($aPatterns, $aReplacements, file_get_contents($sExpectedCssFile));
|
||||
|
||||
//echo($sExpectedContent);
|
||||
if ($sExpectedContent != $sActualContent)
|
||||
{
|
||||
if ($sExpectedContent != $sActualContent) {
|
||||
//try to have inner json diff failure
|
||||
/** @var array $aExpectedJson */
|
||||
//replace absolute path to fix it in any envt
|
||||
$sExpectedJson = preg_replace($aPatterns, $aReplacements, ThemeHandler::GetSignature($sExpectedCssFile));
|
||||
$sExpectedJson = preg_replace($aPatterns, $aReplacements, ThemeHandler::GetSignature($sExpectedCssFile));
|
||||
$aExpectedJson = json_decode($sExpectedJson, true);
|
||||
/** @var array $aActualJson */
|
||||
$aActualJson = json_decode(ThemeHandler::GetSignature($sActualCssFile), true);
|
||||
echo (ThemeHandler::GetSignature($sActualCssFile));
|
||||
echo(ThemeHandler::GetSignature($sActualCssFile));
|
||||
$this->assertEquals($aExpectedJson, $aActualJson, "CSS file dont match ($sExpectedCssFile / $sActualCssFile)");
|
||||
}
|
||||
|
||||
@@ -405,14 +388,16 @@ JSON;
|
||||
*/
|
||||
public function testGetAllUrlFromScss($sScssFile)
|
||||
{
|
||||
$aIncludedUrls = ThemeHandler::GetAllUrlFromScss(['attr' => "123"],APPROOT.$sScssFile);
|
||||
$aIncludedUrls = ThemeHandler::GetAllUrlFromScss(['attr' => "123"], APPROOT.$sScssFile);
|
||||
$this->assertEquals(['approot-relative', 'version', 'version1'], array_values($aIncludedUrls['aMissingVariables']));
|
||||
$this->assertEquals(["attr"=>"123"],
|
||||
$aIncludedUrls['aFoundVariables']);
|
||||
$this->assertEquals(
|
||||
["attr" => "123"],
|
||||
$aIncludedUrls['aFoundVariables']
|
||||
);
|
||||
$aExpectedCompletedUrls = [
|
||||
'css/ui-lightness/images/tutu.jpg',
|
||||
"css/ui-lightness/images/tata.jpeg",
|
||||
"css/ui-lightness/images/tete.jpeg?g=123"
|
||||
"css/ui-lightness/images/tete.jpeg?g=123",
|
||||
];
|
||||
$aExpectedToCompleteUrls = [
|
||||
'\'abc/\'+ $approot-relative + "css/ui-lightness/images/toutou.png?v=" + $version',
|
||||
@@ -467,7 +452,8 @@ SCSS;
|
||||
$this->assertEquals(['gray-darker', 'brand-primary', 'brand-primary-lightest'], $aMissingVariables);
|
||||
}
|
||||
|
||||
public function testGetVariablesFromFile(){
|
||||
public function testGetVariablesFromFile()
|
||||
{
|
||||
$sContent = <<< 'SCSS'
|
||||
$approot-relative: "../../../../../" !default; // relative to env-***/branding/themes/***/main.css
|
||||
$approot-relative2: "../../" !default; // relative to env-***/branding/themes/***/main.css
|
||||
@@ -482,7 +468,7 @@ $icons-filter: hue-rotate(0deg) !default;
|
||||
$toto : titi;
|
||||
SCSS;
|
||||
|
||||
file_put_contents(static::$sTmpDir . DIRECTORY_SEPARATOR . 'css-variable.scss', $sContent);
|
||||
file_put_contents(static::$sTmpDir.DIRECTORY_SEPARATOR.'css-variable.scss', $sContent);
|
||||
$aVariables = ThemeHandler::GetVariablesFromFile(
|
||||
[ 'css-variable.scss' ],
|
||||
[ static::$sTmpDir ]
|
||||
@@ -504,7 +490,8 @@ SCSS;
|
||||
|
||||
$this->assertEquals(
|
||||
$aExpectedVariables,
|
||||
$aVariables);
|
||||
$aVariables
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -522,13 +509,13 @@ SCSS;
|
||||
public function ResolveUrlProvider()
|
||||
{
|
||||
return [
|
||||
'XXX + $key1 UNresolved' => ["abc/'+ \$key1", ['key'=>'123'], false],
|
||||
'$key1 + XXX UNresolved' => ["\$key1 + abs", ['key'=>'123'], false],
|
||||
'XXX + $key UNresolved' => ["abc/'+ \$unknownkey", ['key'=>'123'], false],
|
||||
'XXX + $key resolved' => ["abc/'+ \$key", ['key'=>'123'], "abc/123"],
|
||||
'XXX + $key1 resolved' => ["abc/'+ \$key1", ['key1'=>'123'], "abc/123"],
|
||||
'$key + XXX resolved' => ["\$key + \"/abc", ['key'=>'123'], "123/abc"],
|
||||
'XXX + $key + YYY resolved' => ["abc/'+ \$key + '/def", ['key'=>'123'], "abc/123/def"],
|
||||
'XXX + $key1 UNresolved' => ["abc/'+ \$key1", ['key' => '123'], false],
|
||||
'$key1 + XXX UNresolved' => ["\$key1 + abs", ['key' => '123'], false],
|
||||
'XXX + $key UNresolved' => ["abc/'+ \$unknownkey", ['key' => '123'], false],
|
||||
'XXX + $key resolved' => ["abc/'+ \$key", ['key' => '123'], "abc/123"],
|
||||
'XXX + $key1 resolved' => ["abc/'+ \$key1", ['key1' => '123'], "abc/123"],
|
||||
'$key + XXX resolved' => ["\$key + \"/abc", ['key' => '123'], "123/abc"],
|
||||
'XXX + $key + YYY resolved' => ["abc/'+ \$key + '/def", ['key' => '123'], "abc/123/def"],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -536,8 +523,8 @@ SCSS;
|
||||
{
|
||||
static::InitCSSDirectory();
|
||||
|
||||
$aStylesheetFile=glob(static::$sTmpDir."/branding/css/*.scss");
|
||||
$aStylesheetFile[]=static::$sTmpDir."/branding/css/ui-lightness/DO_NOT_CHANGE.jqueryui.scss";
|
||||
$aStylesheetFile = glob(static::$sTmpDir."/branding/css/*.scss");
|
||||
$aStylesheetFile[] = static::$sTmpDir."/branding/css/ui-lightness/DO_NOT_CHANGE.jqueryui.scss";
|
||||
$expectJsonFilePath = APPROOT.'tests/php-unit-tests/unitary-tests/application/theme-handler/expected/themes/basque-red/theme-parameters.json';
|
||||
$expectedThemeParamJson = file_get_contents($expectJsonFilePath);
|
||||
$aThemeParametersVariables = json_decode($expectedThemeParamJson, true);
|
||||
@@ -549,8 +536,7 @@ SCSS;
|
||||
|
||||
$aExpectedUris = json_decode(file_get_contents(APPROOT.'tests/php-unit-tests/unitary-tests/application/theme-handler/getimages/expected-getimages.json'), true);
|
||||
$aExpectedImages = [];
|
||||
foreach ($aExpectedUris as $sExpectedUri)
|
||||
{
|
||||
foreach ($aExpectedUris as $sExpectedUri) {
|
||||
$aExpectedImages[] = ThemeHandler::GetAppRootWithSlashes().$sExpectedUri;
|
||||
}
|
||||
|
||||
@@ -561,7 +547,8 @@ SCSS;
|
||||
* @dataProvider FindStylesheetFileProvider
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function testFindStylesheetFile(string $sFileToFind, array $aAllImports){
|
||||
public function testFindStylesheetFile(string $sFileToFind, array $aAllImports)
|
||||
{
|
||||
$sImportsPath = static::$sTmpDir.'branding/';
|
||||
|
||||
// Windows compat O:)
|
||||
@@ -575,7 +562,6 @@ SCSS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$oFindStylesheetObject = new FindStylesheetObject();
|
||||
ThemeHandler::FindStylesheetFile($sFileToFind, [$sImportsPath], $oFindStylesheetObject);
|
||||
|
||||
@@ -607,15 +593,15 @@ SCSS;
|
||||
],
|
||||
"scss with multi @imports" => [
|
||||
"sFileToFind" => $sFileToFind3,
|
||||
"aAllImports" => [$sFileToFind4, $sFileToFind5]
|
||||
"aAllImports" => [$sFileToFind4, $sFileToFind5],
|
||||
],
|
||||
"scss with simple @imports in another folder" => [
|
||||
"sFileToFind" => "css/simple_import2.scss",
|
||||
"aAllImports" => [$sFileToFind5]
|
||||
"aAllImports" => [$sFileToFind5],
|
||||
],
|
||||
"scss with @imports shortcut included_file3 => _included_file3.scss" => [
|
||||
"sFileToFind" => "css/shortcut.scss",
|
||||
"aAllImports" => ["css/_included_file3.scss", "css/included_scss/included_file4.scss"]
|
||||
"aAllImports" => ["css/_included_file3.scss", "css/included_scss/included_file4.scss"],
|
||||
],
|
||||
"scss with @imports shortcut same file and folder names => feature1/_feature1.scss" => [
|
||||
"sFileToFind" => "css/shortcut2.scss",
|
||||
@@ -656,7 +642,7 @@ SCSS;
|
||||
return [
|
||||
[ '/var/www/html/iTop/images/itop-logo-2.png', '/var/www/html/iTop/env-production/branding/themes/light-grey/../../../../images/itop-logo-2.png' ],
|
||||
[ '/var/www/html/iTop/env-production/branding/themes/light-grey/images/', '/var/www/html/iTop/env-production/branding/themes/light-grey/images/' ],
|
||||
[ '/var/www/html/iTop/css/ui-lightness/images/ui-icons_222222_256x240.png', '/var/www/html/iTop/env-production//branding/themes/light-grey//../../../../css/ui-lightness/images/ui-icons_222222_256x240.png' ]
|
||||
[ '/var/www/html/iTop/css/ui-lightness/images/ui-icons_222222_256x240.png', '/var/www/html/iTop/env-production//branding/themes/light-grey//../../../../css/ui-lightness/images/ui-icons_222222_256x240.png' ],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,10 @@ use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
*
|
||||
* @package UI\Base\Layout
|
||||
*/
|
||||
class NavigationMenuTest extends ItopDataTestCase {
|
||||
public function IsAllowedProvider(){
|
||||
class NavigationMenuTest extends ItopDataTestCase
|
||||
{
|
||||
public function IsAllowedProvider()
|
||||
{
|
||||
return [
|
||||
'show menu' => [ true ],
|
||||
'hide menu' => [ false ],
|
||||
@@ -25,17 +27,20 @@ class NavigationMenuTest extends ItopDataTestCase {
|
||||
* @dataProvider IsAllowedProvider
|
||||
* test used to make sure backward compatibility is ensured
|
||||
*/
|
||||
public function testIsAllowed($bExpectedIsAllowed=true){
|
||||
public function testIsAllowed($bExpectedIsAllowed = true)
|
||||
{
|
||||
\MetaModel::GetConfig()->Set('navigation_menu.show_organization_filter', $bExpectedIsAllowed);
|
||||
$oNavigationMenu = new NavigationMenu(
|
||||
$this->createMock(ApplicationContext::class),
|
||||
$this->createMock(PopoverMenu::class));
|
||||
$this->createMock(PopoverMenu::class)
|
||||
);
|
||||
|
||||
$isAllowed = $oNavigationMenu->IsSiloSelectionEnabled();
|
||||
$this->assertEquals($bExpectedIsAllowed, $isAllowed);
|
||||
}
|
||||
|
||||
public function testIsAllowed_BackwardCompatibility_NoVariableInConfFile(){
|
||||
public function testIsAllowed_BackwardCompatibility_NoVariableInConfFile()
|
||||
{
|
||||
\MetaModel::GetConfig()->Set('navigation_menu.show_organization_filter', false);
|
||||
|
||||
$sTmpFilePath = tempnam(sys_get_temp_dir(), 'test_');
|
||||
@@ -45,7 +50,7 @@ class NavigationMenuTest extends ItopDataTestCase {
|
||||
//remove variable for the test
|
||||
$aLines = file($sTmpFilePath);
|
||||
|
||||
$aRows = array();
|
||||
$aRows = [];
|
||||
|
||||
foreach ($aLines as $key => $sLine) {
|
||||
if (!preg_match('/navigation_menu.show_organization_filter/', $sLine)) {
|
||||
|
||||
@@ -21,12 +21,12 @@ class WelcomePopupTest extends ItopDataTestCase
|
||||
$bResult = usort($aProvidersMessagesData, [WelcomePopupService::class, 'SortOnImportance']);
|
||||
$this->assertTrue($bResult);
|
||||
|
||||
$aMessageIdsSorted = array_map(function($aItem) {
|
||||
$aMessageIdsSorted = array_map(function ($aItem) {
|
||||
return $aItem['message']->GetId();
|
||||
}, $aProvidersMessagesData);
|
||||
$this->assertEquals($aExpected, $aMessageIdsSorted);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Data provider for testSortOnImportance
|
||||
* @return array[][]|string[][][][]|number[][][][]
|
||||
@@ -76,10 +76,10 @@ class WelcomePopupTest extends ItopDataTestCase
|
||||
{
|
||||
$oService = WelcomePopupService::GetInstance();
|
||||
$this->InvokeNonPublicMethod(WelcomePopupService::class, 'SetAcknowledgedMessagesCache', $oService, [$aCache]);
|
||||
|
||||
|
||||
$this->assertEquals($bExpected, $this->InvokeNonPublicMethod(WelcomePopupService::class, 'IsMessageAcknowledged', $oService, [$sMessageId]));
|
||||
}
|
||||
|
||||
|
||||
public function isMessageAcknowledgedDataProvider()
|
||||
{
|
||||
return [
|
||||
@@ -94,7 +94,7 @@ class WelcomePopupTest extends ItopDataTestCase
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function testProcessMessages()
|
||||
{
|
||||
// Mock a WelcomePopup message provider, with a fixed class name
|
||||
@@ -103,7 +103,7 @@ class WelcomePopupTest extends ItopDataTestCase
|
||||
new Message('123', 'foo', '<p>Hello Foo</p>', null, [], 0),
|
||||
new Message('456', 'bar', '<p>Hello Bar</p>', null, [], 1), // Already acknowledged will be skipped
|
||||
]);
|
||||
|
||||
|
||||
// Mock another WelcomePopup message provider, with a different class name
|
||||
$oProvider2 = $this->getMockBuilder(iWelcomePopupExtension::class)->setMockClassName('Provider2')->getMock();
|
||||
$oProvider2->expects($this->once())->method('GetMessages')->willReturn([
|
||||
@@ -113,7 +113,7 @@ class WelcomePopupTest extends ItopDataTestCase
|
||||
$oService = WelcomePopupService::GetInstance();
|
||||
$this->InvokeNonPublicMethod(WelcomePopupService::class, 'SetAcknowledgedMessagesCache', $oService, [[get_class($oProvider1).'::456']]);
|
||||
$this->InvokeNonPublicMethod(WelcomePopupService::class, 'SetMessagesProviders', $oService, [[$oProvider1, $oProvider2]]);
|
||||
|
||||
|
||||
$aProvidersMessagesData = $this->InvokeNonPublicMethod(WelcomePopupService::class, 'ProcessMessages', $oService, []);
|
||||
$this->assertEquals(
|
||||
[
|
||||
@@ -141,11 +141,11 @@ class WelcomePopupTest extends ItopDataTestCase
|
||||
{
|
||||
self::CreateUser('admin-testAcknowledgeMessage', 1, '-Passw0rd!Complex-');
|
||||
UserRights::Login('admin-testAcknowledgeMessage');
|
||||
|
||||
|
||||
// Mock a WelcomePopup message provider, with a fixed class name
|
||||
$oProvider1 = $this->getMockBuilder(iWelcomePopupExtension::class)->setMockClassName('Provider1')->getMock();
|
||||
$oProvider1->expects($this->exactly(2))->method('AcknowledgeMessage');
|
||||
|
||||
|
||||
// Mock another WelcomePopup message provider, with a different class name
|
||||
$oProvider2 = $this->getMockBuilder(iWelcomePopupExtension::class)->setMockClassName('Provider2')->getMock();
|
||||
$oProvider2->expects($this->exactly(1))->method('AcknowledgeMessage');
|
||||
@@ -154,24 +154,24 @@ class WelcomePopupTest extends ItopDataTestCase
|
||||
$sMessageUUID2 = get_class($oProvider1).'::456789';
|
||||
$sMessageUUID3 = get_class($oProvider2).'::456789'; // Same message id but different provider / UUID
|
||||
$oService = WelcomePopupService::GetInstance();
|
||||
|
||||
|
||||
$this->InvokeNonPublicMethod(WelcomePopupService::class, 'SetMessagesProviders', $oService, [[$oProvider1, $oProvider2]]);
|
||||
|
||||
|
||||
$oService->AcknowledgeMessage($sMessageUUID1);
|
||||
$this->assertTrue($this->InvokeNonPublicMethod(WelcomePopupService::class, 'IsMessageAcknowledged', $oService, [$sMessageUUID1]));
|
||||
$this->assertFalse($this->InvokeNonPublicMethod(WelcomePopupService::class, 'IsMessageAcknowledged', $oService, ['-This-Message-Id-Is-Not-Ack0ledg3dged!']));
|
||||
$this->assertFalse($this->InvokeNonPublicMethod(WelcomePopupService::class, 'IsMessageAcknowledged', $oService, [$sMessageUUID3]));
|
||||
|
||||
|
||||
$oService->AcknowledgeMessage($sMessageUUID2);
|
||||
$this->assertTrue($this->InvokeNonPublicMethod(WelcomePopupService::class, 'IsMessageAcknowledged', $oService, [$sMessageUUID1]));
|
||||
$this->assertTrue($this->InvokeNonPublicMethod(WelcomePopupService::class, 'IsMessageAcknowledged', $oService, [$sMessageUUID2]));
|
||||
$this->assertFalse($this->InvokeNonPublicMethod(WelcomePopupService::class, 'IsMessageAcknowledged', $oService, ['-This-Message-Id-Is-Not-Ack0ledg3dged!']));
|
||||
$this->assertFalse($this->InvokeNonPublicMethod(WelcomePopupService::class, 'IsMessageAcknowledged', $oService, [$sMessageUUID3]));
|
||||
|
||||
|
||||
$oService->AcknowledgeMessage($sMessageUUID3);
|
||||
$this->assertTrue($this->InvokeNonPublicMethod(WelcomePopupService::class, 'IsMessageAcknowledged', $oService, [$sMessageUUID3]));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dataProvider makeStringFitInProvider
|
||||
*/
|
||||
@@ -182,7 +182,7 @@ class WelcomePopupTest extends ItopDataTestCase
|
||||
$this->assertTrue(mb_strlen($sFitted) <= $iLimit);
|
||||
$this->assertEquals($sExpected, $sFitted);
|
||||
}
|
||||
|
||||
|
||||
public function makeStringFitInProvider()
|
||||
{
|
||||
return [
|
||||
@@ -193,4 +193,3 @@ class WelcomePopupTest extends ItopDataTestCase
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,4 +23,4 @@ class ApplicationContextTest extends \Combodo\iTop\Test\UnitTest\ItopTestCase
|
||||
$this->assertEquals($sExpected, $sActual, 'Query parameters string should not start with & when $bIncludeAmpersand is false');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,10 @@ namespace applicationContext;
|
||||
|
||||
class MockApplicationContext extends \ApplicationContext
|
||||
{
|
||||
|
||||
public function __construct(array $applicationContextConfig)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->aValues = $applicationContextConfig;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -25,7 +26,7 @@ class ApplicationExtensionTest extends ItopCustomDatamodelTestCase
|
||||
*/
|
||||
public function GetDatamodelDeltaAbsPath(): string
|
||||
{
|
||||
return __DIR__ . '/Delta/application-extension-usages-in-snippets.xml';
|
||||
return __DIR__.'/Delta/application-extension-usages-in-snippets.xml';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -14,7 +15,6 @@ class MockApplicationObjectExtensionForTest1 extends AbstractApplicationObjectEx
|
||||
protected static $sAttCodeToModify;
|
||||
protected static $callBack;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
@@ -72,4 +72,4 @@ class MockApplicationObjectExtensionForTest1 extends AbstractApplicationObjectEx
|
||||
$oObject->DBUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -14,7 +15,6 @@ class MockApplicationObjectExtensionForTest2 extends AbstractApplicationObjectEx
|
||||
protected static $sAttCodeToModify;
|
||||
protected static $callBack;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
@@ -72,4 +72,4 @@ class MockApplicationObjectExtensionForTest2 extends AbstractApplicationObjectEx
|
||||
$oObject->DBUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -32,9 +33,9 @@ use UserRights;
|
||||
class privUITransactionFileTest extends ItopDataTestCase
|
||||
{
|
||||
/** @var int ID of the "support agent" pofile in the sample data */
|
||||
const SAMPLE_DATA_SUPPORT_PROFILE_ID = 5;
|
||||
const USER1_TEST_LOGIN = 'user1_support_test_privUITransaction';
|
||||
const USER2_TEST_LOGIN = 'user2_support_test_privUITransaction';
|
||||
public const SAMPLE_DATA_SUPPORT_PROFILE_ID = 5;
|
||||
public const USER1_TEST_LOGIN = 'user1_support_test_privUITransaction';
|
||||
public const USER2_TEST_LOGIN = 'user2_support_test_privUITransaction';
|
||||
|
||||
/**
|
||||
* @dataProvider cleanupOldTransactionsProvider
|
||||
@@ -43,7 +44,7 @@ class privUITransactionFileTest extends ItopDataTestCase
|
||||
{
|
||||
MetaModel::GetConfig()->Set('transactions_gc_threshold', 100);
|
||||
|
||||
$iBaseLimit = time() - 24*3600; //24h
|
||||
$iBaseLimit = time() - 24 * 3600; //24h
|
||||
|
||||
$sBaseDir = sys_get_temp_dir();
|
||||
$sDir = "$sBaseDir/privUITransactionFileTest/cleanupOldTransactions";
|
||||
@@ -53,10 +54,10 @@ class privUITransactionFileTest extends ItopDataTestCase
|
||||
mkdir("$sDir", 0777, true);
|
||||
|
||||
for ($i = 0; $i < $iCleanableCreated; $i++) {
|
||||
touch("$sDir/{$sCleanablePrefix}$i", $iBaseLimit - 10*60);
|
||||
touch("$sDir/{$sCleanablePrefix}$i", $iBaseLimit - 10 * 60);
|
||||
}
|
||||
for ($i = 0; $i < $iPreservableCreated; $i++) {
|
||||
touch("$sDir/{$sPreservablePrefix}$i", $iBaseLimit + 10*60);
|
||||
touch("$sDir/{$sPreservablePrefix}$i", $iBaseLimit + 10 * 60);
|
||||
}
|
||||
|
||||
$iCleanableCount = count(glob("$sDir/{$sCleanablePrefix}*"));
|
||||
@@ -123,7 +124,8 @@ class privUITransactionFileTest extends ItopDataTestCase
|
||||
];
|
||||
}
|
||||
|
||||
public function rm($sDir) {
|
||||
public function rm($sDir)
|
||||
{
|
||||
$aFiles = array_diff(scandir($sDir), ['.','..']);
|
||||
foreach ($aFiles as $sFile) {
|
||||
if ((is_dir("$sDir/$sFile"))) {
|
||||
@@ -135,7 +137,7 @@ class privUITransactionFileTest extends ItopDataTestCase
|
||||
return rmdir($sDir);
|
||||
}
|
||||
|
||||
const USER_TEST_LOGIN = 'support_test_privUITransaction';
|
||||
public const USER_TEST_LOGIN = 'support_test_privUITransaction';
|
||||
|
||||
/**
|
||||
* @throws \SecurityException
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2018 Dennis Lassiter
|
||||
*
|
||||
@@ -38,11 +39,11 @@ use utils;
|
||||
class QueryTest extends ItopDataTestCase
|
||||
{
|
||||
// disable transaction to avoid data inconsistency between test and call to export (outside test scope)
|
||||
const USE_TRANSACTION = false;
|
||||
public const USE_TRANSACTION = false;
|
||||
|
||||
// user for exportation process
|
||||
const USER = 'dani2';
|
||||
const PASSWORD = '1TopCombodo+';
|
||||
public const USER = 'dani2';
|
||||
public const PASSWORD = '1TopCombodo+';
|
||||
private $oUser;
|
||||
|
||||
/** @inheritDoc */
|
||||
@@ -60,7 +61,7 @@ class QueryTest extends ItopDataTestCase
|
||||
*/
|
||||
private function CreateExportUser()
|
||||
{
|
||||
$oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => 'Administrator'), true);
|
||||
$oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", ['name' => 'Administrator'], true);
|
||||
$this->oUser = $this->CreateUser(self::USER, $oAdminProfile->GetKey(), self::PASSWORD);
|
||||
}
|
||||
|
||||
@@ -72,14 +73,14 @@ class QueryTest extends ItopDataTestCase
|
||||
* @param string $sOql query oql phrase
|
||||
* @param string|null $sFields fields to export
|
||||
*/
|
||||
private function CreateQueryOQL(string $sName, string $sDescription, string $sOql, string $sFields = null) : QueryOQL
|
||||
private function CreateQueryOQL(string $sName, string $sDescription, string $sOql, string $sFields = null): QueryOQL
|
||||
{
|
||||
$oQuery = new QueryOQL();
|
||||
$oQuery->Set('name', $sName);
|
||||
$oQuery->Set('description', $sDescription);
|
||||
$oQuery->Set('oql', $sOql);
|
||||
|
||||
if($sFields != null){
|
||||
if ($sFields != null) {
|
||||
$oQuery->Set('fields', $sFields);
|
||||
}
|
||||
|
||||
@@ -154,10 +155,10 @@ class QueryTest extends ItopDataTestCase
|
||||
*/
|
||||
public function getQueryProvider()
|
||||
{
|
||||
return array(
|
||||
'Export #1' => array('query without params', 'SELECT Person'),
|
||||
'Export #2' => array('query with params', "SELECT Person WHERE first_name LIKE 'B%'")
|
||||
);
|
||||
return [
|
||||
'Export #1' => ['query without params', 'SELECT Person'],
|
||||
'Export #2' => ['query with params', "SELECT Person WHERE first_name LIKE 'B%'"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -177,7 +178,7 @@ class QueryTest extends ItopDataTestCase
|
||||
|
||||
// curl options
|
||||
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($curl, CURLOPT_USERPWD, self::USER . ':' . self::PASSWORD);
|
||||
curl_setopt($curl, CURLOPT_USERPWD, self::USER.':'.self::PASSWORD);
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
// Force disable of certificate check as most of dev / test env have a self-signed certificate
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Application\TwigBase\Controller;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use MetaModel;
|
||||
|
||||
class ControllerTest extends ItopDataTestCase {
|
||||
class ControllerTest extends ItopDataTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
@@ -12,7 +14,8 @@ class ControllerTest extends ItopDataTestCase {
|
||||
$this->RequireOnceUnitTestFile('FakeController.php');
|
||||
}
|
||||
|
||||
public function CheckAccessProvider() {
|
||||
public function CheckAccessProvider()
|
||||
{
|
||||
return [
|
||||
'simple token access OK' => [
|
||||
'access_token' => 'toto123',
|
||||
@@ -42,7 +45,8 @@ class ControllerTest extends ItopDataTestCase {
|
||||
* Fix N°7147
|
||||
* @dataProvider CheckAccessProvider
|
||||
*/
|
||||
public function testCheckAccess($sConfiguredAccessToken, $sHttpAccessToken, $bSuccess, $bPost=false){
|
||||
public function testCheckAccess($sConfiguredAccessToken, $sHttpAccessToken, $bSuccess, $bPost = false)
|
||||
{
|
||||
$sModuleName = "MyModule";
|
||||
$sTokenParamName = "access_token_conf_param";
|
||||
|
||||
@@ -51,7 +55,7 @@ class ControllerTest extends ItopDataTestCase {
|
||||
$_REQUEST = [];
|
||||
|
||||
$_REQUEST['exec_module'] = $sModuleName;
|
||||
if ($bPost){
|
||||
if ($bPost) {
|
||||
$_POST[$sTokenParamName] = $sHttpAccessToken;
|
||||
} else {
|
||||
$_REQUEST[$sTokenParamName] = $sHttpAccessToken;
|
||||
@@ -62,13 +66,13 @@ class ControllerTest extends ItopDataTestCase {
|
||||
|
||||
MetaModel::GetConfig()->SetModuleSetting($sModuleName, $sTokenParamName, $sConfiguredAccessToken);
|
||||
|
||||
if (! $bSuccess){
|
||||
if (! $bSuccess) {
|
||||
$this->expectExceptionMessage("Invalid token");
|
||||
}
|
||||
|
||||
$this->InvokeNonPublicMethod(FakeController::class, "CheckAccess", $oController);
|
||||
|
||||
if ($bSuccess){
|
||||
if ($bSuccess) {
|
||||
$this->assertTrue(true, "no issue encountered");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Application\TwigBase\Controller;
|
||||
|
||||
class FakeController extends Controller {
|
||||
class FakeController extends Controller
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2018 Dennis Lassiter
|
||||
*
|
||||
@@ -42,7 +43,6 @@ class utilsTest extends ItopTestCase
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
|
||||
public function testEndsWith()
|
||||
{
|
||||
$this->assertFalse(utils::EndsWith('a', 'bbbb'));
|
||||
@@ -87,8 +87,7 @@ class utilsTest extends ItopTestCase
|
||||
$sSep = DIRECTORY_SEPARATOR;
|
||||
$sItopRootRealPath = realpath($sAppRoot).$sSep;
|
||||
$sLicenseFileName = 'license.txt';
|
||||
if (!is_file($sAppRoot.$sLicenseFileName))
|
||||
{
|
||||
if (!is_file($sAppRoot.$sLicenseFileName)) {
|
||||
$sLicenseFileName = 'LICENSE';
|
||||
}
|
||||
|
||||
@@ -96,7 +95,7 @@ class utilsTest extends ItopTestCase
|
||||
$sLicenseFileName => [$sAppRoot.$sLicenseFileName, $sAppRoot, $sItopRootRealPath.$sLicenseFileName],
|
||||
'unexisting file' => [$sAppRoot.'license_DOES_NOT_EXIST.txt', $sAppRoot, false],
|
||||
'/'.$sLicenseFileName => [$sAppRoot.$sSep.$sLicenseFileName, $sAppRoot, $sItopRootRealPath.$sLicenseFileName],
|
||||
'%2f'.$sLicenseFileName => [$sAppRoot.'%2f'. $sLicenseFileName, $sAppRoot, false],
|
||||
'%2f'.$sLicenseFileName => [$sAppRoot.'%2f'.$sLicenseFileName, $sAppRoot, false],
|
||||
'../'.$sLicenseFileName => [$sAppRoot.'..'.$sSep.$sLicenseFileName, $sAppRoot, false],
|
||||
'%2e%2e%2f'.$sLicenseFileName => [$sAppRoot.'%2e%2e%2f'.$sLicenseFileName, $sAppRoot, false],
|
||||
'application/utils.inc.php with basepath=APPROOT' => [
|
||||
@@ -132,32 +131,32 @@ class utilsTest extends ItopTestCase
|
||||
public function LocalPathProvider()
|
||||
{
|
||||
$sAppRoot = static::GetAppRoot();
|
||||
return array(
|
||||
'index.php' => array(
|
||||
return [
|
||||
'index.php' => [
|
||||
'sAbsolutePath' => $sAppRoot.'index.php',
|
||||
'expected' => 'index.php',
|
||||
),
|
||||
'non existing' => array(
|
||||
],
|
||||
'non existing' => [
|
||||
'sAbsolutePath' => $sAppRoot.'nonexisting/nonexisting',
|
||||
'expected' => false,
|
||||
),
|
||||
'outside' => array(
|
||||
],
|
||||
'outside' => [
|
||||
'sAbsolutePath' => '/tmp',
|
||||
'expected' => false,
|
||||
),
|
||||
'application/cmdbabstract.class.inc.php' => array(
|
||||
],
|
||||
'application/cmdbabstract.class.inc.php' => [
|
||||
'sAbsolutePath' => $sAppRoot.'application/cmdbabstract.class.inc.php',
|
||||
'expected' => 'application/cmdbabstract.class.inc.php',
|
||||
),
|
||||
'dir' => array(
|
||||
],
|
||||
'dir' => [
|
||||
'sAbsolutePath' => $sAppRoot.'application/.',
|
||||
'expected' => 'application',
|
||||
),
|
||||
'root' => array(
|
||||
],
|
||||
'root' => [
|
||||
'sAbsolutePath' => $sAppRoot.'.',
|
||||
'expected' => '',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,14 +170,15 @@ class utilsTest extends ItopTestCase
|
||||
|
||||
public function appRootUrlProvider()
|
||||
{
|
||||
return array(
|
||||
'Setup index (windows antislash)' => array('http://localhost/', 'C:\Dev\wamp64\www\itop-dev\setup\index.php', 'C:\Dev\wamp64\www\itop-dev', 'http://localhost/setup/'),
|
||||
'Setup index (windows slash)' => array('http://127.0.0.1/', 'C:/web/setup/index.php', 'C:/web', 'http://127.0.0.1/setup/'),
|
||||
'Setup index (windows slash, drive letter case difference)' => array('http://127.0.0.1/', 'c:/web/setup/index.php', 'C:/web', 'http://127.0.0.1/setup/'),
|
||||
);
|
||||
return [
|
||||
'Setup index (windows antislash)' => ['http://localhost/', 'C:\Dev\wamp64\www\itop-dev\setup\index.php', 'C:\Dev\wamp64\www\itop-dev', 'http://localhost/setup/'],
|
||||
'Setup index (windows slash)' => ['http://127.0.0.1/', 'C:/web/setup/index.php', 'C:/web', 'http://127.0.0.1/setup/'],
|
||||
'Setup index (windows slash, drive letter case difference)' => ['http://127.0.0.1/', 'c:/web/setup/index.php', 'C:/web', 'http://127.0.0.1/setup/'],
|
||||
];
|
||||
}
|
||||
|
||||
public function GetAbsoluteUrlAppRootPersistency() {
|
||||
public function GetAbsoluteUrlAppRootPersistency()
|
||||
{
|
||||
$this->setUp();
|
||||
|
||||
return [
|
||||
@@ -260,7 +260,7 @@ class utilsTest extends ItopTestCase
|
||||
/**
|
||||
* @dataProvider GetAbsoluteUrlAppRootPersistency
|
||||
*/
|
||||
public function testGetAbsoluteUrlAppRootPersistency($bBehindReverseProxy,$bForceTrustProxy1 ,$sExpectedAppRootUrl1,$bForceTrustProxy2 , $sExpectedAppRootUrl2,$bForceTrustProxy3 , $sExpectedAppRootUrl3)
|
||||
public function testGetAbsoluteUrlAppRootPersistency($bBehindReverseProxy, $bForceTrustProxy1, $sExpectedAppRootUrl1, $bForceTrustProxy2, $sExpectedAppRootUrl2, $bForceTrustProxy3, $sExpectedAppRootUrl3)
|
||||
{
|
||||
// resetting static property for each test pass
|
||||
$this->SetNonPublicStaticProperty(utils::class, 'sAbsoluteUrlAppRootCache', null);
|
||||
@@ -291,7 +291,6 @@ class utilsTest extends ItopTestCase
|
||||
$this->assertEquals($sExpectedAppRootUrl3, utils::GetAbsoluteUrlAppRoot($bForceTrustProxy3));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dataProvider GetDefaultUrlAppRootProvider
|
||||
*/
|
||||
@@ -923,78 +922,78 @@ HTML,
|
||||
'Basic positional with enough args' => [
|
||||
'Format: %1$s, %2$d, %3$s',
|
||||
['Hello', 42, 'World'],
|
||||
'Format: Hello, 42, World'
|
||||
'Format: Hello, 42, World',
|
||||
],
|
||||
'Basic positional with args in different order' => [
|
||||
'Format: %2$s, %1$d, %3$s',
|
||||
[42, 'Hello', 'World'],
|
||||
'Format: Hello, 42, World'
|
||||
'Format: Hello, 42, World',
|
||||
],
|
||||
'Positional with reused specifiers' => [
|
||||
'Format: %1$s, %2$d, %1$s again',
|
||||
['Hello', 42],
|
||||
'Format: Hello, 42, Hello again'
|
||||
'Format: Hello, 42, Hello again',
|
||||
],
|
||||
|
||||
// Missing arguments tests
|
||||
'Missing one positional arg' => [
|
||||
'Format: %1$s, %2$d, %3$s',
|
||||
['Hello', 42],
|
||||
'Format: Hello, 42, %3$s'
|
||||
'Format: Hello, 42, %3$s',
|
||||
],
|
||||
'Missing multiple positional args' => [
|
||||
'Format: %1$s, %2$s, %3$s, %4$s',
|
||||
['Hello'],
|
||||
'Format: Hello, %2$s, %3$s, %4$s'
|
||||
'Format: Hello, %2$s, %3$s, %4$s',
|
||||
],
|
||||
'Missing first positional arg' => [
|
||||
'Format: %1$s, %2$s, %3$s',
|
||||
[],
|
||||
'Format: %1$s, %2$s, %3$s'
|
||||
'Format: %1$s, %2$s, %3$s',
|
||||
],
|
||||
|
||||
|
||||
// Edge cases
|
||||
'Positional with larger numbers' => [
|
||||
'Format: %2$s, %1$d, %3$s, %2$s again',
|
||||
[123456, 'Hello', 'World'],
|
||||
'Format: Hello, 123456, World, Hello again'
|
||||
'Format: Hello, 123456, World, Hello again',
|
||||
],
|
||||
'Positional specifiers with non-sequential indexes' => [
|
||||
'Format: %3$s then %1$s and %5$d',
|
||||
['first', 'second', 'third', 'fourth', 42],
|
||||
'Format: third then first and 42'
|
||||
'Format: third then first and 42',
|
||||
],
|
||||
|
||||
// More complex format specifiers
|
||||
'Positional with format modifiers' => [
|
||||
'Format: %1$\'*10s, %2$04d',
|
||||
['Hello', 42],
|
||||
'Format: *****Hello, 0042'
|
||||
'Format: *****Hello, 0042',
|
||||
],
|
||||
'Positional with various types' => [
|
||||
'Format: String: %1$s, Integer: %2$d, Char: %3$c',
|
||||
['Hello', 42, 65],
|
||||
'Format: String: Hello, Integer: 42, Char: A'
|
||||
'Format: String: Hello, Integer: 42, Char: A',
|
||||
],
|
||||
|
||||
// Testing with non-Latin characters
|
||||
'Positional with UTF-8 characters' => [
|
||||
'Format: %1$s %2$s %3$s',
|
||||
['こんにちは', 'Здравствуйте', '你好'],
|
||||
'Format: こんにちは Здравствуйте 你好'
|
||||
'Format: こんにちは Здравствуйте 你好',
|
||||
],
|
||||
|
||||
// Mixed formats
|
||||
'Mixed positional with complex specifiers' => [
|
||||
'Format: %1$-10s | %2$+d',
|
||||
['Hello', 42],
|
||||
'Format: Hello | +42'
|
||||
'Format: Hello | +42',
|
||||
],
|
||||
'Reused positional indexes with some missing' => [
|
||||
'Format: %1$s %2$d %1$s %3$s %2$d',
|
||||
['Hello', 42],
|
||||
'Format: Hello 42 Hello %3$s 42'
|
||||
]
|
||||
'Format: Hello 42 Hello %3$s 42',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,18 +17,18 @@ class ActionEmailTest extends ItopDataTestCase
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
const CREATE_TEST_ORG = true;
|
||||
public const CREATE_TEST_ORG = true;
|
||||
|
||||
/** @var \ActionEmail|null Temp ActionEmail created for tests */
|
||||
protected static $oActionEmail = null;
|
||||
|
||||
|
||||
/** @var \ormDocument|null Temp ormDocument for tests */
|
||||
protected static $oDocument = null;
|
||||
|
||||
/** @var \UserRequest|null Temp ormDocument for tests */
|
||||
protected static $oUserRequest = null;
|
||||
|
||||
/** @var string[] Dict formatted message, because the Dict class is not available in providers */
|
||||
|
||||
/** @var string[] Dict formatted message, because the Dict class is not available in providers */
|
||||
protected static $aWarningMessages;
|
||||
|
||||
protected function setUp(): void
|
||||
@@ -57,11 +57,11 @@ HTML
|
||||
static::$oDocument = new \ormDocument($sHtml, 'text/html', 'sample.html');
|
||||
static::$oUserRequest = MetaModel::NewObject('UserRequest', [
|
||||
'title' => 'Test UserRequest',
|
||||
'description' => '<p>Multi-line<br/>description</p>'
|
||||
'description' => '<p>Multi-line<br/>description</p>',
|
||||
]);
|
||||
|
||||
static::$aWarningMessages = [
|
||||
'warning-missing-content' => Dict::Format('ActionEmail:content_placeholder_missing', '$content$', Dict::S('Class:ActionEmail/Attribute:body'))
|
||||
'warning-missing-content' => Dict::Format('ActionEmail:content_placeholder_missing', '$content$', Dict::S('Class:ActionEmail/Attribute:body')),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ HTML
|
||||
'subject' => 'Test subject',
|
||||
'body' => 'Test body',
|
||||
]);
|
||||
foreach($aActionFields as $sCode => $value) {
|
||||
foreach ($aActionFields as $sCode => $value) {
|
||||
if ($sCode === 'html_template') {
|
||||
// special case since the data provider cannot create ormDocument objects
|
||||
$oActionEmail->Set($sCode, static::$oDocument);
|
||||
@@ -139,9 +139,9 @@ HTML
|
||||
|
||||
}
|
||||
$oActionEmail->DBInsert();
|
||||
|
||||
|
||||
$oOrg = $this->CreateOrganization('testPrepareMessageContent');
|
||||
|
||||
|
||||
$oContact1 = MetaModel::NewObject('Person', [
|
||||
'name' => 'Person 1',
|
||||
'first_name' => 'PrepareMessageContent',
|
||||
@@ -150,8 +150,7 @@ HTML
|
||||
'notify' => 'yes',
|
||||
]);
|
||||
$oContact1->DBInsert();
|
||||
|
||||
|
||||
|
||||
$oContact2 = MetaModel::NewObject('Person', [
|
||||
'name' => 'Person 2',
|
||||
'first_name' => 'PrepareMessageContent',
|
||||
@@ -160,19 +159,19 @@ HTML
|
||||
'notify' => 'no',
|
||||
]);
|
||||
$oContact2->DBInsert();
|
||||
|
||||
|
||||
$oLog = null;
|
||||
|
||||
|
||||
$aEmailContent = $this->InvokeNonPublicMethod('\ActionEmail', 'PrepareMessageContent', $oActionEmail, [$aContext, &$oLog]);
|
||||
// Normalize the content of the body to simplify the comparison, useful when status == test
|
||||
$aEmailContent['body'] = preg_replace('/title="[^"]+"/', 'title="****"', $aEmailContent['body']);
|
||||
$aEmailContent['body'] = preg_replace('/class="object-ref-link" href="[^"]+"/', 'class="object-ref-link" href="****"', $aEmailContent['body']);
|
||||
$aEmailContent['body'] = preg_replace('/References: <[^>]+>/', 'References: ****', $aEmailContent['body']);
|
||||
foreach($aFieldsToCheck as $sCode => $expectedValue) {
|
||||
foreach ($aFieldsToCheck as $sCode => $expectedValue) {
|
||||
$this->assertEquals($expectedValue, $aEmailContent[$sCode]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function prepareMessageContentProvider()
|
||||
{
|
||||
return [
|
||||
@@ -226,7 +225,7 @@ HTML
|
||||
'simple-body-with-placeholder-TEST-mode' => [
|
||||
'EN US',
|
||||
['body' => '<p>Ticket "$this->title$" created.</p>', 'status' => 'test'],
|
||||
['body' =>
|
||||
['body' =>
|
||||
<<<HTML
|
||||
<div class="email-is-html-content">
|
||||
<p>Ticket "Test UserRequest" created.</p>
|
||||
@@ -259,7 +258,7 @@ HTML
|
||||
'simple-body-with-placeholder_and_template' => [
|
||||
'EN US',
|
||||
['body' => '<p>Ticket "$this->title$" created.</p>', 'html_template' => true],
|
||||
['body' =>
|
||||
['body' =>
|
||||
<<<HTML
|
||||
<body>
|
||||
<table data-something-that-would-be-removed-by-the-sanitizer-through-ckeditor-but-that-will-stay-with-the-template="bar">
|
||||
@@ -298,9 +297,9 @@ HTML
|
||||
$this->assertEquals($aWarnings, $expectedWarnings);
|
||||
} else {
|
||||
// The warning messages are localized, but the provider functions does not
|
||||
// have access to the Dict class, so let's replace the value given by the
|
||||
// have access to the Dict class, so let's replace the value given by the
|
||||
// provider by a statically precomputed and localized message
|
||||
foreach($expectedWarnings as $index => $sMessageKey) {
|
||||
foreach ($expectedWarnings as $index => $sMessageKey) {
|
||||
$expectedWarnings[$index] = static::$aWarningMessages[$sMessageKey];
|
||||
}
|
||||
$this->assertEquals($aWarnings, $expectedWarnings);
|
||||
@@ -313,14 +312,14 @@ HTML
|
||||
'no warnings' => [
|
||||
'<p>Some text here</p>',
|
||||
'<div>$content$</div>',
|
||||
null
|
||||
],
|
||||
null,
|
||||
],
|
||||
'$content$ missing' => [
|
||||
'<p>Some text here</p>',
|
||||
'<div>no placeholder</div>',
|
||||
[ 'warning-missing-content' ]
|
||||
[ 'warning-missing-content' ],
|
||||
],
|
||||
];
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -330,9 +329,9 @@ HTML
|
||||
{
|
||||
$oConfig = utils::GetConfig();
|
||||
$sCurrentEmailAsync = $oConfig->Get('email_asynchronous');
|
||||
|
||||
|
||||
$oConfig->Set('email_asynchronous', $sConfigAsyncValue);
|
||||
|
||||
|
||||
$oActionEmail = MetaModel::NewObject('ActionEmail', [
|
||||
'name' => 'Test action',
|
||||
'status' => 'disabled',
|
||||
@@ -341,46 +340,45 @@ HTML
|
||||
'body' => 'Test body',
|
||||
'asynchronous' => $sActionAsyncValue,
|
||||
]);
|
||||
|
||||
|
||||
self::assertEquals($sExpectedValue, $oActionEmail->IsAsynchronous());
|
||||
|
||||
$oConfig->Set('email_asynchronous', $sCurrentEmailAsync);
|
||||
}
|
||||
|
||||
|
||||
public function asynchronousValuesContentProvider()
|
||||
{
|
||||
return [
|
||||
'ActionEmail is asynchronous' => [
|
||||
'yes',
|
||||
false,
|
||||
true
|
||||
true,
|
||||
],
|
||||
'ActionEmail is not asynchronous' => [
|
||||
'no',
|
||||
true,
|
||||
false
|
||||
false,
|
||||
],
|
||||
'ActionEmail is asynchronous and config is asynchronous' => [
|
||||
'yes',
|
||||
true,
|
||||
true
|
||||
true,
|
||||
],
|
||||
'ActionEmail is not asynchronous and config is not asynchronous' => [
|
||||
'no',
|
||||
false,
|
||||
false
|
||||
false,
|
||||
],
|
||||
'ActionEmail follows global settings, config is not asynchronous' => [
|
||||
'use_global_setting',
|
||||
false,
|
||||
false
|
||||
false,
|
||||
],
|
||||
'ActionEmail follows global settings, config is asynchronous' => [
|
||||
'use_global_setting',
|
||||
true,
|
||||
true
|
||||
true,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,23 +9,28 @@ use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use MetaModel;
|
||||
use UserRequest;
|
||||
|
||||
class AttributeDefinitionTest extends ItopDataTestCase {
|
||||
const CREATE_TEST_ORG = true;
|
||||
class AttributeDefinitionTest extends ItopDataTestCase
|
||||
{
|
||||
public const CREATE_TEST_ORG = true;
|
||||
|
||||
protected function setUp(): void {
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
require_once(APPROOT.'core/attributedef.class.inc.php');
|
||||
|
||||
}
|
||||
|
||||
public function testGetImportColumns(){
|
||||
public function testGetImportColumns()
|
||||
{
|
||||
$oAttributeDefinition = MetaModel::GetAttributeDef("ApplicationSolution", "status");
|
||||
$aImportColumns = $oAttributeDefinition->GetImportColumns();
|
||||
var_dump($aImportColumns);
|
||||
|
||||
$this->assertTrue(is_array($aImportColumns), var_export($aImportColumns, true));
|
||||
$this->assertEquals(["status" => "ENUM('active','inactive') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"],
|
||||
$aImportColumns);
|
||||
$this->assertEquals(
|
||||
["status" => "ENUM('active','inactive') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"],
|
||||
$aImportColumns
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,7 +284,6 @@ PHP
|
||||
self::assertNull($defaultValue, 'Invalid default value for Date attribute should give null default value');
|
||||
}
|
||||
|
||||
|
||||
public function testDateInvalidDefaultReturnsNullAsDefaultValue_Case2()
|
||||
{
|
||||
$oDateAttribute = $this->GivenAttribute(\WorkOrder::class, 'start_date', AttributeDate::class, '"27/01/2025"', false);
|
||||
@@ -337,10 +341,10 @@ PHP
|
||||
'default_value' => $defaultValue,
|
||||
'allowed_values' => null,
|
||||
'depends_on' => [],
|
||||
'always_load_in_tables' => false
|
||||
'always_load_in_tables' => false,
|
||||
]);
|
||||
$oAttribute->SetHostClass($sHostClass);
|
||||
return $oAttribute;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,8 @@ class AttributeImageTest extends ItopDataTestCase
|
||||
/**
|
||||
* Note that we need to reset manually the cache in \utils::GetAbsoluteUrlAppRoot, which is called from \AttributeImage::Get
|
||||
*/
|
||||
private function SetNewAppRootUrl(Config $oConfig, string $sAppRootUrl):void {
|
||||
private function SetNewAppRootUrl(Config $oConfig, string $sAppRootUrl): void
|
||||
{
|
||||
$oConfig->Set('app_root_url', $sAppRootUrl);
|
||||
$this->SetNonPublicStaticProperty(utils::class, 'sAbsoluteUrlAppRootCache', null);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
* @since 3.0.0 N°4515
|
||||
* @used-by \Combodo\iTop\Test\UnitTest\Core\AttributeURLTest
|
||||
*/
|
||||
class AttributeURLDefaultPattern extends AttributeURL {
|
||||
class AttributeURLDefaultPattern extends AttributeURL
|
||||
{
|
||||
public function GetValidationPattern()
|
||||
{
|
||||
/** @noinspection OneTimeUseVariablesInspection */
|
||||
|
||||
@@ -5,7 +5,8 @@ namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
use AttributeURLDefaultPattern;
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
|
||||
class AttributeURLTest extends ItopTestCase {
|
||||
class AttributeURLTest extends ItopTestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
@@ -19,7 +20,7 @@ class AttributeURLTest extends ItopTestCase {
|
||||
*/
|
||||
public function testCheckFormat(string $sUrlValue, int $iExpectedResult): void
|
||||
{
|
||||
$oAttDefUrl = new AttributeURLDefaultPattern('myCode', ["target"=>'_blank', "allowed_values"=>null, "sql"=>'url', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false]);
|
||||
$oAttDefUrl = new AttributeURLDefaultPattern('myCode', ["target" => '_blank', "allowed_values" => null, "sql" => 'url', "default_value" => '', "is_null_allowed" => true, "depends_on" => [], "always_load_in_tables" => false]);
|
||||
$bResult = $oAttDefUrl->CheckFormat($sUrlValue);
|
||||
|
||||
$this->assertSame($iExpectedResult, $bResult);
|
||||
|
||||
@@ -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 => "'<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 => '<Bad', "org_id" => "No match for value '<Bad'",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,26 +226,27 @@ 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],
|
||||
));
|
||||
$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();
|
||||
]);
|
||||
$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();
|
||||
}
|
||||
}
|
||||
$this->debug("oServer->GetKey():".$oServer->GetKey());
|
||||
@@ -269,38 +274,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) {
|
||||
$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",
|
||||
@@ -309,7 +315,7 @@ class BulkChangeTest extends ItopDataTestCase
|
||||
"__STATUS__" => "Issue: ambiguous reconciliation",
|
||||
"__ERRORS__" => "Allowed 'status' value(s): stock,implementation,production,obsolete",
|
||||
],
|
||||
"expectedResultHTML"=>
|
||||
"expectedResultHTML" =>
|
||||
[
|
||||
0 => ">Demo",
|
||||
"org_id" => "n/a",
|
||||
@@ -320,17 +326,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",
|
||||
@@ -342,32 +348,32 @@ 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 => ">ServerTest",
|
||||
2 => "1",
|
||||
3 => "'>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 => ">ServerTest",
|
||||
2 => "1",
|
||||
3 => "'>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",
|
||||
@@ -379,7 +385,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",
|
||||
@@ -393,17 +399,17 @@ class BulkChangeTest extends ItopDataTestCase
|
||||
],
|
||||
],
|
||||
"Case 6 - 3 : Unexpected value (creation)" => [
|
||||
"initData"=>
|
||||
"initData" =>
|
||||
[],
|
||||
"csvData"=>
|
||||
"csvData" =>
|
||||
[["Demo", ">ServerTest", "<svg onclick\"alert(1)\">", ""]],
|
||||
"attributes"=>
|
||||
"attributes" =>
|
||||
["name" => 1, "status" => 2, "purchase_date" => 3],
|
||||
"extKeys"=>
|
||||
"extKeys" =>
|
||||
["org_id" => ["name" => 0]],
|
||||
"reconcilKeys"=>
|
||||
"reconcilKeys" =>
|
||||
["name"],
|
||||
"expectedResult"=>
|
||||
"expectedResult" =>
|
||||
[
|
||||
"id" => "{Id of the server created by the test}",
|
||||
0 => "Demo",
|
||||
@@ -414,7 +420,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",
|
||||
@@ -427,164 +433,162 @@ 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 => '<svg onclick"alert(1)">', 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "updated 1 cols"],
|
||||
0 => "Demo", "org_id" => "3", 1 => '<svg onclick"alert(1)">', 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 => ">ServerTest", 2 => "1", 3 => "production", 4 => "", "__STATUS__" => "updated 1 cols"],
|
||||
0 => "Demo", "org_id" => "3", 1 => ">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 => ">ServerTest", 2 => "1", 3 => "production", 4 => "'date>' is an invalid value", "__STATUS__" => "Issue: wrong date format"],
|
||||
0 => "Demo", "org_id" => "n/a", 1 => ">ServerTest", 2 => "1", 3 => "production", 4 => "'date>' 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 => ">ServerTest", 2 => "1", 3 => "production", 4 => '\'<svg onclick"alert(1)">\' is an invalid value',"__STATUS__" => "Issue: wrong date format"],
|
||||
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"],
|
||||
|
||||
],
|
||||
"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 => ">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",
|
||||
],
|
||||
],
|
||||
"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 => '<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",
|
||||
],
|
||||
],
|
||||
"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 => ">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",
|
||||
],
|
||||
],
|
||||
"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"],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* test $oBulk->Process with new server and new organization datas
|
||||
*
|
||||
@@ -596,35 +600,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();
|
||||
]);
|
||||
$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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -654,9 +659,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());
|
||||
@@ -664,23 +669,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],
|
||||
"extKeys"=>
|
||||
"extKeys" =>
|
||||
["org_id" => ["name" => 0]],
|
||||
"reconcilKeys"=>
|
||||
"reconcilKeys" =>
|
||||
["org_id"],
|
||||
"expectedResult"=>
|
||||
"expectedResult" =>
|
||||
[
|
||||
0 => "Demo",
|
||||
"org_id" => "Invalid value for attribute",
|
||||
@@ -689,7 +695,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",
|
||||
@@ -700,67 +706,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 => ">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"],
|
||||
],
|
||||
"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 => "<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"],
|
||||
],
|
||||
"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 => '<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"],
|
||||
],
|
||||
"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 => '<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"],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -5,18 +5,15 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
|
||||
use BulkExport;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use DBObjectSearch;
|
||||
|
||||
class BulkExportTest extends ItopDataTestCase
|
||||
{
|
||||
const CREATE_TEST_ORG = true;
|
||||
|
||||
public const CREATE_TEST_ORG = true;
|
||||
|
||||
public function OrganizationsForExportProvider()
|
||||
{
|
||||
@@ -45,7 +42,7 @@ EOF;
|
||||
EOF;
|
||||
|
||||
return [
|
||||
'Page1'=>[
|
||||
'Page1' => [
|
||||
'list_org' => [
|
||||
['org1', true],
|
||||
['org2', true],
|
||||
@@ -63,9 +60,9 @@ EOF;
|
||||
],
|
||||
'export_org' => $sExportResultPage1,
|
||||
'nb_pages' => 1,
|
||||
'expected_status' =>'run'
|
||||
'expected_status' => 'run',
|
||||
],
|
||||
'Page2'=>[
|
||||
'Page2' => [
|
||||
'list_org' => [
|
||||
['org1', true],
|
||||
['org2', true],
|
||||
@@ -83,8 +80,8 @@ EOF;
|
||||
],
|
||||
'export_org' => $sExportResultPage2,
|
||||
'nb_pages' => 2,
|
||||
'expected_status' =>'done'
|
||||
]
|
||||
'expected_status' => 'done',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -99,9 +96,12 @@ EOF;
|
||||
* @throws \OQLException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function testExportWithShowObsoleteParam($aListOrg,
|
||||
$sExpectedValue, $iNbPage, $sExpectedStatus)
|
||||
{
|
||||
public function testExportWithShowObsoleteParam(
|
||||
$aListOrg,
|
||||
$sExpectedValue,
|
||||
$iNbPage,
|
||||
$sExpectedStatus
|
||||
) {
|
||||
// Create tests organizations to have enough data (some obsolete)
|
||||
$iFirstOrg = 0;
|
||||
foreach ($aListOrg as $aOrg) {
|
||||
@@ -110,18 +110,18 @@ EOF;
|
||||
$oObj->Set('status', 'inactive');
|
||||
$oObj->DBUpdate();
|
||||
}
|
||||
if($iFirstOrg === 0){
|
||||
if ($iFirstOrg === 0) {
|
||||
$iFirstOrg = $oObj->GetKey();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$aResult = [
|
||||
// Fallback error, just in case
|
||||
'code' => 'error',
|
||||
'percentage' => 100,
|
||||
'message' => "Export not found for token",
|
||||
];
|
||||
|
||||
|
||||
// Prepare status info and for obsolete data to `false` in order to check that we have less organizations
|
||||
// in the export result than we have in DB
|
||||
$aStatusInfo = [
|
||||
@@ -132,15 +132,15 @@ EOF;
|
||||
"sClass" => "Organization",
|
||||
"sAttCode" => "name",
|
||||
"sLabel" => "Name",
|
||||
"sColLabel" => "Name"
|
||||
]
|
||||
"sColLabel" => "Name",
|
||||
],
|
||||
],
|
||||
"text_qualifier" => "\"",
|
||||
"charset" => "ISO-8859-1",
|
||||
"separator" => ",",
|
||||
"date_format" => "Y-m-d H:i:s",
|
||||
"formatted_text" => false,
|
||||
"show_obsolete_data" => false
|
||||
"text_qualifier" => "\"",
|
||||
"charset" => "ISO-8859-1",
|
||||
"separator" => ",",
|
||||
"date_format" => "Y-m-d H:i:s",
|
||||
"formatted_text" => false,
|
||||
"show_obsolete_data" => false,
|
||||
];
|
||||
|
||||
$oSearch = DBObjectSearch::FromOQL('SELECT Organization WHERE id >= '.$iFirstOrg);
|
||||
@@ -154,7 +154,7 @@ EOF;
|
||||
for ($i = 0; $i < $iNbPage; $i++) {
|
||||
$data .= $oExporter->GetNextChunk($aResult);
|
||||
}
|
||||
$this->assertEquals($sExpectedStatus,$aResult['code']);
|
||||
$this->assertEquals($sExpectedStatus, $aResult['code']);
|
||||
$this->assertEquals($sExpectedValue, $data);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
use CMDBSource;
|
||||
@@ -48,79 +47,79 @@ class CMDBSourceTest extends ItopTestCase
|
||||
|
||||
public function compareFieldTypesProvider()
|
||||
{
|
||||
return array(
|
||||
'same datetime types' => array(true, 'DATETIME', 'DATETIME'),
|
||||
'different types' => array(false, 'VARCHAR(255)', 'INT(11)'),
|
||||
'different types, same type options' => array(false, 'VARCHAR(11)', 'INT(11)'),
|
||||
'same int declaration, same case' => array(true, 'INT(11)', 'INT(11)'),
|
||||
'same int declaration, different case on data type' => array(true, 'INT(11)', 'int(11)'),
|
||||
'same enum declaration, same case' => array(
|
||||
return [
|
||||
'same datetime types' => [true, 'DATETIME', 'DATETIME'],
|
||||
'different types' => [false, 'VARCHAR(255)', 'INT(11)'],
|
||||
'different types, same type options' => [false, 'VARCHAR(11)', 'INT(11)'],
|
||||
'same int declaration, same case' => [true, 'INT(11)', 'INT(11)'],
|
||||
'same int declaration, different case on data type' => [true, 'INT(11)', 'int(11)'],
|
||||
'same enum declaration, same case' => [
|
||||
true,
|
||||
"ENUM('error','idle','planned','running')",
|
||||
"ENUM('error','idle','planned','running')",
|
||||
),
|
||||
'same enum declaration, different case on data type' => array(
|
||||
],
|
||||
'same enum declaration, different case on data type' => [
|
||||
true,
|
||||
"ENUM('error','idle','planned','running')",
|
||||
"enum('error','idle','planned','running')",
|
||||
),
|
||||
'same enum declaration, different case on type options' => array(
|
||||
],
|
||||
'same enum declaration, different case on type options' => [
|
||||
false,
|
||||
"ENUM('ERROR','IDLE','planned','running')",
|
||||
"ENUM('error','idle','planned','running')",
|
||||
),
|
||||
'same enum declaration, different case on both data type and type options' => array(
|
||||
],
|
||||
'same enum declaration, different case on both data type and type options' => [
|
||||
false,
|
||||
"ENUM('ERROR','IDLE','planned','running')",
|
||||
"enum('error','idle','planned','running')",
|
||||
),
|
||||
'MariaDB 10.2 nullable datetime' => array(
|
||||
],
|
||||
'MariaDB 10.2 nullable datetime' => [
|
||||
true,
|
||||
'DATETIME',
|
||||
"datetime DEFAULT 'NULL'",
|
||||
),
|
||||
'MariaDB 10.2 nullable text' => array(
|
||||
],
|
||||
'MariaDB 10.2 nullable text' => [
|
||||
true,
|
||||
'TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci',
|
||||
"text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT 'NULL'",
|
||||
),
|
||||
'MariaDB 10.2 nullable unsigned int' => array(
|
||||
],
|
||||
'MariaDB 10.2 nullable unsigned int' => [
|
||||
true,
|
||||
'INT(11) UNSIGNED',
|
||||
"int(11) unsigned DEFAULT 'NULL'",
|
||||
),
|
||||
'MariaDB 10.2 varchar with default value' => array(
|
||||
],
|
||||
'MariaDB 10.2 varchar with default value' => [
|
||||
true,
|
||||
'VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT 0',
|
||||
"varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '0'",
|
||||
),
|
||||
'varchar with default value not at the end' => array(
|
||||
],
|
||||
'varchar with default value not at the end' => [
|
||||
true,
|
||||
"VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT 0 COMMENT 'my comment'",
|
||||
"varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '0' COMMENT 'my comment'",
|
||||
),
|
||||
'MariaDB 10.2 Enum with string default value' => array(
|
||||
],
|
||||
'MariaDB 10.2 Enum with string default value' => [
|
||||
true,
|
||||
"ENUM('error','idle','planned','running') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT 'planned'",
|
||||
"enum('error','idle','planned','running') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT 'planned'",
|
||||
),
|
||||
'MariaDB 10.2 Enum with numeric default value' => array(
|
||||
],
|
||||
'MariaDB 10.2 Enum with numeric default value' => [
|
||||
true,
|
||||
"ENUM('1','2','3') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '1'",
|
||||
"enum('1','2','3') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '1'",
|
||||
),
|
||||
'ENUM with values containing parenthesis' => array(
|
||||
],
|
||||
'ENUM with values containing parenthesis' => [
|
||||
true, // see N°3065 : if having distinct values having parenthesis in enum values will cause comparison to be inexact
|
||||
"ENUM('CSP A','CSP M','NA','OEM(ROC)','OPEN(VL)','RETAIL (Boite)') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",
|
||||
"enum('CSP A','CSP M','NA','OEM(ROC)','OPEN(VL)','RETAIL (Boite)') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",
|
||||
),
|
||||
],
|
||||
// N°3065 before the fix this returned true :(
|
||||
'ENUM with different values, containing parenthesis' => array(
|
||||
'ENUM with different values, containing parenthesis' => [
|
||||
false,
|
||||
"ENUM('value 1 (with parenthesis)','value 2') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",
|
||||
"enum('value 1 (with parenthesis)','value 3') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,7 +203,7 @@ class CMDBSourceTest extends ItopTestCase
|
||||
});
|
||||
DbConnectionWrapper::SetDbConnectionMockForQuery($oMockMysqli);
|
||||
|
||||
$sTestErrorLogPath = APPROOT . 'log/error.phpunit.log';
|
||||
$sTestErrorLogPath = APPROOT.'log/error.phpunit.log';
|
||||
IssueLog::Enable($sTestErrorLogPath);
|
||||
try {
|
||||
$this->InvokeNonPublicStaticMethod(CMDBSource::class, 'LogDeadLock', [$oDeadlockException, true, false]);
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
|
||||
use CMDBSource;
|
||||
use Exception;
|
||||
use IssueLog;
|
||||
@@ -41,7 +40,6 @@ class DeadLockInjection
|
||||
$this->bShowRequest = $bShowRequest;
|
||||
}
|
||||
|
||||
|
||||
public function query($sSQL)
|
||||
{
|
||||
if (utils::StartsWith($sSQL, "SELECT")) {
|
||||
@@ -60,4 +58,4 @@ class DeadLockInjection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -89,8 +90,7 @@ class TransactionsTest extends ItopTestCase
|
||||
$this->debug("---> DBInsert()");
|
||||
try {
|
||||
$oTicket->DBWrite();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// If an exception occurs must be a deadlock
|
||||
$this->assertTrue(CMDBSource::IsDeadlockException($e), $e->getMessage());
|
||||
}
|
||||
@@ -161,7 +161,7 @@ class TransactionsTest extends ItopTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* Test DBUpdate database transaction by provoking deadlock exceptions
|
||||
* Test DBUpdate database transaction by provoking deadlock exceptions
|
||||
*
|
||||
* @dataProvider DBUpdateProvider
|
||||
* @param $iFailAt
|
||||
@@ -210,8 +210,7 @@ class TransactionsTest extends ItopTestCase
|
||||
$this->debug("---> DBUpdate()");
|
||||
try {
|
||||
$oTicket->DBWrite();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// If an exception occurs must be a deadlock
|
||||
$this->assertTrue(CMDBSource::IsDeadlockException($e));
|
||||
}
|
||||
@@ -281,11 +280,10 @@ class TransactionsTest extends ItopTestCase
|
||||
try {
|
||||
DbConnectionWrapper::SetDbConnectionMockForQuery();
|
||||
parent::tearDown();
|
||||
}
|
||||
catch (MySQLTransactionNotClosedException $e) {
|
||||
} catch (MySQLTransactionNotClosedException $e) {
|
||||
if ($this->getName() === 'testTransactionOpenedNotClosed') {
|
||||
$this->debug('Executing the testTransactionOpenNoClose method throws a '.MySQLTransactionNotClosedException::class.' exception in tearDown');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use CSVParser;
|
||||
|
||||
|
||||
class CSVParserTest extends ItopTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
@@ -36,32 +35,29 @@ a2?;?b?;?c?
|
||||
?a?;?b?;?ouf !?
|
||||
spaces trimmed out ; 1234; mac@enroe.com ';
|
||||
|
||||
$aExpectedResult = array(
|
||||
array('line 0, col 0', 'line 0, col 1', 'line 0, col 2'),
|
||||
array('a', 'b', 'c'),
|
||||
array('a', 'b', null),
|
||||
array(' a ', ' b ', ' c '),
|
||||
array('a', 'b', 'c'),
|
||||
array('', '', ''),
|
||||
array('', '', ''),
|
||||
array('a"', 'b', 'c'),
|
||||
array("a1\na2", 'b', 'c'),
|
||||
array('a1,a2', 'b', 'c'),
|
||||
array('a', 'b', "c1,\",c2\n,c3"),
|
||||
array('a', 'b', 'ouf !'),
|
||||
array('spaces trimmed out', '1234', 'mac@enroe.com'),
|
||||
);
|
||||
$aExpectedResult = [
|
||||
['line 0, col 0', 'line 0, col 1', 'line 0, col 2'],
|
||||
['a', 'b', 'c'],
|
||||
['a', 'b', null],
|
||||
[' a ', ' b ', ' c '],
|
||||
['a', 'b', 'c'],
|
||||
['', '', ''],
|
||||
['', '', ''],
|
||||
['a"', 'b', 'c'],
|
||||
["a1\na2", 'b', 'c'],
|
||||
['a1,a2', 'b', 'c'],
|
||||
['a', 'b', "c1,\",c2\n,c3"],
|
||||
['a', 'b', 'ouf !'],
|
||||
['spaces trimmed out', '1234', 'mac@enroe.com'],
|
||||
];
|
||||
|
||||
$oCSVParser = new CSVParser($sDataFile, $sSeparator, $sDelimiter);
|
||||
$aData = $oCSVParser->ToArray(1, null, 0);
|
||||
|
||||
foreach ($aData as $iRow => $aRow)
|
||||
{
|
||||
foreach ($aRow as $iCol => $cellValue)
|
||||
{
|
||||
foreach ($aData as $iRow => $aRow) {
|
||||
foreach ($aRow as $iCol => $cellValue) {
|
||||
$this->assertSame($aExpectedResult[$iRow][$iCol], $cellValue, "Line $iRow, Column $iCol");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,21 +2,18 @@
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
|
||||
use CMDBObject;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use CoreException;
|
||||
use Exception;
|
||||
use MetaModel;
|
||||
|
||||
|
||||
/**
|
||||
* @since 2.7.7 3.0.2 3.1.0 N°3717 tests history objects creation
|
||||
*
|
||||
* @package Combodo\iTop\Test\UnitTest\Core
|
||||
*/
|
||||
|
||||
|
||||
class CMDBObjectTest extends ItopDataTestCase
|
||||
{
|
||||
private $sAdminLogin;
|
||||
@@ -51,8 +48,11 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
$oTestObject->Set('url', 'https://www.combodo.com');
|
||||
$oTestObject->DBWrite();
|
||||
self::assertFalse(CMDBObject::GetCurrentChange()->IsNew(), 'TrackInfo : Current change persisted');
|
||||
self::assertEquals($sTrackInfo, CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : current change created with expected trackinfo');
|
||||
self::assertEquals(
|
||||
$sTrackInfo,
|
||||
CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : current change created with expected trackinfo'
|
||||
);
|
||||
|
||||
//-- new object with non persisted current change
|
||||
$sTrackInfo2 = $sTrackInfo.'_2';
|
||||
@@ -64,8 +64,11 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
$oTestObject->Set('url', 'https://fr.wikipedia.org');
|
||||
$oTestObject->DBUpdate();
|
||||
self::assertFalse(CMDBObject::GetCurrentChange()->IsNew(), 'SetCurrentChange : Current change persisted');
|
||||
self::assertEquals($sTrackInfo2, CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'SetCurrentChange : current change created with expected trackinfo');
|
||||
self::assertEquals(
|
||||
$sTrackInfo2,
|
||||
CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'SetCurrentChange : current change created with expected trackinfo'
|
||||
);
|
||||
|
||||
//-- new object with current change init using helper method
|
||||
$sTrackInfo3 = $sTrackInfo.'_3';
|
||||
@@ -73,8 +76,11 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
$oTestObject->Set('url', 'https://en.wikipedia.org');
|
||||
$oTestObject->DBUpdate();
|
||||
self::assertFalse(CMDBObject::GetCurrentChange()->IsNew(), 'SetCurrentChangeFromParams : Current change persisted');
|
||||
self::assertEquals($sTrackInfo3, CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'SetCurrentChangeFromParams : current change created with expected trackinfo');
|
||||
self::assertEquals(
|
||||
$sTrackInfo3,
|
||||
CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'SetCurrentChangeFromParams : current change created with expected trackinfo'
|
||||
);
|
||||
|
||||
// restore initial conditions
|
||||
$oTestObject->DBDelete();
|
||||
@@ -82,7 +88,8 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
CMDBObject::SetTrackInfo($sInitialTrackInfo);
|
||||
}
|
||||
|
||||
public function CurrentChangeUnderImpersonationProvider(){
|
||||
public function CurrentChangeUnderImpersonationProvider()
|
||||
{
|
||||
return [
|
||||
'no track info' => [ 'sTrackInfo' => null ],
|
||||
'track info from approvalbase' => [
|
||||
@@ -99,7 +106,8 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
* @runInSeparateProcess
|
||||
* @dataProvider CurrentChangeUnderImpersonationProvider
|
||||
*/
|
||||
public function testCurrentChangeUnderImpersonation($sTrackInfo=null, $sExpectedChangeLogWhenImpersonation=null) {
|
||||
public function testCurrentChangeUnderImpersonation($sTrackInfo = null, $sExpectedChangeLogWhenImpersonation = null)
|
||||
{
|
||||
$this->CreateTestOrganization();
|
||||
|
||||
$sUid = date('dmYHis');
|
||||
@@ -119,7 +127,7 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
// reset current change
|
||||
CMDBObject::SetCurrentChange(null);
|
||||
|
||||
if (is_null($sTrackInfo)){
|
||||
if (is_null($sTrackInfo)) {
|
||||
CMDBObject::SetTrackInfo(null);
|
||||
} else {
|
||||
$sTrackInfo = $this->ReplaceByFriendlyNames($sTrackInfo, $oAdminUser, $oImpersonatedUser);
|
||||
@@ -127,43 +135,70 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
}
|
||||
|
||||
$this->CreateSimpleObject();
|
||||
if (is_null($sTrackInfo)){
|
||||
self::assertEquals($oAdminUser->GetFriendlyName(), CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : no impersonation');
|
||||
if (is_null($sTrackInfo)) {
|
||||
self::assertEquals(
|
||||
$oAdminUser->GetFriendlyName(),
|
||||
CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : no impersonation'
|
||||
);
|
||||
} else {
|
||||
self::assertEquals($sTrackInfo, CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : no impersonation');
|
||||
self::assertEquals(
|
||||
$sTrackInfo,
|
||||
CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : no impersonation'
|
||||
);
|
||||
}
|
||||
self::assertEquals($oAdminUser->GetKey(), CMDBObject::GetCurrentChange()->Get('user_id'),
|
||||
'TrackInfo : admin userid');
|
||||
self::assertEquals(
|
||||
$oAdminUser->GetKey(),
|
||||
CMDBObject::GetCurrentChange()->Get('user_id'),
|
||||
'TrackInfo : admin userid'
|
||||
);
|
||||
|
||||
\UserRights::Impersonate($sImpersonatedLogin);
|
||||
$this->CreateSimpleObject();
|
||||
|
||||
if (is_null($sExpectedChangeLogWhenImpersonation)){
|
||||
if (is_null($sExpectedChangeLogWhenImpersonation)) {
|
||||
$sExpectedMsg = $this->ReplaceByFriendlyNames("AdminSurName AdminName on behalf of ImpersonatedSurName ImpersonatedName", $oAdminUser, $oImpersonatedUser);
|
||||
self::assertEquals($sExpectedMsg, CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : impersonation');
|
||||
self::assertEquals(
|
||||
$sExpectedMsg,
|
||||
CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : impersonation'
|
||||
);
|
||||
} else {
|
||||
$sExpectedMsg = $this->ReplaceByFriendlyNames($sExpectedChangeLogWhenImpersonation, $oAdminUser, $oImpersonatedUser);
|
||||
self::assertEquals($sExpectedMsg, CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : impersonation');
|
||||
self::assertEquals(
|
||||
$sExpectedMsg,
|
||||
CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : impersonation'
|
||||
);
|
||||
}
|
||||
|
||||
self::assertEquals(null, CMDBObject::GetCurrentChange()->Get('user_id'),
|
||||
'TrackInfo : no userid to force userinfo being displayed on UI caselog side');
|
||||
self::assertEquals(
|
||||
null,
|
||||
CMDBObject::GetCurrentChange()->Get('user_id'),
|
||||
'TrackInfo : no userid to force userinfo being displayed on UI caselog side'
|
||||
);
|
||||
|
||||
\UserRights::Deimpersonate();
|
||||
$this->CreateSimpleObject();
|
||||
if (is_null($sTrackInfo)){
|
||||
self::assertEquals($oAdminUser->GetFriendlyName(), CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : no impersonation');
|
||||
if (is_null($sTrackInfo)) {
|
||||
self::assertEquals(
|
||||
$oAdminUser->GetFriendlyName(),
|
||||
CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : no impersonation'
|
||||
);
|
||||
} else {
|
||||
self::assertEquals($sTrackInfo, CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : no impersonation');
|
||||
self::assertEquals(
|
||||
$sTrackInfo,
|
||||
CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : no impersonation'
|
||||
);
|
||||
}
|
||||
self::assertEquals($oAdminUser->GetKey(), CMDBObject::GetCurrentChange()->Get('user_id'),
|
||||
'TrackInfo : admin userid');
|
||||
self::assertEquals(
|
||||
$oAdminUser->GetKey(),
|
||||
CMDBObject::GetCurrentChange()->Get('user_id'),
|
||||
'TrackInfo : admin userid'
|
||||
);
|
||||
|
||||
// restore initial conditions
|
||||
CMDBObject::SetCurrentChange($oInitialCurrentChange);
|
||||
@@ -196,7 +231,7 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
* @dataProvider RecordObjDeletionProvider
|
||||
*
|
||||
*/
|
||||
public function testRecordObjDeletion( string $sFirstName, string $sName)
|
||||
public function testRecordObjDeletion(string $sFirstName, string $sName)
|
||||
{
|
||||
$oPerson = MetaModel::NewObject('Person', [
|
||||
'first_name' => $sFirstName,
|
||||
@@ -208,39 +243,40 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
$bDeletionOK = true;
|
||||
try {
|
||||
$oDeletionPlan = $this->InvokeNonPublicMethod(CMDBObject::class, 'RecordObjDeletion', $oPerson, [$oPerson->GetKey()]);
|
||||
}
|
||||
catch (CoreException $e) {
|
||||
} catch (CoreException $e) {
|
||||
$bDeletionOK = false;
|
||||
}
|
||||
// We don't need to test the result (truncated string), it's already done in \DBObject::SetTrim() with N°3448
|
||||
$this->assertTrue($bDeletionOK);
|
||||
}
|
||||
|
||||
|
||||
private function ReplaceByFriendlyNames($sMessage, $oAdminUser, $oImpersonatedUser) : string {
|
||||
private function ReplaceByFriendlyNames($sMessage, $oAdminUser, $oImpersonatedUser): string
|
||||
{
|
||||
$sNewMessage = str_replace('AdminSurName AdminName', $oAdminUser->GetFriendlyName(), $sMessage);
|
||||
$sNewMessage = str_replace('ImpersonatedSurName ImpersonatedName', $oImpersonatedUser->GetFriendlyName(), $sNewMessage);
|
||||
return $sNewMessage;
|
||||
}
|
||||
|
||||
private function CreateSimpleObject(){
|
||||
private function CreateSimpleObject()
|
||||
{
|
||||
/** @var \DocumentWeb $oTestObject */
|
||||
$oTestObject = MetaModel::NewObject('DocumentWeb');
|
||||
$oTestObject->Set('name', 'PHPUnit test');
|
||||
$oTestObject->Set('org_id', $this->getTestOrgId() );
|
||||
$oTestObject->Set('org_id', $this->getTestOrgId());
|
||||
$oTestObject->Set('url', 'https://www.combodo.com');
|
||||
$oTestObject->DBWrite();
|
||||
}
|
||||
|
||||
private function CreateUserForImpersonation($sLogin, $sProfileName, $sName, $sSurname): \UserLocal {
|
||||
private function CreateUserForImpersonation($sLogin, $sProfileName, $sName, $sSurname): \UserLocal
|
||||
{
|
||||
/** @var \Person $oPerson */
|
||||
$oPerson = $this->createObject('Person', array(
|
||||
$oPerson = $this->createObject('Person', [
|
||||
'name' => $sName,
|
||||
'first_name' => $sSurname,
|
||||
'org_id' => $this->getTestOrgId(),
|
||||
));
|
||||
]);
|
||||
|
||||
$oProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => $sProfileName), true);
|
||||
$oProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", ['name' => $sProfileName], true);
|
||||
/** @var \UserLocal $oUser */
|
||||
$oUser = $this->CreateUser($sLogin, $oProfile->GetKey(), "1234567Azert@", $oPerson->GetKey());
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -23,6 +24,7 @@ use Server;
|
||||
use Team;
|
||||
use UserRequest;
|
||||
use utils;
|
||||
|
||||
use const EVENT_DB_ABOUT_TO_DELETE;
|
||||
use const EVENT_DB_AFTER_DELETE;
|
||||
use const EVENT_DB_AFTER_WRITE;
|
||||
@@ -35,11 +37,10 @@ use const EVENT_ENUM_TRANSITIONS;
|
||||
|
||||
class CRUDEventTest extends ItopDataTestCase
|
||||
{
|
||||
const USE_TRANSACTION = true;
|
||||
const CREATE_TEST_ORG = true;
|
||||
|
||||
use DBObject\Utils\EventTest;
|
||||
use DBObject\Utils\ClassesWithDebug;
|
||||
public const USE_TRANSACTION = true;
|
||||
public const CREATE_TEST_ORG = true;
|
||||
|
||||
private static string $sLogFile = 'log/test_error_CRUDEventTest.log';
|
||||
|
||||
@@ -447,10 +448,10 @@ class CRUDEventTest extends ItopDataTestCase
|
||||
$oUserRequest->DBInsert();
|
||||
|
||||
// 1 insert for UserRequest, 3 insert for lnkFunctionalCIToTicket
|
||||
$this->AssertEventCountEquals(4,EVENT_DB_COMPUTE_VALUES);
|
||||
$this->AssertEventCountEquals(4,EVENT_DB_CHECK_TO_WRITE);
|
||||
$this->AssertEventCountEquals(4,EVENT_DB_BEFORE_WRITE);
|
||||
$this->AssertEventCountEquals(4,EVENT_DB_AFTER_WRITE);
|
||||
$this->AssertEventCountEquals(4, EVENT_DB_COMPUTE_VALUES);
|
||||
$this->AssertEventCountEquals(4, EVENT_DB_CHECK_TO_WRITE);
|
||||
$this->AssertEventCountEquals(4, EVENT_DB_BEFORE_WRITE);
|
||||
$this->AssertEventCountEquals(4, EVENT_DB_AFTER_WRITE);
|
||||
$this->AssertEventNotReceived(EVENT_DB_LINKS_CHANGED, 'Event must not be fired if host object is created with links');
|
||||
$this->AssertTotalEventCountEquals(16);
|
||||
|
||||
@@ -724,4 +725,4 @@ class CRUDEventTest extends ItopDataTestCase
|
||||
$this->assertArrayNotHasKey('ev_assign', $aTransitions, 'Assign transition should have been removed by EVENT_ENUM_TRANSITIONS handler');
|
||||
$this->assertEquals(1, count($aRefTransitions) - count($aTransitions), 'Only one transition should have been removed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -14,20 +15,20 @@ use IssueLog;
|
||||
use LogChannels;
|
||||
use MetaModel;
|
||||
use utils;
|
||||
|
||||
use const EVENT_DB_LINKS_CHANGED;
|
||||
|
||||
class CRUDEventWithModifiedDataModelTest extends ItopCustomDatamodelTestCase
|
||||
{
|
||||
use EventTest;
|
||||
use ClassesWithDebug;
|
||||
public function GetDatamodelDeltaAbsPath(): string
|
||||
{
|
||||
return __DIR__.'/Delta/dbobjecttest.xml';
|
||||
}
|
||||
|
||||
const USE_TRANSACTION = true;
|
||||
const CREATE_TEST_ORG = false;
|
||||
|
||||
use EventTest;
|
||||
use ClassesWithDebug;
|
||||
public const USE_TRANSACTION = true;
|
||||
public const CREATE_TEST_ORG = false;
|
||||
|
||||
private static string $sLogFile = 'log/test_error_CRUDEventTest.log';
|
||||
|
||||
@@ -79,4 +80,3 @@ class CRUDEventWithModifiedDataModelTest extends ItopCustomDatamodelTestCase
|
||||
$this->AssertEventCountEquals(0, EVENT_DB_LINKS_CHANGED, 'Event EVENT_DB_LINKS_CHANGED should not have been thrown on deleted objects');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
// Copyright (c) 2010-2024 Combodo SAS
|
||||
//
|
||||
// This file is part of iTop.
|
||||
@@ -38,19 +39,17 @@ use UserRequest;
|
||||
use UserRights;
|
||||
use utils;
|
||||
|
||||
|
||||
/**
|
||||
* @group specificOrgInSampleData
|
||||
*/
|
||||
class DBObjectTest extends ItopDataTestCase
|
||||
{
|
||||
const CREATE_TEST_ORG = true;
|
||||
const INVALID_OBJECT_KEY = 123456789;
|
||||
public const CREATE_TEST_ORG = true;
|
||||
public const INVALID_OBJECT_KEY = 123456789;
|
||||
|
||||
// Counts
|
||||
public $aReloadCount = [];
|
||||
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
@@ -81,18 +80,18 @@ class DBObjectTest extends ItopDataTestCase
|
||||
|
||||
public function keyProviderOK()
|
||||
{
|
||||
return array(
|
||||
array(1, true),
|
||||
array('255', true),
|
||||
array(-24576, true),
|
||||
array(0123, true),
|
||||
array(0xCAFE, true),
|
||||
array(PHP_INT_MIN, true),
|
||||
array(PHP_INT_MAX, true),
|
||||
array('test', false),
|
||||
array('', false),
|
||||
array('a255', false),
|
||||
array('PHP_INT_MIN', false));
|
||||
return [
|
||||
[1, true],
|
||||
['255', true],
|
||||
[-24576, true],
|
||||
[0123, true],
|
||||
[0xCAFE, true],
|
||||
[PHP_INT_MIN, true],
|
||||
[PHP_INT_MAX, true],
|
||||
['test', false],
|
||||
['', false],
|
||||
['a255', false],
|
||||
['PHP_INT_MIN', false]];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,7 +149,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
*/
|
||||
public function testAttributeRefresh_FriendlyNameWithoutCascade()
|
||||
{
|
||||
$oObject = \MetaModel::NewObject('Person', array('name' => 'Foo', 'first_name' => 'John', 'org_id' => 3, 'location_id' => 2));
|
||||
$oObject = \MetaModel::NewObject('Person', ['name' => 'Foo', 'first_name' => 'John', 'org_id' => 3, 'location_id' => 2]);
|
||||
|
||||
static::assertEquals('John Foo', $oObject->Get('friendlyname'));
|
||||
$oObject->Set('name', 'Who');
|
||||
@@ -179,7 +178,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
*/
|
||||
public function testAttributeRefresh_FriendlyNameFromDB()
|
||||
{
|
||||
$oObject = \MetaModel::NewObject('Person', array('name' => 'Gary', 'first_name' => 'Romain', 'org_id' => 3, 'location_id' => 2));
|
||||
$oObject = \MetaModel::NewObject('Person', ['name' => 'Gary', 'first_name' => 'Romain', 'org_id' => 3, 'location_id' => 2]);
|
||||
$oObject->DBInsert();
|
||||
$iObjKey = $oObject->GetKey();
|
||||
|
||||
@@ -196,7 +195,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
*/
|
||||
public function testPartialAttributeEvaluation()
|
||||
{
|
||||
$oObject = \MetaModel::NewObject('Person', array('name' => 'Foo', 'org_id' => 3, 'location_id' => 2));
|
||||
$oObject = \MetaModel::NewObject('Person', ['name' => 'Foo', 'org_id' => 3, 'location_id' => 2]);
|
||||
static::assertEquals(' Foo', $oObject->Get('friendlyname'));
|
||||
}
|
||||
|
||||
@@ -206,7 +205,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
*/
|
||||
public function testEmptyAttributeEvaluation()
|
||||
{
|
||||
$oObject = \MetaModel::NewObject('Person', array('org_id' => 3, 'location_id' => 2));
|
||||
$oObject = \MetaModel::NewObject('Person', ['org_id' => 3, 'location_id' => 2]);
|
||||
|
||||
static::assertEquals(' ', $oObject->Get('friendlyname'));
|
||||
}
|
||||
@@ -230,7 +229,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
*/
|
||||
public function testAttributeRefresh_ObsolescenceFlagWithoutCascade()
|
||||
{
|
||||
$oObject = \MetaModel::NewObject('Person', array('name' => 'Foo', 'first_name' => 'John', 'org_id' => 3, 'location_id' => 2));
|
||||
$oObject = \MetaModel::NewObject('Person', ['name' => 'Foo', 'first_name' => 'John', 'org_id' => 3, 'location_id' => 2]);
|
||||
|
||||
static::assertEquals(false, (bool)$oObject->Get('obsolescence_flag'));
|
||||
$oObject->Set('status', 'inactive');
|
||||
@@ -262,26 +261,26 @@ class DBObjectTest extends ItopDataTestCase
|
||||
*/
|
||||
public function testAttributeRefresh_ExternalKeysAndFields()
|
||||
{
|
||||
$this->assertDBQueryCount(0, function() use (&$oObject){
|
||||
$oObject = \MetaModel::NewObject('Person', array('name' => 'Foo', 'first_name' => 'John', 'org_id' => 3, 'location_id' => 2));
|
||||
$this->assertDBQueryCount(0, function () use (&$oObject) {
|
||||
$oObject = \MetaModel::NewObject('Person', ['name' => 'Foo', 'first_name' => 'John', 'org_id' => 3, 'location_id' => 2]);
|
||||
});
|
||||
$this->assertDBQueryCount(2, function() use (&$oObject){
|
||||
$this->assertDBQueryCount(2, function () use (&$oObject) {
|
||||
static::assertEquals('Demo', $oObject->Get('org_id_friendlyname'));
|
||||
static::assertEquals('Grenoble', $oObject->Get('location_id_friendlyname'));
|
||||
});
|
||||
|
||||
// External key given as an id
|
||||
$this->assertDBQueryCount(1, function() use (&$oObject){
|
||||
$this->assertDBQueryCount(1, function () use (&$oObject) {
|
||||
$oObject->Set('org_id', 2);
|
||||
static::assertEquals('IT Department', $oObject->Get('org_id_friendlyname'));
|
||||
});
|
||||
|
||||
// External key given as an object
|
||||
$this->assertDBQueryCount(1, function() use (&$oBordeaux){
|
||||
$this->assertDBQueryCount(1, function () use (&$oBordeaux) {
|
||||
$oBordeaux = \MetaModel::GetObject('Location', 1);
|
||||
});
|
||||
|
||||
$this->assertDBQueryCount(0, function() use (&$oBordeaux, &$oObject){
|
||||
$this->assertDBQueryCount(0, function () use (&$oBordeaux, &$oObject) {
|
||||
/** @var DBObject $oObject */
|
||||
$oObject->Set('location_id', $oBordeaux);
|
||||
static::assertEquals('IT Department', $oObject->Get('org_id_friendlyname'));
|
||||
@@ -290,7 +289,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
});
|
||||
|
||||
static::assertEquals('Bordeaux', $oObject->Get('location_id_friendlyname'));
|
||||
// static::assertEquals('toto', $oObject->EvaluateExpression(\Expression::FromOQL("CONCAT(org_name, '-', location_id_friendlyname)")));
|
||||
// static::assertEquals('toto', $oObject->EvaluateExpression(\Expression::FromOQL("CONCAT(org_name, '-', location_id_friendlyname)")));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -302,7 +301,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
{
|
||||
$this->ResetReloadCount();
|
||||
|
||||
$this->assertDBQueryCount(0, function() use (&$oObject){
|
||||
$this->assertDBQueryCount(0, function () use (&$oObject) {
|
||||
$oObject = \MetaModel::NewObject('Person', ['name' => 'Foo', 'first_name' => 'John', 'org_id' => 3, 'location_id' => 2]);
|
||||
});
|
||||
// The number of queries depends on the installed modules so it varies on CI
|
||||
@@ -312,14 +311,14 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$this->debug("Created $sClass::$sKey");
|
||||
$this->DebugReloadCount("Person::DBInsertNoReload()");
|
||||
|
||||
$this->assertDBQueryCount(0, function() use (&$oObject){
|
||||
$this->assertDBQueryCount(0, function () use (&$oObject) {
|
||||
static::assertEquals('Demo', $oObject->Get('org_id_friendlyname'));
|
||||
static::assertEquals('Grenoble', $oObject->Get('location_id_friendlyname'));
|
||||
});
|
||||
$this->DebugReloadCount("Get('org_id_friendlyname') and Get('location_id_friendlyname')");
|
||||
|
||||
// External key given as an id
|
||||
$this->assertDBQueryCount(1, function() use (&$oObject){
|
||||
$this->assertDBQueryCount(1, function () use (&$oObject) {
|
||||
$oObject->Set('org_id', 2);
|
||||
static::assertEquals('IT Department', $oObject->Get('org_id_friendlyname'));
|
||||
});
|
||||
@@ -327,12 +326,12 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$this->DebugReloadCount("Set('org_id', 2) and Get('org_id_friendlyname')");
|
||||
|
||||
// External key given as an object
|
||||
$this->assertDBQueryCount(1, function() use (&$oBordeaux){
|
||||
$this->assertDBQueryCount(1, function () use (&$oBordeaux) {
|
||||
$oBordeaux = MetaModel::GetObject('Location', 1);
|
||||
});
|
||||
$this->DebugReloadCount("GetObject('Location', 1)");
|
||||
|
||||
$this->assertDBQueryCount(0, function() use (&$oBordeaux, &$oObject){
|
||||
$this->assertDBQueryCount(0, function () use (&$oBordeaux, &$oObject) {
|
||||
$oObject->Set('location_id', $oBordeaux);
|
||||
static::assertEquals('IT Department', $oObject->Get('org_id_friendlyname'));
|
||||
static::assertEquals('IT Department', $oObject->Get('org_name'));
|
||||
@@ -341,7 +340,6 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$this->DebugReloadCount("Set('location_id',...) Get('org_id_friendlyname') Get('org_name') Get('location_id_friendlyname')");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @covers DBObject::NewObject
|
||||
* @covers DBObject::Get
|
||||
@@ -351,7 +349,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
{
|
||||
$this->ResetReloadCount();
|
||||
|
||||
$this->assertDBQueryCount(0, function() use (&$oPerson){
|
||||
$this->assertDBQueryCount(0, function () use (&$oPerson) {
|
||||
$oPerson = MetaModel::NewObject('Person', ['name' => 'Foo', 'first_name' => 'John', 'org_id' => 3, 'location_id' => 2]);
|
||||
});
|
||||
// The number of queries depends on the installed modules so it varies on CI
|
||||
@@ -361,7 +359,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$this->debug("Created $sPersonClass::$sPersonKey");
|
||||
$this->DebugReloadCount("Person::DBInsertNoReload()");
|
||||
|
||||
$this->assertDBQueryCount(1, function() use (&$oTeam, &$oPerson){
|
||||
$this->assertDBQueryCount(1, function () use (&$oTeam, &$oPerson) {
|
||||
$oTeam = MetaModel::NewObject('Team', ['name' => 'Team Foo', 'org_id' => 3]);
|
||||
// Add person to team
|
||||
$oNewLink = new lnkPersonToTeam();
|
||||
@@ -387,7 +385,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$this->assertCount(0, $oTeam->ListChanges());
|
||||
|
||||
// External key given as an id
|
||||
$this->assertDBQueryCount(1, function() use (&$oTeam){
|
||||
$this->assertDBQueryCount(1, function () use (&$oTeam) {
|
||||
$oTeam->Set('org_id', 2);
|
||||
static::assertEquals('IT Department', $oTeam->Get('org_id_friendlyname'));
|
||||
});
|
||||
@@ -395,10 +393,9 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$this->assertCount(1, $oTeam->ListChanges());
|
||||
}
|
||||
|
||||
|
||||
public function testSetExtKeyUnsetDependentAttribute()
|
||||
{
|
||||
$oObject = \MetaModel::NewObject('Person', array('name' => 'Foo', 'first_name' => 'John', 'org_id' => 3, 'location_id' => 2));
|
||||
$oObject = \MetaModel::NewObject('Person', ['name' => 'Foo', 'first_name' => 'John', 'org_id' => 3, 'location_id' => 2]);
|
||||
$oOrg = \MetaModel::GetObject('Organization', 2);
|
||||
$oObject->Set('org_id', $oOrg);
|
||||
|
||||
@@ -406,13 +403,13 @@ class DBObjectTest extends ItopDataTestCase
|
||||
static::assertEquals(2, $oObject->Get('location_id'));
|
||||
|
||||
// Dependent external field is updated because the Set('org_id') is done with an object
|
||||
$this->assertDBQueryCount(0, function() use (&$oObject){
|
||||
$this->assertDBQueryCount(0, function () use (&$oObject) {
|
||||
static::assertNotEmpty($oObject->Get('org_name'));
|
||||
});
|
||||
|
||||
// Dependent external field is reset and reloaded from DB
|
||||
$oObject->Set('org_id', 3);
|
||||
$this->assertDBQueryCount(1, function() use (&$oObject){
|
||||
$this->assertDBQueryCount(1, function () use (&$oObject) {
|
||||
static::assertNotEmpty($oObject->Get('org_name'));
|
||||
});
|
||||
}
|
||||
@@ -469,17 +466,16 @@ class DBObjectTest extends ItopDataTestCase
|
||||
*/
|
||||
public function testModelExpressions()
|
||||
{
|
||||
foreach (\MetaModel::GetClasses() as $sClass)
|
||||
{
|
||||
if (\MetaModel::IsAbstract($sClass)) continue;
|
||||
foreach (\MetaModel::GetClasses() as $sClass) {
|
||||
if (\MetaModel::IsAbstract($sClass)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oObject = \MetaModel::NewObject($sClass);
|
||||
foreach (\MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if ($oAttDef->IsBasedOnOQLExpression())
|
||||
{
|
||||
foreach (\MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
|
||||
if ($oAttDef->IsBasedOnOQLExpression()) {
|
||||
$this->debug("$sClass::$sAttCode");
|
||||
$this->assertDBQueryCount(0, function() use (&$oObject, &$oAttDef){
|
||||
$this->assertDBQueryCount(0, function () use (&$oObject, &$oAttDef) {
|
||||
$oObject->EvaluateExpression($oAttDef->GetOQLExpression());
|
||||
});
|
||||
}
|
||||
@@ -602,7 +598,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
|
||||
$oTeam = MetaModel::NewObject(Team::class, [
|
||||
'name' => 'The A Team',
|
||||
'org_id' => $oDemoOrg->GetKey()
|
||||
'org_id' => $oDemoOrg->GetKey(),
|
||||
]);
|
||||
|
||||
// Part 1 - Test with an invalid id (non-existing object)
|
||||
@@ -664,8 +660,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
try {
|
||||
$oTeam->CheckChangedExtKeysValues();
|
||||
$this->fail('An unauthorized object should be detected as invalid');
|
||||
}
|
||||
catch (InvalidExternalKeyValueException $e) {
|
||||
} catch (InvalidExternalKeyValueException $e) {
|
||||
// Ok, the exception was expected
|
||||
}
|
||||
|
||||
@@ -678,8 +673,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$oTeam->DBInsert(); // persisting invalid value and resets the object changed values
|
||||
try {
|
||||
$oTeam->CheckChangedExtKeysValues();
|
||||
}
|
||||
catch (InvalidExternalKeyValueException $e) {
|
||||
} catch (InvalidExternalKeyValueException $e) {
|
||||
$this->fail('An unauthorized value should be ignored when it is not being modified');
|
||||
}
|
||||
}
|
||||
@@ -743,7 +737,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$oQueryOQL = \MetaModel::NewObject('QueryOQL', [
|
||||
'name' => 'Test Query',
|
||||
'description' => 'Test Query',
|
||||
'oql' => 'SELECT Person'
|
||||
'oql' => 'SELECT Person',
|
||||
]);
|
||||
$oQueryOQL->DBInsert();
|
||||
|
||||
@@ -766,12 +760,12 @@ class DBObjectTest extends ItopDataTestCase
|
||||
*/
|
||||
public function getAttributeIntegerDBIncrementProvider()
|
||||
{
|
||||
return array(
|
||||
'Incrementation #1' => array('export_count', [5], 5),
|
||||
'Incrementation #2' => array('export_count', [5, 10], 15),
|
||||
'Incrementation #3' => array('export_count', [50, 20, 10, 100], 180),
|
||||
'Incrementation #4' => array('export_count', [50, 20, -10, 1000], 1060)
|
||||
);
|
||||
return [
|
||||
'Incrementation #1' => ['export_count', [5], 5],
|
||||
'Incrementation #2' => ['export_count', [5, 10], 15],
|
||||
'Incrementation #3' => ['export_count', [50, 20, 10, 100], 180],
|
||||
'Incrementation #4' => ['export_count', [50, 20, -10, 1000], 1060],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -786,7 +780,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$oQueryOQL = \MetaModel::NewObject('QueryOQL', [
|
||||
'name' => 'Test Query',
|
||||
'description' => 'Test Query',
|
||||
'oql' => 'SELECT Person'
|
||||
'oql' => 'SELECT Person',
|
||||
]);
|
||||
$oQueryOQL->DBInsert();
|
||||
|
||||
@@ -809,7 +803,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$oQueryOQL = \MetaModel::NewObject('QueryOQL', [
|
||||
'name' => 'Test Query',
|
||||
'description' => 'Test Query',
|
||||
'oql' => 'SELECT Person'
|
||||
'oql' => 'SELECT Person',
|
||||
]);
|
||||
$oQueryOQL->DBInsert();
|
||||
|
||||
@@ -835,12 +829,12 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$oQueryOQL = \MetaModel::NewObject('QueryOQL', [
|
||||
'name' => 'Test Query',
|
||||
'description' => 'Test Query',
|
||||
'oql' => 'SELECT Person'
|
||||
'oql' => 'SELECT Person',
|
||||
]);
|
||||
$oQueryOQL->DBInsert();
|
||||
|
||||
// assert query count
|
||||
$this->assertDBQueryCount(2, function() use (&$oQueryOQL) {
|
||||
$this->assertDBQueryCount(2, function () use (&$oQueryOQL) {
|
||||
$oQueryOQL->DBIncrement('export_count', 1);
|
||||
});
|
||||
}
|
||||
@@ -976,8 +970,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
try {
|
||||
$oPerson->Set('email', 'test1@combodo.com');
|
||||
$this->assertTrue(false, 'Set() should have raised a CoreException');
|
||||
}
|
||||
catch (\CoreException $e) {
|
||||
} catch (\CoreException $e) {
|
||||
$this->assertEquals($sMessage, $e->getMessage());
|
||||
}
|
||||
|
||||
@@ -1043,9 +1036,9 @@ class DBObjectTest extends ItopDataTestCase
|
||||
'xml',
|
||||
[
|
||||
'ev_assign',
|
||||
'ev_timeout',
|
||||
'ev_wait_for_approval',
|
||||
'ev_autoresolve',
|
||||
'ev_timeout',
|
||||
'ev_wait_for_approval',
|
||||
'ev_autoresolve',
|
||||
],
|
||||
],
|
||||
'UserRequest - XML sort when in specific state' => [
|
||||
@@ -1055,10 +1048,10 @@ class DBObjectTest extends ItopDataTestCase
|
||||
'xml',
|
||||
[
|
||||
'ev_pending',
|
||||
'ev_resolve',
|
||||
'ev_reassign',
|
||||
'ev_timeout',
|
||||
'ev_autoresolve',
|
||||
'ev_resolve',
|
||||
'ev_reassign',
|
||||
'ev_timeout',
|
||||
'ev_autoresolve',
|
||||
],
|
||||
],
|
||||
'UserRequest - Alphabetical (labels not codes) sort' => [
|
||||
@@ -1068,9 +1061,9 @@ class DBObjectTest extends ItopDataTestCase
|
||||
'alphabetical',
|
||||
[
|
||||
'ev_assign',
|
||||
'ev_autoresolve',
|
||||
'ev_timeout',
|
||||
'ev_wait_for_approval',
|
||||
'ev_autoresolve',
|
||||
'ev_timeout',
|
||||
'ev_wait_for_approval',
|
||||
],
|
||||
],
|
||||
'UserRequest - Alphabetical (labels not codes) sort when in specific state' => [
|
||||
@@ -1079,11 +1072,11 @@ class DBObjectTest extends ItopDataTestCase
|
||||
'assigned',
|
||||
'alphabetical',
|
||||
[
|
||||
'ev_autoresolve',
|
||||
'ev_autoresolve',
|
||||
'ev_resolve',
|
||||
'ev_pending',
|
||||
'ev_reassign',
|
||||
'ev_timeout',
|
||||
'ev_pending',
|
||||
'ev_reassign',
|
||||
'ev_timeout',
|
||||
],
|
||||
],
|
||||
'UserRequest - Fixed sort' => [
|
||||
@@ -1092,10 +1085,10 @@ class DBObjectTest extends ItopDataTestCase
|
||||
null,
|
||||
'fixed',
|
||||
[
|
||||
'ev_wait_for_approval',
|
||||
'ev_wait_for_approval',
|
||||
'ev_assign',
|
||||
'ev_timeout',
|
||||
'ev_autoresolve',
|
||||
'ev_timeout',
|
||||
'ev_autoresolve',
|
||||
],
|
||||
],
|
||||
'UserRequest - Fixed sort when in specific state' => [
|
||||
@@ -1115,10 +1108,10 @@ class DBObjectTest extends ItopDataTestCase
|
||||
null,
|
||||
'relative',
|
||||
[
|
||||
'ev_wait_for_approval',
|
||||
'ev_wait_for_approval',
|
||||
'ev_assign',
|
||||
'ev_timeout',
|
||||
'ev_autoresolve',
|
||||
'ev_timeout',
|
||||
'ev_autoresolve',
|
||||
],
|
||||
],
|
||||
'UserRequest - Relative sort when in specific state' => [
|
||||
@@ -1210,8 +1203,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$bDeletionOK = true;
|
||||
try {
|
||||
$oDeletionPlan = $oPerson->DBDelete();
|
||||
}
|
||||
catch (CoreException $e) {
|
||||
} catch (CoreException $e) {
|
||||
$bDeletionOK = false;
|
||||
}
|
||||
$this->assertTrue($bDeletionOK);
|
||||
@@ -1263,7 +1255,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
/**
|
||||
* @since 3.1.0-3 3.1.1 3.2.0 N°6716 test creation
|
||||
*/
|
||||
public function testConstructorMemoryFootprint():void
|
||||
public function testConstructorMemoryFootprint(): void
|
||||
{
|
||||
$idx = 0;
|
||||
$fStart = microtime(true);
|
||||
@@ -1285,7 +1277,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$sCurrPeak = \utils::BytesToFriendlyFormat($iMemoryPeakUsage, 4);
|
||||
echo "$idx ".sprintf('%.1f ms', $fDuration * 1000)." - Peak Memory Usage: $sCurrPeak\n";
|
||||
|
||||
$this->assertTrue(($iMemoryPeakUsage - $iInitialPeak) <= $iMaxAllowedMemoryIncrease , "Peak memory changed from $sInitialPeak to $sCurrPeak after $i loops");
|
||||
$this->assertTrue(($iMemoryPeakUsage - $iInitialPeak) <= $iMaxAllowedMemoryIncrease, "Peak memory changed from $sInitialPeak to $sCurrPeak after $i loops");
|
||||
|
||||
$fStartLoop = microtime(true);
|
||||
}
|
||||
@@ -1335,7 +1327,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$sPrefix = 'a'; // just a small prefix so that the emoji bytes won't have a power of 2 (we want a non even value)
|
||||
$sEmojiToRepeat = '😎'; // this emoji is 4 bytes long
|
||||
$sEmojiRepeats = str_repeat($sEmojiToRepeat, $iValueLength - mb_strlen($sPrefix));
|
||||
$sValueToSet = $sPrefix . $sEmojiRepeats;
|
||||
$sValueToSet = $sPrefix.$sEmojiRepeats;
|
||||
|
||||
$oTicket = MetaModel::NewObject('UserRequest', [
|
||||
'ref' => 'Test Ticket',
|
||||
@@ -1354,14 +1346,14 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$bIsValueToSetBelowAttrMaxSize = ($iValueLength <= $iAttrMaxSize);
|
||||
/** @noinspection PhpUnusedLocalVariableInspection */
|
||||
[$bCheckStatus, $aCheckIssues, $bSecurityIssue] = $oTicket->CheckToWrite();
|
||||
$this->assertEquals($bIsValueToSetBelowAttrMaxSize, $bCheckStatus, "CheckResult result:" . var_export($aCheckIssues, true));
|
||||
$this->assertEquals($bIsValueToSetBelowAttrMaxSize, $bCheckStatus, "CheckResult result:".var_export($aCheckIssues, true));
|
||||
|
||||
$oTicket->SetTrim($sAttrCode, $sValueToSet);
|
||||
$sValueInObject = $oTicket->Get($sAttrCode);
|
||||
if ($bIsValueToSetBelowAttrMaxSize) {
|
||||
$this->assertEquals($sValueToSet, $sValueInObject,'Should not alter string that is already shorter than attribute max length');
|
||||
$this->assertEquals($sValueToSet, $sValueInObject, 'Should not alter string that is already shorter than attribute max length');
|
||||
} else {
|
||||
$this->assertEquals($iAttrMaxSize, mb_strlen($sValueInObject),'Should truncate at the same length than attribute max length');
|
||||
$this->assertEquals($iAttrMaxSize, mb_strlen($sValueInObject), 'Should truncate at the same length than attribute max length');
|
||||
$sLastCharsOfValueInObject = mb_substr($sValueInObject, -30);
|
||||
$this->assertStringContainsString(' -truncated', $sLastCharsOfValueInObject, 'Should end with "truncated" comment');
|
||||
}
|
||||
@@ -1371,13 +1363,13 @@ class DBObjectTest extends ItopDataTestCase
|
||||
{
|
||||
return [
|
||||
'short string should not be truncated' => ['name','name'],
|
||||
'simple ascii string longer than 255 characters truncated' => [
|
||||
str_repeat('e',300),
|
||||
str_repeat('e',232) . ' -truncated (300 chars)'
|
||||
],
|
||||
'simple ascii string longer than 255 characters truncated' => [
|
||||
str_repeat('e', 300),
|
||||
str_repeat('e', 232).' -truncated (300 chars)',
|
||||
],
|
||||
'smiley string longer than 255 characters truncated' => [
|
||||
str_repeat('😃',300),
|
||||
str_repeat('😃',232) . ' -truncated (300 chars)'
|
||||
str_repeat('😃', 300),
|
||||
str_repeat('😃', 232).' -truncated (300 chars)',
|
||||
],
|
||||
|
||||
];
|
||||
@@ -1387,7 +1379,8 @@ class DBObjectTest extends ItopDataTestCase
|
||||
* @dataProvider SetTrimProvider
|
||||
* @return void
|
||||
*/
|
||||
public function testSetTrim($sName, $sResult){
|
||||
public function testSetTrim($sName, $sResult)
|
||||
{
|
||||
$oOrganisation = MetaModel::NewObject(Organization::class);
|
||||
$oOrganisation->SetTrim('name', $sName);
|
||||
$this->assertEquals($sResult, $oOrganisation->Get('name'), 'SetTrim must limit string to 255 characters');
|
||||
@@ -1397,21 +1390,23 @@ class DBObjectTest extends ItopDataTestCase
|
||||
* @covers DBObject::SetComputedDate
|
||||
* @return void
|
||||
*/
|
||||
public function testSetComputedDateOnAttributeDate(){
|
||||
$oObject = MetaModel::NewObject(\CustomerContract::class, ['name'=>'Test contract','org_id'=>'3','provider_id'=>'2']);
|
||||
$oObject->Set('start_date',time());
|
||||
public function testSetComputedDateOnAttributeDate()
|
||||
{
|
||||
$oObject = MetaModel::NewObject(\CustomerContract::class, ['name' => 'Test contract','org_id' => '3','provider_id' => '2']);
|
||||
$oObject->Set('start_date', time());
|
||||
$oObject->SetComputedDate('end_date', "+2 weeks", 'start_date');
|
||||
$this->assertTrue(true,'No fatal error on computing date');
|
||||
$this->assertTrue(true, 'No fatal error on computing date');
|
||||
}
|
||||
/**
|
||||
* @covers DBObject::SetComputedDate
|
||||
* @return void
|
||||
*/
|
||||
public function testSetComputedDateOnAttributeDateTime(){
|
||||
$oObject = MetaModel::NewObject(\WorkOrder::class, ['name'=>'Test workorder','description'=>'Toto']);
|
||||
$oObject->Set('start_date','2024-01-01 09:45:00');
|
||||
public function testSetComputedDateOnAttributeDateTime()
|
||||
{
|
||||
$oObject = MetaModel::NewObject(\WorkOrder::class, ['name' => 'Test workorder','description' => 'Toto']);
|
||||
$oObject->Set('start_date', '2024-01-01 09:45:00');
|
||||
$oObject->SetComputedDate('end_date', "+2 weeks", 'start_date');
|
||||
$this->assertTrue(true,'No fatal error on computing date');
|
||||
$this->assertTrue(true, 'No fatal error on computing date');
|
||||
$this->assertEquals("2024-01-15 09:45:00", $oObject->Get('end_date'), 'SetComputedDate +2 weeks on a WorkOrder DateTimeAttribute');
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -11,6 +12,7 @@ use IssueLog;
|
||||
use LogChannels;
|
||||
use MetaModel;
|
||||
use utils;
|
||||
|
||||
use const EVENT_DB_LINKS_CHANGED;
|
||||
|
||||
class DBObjectWithModifiedDataModelTest extends ItopCustomDatamodelTestCase
|
||||
@@ -20,9 +22,8 @@ class DBObjectWithModifiedDataModelTest extends ItopCustomDatamodelTestCase
|
||||
return __DIR__.'/Delta/dbobjecttest.xml';
|
||||
}
|
||||
|
||||
const USE_TRANSACTION = true;
|
||||
const CREATE_TEST_ORG = false;
|
||||
|
||||
public const USE_TRANSACTION = true;
|
||||
public const CREATE_TEST_ORG = false;
|
||||
|
||||
private static string $sLogFile = 'log/test_error_CRUDEventTest.log';
|
||||
|
||||
@@ -81,4 +82,3 @@ class DBObjectWithModifiedDataModelTest extends ItopCustomDatamodelTestCase
|
||||
$this->assertEquals('resolved', $oParent->Get('status'), 'The status should have been modified to resolved (the final state after a nested stimulus)');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -10,7 +11,6 @@ use Combodo\iTop\Service\Events\EventData;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use MetaModel;
|
||||
|
||||
|
||||
/**
|
||||
* Test support class used to count events received
|
||||
* And allow callbacks on events
|
||||
@@ -51,7 +51,6 @@ class CRUDEventReceiver
|
||||
$this->bDBUpdateCalledSuccessfullyDuringEvent = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Event callbacks => this function counts the received events by event name and source class
|
||||
* If AddCallback() method has been called a specific callback is called, else only the count is done
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -6,11 +7,10 @@
|
||||
|
||||
namespace DBObject\Utils;
|
||||
|
||||
|
||||
/**
|
||||
* Add debug feature to test support class
|
||||
*/
|
||||
Trait ClassesWithDebug
|
||||
trait ClassesWithDebug
|
||||
{
|
||||
public static function DebugStatic($sMsg)
|
||||
{
|
||||
@@ -22,4 +22,4 @@ Trait ClassesWithDebug
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -42,4 +43,4 @@ trait EventTest
|
||||
{
|
||||
$this->assertArrayNotHasKey($sEvent, self::$aEventCallsCount, $sMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -11,7 +12,6 @@ use DBSearch;
|
||||
|
||||
class DBSearchAddConditionPointingToTest extends ItopTestCase
|
||||
{
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
@@ -67,4 +67,4 @@ class DBSearchAddConditionPointingToTest extends ItopTestCase
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Eric
|
||||
@@ -21,7 +22,7 @@ use DBSearch;
|
||||
class DBSearchCommitTest extends ItopDataTestCase
|
||||
{
|
||||
// Need database COMMIT in order to create the FULLTEXT INDEX of MySQL
|
||||
const USE_TRANSACTION = false;
|
||||
public const USE_TRANSACTION = false;
|
||||
|
||||
/**
|
||||
* @group itopFaqLight
|
||||
@@ -47,7 +48,6 @@ class DBSearchCommitTest extends ItopDataTestCase
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
static::assertEquals(1, $oSet->Count());
|
||||
|
||||
|
||||
$oObjWithTagSet->Set(TAG_ATTCODE, 'tag1 tag2');
|
||||
$oObjWithTagSet->DBWrite();
|
||||
|
||||
@@ -80,7 +80,6 @@ class DBSearchCommitTest extends ItopDataTestCase
|
||||
$oSet = new \DBObjectSet($oSearch);
|
||||
static::assertEquals(1, $oSet->Count());
|
||||
|
||||
|
||||
$oObjWithTagSet->Set(TAG_ATTCODE, 'tag1 tag2');
|
||||
$oObjWithTagSet->DBWrite();
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ use DBSearch;
|
||||
*/
|
||||
class DBSearchIntersectTest extends ItopTestCase
|
||||
{
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
@@ -46,104 +45,101 @@ class DBSearchIntersectTest extends ItopTestCase
|
||||
|
||||
public function FilterProvider()
|
||||
{
|
||||
$aTests = array();
|
||||
$aTests = [];
|
||||
|
||||
$aTests['Union filtered by parent class'] = array(
|
||||
$aTests['Union filtered by parent class'] = [
|
||||
'left' => "SELECT ApplicationSolution UNION SELECT BusinessProcess",
|
||||
'right' => "SELECT FunctionalCI WHERE org_id = 3",
|
||||
'alias' => "ApplicationSolution",
|
||||
'result' => "SELECT `ApplicationSolution` FROM ApplicationSolution AS `ApplicationSolution` WHERE (`ApplicationSolution`.`org_id` = 3) UNION SELECT `BusinessProcess` FROM BusinessProcess AS `BusinessProcess` WHERE (`BusinessProcess`.`org_id` = 3)");
|
||||
'result' => "SELECT `ApplicationSolution` FROM ApplicationSolution AS `ApplicationSolution` WHERE (`ApplicationSolution`.`org_id` = 3) UNION SELECT `BusinessProcess` FROM BusinessProcess AS `BusinessProcess` WHERE (`BusinessProcess`.`org_id` = 3)"];
|
||||
|
||||
$aTests['Test union #2902'] = array(
|
||||
$aTests['Test union #2902'] = [
|
||||
'left' => "SELECT `L-1` FROM ServiceFamily AS `L-1` WHERE 1",
|
||||
'right' => "SELECT `sf` FROM ServiceFamily AS `sf` JOIN Service AS `s` ON `s`.servicefamily_id = `sf`.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` = 3) UNION SELECT `sf` FROM ServiceFamily AS `sf` JOIN Service AS `s` ON `s`.servicefamily_id = `sf`.id JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `s`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN Organization AS `child` ON `cc`.org_id = `child`.id JOIN Organization AS `root` ON `child`.parent_id BELOW `root`.id WHERE (`root`.`id` = 3)",
|
||||
'alias' => "L-1",
|
||||
'result' => "SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `s` ON `s`.servicefamily_id = `L-1`.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` = 3) UNION SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `s` ON `s`.servicefamily_id = `L-1`.id JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `s`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN Organization AS `child` ON `cc`.org_id = `child`.id JOIN Organization AS `root` ON `child`.parent_id BELOW `root`.id WHERE (`root`.`id` = 3)");
|
||||
'result' => "SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `s` ON `s`.servicefamily_id = `L-1`.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` = 3) UNION SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `s` ON `s`.servicefamily_id = `L-1`.id JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `s`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN Organization AS `child` ON `cc`.org_id = `child`.id JOIN Organization AS `root` ON `child`.parent_id BELOW `root`.id WHERE (`root`.`id` = 3)"];
|
||||
|
||||
$aTests['Multiple selected classes inverted'] = array(
|
||||
$aTests['Multiple selected classes inverted'] = [
|
||||
'left' => "SELECT `L`, `P` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id WHERE 1",
|
||||
'right' => "SELECT Person WHERE org_id = 3",
|
||||
'alias' => "P",
|
||||
'result' => "SELECT `L`, `P` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id WHERE (`P`.`org_id` = 3)");
|
||||
'result' => "SELECT `L`, `P` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id WHERE (`P`.`org_id` = 3)"];
|
||||
|
||||
$aTests['Multiple selected classes inverted 1'] = array(
|
||||
$aTests['Multiple selected classes inverted 1'] = [
|
||||
'left' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS D ON D.location_id = L.id JOIN Person AS P2 ON P.manager_id = P2.id WHERE 1",
|
||||
'right' => "SELECT Location WHERE org_id = 3",
|
||||
'alias' => "L",
|
||||
'result' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS `D` ON `D`.location_id = `L`.id JOIN Person AS `P2` ON `P`.manager_id = `P2`.id WHERE (`L`.`org_id` = 3)");
|
||||
'result' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS `D` ON `D`.location_id = `L`.id JOIN Person AS `P2` ON `P`.manager_id = `P2`.id WHERE (`L`.`org_id` = 3)"];
|
||||
|
||||
$aTests['Multiple selected classes inverted 2'] = array(
|
||||
$aTests['Multiple selected classes inverted 2'] = [
|
||||
'left' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS D ON D.location_id = L.id JOIN Person AS P2 ON P.manager_id = P2.id WHERE (`L`.`org_id` = 3)",
|
||||
'right' => "SELECT Person WHERE org_id = 3",
|
||||
'alias' => "P",
|
||||
'result' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS `D` ON `D`.location_id = `L`.id JOIN Person AS `P2` ON `P`.manager_id = `P2`.id WHERE ((`L`.`org_id` = 3) AND (`P`.`org_id` = 3))");
|
||||
'result' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS `D` ON `D`.location_id = `L`.id JOIN Person AS `P2` ON `P`.manager_id = `P2`.id WHERE ((`L`.`org_id` = 3) AND (`P`.`org_id` = 3))"];
|
||||
|
||||
$aTests['Same class'] = array(
|
||||
$aTests['Same class'] = [
|
||||
'left' => "SELECT Contact WHERE name = 'Christie'",
|
||||
'right' => "SELECT Contact WHERE org_id = 3",
|
||||
'alias' => "Contact",
|
||||
'result' => "SELECT `Contact` FROM Contact AS `Contact` WHERE ((`Contact`.`name` = 'Christie') AND (`Contact`.`org_id` = 3))");
|
||||
'result' => "SELECT `Contact` FROM Contact AS `Contact` WHERE ((`Contact`.`name` = 'Christie') AND (`Contact`.`org_id` = 3))"];
|
||||
|
||||
$aTests['Different Alias'] = array(
|
||||
$aTests['Different Alias'] = [
|
||||
'left' => "SELECT Contact AS C WHERE C.name = 'Christie'",
|
||||
'right' => "SELECT Contact AS CC WHERE CC.org_id = 3",
|
||||
'alias' => "C",
|
||||
'result' => "SELECT `C` FROM Contact AS `C` WHERE ((`C`.`name` = 'Christie') AND (`C`.`org_id` = 3))");
|
||||
'result' => "SELECT `C` FROM Contact AS `C` WHERE ((`C`.`name` = 'Christie') AND (`C`.`org_id` = 3))"];
|
||||
|
||||
$aTests['Multiple selected classes'] = array(
|
||||
$aTests['Multiple selected classes'] = [
|
||||
'left' => "SELECT `L`, `P` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE 1",
|
||||
'right' => "SELECT Location WHERE org_id = 3",
|
||||
'alias' => "L",
|
||||
'result' => "SELECT `L`, `P` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE (`L`.`org_id` = 3)");
|
||||
'result' => "SELECT `L`, `P` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE (`L`.`org_id` = 3)"];
|
||||
|
||||
$aTests['Joined classes'] = array(
|
||||
$aTests['Joined classes'] = [
|
||||
'left' => "SELECT `L` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE 1",
|
||||
'right' => "SELECT Person WHERE org_id = 3",
|
||||
'alias' => "P",
|
||||
'result' => "SELECT `L` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE (`P`.`org_id` = 3)");
|
||||
'result' => "SELECT `L` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE (`P`.`org_id` = 3)"];
|
||||
|
||||
$aTests['Joined filter'] = array(
|
||||
$aTests['Joined filter'] = [
|
||||
'left' => "SELECT `P` FROM Person AS `P` WHERE 1",
|
||||
'right' => "SELECT `P` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id WHERE `L`.org_id = 3",
|
||||
'alias' => "P",
|
||||
'result' => "SELECT `P` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id WHERE (`L`.`org_id` = 3)");
|
||||
'result' => "SELECT `P` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id WHERE (`L`.`org_id` = 3)"];
|
||||
|
||||
$aTests['Joined filter on joined classes'] = array(
|
||||
$aTests['Joined filter on joined classes'] = [
|
||||
'left' => "SELECT `L` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE 1",
|
||||
'right' => "SELECT Person FROM Person AS Person JOIN Location ON Person.location_id = Location.id WHERE Location.org_id = 3",
|
||||
'alias' => "P",
|
||||
'result' => "SELECT `L` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id JOIN Location AS `Location` ON `P`.location_id = `Location`.id WHERE (`Location`.`org_id` = 3)");
|
||||
'result' => "SELECT `L` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id JOIN Location AS `Location` ON `P`.location_id = `Location`.id WHERE (`Location`.`org_id` = 3)"];
|
||||
|
||||
$aTests['Alias collision'] = array(
|
||||
$aTests['Alias collision'] = [
|
||||
'left' => "SELECT `L` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE 1",
|
||||
'right' => "SELECT Person FROM Person AS Person JOIN Location AS `L` ON Person.location_id = `L`.id WHERE `L`.org_id = 3",
|
||||
'alias' => "P",
|
||||
'result' => "SELECT `L` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id JOIN Location AS `L1` ON `P`.location_id = `L1`.id WHERE (`L1`.`org_id` = 3)");
|
||||
'result' => "SELECT `L` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id JOIN Location AS `L1` ON `P`.location_id = `L1`.id WHERE (`L1`.`org_id` = 3)"];
|
||||
|
||||
$aTests['Test Subclass1'] = array(
|
||||
$aTests['Test Subclass1'] = [
|
||||
'left' => "SELECT `U` FROM UserRequest AS `U` WHERE `U`.agent_id = 3",
|
||||
'right' => "SELECT `Ticket` WHERE org_id = 3",
|
||||
'alias' => "U",
|
||||
'result' => "SELECT `U` FROM UserRequest AS `U` WHERE ((`U`.`agent_id` = 3) AND (`U`.`org_id` = 3))");
|
||||
'result' => "SELECT `U` FROM UserRequest AS `U` WHERE ((`U`.`agent_id` = 3) AND (`U`.`org_id` = 3))"];
|
||||
|
||||
$aTests['Test Subclass and join'] = array(
|
||||
$aTests['Test Subclass and join'] = [
|
||||
'left' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` JOIN Person AS `P` ON `UserRequest`.agent_id = `P`.id WHERE `UserRequest`.agent_id = 3",
|
||||
'right' => "SELECT `Ticket` WHERE org_id = 3",
|
||||
'alias' => "UserRequest",
|
||||
'result' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` JOIN Person AS `P` ON `UserRequest`.agent_id = `P`.id WHERE ((`UserRequest`.`agent_id` = 3) AND (`UserRequest`.`org_id` = 3))");
|
||||
'result' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` JOIN Person AS `P` ON `UserRequest`.agent_id = `P`.id WHERE ((`UserRequest`.`agent_id` = 3) AND (`UserRequest`.`org_id` = 3))"];
|
||||
|
||||
$aTests['Test Subclass and union'] = array(
|
||||
$aTests['Test Subclass and union'] = [
|
||||
'left' => "SELECT `U` FROM UserRequest AS `U` WHERE `U`.agent_id = 3 UNION SELECT `T` FROM Ticket AS `T` WHERE `T`.agent_id = 3 ",
|
||||
'right' => "SELECT `Ticket` WHERE org_id = 3",
|
||||
'alias' => "U",
|
||||
'result' => "SELECT `U` FROM UserRequest AS `U` WHERE ((`U`.`agent_id` = 3) AND (`U`.`org_id` = 3)) UNION SELECT `T` FROM Ticket AS `T` WHERE ((`T`.`agent_id` = 3) AND (`T`.`org_id` = 3))");
|
||||
|
||||
|
||||
'result' => "SELECT `U` FROM UserRequest AS `U` WHERE ((`U`.`agent_id` = 3) AND (`U`.`org_id` = 3)) UNION SELECT `T` FROM Ticket AS `T` WHERE ((`T`.`agent_id` = 3) AND (`T`.`org_id` = 3))"];
|
||||
|
||||
return $aTests;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dataProvider IntersectProvider
|
||||
*
|
||||
@@ -169,47 +165,47 @@ class DBSearchIntersectTest extends ItopTestCase
|
||||
|
||||
public function IntersectProvider()
|
||||
{
|
||||
$aTests = array();
|
||||
$aTests = [];
|
||||
|
||||
$aTests['Nested selects 2'] = array(
|
||||
$aTests['Nested selects 2'] = [
|
||||
'left' => "SELECT `U` FROM UserRequest AS `U` WHERE U.agent_id = 3",
|
||||
'right' => "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`)))",
|
||||
'result' => "SELECT `U` FROM UserRequest AS `U` JOIN Person AS `P` ON `U`.agent_id = `P`.id JOIN Organization AS `Organization` ON `P`.org_id = `Organization`.id WHERE ((`U`.`agent_id` = 3) AND (`U`.`org_id` IN (SELECT `Organization1` FROM Organization AS `Organization1` WHERE (`Organization1`.`id` = `U`.`org_id`))))");
|
||||
'result' => "SELECT `U` FROM UserRequest AS `U` JOIN Person AS `P` ON `U`.agent_id = `P`.id JOIN Organization AS `Organization` ON `P`.org_id = `Organization`.id WHERE ((`U`.`agent_id` = 3) AND (`U`.`org_id` IN (SELECT `Organization1` FROM Organization AS `Organization1` WHERE (`Organization1`.`id` = `U`.`org_id`))))"];
|
||||
|
||||
$aTests['Nested selects'] = array(
|
||||
$aTests['Nested selects'] = [
|
||||
'left' => "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`)))",
|
||||
'right' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE UserRequest.agent_id = 3",
|
||||
'result' => "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 `Organization1` FROM Organization AS `Organization1` WHERE (`Organization1`.`id` = `UserRequest`.`org_id`))) AND (`UserRequest`.`agent_id` = 3))");
|
||||
'result' => "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 `Organization1` FROM Organization AS `Organization1` WHERE (`Organization1`.`id` = `UserRequest`.`org_id`))) AND (`UserRequest`.`agent_id` = 3))"];
|
||||
|
||||
$aTests['Multiple selected classes inverted'] = array(
|
||||
$aTests['Multiple selected classes inverted'] = [
|
||||
'left' => "SELECT `L`, `P` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id WHERE 1",
|
||||
'right' => "SELECT Person WHERE org_id = 3",
|
||||
'result' => "SELECT `L`, `P` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id WHERE (`P`.`org_id` = 3)");
|
||||
'result' => "SELECT `L`, `P` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id WHERE (`P`.`org_id` = 3)"];
|
||||
|
||||
// $aTests['Multiple selected classes inverted 2'] = array(
|
||||
// 'left' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS D ON D.location_id = L.id JOIN Person AS P2 ON P.manager_id = P2.id WHERE (`L`.`org_id` = 3)",
|
||||
// 'right' => "SELECT Person WHERE org_id = 3",
|
||||
// 'result' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS `D` ON `D`.location_id = `L`.id JOIN Person AS `P2` ON `P`.manager_id = `P2`.id WHERE ((`L`.`org_id` = 3) AND (`P`.`org_id` = 3))");
|
||||
// $aTests['Multiple selected classes inverted 2'] = array(
|
||||
// 'left' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS D ON D.location_id = L.id JOIN Person AS P2 ON P.manager_id = P2.id WHERE (`L`.`org_id` = 3)",
|
||||
// 'right' => "SELECT Person WHERE org_id = 3",
|
||||
// 'result' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS `D` ON `D`.location_id = `L`.id JOIN Person AS `P2` ON `P`.manager_id = `P2`.id WHERE ((`L`.`org_id` = 3) AND (`P`.`org_id` = 3))");
|
||||
|
||||
$aTests['Same class'] = array(
|
||||
$aTests['Same class'] = [
|
||||
'left' => "SELECT Contact WHERE name = 'Christie'",
|
||||
'right' => "SELECT Contact WHERE org_id = 3",
|
||||
'result' => "SELECT `Contact` FROM Contact AS `Contact` WHERE ((`Contact`.`name` = 'Christie') AND (`Contact`.`org_id` = 3))");
|
||||
'result' => "SELECT `Contact` FROM Contact AS `Contact` WHERE ((`Contact`.`name` = 'Christie') AND (`Contact`.`org_id` = 3))"];
|
||||
|
||||
$aTests['Different Alias'] = array(
|
||||
$aTests['Different Alias'] = [
|
||||
'left' => "SELECT Contact AS C WHERE C.name = 'Christie'",
|
||||
'right' => "SELECT Contact AS CC WHERE CC.org_id = 3",
|
||||
'result' => "SELECT `C` FROM Contact AS `C` WHERE ((`C`.`name` = 'Christie') AND (`C`.`org_id` = 3))");
|
||||
'result' => "SELECT `C` FROM Contact AS `C` WHERE ((`C`.`name` = 'Christie') AND (`C`.`org_id` = 3))"];
|
||||
|
||||
$aTests['Multiple selected classes'] = array(
|
||||
$aTests['Multiple selected classes'] = [
|
||||
'left' => "SELECT `L`, `P` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE 1",
|
||||
'right' => "SELECT Location WHERE org_id = 3",
|
||||
'result' => "SELECT `L`, `P` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE (`L`.`org_id` = 3)");
|
||||
'result' => "SELECT `L`, `P` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE (`L`.`org_id` = 3)"];
|
||||
|
||||
$aTests['Alias collision'] = array(
|
||||
$aTests['Alias collision'] = [
|
||||
'left' => "SELECT `P` FROM Person AS `P` WHERE 1",
|
||||
'right' => "SELECT `Person` FROM Person AS `Person` JOIN Person AS `P` ON `P`.manager_id = `Person`.id WHERE `P`.org_id = 3",
|
||||
'result' => "SELECT `P` FROM Person AS `P` JOIN Person AS `P1` ON `P1`.manager_id = `P`.id WHERE (`P1`.`org_id` = 3)");
|
||||
'result' => "SELECT `P` FROM Person AS `P` JOIN Person AS `P1` ON `P1`.manager_id = `P`.id WHERE (`P1`.`org_id` = 3)"];
|
||||
|
||||
return $aTests;
|
||||
}
|
||||
@@ -352,100 +348,100 @@ class DBSearchIntersectTest extends ItopTestCase
|
||||
|
||||
public function IntersectOptimizationProvider()
|
||||
{
|
||||
$aQueries = array(
|
||||
'Exact same query' => array(
|
||||
$aQueries = [
|
||||
'Exact same query' => [
|
||||
'Base Query' => 'SELECT s FROM Service AS s JOIN Organization AS o ON s.org_id = o.id WHERE o.name = "The World Company"',
|
||||
'Filter OQL' => 'SELECT s FROM Service AS s JOIN Organization AS o ON s.org_id = o.id WHERE o.name = "The World Company"',
|
||||
'Result ' => "SELECT `s` FROM Service AS `s` JOIN Organization AS `o` ON `s`.org_id = `o`.id WHERE ((`o`.`name` = 'The World Company') AND (`o`.`name` = 'The World Company'))",
|
||||
),
|
||||
'Same query, other aliases' => array(
|
||||
],
|
||||
'Same query, other aliases' => [
|
||||
'Base Query' => 'SELECT s FROM Service AS s JOIN Organization AS o ON s.org_id = o.id WHERE o.name = "The World Company"',
|
||||
'Filter OQL' => 'SELECT s2 FROM Service AS s2 JOIN Organization AS o2 ON s2.org_id = o2.id WHERE o2.name = "The World Company"',
|
||||
'Result ' => "SELECT `s` FROM Service AS `s` JOIN Organization AS `o` ON `s`.org_id = `o`.id WHERE ((`o`.`name` = 'The World Company') AND (`o`.`name` = 'The World Company'))",
|
||||
),
|
||||
'Same aliases, different condition' => array(
|
||||
],
|
||||
'Same aliases, different condition' => [
|
||||
'Base Query' => 'SELECT s FROM Service AS s JOIN Organization AS o ON s.org_id = o.id WHERE o.name = "The World Company"',
|
||||
'Filter OQL' => 'SELECT s FROM Service AS s JOIN Organization AS o ON s.org_id = o.id WHERE o.parent_id = 0',
|
||||
'Result ' => "SELECT `s` FROM Service AS `s` JOIN Organization AS `o` ON `s`.org_id = `o`.id WHERE ((`o`.`name` = 'The World Company') AND (`o`.`parent_id` = 0))",
|
||||
),
|
||||
'Other aliases, different condition' => array(
|
||||
],
|
||||
'Other aliases, different condition' => [
|
||||
'Base Query' => 'SELECT s FROM Service AS s JOIN Organization AS o ON s.org_id = o.id WHERE o.name = "The World Company"',
|
||||
'Filter OQL' => 'SELECT s2 FROM Service AS s2 JOIN Organization AS o2 ON s2.org_id = o2.id WHERE o2.parent_id = 0',
|
||||
'Result ' => "SELECT `s` FROM Service AS `s` JOIN Organization AS `o` ON `s`.org_id = `o`.id WHERE ((`o`.`name` = 'The World Company') AND (`o`.`parent_id` = 0))",
|
||||
),
|
||||
'Same aliases, simpler query tree' => array(
|
||||
],
|
||||
'Same aliases, simpler query tree' => [
|
||||
'Base Query' => 'SELECT s FROM Service AS s JOIN Organization AS o ON s.org_id = o.id WHERE o.name = "The World Company"',
|
||||
'Filter OQL' => 'SELECT s FROM Service AS s WHERE name LIKE "Save the World"',
|
||||
'Result ' => "SELECT `s` FROM Service AS `s` JOIN Organization AS `o` ON `s`.org_id = `o`.id WHERE ((`o`.`name` = 'The World Company') AND (`s`.`name` LIKE 'Save the World'))",
|
||||
),
|
||||
'Other aliases, simpler query tree' => array(
|
||||
],
|
||||
'Other aliases, simpler query tree' => [
|
||||
'Base Query' => 'SELECT s FROM Service AS s JOIN Organization AS o ON s.org_id = o.id WHERE o.name = "The World Company"',
|
||||
'Filter OQL' => 'SELECT s2 FROM Service AS s2 WHERE name LIKE "Save the World"',
|
||||
'Result ' => "SELECT `s` FROM Service AS `s` JOIN Organization AS `o` ON `s`.org_id = `o`.id WHERE ((`o`.`name` = 'The World Company') AND (`s`.`name` LIKE 'Save the World'))",
|
||||
),
|
||||
'Same aliases, different query tree' => array(
|
||||
],
|
||||
'Same aliases, different query tree' => [
|
||||
'Base Query' => 'SELECT s FROM Service AS s JOIN Organization AS o ON s.org_id = o.id WHERE o.name = "The World Company"',
|
||||
'Filter OQL' => 'SELECT s FROM Service AS s JOIN ServiceFamily AS f ON s.servicefamily_id = f.id WHERE s.org_id = 123 AND f.name = "Care"',
|
||||
'Result ' => "SELECT `s` FROM Service AS `s` JOIN Organization AS `o` ON `s`.org_id = `o`.id JOIN ServiceFamily AS `f` ON `s`.servicefamily_id = `f`.id WHERE ((`o`.`name` = 'The World Company') AND ((`s`.`org_id` = 123) AND (`f`.`name` = 'Care')))",
|
||||
),
|
||||
'Other aliases, different query tree' => array(
|
||||
],
|
||||
'Other aliases, different query tree' => [
|
||||
'Base Query' => 'SELECT s FROM Service AS s JOIN Organization AS o ON s.org_id = o.id WHERE o.name = "The World Company"',
|
||||
'Filter OQL' => 'SELECT s2 FROM Service AS s2 JOIN ServiceFamily AS f ON s2.servicefamily_id = f.id WHERE s2.org_id = 123 AND f.name = "Care"',
|
||||
'Result ' => "SELECT `s` FROM Service AS `s` JOIN Organization AS `o` ON `s`.org_id = `o`.id JOIN ServiceFamily AS `f` ON `s`.servicefamily_id = `f`.id WHERE ((`o`.`name` = 'The World Company') AND ((`s`.`org_id` = 123) AND (`f`.`name` = 'Care')))",
|
||||
),
|
||||
],
|
||||
|
||||
'2 - Exact same query' => array(
|
||||
'2 - Exact same query' => [
|
||||
'Base Query' => 'SELECT o FROM Organization AS o JOIN Service AS s ON s.org_id = o.id WHERE s.name = "Help"',
|
||||
'Filter OQL' => 'SELECT o FROM Organization AS o JOIN Service AS s ON s.org_id = o.id WHERE s.name = "Help"',
|
||||
'Result ' => "SELECT `o` FROM Organization AS `o` JOIN Service AS `s` ON `s`.org_id = `o`.id WHERE ((`s`.`name` = 'Help') AND (`s`.`name` = 'Help'))",
|
||||
),
|
||||
'2 - Same query, other aliases' => array(
|
||||
],
|
||||
'2 - Same query, other aliases' => [
|
||||
'Base Query' => 'SELECT o FROM Organization AS o JOIN Service AS s ON s.org_id = o.id WHERE s.name = "Help"',
|
||||
'Filter OQL' => 'SELECT o2 FROM Organization AS o2 JOIN Service AS s2 ON s2.org_id = o2.id WHERE s2.name = "Help"',
|
||||
'Result ' => "SELECT `o` FROM Organization AS `o` JOIN Service AS `s` ON `s`.org_id = `o`.id WHERE ((`s`.`name` = 'Help') AND (`s`.`name` = 'Help'))",
|
||||
),
|
||||
'2 - Same aliases, different condition' => array(
|
||||
],
|
||||
'2 - Same aliases, different condition' => [
|
||||
'Base Query' => 'SELECT o FROM Organization AS o JOIN Service AS s ON s.org_id = o.id WHERE s.name = "Help"',
|
||||
'Filter OQL' => 'SELECT o FROM Organization AS o JOIN Service AS s ON s.org_id = o.id WHERE s.servicefamily_id = 321',
|
||||
'Result ' => "SELECT `o` FROM Organization AS `o` JOIN Service AS `s` ON `s`.org_id = `o`.id WHERE ((`s`.`name` = 'Help') AND (`s`.`servicefamily_id` = 321))",
|
||||
),
|
||||
'2 - Other aliases, different condition' => array(
|
||||
],
|
||||
'2 - Other aliases, different condition' => [
|
||||
'Base Query' => 'SELECT o FROM Organization AS o JOIN Service AS s ON s.org_id = o.id WHERE s.name = "Help"',
|
||||
'Filter OQL' => 'SELECT o2 FROM Organization AS o2 JOIN Service AS s2 ON s2.org_id = o2.id WHERE s2.servicefamily_id = 321',
|
||||
'Result ' => "SELECT `o` FROM Organization AS `o` JOIN Service AS `s` ON `s`.org_id = `o`.id WHERE ((`s`.`name` = 'Help') AND (`s`.`servicefamily_id` = 321))",
|
||||
),
|
||||
'2 - Same aliases, simpler query tree' => array(
|
||||
],
|
||||
'2 - Same aliases, simpler query tree' => [
|
||||
'Base Query' => 'SELECT o FROM Organization AS o JOIN Service AS s ON s.org_id = o.id WHERE s.name = "Help"',
|
||||
'Filter OQL' => 'SELECT o FROM Organization AS o WHERE o.name = "Demo"',
|
||||
'Result ' => "SELECT `o` FROM Organization AS `o` JOIN Service AS `s` ON `s`.org_id = `o`.id WHERE ((`s`.`name` = 'Help') AND (`o`.`name` = 'Demo'))",
|
||||
),
|
||||
'2 - Other aliases, simpler query tree' => array(
|
||||
],
|
||||
'2 - Other aliases, simpler query tree' => [
|
||||
'Base Query' => 'SELECT o FROM Organization AS o JOIN Service AS s ON s.org_id = o.id WHERE s.name = "Help"',
|
||||
'Filter OQL' => 'SELECT o2 FROM Organization AS o2 WHERE o2.name = "Demo"',
|
||||
'Result ' => "SELECT `o` FROM Organization AS `o` JOIN Service AS `s` ON `s`.org_id = `o`.id WHERE ((`s`.`name` = 'Help') AND (`o`.`name` = 'Demo'))",
|
||||
),
|
||||
'2 - Same aliases, different query tree' => array(
|
||||
],
|
||||
'2 - Same aliases, different query tree' => [
|
||||
'Base Query' => 'SELECT o FROM Organization AS o JOIN Service AS s ON s.org_id = o.id WHERE s.name = "Help"',
|
||||
'Filter OQL' => 'SELECT o FROM Organization AS o JOIN Location AS l ON l.org_id = o.id WHERE l.name = "Paris"',
|
||||
'Result ' => "SELECT `o` FROM Organization AS `o` JOIN Service AS `s` ON `s`.org_id = `o`.id JOIN Location AS `l` ON `l`.org_id = `o`.id WHERE ((`s`.`name` = 'Help') AND (`l`.`name` = 'Paris'))",
|
||||
),
|
||||
'2 - Other aliases, different query tree' => array(
|
||||
],
|
||||
'2 - Other aliases, different query tree' => [
|
||||
'Base Query' => 'SELECT o FROM Organization AS o JOIN Service AS s ON s.org_id = o.id WHERE s.name = "Help"',
|
||||
'Filter OQL' => 'SELECT o2 FROM Organization AS o2 JOIN Location AS l ON l.org_id = o2.id WHERE l.name = "Paris"',
|
||||
'Result ' => "SELECT `o` FROM Organization AS `o` JOIN Service AS `s` ON `s`.org_id = `o`.id JOIN Location AS `l` ON `l`.org_id = `o`.id WHERE ((`s`.`name` = 'Help') AND (`l`.`name` = 'Paris'))",
|
||||
),
|
||||
],
|
||||
|
||||
'Internal query optimizations 1' => array(
|
||||
'Internal query optimizations 1' => [
|
||||
'Base Query' => 'SELECT o FROM Organization AS o',
|
||||
'Filter OQL' => 'SELECT o FROM Organization AS o JOIN Location AS l ON l.org_id = o.id JOIN Organization AS p ON o.parent_id = p.id WHERE l.name = "Paris" AND p.code LIKE "toto"',
|
||||
'Result ' => "SELECT `o` FROM Organization AS `o` JOIN Organization AS `p` ON `o`.parent_id = `p`.id JOIN Location AS `l` ON `l`.org_id = `o`.id WHERE ((`l`.`name` = 'Paris') AND (`p`.`code` LIKE 'toto'))",
|
||||
),
|
||||
'Internal query optimizations 2' => array(
|
||||
],
|
||||
'Internal query optimizations 2' => [
|
||||
'Base Query' => 'SELECT r FROM UserRequest AS r JOIN Service AS s ON r.service_id = s.id JOIN Organization AS o ON s.org_id = o.id WHERE o.name = "left_name"',
|
||||
'Filter OQL' => 'SELECT r FROM UserRequest AS r JOIN Service AS s ON r.service_id = s.id JOIN Organization AS o ON s.org_id = o.id WHERE o.name = "right_name"',
|
||||
'Result ' => "SELECT `r` FROM UserRequest AS `r` JOIN Service AS `s` ON `r`.service_id = `s`.id JOIN Organization AS `o` ON `s`.org_id = `o`.id WHERE ((`o`.`name` = 'left_name') AND (`o`.`name` = 'right_name'))",
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
return $aQueries;
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ use DBSearch;
|
||||
*
|
||||
* @package Combodo\iTop\Test\UnitTest\Core
|
||||
*/
|
||||
class DBSearchJoinTest extends ItopDataTestCase {
|
||||
|
||||
const USE_TRANSACTION = false;
|
||||
class DBSearchJoinTest extends ItopDataTestCase
|
||||
{
|
||||
public const USE_TRANSACTION = false;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
@@ -43,9 +43,13 @@ class DBSearchJoinTest extends ItopDataTestCase {
|
||||
|
||||
$aRealiasingMap = [];
|
||||
|
||||
$oResultSearch = $oLeftSearch->Join($oRightSearch,
|
||||
DBSearch::JOIN_REFERENCED_BY, $sParentAtt,
|
||||
TREE_OPERATOR_EQUALS, $aRealiasingMap);
|
||||
$oResultSearch = $oLeftSearch->Join(
|
||||
$oRightSearch,
|
||||
DBSearch::JOIN_REFERENCED_BY,
|
||||
$sParentAtt,
|
||||
TREE_OPERATOR_EQUALS,
|
||||
$aRealiasingMap
|
||||
);
|
||||
|
||||
$this->debug("\nRealiasing Map");
|
||||
$this->debug($aRealiasingMap);
|
||||
@@ -57,12 +61,9 @@ class DBSearchJoinTest extends ItopDataTestCase {
|
||||
$this->debug("\nBefore renaming");
|
||||
$this->debug($oResultSearch->ToOQL());
|
||||
$aLevelsPropertiesKeys = ['L-1', 'L-1-1', 'L-1-1-1'];
|
||||
foreach ($aLevelsPropertiesKeys as $sLevelAlias)
|
||||
{
|
||||
if (array_key_exists($sLevelAlias, $aRealiasingMap))
|
||||
{
|
||||
foreach ($aRealiasingMap[$sLevelAlias] as $sAliasToRename)
|
||||
{
|
||||
foreach ($aLevelsPropertiesKeys as $sLevelAlias) {
|
||||
if (array_key_exists($sLevelAlias, $aRealiasingMap)) {
|
||||
foreach ($aRealiasingMap[$sLevelAlias] as $sAliasToRename) {
|
||||
$oResultSearch->RenameAlias($sAliasToRename, $sLevelAlias);
|
||||
}
|
||||
}
|
||||
@@ -137,11 +138,14 @@ class DBSearchJoinTest extends ItopDataTestCase {
|
||||
|
||||
$oFilter1 = DBSearch::FromOQL($sReq1);
|
||||
$oFilter2 = DBSearch::FromOQL($sReq2);
|
||||
$aRealiasingMap = array();
|
||||
$oFilter1 = $oFilter1->Join($oFilter2,
|
||||
$aRealiasingMap = [];
|
||||
$oFilter1 = $oFilter1->Join(
|
||||
$oFilter2,
|
||||
DBSearch::JOIN_REFERENCED_BY,
|
||||
'org_id',
|
||||
TREE_OPERATOR_EQUALS, $aRealiasingMap);
|
||||
TREE_OPERATOR_EQUALS,
|
||||
$aRealiasingMap
|
||||
);
|
||||
|
||||
$this->debug("\nRealiasing Map");
|
||||
$this->debug($aRealiasingMap);
|
||||
@@ -150,14 +154,10 @@ class DBSearchJoinTest extends ItopDataTestCase {
|
||||
$this->debug("\nJoined");
|
||||
$this->debug($sRes1);
|
||||
|
||||
foreach($oFilter1->GetCriteria_ReferencedBy() as $sForeignClass => $aReferences)
|
||||
{
|
||||
foreach ($aReferences as $sForeignExtKeyAttCode => $aFiltersByOperator)
|
||||
{
|
||||
foreach ($aFiltersByOperator as $iOperatorCode => $aFilters)
|
||||
{
|
||||
foreach ($aFilters as $index => $oForeignFilter)
|
||||
{
|
||||
foreach ($oFilter1->GetCriteria_ReferencedBy() as $sForeignClass => $aReferences) {
|
||||
foreach ($aReferences as $sForeignExtKeyAttCode => $aFiltersByOperator) {
|
||||
foreach ($aFiltersByOperator as $iOperatorCode => $aFilters) {
|
||||
foreach ($aFilters as $index => $oForeignFilter) {
|
||||
$this->debug("\nReferencedBy");
|
||||
$this->debug($oForeignFilter->ToOQL());
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
// Copyright (c) 2010-2024 Combodo SAS
|
||||
//
|
||||
// This file is part of iTop.
|
||||
@@ -26,7 +27,6 @@
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
|
||||
use CMDBSource;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use CoreOqlMultipleResultsForbiddenException;
|
||||
@@ -36,7 +36,6 @@ use Exception;
|
||||
use Expression;
|
||||
use FunctionExpression;
|
||||
|
||||
|
||||
/**
|
||||
* @group itopStorageMgmt
|
||||
* Tests of the DBSearch class.
|
||||
@@ -46,7 +45,7 @@ use FunctionExpression;
|
||||
*/
|
||||
class DBSearchTest extends ItopDataTestCase
|
||||
{
|
||||
const CREATE_TEST_ORG = true;
|
||||
public const CREATE_TEST_ORG = true;
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
@@ -77,25 +76,25 @@ class DBSearchTest extends ItopDataTestCase
|
||||
$oExpr1 = Expression::FromOQL('UserRequest.org_id');
|
||||
|
||||
// Alias => Expression
|
||||
$aGroupBy = array('org_id' => $oExpr1);
|
||||
$aGroupBy = ['org_id' => $oExpr1];
|
||||
|
||||
$oTimeExpr = Expression::FromOQL('UserRequest.time_spent');
|
||||
$oSumExpr = new FunctionExpression('SUM', array($oTimeExpr));
|
||||
$oAvgExpr = new FunctionExpression('AVG', array($oTimeExpr));
|
||||
$oMinExpr = new FunctionExpression('MIN', array($oTimeExpr));
|
||||
$oMaxExpr = new FunctionExpression('MAX', array($oTimeExpr));
|
||||
$oSumExpr = new FunctionExpression('SUM', [$oTimeExpr]);
|
||||
$oAvgExpr = new FunctionExpression('AVG', [$oTimeExpr]);
|
||||
$oMinExpr = new FunctionExpression('MIN', [$oTimeExpr]);
|
||||
$oMaxExpr = new FunctionExpression('MAX', [$oTimeExpr]);
|
||||
// Alias => Expression
|
||||
$aFunctions = array(
|
||||
$aFunctions = [
|
||||
'_itop_sum_' => $oSumExpr,
|
||||
'_itop_avg_' => $oAvgExpr,
|
||||
'_itop_min_' => $oMinExpr,
|
||||
'_itop_max_' => $oMaxExpr,
|
||||
);
|
||||
];
|
||||
|
||||
// Alias => Order
|
||||
$aOrderBy = array('_itop_sum_' => true, '_itop_count_' => true);
|
||||
$aOrderBy = ['_itop_sum_' => true, '_itop_count_' => true];
|
||||
|
||||
$aArgs = array();
|
||||
$aArgs = [];
|
||||
|
||||
$sSQL = $oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy, $iLimit);
|
||||
$this->debug($sSQL);
|
||||
@@ -104,24 +103,22 @@ class DBSearchTest extends ItopDataTestCase
|
||||
$this->debug($aRes);
|
||||
|
||||
self::assertEquals(count($aCountRes), count($aRes));
|
||||
for ($i = 0; $i < count($aCountRes); $i++)
|
||||
{
|
||||
for ($i = 0; $i < count($aCountRes); $i++) {
|
||||
self::assertEquals($aCountRes[$i], $aRes[$i]['_itop_count_']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function UReqProvider()
|
||||
{
|
||||
return array(
|
||||
"1 line" => array(1, 1, array(array(1, 0, 0)), 0, array('1')),
|
||||
"2 same lines" => array(1, 1, array(array(1, 0, 0), array(1, 0, 0)), 0, array('2')),
|
||||
"2 diff lines" => array(2, 2, array(array(1, 0, 0), array(1, 1, 1)), 0, array('1', '1')),
|
||||
"4 lines" => array(2, 2, array(array(1, 0, 0), array(1, 1, 1), array(1, 0, 0), array(1, 1, 1)), 0, array('2', '2')),
|
||||
"5 lines" => array(2, 2, array(array(1, 0, 0), array(1, 0, 0), array(1, 1, 1), array(1, 0, 0), array(1, 1, 1)), 0, array('2', '3')),
|
||||
"6 lines" => array(2, 4, array(array(1, 0, 0), array(1, 1, 3), array(1, 1, 1), array(1, 1, 3), array(1, 0, 2), array(1, 1, 1)), 0, array('2', '4')),
|
||||
"6 lines limit" => array(2, 4, array(array(1, 0, 0), array(1, 1, 3), array(1, 1, 1), array(1, 1, 1), array(1, 0, 0), array(1, 1, 1)), 1, array('2')),
|
||||
);
|
||||
return [
|
||||
"1 line" => [1, 1, [[1, 0, 0]], 0, ['1']],
|
||||
"2 same lines" => [1, 1, [[1, 0, 0], [1, 0, 0]], 0, ['2']],
|
||||
"2 diff lines" => [2, 2, [[1, 0, 0], [1, 1, 1]], 0, ['1', '1']],
|
||||
"4 lines" => [2, 2, [[1, 0, 0], [1, 1, 1], [1, 0, 0], [1, 1, 1]], 0, ['2', '2']],
|
||||
"5 lines" => [2, 2, [[1, 0, 0], [1, 0, 0], [1, 1, 1], [1, 0, 0], [1, 1, 1]], 0, ['2', '3']],
|
||||
"6 lines" => [2, 4, [[1, 0, 0], [1, 1, 3], [1, 1, 1], [1, 1, 3], [1, 0, 2], [1, 1, 1]], 0, ['2', '4']],
|
||||
"6 lines limit" => [2, 4, [[1, 0, 0], [1, 1, 3], [1, 1, 1], [1, 1, 1], [1, 0, 0], [1, 1, 1]], 1, ['2']],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,32 +130,28 @@ class DBSearchTest extends ItopDataTestCase
|
||||
*/
|
||||
private function init_db($iOrgNb, $iPersonNb, $aReq)
|
||||
{
|
||||
$aOrgIds = array();
|
||||
$aOrgIds = [];
|
||||
$sOrgs = '';
|
||||
for($i = 0; $i < $iOrgNb; $i++)
|
||||
{
|
||||
for ($i = 0; $i < $iOrgNb; $i++) {
|
||||
$oObj = $this->CreateOrganization('UnitTest_Org'.$i);
|
||||
$sKey = $oObj->GetKey();
|
||||
$aOrgIds[] = $sKey;
|
||||
if ($i > 0)
|
||||
{
|
||||
if ($i > 0) {
|
||||
$sOrgs .= ",";
|
||||
}
|
||||
$sOrgs .= $sKey;
|
||||
}
|
||||
self::assertEquals($iOrgNb, count($aOrgIds));
|
||||
|
||||
$aPersonIds = array();
|
||||
for($i = 0; $i < $iPersonNb; $i++)
|
||||
{
|
||||
$aPersonIds = [];
|
||||
for ($i = 0; $i < $iPersonNb; $i++) {
|
||||
$oObj = $this->CreatePerson($i, $aOrgIds[$i % $iOrgNb]);
|
||||
$aPersonIds[] = $oObj->GetKey();
|
||||
}
|
||||
self::assertEquals($iPersonNb, count($aPersonIds));
|
||||
|
||||
$i = 0;
|
||||
foreach($aReq as $aParams)
|
||||
{
|
||||
foreach ($aReq as $aParams) {
|
||||
$oObj = $this->CreateUserRequest($i, [
|
||||
'time_spent' => $aParams[0],
|
||||
'org_id' => $aOrgIds[$aParams[1]],
|
||||
@@ -180,31 +173,30 @@ class DBSearchTest extends ItopDataTestCase
|
||||
$this->CreatePhysicalInterface(1, 1000, $oServer->GetKey());
|
||||
$this->CreateFiberChannelInterface(1, 1000, $oServer->GetKey());
|
||||
|
||||
|
||||
$oSearch = DBSearch::FromOQL("SELECT FiberChannelInterface AS FCI WHERE FCI.name = '1' UNION SELECT PhysicalInterface AS PHI WHERE PHI.name = '1'");
|
||||
self::assertNotNull($oSearch);
|
||||
$oExpr1 = Expression::FromOQL('FCI.name');
|
||||
|
||||
// Alias => Expression (first select reference)
|
||||
$aGroupBy = array('group1' => $oExpr1);
|
||||
$aGroupBy = ['group1' => $oExpr1];
|
||||
|
||||
$oTimeExpr = Expression::FromOQL('FCI.speed');
|
||||
$oSumExpr = new FunctionExpression('SUM', array($oTimeExpr));
|
||||
$oAvgExpr = new FunctionExpression('AVG', array($oTimeExpr));
|
||||
$oMinExpr = new FunctionExpression('MIN', array($oTimeExpr));
|
||||
$oMaxExpr = new FunctionExpression('MAX', array($oTimeExpr));
|
||||
$oSumExpr = new FunctionExpression('SUM', [$oTimeExpr]);
|
||||
$oAvgExpr = new FunctionExpression('AVG', [$oTimeExpr]);
|
||||
$oMinExpr = new FunctionExpression('MIN', [$oTimeExpr]);
|
||||
$oMaxExpr = new FunctionExpression('MAX', [$oTimeExpr]);
|
||||
// Alias => Expression
|
||||
$aFunctions = array(
|
||||
$aFunctions = [
|
||||
'_itop_sum_' => $oSumExpr,
|
||||
'_itop_avg_' => $oAvgExpr,
|
||||
'_itop_min_' => $oMinExpr,
|
||||
'_itop_max_' => $oMaxExpr,
|
||||
);
|
||||
];
|
||||
|
||||
// Alias => Order
|
||||
$aOrderBy = array('group1' => true, '_itop_count_' => true);
|
||||
$aOrderBy = ['group1' => true, '_itop_count_' => true];
|
||||
|
||||
$aArgs = array();
|
||||
$aArgs = [];
|
||||
|
||||
$sSQL = $oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy);
|
||||
$this->debug($sSQL);
|
||||
@@ -224,34 +216,34 @@ class DBSearchTest extends ItopDataTestCase
|
||||
|
||||
// Alias => Expression (first select reference)
|
||||
$oExpr1 = Expression::FromOQL('FiberChannelInterface.name');
|
||||
$aGroupBy = array('group1' => $oExpr1);
|
||||
$aGroupBy = ['group1' => $oExpr1];
|
||||
|
||||
$oTimeExpr = Expression::FromOQL('FiberChannelInterface.speed');
|
||||
$oSumExpr = new FunctionExpression('SUM', array($oTimeExpr));
|
||||
$oAvgExpr = new FunctionExpression('AVG', array($oTimeExpr));
|
||||
$oMinExpr = new FunctionExpression('MIN', array($oTimeExpr));
|
||||
$oMaxExpr = new FunctionExpression('MAX', array($oTimeExpr));
|
||||
$oSumExpr = new FunctionExpression('SUM', [$oTimeExpr]);
|
||||
$oAvgExpr = new FunctionExpression('AVG', [$oTimeExpr]);
|
||||
$oMinExpr = new FunctionExpression('MIN', [$oTimeExpr]);
|
||||
$oMaxExpr = new FunctionExpression('MAX', [$oTimeExpr]);
|
||||
// Alias => Expression
|
||||
$aFunctions = array(
|
||||
$aFunctions = [
|
||||
'_itop_sum_' => $oSumExpr,
|
||||
'_itop_avg_' => $oAvgExpr,
|
||||
'_itop_min_' => $oMinExpr,
|
||||
'_itop_max_' => $oMaxExpr,
|
||||
);
|
||||
$aArgs = array();
|
||||
];
|
||||
$aArgs = [];
|
||||
|
||||
// Alias => Order
|
||||
$aOrderBy = array(
|
||||
$aOrderBy = [
|
||||
'group1' => true,
|
||||
'_itop_sum_' => true,
|
||||
'_itop_avg_' => true,
|
||||
'_itop_min_' => true,
|
||||
'_itop_max_' => true);
|
||||
'_itop_max_' => true];
|
||||
$sSQL = $oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy);
|
||||
self::assertNotEmpty($sSQL);
|
||||
|
||||
// Alias => Order
|
||||
$aOrderBy = array('nothing_good' => true);
|
||||
$aOrderBy = ['nothing_good' => true];
|
||||
$this->expectException("CoreException");
|
||||
$oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy);
|
||||
|
||||
@@ -268,29 +260,29 @@ class DBSearchTest extends ItopDataTestCase
|
||||
$oExpr1 = Expression::FromOQL('FCI.name');
|
||||
|
||||
// Alias => Expression (first select reference)
|
||||
$aGroupBy = array('group1' => $oExpr1);
|
||||
$aGroupBy = ['group1' => $oExpr1];
|
||||
|
||||
$oTimeExpr = Expression::FromOQL('FCI.speed');
|
||||
$oSumExpr = new FunctionExpression('SUM', array($oTimeExpr));
|
||||
$oAvgExpr = new FunctionExpression('AVG', array($oTimeExpr));
|
||||
$oMinExpr = new FunctionExpression('MIN', array($oTimeExpr));
|
||||
$oMaxExpr = new FunctionExpression('MAX', array($oTimeExpr));
|
||||
$oSumExpr = new FunctionExpression('SUM', [$oTimeExpr]);
|
||||
$oAvgExpr = new FunctionExpression('AVG', [$oTimeExpr]);
|
||||
$oMinExpr = new FunctionExpression('MIN', [$oTimeExpr]);
|
||||
$oMaxExpr = new FunctionExpression('MAX', [$oTimeExpr]);
|
||||
// Alias => Expression
|
||||
$aFunctions = array(
|
||||
$aFunctions = [
|
||||
'_itop_sum_' => $oSumExpr,
|
||||
'_itop_avg_' => $oAvgExpr,
|
||||
'group1' => $oMinExpr,
|
||||
'_itop_max_' => $oMaxExpr,
|
||||
);
|
||||
$aArgs = array();
|
||||
];
|
||||
$aArgs = [];
|
||||
|
||||
// Alias => Order
|
||||
$aOrderBy = array(
|
||||
$aOrderBy = [
|
||||
'group1' => true,
|
||||
'_itop_sum_' => true,
|
||||
'_itop_avg_' => true,
|
||||
'_itop_min_' => true,
|
||||
'_itop_max_' => true);
|
||||
'_itop_max_' => true];
|
||||
|
||||
$this->expectException("CoreException");
|
||||
$oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy);
|
||||
@@ -308,34 +300,34 @@ class DBSearchTest extends ItopDataTestCase
|
||||
|
||||
// Alias => Expression (first select reference)
|
||||
$oExpr1 = Expression::FromOQL('FCI.name');
|
||||
$aGroupBy = array('group1' => $oExpr1);
|
||||
$aGroupBy = ['group1' => $oExpr1];
|
||||
|
||||
$oTimeExpr = Expression::FromOQL('FCI.speed');
|
||||
$oSumExpr = new FunctionExpression('SUM', array($oTimeExpr));
|
||||
$oAvgExpr = new FunctionExpression('AVG', array($oTimeExpr));
|
||||
$oMinExpr = new FunctionExpression('MIN', array($oTimeExpr));
|
||||
$oMaxExpr = new FunctionExpression('MAX', array($oTimeExpr));
|
||||
$oSumExpr = new FunctionExpression('SUM', [$oTimeExpr]);
|
||||
$oAvgExpr = new FunctionExpression('AVG', [$oTimeExpr]);
|
||||
$oMinExpr = new FunctionExpression('MIN', [$oTimeExpr]);
|
||||
$oMaxExpr = new FunctionExpression('MAX', [$oTimeExpr]);
|
||||
// Alias => Expression
|
||||
$aFunctions = array(
|
||||
$aFunctions = [
|
||||
'_itop_sum_' => $oSumExpr,
|
||||
'_itop_avg_' => $oAvgExpr,
|
||||
'_itop_min_' => $oMinExpr,
|
||||
'_itop_max_' => $oMaxExpr,
|
||||
);
|
||||
$aArgs = array();
|
||||
];
|
||||
$aArgs = [];
|
||||
|
||||
// Alias => Order
|
||||
$aOrderBy = array(
|
||||
$aOrderBy = [
|
||||
'group1' => true,
|
||||
'_itop_sum_' => true,
|
||||
'_itop_avg_' => true,
|
||||
'_itop_min_' => true,
|
||||
'_itop_max_' => true);
|
||||
'_itop_max_' => true];
|
||||
|
||||
$sSQL = $oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy);
|
||||
self::assertNotEmpty($sSQL);
|
||||
|
||||
$aGroupBy = array('group1' => 'FCI.name');
|
||||
$aGroupBy = ['group1' => 'FCI.name'];
|
||||
$this->expectException("CoreException");
|
||||
$oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy);
|
||||
|
||||
@@ -352,39 +344,39 @@ class DBSearchTest extends ItopDataTestCase
|
||||
|
||||
// Alias => Expression (first select reference)
|
||||
$oExpr1 = Expression::FromOQL('FCI.name');
|
||||
$aGroupBy = array('group1' => $oExpr1);
|
||||
$aGroupBy = ['group1' => $oExpr1];
|
||||
|
||||
$oTimeExpr = Expression::FromOQL('FCI.speed');
|
||||
$oSumExpr = new FunctionExpression('SUM', array($oTimeExpr));
|
||||
$oAvgExpr = new FunctionExpression('AVG', array($oTimeExpr));
|
||||
$oMinExpr = new FunctionExpression('MIN', array($oTimeExpr));
|
||||
$oMaxExpr = new FunctionExpression('MAX', array($oTimeExpr));
|
||||
$oSumExpr = new FunctionExpression('SUM', [$oTimeExpr]);
|
||||
$oAvgExpr = new FunctionExpression('AVG', [$oTimeExpr]);
|
||||
$oMinExpr = new FunctionExpression('MIN', [$oTimeExpr]);
|
||||
$oMaxExpr = new FunctionExpression('MAX', [$oTimeExpr]);
|
||||
// Alias => Expression
|
||||
$aFunctions = array(
|
||||
$aFunctions = [
|
||||
'_itop_sum_' => $oSumExpr,
|
||||
'_itop_avg_' => $oAvgExpr,
|
||||
'_itop_min_' => $oMinExpr,
|
||||
'_itop_max_' => $oMaxExpr,
|
||||
);
|
||||
$aArgs = array();
|
||||
];
|
||||
$aArgs = [];
|
||||
|
||||
// Alias => Order
|
||||
$aOrderBy = array(
|
||||
$aOrderBy = [
|
||||
'group1' => true,
|
||||
'_itop_sum_' => true,
|
||||
'_itop_avg_' => true,
|
||||
'_itop_min_' => true,
|
||||
'_itop_max_' => true);
|
||||
'_itop_max_' => true];
|
||||
|
||||
$sSQL = $oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy);
|
||||
self::assertNotEmpty($sSQL);
|
||||
|
||||
$aFunctions = array(
|
||||
$aFunctions = [
|
||||
'_itop_sum_' => 'SumExpr',
|
||||
'_itop_avg_' => $oAvgExpr,
|
||||
'_itop_min_' => $oMinExpr,
|
||||
'_itop_max_' => $oMaxExpr,
|
||||
);
|
||||
];
|
||||
|
||||
$this->expectException("CoreException");
|
||||
$oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy);
|
||||
@@ -402,39 +394,39 @@ class DBSearchTest extends ItopDataTestCase
|
||||
|
||||
// Alias => Expression (first select reference)
|
||||
$oExpr1 = Expression::FromOQL('FCI.name');
|
||||
$aGroupBy = array('group1' => $oExpr1);
|
||||
$aGroupBy = ['group1' => $oExpr1];
|
||||
|
||||
$oTimeExpr = Expression::FromOQL('FCI.speed');
|
||||
$oSumExpr = new FunctionExpression('SUM', array($oTimeExpr));
|
||||
$oAvgExpr = new FunctionExpression('AVG', array($oTimeExpr));
|
||||
$oMinExpr = new FunctionExpression('MIN', array($oTimeExpr));
|
||||
$oMaxExpr = new FunctionExpression('MAX', array($oTimeExpr));
|
||||
$oSumExpr = new FunctionExpression('SUM', [$oTimeExpr]);
|
||||
$oAvgExpr = new FunctionExpression('AVG', [$oTimeExpr]);
|
||||
$oMinExpr = new FunctionExpression('MIN', [$oTimeExpr]);
|
||||
$oMaxExpr = new FunctionExpression('MAX', [$oTimeExpr]);
|
||||
// Alias => Expression
|
||||
$aFunctions = array(
|
||||
$aFunctions = [
|
||||
'_itop_sum_' => $oSumExpr,
|
||||
'_itop_avg_' => $oAvgExpr,
|
||||
'_itop_min_' => $oMinExpr,
|
||||
'_itop_max_' => $oMaxExpr,
|
||||
);
|
||||
$aArgs = array();
|
||||
];
|
||||
$aArgs = [];
|
||||
|
||||
// Alias => Order
|
||||
$aOrderBy = array(
|
||||
$aOrderBy = [
|
||||
'group1' => true,
|
||||
'_itop_sum_' => true,
|
||||
'_itop_avg_' => true,
|
||||
'_itop_min_' => true,
|
||||
'_itop_max_' => true);
|
||||
'_itop_max_' => true];
|
||||
|
||||
$sSQL = $oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy);
|
||||
self::assertNotEmpty($sSQL);
|
||||
|
||||
$aOrderBy = array(
|
||||
$aOrderBy = [
|
||||
'group1' => true,
|
||||
'_itop_sum_' => true,
|
||||
'_itop_avg_' => 'ASC',
|
||||
'_itop_min_' => true,
|
||||
'_itop_max_' => true);
|
||||
'_itop_max_' => true];
|
||||
|
||||
$this->expectException("CoreException");
|
||||
$oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy);
|
||||
@@ -452,34 +444,34 @@ class DBSearchTest extends ItopDataTestCase
|
||||
|
||||
// Alias => Expression (first select reference)
|
||||
$oExpr1 = Expression::FromOQL('FCI.name');
|
||||
$aGroupBy = array('group1' => $oExpr1);
|
||||
$aGroupBy = ['group1' => $oExpr1];
|
||||
|
||||
$oTimeExpr = Expression::FromOQL('FCI.speed');
|
||||
$oSumExpr = new FunctionExpression('SUM', array($oTimeExpr));
|
||||
$oAvgExpr = new FunctionExpression('AVG', array($oTimeExpr));
|
||||
$oMinExpr = new FunctionExpression('MIN', array($oTimeExpr));
|
||||
$oMaxExpr = new FunctionExpression('MAX', array($oTimeExpr));
|
||||
$oSumExpr = new FunctionExpression('SUM', [$oTimeExpr]);
|
||||
$oAvgExpr = new FunctionExpression('AVG', [$oTimeExpr]);
|
||||
$oMinExpr = new FunctionExpression('MIN', [$oTimeExpr]);
|
||||
$oMaxExpr = new FunctionExpression('MAX', [$oTimeExpr]);
|
||||
// Alias => Expression
|
||||
$aFunctions = array(
|
||||
$aFunctions = [
|
||||
'_itop_sum_' => $oSumExpr,
|
||||
'_itop_avg_' => $oAvgExpr,
|
||||
'_itop_min_' => $oMinExpr,
|
||||
'_itop_max_' => $oMaxExpr,
|
||||
);
|
||||
$aArgs = array();
|
||||
];
|
||||
$aArgs = [];
|
||||
|
||||
// Alias => Order
|
||||
$aOrderBy = array(
|
||||
$aOrderBy = [
|
||||
'group1' => true,
|
||||
'_itop_sum_' => true,
|
||||
'_itop_avg_' => true,
|
||||
'_itop_min_' => true,
|
||||
'_itop_max_' => true);
|
||||
'_itop_max_' => true];
|
||||
$sSQL = $oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy);
|
||||
self::assertNotEmpty($sSQL);
|
||||
|
||||
// Alias => Order
|
||||
$aOrderBy = array('nothing_good' => true);
|
||||
$aOrderBy = ['nothing_good' => true];
|
||||
$this->expectException("CoreException");
|
||||
$oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy);
|
||||
|
||||
@@ -493,29 +485,28 @@ class DBSearchTest extends ItopDataTestCase
|
||||
*/
|
||||
public function testNoGroupBy()
|
||||
{
|
||||
$aReq = array(array(1, 0, 0), array(1, 1, 3), array(1, 1, 1), array(1, 1, 1), array(1, 0, 0), array(1, 1, 1));
|
||||
$aReq = [[1, 0, 0], [1, 1, 3], [1, 1, 1], [1, 1, 1], [1, 0, 0], [1, 1, 1]];
|
||||
$sOrgs = $this->init_db(2, 4, $aReq);
|
||||
|
||||
$oSearch = DBSearch::FromOQL("SELECT UserRequest WHERE org_id IN ($sOrgs)");
|
||||
self::assertNotNull($oSearch);
|
||||
|
||||
|
||||
$oTimeExpr = Expression::FromOQL('UserRequest.time_spent');
|
||||
$oSumExpr = new FunctionExpression('SUM', array($oTimeExpr));
|
||||
$oAvgExpr = new FunctionExpression('AVG', array($oTimeExpr));
|
||||
$oMinExpr = new FunctionExpression('MIN', array($oTimeExpr));
|
||||
$oMaxExpr = new FunctionExpression('MAX', array($oTimeExpr));
|
||||
$oSumExpr = new FunctionExpression('SUM', [$oTimeExpr]);
|
||||
$oAvgExpr = new FunctionExpression('AVG', [$oTimeExpr]);
|
||||
$oMinExpr = new FunctionExpression('MIN', [$oTimeExpr]);
|
||||
$oMaxExpr = new FunctionExpression('MAX', [$oTimeExpr]);
|
||||
// Alias => Expression
|
||||
$aFunctions = array(
|
||||
$aFunctions = [
|
||||
'_itop_sum_' => $oSumExpr,
|
||||
'_itop_avg_' => $oAvgExpr,
|
||||
'_itop_min_' => $oMinExpr,
|
||||
'_itop_max_' => $oMaxExpr,
|
||||
);
|
||||
];
|
||||
|
||||
$aGroupBy = array();
|
||||
$aOrderBy = array();
|
||||
$aArgs = array();
|
||||
$aGroupBy = [];
|
||||
$aOrderBy = [];
|
||||
$aArgs = [];
|
||||
|
||||
$sSQL = $oSearch->MakeGroupByQuery($aArgs, $aGroupBy, false, $aFunctions, $aOrderBy, 0);
|
||||
$this->debug($sSQL);
|
||||
@@ -546,18 +537,14 @@ class DBSearchTest extends ItopDataTestCase
|
||||
$oSearch = DBSearch::FromOQL($sOql);
|
||||
|
||||
$bHasThrownException = false;
|
||||
try
|
||||
{
|
||||
try {
|
||||
$oFirstResult = $oSearch->GetFirstResult($bMustHaveOneResultMax);
|
||||
}
|
||||
catch (CoreOqlMultipleResultsForbiddenException $e)
|
||||
{
|
||||
} catch (CoreOqlMultipleResultsForbiddenException $e) {
|
||||
$oFirstResult = null;
|
||||
$bHasThrownException = true;
|
||||
}
|
||||
|
||||
switch ($sReturn)
|
||||
{
|
||||
switch ($sReturn) {
|
||||
case 'exception':
|
||||
self::assertEquals(true, $bHasThrownException, 'Exception raised');
|
||||
break;
|
||||
@@ -572,33 +559,33 @@ class DBSearchTest extends ItopDataTestCase
|
||||
|
||||
public function GetFirstResultProvider()
|
||||
{
|
||||
return array(
|
||||
'One result' => array(
|
||||
return [
|
||||
'One result' => [
|
||||
'SELECT Person WHERE id = 1',
|
||||
false,
|
||||
'object',
|
||||
),
|
||||
'Multiple results, no exception' => array(
|
||||
],
|
||||
'Multiple results, no exception' => [
|
||||
'SELECT Person',
|
||||
false,
|
||||
'object',
|
||||
),
|
||||
'Multiple results, with exception' => array(
|
||||
],
|
||||
'Multiple results, with exception' => [
|
||||
'SELECT Person',
|
||||
true,
|
||||
'exception',
|
||||
),
|
||||
'Multiple results with "WHERE 1", with exception' => array(
|
||||
],
|
||||
'Multiple results with "WHERE 1", with exception' => [
|
||||
'SELECT Person WHERE 1',
|
||||
true,
|
||||
'exception',
|
||||
),
|
||||
'No result' => array(
|
||||
],
|
||||
'No result' => [
|
||||
'SELECT Person WHERE id = -1',
|
||||
true,
|
||||
'null',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -610,14 +597,11 @@ class DBSearchTest extends ItopDataTestCase
|
||||
$oSearch = DBSearch::FromOQL("SELECT FiberChannelInterface AS FCI");
|
||||
self::assertNotNull($oSearch);
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
$oExpr1 = Expression::FromOQL('AVC(FCI.name)');
|
||||
//$aGroupBy = array('group1' => $oExpr1);
|
||||
//$oSearch->MakeGroupByQuery(array(), $aGroupBy, false, array(), array());
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
$sExceptionClass = get_class($e);
|
||||
}
|
||||
|
||||
@@ -627,13 +611,10 @@ class DBSearchTest extends ItopDataTestCase
|
||||
public function testSanity_GroupFunction_In_GroupByPart()
|
||||
{
|
||||
$sExceptionClass = '';
|
||||
try
|
||||
{
|
||||
try {
|
||||
$oSearch = DBSearch::FromOQL("SELECT FiberChannelInterface AS FCI WHERE COUNT(FCI.name) = AVC(FCI.name)");
|
||||
//$oSearch->MakeGroupByQuery(array(), array(), false, array(), array());
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
$sExceptionClass = get_class($e);
|
||||
}
|
||||
|
||||
@@ -643,19 +624,16 @@ class DBSearchTest extends ItopDataTestCase
|
||||
public function testSanity_UnknownGroupFunction_In_SelectPart()
|
||||
{
|
||||
$sExceptionClass = '';
|
||||
try
|
||||
{
|
||||
try {
|
||||
$oTimeExpr = Expression::FromOQL('FCI.speed');
|
||||
$oWrongExpr = new FunctionExpression('GABUZOMEU', array($oTimeExpr));
|
||||
$oWrongExpr = new FunctionExpression('GABUZOMEU', [$oTimeExpr]);
|
||||
// Alias => Expression
|
||||
$aFunctions = array(
|
||||
$aFunctions = [
|
||||
'_itop_wrong_' => $oWrongExpr,
|
||||
);
|
||||
];
|
||||
$oSearch = DBSearch::FromOQL("SELECT FiberChannelInterface AS FCI");
|
||||
$oSearch->MakeGroupByQuery(array(), array(), false, $aFunctions, array());
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$oSearch->MakeGroupByQuery([], [], false, $aFunctions, []);
|
||||
} catch (Exception $e) {
|
||||
$sExceptionClass = get_class($e);
|
||||
}
|
||||
|
||||
@@ -673,14 +651,14 @@ class DBSearchTest extends ItopDataTestCase
|
||||
*/
|
||||
public function testSelectInWithVariableExpressions()
|
||||
{
|
||||
$aReq = array(array(1, 0, 0), array(1, 1, 3), array(1, 2, 1), array(1, 0, 1), array(1, 1, 0), array(1, 2, 1));
|
||||
$aReq = [[1, 0, 0], [1, 1, 3], [1, 2, 1], [1, 0, 1], [1, 1, 0], [1, 2, 1]];
|
||||
$sOrgs = $this->init_db(3, 4, $aReq);
|
||||
$allOrgIds = explode(",", $sOrgs);
|
||||
|
||||
$TwoOrgIdsOnly = array($allOrgIds[0], $allOrgIds[1]);
|
||||
$TwoOrgIdsOnly = [$allOrgIds[0], $allOrgIds[1]];
|
||||
$oSearch = DBSearch::FromOQL("SELECT UserRequest WHERE org_id IN (:org_ids)");
|
||||
self::assertNotNull($oSearch);
|
||||
$oSet = new \CMDBObjectSet($oSearch, array(), array('org_ids' => $TwoOrgIdsOnly));
|
||||
$oSet = new \CMDBObjectSet($oSearch, [], ['org_ids' => $TwoOrgIdsOnly]);
|
||||
static::assertEquals(4, $oSet->Count());
|
||||
|
||||
// Content now generated with ajax call
|
||||
@@ -703,7 +681,8 @@ class DBSearchTest extends ItopDataTestCase
|
||||
/**
|
||||
* @since 2.7.2 3.0.0 N°3324
|
||||
*/
|
||||
public function testAllowAllData() {
|
||||
public function testAllowAllData()
|
||||
{
|
||||
$oSimpleSearch = \DBObjectSearch::FromOQL('SELECT FunctionalCI');
|
||||
$oSimpleSearch->AllowAllData(false);
|
||||
self::assertFalse($oSimpleSearch->IsAllDataAllowed(), 'DBSearch AllowData value');
|
||||
@@ -715,7 +694,8 @@ class DBSearchTest extends ItopDataTestCase
|
||||
$this->CheckNestedSearch($sNestedQuery, false);
|
||||
}
|
||||
|
||||
private function CheckNestedSearch($sQuery, $bAllowAllData) {
|
||||
private function CheckNestedSearch($sQuery, $bAllowAllData)
|
||||
{
|
||||
$oNestedQuerySearch = \DBObjectSearch::FromOQL($sQuery);
|
||||
$oNestedQuerySearch->AllowAllData($bAllowAllData);
|
||||
self::assertEquals($bAllowAllData, $oNestedQuerySearch->IsAllDataAllowed(), 'root DBSearch AllowData value');
|
||||
@@ -746,110 +726,111 @@ class DBSearchTest extends ItopDataTestCase
|
||||
$oSearch->MakeSelectQuery();
|
||||
self::assertTrue(true);
|
||||
}
|
||||
/**
|
||||
* @dataProvider QueriesProvider
|
||||
* @param $sOQL
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testQueries($sOQL)
|
||||
{
|
||||
$oSearch = DBSearch::FromOQL($sOQL);
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
if ($oSet->Count() > 0) {
|
||||
$aSelectedAliases = array_keys($oSearch->GetSelectedClasses());
|
||||
$aFirstRow = $oSet->FetchAssoc();
|
||||
$aAliases = array_keys($aFirstRow);
|
||||
$this->assertEquals($aSelectedAliases, $aAliases);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @dataProvider QueriesProvider
|
||||
* @param $sOQL
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testQueries($sOQL)
|
||||
{
|
||||
$oSearch = DBSearch::FromOQL($sOQL);
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
if ($oSet->Count() > 0) {
|
||||
$aSelectedAliases = array_keys($oSearch->GetSelectedClasses());
|
||||
$aFirstRow = $oSet->FetchAssoc();
|
||||
$aAliases = array_keys($aFirstRow);
|
||||
$this->assertEquals($aSelectedAliases, $aAliases);
|
||||
}
|
||||
}
|
||||
|
||||
public function QueriesProvider()
|
||||
{
|
||||
return [
|
||||
['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'],
|
||||
];
|
||||
}
|
||||
public function SelectAttributeToArrayProvider()
|
||||
{
|
||||
return array(
|
||||
'select id from FunctionalCI' => array(
|
||||
'SELECT FunctionalCI',
|
||||
'id',
|
||||
),
|
||||
'select name from FunctionalCI' => array(
|
||||
'SELECT FunctionalCI',
|
||||
'name',
|
||||
),
|
||||
'select org_id from FunctionalCI' => array(
|
||||
'SELECT FunctionalCI',
|
||||
'org_id',
|
||||
),
|
||||
'select organization_name from FunctionalCI' => array(
|
||||
'SELECT FunctionalCI',
|
||||
'organization_name',
|
||||
),
|
||||
'select business_criticity from FunctionalCI' => array(
|
||||
'SELECT FunctionalCI',
|
||||
'business_criticity',
|
||||
),
|
||||
'select org_id from FunctionalCI' => array(
|
||||
'SELECT FunctionalCI',
|
||||
'org_id',
|
||||
),
|
||||
'select email from Person' => array(
|
||||
'SELECT Person',
|
||||
'email',
|
||||
),
|
||||
'select phone from Person' => array(
|
||||
'SELECT Person',
|
||||
'phone',
|
||||
),
|
||||
'select picture from Person' => array(
|
||||
'SELECT Person',
|
||||
'picture',
|
||||
),
|
||||
'select description from Ticket' => array(
|
||||
'SELECT Ticket',
|
||||
'description',
|
||||
),
|
||||
'select start_date from Ticket' => array(
|
||||
'SELECT Ticket',
|
||||
'start_date',
|
||||
),
|
||||
'select private_log from Ticket' => array(
|
||||
'SELECT Ticket',
|
||||
'private_log',
|
||||
),
|
||||
);
|
||||
}
|
||||
public function QueriesProvider()
|
||||
{
|
||||
return [
|
||||
['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'],
|
||||
];
|
||||
}
|
||||
public function SelectAttributeToArrayProvider()
|
||||
{
|
||||
return [
|
||||
'select id from FunctionalCI' => [
|
||||
'SELECT FunctionalCI',
|
||||
'id',
|
||||
],
|
||||
'select name from FunctionalCI' => [
|
||||
'SELECT FunctionalCI',
|
||||
'name',
|
||||
],
|
||||
'select org_id from FunctionalCI' => [
|
||||
'SELECT FunctionalCI',
|
||||
'org_id',
|
||||
],
|
||||
'select organization_name from FunctionalCI' => [
|
||||
'SELECT FunctionalCI',
|
||||
'organization_name',
|
||||
],
|
||||
'select business_criticity from FunctionalCI' => [
|
||||
'SELECT FunctionalCI',
|
||||
'business_criticity',
|
||||
],
|
||||
'select org_id from FunctionalCI' => [
|
||||
'SELECT FunctionalCI',
|
||||
'org_id',
|
||||
],
|
||||
'select email from Person' => [
|
||||
'SELECT Person',
|
||||
'email',
|
||||
],
|
||||
'select phone from Person' => [
|
||||
'SELECT Person',
|
||||
'phone',
|
||||
],
|
||||
'select picture from Person' => [
|
||||
'SELECT Person',
|
||||
'picture',
|
||||
],
|
||||
'select description from Ticket' => [
|
||||
'SELECT Ticket',
|
||||
'description',
|
||||
],
|
||||
'select start_date from Ticket' => [
|
||||
'SELECT Ticket',
|
||||
'start_date',
|
||||
],
|
||||
'select private_log from Ticket' => [
|
||||
'SELECT Ticket',
|
||||
'private_log',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider SelectAttributeToArrayProvider
|
||||
*
|
||||
* @return void
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function testSelectAttributeToArray($sQuery, $sField){
|
||||
/**
|
||||
* @dataProvider SelectAttributeToArrayProvider
|
||||
*
|
||||
* @return void
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function testSelectAttributeToArray($sQuery, $sField)
|
||||
{
|
||||
|
||||
$oSearch = \DBObjectSearch::FromOQL($sQuery);
|
||||
$aResToDataArray=[];
|
||||
$oSet = new \DBObjectSet($oSearch);
|
||||
while ($oRecord = $oSet->Fetch()) {
|
||||
$aMappedRow[$sField] =$oRecord->Get($sField);
|
||||
$aResToDataArray[] = $aMappedRow;
|
||||
}
|
||||
array_multisort (array_column($aResToDataArray, $sField), SORT_DESC, $aResToDataArray);
|
||||
$aResToDataArray = [];
|
||||
$oSet = new \DBObjectSet($oSearch);
|
||||
while ($oRecord = $oSet->Fetch()) {
|
||||
$aMappedRow[$sField] = $oRecord->Get($sField);
|
||||
$aResToDataArray[] = $aMappedRow;
|
||||
}
|
||||
array_multisort(array_column($aResToDataArray, $sField), SORT_DESC, $aResToDataArray);
|
||||
|
||||
$aResSelectColumnToArray = $oSearch->SelectAttributeToArray($sField);
|
||||
array_multisort (array_column($aResSelectColumnToArray, $sField), SORT_DESC, $aResSelectColumnToArray);
|
||||
array_multisort(array_column($aResSelectColumnToArray, $sField), SORT_DESC, $aResSelectColumnToArray);
|
||||
|
||||
self::assertEquals( $aResToDataArray, $aResSelectColumnToArray, 'The array constructed using the OQL query and the result of testSelectAttributeToArray must be the same');
|
||||
}
|
||||
}
|
||||
self::assertEquals($aResToDataArray, $aResSelectColumnToArray, 'The array constructed using the OQL query and the result of testSelectAttributeToArray must be the same');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use DBObjectSearch;
|
||||
|
||||
|
||||
/**
|
||||
* Class DBSearchUpdateRealiasingMapTest
|
||||
*
|
||||
@@ -13,7 +12,7 @@ use DBObjectSearch;
|
||||
*/
|
||||
class DBSearchUpdateRealiasingMapTest extends ItopDataTestCase
|
||||
{
|
||||
const USE_TRANSACTION = false;
|
||||
public const USE_TRANSACTION = false;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
@@ -41,37 +40,37 @@ class DBSearchUpdateRealiasingMapTest extends ItopDataTestCase
|
||||
'empty' => [
|
||||
'OriginalMap' => null,
|
||||
'AliasTranslation' => [],
|
||||
'ExpectedMap' => null
|
||||
'ExpectedMap' => null,
|
||||
],
|
||||
'Add 1 alias' => [
|
||||
'OriginalMap' => [],
|
||||
'AliasTranslation' => ['a' => ['*' => 'b']],
|
||||
'ExpectedMap' => ['a' => ['b']]
|
||||
'ExpectedMap' => ['a' => ['b']],
|
||||
],
|
||||
'Add 2 aliases' => [
|
||||
'OriginalMap' => [],
|
||||
'AliasTranslation' => ['a' => ['*' => 'b'], 'c' => ['*' => 'd']],
|
||||
'ExpectedMap' => ['a' => ['b'], 'c' => ['d']]
|
||||
'ExpectedMap' => ['a' => ['b'], 'c' => ['d']],
|
||||
],
|
||||
'Append 1 alias' => [
|
||||
'OriginalMap' => ['a' => ['b']],
|
||||
'AliasTranslation' => ['c' => ['*' => 'd']],
|
||||
'ExpectedMap' => ['a' => ['b'], 'c' => ['d']]
|
||||
'ExpectedMap' => ['a' => ['b'], 'c' => ['d']],
|
||||
],
|
||||
'Merge 1 alias' => [
|
||||
'OriginalMap' => ['a' => ['b']],
|
||||
'AliasTranslation' => ['a' => ['*' => 'd']],
|
||||
'ExpectedMap' => ['a' => ['b', 'd']]
|
||||
'ExpectedMap' => ['a' => ['b', 'd']],
|
||||
],
|
||||
'Merge same alias' => [
|
||||
'OriginalMap' => ['a' => ['b']],
|
||||
'AliasTranslation' => ['a' => ['*' => 'b']],
|
||||
'ExpectedMap' => ['a' => ['b']]
|
||||
'ExpectedMap' => ['a' => ['b']],
|
||||
],
|
||||
'Transitivity a->b + b->f = a->f' => [
|
||||
'OriginalMap' => ['a' => ['b', 'd'], 'c' => ['e']],
|
||||
'AliasTranslation' => ['b' => ['*' => 'f']],
|
||||
'ExpectedMap' => ['a' => ['f', 'd'], 'c' => ['e']]
|
||||
'ExpectedMap' => ['a' => ['f', 'd'], 'c' => ['e']],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
|
||||
class DBUnionSearchTest extends ItopDataTestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @dataProvider UnionSearchProvider
|
||||
*
|
||||
|
||||
@@ -6,8 +6,8 @@ use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use EMail;
|
||||
use utils;
|
||||
|
||||
class EMailTest extends ItopTestCase {
|
||||
|
||||
class EMailTest extends ItopTestCase
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
* @throws \ConfigException
|
||||
@@ -20,7 +20,7 @@ class EMailTest extends ItopTestCase {
|
||||
$oConfig = utils::GetConfig();
|
||||
$sCurrentEmailTransport = $oConfig->Get('email_transport');
|
||||
$sCurrentEmailAsync = $oConfig->Get('email_asynchronous');
|
||||
|
||||
|
||||
// Set our email transport to file, so we can read it after
|
||||
$oConfig->Set('email_transport', 'LogFile');
|
||||
$oConfig->Set('email_asynchronous', false);
|
||||
@@ -30,17 +30,17 @@ class EMailTest extends ItopTestCase {
|
||||
$oEmail->SetRecipientFrom('email2@email2.com');
|
||||
$oEmail->SetSubject('dummy subject');
|
||||
$oEmail->SetBody('dummy body');
|
||||
|
||||
|
||||
// Send the mail and check if there's any issue
|
||||
$aIssues = [];
|
||||
$oEmail->Send($aIssues);
|
||||
$this->assertEmpty($aIssues);
|
||||
|
||||
|
||||
// Check if our charset is correctly set
|
||||
// We know this file may be used by other future test, but as we can't configure output filename, it is what it is
|
||||
$sEmailContent = file_get_contents(APPROOT.'log/mail.log');
|
||||
$this->assertStringContainsStringIgnoringCase('charset=UTF-8', $sEmailContent);
|
||||
|
||||
|
||||
// Set our previous email transport value back, so it doesn't affect other tests
|
||||
$oConfig->Set('email_transport', $sCurrentEmailTransport);
|
||||
$oConfig->Set('email_asynchronous', $sCurrentEmailAsync);
|
||||
@@ -84,4 +84,4 @@ class EMailTest extends ItopTestCase {
|
||||
$oConfig->Set('email_transport', $sCurrentEmailTransport);
|
||||
$oConfig->Set('email_asynchronous', $sCurrentEmailAsync);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,10 +60,9 @@ class EventIssueTest extends ItopDataTestCase
|
||||
|
||||
try {
|
||||
$oEventIssue->DBInsert();
|
||||
}
|
||||
catch (CoreException $e) {
|
||||
} catch (CoreException $e) {
|
||||
$this->fail('we should be able to persist the object though it contains long values in its attributes: '.$e->getMessage());
|
||||
}
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
|
||||
use CMDBSource;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use DateInterval;
|
||||
@@ -15,7 +13,7 @@ use ScalarExpression;
|
||||
|
||||
class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
{
|
||||
const USE_TRANSACTION = false;
|
||||
public const USE_TRANSACTION = false;
|
||||
|
||||
/**
|
||||
* @covers Expression::GetParameters()
|
||||
@@ -38,14 +36,14 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
|
||||
public function GetParametersProvider()
|
||||
{
|
||||
return array(
|
||||
array('1 AND 0 OR :hello + :world', null, array('hello', 'world')),
|
||||
array('1 AND 0 OR :hello + :world', 'this', array()),
|
||||
array(':this->left + :this->right', null, array('this->left', 'this->right')),
|
||||
array(':this->left + :this->right', 'this', array('left', 'right')),
|
||||
array(':this->left + :this->right', 'that', array()),
|
||||
array(':this_left + :this_right', 'this', array()),
|
||||
);
|
||||
return [
|
||||
['1 AND 0 OR :hello + :world', null, ['hello', 'world']],
|
||||
['1 AND 0 OR :hello + :world', 'this', []],
|
||||
[':this->left + :this->right', null, ['this->left', 'this->right']],
|
||||
[':this->left + :this->right', 'this', ['left', 'right']],
|
||||
[':this->left + :this->right', 'that', []],
|
||||
[':this_left + :this_right', 'this', []],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,8 +57,7 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
public function _testExpressionEvaluateAllAtOnce()
|
||||
{
|
||||
$aTestCases = $this->VariousExpressionsProvider();
|
||||
foreach ($aTestCases as $sCaseId => $aTestArgs)
|
||||
{
|
||||
foreach ($aTestCases as $sCaseId => $aTestArgs) {
|
||||
$this->debug("Case $sCaseId:");
|
||||
$this->testVariousExpressions($aTestArgs[0], $aTestArgs[1]);
|
||||
}
|
||||
@@ -80,141 +77,137 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
public function testVariousExpressions($sExpression, $expectedValue)
|
||||
{
|
||||
$oExpression = Expression::FromOQL($sExpression);
|
||||
$value = $oExpression->Evaluate(array());
|
||||
$value = $oExpression->Evaluate([]);
|
||||
$this->assertEquals($expectedValue, $value);
|
||||
}
|
||||
|
||||
public function VariousExpressionsProvider()
|
||||
{
|
||||
if (false)
|
||||
{
|
||||
$aExpressions = array(
|
||||
if (false) {
|
||||
$aExpressions = [
|
||||
// Test case to isolate for troubleshooting purposes
|
||||
array("'a' IN ('a', 'b')", true),
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aExpressions = array(
|
||||
["'a' IN ('a', 'b')", true],
|
||||
];
|
||||
} else {
|
||||
$aExpressions = [
|
||||
// The bare minimum
|
||||
array('"blah"', 'blah'),
|
||||
array('"\\\\"', '\\'),
|
||||
['"blah"', 'blah'],
|
||||
['"\\\\"', '\\'],
|
||||
|
||||
// Arithmetics
|
||||
array('2+2', 4),
|
||||
array('2+2-2', 2),
|
||||
array('2*(3+4)', 14),
|
||||
array('(2*3)+4', 10),
|
||||
array('2*3+4', 10),
|
||||
['2+2', 4],
|
||||
['2+2-2', 2],
|
||||
['2*(3+4)', 14],
|
||||
['(2*3)+4', 10],
|
||||
['2*3+4', 10],
|
||||
|
||||
// Strings
|
||||
array("CONCAT('hello', 'world')", 'helloworld'),
|
||||
["CONCAT('hello', 'world')", 'helloworld'],
|
||||
|
||||
// Not yet parsed - array("CONCAT_WS(' ', 'hello', 'world')", 'hello world'),
|
||||
array("SUBSTR('abcdef', 2, 3)", 'bcd'),
|
||||
array("TRIM(' Sin dolor ')", 'Sin dolor'),
|
||||
["SUBSTR('abcdef', 2, 3)", 'bcd'],
|
||||
["TRIM(' Sin dolor ')", 'Sin dolor'],
|
||||
|
||||
// Comparison operators
|
||||
array('1 = 1', 1),
|
||||
array('1 != 1', 0),
|
||||
array('0 = 1', 0),
|
||||
array('0 != 1', 1),
|
||||
array('2 > 1', 1),
|
||||
array('2 < 1', 0),
|
||||
array('1 > 2', 0),
|
||||
array('2 > 1', 1),
|
||||
array('2 >= 1', 1),
|
||||
array('2 >= 2', 1),
|
||||
array("'the quick brown dog' LIKE '%QUICK%'", 1),
|
||||
array("'the quick brown dog' LIKE '%SLOW%'", 0),
|
||||
array("'the quick brown dog' LIKE '%QU_CK%'", 1),
|
||||
array("'the quick brown dog' LIKE '%QU_ICK%'", 0),
|
||||
array('"400 (km/h)" LIKE "400%"', 1),
|
||||
array('"400 (km/h)" LIKE "100%"', 0),
|
||||
array('"400 (km/h)" NOT LIKE "400%"', 0),
|
||||
array('"400 (km/h)" NOT LIKE "100%"', 1),
|
||||
array('"2020-06-12" > "2020-06-11"', 1),
|
||||
array('"2020-06-12" < "2020-06-11"', 0),
|
||||
array('" 2020-06-12" > "2020-06-11"', 0), // Leading spaces => a string
|
||||
array('" 2020-06-12 " > "2020-06-11"', 0), // Trailing spaces => a string
|
||||
array('"2020-06-12 17:35:13" > "2020-06-12 17:35:12"', 1),
|
||||
array('"2020-06-12 17:35:13" < "2020-06-12 17:35:12"', 0),
|
||||
array('"2020-06-12 17:35:13" > "2020-06-12"', 1),
|
||||
array('"2020-06-12 17:35:13" < "2020-06-12"', 0),
|
||||
array('"2020-06-12 00:00:00" = "2020-06-12"', 0),
|
||||
['1 = 1', 1],
|
||||
['1 != 1', 0],
|
||||
['0 = 1', 0],
|
||||
['0 != 1', 1],
|
||||
['2 > 1', 1],
|
||||
['2 < 1', 0],
|
||||
['1 > 2', 0],
|
||||
['2 > 1', 1],
|
||||
['2 >= 1', 1],
|
||||
['2 >= 2', 1],
|
||||
["'the quick brown dog' LIKE '%QUICK%'", 1],
|
||||
["'the quick brown dog' LIKE '%SLOW%'", 0],
|
||||
["'the quick brown dog' LIKE '%QU_CK%'", 1],
|
||||
["'the quick brown dog' LIKE '%QU_ICK%'", 0],
|
||||
['"400 (km/h)" LIKE "400%"', 1],
|
||||
['"400 (km/h)" LIKE "100%"', 0],
|
||||
['"400 (km/h)" NOT LIKE "400%"', 0],
|
||||
['"400 (km/h)" NOT LIKE "100%"', 1],
|
||||
['"2020-06-12" > "2020-06-11"', 1],
|
||||
['"2020-06-12" < "2020-06-11"', 0],
|
||||
['" 2020-06-12" > "2020-06-11"', 0], // Leading spaces => a string
|
||||
['" 2020-06-12 " > "2020-06-11"', 0], // Trailing spaces => a string
|
||||
['"2020-06-12 17:35:13" > "2020-06-12 17:35:12"', 1],
|
||||
['"2020-06-12 17:35:13" < "2020-06-12 17:35:12"', 0],
|
||||
['"2020-06-12 17:35:13" > "2020-06-12"', 1],
|
||||
['"2020-06-12 17:35:13" < "2020-06-12"', 0],
|
||||
['"2020-06-12 00:00:00" = "2020-06-12"', 0],
|
||||
|
||||
// IN operator
|
||||
array("'a' IN ('a')", true),
|
||||
array("'a' IN ('b')", false),
|
||||
array("'a' IN ('a', 'b')", true),
|
||||
array("'z' IN ('a', 'b')", false),
|
||||
array("'a' NOT IN ('a')", false),
|
||||
array("'a' NOT IN ('b')", true),
|
||||
array("'a' NOT IN ('a', 'b')", false),
|
||||
array("'z' NOT IN ('a', 'b')", true),
|
||||
["'a' IN ('a')", true],
|
||||
["'a' IN ('b')", false],
|
||||
["'a' IN ('a', 'b')", true],
|
||||
["'z' IN ('a', 'b')", false],
|
||||
["'a' NOT IN ('a')", false],
|
||||
["'a' NOT IN ('b')", true],
|
||||
["'a' NOT IN ('a', 'b')", false],
|
||||
["'z' NOT IN ('a', 'b')", true],
|
||||
|
||||
// Logical operators
|
||||
array('0 AND 0', 0),
|
||||
array('1 AND 0', 0),
|
||||
array('0 AND 1', 0),
|
||||
array('1 AND 1', 1),
|
||||
array('0 OR 0', 0),
|
||||
array('0 OR 1', 1),
|
||||
array('1 OR 0', 1),
|
||||
array('1 OR 1', 1),
|
||||
array('1 AND 0 OR 1', 1),
|
||||
['0 AND 0', 0],
|
||||
['1 AND 0', 0],
|
||||
['0 AND 1', 0],
|
||||
['1 AND 1', 1],
|
||||
['0 OR 0', 0],
|
||||
['0 OR 1', 1],
|
||||
['1 OR 0', 1],
|
||||
['1 OR 1', 1],
|
||||
['1 AND 0 OR 1', 1],
|
||||
|
||||
// Casting
|
||||
array('1 AND "blah"', 0),
|
||||
array('1 AND "1"', 1),
|
||||
array('1 AND "2"', 1),
|
||||
array('1 AND "0"', 0),
|
||||
array('1 AND "-1"', 1),
|
||||
['1 AND "blah"', 0],
|
||||
['1 AND "1"', 1],
|
||||
['1 AND "2"', 1],
|
||||
['1 AND "0"', 0],
|
||||
['1 AND "-1"', 1],
|
||||
|
||||
// Null
|
||||
array('NULL', null),
|
||||
array('1 AND NULL', null),
|
||||
array('CONCAT("Great but...", NULL)', null),
|
||||
array('COALESCE(NULL, 123)', 123),
|
||||
array('COALESCE(321, 123)', 321),
|
||||
array('ISNULL(NULL)', 1),
|
||||
array('ISNULL(123)', 0),
|
||||
['NULL', null],
|
||||
['1 AND NULL', null],
|
||||
['CONCAT("Great but...", NULL)', null],
|
||||
['COALESCE(NULL, 123)', 123],
|
||||
['COALESCE(321, 123)', 321],
|
||||
['ISNULL(NULL)', 1],
|
||||
['ISNULL(123)', 0],
|
||||
|
||||
// Date functions
|
||||
array("DATE('2020-03-12 13:18:30')", '2020-03-12'),
|
||||
array("DATE_FORMAT('2009-10-04 22:23:00', '%Y %m %d %H %i %s')", '2009 10 04 22 23 00'),
|
||||
array("DATE(NOW()) = CURRENT_DATE()", 1), // Could fail if executed around midnight!
|
||||
array("TO_DAYS('2020-01-02')", 737791),
|
||||
array("FROM_DAYS(737791)", '2020-01-02'),
|
||||
array("FROM_DAYS(TO_DAYS('2020-01-02'))", '2020-01-02'), // Back and forth conversion to ensure it returns the same
|
||||
array("YEAR('2020-05-03')", 2020),
|
||||
array("MONTH('2020-05-03')", 5),
|
||||
array("DAY('2020-05-03')", 3),
|
||||
array("DATE_ADD('2020-02-28 18:00:00', INTERVAL 1 HOUR)", '2020-02-28 19:00:00'),
|
||||
array("DATE_ADD('2020-02-28 18:00:00', INTERVAL 1 DAY)", '2020-02-29 18:00:00'),
|
||||
array("DATE_SUB('2020-03-01 18:00:00', INTERVAL 1 HOUR)", '2020-03-01 17:00:00'),
|
||||
array("DATE_SUB('2020-03-01 18:00:00', INTERVAL 1 DAY)", '2020-02-29 18:00:00'),
|
||||
["DATE('2020-03-12 13:18:30')", '2020-03-12'],
|
||||
["DATE_FORMAT('2009-10-04 22:23:00', '%Y %m %d %H %i %s')", '2009 10 04 22 23 00'],
|
||||
["DATE(NOW()) = CURRENT_DATE()", 1], // Could fail if executed around midnight!
|
||||
["TO_DAYS('2020-01-02')", 737791],
|
||||
["FROM_DAYS(737791)", '2020-01-02'],
|
||||
["FROM_DAYS(TO_DAYS('2020-01-02'))", '2020-01-02'], // Back and forth conversion to ensure it returns the same
|
||||
["YEAR('2020-05-03')", 2020],
|
||||
["MONTH('2020-05-03')", 5],
|
||||
["DAY('2020-05-03')", 3],
|
||||
["DATE_ADD('2020-02-28 18:00:00', INTERVAL 1 HOUR)", '2020-02-28 19:00:00'],
|
||||
["DATE_ADD('2020-02-28 18:00:00', INTERVAL 1 DAY)", '2020-02-29 18:00:00'],
|
||||
["DATE_SUB('2020-03-01 18:00:00', INTERVAL 1 HOUR)", '2020-03-01 17:00:00'],
|
||||
["DATE_SUB('2020-03-01 18:00:00', INTERVAL 1 DAY)", '2020-02-29 18:00:00'],
|
||||
|
||||
// Misc. functions
|
||||
array('IF(1, 123, 567)', 123),
|
||||
array('IF(0, 123, 567)', 567),
|
||||
array('ELT(3, "a", "b", "c")', 'c'),
|
||||
array('ELT(0, "a", "b", "c")', null),
|
||||
array('ELT(4, "a", "b", "c")', null),
|
||||
array('INET_ATON("128.0.0.1")', 2147483649),
|
||||
array('INET_NTOA(2147483649)', '128.0.0.1'),
|
||||
);
|
||||
['IF(1, 123, 567)', 123],
|
||||
['IF(0, 123, 567)', 567],
|
||||
['ELT(3, "a", "b", "c")', 'c'],
|
||||
['ELT(0, "a", "b", "c")', null],
|
||||
['ELT(4, "a", "b", "c")', null],
|
||||
['INET_ATON("128.0.0.1")', 2147483649],
|
||||
['INET_NTOA(2147483649)', '128.0.0.1'],
|
||||
];
|
||||
|
||||
// N°5985 - Test bidirectional conversion across the centuries to ensure that it works on PHP 7.4 => 8.2+ even though the bug has been fixed in PHP 8.1 but still exists in PHP 7.4 => 8.1
|
||||
for ($iUpperYearBound = 1925; $iUpperYearBound <= 2100; $iUpperYearBound = $iUpperYearBound + 25) {
|
||||
$aExpressions[] = array("FROM_DAYS(TO_DAYS('$iUpperYearBound-01-02'))", "$iUpperYearBound-01-02");
|
||||
$aExpressions[] = ["FROM_DAYS(TO_DAYS('$iUpperYearBound-01-02'))", "$iUpperYearBound-01-02"];
|
||||
}
|
||||
}
|
||||
|
||||
// Build a comprehensive index
|
||||
$aRet = array();
|
||||
foreach ($aExpressions as $aExp)
|
||||
{
|
||||
$aRet = [];
|
||||
foreach ($aExpressions as $aExp) {
|
||||
$aRet[$aExp[0]] = $aExp;
|
||||
}
|
||||
return $aRet;
|
||||
@@ -231,27 +224,26 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
{
|
||||
$sNewExpression = "return $sExpression;";
|
||||
$oExpression = eval($sNewExpression);
|
||||
$res = $oExpression->Evaluate(array());
|
||||
$res = $oExpression->Evaluate([]);
|
||||
$this->assertEquals($expectedValue, $res);
|
||||
}
|
||||
|
||||
public function NotYetParsableExpressionsProvider()
|
||||
{
|
||||
$aExpressions = array(
|
||||
array("new \\FunctionExpression('CONCAT_WS', array(new \\ScalarExpression(' '), new \\ScalarExpression('Hello'), new \ScalarExpression('world!')))", 'Hello world!'),
|
||||
array("new \\ScalarExpression('windows\\system32')", 'windows\\system32'),
|
||||
array("new \\BinaryExpression(new \\ScalarExpression('100%'), 'LIKE', new \\ScalarExpression('___\%'))", 1),
|
||||
array("new \\BinaryExpression(new \ScalarExpression('1000'), 'LIKE', new \ScalarExpression('___\%'))", 0),
|
||||
$aExpressions = [
|
||||
["new \\FunctionExpression('CONCAT_WS', array(new \\ScalarExpression(' '), new \\ScalarExpression('Hello'), new \ScalarExpression('world!')))", 'Hello world!'],
|
||||
["new \\ScalarExpression('windows\\system32')", 'windows\\system32'],
|
||||
["new \\BinaryExpression(new \\ScalarExpression('100%'), 'LIKE', new \\ScalarExpression('___\%'))", 1],
|
||||
["new \\BinaryExpression(new \ScalarExpression('1000'), 'LIKE', new \ScalarExpression('___\%'))", 0],
|
||||
// Net yet parsed - array("TIME(NOW()) = CURRENT_TIME()", 1), // Not relevant
|
||||
// Not yet parsed - array("DATE_ADD('2020-02-28 18:00:00', INTERVAL 1 WEEK)", '2020-03-06 18:00:00'),
|
||||
// Not yet parsed - array("DATE_SUB('2020-03-01 18:00:00', INTERVAL 1 WEEK)", '2020-02-23 18:00:00'),
|
||||
// Not yet parsed - array('ROUND(1.2345, 2)', 1.23),
|
||||
// Not yet parsed - array('FLOOR(1.2)', 1),
|
||||
);
|
||||
];
|
||||
// Build a comprehensive index
|
||||
$aRet = array();
|
||||
foreach ($aExpressions as $aExp)
|
||||
{
|
||||
$aRet = [];
|
||||
foreach ($aExpressions as $aExp) {
|
||||
$aRet[$aExp[0]] = $aExp;
|
||||
}
|
||||
return $aRet;
|
||||
@@ -269,17 +261,15 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
$aTests = array_values($this->VariousExpressionsProvider());
|
||||
|
||||
// Expressions given as a PHP statement
|
||||
foreach (array_values($this->NotYetParsableExpressionsProvider()) as $i => $aTest)
|
||||
{
|
||||
foreach (array_values($this->NotYetParsableExpressionsProvider()) as $i => $aTest) {
|
||||
$sNewExpression = "return {$aTest[0]};";
|
||||
$oExpression = eval($sNewExpression);
|
||||
$sExpression = $oExpression->RenderExpression(true);
|
||||
$aTests[] = array($sExpression, $aTest[1]);
|
||||
$aTests[] = [$sExpression, $aTest[1]];
|
||||
}
|
||||
|
||||
$aExpressions = array();
|
||||
foreach ($aTests as $i => $aTest)
|
||||
{
|
||||
$aExpressions = [];
|
||||
foreach ($aTests as $i => $aTest) {
|
||||
$aExpressions[] = "{$aTest[0]} as test_$i";
|
||||
}
|
||||
|
||||
@@ -289,8 +279,7 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
$this->debug($sQuery);
|
||||
$aResults = CMDBSource::QueryToArray($sQuery);
|
||||
|
||||
foreach ($aTests as $i => $aTest)
|
||||
{
|
||||
foreach ($aTests as $i => $aTest) {
|
||||
$value = $aResults[0]["test_$i"];
|
||||
$expectedValue = $aTest[1];
|
||||
$this->debug("Test #$i: {$aTests[$i][0]} => ".var_export($value, true));
|
||||
@@ -352,15 +341,15 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
|
||||
public function ExpressionWithParametersProvider()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
['`DBVariables["analyze_sample_percentage"]` > 10', ['DBVariables["analyze_sample_percentage"]' => 20], true],
|
||||
['`DataBase["DBDataSize"]`', ['DataBase["DBDataSize"]' => 4096], 4096],
|
||||
['`FileSystem["ItopInstallationIntegrity"]`', ['FileSystem["ItopInstallationIntegrity"]' => 'not_conform'], 'not_conform'],
|
||||
['`DBTablesInfo["attachment"].DataSize` > 100', ['DBTablesInfo["attachment"].DataSize' => 200], true],
|
||||
['`DBTablesInfo[].DataSize` > 100', ['DBTablesInfo[].DataSize' => 50], false],
|
||||
['(`DBTablesInfo[].DataSize` > 100) AND (`DBTablesInfo[].DataFree` * 100 / (`DBTablesInfo[].DataSize` + `DBTablesInfo[].IndexSize` + `DBTablesInfo[].DataFree`) > 10)', ['DBTablesInfo[].DataSize' => 200, 'DBTablesInfo[].DataFree' => 100, 'DBTablesInfo[].IndexSize' => 10], true],
|
||||
array('CONCAT(SUBSTR(name, 4), " cause")', array('name' => 'noble'), 'le cause'),
|
||||
);
|
||||
['CONCAT(SUBSTR(name, 4), " cause")', ['name' => 'noble'], 'le cause'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -380,28 +369,24 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
$oExpression = Expression::FromOQL($sExpression);
|
||||
|
||||
$res = $oExpression->IsTrue();
|
||||
if ($bExpectTrue)
|
||||
{
|
||||
if ($bExpectTrue) {
|
||||
$this->assertTrue($res, 'arg: '.$sExpression);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->assertFalse($res, 'arg: '.$sExpression);
|
||||
}
|
||||
}
|
||||
|
||||
public function TrueExpressionsProvider()
|
||||
{
|
||||
$aExpressions = array(
|
||||
array('1', true),
|
||||
array('0 OR 0', false),
|
||||
array('1 AND 1', true),
|
||||
array('1 AND (1 OR 0)', true)
|
||||
);
|
||||
$aExpressions = [
|
||||
['1', true],
|
||||
['0 OR 0', false],
|
||||
['1 AND 1', true],
|
||||
['1 AND (1 OR 0)', true],
|
||||
];
|
||||
// Build a comprehensive index
|
||||
$aRet = array();
|
||||
foreach ($aExpressions as $aExp)
|
||||
{
|
||||
$aRet = [];
|
||||
foreach ($aExpressions as $aExp) {
|
||||
$aRet[$aExp[0]] = $aExp;
|
||||
}
|
||||
return $aRet;
|
||||
@@ -423,60 +408,56 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
public function testTimeFormat($sFormat, $bProcessed, $sValueOrException)
|
||||
{
|
||||
$sDate = '2009-06-04 21:23:24';
|
||||
$oExpression = new FunctionExpression('DATE_FORMAT', array(new ScalarExpression($sDate), new ScalarExpression("%$sFormat")));
|
||||
if ($bProcessed)
|
||||
{
|
||||
$oExpression = new FunctionExpression('DATE_FORMAT', [new ScalarExpression($sDate), new ScalarExpression("%$sFormat")]);
|
||||
if ($bProcessed) {
|
||||
$sqlValue = CMDBSource::QueryToScalar("SELECT DATE_FORMAT('$sDate', '%$sFormat')");
|
||||
$this->assertEquals($sqlValue, $sValueOrException, 'Check test against MySQL');
|
||||
|
||||
$res = $oExpression->Evaluate(array());
|
||||
$res = $oExpression->Evaluate([]);
|
||||
$this->assertEquals($sValueOrException, $res, 'Check evaluation');
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
static::expectException($sValueOrException);
|
||||
$oExpression->Evaluate(array());
|
||||
$oExpression->Evaluate([]);
|
||||
}
|
||||
}
|
||||
|
||||
public function TimeFormatsProvider()
|
||||
{
|
||||
$aTests = array(
|
||||
array('a', true, 'Thu'),
|
||||
array('b', true, 'Jun'),
|
||||
array('c', true, '6'),
|
||||
array('D', true, '4th'),
|
||||
array('d', true, '04'),
|
||||
array('e', true, '4'),
|
||||
array('f', false, 'NotYetEvaluatedExpression'), // microseconds: no way!
|
||||
array('H', true, '21'),
|
||||
array('h', true, '09'),
|
||||
array('I', true, '09'),
|
||||
array('i', true, '23'),
|
||||
array('j', true, '155'), // day of the year
|
||||
array('k', true, '21'),
|
||||
array('l', true, '9'),
|
||||
array('M', true, 'June'),
|
||||
array('m', true, '06'),
|
||||
array('p', true, 'PM'),
|
||||
array('r', true, '09:23:24 PM'),
|
||||
array('S', true, '24'),
|
||||
array('s', true, '24'),
|
||||
array('T', true, '21:23:24'),
|
||||
array('U', false, 'NotYetEvaluatedExpression'), // Week sunday based (mode 0)
|
||||
array('u', false, 'NotYetEvaluatedExpression'), // Week monday based (mode 1)
|
||||
array('V', false, 'NotYetEvaluatedExpression'), // Week sunday based (mode 2)
|
||||
array('v', true, '23'), // Week monday based (mode 3 - ISO-8601)
|
||||
array('W', true, 'Thursday'),
|
||||
array('w', true, '4'),
|
||||
array('X', false, 'NotYetEvaluatedExpression'),
|
||||
array('x', true, '2009'), // to be used with %v (ISO - 8601)
|
||||
array('Y', true, '2009'),
|
||||
array('y', true, '09'),
|
||||
);
|
||||
$aRes = array();
|
||||
foreach ($aTests as $aTest)
|
||||
{
|
||||
$aTests = [
|
||||
['a', true, 'Thu'],
|
||||
['b', true, 'Jun'],
|
||||
['c', true, '6'],
|
||||
['D', true, '4th'],
|
||||
['d', true, '04'],
|
||||
['e', true, '4'],
|
||||
['f', false, 'NotYetEvaluatedExpression'], // microseconds: no way!
|
||||
['H', true, '21'],
|
||||
['h', true, '09'],
|
||||
['I', true, '09'],
|
||||
['i', true, '23'],
|
||||
['j', true, '155'], // day of the year
|
||||
['k', true, '21'],
|
||||
['l', true, '9'],
|
||||
['M', true, 'June'],
|
||||
['m', true, '06'],
|
||||
['p', true, 'PM'],
|
||||
['r', true, '09:23:24 PM'],
|
||||
['S', true, '24'],
|
||||
['s', true, '24'],
|
||||
['T', true, '21:23:24'],
|
||||
['U', false, 'NotYetEvaluatedExpression'], // Week sunday based (mode 0)
|
||||
['u', false, 'NotYetEvaluatedExpression'], // Week monday based (mode 1)
|
||||
['V', false, 'NotYetEvaluatedExpression'], // Week sunday based (mode 2)
|
||||
['v', true, '23'], // Week monday based (mode 3 - ISO-8601)
|
||||
['W', true, 'Thursday'],
|
||||
['w', true, '4'],
|
||||
['X', false, 'NotYetEvaluatedExpression'],
|
||||
['x', true, '2009'], // to be used with %v (ISO - 8601)
|
||||
['Y', true, '2009'],
|
||||
['y', true, '09'],
|
||||
];
|
||||
$aRes = [];
|
||||
foreach ($aTests as $aTest) {
|
||||
$aRes["Format %{$aTest[0]}"] = $aTest;
|
||||
}
|
||||
return $aRes;
|
||||
@@ -501,13 +482,11 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
public function testEveryTimeFormat($sDate)
|
||||
{
|
||||
$aFormats = $this->TimeFormatsProvider();
|
||||
$aSelects = array();
|
||||
foreach ($aFormats as $sFormatDesc => $aFormatSpec)
|
||||
{
|
||||
$aSelects = [];
|
||||
foreach ($aFormats as $sFormatDesc => $aFormatSpec) {
|
||||
$sFormat = $aFormatSpec[0];
|
||||
$bProcessed = $aFormatSpec[1];
|
||||
if ($bProcessed)
|
||||
{
|
||||
if ($bProcessed) {
|
||||
$aSelects["%$sFormat"] = "DATE_FORMAT('$sDate', '%$sFormat') AS `$sFormat`";
|
||||
}
|
||||
}
|
||||
@@ -515,29 +494,27 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
$aRes = CMDBSource::QueryToArray($sSelects);
|
||||
/** @var array $aMysqlDateFormatRsultsForAllFormats format as key, MySQL evaluated result as value */
|
||||
$aMysqlDateFormatRsultsForAllFormats = $aRes[0];
|
||||
foreach ($aFormats as $sFormatDesc => $aFormatSpec)
|
||||
{
|
||||
foreach ($aFormats as $sFormatDesc => $aFormatSpec) {
|
||||
$sFormat = $aFormatSpec[0];
|
||||
$bProcessed = $aFormatSpec[1];
|
||||
if ($bProcessed)
|
||||
{
|
||||
$oExpression = new FunctionExpression('DATE_FORMAT', array(new ScalarExpression($sDate), new ScalarExpression("%$sFormat")));
|
||||
$itopExpressionResult = $oExpression->Evaluate(array());
|
||||
if ($bProcessed) {
|
||||
$oExpression = new FunctionExpression('DATE_FORMAT', [new ScalarExpression($sDate), new ScalarExpression("%$sFormat")]);
|
||||
$itopExpressionResult = $oExpression->Evaluate([]);
|
||||
$this->assertSame($aMysqlDateFormatRsultsForAllFormats[$sFormat], $itopExpressionResult, "Format %$sFormat not matching MySQL for '$sDate'");
|
||||
}
|
||||
}
|
||||
}
|
||||
public function EveryTimeFormatProvider()
|
||||
{
|
||||
return array(
|
||||
array('1971-07-19 8:40:00'),
|
||||
array('1999-12-31 23:59:59'),
|
||||
array('2000-01-01 00:00:00'),
|
||||
array('2009-06-04 21:23:24'),
|
||||
array('2020-02-29 23:59:59'),
|
||||
array('2030-10-21 23:59:59'),
|
||||
array('2050-12-21 23:59:59'),
|
||||
);
|
||||
return [
|
||||
['1971-07-19 8:40:00'],
|
||||
['1999-12-31 23:59:59'],
|
||||
['2000-01-01 00:00:00'],
|
||||
['2009-06-04 21:23:24'],
|
||||
['2020-02-29 23:59:59'],
|
||||
['2030-10-21 23:59:59'],
|
||||
['2050-12-21 23:59:59'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -557,8 +534,7 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
public function testEveryTimeFormatOnDateRange($sStartDate, $sInterval, $iRepeat)
|
||||
{
|
||||
$oDate = new DateTime($sStartDate);
|
||||
for ($i = 0 ; $i < $iRepeat ; $i++)
|
||||
{
|
||||
for ($i = 0 ; $i < $iRepeat ; $i++) {
|
||||
$sDate = date_format($oDate, 'Y-m-d H:i:s');
|
||||
$this->debug("Checking '$sDate'");
|
||||
$this->testEveryTimeFormat($sDate);
|
||||
@@ -568,11 +544,11 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
|
||||
public function EveryTimeFormatOnDateRangeProvider()
|
||||
{
|
||||
return array(
|
||||
'10 years, each 17 days' => array('2000-01-01', 'P17D', 365 * 10 / 17),
|
||||
'1 day, hour by hour' => array('2000-01-01 00:01:02', 'PT1H', 24),
|
||||
'1 hour, minute by minute' => array('2000-01-01 00:01:02', 'PT1M', 60),
|
||||
'1 minute, second by second' => array('2000-01-01 00:01:02', 'PT1S', 60),
|
||||
);
|
||||
return [
|
||||
'10 years, each 17 days' => ['2000-01-01', 'P17D', 365 * 10 / 17],
|
||||
'1 day, hour by hour' => ['2000-01-01 00:01:02', 'PT1H', 24],
|
||||
'1 hour, minute by minute' => ['2000-01-01 00:01:02', 'PT1M', 60],
|
||||
'1 minute, second by second' => ['2000-01-01 00:01:02', 'PT1S', 60],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use Expression;
|
||||
|
||||
class ExpressionTest extends ItopDataTestCase
|
||||
{
|
||||
const USE_TRANSACTION = false;
|
||||
public const USE_TRANSACTION = false;
|
||||
|
||||
/**
|
||||
* @dataProvider ListParametersProvider
|
||||
@@ -20,9 +20,8 @@ class ExpressionTest extends ItopDataTestCase
|
||||
{
|
||||
$oExpression = Expression::FromOQL($sOQL);
|
||||
$aParameters = $oExpression->ListParameters();
|
||||
$aResult = array();
|
||||
foreach ($aParameters as $oVarExpr)
|
||||
{
|
||||
$aResult = [];
|
||||
foreach ($aParameters as $oVarExpr) {
|
||||
/** var \VariableExpression $oVarExpr */
|
||||
$aResult[] = $oVarExpr->RenderExpression();
|
||||
}
|
||||
@@ -42,7 +41,7 @@ class ExpressionTest extends ItopDataTestCase
|
||||
["name REGEXP :regexp", [':regexp']],
|
||||
[" t.agent_id = :current_contact_id", [':current_contact_id']],
|
||||
["INET_ATON(dev.managementip) > INET_ATON('10.22.32.224') AND INET_ATON(:ip) < INET_ATON('10.22.32.255')", [':ip']],
|
||||
["((`UserRequest`.`status` IN ('closed','rejected','resolved')))", []]
|
||||
["((`UserRequest`.`status` IN ('closed','rejected','resolved')))", []],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ use UserInternal;
|
||||
use UserLocal;
|
||||
use UserRightsProfile;
|
||||
|
||||
|
||||
/**
|
||||
* @group getSelectFilterTest
|
||||
* @group sampleDataNeeded
|
||||
@@ -33,20 +32,20 @@ class GetSelectFilterTest extends ItopDataTestCase
|
||||
parent::setUp();
|
||||
require_once(APPROOT.'application/startup.inc.php');
|
||||
|
||||
$oRestProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => 'REST Services User'), true);
|
||||
$oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => 'Administrator'), true);
|
||||
$oRestProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", ['name' => 'REST Services User'], true);
|
||||
$oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", ['name' => 'Administrator'], true);
|
||||
|
||||
$this->sLogin = "getselectfilter-user-" . date('dmYHis');
|
||||
$this->sLogin = "getselectfilter-user-".date('dmYHis');
|
||||
|
||||
// Ensure that we have at least one administrator account
|
||||
if (is_object($oRestProfile) && is_object($oAdminProfile))
|
||||
{
|
||||
if (is_object($oRestProfile) && is_object($oAdminProfile)) {
|
||||
$this->oUser = $this->CreateUser($this->sLogin, $oRestProfile->GetKey(), $this->sPassword);
|
||||
$this->AddProfileToUser($this->oUser, $oAdminProfile->GetKey());
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetSelectFilter() {
|
||||
public function testGetSelectFilter()
|
||||
{
|
||||
$oUserRights = new UserRightsProfile();
|
||||
$aClasses = get_declared_classes();
|
||||
$aUserClasses = [User::class];
|
||||
@@ -71,35 +70,28 @@ class GetSelectFilterTest extends ItopDataTestCase
|
||||
$oConfig->Set('security.hide_administrators', false);
|
||||
|
||||
$oFilterProfiles = $oUserRights->GetSelectFilter($this->oUser, URP_Profiles::class);
|
||||
if ($oFilterProfiles === true)
|
||||
{
|
||||
if ($oFilterProfiles === true) {
|
||||
$oFilterProfiles = new DBObjectSearch(URP_Profiles::class);
|
||||
}
|
||||
$oSet = new DBObjectSet($oFilterProfiles);
|
||||
$bAdminProfileFound = false;
|
||||
while($oProfile = $oSet->Fetch())
|
||||
{
|
||||
if ($oProfile->GetKey() == 1)
|
||||
{
|
||||
while ($oProfile = $oSet->Fetch()) {
|
||||
if ($oProfile->GetKey() == 1) {
|
||||
$bAdminProfileFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->assertEquals($bAdminProfileFound, true);
|
||||
|
||||
foreach($aUserLocalAncestors as $sUserClass)
|
||||
{
|
||||
foreach ($aUserLocalAncestors as $sUserClass) {
|
||||
$bAdminUserFound = false;
|
||||
$oFilterUser = $oUserRights->GetSelectFilter($this->oUser,$sUserClass);
|
||||
if ($oFilterUser === true)
|
||||
{
|
||||
$oFilterUser = $oUserRights->GetSelectFilter($this->oUser, $sUserClass);
|
||||
if ($oFilterUser === true) {
|
||||
$oFilterUser = new DBObjectSearch($sUserClass);
|
||||
}
|
||||
$oSet = new DBObjectSet($oFilterUser);
|
||||
while($oUser = $oSet->Fetch())
|
||||
{
|
||||
if($oUser->GetKey() == $this->oUser->GetKey())
|
||||
{
|
||||
while ($oUser = $oSet->Fetch()) {
|
||||
if ($oUser->GetKey() == $this->oUser->GetKey()) {
|
||||
$bAdminUserFound = true;
|
||||
break;
|
||||
}
|
||||
@@ -108,29 +100,24 @@ class GetSelectFilterTest extends ItopDataTestCase
|
||||
}
|
||||
|
||||
$oFilterLnkProfiles = $oUserRights->GetSelectFilter($this->oUser, URP_UserProfile::class);
|
||||
if ($oFilterLnkProfiles === true)
|
||||
{
|
||||
if ($oFilterLnkProfiles === true) {
|
||||
$oFilterLnkProfiles = new DBObjectSearch(URP_UserProfile::class);
|
||||
}
|
||||
$oSet = new DBObjectSet($oFilterLnkProfiles);
|
||||
// There should some lnk referencing either our administrator account or the Administrator profile
|
||||
$bUserFound = false;
|
||||
$bProfileFound = false;
|
||||
while($oLnk = $oSet->Fetch())
|
||||
{
|
||||
if($oLnk->Get('userid') == $this->oUser->GetKey())
|
||||
{
|
||||
while ($oLnk = $oSet->Fetch()) {
|
||||
if ($oLnk->Get('userid') == $this->oUser->GetKey()) {
|
||||
$bUserFound = true;
|
||||
}
|
||||
if($oLnk->Get('profileid') == 1)
|
||||
{
|
||||
if ($oLnk->Get('profileid') == 1) {
|
||||
$bProfileFound = true;
|
||||
}
|
||||
}
|
||||
$this->assertEquals($bUserFound, true);
|
||||
$this->assertEquals($bProfileFound, true);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Administrator account, Administrator profile and URP_UserProfile related to administrators are now hidden
|
||||
// via GetSelectFilter
|
||||
@@ -139,17 +126,14 @@ class GetSelectFilterTest extends ItopDataTestCase
|
||||
$oFilterProfiles = $oUserRights->GetSelectFilter($this->oUser, URP_Profiles::class);
|
||||
$this->assertNotEquals($oFilterProfiles, true); // This class must be filtered
|
||||
$oSet = new DBObjectSet($oFilterProfiles);
|
||||
while($oProfile = $oSet->Fetch())
|
||||
{
|
||||
while ($oProfile = $oSet->Fetch()) {
|
||||
$this->assertNotEquals($oProfile->GetKey(), 1); // No profile should have id = 1 (Administrator)
|
||||
}
|
||||
foreach($aUserClasses as $sUserClass)
|
||||
{
|
||||
foreach ($aUserClasses as $sUserClass) {
|
||||
$oFilterUser = $oUserRights->GetSelectFilter($this->oUser, $sUserClass);
|
||||
$this->assertNotEquals($oFilterUser,true); // This class must be filtered
|
||||
$this->assertNotEquals($oFilterUser, true); // This class must be filtered
|
||||
$oSet = new DBObjectSet($oFilterUser);
|
||||
while($oUser = $oSet->Fetch())
|
||||
{
|
||||
while ($oUser = $oSet->Fetch()) {
|
||||
$this->assertNotEquals($oUser->GetKey(), $this->oUser->GetKey()); // Our administrator account should not be visible
|
||||
}
|
||||
}
|
||||
@@ -158,8 +142,7 @@ class GetSelectFilterTest extends ItopDataTestCase
|
||||
$this->assertNotEquals($oFilterLnkProfiles, true); // This class must be filtered
|
||||
$oSet = new DBObjectSet($oFilterLnkProfiles);
|
||||
// There should be no lnk referencing either our administrator account or the profile Administrator
|
||||
while($oLnk = $oSet->Fetch())
|
||||
{
|
||||
while ($oLnk = $oSet->Fetch()) {
|
||||
$this->assertNotEquals($oLnk->Get('userid'), $this->oUser->GetKey());
|
||||
$this->assertNotEquals($oLnk->Get('profileid'), 1);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -6,7 +7,6 @@
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core\Log;
|
||||
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use Config;
|
||||
use DeprecatedCallsLog;
|
||||
@@ -14,10 +14,12 @@ use FileLog;
|
||||
use IssueLog;
|
||||
use LogAPI;
|
||||
use utils;
|
||||
|
||||
use const E_USER_DEPRECATED;
|
||||
use const ITOP_PHPUNIT_RUNNING_CONSTANT_NAME;
|
||||
|
||||
class DeprecatedCallsLogErrorHandlerTest extends ItopTestCase {
|
||||
class DeprecatedCallsLogErrorHandlerTest extends ItopTestCase
|
||||
{
|
||||
public const DISABLE_DEPRECATEDCALLSLOG_ERRORHANDLER = false;
|
||||
|
||||
/**
|
||||
@@ -26,7 +28,8 @@ class DeprecatedCallsLogErrorHandlerTest extends ItopTestCase {
|
||||
*
|
||||
* @runInSeparateProcess so that other tests won't set the constant !
|
||||
*/
|
||||
public function testPhpLibMethodNoticeCatched():void {
|
||||
public function testPhpLibMethodNoticeCatched(): void
|
||||
{
|
||||
if (defined(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME)) {
|
||||
// Should not happen thanks to the process isolation !
|
||||
$this->fail('Constant to disable error handler is set, so we cannot test :(');
|
||||
@@ -50,9 +53,9 @@ class DeprecatedCallsLogErrorHandlerTest extends ItopTestCase {
|
||||
$oMockConfig
|
||||
->method("Get")
|
||||
->willReturnCallback(function ($sConfigParameterName) {
|
||||
if ($sConfigParameterName==='log_level_min'){
|
||||
if ($sConfigParameterName === 'log_level_min') {
|
||||
return [
|
||||
DeprecatedCallsLog::ENUM_CHANNEL_PHP_LIBMETHOD => LogAPI::LEVEL_TRACE
|
||||
DeprecatedCallsLog::ENUM_CHANNEL_PHP_LIBMETHOD => LogAPI::LEVEL_TRACE,
|
||||
];
|
||||
}
|
||||
/** @noinspection NullPointerExceptionInspection */
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -6,7 +7,6 @@
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core\Log;
|
||||
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use DeprecatedCallsLog;
|
||||
|
||||
@@ -208,7 +208,7 @@ class DeprecatedCallsLogTest extends ItopTestCase
|
||||
'function' => 'require_once',
|
||||
],
|
||||
],
|
||||
'out' => 'itop-root/env-production/core/main.php#1290'
|
||||
'out' => 'itop-root/env-production/core/main.php#1290',
|
||||
],
|
||||
'From a persistent object method (deprecated PHP function)' => [
|
||||
'in:stripped call stack' => [
|
||||
@@ -262,7 +262,7 @@ class DeprecatedCallsLogTest extends ItopTestCase
|
||||
'type' => '->',
|
||||
],
|
||||
],
|
||||
'out' => 'Ticket->OnBeforeWriteTicket (itop-root/env-production/itop-tickets/model.itop-tickets.php#165), itself called from DBObject->FireEvent (itop-root/core/dbobject.class.php#6575)'
|
||||
'out' => 'Ticket->OnBeforeWriteTicket (itop-root/env-production/itop-tickets/model.itop-tickets.php#165), itself called from DBObject->FireEvent (itop-root/core/dbobject.class.php#6575)',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
* This file is part of iTop.
|
||||
@@ -18,12 +19,11 @@ namespace Combodo\iTop\Test\UnitTest\Core\Log;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use ExceptionLog;
|
||||
|
||||
|
||||
require_once(__DIR__.'/ExceptionLogTest/Exceptions.php');
|
||||
|
||||
class ExceptionLogTest extends ItopDataTestCase
|
||||
{
|
||||
const USE_TRANSACTION = false;
|
||||
public const USE_TRANSACTION = false;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
@@ -46,16 +46,14 @@ class ExceptionLogTest extends ItopDataTestCase
|
||||
switch ($code) {
|
||||
case 'log_level_min':
|
||||
|
||||
if (is_null($logLevelMin))
|
||||
{
|
||||
if (is_null($logLevelMin)) {
|
||||
$logLevelMin = '';//this should be the default value, if it did change, please fix it here
|
||||
}
|
||||
|
||||
return $logLevelMin;
|
||||
case 'log_level_min.write_in_db':
|
||||
|
||||
if (is_null($logLevelMinWriteInDb))
|
||||
{
|
||||
if (is_null($logLevelMinWriteInDb)) {
|
||||
$logLevelMinWriteInDb = [ 'Exception' => 'Error', ];//this should be the default value, if it did change, please fix it here
|
||||
}
|
||||
|
||||
@@ -69,12 +67,15 @@ class ExceptionLogTest extends ItopDataTestCase
|
||||
foreach ($aLevels as $i => $sLevel) {
|
||||
$sExpectedFile = __FILE__;
|
||||
// @formatter:off
|
||||
$oException = new $aExceptions[$i]("Iteration number $i"); $sExpectedLine = __LINE__; //Both should remain on the same line
|
||||
$oException = new $aExceptions[$i]("Iteration number $i");
|
||||
$sExpectedLine = __LINE__; //Both should remain on the same line
|
||||
// @formatter:on
|
||||
|
||||
$iExpectedWriteNumber = $aExpectedWriteNumber[$i];
|
||||
$iExpectedDbWriteNumber = $aExpectedDbWriteNumber[$i];
|
||||
$aExpectedFileContext = array_merge($aContext, [
|
||||
$aExpectedFileContext = array_merge(
|
||||
$aContext,
|
||||
[
|
||||
'exception class' => get_class($oException),
|
||||
'file' => $sExpectedFile,
|
||||
'line' => $sExpectedLine,
|
||||
@@ -294,6 +295,3 @@ class ExceptionLogTest extends ItopDataTestCase
|
||||
$this->assertEquals('Ok', $resultFilePerDefaultWhenKeyNotFound);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
* This file is part of iTop.
|
||||
@@ -14,10 +15,16 @@
|
||||
*/
|
||||
|
||||
namespace {
|
||||
class ChildException extends Exception {};
|
||||
class GrandChildException extends ChildException {};
|
||||
class ChildException extends Exception
|
||||
{
|
||||
};
|
||||
class GrandChildException extends ChildException
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
namespace Namespaced\Exception {
|
||||
class ExceptionInNamespace extends \ChildException {}
|
||||
class ExceptionInNamespace extends \ChildException
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -13,7 +14,6 @@
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core\Log;
|
||||
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
|
||||
class LogAPITest extends ItopDataTestCase
|
||||
@@ -21,7 +21,7 @@ class LogAPITest extends ItopDataTestCase
|
||||
private $mockFileLog;
|
||||
private $oMetaModelConfig;
|
||||
|
||||
protected function setUp():void
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
@@ -29,7 +29,6 @@ class LogAPITest extends ItopDataTestCase
|
||||
$this->oMetaModelConfig = $this->createMock('Config');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dataProvider LogApiProvider
|
||||
* @test
|
||||
@@ -58,7 +57,7 @@ class LogAPITest extends ItopDataTestCase
|
||||
* @dataProvider LogWarningWithASpecificChannelProvider
|
||||
* @test
|
||||
*/
|
||||
public function TestLogWarningWithASpecificChannel($expectedCallNb, $sExpectedLevel, $ConfigReturnedObject, $bExceptionRaised=false)
|
||||
public function TestLogWarningWithASpecificChannel($expectedCallNb, $sExpectedLevel, $ConfigReturnedObject, $bExceptionRaised = false)
|
||||
{
|
||||
$this->oMetaModelConfig
|
||||
->method("Get")
|
||||
@@ -73,13 +72,12 @@ class LogAPITest extends ItopDataTestCase
|
||||
->method($sExpectedLevel)
|
||||
->with("log msg", "GaBuZoMeuChannel");
|
||||
|
||||
try{
|
||||
try {
|
||||
\IssueLog::Warning("log msg", "GaBuZoMeuChannel");
|
||||
if ($bExceptionRaised) {
|
||||
$this->fail("raised should have been raised");
|
||||
}
|
||||
}
|
||||
catch(\Exception $e) {
|
||||
} catch (\Exception $e) {
|
||||
if (!$bExceptionRaised) {
|
||||
$this->fail("raised should NOT have been raised");
|
||||
}
|
||||
@@ -93,7 +91,7 @@ class LogAPITest extends ItopDataTestCase
|
||||
"Default Unknown Level" => [ 0, "Ok", 'TotoLevel', true],
|
||||
"Info as Default Level" => [ 1 , "Warning", 'Info'],
|
||||
"Error as Default Level" => [ 0, "Warning", 'Error'],
|
||||
"Empty array" => [ 0, "Ok", array()],
|
||||
"Empty array" => [ 0, "Ok", []],
|
||||
"Channel configured on an undefined level" => [ 0, "Ok", ["GaBuZoMeuChannel" => "TotoLevel"], true],
|
||||
"Channel defined with Error" => [ 0, "Warning", ["GaBuZoMeuChannel" => "Error"]],
|
||||
"Channel defined with Info" => [ 1, "Warning", ["GaBuZoMeuChannel" => "Info"]],
|
||||
@@ -104,7 +102,7 @@ class LogAPITest extends ItopDataTestCase
|
||||
* @dataProvider LogOkWithASpecificChannel
|
||||
* @test
|
||||
*/
|
||||
public function TestLogOkWithASpecificChannel($expectedCallNb, $sExpectedLevel, $ConfigReturnedObject, $bExceptionRaised=false)
|
||||
public function TestLogOkWithASpecificChannel($expectedCallNb, $sExpectedLevel, $ConfigReturnedObject, $bExceptionRaised = false)
|
||||
{
|
||||
$this->oMetaModelConfig
|
||||
->method("Get")
|
||||
@@ -124,8 +122,7 @@ class LogAPITest extends ItopDataTestCase
|
||||
if ($bExceptionRaised) {
|
||||
$this->fail("raised should have been raised");
|
||||
}
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
} catch (\Exception $e) {
|
||||
if (!$bExceptionRaised) {
|
||||
$this->fail("raised should NOT have been raised");
|
||||
}
|
||||
@@ -136,7 +133,7 @@ class LogAPITest extends ItopDataTestCase
|
||||
{
|
||||
return [
|
||||
"empty config" => [1, "Ok", ''],
|
||||
"Empty array" => [1, "Ok", array()],
|
||||
"Empty array" => [1, "Ok", []],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -169,7 +166,6 @@ class LogAPITest extends ItopDataTestCase
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function testGetLevelDefault()
|
||||
{
|
||||
$resultDb = $this->InvokeNonPublicStaticMethod(\LogAPI::class, 'GetLevelDefault', [\LogAPI::ENUM_CONFIG_PARAM_DB]);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -6,15 +7,14 @@
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core\Log;
|
||||
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use DailyRotatingLogFileNameBuilder;
|
||||
use DateTime;
|
||||
|
||||
class LogFileNameBuilderTest extends ItopTestCase
|
||||
{
|
||||
const TEST_LOGFILE_PREFIX = 'fileNameBuilder.test';
|
||||
const TEST_LOGFILE_EXTENSION = 'log';
|
||||
public const TEST_LOGFILE_PREFIX = 'fileNameBuilder.test';
|
||||
public const TEST_LOGFILE_EXTENSION = 'log';
|
||||
|
||||
/**
|
||||
* @param $sLogFile
|
||||
@@ -51,8 +51,7 @@ class LogFileNameBuilderTest extends ItopTestCase
|
||||
$sLogFile = __DIR__.DIRECTORY_SEPARATOR.self::TEST_LOGFILE_PREFIX.'.'.self::TEST_LOGFILE_EXTENSION;
|
||||
$oFileBuilder = new DailyRotatingLogFileNameBuilder($sLogFile);
|
||||
|
||||
if (file_exists($sLogFile))
|
||||
{
|
||||
if (file_exists($sLogFile)) {
|
||||
unlink($sLogFile);
|
||||
}
|
||||
|
||||
@@ -92,21 +91,21 @@ class LogFileNameBuilderTest extends ItopTestCase
|
||||
|
||||
public function ShouldRotateProvider()
|
||||
{
|
||||
return array(
|
||||
'DAILY Same day' => array('DailyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-01 15:42', false),
|
||||
'DAILY Same week, different day less 24h diff' => array('DailyRotatingLogFileNameBuilder', '2020-02-01 12:00', '2020-02-02 09:00', true),
|
||||
'DAILY Same week, different day' => array('DailyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-02 00:00', true),
|
||||
'DAILY 1 week diff' => array('DailyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-08 00:00', true),
|
||||
'WEEKLY Same week' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-01 00:00', false),
|
||||
'WEEKLY 1 week diff, same month' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-08 00:00', true),
|
||||
'WEEKLY 2 weeks diff, same month' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-15 00:00', true),
|
||||
'WEEKLY 1 week diff, different month' => array('WeeklyRotatingLogFileNameBuilder', '2020-01-27 00:00', '2020-02-03 00:00', true),
|
||||
'WEEKLY same week, different month' => array('WeeklyRotatingLogFileNameBuilder', '2020-01-27 00:00', '2020-02-02 00:00', false),
|
||||
'WEEKLY 1 week diff, different year' => array('WeeklyRotatingLogFileNameBuilder', '2019-12-30 00:00', '2020-01-06 00:00', true),
|
||||
'WEEKLY same week, different year' => array('WeeklyRotatingLogFileNameBuilder', '2019-12-30 00:00', '2020-01-05 00:00', true),
|
||||
'MONTHLY same month' => array('MonthlyRotatingLogFileNameBuilder', '2020-02-10 00:00', '2020-02-14 00:00', false),
|
||||
'MONTHLY on first day which is a sunday' => array('MonthlyRotatingLogFileNameBuilder', '2020-01-30 00:00', '2020-02-01 00:00', true),
|
||||
);
|
||||
return [
|
||||
'DAILY Same day' => ['DailyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-01 15:42', false],
|
||||
'DAILY Same week, different day less 24h diff' => ['DailyRotatingLogFileNameBuilder', '2020-02-01 12:00', '2020-02-02 09:00', true],
|
||||
'DAILY Same week, different day' => ['DailyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-02 00:00', true],
|
||||
'DAILY 1 week diff' => ['DailyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-08 00:00', true],
|
||||
'WEEKLY Same week' => ['WeeklyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-01 00:00', false],
|
||||
'WEEKLY 1 week diff, same month' => ['WeeklyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-08 00:00', true],
|
||||
'WEEKLY 2 weeks diff, same month' => ['WeeklyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-15 00:00', true],
|
||||
'WEEKLY 1 week diff, different month' => ['WeeklyRotatingLogFileNameBuilder', '2020-01-27 00:00', '2020-02-03 00:00', true],
|
||||
'WEEKLY same week, different month' => ['WeeklyRotatingLogFileNameBuilder', '2020-01-27 00:00', '2020-02-02 00:00', false],
|
||||
'WEEKLY 1 week diff, different year' => ['WeeklyRotatingLogFileNameBuilder', '2019-12-30 00:00', '2020-01-06 00:00', true],
|
||||
'WEEKLY same week, different year' => ['WeeklyRotatingLogFileNameBuilder', '2019-12-30 00:00', '2020-01-05 00:00', true],
|
||||
'MONTHLY same month' => ['MonthlyRotatingLogFileNameBuilder', '2020-02-10 00:00', '2020-02-14 00:00', false],
|
||||
'MONTHLY on first day which is a sunday' => ['MonthlyRotatingLogFileNameBuilder', '2020-01-30 00:00', '2020-02-01 00:00', true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,15 +130,15 @@ class LogFileNameBuilderTest extends ItopTestCase
|
||||
|
||||
public function CronNextOccurrenceProvider()
|
||||
{
|
||||
return array(
|
||||
'DAILY morning' => array('DailyRotatingLogFileNameBuilder', '2020-02-01 05:00', '2020-02-02 00:00'),
|
||||
'DAILY midnight' => array('DailyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-02 00:00'),
|
||||
'WEEKLY monday 12:42' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-03 12:42', '2020-02-10 00:00'),
|
||||
'WEEKLY monday 00:00' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-03 00:00', '2020-02-10 00:00'),
|
||||
'WEEKLY tuesday 12:42' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-04 12:42', '2020-02-10 00:00'),
|
||||
'WEEKLY sunday 12:42' => array('WeeklyRotatingLogFileNameBuilder', '2020-02-02 12:42', '2020-02-03 00:00'),
|
||||
'MONTHLY 12/02 12:42' => array('MonthlyRotatingLogFileNameBuilder', '2020-02-12 12:42', '2020-03-01 00:00'),
|
||||
);
|
||||
return [
|
||||
'DAILY morning' => ['DailyRotatingLogFileNameBuilder', '2020-02-01 05:00', '2020-02-02 00:00'],
|
||||
'DAILY midnight' => ['DailyRotatingLogFileNameBuilder', '2020-02-01 00:00', '2020-02-02 00:00'],
|
||||
'WEEKLY monday 12:42' => ['WeeklyRotatingLogFileNameBuilder', '2020-02-03 12:42', '2020-02-10 00:00'],
|
||||
'WEEKLY monday 00:00' => ['WeeklyRotatingLogFileNameBuilder', '2020-02-03 00:00', '2020-02-10 00:00'],
|
||||
'WEEKLY tuesday 12:42' => ['WeeklyRotatingLogFileNameBuilder', '2020-02-04 12:42', '2020-02-10 00:00'],
|
||||
'WEEKLY sunday 12:42' => ['WeeklyRotatingLogFileNameBuilder', '2020-02-02 12:42', '2020-02-03 00:00'],
|
||||
'MONTHLY 12/02 12:42' => ['MonthlyRotatingLogFileNameBuilder', '2020-02-12 12:42', '2020-03-01 00:00'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -197,13 +197,13 @@ class MetaModelMagicPlaceholderTest extends ItopDataTestCase
|
||||
$this->assertEqualsShallow(
|
||||
[
|
||||
'gabu' => 'zomeu',
|
||||
'current_contact_id' => '',
|
||||
'current_contact_id' => '',
|
||||
'current_user->object()' => '(current_user->object() : cannot be resolved)',
|
||||
'current_user->not_existing_attribute' => '(current_user->not_existing_attribute : cannot be resolved)',
|
||||
'current_user->not_existing_attribute' => '(current_user->not_existing_attribute : cannot be resolved)',
|
||||
'current_user->login' => '(current_user->login : cannot be resolved)',
|
||||
'current_contact->object()' => '(current_contact->object() : cannot be resolved)',
|
||||
'current_contact->object()' => '(current_contact->object() : cannot be resolved)',
|
||||
'current_contact->org_id' => '(current_contact->org_id : cannot be resolved)',
|
||||
'current_contact->not_existing_attribute' => '(current_contact->not_existing_attribute : cannot be resolved)',
|
||||
'current_contact->not_existing_attribute' => '(current_contact->not_existing_attribute : cannot be resolved)',
|
||||
],
|
||||
$aPlaceholders,
|
||||
'AddMagicPlaceholders should add expected arguments and render them with an explicit error when the information could not be known'
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
@@ -16,11 +15,11 @@ use MetaModel;
|
||||
*/
|
||||
class MetaModelTest extends ItopDataTestCase
|
||||
{
|
||||
protected static $iDefaultUserOrgId = 1;
|
||||
protected static $iDefaultUserCallerId = 1;
|
||||
protected static $sDefaultUserRequestTitle = 'Unit test title';
|
||||
protected static $sDefaultUserRequestDescription = 'Unit test description';
|
||||
protected static $sDefaultUserRequestDescriptionAsHtml = '<p>Unit test description</p>';
|
||||
protected static $iDefaultUserOrgId = 1;
|
||||
protected static $iDefaultUserCallerId = 1;
|
||||
protected static $sDefaultUserRequestTitle = 'Unit test title';
|
||||
protected static $sDefaultUserRequestDescription = 'Unit test description';
|
||||
protected static $sDefaultUserRequestDescriptionAsHtml = '<p>Unit test description</p>';
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
@@ -52,49 +51,49 @@ class MetaModelTest extends ItopDataTestCase
|
||||
// multi-level hierarchy
|
||||
$oServer1 = MetaModel::GetObjectByName('Server', 'Server1');
|
||||
$sServer1Id = $oServer1->GetKey();
|
||||
foreach (MetaModel::EnumParentClasses('Server',ENUM_PARENT_CLASSES_ALL) as $sClass) {
|
||||
foreach (MetaModel::EnumParentClasses('Server', ENUM_PARENT_CLASSES_ALL) as $sClass) {
|
||||
$this->assertEquals('Server', MetaModel::GetFinalClassName($sClass, $sServer1Id), 'Should return Server for all the classes in the hierarchy');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @group itopRequestMgmt
|
||||
* @covers MetaModel::ApplyParams()
|
||||
* @dataProvider ApplyParamsProvider
|
||||
*
|
||||
* @param string $sInput
|
||||
* @param array $aParams
|
||||
* @param string $sExpectedOutput
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
* @group itopRequestMgmt
|
||||
* @covers MetaModel::ApplyParams()
|
||||
* @dataProvider ApplyParamsProvider
|
||||
*
|
||||
* @param string $sInput
|
||||
* @param array $aParams
|
||||
* @param string $sExpectedOutput
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function testApplyParams($sInput, $aParams, $sExpectedOutput)
|
||||
{
|
||||
$oUserRequest = $this->createObject(
|
||||
'UserRequest',
|
||||
array(
|
||||
'org_id' => static::$iDefaultUserOrgId,
|
||||
'caller_id' => static::$iDefaultUserCallerId,
|
||||
'title' => static::$sDefaultUserRequestTitle,
|
||||
'description' => static::$sDefaultUserRequestDescriptionAsHtml,
|
||||
)
|
||||
);
|
||||
$oUserRequest = $this->createObject(
|
||||
'UserRequest',
|
||||
[
|
||||
'org_id' => static::$iDefaultUserOrgId,
|
||||
'caller_id' => static::$iDefaultUserCallerId,
|
||||
'title' => static::$sDefaultUserRequestTitle,
|
||||
'description' => static::$sDefaultUserRequestDescriptionAsHtml,
|
||||
]
|
||||
);
|
||||
|
||||
$aParams['this->object()'] = $oUserRequest;
|
||||
$aParams['this->object()'] = $oUserRequest;
|
||||
|
||||
$sGeneratedOutput = MetaModel::ApplyParams($sInput, $aParams);
|
||||
$sGeneratedOutput = MetaModel::ApplyParams($sInput, $aParams);
|
||||
|
||||
$this->assertEquals($sExpectedOutput, $sGeneratedOutput, "ApplyParams test returned $sGeneratedOutput");
|
||||
}
|
||||
|
||||
public function ApplyParamsProvider()
|
||||
{
|
||||
$sTitle = static::$sDefaultUserRequestTitle;
|
||||
$sTitle = static::$sDefaultUserRequestTitle;
|
||||
|
||||
$aParams = [
|
||||
$aParams = [
|
||||
'simple' => 'I am simple',
|
||||
'foo->bar' => 'I am bar', // N°2889 - Placeholder with an arrow that is not an object
|
||||
];
|
||||
'foo->bar' => 'I am bar', // N°2889 - Placeholder with an arrow that is not an object
|
||||
];
|
||||
|
||||
return [
|
||||
'Simple placeholder' => [
|
||||
@@ -118,19 +117,19 @@ class MetaModelTest extends ItopDataTestCase
|
||||
'Result: <a href="http://foo.bar/I am bar">Hyperlink</a>',
|
||||
],
|
||||
'Placeholder for an object string attribute (text format)' => [
|
||||
'Title: $this->title$',
|
||||
$aParams,
|
||||
'Title: '.$sTitle,
|
||||
'Title: $this->title$',
|
||||
$aParams,
|
||||
'Title: '.$sTitle,
|
||||
],
|
||||
'Placeholder for an object string attribute (html format)' => [
|
||||
'Title: <p>$this->title$</p>',
|
||||
$aParams,
|
||||
'Title: <p>'.$sTitle.'</p>',
|
||||
'Title: <p>$this->title$</p>',
|
||||
$aParams,
|
||||
'Title: <p>'.$sTitle.'</p>',
|
||||
],
|
||||
'Placeholder for an object string attribute url-encoded (html format)' => [
|
||||
'Title: <a href="http://foo.bar/%24this->title%24">Hyperlink</a>',
|
||||
$aParams,
|
||||
'Title: <a href="http://foo.bar/'.$sTitle.'">Hyperlink</a>',
|
||||
'Title: <a href="http://foo.bar/%24this->title%24">Hyperlink</a>',
|
||||
$aParams,
|
||||
'Title: <a href="http://foo.bar/'.$sTitle.'">Hyperlink</a>',
|
||||
],
|
||||
'Placeholder for an object HTML attribute as its default format' => [
|
||||
'$this->description$',
|
||||
@@ -171,14 +170,13 @@ class MetaModelTest extends ItopDataTestCase
|
||||
|
||||
public function GetDependentAttributesProvider()
|
||||
{
|
||||
$aRawCases = array(
|
||||
array('Person', 'org_id', array('location_id', 'org_name', 'org_id_friendlyname', 'org_id_obsolescence_flag')),
|
||||
array('Person', 'name', array('friendlyname')),
|
||||
array('Person', 'status', array('obsolescence_flag')),
|
||||
);
|
||||
$aRet = array();
|
||||
foreach ($aRawCases as $i => $aData)
|
||||
{
|
||||
$aRawCases = [
|
||||
['Person', 'org_id', ['location_id', 'org_name', 'org_id_friendlyname', 'org_id_obsolescence_flag']],
|
||||
['Person', 'name', ['friendlyname']],
|
||||
['Person', 'status', ['obsolescence_flag']],
|
||||
];
|
||||
$aRet = [];
|
||||
foreach ($aRawCases as $i => $aData) {
|
||||
$aRet[$aData[0].'::'.$aData[1]] = $aData;
|
||||
}
|
||||
return $aRet;
|
||||
@@ -205,16 +203,15 @@ class MetaModelTest extends ItopDataTestCase
|
||||
|
||||
public function GetPrerequisiteAttributesProvider()
|
||||
{
|
||||
$aRawCases = array(
|
||||
array('Person', 'friendlyname', array('name', 'first_name')),
|
||||
array('Person', 'obsolescence_flag', array('status')),
|
||||
array('Person', 'org_id_friendlyname', array('org_id')),
|
||||
array('Person', 'org_id', array()),
|
||||
array('Person', 'org_name', array('org_id')),
|
||||
);
|
||||
$aRet = array();
|
||||
foreach ($aRawCases as $i => $aData)
|
||||
{
|
||||
$aRawCases = [
|
||||
['Person', 'friendlyname', ['name', 'first_name']],
|
||||
['Person', 'obsolescence_flag', ['status']],
|
||||
['Person', 'org_id_friendlyname', ['org_id']],
|
||||
['Person', 'org_id', []],
|
||||
['Person', 'org_name', ['org_id']],
|
||||
];
|
||||
$aRet = [];
|
||||
foreach ($aRawCases as $i => $aData) {
|
||||
$aRet[$aData[0].'::'.$aData[1]] = $aData;
|
||||
}
|
||||
return $aRet;
|
||||
@@ -226,14 +223,18 @@ class MetaModelTest extends ItopDataTestCase
|
||||
*/
|
||||
public function testManualVersusAutomaticDependenciesOnExtKeys()
|
||||
{
|
||||
foreach (\MetaModel::GetClasses() as $sClass)
|
||||
{
|
||||
if (\MetaModel::IsAbstract($sClass)) continue;
|
||||
foreach (\MetaModel::GetClasses() as $sClass) {
|
||||
if (\MetaModel::IsAbstract($sClass)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (\MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if (\MetaModel::GetAttributeOrigin($sClass, $sAttCode) != $sClass) continue;
|
||||
if (!$oAttDef instanceof \AttributeExternalKey) continue;
|
||||
foreach (\MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
|
||||
if (\MetaModel::GetAttributeOrigin($sClass, $sAttCode) != $sClass) {
|
||||
continue;
|
||||
}
|
||||
if (!$oAttDef instanceof \AttributeExternalKey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$aManual = $oAttDef->Get('depends_on');
|
||||
$aAuto = \MetaModel::GetPrerequisiteAttributes($sClass, $sAttCode);
|
||||
@@ -254,7 +255,7 @@ class MetaModelTest extends ItopDataTestCase
|
||||
* @param $interface
|
||||
* @param null $sFilterInstanceOf
|
||||
*/
|
||||
public function testEnumPlugins($expectedInstanciationCalls, $expectedResults, $m_aExtensionClassNames, $m_aExtensionClasses, $interface, $sFilterInstanceOf=null)
|
||||
public function testEnumPlugins($expectedInstanciationCalls, $expectedResults, $m_aExtensionClassNames, $m_aExtensionClasses, $interface, $sFilterInstanceOf = null)
|
||||
{
|
||||
$pluginInstanciationManager = new \PluginInstanciationManager();
|
||||
$res = $pluginInstanciationManager->InstantiatePlugins($m_aExtensionClassNames, $interface);
|
||||
@@ -282,7 +283,8 @@ class MetaModelTest extends ItopDataTestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function enumPluginsProvider(){
|
||||
public function enumPluginsProvider()
|
||||
{
|
||||
$aInterfaces = [
|
||||
"empty conf" => [0, [], [], [], 'Wizzard'],
|
||||
"simple instance retrieval" => [1, [Gryffindor::class => Gryffindor::class], ['Wizzard' => [Gryffindor::class]], [], 'Wizzard'],
|
||||
@@ -458,36 +460,38 @@ class MetaModelTest extends ItopDataTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws CoreException
|
||||
* @throws \OQLException
|
||||
* @dataProvider PurgeDataProvider
|
||||
*
|
||||
*/
|
||||
public function testPurgeData( $iMaxChunkSize, $iNbQueriesExpected){
|
||||
// Set max_chunk_size to $iMaxChunkSize (default 1000) to test chunk deletion with only 10 items
|
||||
$oConfig = MetaModel::GetConfig();
|
||||
$oConfig->Set('purge_data.max_chunk_size', $iMaxChunkSize);
|
||||
/**
|
||||
* @return void
|
||||
* @throws CoreException
|
||||
* @throws \OQLException
|
||||
* @dataProvider PurgeDataProvider
|
||||
*
|
||||
*/
|
||||
public function testPurgeData($iMaxChunkSize, $iNbQueriesExpected)
|
||||
{
|
||||
// Set max_chunk_size to $iMaxChunkSize (default 1000) to test chunk deletion with only 10 items
|
||||
$oConfig = MetaModel::GetConfig();
|
||||
$oConfig->Set('purge_data.max_chunk_size', $iMaxChunkSize);
|
||||
|
||||
$aPkPerson = [];
|
||||
for ($i=0; $i < 10; $i++) {
|
||||
$oPerson = $this->CreatePerson($i, 1);
|
||||
$sClass = get_class($oPerson);
|
||||
$aPkPerson[] = $oPerson->GetKey();
|
||||
}
|
||||
$aPkPerson = [];
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$oPerson = $this->CreatePerson($i, 1);
|
||||
$sClass = get_class($oPerson);
|
||||
$aPkPerson[] = $oPerson->GetKey();
|
||||
}
|
||||
|
||||
$oFilter = DBObjectSearch::FromOQL('SELECT '.$sClass.' WHERE id IN ('.implode(',', $aPkPerson).')');
|
||||
$iNbDelete = 0;
|
||||
$oFilter = DBObjectSearch::FromOQL('SELECT '.$sClass.' WHERE id IN ('.implode(',', $aPkPerson).')');
|
||||
$iNbDelete = 0;
|
||||
|
||||
$this->assertDBQueryCount($iNbQueriesExpected, function() use ($oFilter, &$iNbDelete) {
|
||||
$this->assertDBQueryCount($iNbQueriesExpected, function () use ($oFilter, &$iNbDelete) {
|
||||
$iNbDelete = MetaModel::PurgeData($oFilter);
|
||||
} );
|
||||
});
|
||||
|
||||
$this->assertEquals($iNbDelete, 10, 'MetaModel::PurgeData must delete 10 objects per batch of 2 items');
|
||||
}
|
||||
$this->assertEquals($iNbDelete, 10, 'MetaModel::PurgeData must delete 10 objects per batch of 2 items');
|
||||
}
|
||||
|
||||
public function PurgeDataProvider(){
|
||||
public function PurgeDataProvider()
|
||||
{
|
||||
return [
|
||||
'Purge 10 items with a max_chunk_size of 2 should be perfomed in 5 steps + an additional query to verify that the job is complete' => [2, 16],
|
||||
'Purge 10 items with a max_chunk_size of 3 should be perfomed in 4 steps' => [3, 12],
|
||||
@@ -498,7 +502,6 @@ class MetaModelTest extends ItopDataTestCase
|
||||
|
||||
abstract class Wizzard
|
||||
{
|
||||
|
||||
/**
|
||||
* Wizzard constructor.
|
||||
*/
|
||||
@@ -509,23 +512,18 @@ abstract class Wizzard
|
||||
|
||||
class Gryffindor extends Wizzard
|
||||
{
|
||||
|
||||
}
|
||||
class Hufflepuff extends Wizzard
|
||||
{
|
||||
|
||||
}
|
||||
class Ravenclaw extends Wizzard
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
class Slytherin extends Wizzard
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
class Muggle
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
class MockValueSetObjects extends ValueSetObjects
|
||||
{
|
||||
public function __construct($sFilterExp, $sValueAttCode = '', $aOrderBy = array(), $bAllowAllData = false, $aModifierProperties = array())
|
||||
public function __construct($sFilterExp, $sValueAttCode = '', $aOrderBy = [], $bAllowAllData = false, $aModifierProperties = [])
|
||||
{
|
||||
parent::__construct($sFilterExp, $sValueAttCode , $aOrderBy, $bAllowAllData, $aModifierProperties );
|
||||
parent::__construct($sFilterExp, $sValueAttCode, $aOrderBy, $bAllowAllData, $aModifierProperties);
|
||||
}
|
||||
public function GetFilterOQL(
|
||||
$sOperation, $sContains
|
||||
)
|
||||
{
|
||||
$sOperation,
|
||||
$sContains
|
||||
) {
|
||||
|
||||
return $this->GetFilter($sOperation, $sContains)->ToOQL();
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use DBObjectSearch;
|
||||
use DBSearch;
|
||||
@@ -21,7 +20,6 @@ use UserRights;
|
||||
|
||||
class OQLParserTest extends ItopDataTestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @group iTopChangeMgt
|
||||
* @group itopConfigMgmt
|
||||
@@ -37,9 +35,9 @@ class OQLParserTest extends ItopDataTestCase
|
||||
{
|
||||
$this->debug($sQuery);
|
||||
$oDbObjectSearch = DBObjectSearch::FromOQL($sQuery);
|
||||
$sOql=$oDbObjectSearch->ToOQL();
|
||||
$sOql = $oDbObjectSearch->ToOQL();
|
||||
$this->debug($sOql);
|
||||
self::assertEquals($sQuery,$sOql);
|
||||
self::assertEquals($sQuery, $sOql);
|
||||
}
|
||||
|
||||
public function testUnknownClassOqlException()
|
||||
@@ -51,29 +49,28 @@ class OQLParserTest extends ItopDataTestCase
|
||||
try {
|
||||
DBSearch::FromOQL('SELECT UnknownClass');
|
||||
$this->fail('An UnknownClassOqlException should have been thrown');
|
||||
}
|
||||
catch (UnknownClassOqlException $e) {
|
||||
} catch (UnknownClassOqlException $e) {
|
||||
$this->assertNotContains('DBProperty', $e->GetSuggestions(), 'user should not be recommanded to perform queries on classes his not allowed to see');
|
||||
}
|
||||
}
|
||||
|
||||
public function NestedQueryProvider()
|
||||
{
|
||||
return array(
|
||||
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 `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 `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` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`org_id` IN (SELECT `Organization` FROM Organization AS `Organization` WHERE 1))'),
|
||||
array('SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`org_id` NOT IN (SELECT `Organization` FROM Organization AS `Organization` WHERE 1))'),
|
||||
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` = \'3\')))'),
|
||||
array("SELECT `L`, `P` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE 1"),
|
||||
array("SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE ((`UserRequest`.`agent_id` = :current_contact_id) AND (`UserRequest`.`status` NOT IN ('closed', 'resolved')))"),
|
||||
array("SELECT `L` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id WHERE 1"),
|
||||
);
|
||||
return [
|
||||
["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 `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 `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`org_id` IN (SELECT `Organization` FROM Organization AS `Organization` WHERE (`Organization`.`id` = `UserRequest`.`org_id`)))'],
|
||||
['SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`org_id` IN (SELECT `Organization` FROM Organization AS `Organization` WHERE 1))'],
|
||||
['SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`org_id` NOT IN (SELECT `Organization` FROM Organization AS `Organization` WHERE 1))'],
|
||||
['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` = \'3\')))'],
|
||||
["SELECT `L`, `P` FROM Location AS `L` JOIN Person AS `P` ON `P`.location_id = `L`.id WHERE 1"],
|
||||
["SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE ((`UserRequest`.`agent_id` = :current_contact_id) AND (`UserRequest`.`status` NOT IN ('closed', 'resolved')))"],
|
||||
["SELECT `L` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id WHERE 1"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,11 +86,9 @@ class OQLParserTest extends ItopDataTestCase
|
||||
try {
|
||||
$oOql = new OqlInterpreter($sQuery);
|
||||
$oOql->ParseQuery();
|
||||
}
|
||||
catch (OQLParserException $e) {
|
||||
} catch (OQLParserException $e) {
|
||||
self::fail("OQL Parser stack overflow");
|
||||
}
|
||||
catch (OQLException $e) {
|
||||
} catch (OQLException $e) {
|
||||
self::fail("OQL Parser stack overflow");
|
||||
}
|
||||
self::assertTrue(true);
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
|
||||
use CMDBSource;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use DBObjectSearch;
|
||||
@@ -23,7 +22,7 @@ use utils;
|
||||
|
||||
class OQLTest extends ItopDataTestCase
|
||||
{
|
||||
const USE_TRANSACTION = false;
|
||||
public const USE_TRANSACTION = false;
|
||||
|
||||
/**
|
||||
* @doesNotPerformAssertions
|
||||
@@ -62,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
|
||||
@@ -330,7 +321,7 @@ class OQLTest extends ItopDataTestCase
|
||||
|
||||
public function OQLIntersectProvider()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
// Wrong result:
|
||||
/*
|
||||
SELECT `SSC`
|
||||
@@ -348,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)))",
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,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);
|
||||
}
|
||||
@@ -385,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
|
||||
@@ -409,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;
|
||||
}
|
||||
}
|
||||
@@ -461,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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
@@ -37,8 +38,10 @@ class RestServicesSanitizeOutputTest extends ItopCustomDatamodelTestCase
|
||||
*/
|
||||
public function testSanitizeAttributeOnRequestedObject()
|
||||
{
|
||||
$oContactTest = MetaModel::NewObject('ContactTest', [
|
||||
'password' => self::SIMPLE_PASSWORD
|
||||
$oContactTest = MetaModel::NewObject(
|
||||
'ContactTest',
|
||||
[
|
||||
'password' => self::SIMPLE_PASSWORD,
|
||||
]
|
||||
);
|
||||
$oRestResultWithObject = new RestResultWithObjects();
|
||||
@@ -46,7 +49,8 @@ class RestServicesSanitizeOutputTest extends ItopCustomDatamodelTestCase
|
||||
$oRestResultWithObject->SanitizeContent();
|
||||
static::assertJsonStringEqualsJsonString(
|
||||
'{"objects":{"ContactTest::-1":{"code":0,"message":"ok","class":"ContactTest","key":-1,"fields":{"password":"*****"}}},"code":0,"message":null}',
|
||||
json_encode($oRestResultWithObject));
|
||||
json_encode($oRestResultWithObject)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,8 +59,10 @@ class RestServicesSanitizeOutputTest extends ItopCustomDatamodelTestCase
|
||||
*/
|
||||
public function testSanitizeAttributeExternalFieldOnLink()
|
||||
{
|
||||
$oContactTest = $this->createObject('ContactTest', [
|
||||
'password' => self::SIMPLE_PASSWORD
|
||||
$oContactTest = $this->createObject(
|
||||
'ContactTest',
|
||||
[
|
||||
'password' => self::SIMPLE_PASSWORD,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -64,26 +70,31 @@ class RestServicesSanitizeOutputTest extends ItopCustomDatamodelTestCase
|
||||
'name' => 'test_server',
|
||||
]);
|
||||
|
||||
|
||||
// create lnkContactTestToServer
|
||||
$oLnkContactTestToServer = $this->createObject('lnkContactTestToServer', [
|
||||
'contact_test_id' => $oContactTest->GetKey(),
|
||||
'test_server_id' => $oTestServer->GetKey()
|
||||
'test_server_id' => $oTestServer->GetKey(),
|
||||
]);
|
||||
|
||||
$oRestResultWithObject = new RestResultWithObjects();
|
||||
$oRestResultWithObject->AddObject(0, 'ok', $oLnkContactTestToServer,
|
||||
['lnkContactTestToServer' => ['contact_test_password']]);
|
||||
$oRestResultWithObject->AddObject(
|
||||
0,
|
||||
'ok',
|
||||
$oLnkContactTestToServer,
|
||||
['lnkContactTestToServer' => ['contact_test_password']]
|
||||
);
|
||||
|
||||
$oRestResultWithObject->SanitizeContent();
|
||||
|
||||
static::assertStringContainsString(
|
||||
'*****',
|
||||
json_encode($oRestResultWithObject));
|
||||
json_encode($oRestResultWithObject)
|
||||
);
|
||||
|
||||
static::assertStringNotContainsString(
|
||||
self::SIMPLE_PASSWORD,
|
||||
json_encode($oRestResultWithObject));
|
||||
json_encode($oRestResultWithObject)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +103,7 @@ class RestServicesSanitizeOutputTest extends ItopCustomDatamodelTestCase
|
||||
public function testSanitizeAttributeOnObjectRelatedThroughNNRelation()
|
||||
{
|
||||
$oContactTest = $this->createObject('ContactTest', [
|
||||
'password' => self::SIMPLE_PASSWORD
|
||||
'password' => self::SIMPLE_PASSWORD,
|
||||
]);
|
||||
|
||||
$oTestServer = $this->createObject('TestServer', [
|
||||
@@ -102,26 +113,31 @@ class RestServicesSanitizeOutputTest extends ItopCustomDatamodelTestCase
|
||||
// create lnkContactTestToServer
|
||||
$this->createObject('lnkContactTestToServer', [
|
||||
'contact_test_id' => $oContactTest->GetKey(),
|
||||
'test_server_id' => $oTestServer->GetKey()
|
||||
'test_server_id' => $oTestServer->GetKey(),
|
||||
]);
|
||||
|
||||
$oTestServer->Reload();
|
||||
|
||||
$oRestResultWithObject = new RestResultWithObjects();
|
||||
$oRestResultWithObject->AddObject(0, 'ok', $oTestServer,
|
||||
['TestServer' => ['contact_list']]);
|
||||
$oRestResultWithObject->AddObject(
|
||||
0,
|
||||
'ok',
|
||||
$oTestServer,
|
||||
['TestServer' => ['contact_list']]
|
||||
);
|
||||
|
||||
$oRestResultWithObject->SanitizeContent();
|
||||
static::assertStringContainsString(
|
||||
'*****',
|
||||
json_encode($oRestResultWithObject));
|
||||
json_encode($oRestResultWithObject)
|
||||
);
|
||||
|
||||
static::assertStringNotContainsString(
|
||||
self::SIMPLE_PASSWORD,
|
||||
json_encode($oRestResultWithObject));
|
||||
json_encode($oRestResultWithObject)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws CoreException
|
||||
* @throws CoreUnexpectedValue
|
||||
@@ -149,11 +165,13 @@ class RestServicesSanitizeOutputTest extends ItopCustomDatamodelTestCase
|
||||
|
||||
static::assertStringContainsString(
|
||||
'*****',
|
||||
json_encode($oRestResultWithObject));
|
||||
json_encode($oRestResultWithObject)
|
||||
);
|
||||
|
||||
static::assertStringNotContainsString(
|
||||
self::SIMPLE_PASSWORD,
|
||||
json_encode($oRestResultWithObject));
|
||||
json_encode($oRestResultWithObject)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
@@ -40,7 +41,7 @@ class RestServicesTest extends ItopDataTestCase
|
||||
"operation": "core/check_credentials",
|
||||
"user": "admin",
|
||||
"password": "*****"
|
||||
}'
|
||||
}',
|
||||
],
|
||||
'core/update' => [
|
||||
'{"operation": "core/update", "comment": "Update user", "class": "UserLocal", "key": {"id":1}, "output_fields": "first_name, password", "fields": {"password" : "123456"}}',
|
||||
@@ -55,7 +56,7 @@ class RestServicesTest extends ItopDataTestCase
|
||||
"fields": {
|
||||
"password": "*****"
|
||||
}
|
||||
}'
|
||||
}',
|
||||
],
|
||||
'core/create' => [
|
||||
'{"operation": "core/create", "comment": "Create user", "class": "UserLocal", "fields": {"first_name": "John", "last_name": "Doe", "email": "jd@example/com", "password" : "123456"}}',
|
||||
@@ -69,7 +70,7 @@ class RestServicesTest extends ItopDataTestCase
|
||||
"email": "jd@example/com",
|
||||
"password": "*****"
|
||||
}
|
||||
}'
|
||||
}',
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -103,22 +104,22 @@ class RestServicesTest extends ItopDataTestCase
|
||||
'core/update' => [
|
||||
'core/update',
|
||||
['comment' => 'Update user', 'class' => 'UserLocal', 'key' => ['login' => 'my_example'], 'output_fields' => 'password', 'fields' => ['password' => 'opkB!req57']],
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"*****"}}},"code":0,"message":null}'
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"*****"}}},"code":0,"message":null}',
|
||||
],
|
||||
'core/create' => [
|
||||
'core/create',
|
||||
['comment' => 'Create user', 'class' => 'UserLocal', 'fields' => ['password' => 'Azertyuiiop*12', 'login' => 'toto', 'profile_list' => [1]]],
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"*****"}}},"code":0,"message":null}'
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"*****"}}},"code":0,"message":null}',
|
||||
],
|
||||
'core/get' => [
|
||||
'core/get',
|
||||
['comment' => 'Get user', 'class' => 'UserLocal', 'key' => ['login' => 'my_example'], 'output_fields' => 'first_name, password'],
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"*****"}}},"code":0,"message":null}'
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"*****"}}},"code":0,"message":null}',
|
||||
],
|
||||
'core/check_credentials' => [
|
||||
'core/check_credentials',
|
||||
['user' => 'admin', 'password' => 'admin'],
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"*****"}}},"code":0,"message":null}'
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"*****"}}},"code":0,"message":null}',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*!
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -14,66 +15,66 @@ use SodiumException;
|
||||
*/
|
||||
class SympleCryptTest extends ItopDataTestCase
|
||||
{
|
||||
public function DecryptClassProvider()
|
||||
{
|
||||
$aClassProvider = ['SimpleCrypt'=>['SimpleCrypt'],
|
||||
'SimpleCryptSimpleEngine'=>['SimpleCryptSimpleEngine']];
|
||||
if(function_exists('sodium_crypto_secretbox_open')){
|
||||
$aClassProvider['SimpleCryptSodiumEngine'] = ['SimpleCryptSodiumEngine'] ;
|
||||
}
|
||||
if(function_exists('openssl_decrypt')){
|
||||
$aClassProvider['SimpleCryptOpenSSLEngine'] = ['SimpleCryptOpenSSLEngine'];
|
||||
$aClassProvider['SimpleCryptOpenSSLMcryptCompatibilityEngine'] = ['SimpleCryptOpenSSLMcryptCompatibilityEngine'];
|
||||
}
|
||||
return$aClassProvider;
|
||||
}
|
||||
/**
|
||||
public function DecryptClassProvider()
|
||||
{
|
||||
$aClassProvider = ['SimpleCrypt' => ['SimpleCrypt'],
|
||||
'SimpleCryptSimpleEngine' => ['SimpleCryptSimpleEngine']];
|
||||
if (function_exists('sodium_crypto_secretbox_open')) {
|
||||
$aClassProvider['SimpleCryptSodiumEngine'] = ['SimpleCryptSodiumEngine'] ;
|
||||
}
|
||||
if (function_exists('openssl_decrypt')) {
|
||||
$aClassProvider['SimpleCryptOpenSSLEngine'] = ['SimpleCryptOpenSSLEngine'];
|
||||
$aClassProvider['SimpleCryptOpenSSLMcryptCompatibilityEngine'] = ['SimpleCryptOpenSSLMcryptCompatibilityEngine'];
|
||||
}
|
||||
return$aClassProvider;
|
||||
}
|
||||
/**
|
||||
* @param $sClass
|
||||
* @dataProvider DecryptClassProvider
|
||||
**/
|
||||
**/
|
||||
public function testDecryptWithNullValue($sClass)
|
||||
{
|
||||
$oSimpleCrypt = new $sClass();
|
||||
$this->assertEquals(null, $oSimpleCrypt->Decrypt("dd", null));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sClass
|
||||
* @dataProvider DecryptClassProvider
|
||||
**/
|
||||
/**
|
||||
* @param $sClass
|
||||
* @dataProvider DecryptClassProvider
|
||||
**/
|
||||
public function testDecryptWithEmptyValue($sClass)
|
||||
{
|
||||
$oSimpleCrypt = new $sClass();
|
||||
$this->assertEquals('', $oSimpleCrypt->Decrypt("dd", ""));
|
||||
}
|
||||
|
||||
public function DecryptClassWithNonDecryptableValueProvider()
|
||||
{
|
||||
$aClassProvider = ['SimpleCrypt'=>['SimpleCrypt', '** decryption error **'],
|
||||
// 'SimpleCryptSimpleEngine'=>['SimpleCryptSimpleEngine', ' ']
|
||||
];
|
||||
if(function_exists('sodium_crypto_secretbox_open')){
|
||||
$aClassProvider['SimpleCryptSodiumEngine'] = ['SimpleCryptSodiumEngine', '', 'SodiumException'] ;
|
||||
}
|
||||
if(function_exists('openssl_decrypt')){
|
||||
$aClassProvider['SimpleCryptOpenSSLEngine'] = ['SimpleCryptOpenSSLEngine', '** decryption error **'];
|
||||
$aClassProvider['SimpleCryptOpenSSLMcryptCompatibilityEngine'] = ['SimpleCryptOpenSSLMcryptCompatibilityEngine', '** decryption error **'];
|
||||
}
|
||||
return$aClassProvider;
|
||||
}
|
||||
/**
|
||||
* @param $sClass
|
||||
* @param $sExpectedValue
|
||||
* @dataProvider DecryptClassWithNonDecryptableValueProvider
|
||||
**/
|
||||
public function DecryptClassWithNonDecryptableValueProvider()
|
||||
{
|
||||
$aClassProvider = ['SimpleCrypt' => ['SimpleCrypt', '** decryption error **'],
|
||||
// 'SimpleCryptSimpleEngine'=>['SimpleCryptSimpleEngine', ' ']
|
||||
];
|
||||
if (function_exists('sodium_crypto_secretbox_open')) {
|
||||
$aClassProvider['SimpleCryptSodiumEngine'] = ['SimpleCryptSodiumEngine', '', 'SodiumException'] ;
|
||||
}
|
||||
if (function_exists('openssl_decrypt')) {
|
||||
$aClassProvider['SimpleCryptOpenSSLEngine'] = ['SimpleCryptOpenSSLEngine', '** decryption error **'];
|
||||
$aClassProvider['SimpleCryptOpenSSLMcryptCompatibilityEngine'] = ['SimpleCryptOpenSSLMcryptCompatibilityEngine', '** decryption error **'];
|
||||
}
|
||||
return$aClassProvider;
|
||||
}
|
||||
/**
|
||||
* @param $sClass
|
||||
* @param $sExpectedValue
|
||||
* @dataProvider DecryptClassWithNonDecryptableValueProvider
|
||||
**/
|
||||
public function testDecrypWithNonDecryptableValue($sClass, $sExpectedValue = '', $sExpectedException = null)
|
||||
{
|
||||
if($sExpectedException !== null) {
|
||||
$this->expectException($sExpectedException);
|
||||
}
|
||||
if ($sExpectedException !== null) {
|
||||
$this->expectException($sExpectedException);
|
||||
}
|
||||
$oSimpleCrypt = new $sClass();
|
||||
$result=$oSimpleCrypt->Decrypt("dd", "gabuzomeuuofteod");
|
||||
$this->assertEquals($sExpectedValue, $result,'');
|
||||
$result = $oSimpleCrypt->Decrypt("dd", "gabuzomeuuofteod");
|
||||
$this->assertEquals($sExpectedValue, $result, '');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Eric
|
||||
@@ -8,7 +9,6 @@
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use CoreException;
|
||||
use DeleteException;
|
||||
@@ -22,7 +22,7 @@ use TagSetFieldData;
|
||||
class TagSetFieldDataTest extends ItopDataTestCase
|
||||
{
|
||||
// Need database COMMIT in order to create the FULLTEXT INDEX of MySQL
|
||||
const USE_TRANSACTION = false;
|
||||
public const USE_TRANSACTION = false;
|
||||
|
||||
/**
|
||||
* @throws \CoreException
|
||||
@@ -65,33 +65,27 @@ class TagSetFieldDataTest extends ItopDataTestCase
|
||||
$iCurrCount = count($aAllowedValues);
|
||||
static::assertEquals(4, $iCurrCount - $iInitialCount);
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
$this->CreateTagData(TAG_CLASS, TAG_ATTCODE, 'tag4', 'Fourth');
|
||||
} catch (CoreException $e)
|
||||
{
|
||||
} catch (CoreException $e) {
|
||||
$this->debug($e->getMessage());
|
||||
}
|
||||
$aAllowedValues = TagSetFieldData::GetAllowedValues(TAG_CLASS, TAG_ATTCODE);
|
||||
$iCurrCount = count($aAllowedValues);
|
||||
static::assertEquals(4, $iCurrCount - $iInitialCount);
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
$this->CreateTagData(TAG_CLASS, TAG_ATTCODE, 'tag4', 'zembrek');
|
||||
} catch (CoreException $e)
|
||||
{
|
||||
} catch (CoreException $e) {
|
||||
$this->debug($e->getMessage());
|
||||
}
|
||||
$aAllowedValues = TagSetFieldData::GetAllowedValues(TAG_CLASS, TAG_ATTCODE);
|
||||
$iCurrCount = count($aAllowedValues);
|
||||
static::assertEquals(4, $iCurrCount - $iInitialCount);
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
$this->CreateTagData(TAG_CLASS, TAG_ATTCODE, 'zembrek', 'Fourth');
|
||||
} catch (CoreException $e)
|
||||
{
|
||||
} catch (CoreException $e) {
|
||||
$this->debug($e->getMessage());
|
||||
}
|
||||
$aAllowedValues = TagSetFieldData::GetAllowedValues(TAG_CLASS, TAG_ATTCODE);
|
||||
@@ -129,10 +123,10 @@ class TagSetFieldDataTest extends ItopDataTestCase
|
||||
public function testComputeValues()
|
||||
{
|
||||
$sTagClass = TagSetFieldData::GetTagDataClassName(TAG_CLASS, TAG_ATTCODE);
|
||||
$oTagData = $this->createObject($sTagClass, array(
|
||||
$oTagData = $this->createObject($sTagClass, [
|
||||
'code' => 'tag1',
|
||||
'label' => 'First',
|
||||
));
|
||||
]);
|
||||
$this->debug("Created {$oTagData->Get('obj_class')}::{$oTagData->Get('obj_attcode')}");
|
||||
|
||||
static::assertEquals(TAG_CLASS, $oTagData->Get('obj_class'));
|
||||
@@ -150,8 +144,7 @@ class TagSetFieldDataTest extends ItopDataTestCase
|
||||
{
|
||||
try {
|
||||
$this->CreateTagData(TAG_CLASS, TAG_ATTCODE, $sTagCode, 'First');
|
||||
}
|
||||
catch (CoreException $e) {
|
||||
} catch (CoreException $e) {
|
||||
static::assertTrue(true);
|
||||
return;
|
||||
}
|
||||
@@ -161,22 +154,22 @@ class TagSetFieldDataTest extends ItopDataTestCase
|
||||
|
||||
public function InvalidTagCodeProvider()
|
||||
{
|
||||
return array(
|
||||
'No space' => array('tag1 1'),
|
||||
'No _' => array('tag_1'),
|
||||
'No -' => array('tag-1'),
|
||||
'No %' => array('tag%1'),
|
||||
'At least 3 chars' => array(''),
|
||||
'At least 3 chars 1' => array('a'),
|
||||
'At least 3 chars 2' => array('ab'),
|
||||
'No #' => array('#tag'),
|
||||
'No !' => array('tag!'),
|
||||
'Stop Word 1' => array('about'),
|
||||
'Stop Word 2' => array('from'),
|
||||
'Stop Word 3' => array('that'),
|
||||
'Stop Word 4' => array('where'),
|
||||
'Stop Word 5' => array('who'),
|
||||
);
|
||||
return [
|
||||
'No space' => ['tag1 1'],
|
||||
'No _' => ['tag_1'],
|
||||
'No -' => ['tag-1'],
|
||||
'No %' => ['tag%1'],
|
||||
'At least 3 chars' => [''],
|
||||
'At least 3 chars 1' => ['a'],
|
||||
'At least 3 chars 2' => ['ab'],
|
||||
'No #' => ['#tag'],
|
||||
'No !' => ['tag!'],
|
||||
'Stop Word 1' => ['about'],
|
||||
'Stop Word 2' => ['from'],
|
||||
'Stop Word 3' => ['that'],
|
||||
'Stop Word 4' => ['where'],
|
||||
'Stop Word 5' => ['who'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,8 +179,7 @@ class TagSetFieldDataTest extends ItopDataTestCase
|
||||
{
|
||||
try {
|
||||
$this->CreateTagData(TAG_CLASS, TAG_ATTCODE, 'tag1', 'First|Second');
|
||||
}
|
||||
catch (CoreException $e) {
|
||||
} catch (CoreException $e) {
|
||||
static::assertFalse(false);
|
||||
return;
|
||||
}
|
||||
@@ -238,11 +230,9 @@ class TagSetFieldDataTest extends ItopDataTestCase
|
||||
|
||||
// Too long
|
||||
$sTagCode = str_repeat('a', $iMaxLength + 1);
|
||||
try
|
||||
{
|
||||
try {
|
||||
$this->CreateTagData(TAG_CLASS, TAG_ATTCODE, $sTagCode, $sTagCode);
|
||||
} catch (CoreException $e)
|
||||
{
|
||||
} catch (CoreException $e) {
|
||||
$this->debug('Awaited: '.$e->getMessage());
|
||||
static::assertTrue(true);
|
||||
return;
|
||||
@@ -259,30 +249,26 @@ class TagSetFieldDataTest extends ItopDataTestCase
|
||||
/** @var \AttributeTagSet $oAttDef */
|
||||
$oAttDef = MetaModel::GetAttributeDef(TAG_CLASS, TAG_ATTCODE);
|
||||
$iMaxTags = $oAttDef->GetMaxItems();
|
||||
for ($i = 0; $i < $iMaxTags; $i++)
|
||||
{
|
||||
for ($i = 0; $i < $iMaxTags; $i++) {
|
||||
$sTagCode = 'MaxTag'.$i;
|
||||
$this->CreateTagData(TAG_CLASS, TAG_ATTCODE, $sTagCode, $sTagCode);
|
||||
}
|
||||
$oObjWithTagSet = $this->CreateObjectWithTagSet();
|
||||
$this->debug("Max number of tags is $iMaxTags");
|
||||
$sValue = '';
|
||||
for ($i = 0; $i < ($iMaxTags + 1); $i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
for ($i = 0; $i < ($iMaxTags + 1); $i++) {
|
||||
try {
|
||||
$sTagCode = 'MaxTag'.$i;
|
||||
$sValue .= "$sTagCode ";
|
||||
$oObjWithTagSet->Set(TAG_ATTCODE, $sValue);
|
||||
$oObjWithTagSet->DBWrite();
|
||||
} catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
// Should fail on the last iteration
|
||||
static::assertEquals($iMaxTags, $i);
|
||||
$this->debug("Setting (".($i+1).") tag(s) failed");
|
||||
$this->debug("Setting (".($i + 1).") tag(s) failed");
|
||||
return;
|
||||
}
|
||||
$this->debug("Setting (".($i+1).") tag(s) worked");
|
||||
$this->debug("Setting (".($i + 1).") tag(s) worked");
|
||||
}
|
||||
|
||||
static::assertFalse(true);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user