From 4d1708ed90d5ff6215e358f0fa2ee81ef151460c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20D?= Date: Sun, 1 Sep 2024 17:39:02 +0200 Subject: [PATCH] test(refactor): Extract duplicated code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rubén D --- .../ConfigEncryption/RefreshController.php | 81 +++---- .../ConfigEncryption/SaveController.php | 151 ++++--------- .../ConfigEncryption/SaveTempController.php | 107 ++++----- tests/SP/InjectConfigParam.php | 41 ++++ tests/SP/InjectCrypt.php | 40 ++++ tests/SP/InjectVault.php | 38 ++++ tests/SP/IntegrationTestCase.php | 208 +++++++++++------- .../AccessManager/IndexControllerTest.php | 7 +- .../Web/Controllers/Account/AccountTest.php | 125 ++--------- .../AccountFavorite/AccountFavoriteTest.php | 20 +- .../AccountFile/AccountFileTest.php | 22 -- .../AccountHistoryManagerTest.php | 20 -- .../AccountManager/AccountManagerTest.php | 27 +-- .../Controllers/AuthToken/AuthTokenTest.php | 23 -- .../Controllers/Bootstrap/BootstrapTest.php | 5 - .../Web/Controllers/Category/CategoryTest.php | 23 -- .../Web/Controllers/Client/ClientTest.php | 23 -- .../ConfigAccountControllerTest.php | 5 - .../ConfigBackupControllerTest.php | 20 -- .../RefreshControllerTest.php | 61 +++++ 20 files changed, 441 insertions(+), 606 deletions(-) create mode 100644 tests/SP/InjectConfigParam.php create mode 100644 tests/SP/InjectCrypt.php create mode 100644 tests/SP/InjectVault.php create mode 100644 tests/SP/Modules/Web/Controllers/ConfigEncryption/RefreshControllerTest.php diff --git a/app/modules/web/Controllers/ConfigEncryption/RefreshController.php b/app/modules/web/Controllers/ConfigEncryption/RefreshController.php index ad0e530c..a9c8d141 100644 --- a/app/modules/web/Controllers/ConfigEncryption/RefreshController.php +++ b/app/modules/web/Controllers/ConfigEncryption/RefreshController.php @@ -24,89 +24,74 @@ namespace SP\Modules\Web\Controllers\ConfigEncryption; - -use Exception; -use JsonException; use SP\Core\Application; use SP\Core\Crypt\Hash; use SP\Core\Crypt\Session as CryptSession; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; +use SP\Domain\Common\Attributes\Action; +use SP\Domain\Common\Dtos\ActionResponse; +use SP\Domain\Common\Enums\ResponseType; use SP\Domain\Core\Acl\AclActionsInterface; use SP\Domain\Core\Acl\UnauthorizedPageException; +use SP\Domain\Core\Exceptions\ConstraintException; +use SP\Domain\Core\Exceptions\CryptException; +use SP\Domain\Core\Exceptions\QueryException; use SP\Domain\Core\Exceptions\SessionTimeout; +use SP\Domain\Core\Exceptions\SPException; use SP\Domain\Crypt\Ports\MasterPassService; -use SP\Domain\Http\Dtos\JsonMessage; use SP\Modules\Web\Controllers\SimpleControllerBase; -use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Mvc\Controller\SimpleControllerHelper; +use function SP\__u; + /** * Class RefreshController */ final class RefreshController extends SimpleControllerBase { - use JsonTrait; - - private MasterPassService $masterPassService; - public function __construct( - Application $application, - SimpleControllerHelper $simpleControllerHelper, - MasterPassService $masterPassService + Application $application, + SimpleControllerHelper $simpleControllerHelper, + private readonly MasterPassService $masterPassService ) { parent::__construct($application, $simpleControllerHelper); - - $this->masterPassService = $masterPassService; } /** * Refresh master password hash * - * @return bool - * @throws JsonException + * @return ActionResponse + * @throws ConstraintException + * @throws CryptException + * @throws QueryException */ - public function refreshAction(): bool + #[Action(ResponseType::JSON)] + public function refreshAction(): ActionResponse { - try { - if ($this->config->getConfigData()->isDemoEnabled()) { - return $this->returnJsonResponse(JsonMessage::JSON_WARNING, __u('Ey, this is a DEMO!!')); - } - - $this->masterPassService->updateConfig(Hash::hashKey(CryptSession::getSessionKey($this->session))); - - $this->eventDispatcher->notify( - 'refresh.masterPassword.hash', - new Event($this, EventMessage::build()->addDescription(__u('Master password hash updated'))) - ); - - return $this->returnJsonResponse(JsonMessage::JSON_SUCCESS, __u('Master password hash updated')); - } catch (Exception $e) { - processException($e); - - $this->eventDispatcher->notify('exception', new Event($e)); - - return $this->returnJsonResponse( - JsonMessage::JSON_ERROR, - __u('Error while updating the master password hash') - ); + if ($this->config->getConfigData()->isDemoEnabled()) { + return ActionResponse::warning(__u('Ey, this is a DEMO!!')); } + + $this->masterPassService->updateConfig(Hash::hashKey(CryptSession::getSessionKey($this->session))); + + $this->eventDispatcher->notify( + 'refresh.masterPassword.hash', + new Event($this, EventMessage::build()->addDescription(__u('Master password hash updated'))) + ); + + return ActionResponse::ok(__u('Master password hash updated')); } /** * @return void - * @throws JsonException * @throws SessionTimeout + * @throws UnauthorizedPageException + * @throws SPException */ protected function initialize(): void { - try { - $this->checks(); - $this->checkAccess(AclActionsInterface::CONFIG_CRYPT); - } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notify('exception', new Event($e)); - - $this->returnJsonResponseException($e); - } + $this->checks(); + $this->checkAccess(AclActionsInterface::CONFIG_CRYPT); } } diff --git a/app/modules/web/Controllers/ConfigEncryption/SaveController.php b/app/modules/web/Controllers/ConfigEncryption/SaveController.php index 653d3587..b243126c 100644 --- a/app/modules/web/Controllers/ConfigEncryption/SaveController.php +++ b/app/modules/web/Controllers/ConfigEncryption/SaveController.php @@ -24,30 +24,31 @@ namespace SP\Modules\Web\Controllers\ConfigEncryption; - use Exception; -use JsonException; use SP\Core\Application; use SP\Core\Crypt\Hash; use SP\Core\Events\Event; +use SP\Domain\Common\Attributes\Action; +use SP\Domain\Common\Dtos\ActionResponse; +use SP\Domain\Common\Enums\ResponseType; use SP\Domain\Common\Services\ServiceException; use SP\Domain\Config\Ports\ConfigService; use SP\Domain\Core\Acl\AclActionsInterface; use SP\Domain\Core\Acl\UnauthorizedPageException; +use SP\Domain\Core\Exceptions\ConstraintException; +use SP\Domain\Core\Exceptions\QueryException; use SP\Domain\Core\Exceptions\SessionTimeout; +use SP\Domain\Core\Exceptions\SPException; use SP\Domain\Crypt\Dtos\UpdateMasterPassRequest; use SP\Domain\Crypt\Ports\MasterPassService; use SP\Domain\Crypt\Services\MasterPass; -use SP\Domain\Http\Dtos\JsonMessage; -use SP\Domain\Task\Ports\TaskInterface; -use SP\Domain\Task\Services\Task; -use SP\Domain\Task\Services\TaskFactory; use SP\Infrastructure\Common\Repositories\NoSuchItemException; -use SP\Infrastructure\File\FileException; use SP\Modules\Web\Controllers\SimpleControllerBase; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Mvc\Controller\SimpleControllerHelper; +use function SP\__u; + /** * Class SaveController */ @@ -55,28 +56,25 @@ final class SaveController extends SimpleControllerBase { use JsonTrait; - private MasterPassService $masterPassService; - private ConfigService $configService; - public function __construct( - Application $application, - SimpleControllerHelper $simpleControllerHelper, - MasterPassService $masterPassService, - ConfigService $configService + Application $application, + SimpleControllerHelper $simpleControllerHelper, + private readonly MasterPassService $masterPassService, + private readonly ConfigService $configService ) { parent::__construct($application, $simpleControllerHelper); - - $this->masterPassService = $masterPassService; - $this->configService = $configService; } /** - * @return bool - * @throws JsonException + * @return ActionResponse * @throws NoSuchItemException * @throws ServiceException + * @throws ConstraintException + * @throws QueryException + * @throws Exception */ - public function saveAction(): bool + #[Action(ResponseType::JSON)] + public function saveAction(): ActionResponse { $currentMasterPass = $this->request->analyzeEncrypted('current_masterpass'); $newMasterPass = $this->request->analyzeEncrypted('new_masterpass'); @@ -85,134 +83,71 @@ final class SaveController extends SimpleControllerBase $noAccountPassChange = $this->request->analyzeBool('no_account_change', false); - if (!$this->masterPassService->checkUserUpdateMPass($this->session->getUserData()->getLastUpdateMPass())) { - return $this->returnJsonResponse( - JsonMessage::JSON_SUCCESS_STICKY, - __u('Master password updated'), - [__u('Please, restart the session for update it')] - ); + if (!$this->masterPassService->checkUserUpdateMPass($this->session->getUserData()->lastUpdateMPass)) { + return ActionResponse::ok(__u('Master password updated'), __u('Please, restart the session for update it')); } if (empty($newMasterPass) || empty($currentMasterPass)) { - return $this->returnJsonResponse( - JsonMessage::JSON_ERROR, - __u('Master password not entered') - ); + return ActionResponse::error(__u('Master password not entered')); } if ($confirmPassChange === false) { - return $this->returnJsonResponse( - JsonMessage::JSON_ERROR, - __u('The password update must be confirmed') - ); + return ActionResponse::ok(__u('The password update must be confirmed')); } if ($newMasterPass === $currentMasterPass) { - return $this->returnJsonResponse( - JsonMessage::JSON_ERROR, - __u('Passwords are the same') - ); + return ActionResponse::ok(__u('Passwords are the same')); } if ($newMasterPass !== $newMasterPassR) { - return $this->returnJsonResponse( - JsonMessage::JSON_ERROR, - __u('Master passwords do not match') - ); + return ActionResponse::ok(__u('Master passwords do not match')); } if (!$this->masterPassService->checkMasterPassword($currentMasterPass)) { - return $this->returnJsonResponse( - JsonMessage::JSON_ERROR, - __u('The current master password does not match') - ); + return ActionResponse::ok(__u('The current master password does not match')); } if (!$this->config->getConfigData()->isMaintenance()) { - return $this->returnJsonResponse( - JsonMessage::JSON_WARNING, + return ActionResponse::warning( __u('Maintenance mode not enabled'), - [__u('Please, enable it to avoid unwanted behavior from other sessions')] + __u('Please, enable it to avoid unwanted behavior from other sessions') ); } if ($this->config->getConfigData()->isDemoEnabled()) { - return $this->returnJsonResponse( - JsonMessage::JSON_WARNING, - __u('Ey, this is a DEMO!!') - ); + return ActionResponse::warning(__u('Ey, this is a DEMO!!')); } if (!$noAccountPassChange) { - try { - $request = new UpdateMasterPassRequest( - $currentMasterPass, - $newMasterPass, - $this->configService->getByParam(MasterPass::PARAM_MASTER_PASS_HASH), - ); + $request = new UpdateMasterPassRequest( + $currentMasterPass, + $newMasterPass, + $this->configService->getByParam(MasterPass::PARAM_MASTER_PASS_HASH), + ); - $this->eventDispatcher->notify('update.masterPassword.start', new Event($this)); + $this->eventDispatcher->notify('update.masterPassword.start', new Event($this)); - $this->masterPassService->changeMasterPassword($request); + $this->masterPassService->changeMasterPassword($request); - $this->eventDispatcher->notify('update.masterPassword.end', new Event($this)); - } catch (Exception $e) { - processException($e); - - $this->eventDispatcher->notify('exception', new Event($e)); - - return $this->returnJsonResponseException($e); - } + $this->eventDispatcher->notify('update.masterPassword.end', new Event($this)); } else { - try { - $this->eventDispatcher->notify('update.masterPassword.hash', new Event($this)); + $this->eventDispatcher->notify('update.masterPassword.hash', new Event($this)); - $this->masterPassService->updateConfig(Hash::hashKey($newMasterPass)); - } catch (Exception $e) { - processException($e); - - $this->eventDispatcher->notify('exception', new Event($e)); - - return $this->returnJsonResponse( - JsonMessage::JSON_ERROR, - __u('Error while saving the Master Password\'s hash') - ); - } + $this->masterPassService->updateConfig(Hash::hashKey($newMasterPass)); } - return $this->returnJsonResponse( - JsonMessage::JSON_SUCCESS_STICKY, - __u('Master password updated'), - [__u('Please, restart the session to update it')] - ); + return ActionResponse::ok(__u('Master password updated'), __u('Please, restart the session to update it')); } /** * @return void - * @throws JsonException * @throws SessionTimeout + * @throws UnauthorizedPageException + * @throws SPException */ protected function initialize(): void { - try { - $this->checks(); - $this->checkAccess(AclActionsInterface::CONFIG_CRYPT); - } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notify('exception', new Event($e)); - - $this->returnJsonResponseException($e); - } - } - - /** - * @throws FileException - */ - private function getTask(): ?TaskInterface - { - $taskId = $this->request->analyzeString('taskId'); - - return $taskId !== null - ? TaskFactory::register(new Task(__FUNCTION__, $taskId)) - : null; + $this->checks(); + $this->checkAccess(AclActionsInterface::CONFIG_CRYPT); } } diff --git a/app/modules/web/Controllers/ConfigEncryption/SaveTempController.php b/app/modules/web/Controllers/ConfigEncryption/SaveTempController.php index 5b1a8e43..6ed5881e 100644 --- a/app/modules/web/Controllers/ConfigEncryption/SaveTempController.php +++ b/app/modules/web/Controllers/ConfigEncryption/SaveTempController.php @@ -24,108 +24,81 @@ namespace SP\Modules\Web\Controllers\ConfigEncryption; -use Exception; -use JsonException; +use PHPMailer\PHPMailer\Exception; use SP\Core\Application; -use SP\Core\Events\Event; +use SP\Domain\Common\Attributes\Action; +use SP\Domain\Common\Dtos\ActionResponse; +use SP\Domain\Common\Enums\ResponseType; +use SP\Domain\Common\Services\ServiceException; use SP\Domain\Core\Acl\AclActionsInterface; use SP\Domain\Core\Acl\UnauthorizedPageException; +use SP\Domain\Core\Exceptions\ConstraintException; +use SP\Domain\Core\Exceptions\QueryException; use SP\Domain\Core\Exceptions\SessionTimeout; +use SP\Domain\Core\Exceptions\SPException; use SP\Domain\Crypt\Ports\TemporaryMasterPassService; -use SP\Domain\Http\Dtos\JsonMessage; use SP\Modules\Web\Controllers\SimpleControllerBase; -use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Mvc\Controller\SimpleControllerHelper; +use function SP\__u; + /** - * Class ConfigEncryptionController - * - * @package SP\Modules\Web\Controllers + * Class SaveTempController */ final class SaveTempController extends SimpleControllerBase { - use JsonTrait; - - private TemporaryMasterPassService $temporaryMasterPassService; public function __construct( - Application $application, - SimpleControllerHelper $simpleControllerHelper, - TemporaryMasterPassService $temporaryMasterPassService + Application $application, + SimpleControllerHelper $simpleControllerHelper, + private readonly TemporaryMasterPassService $temporaryMasterPassService ) { parent::__construct($application, $simpleControllerHelper); - - $this->temporaryMasterPassService = $temporaryMasterPassService; } /** * Create a temporary master pass * - * @return bool - * @throws JsonException + * @return ActionResponse + * @throws Exception + * @throws ServiceException + * @throws ConstraintException + * @throws QueryException */ - public function saveTempAction(): bool + #[Action(ResponseType::JSON)] + public function saveTempAction(): ActionResponse { - try { - $key = - $this->temporaryMasterPassService->create( - $this->request->analyzeInt('temporary_masterpass_maxtime', 3600) - ); + $key = + $this->temporaryMasterPassService->create( + $this->request->analyzeInt('temporary_masterpass_maxtime', 3600) + ); - $groupId = $this->request->analyzeInt('temporary_masterpass_group', 0); - $sendEmail = $this->configData->isMailEnabled() - && $this->request->analyzeBool('temporary_masterpass_email'); + $groupId = $this->request->analyzeInt('temporary_masterpass_group', 0); + $sendEmail = $this->configData->isMailEnabled() + && $this->request->analyzeBool('temporary_masterpass_email'); - if ($sendEmail) { - try { - if ($groupId > 0) { - $this->temporaryMasterPassService->sendByEmailForGroup($groupId, $key); - } else { - $this->temporaryMasterPassService->sendByEmailForAllUsers($key); - } - - return $this->returnJsonResponse( - JsonMessage::JSON_SUCCESS, - __u('Temporary password generated'), - [__u('Email sent')] - ); - } catch (Exception $e) { - processException($e); - - $this->eventDispatcher->notify('exception', new Event($e)); - - return $this->returnJsonResponse( - JsonMessage::JSON_WARNING, - __u('Temporary password generated'), - [__u('Error while sending the email')] - ); - } + if ($sendEmail) { + if ($groupId > 0) { + $this->temporaryMasterPassService->sendByEmailForGroup($groupId, $key); + } else { + $this->temporaryMasterPassService->sendByEmailForAllUsers($key); } - return $this->returnJsonResponse(JsonMessage::JSON_SUCCESS, __u('Temporary password generated')); - } catch (Exception $e) { - processException($e); - - $this->eventDispatcher->notify('exception', new Event($e)); - - return $this->returnJsonResponseException($e); + return ActionResponse::ok(__u('Temporary password generated'), __u('Email sent')); } + + return ActionResponse::ok(__u('Temporary password generated')); } /** * @return void - * @throws JsonException * @throws SessionTimeout + * @throws UnauthorizedPageException + * @throws SPException */ protected function initialize(): void { - try { - $this->checks(); - $this->checkAccess(AclActionsInterface::CONFIG_CRYPT); - } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notify('exception', new Event($e)); - - $this->returnJsonResponseException($e); - } + $this->checks(); + $this->checkAccess(AclActionsInterface::CONFIG_CRYPT); } } diff --git a/tests/SP/InjectConfigParam.php b/tests/SP/InjectConfigParam.php new file mode 100644 index 00000000..990b47af --- /dev/null +++ b/tests/SP/InjectConfigParam.php @@ -0,0 +1,41 @@ +. + */ + +declare(strict_types=1); + +namespace SP\Tests; + +use Attribute; + +/** + * Class InjectConfigParam + */ +#[Attribute(Attribute::TARGET_METHOD)] +final readonly class InjectConfigParam +{ + + public function __construct(public ?string $returnValue = null) + { + } +} diff --git a/tests/SP/InjectCrypt.php b/tests/SP/InjectCrypt.php new file mode 100644 index 00000000..6ed02628 --- /dev/null +++ b/tests/SP/InjectCrypt.php @@ -0,0 +1,40 @@ +. + */ + +declare(strict_types=1); + +namespace SP\Tests; + +use Attribute; + +/** + * Class InjectCrypt + */ +#[Attribute(Attribute::TARGET_METHOD)] +final readonly class InjectCrypt +{ + public function __construct(public string $returnValue = 'some_data') + { + } +} diff --git a/tests/SP/InjectVault.php b/tests/SP/InjectVault.php new file mode 100644 index 00000000..a23973a2 --- /dev/null +++ b/tests/SP/InjectVault.php @@ -0,0 +1,38 @@ +. + */ + +declare(strict_types=1); + +namespace SP\Tests; + +use Attribute; + +/** + * Class InjectVault + */ +#[Attribute(Attribute::TARGET_CLASS)] +final class InjectVault +{ + +} diff --git a/tests/SP/IntegrationTestCase.php b/tests/SP/IntegrationTestCase.php index 5681f3fe..534c486f 100644 --- a/tests/SP/IntegrationTestCase.php +++ b/tests/SP/IntegrationTestCase.php @@ -39,7 +39,6 @@ use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; use ReflectionAttribute; -use ReflectionException; use ReflectionMethod; use ReflectionObject; use SP\Core\Bootstrap\Path; @@ -52,12 +51,15 @@ use SP\Domain\Account\Ports\AccountAclService; use SP\Domain\Auth\Ports\LdapConnectionInterface; use SP\Domain\Config\Ports\ConfigDataInterface; use SP\Domain\Config\Ports\ConfigFileService; +use SP\Domain\Config\Ports\ConfigService; use SP\Domain\Core\Acl\AclInterface; use SP\Domain\Core\Bootstrap\BootstrapInterface; use SP\Domain\Core\Bootstrap\ModuleInterface; use SP\Domain\Core\Bootstrap\UriContextInterface; use SP\Domain\Core\Context\Context; use SP\Domain\Core\Context\SessionContext; +use SP\Domain\Core\Crypt\CryptInterface; +use SP\Domain\Core\Crypt\VaultInterface; use SP\Domain\Core\Exceptions\InvalidClassException; use SP\Domain\Core\Exceptions\SPException; use SP\Domain\Core\UI\ThemeContextInterface; @@ -73,10 +75,8 @@ use SP\Infrastructure\File\ArchiveHandler; use SP\Infrastructure\File\FileException; use SP\Infrastructure\File\FileSystem; use SP\Modules\Web\Bootstrap; -use SP\Mvc\View\OutputHandlerInterface; use SP\Tests\Generators\UserDataGenerator; use SP\Tests\Generators\UserProfileDataGenerator; -use SP\Tests\Stubs\OutputHandlerStub; use function DI\autowire; use function DI\factory; @@ -87,8 +87,10 @@ use function DI\factory; abstract class IntegrationTestCase extends TestCase { protected static Generator $faker; + private static array $definitionsCache; protected readonly string $passwordSalt; - protected Closure|null $databaseQueryResolver = null; + protected Closure|null $databaseQueryResolver = null; + protected array $definitions; /** * @var array $databaseMapperResolvers */ @@ -99,13 +101,39 @@ abstract class IntegrationTestCase extends TestCase parent::setUpBeforeClass(); self::$faker = Factory::create(); + self::$definitionsCache = array_merge( + DomainDefinitions::getDefinitions(), + CoreDefinitions::getDefinitions(REAL_APP_ROOT, 'web') + ); } /** * @throws Exception * @throws \Exception */ - protected function buildContainer(array $definitions = [], Request $request = null): ContainerInterface + protected function buildContainer(Request $request): ContainerInterface + { + $this->definitions[Request::class] = $request; + + $testDefinitions = array_merge($this->definitions, $this->getMockedDefinitions()); + + $this->processAttributes( + $this->getClassAttributesMap($testDefinitions), + $this->getMethodAttributesMap($testDefinitions) + ); + + $containerBuilder = new ContainerBuilder(); + $containerBuilder->addDefinitions(self::$definitionsCache, $testDefinitions); + + return $containerBuilder->build(); + } + + /** + * @return array + * @throws Exception + * @throws SPException + */ + private function getMockedDefinitions(): array { $configData = $this->getConfigData(); @@ -122,7 +150,7 @@ abstract class IntegrationTestCase extends TestCase $database->method('endTransaction')->willReturn(true); $database->method('rollbackTransaction')->willReturn(true); - $acl = self::createMock(AclInterface::class); + $acl = $this->createMock(AclInterface::class); $acl->method('checkUserAccess')->willReturn(true); $acl->method('getRouteFor')->willReturnCallback(static fn(int $actionId) => (string)$actionId); @@ -138,7 +166,7 @@ abstract class IntegrationTestCase extends TestCase return $accountPermission; }); - $mockedDefinitions = [ + return [ ConfigFileService::class => $configFileService, LdapConnectionInterface::class => self::createStub(LdapConnectionInterface::class), 'backup.dbArchiveHandler' => self::createStub(ArchiveHandler::class), @@ -159,44 +187,6 @@ abstract class IntegrationTestCase extends TestCase AclInterface::class => $acl, AccountAclService::class => $accountAcl, ]; - - $outputChecker = $this->getOutputChecker(); - - if ($outputChecker !== null) { - $definitions[OutputHandlerInterface::class] = new OutputHandlerStub($outputChecker->bindTo($this)); - } - - $bodyChecker = $this->getBodyChecker(); - - if ($bodyChecker !== null) { - $response = $this->getMockBuilder(Response::class)->onlyMethods(['body'])->getMock(); - $response->method('body') - ->with( - self::callback(static function (string $output) use ($bodyChecker) { - self::assertNotEmpty($output); - - $bodyChecker($output); - - return true; - }) - ); - - $definitions[Response::class] = $response; - } - - if ($request) { - $definitions += [Request::class => $request]; - } - - $containerBuilder = new ContainerBuilder(); - $containerBuilder->addDefinitions( - DomainDefinitions::getDefinitions(), - CoreDefinitions::getDefinitions(REAL_APP_ROOT, 'web'), - $definitions, - $mockedDefinitions - ); - - return $containerBuilder->build(); } /** @@ -271,44 +261,103 @@ abstract class IntegrationTestCase extends TestCase return UserProfileDataGenerator::factory()->buildProfileData(); } - /** - * @throws ReflectionException - */ - private function getOutputChecker(): ?Closure + private function processAttributes(array $classAtrributes, array $methodAttributes): void { - $reflection = new ReflectionObject($this); - foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { - if ($this->name() === $method->name) { - /** @var array> $attributes */ - $attributes = $method->getAttributes(OutputChecker::class); + $object = new ReflectionObject($this); - if (count($attributes) === 1) { - return (new ReflectionMethod($this, $attributes[0]->newInstance()->target))->getClosure($this); - } - } + if (!empty($classAtrributes)) { + $this->invokeAttributes($object, $classAtrributes); } - return null; + if (!empty($methodAttributes)) { + $methods = array_filter( + $object->getMethods(), + fn(ReflectionMethod $method) => $method->name === $this->name() + ); + + foreach ($methods as $method) { + $this->invokeAttributes($method, $methodAttributes); + } + } + } + + private function invokeAttributes(ReflectionObject|ReflectionMethod $reflection, array $attributeMap): void + { + foreach ($reflection->getAttributes() as $attribute) { + $callable = $attributeMap[$attribute->getName()] ?? null; + + if (is_callable($callable)) { + $callable($attribute); + } + } + } + + private function getClassAttributesMap(array &$definitions): array + { + return [ + InjectVault::class => function () use (&$definitions): void { + $vault = self::createStub(VaultInterface::class); + $vault->method('getData')->willReturn('some_data'); + + /** @var Context|Stub $context */ + $context = $definitions[Context::class]; + $context->method('getVault')->willReturn($vault); + } + ]; } /** - * @throws ReflectionException + * @param array $definitions + * @return Closure[] */ - private function getBodyChecker(): ?Closure + private function getMethodAttributesMap(array &$definitions): array { - $reflection = new ReflectionObject($this); - foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { - if ($this->name() === $method->name) { - /** @var array> $attributes */ - $attributes = $method->getAttributes(BodyChecker::class); + return [ + BodyChecker::class => + function (ReflectionAttribute $attribute) use (&$definitions): void { + /** @var ReflectionAttribute $attribute */ + $bodyChecker = (new ReflectionMethod($this, $attribute->newInstance()->target)) + ->getClosure($this); - if (count($attributes) === 1) { - return (new ReflectionMethod($this, $attributes[0]->newInstance()->target))->getClosure($this); + $response = $this->getMockBuilder(Response::class)->onlyMethods(['body'])->getMock(); + $response->method('body') + ->with( + self::callback(static function (string $output) use ($bodyChecker) { + self::assertNotEmpty($output); + + $bodyChecker($output); + + return true; + }) + ); + + $definitions[Response::class] = $response; + }, + InjectCrypt::class => function (ReflectionAttribute $attribute) use (&$definitions): void { + /** @var ReflectionAttribute $attribute */ + $value = $attribute->newInstance()->returnValue; + + $crypt = $this->createStub(CryptInterface::class); + $crypt->method('decrypt')->willReturn($value); + $crypt->method('encrypt')->willReturn($value); + + $definitions[CryptInterface::class] = $crypt; + }, + InjectConfigParam::class => function (ReflectionAttribute $attribute) use (&$definitions): void { + /** @var ReflectionAttribute $attribute */ + $value = $attribute->newInstance()->returnValue; + + $configService = self::createStub(ConfigService::class); + + if ($value) { + $configService->method('getByParam')->willReturn($value); + } else { + $configService->method('getByParam')->willReturnArgument(0); } - } - } - return null; + $definitions[ConfigService::class] = $configService; + } + ]; } final protected function addDatabaseMapperResolver(string $className, QueryResult $queryResult): void @@ -344,15 +393,6 @@ abstract class IntegrationTestCase extends TestCase ); } - /** - * @param callable $outputChecker - * @return OutputHandlerInterface - */ - protected function setupOutputHandler(callable $outputChecker): OutputHandlerInterface - { - return new OutputHandlerStub($outputChecker(...)->bindTo($this)); - } - /** * @param ContainerInterface $container * @return void @@ -368,15 +408,13 @@ abstract class IntegrationTestCase extends TestCase * @throws FileException * @throws InvalidClassException */ - protected function getModuleDefinitions(): array - { - return FileSystem::require(FileSystem::buildPath(REAL_APP_ROOT, 'app', 'modules', 'web', 'module.php')); - } - protected function setUp(): void { parent::setUp(); $this->passwordSalt = self::$faker->sha1(); + $this->definitions = FileSystem::require( + FileSystem::buildPath(REAL_APP_ROOT, 'app', 'modules', 'web', 'module.php') + ); } } diff --git a/tests/SP/Modules/Web/Controllers/AccessManager/IndexControllerTest.php b/tests/SP/Modules/Web/Controllers/AccessManager/IndexControllerTest.php index 31af41ac..fef4e401 100644 --- a/tests/SP/Modules/Web/Controllers/AccessManager/IndexControllerTest.php +++ b/tests/SP/Modules/Web/Controllers/AccessManager/IndexControllerTest.php @@ -33,9 +33,7 @@ use PHPUnit\Framework\MockObject\Stub; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Domain\Config\Ports\ConfigDataInterface; -use SP\Domain\Core\Exceptions\InvalidClassException; use SP\Domain\User\Models\ProfileData; -use SP\Infrastructure\File\FileException; use SP\Tests\BodyChecker; use SP\Tests\IntegrationTestCase; use Symfony\Component\DomCrawler\Crawler; @@ -47,10 +45,8 @@ use Symfony\Component\DomCrawler\Crawler; class IndexControllerTest extends IntegrationTestCase { /** - * @throws Exception - * @throws FileException - * @throws InvalidClassException * @throws ContainerExceptionInterface + * @throws Exception * @throws NotFoundExceptionInterface */ #[Test] @@ -58,7 +54,6 @@ class IndexControllerTest extends IntegrationTestCase public function index() { $container = $this->buildContainer( - $this->getModuleDefinitions(), $this->buildRequest('get', 'index.php', ['r' => 'accessManager/index']) ); diff --git a/tests/SP/Modules/Web/Controllers/Account/AccountTest.php b/tests/SP/Modules/Web/Controllers/Account/AccountTest.php index a2b104bb..5f87820c 100644 --- a/tests/SP/Modules/Web/Controllers/Account/AccountTest.php +++ b/tests/SP/Modules/Web/Controllers/Account/AccountTest.php @@ -30,7 +30,6 @@ use Defuse\Crypto\Exception\EnvironmentIsBrokenException; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\Exception; -use PHPUnit\Framework\MockObject\Stub; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Core\Crypt\Crypt; @@ -44,20 +43,17 @@ use SP\Domain\Account\Models\AccountView; use SP\Domain\Account\Models\PublicLink; use SP\Domain\Common\Models\Item; use SP\Domain\Common\Models\Simple; -use SP\Domain\Config\Ports\ConfigService; -use SP\Domain\Core\Context\SessionContext; -use SP\Domain\Core\Crypt\CryptInterface; -use SP\Domain\Core\Crypt\VaultInterface; use SP\Domain\Core\Exceptions\CryptException; -use SP\Domain\Core\Exceptions\InvalidClassException; use SP\Domain\User\Dtos\UserDto; use SP\Domain\User\Models\ProfileData; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\File\FileException; use SP\Tests\BodyChecker; use SP\Tests\Generators\AccountDataGenerator; use SP\Tests\Generators\PublicLinkDataGenerator; use SP\Tests\Generators\UserDataGenerator; +use SP\Tests\InjectConfigParam; +use SP\Tests\InjectCrypt; +use SP\Tests\InjectVault; use SP\Tests\IntegrationTestCase; use Symfony\Component\DomCrawler\Crawler; @@ -65,10 +61,9 @@ use Symfony\Component\DomCrawler\Crawler; * Class AccountTest */ #[Group('integration')] +#[InjectVault] class AccountTest extends IntegrationTestCase { - private array $definitions; - /** * @throws ContainerExceptionInterface * @throws Exception @@ -76,6 +71,7 @@ class AccountTest extends IntegrationTestCase */ #[Test] #[BodyChecker('outputCheckerViewPassHistory')] + #[InjectCrypt] public function viewPassHistory() { $this->addDatabaseMapperResolver( @@ -86,14 +82,8 @@ class AccountTest extends IntegrationTestCase ) ]) ); - $crypt = $this->createStub(CryptInterface::class); - $crypt->method('decrypt')->willReturn('some_data'); - $crypt->method('encrypt')->willReturn('some_data'); - - $this->definitions[CryptInterface::class] = $crypt; $container = $this->buildContainer( - $this->definitions, $this->buildRequest( 'get', 'index.php', @@ -116,6 +106,7 @@ class AccountTest extends IntegrationTestCase */ #[Test] #[BodyChecker('outputCheckerViewPass')] + #[InjectCrypt] public function viewPass() { $this->addDatabaseMapperResolver( @@ -126,14 +117,8 @@ class AccountTest extends IntegrationTestCase ) ]) ); - $crypt = $this->createStub(CryptInterface::class); - $crypt->method('decrypt')->willReturn('some_data'); - $crypt->method('encrypt')->willReturn('some_data'); - - $this->definitions[CryptInterface::class] = $crypt; $container = $this->buildContainer( - $this->definitions, $this->buildRequest( 'get', 'index.php', @@ -179,7 +164,6 @@ class AccountTest extends IntegrationTestCase $this->addDatabaseMapperResolver(PublicLink::class, new QueryResult([$publicLink])); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'account/viewLink/' . self::$faker->sha1()]) ); @@ -220,7 +204,6 @@ class AccountTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'account/viewHistory/id/' . self::$faker->randomNumber(3)]) ); @@ -253,7 +236,6 @@ class AccountTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'account/view/id/' . self::$faker->randomNumber(3)]) ); @@ -277,7 +259,6 @@ class AccountTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest( 'post', 'index.php', @@ -295,6 +276,7 @@ class AccountTest extends IntegrationTestCase * @throws NotFoundExceptionInterface */ #[Test] + #[InjectConfigParam] public function saveRequest() { $accountDataGenerator = AccountDataGenerator::factory(); @@ -304,13 +286,7 @@ class AccountTest extends IntegrationTestCase new QueryResult([$accountDataGenerator->buildAccountDataView()]) ); - $configService = self::createStub(ConfigService::class); - $configService->method('getByParam')->willReturnArgument(0); - - $this->definitions[ConfigService::class] = $configService; - $container = $this->buildContainer( - $this->definitions, $this->buildRequest( 'post', 'index.php', @@ -332,6 +308,7 @@ class AccountTest extends IntegrationTestCase * @throws NotFoundExceptionInterface */ #[Test] + #[InjectConfigParam] public function saveEditRestore() { $accountDataGenerator = AccountDataGenerator::factory(); @@ -351,11 +328,6 @@ class AccountTest extends IntegrationTestCase new QueryResult([$accountDataGenerator->buildAccountDataView()]) ); - $configService = self::createStub(ConfigService::class); - $configService->method('getByParam')->willReturnArgument(0); - - $this->definitions[ConfigService::class] = $configService; - $account = $accountDataGenerator->buildAccount(); $paramsPost = [ @@ -367,7 +339,6 @@ class AccountTest extends IntegrationTestCase $accountId = self::$faker->randomNumber(3); $container = $this->buildContainer( - $this->definitions, $this->buildRequest( 'post', 'index.php', @@ -391,6 +362,7 @@ class AccountTest extends IntegrationTestCase * @throws NotFoundExceptionInterface */ #[Test] + #[InjectConfigParam] public function saveEditPass() { $accountDataGenerator = AccountDataGenerator::factory(); @@ -405,11 +377,6 @@ class AccountTest extends IntegrationTestCase new QueryResult([$accountDataGenerator->buildAccountDataView()]) ); - $configService = self::createStub(ConfigService::class); - $configService->method('getByParam')->willReturnArgument(0); - - $this->definitions[ConfigService::class] = $configService; - $account = $accountDataGenerator->buildAccount(); $paramsPost = [ @@ -420,7 +387,6 @@ class AccountTest extends IntegrationTestCase $accountId = self::$faker->randomNumber(3); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('post', 'index.php', ['r' => 'account/saveEditPass/' . $accountId], $paramsPost) ); @@ -438,6 +404,7 @@ class AccountTest extends IntegrationTestCase * @throws NotFoundExceptionInterface */ #[Test] + #[InjectConfigParam] public function saveEdit() { $accountDataGenerator = AccountDataGenerator::factory(); @@ -452,11 +419,6 @@ class AccountTest extends IntegrationTestCase new QueryResult([$accountDataGenerator->buildAccountDataView()]) ); - $configService = self::createStub(ConfigService::class); - $configService->method('getByParam')->willReturnArgument(0); - - $this->definitions[ConfigService::class] = $configService; - $account = $accountDataGenerator->buildAccount(); $paramsPost = [ @@ -488,7 +450,6 @@ class AccountTest extends IntegrationTestCase $accountId = self::$faker->randomNumber(3); $container = $this->buildContainer( - $this->definitions, $this->buildRequest( 'post', 'index.php', @@ -511,6 +472,7 @@ class AccountTest extends IntegrationTestCase * @throws NotFoundExceptionInterface */ #[Test] + #[InjectConfigParam] public function saveDelete() { $accountDataGenerator = AccountDataGenerator::factory(); @@ -525,13 +487,7 @@ class AccountTest extends IntegrationTestCase new QueryResult([$accountDataGenerator->buildAccount()]) ); - $configService = self::createStub(ConfigService::class); - $configService->method('getByParam')->willReturnArgument(0); - - $this->definitions[ConfigService::class] = $configService; - $container = $this->buildContainer( - $this->definitions, $this->buildRequest('post', 'index.php', ['r' => 'account/saveDelete/1']) ); @@ -568,7 +524,6 @@ class AccountTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'account/copy/id/' . self::$faker->randomNumber(3)]) ); @@ -581,6 +536,7 @@ class AccountTest extends IntegrationTestCase * @throws NotFoundExceptionInterface */ #[Test] + #[InjectCrypt] public function copyPass() { $this->addDatabaseMapperResolver( @@ -591,14 +547,8 @@ class AccountTest extends IntegrationTestCase ) ]) ); - $crypt = $this->createStub(CryptInterface::class); - $crypt->method('decrypt')->willReturn('some_data'); - $crypt->method('encrypt')->willReturn('some_data'); - - $this->definitions[CryptInterface::class] = $crypt; $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'account/copyPass/id/' . self::$faker->randomNumber(3)]) ); @@ -613,6 +563,7 @@ class AccountTest extends IntegrationTestCase * @throws NotFoundExceptionInterface */ #[Test] + #[InjectCrypt] public function copyPassHistory() { $this->addDatabaseMapperResolver( @@ -624,14 +575,7 @@ class AccountTest extends IntegrationTestCase ]) ); - $crypt = $this->createStub(CryptInterface::class); - $crypt->method('decrypt')->willReturn('some_data'); - $crypt->method('encrypt')->willReturn('some_data'); - - $this->definitions[CryptInterface::class] = $crypt; - $container = $this->buildContainer( - $this->definitions, $this->buildRequest( 'get', 'index.php', @@ -654,7 +598,6 @@ class AccountTest extends IntegrationTestCase public function create() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'account/create']) ); @@ -676,7 +619,6 @@ class AccountTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'account/delete/100']) ); @@ -698,7 +640,6 @@ class AccountTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'account/edit/' . self::$faker->randomNumber(3)]) ); @@ -715,7 +656,6 @@ class AccountTest extends IntegrationTestCase public function index() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'account']) ); @@ -737,7 +677,6 @@ class AccountTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'account/requestAccess/' . self::$faker->randomNumber(3)]) ); @@ -750,6 +689,7 @@ class AccountTest extends IntegrationTestCase * @throws NotFoundExceptionInterface */ #[Test] + #[InjectCrypt] public function saveCopy() { $accountDataGenerator = AccountDataGenerator::factory(); @@ -759,12 +699,6 @@ class AccountTest extends IntegrationTestCase new QueryResult([$accountDataGenerator->buildAccountDataView()]) ); - $crypt = $this->createStub(CryptInterface::class); - $crypt->method('decrypt')->willReturn('some_data'); - $crypt->method('encrypt')->willReturn('some_data'); - - $this->definitions[CryptInterface::class] = $crypt; - $account = $accountDataGenerator->buildAccount(); $paramsPost = [ @@ -794,7 +728,6 @@ class AccountTest extends IntegrationTestCase ]; $container = $this->buildContainer( - $this->definitions, $this->buildRequest('post', 'index.php', ['r' => 'account/saveCopy'], $paramsPost) ); @@ -811,6 +744,7 @@ class AccountTest extends IntegrationTestCase * @throws NotFoundExceptionInterface */ #[Test] + #[InjectCrypt] public function saveCreate() { $accountDataGenerator = AccountDataGenerator::factory(); @@ -820,12 +754,6 @@ class AccountTest extends IntegrationTestCase new QueryResult([$accountDataGenerator->buildAccountDataView()]) ); - $crypt = $this->createStub(CryptInterface::class); - $crypt->method('decrypt')->willReturn('some_data'); - $crypt->method('encrypt')->willReturn('some_data'); - - $this->definitions[CryptInterface::class] = $crypt; - $account = $accountDataGenerator->buildAccount(); $paramsPost = [ @@ -855,7 +783,6 @@ class AccountTest extends IntegrationTestCase ]; $container = $this->buildContainer( - $this->definitions, $this->buildRequest('post', 'index.php', ['r' => 'account/saveCreate'], $paramsPost) ); @@ -866,34 +793,12 @@ class AccountTest extends IntegrationTestCase ); } - /** - * @throws FileException - * @throws InvalidClassException - */ - protected function setUp(): void - { - parent::setUp(); - - $this->definitions = $this->getModuleDefinitions(); - } - protected function getUserDataDto(): UserDto { $userPreferences = UserDataGenerator::factory()->buildUserPreferencesData()->mutate(['topNavbar' => true]); return parent::getUserDataDto()->mutate(['preferences' => $userPreferences]); } - protected function getContext(): SessionContext|Stub - { - $vault = self::createStub(VaultInterface::class); - $vault->method('getData')->willReturn('some_data'); - - $context = parent::getContext(); - $context->method('getVault')->willReturn($vault); - - return $context; - } - protected function getUserProfile(): ProfileData { return new ProfileData( diff --git a/tests/SP/Modules/Web/Controllers/AccountFavorite/AccountFavoriteTest.php b/tests/SP/Modules/Web/Controllers/AccountFavorite/AccountFavoriteTest.php index 26f92d78..b95cf39a 100644 --- a/tests/SP/Modules/Web/Controllers/AccountFavorite/AccountFavoriteTest.php +++ b/tests/SP/Modules/Web/Controllers/AccountFavorite/AccountFavoriteTest.php @@ -30,8 +30,6 @@ use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\MockObject\Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; -use SP\Domain\Core\Exceptions\InvalidClassException; -use SP\Infrastructure\File\FileException; use SP\Tests\IntegrationTestCase; /** @@ -41,18 +39,13 @@ use SP\Tests\IntegrationTestCase; class AccountFavoriteTest extends IntegrationTestCase { /** - * @throws NotFoundExceptionInterface - * @throws Exception - * @throws FileException - * @throws InvalidClassException * @throws ContainerExceptionInterface + * @throws Exception + * @throws NotFoundExceptionInterface */ public function testMarkAction() { - $definitions = $this->getModuleDefinitions(); - $container = $this->buildContainer( - $definitions, $this->buildRequest('post', 'index.php', ['r' => 'accountFavorite/mark/100']) ); @@ -62,18 +55,13 @@ class AccountFavoriteTest extends IntegrationTestCase } /** - * @throws NotFoundExceptionInterface - * @throws Exception - * @throws FileException - * @throws InvalidClassException * @throws ContainerExceptionInterface + * @throws Exception + * @throws NotFoundExceptionInterface */ public function testUnmarkAction() { - $definitions = $this->getModuleDefinitions(); - $container = $this->buildContainer( - $definitions, $this->buildRequest('post', 'index.php', ['r' => 'accountFavorite/unmark/100']) ); diff --git a/tests/SP/Modules/Web/Controllers/AccountFile/AccountFileTest.php b/tests/SP/Modules/Web/Controllers/AccountFile/AccountFileTest.php index 3ae83501..47c397c4 100644 --- a/tests/SP/Modules/Web/Controllers/AccountFile/AccountFileTest.php +++ b/tests/SP/Modules/Web/Controllers/AccountFile/AccountFileTest.php @@ -34,10 +34,8 @@ use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Domain\Account\Models\File; use SP\Domain\Config\Ports\ConfigDataInterface; -use SP\Domain\Core\Exceptions\InvalidClassException; use SP\Infrastructure\Database\QueryData; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\File\FileException; use SP\Tests\BodyChecker; use SP\Tests\Generators\FileDataGenerator; use SP\Tests\IntegrationTestCase; @@ -49,8 +47,6 @@ use Symfony\Component\DomCrawler\Crawler; #[Group('integration')] class AccountFileTest extends IntegrationTestCase { - private array $moduleDefinitions; - /** * @throws ContainerExceptionInterface * @throws Exception @@ -60,7 +56,6 @@ class AccountFileTest extends IntegrationTestCase public function deleteSingleFile() { $container = $this->buildContainer( - $this->moduleDefinitions, $this->buildRequest('post', 'index.php', ['r' => 'accountFile/delete/100']) ); @@ -87,7 +82,6 @@ class AccountFileTest extends IntegrationTestCase }; $container = $this->buildContainer( - $this->moduleDefinitions, $this->buildRequest('post', 'index.php', ['r' => 'accountFile/delete'], ['items' => [100, 200, 300]]) ); @@ -115,7 +109,6 @@ class AccountFileTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->moduleDefinitions, $this->buildRequest('get', 'index.php', ['r' => 'accountFile/download/100']) ); @@ -147,7 +140,6 @@ class AccountFileTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->moduleDefinitions, $this->buildRequest('get', 'index.php', ['r' => 'accountFile/list/100']) ); @@ -178,7 +170,6 @@ class AccountFileTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->moduleDefinitions, $this->buildRequest('get', 'index.php', ['r' => 'accountFile/search']) ); @@ -209,7 +200,6 @@ class AccountFileTest extends IntegrationTestCase ]; $container = $this->buildContainer( - $this->moduleDefinitions, $this->buildRequest('post', 'index.php', ['r' => 'accountFile/upload/100'], [], $files) ); @@ -234,7 +224,6 @@ class AccountFileTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->moduleDefinitions, $this->buildRequest('get', 'index.php', ['r' => 'accountFile/view/100']) ); @@ -251,17 +240,6 @@ class AccountFileTest extends IntegrationTestCase return $configData; } - /** - * @throws FileException - * @throws InvalidClassException - */ - protected function setUp(): void - { - parent::setUp(); - - $this->moduleDefinitions = $this->getModuleDefinitions(); - } - /** * @param string $output * @return void diff --git a/tests/SP/Modules/Web/Controllers/AccountHistoryManager/AccountHistoryManagerTest.php b/tests/SP/Modules/Web/Controllers/AccountHistoryManager/AccountHistoryManagerTest.php index 54b2cf7b..35008c61 100644 --- a/tests/SP/Modules/Web/Controllers/AccountHistoryManager/AccountHistoryManagerTest.php +++ b/tests/SP/Modules/Web/Controllers/AccountHistoryManager/AccountHistoryManagerTest.php @@ -35,10 +35,8 @@ use SP\Domain\Account\Models\Account; use SP\Domain\Account\Models\AccountHistory; use SP\Domain\Common\Models\Simple; use SP\Domain\Config\Models\Config; -use SP\Domain\Core\Exceptions\InvalidClassException; use SP\Infrastructure\Database\QueryData; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\File\FileException; use SP\Tests\BodyChecker; use SP\Tests\Generators\AccountDataGenerator; use SP\Tests\IntegrationTestCase; @@ -50,8 +48,6 @@ use Symfony\Component\DomCrawler\Crawler; #[Group('integration')] class AccountHistoryManagerTest extends IntegrationTestCase { - private array $definitions; - /** * @throws ContainerExceptionInterface * @throws Exception @@ -66,7 +62,6 @@ class AccountHistoryManagerTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'accountHistoryManager/delete/100']) ); @@ -89,7 +84,6 @@ class AccountHistoryManagerTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest( 'post', 'index.php', @@ -138,7 +132,6 @@ class AccountHistoryManagerTest extends IntegrationTestCase }; $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'accountHistoryManager/restore/100']) ); @@ -182,7 +175,6 @@ class AccountHistoryManagerTest extends IntegrationTestCase }; $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'accountHistoryManager/restore/100']) ); @@ -214,24 +206,12 @@ class AccountHistoryManagerTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'accountHistoryManager/search']) ); $this->runApp($container); } - /** - * @throws FileException - * @throws InvalidClassException - */ - protected function setUp(): void - { - parent::setUp(); - - $this->definitions = $this->getModuleDefinitions(); - } - /** * @param string $output * @return void diff --git a/tests/SP/Modules/Web/Controllers/AccountManager/AccountManagerTest.php b/tests/SP/Modules/Web/Controllers/AccountManager/AccountManagerTest.php index 102bc198..95e7a023 100644 --- a/tests/SP/Modules/Web/Controllers/AccountManager/AccountManagerTest.php +++ b/tests/SP/Modules/Web/Controllers/AccountManager/AccountManagerTest.php @@ -38,13 +38,11 @@ use SP\Domain\Category\Models\Category; use SP\Domain\Client\Models\Client; use SP\Domain\Config\Models\Config; use SP\Domain\Config\Ports\ConfigService; -use SP\Domain\Core\Exceptions\InvalidClassException; use SP\Domain\Tag\Models\Tag; use SP\Domain\User\Models\User; use SP\Domain\User\Models\UserGroup; use SP\Infrastructure\Database\QueryData; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\File\FileException; use SP\Tests\BodyChecker; use SP\Tests\Generators\AccountDataGenerator; use SP\Tests\Generators\CategoryGenerator; @@ -52,6 +50,7 @@ use SP\Tests\Generators\ClientGenerator; use SP\Tests\Generators\TagGenerator; use SP\Tests\Generators\UserDataGenerator; use SP\Tests\Generators\UserGroupGenerator; +use SP\Tests\InjectConfigParam; use SP\Tests\IntegrationTestCase; use Symfony\Component\DomCrawler\Crawler; @@ -61,8 +60,6 @@ use Symfony\Component\DomCrawler\Crawler; #[Group('integration')] class AccountManagerTest extends IntegrationTestCase { - private array $definitions; - /** * @throws ContainerExceptionInterface * @throws Exception @@ -98,7 +95,6 @@ class AccountManagerTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('post', 'index.php', ['r' => 'accountManager/bulkEdit'], ['items' => [100, 200, 300]]) ); @@ -111,6 +107,7 @@ class AccountManagerTest extends IntegrationTestCase * @throws NotFoundExceptionInterface */ #[Test] + #[InjectConfigParam] public function deleteSingle() { $accountDataGenerator = AccountDataGenerator::factory(); @@ -125,13 +122,7 @@ class AccountManagerTest extends IntegrationTestCase new QueryResult([$accountDataGenerator->buildAccount()]) ); - $configService = self::createStub(ConfigService::class); - $configService->method('getByParam')->willReturnArgument(0); - - $this->definitions[ConfigService::class] = $configService; - $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'accountManager/delete/100']) ); @@ -172,7 +163,6 @@ class AccountManagerTest extends IntegrationTestCase }; $container = $this->buildContainer( - $this->definitions, $this->buildRequest('post', 'index.php', ['r' => 'accountManager/delete'], ['items' => [100, 200, 300]]) ); @@ -222,7 +212,6 @@ class AccountManagerTest extends IntegrationTestCase ]; $container = $this->buildContainer( - $this->definitions, $this->buildRequest( 'post', 'index.php', @@ -259,24 +248,12 @@ class AccountManagerTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'accountManager/search', 'search' => 'test']) ); $this->runApp($container); } - /** - * @throws InvalidClassException - * @throws FileException - */ - protected function setUp(): void - { - parent::setUp(); - - $this->definitions = $this->getModuleDefinitions(); - } - private function outputCheckerBulkEdit(string $output): void { $json = json_decode($output); diff --git a/tests/SP/Modules/Web/Controllers/AuthToken/AuthTokenTest.php b/tests/SP/Modules/Web/Controllers/AuthToken/AuthTokenTest.php index 497f5d79..47cd3afb 100644 --- a/tests/SP/Modules/Web/Controllers/AuthToken/AuthTokenTest.php +++ b/tests/SP/Modules/Web/Controllers/AuthToken/AuthTokenTest.php @@ -32,9 +32,7 @@ use PHPUnit\Framework\MockObject\Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Domain\Auth\Models\AuthToken; -use SP\Domain\Core\Exceptions\InvalidClassException; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\File\FileException; use SP\Tests\BodyChecker; use SP\Tests\Generators\AuthTokenGenerator; use SP\Tests\IntegrationTestCase; @@ -46,8 +44,6 @@ use Symfony\Component\DomCrawler\Crawler; #[Group('integration')] class AuthTokenTest extends IntegrationTestCase { - private array $definitions; - /** * @throws ContainerExceptionInterface * @throws Exception @@ -58,7 +54,6 @@ class AuthTokenTest extends IntegrationTestCase public function create() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'authToken/create']) ); @@ -74,7 +69,6 @@ class AuthTokenTest extends IntegrationTestCase public function deleteMultiple() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'authToken/delete', 'items' => [100, 200, 300]]) ); @@ -92,7 +86,6 @@ class AuthTokenTest extends IntegrationTestCase public function deleteSingle() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'authToken/delete/100']) ); @@ -116,7 +109,6 @@ class AuthTokenTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'authToken/edit/100']) ); @@ -138,7 +130,6 @@ class AuthTokenTest extends IntegrationTestCase ]; $container = $this->buildContainer( - $this->definitions, $this->buildRequest('post', 'index.php', ['r' => 'authToken/saveCreate'], $data) ); @@ -162,7 +153,6 @@ class AuthTokenTest extends IntegrationTestCase ]; $container = $this->buildContainer( - $this->definitions, $this->buildRequest('post', 'index.php', ['r' => 'authToken/saveEdit/100'], $data) ); @@ -194,7 +184,6 @@ class AuthTokenTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'authToken/search', 'search' => 'test']) ); @@ -216,24 +205,12 @@ class AuthTokenTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'authToken/view/100']) ); $this->runApp($container); } - /** - * @throws FileException - * @throws InvalidClassException - */ - protected function setUp(): void - { - parent::setUp(); - - $this->definitions = $this->getModuleDefinitions(); - } - /** * @param string $output * @return void diff --git a/tests/SP/Modules/Web/Controllers/Bootstrap/BootstrapTest.php b/tests/SP/Modules/Web/Controllers/Bootstrap/BootstrapTest.php index d6d192b4..8e843ceb 100644 --- a/tests/SP/Modules/Web/Controllers/Bootstrap/BootstrapTest.php +++ b/tests/SP/Modules/Web/Controllers/Bootstrap/BootstrapTest.php @@ -31,8 +31,6 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; -use SP\Domain\Core\Exceptions\InvalidClassException; -use SP\Infrastructure\File\FileException; use SP\Tests\BodyChecker; use SP\Tests\IntegrationTestCase; @@ -47,15 +45,12 @@ class BootstrapTest extends IntegrationTestCase * @throws ContainerExceptionInterface * @throws Exception * @throws NotFoundExceptionInterface - * @throws InvalidClassException - * @throws FileException */ #[Test] #[BodyChecker('getEnvironmentOutputChecker')] public function getEnvironment() { $container = $this->buildContainer( - $this->getModuleDefinitions(), $this->buildRequest('get', 'index.php', ['r' => 'bootstrap/getEnvironment']) ); diff --git a/tests/SP/Modules/Web/Controllers/Category/CategoryTest.php b/tests/SP/Modules/Web/Controllers/Category/CategoryTest.php index 62fe0f7c..5231496b 100644 --- a/tests/SP/Modules/Web/Controllers/Category/CategoryTest.php +++ b/tests/SP/Modules/Web/Controllers/Category/CategoryTest.php @@ -32,9 +32,7 @@ use PHPUnit\Framework\MockObject\Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Domain\Category\Models\Category; -use SP\Domain\Core\Exceptions\InvalidClassException; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\File\FileException; use SP\Tests\BodyChecker; use SP\Tests\Generators\CategoryGenerator; use SP\Tests\IntegrationTestCase; @@ -46,8 +44,6 @@ use Symfony\Component\DomCrawler\Crawler; #[Group('integration')] class CategoryTest extends IntegrationTestCase { - private array $definitions; - /** * @throws ContainerExceptionInterface * @throws Exception @@ -58,7 +54,6 @@ class CategoryTest extends IntegrationTestCase public function create() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'category/create']) ); @@ -74,7 +69,6 @@ class CategoryTest extends IntegrationTestCase public function deleteMultiple() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'category/delete', 'items' => [100, 200, 300]]) ); @@ -92,7 +86,6 @@ class CategoryTest extends IntegrationTestCase public function deleteSingle() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'category/delete/100']) ); @@ -116,7 +109,6 @@ class CategoryTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'category/edit/100']) ); @@ -137,7 +129,6 @@ class CategoryTest extends IntegrationTestCase ]; $container = $this->buildContainer( - $this->definitions, $this->buildRequest('post', 'index.php', ['r' => 'category/saveCreate'], $data) ); @@ -160,7 +151,6 @@ class CategoryTest extends IntegrationTestCase ]; $container = $this->buildContainer( - $this->definitions, $this->buildRequest('post', 'index.php', ['r' => 'category/saveEdit/100'], $data) ); @@ -192,7 +182,6 @@ class CategoryTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'category/search', 'search' => 'test']) ); @@ -214,24 +203,12 @@ class CategoryTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'category/view/100']) ); $this->runApp($container); } - /** - * @throws FileException - * @throws InvalidClassException - */ - protected function setUp(): void - { - parent::setUp(); - - $this->definitions = $this->getModuleDefinitions(); - } - /** * @param string $output * @return void diff --git a/tests/SP/Modules/Web/Controllers/Client/ClientTest.php b/tests/SP/Modules/Web/Controllers/Client/ClientTest.php index c405b634..ed230a7b 100644 --- a/tests/SP/Modules/Web/Controllers/Client/ClientTest.php +++ b/tests/SP/Modules/Web/Controllers/Client/ClientTest.php @@ -32,9 +32,7 @@ use PHPUnit\Framework\MockObject\Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Domain\Client\Models\Client; -use SP\Domain\Core\Exceptions\InvalidClassException; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\File\FileException; use SP\Tests\BodyChecker; use SP\Tests\Generators\ClientGenerator; use SP\Tests\IntegrationTestCase; @@ -46,8 +44,6 @@ use Symfony\Component\DomCrawler\Crawler; #[Group('integration')] class ClientTest extends IntegrationTestCase { - private array $definitions; - /** * @throws ContainerExceptionInterface * @throws Exception @@ -58,7 +54,6 @@ class ClientTest extends IntegrationTestCase public function create() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'client/create']) ); @@ -74,7 +69,6 @@ class ClientTest extends IntegrationTestCase public function deleteMultiple() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'client/delete', 'items' => [100, 200, 300]]) ); @@ -92,7 +86,6 @@ class ClientTest extends IntegrationTestCase public function deleteSingle() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'client/delete/100']) ); @@ -116,7 +109,6 @@ class ClientTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'client/edit/100']) ); @@ -138,7 +130,6 @@ class ClientTest extends IntegrationTestCase ]; $container = $this->buildContainer( - $this->definitions, $this->buildRequest('post', 'index.php', ['r' => 'client/saveCreate'], $data) ); @@ -162,7 +153,6 @@ class ClientTest extends IntegrationTestCase ]; $container = $this->buildContainer( - $this->definitions, $this->buildRequest('post', 'index.php', ['r' => 'client/saveEdit/100'], $data) ); @@ -194,7 +184,6 @@ class ClientTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'client/search', 'search' => 'test']) ); @@ -216,24 +205,12 @@ class ClientTest extends IntegrationTestCase ); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'client/view/100']) ); $this->runApp($container); } - /** - * @throws FileException - * @throws InvalidClassException - */ - protected function setUp(): void - { - parent::setUp(); - - $this->definitions = $this->getModuleDefinitions(); - } - /** * @param string $output * @return void diff --git a/tests/SP/Modules/Web/Controllers/ConfigAccount/ConfigAccountControllerTest.php b/tests/SP/Modules/Web/Controllers/ConfigAccount/ConfigAccountControllerTest.php index dcad8015..3968c054 100644 --- a/tests/SP/Modules/Web/Controllers/ConfigAccount/ConfigAccountControllerTest.php +++ b/tests/SP/Modules/Web/Controllers/ConfigAccount/ConfigAccountControllerTest.php @@ -31,8 +31,6 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; -use SP\Domain\Core\Exceptions\InvalidClassException; -use SP\Infrastructure\File\FileException; use SP\Tests\IntegrationTestCase; /** @@ -46,8 +44,6 @@ class ConfigAccountControllerTest extends IntegrationTestCase * @throws ContainerExceptionInterface * @throws Exception * @throws NotFoundExceptionInterface - * @throws InvalidClassException - * @throws FileException */ #[Test] public function save() @@ -71,7 +67,6 @@ class ConfigAccountControllerTest extends IntegrationTestCase ]; $container = $this->buildContainer( - $this->getModuleDefinitions(), $this->buildRequest('post', 'index.php', ['r' => 'configAccount/save'], $data) ); diff --git a/tests/SP/Modules/Web/Controllers/ConfigBackup/ConfigBackupControllerTest.php b/tests/SP/Modules/Web/Controllers/ConfigBackup/ConfigBackupControllerTest.php index f73ace9c..08d5e893 100644 --- a/tests/SP/Modules/Web/Controllers/ConfigBackup/ConfigBackupControllerTest.php +++ b/tests/SP/Modules/Web/Controllers/ConfigBackup/ConfigBackupControllerTest.php @@ -33,8 +33,6 @@ use PHPUnit\Framework\MockObject\Stub; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Domain\Config\Ports\ConfigDataInterface; -use SP\Domain\Core\Exceptions\InvalidClassException; -use SP\Infrastructure\File\FileException; use SP\Tests\IntegrationTestCase; /** @@ -43,8 +41,6 @@ use SP\Tests\IntegrationTestCase; #[Group('integration')] class ConfigBackupControllerTest extends IntegrationTestCase { - private array $definitions; - /** * @throws ContainerExceptionInterface * @throws Exception @@ -66,7 +62,6 @@ class ConfigBackupControllerTest extends IntegrationTestCase file_put_contents($filename, 'test_data_app'); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'configBackup/downloadBackupApp']) ); @@ -98,7 +93,6 @@ class ConfigBackupControllerTest extends IntegrationTestCase file_put_contents($filename, 'test_data_db'); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'configBackup/downloadBackupDb']) ); @@ -130,7 +124,6 @@ class ConfigBackupControllerTest extends IntegrationTestCase file_put_contents($filename, 'test_data_export'); $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'configBackup/downloadExport']) ); @@ -150,7 +143,6 @@ class ConfigBackupControllerTest extends IntegrationTestCase public function fileBackup() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'configBackup/fileBackup']) ); @@ -168,7 +160,6 @@ class ConfigBackupControllerTest extends IntegrationTestCase public function xmlExport() { $container = $this->buildContainer( - $this->definitions, $this->buildRequest('get', 'index.php', ['r' => 'configBackup/xmlExport']) ); @@ -177,17 +168,6 @@ class ConfigBackupControllerTest extends IntegrationTestCase $this->runApp($container); } - /** - * @throws InvalidClassException - * @throws FileException - */ - protected function setUp(): void - { - parent::setUp(); - - $this->definitions = $this->getModuleDefinitions(); - } - protected function getConfigData(): ConfigDataInterface|Stub { $configData = parent::getConfigData(); diff --git a/tests/SP/Modules/Web/Controllers/ConfigEncryption/RefreshControllerTest.php b/tests/SP/Modules/Web/Controllers/ConfigEncryption/RefreshControllerTest.php new file mode 100644 index 00000000..b9563d5a --- /dev/null +++ b/tests/SP/Modules/Web/Controllers/ConfigEncryption/RefreshControllerTest.php @@ -0,0 +1,61 @@ +. + */ + +declare(strict_types=1); + +namespace SP\Tests\Modules\Web\Controllers\ConfigEncryption; + +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\MockObject\Exception; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; +use SP\Tests\InjectVault; +use SP\Tests\IntegrationTestCase; + +/** + * Class RefreshControllerTest + */ +#[Group('integration')] +#[InjectVault] +class RefreshControllerTest extends IntegrationTestCase +{ + + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws Exception + */ + #[Test] + public function refresh() + { + $container = $this->buildContainer( + $this->buildRequest('get', 'index.php', ['r' => 'configEncryption/refresh']) + ); + + $this->runApp($container); + + $this->expectOutputString('{"status":"OK","description":"Master password hash updated","data":null}'); + } +}