mirror of
https://github.com/Combodo/iTop.git
synced 2026-08-27 08:28:28 +02:00
Compare commits
10 Commits
feature/91
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
175b88de30 | ||
|
|
0a5b0b403e | ||
|
|
a346b71e9a | ||
|
|
8065343ea6 | ||
|
|
9c6087fd54 | ||
|
|
66073ba390 | ||
|
|
4756e2474c | ||
|
|
7dbbf742c4 | ||
|
|
2cd4fd1e0e | ||
|
|
fffff76c82 |
@@ -42,7 +42,7 @@ css/backoffice/
|
||||
|– vendors/ # Third-party libs, should be either:
|
||||
| # - Overload of the lib SCSS variables (BEST way, but possible only if the lib exposes them. e.g. Bulma)
|
||||
| # - Overload of the lib necessary CSS classes only (not great as it duplicates some rules in the browser, which add weight and computation. e.g. dataTables)
|
||||
| # - Duplicate the lib CSS completly to insert SCSS variables (not great as it will be outdated when updating the lib itself. e.g. jQuery UI)
|
||||
| # - Duplicate the lib CSS completely to insert SCSS variables (not great as it will be outdated when updating the lib itself. e.g. jQuery UI)
|
||||
| |– _bulma-variables-overload.scss # Bulma CSS framework
|
||||
| |– _jquery-ui.scss # jQuery UI
|
||||
| ... # Etc…
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
{% UIColumn Standard {} %}
|
||||
{% for aExtension in aAvailableExtensions[iColumnIndex] %}
|
||||
{% if aExtension['installed'] %}
|
||||
{% UIExtensionDetails Installed { sCode : aExtension['code'], sLabel : aExtension['label'], sDescription : aExtension['description'], aMetaData : [aExtension['version'], aExtension['source']], aExtraFlags : aExtension['extra_flags']} %}{% EndUIExtensionDetails %}
|
||||
{% UIExtensionDetails Installed { sCode : aExtension['code'], sLabel : aExtension['label'], sDescription : aExtension['description'], aMetaData : [aExtension['version'], aExtension['source'], aExtension['code']], aExtraFlags : aExtension['extra_flags']} %}{% EndUIExtensionDetails %}
|
||||
{% else %}
|
||||
{% UIExtensionDetails NotInstalled { sCode : aExtension['code'], sLabel : aExtension['label'], sDescription : aExtension['description'], aMetaData : [aExtension['version'], aExtension['source']], aExtraFlags : aExtension['extra_flags']} %}{% EndUIExtensionDetails %}
|
||||
{% UIExtensionDetails NotInstalled { sCode : aExtension['code'], sLabel : aExtension['label'], sDescription : aExtension['description'], aMetaData : [aExtension['version'], aExtension['source'], aExtension['code']], aExtraFlags : aExtension['extra_flags']} %}{% EndUIExtensionDetails %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% EndUIColumn %}
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
{% UIColumn Standard {} %}
|
||||
{% for aExtension in aAvailableExtensions[iColumnIndex] %}
|
||||
{% if aExtension['installed'] %}
|
||||
{% UIExtensionDetails Installed { sCode : aExtension['code'], sLabel : aExtension['label'], sDescription : aExtension['description'], aMetaData : [aExtension['version'], aExtension['source']], aExtraFlags : aExtension['extra_flags']} %}{% EndUIExtensionDetails %}
|
||||
{% UIExtensionDetails Installed { sCode : aExtension['code'], sLabel : aExtension['label'], sDescription : aExtension['description'], aMetaData : [aExtension['version'], aExtension['source'], aExtension['code']], aExtraFlags : aExtension['extra_flags']} %}{% EndUIExtensionDetails %}
|
||||
{% else %}
|
||||
{% UIExtensionDetails NotInstalled { sCode : aExtension['code'], sLabel : aExtension['label'], sDescription : aExtension['description'], aMetaData : [aExtension['version'], aExtension['source']], aExtraFlags : aExtension['extra_flags']} %}{% EndUIExtensionDetails %}
|
||||
{% UIExtensionDetails NotInstalled { sCode : aExtension['code'], sLabel : aExtension['label'], sDescription : aExtension['description'], aMetaData : [aExtension['version'], aExtension['source'], aExtension['code']], aExtraFlags : aExtension['extra_flags']} %}{% EndUIExtensionDetails %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% EndUIColumn %}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
class ModuleInstallationRepository
|
||||
{
|
||||
private static ModuleInstallationRepository $oInstance;
|
||||
private static ?ModuleInstallationRepository $oInstance;
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
@@ -60,6 +60,7 @@ class ModuleInstallationRepository
|
||||
CMDBSource::InitFromConfig($oConfig);
|
||||
//read db module installations
|
||||
$tableWithPrefix = $this->GetTableWithPrefix($oConfig);
|
||||
|
||||
$iRootId = CMDBSource::QueryToScalar("SELECT max(parent_id) FROM $tableWithPrefix");
|
||||
// Get the latest installed modules, without the "root" ones (iTop version and datamodel version)
|
||||
$sSQL = <<<SQL
|
||||
@@ -94,10 +95,7 @@ SQL;
|
||||
public function GetApplicationVersion(Config $oConfig)
|
||||
{
|
||||
try {
|
||||
CMDBSource::InitFromConfig($oConfig);
|
||||
$tableWithPrefix = $this->GetTableWithPrefix($oConfig);
|
||||
$sSQLQuery = "SELECT * FROM $tableWithPrefix";
|
||||
$aSelectInstall = CMDBSource::QueryToArray($sSQLQuery);
|
||||
$aSelectInstall = $this->ReadFromDB($oConfig);
|
||||
} catch (MySQLException $e) {
|
||||
// No database or erroneous information
|
||||
SetupLog::Error(
|
||||
@@ -105,8 +103,6 @@ SQL;
|
||||
null,
|
||||
[
|
||||
'host' => $oConfig->Get('db_host'),
|
||||
'user' => $oConfig->Get('db_user'),
|
||||
'pwd:' => $oConfig->Get('db_pwd'),
|
||||
'db name' => $oConfig->Get('db_name'),
|
||||
'msg' => $e->getMessage(),
|
||||
]
|
||||
|
||||
@@ -645,6 +645,7 @@ class RunTimeEnvironment
|
||||
$iPrevAccessMode = $oConfig->Get('access_mode');
|
||||
$oConfig->Set('access_mode', ACCESS_FULL);
|
||||
$this->InitDataModel($oConfig, true); // load data model and connect to the database
|
||||
$oParams = new SessionParameters(SetupUtils::SESSION_PARAMETERS_NAME);
|
||||
|
||||
if (CMDBSource::DBName() == '') {
|
||||
// In case this has not yet been done
|
||||
@@ -652,8 +653,9 @@ class RunTimeEnvironment
|
||||
}
|
||||
|
||||
if ($sShortComment === null) {
|
||||
$sShortComment = 'Done by the setup program';
|
||||
$sShortComment = $oParams->GetParameter('install_comment', 'Done by the setup program');
|
||||
}
|
||||
$oParams->SetParameter('install_comment', null);
|
||||
$sMainComment = $sShortComment."\nBuilt on ".ITOP_BUILD_DATE;
|
||||
|
||||
// Record datamodel version
|
||||
@@ -748,7 +750,6 @@ class RunTimeEnvironment
|
||||
}
|
||||
}
|
||||
|
||||
$oParams = new SessionParameters(SetupUtils::SESSION_PARAMETERS_NAME);
|
||||
if (class_exists('DesignerUpdate') && $oParams->GetParameter('return_application') === 'designer') {
|
||||
// Now keep track of this update
|
||||
$oLog = new DesignerUpdate();
|
||||
@@ -1275,14 +1276,14 @@ class RunTimeEnvironment
|
||||
* - plus the list of modules present in the "extra" directory of the build environment: data/<build_environment>-modules/
|
||||
*
|
||||
* @param string $sSourceEnv The name of the source environment to 'imitate'
|
||||
* @param null $bUseSymLinks Whether to create symbolic links instead of copies
|
||||
* @param bool|null $bUseSymLinks Whether to create symbolic links instead of copies
|
||||
* @param array $aAddedExtensions List of additional extensions to add to the build environment
|
||||
*
|
||||
* @return string[]
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function CompileFrom($sSourceEnv, $bUseSymLinks = null, $aAddedExtensions = [])
|
||||
public function CompileFrom($sSourceEnv, ?bool $bUseSymLinks = null, $aAddedExtensions = [])
|
||||
{
|
||||
$oConfig = new Config(utils::GetConfigFilePath($sSourceEnv));
|
||||
$this->InitExtensionMap($oConfig);
|
||||
|
||||
@@ -70,7 +70,7 @@ $("[data-role=\"setup-collapsable-options--toggler\"").on('click', function() {
|
||||
$("#force-uninstall").on("click", function() {
|
||||
let $this = $(this);
|
||||
let bForceUninstall = $this.prop("checked");
|
||||
if( bForceUninstall && !confirm('Beware, uninstalling extensions flagged as non uninstallable may result in data corruption and application crashes. Are you sure you want to continue ?')){
|
||||
if( bForceUninstall && !confirm('Beware, uninstalling extensions flagged as non uninstallable may result in data corruption and application crashes. Are you sure you want to continue?')){
|
||||
$this.prop("checked",false);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -944,7 +944,7 @@ EOF
|
||||
|
||||
$sMetadata = '';
|
||||
if (isset($aChoice['version']) && isset($aChoice['source_label'])) {
|
||||
$sMetadata = '<span>v'.$aChoice['version'].'</span><span>'.$aChoice['source_label'].'</span>';
|
||||
$sMetadata = '<span>v'.$aChoice['version'].'</span><span>'.$aChoice['source_label'].'</span><span>'.$aChoice['extension_code'].'</span>';
|
||||
}
|
||||
$sChoiceDisabled = $aFlags['disabled'] && !$aFlags['checked'] ? 'choice-disabled' : '';
|
||||
|
||||
|
||||
@@ -158,15 +158,45 @@ HTML
|
||||
</form>
|
||||
HTML
|
||||
);
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
|
||||
if ($this->DisplaySetupShortcutButton()) {
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
$('.ibo-setup--wizard--buttons-container tr td:nth-child(1)').before('<td style="text-align:center;"><button class="ibo-button ibo-is-alternative ibo-is-neutral" form="fast_setup"><span class="ibo-button--label">Keep current choices</span></button></td>');
|
||||
JS
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function DisplaySetupShortcutButton(): bool
|
||||
{
|
||||
if ('install' === $this->oWizard->GetParameter('mode', 'install')) {
|
||||
//fresh install
|
||||
return false;
|
||||
}
|
||||
|
||||
$oConfig = utils::GetConfig();
|
||||
$res = ModuleInstallationRepository::GetInstance()->GetApplicationVersion($oConfig);
|
||||
if (false === $res) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sProductName = $res['product_name'] ?? null;
|
||||
$sProductVersion = $res['product_version'] ?? null;
|
||||
if (is_null($sProductName) || is_null($sProductVersion)) {
|
||||
\SetupLog::Error(__METHOD__.": cannot fetch itop version", null, $res);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ITOP_VERSION_FULL !== $sProductVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (ITOP_APPLICATION === $sProductName);
|
||||
}
|
||||
|
||||
public function CanMoveForward()
|
||||
{
|
||||
return $this->bCanMoveForward;
|
||||
|
||||
@@ -70,6 +70,13 @@ class SymfonyPHPMailTransport extends AbstractTransport
|
||||
return $sHeaders;
|
||||
}
|
||||
|
||||
public function prepareAdditionalParameters(SentMessage $message): string
|
||||
{
|
||||
$sender = $message->getEnvelope()->getSender()->getEncodedAddress();
|
||||
|
||||
return '-f'.escapeshellarg($sender);
|
||||
}
|
||||
|
||||
protected function doSend(SentMessage $message): void
|
||||
{
|
||||
$oRawEmail = $message->getOriginalMessage();
|
||||
@@ -82,8 +89,9 @@ class SymfonyPHPMailTransport extends AbstractTransport
|
||||
$sSubject = $this->prepareSubject($oRawEmail);
|
||||
$sBody = $this->prepareBody($oRawEmail);
|
||||
$sHeaders = $this->prepareHeaders($oRawEmail);
|
||||
$sAdditionalParameters = $this->prepareAdditionalParameters($message);
|
||||
|
||||
$success = mail($sTo, $sSubject, $sBody, $sHeaders);
|
||||
$success = mail($sTo, $sSubject, $sBody, $sHeaders, $sAdditionalParameters);
|
||||
|
||||
if (!$success) {
|
||||
throw new \RuntimeException('The mail() function failed to send the message. Check server mail configuration.');
|
||||
|
||||
@@ -1295,7 +1295,7 @@ class WizStepModulesChoiceTest extends ItopTestCase
|
||||
<div id="badge--itop-ext-not-installed--to-be-installed" class="ibo-badge ibo-block checked ibo-is-cyan" title="This extension will be installed during the setup." >to be installed</div><div id="badge--itop-ext-not-installed--not-installed" class="ibo-badge ibo-block unchecked ibo-is-blue-grey" title="This extension is not part of the current installation." >not installed</div>
|
||||
</div>
|
||||
<div class="ibo-extension-details--information--metadata">
|
||||
<span>v1.2.3</span><span>Local extensions folder</span>
|
||||
<span>v1.2.3</span><span>Local extensions folder</span><span>itop-ext-not-installed</span>
|
||||
</div>
|
||||
<div class="ibo-extension-details--information--description">
|
||||
Do something
|
||||
@@ -1338,7 +1338,7 @@ HTML,
|
||||
<div id="badge--itop-ext-installed--installed" class="ibo-badge ibo-block checked ibo-is-green" title="This extension is part of the current installation." >installed</div><div id="badge--itop-ext-installed--to-be-uninstalled" class="ibo-badge ibo-block unchecked ibo-is-red" title="This extension will be uninstalled during the setup." >to be uninstalled</div>
|
||||
</div>
|
||||
<div class="ibo-extension-details--information--metadata">
|
||||
<span>v1.2.3</span><span>Local extensions folder</span>
|
||||
<span>v1.2.3</span><span>Local extensions folder</span><span>itop-ext-installed</span>
|
||||
</div>
|
||||
<div class="ibo-extension-details--information--description">
|
||||
Do something
|
||||
@@ -1382,7 +1382,7 @@ HTML,
|
||||
<div id="badge--itop-ext-installed--installed" class="ibo-badge ibo-block checked ibo-is-green" title="This extension is part of the current installation." >installed</div><div id="badge--itop-ext-installed--to-be-uninstalled" class="ibo-badge ibo-block unchecked ibo-is-red" title="This extension will be uninstalled during the setup." >to be uninstalled</div><div id="badge--itop-ext-installed--not-uninstallable" class="ibo-badge ibo-block ibo-is-yellow" title="Once this extension has been installed, it should not be uninstalled." >cannot be uninstalled</div>
|
||||
</div>
|
||||
<div class="ibo-extension-details--information--metadata">
|
||||
<span>v1.2.3</span><span>Local extensions folder</span>
|
||||
<span>v1.2.3</span><span>Local extensions folder</span><span>itop-ext-installed</span>
|
||||
</div>
|
||||
<div class="ibo-extension-details--information--description">
|
||||
Do something
|
||||
|
||||
134
tests/php-unit-tests/unitary-tests/setup/WizStepWelcomeTest.php
Normal file
134
tests/php-unit-tests/unitary-tests/setup/WizStepWelcomeTest.php
Normal file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Integration;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use WizardController;
|
||||
use ModuleInstallationRepository;
|
||||
|
||||
class WizStepWelcomeTest extends ItopDataTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp(); // TODO: Change the autogenerated stub
|
||||
require_once(APPROOT.'/setup/wizardsteps_autoload.php');
|
||||
require_once(APPROOT.'/setup/moduleinstallation/ModuleInstallationRepository.php');
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown(); // TODO: Change the autogenerated stub
|
||||
ModuleInstallationRepository::SetInstance(null);
|
||||
}
|
||||
|
||||
public function testDisplaySetupShortcutButton_NoButtonWhenFreshInstall()
|
||||
{
|
||||
$oWizard = $this->createMock(WizardController::class);
|
||||
$this->GivenSetupMode($oWizard);
|
||||
|
||||
$oWiz = new \WizStepWelcome($oWizard, "");
|
||||
$this->assertEquals(false, $oWiz->DisplaySetupShortcutButton());
|
||||
}
|
||||
|
||||
public function testDisplaySetupShortcutButton_NoButtonWhenNoItopVersionFetched()
|
||||
{
|
||||
$oWizard = $this->createMock(WizardController::class);
|
||||
$this->GivenSetupMode($oWizard, 'upgrade');
|
||||
|
||||
$aApplicationVersion = [
|
||||
'product_name' => ITOP_APPLICATION,
|
||||
];
|
||||
$this->GivenGetApplicationVersion($aApplicationVersion);
|
||||
|
||||
$oWiz = new \WizStepWelcome($oWizard, "");
|
||||
$this->assertEquals(false, $oWiz->DisplaySetupShortcutButton());
|
||||
}
|
||||
|
||||
public function testDisplaySetupShortcutButton_NoButtonWhenNoApplicationVersionFetched()
|
||||
{
|
||||
$oWizard = $this->createMock(WizardController::class);
|
||||
$this->GivenSetupMode($oWizard, 'upgrade');
|
||||
|
||||
$aApplicationVersion = [
|
||||
'product_version' => ITOP_VERSION_FULL,
|
||||
];
|
||||
$this->GivenGetApplicationVersion($aApplicationVersion);
|
||||
|
||||
$oWiz = new \WizStepWelcome($oWizard, "");
|
||||
$this->assertEquals(false, $oWiz->DisplaySetupShortcutButton());
|
||||
}
|
||||
|
||||
public function testDisplaySetupShortcutButton_NoButtonWhenApplicationChangeDuringUpgrade()
|
||||
{
|
||||
$oWizard = $this->createMock(WizardController::class);
|
||||
$this->GivenSetupMode($oWizard, 'upgrade');
|
||||
|
||||
$aApplicationVersion = [
|
||||
'product_version' => ITOP_VERSION_FULL,
|
||||
'product_name' => 'toto',
|
||||
];
|
||||
$this->GivenGetApplicationVersion($aApplicationVersion);
|
||||
|
||||
$oWiz = new \WizStepWelcome($oWizard, "");
|
||||
$this->assertEquals(false, $oWiz->DisplaySetupShortcutButton());
|
||||
}
|
||||
|
||||
public function testDisplaySetupShortcutButton_NoButtonWhenVersionChangeDuringUpgrade()
|
||||
{
|
||||
$oWizard = $this->createMock(WizardController::class);
|
||||
$this->GivenSetupMode($oWizard, 'upgrade');
|
||||
|
||||
$aApplicationVersion = [
|
||||
'product_version' => '6.6.6',
|
||||
'product_name' => ITOP_APPLICATION,
|
||||
];
|
||||
$this->GivenGetApplicationVersion($aApplicationVersion);
|
||||
|
||||
$oWiz = new \WizStepWelcome($oWizard, "");
|
||||
$this->assertEquals(false, $oWiz->DisplaySetupShortcutButton());
|
||||
}
|
||||
|
||||
public function testDisplaySetupShortcutButton_NoButtonWhenMySQLException()
|
||||
{
|
||||
$oWizard = $this->createMock(WizardController::class);
|
||||
$this->GivenSetupMode($oWizard, 'upgrade');
|
||||
$this->GivenGetApplicationVersion(false);
|
||||
|
||||
$oWiz = new \WizStepWelcome($oWizard, "");
|
||||
$this->assertEquals(false, $oWiz->DisplaySetupShortcutButton());
|
||||
}
|
||||
|
||||
public function testDisplaySetupShortcutButton_ButtonDisplayed()
|
||||
{
|
||||
|
||||
$oWizard = $this->createMock(WizardController::class);
|
||||
$this->GivenSetupMode($oWizard, 'upgrade');
|
||||
|
||||
$aApplicationVersion = [
|
||||
'product_version' => ITOP_VERSION_FULL,
|
||||
'product_name' => ITOP_APPLICATION,
|
||||
];
|
||||
$this->GivenGetApplicationVersion($aApplicationVersion);
|
||||
|
||||
$oWiz = new \WizStepWelcome($oWizard, "");
|
||||
$this->assertEquals(true, $oWiz->DisplaySetupShortcutButton());
|
||||
}
|
||||
|
||||
private function GivenSetupMode(WizardController $oWizardMock, $sMode = 'install'): void
|
||||
{
|
||||
$oWizardMock->expects($this->once())
|
||||
->method('GetParameter')
|
||||
->with('mode')
|
||||
->willReturn($sMode);
|
||||
}
|
||||
|
||||
private function GivenGetApplicationVersion($sExpectedReturnedValue): void
|
||||
{
|
||||
$oModuleInstallationRepository = $this->createMock(ModuleInstallationRepository::class);
|
||||
ModuleInstallationRepository::SetInstance($oModuleInstallationRepository);
|
||||
|
||||
$oModuleInstallationRepository->expects($this->once())
|
||||
->method('GetApplicationVersion')
|
||||
->willReturn($sExpectedReturnedValue);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ class SymfonyPHPMailTransportTest extends ItopTestCase
|
||||
{
|
||||
public function testPrepareMustNotThrowErrorWhenToHeaderIsMissing(): void
|
||||
{
|
||||
$oEmail = new Email()
|
||||
$oEmail = (new Email())
|
||||
->from('sender@example.com')
|
||||
->cc('cc1@example.com', 'cc2@example.com')
|
||||
->text('Body');
|
||||
|
||||
Reference in New Issue
Block a user