From 3f8f52d7cd700ac8bcd4ac6260b63d1da4f496c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20D?= Date: Sun, 4 Aug 2024 20:00:03 +0200 Subject: [PATCH] test(IT): Test account index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rubén D --- .../Controllers/Account/IndexController.php | 17 ++--- .../Account/RequestAccessController.php | 22 +++--- .../Helpers/Account/AccountActionsHelper.php | 7 +- .../Helpers/Account/AccountHelper.php | 2 +- .../Helpers/Account/AccountRequestHelper.php | 32 +++----- .../Helpers/Account/AccountSearchHelper.php | 60 +++++++-------- .../DataGrid/Action/DataGridActionBase.php | 7 +- .../Action/DataGridActionInterface.php | 1 + .../DataGrid/Action/DataGridActionSearch.php | 2 +- lib/SP/Infrastructure/File/FileCache.php | 1 + lib/SP/Infrastructure/File/FileHandler.php | 7 +- .../Account/IndexControllerTest.php | 76 +++++++++++++++++++ 12 files changed, 143 insertions(+), 91 deletions(-) create mode 100644 tests/SP/Modules/Web/Controllers/Account/IndexControllerTest.php diff --git a/app/modules/web/Controllers/Account/IndexController.php b/app/modules/web/Controllers/Account/IndexController.php index 015194bb..71382a2c 100644 --- a/app/modules/web/Controllers/Account/IndexController.php +++ b/app/modules/web/Controllers/Account/IndexController.php @@ -24,7 +24,6 @@ namespace SP\Modules\Web\Controllers\Account; - use Exception; use SP\Core\Application; use SP\Core\Events\Event; @@ -32,24 +31,20 @@ use SP\Modules\Web\Controllers\Helpers\Account\AccountSearchHelper; use SP\Modules\Web\Util\ErrorUtil; use SP\Mvc\Controller\WebControllerHelper; +use function SP\processException; + /** * Class IndexController */ final class IndexController extends AccountControllerBase { - private AccountSearchHelper $accountSearchHelper; public function __construct( - Application $application, - WebControllerHelper $webControllerHelper, - AccountSearchHelper $accountSearchHelper + Application $application, + WebControllerHelper $webControllerHelper, + private readonly AccountSearchHelper $accountSearchHelper ) { - parent::__construct( - $application, - $webControllerHelper - ); - - $this->accountSearchHelper = $accountSearchHelper; + parent::__construct($application, $webControllerHelper); } /** diff --git a/app/modules/web/Controllers/Account/RequestAccessController.php b/app/modules/web/Controllers/Account/RequestAccessController.php index 04b6482b..5c78365a 100644 --- a/app/modules/web/Controllers/Account/RequestAccessController.php +++ b/app/modules/web/Controllers/Account/RequestAccessController.php @@ -27,6 +27,7 @@ namespace SP\Modules\Web\Controllers\Account; use Exception; use SP\Core\Application; use SP\Core\Events\Event; +use SP\Domain\Account\Dtos\AccountEnrichedDto; use SP\Domain\Account\Ports\AccountService; use SP\Domain\Core\Acl\AclActionsInterface; use SP\Modules\Web\Controllers\ControllerBase; @@ -34,39 +35,36 @@ use SP\Modules\Web\Controllers\Helpers\Account\AccountRequestHelper; use SP\Modules\Web\Util\ErrorUtil; use SP\Mvc\Controller\WebControllerHelper; +use function SP\processException; + /** * Class RequestAccessController */ final class RequestAccessController extends ControllerBase { - private AccountRequestHelper $accountRequestHelper; - private AccountService $accountService; public function __construct( - Application $application, - WebControllerHelper $webControllerHelper, - AccountService $accountService, - AccountRequestHelper $accountRequestHelper + Application $application, + WebControllerHelper $webControllerHelper, + private readonly AccountService $accountService, + private readonly AccountRequestHelper $accountRequestHelper ) { parent::__construct($application, $webControllerHelper); - - $this->accountRequestHelper = $accountRequestHelper; - $this->accountService = $accountService; } /** * Obtener los datos para mostrar el interface de solicitud de cambios en una cuenta * - * @param int $id Account's ID + * @param int $id Account's ID * */ public function requestAccessAction(int $id): void { try { + $this->accountRequestHelper->initializeFor(AclActionsInterface::ACCOUNT_REQUEST); $this->accountRequestHelper->setIsView(true); $this->accountRequestHelper->setViewForRequest( - $this->accountService->getByIdEnriched($id), - AclActionsInterface::ACCOUNT_REQUEST + new AccountEnrichedDto($this->accountService->getByIdEnriched($id)) ); $this->view->addTemplate('account-request'); diff --git a/app/modules/web/Controllers/Helpers/Account/AccountActionsHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountActionsHelper.php index cbd23e11..01aee849 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountActionsHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountActionsHelper.php @@ -24,7 +24,6 @@ namespace SP\Modules\Web\Controllers\Helpers\Account; -use SP\Core\Acl\Acl; use SP\Core\Application; use SP\Domain\Account\Adapters\AccountPermission; use SP\Domain\Account\Adapters\AccountSearchItem; @@ -67,8 +66,8 @@ final class AccountActionsHelper extends HelperBase $action->addClass('btn-action'); $action->setIcon($this->icons->view()); $action->setRuntimeFilter(AccountSearchItem::class, 'isShowView'); - $action->addData('action-route', Acl::getActionRoute(AclActionsInterface::ACCOUNT_VIEW)); - $action->addData('onclick', Acl::getActionRoute(AclActionsInterface::ACCOUNT_VIEW)); + $action->addData('action-route', $this->acl->getRouteFor(AclActionsInterface::ACCOUNT_VIEW)); + $action->addData('onclick', $this->acl->getRouteFor(AclActionsInterface::ACCOUNT_VIEW)); $action->addAttribute('type', 'button'); return $action; @@ -137,7 +136,7 @@ final class AccountActionsHelper extends HelperBase public function getBackAction(): DataGridAction { $action = new DataGridAction(); - $action->setId('btnBack'); + $action->setId(0); $action->setName(__('Back')); $action->setTitle(__('Back')); $action->addClass('btn-action'); diff --git a/app/modules/web/Controllers/Helpers/Account/AccountHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountHelper.php index 05cd3da9..1f40b02b 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountHelper.php @@ -118,7 +118,7 @@ final class AccountHelper extends AccountHelperBase public function setViewForAccount(AccountEnrichedDto $accountDetailsResponse): void { if (!$this->actionGranted) { - throw UnauthorizedActionException::error('This view requires initialization'); + throw new UnauthorizedActionException(); } $this->accountId = $accountDetailsResponse->getAccountView()->getId(); diff --git a/app/modules/web/Controllers/Helpers/Account/AccountRequestHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountRequestHelper.php index f820207c..3c13b2e0 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountRequestHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountRequestHelper.php @@ -24,13 +24,9 @@ namespace SP\Modules\Web\Controllers\Helpers\Account; - use SP\Domain\Account\Adapters\AccountPermission; use SP\Domain\Account\Dtos\AccountEnrichedDto; -use SP\Domain\Common\Services\ServiceException; -use SP\Domain\Core\Acl\UnauthorizedPageException; -use SP\Domain\User\Services\UpdatedMasterPassException; -use SP\Infrastructure\Common\Repositories\NoSuchItemException; +use SP\Domain\Core\Acl\UnauthorizedActionException; /** * Class AccountRequestHelper @@ -41,23 +37,17 @@ final class AccountRequestHelper extends AccountHelperBase * Sets account's view variables * * @param AccountEnrichedDto $accountDetailsResponse - * @param int $actionId - * * @return bool - * @throws UnauthorizedPageException - * @throws NoSuchItemException - * @throws ServiceException - * @throws UpdatedMasterPassException + * @throws UnauthorizedActionException */ - public function setViewForRequest( - AccountEnrichedDto $accountDetailsResponse, - int $actionId - ): bool { - $this->accountId = $accountDetailsResponse->getAccountView()->getId(); - $this->actionId = $actionId; - $this->accountAcl = new AccountPermission($actionId); + public function setViewForRequest(AccountEnrichedDto $accountDetailsResponse,): bool + { + if (!$this->actionGranted) { + throw new UnauthorizedActionException(); + } - $this->initializeFor(); + $accountId = $accountDetailsResponse->getAccountView()->getId(); + $accountPermission = new AccountPermission($this->actionId); $accountData = $accountDetailsResponse->getAccountView(); @@ -66,9 +56,9 @@ final class AccountRequestHelper extends AccountHelperBase $this->view->assign( 'accountActions', $this->accountActionsHelper->getActionsForAccount( - $this->accountAcl, + $accountPermission, new AccountActionsDto( - $this->accountId, + $accountId, null, $accountData->getParentId() ) diff --git a/app/modules/web/Controllers/Helpers/Account/AccountSearchHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountSearchHelper.php index aebd3db6..886f3bda 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountSearchHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountSearchHelper.php @@ -26,7 +26,6 @@ namespace SP\Modules\Web\Controllers\Helpers\Account; use DI\DependencyException; use DI\NotFoundException; -use SP\Core\Acl\Acl; use SP\Core\Application; use SP\Domain\Account\Adapters\AccountSearchItem; use SP\Domain\Account\Dtos\AccountSearchFilterDto; @@ -35,9 +34,11 @@ use SP\Domain\Account\Ports\AccountSearchService; use SP\Domain\Category\Ports\CategoryService; use SP\Domain\Client\Ports\ClientService; use SP\Domain\Core\Acl\AclActionsInterface; +use SP\Domain\Core\Acl\AclInterface; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; use SP\Domain\Core\Exceptions\SPException; +use SP\Domain\Core\UI\ThemeInterface; use SP\Domain\Http\Ports\RequestService; use SP\Domain\Tag\Ports\TagService; use SP\Domain\User\Models\ProfileData; @@ -53,6 +54,7 @@ use SP\Modules\Web\Controllers\Helpers\HelperBase; use SP\Mvc\View\Components\SelectItemAdapter; use SP\Mvc\View\TemplateInterface; +use function SP\__; use function SP\getElapsedTime; /** @@ -65,38 +67,30 @@ final class AccountSearchHelper extends HelperBase /** * @var bool Indica si el filtrado de cuentas está activo */ - private bool $filterOn = false; - private bool $isAjax = false; - private int $queryTimeStart; + private bool $filterOn = false; + private bool $isAjax = false; + private int $queryTimeStart; private bool $isIndex; private ?AccountSearchFilterDto $accountSearchFilter = null; - private ClientService $clientService; - private AccountSearchService $accountSearchService; - private AccountActionsHelper $accountActionsHelper; - private CategoryService $categoryService; - private TagService $tagService; public function __construct( - Application $application, - TemplateInterface $template, - RequestService $request, - ClientService $clientService, - CategoryService $categoryService, - TagService $tagService, - AccountSearchService $accountSearchService, - AccountActionsHelper $accountActionsHelper, - private readonly AccountSearchData $accountSearchData + Application $application, + TemplateInterface $template, + RequestService $request, + private readonly ClientService $clientService, + private readonly CategoryService $categoryService, + private readonly TagService $tagService, + private readonly AccountSearchService $accountSearchService, + private readonly AccountActionsHelper $accountActionsHelper, + private readonly AccountSearchData $accountSearchData, + private readonly AclInterface $acl, + private readonly ThemeInterface $theme ) { parent::__construct($application, $template, $request); - $this->clientService = $clientService; - $this->categoryService = $categoryService; - $this->tagService = $tagService; - $this->accountSearchService = $accountSearchService; - $this->accountActionsHelper = $accountActionsHelper; - $this->queryTimeStart = microtime(true); - $this->isIndex = $this->request->analyzeString('r') === Acl::getActionRoute(AclActionsInterface::ACCOUNT); + $this->isIndex = $this->request->analyzeString('r') === + $this->acl->getRouteFor(AclActionsInterface::ACCOUNT); $this->setVars(); } @@ -124,10 +118,10 @@ final class AccountSearchHelper extends HelperBase $this->view->assign('searchTxt', $this->accountSearchFilter->getTxtSearch()); $this->view->assign('searchGlobal', $this->accountSearchFilter->getGlobalSearch()); $this->view->assign('searchFavorites', $this->accountSearchFilter->isSearchFavorites()); - $this->view->assign('searchRoute', Acl::getActionRoute(AclActionsInterface::ACCOUNT_SEARCH)); - $this->view->assign('favoriteRouteOn', Acl::getActionRoute(AclActionsInterface::ACCOUNT_FAVORITE_ADD)); - $this->view->assign('favoriteRouteOff', Acl::getActionRoute(AclActionsInterface::ACCOUNT_FAVORITE_DELETE)); - $this->view->assign('viewAccountRoute', Acl::getActionRoute(AclActionsInterface::ACCOUNT_VIEW)); + $this->view->assign('searchRoute', $this->acl->getRouteFor(AclActionsInterface::ACCOUNT_SEARCH)); + $this->view->assign('favoriteRouteOn', $this->acl->getRouteFor(AclActionsInterface::ACCOUNT_FAVORITE_ADD)); + $this->view->assign('favoriteRouteOff', $this->acl->getRouteFor(AclActionsInterface::ACCOUNT_FAVORITE_DELETE)); + $this->view->assign('viewAccountRoute', $this->acl->getRouteFor(AclActionsInterface::ACCOUNT_VIEW)); } /** @@ -264,12 +258,10 @@ final class AccountSearchHelper extends HelperBase * Devuelve la matriz a utilizar en la vista * * @return DataGrid - * @throws DependencyException - * @throws NotFoundException */ private function getGrid(): DataGrid { - $icons = $this->view->getTheme()->getIcons(); + $icons = $this->theme->getIcons(); $gridActionOptional = new DataGridAction(); $gridActionOptional->setId(0); @@ -301,7 +293,7 @@ final class AccountSearchHelper extends HelperBase || ($userPreferences->getUserId() === 0 && $this->configData->isResultsAsCards()); - $dataGrid = new DataGrid($this->view->getTheme()); + $dataGrid = new DataGrid($this->theme); $dataGrid->setId('gridSearch'); $dataGrid->setDataHeaderTemplate('account/search-header'); $dataGrid->setDataRowTemplate( @@ -342,7 +334,7 @@ final class AccountSearchHelper extends HelperBase */ private function getHeaderSort(): DataGridHeaderSort { - $icons = $this->view->getTheme()->getIcons(); + $icons = $this->theme->getIcons(); $gridSortCustomer = new DataGridSort(); $gridSortCustomer->setName(__('Client')) diff --git a/lib/SP/Html/DataGrid/Action/DataGridActionBase.php b/lib/SP/Html/DataGrid/Action/DataGridActionBase.php index 62f9b7fa..377f6e12 100644 --- a/lib/SP/Html/DataGrid/Action/DataGridActionBase.php +++ b/lib/SP/Html/DataGrid/Action/DataGridActionBase.php @@ -51,10 +51,6 @@ abstract class DataGridActionBase implements DataGridActionInterface * Action's title */ protected ?string $title = null; - /** - * Action's title ID - */ - protected ?string $id = null; /** * The JavaScript function to be triggered on OnClick event */ @@ -103,9 +99,8 @@ abstract class DataGridActionBase implements DataGridActionInterface /** * DataGridActionBase constructor. */ - public function __construct(?int $id = null) + public function __construct(protected ?string $id = null) { - $this->id = $id; } /** diff --git a/lib/SP/Html/DataGrid/Action/DataGridActionInterface.php b/lib/SP/Html/DataGrid/Action/DataGridActionInterface.php index 541f47f5..a2645209 100644 --- a/lib/SP/Html/DataGrid/Action/DataGridActionInterface.php +++ b/lib/SP/Html/DataGrid/Action/DataGridActionInterface.php @@ -1,4 +1,5 @@ autoDetectEOL(); - $data = $this->fread($this->getSize()); + try { + $data = $this->fread($this->getSize()); + } catch (ValueError $e) { + throw FileException::error(sprintf(__('Unable to read from file (%s)'), $this->file, $e->getCode(), $e)); + } if ($data === false) { throw FileException::error(sprintf(__('Unable to read from file (%s)'), $this->file)); diff --git a/tests/SP/Modules/Web/Controllers/Account/IndexControllerTest.php b/tests/SP/Modules/Web/Controllers/Account/IndexControllerTest.php new file mode 100644 index 00000000..8106c011 --- /dev/null +++ b/tests/SP/Modules/Web/Controllers/Account/IndexControllerTest.php @@ -0,0 +1,76 @@ +. + */ + +declare(strict_types=1); + +namespace SP\Tests\Modules\Web\Controllers\Account; + +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\Mvc\View\OutputHandlerInterface; +use SP\Tests\IntegrationTestCase; +use Symfony\Component\DomCrawler\Crawler; + +/** + * Class IndexControllerTest + */ +#[Group('integration')] +class IndexControllerTest extends IntegrationTestCase +{ + + /** + * @throws NotFoundExceptionInterface + * @throws Exception + * @throws InvalidClassException + * @throws FileException + * @throws ContainerExceptionInterface + */ + public function testIndexAction() + { + $definitions = $this->getModuleDefinitions(); + + $definitions[OutputHandlerInterface::class] = $this->setupOutputHandler(function (string $output): void { + $crawler = new Crawler($output); + $filter = $crawler->filterXPath( + '//div[@id="searchbox"]/form[@name="frmSearch"]|//div[@id="res-content"]' + )->extract(['id']); + + assert(!empty($output)); + assert(count($filter) === 2); + + $this->assertTrue(true); + }); + + $container = $this->buildContainer( + $definitions, + $this->buildRequest('get', 'index.php', ['r' => 'account']) + ); + + $this->runApp($container); + } +}