diff --git a/setup/extensionsmap.class.inc.php b/setup/extensionsmap.class.inc.php index 0ae6bacd07..e5acebe1c4 100644 --- a/setup/extensionsmap.class.inc.php +++ b/setup/extensionsmap.class.inc.php @@ -557,9 +557,6 @@ class iTopExtensionsMap continue; } - if (!$oExtension->bMandatory && $bRemoteExtensionsShouldBeMandatory) { - $oExtension->bMandatory = ($oExtension->sSource === iTopExtension::SOURCE_REMOTE); - } $aRes[$oExtension->sCode] = $oExtension; } diff --git a/setup/wizardsteps/WizStepModulesChoice.php b/setup/wizardsteps/WizStepModulesChoice.php index 342daa38dc..f4c6d256ee 100644 --- a/setup/wizardsteps/WizStepModulesChoice.php +++ b/setup/wizardsteps/WizStepModulesChoice.php @@ -760,7 +760,7 @@ EOF return $this->aSteps[$index] ?? null; } - public function ComputeChoiceFlags(array $aChoice, string $sChoiceId, array $aSelectedComponents, bool $bAllDisabled, bool $bDisableUninstallCheck) + public function ComputeChoiceFlags(array $aChoice, string $sChoiceId, array $aSelectedComponents, bool $bAllDisabled, bool $bDisableUninstallCheck): array { if (array_key_exists($sChoiceId, $this->aFlagsByChoiceId)) { return $this->aFlagsByChoiceId[$sChoiceId]; @@ -774,50 +774,48 @@ EOF $bMandatory = (isset($aChoice['mandatory']) && $aChoice['mandatory']); $bInstalled = $bMissingFromDisk || $oITopExtension?->bInstalled ?? false; $bDependencyIssue = $oITopExtension?->HasDependencyIssue() ?? false; + $bIsRemoteExtension = $oITopExtension?->sSource === iTopExtension::SOURCE_REMOTE; + $bIsPackageExtension = $oITopExtension?->sSource === iTopExtension::SOURCE_WIZARD; + $bDoNotUninstall = !$bCanBeUninstalled || $bIsRemoteExtension; $bChecked = $bSelected; $bDisabled = false; + if ($bMissingFromDisk) { $bDisabled = true; $bChecked = false; - } elseif ($bDependencyIssue && ($oITopExtension->sSource !== iTopExtension::SOURCE_WIZARD || !$bMandatory)) { - // If the extension is not installed, the user cannot select it - // If the extension is installed and mandatory or not uninstallable, the user cannot unselect it - // Unless the user uses the "force-uninstall" option - $bDisabled = (!$bInstalled || $bMandatory || !$bCanBeUninstalled) && !$bDisableUninstallCheck; - // If the extension is a remote extension and not be installed means the user previously uninstalled it - // Otherwise, it will be checked if it is mandatory or if it was selected by the user - if ($oITopExtension->sSource !== iTopExtension::SOURCE_REMOTE || $bInstalled) { - $bChecked = $bMandatory ?: $bSelected; + } elseif ($bMandatory && $bIsPackageExtension) { + $bDisabled = true; + $bChecked = true; + } else { + if ($bDependencyIssue) { + // If the extension has a dependency issue, it cannot be checked and must be unchecked using the "force-uninstall" option + $bDisabled = !$bInstalled || !$bDisableUninstallCheck; + } elseif ($bInstalled && $bDoNotUninstall) { + // If the extension is uninstallable, it must be unchecked using the "force-uninstall" option + $bDisabled = !$bDisableUninstallCheck; + } + + if (isset($aChoice['sub_options'])) { + $aOptions = $aChoice['sub_options']['options'] ?? []; + foreach ($aOptions as $index => $aSubChoice) { + $sSubChoiceId = $sChoiceId.self::$SEP.$index; + $aSubFlags = $this->ComputeChoiceFlags($aSubChoice, $sSubChoiceId, $aSelectedComponents, $bAllDisabled, $bDisableUninstallCheck); + if ($aSubFlags['checked']) { + $bChecked = true; + if ($aSubFlags['disabled']) { + // If some sub options are checked and cannot be unchecked, this choice also cannot be unchecked since it would uncheck all its sub options + $bDisabled = true; + } + } + } } - } elseif ($bMandatory) { - $bDisabled = true; - $bChecked = true; - } elseif ($bInstalled && !$bCanBeUninstalled && !$bDisableUninstallCheck) { - $bChecked = true; - $bDisabled = true; } if ($bAllDisabled) { $bDisabled = true; } - if (isset($aChoice['sub_options'])) { - $aOptions = $aChoice['sub_options']['options'] ?? []; - foreach ($aOptions as $index => $aSubChoice) { - $sSubChoiceId = $sChoiceId.self::$SEP.$index; - $aSubFlags = $this->ComputeChoiceFlags($aSubChoice, $sSubChoiceId, $aSelectedComponents, $bAllDisabled, $bDisableUninstallCheck); - if ($aSubFlags['checked']) { - $bChecked = true; - if ($aSubFlags['disabled']) { - //If some sub options are enabled and cannot be disabled, this choice should also cannot be disabled since it would disable all its sub options - $bDisabled = true; - } - } - - } - } - $aFlags = [ 'uninstallable' => $bCanBeUninstalled, 'dependency_issue' => $bDependencyIssue, @@ -907,10 +905,6 @@ EOF if (!$aFlags['uninstallable']) { return false; } - // An extension cannot be uninstalled if it is mandatory - if ($aFlags['mandatory']) { - return false; - } } return true; @@ -1010,5 +1004,4 @@ EOF return 'Next'; } - } diff --git a/tests/php-unit-tests/unitary-tests/setup/WizStepModulesChoiceTest.php b/tests/php-unit-tests/unitary-tests/setup/WizStepModulesChoiceTest.php index 213de73127..e7ebe6148a 100644 --- a/tests/php-unit-tests/unitary-tests/setup/WizStepModulesChoiceTest.php +++ b/tests/php-unit-tests/unitary-tests/setup/WizStepModulesChoiceTest.php @@ -28,65 +28,23 @@ class WizStepModulesChoiceTest extends ItopTestCase ModuleDiscovery::ResetCache(); } - public function ProviderComputeChoiceFlags() + /** + * Expected flags for the different scenarios, see the flowchart for a visual representation of the logic: + * @see ressources/compute_choice_flags.flowchart.fun + * @link https://flowchart.fun + */ + public function ProviderComputeChoiceFlags(): array { return [ - 'A not selected, not installed extension should not be checked and be enabled' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => false, - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => false, - 'uninstallable' => true, - ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => false, - 'aExpectedFlags' => [ - 'uninstallable' => true, - 'missing' => false, - 'installed' => false, - 'disabled' => false, - 'checked' => false, - 'dependency_issue' => false, - 'mandatory' => false, - ], - ], - 'A selected but not installed extension should be checked and enabled' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => false, - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => false, - 'uninstallable' => true, - ], - 'bCurrentSelected' => true, - 'bDisableUninstallChecks' => false, - 'aExpectedFlags' => [ - 'uninstallable' => true, - 'missing' => false, - 'installed' => false, - 'disabled' => false, - 'checked' => true, - 'dependency_issue' => false, - 'mandatory' => false, - ], - ], - 'A missing extension should be disabled and unchecked' => [ + '#node1 - A missing extension should be disabled and unchecked' => [ 'aExtensionsOnDiskOrDb' => [ ], 'aWizardStepDefinition' => [ 'extension_code' => 'itop-ext1', - 'mandatory' => false, 'missing' => true, 'uninstallable' => true, ], - 'bCurrentSelected' => false, + 'aSelectedComponents' => [], 'bDisableUninstallChecks' => false, 'aExpectedFlags' => [ 'uninstallable' => true, @@ -98,121 +56,36 @@ class WizStepModulesChoiceTest extends ItopTestCase 'mandatory' => false, ], ], - 'A missing extension should always be disabled and unchecked, even when mandatory' => [ - 'aExtensionsOnDiskOrDb' => [ - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => true, - 'missing' => true, - 'uninstallable' => true, - ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => false, - 'aExpectedFlags' => [ - 'uninstallable' => true, - 'missing' => true, - 'installed' => true, - 'disabled' => true, - 'checked' => false, - 'dependency_issue' => false, - 'mandatory' => true, - ], - ], - 'A missing extension should always be disabled and unchecked, even when non-uninstallable' => [ - 'aExtensionsOnDiskOrDb' => [ - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => true, - 'missing' => true, - 'uninstallable' => false, - ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => false, - 'aExpectedFlags' => [ - 'uninstallable' => false, - 'missing' => true, - 'installed' => true, - 'disabled' => true, - 'checked' => false, - 'dependency_issue' => false, - 'mandatory' => true, - ], - ], - 'An installed but not selected extension should not be checked and be enabled' => [ + '#node1 - A missing extension should always be disabled and unchecked, even a mandatory extension included in package' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext1' => [ 'installed' => true, + 'source' => 'datamodels', // iTopExtension::SOURCE_WIZARD ], ], 'aWizardStepDefinition' => [ 'extension_code' => 'itop-ext1', - 'mandatory' => false, + 'mandatory' => true, + 'missing' => true, 'uninstallable' => true, ], - 'bCurrentSelected' => false, + 'aSelectedComponents' => [], 'bDisableUninstallChecks' => false, 'aExpectedFlags' => [ 'uninstallable' => true, - 'missing' => false, + 'missing' => true, 'installed' => true, - 'disabled' => false, + 'disabled' => true, 'checked' => false, 'dependency_issue' => false, - 'mandatory' => false, + 'mandatory' => true, ], ], - 'An installed non uninstallable extension should be checked and disabled' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => true, - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => false, - 'uninstallable' => false, - ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => false, - 'aExpectedFlags' => [ - 'uninstallable' => false, - 'missing' => false, - 'installed' => true, - 'disabled' => true, - 'checked' => true, - 'dependency_issue' => false, - 'mandatory' => false, - ], - ], - 'An installed non uninstallable extension should be enabled if the "disable uninstallation check" flag is set' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => true, - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => false, - 'uninstallable' => false, - ], - 'bCurrentSelected' => true, - 'bDisableUninstallChecks' => true, - 'aExpectedFlags' => [ - 'uninstallable' => false, - 'missing' => false, - 'installed' => true, - 'disabled' => false, - 'checked' => true, - 'dependency_issue' => false, - 'mandatory' => false, - ], - ], - 'A mandatory extension should be checked and disabled' => [ + '#node2 - A mandatory extension included in package should be checked and disabled even if the "disable uninstallation check" flag is set' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext1' => [ 'installed' => false, + 'source' => 'datamodels', // iTopExtension::SOURCE_WIZARD ], ], 'aWizardStepDefinition' => [ @@ -220,30 +93,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'mandatory' => true, 'uninstallable' => true, ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => false, - 'aExpectedFlags' => [ - 'uninstallable' => true, - 'missing' => false, - 'installed' => false, - 'disabled' => true, - 'checked' => true, - 'dependency_issue' => false, - 'mandatory' => true, - ], - ], - 'A mandatory extension should be checked and disabled even if the "disable uninstallation check" flag is set' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => false, - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => true, - 'uninstallable' => true, - ], - 'bCurrentSelected' => false, + 'aSelectedComponents' => [], 'bDisableUninstallChecks' => true, 'aExpectedFlags' => [ 'uninstallable' => true, @@ -255,77 +105,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'mandatory' => true, ], ], - 'An optional sub extension should not force its parent flags' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => false, - ], - 'itop-ext1-1' => [ - 'installed' => false, - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => false, - 'uninstallable' => true, - 'sub_options' => [ - 'options' => [ - [ - 'extension_code' => 'itop-ext1-1', - 'mandatory' => false, - 'uninstallable' => true, - ], - ], - ], - ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => false, - 'aExpectedFlags' => [ - 'uninstallable' => true, - 'missing' => false, - 'installed' => false, - 'disabled' => false, - 'checked' => false, - 'dependency_issue' => false, - 'mandatory' => false, - ], - ], - 'A mandatory sub extension should force its parent to be checked and disabled' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => false, - ], - 'itop-ext1-1' => [ - 'installed' => false, - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => false, - 'uninstallable' => true, - 'sub_options' => [ - 'options' => [ - [ - 'extension_code' => 'itop-ext1-1', - 'mandatory' => true, - 'uninstallable' => true, - ], - ], - ], - ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => false, - 'aExpectedFlags' => [ - 'uninstallable' => true, - 'missing' => false, - 'installed' => false, - 'disabled' => true, - 'checked' => true, - 'dependency_issue' => false, - 'mandatory' => false, - ], - ], - 'An installed non uninstallable sub extension should force its parent to be checked and disabled' => [ + '#node3 - An installed non uninstallable sub extension should force its parent to be checked and disabled' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext1' => [ 'installed' => true, @@ -336,19 +116,17 @@ class WizStepModulesChoiceTest extends ItopTestCase ], 'aWizardStepDefinition' => [ 'extension_code' => 'itop-ext1', - 'mandatory' => false, 'uninstallable' => true, 'sub_options' => [ 'options' => [ [ 'extension_code' => 'itop-ext1-1', - 'mandatory' => false, 'uninstallable' => false, ], ], ], ], - 'bCurrentSelected' => false, + 'aSelectedComponents' => ['_0' => '_0', '_0_0' => '_0_0'], 'bDisableUninstallChecks' => false, 'aExpectedFlags' => [ 'uninstallable' => true, @@ -360,7 +138,495 @@ class WizStepModulesChoiceTest extends ItopTestCase 'mandatory' => false, ], ], - 'A non installed non uninstallable sub extension should not force its parent flags' => [ + '#node3 - An installed remote sub extension should force its parent to be checked and disabled' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + ], + 'itop-ext1-1' => [ + 'installed' => true, + 'source' => 'data', // iTopExtension::SOURCE_REMOTE + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + 'sub_options' => [ + 'options' => [ + [ + 'extension_code' => 'itop-ext1-1', + 'uninstallable' => true, + ], + ], + ], + ], + 'aSelectedComponents' => ['_0' => '_0', '_0_0' => '_0_0'], + 'bDisableUninstallChecks' => false, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => true, + 'disabled' => true, + 'checked' => true, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node4 - An installed uninstallable sub extension should force its parent to be checked but not disabled' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => false, + ], + 'itop-ext1-1' => [ + 'installed' => true, + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + 'sub_options' => [ + 'options' => [ + [ + 'extension_code' => 'itop-ext1-1', + 'uninstallable' => true, + ], + ], + ], + ], + 'aSelectedComponents' => ['_0_0' => '_0_0'], + 'bDisableUninstallChecks' => false, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => false, + 'disabled' => false, + 'checked' => true, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node4 - An installed non uninstallable sub extension should force its parent to be checked but not disabled if the "disable uninstallation check" flag is set' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + ], + 'itop-ext1-1' => [ + 'installed' => true, + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + 'sub_options' => [ + 'options' => [ + [ + 'extension_code' => 'itop-ext1-1', + 'uninstallable' => false, + ], + ], + ], + ], + 'aSelectedComponents' => ['_0' => '_0', '_0_0' => '_0_0'], + 'bDisableUninstallChecks' => true, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => true, + 'disabled' => false, + 'checked' => true, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node4 - An installed remote sub extension should force its parent to be checked but not disabled if the "disable uninstallation check" flag is set' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + ], + 'itop-ext1-1' => [ + 'installed' => true, + 'source' => 'data', // iTopExtension::SOURCE_REMOTE + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + 'sub_options' => [ + 'options' => [ + [ + 'extension_code' => 'itop-ext1-1', + 'uninstallable' => true, + ], + ], + ], + ], + 'aSelectedComponents' => ['_0' => '_0', '_0_0' => '_0_0'], + 'bDisableUninstallChecks' => true, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => true, + 'disabled' => false, + 'checked' => true, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node5 - A non installed extension with missing dependencies should be not checked and disabled' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => false, + 'missing_dependencies' => [ + 'itop-ext1-1', + ], + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + 'missing_dependencies' => true, + ], + 'aSelectedComponents' => [], + 'bDisableUninstallChecks' => false, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => false, + 'disabled' => true, + 'checked' => false, + 'dependency_issue' => true, + 'mandatory' => false, + ], + ], + '#node5 - A non installed extension with missing dependencies should be not checked and disabled even with force uninstall' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => false, + 'missing_dependencies' => [ + 'itop-ext1-1', + ], + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + 'missing_dependencies' => true, + ], + 'aSelectedComponents' => [], + 'bDisableUninstallChecks' => true, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => false, + 'disabled' => true, + 'checked' => false, + 'dependency_issue' => true, + 'mandatory' => false, + ], + ], + '#node6 - An installed extension with missing dependencies and without force uninstall should be checked and disabled' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + 'missing_dependencies' => [ + 'itop-ext1-1', + ], + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + 'missing_dependencies' => true, + ], + 'aSelectedComponents' => ['_0' => '_0'], + 'bDisableUninstallChecks' => false, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => true, + 'disabled' => true, + 'checked' => true, + 'dependency_issue' => true, + 'mandatory' => false, + ], + ], + '#node7 - An installed extension with missing dependencies and with force uninstall should be checked and enabled' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + 'missing_dependencies' => [ + 'itop-ext1-1', + ], + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + 'missing_dependencies' => true, + ], + 'aSelectedComponents' => ['_0' => '_0'], + 'bDisableUninstallChecks' => true, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => true, + 'disabled' => false, + 'checked' => true, + 'dependency_issue' => true, + 'mandatory' => false, + ], + ], + '#node8 - An installed but not selected extension with missing dependencies and with force uninstall should be unchecked and enabled' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + 'missing_dependencies' => [ + 'itop-ext1-1', + ], + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + 'missing_dependencies' => true, + ], + 'aSelectedComponents' => [], + 'bDisableUninstallChecks' => true, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => true, + 'disabled' => false, + 'checked' => false, + 'dependency_issue' => true, + 'mandatory' => false, + ], + ], + '#node9 - A not selected, not installed extension should not be checked and be enabled' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => false, + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + ], + 'aSelectedComponents' => [], + 'bDisableUninstallChecks' => false, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => false, + 'disabled' => false, + 'checked' => false, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node10 - A selected but not installed extension should be checked and enabled' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => false, + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + ], + 'aSelectedComponents' => ['_0' => '_0'], + 'bDisableUninstallChecks' => false, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => false, + 'disabled' => false, + 'checked' => true, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node11 - An installed but not selected extension should not be checked and be enabled' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + ], + 'aSelectedComponents' => [], + 'bDisableUninstallChecks' => false, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => true, + 'disabled' => false, + 'checked' => false, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node12 - An installed and selected extension should be checked and enabled' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + 'missing_dependencies' => false, + ], + 'aSelectedComponents' => ['_0' => '_0'], + 'bDisableUninstallChecks' => false, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => true, + 'disabled' => false, + 'checked' => true, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node13 - An installed non uninstallable extension should be checked and disabled' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => false, + ], + 'aSelectedComponents' => ['_0' => '_0'], + 'bDisableUninstallChecks' => false, + 'aExpectedFlags' => [ + 'uninstallable' => false, + 'missing' => false, + 'installed' => true, + 'disabled' => true, + 'checked' => true, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node13 - An installed remote extension should be checked and disabled' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + 'source' => 'data', // iTopExtension::SOURCE_REMOTE + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + ], + 'aSelectedComponents' => ['_0' => '_0'], + 'bDisableUninstallChecks' => false, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => true, + 'disabled' => true, + 'checked' => true, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node14 - An installed but not selected non uninstallable extension should be checked and enabled if the "disable uninstallation check" flag is set' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => false, + ], + 'aSelectedComponents' => [], + 'bDisableUninstallChecks' => true, + 'aExpectedFlags' => [ + 'uninstallable' => false, + 'missing' => false, + 'installed' => true, + 'disabled' => false, + 'checked' => false, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node14 - An installed but not selected remote extension should be checked and enabled if the "disable uninstallation check" flag is set' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + 'source' => 'data', // iTopExtension::SOURCE_REMOTE + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + ], + 'aSelectedComponents' => [], + 'bDisableUninstallChecks' => true, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => true, + 'disabled' => false, + 'checked' => false, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node15 - An installed non uninstallable extension should be checked and enabled if the "disable uninstallation check" flag is set' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => false, + ], + 'aSelectedComponents' => ['_0' => '_0'], + 'bDisableUninstallChecks' => true, + 'aExpectedFlags' => [ + 'uninstallable' => false, + 'missing' => false, + 'installed' => true, + 'disabled' => false, + 'checked' => true, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node15 - An installed remote extension should be checked and enabled if the "disable uninstallation check" flag is set' => [ + 'aExtensionsOnDiskOrDb' => [ + 'itop-ext1' => [ + 'installed' => true, + 'source' => 'data', // iTopExtension::SOURCE_REMOTE + ], + ], + 'aWizardStepDefinition' => [ + 'extension_code' => 'itop-ext1', + 'uninstallable' => true, + ], + 'aSelectedComponents' => ['_0' => '_0'], + 'bDisableUninstallChecks' => true, + 'aExpectedFlags' => [ + 'uninstallable' => true, + 'missing' => false, + 'installed' => true, + 'disabled' => false, + 'checked' => true, + 'dependency_issue' => false, + 'mandatory' => false, + ], + ], + '#node16 - A non installed non uninstallable sub extension should not force its parent flags' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext1' => [ 'installed' => true, @@ -371,19 +637,17 @@ class WizStepModulesChoiceTest extends ItopTestCase ], 'aWizardStepDefinition' => [ 'extension_code' => 'itop-ext1', - 'mandatory' => false, 'uninstallable' => true, 'sub_options' => [ 'options' => [ [ 'extension_code' => 'itop-ext1-1', - 'mandatory' => false, 'uninstallable' => false, ], ], ], ], - 'bCurrentSelected' => false, + 'aSelectedComponents' => [], 'bDisableUninstallChecks' => false, 'aExpectedFlags' => [ 'uninstallable' => true, @@ -395,49 +659,29 @@ class WizStepModulesChoiceTest extends ItopTestCase 'mandatory' => false, ], ], - 'A non installed and non mandatory extension with missing dependencies and without force uninstall should be not checked and disabled' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => false, - 'missing_dependencies' => [ - 'itop-ext1-1', - ], - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => false, - 'uninstallable' => true, - 'missing_dependencies' => true, - ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => false, - 'aExpectedFlags' => [ - 'uninstallable' => true, - 'missing' => false, - 'installed' => false, - 'disabled' => true, - 'checked' => false, - 'dependency_issue' => true, - 'mandatory' => false, - ], - ], - 'An installed non mandatory extension with missing dependencies and without force uninstall should be not checked and enabled' => [ + '#node16 - A non installed remote sub extension should not force its parent flags' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext1' => [ 'installed' => true, - 'missing_dependencies' => [ - 'itop-ext1-1', - ], + ], + 'itop-ext1-1' => [ + 'installed' => false, + 'source' => 'data', // iTopExtension::SOURCE_REMOTE ], ], 'aWizardStepDefinition' => [ 'extension_code' => 'itop-ext1', - 'mandatory' => false, 'uninstallable' => true, - 'missing_dependencies' => true, + 'sub_options' => [ + 'options' => [ + [ + 'extension_code' => 'itop-ext1-1', + 'uninstallable' => true, + ], + ], + ], ], - 'bCurrentSelected' => false, + 'aSelectedComponents' => [], 'bDisableUninstallChecks' => false, 'aExpectedFlags' => [ 'uninstallable' => true, @@ -445,196 +689,23 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => true, 'disabled' => false, 'checked' => false, - 'dependency_issue' => true, + 'dependency_issue' => false, 'mandatory' => false, ], ], - 'An installed non mandatory and not uninstallable extension with missing dependencies and without force uninstall should be not checked and disabled' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => true, - 'missing_dependencies' => [ - 'itop-ext1-1', - ], - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => false, - 'uninstallable' => false, - 'missing_dependencies' => true, - ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => false, - 'aExpectedFlags' => [ - 'uninstallable' => false, - 'missing' => false, - 'installed' => true, - 'disabled' => true, - 'checked' => false, - 'dependency_issue' => true, - 'mandatory' => false, - ], - ], - 'A non installed and non mandatory extension with missing dependencies and force uninstall should be not checked and enabled' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => false, - 'missing_dependencies' => [ - 'itop-ext1-1', - ], - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => false, - 'uninstallable' => true, - 'missing_dependencies' => true, - ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => true, - 'aExpectedFlags' => [ - 'uninstallable' => true, - 'missing' => false, - 'installed' => false, - 'disabled' => false, - 'checked' => false, - 'dependency_issue' => true, - 'mandatory' => false, - ], - ], - 'An installed non mandatory extension with missing dependencies and force uninstall should be not checked and enabled' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => true, - 'missing_dependencies' => [ - 'itop-ext1-1', - ], - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => false, - 'uninstallable' => true, - 'missing_dependencies' => true, - ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => true, - 'aExpectedFlags' => [ - 'uninstallable' => true, - 'missing' => false, - 'installed' => true, - 'disabled' => false, - 'checked' => false, - 'dependency_issue' => true, - 'mandatory' => false, - ], - ], - 'An installed mandatory extension with missing dependencies and without force uninstall should be checked and disabled' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => true, - 'missing_dependencies' => [ - 'itop-ext1-1', - ], - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => true, - 'uninstallable' => true, - 'missing_dependencies' => true, - ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => false, - 'aExpectedFlags' => [ - 'uninstallable' => true, - 'missing' => false, - 'installed' => true, - 'disabled' => true, - 'checked' => true, - 'dependency_issue' => true, - 'mandatory' => true, - ], - ], - 'An non installed mandatory extension with missing dependencies and without force uninstall should be checked and disabled' => [ - 'aExtensionsOnDiskOrDb' => [ - 'itop-ext1' => [ - 'installed' => false, - 'missing_dependencies' => [ - 'itop-ext1-1', - ], - ], - ], - 'aWizardStepDefinition' => [ - 'extension_code' => 'itop-ext1', - 'mandatory' => true, - 'uninstallable' => true, - 'missing_dependencies' => true, - ], - 'bCurrentSelected' => false, - 'bDisableUninstallChecks' => false, - 'aExpectedFlags' => [ - 'uninstallable' => true, - 'missing' => false, - 'installed' => false, - 'disabled' => true, - 'checked' => true, - 'dependency_issue' => true, - 'mandatory' => true, - ], - ], ]; } /** * @dataProvider ProviderComputeChoiceFlags */ - public function testComputeChoiceFlags($aExtensionsOnDiskOrDb, $aWizardStepDefinition, $bIsCurrentSelected, $bDisableUninstallChecks, $aExpectedFlags) + public function testComputeChoiceFlags($aExtensionsOnDiskOrDb, $aWizardStepDefinition, $aSelectedComponents, $bDisableUninstallChecks, $aExpectedFlags) { $this->oWizStepModulesChoiceFake->setExtensionMap(iTopExtensionsMapFake::createFromArray($aExtensionsOnDiskOrDb)); - $aFlags = $this->oWizStepModulesChoiceFake->ComputeChoiceFlags($aWizardStepDefinition, '_0', $bIsCurrentSelected ? ['_0' => '_0'] : [], false, $bDisableUninstallChecks); + $aFlags = $this->oWizStepModulesChoiceFake->ComputeChoiceFlags($aWizardStepDefinition, '_0', $aSelectedComponents, false, $bDisableUninstallChecks); $this->assertEquals($aExpectedFlags, $aFlags); } - public function ProviderGetAllExtensionsToDisplayInSetupMandatoryFlag() - { - return [ - 'A manually added extension should not be mandatory by default' => [ - 'bExtensionSource' => 'extensions',//iTopExtension::SOURCE_MANUAL - 'bDisableUninstallChecks' => false, - 'bExpectedMandatory' => false, - ], - 'A remotely added extension should be mandatory by default' => [ - 'bExtensionSource' => 'data',//iTopExtension::SOURCE_REMOTE - 'bDisableUninstallChecks' => false, - 'bExpectedMandatory' => true, - ], - 'A remotely added extension should not be mandatory by default if uninstall checks has been disabled' => [ - 'bExtensionSource' => 'data',//iTopExtension::SOURCE_REMOTE - 'bDisableUninstallChecks' => true, - 'bExpectedMandatory' => false, - ], - - ]; - } - - /** - * @dataProvider ProviderGetAllExtensionsToDisplayInSetupMandatoryFlag - */ - public function testGetAllExtensionsToDisplayInSetupMandatoryFlag($bExtensionSource, $bDisableUninstallChecks, $bExpectedMandatory) - { - $aExtensionsOnDiskOrDb = [ - 'itop-ext1' => [ - 'installed' => true, - 'source' => $bExtensionSource, - ], - ]; - $oMap = iTopExtensionsMapFake::createFromArray($aExtensionsOnDiskOrDb); - $aExtensions = $oMap->GetAllExtensionsToDisplayInSetup(false, !$bDisableUninstallChecks); - $this->assertEquals($bExpectedMandatory, $aExtensions['itop-ext1']->bMandatory); - } - public function ProviderGetAddedAndRemovedExtensions() { return [ @@ -1200,7 +1271,6 @@ class WizStepModulesChoiceTest extends ItopTestCase 'description' => 'Do something', 'more_info' => '', 'modules' => [], - 'mandatory' => false, 'source_label' => 'Local extensions folder', 'uninstallable' => true, 'missing' => false, @@ -1244,7 +1314,6 @@ HTML, 'description' => 'Do something', 'more_info' => '', 'modules' => [], - 'mandatory' => false, 'source_label' => 'Local extensions folder', 'uninstallable' => true, 'missing' => false, @@ -1289,7 +1358,6 @@ HTML, 'description' => 'Do something', 'more_info' => '', 'modules' => [], - 'mandatory' => false, 'source_label' => 'Local extensions folder', 'uninstallable' => false, 'missing' => false, @@ -1298,7 +1366,7 @@ HTML, ], 'aStepAlternatives' => [], - 'aSelectedComponents' => [], + 'aSelectedComponents' => ['_0' => '_0'], 'aDefaults' => [], 'aExpectedHTML' => << -HTML, - ], - 'one mandatory extension' => [ - 'aStepOptions' => [ - [ - 'extension_code' => 'itop-ext-not-installed', - 'title' => 'My extension', - 'description' => 'Do something', - 'more_info' => '', - 'modules' => [], - 'mandatory' => true, - 'source_label' => 'Local extensions folder', - 'uninstallable' => true, - 'missing' => false, - 'version' => '1.2.3', - ], - ], - 'aStepAlternatives' => [], - - 'aSelectedComponents' => [], - 'aDefaults' => [], - 'aExpectedHTML' => << -
- - -
-
-
- - -
to be installed
not installed
-
-
- v1.2.3Local extensions folder -
-
- Do something - -
-
- - HTML, ], 'one choice alternative' => [ @@ -1490,7 +1514,6 @@ HTML, 'description' => 'Do something', 'more_info' => '', 'modules' => [], - 'mandatory' => false, //'source_label' => '', 'uninstallable' => true, 'missing' => false, diff --git a/tests/php-unit-tests/unitary-tests/setup/ressources/compute_choice_flags.flowchart.fun b/tests/php-unit-tests/unitary-tests/setup/ressources/compute_choice_flags.flowchart.fun new file mode 100644 index 0000000000..aad4280f2f --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/setup/ressources/compute_choice_flags.flowchart.fun @@ -0,0 +1,33 @@ +Removed from disk + Yes : Installed + No : Do not show extension .color_grey + Yes : Forced uninstallation, unchecked & disabled .color_red #node1 + No : Mandatory & part of package + Yes : Forced installation, checked & disabled .color_orange #node2 + No : Has sub options + Yes : Sub option checked + Yes : Sub option disabled + Yes : checked & disabled .color_orange #node3 + No : force checked .color_yellow #node4 + #node16 No : (Dependency issue) + No : Dependency issue + Yes : Installed + No : unchecked & disabled .color_orange #node5 + Yes : Force uninstall + No : checked & disabled .color_orange #node6 + Yes : Selected + Yes : checked & enabled .color_green #node7 + No : unchecked & enabled .color_green #node8 + No : Installed + No : Selected + No : unchecked & enabled .color_green #node9 + Yes : checked & enabled .color_green #node10 + Yes : Remote | cannot_be_uninstalled + No : Selected + No : unchecked & enabled .color_green #node11 + Yes : checked & enabled .color_green #node12 + Yes : Force uninstall + No : checked & disabled .color_orange #node13 + Yes : Selected + No : unchecked & enabled .color_green #node14 + Yes : checked & enabled .color_green #node15