Merge remote-tracking branch 'origin/support/3.2' into develop

This commit is contained in:
Molkobain
2024-07-24 10:58:05 +02:00
368 changed files with 2676 additions and 12099 deletions

View File

@@ -501,4 +501,26 @@ abstract class ItopTestCase extends TestCase
}
closedir($dir);
}
/**
* An alternative to assertEquals in case the order of the elements in the array is not important
*
* @since 3.2.0
*/
protected function AssertArraysHaveSameItems(array $aExpectedClasses, array $aClasses, string $sMessage = ''): void
{
sort($aClasses);
sort($aExpectedClasses);
$sExpected = implode("\n", $aExpectedClasses);
$sActual = implode("\n", $aClasses);
if ($sExpected === $sActual) {
$this->assertTrue(true);
return;
}
$sMessage .= "\nExpected:\n$sExpected\nActual:\n$sActual";
var_export($aClasses);
$this->fail($sMessage);
}
}

View File

@@ -6,6 +6,8 @@
namespace Combodo\iTop\Test\UnitTest\Application;
use Combodo\iTop\Application\UI\Base\iUIBlockFactory;
use Combodo\iTop\Service\InterfaceDiscovery\InterfaceDiscovery;
use Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase;
use MetaModel;
use utils;
@@ -44,7 +46,7 @@ class ApplicationExtensionTest extends ItopCustomDatamodelTestCase
if ($sCallMethod === static::ENUM_API_CALL_METHOD_ENUMPLUGINS) {
$iExtendingClassesCount = count(MetaModel::EnumPlugins($sAPIFQCN));
} else {
$iExtendingClassesCount = count(utils::GetClassesForInterface($sAPIFQCN, '', ['[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]', '[\\\\/]tests[\\\\/]']));
$iExtendingClassesCount = count(InterfaceDiscovery::GetInstance()->FindItopClasses($sAPIFQCN));
}
$this->assertGreaterThan(0, $iExtendingClassesCount, "Found no class extending the $sAPIFQCN API");
}

View File

@@ -219,14 +219,18 @@ HTML
'simple-body-with-placeholder' => [
'EN US',
['body' => '<p>Ticket "$this->title$" created.</p>'],
['body' => '<p>Ticket "Test UserRequest" created.</p>'],
['body' => '<div class="email-is-html-content">
<p>Ticket "Test UserRequest" created.</p>
</div>'],
],
'simple-body-with-placeholder-TEST-mode' => [
'EN US',
['body' => '<p>Ticket "$this->title$" created.</p>', 'status' => 'test'],
['body' =>
<<<HTML
<p>Ticket "Test UserRequest" created.</p><div style="border: dashed;">
<div class="email-is-html-content">
<p>Ticket "Test UserRequest" created.</p>
</div><div style="border: dashed;">
<h1>Testing email notification <span class="object-ref " title="****"><a class="object-ref-link" href="****">Test action</a></span></h1>
<p>The email should be sent with the following properties
<ul>
@@ -260,7 +264,9 @@ HTML
<body>
<table data-something-that-would-be-removed-by-the-sanitizer-through-ckeditor-but-that-will-stay-with-the-template="bar">
<tr><td>Formatted eMail</td></tr>
<tr><td><p>Ticket "Test UserRequest" created.</p></td></tr>
<tr><td><div class="email-is-html-content">
<p>Ticket "Test UserRequest" created.</p>
</div></td></tr>
</body>
HTML
],

View File

@@ -241,4 +241,30 @@ SQL
$this->assertEquals('from table 2', $sFromTable2Data, "Data was not moved as expected");
}
/**
* Test that the table has been renamed
*
* @covers ModuleInstallerAPI::RenameTableInDB
*
* @return void
* @throws \CoreException
* @throws \MySQLException
*/
public function testRenameTableInDB()
{
$sOrigTable = MetaModel::DBGetTable('Person');
$aOrigTableInfo = CMDBSource::GetTableInfo($sOrigTable);
$this->assertNotEmpty($aOrigTableInfo, 'Origin table does not exist');
$sDstTable = static::$sWorkTable;
$this->assertFalse(CMDBSource::IsTable($sDstTable), 'Work table already exists');
ModuleInstallerAPI::RenameTableInDB($sOrigTable, $sDstTable);
$this->assertEquals($aOrigTableInfo, CMDBSource::GetTableInfo($sDstTable), 'Table was not renamed');
// Revert
ModuleInstallerAPI::RenameTableInDB($sDstTable, $sOrigTable);
$this->assertEquals($aOrigTableInfo, CMDBSource::GetTableInfo($sOrigTable));
}
}

