* [ADD] Backup CLI command and tests.

* [MOD] Code refactoring.

Signed-off-by: Rubén D <nuxsmin@syspass.org>
This commit is contained in:
Rubén D
2021-09-26 18:42:34 +02:00
parent 0b02c8fdbf
commit f8e9e19731
16 changed files with 571 additions and 157 deletions

View File

@@ -0,0 +1,140 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Modules\Cli\Commands;
use Exception;
use Psr\Log\LoggerInterface;
use RuntimeException;
use SP\Config\Config;
use SP\Services\Backup\FileBackupService;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\StyleInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* Class BackupCommand
*
* @package SP\Modules\Cli\Commands
*/
final class BackupCommand extends CommandBase
{
/**
* @var string[]
*/
public static array $envVarsMapping = [
'path' => 'BACKUP_PATH'
];
/**
* @var string
*/
protected static $defaultName = 'sp:backup';
/**
* @var FileBackupService
*/
private FileBackupService $fileBackupService;
public function __construct(FileBackupService $fileBackupService,
LoggerInterface $logger,
Config $config)
{
$this->fileBackupService = $fileBackupService;
parent::__construct($logger, $config);
}
protected function configure(): void
{
$this->setDescription(__('Backup actions'))
->setHelp(__('This command performs a file based backup from sysPass database and application'))
->addOption('path',
null,
InputOption::VALUE_OPTIONAL,
__('Path where to store the backup files'),
BACKUP_PATH);
}
/**
* @param InputInterface $input
* @param OutputInterface $output
*
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$style = new SymfonyStyle($input, $output);
try {
$this->checkInstalled();
$path = $this->getPath($input, $style);
$this->logger->info(sprintf(__u('Backup path set to: %s'), $path));
$this->fileBackupService->doBackup($path);
$this->logger->info(__u('Application and database backup completed successfully'));
$style->success(__('Application and database backup completed successfully'));
return self::SUCCESS;
} catch (Exception $e) {
$this->logger->error($e->getTraceAsString());
$this->logger->error($e->getMessage());
$style->error(__($e->getMessage()));
}
return self::FAILURE;
}
private function checkInstalled(): void
{
if (!defined('TEST_ROOT')
&& !$this->configData->isInstalled()) {
throw new RuntimeException(__u('sysPass is not installed'));
}
}
/**
* @param InputInterface $input
* @param StyleInterface $style
*
* @return string
*/
private function getPath(InputInterface $input, StyleInterface $style): string
{
$path = self::getEnvVarOrOption('path', $input);
if (empty($path)) {
$this->logger->debug(__u('Ask for path'));
return $style->ask(__('Please enter the path where to store the backup files'), BACKUP_PATH);
}
return $path;
}
}

View File

@@ -28,6 +28,7 @@ use Psr\Log\LoggerInterface;
use SP\Config\Config;
use SP\Config\ConfigData;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
/**
* Class CommandBase
@@ -36,19 +37,22 @@ use Symfony\Component\Console\Command\Command;
*/
abstract class CommandBase extends Command
{
/**
* @var string[]
*/
public static array $envVarsMapping = [];
/**
* @var LoggerInterface
*/
protected $logger;
protected LoggerInterface $logger;
/**
* @var Config
*/
protected $config;
protected Config $config;
/**
* @var ConfigData
*/
protected $configData;
protected ConfigData $configData;
/**
* CommandBase constructor.
@@ -67,4 +71,44 @@ abstract class CommandBase extends Command
parent::__construct();
}
/**
* @param string $option
* @param InputInterface $input
*
* @return array|false|mixed|string
*/
protected static function getEnvVarOrOption(
string $option,
InputInterface $input
)
{
return static::getEnvVarForOption($option)
?: $input->getOption($option);
}
/**
* @param string $option
*
* @return string|false
*/
protected static function getEnvVarForOption(string $option)
{
return getenv(static::$envVarsMapping[$option]);
}
/**
* @param string $argument
* @param InputInterface $input
*
* @return array|false|mixed|string
*/
protected static function getEnvVarOrArgument(
string $argument,
InputInterface $input
)
{
return static::getEnvVarForOption($argument)
?: $input->getArgument($argument);
}
}

View File

