mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
Merge branch 'support/3.2' into develop
This commit is contained in:
@@ -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,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
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
],
|
||||
];
|
||||
|
||||
@@ -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/stimulus.class.inc.php');
|
||||
require_once(APPROOT.'/core/MyHelpers.class.inc.php');
|
||||
@@ -47,11 +47,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
|
||||
@@ -68,7 +67,6 @@ class ExceptionFromError extends Exception
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test handler API and basic helpers
|
||||
*
|
||||
@@ -83,21 +81,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";
|
||||
}
|
||||
@@ -141,24 +151,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
|
||||
}
|
||||
@@ -166,24 +177,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());
|
||||
@@ -193,10 +197,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;
|
||||
@@ -211,50 +215,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
|
||||
*/
|
||||
@@ -263,9 +258,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
|
||||
*/
|
||||
@@ -274,7 +268,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
|
||||
*/
|
||||
@@ -282,60 +276,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()
|
||||
{
|
||||
@@ -343,9 +329,8 @@ abstract class TestUrl extends TestHandler
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to check a user management module
|
||||
* Test to check a user management module
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
@@ -357,7 +342,6 @@ abstract class TestUserRights extends TestHandler
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to execute a scenario on a given DB
|
||||
*
|
||||
@@ -365,10 +349,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()
|
||||
{
|
||||
@@ -379,8 +363,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);
|
||||
@@ -392,26 +375,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
|
||||
}
|
||||
@@ -419,52 +404,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";
|
||||
@@ -473,22 +451,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.)
|
||||
*
|
||||
@@ -496,12 +473,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.';
|
||||
}
|
||||
@@ -510,8 +487,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
|
||||
@@ -519,12 +495,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
|
||||
@@ -532,8 +509,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>");
|
||||
}
|
||||
|
||||
@@ -545,6 +521,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
|
||||
@@ -14,6 +15,7 @@ use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
use ReflectionMethod;
|
||||
use SetupUtils;
|
||||
use Symfony\Component\HttpKernel\KernelInterface;
|
||||
|
||||
use const DEBUG_BACKTRACE_IGNORE_ARGS;
|
||||
|
||||
/**
|
||||
@@ -97,7 +99,6 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
* @param string $sExportFileName relative to log folder
|
||||
@@ -141,15 +142,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();
|
||||
@@ -188,22 +190,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);
|
||||
@@ -211,7 +213,6 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overload this method to require necessary files through {@see \Combodo\iTop\Test\UnitTest\ItopTestCase::RequireOnceItopFile()}
|
||||
*
|
||||
@@ -222,7 +223,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()}
|
||||
@@ -246,7 +247,7 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
*/
|
||||
protected function RequireOnceItopFile(string $sFileRelPath): void
|
||||
{
|
||||
require_once $this->GetAppRoot() . $sFileRelPath;
|
||||
require_once $this->GetAppRoot().$sFileRelPath;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,7 +264,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)
|
||||
@@ -272,11 +273,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()
|
||||
{
|
||||
@@ -287,8 +288,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));
|
||||
@@ -379,7 +379,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();
|
||||
}
|
||||
@@ -397,7 +399,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()]);
|
||||
}
|
||||
@@ -415,7 +419,6 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
return $oProperty;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param object $oObject
|
||||
* @param string $sProperty
|
||||
@@ -455,38 +458,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);
|
||||
@@ -495,16 +498,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 (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' ],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,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 ],
|
||||
@@ -26,17 +28,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_');
|
||||
@@ -46,7 +51,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
|
||||
@@ -24,7 +25,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 (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);
|
||||
}
|
||||
|
||||
@@ -125,10 +126,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%'"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,7 +149,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
|
||||
*/
|
||||
@@ -863,78 +862,78 @@ class utilsTest extends ItopTestCase
|
||||
'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);
|
||||
|
||||
@@ -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.
|
||||
@@ -40,19 +41,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();
|
||||
@@ -83,18 +82,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]];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,7 +151,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');
|
||||
@@ -181,7 +180,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();
|
||||
|
||||
@@ -198,7 +197,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'));
|
||||
}
|
||||
|
||||
@@ -208,7 +207,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'));
|
||||
}
|
||||
@@ -232,7 +231,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');
|
||||
@@ -264,26 +263,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'));
|
||||
@@ -292,7 +291,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)")));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -304,7 +303,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
|
||||
@@ -314,14 +313,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'));
|
||||
});
|
||||
@@ -329,12 +328,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'));
|
||||
@@ -343,7 +342,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
|
||||
@@ -353,7 +351,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
|
||||
@@ -363,7 +361,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();
|
||||
@@ -389,7 +387,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'));
|
||||
});
|
||||
@@ -397,10 +395,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);
|
||||
|
||||
@@ -408,13 +405,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'));
|
||||
});
|
||||
}
|
||||
@@ -471,17 +468,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());
|
||||
});
|
||||
}
|
||||
@@ -604,7 +600,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)
|
||||
@@ -666,8 +662,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
|
||||
}
|
||||
|
||||
@@ -680,8 +675,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');
|
||||
}
|
||||
}
|
||||
@@ -745,7 +739,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$oQueryOQL = \MetaModel::NewObject('QueryOQL', [
|
||||
'name' => 'Test Query',
|
||||
'description' => 'Test Query',
|
||||
'oql' => 'SELECT Person'
|
||||
'oql' => 'SELECT Person',
|
||||
]);
|
||||
$oQueryOQL->DBInsert();
|
||||
|
||||
@@ -768,12 +762,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],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -788,7 +782,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$oQueryOQL = \MetaModel::NewObject('QueryOQL', [
|
||||
'name' => 'Test Query',
|
||||
'description' => 'Test Query',
|
||||
'oql' => 'SELECT Person'
|
||||
'oql' => 'SELECT Person',
|
||||
]);
|
||||
$oQueryOQL->DBInsert();
|
||||
|
||||
@@ -811,7 +805,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$oQueryOQL = \MetaModel::NewObject('QueryOQL', [
|
||||
'name' => 'Test Query',
|
||||
'description' => 'Test Query',
|
||||
'oql' => 'SELECT Person'
|
||||
'oql' => 'SELECT Person',
|
||||
]);
|
||||
$oQueryOQL->DBInsert();
|
||||
|
||||
@@ -837,12 +831,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);
|
||||
});
|
||||
}
|
||||
@@ -978,8 +972,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());
|
||||
}
|
||||
|
||||
@@ -1045,9 +1038,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' => [
|
||||
@@ -1057,10 +1050,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' => [
|
||||
@@ -1070,9 +1063,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' => [
|
||||
@@ -1081,11 +1074,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' => [
|
||||
@@ -1094,10 +1087,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' => [
|
||||
@@ -1117,10 +1110,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' => [
|
||||
@@ -1212,8 +1205,7 @@ class DBObjectTest extends ItopDataTestCase
|
||||
$bDeletionOK = true;
|
||||
try {
|
||||
$oDeletionPlan = $oPerson->DBDelete();
|
||||
}
|
||||
catch (CoreException $e) {
|
||||
} catch (CoreException $e) {
|
||||
$bDeletionOK = false;
|
||||
}
|
||||
$this->assertTrue($bDeletionOK);
|
||||
@@ -1265,7 +1257,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);
|
||||
@@ -1287,7 +1279,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);
|
||||
}
|
||||
@@ -1337,7 +1329,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',
|
||||
@@ -1356,14 +1348,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');
|
||||
}
|
||||
@@ -1373,13 +1365,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)',
|
||||
],
|
||||
|
||||
];
|
||||
@@ -1389,7 +1381,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');
|
||||
@@ -1399,21 +1392,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__-1; //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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -8,7 +8,7 @@ use Person;
|
||||
|
||||
class TriggerOnStateEnterTest extends ItopDataTestCase
|
||||
{
|
||||
const CREATE_TEST_ORG = true;
|
||||
public const CREATE_TEST_ORG = true;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
@@ -86,4 +86,4 @@ class TriggerOnStateEnterTest extends ItopDataTestCase
|
||||
]);
|
||||
return MetaModel::GetObject('UserRequest', $iUserRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,7 @@ use TriggerOnObjectCreate;
|
||||
*/
|
||||
class TriggerTest extends ItopDataTestCase
|
||||
{
|
||||
const USE_TRANSACTION = false;
|
||||
|
||||
public const USE_TRANSACTION = false;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
@@ -43,18 +42,16 @@ class TriggerTest extends ItopDataTestCase
|
||||
try {
|
||||
try {
|
||||
MetaModel::NewObject('Toto');
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
} catch (\Exception $e) {
|
||||
\utils::EnrichRaisedException($oTrigger, $e);
|
||||
}
|
||||
$this->assertTrue(false, "An exception should have been thrown");
|
||||
}
|
||||
catch (\CoreException $e1) {
|
||||
} catch (\CoreException $e1) {
|
||||
$this->assertEquals('CoreException', get_class($e1));
|
||||
$this->assertStringStartsWith('Unknown class \'Toto\' (<b title="Trigger">TriggerOnObjectCreate</b>::-', $e1->getMessage());
|
||||
|
||||
$fullStackTraceAsString = $e1->getFullStackTraceAsString();
|
||||
$this->assertStringContainsString("MetaModel::NewObject", $fullStackTraceAsString,"new enriched exception should contain root cause method: " . $fullStackTraceAsString);
|
||||
$this->assertStringContainsString("MetaModel::NewObject", $fullStackTraceAsString, "new enriched exception should contain root cause method: ".$fullStackTraceAsString);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,13 +72,11 @@ class TriggerTest extends ItopDataTestCase
|
||||
try {
|
||||
try {
|
||||
MetaModel::NewObject('CoreException');
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
} catch (\Exception $e) {
|
||||
\utils::EnrichRaisedException($oCmdbAbstract, $e);
|
||||
}
|
||||
$this->assertTrue(false, "An exception should have been thrown");
|
||||
}
|
||||
catch (\Exception $e1) {
|
||||
} catch (\Exception $e1) {
|
||||
$this->assertEquals($e, $e1);
|
||||
}
|
||||
}
|
||||
@@ -113,13 +108,12 @@ class TriggerTest extends ItopDataTestCase
|
||||
$this->assertStringContainsString($oPerson1->GetRawName(), $sTestLogFileContent);
|
||||
|
||||
$this->assertStringContainsString($sExceptionMessage, $sTestLogFileContent);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
IssueLog::Enable(APPROOT.'log/error.log');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NonCmdbAbstractObject{
|
||||
|
||||
class NonCmdbAbstractObject
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
@@ -33,12 +32,9 @@ class UniquenessConstraintTest extends ItopTestCase
|
||||
public function testUniquenessRuleValidityCheck($bIsRuleShouldBeValid, $bIsRuleOverride, $aRuleProperties)
|
||||
{
|
||||
$bRuleValidResult = true;
|
||||
try
|
||||
{
|
||||
try {
|
||||
MetaModel::CheckUniquenessRuleValidity($aRuleProperties, $bIsRuleOverride);
|
||||
}
|
||||
catch (CoreUnexpectedValue $e)
|
||||
{
|
||||
} catch (CoreUnexpectedValue $e) {
|
||||
$bRuleValidResult = false;
|
||||
}
|
||||
|
||||
@@ -47,32 +43,32 @@ class UniquenessConstraintTest extends ItopTestCase
|
||||
|
||||
public function uniquenessRuleValidityCheckProvider()
|
||||
{
|
||||
return array(
|
||||
'simplest rule' => array(true, false, array('attributes' => array('name'))),
|
||||
'with all properties' => array(
|
||||
return [
|
||||
'simplest rule' => [true, false, ['attributes' => ['name']]],
|
||||
'with all properties' => [
|
||||
true,
|
||||
false,
|
||||
array(
|
||||
'attributes' => array('name'),
|
||||
[
|
||||
'attributes' => ['name'],
|
||||
'filter' => 'name != \'\'',
|
||||
'disabled' => false,
|
||||
'is_blocking' => true,
|
||||
),
|
||||
),
|
||||
'only disabled key without ancestor' => array(
|
||||
],
|
||||
],
|
||||
'only disabled key without ancestor' => [
|
||||
false,
|
||||
false,
|
||||
array(
|
||||
[
|
||||
'disabled' => true,
|
||||
),
|
||||
),
|
||||
'only disabled key with ancestor' => array(
|
||||
],
|
||||
],
|
||||
'only disabled key with ancestor' => [
|
||||
true,
|
||||
true,
|
||||
array(
|
||||
[
|
||||
'disabled' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
@@ -16,7 +15,6 @@ use Team;
|
||||
*/
|
||||
class UniquenessMessageTest extends ItopDataTestCase
|
||||
{
|
||||
|
||||
/** @inheritdoc */
|
||||
protected function setUp(): void
|
||||
{
|
||||
@@ -34,10 +32,10 @@ class UniquenessMessageTest extends ItopDataTestCase
|
||||
protected function CreateTeam($iNum)
|
||||
{
|
||||
/** @var Team $oTeam */
|
||||
$oTeam = $this->createObject('Team', array(
|
||||
$oTeam = $this->createObject('Team', [
|
||||
'name' => 'Name_'.$iNum,
|
||||
'org_id' => $this->getTestOrgId(),
|
||||
));
|
||||
]);
|
||||
$this->debug("Created Team {$oTeam->GetName()} ({$oTeam->GetKey()})");
|
||||
|
||||
return $oTeam;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
// Copyright (c) 2010-2024 Combodo SAS
|
||||
//
|
||||
// This file is part of iTop.
|
||||
@@ -74,7 +75,7 @@ class UserRightsTest extends ItopDataTestCase
|
||||
$iCount++;
|
||||
|
||||
$oUser = self::CreateUser($sLogin, $iProfileId);
|
||||
$_SESSION = array();
|
||||
$_SESSION = [];
|
||||
UserRights::Login($sLogin);
|
||||
return $oUser;
|
||||
}
|
||||
@@ -102,8 +103,7 @@ class UserRightsTest extends ItopDataTestCase
|
||||
// Fixture data required in this case only
|
||||
try {
|
||||
self::CreateUser('admin', 1);
|
||||
}
|
||||
catch (CoreCannotSaveObjectException $e) {
|
||||
} catch (CoreCannotSaveObjectException $e) {
|
||||
// The admin account could exist, depending on where and when the test suite is executed
|
||||
}
|
||||
}
|
||||
@@ -225,7 +225,6 @@ class UserRightsTest extends ItopDataTestCase
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/** Test IsActionAllowedOnAttribute
|
||||
*
|
||||
* @dataProvider ActionAllowedOnAttributeProvider
|
||||
@@ -455,7 +454,7 @@ class UserRightsTest extends ItopDataTestCase
|
||||
public function NonAdminCanListOwnProfilesProvider(): array
|
||||
{
|
||||
return [
|
||||
'with Admins visible'=> [false],
|
||||
'with Admins visible' => [false],
|
||||
'with Admins hidden' => [true],
|
||||
];
|
||||
}
|
||||
@@ -482,7 +481,7 @@ class UserRightsTest extends ItopDataTestCase
|
||||
public function NonAdminCannotListAdminProfilesProvider(): array
|
||||
{
|
||||
return [
|
||||
'with Admins visible'=> [false, 1],
|
||||
'with Admins visible' => [false, 1],
|
||||
'with Admins hidden' => [true, 0],
|
||||
];
|
||||
}
|
||||
@@ -494,13 +493,13 @@ class UserRightsTest extends ItopDataTestCase
|
||||
|
||||
$this->assertDBQueryCount(
|
||||
1,
|
||||
fn() => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey),
|
||||
fn () => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey),
|
||||
'A query should be performed the first time FindUser is called'
|
||||
);
|
||||
|
||||
$this->assertDBQueryCount(
|
||||
0,
|
||||
fn() => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey),
|
||||
fn () => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey),
|
||||
'The cache should prevent additional queries on subsequent calls'
|
||||
);
|
||||
}
|
||||
@@ -512,13 +511,13 @@ class UserRightsTest extends ItopDataTestCase
|
||||
|
||||
$this->assertDBQueryCount(
|
||||
2,
|
||||
fn() => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey),
|
||||
fn () => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey),
|
||||
'Some queries should be performed the first time FindUser is called'
|
||||
);
|
||||
|
||||
$this->assertDBQueryCount(
|
||||
0,
|
||||
fn() => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey),
|
||||
fn () => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey),
|
||||
'The cache should prevent additional queries on subsequent calls'
|
||||
);
|
||||
}
|
||||
@@ -529,13 +528,13 @@ class UserRightsTest extends ItopDataTestCase
|
||||
|
||||
$this->assertDBQueryCount(
|
||||
2,
|
||||
fn() => $this->FindUserAndAssertItWasNotFound($sLogin),
|
||||
fn () => $this->FindUserAndAssertItWasNotFound($sLogin),
|
||||
'Some queries should be performed the first time FindUser is called'
|
||||
);
|
||||
|
||||
$this->assertDBQueryCount(
|
||||
0,
|
||||
fn() => $this->FindUserAndAssertItWasNotFound($sLogin),
|
||||
fn () => $this->FindUserAndAssertItWasNotFound($sLogin),
|
||||
'The cache should prevent additional queries on subsequent calls'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -10,7 +11,6 @@ use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use ValueSetDefinition;
|
||||
use ValueSetEnum;
|
||||
|
||||
|
||||
class ValueSetDefinitionTest extends ItopTestCase
|
||||
{
|
||||
/**
|
||||
@@ -53,4 +53,4 @@ class ValueSetDefinitionTest extends ItopTestCase
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -6,7 +7,8 @@
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core\ValueSetEnum;
|
||||
|
||||
enum ABCEnum: string {
|
||||
enum ABCEnum: string
|
||||
{
|
||||
case A = "a";
|
||||
case B = "b";
|
||||
case C = "c";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -10,7 +11,6 @@ use Combodo\iTop\Test\UnitTest\Core\ValueSetEnum\ABCEnum;
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use ValueSetEnum;
|
||||
|
||||
|
||||
/**
|
||||
* Class ValueSetEnumTest
|
||||
*
|
||||
@@ -22,7 +22,7 @@ class ValueSetEnumTest extends ItopTestCase
|
||||
{
|
||||
public static function setupBeforeClass(): void
|
||||
{
|
||||
require_once __DIR__ . "/ValueSetEnum/ABCEnum.php";
|
||||
require_once __DIR__."/ValueSetEnum/ABCEnum.php";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +92,7 @@ class ValueSetEnumTest extends ItopTestCase
|
||||
"Invalid int value" => [
|
||||
123,
|
||||
[],
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -10,10 +11,8 @@ use MockValueSetObjects;
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use MetaModel;
|
||||
|
||||
|
||||
class ValueSetObjectsTest extends ItopTestCase
|
||||
{
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
@@ -27,17 +26,16 @@ class ValueSetObjectsTest extends ItopTestCase
|
||||
*/
|
||||
public function GetGetFilterProvider()
|
||||
{
|
||||
return array(
|
||||
'Ticket contains bla' => array("Ticket", "bla", "contains", "SELECT `Ticket` FROM Ticket AS `Ticket` WHERE (`Ticket`.`friendlyname` LIKE '%bla%')"),
|
||||
'Ticket equals bla' => array("Ticket", "bla", "equals", "SELECT `Ticket` FROM Ticket AS `Ticket` WHERE (`Ticket`.`ref` = 'bla')"),
|
||||
'Ticket start_with bla' => array("Ticket", "bla", "start_with", "SELECT `Ticket` FROM Ticket AS `Ticket` WHERE (`Ticket`.`ref` LIKE 'bla%')"),
|
||||
'UserRequest contains bla' => array("UserRequest", "bla", "contains", "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`friendlyname` LIKE '%bla%')"),
|
||||
'UserRequest equals bla' => array("UserRequest", "bla", "equals", "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`ref` = 'bla')"),
|
||||
'UserRequest start_with bla' => array("UserRequest", "bla", "start_with", "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`ref` LIKE 'bla%')"),
|
||||
);
|
||||
return [
|
||||
'Ticket contains bla' => ["Ticket", "bla", "contains", "SELECT `Ticket` FROM Ticket AS `Ticket` WHERE (`Ticket`.`friendlyname` LIKE '%bla%')"],
|
||||
'Ticket equals bla' => ["Ticket", "bla", "equals", "SELECT `Ticket` FROM Ticket AS `Ticket` WHERE (`Ticket`.`ref` = 'bla')"],
|
||||
'Ticket start_with bla' => ["Ticket", "bla", "start_with", "SELECT `Ticket` FROM Ticket AS `Ticket` WHERE (`Ticket`.`ref` LIKE 'bla%')"],
|
||||
'UserRequest contains bla' => ["UserRequest", "bla", "contains", "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`friendlyname` LIKE '%bla%')"],
|
||||
'UserRequest equals bla' => ["UserRequest", "bla", "equals", "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`ref` = 'bla')"],
|
||||
'UserRequest start_with bla' => ["UserRequest", "bla", "start_with", "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`ref` LIKE 'bla%')"],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $Class
|
||||
* @param $sContains
|
||||
@@ -56,4 +54,4 @@ class ValueSetObjectsTest extends ItopTestCase
|
||||
$this->assertEquals($sExpectedOQL, $sFilter);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
class WeeklyScheduledProcessMockConfig extends AbstractWeeklyScheduledProcess
|
||||
{
|
||||
const MODULE_NAME = 'itop-zabu-gomeu';
|
||||
public const MODULE_NAME = 'itop-zabu-gomeu';
|
||||
|
||||
public function __construct($bEnabledValue, $sTimeValue, $sWeekDays)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user