mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-16 22:08:44 +02:00
Merge remote-tracking branch 'origin/support/3.1' into develop
This commit is contained in:
@@ -502,6 +502,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
}
|
||||
|
||||
protected $m_aUserOrgs = array(); // userid -> array of orgid
|
||||
protected $m_aAdministrators = null; // [user id]
|
||||
|
||||
// Built on demand, could be optimized if necessary (doing a query for each attribute that needs to be read)
|
||||
protected $m_aObjectActionGrants = array();
|
||||
@@ -558,6 +559,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
|
||||
// Cache
|
||||
$this->m_aObjectActionGrants = array();
|
||||
$this->m_aAdministrators = null;
|
||||
}
|
||||
|
||||
public function LoadCache()
|
||||
@@ -700,12 +702,10 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
*/
|
||||
private function GetAdministrators()
|
||||
{
|
||||
static $aAdministrators = null;
|
||||
|
||||
if ($aAdministrators === null)
|
||||
if ($this->m_aAdministrators === null)
|
||||
{
|
||||
// Find all administrators
|
||||
$aAdministrators = array();
|
||||
$this->m_aAdministrators = array();
|
||||
$oAdministratorsFilter = new DBObjectSearch('User');
|
||||
$oLnkFilter = new DBObjectSearch('URP_UserProfile');
|
||||
$oExpression = new FieldExpression('profileid', 'URP_UserProfile');
|
||||
@@ -718,10 +718,10 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
$oSet->OptimizeColumnLoad(array('User' => array('login')));
|
||||
while($oUser = $oSet->Fetch())
|
||||
{
|
||||
$aAdministrators[] = $oUser->GetKey();
|
||||
$this->m_aAdministrators[] = $oUser->GetKey();
|
||||
}
|
||||
}
|
||||
return $aAdministrators;
|
||||
return $this->m_aAdministrators;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -165,6 +165,8 @@ class utils
|
||||
|
||||
private static $iNextId = 0;
|
||||
|
||||
private static $m_sAppRootUrl = null;
|
||||
|
||||
protected static function LoadParamFile($sParamFile)
|
||||
{
|
||||
if (!file_exists($sParamFile)) {
|
||||
@@ -1046,7 +1048,7 @@ class utils
|
||||
*/
|
||||
public static function GetAbsoluteUrlAppRoot($bForceTrustProxy = false)
|
||||
{
|
||||
static $sUrl = null;
|
||||
$sUrl = static::$m_sAppRootUrl;
|
||||
if ($sUrl === null || $bForceTrustProxy)
|
||||
{
|
||||
$sUrl = self::GetConfig()->Get('app_root_url');
|
||||
@@ -1067,8 +1069,9 @@ class utils
|
||||
}
|
||||
$sUrl = str_replace(SERVER_NAME_PLACEHOLDER, $sServerName, $sUrl);
|
||||
}
|
||||
static::$m_sAppRootUrl = $sUrl;
|
||||
}
|
||||
return $sUrl;
|
||||
return static::$m_sAppRootUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1671,6 +1671,8 @@ class ExceptionLog extends LogAPI
|
||||
*/
|
||||
private static function GetLastEventIssue()
|
||||
{
|
||||
return self::$oLastEventIssue;
|
||||
$oRet = self::$oLastEventIssue;
|
||||
self::$oLastEventIssue = null;
|
||||
return $oRet;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,11 @@ class Router
|
||||
return static::$oSingleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var bool $bUseCache
|
||||
*/
|
||||
protected $bUseCache = null;
|
||||
|
||||
/**********************/
|
||||
/* Non-static methods */
|
||||
/**********************/
|
||||
@@ -54,6 +59,14 @@ class Router
|
||||
// Don't do anything, we don't want to be initialized
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|null $bUseCache Force cache usage for testing purposes, or leave it null for the default behavior
|
||||
*/
|
||||
public function SetUseCache(?bool $bUseCache): void
|
||||
{
|
||||
$this->bUseCache = $bUseCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a complete URL for a specific route and optional parameters
|
||||
*
|
||||
@@ -137,7 +150,7 @@ class Router
|
||||
public function GetRoutes(): array
|
||||
{
|
||||
$aRoutes = [];
|
||||
$bUseCache = false === utils::IsDevelopmentEnvironment();
|
||||
$bUseCache = is_null($this->bUseCache) ? (false === utils::IsDevelopmentEnvironment()) : $this->bUseCache;
|
||||
$bMustWriteCache = false;
|
||||
$sCacheFilePath = $this->GetCacheFileAbsPath();
|
||||
|
||||
|
||||
@@ -17,6 +17,18 @@ namespace Combodo\iTop\Test\UnitTest\Integration;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper to load dictionnary files without altering the main dictionnary
|
||||
* Eval will be called within the current namespace (this is done by adding a "namespace" statement)
|
||||
*/
|
||||
class Dict
|
||||
{
|
||||
public static function Add($sLanguageCode, $sEnglishLanguageDesc, $sLocalizedLanguageDesc, $aEntries)
|
||||
{
|
||||
}
|
||||
}
|
||||
/**
|
||||
* For tests on compiled dict files, see {@see CompiledDictionariesConsistencyTest}
|
||||
* @group beforeSetup
|
||||
@@ -141,17 +153,40 @@ class DictionariesConsistencyTest extends ItopTestCase
|
||||
/**
|
||||
* @param string $sDictFile complete path for the file to check
|
||||
* @param bool $bIsSyntaxValid expected assert value
|
||||
*
|
||||
* @uses `php -l`
|
||||
* @uses \assertEquals()
|
||||
*/
|
||||
private function CheckDictionarySyntax(string $sDictFile, $bIsSyntaxValid = true): void
|
||||
{
|
||||
exec("php -l {$sDictFile}", $output, $return);
|
||||
|
||||
$bDictFileSyntaxOk = ($return === 0);
|
||||
|
||||
$sMessage = "File `{$sDictFile}` syntax didn't matched expectations\nparsing results=".var_export($output, true);
|
||||
self::assertEquals($bIsSyntaxValid, $bDictFileSyntaxOk, $sMessage);
|
||||
$sPHP = file_get_contents($sDictFile);
|
||||
// Strip php tag to allow "eval"
|
||||
$sPHP = substr(trim($sPHP), strlen('<?php'));
|
||||
// Make sure the Dict class is the one declared in the current file
|
||||
$sPHP = 'namespace '.__NAMESPACE__.";\n".$sPHP;
|
||||
$iLineShift = 1; // Cope with the shift due to the namespace statement
|
||||
$sPHP = str_replace(
|
||||
['ITOP_APPLICATION_SHORT', 'ITOP_APPLICATION', 'ITOP_VERSION_NAME'],
|
||||
['\'itop\'', '\'itop\'', '\'1.2.3\''],
|
||||
$sPHP
|
||||
);
|
||||
try {
|
||||
eval($sPHP);
|
||||
// Reaching this point => No syntax error
|
||||
if (!$bIsSyntaxValid) {
|
||||
$this->fail("Failed to detect syntax error in dictionary `{$sDictFile}` (which is known as being INCORRECT)");
|
||||
}
|
||||
}
|
||||
catch (\Error $e) {
|
||||
if ($bIsSyntaxValid) {
|
||||
$iLine = $e->getLine() - $iLineShift;
|
||||
$this->fail("Invalid dictionary: {$e->getMessage()} in {$sDictFile}:{$iLine}");
|
||||
}
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
if ($bIsSyntaxValid) {
|
||||
$iLine = $e->getLine() - $iLineShift;
|
||||
$sExceptionClass = get_class($e);
|
||||
$this->fail("Exception thrown from dictionary: '$sExceptionClass: {$e->getMessage()}' in {$sDictFile}:{$iLine}");
|
||||
}
|
||||
}
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
|
||||
<?php
|
||||
/**
|
||||
* @used-by \Combodo\iTop\Test\UnitTest\Integration\DictionariesConsistencyTest::testPlaygroundDictionariesPhpSyntax
|
||||
*/
|
||||
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'MyDictKey1' => 'l\'échappement : bon exemple 1',
|
||||
'MyDictKey1' => 'l\'échappement : bon exemple 1'.ITOP_APPLICATION,
|
||||
'MyDictKey2' => 'l\'échappement : bon exemple 2',
|
||||
'MyDictKey3' => 'l\'échappement : bon exemple 3',
|
||||
));
|
||||
|
||||
@@ -13,6 +13,8 @@ use SetupUtils;
|
||||
use const DEBUG_BACKTRACE_IGNORE_ARGS;
|
||||
|
||||
/**
|
||||
* Class ItopTestCase
|
||||
*
|
||||
* Helper class to extend for tests that DO NOT need to access the DataModel or the Database
|
||||
*
|
||||
* @since 3.0.4 3.1.1 3.2.0 N°6658 move some setUp/tearDown code to the corresponding methods *BeforeClass to speed up tests process time.
|
||||
@@ -21,6 +23,7 @@ abstract class ItopTestCase extends TestCase
|
||||
{
|
||||
public const TEST_LOG_DIR = 'test';
|
||||
public static $DEBUG_UNIT_TEST = false;
|
||||
protected static $aBackupStaticProperties = [];
|
||||
|
||||
/**
|
||||
* @link https://docs.phpunit.de/en/9.6/annotations.html#preserveglobalstate PHPUnit `preserveGlobalState` annotation documentation
|
||||
@@ -302,6 +305,42 @@ abstract class ItopTestCase extends TestCase
|
||||
return $oProperty->getValue($oObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup every static property of the class (even protected ones)
|
||||
* @param string $sClass
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function BackupStaticProperties($sClass)
|
||||
{
|
||||
$class = new \ReflectionClass($sClass);
|
||||
foreach ($class->getProperties() as $property) {
|
||||
if (!$property->isStatic()) continue;
|
||||
$property->setAccessible(true);
|
||||
static::$aBackupStaticProperties[$sClass][$property->getName()] = $property->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore every static property of the class (even protected ones)
|
||||
* @param string $sClass
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function RestoreStaticProperties($sClass)
|
||||
{
|
||||
$class = new \ReflectionClass($sClass);
|
||||
foreach ($class->getProperties() as $property) {
|
||||
if (!$property->isStatic()) continue;
|
||||
$property->setAccessible(true);
|
||||
$property->setValue(static::$aBackupStaticProperties[$sClass][$property->getName()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.7.10 3.1.0
|
||||
*/
|
||||
@@ -337,14 +376,14 @@ abstract class ItopTestCase extends TestCase
|
||||
$oProperty->setValue($value);
|
||||
}
|
||||
|
||||
public function RecurseRmdir($dir)
|
||||
public static function RecurseRmdir($dir)
|
||||
{
|
||||
if (is_dir($dir)) {
|
||||
$objects = scandir($dir);
|
||||
foreach ($objects as $object) {
|
||||
if ($object != "." && $object != "..") {
|
||||
if (is_dir($dir.DIRECTORY_SEPARATOR.$object)) {
|
||||
$this->RecurseRmdir($dir.DIRECTORY_SEPARATOR.$object);
|
||||
static::RecurseRmdir($dir.DIRECTORY_SEPARATOR.$object);
|
||||
} else {
|
||||
unlink($dir.DIRECTORY_SEPARATOR.$object);
|
||||
}
|
||||
@@ -354,7 +393,7 @@ abstract class ItopTestCase extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function CreateTmpdir() {
|
||||
public static function CreateTmpdir() {
|
||||
$sTmpDir=tempnam(sys_get_temp_dir(),'');
|
||||
if (file_exists($sTmpDir))
|
||||
{
|
||||
@@ -369,7 +408,7 @@ abstract class ItopTestCase extends TestCase
|
||||
return sys_get_temp_dir();
|
||||
}
|
||||
|
||||
public function RecurseMkdir($sDir){
|
||||
public static function RecurseMkdir($sDir){
|
||||
if (strpos($sDir, DIRECTORY_SEPARATOR) === 0){
|
||||
$sPath = DIRECTORY_SEPARATOR;
|
||||
} else {
|
||||
@@ -394,13 +433,13 @@ abstract class ItopTestCase extends TestCase
|
||||
|
||||
}
|
||||
|
||||
public 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) ) {
|
||||
$this->RecurseCopy($src . DIRECTORY_SEPARATOR . $file,$dst . DIRECTORY_SEPARATOR . $file);
|
||||
static::RecurseCopy($src . DIRECTORY_SEPARATOR . $file,$dst . DIRECTORY_SEPARATOR . $file);
|
||||
}
|
||||
else {
|
||||
copy($src . DIRECTORY_SEPARATOR . $file,$dst . DIRECTORY_SEPARATOR . $file);
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @runTestsInSeparateProcesses
|
||||
*/
|
||||
class ApplicationObjectExtensionTest extends \Combodo\iTop\Test\UnitTest\ItopDataTestCase
|
||||
{
|
||||
const CREATE_TEST_ORG = true;
|
||||
|
||||
@@ -6,7 +6,7 @@ use Combodo\iTop\Application\Helper\Session;
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
|
||||
/**
|
||||
* @runTestsInSeparateProcesses
|
||||
* @runClassInSeparateProcess Required because PHPUnit outputs something earlier, thus causing the headers to be sent
|
||||
*/
|
||||
class SessionTest extends ItopTestCase
|
||||
{
|
||||
@@ -24,18 +24,9 @@ class SessionTest extends ItopTestCase
|
||||
|
||||
/**
|
||||
* @covers \Combodo\iTop\Application\Helper\Session::Start
|
||||
*/
|
||||
public function testStart()
|
||||
{
|
||||
$this->assertNull(Session::$iSessionId);
|
||||
Session::Start();
|
||||
$this->assertNotNull(Session::$iSessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Combodo\iTop\Application\Helper\Session::WriteClose
|
||||
*/
|
||||
public function testWriteClose()
|
||||
public function testStartWriteClose()
|
||||
{
|
||||
$this->assertNull(Session::$iSessionId);
|
||||
Session::Start();
|
||||
|
||||
@@ -12,46 +12,65 @@ use ThemeHandler;
|
||||
class ThemeHandlerTest extends ItopTestCase
|
||||
{
|
||||
const PATTERN = '|\\\/var[^"]+testimages|';
|
||||
|
||||
|
||||
private $oCompileCSSServiceMock;
|
||||
private $sCompiledThemesDirAbsPath;
|
||||
private $sCssAbsPath;
|
||||
private $sDmCssAbsPath;
|
||||
private $sJsonThemeParamFile;
|
||||
private $sTmpDir;
|
||||
private $aDirsToCleanup= [];
|
||||
static private $sTmpDir = null;
|
||||
static private $aDirsToCleanup = [];
|
||||
static private $sAbsoluteImagePath;
|
||||
|
||||
|
||||
static function setUpBeforeClass(): void
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
static::$sTmpDir = static::CreateTmpdir().'/';
|
||||
static::$aDirsToCleanup[] = static::$sTmpDir;
|
||||
|
||||
static::$sAbsoluteImagePath = APPROOT.'tests/php-unit-tests/unitary-tests/application/theme-handler/copied/testimages/';
|
||||
static::RecurseMkdir(static::$sAbsoluteImagePath);
|
||||
|
||||
// Required by testCompileThemesxxx - copy images in test dir
|
||||
static::RecurseCopy(APPROOT.'tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/', static::$sAbsoluteImagePath);
|
||||
|
||||
static::$aDirsToCleanup[] = dirname(static::$sAbsoluteImagePath);
|
||||
}
|
||||
|
||||
static function tearDownAfterClass(): void
|
||||
{
|
||||
foreach (static::$aDirsToCleanup as $sDir)
|
||||
{
|
||||
static::RecurseRmdir($sDir);
|
||||
}
|
||||
|
||||
parent::tearDownAfterClass();
|
||||
}
|
||||
|
||||
protected static function InitCSSDirectory()
|
||||
{
|
||||
static::RecurseCopy(APPROOT."/tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css", static::$sTmpDir."/branding/css");
|
||||
}
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->RequireOnceItopFile('application/themehandler.class.inc.php');
|
||||
$this->RequireOnceItopFile('setup/modelfactory.class.inc.php');
|
||||
$this->RequireOnceUnitTestFile('../setup/SubMFCompiler.php');
|
||||
|
||||
$this->oCompileCSSServiceMock = $this->createMock('CompileCSSService');
|
||||
ThemeHandler::mockCompileCSSService($this->oCompileCSSServiceMock);
|
||||
|
||||
$this->sTmpDir = $this->CreateTmpdir().'/';
|
||||
$this->aDirsToCleanup[] = $this->sTmpDir;
|
||||
|
||||
|
||||
$this->sCompiledThemesDirAbsPath = $this->sTmpDir."branding/themes/";
|
||||
$this->recurseMkdir($this->sCompiledThemesDirAbsPath."basque-red/");
|
||||
$this->sCompiledThemesDirAbsPath = static::$sTmpDir."branding/themes/";
|
||||
static::RecurseMkdir($this->sCompiledThemesDirAbsPath."basque-red/");
|
||||
$this->sCssAbsPath = $this->sCompiledThemesDirAbsPath.'basque-red/main.css';
|
||||
$this->sDmCssAbsPath = $this->sCompiledThemesDirAbsPath.'datamodel-compiled-scss-rules.scss';
|
||||
$this->sJsonThemeParamFile = $this->sCompiledThemesDirAbsPath.'basque-red/theme-parameters.json';
|
||||
$this->RecurseCopy(APPROOT."/tests/php-unit-tests/unitary-tests/application/theme-handler/expected/css", $this->sTmpDir."/branding/css");
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
foreach ($this->aDirsToCleanup as $sDir)
|
||||
{
|
||||
echo $sDir;
|
||||
$this->RecurseRmdir($sDir);
|
||||
}
|
||||
}
|
||||
|
||||
function KeepSignatureDiff($sSignature1, $sSignature2) : string {
|
||||
@@ -83,14 +102,14 @@ class ThemeHandlerTest extends ItopTestCase
|
||||
$aDiffOuput[$sKey] = $aCurrentDiffVal;
|
||||
}
|
||||
} else if ($oVal1 !== $aSignature2[$sKey]){
|
||||
$aDiffOuput[$sKey] = "expected:$oVal1 | actual:$aSignature2[$sKey]";
|
||||
$aDiffOuput[$sKey] = "expected:$oVal1 | actual:$aSignature2[$sKey]";
|
||||
}
|
||||
}
|
||||
|
||||
return json_encode($aDiffOuput, true);
|
||||
}
|
||||
|
||||
function recurseMkdir($dir)
|
||||
public static function RecurseMkdir($dir)
|
||||
{
|
||||
if (is_dir($dir))
|
||||
{
|
||||
@@ -98,7 +117,7 @@ class ThemeHandlerTest extends ItopTestCase
|
||||
}
|
||||
|
||||
$sParentDir = dirname($dir);
|
||||
if (!$this->recurseMkdir($sParentDir))
|
||||
if (!static::RecurseMkdir($sParentDir))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -141,6 +160,8 @@ JSON;
|
||||
*/
|
||||
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);
|
||||
@@ -160,11 +181,11 @@ JSON;
|
||||
if($readFromParamAttributeFromJson)
|
||||
{
|
||||
copy($sExpectJsonFilePath, $this->sJsonThemeParamFile);
|
||||
$this->assertTrue(ThemeHandler::CompileTheme('basque-red', true, "COMPILATIONTIMESTAMP", null, [$this->sTmpDir.'/branding/themes/'], $this->sTmpDir));
|
||||
$this->assertTrue(ThemeHandler::CompileTheme('basque-red', true, "COMPILATIONTIMESTAMP", null, [static::$sTmpDir.'/branding/themes/'], static::$sTmpDir));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->assertTrue(ThemeHandler::CompileTheme('basque-red', true, "COMPILATIONTIMESTAMP", $aThemeParameters, [$this->sTmpDir.'/branding/themes/'], $this->sTmpDir));
|
||||
$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));
|
||||
@@ -189,14 +210,14 @@ JSON;
|
||||
*/
|
||||
public function testCompileThemesEmptyArray($ThemeParametersJson, $CompileCount=0)
|
||||
{
|
||||
$sCssPath = $this->sTmpDir . '/branding/themes/basque-red/main.css';
|
||||
$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), [$this->sTmpDir.'/branding/themes/'], $this->sTmpDir));
|
||||
$this->assertEquals($CompileCount!=0,ThemeHandler::CompileTheme('basque-red', true, "COMPILATIONTIMESTAMP", json_decode($ThemeParametersJson, true), [static::$sTmpDir.'/branding/themes/'], static::$sTmpDir));
|
||||
}
|
||||
|
||||
public function CompileThemesProviderEmptyArray()
|
||||
@@ -213,6 +234,14 @@ JSON;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* mixed $ThemeParametersJson
|
||||
* int $iCompileCSSFromSASSCount
|
||||
* boolean $bMissingFile
|
||||
* boolean $bFilesTouchedRecently
|
||||
* boolean $bFileMd5sumModified
|
||||
* null $sFileToTest
|
||||
* null $sExpectedMainCssPath
|
||||
* bool $bSetup
|
||||
*/
|
||||
public function CompileThemesProvider()
|
||||
{
|
||||
@@ -260,26 +289,24 @@ JSON;
|
||||
*/
|
||||
public function testCompileThemes($ThemeParametersJson, $iCompileCSSFromSASSCount, $bMissingFile=false, $bFilesTouchedRecently=false, $bFileMd5sumModified=false, $sFileToTest=null, $sExpectedMainCssPath=null, $bSetup=true)
|
||||
{
|
||||
static::InitCSSDirectory();
|
||||
|
||||
$sAfterReplacementCssVariableMd5sum='';
|
||||
if (is_file($this->sTmpDir.'/'.$sFileToTest))
|
||||
if (is_file(static::$sTmpDir.'/'.$sFileToTest))
|
||||
{
|
||||
$sFileToTest = $this->sTmpDir.'/'.$sFileToTest;
|
||||
$sFileToTest = static::$sTmpDir.'/'.$sFileToTest;
|
||||
} else {
|
||||
$sFileToTest = APPROOT.'/'.$sFileToTest;
|
||||
}
|
||||
|
||||
//copy images in test dir
|
||||
$sAbsoluteImagePath = APPROOT.'tests/php-unit-tests/unitary-tests/application/theme-handler/copied/testimages/';
|
||||
$this->recurseMkdir($sAbsoluteImagePath);
|
||||
$this->aDirsToCleanup[] = dirname($sAbsoluteImagePath);
|
||||
$this->RecurseCopy(APPROOT.'tests/php-unit-tests/unitary-tests/application/theme-handler/expected/testimages/', $sAbsoluteImagePath);
|
||||
// Backup the file to test
|
||||
copy($sFileToTest, static::$sTmpDir.'/file-to-test-backup');
|
||||
|
||||
//change approot-relative in css-variable to use absolute path
|
||||
$sCssVarPath = $this->sTmpDir."/branding/css/DO_NOT_CHANGE.css-variables.scss";
|
||||
$sCssVarPath = static::$sTmpDir."/branding/css/DO_NOT_CHANGE.css-variables.scss";
|
||||
$sBeforeReplacementCssVariableMd5sum = md5_file($sCssVarPath);
|
||||
echo 'BEFORE :'.$sBeforeReplacementCssVariableMd5sum.' '.$sCssVarPath.' ';
|
||||
$sCssVariableContent = file_get_contents($sCssVarPath);
|
||||
$sLine = '$approot-relative: "'.$sAbsoluteImagePath.'" !default;';
|
||||
$sLine = '$approot-relative: "'.static::$sAbsoluteImagePath.'" !default;';
|
||||
$sCssVariableContent = preg_replace("/\\\$approot-relative: \"(.*)\"/", $sLine, $sCssVariableContent);
|
||||
file_put_contents($sCssVarPath, $sCssVariableContent);
|
||||
if ($bMissingFile)
|
||||
@@ -296,30 +323,23 @@ JSON;
|
||||
//change cssvar md5sum + image absolute paths
|
||||
$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($sAbsoluteImagePath, '/');
|
||||
$sReplacement = rtrim(static::$sAbsoluteImagePath, '/');
|
||||
$sReplacement=preg_replace('|\/|', '\/', $sReplacement);
|
||||
$sMainCssContent = preg_replace(static::PATTERN, $sReplacement, $sMainCssContent);
|
||||
$cssPath = $this->sTmpDir . '/branding/themes/basque-red/main.css';
|
||||
echo 'PUT md5sum: '.$sAfterReplacementCssVariableMd5sum.' in '.$cssPath.' ';
|
||||
$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)
|
||||
{
|
||||
sleep(1);
|
||||
touch($sFileToTest);
|
||||
touch($sFileToTest, time() + 2, time() + 2);
|
||||
}
|
||||
|
||||
//same: it should be after main.css modification
|
||||
if ($bFileMd5sumModified)
|
||||
{
|
||||
$sMd5sum = md5_file($sFileToTest);
|
||||
echo ' BEFORE touch: ' . $sMd5sum .' ' . $sFileToTest;
|
||||
sleep(1);
|
||||
file_put_contents($sFileToTest, "###\n".file_get_contents($sFileToTest));
|
||||
|
||||
$sMd5sum = md5_file($sFileToTest);
|
||||
echo ' AFTER touch: ' . $sMd5sum .' ' . $sFileToTest;
|
||||
touch($sFileToTest, time() + 2, time() + 2);
|
||||
}
|
||||
|
||||
if (is_file($sCssVarPath))
|
||||
@@ -332,7 +352,7 @@ JSON;
|
||||
->willReturn("====CSSCOMPILEDCONTENT====");
|
||||
|
||||
$aThemeParameters = json_decode($ThemeParametersJson, true);
|
||||
$this->assertEquals($iCompileCSSFromSASSCount!=0, ThemeHandler::CompileTheme('basque-red', $bSetup, "COMPILATIONTIMESTAMP", $aThemeParameters, [$this->sTmpDir.'/branding/themes/'], $this->sTmpDir));
|
||||
$this->assertEquals($iCompileCSSFromSASSCount!=0, ThemeHandler::CompileTheme('basque-red', $bSetup, "COMPILATIONTIMESTAMP", $aThemeParameters, [static::$sTmpDir.'/branding/themes/'], static::$sTmpDir));
|
||||
|
||||
if ($iCompileCSSFromSASSCount==1)
|
||||
{
|
||||
@@ -347,9 +367,11 @@ JSON;
|
||||
$aReplacements = [$sReplacement, $sAfterReplacementCssVariableMd5sum];
|
||||
$aReplacements[] = md5(json_encode($aThemeParameters['variables']));
|
||||
$aReplacements[] = $sAfterReplacementCssVariableMd5sum;
|
||||
var_dump($aReplacements);
|
||||
$this->DoInnerJsonValidation($sExpectedMainCssFile, $cssPath, $aPatterns, $aReplacements);
|
||||
}
|
||||
|
||||
// Restore the file to test (possible improvement: do that in tearDown)
|
||||
copy(static::$sTmpDir.'/file-to-test-backup', $sFileToTest);
|
||||
}
|
||||
|
||||
public function DoInnerJsonValidation($sExpectedCssFile, $sActualCssFile, $aPatterns, $aReplacements)
|
||||
@@ -396,8 +418,8 @@ JSON;
|
||||
'\'abc/\'+ $approot-relative + "css/ui-lightness/images/toutou.png?v=" + $version',
|
||||
"\$approot-relative + \"css/ui-lightness/images/toto.png?v=\" + \$version",
|
||||
'$approot-relative + \'css/ui-lightness/images/titi.gif?v=\' + $version1',
|
||||
'"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7?v=" + $version',
|
||||
'$approot-relative + \'node_modules/raleway-webfont/fonts/Raleway-Thin.jpeg\'',
|
||||
'"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7?v=" + $version',
|
||||
'$approot-relative + \'node_modules/raleway-webfont/fonts/Raleway-Thin.jpeg\'',
|
||||
];
|
||||
|
||||
$aIncludedUrls['aCompleteUrls'];
|
||||
@@ -432,13 +454,13 @@ SCSS;
|
||||
$aExpectedFoundVariables = [
|
||||
'gabu' => 'zomeu',
|
||||
'toto' => 'titi',
|
||||
'approot-relative' => '../../../../../',
|
||||
'approot-relative2' => '../../',
|
||||
'gray-base' => '#000',
|
||||
'a' => 'b',
|
||||
'content-color' => '#eeeeee',
|
||||
'default-font-family' => 'Trebuchet MS,Tahoma,Verdana,Arial,sans-serif',
|
||||
'icons-filter' => 'hue-rotate(0deg)',
|
||||
'approot-relative' => '../../../../../',
|
||||
'approot-relative2' => '../../',
|
||||
'gray-base' => '#000',
|
||||
'a' => 'b',
|
||||
'content-color' => '#eeeeee',
|
||||
'default-font-family' => 'Trebuchet MS,Tahoma,Verdana,Arial,sans-serif',
|
||||
'icons-filter' => 'hue-rotate(0deg)',
|
||||
'toto' => 'titi',
|
||||
];
|
||||
$this->assertEquals($aExpectedFoundVariables, $aFoundVariables);
|
||||
@@ -460,10 +482,10 @@ $icons-filter: hue-rotate(0deg) !default;
|
||||
$toto : titi;
|
||||
SCSS;
|
||||
|
||||
file_put_contents($this->sTmpDir . DIRECTORY_SEPARATOR . 'css-variable.scss', $sContent);
|
||||
file_put_contents(static::$sTmpDir . DIRECTORY_SEPARATOR . 'css-variable.scss', $sContent);
|
||||
$aVariables = ThemeHandler::GetVariablesFromFile(
|
||||
[ 'css-variable.scss' ],
|
||||
[ $this->sTmpDir ]
|
||||
[ static::$sTmpDir ]
|
||||
);
|
||||
|
||||
$aExpectedVariables = [
|
||||
@@ -512,8 +534,10 @@ SCSS;
|
||||
|
||||
public function testGetIncludedImages()
|
||||
{
|
||||
$aStylesheetFile=glob($this->sTmpDir."/branding/css/*.scss");
|
||||
$aStylesheetFile[]=$this->sTmpDir."/branding/css/ui-lightness/DO_NOT_CHANGE.jqueryui.scss";
|
||||
static::InitCSSDirectory();
|
||||
|
||||
$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);
|
||||
@@ -538,7 +562,7 @@ SCSS;
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function testFindStylesheetFile(string $sFileToFind, array $aAllImports){
|
||||
$sImportsPath = $this->sTmpDir.'branding/';
|
||||
$sImportsPath = static::$sTmpDir.'branding/';
|
||||
|
||||
// Windows compat O:)
|
||||
$sFileToFind = $this->UpdateDirSep($sFileToFind);
|
||||
|
||||
@@ -36,20 +36,18 @@ class ApplicationExtensionTest extends ItopCustomDatamodelTestCase
|
||||
* - Add the API to the provider
|
||||
* - Add a class extending / implementing the API in ./Delta/application-extension-usages-in-snippets.xml
|
||||
*
|
||||
* @param string $sAPIFQCN
|
||||
* @param string $sCallMethod
|
||||
*
|
||||
* @return void
|
||||
* @dataProvider ExtensionAPIRegisteredAndCalledProvider
|
||||
*/
|
||||
public function testExtensionAPIRegisteredAndCalled(string $sAPIFQCN, string $sCallMethod)
|
||||
public function testExtensionAPIRegisteredAndCalled()
|
||||
{
|
||||
if ($sCallMethod === static::ENUM_API_CALL_METHOD_ENUMPLUGINS) {
|
||||
$iExtendingClassesCount = count(MetaModel::EnumPlugins($sAPIFQCN));
|
||||
} else {
|
||||
$iExtendingClassesCount = count(utils::GetClassesForInterface($sAPIFQCN, '', ['[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]', '[\\\\/]tests[\\\\/]']));
|
||||
foreach ($this->ExtensionAPIRegisteredAndCalledProvider() as list($sAPIFQCN, $sCallMethod)) {
|
||||
if ($sCallMethod === static::ENUM_API_CALL_METHOD_ENUMPLUGINS) {
|
||||
$iExtendingClassesCount = count(MetaModel::EnumPlugins($sAPIFQCN));
|
||||
} else {
|
||||
$iExtendingClassesCount = count(utils::GetClassesForInterface($sAPIFQCN, '', ['[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]', '[\\\\/]tests[\\\\/]']));
|
||||
}
|
||||
$this->assertGreaterThan(0, $iExtendingClassesCount, "Found no class extending the $sAPIFQCN API");
|
||||
}
|
||||
$this->assertGreaterThan(0, $iExtendingClassesCount, "Found no class extending the $sAPIFQCN API");
|
||||
}
|
||||
|
||||
public function ExtensionAPIRegisteredAndCalledProvider(): array
|
||||
|
||||
@@ -77,9 +77,6 @@ class cmdbAbstractObjectTest extends ItopDataTestCase {
|
||||
self::assertSame($aExpectedLinkStack, $aLinkModificationsStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testProcessClassIdDeferredUpdate()
|
||||
{
|
||||
// Create the team
|
||||
@@ -157,7 +154,6 @@ class cmdbAbstractObjectTest extends ItopDataTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* Check that EVENT_DB_LINKS_CHANGED events are not sent to the current updated/created object (Team)
|
||||
* the events are sent to the other side (Person)
|
||||
*
|
||||
@@ -201,8 +197,6 @@ class cmdbAbstractObjectTest extends ItopDataTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*
|
||||
* Check that EVENT_DB_LINKS_CHANGED events are sent to all the linked objects when creating a new lnk object
|
||||
*
|
||||
* @return void
|
||||
@@ -238,7 +232,6 @@ class cmdbAbstractObjectTest extends ItopDataTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* Check that EVENT_DB_LINKS_CHANGED events are sent to all the linked objects when updating an existing lnk object
|
||||
*
|
||||
* @return void
|
||||
@@ -281,7 +274,6 @@ class cmdbAbstractObjectTest extends ItopDataTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* Check that when a link changes from an object to another, then both objects are notified
|
||||
*
|
||||
* @return void
|
||||
@@ -325,7 +317,6 @@ class cmdbAbstractObjectTest extends ItopDataTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* Check that EVENT_DB_LINKS_CHANGED events are sent to all the linked objects when deleting an existing lnk object
|
||||
*
|
||||
* @return void
|
||||
|
||||
@@ -25,7 +25,6 @@ use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* @runClassInSeparateProcess
|
||||
* @covers utils
|
||||
*/
|
||||
class utilsTest extends ItopTestCase
|
||||
@@ -245,7 +244,6 @@ class utilsTest extends ItopTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @dataProvider GetAbsoluteUrlAppRootPersistency
|
||||
*/
|
||||
public function testGetAbsoluteUrlAppRootPersistency($bBehindReverseProxy,$bForceTrustProxy1 ,$sExpectedAppRootUrl1,$bForceTrustProxy2 , $sExpectedAppRootUrl2,$bForceTrustProxy3 , $sExpectedAppRootUrl3)
|
||||
@@ -274,6 +272,9 @@ class utilsTest extends ItopTestCase
|
||||
$this->assertEquals($sExpectedAppRootUrl2, utils::GetAbsoluteUrlAppRoot($bForceTrustProxy2));
|
||||
|
||||
$this->assertEquals($sExpectedAppRootUrl3, utils::GetAbsoluteUrlAppRoot($bForceTrustProxy3));
|
||||
|
||||
// Leave the place clean
|
||||
static::SetNonPublicStaticProperty('utils', 'm_sAppRootUrl', null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,10 +6,8 @@ use CMDBSource;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use MetaModel;
|
||||
|
||||
/**
|
||||
* @runClassInSeparateProcess
|
||||
*/
|
||||
class BulkChangeTest extends ItopDataTestCase {
|
||||
class BulkChangeTest extends ItopDataTestCase
|
||||
{
|
||||
const CREATE_TEST_ORG = true;
|
||||
|
||||
protected function setUp(): void
|
||||
@@ -57,8 +55,7 @@ class BulkChangeTest extends ItopDataTestCase {
|
||||
true // localize
|
||||
);
|
||||
|
||||
$oChange = \CMDBObject::GetCurrentChange();
|
||||
$aRes = $oBulk->Process($oChange);
|
||||
$aRes = $oBulk->Process();
|
||||
static::assertNotNull($aRes);
|
||||
|
||||
foreach ($aRes as $aRow) {
|
||||
@@ -94,8 +91,7 @@ class BulkChangeTest extends ItopDataTestCase {
|
||||
true // localize
|
||||
);
|
||||
|
||||
$oChange = \CMDBObject::GetCurrentChange();
|
||||
$aRes = $oBulk->Process($oChange);
|
||||
$aRes = $oBulk->Process();
|
||||
static::assertNotNull($aRes);
|
||||
|
||||
foreach ($aRes as $aRow) {
|
||||
@@ -175,7 +171,6 @@ class BulkChangeTest extends ItopDataTestCase {
|
||||
* @param $aReconcilKeys
|
||||
*/
|
||||
public function testCas1BulkChangeIssue($aInitData, $aCsvData, $aAttributes, $aExtKeys, $aReconcilKeys, $aResult) {
|
||||
CMDBSource::Query('START TRANSACTION');
|
||||
//change value during the test
|
||||
$db_core_transactions_enabled=MetaModel::GetConfig()->Get('db_core_transactions_enabled');
|
||||
MetaModel::GetConfig()->Set('db_core_transactions_enabled',false);
|
||||
@@ -193,8 +188,6 @@ class BulkChangeTest extends ItopDataTestCase {
|
||||
$aResult["id"]=$oServer->GetKey();
|
||||
$this->debug("oServer->GetKey():".$oServer->GetKey());
|
||||
}
|
||||
$this->debug("aCsvData:".json_encode($aCsvData[0]));
|
||||
$this->debug("aReconcilKeys:".$aReconcilKeys[0]);
|
||||
$oBulk = new \BulkChange(
|
||||
"Server",
|
||||
$aCsvData,
|
||||
@@ -206,13 +199,8 @@ class BulkChangeTest extends ItopDataTestCase {
|
||||
"Y-m-d H:i:s", // date format
|
||||
true // localize
|
||||
);
|
||||
$this->debug("BulkChange:");
|
||||
$oChange = \CMDBObject::GetCurrentChange();
|
||||
$this->debug("GetCurrentChange:");
|
||||
$aRes = $oBulk->Process($oChange);
|
||||
$this->debug("Process:");
|
||||
$aRes = $oBulk->Process();
|
||||
static::assertNotNull($aRes);
|
||||
$this->debug("assertNotNull:");
|
||||
foreach ($aRes as $aRow) {
|
||||
if (array_key_exists('__STATUS__', $aRow)) {
|
||||
$sStatus = $aRow['__STATUS__'];
|
||||
@@ -232,7 +220,6 @@ class BulkChangeTest extends ItopDataTestCase {
|
||||
$this->assertEquals( $aResult[0], $aRow[0]->GetDisplayableValue());
|
||||
}
|
||||
}
|
||||
CMDBSource::Query('ROLLBACK');
|
||||
MetaModel::GetConfig()->Set('db_core_transactions_enabled',$db_core_transactions_enabled);
|
||||
}
|
||||
|
||||
@@ -378,7 +365,6 @@ class BulkChangeTest extends ItopDataTestCase {
|
||||
* @param $aReconcilKeys
|
||||
*/
|
||||
public function testCas2BulkChangeIssue($aInitData, $aCsvData, $aAttributes, $aExtKeys, $aReconcilKeys, $aResult) {
|
||||
CMDBSource::Query('START TRANSACTION');
|
||||
//change value during the test
|
||||
$db_core_transactions_enabled=MetaModel::GetConfig()->Get('db_core_transactions_enabled');
|
||||
MetaModel::GetConfig()->Set('db_core_transactions_enabled',false);
|
||||
@@ -409,8 +395,7 @@ class BulkChangeTest extends ItopDataTestCase {
|
||||
"Y-m-d H:i:s", // date format
|
||||
true // localize
|
||||
);
|
||||
$oChange = \CMDBObject::GetCurrentChange();
|
||||
$aRes = $oBulk->Process($oChange);
|
||||
$aRes = $oBulk->Process();
|
||||
static::assertNotNull($aRes);
|
||||
foreach ($aRes as $aRow) {
|
||||
foreach ($aRow as $i => $oCell) {
|
||||
@@ -429,7 +414,6 @@ class BulkChangeTest extends ItopDataTestCase {
|
||||
}
|
||||
$this->assertEquals($aResult[0], $aRow[0]->GetDisplayableValue());
|
||||
}
|
||||
CMDBSource::Query('ROLLBACK');
|
||||
MetaModel::GetConfig()->Set('db_core_transactions_enabled',$db_core_transactions_enabled);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,13 @@ class CMDBSourceTest extends ItopTestCase
|
||||
$this->RequireOnceItopFile('/core/cmdbsource.class.inc.php');
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
DbConnectionWrapper::SetDbConnectionMockForQuery();
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers CMDBSource::IsSameFieldTypes
|
||||
* @dataProvider compareFieldTypesProvider
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -257,30 +257,28 @@ class TransactionsTest extends ItopTestCase
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @doesNotPerformAssertions
|
||||
*/
|
||||
public function testTransactionOpenedThenClosed()
|
||||
public function testIsInsideTransaction()
|
||||
{
|
||||
CMDBSource::Query('START TRANSACTION;');
|
||||
CMDBSource::Query('COMMIT;');
|
||||
}
|
||||
static::assertFalse(CMDBSource::IsInsideTransaction(), 'Should not be already inside a transaction');
|
||||
|
||||
/**
|
||||
* This will throw an exception in the tearDown method.
|
||||
* This cannot be detected nor by `@expectedException` nor `expectException` method, so we have a specific tearDown impl
|
||||
*
|
||||
* @return void
|
||||
* @doesNotPerformAssertions
|
||||
*/
|
||||
public function testTransactionOpenedNotClosed()
|
||||
{
|
||||
// First, with a transaction ended by a "COMMIT" statement
|
||||
CMDBSource::Query('START TRANSACTION;');
|
||||
static::assertTrue(CMDBSource::IsInsideTransaction(), 'Should be inside a translation');
|
||||
CMDBSource::Query('COMMIT;');
|
||||
static::assertFalse(CMDBSource::IsInsideTransaction(), 'Should not be inside a transaction anymore');
|
||||
|
||||
// Second, with a transaction ended by a "ROLLBACK" statement
|
||||
CMDBSource::Query('START TRANSACTION;');
|
||||
static::assertTrue(CMDBSource::IsInsideTransaction(), 'Should be inside a translation (again)');
|
||||
CMDBSource::Query('ROLLBACK;');
|
||||
static::assertFalse(CMDBSource::IsInsideTransaction(), 'Should not be inside a transaction anymore');
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
try {
|
||||
DbConnectionWrapper::SetDbConnectionMockForQuery(); // Else will throw error on PHP 8.1+ (see N°6848)
|
||||
DbConnectionWrapper::SetDbConnectionMockForQuery();
|
||||
parent::tearDown();
|
||||
}
|
||||
catch (MySQLTransactionNotClosedException $e) {
|
||||
|
||||
@@ -557,7 +557,7 @@ class ExpressionEvaluateTest extends ItopDataTestCase
|
||||
public function EveryTimeFormatOnDateRangeProvider()
|
||||
{
|
||||
return array(
|
||||
'10 years, day by day' => array('2000-01-01', 'P1D', 365 * 10),
|
||||
'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),
|
||||
|
||||
@@ -30,8 +30,6 @@ class ExceptionLogTest extends ItopDataTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*
|
||||
* @dataProvider logProvider
|
||||
*/
|
||||
public function testLogInFile($aLevels, $aExceptions, $sChannel, $aExpectedWriteNumber, $logLevelMin, $aExpectedDbWriteNumber, $logLevelMinWriteInDb)
|
||||
@@ -91,14 +89,26 @@ class ExceptionLogTest extends ItopDataTestCase
|
||||
$oExpectedLastEventIssue = $this->InvokeNonPublicStaticMethod('ExceptionLog', 'GetLastEventIssue', []);
|
||||
|
||||
if (0 == $iExpectedDbWriteNumber) {
|
||||
$this->assertNull($oExpectedLastEventIssue);
|
||||
if (!is_null($oExpectedLastEventIssue)) {
|
||||
$this->fail("Level '$sLevel': unexpected EventIssue");
|
||||
}
|
||||
} else {
|
||||
$this->assertInstanceOf(\EventIssue::class, $oExpectedLastEventIssue);
|
||||
$this->assertInstanceOf(\EventIssue::class, $oExpectedLastEventIssue, "Level '$sLevel': missing EventIssue");
|
||||
$this->assertEquals($aExpectedFileContext, $oExpectedLastEventIssue->Get('data'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* aLevels: log levels to iterate on (AND name of the method that will be called on the underlying FileLog)
|
||||
* aExceptions: For each log level => Exception to generate
|
||||
* sChannel: Expected 2nd argument to the FileLog::{Level}
|
||||
* aExpectedWriteNumber: For each log level => Number of times the method FileLog::{Level} will be called
|
||||
* logLevelMin: Configuration / log_level_min
|
||||
* iExpectedDbWriteNumber: For each log level => 1 if at least ONE EventIssue has been recorded into the DB
|
||||
* logLevelMinWriteInDb: Configuration / log_level_min.write_in_db
|
||||
*/
|
||||
public function logProvider()
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -27,7 +27,13 @@ class MetaModelTest extends ItopDataTestCase
|
||||
$this->RequireOnceItopFile('/core/metamodel.class.php');
|
||||
}
|
||||
|
||||
/**
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$this->InvokeNonPublicStaticMethod('PluginManager', 'ResetPlugins');
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* @group itopRequestMgmt
|
||||
* @covers MetaModel::ApplyParams()
|
||||
* @dataProvider ApplyParamsProvider
|
||||
@@ -216,8 +222,6 @@ class MetaModelTest extends ItopDataTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*
|
||||
* @dataProvider enumPluginsProvider
|
||||
*
|
||||
* @param $expectedResults
|
||||
@@ -265,8 +269,6 @@ class MetaModelTest extends ItopDataTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*
|
||||
* @dataProvider getPluginsProvider
|
||||
*
|
||||
* @param $expectedInstanciationCalls
|
||||
|
||||
@@ -48,12 +48,7 @@ class UserRightsTest extends ItopDataTestCase
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
try {
|
||||
utils::GetConfig()->SetModuleSetting('authent-local', 'password_validation.pattern', '');
|
||||
self::CreateUser('admin', 1);
|
||||
}
|
||||
catch (CoreCannotSaveObjectException $e) {
|
||||
}
|
||||
utils::GetConfig()->SetModuleSetting('authent-local', 'password_validation.pattern', '');
|
||||
}
|
||||
|
||||
public static $aClasses = [
|
||||
@@ -103,6 +98,15 @@ class UserRightsTest extends ItopDataTestCase
|
||||
public function testLogin($sLogin, $bResult)
|
||||
{
|
||||
$_SESSION = [];
|
||||
if ($sLogin == 'admin') {
|
||||
// Fixture data required in this case only
|
||||
try {
|
||||
self::CreateUser('admin', 1);
|
||||
}
|
||||
catch (CoreCannotSaveObjectException $e) {
|
||||
// The admin account could exist, depending on where and when the test suite is executed
|
||||
}
|
||||
}
|
||||
$this->assertEquals($bResult, UserRights::Login($sLogin));
|
||||
$this->assertEquals($bResult, UserRights::IsLoggedIn());
|
||||
UserRights::Logoff();
|
||||
@@ -487,8 +491,7 @@ class UserRightsTest extends ItopDataTestCase
|
||||
];
|
||||
}
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*@dataProvider NonAdminCannotListAdminProfilesProvider
|
||||
* @dataProvider NonAdminCannotListAdminProfilesProvider
|
||||
*/
|
||||
public function testNonAdminCannotListAdminProfiles($bHideAdministrators, $iExpectedCount)
|
||||
{
|
||||
|
||||
@@ -11,9 +11,6 @@ use ValueSetDefinition;
|
||||
use ValueSetEnum;
|
||||
|
||||
|
||||
/**
|
||||
* @runTestsInSeparateProcesses
|
||||
*/
|
||||
class ValueSetDefinitionTest extends ItopTestCase
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -32,7 +32,7 @@ define('UNIT_MAX_CACHE_FILES', 10);
|
||||
|
||||
|
||||
/**
|
||||
* @runTestsInSeparateProcesses
|
||||
* @runTestsInSeparateProcesses Required (at least) to mock the MetaModel and utils class
|
||||
*/
|
||||
class apcEmulationTest extends ItopTestCase
|
||||
{
|
||||
|
||||
@@ -30,9 +30,6 @@ use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use Dict;
|
||||
|
||||
|
||||
/**
|
||||
* @runTestsInSeparateProcesses
|
||||
*/
|
||||
class dictApcuTest extends ItopTestCase
|
||||
{
|
||||
private $sEnvName;
|
||||
@@ -45,9 +42,16 @@ class dictApcuTest extends ItopTestCase
|
||||
|
||||
$this->RequireOnceItopFile('core'.DIRECTORY_SEPARATOR.'apc-service.class.inc.php');
|
||||
|
||||
$this->sEnvName = time();
|
||||
// This id will be used as path to the dictionary files
|
||||
// It must be unique enough for the magic of Dict to operate (due to the use of require_once to load dictionaries)
|
||||
$this->sEnvName = uniqid();
|
||||
$_SESSION['itop_env'] = $this->sEnvName;
|
||||
|
||||
// Preserve the dictionary for test that will be executed later on
|
||||
static::BackupStaticProperties('Dict');
|
||||
|
||||
// Reset and prepare the dictionary
|
||||
static::SetNonPublicStaticProperty('Dict', 'm_aData', []);
|
||||
$this->oApcService = $this->createMock(\ApcService::class);
|
||||
Dict::SetApcService($this->oApcService);
|
||||
Dict::EnableCache('toto');
|
||||
@@ -57,7 +61,8 @@ class dictApcuTest extends ItopTestCase
|
||||
$this->InitDictionnaries();
|
||||
}
|
||||
|
||||
private function InitDictionnaries(){
|
||||
private function InitDictionnaries()
|
||||
{
|
||||
clearstatcache();
|
||||
$this->sDictionaryFolder = APPROOT."env-$this->sEnvName" . DIRECTORY_SEPARATOR . "dictionaries";
|
||||
@mkdir($this->sDictionaryFolder, 0777, true);
|
||||
@@ -82,7 +87,8 @@ STR;
|
||||
clearstatcache();
|
||||
}
|
||||
|
||||
private function InitDictionnary($sDictionaryFolder, $sLanguageCode, $sLanguageCodeInFilename, $sLabels){
|
||||
private function InitDictionnary($sDictionaryFolder, $sLanguageCode, $sLanguageCodeInFilename, $sLabels)
|
||||
{
|
||||
$sContent = <<<PHP
|
||||
<?php
|
||||
//
|
||||
@@ -95,7 +101,8 @@ PHP;
|
||||
file_put_contents($sDictionaryFolder . DIRECTORY_SEPARATOR . "$sLanguageCodeInFilename.dict.php", $sContent);
|
||||
}
|
||||
|
||||
private function InitBrokenDictionnary($sDictionaryFolder, $sLanguageCode, $sLanguageCodeInFilename){
|
||||
private function InitBrokenDictionnary($sDictionaryFolder, $sLanguageCode, $sLanguageCodeInFilename)
|
||||
{
|
||||
$sContent = <<<PHP
|
||||
<?php
|
||||
//
|
||||
@@ -114,10 +121,13 @@ PHP;
|
||||
rmdir(APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries");
|
||||
rmdir(APPROOT."env-$this->sEnvName");
|
||||
|
||||
static::RestoreStaticProperties('Dict');
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function InitLangIfNeeded_NoApcProvider(){
|
||||
public function InitLangIfNeeded_NoApcProvider()
|
||||
{
|
||||
return [
|
||||
'apcu mocked' => [ 'bApcuMocked' => true ],
|
||||
'integration test - apcu service like in production - install php-apcu before' => [ 'bApcuMocked' => false ],
|
||||
@@ -127,7 +137,8 @@ PHP;
|
||||
/**
|
||||
* @dataProvider InitLangIfNeeded_NoApcProvider
|
||||
*/
|
||||
public function testInitLangIfNeeded_NoApc($bApcuMocked){
|
||||
public function testInitLangIfNeeded_NoApc($bApcuMocked)
|
||||
{
|
||||
if ($bApcuMocked) {
|
||||
$this->oApcService->expects($this->any())
|
||||
->method('function_exists')
|
||||
@@ -163,7 +174,8 @@ PHP;
|
||||
$this->assertEquals('not_defined_label', Dict::S('not_defined_label'));
|
||||
}
|
||||
|
||||
public function testInitLangIfNeeded_Apc_LanguageMismatchDictionnary(){
|
||||
public function testInitLangIfNeeded_Apc_LanguageMismatchDictionnary()
|
||||
{
|
||||
//language mismatch!!
|
||||
$sLabels = <<<STR
|
||||
'label1' => 'de1',
|
||||
@@ -185,7 +197,8 @@ STR;
|
||||
$this->assertEquals('label1', Dict::S('label1'));
|
||||
}
|
||||
|
||||
public function testInitLangIfNeeded_Apc_BrokenUserDictionnary(){
|
||||
public function testInitLangIfNeeded_Apc_BrokenUserDictionnary()
|
||||
{
|
||||
$this->InitBrokenDictionnary($this->sDictionaryFolder, 'DE DE', 'de-de');
|
||||
|
||||
$this->oApcService->expects($this->any())
|
||||
@@ -205,7 +218,8 @@ STR;
|
||||
$this->assertEquals('ru1', Dict::S('label1'));
|
||||
}
|
||||
|
||||
public function testInitLangIfNeeded_Apc_BrokenDictionnary_UserAndDefault(){
|
||||
public function testInitLangIfNeeded_Apc_BrokenDictionnary_UserAndDefault()
|
||||
{
|
||||
$this->InitBrokenDictionnary($this->sDictionaryFolder, 'DE DE', 'de-de');
|
||||
$this->InitBrokenDictionnary($this->sDictionaryFolder, 'RU RU', 'ru-ru');
|
||||
|
||||
@@ -224,7 +238,8 @@ STR;
|
||||
$this->assertEquals('en1', Dict::S('label1'));
|
||||
}
|
||||
|
||||
public function testInitLangIfNeeded_Apc_BrokenDictionnary_ALL(){
|
||||
public function testInitLangIfNeeded_Apc_BrokenDictionnary_ALL()
|
||||
{
|
||||
$this->InitBrokenDictionnary($this->sDictionaryFolder, 'DE DE', 'de-de');
|
||||
$this->InitBrokenDictionnary($this->sDictionaryFolder, 'RU RU', 'ru-ru');
|
||||
$this->InitBrokenDictionnary($this->sDictionaryFolder, 'EN US', 'en-us');
|
||||
@@ -244,7 +259,8 @@ STR;
|
||||
$this->assertEquals('label1', Dict::S('label1'));
|
||||
}
|
||||
|
||||
public function testInitLangIfNeeded_ApcFromCache_PropertyInUserDictionnary(){
|
||||
public function testInitLangIfNeeded_ApcFromCache_PropertyInUserDictionnary()
|
||||
{
|
||||
$this->oApcService->expects($this->any())
|
||||
->method('function_exists')
|
||||
->willReturn(true);
|
||||
@@ -262,7 +278,8 @@ STR;
|
||||
$this->assertEquals('fr1', Dict::S('label1'));
|
||||
}
|
||||
|
||||
public function testInitLangIfNeeded_ApcStore_PropertyInUserDictionnary(){
|
||||
public function testInitLangIfNeeded_ApcStore_PropertyInUserDictionnary()
|
||||
{
|
||||
$this->oApcService->expects($this->any())
|
||||
->method('function_exists')
|
||||
->willReturn(true);
|
||||
@@ -341,7 +358,8 @@ STR;
|
||||
$this->assertEquals('en2', Dict::S('label2'));
|
||||
}
|
||||
|
||||
public function testInitLangIfNeeded_Apc_PropertyInDictDefaultLanguageDictionnary(){
|
||||
public function testInitLangIfNeeded_Apc_PropertyInDictDefaultLanguageDictionnary()
|
||||
{
|
||||
$this->oApcService->expects($this->any())
|
||||
->method('function_exists')
|
||||
->willReturn(true);
|
||||
@@ -362,7 +380,8 @@ STR;
|
||||
$this->assertEquals('en3', Dict::S('label3'));
|
||||
}
|
||||
|
||||
public function testInitLangIfNeeded_ApcCorrupted_PropertyInDictDefaultLanguageDictionnary(){
|
||||
public function testInitLangIfNeeded_ApcCorrupted_PropertyInDictDefaultLanguageDictionnary()
|
||||
{
|
||||
$this->oApcService->expects($this->any())
|
||||
->method('function_exists')
|
||||
->willReturn(true);
|
||||
@@ -380,7 +399,8 @@ STR;
|
||||
$this->assertEquals('label3', Dict::S('label3'));
|
||||
}
|
||||
|
||||
public function testInitLangIfNeeded_Apc_PropertyNotFound(){
|
||||
public function testInitLangIfNeeded_Apc_PropertyNotFound()
|
||||
{
|
||||
$this->oApcService->expects($this->any())
|
||||
->method('function_exists')
|
||||
->willReturn(true);
|
||||
|
||||
@@ -30,9 +30,6 @@ use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use Dict;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @runClassInSeparateProcess
|
||||
*/
|
||||
class dictTest extends ItopTestCase
|
||||
{
|
||||
private $sEnvName;
|
||||
@@ -42,7 +39,9 @@ class dictTest extends ItopTestCase
|
||||
|
||||
$this->RequireOnceItopFile('core'.DIRECTORY_SEPARATOR.'apc-service.class.inc.php');
|
||||
|
||||
$this->sEnvName = time();
|
||||
// This id will be used as path to the dictionary files
|
||||
// It must be unique enough for the magic of Dict to operate (due to the use of require_once to load dictionaries)
|
||||
$this->sEnvName = uniqid();
|
||||
$sDictionaryFolder = APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries";
|
||||
@mkdir($sDictionaryFolder, 0777, true);
|
||||
|
||||
@@ -68,6 +67,9 @@ PHP;
|
||||
file_put_contents($sDictionaryFolder.DIRECTORY_SEPARATOR."en-en.dict.php", $sContent);
|
||||
|
||||
$_SESSION['itop_env'] = $this->sEnvName;
|
||||
|
||||
// Preserve the dictionary for test that will be executed later on
|
||||
static::BackupStaticProperties('Dict');
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
@@ -78,6 +80,8 @@ PHP;
|
||||
rmdir(APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries");
|
||||
rmdir(APPROOT."env-$this->sEnvName");
|
||||
|
||||
static::RestoreStaticProperties('Dict');
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
@@ -93,6 +97,9 @@ PHP;
|
||||
|
||||
public function testInitLangIfNeeded_NoApc()
|
||||
{
|
||||
// Reset the dictionary
|
||||
static::SetNonPublicStaticProperty('Dict', 'm_aData', []);
|
||||
|
||||
$oApcService = $this->createMock(\ApcService::class);
|
||||
Dict::SetApcService($oApcService);
|
||||
Dict::EnableCache('toto');
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use Expression;
|
||||
|
||||
class ExpressionTranslateTest extends ItopDataTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider TranslationsProvider
|
||||
* @param $sExpressionBefore
|
||||
* @param $sTranslationMap
|
||||
* @param $sExpressionAfter
|
||||
**/
|
||||
public function testTranslate($sExpressionBefore, $sTranslationMap, $sExpressionAfter)
|
||||
{
|
||||
$oExpressionBefore = Expression::FromOQL($sExpressionBefore);
|
||||
$aTranslationMap = eval('return '.$sTranslationMap.';');
|
||||
$oExpressionAfter = $oExpressionBefore->Translate($aTranslationMap);
|
||||
static::assertEquals($sExpressionAfter, $oExpressionAfter->RenderExpression());
|
||||
}
|
||||
|
||||
public function TranslationsProvider()
|
||||
{
|
||||
return [
|
||||
'simplest illustration of the concept: field translated into a scalar' => [
|
||||
'before' => "alias1.column1",
|
||||
'map' => "['alias1' => ['column1' => new \ScalarExpression('hello')]]",
|
||||
'after' => "'hello'"
|
||||
],
|
||||
'field translated wherever it is in the expression tree' => [
|
||||
'before' => "1 + (2 * (3 / (4 - (5 + FLOOR(alias1.column1)))))",
|
||||
'map' => "['alias1' => ['column1' => new \ScalarExpression('hello')]]",
|
||||
'after' => "(1 + (2 * (3 / (4 - (5 + FLOOR('hello'))))))"
|
||||
],
|
||||
'each and every occurrences of a field are translated' => [
|
||||
'before' => "CONCAT(alias1.column1, alias1.column1)",
|
||||
'map' => "['alias1' => ['column1' => new \ScalarExpression('hello')]]",
|
||||
'after' => "CONCAT('hello', 'hello')"
|
||||
],
|
||||
'field translated into a complex expression (decomposition)' => [
|
||||
'before' => "alias1.column1",
|
||||
'map' => "['alias1' => ['column1' => \Expression::FromOQL(\"CONCAT(person.first_name, ' ', contact.name)\")]]",
|
||||
'after' => "CONCAT(`person`.`first_name`, ' ', `contact`.`name`)"
|
||||
],
|
||||
'translate several fields at once' => [
|
||||
'before' => "CONCAT(`person`.`first_name`, ' ', `contact`.`name`)",
|
||||
'map' => "['person' => ['*' => 'table_person'], 'contact' => ['*' => 'table_contact']]",
|
||||
'after' => "CONCAT(`table_person`.`first_name`, ' ', `table_contact`.`name`)"
|
||||
],
|
||||
'translation is done once and only once' => [
|
||||
'before' => "alias1.column1",
|
||||
'map' => "['alias1' => ['column1' => \Expression::FromOQL('alias2.column1')], 'alias2' => ['column1' => new \ScalarExpression('translated again?')]]",
|
||||
'after' => "`alias2`.`column1`"
|
||||
],
|
||||
'translation of aliases, basic' => [
|
||||
'before' => "alias1.column1",
|
||||
'map' => "['alias1' => ['*' => 'A']]",
|
||||
'after' => "`A`.`column1`"
|
||||
],
|
||||
'translation of aliases, several hits and mappings' => [
|
||||
'before' => "CONCAT(alias1.column1, alias1.column2, alias2.column1)",
|
||||
'map' => "['alias1' => ['*' => 'A'], 'alias2' => ['*' => 'B']]",
|
||||
'after' => "CONCAT(`A`.`column1`, `A`.`column2`, `B`.`column1`)"
|
||||
],
|
||||
'nothing to change (+ map exceeds translation needs)' => [
|
||||
'before' => "CONCAT('hello', 1 + 2, :paramX)",
|
||||
'map' => "['alias1' => ['*' => 'alias2']]",
|
||||
'after' => "CONCAT('hello', (1 + 2), :paramX)"
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testTranslateFailsWhenSomeFieldsAreNotTranslated()
|
||||
{
|
||||
$oExpressionBefore = Expression::FromOQL('alias1.column1');
|
||||
$aTranslationMap = [];
|
||||
static::expectException(\CoreException::class);
|
||||
static::expectExceptionMessageMatches('/Unknown parent id in translation table/');
|
||||
$oExpressionAfter = $oExpressionBefore->Translate($aTranslationMap);
|
||||
}
|
||||
|
||||
public function testTranslateCanOptionalyIgnoreUntranslatedFields()
|
||||
{
|
||||
$oExpressionBefore = Expression::FromOQL('alias1.column1');
|
||||
$aTranslationMap = [];
|
||||
$oExpressionAfter = $oExpressionBefore->Translate($aTranslationMap, false);
|
||||
static::assertTrue(true); // No exception at that point, ok
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider TranslateMarksFieldsAsResolvedOrNotProvider
|
||||
* @param $sExpressionBefore
|
||||
* @param $sTranslationMap
|
||||
* @param $bMarkAsResolved
|
||||
* @param $sclassForExpressionAfter
|
||||
**/
|
||||
public function testTranslateMarksFieldsAsResolvedOrNot($sExpressionBefore, $sTranslationMap, $bMarkAsResolved, $sclassForExpressionAfter)
|
||||
{
|
||||
$oExpressionBefore = Expression::FromOQL($sExpressionBefore);
|
||||
$aTranslationMap = eval('return '.$sTranslationMap.';');
|
||||
$oExpressionAfter = $oExpressionBefore->Translate($aTranslationMap, true, $bMarkAsResolved);
|
||||
static::assertIsObject($oExpressionAfter);
|
||||
static::assertEquals($sclassForExpressionAfter, get_class($oExpressionAfter));
|
||||
}
|
||||
|
||||
|
||||
public function TranslateMarksFieldsAsResolvedOrNotProvider()
|
||||
{
|
||||
return [
|
||||
'Translation of class/table alias' => [
|
||||
'before' => "alias1.column1",
|
||||
'map' => "['alias1' => ['*' => 'alias2']]",
|
||||
'mark-as-resolved' => true,
|
||||
'class-for-expression-after' => "FieldExpressionResolved"
|
||||
],
|
||||
'Translation of class/table alias and opt-out on bMarkFieldsAsResolved' => [
|
||||
'before' => "alias1.column1",
|
||||
'map' => "['alias1' => ['*' => 'alias2']]",
|
||||
'mark-as-resolved' => false,
|
||||
'class-for-expression-after' => "FieldExpression"
|
||||
],
|
||||
'Decomposition of fields' => [
|
||||
'before' => "alias1.column1",
|
||||
'map' => "['alias1' => ['column1' => new \FieldExpression('col2', 'alias2')]]",
|
||||
'mark-as-resolved' => true,
|
||||
'class-for-expression-after' => "FieldExpression"
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,6 @@ use MetaModel;
|
||||
* Class BulkChangeExtKeyTest
|
||||
*
|
||||
* @package Combodo\iTop\Test\UnitTest\Core
|
||||
*
|
||||
* @runTestsInSeparateProcesses
|
||||
*/
|
||||
class BulkChangeExtKeyTest extends ItopDataTestCase {
|
||||
const CREATE_TEST_ORG = true;
|
||||
@@ -219,7 +217,7 @@ class BulkChangeExtKeyTest extends ItopDataTestCase {
|
||||
|
||||
private function GetUid(){
|
||||
if (is_null($this->sUid)){
|
||||
$this->sUid = date('dmYHis');
|
||||
$this->sUid = uniqid('test');
|
||||
}
|
||||
|
||||
return $this->sUid;
|
||||
|
||||
@@ -9,7 +9,6 @@ use SubMFCompiler;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* @runClassInSeparateProcess
|
||||
* @covers \MFCompiler::UseLatestPrecompiledFile
|
||||
*/
|
||||
class MFCompilerTest extends ItopTestCase {
|
||||
@@ -57,23 +56,25 @@ class MFCompilerTest extends ItopTestCase {
|
||||
|
||||
self::$aFoldersToCleanup = [ $sTempTargetDir, $sExtensionTargetDir, $sDatamodel2xTargetDir ];
|
||||
|
||||
// Sometime in the past
|
||||
$iTimeStart = time() - 100;
|
||||
|
||||
self::$aRessources['sPostCompilation1'] = tempnam($sTempTargetDir, $sPrefix);
|
||||
sleep(1);
|
||||
touch(self::$aRessources['sPostCompilation1'], $iTimeStart+=2);
|
||||
|
||||
//datamodel XML file in extension folder
|
||||
self::$aRessources['sPrecompiledInExtensionFile1'] = tempnam($sExtensionTargetDir, $sPrefix);
|
||||
touch(self::$aRessources['sPrecompiledInExtensionFile1'], $iTimeStart+=2);
|
||||
self::$aRessources['sPrecompiledInExtensionFileUri1'] = "UseLatestPrecompiledFileProvider" . DIRECTORY_SEPARATOR . basename(self::$aRessources['sPrecompiledInExtensionFile1']);
|
||||
|
||||
//datamodel XML file in source dir /datamodels/2.x folder
|
||||
self::$aRessources['sPrecompiledInDataModelXXFile1'] = tempnam($sDatamodel2xTargetDir, $sPrefix);
|
||||
touch(self::$aRessources['sPrecompiledInDataModelXXFile1'], $iTimeStart+=2);
|
||||
self::$aRessources['sPrecompiledInDataModelXXFileUri1'] = "UseLatestPrecompiledFileProvider" . DIRECTORY_SEPARATOR . basename(self::$aRessources['sPrecompiledInDataModelXXFile1']);
|
||||
|
||||
sleep(1);
|
||||
|
||||
|
||||
//generate ressources from a previous setup: called postcompiled
|
||||
self::$aRessources['sPostCompilation2'] = tempnam($sTempTargetDir, $sPrefix);
|
||||
sleep(1);
|
||||
touch(self::$aRessources['sPostCompilation2'], $iTimeStart+=2);
|
||||
|
||||
//simulate copy of /data/models.2.x or extensions ressources during setup in a temp directory
|
||||
self::$aRessources['sCopiedExtensionFile1'] = $sTempTargetDir . DIRECTORY_SEPARATOR . basename(self::$aRessources['sPrecompiledInExtensionFile1']);
|
||||
@@ -118,9 +119,8 @@ class MFCompilerTest extends ItopTestCase {
|
||||
* @param ?string $sExpectedReturn
|
||||
*/
|
||||
public function testUseLatestPrecompiledFile(string $sTempTargetDir, string $sPrecompiledFileUri, string $sPostCompilationLatestPrecompiledFile, string $sThemeDir, ?string $sExpectedReturn, bool $bDisableThemePrecompilationViaConf = false){
|
||||
if ($bDisableThemePrecompilationViaConf){
|
||||
utils::GetConfig()->Set('theme.enable_precompilation', false);
|
||||
}
|
||||
// Enable or disable precompilation depending on the test case
|
||||
utils::GetConfig()->Set('theme.enable_precompilation', !$bDisableThemePrecompilationViaConf);
|
||||
$sRes = $this->oMFCompiler->UseLatestPrecompiledFile($sTempTargetDir, $sPrecompiledFileUri, $sPostCompilationLatestPrecompiledFile, $sThemeDir);
|
||||
$this->assertEquals($sExpectedReturn, $sRes);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ class StatusIncTest extends ItopTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @runInSeparateProcess Required because Status constructor invokes MetaModel::Startup... which does nothing when already loaded
|
||||
*/
|
||||
public function testStatusStartupWrongDbPwd()
|
||||
{
|
||||
|
||||
@@ -18,14 +18,6 @@ class StatusTest extends ItopTestCase
|
||||
require_once APPROOT.'core/config.class.inc.php'; // for constants
|
||||
}
|
||||
|
||||
public function testStatusWrongUrl() {
|
||||
$sPath = APPROOT.'/status_wrong.php';
|
||||
|
||||
exec("php $sPath", $aOutput, $iRet);
|
||||
$this->assertNotEquals(0, $iRet, "Problem executing status page: $sPath, $iRet, aOutput:\n" . var_export($aOutput, true));
|
||||
|
||||
}
|
||||
|
||||
protected function GetPHPCommand()
|
||||
{
|
||||
$this->RequireOnceItopFile('application/utils.inc.php');
|
||||
@@ -33,23 +25,14 @@ class StatusTest extends ItopTestCase
|
||||
return $oConfig->Get('php_path');
|
||||
}
|
||||
|
||||
public function testStatusGood() {
|
||||
$sPath = APPROOT.'/webservices/status.php';
|
||||
|
||||
$sPHP = $this->GetPHPCommand();
|
||||
exec("$sPHP $sPath", $aOutput, $iRet);
|
||||
$this->assertEquals(0, $iRet, "Problem executing status page: $sPath, $iRet, aOutput:\n".var_export($aOutput, true));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function testStatusGoodWithJson()
|
||||
public function testStatusPageRepliesAsExpected()
|
||||
{
|
||||
$sPath = APPROOT.'/webservices/status.php';
|
||||
|
||||
$sPHP = $this->GetPHPCommand();
|
||||
exec("$sPHP $sPath", $aOutput, $iRet);
|
||||
$this->assertEquals(0, $iRet, "Problem executing status page: $sPath, $iRet, aOutput:\n".var_export($aOutput, true));
|
||||
|
||||
$sAdditionalInfo = "aOutput:\n".var_export($aOutput, true).'.';
|
||||
|
||||
//Check response
|
||||
|
||||
@@ -28,6 +28,10 @@ class RouterTest extends ItopDataTestCase
|
||||
parent::setUp();
|
||||
|
||||
$this->RequireOnceItopFile('setup/setuputils.class.inc.php');
|
||||
|
||||
// Speedup test by forcing the use of the cache, even on a development environment
|
||||
$oRouter = Router::GetInstance();
|
||||
$oRouter->SetUseCache(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,12 +207,9 @@ class RouterTest extends ItopDataTestCase
|
||||
$this->fail("Cache file was not generated ($sRoutesCacheFilePath)");
|
||||
}
|
||||
|
||||
clearstatcache();
|
||||
$iFirstModificationTimestamp = filemtime($sRoutesCacheFilePath);
|
||||
$this->debug("Initial timestamp: $iFirstModificationTimestamp");
|
||||
|
||||
// Wait for just 1s to ensure timestamps would be different is the file is re-generated
|
||||
sleep(1);
|
||||
// Set its modification date in the past so that regenerating it will result in a new modification date without any doubt
|
||||
$iFirstModificationTimestamp = time() - 2;
|
||||
touch($sRoutesCacheFilePath, $iFirstModificationTimestamp);
|
||||
|
||||
// Call GetRoutes() again to see if cache gets re-generated or not
|
||||
$this->InvokeNonPublicMethod(Router::class, 'GetRoutes', $oRouter, []);
|
||||
|
||||
@@ -12,9 +12,6 @@ use Combodo\iTop\Service\TemporaryObjects\TemporaryObjectManager;
|
||||
use Combodo\iTop\Service\TemporaryObjects\TemporaryObjectRepository;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
|
||||
/**
|
||||
* @runTestsInSeparateProcesses
|
||||
*/
|
||||
class TemporaryObjectManagerTest extends ItopDataTestCase
|
||||
{
|
||||
const USE_TRANSACTION = true;
|
||||
|
||||
@@ -13,9 +13,6 @@ use Combodo\iTop\Service\TemporaryObjects\TemporaryObjectRepository;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use DBObject;
|
||||
|
||||
/**
|
||||
* @runTestsInSeparateProcesses
|
||||
*/
|
||||
class TemporaryObjectRepositoryTest extends ItopDataTestCase
|
||||
{
|
||||
const USE_TRANSACTION = true;
|
||||
|
||||
@@ -8,9 +8,6 @@ use Exception;
|
||||
use MetaModel;
|
||||
|
||||
|
||||
/**
|
||||
* @runTestsInSeparateProcesses
|
||||
*/
|
||||
class CliResetSessionTest extends ItopDataTestCase
|
||||
{
|
||||
const USE_TRANSACTION = false;
|
||||
|
||||
@@ -12,8 +12,6 @@ use utils;
|
||||
* @group itopRequestMgmt
|
||||
* @group restApi
|
||||
* @group defaultProfiles
|
||||
*
|
||||
* @runClassInSeparateProcess
|
||||
*/
|
||||
class RestTest extends ItopDataTestCase
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user