View File

@@ -32,4 +32,318 @@ class CKEditorHelperTest extends ItopTestCase
'GetJSFilesRelPathsForCKEditor' => ['GetJSFilesRelPathsForCKEditor'],
];
}
/**
* @dataProvider DOMSanitizerForCKEditorProvider
*
* @param $aSanitizerConfiguration
* @param $aExpectedCKEditorConfiguration
*
* @return void
* @throws \ConfigException
* @throws \CoreException
*/
public function testDOMSanitizerForCKEditor($aSanitizerConfiguration, $aExpectedCKEditorConfiguration)
{
$oSanitizer = new TestDOMSanitizer();
$oSanitizer->SetTagsWhiteList($aSanitizerConfiguration['tagsWhiteList']);
$oSanitizer->SetAttrsWhiteList($aSanitizerConfiguration['attrsWhiteList']);
$oSanitizer->SetStylesWhiteList($aSanitizerConfiguration['stylesWhiteList']);
$oSanitizer->SetTagsBlackList($aSanitizerConfiguration['tagsBlackList']);
$oSanitizer->SetAttrsBlackList($aSanitizerConfiguration['attrsBlackList']);
$aCKEditorConfiguration = CKEditorHelper::GetDOMSanitizerForCKEditor($oSanitizer);
$this->assertEquals($aExpectedCKEditorConfiguration, $aCKEditorConfiguration);
}
public function DOMSanitizerForCKEditorProvider(): array
{
return [
'Allow list small dataset' => [
[
'tagsWhiteList' => [
'html' => array(),
'p' => array('style', 'class'),
'a' => array('href', 'name'),
],
'attrsWhiteList' => [
'href' => '/^(https:)/i'
],
'stylesWhiteList' => [
'color',
'font-size'
],
'tagsBlackList' => [],
'attrsBlackList' => [],
],
[
'allow' => [
[
'name' => 'html',
'attributes' => false,
'classes' => false,
'styles' => false
],
[
'name' => 'p',
'attributes' => false,
'classes' => true,
'styles' => [
'color' => true,
'font-size' => true
]
],
[
'name' => 'a',
'attributes' => [
'href' => [
'pattern' => '/^(https:)/i'
],
'name' => true
],
'classes' => false,
'styles' => false
]
],
'disallow' => []
]
],
'Allow list medium dataset' => [
[
'tagsWhiteList' => [
'h1' => array('style', 'class'),
'h2' => array('style', 'class'),
'h3' => array('style', 'class'),
'h4' => array('style', 'class'),
'table' => array('style', 'class', 'width', 'summary', 'align', 'border', 'cellpadding', 'cellspacing', 'style'),
'tr' => array('style', 'class', 'align', 'valign', 'bgcolor', 'style'),
'ul' => array(),
'ol' => array(),
],
'attrsWhiteList' => [
'href' => '/^(https:)/i',
'src' => '/^(https:)/i',
'width' => '/^([0-9]+(px|em|%)?)$/i',
'height' => '/^([0-9]+(px|em|%)?)$/i',
'align' => '/^(left|right|center|justify)$/i',
'valign' => '/^(top|middle|bottom)$/i',
'bgcolor' => '/^#[0-9a-f]{6}$/i',
],
'stylesWhiteList' => [
'color',
'float',
'font',
'font-family',
'font-size',
'font-style',
'height',
'margin',
'padding',
'text-align',
'vertical-align',
'width',
'white-space',
],
'tagsBlackList' => [],
'attrsBlackList' => [],
],
[
'allow' => [
[
'name' => 'h1',
'attributes' => false,
'classes' => true,
'styles' => [
'color' => true,
'font' => true,
'font-family' => true,
'font-size' => true,
'font-style' => true,
'height' => true,
'margin' => true,
'padding' => true,
'text-align' => true,
'vertical-align' => true,
'width' => true,
'white-space' => true,
'float' => true
]
],
[
'name' => 'h2',
'attributes' => false,
'classes' => true,
'styles' => [
'color' => true,
'font' => true,
'font-family' => true,
'font-size' => true,
'font-style' => true,
'height' => true,
'margin' => true,
'padding' => true,
'text-align' => true,
'vertical-align' => true,
'width' => true,
'white-space' => true,
'float' => true
]
],
[
'name' => 'h3',
'attributes' => false,
'classes' => true,
'styles' => [
'color' => true,
'font' => true,
'font-family' => true,
'font-size' => true,
'font-style' => true,
'height' => true,
'margin' => true,
'padding' => true,
'text-align' => true,
'vertical-align' => true,
'width' => true,
'white-space' => true,
'float' => true
]
],
[
'name' => 'h4',
'attributes' => false,
'classes' => true,
'styles' => [
'color' => true,
'font' => true,
'font-family' => true,
'font-size' => true,
'font-style' => true,
'height' => true,
'margin' => true,
'padding' => true,
'text-align' => true,
'vertical-align' => true,
'width' => true,
'white-space' => true,
'float' => true
]
],
[
'name' => 'table',
'attributes' => [
'width' => [
'pattern' => '/^([0-9]+(px|em|%)?)$/i'
],
'summary' => true,
'align' => [
'pattern' => '/^(left|right|center|justify)$/i'
],
'border' => true,
'cellpadding' => true,
'cellspacing' => true,
],
'classes' => true,
'styles' => [
'color' => true,
'font' => true,
'font-family' => true,
'font-size' => true,
'font-style' => true,
'height' => true,
'margin' => true,
'padding' => true,
'text-align' => true,
'vertical-align' => true,
'width' => true,
'white-space' => true,
'float' => true
]
],
[
'name' => 'tr',
'attributes' => [
'align' => [
'pattern' => '/^(left|right|center|justify)$/i'
],
'valign' => [
'pattern' => '/^(top|middle|bottom)$/i'
],
'bgcolor' => [
'pattern' => '/^#[0-9a-f]{6}$/i'
]
],
'classes' => true,
'styles' => [
'color' => true,
'font' => true,
'font-family' => true,
'font-size' => true,
'font-style' => true,
'height' => true,
'margin' => true,
'padding' => true,
'text-align' => true,
'vertical-align' => true,
'width' => true,
'white-space' => true,
'float' => true
]
],
[
'name' => 'ul',
'attributes' => false,
'classes' => false,
'styles' => false
],
[
'name' => 'ol',
'attributes' => false,
'classes' => false,
'styles' => false
]
],
'disallow' => []
]
],
'Disallow list small dataset' => [
[
'tagsWhiteList' => [],
'attrsWhiteList' => [],
'stylesWhiteList' => [],
'tagsBlackList' => [
'html',
'p',
'a',
],
'attrsBlackList' => [
'href',
],
],
[
'allow' => [],
'disallow' => [
[
'name' => 'html',
'attributes' => [
'href' => true
],
],
[
'name' => 'p',
'attributes' => [
'href' => true
],
],
[
'name' => 'a',
'attributes' => [
'href' => true
],
]
]
]
]
];
}
}

