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

This commit is contained in:
jf-cbd
2024-10-23 17:56:09 +02:00
48 changed files with 2412 additions and 395 deletions

View File

@@ -0,0 +1,76 @@
<?php
namespace Combodo\iTop\Test\UnitTest\HubConnector;
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
use PHPUnit\Framework\SkippedTestCase;
class AjaxPageTest extends ItopDataTestCase {
const USE_TRANSACTION = false;
const AUTHENTICATION_TOKEN = '14b5da9d092f84044187421419a0347e7317bc8cd2b486fdda631be06b959269';
const AUTHENTICATION_PASSWORD = "tagada-Secret,007";
protected function setUp(): void
{
$this->SkipIfModuleNotPresent('itop-hub-connector');
parent::setUp();
}
public function testCompileOperation()
{
// Given
static::RecurseMkdir(APPROOT.'data/hub');
file_put_contents(APPROOT.'data/hub/compile_authent', self::AUTHENTICATION_TOKEN);
$sLogin = $this->GivenUserInDB(self::AUTHENTICATION_PASSWORD, ['Administrator']);
$iLastCompilation = filemtime(APPROOT.'env-production');
// When
$sOutput = $this->CallItopUrl(
"/pages/exec.php?exec_module=itop-hub-connector&exec_page=ajax.php",
[
'auth_user' => $sLogin,
'auth_pwd' => self::AUTHENTICATION_PASSWORD,
'operation' => "compile",
'authent' => self::AUTHENTICATION_TOKEN,
]
);
// Then
$aRes = json_decode($sOutput, true);
$this->assertNotNull($aRes, "Response should be a valid json, found instead:" . PHP_EOL . $sOutput);
$this->assertEquals(
[
'code' => 0,
'message' => 'Ok',
'fields' => []
],
$aRes
);
clearstatcache();
$this->assertGreaterThan($iLastCompilation, filemtime(APPROOT.'env-production'), 'The env-production directory should have been rebuilt');
}
protected function CallItopUrl($sUri, ?array $aPostFields = null, bool $bXDebugEnabled = false)
{
$ch = curl_init();
if ($bXDebugEnabled) {
curl_setopt($ch, CURLOPT_COOKIE, 'XDEBUG_SESSION=phpstorm');
}
$sUrl = \MetaModel::GetConfig()->Get('app_root_url')."/$sUri";
var_dump($sUrl);
curl_setopt($ch, CURLOPT_URL, $sUrl);
curl_setopt($ch, CURLOPT_POST, 1);// set post data to true
curl_setopt($ch, CURLOPT_POSTFIELDS, $aPostFields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$sOutput = curl_exec($ch);
//echo "$sUrl error code:".curl_error($ch);
curl_close($ch);
return $sOutput;
}
}

View File

@@ -2,7 +2,7 @@
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.5/phpunit.xsd"
bootstrap="vendor/autoload.php"
bootstrap="unittestautoload.php"
backupGlobals="true"
colors="true"
columns="120"

View File

@@ -2,7 +2,7 @@
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.5/phpunit.xsd"
bootstrap="vendor/autoload.php"
bootstrap="unittestautoload.php"
backupGlobals="true"
colors="true"
columns="120"

View File

@@ -2,7 +2,7 @@
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.5/phpunit.xsd"
bootstrap="vendor/autoload.php"
bootstrap="unittestautoload.php"
backupGlobals="true"
colors="true"
columns="120"

View File

@@ -1368,4 +1368,42 @@ abstract class ItopDataTestCase extends ItopTestCase
]);
return $sLogin;
}
/**
* @param string $sPassword
* @param array $aProfiles Profile names Example: ['Administrator']
*
* @return string The unique login
* @throws \Exception
*/
protected function GivenUserInDB(string $sPassword, array $aProfiles): string
{
$sLogin = 'demo_test_'.uniqid(__CLASS__, true);
$aProfileList = array_map(function($sProfileId) {
return 'profileid:'.self::$aURP_Profiles[$sProfileId];
}, $aProfiles);
$iUser = $this->GivenObjectInDB('UserLocal', [
'login' => $sLogin,
'password' => $sPassword,
'language' => 'EN US',
'profile_list' => $aProfileList,
]);
return $sLogin;
}
/**
* Can be invoked in setUp or any test method to skip the test if the module is not present
*
* @param string $sModule e.g: itop-hub-connector
*
* @return void
*/
protected function SkipIfModuleNotPresent(string $sModule): void
{
if (!file_exists(\utils::GetAbsoluteModulePath($sModule))) {
self::markTestSkipped("Test skipped: module '$sModule' is not present");
}
}
}

View File

