RequireOnceItopFile('/setup/unattended-install/InstallationFileService.php'); ModuleDiscovery::ResetCache(); } public function testGetAllExtensionsWithPreviouslyInstalledDoesNotCrash() { $oExtensionsMap = iTopExtensionsMap::GetExtensionsMap(); $aExtensions = $oExtensionsMap->GetAllExtensionsWithPreviouslyInstalled(); $this->assertGreaterThan(0, count($aExtensions)); } public function testGetAllExtensionsToDisplayInSetup() { $oExtensionsMap = $this->GiveExtensionMapWithAllTypeOfExtensions(); $aExtensions = $oExtensionsMap->GetAllExtensionsToDisplayInSetup(); $expected = [ 'installed_ext1', 'ext1', ]; $this->assertEquals($expected, array_keys($aExtensions)); } public function testGetAllExtensionsToDisplayInSetup_WithExtensionsHavingDependencyIssues() { $oExtensionsMap = $this->GiveExtensionMapWithAllTypeOfExtensions(); $aExtensions = $oExtensionsMap->GetAllExtensionsToDisplayInSetup(true); $expected = [ 'installed_ext1', 'installed_ext_with_deps_issues', 'ext1', 'ext_with_deps_issues', ]; $this->assertEquals($expected, array_keys($aExtensions)); } public function testGetAllExtensionsToDisplayInSetup_LegacyPackage() { $oExtensionsMap = $this->GiveExtensionMapWithAllTypeOfExtensions(); $this->SetNonPublicProperty($oExtensionsMap, 'bHasXmlInstallationFile', false); $aExtensions = $oExtensionsMap->GetAllExtensionsToDisplayInSetup(); $expected = [ 'installed_ext1', 'installed_ext_in_package', 'ext1', 'ext_in_package', ]; $this->assertEquals($expected, array_keys($aExtensions)); } public function testGetAllExtensionsToDisplayInSetup_LegacyPackage_WithExtensionsHavingDependencyIssues() { $oExtensionsMap = $this->GiveExtensionMapWithAllTypeOfExtensions(); $this->SetNonPublicProperty($oExtensionsMap, 'bHasXmlInstallationFile', false); $aExtensions = $oExtensionsMap->GetAllExtensionsToDisplayInSetup(true); $expected = [ 'installed_ext1', 'installed_ext_in_package', 'installed_ext_with_deps_issues', 'ext1', 'ext_in_package', 'ext_with_deps_issues', ]; $this->assertEquals($expected, array_keys($aExtensions)); } private function GiveExtensionMapWithAllTypeOfExtensions(): iTopExtensionsMap { $oExtensionsMap = iTopExtensionsMap::GetExtensionsMap(); $this->SetNonPublicProperty($oExtensionsMap, 'aInstalledExtensions', []); $this->SetNonPublicProperty($oExtensionsMap, 'aExtensions', []); $this->AddExtension( $oExtensionsMap, $this->GivenExtension("installed_ext1", "123", true, iTopExtension::SOURCE_REMOTE, true, []), 'aInstalledExtensions' ); $this->AddExtension( $oExtensionsMap, $this->GivenExtension("installed_notvisible", "123", false, iTopExtension::SOURCE_REMOTE, true, []), 'aInstalledExtensions' ); $this->AddExtension( $oExtensionsMap, $this->GivenExtension("installed_ext_in_package", "123", true, iTopExtension::SOURCE_WIZARD, true, []), 'aInstalledExtensions' ); $this->AddExtension( $oExtensionsMap, $this->GivenExtension("installed_ext_with_deps_issues", "123", true, iTopExtension::SOURCE_REMOTE, true, ["aa"]), 'aInstalledExtensions' ); $this->AddExtension( $oExtensionsMap, $this->GivenExtension("ext1", "123", true, iTopExtension::SOURCE_REMOTE, true, []), 'aExtensions' ); $this->AddExtension( $oExtensionsMap, $this->GivenExtension("notvisible", "123", false, iTopExtension::SOURCE_REMOTE, true, []), 'aExtensions' ); $this->AddExtension( $oExtensionsMap, $this->GivenExtension("ext_in_package", "123", true, iTopExtension::SOURCE_WIZARD, true, []), 'aExtensions' ); $this->AddExtension( $oExtensionsMap, $this->GivenExtension("ext_with_deps_issues", "123", true, iTopExtension::SOURCE_REMOTE, true, ["aa"]), 'aExtensions' ); return $oExtensionsMap; } private function GivenExtension(string $sCode, string $sVersion, bool $bVisible, string $sSource, bool $bMandatory, array $aMissingDependencies = []): iTopExtension { $oExt = new iTopExtension(); $oExt->sCode = $sCode; $oExt->sVersion = $sVersion; $oExt->bVisible = $bVisible; $oExt->sSource = $sSource; $oExt->aMissingDependencies = $aMissingDependencies; $oExt->bMandatory = $bMandatory; return $oExt; } private function AddExtension(iTopExtensionsMap $oExtensionsMap, iTopExtension $oExt, string $mapKeyInItopExtensionMap) { $aMap = $this->GetNonPublicProperty($oExtensionsMap, $mapKeyInItopExtensionMap); $aMap[$oExt->sCode.'/'.$oExt->sVersion] = $oExt; $this->SetNonPublicProperty($oExtensionsMap, $mapKeyInItopExtensionMap, $aMap); } public function testiTopExtensionsMapInit() { $oiTopExtensionsMap = iTopExtensionsMap::GetExtensionsMap(sAppRootForTests: __DIR__."/ressources/"); $sExpected = file_get_contents(__DIR__.'/ressources/all_extensions_from_datamodels.json'); $sExpected = str_replace('"sVersion": "ITOP_VERSION"', '"sVersion": "'.ITOP_VERSION.'"', $sExpected); $sExpected = preg_replace('/"module_file_path": .*/', '"module_file_path": ANYPATH', $sExpected); $actual = json_encode($this->SerializeExtensionMap($oiTopExtensionsMap), JSON_PRETTY_PRINT); $actual = preg_replace('/"module_file_path": .*/', '"module_file_path": ANYPATH', $actual); $this->assertEquals($sExpected, $actual); } public function testGetScannedModulesRootDirs() { $sAppRootForTest = __DIR__."/resources2/"; $oiTopExtensionsMap = iTopExtensionsMap::GetExtensionsMap(sAppRootForTests: $sAppRootForTest); $aExpectedDirs = [ "{$sAppRootForTest}datamodels/2.x", "{$sAppRootForTest}extensions", "{$sAppRootForTest}data/production-modules", ]; self::assertEquals($aExpectedDirs, $oiTopExtensionsMap->GetScannedModulesRootDirs()); } public function testCheckExtensionsValidityReturnsFalseWhenSelectedExtensionCodeAndLabelAreMissing(): void { [$sEnvironment, $sExtensionsDirRelative] = $this->CreateFixtureContext('env-missing-label-'); $sInvalidExtensionXml = << Test extension without code and label 1.0.0 false XML; $sExtensionsDirAbsolute = APPROOT.$sExtensionsDirRelative; file_put_contents($sExtensionsDirAbsolute.'/extension.xml', $sInvalidExtensionXml); $oExtensionMap = ItopExtensionsMap::GetExtensionsMap($sEnvironment); //echo json_encode(array_keys($oExtensionMap->GetAllExtensions()), JSON_PRETTY_PRINT); // $this->expectException(CoreException::class); // $this->expectExceptionMessage("Selected extension(s) cannot be installed: Missing extension code ($sExtensionsDirAbsolute)"); self::assertFalse($oExtensionMap->CheckExtensionsValidity(), 'Check extensions validity should have detected an extension without code.'); } public function testCheckExtensionsValidityReturnsFalseWhenSelectedExtensionCodeIsMissing(): void { [$sEnvironment, $sExtensionsDirRelative] = $this->CreateFixtureContext('env-missing-label-'); $sInvalidExtensionXml = << Test extension without code and label 1.0.0 false XML; $sExtensionsDirAbsolute = APPROOT.$sExtensionsDirRelative; file_put_contents($sExtensionsDirAbsolute.'/extension.xml', $sInvalidExtensionXml); $oExtensionMap = ItopExtensionsMap::GetExtensionsMap($sEnvironment); //echo json_encode(array_keys($oExtensionMap->GetAllExtensions()), JSON_PRETTY_PRINT); // $this->expectException(CoreException::class); // $this->expectExceptionMessage("Selected extension(s) cannot be installed: Missing extension code ($sExtensionsDirAbsolute)"); self::assertFalse($oExtensionMap->CheckExtensionsValidity(), 'Check extensions validity should have detected an extension without code.'); } public function testCheckExtensionsValidityThrowExceptionWhenSelectedExtensionCodeAndLabelAreMissingAndExtensionIsChosen(): void { [$sEnvironment, $sExtensionsDirRelative] = $this->CreateFixtureContext('env-missing-label-'); $sInvalidExtensionXml = << Test extension without code and label 1.0.0 false XML; $sExtensionsDirAbsolute = APPROOT.$sExtensionsDirRelative; file_put_contents($sExtensionsDirAbsolute.'/extension.xml', $sInvalidExtensionXml); $oExtensionMap = ItopExtensionsMap::GetExtensionsMap($sEnvironment); $oExtensionMap->MarkAsChosen(''); //echo json_encode(array_keys($oExtensionMap->GetAllExtensions()), JSON_PRETTY_PRINT); $this->expectException(CoreException::class); $this->expectExceptionMessage("Selected extension(s) cannot be installed: Missing extension code ($sExtensionsDirAbsolute)"); $oExtensionMap->CheckExtensionsValidity(); } public function testCheckExtensionsValidityThrowExceptionWhenSelectedExtensionCodeIsMissingAndExtensionIsChosen(): void { [$sEnvironment, $sExtensionsDirRelative] = $this->CreateFixtureContext('env-missing-label-'); $sInvalidExtensionXml = << Test extension without code and label 1.0.0 false XML; $sExtensionsDirAbsolute = APPROOT.$sExtensionsDirRelative; file_put_contents($sExtensionsDirAbsolute.'/extension.xml', $sInvalidExtensionXml); $oExtensionMap = ItopExtensionsMap::GetExtensionsMap($sEnvironment); $oExtensionMap->MarkAsChosen(''); //echo json_encode(array_keys($oExtensionMap->GetAllExtensions()), JSON_PRETTY_PRINT); $this->expectException(CoreException::class); $this->expectExceptionMessage("Selected extension(s) cannot be installed: Missing extension code (Broken extension)"); $oExtensionMap->CheckExtensionsValidity(); } private function CreateFixtureContext(string $sEnvPrefix): array { $sEnvironment = str_replace('.', '-', uniqid($sEnvPrefix, true)); $sExtensionsDirRelative = 'data/'.$sEnvironment.'-modules'; mkdir(APPROOT.$sExtensionsDirRelative, 0777, true); $this->aFileToClean[] = APPROOT.$sExtensionsDirRelative; return [$sEnvironment, $sExtensionsDirRelative]; } public function SerializeExtensionMap(iTopExtensionsMap $oiTopExtensionsMap): array { $aRes = []; foreach ($oiTopExtensionsMap->GetAllExtensions() as $oExtension) { $aRes[] = [ 'sCode' => $oExtension->sCode, 'sSource' => $oExtension->sSource, 'sVersion' => $oExtension->sVersion, 'aModules' => $oExtension->aModules, 'aModuleVersion' => $oExtension->aModuleVersion, 'aModuleInfo' => $oExtension->aModuleInfo, ]; } return $aRes; } }