View File

@@ -0,0 +1,76 @@
<?php
namespace Combodo\iTop\Test\UnitTest\Application\Helper;
use DOMSanitizer;
class TestDOMSanitizer extends DOMSanitizer
{
protected static array $aTagsWhiteList = [];
private static $aStylesWhiteList = [];
private static $aAttrsWhiteList = [];
protected static array $aTagsBlackList = [];
private static $aAttrsBlackList = [];
public function GetTagsWhiteList()
{
return static::$aTagsWhiteList;
}
public function GetTagsBlackList()
{
return static::$aTagsBlackList;
}
public function GetAttrsWhiteList()
{
return static::$aAttrsWhiteList;
}
public function GetAttrsBlackList()
{
return static::$aAttrsBlackList;
}
public function GetStylesWhiteList()
{
return static::$aStylesWhiteList;
}
public function SetTagsWhiteList(array $aTagsWhiteList)
{
static::$aTagsWhiteList = $aTagsWhiteList;
}
public function SetAttrsWhiteList(array $aAttrsWhiteList)
{
static::$aAttrsWhiteList = $aAttrsWhiteList;
}
public function SetStylesWhiteList(array $aStylesWhiteList)
{
static::$aStylesWhiteList = $aStylesWhiteList;
}
public function SetTagsBlackList(array $aTagsBlackList)
{
static::$aTagsBlackList = $aTagsBlackList;
}
public function SetAttrsBlackList(array $aAttrsBlackList)
{
static::$aAttrsBlackList = $aAttrsBlackList;
}
public function LoadDoc($sHTML)
{
// TODO: Implement LoadDoc() method.
}
public function PrintDoc()
{
// TODO: Implement PrintDoc() method.
}
}

