From 74263ef95d4128b9d508eabecfce51ed742c7080 Mon Sep 17 00:00:00 2001 From: cezarystepkowski Date: Tue, 25 Aug 2026 16:49:04 +0200 Subject: [PATCH 01/10] Add support for pretty urls --- .../Controller/AdminControllerWebTestCase.php | 39 ++++++++++++++++++- src/Test/Controller/DeleteActionTestCase.php | 15 ++++++- src/Test/Controller/DetailActionTestCase.php | 17 +++++++- src/Test/Controller/EditActionTestCase.php | 19 +++++++-- 4 files changed, 83 insertions(+), 7 deletions(-) diff --git a/src/Test/Controller/AdminControllerWebTestCase.php b/src/Test/Controller/AdminControllerWebTestCase.php index 32a6a19..72591bc 100644 --- a/src/Test/Controller/AdminControllerWebTestCase.php +++ b/src/Test/Controller/AdminControllerWebTestCase.php @@ -7,6 +7,8 @@ use DOMElement; use EasyCorp\Bundle\EasyAdminBundle\Config\Option\EA; use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; +use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\DashboardControllerInterface; +use EasyCorp\Bundle\EasyAdminBundle\Router\AdminRouteGenerator; use Psl\Dict; use Psl\Iter; use Psl\Str; @@ -17,6 +19,7 @@ use Symfony\Component\DomCrawler\Form; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use function array_merge; use function http_build_query; @@ -35,6 +38,11 @@ abstract protected function controllerUnderTest(): string; abstract protected function actionName(): string; + protected static function usePrettyUrls(): bool + { + return false; + } + protected static function easyAdminRoutePath(): string { return '/admin'; @@ -65,7 +73,36 @@ protected function assertRequestGet( */ protected function prepareAdminUrl(array $queryParameters, string|null $fragment = null): string { - return static::easyAdminRoutePath() . '?' . $this->prepareAdminUrlQueryParameters($queryParameters) . ($fragment ?? ''); + if (! static::usePrettyUrls()) { + return static::easyAdminRoutePath() . '?' . $this->prepareAdminUrlQueryParameters($queryParameters) . ($fragment ?? ''); + } + + $route = $this->getContainerService(AdminRouteGenerator::class)->findRouteName( + dashboardFqcn: static::dashboardFqcn(), + crudControllerFqcn: $this->controllerUnderTest(), + actionName: $this->actionName(), + ); + + $path = $this->getContainerService(UrlGeneratorInterface::class)->generate( + Type\non_empty_string()->assert($route), + $this->prepareAdminUrlRouteParameters(), + ); + + return $path . '?' . $this->prepareAdminUrlQueryParameters($queryParameters) . ($fragment ?? ''); + } + + /** + * @return array $routeParameters + */ + protected function prepareAdminUrlRouteParameters(): array + { + return []; + } + + /** @return class-string|null */ + protected static function dashboardFqcn(): string|null + { + return null; } /** diff --git a/src/Test/Controller/DeleteActionTestCase.php b/src/Test/Controller/DeleteActionTestCase.php index a95487a..ec3d0d1 100644 --- a/src/Test/Controller/DeleteActionTestCase.php +++ b/src/Test/Controller/DeleteActionTestCase.php @@ -87,7 +87,7 @@ protected function assertRemovingEntityFromDetailPageAndRedirectingToIndexAction */ protected function assertDeleteEntityRespondsWithStatusCodeForbidden(array $queryParameters = []): void { - if (! array_key_exists(EA::ENTITY_ID, $queryParameters)) { + if (! static::usePrettyUrls() && ! array_key_exists(EA::ENTITY_ID, $queryParameters)) { $queryParameters[EA::ENTITY_ID] = $this->entityIdUnderTest(); } @@ -129,6 +129,19 @@ protected function entityIdUnderTest(): string|int return static::$expectedEntityIdUnderTest; } + /** + * @return array $routeParameters + */ + #[Override] + protected function prepareAdminUrlRouteParameters(): array + { + $routeParameters = parent::prepareAdminUrlRouteParameters(); + + $routeParameters[EA::ENTITY_ID] ??= $this->entityIdUnderTest(); + + return $routeParameters; + } + /** * @return TEntity|null */ diff --git a/src/Test/Controller/DetailActionTestCase.php b/src/Test/Controller/DetailActionTestCase.php index fe05443..c585a6a 100644 --- a/src/Test/Controller/DetailActionTestCase.php +++ b/src/Test/Controller/DetailActionTestCase.php @@ -48,12 +48,25 @@ protected function entityIdUnderTest(): string|int return static::$expectedEntityIdUnderTest; } + /** + * @return array $routeParameters + */ + #[Override] + protected function prepareAdminUrlRouteParameters(): array + { + $routeParameters = parent::prepareAdminUrlRouteParameters(); + + $routeParameters[EA::ENTITY_ID] ??= $this->entityIdUnderTest(); + + return $routeParameters; + } + /** * @param array $queryParameters */ public function assertRespondsWithStatusCodeForbidden(array $queryParameters = []): void { - if (! array_key_exists(EA::ENTITY_ID, $queryParameters)) { + if (! static::usePrettyUrls() && ! array_key_exists(EA::ENTITY_ID, $queryParameters)) { $queryParameters[EA::ENTITY_ID] = $this->entityIdUnderTest(); } @@ -65,7 +78,7 @@ public function assertRespondsWithStatusCodeForbidden(array $queryParameters = [ */ protected function assertPage(array $queryParameters = []): void { - if (! array_key_exists(EA::ENTITY_ID, $queryParameters)) { + if (! static::usePrettyUrls() && ! array_key_exists(EA::ENTITY_ID, $queryParameters)) { $queryParameters[EA::ENTITY_ID] = $this->entityIdUnderTest(); } diff --git a/src/Test/Controller/EditActionTestCase.php b/src/Test/Controller/EditActionTestCase.php index a89abc5..2bd0165 100644 --- a/src/Test/Controller/EditActionTestCase.php +++ b/src/Test/Controller/EditActionTestCase.php @@ -53,12 +53,25 @@ protected function entityIdUnderTest(): string|int return static::$expectedEntityIdUnderTest; } + /** + * @return array $routeParameters + */ + #[Override] + protected function prepareAdminUrlRouteParameters(): array + { + $routeParameters = parent::prepareAdminUrlRouteParameters(); + + $routeParameters[EA::ENTITY_ID] ??= $this->entityIdUnderTest(); + + return $routeParameters; + } + /** * @param array $queryParameters */ public function assertShowingEntityToEditRespondsWithStatusCodeForbidden(array $queryParameters = []): void { - if (! array_key_exists(EA::ENTITY_ID, $queryParameters)) { + if (! static::usePrettyUrls() && ! array_key_exists(EA::ENTITY_ID, $queryParameters)) { $queryParameters[EA::ENTITY_ID] = $this->entityIdUnderTest(); } @@ -70,7 +83,7 @@ public function assertShowingEntityToEditRespondsWithStatusCodeForbidden(array $ */ protected function assertShowingEntityToEdit(array $queryParameters = []): void { - if (! array_key_exists(EA::ENTITY_ID, $queryParameters)) { + if (! static::usePrettyUrls() && ! array_key_exists(EA::ENTITY_ID, $queryParameters)) { $queryParameters[EA::ENTITY_ID] = $this->entityIdUnderTest(); } @@ -180,7 +193,7 @@ protected function submitFormRequest( array $queryParameters = [], string $submitButton = Action::SAVE_AND_RETURN, ): Crawler { - if (! array_key_exists(EA::ENTITY_ID, $queryParameters)) { + if (! static::usePrettyUrls() && ! array_key_exists(EA::ENTITY_ID, $queryParameters)) { $queryParameters[EA::ENTITY_ID] = $this->entityIdUnderTest(); } From da69b40256053bc5380c63d73df51bd95952f511 Mon Sep 17 00:00:00 2001 From: cezarystepkowski Date: Thu, 27 Aug 2026 11:05:51 +0200 Subject: [PATCH 02/10] More --- .../Controller/AdminControllerWebTestCase.php | 91 ++++++++++++++++--- .../Controller/AutocompleteActionTestCase.php | 2 +- src/Test/Controller/CustomActionTestCase.php | 3 +- src/Test/Controller/DetailActionTestCase.php | 3 +- src/Test/Controller/EditActionTestCase.php | 28 +++++- src/Test/Controller/IndexActionTestCase.php | 3 +- src/Test/Controller/NewActionTestCase.php | 32 +++++-- 7 files changed, 135 insertions(+), 27 deletions(-) diff --git a/src/Test/Controller/AdminControllerWebTestCase.php b/src/Test/Controller/AdminControllerWebTestCase.php index 72591bc..1896d41 100644 --- a/src/Test/Controller/AdminControllerWebTestCase.php +++ b/src/Test/Controller/AdminControllerWebTestCase.php @@ -7,6 +7,7 @@ use DOMElement; use EasyCorp\Bundle\EasyAdminBundle\Config\Option\EA; use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; +use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface; use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\DashboardControllerInterface; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminRouteGenerator; use Psl\Dict; @@ -27,7 +28,7 @@ use function iterator_to_array; /** - * @template TCrudController + * @template TCrudController of CrudControllerInterface */ abstract class AdminControllerWebTestCase extends AdminWebTestCase { @@ -36,6 +37,9 @@ abstract class AdminControllerWebTestCase extends AdminWebTestCase */ abstract protected function controllerUnderTest(): string; + /** + * @return non-empty-string + */ abstract protected function actionName(): string; protected static function usePrettyUrls(): bool @@ -68,27 +72,65 @@ protected function assertRequestGet( return $crawler; } + /** + * @param class-string|null $dashboardFqcn + * @param class-string $crudControllerFqcn + * @param non-empty-string $actionName + * @param array $routeParameters + * @param array $queryParameters + */ + protected function generateAdminPrettyUrl( + string|null $dashboardFqcn, + string $crudControllerFqcn, + string $actionName, + array $routeParameters = [], + array $queryParameters = [], + string|null $fragment = null, + ): string { + $route = $this->getContainerService(AdminRouteGenerator::class)->findRouteName( + dashboardFqcn: $dashboardFqcn, + crudControllerFqcn: $crudControllerFqcn, + actionName: $actionName, + ); + + $path = $this->getContainerService(UrlGeneratorInterface::class)->generate( + Type\non_empty_string()->assert($route), + $routeParameters, + ); + + $queryAndFragment = $this->prepareAdminUrlQueryParameters($queryParameters) . ($fragment ?? ''); + if ($queryAndFragment !== '') { + return $path . '?' . $queryAndFragment; + } + + return $path; + } + /** * @param array $queryParameters */ protected function prepareAdminUrl(array $queryParameters, string|null $fragment = null): string { if (! static::usePrettyUrls()) { - return static::easyAdminRoutePath() . '?' . $this->prepareAdminUrlQueryParameters($queryParameters) . ($fragment ?? ''); + return $this->prepareLegacyAdminUrl($queryParameters, $fragment); } - $route = $this->getContainerService(AdminRouteGenerator::class)->findRouteName( + return $this->generateAdminPrettyUrl( dashboardFqcn: static::dashboardFqcn(), crudControllerFqcn: $this->controllerUnderTest(), actionName: $this->actionName(), + routeParameters: $this->prepareAdminUrlRouteParameters(), + queryParameters: $queryParameters, + fragment: $fragment, ); + } - $path = $this->getContainerService(UrlGeneratorInterface::class)->generate( - Type\non_empty_string()->assert($route), - $this->prepareAdminUrlRouteParameters(), - ); - - return $path . '?' . $this->prepareAdminUrlQueryParameters($queryParameters) . ($fragment ?? ''); + /** + * @param array $queryParameters + */ + protected function prepareLegacyAdminUrl(array $queryParameters, string|null $fragment = null): string + { + return static::easyAdminRoutePath() . '?' . $this->prepareAdminUrlQueryParameters($queryParameters) . ($fragment ?? ''); } /** @@ -110,8 +152,10 @@ protected static function dashboardFqcn(): string|null */ protected function prepareAdminUrlQueryParameters(array $queryParameters): string { - $queryParameters[EA::CRUD_CONTROLLER_FQCN] ??= $this->controllerUnderTest(); - $queryParameters[EA::CRUD_ACTION] ??= $this->actionName(); + if (! static::usePrettyUrls()) { + $queryParameters[EA::CRUD_CONTROLLER_FQCN] ??= $this->controllerUnderTest(); + $queryParameters[EA::CRUD_ACTION] ??= $this->actionName(); + } // we need to prepare the URL having some query parameters in a specific order $queryParameters = Dict\sort_by_key($queryParameters); @@ -249,6 +293,31 @@ protected function assertResponseIsRedirect(array $redirectQueryParameters, stri self::assertResponseRedirectsToUrl($this->getClient()->getResponse(), $expectedRedirectUrl); } + /** + * @param class-string $crudControllerFqcn + * @param non-empty-string $actionName + * @param array $redirectRouteParameters + * @param array $redirectQueryParameters + */ + protected function assertResponseIsRedirectWithPrettyUrl( + string $crudControllerFqcn, + string $actionName, + array $redirectRouteParameters = [], + array $redirectQueryParameters = [], + string|null $fragment = null, + ): void { + $expectedRedirectUrl = 'http://' . static::serverHost() . $this->generateAdminPrettyUrl( + static::dashboardFqcn(), + $crudControllerFqcn, + $actionName, + $redirectRouteParameters, + $redirectQueryParameters, + $fragment, + ); + + self::assertResponseRedirectsToUrl($this->getClient()->getResponse(), $expectedRedirectUrl); + } + protected function getAdminContextFromLastRequest(): AdminContext { $context = $this->getClient()->getRequest()->attributes->get(EA::CONTEXT_REQUEST_ATTRIBUTE); diff --git a/src/Test/Controller/AutocompleteActionTestCase.php b/src/Test/Controller/AutocompleteActionTestCase.php index 3d71bf9..956f664 100644 --- a/src/Test/Controller/AutocompleteActionTestCase.php +++ b/src/Test/Controller/AutocompleteActionTestCase.php @@ -13,7 +13,7 @@ use function array_merge; /** - * @template TController + * @template TController of CrudControllerInterface * @template-extends CustomActionTestCase */ abstract class AutocompleteActionTestCase extends CustomActionTestCase diff --git a/src/Test/Controller/CustomActionTestCase.php b/src/Test/Controller/CustomActionTestCase.php index cb18da5..a21fd38 100644 --- a/src/Test/Controller/CustomActionTestCase.php +++ b/src/Test/Controller/CustomActionTestCase.php @@ -6,6 +6,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Option\EA; +use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface; use Override; use Psl\Type; use Symfony\Component\DomCrawler\Crawler; @@ -15,7 +16,7 @@ use Symfony\Component\HttpFoundation\Response; /** - * @template TCrudController + * @template TCrudController of CrudControllerInterface * @template-extends AdminControllerWebTestCase */ abstract class CustomActionTestCase extends AdminControllerWebTestCase diff --git a/src/Test/Controller/DetailActionTestCase.php b/src/Test/Controller/DetailActionTestCase.php index c585a6a..686428b 100644 --- a/src/Test/Controller/DetailActionTestCase.php +++ b/src/Test/Controller/DetailActionTestCase.php @@ -6,6 +6,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Option\EA; +use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface; use LogicException; use Override; use Psl\Str; @@ -17,7 +18,7 @@ use function array_key_exists; /** - * @template TCrudController + * @template TCrudController of CrudControllerInterface * @template-extends AdminControllerWebTestCase */ abstract class DetailActionTestCase extends AdminControllerWebTestCase diff --git a/src/Test/Controller/EditActionTestCase.php b/src/Test/Controller/EditActionTestCase.php index 2bd0165..a75f911 100644 --- a/src/Test/Controller/EditActionTestCase.php +++ b/src/Test/Controller/EditActionTestCase.php @@ -112,9 +112,18 @@ protected function assertSavingEntityAndRedirectingToIndexAction( ): void { $this->submitFormRequest($data, $files, $queryParameters); - $redirectQueryParameters[EA::CRUD_ACTION] = Action::INDEX; + if (static::usePrettyUrls()) { + $this->assertResponseIsRedirectWithPrettyUrl( + $this->controllerUnderTest(), + Action::INDEX, + [], + $redirectQueryParameters, + ); + } else { + $redirectQueryParameters[EA::CRUD_ACTION] = Action::INDEX; - $this->assertResponseIsRedirect($redirectQueryParameters); + $this->assertResponseIsRedirect($redirectQueryParameters); + } } /** @@ -131,10 +140,19 @@ protected function assertSavingEntityAndRedirectingToDetailAction( ): void { $this->submitFormRequest($data, $files, $queryParameters); - $redirectQueryParameters[EA::CRUD_ACTION] = Action::DETAIL; - $redirectQueryParameters[EA::ENTITY_ID] = $this->entityIdUnderTest(); + if (static::usePrettyUrls()) { + $this->assertResponseIsRedirectWithPrettyUrl( + $this->controllerUnderTest(), + Action::DETAIL, + [EA::ENTITY_ID => $this->entityIdUnderTest()], + $redirectQueryParameters, + ); + } else { + $redirectQueryParameters[EA::CRUD_ACTION] = Action::DETAIL; + $redirectQueryParameters[EA::ENTITY_ID] = $this->entityIdUnderTest(); - $this->assertResponseIsRedirect($redirectQueryParameters); + $this->assertResponseIsRedirect($redirectQueryParameters); + } } /** diff --git a/src/Test/Controller/IndexActionTestCase.php b/src/Test/Controller/IndexActionTestCase.php index b7c65eb..b25e8e2 100644 --- a/src/Test/Controller/IndexActionTestCase.php +++ b/src/Test/Controller/IndexActionTestCase.php @@ -6,6 +6,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Option\EA; +use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface; use Override; use Psl\Dict; use Psl\Type; @@ -13,7 +14,7 @@ use Symfony\Component\DomCrawler\Crawler; /** - * @template TCrudController + * @template TCrudController of CrudControllerInterface * @template-extends AdminControllerWebTestCase */ abstract class IndexActionTestCase extends AdminControllerWebTestCase diff --git a/src/Test/Controller/NewActionTestCase.php b/src/Test/Controller/NewActionTestCase.php index 9e4e186..44e7afe 100644 --- a/src/Test/Controller/NewActionTestCase.php +++ b/src/Test/Controller/NewActionTestCase.php @@ -60,9 +60,18 @@ protected function assertSavingEntityAndRedirectingToIndexAction( ): void { $this->submitFormRequest($data, $files, $queryParameters); - $redirectQueryParameters[EA::CRUD_ACTION] = Action::INDEX; - - $this->assertResponseIsRedirect($redirectQueryParameters); + if (static::usePrettyUrls()) { + $this->assertResponseIsRedirectWithPrettyUrl( + $this->controllerUnderTest(), + Action::INDEX, + [], + $redirectQueryParameters, + ); + } else { + $redirectQueryParameters[EA::CRUD_ACTION] = Action::INDEX; + + $this->assertResponseIsRedirect($redirectQueryParameters); + } } /** @@ -79,10 +88,19 @@ protected function assertSavingEntityAndRedirectingToDetailAction( ): void { $this->submitFormRequest($data, $files, $queryParameters); - $redirectQueryParameters[EA::CRUD_ACTION] = Action::DETAIL; - $redirectQueryParameters[EA::ENTITY_ID] = $this->getAdminContextFromLastRequest()->getEntity()->getPrimaryKeyValueAsString(); - - $this->assertResponseIsRedirect($redirectQueryParameters); + if (static::usePrettyUrls()) { + $this->assertResponseIsRedirectWithPrettyUrl( + $this->controllerUnderTest(), + Action::DETAIL, + [EA::ENTITY_ID => $this->getAdminContextFromLastRequest()->getEntity()->getPrimaryKeyValueAsString()], + $redirectQueryParameters, + ); + } else { + $redirectQueryParameters[EA::CRUD_ACTION] = Action::DETAIL; + $redirectQueryParameters[EA::ENTITY_ID] = $this->getAdminContextFromLastRequest()->getEntity()->getPrimaryKeyValueAsString(); + + $this->assertResponseIsRedirect($redirectQueryParameters); + } } /** From e15c71a46e91902f7e05a091497d2e8fca37136e Mon Sep 17 00:00:00 2001 From: cezarystepkowski Date: Thu, 27 Aug 2026 12:23:07 +0200 Subject: [PATCH 03/10] More --- .../Controller/AdminControllerWebTestCase.php | 44 ++-------------- src/Test/Controller/AdminWebTestCase.php | 51 +++++++++++++++++++ 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/src/Test/Controller/AdminControllerWebTestCase.php b/src/Test/Controller/AdminControllerWebTestCase.php index 1896d41..31f7cb7 100644 --- a/src/Test/Controller/AdminControllerWebTestCase.php +++ b/src/Test/Controller/AdminControllerWebTestCase.php @@ -9,7 +9,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface; use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\DashboardControllerInterface; -use EasyCorp\Bundle\EasyAdminBundle\Router\AdminRouteGenerator; +use Override; use Psl\Dict; use Psl\Iter; use Psl\Str; @@ -20,10 +20,8 @@ use Symfony\Component\DomCrawler\Form; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use function array_merge; -use function http_build_query; use function is_array; use function iterator_to_array; @@ -72,40 +70,6 @@ protected function assertRequestGet( return $crawler; } - /** - * @param class-string|null $dashboardFqcn - * @param class-string $crudControllerFqcn - * @param non-empty-string $actionName - * @param array $routeParameters - * @param array $queryParameters - */ - protected function generateAdminPrettyUrl( - string|null $dashboardFqcn, - string $crudControllerFqcn, - string $actionName, - array $routeParameters = [], - array $queryParameters = [], - string|null $fragment = null, - ): string { - $route = $this->getContainerService(AdminRouteGenerator::class)->findRouteName( - dashboardFqcn: $dashboardFqcn, - crudControllerFqcn: $crudControllerFqcn, - actionName: $actionName, - ); - - $path = $this->getContainerService(UrlGeneratorInterface::class)->generate( - Type\non_empty_string()->assert($route), - $routeParameters, - ); - - $queryAndFragment = $this->prepareAdminUrlQueryParameters($queryParameters) . ($fragment ?? ''); - if ($queryAndFragment !== '') { - return $path . '?' . $queryAndFragment; - } - - return $path; - } - /** * @param array $queryParameters */ @@ -150,6 +114,7 @@ protected static function dashboardFqcn(): string|null /** * @param array $queryParameters */ + #[Override] protected function prepareAdminUrlQueryParameters(array $queryParameters): string { if (! static::usePrettyUrls()) { @@ -157,10 +122,7 @@ protected function prepareAdminUrlQueryParameters(array $queryParameters): strin $queryParameters[EA::CRUD_ACTION] ??= $this->actionName(); } - // we need to prepare the URL having some query parameters in a specific order - $queryParameters = Dict\sort_by_key($queryParameters); - - return http_build_query($queryParameters); + return parent::prepareAdminUrlQueryParameters($queryParameters); } /** diff --git a/src/Test/Controller/AdminWebTestCase.php b/src/Test/Controller/AdminWebTestCase.php index 497ca8f..46a1f58 100644 --- a/src/Test/Controller/AdminWebTestCase.php +++ b/src/Test/Controller/AdminWebTestCase.php @@ -4,7 +4,11 @@ namespace Protung\EasyAdminPlusBundle\Test\Controller; +use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface; +use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\DashboardControllerInterface; +use EasyCorp\Bundle\EasyAdminBundle\Router\AdminRouteGenerator; use Override; +use Psl\Dict; use Psl\Iter; use Psl\Str; use Psl\Type; @@ -15,11 +19,13 @@ use Symfony\Component\DomCrawler\Crawler; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Session\SessionFactoryInterface; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\User\InMemoryUser; use Symfony\Component\Security\Core\User\UserInterface; use function array_merge; +use function http_build_query; use function serialize; abstract class AdminWebTestCase extends WebTestCase @@ -139,6 +145,51 @@ protected static function loginAsAdmin(): UserInterface return $user; } + /** + * @param class-string|null $dashboardFqcn + * @param class-string $crudControllerFqcn + * @param non-empty-string $actionName + * @param array $routeParameters + * @param array $queryParameters + */ + protected function generateAdminPrettyUrl( + string|null $dashboardFqcn, + string $crudControllerFqcn, + string $actionName, + array $routeParameters = [], + array $queryParameters = [], + string|null $fragment = null, + ): string { + $route = $this->getContainerService(AdminRouteGenerator::class)->findRouteName( + dashboardFqcn: $dashboardFqcn, + crudControllerFqcn: $crudControllerFqcn, + actionName: $actionName, + ); + + $path = $this->getContainerService(UrlGeneratorInterface::class)->generate( + Type\non_empty_string()->assert($route), + $routeParameters, + ); + + $queryAndFragment = $this->prepareAdminUrlQueryParameters($queryParameters) . ($fragment ?? ''); + if ($queryAndFragment !== '') { + return $path . '?' . $queryAndFragment; + } + + return $path; + } + + /** + * @param array $queryParameters + */ + protected function prepareAdminUrlQueryParameters(array $queryParameters): string + { + // we need to prepare the URL having some query parameters in a specific order + $queryParameters = Dict\sort_by_key($queryParameters); + + return http_build_query($queryParameters); + } + /** * @param non-empty-string $expectedMessage * @param non-empty-string ...$expectedMessages From 97b305686c7a78a1d1a14928ac5035eb072045f2 Mon Sep 17 00:00:00 2001 From: cezarystepkowski Date: Thu, 27 Aug 2026 13:01:24 +0200 Subject: [PATCH 04/10] More --- src/Test/Controller/AdminControllerWebTestCase.php | 5 ----- src/Test/Controller/AdminWebTestCase.php | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Test/Controller/AdminControllerWebTestCase.php b/src/Test/Controller/AdminControllerWebTestCase.php index 31f7cb7..3815e18 100644 --- a/src/Test/Controller/AdminControllerWebTestCase.php +++ b/src/Test/Controller/AdminControllerWebTestCase.php @@ -40,11 +40,6 @@ abstract protected function controllerUnderTest(): string; */ abstract protected function actionName(): string; - protected static function usePrettyUrls(): bool - { - return false; - } - protected static function easyAdminRoutePath(): string { return '/admin'; diff --git a/src/Test/Controller/AdminWebTestCase.php b/src/Test/Controller/AdminWebTestCase.php index 46a1f58..49e2cde 100644 --- a/src/Test/Controller/AdminWebTestCase.php +++ b/src/Test/Controller/AdminWebTestCase.php @@ -57,6 +57,11 @@ protected static function authenticationFirewallContext(): string return 'easyadmin'; } + protected static function usePrettyUrls(): bool + { + return false; + } + /** @param array $server */ #[Override] protected static function createClient(array $server = []): KernelBrowser From 8bf290174fae84ba6eb987a27b7f079d32b0cd99 Mon Sep 17 00:00:00 2001 From: cezarystepkowski Date: Thu, 27 Aug 2026 13:35:09 +0200 Subject: [PATCH 05/10] More --- .../Controller/AdminControllerWebTestCase.php | 45 +++++++++++-------- src/Test/Controller/EditActionTestCase.php | 4 +- src/Test/Controller/NewActionTestCase.php | 4 +- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/Test/Controller/AdminControllerWebTestCase.php b/src/Test/Controller/AdminControllerWebTestCase.php index 3815e18..91f363d 100644 --- a/src/Test/Controller/AdminControllerWebTestCase.php +++ b/src/Test/Controller/AdminControllerWebTestCase.php @@ -240,37 +240,44 @@ protected function assertPageTitle(string $expectedPageTitle): void self::assertSame($expectedPageTitle, $title->text(normalizeWhitespace: true)); } - /** - * @param array $redirectQueryParameters - */ - protected function assertResponseIsRedirect(array $redirectQueryParameters, string|null $fragment = null): void - { - $expectedRedirectUrl = 'http://' . static::serverHost() . $this->prepareAdminUrl($redirectQueryParameters, $fragment); - - self::assertResponseRedirectsToUrl($this->getClient()->getResponse(), $expectedRedirectUrl); - } - /** * @param class-string $crudControllerFqcn * @param non-empty-string $actionName * @param array $redirectRouteParameters * @param array $redirectQueryParameters */ - protected function assertResponseIsRedirectWithPrettyUrl( + protected function assertResponseRedirectsToCrudController( string $crudControllerFqcn, string $actionName, array $redirectRouteParameters = [], array $redirectQueryParameters = [], string|null $fragment = null, ): void { - $expectedRedirectUrl = 'http://' . static::serverHost() . $this->generateAdminPrettyUrl( - static::dashboardFqcn(), - $crudControllerFqcn, - $actionName, - $redirectRouteParameters, - $redirectQueryParameters, - $fragment, - ); + if (static::usePrettyUrls()) { + $expectedRedirectUrl = 'http://' . static::serverHost() . $this->generateAdminPrettyUrl( + static::dashboardFqcn(), + $crudControllerFqcn, + $actionName, + $redirectRouteParameters, + $redirectQueryParameters, + $fragment, + ); + + self::assertResponseRedirectsToUrl($this->getClient()->getResponse(), $expectedRedirectUrl); + } else { + $redirectQueryParameters[EA::CRUD_CONTROLLER_FQCN] ??= $crudControllerFqcn; + $redirectQueryParameters[EA::CRUD_ACTION] ??= $actionName; + + $this->assertResponseIsRedirect($redirectQueryParameters, $fragment); + } + } + + /** + * @param array $redirectQueryParameters + */ + protected function assertResponseIsRedirect(array $redirectQueryParameters, string|null $fragment = null): void + { + $expectedRedirectUrl = 'http://' . static::serverHost() . $this->prepareAdminUrl($redirectQueryParameters, $fragment); self::assertResponseRedirectsToUrl($this->getClient()->getResponse(), $expectedRedirectUrl); } diff --git a/src/Test/Controller/EditActionTestCase.php b/src/Test/Controller/EditActionTestCase.php index a75f911..f0f1b8a 100644 --- a/src/Test/Controller/EditActionTestCase.php +++ b/src/Test/Controller/EditActionTestCase.php @@ -113,7 +113,7 @@ protected function assertSavingEntityAndRedirectingToIndexAction( $this->submitFormRequest($data, $files, $queryParameters); if (static::usePrettyUrls()) { - $this->assertResponseIsRedirectWithPrettyUrl( + $this->assertResponseRedirectsToCrudController( $this->controllerUnderTest(), Action::INDEX, [], @@ -141,7 +141,7 @@ protected function assertSavingEntityAndRedirectingToDetailAction( $this->submitFormRequest($data, $files, $queryParameters); if (static::usePrettyUrls()) { - $this->assertResponseIsRedirectWithPrettyUrl( + $this->assertResponseRedirectsToCrudController( $this->controllerUnderTest(), Action::DETAIL, [EA::ENTITY_ID => $this->entityIdUnderTest()], diff --git a/src/Test/Controller/NewActionTestCase.php b/src/Test/Controller/NewActionTestCase.php index 44e7afe..6ece14f 100644 --- a/src/Test/Controller/NewActionTestCase.php +++ b/src/Test/Controller/NewActionTestCase.php @@ -61,7 +61,7 @@ protected function assertSavingEntityAndRedirectingToIndexAction( $this->submitFormRequest($data, $files, $queryParameters); if (static::usePrettyUrls()) { - $this->assertResponseIsRedirectWithPrettyUrl( + $this->assertResponseRedirectsToCrudController( $this->controllerUnderTest(), Action::INDEX, [], @@ -89,7 +89,7 @@ protected function assertSavingEntityAndRedirectingToDetailAction( $this->submitFormRequest($data, $files, $queryParameters); if (static::usePrettyUrls()) { - $this->assertResponseIsRedirectWithPrettyUrl( + $this->assertResponseRedirectsToCrudController( $this->controllerUnderTest(), Action::DETAIL, [EA::ENTITY_ID => $this->getAdminContextFromLastRequest()->getEntity()->getPrimaryKeyValueAsString()], From 47cdec9d7cf6290e062e37d024a22ecf177f8e41 Mon Sep 17 00:00:00 2001 From: cezarystepkowski Date: Thu, 27 Aug 2026 13:39:07 +0200 Subject: [PATCH 06/10] More --- src/Test/Controller/DashboardControllerTestCase.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Test/Controller/DashboardControllerTestCase.php b/src/Test/Controller/DashboardControllerTestCase.php index 7d1d256..878430b 100644 --- a/src/Test/Controller/DashboardControllerTestCase.php +++ b/src/Test/Controller/DashboardControllerTestCase.php @@ -4,6 +4,7 @@ namespace Protung\EasyAdminPlusBundle\Test\Controller; +use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\DashboardControllerInterface; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; use Psl\Dict; use Psl\Str; @@ -14,7 +15,7 @@ use function array_key_exists; /** - * @template TDashboardController + * @template TDashboardController of DashboardControllerInterface */ abstract class DashboardControllerTestCase extends AdminWebTestCase { From bdf5e4d4e19134dd51811423349bdacf97b53d88 Mon Sep 17 00:00:00 2001 From: cezarystepkowski Date: Thu, 27 Aug 2026 17:02:09 +0200 Subject: [PATCH 07/10] More --- src/Test/Controller/DeleteActionTestCase.php | 13 +++++++++++++ src/Test/Controller/DetailActionTestCase.php | 13 +++++++++++++ src/Test/Controller/EditActionTestCase.php | 13 +++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/Test/Controller/DeleteActionTestCase.php b/src/Test/Controller/DeleteActionTestCase.php index ec3d0d1..64d3845 100644 --- a/src/Test/Controller/DeleteActionTestCase.php +++ b/src/Test/Controller/DeleteActionTestCase.php @@ -142,6 +142,19 @@ protected function prepareAdminUrlRouteParameters(): array return $routeParameters; } + /** + * @param array $queryParameters + */ + #[Override] + protected function prepareAdminUrlQueryParameters(array $queryParameters): string + { + if (! static::usePrettyUrls()) { + $queryParameters[EA::ENTITY_ID] ??= $this->entityIdUnderTest(); + } + + return parent::prepareAdminUrlQueryParameters($queryParameters); + } + /** * @return TEntity|null */ diff --git a/src/Test/Controller/DetailActionTestCase.php b/src/Test/Controller/DetailActionTestCase.php index 686428b..bee1b24 100644 --- a/src/Test/Controller/DetailActionTestCase.php +++ b/src/Test/Controller/DetailActionTestCase.php @@ -62,6 +62,19 @@ protected function prepareAdminUrlRouteParameters(): array return $routeParameters; } + /** + * @param array $queryParameters + */ + #[Override] + protected function prepareAdminUrlQueryParameters(array $queryParameters): string + { + if (! static::usePrettyUrls()) { + $queryParameters[EA::ENTITY_ID] ??= $this->entityIdUnderTest(); + } + + return parent::prepareAdminUrlQueryParameters($queryParameters); + } + /** * @param array $queryParameters */ diff --git a/src/Test/Controller/EditActionTestCase.php b/src/Test/Controller/EditActionTestCase.php index f0f1b8a..a2912fd 100644 --- a/src/Test/Controller/EditActionTestCase.php +++ b/src/Test/Controller/EditActionTestCase.php @@ -66,6 +66,19 @@ protected function prepareAdminUrlRouteParameters(): array return $routeParameters; } + /** + * @param array $queryParameters + */ + #[Override] + protected function prepareAdminUrlQueryParameters(array $queryParameters): string + { + if (! static::usePrettyUrls()) { + $queryParameters[EA::ENTITY_ID] ??= $this->entityIdUnderTest(); + } + + return parent::prepareAdminUrlQueryParameters($queryParameters); + } + /** * @param array $queryParameters */ From 721a012f3b808941c12167d4df6caec46730f2c5 Mon Sep 17 00:00:00 2001 From: cezarystepkowski Date: Thu, 27 Aug 2026 17:17:54 +0200 Subject: [PATCH 08/10] More --- src/Test/Controller/DeleteActionTestCase.php | 13 ------------- src/Test/Controller/DetailActionTestCase.php | 13 ------------- src/Test/Controller/EditActionTestCase.php | 13 ------------- 3 files changed, 39 deletions(-) diff --git a/src/Test/Controller/DeleteActionTestCase.php b/src/Test/Controller/DeleteActionTestCase.php index 64d3845..ec3d0d1 100644 --- a/src/Test/Controller/DeleteActionTestCase.php +++ b/src/Test/Controller/DeleteActionTestCase.php @@ -142,19 +142,6 @@ protected function prepareAdminUrlRouteParameters(): array return $routeParameters; } - /** - * @param array $queryParameters - */ - #[Override] - protected function prepareAdminUrlQueryParameters(array $queryParameters): string - { - if (! static::usePrettyUrls()) { - $queryParameters[EA::ENTITY_ID] ??= $this->entityIdUnderTest(); - } - - return parent::prepareAdminUrlQueryParameters($queryParameters); - } - /** * @return TEntity|null */ diff --git a/src/Test/Controller/DetailActionTestCase.php b/src/Test/Controller/DetailActionTestCase.php index bee1b24..686428b 100644 --- a/src/Test/Controller/DetailActionTestCase.php +++ b/src/Test/Controller/DetailActionTestCase.php @@ -62,19 +62,6 @@ protected function prepareAdminUrlRouteParameters(): array return $routeParameters; } - /** - * @param array $queryParameters - */ - #[Override] - protected function prepareAdminUrlQueryParameters(array $queryParameters): string - { - if (! static::usePrettyUrls()) { - $queryParameters[EA::ENTITY_ID] ??= $this->entityIdUnderTest(); - } - - return parent::prepareAdminUrlQueryParameters($queryParameters); - } - /** * @param array $queryParameters */ diff --git a/src/Test/Controller/EditActionTestCase.php b/src/Test/Controller/EditActionTestCase.php index a2912fd..f0f1b8a 100644 --- a/src/Test/Controller/EditActionTestCase.php +++ b/src/Test/Controller/EditActionTestCase.php @@ -66,19 +66,6 @@ protected function prepareAdminUrlRouteParameters(): array return $routeParameters; } - /** - * @param array $queryParameters - */ - #[Override] - protected function prepareAdminUrlQueryParameters(array $queryParameters): string - { - if (! static::usePrettyUrls()) { - $queryParameters[EA::ENTITY_ID] ??= $this->entityIdUnderTest(); - } - - return parent::prepareAdminUrlQueryParameters($queryParameters); - } - /** * @param array $queryParameters */ From 89917b5bae6751b24dc457b3ba7415c758fc637c Mon Sep 17 00:00:00 2001 From: cezarystepkowski Date: Thu, 27 Aug 2026 17:46:26 +0200 Subject: [PATCH 09/10] More --- src/Test/Controller/AdminControllerWebTestCase.php | 12 ++++++++++-- src/Test/Controller/EditActionTestCase.php | 4 ++-- src/Test/Controller/NewActionTestCase.php | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Test/Controller/AdminControllerWebTestCase.php b/src/Test/Controller/AdminControllerWebTestCase.php index 91f363d..413f27a 100644 --- a/src/Test/Controller/AdminControllerWebTestCase.php +++ b/src/Test/Controller/AdminControllerWebTestCase.php @@ -243,17 +243,21 @@ protected function assertPageTitle(string $expectedPageTitle): void /** * @param class-string $crudControllerFqcn * @param non-empty-string $actionName - * @param array $redirectRouteParameters * @param array $redirectQueryParameters */ protected function assertResponseRedirectsToCrudController( string $crudControllerFqcn, string $actionName, - array $redirectRouteParameters = [], + string|int|null $entityId = null, array $redirectQueryParameters = [], string|null $fragment = null, ): void { if (static::usePrettyUrls()) { + $redirectRouteParameters = []; + if ($entityId !== null) { + $redirectRouteParameters[EA::ENTITY_ID] = $entityId; + } + $expectedRedirectUrl = 'http://' . static::serverHost() . $this->generateAdminPrettyUrl( static::dashboardFqcn(), $crudControllerFqcn, @@ -268,6 +272,10 @@ protected function assertResponseRedirectsToCrudController( $redirectQueryParameters[EA::CRUD_CONTROLLER_FQCN] ??= $crudControllerFqcn; $redirectQueryParameters[EA::CRUD_ACTION] ??= $actionName; + if ($entityId !== null) { + $redirectQueryParameters[EA::ENTITY_ID] = $entityId; + } + $this->assertResponseIsRedirect($redirectQueryParameters, $fragment); } } diff --git a/src/Test/Controller/EditActionTestCase.php b/src/Test/Controller/EditActionTestCase.php index f0f1b8a..bf5c9b0 100644 --- a/src/Test/Controller/EditActionTestCase.php +++ b/src/Test/Controller/EditActionTestCase.php @@ -116,7 +116,7 @@ protected function assertSavingEntityAndRedirectingToIndexAction( $this->assertResponseRedirectsToCrudController( $this->controllerUnderTest(), Action::INDEX, - [], + null, $redirectQueryParameters, ); } else { @@ -144,7 +144,7 @@ protected function assertSavingEntityAndRedirectingToDetailAction( $this->assertResponseRedirectsToCrudController( $this->controllerUnderTest(), Action::DETAIL, - [EA::ENTITY_ID => $this->entityIdUnderTest()], + $this->entityIdUnderTest(), $redirectQueryParameters, ); } else { diff --git a/src/Test/Controller/NewActionTestCase.php b/src/Test/Controller/NewActionTestCase.php index 6ece14f..8ab5fa6 100644 --- a/src/Test/Controller/NewActionTestCase.php +++ b/src/Test/Controller/NewActionTestCase.php @@ -64,7 +64,7 @@ protected function assertSavingEntityAndRedirectingToIndexAction( $this->assertResponseRedirectsToCrudController( $this->controllerUnderTest(), Action::INDEX, - [], + null, $redirectQueryParameters, ); } else { @@ -92,7 +92,7 @@ protected function assertSavingEntityAndRedirectingToDetailAction( $this->assertResponseRedirectsToCrudController( $this->controllerUnderTest(), Action::DETAIL, - [EA::ENTITY_ID => $this->getAdminContextFromLastRequest()->getEntity()->getPrimaryKeyValueAsString()], + $this->getAdminContextFromLastRequest()->getEntity()->getPrimaryKeyValueAsString(), $redirectQueryParameters, ); } else { From 1305a007e8cfce8401c8226cabeeebc5ec4e780c Mon Sep 17 00:00:00 2001 From: Dragos Protung Date: Fri, 28 Aug 2026 10:02:40 +0200 Subject: [PATCH 10/10] More --- src/Test/Controller/AdminControllerWebTestCase.php | 6 +++--- src/Test/Controller/DashboardControllerTestCase.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Test/Controller/AdminControllerWebTestCase.php b/src/Test/Controller/AdminControllerWebTestCase.php index 413f27a..ca22798 100644 --- a/src/Test/Controller/AdminControllerWebTestCase.php +++ b/src/Test/Controller/AdminControllerWebTestCase.php @@ -75,7 +75,7 @@ protected function prepareAdminUrl(array $queryParameters, string|null $fragment } return $this->generateAdminPrettyUrl( - dashboardFqcn: static::dashboardFqcn(), + dashboardFqcn: $this->dashboardControllerFqcn(), crudControllerFqcn: $this->controllerUnderTest(), actionName: $this->actionName(), routeParameters: $this->prepareAdminUrlRouteParameters(), @@ -101,7 +101,7 @@ protected function prepareAdminUrlRouteParameters(): array } /** @return class-string|null */ - protected static function dashboardFqcn(): string|null + protected function dashboardControllerFqcn(): string|null { return null; } @@ -259,7 +259,7 @@ protected function assertResponseRedirectsToCrudController( } $expectedRedirectUrl = 'http://' . static::serverHost() . $this->generateAdminPrettyUrl( - static::dashboardFqcn(), + $this->dashboardControllerFqcn(), $crudControllerFqcn, $actionName, $redirectRouteParameters, diff --git a/src/Test/Controller/DashboardControllerTestCase.php b/src/Test/Controller/DashboardControllerTestCase.php index 878430b..c5736e9 100644 --- a/src/Test/Controller/DashboardControllerTestCase.php +++ b/src/Test/Controller/DashboardControllerTestCase.php @@ -101,7 +101,7 @@ protected function prepareDashboardUrl(array $routeParameters): string { return $this->getContainerService(AdminUrlGenerator::class) ->setAll(Dict\sort_by_key($routeParameters)) - ->setDashboard($this->getDashboardControllerFqcn()) + ->setDashboard($this->dashboardControllerFqcn()) ->generateUrl(); } @@ -119,5 +119,5 @@ private function makeGetRequestAndFollowRedirects(string $url): Crawler /** * @return class-string */ - abstract protected function getDashboardControllerFqcn(): string; + abstract protected function dashboardControllerFqcn(): string; }