From a6dad3341f704863491d178102713c8a81964bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20D?= Date: Fri, 7 Jun 2024 14:31:08 +0200 Subject: [PATCH] test(DI): Implement definitions test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rubén D --- .../Controllers/Config/BackupController.php | 33 +-- .../DownloadBackupAppController.php | 13 +- .../DownloadBackupDbController.php | 13 +- .../ConfigBackup/DownloadExportController.php | 12 +- .../ConfigManager/IndexController.php | 54 ++--- .../Controllers/Upgrade/UpgradeController.php | 2 +- app/modules/web/module.php | 10 +- lib/BaseFunctions.php | 6 +- lib/SP/Core/Application.php | 5 +- .../Core/Context/SessionLifecycleHandler.php | 2 +- lib/SP/Core/Context/Stateless.php | 14 +- lib/SP/Core/Definitions/CoreDefinitions.php | 123 +++++++---- lib/SP/Core/Definitions/DomainDefinitions.php | 6 +- lib/SP/Core/UI/ThemeIcons.php | 5 +- lib/SP/Domain/Common/Providers/Image.php | 5 +- .../Config/Ports/ConfigDataInterface.php | 3 +- .../Domain/Config/Ports/ConfigFileService.php | 2 - lib/SP/Domain/Config/Services/ConfigFile.php | 51 +++-- lib/SP/Domain/Export/Dtos/BackupFile.php | 66 ++++++ lib/SP/Domain/Export/Dtos/BackupFiles.php | 64 ++++++ .../Dtos/BackupType.php} | 22 +- .../Domain/Export/Ports/BackupFileService.php | 3 +- lib/SP/Domain/Export/Services/BackupFile.php | 105 ++++----- .../Export/Services/BackupFileHelper.php | 131 ----------- lib/SP/Domain/Export/Services/XmlExport.php | 27 +-- .../File/Ports/ArchiveHandlerInterface.php | 2 +- lib/SP/Domain/Http/Services/Request.php | 13 +- ...Interface.php => DatabaseSetupService.php} | 6 +- lib/SP/Domain/Install/Services/Installer.php | 8 +- .../{MysqlService.php => MysqlSetup.php} | 7 +- .../Install/Services/MysqlSetupBuilder.php | 57 ----- .../Domain/Storage/Ports/FileCacheService.php | 5 +- lib/SP/Domain/Upgrade/Services/Upgrade.php | 2 +- lib/SP/Domain/User/Dtos/UserDataDto.php | 42 ++-- .../Common/Repositories/BaseRepository.php | 5 + .../Database/DatabaseConnectionData.php | 15 ++ .../Infrastructure/Database/MysqlHandler.php | 19 +- lib/SP/Infrastructure/File/ArchiveHandler.php | 33 +-- lib/SP/Infrastructure/File/FileCache.php | 4 +- lib/SP/Infrastructure/File/FileCacheBase.php | 9 +- lib/SP/Infrastructure/File/FileHandler.php | 21 +- lib/SP/Infrastructure/File/FileSystem.php | 15 ++ .../Context/SessionLifecycleHandlerTest.php | 18 ++ tests/SP/Core/Definitions/DefinitionsTest.php | 118 ++++++++++ tests/SP/Core/UI/ThemeIconsTest.php | 5 +- tests/SP/Core/UI/ThemeTest.php | 2 - .../SP/Domain/Common/Providers/ImageTest.php | 5 +- .../Domain/Config/Services/ConfigFileTest.php | 117 ++-------- .../Export/Services/BackupFileHelperTest.php | 141 ------------ .../Export/Services/FileBackupServiceTest.php | 106 ++++----- .../Domain/Export/Services/XmlExportTest.php | 14 -- tests/SP/Domain/Http/Services/RequestTest.php | 25 +-- .../Domain/Install/Services/InstallerTest.php | 8 +- .../SP/Domain/Install/Services/MySQLTest.php | 8 +- .../Upgrade/Services/UpgradeDatabaseTest.php | 2 +- .../Domain/Upgrade/Services/UpgradeTest.php | 2 +- .../Helpers/Account/AccountSearchDataTest.php | 0 tests/SP/bootstrap.php | 76 ++++--- tests/res/config/mime.xml | 209 ++++++++++++++++++ tests/res/view/theme/inc/Icons.php | 25 +++ 60 files changed, 1017 insertions(+), 904 deletions(-) create mode 100644 lib/SP/Domain/Export/Dtos/BackupFile.php create mode 100644 lib/SP/Domain/Export/Dtos/BackupFiles.php rename lib/SP/Domain/{Install/Services/MysqlSetupBuilderInterface.php => Export/Dtos/BackupType.php} (60%) delete mode 100644 lib/SP/Domain/Export/Services/BackupFileHelper.php rename lib/SP/Domain/Install/Services/{DatabaseSetupInterface.php => DatabaseSetupService.php} (95%) rename lib/SP/Domain/Install/Services/{MysqlService.php => MysqlSetup.php} (99%) delete mode 100644 lib/SP/Domain/Install/Services/MysqlSetupBuilder.php create mode 100644 tests/SP/Core/Definitions/DefinitionsTest.php delete mode 100644 tests/SP/Domain/Export/Services/BackupFileHelperTest.php rename tests/SP/{Domain/SP/Tests => }/Modules/Web/Controllers/Helpers/Account/AccountSearchDataTest.php (100%) create mode 100644 tests/res/config/mime.xml create mode 100644 tests/res/view/theme/inc/Icons.php diff --git a/app/modules/api/Controllers/Config/BackupController.php b/app/modules/api/Controllers/Config/BackupController.php index 2a1e5787c..e8acd161a 100644 --- a/app/modules/api/Controllers/Config/BackupController.php +++ b/app/modules/api/Controllers/Config/BackupController.php @@ -34,8 +34,8 @@ use SP\Domain\Core\Acl\AclActionsInterface; use SP\Domain\Core\Acl\AclInterface; use SP\Domain\Core\Exceptions\InvalidClassException; +use SP\Domain\Export\Dtos\BackupFiles; use SP\Domain\Export\Ports\BackupFileService; -use SP\Domain\Export\Services\BackupFileHelper; use SP\Modules\Api\Controllers\ControllerBase; use SP\Modules\Api\Controllers\Help\ConfigHelp; @@ -46,22 +46,19 @@ */ final class BackupController extends ControllerBase { - private BackupFileService $fileBackupService; - /** * @throws InvalidClassException */ public function __construct( - Application $application, - Klein $router, - ApiService $apiService, - AclInterface $acl, - BackupFileService $fileBackupService + Application $application, + Klein $router, + ApiService $apiService, + AclInterface $acl, + private readonly BackupFileService $fileBackupService, + private readonly BackupFiles $backupFiles ) { parent::__construct($application, $router, $apiService, $acl); - $this->fileBackupService = $fileBackupService; - $this->apiService->setHelpClass(ConfigHelp::class); } @@ -98,24 +95,18 @@ public function backupAction(): void } /** - * @param string|null $path + * @param string|null $path * * @return array[] */ private function buildBackupFiles(?string $path): array { + $backupFiles = $this->backupFiles->withPath($path); + return [ 'files' => [ - 'app' => BackupFileHelper::getAppBackupFilename( - $path, - $this->fileBackupService->getHash(), - true - ), - 'db' => BackupFileHelper::getDbBackupFilename( - $path, - $this->fileBackupService->getHash(), - true - ), + 'app' => (string)$backupFiles->getAppBackupFile(), + 'db' => (string)$backupFiles->getDbBackupFile(), ], ]; } diff --git a/app/modules/web/Controllers/ConfigBackup/DownloadBackupAppController.php b/app/modules/web/Controllers/ConfigBackup/DownloadBackupAppController.php index 77d27813f..faf0f5a23 100644 --- a/app/modules/web/Controllers/ConfigBackup/DownloadBackupAppController.php +++ b/app/modules/web/Controllers/ConfigBackup/DownloadBackupAppController.php @@ -33,7 +33,8 @@ use SP\Domain\Core\Acl\UnauthorizedPageException; use SP\Domain\Core\Exceptions\SessionTimeout; use SP\Domain\Core\Exceptions\SPException; -use SP\Domain\Export\Services\BackupFileHelper; +use SP\Domain\Export\Dtos\BackupFile; +use SP\Domain\Export\Dtos\BackupType; use SP\Infrastructure\File\FileHandler; use SP\Modules\Web\Controllers\SimpleControllerBase; use SP\Modules\Web\Controllers\Traits\JsonTrait; @@ -57,13 +58,9 @@ public function downloadBackupAppAction(): string try { Session::close(); - $filePath = BackupFileHelper::getAppBackupFilename( - BACKUP_PATH, - $this->configData->getBackupHash(), - true - ); + $filePath = new BackupFile(BackupType::app, $this->configData->getBackupHash(), BACKUP_PATH, 'gz'); - $file = new FileHandler($filePath); + $file = new FileHandler((string)$filePath); $file->checkFileExists(); $this->eventDispatcher->notify( @@ -83,7 +80,7 @@ public function downloadBackupAppAction(): string ->header('Content-type', $file->getFileType()) ->header('Content-Description', ' sysPass file') ->header('Content-transfer-encoding', 'chunked') - ->header('Content-Disposition', 'attachment; filename="'.basename($file->getFile()).'"') + ->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"') ->header('Set-Cookie', 'fileDownload=true; path=/') ->send(); diff --git a/app/modules/web/Controllers/ConfigBackup/DownloadBackupDbController.php b/app/modules/web/Controllers/ConfigBackup/DownloadBackupDbController.php index 6c24b82ba..be00dbecb 100644 --- a/app/modules/web/Controllers/ConfigBackup/DownloadBackupDbController.php +++ b/app/modules/web/Controllers/ConfigBackup/DownloadBackupDbController.php @@ -32,7 +32,8 @@ use SP\Domain\Core\Acl\UnauthorizedPageException; use SP\Domain\Core\Exceptions\SessionTimeout; use SP\Domain\Core\Exceptions\SPException; -use SP\Domain\Export\Services\BackupFileHelper; +use SP\Domain\Export\Dtos\BackupFile; +use SP\Domain\Export\Dtos\BackupType; use SP\Infrastructure\File\FileHandler; use SP\Modules\Web\Controllers\SimpleControllerBase; use SP\Modules\Web\Controllers\Traits\JsonTrait; @@ -58,13 +59,9 @@ public function downloadBackupDbAction(): string try { Session::close(); - $filePath = BackupFileHelper::getDbBackupFilename( - BACKUP_PATH, - $this->configData->getBackupHash(), - true - ); + $filePath = new BackupFile(BackupType::db, $this->configData->getBackupHash(), BACKUP_PATH, 'gz'); - $file = new FileHandler($filePath); + $file = new FileHandler((string)$filePath); $file->checkFileExists(); $this->eventDispatcher->notify( @@ -84,7 +81,7 @@ public function downloadBackupDbAction(): string ->header('Content-type', $file->getFileType()) ->header('Content-Description', ' sysPass file') ->header('Content-transfer-encoding', 'chunked') - ->header('Content-Disposition', 'attachment; filename="'.basename($file->getFile()).'"') + ->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"') ->header('Set-Cookie', 'fileDownload=true; path=/') ->send(); diff --git a/app/modules/web/Controllers/ConfigBackup/DownloadExportController.php b/app/modules/web/Controllers/ConfigBackup/DownloadExportController.php index f8478a228..38c8766d6 100644 --- a/app/modules/web/Controllers/ConfigBackup/DownloadExportController.php +++ b/app/modules/web/Controllers/ConfigBackup/DownloadExportController.php @@ -33,7 +33,8 @@ use SP\Domain\Core\Acl\UnauthorizedPageException; use SP\Domain\Core\Exceptions\SessionTimeout; use SP\Domain\Core\Exceptions\SPException; -use SP\Domain\Export\Services\XmlExport; +use SP\Domain\Export\Dtos\BackupFile as BackupFileDto; +use SP\Domain\Export\Dtos\BackupType; use SP\Infrastructure\File\FileHandler; use SP\Modules\Web\Controllers\SimpleControllerBase; use SP\Modules\Web\Controllers\Traits\JsonTrait; @@ -53,10 +54,11 @@ public function downloadExportAction(): string try { Session::close(); - $filePath = XmlExport::buildFilename( + $filePath = (string)new BackupFileDto( + BackupType::export, + $this->configData->getExportHash() ?: '', BACKUP_PATH, - $this->configData->getExportHash(), - true + 'gz' ); $file = new FileHandler($filePath); @@ -79,7 +81,7 @@ public function downloadExportAction(): string ->header('Content-type', $file->getFileType()) ->header('Content-Description', ' sysPass file') ->header('Content-transfer-encoding', 'chunked') - ->header('Content-Disposition', 'attachment; filename="'.basename($file->getFile()).'"') + ->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"') ->header('Set-Cookie', 'fileDownload=true; path=/') ->send(); diff --git a/app/modules/web/Controllers/ConfigManager/IndexController.php b/app/modules/web/Controllers/ConfigManager/IndexController.php index 84642b7af..9f46be110 100644 --- a/app/modules/web/Controllers/ConfigManager/IndexController.php +++ b/app/modules/web/Controllers/ConfigManager/IndexController.php @@ -48,8 +48,9 @@ use SP\Domain\Core\File\MimeType; use SP\Domain\Core\File\MimeTypesService; use SP\Domain\Crypt\Services\TemporaryMasterPass; -use SP\Domain\Export\Services\BackupFileHelper; -use SP\Domain\Export\Services\XmlExport; +use SP\Domain\Export\Dtos\BackupFile as BackupFileDto; +use SP\Domain\Export\Dtos\BackupFiles; +use SP\Domain\Export\Dtos\BackupType; use SP\Domain\Log\Providers\LogInterface; use SP\Domain\Notification\Services\MailEvent; use SP\Domain\Task\Services\Task; @@ -84,17 +85,18 @@ final class IndexController extends ControllerBase private PluginManager $pluginManager; public function __construct( - Application $application, - WebControllerHelper $webControllerHelper, - TabsHelper $tabsHelper, - UserService $userService, - UserGroupService $userGroupService, - UserProfileService $userProfileService, - MimeTypesService $mimeTypes, - DatabaseUtil $databaseUtil, - ConfigService $configService, - AccountService $accountService, - PluginManager $pluginManager + Application $application, + WebControllerHelper $webControllerHelper, + TabsHelper $tabsHelper, + UserService $userService, + UserGroupService $userGroupService, + UserProfileService $userProfileService, + MimeTypesService $mimeTypes, + DatabaseUtil $databaseUtil, + ConfigService $configService, + AccountService $accountService, + PluginManager $pluginManager, + private readonly BackupFiles $backupFiles ) { parent::__construct($application, $webControllerHelper); @@ -457,25 +459,17 @@ protected function getBackupConfig(): DataTab $template->assign('siteName', AppInfoInterface::APP_NAME); - $backupAppFile = new FileHandler( - BackupFileHelper::getAppBackupFilename( - BACKUP_PATH, - $this->configData->getBackupHash() ?: '', - true - ) - ); - $backupDbFile = new FileHandler( - BackupFileHelper::getDbBackupFilename( - BACKUP_PATH, - $this->configData->getBackupHash() ?: '', - true - ) - ); + $backupFiles = $this->backupFiles->withHash($this->configData->getBackupHash() ?? ''); + + $backupAppFile = new FileHandler((string)$backupFiles->getAppBackupFile()); + $backupDbFile = new FileHandler((string)$backupFiles->getDbBackupFile()); + $exportFile = new FileHandler( - XmlExport::buildFilename( - BACKUP_PATH, + (string)new BackupFileDto( + BackupType::export, $this->configData->getExportHash() ?: '', - true + BACKUP_PATH, + 'gz' ) ); diff --git a/app/modules/web/Controllers/Upgrade/UpgradeController.php b/app/modules/web/Controllers/Upgrade/UpgradeController.php index d5e83f52a..057e08d74 100644 --- a/app/modules/web/Controllers/Upgrade/UpgradeController.php +++ b/app/modules/web/Controllers/Upgrade/UpgradeController.php @@ -75,7 +75,7 @@ public function upgradeAction(): bool $this->handleApplication(); $this->configData->setUpgradeKey(null); - $this->config->save($this->configData, false); + $this->config->save($this->configData); return $this->returnJsonResponse( JsonMessage::JSON_SUCCESS, diff --git a/app/modules/web/module.php b/app/modules/web/module.php index 05f25eaad..1d7c8595e 100644 --- a/app/modules/web/module.php +++ b/app/modules/web/module.php @@ -23,11 +23,12 @@ */ use SP\Core\Context\Session; +use SP\Core\Crypt\Csrf; use SP\Domain\Config\Ports\ConfigDataInterface; use SP\Domain\Core\Bootstrap\BootstrapInterface; use SP\Domain\Core\Bootstrap\ModuleInterface; use SP\Domain\Core\Context\Context; -use SP\Domain\Html\Ports\MinifyService; +use SP\Domain\Core\Crypt\CsrfHandler; use SP\Domain\Html\Services\MinifyCss; use SP\Domain\Html\Services\MinifyJs; use SP\Modules\Web\Bootstrap; @@ -47,10 +48,10 @@ ModuleInterface::class => autowire(Init::class), CssController::class => autowire( CssController::class - )->constructorParameter(MinifyService::class, autowire(MinifyCss::class)), + )->constructorParameter('minify', autowire(MinifyCss::class)), JsController::class => autowire( JsController::class - )->constructorParameter(MinifyService::class, autowire(MinifyJs::class)), + )->constructorParameter('minify', autowire(MinifyJs::class)), Context::class => factory( static function (ConfigDataInterface $configData, SessionHandlerInterface $sessionHandler) { if ($configData->isEncryptSession()) { @@ -59,5 +60,6 @@ static function (ConfigDataInterface $configData, SessionHandlerInterface $sessi return new Session(); } - ) + ), + CsrfHandler::class => autowire(Csrf::class), ]; diff --git a/lib/BaseFunctions.php b/lib/BaseFunctions.php index eb65ef24c..4a5490ac4 100644 --- a/lib/BaseFunctions.php +++ b/lib/BaseFunctions.php @@ -66,9 +66,8 @@ function logger(mixed $data, string $type = 'DEBUG'): void $caller ); - /** @noinspection ForgottenDebugOutputInspection */ $useOwn = (!defined('LOG_FILE') - || !@error_log($line, 3, LOG_FILE) + || !@file_put_contents(LOG_FILE, $line, FILE_APPEND) ); if ($useOwn === false) { @@ -79,8 +78,7 @@ function logger(mixed $data, string $type = 'DEBUG'): void $caller ); - /** @noinspection ForgottenDebugOutputInspection */ - @error_log($line); + @file_put_contents(LOG_FILE, $line, FILE_APPEND); } } diff --git a/lib/SP/Core/Application.php b/lib/SP/Core/Application.php index 4b13c1d22..0dc835f6d 100644 --- a/lib/SP/Core/Application.php +++ b/lib/SP/Core/Application.php @@ -1,4 +1,5 @@ setContext(new ContextCollection()); + } + /** * Establece los datos del usuario en la sesión. */ @@ -146,12 +156,8 @@ public function resetAppStatus(): ?bool return $this->setContextKey('status', null); } - /** - * @throws ContextException - */ public function initialize(): void { - $this->setContext(new ContextCollection()); } /** diff --git a/lib/SP/Core/Definitions/CoreDefinitions.php b/lib/SP/Core/Definitions/CoreDefinitions.php index 3ea4a9e41..cc7dd1ddb 100644 --- a/lib/SP/Core/Definitions/CoreDefinitions.php +++ b/lib/SP/Core/Definitions/CoreDefinitions.php @@ -43,11 +43,12 @@ use SP\Core\Crypt\Crypt; use SP\Core\Crypt\CryptPKI; use SP\Core\Crypt\CryptSessionHandler; -use SP\Core\Crypt\Csrf; use SP\Core\Crypt\RequestBasedPassword; use SP\Core\Crypt\UuidCookie; +use SP\Core\Events\EventDispatcher; use SP\Core\Language; use SP\Core\MimeTypes; +use SP\Core\PhpExtensionChecker; use SP\Core\ProvidersHelper; use SP\Core\UI\Theme; use SP\Core\UI\ThemeContext; @@ -69,7 +70,6 @@ use SP\Domain\Auth\Providers\Ldap\LdapConnection; use SP\Domain\Auth\Providers\Ldap\LdapParams; use SP\Domain\Common\Providers\Filter; -use SP\Domain\Config\Ports\ConfigBackupService; use SP\Domain\Config\Ports\ConfigDataInterface; use SP\Domain\Config\Ports\ConfigFileService; use SP\Domain\Config\Services\ConfigFile; @@ -80,30 +80,32 @@ use SP\Domain\Core\Context\Context; use SP\Domain\Core\Crypt\CryptInterface; use SP\Domain\Core\Crypt\CryptPKIHandler; -use SP\Domain\Core\Crypt\CsrfHandler; use SP\Domain\Core\Crypt\RequestBasedPasswordInterface; use SP\Domain\Core\Crypt\UuidCookieInterface; -use SP\Domain\Core\Exceptions\SPException; +use SP\Domain\Core\Events\EventDispatcherInterface; use SP\Domain\Core\File\MimeTypesService; use SP\Domain\Core\LanguageInterface; +use SP\Domain\Core\PhpExtensionCheckerService; use SP\Domain\Core\UI\ThemeContextInterface; use SP\Domain\Core\UI\ThemeIconsInterface; use SP\Domain\Core\UI\ThemeInterface; use SP\Domain\Crypt\Ports\SecureSessionService; use SP\Domain\Crypt\Services\SecureSession; +use SP\Domain\Database\Ports\DatabaseFileInterface; use SP\Domain\Database\Ports\DatabaseInterface; use SP\Domain\Database\Ports\DbStorageHandler; -use SP\Domain\Export\Ports\BackupFileHelperService; -use SP\Domain\Export\Services\BackupFileHelper; -use SP\Domain\File\Ports\FileHandlerInterface; -use SP\Domain\Html\Ports\MinifyService; -use SP\Domain\Html\Services\Minify; +use SP\Domain\Export\Dtos\BackupFile as BackupFileDto; +use SP\Domain\Export\Dtos\BackupFiles; +use SP\Domain\Export\Dtos\BackupType; +use SP\Domain\Export\Ports\BackupFileService; +use SP\Domain\Export\Services\BackupFile; use SP\Domain\Http\Client; use SP\Domain\Http\Ports\RequestService; use SP\Domain\Http\Services\Request; +use SP\Domain\Install\Adapters\InstallData; use SP\Domain\Install\Adapters\InstallDataFactory; -use SP\Domain\Install\Services\DatabaseSetupInterface; -use SP\Domain\Install\Services\MysqlSetupBuilder; +use SP\Domain\Install\Services\DatabaseSetupService; +use SP\Domain\Install\Services\MysqlSetup; use SP\Domain\Log\Providers\DatabaseHandler; use SP\Domain\Log\Providers\LogHandler; use SP\Domain\Notification\Ports\MailerInterface; @@ -114,19 +116,24 @@ use SP\Domain\Storage\Ports\FileCacheService; use SP\Infrastructure\Database\Database; use SP\Infrastructure\Database\DatabaseConnectionData; +use SP\Infrastructure\Database\MysqlFileParser; use SP\Infrastructure\Database\MysqlHandler; -use SP\Infrastructure\File\DirectoryHandler; +use SP\Infrastructure\File\ArchiveHandler; use SP\Infrastructure\File\FileCache; use SP\Infrastructure\File\FileHandler; +use SP\Infrastructure\File\FileSystem; use SP\Infrastructure\File\XmlFileStorage; +use SP\Mvc\View\OutputHandler; +use SP\Mvc\View\OutputHandlerInterface; use SP\Mvc\View\Template; use SP\Mvc\View\TemplateInterface; +use SP\Mvc\View\TemplateResolver; +use SP\Mvc\View\TemplateResolverInterface; use function DI\autowire; use function DI\create; use function DI\factory; use function DI\get; -use function SP\__u; /** * Class CoreDefinitions @@ -140,17 +147,33 @@ public static function getDefinitions(): array RequestService::class => autowire(Request::class), UriContextInterface::class => autowire(UriContext::class), Context::class => create(Stateless::class), + EventDispatcherInterface::class => create(EventDispatcher::class), ConfigFileService::class => create(ConfigFile::class) ->constructor( create(XmlFileStorage::class) - ->constructor(create(FileHandlerInterface::class)->constructor(CONFIG_FILE)), - create(FileCacheService::class)->constructor(ConfigFile::CONFIG_CACHE_FILE), - get(Context::class), - autowire(ConfigBackupService::class) + ->constructor(create(FileHandler::class)->constructor(CONFIG_FILE)), + create(FileCache::class)->constructor(ConfigFile::CONFIG_CACHE_FILE), + get(Context::class) ), ConfigDataInterface::class => factory([ConfigFileService::class, 'getConfigData']), - DatabaseConnectionData::class => factory([DatabaseConnectionData::class, 'getFromConfig']), + InstallData::class => factory([InstallDataFactory::class, 'buildFromRequest']), + DatabaseConnectionData::class => factory( + static function (ConfigDataInterface $configData, InstallData $installData) { + if (!$configData->isInstalled()) { + return DatabaseConnectionData::getFromInstallData($installData); + } + + // TODO: get from env vars + return DatabaseConnectionData::getFromConfig($configData); + } + ), + DatabaseFileInterface::class => create(MysqlFileParser::class) + ->constructor( + create(FileHandler::class) + ->constructor(FileSystem::buildPath(SQL_PATH, 'dbstructure.sql')) + ), DbStorageHandler::class => autowire(MysqlHandler::class), + DatabaseSetupService::class => autowire(MysqlSetup::class), ActionsInterface::class => static fn() => new Actions( new FileCache(Actions::ACTIONS_CACHE_FILE), @@ -170,8 +193,9 @@ public static function getDefinitions(): array ->constructorParameter('name', factory([Theme::class, 'getThemeName'])), ThemeIconsInterface::class => factory([ThemeIcons::class, 'loadIcons']) ->parameter( - 'iconsCache', - create(FileCache::class)->constructor(ThemeIcons::ICONS_CACHE_FILE) + 'cache', + create(FileCache::class) + ->constructor(FileSystem::buildPath(CACHE_PATH, ThemeIcons::ICONS_CACHE_FILE)) ), ThemeInterface::class => autowire(Theme::class), TemplateInterface::class => autowire(Template::class) @@ -232,7 +256,6 @@ static function ( }), \GuzzleHttp\Client::class => create(\GuzzleHttp\Client::class) ->constructor(factory([Client::class, 'getOptions'])), - CsrfHandler::class => autowire(Csrf::class), LanguageInterface::class => autowire(Language::class), DatabaseInterface::class => autowire(Database::class), PhpMailerService::class => autowire(PhpMailerService::class), @@ -240,17 +263,7 @@ static function ( ->parameter( 'mailParams', factory([Mail::class, 'getParamsFromConfig']) - ->parameter('configData', get(ConfigDataInterface::class)) ), - DatabaseSetupInterface::class => static function (RequestService $request) { - $installData = InstallDataFactory::buildFromRequest($request); - - if ($installData->getBackendType() === 'mysql') { - return MysqlSetupBuilder::build($installData); - } - - throw SPException::error(__u('Unimplemented'), __u('Wrong backend type')); - }, ProvidersHelper::class => factory(static function (ContainerInterface $c) { $configData = $c->get(ConfigDataInterface::class); @@ -270,13 +283,47 @@ static function ( ->constructor('mysql', QueryFactory::COMMON), CryptInterface::class => create(Crypt::class), CryptPKIHandler::class => autowire(CryptPKI::class) - ->constructorParameter('publicKeyFile', new FileHandler(CryptPKI::PUBLIC_KEY_FILE)) - ->constructorParameter('privateKeyFile', new FileHandler(CryptPKI::PRIVATE_KEY_FILE)), + ->constructorParameter( + 'publicKeyFile', + create(FileHandler::class)->constructor(CryptPKI::PUBLIC_KEY_FILE, 'w') + ) + ->constructorParameter( + 'privateKeyFile', + create(FileHandler::class)->constructor(CryptPKI::PRIVATE_KEY_FILE, 'w') + ), FileCacheService::class => create(FileCache::class), RequestBasedPasswordInterface::class => autowire(RequestBasedPassword::class), - MinifyService::class => autowire(Minify::class), - BackupFileHelperService::class => autowire(BackupFileHelper::class) - ->constructorParameter('path', new DirectoryHandler(BACKUP_PATH)), + PhpExtensionCheckerService::class => create(PhpExtensionChecker::class), + BackupFiles::class => factory(static function () { + $hash = BackupFiles::buildHash(); + $appBackupFile = new BackupFileDto(BackupType::app, $hash, BACKUP_PATH, 'tar'); + $dbBackupFile = new BackupFileDto(BackupType::db, $hash, BACKUP_PATH, 'sql'); + + return new BackupFiles($appBackupFile, $dbBackupFile); + }), + 'backup.dbArchiveHandler' => autowire(ArchiveHandler::class) + ->constructorParameter( + 'archive', + factory( + static fn(BackupFiles $backupFiles) => (string)$backupFiles->getDbBackupFile() + ) + ), + 'backup.appArchiveHandler' => autowire(ArchiveHandler::class) + ->constructorParameter( + 'archive', + factory( + static fn(BackupFiles $backupFiles) => (string)$backupFiles->getAppBackupFile() + ) + ) + , + BackupFileService::class => autowire(BackupFile::class) + ->constructorParameter( + 'dbBackupFile', + create(FileHandler::class) + ->constructor(FileSystem::buildPath(BACKUP_PATH, 'database.sql'), 'wb+') + ) + ->constructorParameter('dbArchiveHandler', get('backup.dbArchiveHandler')) + ->constructorParameter('appArchiveHandler', get('backup.appArchiveHandler')), RouteContextData::class => factory(static function (KleinRequest $request) { return RouteContext::getRouteContextData(Filter::getString($request->param('r', 'index/index'))); }), @@ -292,7 +339,9 @@ static function (UuidCookieInterface $uuidCookie, ConfigDataInterface $configDat )->parameter('uuidCookie', factory([UuidCookie::class, 'factory'])) ), SessionHandlerInterface::class => autowire(CryptSessionHandler::class) - ->constructorParameter('key', [SecureSessionService::class, 'getKey']) + ->constructorParameter('key', factory([SecureSessionService::class, 'getKey'])), + OutputHandlerInterface::class => create(OutputHandler::class), + TemplateResolverInterface::class => autowire(TemplateResolver::class) ]; } } diff --git a/lib/SP/Core/Definitions/DomainDefinitions.php b/lib/SP/Core/Definitions/DomainDefinitions.php index 1c7784ce9..26de5b879 100644 --- a/lib/SP/Core/Definitions/DomainDefinitions.php +++ b/lib/SP/Core/Definitions/DomainDefinitions.php @@ -54,9 +54,9 @@ final class DomainDefinitions ]; private const PORTS = [ - 'Service' => 'SP\Domain\%s\Services', - 'Repository' => 'SP\Infrastructure\%s\Repositories', - 'Adapter' => 'SP\Domain\%s\Adapters' + 'Service' => 'SP\Domain\%s\Services\*', + 'Repository' => 'SP\Infrastructure\%s\Repositories\*', + 'Adapter' => 'SP\Domain\%s\Adapters\*' ]; public static function getDefinitions(): array diff --git a/lib/SP/Core/UI/ThemeIcons.php b/lib/SP/Core/UI/ThemeIcons.php index 406a446a3..c7da8bdc0 100644 --- a/lib/SP/Core/UI/ThemeIcons.php +++ b/lib/SP/Core/UI/ThemeIcons.php @@ -1,4 +1,5 @@ getAppStatus() !== ContextBase::APP_STATUS_RELOADED - && $cache->isExpired(self::CACHE_EXPIRE) + && !$cache->isExpired(self::CACHE_EXPIRE) ) { return $cache->load(); // logger('Loaded icons cache', 'INFO'); diff --git a/lib/SP/Domain/Common/Providers/Image.php b/lib/SP/Domain/Common/Providers/Image.php index 613220242..d9bf48cc6 100644 --- a/lib/SP/Domain/Common/Providers/Image.php +++ b/lib/SP/Domain/Common/Providers/Image.php @@ -1,4 +1,5 @@ checkCurl(true); } @@ -106,7 +107,7 @@ public function convertText(string $text): false|string || ($bgColor = imagecolorallocate($im, 245, 245, 245)) === false || ($fgColor = imagecolorallocate($im, 128, 128, 128)) === false || !imagefilledrectangle($im, 0, 0, $width, 30, $bgColor) || - !imagefttext($im, 10, 0, 10, 20, $fgColor, self::IMAGE_FONT, $text) + !imagefttext($im, 10, 0, 10, 20, $fgColor, $this->font, $text) ) { throw SPException::error(__u('Unable to create image')); } diff --git a/lib/SP/Domain/Config/Ports/ConfigDataInterface.php b/lib/SP/Domain/Config/Ports/ConfigDataInterface.php index 543cb52fb..59043b317 100644 --- a/lib/SP/Domain/Config/Ports/ConfigDataInterface.php +++ b/lib/SP/Domain/Config/Ports/ConfigDataInterface.php @@ -1,4 +1,5 @@ configData = $this->configData ?? $this->initialize(); + $this->configData = $configData ?? $this->initialize(); } /** @@ -114,14 +117,14 @@ private function isCacheExpired(): bool } } - private function loadFromFile(): ConfigData|null + private function loadFromFile(): ?ConfigDataInterface { try { $configData = $this->configMapper($this->fileStorage->load('config')); $this->fileCache->save($configData); return $configData; - } catch (FileException $e) { + } catch (ReflectionException|FileException $e) { processException($e); } @@ -130,16 +133,35 @@ private function loadFromFile(): ConfigData|null /** * Map the config array keys with ConfigData class setters + * @throws ReflectionException */ private function configMapper(array $items): ConfigDataInterface { $configData = new ConfigData(); + $reflectionObject = new ReflectionObject($configData); + + $methods = array_filter( + $reflectionObject->getMethods(ReflectionMethod::IS_PUBLIC), + static fn(ReflectionMethod $method) => str_starts_with($method->getName(), 'set') + ); + foreach ($items as $item => $value) { $methodName = sprintf("set%s", ucfirst($item)); - if (method_exists($configData, $methodName)) { - $configData->{$methodName}($value); + if (isset($methods[$methodName])) { + foreach ($methods[$methodName]->getParameters() as $parameter) { + $type = $parameter->getType(); + + if ($type instanceof ReflectionNamedType && $type->isBuiltin()) { + $value = match ($type->getName()) { + 'int' => (int)$value, + 'bool' => (bool)$value, + default => (string)$value + }; + $methods[$methodName]->invoke($configData, $value); + } + } } } @@ -150,17 +172,14 @@ private function configMapper(array $items): ConfigDataInterface * Guardar la configuración * * @param ConfigDataInterface $configData - * @param bool|null $backup * @param bool|null $commit * @return ConfigFileService * @throws FileException */ - public function save(ConfigDataInterface $configData, ?bool $backup = true, ?bool $commit = true): ConfigFileService - { - if ($backup) { - $this->configBackupService->backup($configData); - } - + public function save( + ConfigDataInterface $configData, + ?bool $commit = true + ): ConfigFileService { $configSaver = $this->context->getUserData()->getLogin() ?: AppInfoInterface::APP_NAME; $configData->setConfigDate(time()); @@ -190,7 +209,7 @@ private function generateNewConfig(): ConfigData // Generate a random salt that is used to add more seed to some passwords $configData->setPasswordSalt(Password::generateRandomBytes()); - $this->save($configData, false); + $this->save($configData); logger('Config file created', 'INFO'); @@ -228,7 +247,7 @@ public function generateUpgradeKey(): ConfigFileService if (empty($this->configData->getUpgradeKey())) { logger('Generating upgrade key'); - return $this->save($this->configData->setUpgradeKey(Password::generateRandomBytes(16)), false); + return $this->save($this->configData->setUpgradeKey(Password::generateRandomBytes(16))); } return $this; diff --git a/lib/SP/Domain/Export/Dtos/BackupFile.php b/lib/SP/Domain/Export/Dtos/BackupFile.php new file mode 100644 index 000000000..7914f9510 --- /dev/null +++ b/lib/SP/Domain/Export/Dtos/BackupFile.php @@ -0,0 +1,66 @@ +. + */ + +declare(strict_types=1); + +namespace SP\Domain\Export\Dtos; + +use SP\Domain\Common\Dtos\Dto; +use SP\Domain\Core\AppInfoInterface; +use SP\Infrastructure\File\FileSystem; + +/** + * Class BackupFile + */ +final class BackupFile extends Dto +{ + public function __construct( + private readonly BackupType $backupType, + private readonly string $hash, + private readonly string $path, + private readonly string $extension + ) { + } + + public function __toString(): string + { + return sprintf( + '%s_%s-%s.%s', + FileSystem::buildPath($this->path, AppInfoInterface::APP_NAME), + $this->backupType->name, + $this->hash, + $this->extension + ); + } + + public function withPath(string $path): BackupFile + { + return new self($this->backupType, $this->hash, $path, $this->extension); + } + + public function withHash(string $hash): BackupFile + { + return new self($this->backupType, $hash, $this->path, $this->extension); + } +} diff --git a/lib/SP/Domain/Export/Dtos/BackupFiles.php b/lib/SP/Domain/Export/Dtos/BackupFiles.php new file mode 100644 index 000000000..7467e6e52 --- /dev/null +++ b/lib/SP/Domain/Export/Dtos/BackupFiles.php @@ -0,0 +1,64 @@ +. + */ + +declare(strict_types=1); + +namespace SP\Domain\Export\Dtos; + +/** + * Class BackupFiles + */ +final readonly class BackupFiles +{ + private const BACKUP_PREFIX = 'sysPassBackup'; + + public function __construct(private BackupFile $appBackupFile, private BackupFile $dbBackupFile) + { + } + + public static function buildHash(): string + { + return sha1(uniqid(self::BACKUP_PREFIX, true)); + } + + public function getAppBackupFile(): BackupFile + { + return $this->appBackupFile; + } + + public function getDbBackupFile(): BackupFile + { + return $this->dbBackupFile; + } + + public function withPath(string $path): BackupFiles + { + return new self($this->appBackupFile->withPath($path), $this->dbBackupFile->withPath($path)); + } + + public function withHash(string $hash): BackupFiles + { + return new self($this->appBackupFile->withHash($hash), $this->dbBackupFile->withHash($hash)); + } +} diff --git a/lib/SP/Domain/Install/Services/MysqlSetupBuilderInterface.php b/lib/SP/Domain/Export/Dtos/BackupType.php similarity index 60% rename from lib/SP/Domain/Install/Services/MysqlSetupBuilderInterface.php rename to lib/SP/Domain/Export/Dtos/BackupType.php index 1db61de53..6fb80c9e9 100644 --- a/lib/SP/Domain/Install/Services/MysqlSetupBuilderInterface.php +++ b/lib/SP/Domain/Export/Dtos/BackupType.php @@ -1,11 +1,10 @@ . */ -namespace SP\Domain\Install\Services; - -use SP\Domain\Core\Exceptions\SPException; -use SP\Domain\Install\Adapters\InstallData; +namespace SP\Domain\Export\Dtos; /** - * Class DatabaseSetupBuilder + * Enum BackupType */ -interface MysqlSetupBuilderInterface +enum BackupType { - /** - * @param InstallData $installData - * - * @return DatabaseSetupInterface - * @throws SPException - */ - public static function build(InstallData $installData): DatabaseSetupInterface; + case db; + case app; + case export; } diff --git a/lib/SP/Domain/Export/Ports/BackupFileService.php b/lib/SP/Domain/Export/Ports/BackupFileService.php index 61be633b0..2f56d2c83 100644 --- a/lib/SP/Domain/Export/Ports/BackupFileService.php +++ b/lib/SP/Domain/Export/Ports/BackupFileService.php @@ -1,4 +1,5 @@ config = $application->getConfig(); - $this->eventDispatcher = $application->getEventDispatcher(); - $this->configData = $this->config->getConfigData(); + parent::__construct($application); } /** @@ -84,27 +79,25 @@ public function doBackup(string $backupPath = BACKUP_PATH, string $applicationPa { set_time_limit(0); - $this->backupPath = $backupPath; - try { - $this->deleteOldBackups(); + $this->deleteOldBackups($backupPath); $this->eventDispatcher->notify( 'run.backup.start', new Event($this, EventMessage::factory()->addDescription(__u('Make Backup'))) ); - $this->backupTables($this->backupFileHelperService->getDbBackupFileHandler()); + $configData = $this->config->getConfigData(); + + $this->backupTables($configData->getDbName()); $this->backupApp($applicationPath); - $this->configData->setBackupHash($this->backupFileHelperService->getHash()); - $this->config->save($this->configData); + $this->config->save($configData->setBackupHash($this->buildHash())); } catch (Exception $e) { $this->eventDispatcher->notify('exception', new Event($e)); - throw new ServiceException( + throw ServiceException::error( __u('Error while doing the backup'), - SPException::ERROR, __u('Please check out the event log for more details'), $e->getCode(), $e @@ -115,34 +108,22 @@ public function doBackup(string $backupPath = BACKUP_PATH, string $applicationPa /** * Eliminar las copias de seguridad anteriores */ - private function deleteOldBackups(): void + private function deleteOldBackups(string $backupPath): void { - $path = sprintf("%s%s%s", $this->backupPath, DIRECTORY_SEPARATOR, AppInfoInterface::APP_NAME); - - array_map( - static function ($file) { - return @unlink($file); - }, - array_merge( - glob($path . '_db-*'), - glob($path . '_app-*'), - glob($path . '*.sql') - ) + FileSystem::deleteByPattern( + $backupPath, + AppInfoInterface::APP_NAME . '_db-*', + AppInfoInterface::APP_NAME . '_app-*', + AppInfoInterface::APP_NAME . '*.sql', ); } /** - * Backup de las tablas de la BBDD. - * Utilizar '*' para toda la BBDD o 'table1 table2 table3...' - * - * @param FileHandlerInterface $fileHandler - * @throws CheckException * @throws ConstraintException - * @throws FileException * @throws QueryException * @throws SPException */ - private function backupTables(FileHandlerInterface $fileHandler): void + private function backupTables(string $dbName): void { $this->eventDispatcher->notify( 'run.backup.process', @@ -152,10 +133,6 @@ private function backupTables(FileHandlerInterface $fileHandler): void ) ); - $fileHandler->open('w'); - - $dbname = $this->configData->getDbName(); - $sqlOut = [ '-- ', sprintf('-- sysPass DB dump generated on %s (START)', time()), @@ -166,13 +143,13 @@ private function backupTables(FileHandlerInterface $fileHandler): void 'SET FOREIGN_KEY_CHECKS = 0;', 'SET UNIQUE_CHECKS = 0;', '-- ', - sprintf('CREATE DATABASE IF NOT EXISTS `%s`;', $dbname), + sprintf('CREATE DATABASE IF NOT EXISTS `%s`;', $dbName), '', - sprintf('USE `%s`;', $dbname), + sprintf('USE `%s`;', $dbName), '' ]; - $fileHandler->write(implode(PHP_EOL, $sqlOut)); + $this->dbBackupFile->write(implode(PHP_EOL, $sqlOut)); $tables = $this->getTables(); $views = $this->getViews(); @@ -191,7 +168,7 @@ private function backupTables(FileHandlerInterface $fileHandler): void '' ]; - $fileHandler->write(implode(PHP_EOL, $sqlOut)); + $this->dbBackupFile->write(implode(PHP_EOL, $sqlOut)); } foreach ($views as $view) { @@ -208,7 +185,7 @@ private function backupTables(FileHandlerInterface $fileHandler): void '' ]; - $fileHandler->write(implode(PHP_EOL, $sqlOut)); + $this->dbBackupFile->write(implode(PHP_EOL, $sqlOut)); } // Save tables' values @@ -237,7 +214,9 @@ function (mixed $value) { $row ); - $fileHandler->write(sprintf('INSERT INTO `%s` VALUES(%s);' . PHP_EOL, $table, implode(',', $values))); + $this->dbBackupFile->write( + sprintf('INSERT INTO `%s` VALUES(%s);' . PHP_EOL, $table, implode(',', $values)) + ); } } @@ -253,11 +232,11 @@ function (mixed $value) { '-- ' ]; - $fileHandler->write(implode(PHP_EOL, $sqlOut)); + $this->dbBackupFile->write(implode(PHP_EOL, $sqlOut)); - $this->backupFileHelperService->getDbBackupArchiveHandler()->compressFile($fileHandler->getFile()); + $this->dbArchiveHandler->compressFile($this->dbBackupFile->getFile()); - $fileHandler->delete(); + $this->dbBackupFile->delete(); } /** @@ -279,7 +258,7 @@ private function getViews(): array /** * Realizar un backup de la aplicación y comprimirlo. * - * @throws CheckException + * @param string $directory * @throws FileException */ private function backupApp(string $directory): void @@ -289,14 +268,14 @@ private function backupApp(string $directory): void new Event($this, EventMessage::factory()->addDescription(__u('Copying application'))) ); - $this->backupFileHelperService->getAppBackupArchiveHandler()->compressDirectory( - $directory, - self::BACKUP_INCLUDE_REGEX - ); + $this->appArchiveHandler->compressDirectory($directory, self::BACKUP_INCLUDE_REGEX); } - public function getHash(): string + /** + * @return string + */ + private function buildHash(): string { - return $this->backupFileHelperService->getHash(); + return sha1(uniqid(self::BACKUP_PREFIX, true)); } } diff --git a/lib/SP/Domain/Export/Services/BackupFileHelper.php b/lib/SP/Domain/Export/Services/BackupFileHelper.php deleted file mode 100644 index a27cf490b..000000000 --- a/lib/SP/Domain/Export/Services/BackupFileHelper.php +++ /dev/null @@ -1,131 +0,0 @@ -. - */ - -namespace SP\Domain\Export\Services; - -use SP\Domain\Core\AppInfoInterface; -use SP\Domain\Core\Exceptions\CheckException; -use SP\Domain\Core\PhpExtensionCheckerService; -use SP\Domain\Export\Ports\BackupFileHelperService; -use SP\Domain\File\Ports\ArchiveHandlerInterface; -use SP\Domain\File\Ports\DirectoryHandlerService; -use SP\Domain\File\Ports\FileHandlerInterface; -use SP\Infrastructure\File\ArchiveHandler; -use SP\Infrastructure\File\FileHandler; -use SP\Infrastructure\File\FileSystem; - -/** - * BackupFileHelper - */ -final class BackupFileHelper implements BackupFileHelperService -{ - private const BACKUP_PREFFIX = 'sysPassBackup'; - private string $hash; - private string $appBackupFilename; - private string $dbBackupFilename; - - /** - * @throws CheckException - */ - public function __construct( - private readonly PhpExtensionCheckerService $phpExtensionCheckerService, - private readonly DirectoryHandlerService $directoryHandlerService - ) { - $this->hash = BackupFileHelper::buildHash(); - $this->directoryHandlerService->checkOrCreate(); - $this->appBackupFilename = self::getAppBackupFilename($this->directoryHandlerService->getPath(), $this->hash); - $this->dbBackupFilename = self::getDbBackupFilename($this->directoryHandlerService->getPath(), $this->hash); - } - - /** - * Generate a unique hash to avoid unwanted downloads - * - * @return string - */ - private static function buildHash(): string - { - return sha1(uniqid(self::BACKUP_PREFFIX, true)); - } - - public static function getAppBackupFilename( - string $path, - string $hash, - bool $compressed = false - ): string { - $file = sprintf('%s_app-%s', FileSystem::buildPath($path, AppInfoInterface::APP_NAME), $hash); - - if ($compressed) { - return $file . ArchiveHandler::COMPRESS_EXTENSION; - } - - return $file; - } - - public static function getDbBackupFilename( - string $path, - string $hash, - bool $compressed = false - ): string { - $file = sprintf('%s_db-%s', FileSystem::buildPath($path, AppInfoInterface::APP_NAME), $hash); - - if ($compressed) { - return $file . ArchiveHandler::COMPRESS_EXTENSION; - } - - return $file . '.sql'; - } - - /** - * @return FileHandlerInterface - */ - public function getDbBackupFileHandler(): FileHandlerInterface - { - return new FileHandler($this->dbBackupFilename, 'w'); - } - - /** - * @return ArchiveHandlerInterface - */ - public function getDbBackupArchiveHandler(): ArchiveHandlerInterface - { - return new ArchiveHandler($this->dbBackupFilename, $this->phpExtensionCheckerService); - } - - /** - * @return ArchiveHandlerInterface - */ - public function getAppBackupArchiveHandler(): ArchiveHandlerInterface - { - return new ArchiveHandler($this->appBackupFilename, $this->phpExtensionCheckerService); - } - - /** - * @return string - */ - public function getHash(): string - { - return $this->hash; - } -} diff --git a/lib/SP/Domain/Export/Services/XmlExport.php b/lib/SP/Domain/Export/Services/XmlExport.php index 0562f2fc5..9fd02b490 100644 --- a/lib/SP/Domain/Export/Services/XmlExport.php +++ b/lib/SP/Domain/Export/Services/XmlExport.php @@ -1,4 +1,5 @@ getPath()); - $file = self::buildFilename($exportPath->getPath(), $this->buildAndSaveHashForFile()); - $this->buildAndSaveXml($file, $password); + $file = new BackupFileDto( + BackupType::export, + $this->buildAndSaveHashForFile(), + $exportPath->getPath(), + 'xml' + ); + + $this->buildAndSaveXml((string)$file, $password); - return $file; + return (string)$file; } private static function deleteExportFiles(string $path): void @@ -125,17 +133,6 @@ private static function deleteExportFiles(string $path): void ); } - public static function buildFilename(string $path, string $hash, bool $compressed = false): string - { - $file = sprintf('%s%s%s_export-%s', $path, DIRECTORY_SEPARATOR, AppInfoInterface::APP_NAME, $hash); - - if ($compressed) { - return $file . ArchiveHandler::COMPRESS_EXTENSION; - } - - return sprintf('%s.xml', $file); - } - /** * @throws FileException */ diff --git a/lib/SP/Domain/File/Ports/ArchiveHandlerInterface.php b/lib/SP/Domain/File/Ports/ArchiveHandlerInterface.php index c97d552c5..6e320de66 100644 --- a/lib/SP/Domain/File/Ports/ArchiveHandlerInterface.php +++ b/lib/SP/Domain/File/Ports/ArchiveHandlerInterface.php @@ -37,7 +37,7 @@ interface ArchiveHandlerInterface * * @throws FileException */ - public function compressDirectory(string $directory, ?string $regex = null): void; + public function compressDirectory(string $directory, ?string $regex = null): string; /** * Realizar un backup de la aplicación y comprimirlo. diff --git a/lib/SP/Domain/Http/Services/Request.php b/lib/SP/Domain/Http/Services/Request.php index a637632f8..d3fe2e25a 100644 --- a/lib/SP/Domain/Http/Services/Request.php +++ b/lib/SP/Domain/Http/Services/Request.php @@ -1,4 +1,5 @@ request = $request; } @@ -200,7 +200,7 @@ private function install(): void $configData->setInstalled(true); - $this->config->save($configData, false); + $this->config->save($configData); } /** @@ -270,7 +270,7 @@ private function setupConfig(): ConfigDataInterface ->setDbName($this->installData->getDbName()) ->setSiteLang($this->installData->getSiteLang()); - $this->config->save($configData, false, false); + $this->config->save($configData, false); return $configData; } @@ -296,7 +296,7 @@ private function setupDb(ConfigDataInterface $configData): void $configData->setDbPass($pass); } - $this->config->save($configData, false, false); + $this->config->save($configData, false); $this->databaseSetup->createDatabase($user); $this->databaseSetup->createDBStructure(); diff --git a/lib/SP/Domain/Install/Services/MysqlService.php b/lib/SP/Domain/Install/Services/MysqlSetup.php similarity index 99% rename from lib/SP/Domain/Install/Services/MysqlService.php rename to lib/SP/Domain/Install/Services/MysqlSetup.php index 831995a39..d8d712aac 100644 --- a/lib/SP/Domain/Install/Services/MysqlService.php +++ b/lib/SP/Domain/Install/Services/MysqlSetup.php @@ -1,4 +1,5 @@ . - */ - -namespace SP\Domain\Install\Services; - -use SP\Domain\Install\Adapters\InstallData; -use SP\Infrastructure\Database\DatabaseConnectionData; -use SP\Infrastructure\Database\DatabaseUtil; -use SP\Infrastructure\Database\MysqlFileParser; -use SP\Infrastructure\Database\MysqlHandler; -use SP\Infrastructure\File\FileHandler; - -/** - * Class MysqlSetupBuilder - */ -final class MysqlSetupBuilder implements MysqlSetupBuilderInterface -{ - private const DATABASE_SCHEMA_FILE = SQL_PATH . DIRECTORY_SEPARATOR . 'dbstructure.sql'; - - public static function build(InstallData $installData): DatabaseSetupInterface - { - $connectionData = (new DatabaseConnectionData()) - ->setDbHost($installData->getDbHost()) - ->setDbPort($installData->getDbPort()) - ->setDbSocket($installData->getDbSocket()) - ->setDbUser($installData->getDbAdminUser()) - ->setDbPass($installData->getDbAdminPass()); - - $parser = new MysqlFileParser(new FileHandler(self::DATABASE_SCHEMA_FILE)); - - $mysqlHandler = new MysqlHandler($connectionData); - - return new MysqlService($mysqlHandler, $installData, $parser, new DatabaseUtil($mysqlHandler)); - } -} diff --git a/lib/SP/Domain/Storage/Ports/FileCacheService.php b/lib/SP/Domain/Storage/Ports/FileCacheService.php index 9858cb952..3d2d6f42a 100644 --- a/lib/SP/Domain/Storage/Ports/FileCacheService.php +++ b/lib/SP/Domain/Storage/Ports/FileCacheService.php @@ -1,4 +1,5 @@ $class - * @return T + * @return T&object * @throws FileException */ public function loadWith(string $class): object; diff --git a/lib/SP/Domain/Upgrade/Services/Upgrade.php b/lib/SP/Domain/Upgrade/Services/Upgrade.php index f00849192..f1e92a898 100644 --- a/lib/SP/Domain/Upgrade/Services/Upgrade.php +++ b/lib/SP/Domain/Upgrade/Services/Upgrade.php @@ -99,7 +99,7 @@ public function upgrade(string $version, ConfigDataInterface $configData): void logger('Upgrade: ' . $upgradeHandler::class); - $this->config->save($configData, false); + $this->config->save($configData); } $this->eventDispatcher->notify( diff --git a/lib/SP/Domain/User/Dtos/UserDataDto.php b/lib/SP/Domain/User/Dtos/UserDataDto.php index b8b039260..f73128b6c 100644 --- a/lib/SP/Domain/User/Dtos/UserDataDto.php +++ b/lib/SP/Domain/User/Dtos/UserDataDto.php @@ -42,67 +42,67 @@ public function __construct(private ?User $user = null) public function getLogin(): ?string { - return $this->user->getLogin(); + return $this->user?->getLogin(); } public function getSsoLogin(): ?string { - return $this->user->getSsoLogin(); + return $this->user?->getSsoLogin(); } public function getName(): ?string { - return $this->user->getName(); + return $this->user?->getName(); } public function getEmail(): ?string { - return $this->user->getEmail(); + return $this->user?->getEmail(); } public function getUserGroupId(): int { - return (int)$this->user->getUserGroupId(); + return (int)$this->user?->getUserGroupId(); } public function getUserProfileId(): int { - return (int)$this->user->getUserProfileId(); + return (int)$this->user?->getUserProfileId(); } public function getIsAdminApp(): bool { - return (bool)$this->user->isAdminApp(); + return (bool)$this->user?->isAdminApp(); } public function getIsAdminAcc(): bool { - return (bool)$this->user->isAdminAcc(); + return (bool)$this->user?->isAdminAcc(); } public function getIsDisabled(): bool { - return (bool)$this->user->isDisabled(); + return (bool)$this->user?->isDisabled(); } public function getIsChangePass(): bool { - return (bool)$this->user->isChangePass(); + return (bool)$this->user?->isChangePass(); } public function getIsChangedPass(): bool { - return (bool)$this->user->isChangedPass(); + return (bool)$this->user?->isChangedPass(); } public function getIsLdap(): bool { - return (bool)$this->user->isLdap(); + return (bool)$this->user?->isLdap(); } public function getIsMigrate(): bool { - return (bool)$this->user->isMigrate(); + return (bool)$this->user?->isMigrate(); } public function getPreferences(): ?UserPreferences @@ -112,41 +112,41 @@ public function getPreferences(): ?UserPreferences public function getPass(): ?string { - return $this->user->getPass(); + return $this->user?->getPass(); } public function getMPass(): ?string { - return $this->user->getMPass(); + return $this->user?->getMPass(); } public function getMKey(): ?string { - return $this->user->getMKey(); + return $this->user?->getMKey(); } public function getLastUpdateMPass(): int { - return $this->user->getLastUpdateMPass(); + return $this->user?->getLastUpdateMPass(); } public function getHashSalt(): ?string { - return $this->user->getHashSalt(); + return $this->user?->getHashSalt(); } public function getId(): ?int { - return $this->user->getId(); + return $this->user?->getId(); } public function getUserGroupName(): ?string { - return $this->user->offsetGet('userGroup.name'); + return $this->user?->offsetGet('userGroup.name'); } public function getLastUpdate(): int { - return (int)strtotime($this->user->getLastUpdate()); + return (int)strtotime($this->user?->getLastUpdate()); } } diff --git a/lib/SP/Infrastructure/Common/Repositories/BaseRepository.php b/lib/SP/Infrastructure/Common/Repositories/BaseRepository.php index f209a2332..b8079cc85 100644 --- a/lib/SP/Infrastructure/Common/Repositories/BaseRepository.php +++ b/lib/SP/Infrastructure/Common/Repositories/BaseRepository.php @@ -1,4 +1,5 @@ dbSocket = $installData->getDbSocket(); + $self->dbHost = $installData->getDbHost(); + $self->dbPort = $installData->getDbPort(); + $self->dbName = $installData->getDbName(); + $self->dbUser = $installData->getDbAdminUser(); + $self->dbPass = $installData->getDbAdminPass(); + + return $self; + } + public function refreshFromConfig(ConfigDataInterface $configData): DatabaseConnectionData { self::setup($configData, $this); diff --git a/lib/SP/Infrastructure/Database/MysqlHandler.php b/lib/SP/Infrastructure/Database/MysqlHandler.php index a05febac8..b9d26b06d 100644 --- a/lib/SP/Infrastructure/Database/MysqlHandler.php +++ b/lib/SP/Infrastructure/Database/MysqlHandler.php @@ -1,4 +1,5 @@ connectionUri = $this->getConnectionUri(); + $this->connectionUri = self::getConnectionUri($connectionData); } - private function getConnectionUri(): string + public static function getConnectionUri(DatabaseConnectionData $connectionData): string { $dsn = ['charset=utf8']; - if (empty($this->connectionData->getDbSocket())) { - $dsn[] = sprintf('host=%s', $this->connectionData->getDbHost()); + if (empty($connectionData->getDbSocket())) { + $dsn[] = sprintf('host=%s', $connectionData->getDbHost()); - if (null !== $this->connectionData->getDbPort()) { - $dsn[] = sprintf('port=%s', $this->connectionData->getDbPort()); + if (null !== $connectionData->getDbPort()) { + $dsn[] = sprintf('port=%s', $connectionData->getDbPort()); } } else { - $dsn[] = sprintf('unix_socket=%s', $this->connectionData->getDbSocket()); + $dsn[] = sprintf('unix_socket=%s', $connectionData->getDbSocket()); } - if (!empty($this->connectionData->getDbName())) { - $dsn[] = sprintf('dbname=%s', $this->connectionData->getDbName()); + if (!empty($connectionData->getDbName())) { + $dsn[] = sprintf('dbname=%s', $connectionData->getDbName()); } return sprintf('mysql:%s', implode(';', $dsn)); diff --git a/lib/SP/Infrastructure/File/ArchiveHandler.php b/lib/SP/Infrastructure/File/ArchiveHandler.php index 3be6f61b0..32b732024 100644 --- a/lib/SP/Infrastructure/File/ArchiveHandler.php +++ b/lib/SP/Infrastructure/File/ArchiveHandler.php @@ -1,4 +1,5 @@ archive->buildFromDirectory($directory, $regex); - $this->archive->compress(Phar::GZ); + $packed = $this->archive->compress(Phar::GZ); // Delete the non-compressed archive (new FileHandler($this->archive->getPath()))->delete(); + + return $packed->getFileInfo()->getPathname(); } /** @@ -87,11 +74,11 @@ public function compressDirectory(string $directory, ?string $regex = null): voi public function compressFile(string $file): string { $this->archive->addFile($file, basename($file)); - $this->archive->compress(Phar::GZ); + $packed = $this->archive->compress(Phar::GZ); // Delete the non-compressed archive - (new FileHandler($this->archive->getPath()))->delete(); + (new FileHandler($this->archive->getPathname()))->delete(); - return $this->archive->getFileInfo()->getPathname(); + return $packed->getFileInfo()->getPathname(); } } diff --git a/lib/SP/Infrastructure/File/FileCache.php b/lib/SP/Infrastructure/File/FileCache.php index 3ce6e7655..8dc61e139 100644 --- a/lib/SP/Infrastructure/File/FileCache.php +++ b/lib/SP/Infrastructure/File/FileCache.php @@ -27,6 +27,7 @@ use SP\Domain\Common\Adapters\Serde; use SP\Domain\Core\Exceptions\InvalidClassException; +use SP\Domain\Core\Exceptions\SPException; use SP\Domain\Storage\Ports\FileCacheService; use function SP\__u; @@ -38,12 +39,13 @@ class FileCache extends FileCacheBase { /** * @throws FileException + * @throws SPException */ public function load(?string $path = null): mixed { $this->checkOrInitializePath($path); - return unserialize($this->path->checkIsReadable()->readToString(), ['allowed_classes' => false]); + return Serde::deserialize($this->path->checkIsReadable()->readToString()); } /** diff --git a/lib/SP/Infrastructure/File/FileCacheBase.php b/lib/SP/Infrastructure/File/FileCacheBase.php index 02171d7df..d07f5365c 100644 --- a/lib/SP/Infrastructure/File/FileCacheBase.php +++ b/lib/SP/Infrastructure/File/FileCacheBase.php @@ -1,4 +1,5 @@ path = new FileHandler($path, 'rwb'); + $this->path = new FileHandler($path, 'c+b'); } } @@ -57,7 +58,7 @@ public function isExpired(int $time = 86400): bool { $this->path->checkFileExists(); - return time() > $this->path->getFileTime() + $time; + return $this->path->getSize() === 0 || time() > $this->path->getFileTime() + $time; } /** @@ -69,7 +70,7 @@ public function isExpiredDate(int $date): bool { $this->path->checkFileExists(); - return $date > $this->path->getFileTime(); + return $this->path->getSize() === 0 || $date > $this->path->getFileTime(); } /** @@ -111,7 +112,7 @@ protected function checkOrInitializePath(?string $path = null): void throw new FileException(__('Path is needed')); } - if (null === $this->path || $this->path->getFile() !== $path) { + if (null === $this->path) { $this->path = new FileHandler($path); } } diff --git a/lib/SP/Infrastructure/File/FileHandler.php b/lib/SP/Infrastructure/File/FileHandler.php index 006259ea7..7e1a1837c 100644 --- a/lib/SP/Infrastructure/File/FileHandler.php +++ b/lib/SP/Infrastructure/File/FileHandler.php @@ -1,4 +1,5 @@ file, $this->mode); + parent::__construct($this->file, $mode); } /** @@ -81,6 +82,14 @@ public function readToString(): string return $data; } + /** + * @return void + */ + private function autoDetectEOL(): void + { + ini_set('auto_detect_line_endings', true); + } + /** * Reads data from a CSV file * @@ -343,12 +352,4 @@ public function getHash(): string { return sha1_file($this->file); } - - /** - * @return void - */ - private function autoDetectEOL(): void - { - ini_set('auto_detect_line_endings', true); - } } diff --git a/lib/SP/Infrastructure/File/FileSystem.php b/lib/SP/Infrastructure/File/FileSystem.php index 953b0be04..cae7ff7b1 100644 --- a/lib/SP/Infrastructure/File/FileSystem.php +++ b/lib/SP/Infrastructure/File/FileSystem.php @@ -150,4 +150,19 @@ public static function buildPath(string ...$parts): string { return implode(DIRECTORY_SEPARATOR, $parts); } + + /** + * Delete files using {@link glob()} patterns + * + * @param string $path + * @param string ...$patterns + * @return void + */ + public static function deleteByPattern(string $path, string...$patterns): void + { + array_map( + static fn(string $file) => @unlink($file), + array_merge(...array_map(static fn(string $pattern) => glob(self::buildPath($path, $pattern)), $patterns)) + ); + } } diff --git a/tests/SP/Core/Context/SessionLifecycleHandlerTest.php b/tests/SP/Core/Context/SessionLifecycleHandlerTest.php index ac2032646..c13fe3d08 100644 --- a/tests/SP/Core/Context/SessionLifecycleHandlerTest.php +++ b/tests/SP/Core/Context/SessionLifecycleHandlerTest.php @@ -27,6 +27,7 @@ namespace SP\Tests\Core\Context; use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\RunClassInSeparateProcess; use SP\Core\Context\SessionLifecycleHandler; use SP\Domain\Core\Exceptions\SPException; use SP\Tests\UnitaryTestCase; @@ -35,6 +36,7 @@ * Class SessionUtilTest */ #[Group('unitary')] +#[RunClassInSeparateProcess] class SessionLifecycleHandlerTest extends UnitaryTestCase { @@ -65,6 +67,22 @@ public function testStart() $this->assertEquals('1', ini_get('session.use_strict_mode')); } + /** + * @throws SPException + */ + public function testStartWithHeadersSent() + { + $this->assertEquals(PHP_SESSION_NONE, session_status()); + + echo "Test"; + ob_flush(); + + $this->expectException(SPException::class); + $this->expectExceptionMessage('Session cannot be initialized'); + + SessionLifecycleHandler::start(); + } + /** * @throws SPException */ diff --git a/tests/SP/Core/Definitions/DefinitionsTest.php b/tests/SP/Core/Definitions/DefinitionsTest.php new file mode 100644 index 000000000..431b188ab --- /dev/null +++ b/tests/SP/Core/Definitions/DefinitionsTest.php @@ -0,0 +1,118 @@ +. + */ + +declare(strict_types=1); + +namespace SP\Tests\Core\Definitions; + +use DI\ContainerBuilder; +use Exception; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\TestCase; +use SP\Core\Application; +use SP\Core\Definitions\CoreDefinitions; +use SP\Core\Definitions\DomainDefinitions; +use SP\Domain\Auth\Ports\LdapConnectionInterface; +use SP\Domain\Config\Ports\ConfigDataInterface; +use SP\Domain\Http\Ports\RequestService; +use SP\Infrastructure\File\ArchiveHandler; + +/** + * Class DefinitionsTest + */ +#[Group('unitary')] +class DefinitionsTest extends TestCase +{ + + /** + * @throws Exception + * @throws \PHPUnit\Framework\MockObject\Exception + */ + public function testGetDefinitions() + { + define('APP_MODULE', 'test'); + + $configData = $this->createStub(ConfigDataInterface::class); + $configData->method('getSiteTheme')->willReturn('theme'); + $configData->method('getLdapServer')->willReturn('a_server'); + $configData->method('getLdapType')->willReturn(1); + $configData->method('getLdapBindUser')->willReturn('a_user'); + $configData->method('getLdapBindPass')->willReturn('a_password'); + $configData->method('getLdapBase')->willReturn('a_base'); + $configData->method('getLdapGroup')->willReturn('a_group'); + $configData->method('getMailServer')->willReturn('a_server'); + $configData->method('getMailUser')->willReturn('a_user'); + $configData->method('getMailPass')->willReturn('a_password'); + $configData->method('getMailSecurity')->willReturn('a_security'); + $configData->method('getMailFrom')->willReturn('an_email'); + $configData->method('isMailAuthenabled')->willReturn(false); + $configData->method('getPasswordSalt')->willReturn('a_salt'); + + $requestService = $this->createStub(RequestService::class); + $requestService->method('analyzeString') + ->willReturnMap( + [ + ['sitelang', 'a_lang'], + ['adminlogin', 'a_login'], + ['dbuser', 'a_user'], + ['dbname', 'a_name'], + ['dbhost', 'a_host'], + ] + ); + $requestService->method('analyzeEncrypted') + ->willReturnMap( + [ + ['adminpass', 'a_password'], + ['masterpassword', 'a_password'], + ] + ); + $requestService->method('analyzeBool') + ->willReturnMap( + [ + ['hostingmode', false] + ] + ); + + $mockedDefinitions = [ + ConfigDataInterface::class => $configData, + LdapConnectionInterface::class => $this->createStub(LdapConnectionInterface::class), + 'backup.dbArchiveHandler' => $this->createStub(ArchiveHandler::class), + 'backup.appArchiveHandler' => $this->createStub(ArchiveHandler::class), + ]; + + $definitions = CoreDefinitions::getDefinitions(); + + $containerBuilder = new ContainerBuilder(); + $containerBuilder->addDefinitions(DomainDefinitions::getDefinitions(), $definitions, $mockedDefinitions); + $out = $containerBuilder->build(); + + $this->assertInstanceOf(Application::class, $out->get(Application::class)); + + foreach (array_keys($definitions) as $definition) { + if (class_exists($definition)) { + $this->assertInstanceOf($definition, $out->get($definition)); + } + } + } +} diff --git a/tests/SP/Core/UI/ThemeIconsTest.php b/tests/SP/Core/UI/ThemeIconsTest.php index 22cbe6736..593b940c6 100644 --- a/tests/SP/Core/UI/ThemeIconsTest.php +++ b/tests/SP/Core/UI/ThemeIconsTest.php @@ -1,4 +1,5 @@ createMock(Context::class); $fileCache = $this->createMock(FileCacheService::class); $themeContext = $this->createMock(ThemeContextInterface::class); + $themeContext->expects($this->never()) + ->method('getFullPath'); $context->expects(self::once()) ->method('getAppStatus') @@ -96,7 +99,7 @@ public function testLoadIconsWithCache() $fileCache->expects(self::once()) ->method('isExpired') - ->willReturn(true); + ->willReturn(false); $fileCache->expects(self::once()) ->method('load') diff --git a/tests/SP/Core/UI/ThemeTest.php b/tests/SP/Core/UI/ThemeTest.php index 044490bbc..7cc2ebf5a 100644 --- a/tests/SP/Core/UI/ThemeTest.php +++ b/tests/SP/Core/UI/ThemeTest.php @@ -140,8 +140,6 @@ public function testGetUri() */ public function testGetAvailable() { - $dirname = self::$faker->filePath(); - $dir = $this->createMock(Directory::class); $dir->expects(self::exactly(2)) ->method('read') diff --git a/tests/SP/Domain/Common/Providers/ImageTest.php b/tests/SP/Domain/Common/Providers/ImageTest.php index 3f533f70c..5c1610b7c 100644 --- a/tests/SP/Domain/Common/Providers/ImageTest.php +++ b/tests/SP/Domain/Common/Providers/ImageTest.php @@ -29,6 +29,7 @@ use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\TestCase; +use SP\Domain\Common\Providers\Image; use SP\Domain\Core\Exceptions\InvalidImageException; use SP\Domain\Core\Exceptions\SPException; use SP\Tests\Stubs\PhpExtensionCheckerStub; @@ -39,7 +40,7 @@ #[Group('unitary')] class ImageTest extends TestCase { - private \SP\Domain\Common\Providers\Image $imageUtil; + private Image $imageUtil; /** * @throws InvalidImageException @@ -88,6 +89,6 @@ protected function setUp(): void ->method('checkCurl') ->with(true); - $this->imageUtil = new \SP\Domain\Common\Providers\Image($phpExtensionCheckerService); + $this->imageUtil = new Image($phpExtensionCheckerService, '/usr/share/fonts/freefont/FreeSans.otf'); } } diff --git a/tests/SP/Domain/Config/Services/ConfigFileTest.php b/tests/SP/Domain/Config/Services/ConfigFileTest.php index 83e74b8e7..416ae346b 100644 --- a/tests/SP/Domain/Config/Services/ConfigFileTest.php +++ b/tests/SP/Domain/Config/Services/ConfigFileTest.php @@ -1,4 +1,5 @@ fileStorageService, $this->fileCacheService, $this->context, - $this->configBackupService, new ConfigData() ); } @@ -115,8 +113,7 @@ public function testInitializeWithCache() new ConfigFile( $this->fileStorageService, $this->fileCacheService, - $this->context, - $this->configBackupService + $this->context ); } @@ -159,8 +156,7 @@ public function testInitializeWithCacheAndNoAttributes() new ConfigFile( $this->fileStorageService, $this->fileCacheService, - $this->context, - $this->configBackupService + $this->context ); } @@ -169,7 +165,7 @@ public function testInitializeWithCacheAndNoAttributes() */ private function ensureConfigFileIsUsed(): void { - $configData = $this->config->getConfigData(); + $configData = new ConfigData(); $this->fileStorageService ->expects(self::once()) @@ -199,8 +195,7 @@ public function testInitializeWithExistingFile() new ConfigFile( $this->fileStorageService, $this->fileCacheService, - $this->context, - $this->configBackupService + $this->context ); } @@ -225,10 +220,6 @@ public function testInitializeWithGenerateNewConfig() ->with('config') ->willThrowException(FileException::error('test')); - $this->configBackupService - ->expects(self::never()) - ->method('backup'); - $this->fileStorageService ->expects(self::once()) ->method('save') @@ -242,8 +233,7 @@ public function testInitializeWithGenerateNewConfig() new ConfigFile( $this->fileStorageService, $this->fileCacheService, - $this->context, - $this->configBackupService + $this->context ); } @@ -283,8 +273,7 @@ public function testInitializeWithExceptionFromCache() new ConfigFile( $this->fileStorageService, $this->fileCacheService, - $this->context, - $this->configBackupService + $this->context ); } @@ -321,8 +310,7 @@ public function testInitializeWithExceptionFromCacheExpired() new ConfigFile( $this->fileStorageService, $this->fileCacheService, - $this->context, - $this->configBackupService + $this->context ); } @@ -367,8 +355,7 @@ public function testInitializeWithExceptionCacheDelete() new ConfigFile( $this->fileStorageService, $this->fileCacheService, - $this->context, - $this->configBackupService + $this->context ); } @@ -395,11 +382,6 @@ public function testSave() $configData = $this->createMock(ConfigDataInterface::class); - $this->configBackupService - ->expects(self::once()) - ->method('backup') - ->with($configData); - $this->fileStorageService ->expects(self::exactly(2)) ->method('save') @@ -413,8 +395,7 @@ public function testSave() $configFile = new ConfigFile( $this->fileStorageService, $this->fileCacheService, - $this->context, - $this->configBackupService + $this->context ); $configData->expects(self::once()) @@ -432,61 +413,6 @@ public function testSave() $this->assertEquals($configData, $configFile->getConfigData()); } - /** - * @throws ConfigException - * @throws Exception - * @throws FileException - */ - public function testSaveWithoutBackup() - { - $this->fileCacheService - ->expects(self::once()) - ->method('exists') - ->willReturn(false); - - $this->fileStorageService - ->expects(self::once()) - ->method('load') - ->willThrowException(FileException::error('test')); - - $configData = $this->createMock(ConfigDataInterface::class); - - $this->configBackupService - ->expects(self::never()) - ->method('backup'); - - $this->fileStorageService - ->expects(self::exactly(2)) - ->method('save') - ->with(self::isType('array'), 'config'); - - $this->fileCacheService - ->expects(self::exactly(2)) - ->method('save') - ->with(self::anything()); - - $configFile = new ConfigFile( - $this->fileStorageService, - $this->fileCacheService, - $this->context, - $this->configBackupService - ); - - $configData->expects(self::once()) - ->method('setConfigDate'); - $configData->expects(self::once()) - ->method('setConfigSaver'); - $configData->expects(self::once()) - ->method('setConfigHash'); - $configData->expects(self::once()) - ->method('getAttributes') - ->willReturn([]); - - $configFile->save($configData, false, true); - - $this->assertEquals($configData, $configFile->getConfigData()); - } - /** * @throws ConfigException * @throws Exception @@ -506,10 +432,6 @@ public function testSaveWithoutCommit() $configData = $this->createMock(ConfigDataInterface::class); - $this->configBackupService - ->expects(self::never()) - ->method('backup'); - $this->fileStorageService ->expects(self::exactly(1)) ->method('save') @@ -523,8 +445,7 @@ public function testSaveWithoutCommit() $configFile = new ConfigFile( $this->fileStorageService, $this->fileCacheService, - $this->context, - $this->configBackupService + $this->context ); $configData->expects(self::once()) @@ -536,7 +457,7 @@ public function testSaveWithoutCommit() $configData->expects(self::never()) ->method('getAttributes'); - $configFile->save($configData, false, false); + $configFile->save($configData, false); $this->assertEquals($configData, $configFile->getConfigData()); } @@ -559,10 +480,6 @@ public function testGenerateUpgradeKey() ->method('load') ->willThrowException(FileException::error('test')); - $this->configBackupService - ->expects(self::never()) - ->method('backup'); - $this->fileStorageService ->expects(self::exactly(2)) ->method('save') @@ -576,8 +493,7 @@ public function testGenerateUpgradeKey() $configFile = new ConfigFile( $this->fileStorageService, $this->fileCacheService, - $this->context, - $this->configBackupService + $this->context ); $configFile->generateUpgradeKey(); @@ -605,7 +521,6 @@ public function testGenerateUpgradeKeyWithExistingKey() $this->fileStorageService, $this->fileCacheService, $this->context, - $this->configBackupService, $configData ); @@ -627,7 +542,7 @@ public function testReload() ->expects(self::never()) ->method('getFileTime'); - $configData = $this->config->getConfigData(); + $configData = new ConfigData(); $this->fileStorageService ->expects(self::exactly(2)) @@ -643,8 +558,7 @@ public function testReload() $configFile = new ConfigFile( $this->fileStorageService, $this->fileCacheService, - $this->context, - $this->configBackupService + $this->context ); $configFile->reload(); @@ -660,6 +574,5 @@ protected function setUp(): void $this->fileStorageService = $this->createMock(XmlFileStorageService::class); $this->fileCacheService = $this->createMock(FileCacheService::class); - $this->configBackupService = $this->createMock(ConfigBackupService::class); } } diff --git a/tests/SP/Domain/Export/Services/BackupFileHelperTest.php b/tests/SP/Domain/Export/Services/BackupFileHelperTest.php deleted file mode 100644 index 51f352178..000000000 --- a/tests/SP/Domain/Export/Services/BackupFileHelperTest.php +++ /dev/null @@ -1,141 +0,0 @@ -. - */ - -namespace SP\Tests\Domain\Export\Services; - -use PHPUnit\Framework\Attributes\Group; -use PHPUnit\Framework\MockObject\Exception; -use PHPUnit\Framework\MockObject\MockObject; -use SP\Core\Context\ContextException; -use SP\Domain\Core\Exceptions\CheckException; -use SP\Domain\Core\PhpExtensionCheckerService; -use SP\Domain\Export\Services\BackupFileHelper; -use SP\Domain\File\Ports\DirectoryHandlerService; -use SP\Tests\Stubs\PhpExtensionCheckerStub; -use SP\Tests\UnitaryTestCase; - -/** - * Class BackupFileHelperTest - * - */ -#[Group('unitary')] -class BackupFileHelperTest extends UnitaryTestCase -{ - - private PhpExtensionCheckerService|MockObject $phpExtensionCheckerService; - private BackupFileHelper $backupFileHelper; - - public function testGetAppBackupFilename() - { - $hash = self::$faker->sha1(); - $out = BackupFileHelper::getAppBackupFilename('/a/path', $hash); - $expected = sprintf('/a/path/sysPass_app-%s', $hash); - - $this->assertEquals($expected, $out); - } - - public function testGetAppBackupFilenameWithCompress() - { - $hash = self::$faker->sha1(); - $out = BackupFileHelper::getAppBackupFilename('/a/path', $hash, true); - $expected = sprintf('/a/path/sysPass_app-%s.tar.gz', $hash); - - $this->assertEquals($expected, $out); - } - - public function testGetDbBackupFilename() - { - $hash = self::$faker->sha1(); - $out = BackupFileHelper::getDbBackupFilename('/a/path', $hash); - $expected = sprintf('/a/path/sysPass_db-%s.sql', $hash); - - $this->assertEquals($expected, $out); - } - - public function testGetDbBackupFilenameWithCompress() - { - $hash = self::$faker->sha1(); - $out = BackupFileHelper::getDbBackupFilename('/a/path', $hash, true); - $expected = sprintf('/a/path/sysPass_db-%s.tar.gz', $hash); - - $this->assertEquals($expected, $out); - } - - public function testGetDbBackupArchiveHandler() - { - $this->phpExtensionCheckerService - ->expects(self::once()) - ->method('checkPhar') - ->with(true); - - $this->backupFileHelper->getDbBackupArchiveHandler(); - } - - public function testGetDbBackupFileHandler() - { - $expected = BackupFileHelper::getDbBackupFilename(TMP_PATH, $this->backupFileHelper->getHash()); - $out = $this->backupFileHelper->getDbBackupFileHandler(); - - $this->assertEquals($expected, $out->getFile()); - } - - public function testGetAppBackupArchiveHandler() - { - $this->phpExtensionCheckerService - ->expects(self::once()) - ->method('checkPhar') - ->with(true); - - $this->backupFileHelper->getAppBackupArchiveHandler(); - } - - /** - * @throws Exception - * @throws ContextException - * @throws CheckException - */ - protected function setUp(): void - { - parent::setUp(); - - $this->phpExtensionCheckerService = $this->createMock(PhpExtensionCheckerStub::class); - - $directoryHandlerService = $this->createMock(DirectoryHandlerService::class); - $directoryHandlerService - ->expects(self::once()) - ->method('checkOrCreate'); - - $directoryHandlerService - ->expects(self::exactly(2)) - ->method('getPath') - ->willReturn(TMP_PATH); - - $this->backupFileHelper = new BackupFileHelper( - $this->phpExtensionCheckerService, - $directoryHandlerService - ); - } -} - diff --git a/tests/SP/Domain/Export/Services/FileBackupServiceTest.php b/tests/SP/Domain/Export/Services/FileBackupServiceTest.php index c7bdfd788..44a6ba13b 100644 --- a/tests/SP/Domain/Export/Services/FileBackupServiceTest.php +++ b/tests/SP/Domain/Export/Services/FileBackupServiceTest.php @@ -56,6 +56,9 @@ class FileBackupServiceTest extends UnitaryTestCase private BackupFile $fileBackupService; private BackupFileHelperService|MockObject $backupFiles; private DatabaseInterface|MockObject $database; + private MockObject|FileHandlerInterface $dbFileHandler; + private ArchiveHandlerInterface|MockObject $dbArchiveHandler; + private ArchiveHandlerInterface|MockObject $appArchiveHandler; /** * @throws ServiceException @@ -63,7 +66,7 @@ class FileBackupServiceTest extends UnitaryTestCase */ public function testDoBackup(): void { - $this->setupBackupFiles(); + $this->config->getConfigData()->setDbName('a_db'); $tablesCount = count(DatabaseUtil::TABLES); $tablesType = ['table', 'view']; @@ -101,50 +104,32 @@ public function testDoBackup(): void ) ->willReturnCallback($rows); - $this->fileBackupService->doBackup(TMP_PATH); - } + $this->dbFileHandler + ->expects($this->exactly(79)) + ->method('write'); - /** - * @return void - * @throws Exception - */ - private function setupBackupFiles(): void - { - $archiveHandler = $this->createMock(ArchiveHandlerInterface::class); - $archiveHandler->expects(self::once()) - ->method('compressFile') - ->withAnyParameters(); - $archiveHandler->expects(self::once()) - ->method('compressDirectory') - ->with( - APP_ROOT, - BackupFile::BACKUP_INCLUDE_REGEX - ); - - $fileHandler = $this->createMock(FileHandlerInterface::class); - $fileHandler->expects(self::once()) - ->method('open') - ->with('w'); - $fileHandler->expects(self::atLeast(5)) - ->method('write') - ->with(self::anything()); - $fileHandler->expects(self::once()) - ->method('getFile'); - $fileHandler->expects(self::once()) - ->method('delete'); - - $this->backupFiles - ->expects(self::once()) - ->method('getDbBackupFileHandler') - ->willReturn($fileHandler); - $this->backupFiles - ->expects(self::once()) - ->method('getDbBackupArchiveHandler') - ->willReturn($archiveHandler); - $this->backupFiles - ->expects(self::once()) - ->method('getAppBackupArchiveHandler') - ->willReturn($archiveHandler); + $this->dbFileHandler + ->expects($this->once()) + ->method('delete'); + + $file = self::$faker->colorName(); + + $this->dbFileHandler + ->expects($this->once()) + ->method('getFile') + ->willReturn($file); + + $this->dbArchiveHandler + ->expects($this->once()) + ->method('compressFile') + ->with($file); + + $this->appArchiveHandler + ->expects($this->once()) + ->method('compressDirectory') + ->with(APP_ROOT, BackupFile::BACKUP_INCLUDE_REGEX); + + $this->fileBackupService->doBackup(TMP_PATH); } private function buildCreateResult(string $type): QueryResult @@ -169,16 +154,12 @@ private function buildCreateResult(string $type): QueryResult */ public function testDoBackupWithException(): void { - $fileHandler = $this->createMock(FileHandlerInterface::class); - $fileHandler->expects(self::once()) - ->method('open') - ->with('w') - ->willThrowException(new FileException('Filexception')); + $this->config->getConfigData()->setDbName('a_db'); - $this->backupFiles - ->expects(self::once()) - ->method('getDbBackupFileHandler') - ->willReturn($fileHandler); + $this->dbFileHandler + ->expects(self::any()) + ->method('write') + ->willThrowException(FileException::error('Filexception')); $exception = new ServiceException( 'Error while doing the backup', @@ -194,18 +175,6 @@ public function testDoBackupWithException(): void $this->fileBackupService->doBackup(); } - public function testGetHash(): void - { - $hash = self::$faker->sha1; - - $this->backupFiles - ->expects(self::once()) - ->method('getHash') - ->willReturn($hash); - - self::assertEquals($hash, $this->fileBackupService->getHash()); - } - /** * @throws Exception * @throws ContextException @@ -216,12 +185,17 @@ protected function setUp(): void $this->database = $this->createMock(DatabaseInterface::class); $this->backupFiles = $this->createMock(BackupFileHelperService::class); + $this->dbFileHandler = $this->createMock(FileHandlerInterface::class); + $this->dbArchiveHandler = $this->createMock(ArchiveHandlerInterface::class); + $this->appArchiveHandler = $this->createMock(ArchiveHandlerInterface::class); $this->fileBackupService = new BackupFile( $this->application, $this->database, $this->createStub(DatabaseUtil::class), - $this->backupFiles + $this->dbFileHandler, + $this->dbArchiveHandler, + $this->appArchiveHandler ); } } diff --git a/tests/SP/Domain/Export/Services/XmlExportTest.php b/tests/SP/Domain/Export/Services/XmlExportTest.php index 60506bff2..9e83ea913 100644 --- a/tests/SP/Domain/Export/Services/XmlExportTest.php +++ b/tests/SP/Domain/Export/Services/XmlExportTest.php @@ -499,20 +499,6 @@ public function testExportWithCryptException() $this->xmlExport->export($exportPath, $password); } - public function testBuildFilename() - { - $out = XmlExport::buildFilename('test', 'a_hash'); - - $this->assertEquals('test/sysPass_export-a_hash.xml', $out); - } - - public function testBuildFilenameCompressed() - { - $out = XmlExport::buildFilename('test', 'a_hash', true); - - $this->assertEquals('test/sysPass_export-a_hash.tar.gz', $out); - } - /** * @throws Exception * @throws ServiceException diff --git a/tests/SP/Domain/Http/Services/RequestTest.php b/tests/SP/Domain/Http/Services/RequestTest.php index fa119b3de..26efae21a 100644 --- a/tests/SP/Domain/Http/Services/RequestTest.php +++ b/tests/SP/Domain/Http/Services/RequestTest.php @@ -1,4 +1,5 @@ assertEquals(sprintf('%s/index.php', APP_ROOT), $out); + $this->assertEquals($appRoot . '/app.js', $out); } public function testGetSecureAppPathWithUnknownFile() @@ -915,15 +914,13 @@ public function testGetHeader() public function testGetSecureAppFile() { - $path = sprintf( - '%s%s/index.php', - implode('', array_fill(0, count(explode('/', APP_ROOT)) - 1, '../')), - APP_ROOT - ); + $appRoot = preg_replace('#\w+://#', '', REAL_APP_ROOT) . '/public/js'; - $out = Request::getSecureAppFile($path); + $path = '/../../public/js/app.js'; + + $out = Request::getSecureAppFile($path, $appRoot); - $this->assertEquals('index.php', $out); + $this->assertEquals('app.js', $out); } public function testGetSecureAppFileWithUnknownFile() diff --git a/tests/SP/Domain/Install/Services/InstallerTest.php b/tests/SP/Domain/Install/Services/InstallerTest.php index 2fb78dd01..da635165d 100644 --- a/tests/SP/Domain/Install/Services/InstallerTest.php +++ b/tests/SP/Domain/Install/Services/InstallerTest.php @@ -36,7 +36,7 @@ use SP\Domain\Http\Ports\RequestService; use SP\Domain\Install\Adapters\InstallData; use SP\Domain\Install\Ports\InstallerService; -use SP\Domain\Install\Services\DatabaseSetupInterface; +use SP\Domain\Install\Services\DatabaseSetupService; use SP\Domain\Install\Services\Installer; use SP\Domain\User\Ports\UserGroupService; use SP\Domain\User\Ports\UserProfileService; @@ -53,7 +53,7 @@ class InstallerTest extends UnitaryTestCase { /** - * @var MockObject|DatabaseSetupInterface + * @var MockObject|DatabaseSetupService */ private $databaseSetup; /** @@ -61,7 +61,7 @@ class InstallerTest extends UnitaryTestCase */ private $userService; /** - * @var Stub|\SP\Domain\Http\Ports\RequestService + * @var Stub|RequestService */ private $request; /** @@ -439,7 +439,7 @@ public function testDbHostIsBlank(): void protected function setUp(): void { - $this->databaseSetup = $this->createMock(DatabaseSetupInterface::class); + $this->databaseSetup = $this->createMock(DatabaseSetupService::class); $this->userService = $this->createMock(UserService::class); $this->request = $this->createStub(RequestService::class); $this->configService = $this->createMock(ConfigService::class); diff --git a/tests/SP/Domain/Install/Services/MySQLTest.php b/tests/SP/Domain/Install/Services/MySQLTest.php index 32c5a3266..d5571898a 100644 --- a/tests/SP/Domain/Install/Services/MySQLTest.php +++ b/tests/SP/Domain/Install/Services/MySQLTest.php @@ -37,7 +37,7 @@ use SP\Domain\Database\Ports\DatabaseFileInterface; use SP\Domain\Database\Ports\DbStorageHandler; use SP\Domain\Install\Adapters\InstallData; -use SP\Domain\Install\Services\MysqlService; +use SP\Domain\Install\Services\MysqlSetup; use SP\Infrastructure\Database\DatabaseUtil; use SP\Infrastructure\File\FileException; use SP\Tests\UnitaryTestCase; @@ -53,8 +53,8 @@ class MySQLTest extends UnitaryTestCase { private DbStorageHandler|MockObject $dbStorage; - private MysqlService $mysqlService; - private PDO|MockObject $pdo; + private MysqlSetup $mysqlService; + private PDO|MockObject $pdo; private InstallData $installData; private ConfigDataInterface $configData; private DatabaseFileInterface|MockObject $databaseFile; @@ -828,7 +828,7 @@ protected function setUp(): void $this->installData = $this->getInstallData(); $this->configData = $this->config->getConfigData(); $this->databaseUtil = $this->createMock(DatabaseUtil::class); - $this->mysqlService = new MysqlService( + $this->mysqlService = new MysqlSetup( $this->dbStorage, $this->installData, $this->databaseFile, diff --git a/tests/SP/Domain/Upgrade/Services/UpgradeDatabaseTest.php b/tests/SP/Domain/Upgrade/Services/UpgradeDatabaseTest.php index b7110a1a1..fb31124b6 100644 --- a/tests/SP/Domain/Upgrade/Services/UpgradeDatabaseTest.php +++ b/tests/SP/Domain/Upgrade/Services/UpgradeDatabaseTest.php @@ -106,7 +106,7 @@ public function testUpgradeWithFileException() ->method('setDatabaseVersion'); $this->expectException(UpgradeException::class); - $this->expectExceptionMessage('Failed to open stream: No such file or directory'); + $this->expectExceptionMessageMatches('/Failed to open stream: .*/'); $this->upgradeDatabase->apply('400.00000000', $configData); } diff --git a/tests/SP/Domain/Upgrade/Services/UpgradeTest.php b/tests/SP/Domain/Upgrade/Services/UpgradeTest.php index 44faeb491..ebaeffce0 100644 --- a/tests/SP/Domain/Upgrade/Services/UpgradeTest.php +++ b/tests/SP/Domain/Upgrade/Services/UpgradeTest.php @@ -135,7 +135,7 @@ public function testUpgradeWithHandler() $this->config->expects($this->exactly(2)) ->method('save') - ->with($configData, false); + ->with($configData, true); $this->upgrade->registerUpgradeHandler(UpgradeHandlerStub::class); $this->upgrade->upgrade('400.00000000', $configData); diff --git a/tests/SP/Domain/SP/Tests/Modules/Web/Controllers/Helpers/Account/AccountSearchDataTest.php b/tests/SP/Modules/Web/Controllers/Helpers/Account/AccountSearchDataTest.php similarity index 100% rename from tests/SP/Domain/SP/Tests/Modules/Web/Controllers/Helpers/Account/AccountSearchDataTest.php rename to tests/SP/Modules/Web/Controllers/Helpers/Account/AccountSearchDataTest.php diff --git a/tests/SP/bootstrap.php b/tests/SP/bootstrap.php index b87570c8a..f958d4da6 100644 --- a/tests/SP/bootstrap.php +++ b/tests/SP/bootstrap.php @@ -26,35 +26,67 @@ namespace SP\Tests; +use org\bovigo\vfs\vfsStream; use RuntimeException; +use SP\Core\UI\ThemeIcons; +use SP\Domain\Config\Adapters\ConfigData; use SP\Domain\Core\Exceptions\FileNotFoundException; use SP\Infrastructure\Database\DatabaseConnectionData; use SP\Infrastructure\Database\MysqlHandler; use SP\Infrastructure\File\FileSystem; use function SP\logger; -use function SP\processException; define('DEBUG', true); define('IS_TESTING', true); -define('APP_ROOT', dirname(__DIR__, 2)); -define('TEST_ROOT', dirname(__DIR__)); - -const APP_DEFINITIONS_FILE = APP_ROOT . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'Definitions.php'; - -define('RESOURCE_PATH', TEST_ROOT . DIRECTORY_SEPARATOR . 'res'); -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('LOCALES_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'locales'); -define('MODULES_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'modules'); -define('SQL_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'schemas'); +define('REAL_APP_ROOT', dirname(__DIR__, 2)); + +$testDirectory = vfsStream::setup( + 'test', + 755, + [ + 'res' => [ + 'cache' => [ + 'secure_session' => [], + 'icons.cache' => serialize(new ThemeIcons()), + 'config.cache' => serialize(new ConfigData()) + ] + ], + 'tmp' => [ + 'test.log' => '' + ], + 'schemas' => [], + 'app' => [ + 'locales' => [], + 'modules' => [], + 'resources' => [] + ] + ] +); + +vfsStream::copyFromFileSystem(dirname(__DIR__) . '/res', $testDirectory->getChild('res')); +vfsStream::copyFromFileSystem(REAL_APP_ROOT . '/schemas', $testDirectory->getChild('schemas')); +vfsStream::copyFromFileSystem(REAL_APP_ROOT . '/app/resources', $testDirectory->getChild('app/resources')); + +define('TEST_ROOT', $testDirectory->url()); +define('APP_ROOT', $testDirectory->getChild('app')->url()); +define('RESOURCE_PATH', $testDirectory->getChild('res')->url()); +define('TMP_PATH', $testDirectory->getChild('tmp')->url()); + +define('VIEW_PATH', RESOURCE_PATH . DIRECTORY_SEPARATOR . 'view'); define('CACHE_PATH', RESOURCE_PATH . DIRECTORY_SEPARATOR . 'cache'); -define('TMP_PATH', TEST_ROOT . DIRECTORY_SEPARATOR . 'tmp'); -define('PUBLIC_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'public'); +define('CONFIG_PATH', RESOURCE_PATH . DIRECTORY_SEPARATOR . 'config'); +define('LOCALES_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'locales'); +define('MODULES_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'modules'); define('BACKUP_PATH', TMP_PATH); define('PLUGINS_PATH', TMP_PATH); -define('XML_SCHEMA', APP_ROOT . DIRECTORY_SEPARATOR . 'schemas' . DIRECTORY_SEPARATOR . 'syspass.xsd'); + +define('CONFIG_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'config.xml'); +define('ACTIONS_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'actions.xml'); +define('MIMETYPES_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'mime.xml'); +define('SQL_PATH', TEST_ROOT . DIRECTORY_SEPARATOR . 'schemas'); +define('PUBLIC_PATH', TEST_ROOT . DIRECTORY_SEPARATOR . 'public'); +define('XML_SCHEMA', TEST_ROOT . DIRECTORY_SEPARATOR . 'schemas' . DIRECTORY_SEPARATOR . 'syspass.xsd'); define('LOG_FILE', TMP_PATH . DIRECTORY_SEPARATOR . 'test.log'); define('FIXTURE_FILES', [ RESOURCE_PATH . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'truncate.sql', @@ -63,21 +95,13 @@ define('SELF_IP_ADDRESS', getRealIpAddress()); define('SELF_HOSTNAME', gethostbyaddr(SELF_IP_ADDRESS)); -require_once APP_ROOT . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; -require_once APP_ROOT . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'BaseFunctions.php'; +require_once REAL_APP_ROOT . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; +require_once REAL_APP_ROOT . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'BaseFunctions.php'; logger('APP_ROOT=' . APP_ROOT); logger('TEST_ROOT=' . TEST_ROOT); logger('SELF_IP_ADDRESS=' . SELF_IP_ADDRESS); -// Setup directories -try { - recreateDir(TMP_PATH); - recreateDir(CACHE_PATH); -} catch (FileNotFoundException $e) { - processException($e); -} - if (is_dir(CONFIG_PATH) && decoct(fileperms(CONFIG_PATH) & 0777) !== '750' ) { diff --git a/tests/res/config/mime.xml b/tests/res/config/mime.xml new file mode 100644 index 000000000..3de9734cd --- /dev/null +++ b/tests/res/config/mime.xml @@ -0,0 +1,209 @@ + + + + + application/x-abiword + AbiWord document + abw + + + application/octet-stream + Archive document (multiple files embedded) + arc + + + application/vnd.amazon.ebook + Amazon Kindle eBook format + azw + + + application/octet-stream + Any kind of binary data + bin + + + image/bmp + Windows OS/2 Bitmap Graphics + bmp + + + application/x-bzip + BZip archive + bz + + + application/x-bzip2 + BZip2 archive + bz2 + + + application/x-csh + C-Shell script + csh + + + text/csv + Comma-separated values (CSV) + csv + + + application/msword + Microsoft Word + doc + + + application/vnd.openxmlformats-officedocument.wordprocessingml.document + Microsoft Word (OpenXML) + docx + + + application/vnd.ms-fontobject + MS Embedded OpenType fonts + eot + + + application/epub+zip + Electronic publication (EPUB) + epub + + + image/gif + Graphics Interchange Format (GIF) + gif + + + text/html + HyperText Markup Language (HTML) + html + + + text/calendar + iCalendar format + ics + + + application/java-archive + Java Archive (JAR) + jar + + + image/jpeg + JPEG images + jpg + + + application/json + JSON format + json + + + application/vnd.apple.installer+xml + Apple Installer Package + mpkg + + + application/vnd.oasis.opendocument.presentation + OpenDocument presentation document + odp + + + application/vnd.oasis.opendocument.spreadsheet + OpenDocument spreadsheet document + ods + + + application/vnd.oasis.opendocument.text + OpenDocument text document + odt + + + image/png + Portable Network Graphics + png + + + application/pdf + Adobe Portable Document Format (PDF) + pdf + + + application/vnd.ms-powerpoint + Microsoft PowerPoint + ppt + + + application/vnd.openxmlformats-officedocument.presentationml.presentation + Microsoft PowerPoint (OpenXML) + pptx + + + application/x-rar-compressed + RAR archive + rar + + + application/rtf + Rich Text Format (RTF) + rtf + + + application/x-sh + Bourne shell script + sh + + + image/svg+xml + Scalable Vector Graphics (SVG) + svg + + + application/x-tar + Tape Archive (TAR) + tar + + + text/plain + Text, (generally ASCII or ISO 8859-n) + txt + + + application/vnd.visio + Microsoft Visio + vsd + + + application/xhtml+xml + XHTML + xhtml + + + application/vnd.ms-excel + Microsoft Excel + xls + + + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + Microsoft Excel (OpenXML) + xlsx + + + application/xml + XML + xml + + + application/vnd.mozilla.xul+xml + XUL + xul + + + application/zip + ZIP archive + zip + + + application/x-7z-compressed + 7-zip archive + 7z + + diff --git a/tests/res/view/theme/inc/Icons.php b/tests/res/view/theme/inc/Icons.php new file mode 100644 index 000000000..5e4e96dc2 --- /dev/null +++ b/tests/res/view/theme/inc/Icons.php @@ -0,0 +1,25 @@ +. + */ + +return new SP\Core\UI\ThemeIcons();