RequireOnceItopFile('/setup/unattended-install/InstallationFileService.php'); require_once __DIR__.'/WebPageFake.php'; require_once __DIR__.'/iTopExtensionsMapFake.php'; require_once __DIR__.'/WizStepModulesChoiceFake.php'; $this->oWizard = new WizardController('', ''); $this->oWizStepModulesChoiceFake = new WizStepModulesChoiceFake($this->oWizard, ''); ModuleDiscovery::ResetCache(); } /** * 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 [ '#node1 - A missing extension should be disabled and unchecked' => [ 'aExtensionsOnDiskOrDb' => [ ], 'aWizardStepDefinition' => [ 'extension_code' => 'itop-ext1', 'missing' => true, 'uninstallable' => true, ], 'aSelectedComponents' => [], 'bDisableUninstallChecks' => false, 'aExpectedFlags' => [ 'uninstallable' => true, 'missing' => true, 'installed' => true, 'disabled' => true, 'checked' => false, 'dependency_issue' => false, 'mandatory' => false, ], ], '#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' => true, 'missing' => true, 'uninstallable' => true, ], 'aSelectedComponents' => [], 'bDisableUninstallChecks' => false, 'aExpectedFlags' => [ 'uninstallable' => true, 'missing' => true, 'installed' => true, 'disabled' => true, 'checked' => false, 'dependency_issue' => false, 'mandatory' => true, ], ], '#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' => [ 'extension_code' => 'itop-ext1', 'mandatory' => true, 'uninstallable' => true, ], 'aSelectedComponents' => [], 'bDisableUninstallChecks' => true, 'aExpectedFlags' => [ 'uninstallable' => true, 'missing' => false, 'installed' => false, 'disabled' => true, 'checked' => true, 'dependency_issue' => false, 'mandatory' => true, ], ], '#node3 - An installed non uninstallable sub extension should force its parent to be checked and disabled' => [ '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' => false, 'aExpectedFlags' => [ 'uninstallable' => true, 'missing' => false, 'installed' => true, 'disabled' => true, 'checked' => true, 'dependency_issue' => false, 'mandatory' => false, ], ], '#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, ], 'itop-ext1-1' => [ 'installed' => false, ], ], 'aWizardStepDefinition' => [ 'extension_code' => 'itop-ext1', 'uninstallable' => true, 'sub_options' => [ 'options' => [ [ 'extension_code' => 'itop-ext1-1', 'uninstallable' => false, ], ], ], ], 'aSelectedComponents' => [], 'bDisableUninstallChecks' => false, 'aExpectedFlags' => [ 'uninstallable' => true, 'missing' => false, 'installed' => true, 'disabled' => false, 'checked' => false, 'dependency_issue' => false, 'mandatory' => false, ], ], '#node16 - A non installed remote sub extension should not force its parent flags' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext1' => [ 'installed' => true, ], 'itop-ext1-1' => [ 'installed' => false, 'source' => 'data', // iTopExtension::SOURCE_REMOTE ], ], 'aWizardStepDefinition' => [ 'extension_code' => 'itop-ext1', 'uninstallable' => true, 'sub_options' => [ 'options' => [ [ 'extension_code' => 'itop-ext1-1', 'uninstallable' => true, ], ], ], ], 'aSelectedComponents' => [], 'bDisableUninstallChecks' => false, 'aExpectedFlags' => [ 'uninstallable' => true, 'missing' => false, 'installed' => true, 'disabled' => false, 'checked' => false, 'dependency_issue' => false, 'mandatory' => false, ], ], '#node17 - An installed non uninstallable extension should be checked and disabled when the "disable uninstallation check" flag is not set, even if it is not selected' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext1' => [ 'installed' => true, ], ], 'aWizardStepDefinition' => [ 'extension_code' => 'itop-ext1', 'uninstallable' => false, ], 'aSelectedComponents' => [], 'bDisableUninstallChecks' => false, 'aExpectedFlags' => [ 'uninstallable' => false, 'missing' => false, 'installed' => true, 'disabled' => true, 'checked' => true, 'dependency_issue' => false, 'mandatory' => false, ], ], '#node18 - An installed but not selected extension with missing dependencies without force uninstall should be checked and disabled, even if it is not selected' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext1' => [ 'installed' => true, 'missing_dependencies' => [ 'itop-ext1-1', ], ], ], 'aWizardStepDefinition' => [ 'extension_code' => 'itop-ext1', 'uninstallable' => true, 'missing_dependencies' => true, ], 'aSelectedComponents' => [], 'bDisableUninstallChecks' => false, 'aExpectedFlags' => [ 'uninstallable' => true, 'missing' => false, 'installed' => true, 'disabled' => true, 'checked' => true, 'dependency_issue' => true, 'mandatory' => false, ], ], ]; } /** * @dataProvider ProviderComputeChoiceFlags */ public function testComputeChoiceFlags($aExtensionsOnDiskOrDb, $aWizardStepDefinition, $aSelectedComponents, $bDisableUninstallChecks, $aExpectedFlags) { $this->oWizStepModulesChoiceFake->setExtensionMap(iTopExtensionsMapFake::createFromArray($aExtensionsOnDiskOrDb)); $aFlags = $this->oWizStepModulesChoiceFake->ComputeChoiceFlags($aWizardStepDefinition, '_0', $aSelectedComponents, false, $bDisableUninstallChecks); $this->assertEquals($aExpectedFlags, $aFlags); } public function ProviderGetAddedAndRemovedExtensions() { return [ 'no extensions' => [ 'aExtensionsOnDiskOrDb' => [], 'aSelected' => [], 'aExpectedAddedList' => [], 'aExpectedRemovedList' => [], ], 'no extensions added nor removed' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext1' => [ 'installed' => false, ], ], 'aSelected' => [], 'aExpectedAddedList' => [], 'aExpectedRemovedList' => [], ], 'One added extension' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext1' => [ 'installed' => false, ], ], 'aSelected' => ['itop-ext1'], 'aExpectedAddedList' => ['itop-ext1' => 'itop-ext1'], 'aExpectedRemovedList' => [], ], 'One removed extension' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext1' => [ 'installed' => true, ], ], 'aSelected' => [], 'aExpectedAddedList' => [], 'aExpectedRemovedList' => ['itop-ext1' => 'itop-ext1'], ], 'Forced removed extension' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext1' => [ 'installed' => true, 'uninstallable' => false, ], ], 'aSelected' => [], 'aExpectedAddedList' => [], 'aExpectedRemovedList' => ['itop-ext1' => 'itop-ext1'], ], 'added and removed extensions' => [ 'aExtensionsOnDiskOrDb' => [ 'itop-ext-added1' => [ 'installed' => false, ], 'itop-ext-added2' => [ 'installed' => false, ], 'itop-ext-removed1' => [ 'installed' => true, ], 'itop-ext-removed2' => [ 'installed' => true, ], ], 'aSelected' => ['itop-ext-added1', 'itop-ext-added2'], 'aExpectedAddedList' => ['itop-ext-added1' => 'itop-ext-added1', 'itop-ext-added2' => 'itop-ext-added2'], 'aExpectedRemovedList' => ['itop-ext-removed1' => 'itop-ext-removed1', 'itop-ext-removed2' => 'itop-ext-removed2'], ], ]; } /** * @dataProvider ProviderGetAddedAndRemovedExtensions */ public function testGetAddedAndRemovedExtensions($aExtensionsOnDiskOrDb, $aSelectedExtensions, $aExpectedAddedList, $aExpectedRemovedList) { $this->oWizStepModulesChoiceFake->setExtensionMap(iTopExtensionsMapFake::createFromArray($aExtensionsOnDiskOrDb)); [$aAddedList, $aRemovedList, $aNotUninstallableList] = $this->oWizStepModulesChoiceFake->GetAddedAndRemovedExtensions($aSelectedExtensions); $this->assertEquals($aExpectedAddedList, $aAddedList); $this->assertEquals($aExpectedRemovedList, $aRemovedList); } public function testGetStepInfo_PackageWithoutInstallationXML() { $aExtensionsOnDiskOrDb = self::GivenExtensionsOnDisk(); $oWizStepModulesChoice = $this->GivenWizStepModulesChoiceWithoutXmlInstallation($aExtensionsOnDiskOrDb); $expected = [ 'title' => 'Modules Selection', 'description' => '