View File

@@ -39,7 +39,7 @@ class iTopComposerTest extends ItopTestCase
*/
public function testIsQuestionnableFolder($sDirName, $bIsTest)
{
$isTestDir = iTopComposer::IsQuestionnableFolder($sDirName);
$isTestDir = iTopComposer::IsQuestionnableFile($sDirName);
$this->assertIsInt($isTestDir);
if (true === $bIsTest) {
$this->assertTrue(($isTestDir > 0));
@@ -65,13 +65,13 @@ class iTopComposerTest extends ItopTestCase
public function testListAllFoldersAbsPaths()
{
$oiTopComposer = new iTopComposer();
$aDirs = $oiTopComposer->ListAllFoldersAbsPaths();
$aDirs = $oiTopComposer->ListAllFilesAbsPaths();
$this->assertTrue(is_array($aDirs));
foreach ($aDirs as $sDir) {
$sDirName = basename($sDir);
$this->assertMatchesRegularExpression(iTopComposer::QUESTIONNABLE_FOLDER_REGEXP, $sDirName, "Directory not matching test dir : $sDir");
$this->assertMatchesRegularExpression(iTopComposer::QUESTIONNABLE_FILES_REGEXP, $sDirName, "Directory not matching test dir : $sDir");
}
}
@@ -79,13 +79,13 @@ class iTopComposerTest extends ItopTestCase
public function testListDeniedFolderAbsPaths()
{
$oiTopComposer = new iTopComposer();
$aDirs = $oiTopComposer->ListDeniedFoldersAbsPaths();
$aDirs = $oiTopComposer->ListDeniedFilesAbsPaths();
$this->assertTrue(is_array($aDirs));
$aDeniedDirWrongFormat = [];
foreach ($aDirs as $sDir) {
if (false === iTopComposer::IsQuestionnableFolder($sDir)) {
if (false === iTopComposer::IsQuestionnableFile($sDir)) {
$aDeniedDirWrongFormat[] = $sDir;
}
}
@@ -97,7 +97,7 @@ class iTopComposerTest extends ItopTestCase
public function testListAllowedFoldersAbsPaths()
{
$oiTopComposer = new iTopComposer();
$aDirs = $oiTopComposer->ListAllowedFoldersAbsPaths();
$aDirs = $oiTopComposer->ListAllowedFilesAbsPaths();
$this->assertTrue(is_array($aDirs));
}
@@ -109,7 +109,7 @@ class iTopComposerTest extends ItopTestCase
{
$oiTopComposer = new iTopComposer();
$aDeniedButStillPresent = $oiTopComposer->ListDeniedButStillPresentFoldersAbsPaths();
$aDeniedButStillPresent = $oiTopComposer->ListDeniedButStillPresentFilesAbsPaths();
$this->assertEmpty(
$aDeniedButStillPresent,
@@ -125,11 +125,11 @@ class iTopComposerTest extends ItopTestCase
{
$oDependenciesHandler = new iTopComposer();
$aAllowedAndDeniedDirs = array_merge(
$oDependenciesHandler->ListAllowedFoldersAbsPaths(),
$oDependenciesHandler->ListDeniedFoldersAbsPaths()
$oDependenciesHandler->ListAllowedFilesAbsPaths(),
$oDependenciesHandler->ListDeniedFilesAbsPaths()
);
$aExistingDirs = $oDependenciesHandler->ListAllFoldersAbsPaths();
$aExistingDirs = $oDependenciesHandler->ListAllFilesAbsPaths();
$aMissing = array_diff($aExistingDirs, $aAllowedAndDeniedDirs);
$aExtra = array_diff($aAllowedAndDeniedDirs, $aExistingDirs);

View File

@@ -40,11 +40,11 @@ class iTopNPMTest extends ItopTestCase
{
$oDependenciesHandler = new iTopNPM();
$aAllowedAndDeniedDirs = array_merge(
$oDependenciesHandler->ListAllowedFoldersAbsPaths(),
$oDependenciesHandler->ListDeniedFoldersAbsPaths()
$oDependenciesHandler->ListAllowedFilesAbsPaths(),
$oDependenciesHandler->ListDeniedFilesAbsPaths()
);
$aExistingDirs = $oDependenciesHandler->ListAllFoldersAbsPaths();
$aExistingDirs = $oDependenciesHandler->ListAllFilesAbsPaths();
$aMissing = array_diff($aExistingDirs, $aAllowedAndDeniedDirs);
$aExtra = array_diff($aAllowedAndDeniedDirs, $aExistingDirs);

View File

@@ -0,0 +1,166 @@
<?php
namespace Combodo\iTop\Test\UnitTest\Service\Cache;
use Combodo\iTop\Service\Cache\DataModelDependantCache;
use Combodo\iTop\Test\UnitTest\ItopTestCase;
use Exception;
class DataModelDependantCacheTest extends ItopTestCase
{
private DataModelDependantCache $oCacheService;
private string $sCacheRootDir;
protected function setUp(): void
{
parent::setUp();
$this->RequireOnceItopFile('setup/setuputils.class.inc.php');
$this->sCacheRootDir = self::CreateTmpdir();
$this->oCacheService = DataModelDependantCache::GetInstance();
$this->SetNonPublicProperty($this->oCacheService, 'sStorageRootDir', $this->sCacheRootDir);
}
protected function tearDown(): void
{
$this->SetNonPublicProperty($this->oCacheService, 'sStorageRootDir', null);
self::RecurseRmdir($this->sCacheRootDir);
parent::tearDown();
}
public function testShouldStoreAndFetchVariousDataTypes(): void
{
$this->oCacheService->Store('pool-A', 'key-array', ['value1', 'value2']);
$this->oCacheService->Store('pool-A', 'key-string', 'foo');
$this->oCacheService->Store('pool-A', 'key-int', 1971);
$this->assertEquals(['value1', 'value2'], $this->oCacheService->Fetch('pool-A', 'key-array'));
$this->assertEquals('foo', $this->oCacheService->Fetch('pool-A', 'key-string'));
$this->assertEquals(1971, $this->oCacheService->Fetch('pool-A', 'key-int'));
}
public function testShouldNotAllowToStoreNull(): void
{
$this->ExpectExceptionMessage('Cannot store NULL in the cache');
$this->oCacheService->Store('pool-A', 'key', null);
}
public function testShouldStoreInADirectoryRebuiltOnCompilation(): void
{
// Given the storage is reset to the default
$this->SetNonPublicProperty($this->oCacheService, 'sStorageRootDir', null);
// Then
$sFilePath = $this->InvokeNonPublicMethod(DataModelDependantCache::class, 'MakeCacheFileName', $this->oCacheService, ['pool-A', 'key']);
$this->assertStringContainsString('data/cache-', $sFilePath);
}
public function testPoolShouldSeparateEntriesHavingTheSameKey(): void
{
// Given
$this->oCacheService->Store('pool-A', 'key', ['data-default']);
$this->oCacheService->Store('pool-B', 'key', ['data-pool-B']);
// Then
$this->assertEquals(['data-default'], $this->oCacheService->Fetch('pool-A', 'key'));
$this->assertEquals(['data-pool-B'], $this->oCacheService->Fetch('pool-B', 'key'));
$this->assertEquals(null, $this->oCacheService->Fetch('pool-C-unknown', 'key'));
}
public function testPoolsShouldBeVisibleInThePath(): void
{
$sFilePath = $this->InvokeNonPublicMethod(DataModelDependantCache::class, 'MakeCacheFileName', $this->oCacheService, ['pool-B', 'key']);
$this->assertStringContainsString('pool-B', $sFilePath);
}
public function testFetchShouldReturnNullForNonExistingKey(): void
{
$this->assertNull($this->oCacheService->Fetch('pool-A', 'non-existing-key'));
}
public function testAnUnknownPoolShouldFailSilently(): void
{
$this->assertNull($this->oCacheService->Fetch('unknown-pool', 'non-existing-key'));
}
public function testDeleteItemAndHasEntry()
{
// Given an empy cache
// Then
$this->assertFalse($this->oCacheService->HasEntry('pool-A', 'key'), 'HasEntry should return false for non-existing key');
// When
$this->oCacheService->Store('pool-A', 'key', 'some data...');
// Then
$this->assertTrue($this->oCacheService->HasEntry('pool-A', 'key'), 'HasEntry should return true for newly created key');
// When
$this->oCacheService->DeleteItem('pool-A', 'key');
// Then
$this->assertFalse($this->oCacheService->HasEntry('pool-A', 'key'), 'HasEntry should return true for a removed key');
}
public function testDeleteItemShouldPreserveOtherEntries()
{
// Given
$this->oCacheService->Store('pool-A', 'key', 'some data...');
$this->oCacheService->Store('pool-A', 'key2', 'some data...');
// Then
$this->oCacheService->DeleteItem('pool-A', 'key');
// When
$this->assertTrue($this->oCacheService->HasEntry('pool-A', 'key2'));
}
public function testDeleteItemShouldPreserveHomonymsFromDifferentPools()
{
// Given
$this->oCacheService->Store('pool-A', 'key', 'some data...');
$this->oCacheService->Store('pool-B', 'key', 'some data...');
// When
$this->oCacheService->DeleteItem('pool-B', 'key');
// Then
$this->assertTrue($this->oCacheService->HasEntry('pool-A', 'key'), 'DeleteItem should not have altered the pool "default"');
}
public function testClearShouldRemoveAllEntriesFromTheCurrentPool()
{
// Given
$this->oCacheService->Store('pool-A', 'key', 'some data...');
$this->oCacheService->Store('pool-A', 'key2', 'some data...');
$this->oCacheService->Store('pool-B', 'key', 'some data...');
// When
$this->oCacheService->Clear('pool-A');
// Then
$this->assertFalse($this->oCacheService->HasEntry('pool-A', 'key'), 'DeleteItem should remove all entries from the current pool');
$this->assertFalse($this->oCacheService->HasEntry('pool-A', 'key2'), 'DeleteItem should remove all entries from the current pool');
$this->assertTrue($this->oCacheService->HasEntry('pool-B', 'key'), 'DeleteItem should not alter entries from other pools');
}
public function testGetEntryModificationTime()
{
// Given an entry created at a specific time
$this->oCacheService->Store('pool-A', 'key', 'some data...');
$iRefTime = time();
$sFilePath = $this->InvokeNonPublicMethod(DataModelDependantCache::class, 'MakeCacheFileName', $this->oCacheService, ['pool-A', 'key']);
touch($sFilePath, $iRefTime);
// Then
$this->assertEquals($iRefTime, $this->oCacheService->GetEntryModificationTime('pool-A', 'key'), 'GetEntryModificationTime should return the modification time of the cache file');
$this->assertEquals(null, $this->oCacheService->GetEntryModificationTime('pool-A', 'non-existing-key'), 'GetEntryModificationTime should return null for an invalid key');
}
public function testKeyUndesiredCharactersShouldBeTransformedToUnderscore()
{
$sUglyKey = 'key with ugly characters:\{&"#@ç^²/,;[(|🤔';
$sFilePath = $this->InvokeNonPublicMethod(DataModelDependantCache::class, 'MakeCacheFileName', $this->oCacheService, ['pool-A', $sUglyKey]);
$this->assertEquals('key_with_ugly_characters______________________.php', basename($sFilePath));
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace Combodo\iTop\Test\UnitTest\Service\InterfaceDiscovery;
use Combodo\iTop\Application\UI\Base\iUIBlockFactory;
use Combodo\iTop\Service\InterfaceDiscovery\InterfaceDiscovery;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
class InterfaceDiscoveryTest extends ItopDataTestCase
{
protected function tearDown(): void
{
$this->SetNonPublicProperty(InterfaceDiscovery::GetInstance(), 'aForcedClassMap', null);
parent::tearDown();
}
public function testShouldSelectTheRequestedItopClasses()
{
$oInterfaceDiscoveryService = InterfaceDiscovery::GetInstance();
$this->GivenClassMap($oInterfaceDiscoveryService, [
'Combodo\iTop\Application\UI\Base\Component\Alert\Alert' => APPROOT . '/sources/Application/UI/Base/Component/Alert/Alert.php',
'Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory' => APPROOT . '/sources/Application/UI/Base/Component/Alert/AlertUIBlockFactory.php',
'Combodo\iTop\Application\UI\Base\Component\ButtonGroup\ButtonGroupUIBlockFactory' => APPROOT . '/sources/Application/UI/Base/Component/ButtonGroup/ButtonGroupUIBlockFactory.php',
]);
$this->AssertArraysHaveSameItems(
[
'Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory',
'Combodo\iTop\Application\UI\Base\Component\ButtonGroup\ButtonGroupUIBlockFactory',
],
$oInterfaceDiscoveryService->FindItopClasses(iUIBlockFactory::class)
);
}
public function testShouldExcludeSpecifiedDirectories()
{
$oInterfaceDiscoveryService = InterfaceDiscovery::GetInstance();
$this->GivenClassMap($oInterfaceDiscoveryService, [
'Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory' => APPROOT . '/sources/Application/UI/Base/Component/Alert/AlertUIBlockFactory.php',
'Combodo\iTop\Application\UI\Base\Component\ButtonGroup\ButtonGroupUIBlockFactory' => APPROOT . '/sources/Application/UI/Base/Component/ButtonGroup/ButtonGroupUIBlockFactory.php',
]);
$this->AssertArraysHaveSameItems(
[],
$oInterfaceDiscoveryService->FindItopClasses(iUIBlockFactory::class, ['Component/ButtonGroup', '/Alert/'])
);
}
public function testShouldExcludeAliases()
{
$oInterfaceDiscoveryService = InterfaceDiscovery::GetInstance();
$this->GivenClassMap($oInterfaceDiscoveryService, [
'Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory' => APPROOT . '/sources/Application/UI/Base/Component/Alert/AlertUIBlockFactory.php',
'AlbertIsBlockingTheFactory' => APPROOT . '/sources/Application/UI/Base/Component/Alert/AlertUIBlockFactory.php',
]);
class_alias('Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory', 'AlbertIsBlockingTheFactory');
$this->AssertArraysHaveSameItems(
[
'Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory',
],
$oInterfaceDiscoveryService->FindItopClasses(iUIBlockFactory::class)
);
}
private function GivenClassMap(InterfaceDiscovery $oInterfaceDiscoveryService, array $aClassMap): void
{
$this->SetNonPublicProperty($oInterfaceDiscoveryService, 'aForcedClassMap', $aClassMap);
}
}