@@ -27,7 +27,6 @@ namespace SP\Modules\Cli\Commands;
use Closure;
use Exception;
use Psr\Log\LoggerInterface;
use RuntimeException;
use SP\Config\Config;
use SP\Core\Exceptions\InstallError;
use SP\Core\Exceptions\InvalidArgumentException;
@@ -52,7 +51,7 @@ final class InstallCommand extends CommandBase
/**
* @var string[]
*/
public static $envVarsMapping = [
public static array $envVarsMapping = [
'adminLogin' => 'ADMIN_LOGIN',
'adminPassword' => 'ADMIN_PASSWORD',
'databaseHost' => 'DATABASE_HOST',
@@ -72,7 +71,7 @@ final class InstallCommand extends CommandBase
/**
* @var Installer
*/
private $installer;
private Installer $installer;
public function __construct(LoggerInterface $logger,
Config $config,
@@ -185,16 +184,8 @@ final class InstallCommand extends CommandBase
*/
private function getInstallData(InputInterface $input, StyleInterface $style): InstallData
{
$passNotEmptyValidator = function ($value) {
if (empty($value)) {
throw new RuntimeException(__('Password cannot be blank'));
}
return $value;
};
$adminPassword = $this->getAdminPassword($input, $style, $passNotEmptyValidator);
$masterPassword = $this->getMasterPassword($input, $style, $passNotEmptyValidator);
$adminPassword = $this->getAdminPassword($input, $style);
$masterPassword = $this->getMasterPassword($input, $style);
$databasePassword = $this->getDatabasePassword($input, $style);
$language = $this->getLanguage($input, $style);
$hostingMode = $this->isHostingMode($input);
@@ -220,15 +211,13 @@ final class InstallCommand extends CommandBase
/**
* @param InputInterface $input
* @param StyleInterface $style
* @param Closure $passNotEmptyValidator
*
* @return array|false|mixed|string
* @throws InstallError
*/
private function getAdminPassword(
InputInterface $input,
StyleInterface $style,
Closure $passNotEmptyValidator
StyleInterface $style
)
{
$option = 'adminPassword';
@@ -242,12 +231,18 @@ final class InstallCommand extends CommandBase
$password = $style->askHidden(
__('Please provide sysPass admin\'s password'),
$passNotEmptyValidator
fn($value) => Validators::valueNotEmpty(
$value,
sprintf(__u('%s cannot be blank'), 'Admin password')
)
);
$passwordRepeat = $style->askHidden(
__('Please provide sysPass admin\'s password again'),
$passNotEmptyValidator
fn($value) => Validators::valueNotEmpty(
$value,
sprintf(__u('%s cannot be blank'), 'Admin password')
)
);
if ($password !== $passwordRepeat) {
@@ -260,18 +255,17 @@ final class InstallCommand extends CommandBase
return $password;
}
/**
* @param InputInterface $input
* @param StyleInterface $style
* @param Closure $passNotEmptyValidator
*
* @return array|false|mixed|string
* @throws InstallError
*/
private function getMasterPassword(
InputInterface $input,
StyleInterface $style,
Closure $passNotEmptyValidator
StyleInterface $style
)
{
$password = self::getEnvVarOrOption('masterPassword', $input);
@@ -281,11 +275,17 @@ final class InstallCommand extends CommandBase
$password = $style->askHidden(
__('Please provide sysPass master password'),
$passNotEmptyValidator
fn($value) => Validators::valueNotEmpty(
$value,
sprintf(__u('%s cannot be blank'), 'Master password')
)
);
$passwordRepeat = $style->askHidden(
__('Please provide sysPass master password again'),
$passNotEmptyValidator
fn($value) => Validators::valueNotEmpty(
$value,
sprintf(__u('%s cannot be blank'), 'Master password')
)
);
if ($password !== $passwordRepeat) {
@@ -298,31 +298,6 @@ final class InstallCommand extends CommandBase
return $password;
}
/**
* @param string $option
* @param InputInterface $input
*
* @return array|false|mixed|string
*/
private static function getEnvVarOrOption(
string $option,
InputInterface $input
)
{
return self::getEnvVarForOption($option)
?: $input->getOption($option);
}
/**
* @param string $option
*
* @return string|false
*/
public static function getEnvVarForOption(string $option)
{
return getenv(self::$envVarsMapping[$option]);
}
/**
* @param InputInterface $input
* @param StyleInterface $style
@@ -387,21 +362,6 @@ final class InstallCommand extends CommandBase
: $input->getOption($option);
}
/**
* @param string $argument
* @param InputInterface $input
*
* @return array|false|mixed|string
*/
private static function getEnvVarOrArgument(
string $argument,
InputInterface $input
)
{
return self::getEnvVarForOption($argument)
?: $input->getArgument($argument);
}
/**
* @param InputInterface $input
*

View File

@@ -0,0 +1,48 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Modules\Cli\Commands;
use RuntimeException;
/**
*
*/
final class Validators
{
/**
* @param string|null $value
* @param string|null $message
*
* @return string
*/
public static function valueNotEmpty(?string $value, ?string $message): string
{
if (empty($value)) {
throw new RuntimeException($message ?? __u('Value cannot be blank'));
}
return $value;
}
}

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -19,7 +19,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Modules\Cli;
@@ -32,6 +32,7 @@ use SP\Core\Context\ContextException;
use SP\Core\Context\StatelessContext;
use SP\Core\Language;
use SP\Core\ModuleBase;
use SP\Modules\Cli\Commands\BackupCommand;
use SP\Modules\Cli\Commands\InstallCommand;
use SP\Util\VersionUtil;
use Symfony\Component\Console\Application;
@@ -46,7 +47,8 @@ use Symfony\Component\Console\Output\OutputInterface;
final class Init extends ModuleBase
{
private const CLI_COMMANDS = [
InstallCommand::class
InstallCommand::class,
BackupCommand::class
];
/**
* @var StatelessContext

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -19,8 +19,8 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
define('MODULE_PATH', __DIR__);
define('PLUGINS_PATH', MODULE_PATH . DIRECTORY_SEPARATOR . 'plugins');
const MODULE_PATH = __DIR__;
const PLUGINS_PATH = MODULE_PATH . DIRECTORY_SEPARATOR . 'plugins';

View File

@@ -202,15 +202,18 @@ final class Config
* @return Config
* @throws FileException
*/
public function saveConfig(ConfigData $configData, $backup = true): Config
public function saveConfig(ConfigData $configData, ?bool $backup = true): Config
{
if ($backup) {
$this->dic->get(ConfigBackupService::class)
->backup($configData);
}
$configSaver = $this->context->getUserData()->getLogin()
?: AppInfoInterface::APP_NAME;
$configData->setConfigDate(time());
$configData->setConfigSaver($this->context->getUserData()->getLogin() ?: AppInfoInterface::APP_NAME);
$configData->setConfigSaver($configSaver);
$configData->setConfigHash();
// Save only attributes to avoid a parent attributes node within the XML
@@ -258,7 +261,7 @@ final class Config
*
* @return ConfigData
*/
public function loadConfig($reload = false): ConfigData
public function loadConfig(?bool $reload = false): ConfigData
{
try {
$configData = $this->fileCache->load();

View File

@@ -85,9 +85,9 @@ interface ContextInterface
/**
* Devuelve los datos del usuario en la sesión.
*
* @return UserLoginResponse|null
* @return UserLoginResponse
*/
public function getUserData(): ?UserLoginResponse;
public function getUserData(): UserLoginResponse;
/**
* Establecer el lenguaje de la sesión

View File

@@ -119,7 +119,7 @@ final class StatelessContext extends ContextBase
*
* @return UserLoginResponse
*/
public function getUserData(): ?UserLoginResponse
public function getUserData(): UserLoginResponse
{
return $this->getContextKey('userData', new UserLoginResponse());
}

View File

@@ -203,22 +203,6 @@ final class LdapConnection implements LdapConnectionInterface
return $this;
}
public function getServerUri(): string
{
$server = $this->getServer();
$port = $this->ldapParams->getPort();
if (strpos($server, '://') !== false) {
return $server . ':' . $port;
} elseif ($port === 389 || $port === null) {
return 'ldap://' . $server;
} elseif ($port === 636) {
return 'ldaps://' . $server;
}
return 'ldap://' . $server . ':' . $port;
}
/**
* @inheritDoc
*/
@@ -229,9 +213,13 @@ final class LdapConnection implements LdapConnectionInterface
if (strpos($server, '://') !== false) {
return $server . ':' . $port;
} elseif ($port === 389 || $port === null) {
}
if ($port === 389 || $port === null) {
return 'ldap://' . $server;
} elseif ($port === 636) {
}
if ($port === 636) {
return 'ldaps://' . $server;
}

View File

@@ -137,13 +137,14 @@ final class FileBackupService extends Service
/**
* Comprobar y crear el directorio de backups.
*
* @return bool
* @return void
* @throws ServiceException
*/
private function checkBackupDir()
private function checkBackupDir(): void
{
if (is_dir($this->path) === false
&& @mkdir($this->path, 0750) === false
&& !@mkdir($concurrentDirectory = $this->path, 0750)
&& !is_dir($concurrentDirectory)
) {
throw new ServiceException(
sprintf(__('Unable to create the backups directory ("%s")'), $this->path));
@@ -154,7 +155,6 @@ final class FileBackupService extends Service
__u('Please, check the backup directory permissions'));
}
return true;
}
/**

View File

@@ -54,11 +54,19 @@ final class FileUtil
throw new FileNotFoundException('Directory does not exist');
}
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST);
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
$dir,
FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($it as $file) {
if ($file->isDir()) rmdir($file->getPathname());
else unlink($file->getPathname());
if ($file->isDir()) {
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}
return rmdir($dir);

View File

@@ -25,9 +25,15 @@
namespace SP\Tests\Modules\Cli;
use DI\ContainerBuilder;
use DI\DependencyException;
use DI\NotFoundException;
use Exception;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use SP\Core\Context\ContextInterface;
use SP\Storage\Database\DBStorageInterface;
use Symfony\Component\Console\Tester\CommandTester;
use function SP\Tests\getDbHandler;
/**
* Class CliTestCase
@@ -40,6 +46,10 @@ abstract class CliTestCase extends TestCase
* @var ContainerInterface
*/
protected static $dic;
/**
* @var string[]
*/
protected static array $commandInputData = [];
/**
* This method is called before the first test of this test class is run.
@@ -57,5 +67,43 @@ abstract class CliTestCase extends TestCase
);
self::$dic = $builder->build();
$context = self::$dic->get(ContextInterface::class);
$context->initialize();
}
/**
* @param string $commandClass
* @param array|null $inputData
* @param bool $useInputData
*
* @return CommandTester
* @throws DependencyException
* @throws NotFoundException
*/
protected function executeCommandTest(
string $commandClass,
?array $inputData = null,
bool $useInputData = true
): CommandTester
{
$installCommand = self::$dic->get($commandClass);
if (null === $inputData && $useInputData) {
$inputData = static::$commandInputData;
}
$commandTester = new CommandTester($installCommand);
$commandTester->execute(
$inputData ?? [],
['interactive' => false]
);
return $commandTester;
}
protected function setupDatabase(): void
{
self::$dic->set(DBStorageInterface::class, getDbHandler());
}
}

View File

@@ -0,0 +1,168 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Tests\Modules\Cli\Commands;
use DI\DependencyException;
use DI\NotFoundException;
use SP\Config\Config;
use SP\Core\Exceptions\FileNotFoundException;
use SP\Modules\Cli\Commands\BackupCommand;
use SP\Services\Backup\FileBackupService;
use SP\Tests\Modules\Cli\CliTestCase;
use function SP\Tests\recreateDir;
/**
*
*/
class BackupCommandTest extends CliTestCase
{
/**
* @var string
*/
protected static string $currentConfig;
/**
* @var string[]
*/
protected static array $commandInputData = [
'--path' => TMP_PATH
];
/**
* @throws DependencyException
* @throws NotFoundException
*/
public function testBackupFails(): void
{
$inputData = ['--path' => '/non/existant/path'];
$commandTester = $this->executeCommandTest(
BackupCommand::class,
$inputData
);
// the output of the command in the console
$output = $commandTester->getDisplay();
$this->assertStringContainsString('Unable to create the backups directory', $output);
}
/**
* @throws DependencyException
* @throws FileNotFoundException
* @throws NotFoundException
*/
public function testBackupIsSuccessful(): void
{
$this->setupDatabase();
$commandTester = $this->executeCommandTest(
BackupCommand::class,
self::$commandInputData
);
// the output of the command in the console
$output = $commandTester->getDisplay();
$this->assertStringContainsString('Application and database backup completed successfully', $output);
$this->checkBackupFilesAreCreated();
// Recreate cache directory to avoid unwanted behavior
recreateDir(CACHE_PATH);
}
private function checkBackupFilesAreCreated(): void
{
$configData = self::$dic->get(Config::class)->getConfigData();
$this->assertFileExists(
FileBackupService::getAppBackupFilename(
TMP_PATH,
$configData->getBackupHash(),
true
)
);
$this->assertFileExists(
FileBackupService::getDbBackupFilename(
TMP_PATH,
$configData->getBackupHash(),
true
)
);
}
/**
* @throws DependencyException
* @throws NotFoundException
*/
public function testBackupFromEnvironmentVarIsAbort(): void
{
putenv(sprintf('%s=%s',
BackupCommand::$envVarsMapping['path'],
'/non/existant/path')
);
$commandTester = $this->executeCommandTest(
BackupCommand::class,
null,
false
);
// the output of the command in the console
$output = $commandTester->getDisplay();
$this->assertStringContainsString('Unable to create the backups directory', $output);
}
/**
* @throws DependencyException
* @throws NotFoundException
* @throws FileNotFoundException
*/
public function testBackupFromEnvironmentVarIsSuccessful(): void
{
$this->setEnvironmentVariables();
$commandTester = $this->executeCommandTest(
BackupCommand::class,
null,
false
);
// the output of the command in the console
$output = $commandTester->getDisplay();
$this->assertStringContainsString('Application and database backup completed successfully', $output);
$this->checkBackupFilesAreCreated();
// Recreate cache directory to avoid unwanted behavior
recreateDir(CACHE_PATH);
}
private function setEnvironmentVariables(): void
{
putenv(sprintf('%s=%s',
BackupCommand::$envVarsMapping['path'],
TMP_PATH)
);
}
}

View File

@@ -32,7 +32,6 @@ use SP\Modules\Cli\Commands\InstallCommand;
use SP\Storage\Database\DatabaseException;
use SP\Tests\DatabaseUtil;
use SP\Tests\Modules\Cli\CliTestCase;
use Symfony\Component\Console\Tester\CommandTester;
use function SP\Tests\getResource;
use function SP\Tests\recreateDir;
use function SP\Tests\saveResource;
@@ -45,11 +44,11 @@ class InstallCommandTest extends CliTestCase
/**
* @var string
*/
protected static $currentConfig;
protected static string $currentConfig;
/**
* @var string[]
*/
private static $commandInputData = [
protected static array $commandInputData = [
'adminLogin' => 'Admin',
'databaseHost' => 'localhost',
'databaseName' => 'syspass-test-install',
@@ -92,41 +91,13 @@ class InstallCommandTest extends CliTestCase
*/
public function testInstallationIsAborted(): void
{
$commandTester = $this->executeCommandTest();
$commandTester = $this->executeCommandTest(InstallCommand::class);
// the output of the command in the console
$output = $commandTester->getDisplay();
$this->assertStringContainsString('Installation aborted', $output);
}
/**
* @param array|null $inputData
* @param bool $useInputData
*
* @return CommandTester
* @throws DependencyException
* @throws NotFoundException
*/
private function executeCommandTest(
?array $inputData = null,
bool $useInputData = true
): CommandTester
{
$installCommand = self::$dic->get(InstallCommand::class);
if (null === $inputData && $useInputData) {
$inputData = self::$commandInputData;
}
$commandTester = new CommandTester($installCommand);
$commandTester->execute(
$inputData ?? [],
['interactive' => false]
);
return $commandTester;
}
/**
* @throws DependencyException
* @throws NotFoundException
@@ -138,7 +109,10 @@ class InstallCommandTest extends CliTestCase
['--forceInstall' => null]
);
$commandTester = $this->executeCommandTest($inputData);
$commandTester = $this->executeCommandTest(
InstallCommand::class,
$inputData
);
// the output of the command in the console
$output = $commandTester->getDisplay();
@@ -156,7 +130,10 @@ class InstallCommandTest extends CliTestCase
['--adminPassword' => '']
);
$commandTester = $this->executeCommandTest($inputData);
$commandTester = $this->executeCommandTest(
InstallCommand::class,
$inputData
);
// the output of the command in the console
$output = $commandTester->getDisplay();
@@ -174,7 +151,10 @@ class InstallCommandTest extends CliTestCase
['--masterPassword' => '']
);
$commandTester = $this->executeCommandTest($inputData);
$commandTester = $this->executeCommandTest(
InstallCommand::class,
$inputData
);
// the output of the command in the console
$output = $commandTester->getDisplay();
@@ -198,7 +178,10 @@ class InstallCommandTest extends CliTestCase
]
);
$commandTester = $this->executeCommandTest($inputData);
$commandTester = $this->executeCommandTest(
InstallCommand::class,
$inputData
);
// the output of the command in the console
$output = $commandTester->getDisplay();
@@ -229,7 +212,10 @@ class InstallCommandTest extends CliTestCase
]
);
$commandTester = $this->executeCommandTest($inputData);
$commandTester = $this->executeCommandTest(
InstallCommand::class,
$inputData
);
// the output of the command in the console
$output = $commandTester->getDisplay();
@@ -273,7 +259,10 @@ class InstallCommandTest extends CliTestCase
]
);
$commandTester = $this->executeCommandTest($inputData);
$commandTester = $this->executeCommandTest(
InstallCommand::class,
$inputData
);
// the output of the command in the console
$output = $commandTester->getDisplay();
@@ -296,7 +285,11 @@ class InstallCommandTest extends CliTestCase
{
$this->setEnvironmentVariables();
$commandTester = $this->executeCommandTest(null, false);
$commandTester = $this->executeCommandTest(
InstallCommand::class,
null,
false
);
// the output of the command in the console
$output = $commandTester->getDisplay();
@@ -347,7 +340,11 @@ class InstallCommandTest extends CliTestCase
$this->setEnvironmentVariables();
$commandTester = $this->executeCommandTest(null, false);
$commandTester = $this->executeCommandTest(
InstallCommand::class,
null,
false
);
// the output of the command in the console
$output = $commandTester->getDisplay();
@@ -370,7 +367,11 @@ class InstallCommandTest extends CliTestCase
$this->setEnvironmentVariables();
$commandTester = $this->executeCommandTest(null, false);
$commandTester = $this->executeCommandTest(
InstallCommand::class,
null,
false
);
// the output of the command in the console
$output = $commandTester->getDisplay();

View File

@@ -27,13 +27,16 @@ namespace SP\Tests;
use DI\Container;
use DI\ContainerBuilder;
use Exception;
use RuntimeException;
use SP\Core\Context\ContextException;
use SP\Core\Context\ContextInterface;
use SP\Core\Exceptions\FileNotFoundException;
use SP\DataModel\ProfileData;
use SP\Services\User\UserLoginResponse;
use SP\Storage\Database\DatabaseConnectionData;
use SP\Storage\Database\DBStorageInterface;
use SP\Storage\Database\MySQLHandler;
use SP\Util\FileUtil;
define('DEBUG', true);
@@ -46,11 +49,11 @@ define('CONFIG_PATH', RESOURCE_PATH . DIRECTORY_SEPARATOR . 'config');
define('CONFIG_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'config.xml');
define('ACTIONS_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'actions.xml');
define('MODULES_PATH', APP_ROOT. DIRECTORY_SEPARATOR. 'app' . DIRECTORY_SEPARATOR . 'modules');
define('MODULES_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'modules');
define('SQL_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'schemas');
define('CACHE_PATH', RESOURCE_PATH . DIRECTORY_SEPARATOR . 'cache');
define('TMP_PATH', TEST_ROOT . DIRECTORY_SEPARATOR . 'tmp');
define('BACKUP_PATH', TMP_PATH);
define('XML_SCHEMA', APP_ROOT . DIRECTORY_SEPARATOR . 'schemas' . DIRECTORY_SEPARATOR . 'syspass.xsd');
@@ -189,19 +192,20 @@ function saveResource($dir, $file, $data): string
/**
* @param $dir
*
* @throws FileNotFoundException
*/
function recreateDir($dir)
{
if (!is_dir($dir)) {
print 'Creating ' . $dir . PHP_EOL;
if (!mkdir($dir) && !is_dir($dir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));
}
} else {
if (is_dir($dir)) {
print 'Deleting ' . $dir . PHP_EOL;
// Delete tmp dir ...
array_map('unlink', glob($dir . DIRECTORY_SEPARATOR . '*'));
FileUtil::rmdir_recursive($dir);
}
print 'Creating ' . $dir . PHP_EOL;
if (!mkdir($dir) && !is_dir($dir)) {
throw new RuntimeException(sprintf('Directory "%s" was not created', $dir));
}
}