@@ -9,19 +9,21 @@ namespace Combodo\iTop\Test\UnitTest;
use CMDBSource;
use DeprecatedCallsLog;
use MySQLTransactionNotClosedException;
use PHPUnit\Framework\TestCase;
use ReflectionMethod;
use SetupUtils;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\HttpKernel\KernelInterface;
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
* Helper class to extend for tests that DO NOT need to access the DataModel or the Database,
* but still need to access the iTop core classes and optionally boot the Symfony kernel (to access the services container).
*
* @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.
*/
abstract class ItopTestCase extends TestCase
abstract class ItopTestCase extends KernelTestCase
{
public const TEST_LOG_DIR = 'test';
@@ -70,6 +72,9 @@ abstract class ItopTestCase extends TestCase
}
}
}
// Required to boot the portal symfony Kernel
$_ENV['PORTAL_ID'] = 'itop-portal';
}
/**
@@ -142,6 +147,9 @@ abstract class ItopTestCase extends TestCase
protected function setUp(): void {
parent::setUp();
// Hack - Required the first time the Portal kernel is booted on a newly installed iTop
$_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'] = __DIR__ . '/../../../../../env-production/itop-portal-base/portal/public/';
$this->LoadRequiredItopFiles();
$this->LoadRequiredTestFiles();
}
@@ -212,7 +220,7 @@ abstract class ItopTestCase extends TestCase
protected function LoadRequiredItopFiles(): void
{
// At least make sure that the autoloader will be loaded, and that the APPROOT constant is defined
require_once __DIR__.'/../../../../approot.inc.php';
require_once __DIR__.'/../../../../approot.inc.php';
}
/**
@@ -541,4 +549,27 @@ abstract class ItopTestCase extends TestCase
$this->AssertArraysHaveSameItems($aExpected, $aFiles, $sMessage);
}
/**
* Control which Kernel will be loaded when invoking the bootKernel method
*
* @see static::bootKernel(), static::getContainer()
* @see \Combodo\iTop\Kernel, \Combodo\iTop\Portal\Kernel
*
* @param string $sKernelClass
*
* @since 3.2.1
*/
static protected function SetKernelClass(string $sKernelClass): void
{
$_SERVER['KERNEL_CLASS'] = $sKernelClass;
}
static protected function bootKernel(array $options = []): KernelInterface
{
if (!array_key_exists('KERNEL_CLASS', $_SERVER)) {
throw new \LogicException('static::SetKernelClass() must be called before booting the kernel.');
}
return parent::bootKernel($options);
}
}

View File

@@ -79,21 +79,18 @@ class UpdateImpactedItemsTest extends ItopDataTestCase
{
/**
* Server1 +----> Hypervisor1
* Server2 +----> Hypervisor1
*/
$this->GivenCITreeInDB(<<<EOF
Hypervisor_1 -> Server_1
Hypervisor_1 -> Server_2
EOF);
$oTicket = $this->GivenTicketWithCIsOrPersons([
'Server_1' => 'manual'
'Hypervisor_1' => 'manual'
]);
$oTicket->UpdateImpactedItems(); // impact analysis
$this->assertCIsOrPersonsListEquals($oTicket, [
'Server_1' => 'manual',
'Hypervisor_1' => 'computed'
'Hypervisor_1' => 'manual',
]);
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Combodo\iTop\Test\UnitTest\Sources\Controller;
use Combodo\iTop\Portal\Controller\AggregatePageBrickController;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
class BootSymfonyKernelTest extends ItopDataTestCase
{
public function testInstantiateServiceWithAnExplicitCallToBootTheKernel()
{
$this->SetKernelClass(\Combodo\iTop\Portal\Kernel::class);
self::bootKernel();
$controller = static::getContainer()->get(AggregatePageBrickController::class);
$this->assertInstanceOf(AggregatePageBrickController::class, $controller);
}
public function testInstantiateServiceWithAnAutomaticKernelBoot()
{
$this->SetKernelClass(\Combodo\iTop\Portal\Kernel::class);
$controller = static::getContainer()->get(AggregatePageBrickController::class);
$this->assertInstanceOf(AggregatePageBrickController::class, $controller);
}
public function testUnspecifiedKernelClassThrowsAnException()
{
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('static::SetKernelClass() must be called before booting the kernel');
static::getContainer();
}
public function testTwoDifferentKernelsCanBeStartedConsecutively()
{
self::markTestSkipped('This test is still failing: the second kernel container does not find the requested service');
$this->SetKernelClass(\Combodo\iTop\Kernel::class);
self::bootKernel();
$this->SetKernelClass(\Combodo\iTop\Portal\Kernel::class);
self::bootKernel();
$controller = static::getContainer()->get(AggregatePageBrickController::class);
$this->assertInstanceOf(AggregatePageBrickController::class, $controller);
}
}

View File

@@ -2,6 +2,8 @@
// Main autoload, this is the one to use in the PHPUnit configuration
//
// It was previously used to include both the vendor autoloader and our custom base test case classes, but these are now autoloaded from ./src/BasetestCase
// This file should then no longer be necessary, but we have to keep it until projects / branches / modules have been corrected.
// This file was previously mentioned as deprecated, and now it HAS to be used (see phpunit.xml/bootstrap attribute)
require_once 'vendor/autoload.php';
// Required to benefit from symfony/framework-bundle's KernelTestCase, which is in a package which is a mix of runtime and test tools
require_once __DIR__.'/../../lib/autoload.php';