From 9b6d321ab034d9b853ee6ebcbdb61219a6b894a0 Mon Sep 17 00:00:00 2001
From: Timmy38 <101416770+Timmy38@users.noreply.github.com>
Date: Thu, 26 Feb 2026 10:28:52 +0100
Subject: [PATCH] =?UTF-8?q?N=C2=B09009=20Add=20phpunit=20test=20to=20GetSe?=
=?UTF-8?q?lectedModules?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
setup/setuputils.class.inc.php | 2 +-
setup/wizardsteps/WizStepModulesChoice.php | 18 +-
.../setup/WizStepModulesChoiceTest.php | 275 ++++++++++++++++++
.../setup/iTopExtensionsMapFake.php | 2 +-
4 files changed, 287 insertions(+), 10 deletions(-)
diff --git a/setup/setuputils.class.inc.php b/setup/setuputils.class.inc.php
index 6378f4179..8c40c9a3c 100644
--- a/setup/setuputils.class.inc.php
+++ b/setup/setuputils.class.inc.php
@@ -2150,7 +2150,7 @@ class SetupInfo
/**
* Called by the setup process to initializes the list of selected modules. Do not call this method
* from an 'auto_select' rule
- * @param hash $aModules
+ * @param array $aModules
* @return void
*/
public static function SetSelectedModules($aModules)
diff --git a/setup/wizardsteps/WizStepModulesChoice.php b/setup/wizardsteps/WizStepModulesChoice.php
index 0a0f6b875..5cb90bd01 100644
--- a/setup/wizardsteps/WizStepModulesChoice.php
+++ b/setup/wizardsteps/WizStepModulesChoice.php
@@ -48,7 +48,7 @@ class WizStepModulesChoice extends WizardStep
*/
protected bool $bChoicesFromDatabase;
- private array $aAnalyzeInstallationModules;
+ private array $aAnalyzeInstallationModules = [];
private ?MissingDependencyException $oMissingDependencyException = null;
public function __construct(WizardController $oWizard, $sCurrentState)
@@ -488,7 +488,7 @@ EOF
*
* @return string A text representation of what will be installed
*/
- protected function GetSelectedModules($aInfo, $aSelectedChoices, &$aModules, $sParentId = '', $sDisplayChoices = '', &$aSelectedExtensions = null)
+ public function GetSelectedModules($aInfo, $aSelectedChoices, &$aModules, $sParentId = '', $sDisplayChoices = '', &$aSelectedExtensions = null)
{
if ($sParentId == '') {
// Check once (before recursing) that the hidden modules are selected
@@ -501,7 +501,7 @@ EOF
}
}
}
- $aOptions = isset($aInfo['options']) ? $aInfo['options'] : [];
+ $aOptions = $aInfo['options'] ?? [];
foreach ($aOptions as $index => $aChoice) {
$sChoiceId = $sParentId.self::$SEP.$index;
$aModuleInfo = [];
@@ -516,16 +516,19 @@ EOF
(isset($aSelectedChoices[$sChoiceId]) && ($aSelectedChoices[$sChoiceId] == $sChoiceId))) {
$sDisplayChoices .= '
'.$aChoice['title'].'';
if (isset($aChoice['modules'])) {
+ if (count($aChoice['modules']) === 0) {
+ throw new Exception('Extension '.$aChoice['extension_code'].' does not have any module associated');
+ }
foreach ($aChoice['modules'] as $sModuleId) {
$bSelected = true;
if (isset($aModuleInfo[$sModuleId])) {
// Test if module has 'auto_select'
- $aInfo = $aModuleInfo[$sModuleId];
- if (isset($aInfo['auto_select'])) {
+ $aCurrentModuleInfo = $aModuleInfo[$sModuleId];
+ if (isset($aCurrentModuleInfo['auto_select'])) {
// Check the module selection
try {
SetupInfo::SetSelectedModules($aModules);
- $bSelected = $this->GetPhpExpressionEvaluator()->ParseAndEvaluateBooleanExpression($aInfo['auto_select']);
+ $bSelected = $this->GetPhpExpressionEvaluator()->ParseAndEvaluateBooleanExpression($aCurrentModuleInfo['auto_select']);
} catch (ModuleFileReaderException $e) {
//logged already
$bSelected = false;
@@ -538,7 +541,6 @@ EOF
}
}
}
- $sChoiceType = isset($aChoice['type']) ? $aChoice['type'] : 'wizard_option';
if ($aSelectedExtensions !== null) {
$aSelectedExtensions[] = $aChoice['extension_code'];
}
@@ -552,7 +554,7 @@ EOF
}
}
- $aAlternatives = isset($aInfo['alternatives']) ? $aInfo['alternatives'] : [];
+ $aAlternatives = $aInfo['alternatives'] ?? [];
$sChoiceName = null;
foreach ($aAlternatives as $index => $aChoice) {
$sChoiceId = $sParentId.self::$SEP.$index;
diff --git a/tests/php-unit-tests/unitary-tests/setup/WizStepModulesChoiceTest.php b/tests/php-unit-tests/unitary-tests/setup/WizStepModulesChoiceTest.php
index 039215a8c..8c4d74edb 100644
--- a/tests/php-unit-tests/unitary-tests/setup/WizStepModulesChoiceTest.php
+++ b/tests/php-unit-tests/unitary-tests/setup/WizStepModulesChoiceTest.php
@@ -613,4 +613,279 @@ class WizStepModulesChoiceTest extends ItopTestCase
return $aSteps[$index] ?? null;
}
+
+ public function ProviderGetSelectedModules()
+ {
+ return [
+ 'No extension selected' => [
+ 'aSelected' => [],
+ 'aExpectedModules' => [],
+ 'aExpectedExtensions' => [],
+ ],
+ 'One extension selected' => [
+ 'aSelected' => ['_0' => '_0'],
+ 'aExpectedModules' => ['combodo-sample-module' => true],
+ 'aExpectedExtensions' => ['combodo-sample'],
+ ],
+ 'More extensions selected' => [
+ 'aSelected' => ['_0' => '_0', '_1' => '_1'],
+ 'aExpectedModules' => ['combodo-sample-module' => true, 'combodo-test-moduleA' => true, 'combodo-test-moduleB' => true],
+ 'aExpectedExtensions' => ['combodo-sample', 'combodo-test'],
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider ProviderGetSelectedModules
+ */
+ public function testGetSelectedModules($aSelectedExtensions, $aExpectedModules, $aExpectedExtensions)
+ {
+ $aExtensionsMapData = [
+ 'combodo-sample' => [
+ 'installed' => false,
+ ],
+ 'combodo-test' => [
+ 'installed' => false,
+ ],
+ ];
+ $this->oStep->setExtensionMap(iTopExtensionsMapFake::createFromArray($aExtensionsMapData));
+
+ $aStepInfo = [
+ 'title' => 'Extensions',
+ 'description' => '',
+ 'banner' => '',
+ 'options' => [
+ [
+ 'extension_code' => 'combodo-sample',
+ 'title' => 'Sample extension',
+ 'description' => '',
+ 'more_info' => '',
+ 'default' => true,
+ 'modules' => [
+ 'combodo-sample-module',
+ ],
+ 'mandatory' => false,
+ 'source_label' => '',
+ 'uninstallable' => true,
+ 'missing' => false,
+ ],
+ [
+ 'extension_code' => 'combodo-test',
+ 'title' => 'Test extension',
+ 'description' => '',
+ 'more_info' => '',
+ 'default' => true,
+ 'modules' => [
+ 'combodo-test-moduleA',
+ 'combodo-test-moduleB',
+ ],
+ 'mandatory' => false,
+ 'source_label' => '',
+ 'uninstallable' => true,
+ 'missing' => false,
+ ],
+ ],
+ ];
+
+ $aModules = [];
+ $aExtensions = [];
+ $this->oStep->GetSelectedModules($aStepInfo, $aSelectedExtensions, $aModules, '', '', $aExtensions);
+ $this->assertEquals($aExpectedModules, $aModules);
+ $this->assertEquals($aExpectedExtensions, $aExtensions);
+ }
+
+ public function testGetSelectedModulesShouldAlwaysSelectMandatoryExtension()
+ {
+
+ $aSelectedExtensions = ['_0' => '_0'];
+
+ $aExtensionsMapData = [
+ 'combodo-sample' => [
+ 'installed' => true,
+ ],
+ ];
+
+ $this->oStep->setExtensionMap(iTopExtensionsMapFake::createFromArray($aExtensionsMapData));
+
+ $aStepInfo = [
+ 'title' => 'Extensions',
+ 'description' => '',
+ 'banner' => '',
+ 'options' => [
+ [
+ 'extension_code' => 'combodo-sample',
+ 'title' => 'Sample extension',
+ 'description' => '',
+ 'more_info' => '',
+ 'default' => true,
+ 'modules' => [
+ 'combodo-sample-module',
+ ],
+ 'mandatory' => false,
+ 'source_label' => '',
+ 'uninstallable' => true,
+ 'missing' => true,
+ ],
+ ],
+ ];
+
+ $aExpectedModules = ['combodo-sample-module' => true];
+ $aExpectedExtensions = ['combodo-sample'];
+
+ $aModules = [];
+ $aExtensions = [];
+ $this->oStep->GetSelectedModules($aStepInfo, $aSelectedExtensions, $aModules, '', '', $aExtensions);
+ $this->assertEquals($aExpectedModules, $aModules);
+ $this->assertEquals($aExpectedExtensions, $aExtensions);
+ }
+
+ public function testGetSelectedModulesShouldShouldParseAutoSelectCondition()
+ {
+ //the 'auto_select' parameter, contrary to its name, deselect the module if its result is false
+
+ $aSelectedExtensions = ['_0' => '_0'];
+
+ $aExtensionsMapData = [
+ 'combodo-sample' => [
+ 'installed' => true,
+ 'module_info' => [
+ 'combodo-sample-module' => [
+ 'auto_select' => 'true && false',
+ ],
+ ],
+ ],
+ ];
+ $this->oStep->setExtensionMap(iTopExtensionsMapFake::createFromArray($aExtensionsMapData));
+
+ $aStepInfo = [
+ 'title' => 'Extensions',
+ 'description' => '',
+ 'banner' => '',
+ 'options' => [
+ [
+ 'extension_code' => 'combodo-sample',
+ 'title' => 'Sample extension',
+ 'description' => '',
+ 'more_info' => '',
+ 'default' => true,
+ 'modules' => [
+ 'combodo-sample-module',
+ ],
+ 'mandatory' => false,
+ 'source_label' => '',
+ 'uninstallable' => true,
+ 'missing' => true,
+ ],
+ ],
+ ];
+
+ $aExpectedModules = [];
+ $aExpectedExtensions = ['combodo-sample'];
+
+ $aModules = [];
+ $aExtensions = [];
+ $this->oStep->GetSelectedModules($aStepInfo, $aSelectedExtensions, $aModules, '', '', $aExtensions);
+ $this->assertEquals($aExpectedModules, $aModules);
+ $this->assertEquals($aExpectedExtensions, $aExtensions);
+ }
+
+ public function testGetSelectedModulesWithSubOptions()
+ {
+
+ $aSelectedExtensions = ['_0' => '_0', '_0_0' => '_0_0'];
+
+ $aExtensionsMapData = [
+ 'combodo-sample' => [
+ 'installed' => false,
+ ],
+ 'combodo-sub-sample' => [
+ 'installed' => false,
+ ],
+ ];
+ $this->oStep->setExtensionMap(iTopExtensionsMapFake::createFromArray($aExtensionsMapData));
+
+ $aStepInfo = [
+ 'options' => [
+ [
+ 'extension_code' => 'combodo-sample',
+ 'title' => 'Sample extension',
+ 'description' => '',
+ 'more_info' => '',
+ 'default' => true,
+ 'modules' => [
+ 'combodo-sample-module',
+ ],
+ 'mandatory' => false,
+ 'source_label' => '',
+ 'uninstallable' => true,
+ 'missing' => false,
+ 'sub_options' => [
+ 'options' => [
+ [
+ 'extension_code' => 'combodo-sub-sample',
+ 'title' => 'Sample sub extension',
+ 'description' => '',
+ 'more_info' => '',
+ 'default' => true,
+ 'modules' => [
+ 'combodo-sub-sample-module',
+ ],
+ 'mandatory' => false,
+ 'source_label' => '',
+ 'uninstallable' => true,
+ 'missing' => false,
+ ],
+ ],
+ ],
+ ],
+ ],
+ ];
+
+ $aExpectedModules = ['combodo-sample-module' => true, 'combodo-sub-sample-module' => true];
+ $aExpectedExtensions = ['combodo-sample', 'combodo-sub-sample'];
+
+ $aModules = [];
+ $aExtensions = [];
+ $this->oStep->GetSelectedModules($aStepInfo, $aSelectedExtensions, $aModules, '', '', $aExtensions);
+ $this->assertEquals($aExpectedModules, $aModules);
+ $this->assertEquals($aExpectedExtensions, $aExtensions);
+ }
+
+ public function testGetSelectedModulesShouldThrowAnExceptionWhenAnySelectedExtensionDoesNotHaveAnyAssociatedModules()
+ {
+ $aExtensionsMapData = [
+ 'combodo-sample' => [
+ 'installed' => false,
+ ],
+ ];
+ $this->oStep->setExtensionMap(iTopExtensionsMapFake::createFromArray($aExtensionsMapData));
+
+ //GetSelectedModules
+ $aStepInfo = [
+ 'title' => 'Extensions',
+ 'description' => '',
+ 'banner' => '',
+ 'options' => [
+ [
+ 'extension_code' => 'combodo-sample',
+ 'title' => 'Sample extension',
+ 'description' => '',
+ 'more_info' => '',
+ 'default' => true,
+ 'modules' => [],
+ 'mandatory' => false,
+ 'source_label' => '',
+ 'uninstallable' => true,
+ 'missing' => false,
+ ],
+ ],
+ ];
+
+ $aModules = [];
+ $aExtensions = [];
+ $this->expectException('Exception');
+ $this->expectExceptionMessage('Extension combodo-sample does not have any module associated');
+ $this->oStep->GetSelectedModules($aStepInfo, ['_0' => '_0'], $aModules, '', '', $aExtensions);
+ }
+
}
diff --git a/tests/php-unit-tests/unitary-tests/setup/iTopExtensionsMapFake.php b/tests/php-unit-tests/unitary-tests/setup/iTopExtensionsMapFake.php
index ff1a204af..f53eb84c7 100644
--- a/tests/php-unit-tests/unitary-tests/setup/iTopExtensionsMapFake.php
+++ b/tests/php-unit-tests/unitary-tests/setup/iTopExtensionsMapFake.php
@@ -21,7 +21,7 @@ class iTopExtensionsMapFake extends iTopExtensionsMap
$oExtension->aModules = $aExtension['modules'] ?? [];
$oExtension->bCanBeUninstalled = $aExtension['uninstallable'] ?? null;
$oExtension->sVersion = $aExtension['version'] ?? '1.0.0';
- $oExtension->aModuleInfo = [];
+ $oExtension->aModuleInfo = $aExtension['module_info'] ?? [];
$oMap->AddExtension($oExtension);
}
return $oMap;