mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-22 00:32:16 +02:00
Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop
This commit is contained in:
@@ -1695,7 +1695,7 @@ JS
|
|||||||
$sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue);
|
$sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue);
|
||||||
$iTotalCount += $aRow['_itop_count_'];
|
$iTotalCount += $aRow['_itop_count_'];
|
||||||
$aValues[] = array(
|
$aValues[] = array(
|
||||||
'label' => html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8'),
|
'label' => $sValue,
|
||||||
'label_html' => $sHtmlValue,
|
'label_html' => $sHtmlValue,
|
||||||
'value' => (float)$aRow[$sFctVar],
|
'value' => (float)$aRow[$sFctVar],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
"sempro/phpunit-pretty-print": "^1.4"
|
"sempro/phpunit-pretty-print": "^1.4"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
"classmap": [
|
||||||
|
"unitary-tests/"
|
||||||
|
],
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Combodo\\iTop\\Test\\UnitTest\\": "src/BaseTestCase/",
|
"Combodo\\iTop\\Test\\UnitTest\\": "src/BaseTestCase/",
|
||||||
"Combodo\\iTop\\Test\\UnitTest\\Hook\\": "src/Hook/",
|
"Combodo\\iTop\\Test\\UnitTest\\Hook\\": "src/Hook/",
|
||||||
|
|||||||
@@ -9,9 +9,11 @@ namespace Combodo\iTop\Test\UnitTest\Service;
|
|||||||
|
|
||||||
use Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase;
|
use Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase;
|
||||||
use IssueLog;
|
use IssueLog;
|
||||||
|
use LogChannels;
|
||||||
use MFCoreModule;
|
use MFCoreModule;
|
||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
use RunTimeEnvironment;
|
use RunTimeEnvironment;
|
||||||
|
use utils;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,12 +35,15 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment
|
|||||||
|
|
||||||
/** @var string[] $aDeltaFiles Referential of loaded deltas. Mostly to avoid duplicates. */
|
/** @var string[] $aDeltaFiles Referential of loaded deltas. Mostly to avoid duplicates. */
|
||||||
$aDeltaFiles = [];
|
$aDeltaFiles = [];
|
||||||
foreach (get_declared_classes() as $sClass) {
|
$aRelatedClasses = $this->GetClassesExtending(
|
||||||
// Filter on classes derived from this \Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCaseItopCustomDatamodelTestCase
|
ItopCustomDatamodelTestCase::class,
|
||||||
if (false === is_a($sClass, ItopCustomDatamodelTestCase::class, true)) {
|
array(
|
||||||
continue;
|
'[\\\\/]tests[\\\\/]php-unit-tests[\\\\/]vendor[\\\\/]',
|
||||||
}
|
'[\\\\/]tests[\\\\/]php-unit-tests[\\\\/]unitary-tests[\\\\/]datamodels[\\\\/]2.x[\\\\/]authent-local',
|
||||||
|
));
|
||||||
|
//Combodo\iTop\Test\UnitTest\Application\ApplicationExtensionTest
|
||||||
|
//Combodo\iTop\Test\UnitTest\Application\ApplicationExtensionTest
|
||||||
|
foreach ($aRelatedClasses as $sClass) {
|
||||||
$oReflectionClass = new ReflectionClass($sClass);
|
$oReflectionClass = new ReflectionClass($sClass);
|
||||||
$oReflectionMethod = $oReflectionClass->getMethod('GetDatamodelDeltaAbsPath');
|
$oReflectionMethod = $oReflectionClass->getMethod('GetDatamodelDeltaAbsPath');
|
||||||
|
|
||||||
@@ -83,4 +88,50 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment
|
|||||||
return $aRet;
|
return $aRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function GetClassesExtending (string $sExtendedClass, array $aExcludedPath = []) : array {
|
||||||
|
$aMatchingClasses = [];
|
||||||
|
|
||||||
|
$aAutoloadClassMaps =[__DIR__."/../../vendor/composer/autoload_classmap.php"];
|
||||||
|
|
||||||
|
$aClassMap = [];
|
||||||
|
$aAutoloaderErrors = [];
|
||||||
|
foreach ($aAutoloadClassMaps as $sAutoloadFile) {
|
||||||
|
$aTmpClassMap = include $sAutoloadFile;
|
||||||
|
/** @noinspection SlowArrayOperationsInLoopInspection we are getting an associative array so the documented workarounds cannot be used */
|
||||||
|
$aClassMap = array_merge($aClassMap, $aTmpClassMap);
|
||||||
|
}
|
||||||
|
foreach ($aClassMap as $sPHPClass => $sPHPFile) {
|
||||||
|
$bSkipped = false;
|
||||||
|
if (utils::IsNotNullOrEmptyString($sPHPFile)) {
|
||||||
|
$sPHPFile = utils::LocalPath($sPHPFile);
|
||||||
|
if ($sPHPFile !== false) {
|
||||||
|
$sPHPFile = '/'.$sPHPFile; // for regex
|
||||||
|
foreach ($aExcludedPath as $sExcludedPath) {
|
||||||
|
// Note: We use '#' as delimiters as usual '/' is often used in paths.
|
||||||
|
if ($sExcludedPath !== '' && preg_match('#'.$sExcludedPath.'#', $sPHPFile) === 1) {
|
||||||
|
$bSkipped = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$bSkipped = true; // file not found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$bSkipped) {
|
||||||
|
try {
|
||||||
|
$oRefClass = new ReflectionClass($sPHPClass);
|
||||||
|
if ($oRefClass->isSubclassOf($sExtendedClass) &&
|
||||||
|
!$oRefClass->isInterface() && !$oRefClass->isAbstract() && !$oRefClass->isTrait()) {
|
||||||
|
$aMatchingClasses[] = $sPHPClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $aMatchingClasses;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0">
|
||||||
|
<classes>
|
||||||
|
<class id="UserRequest">
|
||||||
|
<fields>
|
||||||
|
<field id="status" xsi:type="AttributeEnum">
|
||||||
|
<always_load_in_tables>true</always_load_in_tables>
|
||||||
|
<sort_type>rank</sort_type>
|
||||||
|
<values>
|
||||||
|
<value id="New_org_name_with_quote" _delta="define">
|
||||||
|
<code>New'status</code>
|
||||||
|
<rank>32</rank>
|
||||||
|
</value>
|
||||||
|
</values>
|
||||||
|
</field>
|
||||||
|
</fields>
|
||||||
|
</class>
|
||||||
|
</classes>
|
||||||
|
</itop_design>
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* @copyright Copyright (C) 2010-2024 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Test\UnitTest\Application;
|
||||||
|
|
||||||
|
use Combodo\iTop\Application\UI\DisplayBlock\BlockChartAjaxPie\BlockChartAjaxPie;
|
||||||
|
use Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase;
|
||||||
|
use DBSearch;
|
||||||
|
use DisplayBlock;
|
||||||
|
use MetaModel;
|
||||||
|
use UserRequest;
|
||||||
|
|
||||||
|
class DisplayBlockTest extends ItopCustomDatamodelTestCase
|
||||||
|
{
|
||||||
|
const CREATE_TEST_ORG = true;
|
||||||
|
public function GetDatamodelDeltaAbsPath(): string
|
||||||
|
{
|
||||||
|
return __DIR__ . '/Delta/add-enum-value-with-quote.xml';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderChartAjaxProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'simple string : name' => [ // chart with UserRequest title (evaluating string/scalar escaping)
|
||||||
|
'class to display' => 'UserRequest',
|
||||||
|
'class attribute to display' => 'title',
|
||||||
|
'class to edit' => 'UserRequest',
|
||||||
|
'related class attribute to edit' => 'title',
|
||||||
|
'expected' => "New'name",
|
||||||
|
'nonExpected' => 'New'name',
|
||||||
|
],
|
||||||
|
'enum : status' => [ // chart with UserRequest status (evaluating enum escaping)
|
||||||
|
// not working because we need to allow a new value for the enum
|
||||||
|
'class to display' => 'UserRequest',
|
||||||
|
'attribute to display' => 'status',
|
||||||
|
'class to edit' => 'UserRequest',
|
||||||
|
'related class attribute to edit' => 'status',
|
||||||
|
'expected' => "New'status",
|
||||||
|
'nonExpected' => 'New'status',
|
||||||
|
],
|
||||||
|
'relation : Org name' => [ // chart with related organization name title (evaluating ext key escaping)
|
||||||
|
'class to display' => 'UserRequest',
|
||||||
|
'class attribute to display' => 'org_name',
|
||||||
|
'class to edit' => 'Organization',
|
||||||
|
'related class attribute to edit' => 'name',
|
||||||
|
'expected' => "New'org_name",
|
||||||
|
'nonExpected' => 'New'org_name',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider renderChartAjaxProvider
|
||||||
|
*/
|
||||||
|
public function testRenderChartAjax(string $sClassToDisplay, string $sAttributeToDisplay, string $sRelatedClass, string $sRelatedClassAttributeToEdit, string $sExpected, string $sNonExpected): void
|
||||||
|
{
|
||||||
|
$oUserRequest = new UserRequest();
|
||||||
|
$oUserRequest->Set('title', 'MyTitle');
|
||||||
|
$oUserRequest->Set('org_id', $this->getTestOrgId());
|
||||||
|
$oUserRequest->Set('description', "MyDescription");
|
||||||
|
$oUserRequest->DBInsert();
|
||||||
|
|
||||||
|
if ($sRelatedClass !== "UserRequest") {
|
||||||
|
$oInstanceRelatedClass = MetaModel::GetObject($sRelatedClass, $this->getTestOrgId());
|
||||||
|
} else {
|
||||||
|
$oInstanceRelatedClass = $oUserRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
$oInstanceRelatedClass->Set($sRelatedClassAttributeToEdit, $sExpected); // attribute that shouldn't be encoded
|
||||||
|
$oInstanceRelatedClass->DBUpdate();
|
||||||
|
|
||||||
|
$oDisplayBlock = new DisplayBlock(
|
||||||
|
DBSearch::FromOQL("SELECT $sClassToDisplay"),
|
||||||
|
DisplayBlock::ENUM_STYLE_CHART_AJAX
|
||||||
|
);
|
||||||
|
|
||||||
|
$aExtraParams = [
|
||||||
|
"group_by" => $sAttributeToDisplay,
|
||||||
|
"currentId" => "fake-dashlet-id",
|
||||||
|
"order_direction" => "asc",
|
||||||
|
"order_by" => $sAttributeToDisplay,
|
||||||
|
"limit" => 10,
|
||||||
|
];
|
||||||
|
/** @var BlockChartAjaxPie $oBlock */
|
||||||
|
$oBlock = $this->InvokeNonPublicMethod(get_class($oDisplayBlock), "RenderChartAjax", $oDisplayBlock, [$aExtraParams]);
|
||||||
|
|
||||||
|
$aJSNames = json_decode($oBlock->sJSNames, true);
|
||||||
|
|
||||||
|
$this->assertFalse(in_array($sNonExpected, $aJSNames));
|
||||||
|
$this->assertTrue(in_array($sExpected, $aJSNames));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -292,6 +292,7 @@ class ExampleFor_iQueryModifier implements \iQueryModifier
|
|||||||
public function GetFieldExpression(QueryBuilderContext &$oBuild, $sClass, $sAttCode, $sColId, Expression $oFieldSQLExp, SQLQuery &$oSelect)
|
public function GetFieldExpression(QueryBuilderContext &$oBuild, $sClass, $sAttCode, $sColId, Expression $oFieldSQLExp, SQLQuery &$oSelect)
|
||||||
{
|
{
|
||||||
// Do nothing, we just need the class to exists for the unit test
|
// Do nothing, we just need the class to exists for the unit test
|
||||||
|
return $oFieldSQLExp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]></content>
|
]]></content>
|
||||||
|
|||||||
Reference in New Issue
Block a user