From 8910e60d77a437b2500a3c3d3fbcd212eb6a2903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Fr=C3=A9mont?= Date: Tue, 4 Jun 2024 10:26:39 +0200 Subject: [PATCH] Test grids with UI instead of API --- .github/workflows/build.yml | 11 +- .gitignore | 2 + composer.json | 3 +- phpunit.xml.dist | 2 +- .../{GridApiTest.php => GridUiTest.php} | 144 ++++++++++++------ .../Tests/Functional/PaginationTest.php | 30 +++- src/Bundle/Tests/Functional/SortingTest.php | 38 +++-- tests/Application/.env | 2 +- tests/Application/config/db.sql | Bin 36864 -> 0 bytes .../Application/config/packages/fos_rest.yaml | 9 -- .../config/packages/sylius_grid.yaml | 10 ++ tests/Application/config/routes.yaml | 14 ++ tests/Application/config/sylius/grids.yaml | 10 +- .../config/sylius/grids/author.php | 37 +++-- ...books_with_use_output_walkers_disabled.php | 15 +- ..._books_with_use_output_walkers_enabled.php | 13 +- .../sylius/grids/book_by_amercian_authors.php | 2 +- .../sylius/grids/book_by_english_authors.php | 2 +- tests/Application/src/Entity/Nationality.php | 5 + tests/Application/src/Grid/AuthorGrid.php | 14 +- ...rWithBooksWithUseOutputWalkersDisabled.php | 3 +- ...orWithBooksWithUseOutputWalkersEnabled.php | 3 +- .../src/Grid/BookByAmericanAuthorsGrid.php | 2 +- .../src/Grid/BookByEnglishAuthorsGrid.php | 2 +- tests/Application/src/Grid/BookGrid.php | 2 +- .../templates/crud/index.html.twig | 6 +- .../grid/action/apply_transition.html.twig | 12 ++ .../templates/grid/action/delete.html.twig | 9 ++ .../templates/grid/action/show.html.twig | 3 + .../templates/grid/action/update.html.twig | 3 + .../bulk_action/apply_transition.html.twig | 15 ++ .../grid/bulk_action/delete.html.twig | 13 ++ .../Application/translations/messages.en.yaml | 2 + 33 files changed, 303 insertions(+), 135 deletions(-) rename src/Bundle/Tests/Functional/{GridApiTest.php => GridUiTest.php} (59%) delete mode 100644 tests/Application/config/db.sql delete mode 100644 tests/Application/config/packages/fos_rest.yaml create mode 100644 tests/Application/config/packages/sylius_grid.yaml create mode 100644 tests/Application/templates/grid/action/apply_transition.html.twig create mode 100644 tests/Application/templates/grid/action/delete.html.twig create mode 100644 tests/Application/templates/grid/action/show.html.twig create mode 100644 tests/Application/templates/grid/action/update.html.twig create mode 100644 tests/Application/templates/grid/bulk_action/apply_transition.html.twig create mode 100644 tests/Application/templates/grid/bulk_action/delete.html.twig diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 86761bdf..46c952d2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -86,21 +86,22 @@ jobs: name: Run component tests run: (cd src/Component && vendor/bin/phpspec run) - - - name: Run bundle tests - run: composer test - - name: Run lint container run: (cd tests/Application && bin/console lint:container) - name: Run tests for grids with php config - if: matrix.symfony == '^5.3' run: | (cd tests/Application && bin/console cache:clear --env=test_grids_with_php_config) composer test-php-config + - + name: Run tests for grids with yaml config + run: | + (cd tests/Application && bin/console cache:clear --env=test_grids_with_yaml_config) + composer test-yaml-config + - name: Run tests with grids as services run: | diff --git a/.gitignore b/.gitignore index 93336e13..1fdf6049 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ src/Bundle/test/tmp src/Bundle/test/vendor/ src/Bundle/test/composer.lock + +tests/Application/config/db.sql diff --git a/composer.json b/composer.json index f8c9163c..c2152cc6 100644 --- a/composer.json +++ b/composer.json @@ -72,6 +72,7 @@ "sylius-labs/coding-standard": "^4.0", "sylius/resource-bundle": "dev-poc-new-resource-metadata", "symfony/console": "^5.4 || ^6.0", + "symfony/css-selector": "^5.4 || ^6.0", "symfony/dotenv": "^5.4 || ^6.0", "symfony/maker-bundle": "^1.36", "symfony/polyfill-mbstring": "<1.22.0 || >1.22.0", @@ -120,7 +121,7 @@ "fix": [ "vendor/bin/ecs check --fix" ], - "test": [ + "test-yaml-config": [ "vendor/bin/phpspec run --ansi --no-interaction", "APP_ENV=test_grids_with_yaml_config vendor/bin/phpunit --colors=always" ], diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 7ba2b865..236f006d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -10,7 +10,7 @@ - + diff --git a/src/Bundle/Tests/Functional/GridApiTest.php b/src/Bundle/Tests/Functional/GridUiTest.php similarity index 59% rename from src/Bundle/Tests/Functional/GridApiTest.php rename to src/Bundle/Tests/Functional/GridUiTest.php index 7974b09c..7dd69d44 100644 --- a/src/Bundle/Tests/Functional/GridApiTest.php +++ b/src/Bundle/Tests/Functional/GridUiTest.php @@ -13,9 +13,13 @@ namespace Sylius\Bundle\GridBundle\Tests\Functional; -use ApiTestCase\JsonApiTestCase; +use ApiTestCase\ApiTestCase; +use Coduo\PHPMatcher\Backtrace\VoidBacktrace; +use Coduo\PHPMatcher\Matcher; +use Symfony\Component\DomCrawler\Crawler; +use Symfony\Component\HttpFoundation\Response; -final class GridApiTest extends JsonApiTestCase +final class GridUiTest extends ApiTestCase { /** @var array */ private $data; @@ -31,8 +35,11 @@ protected function setUp(): void public function it_shows_authors_grid(): void { $this->client->request('GET', '/authors/'); + $response = $this->client->getResponse(); - $this->assertResponse($this->client->getResponse(), 'authors_grid'); + $this->assertResponseCode($response, Response::HTTP_OK); + + $this->assertCount(10, $this->getAuthorNames()); } /** @test */ @@ -40,10 +47,7 @@ public function it_sorts_authors_by_name_ascending_by_default(): void { $this->client->request('GET', '/authors/?limit=100'); - $items = $this->getItemsFromCurrentResponse(); - $names = array_map(static function (array $item): string { - return $item['name']; - }, $items); + $names = $this->getAuthorNames(); $sortedNames = $names; sort($names); @@ -56,10 +60,7 @@ public function it_sorts_authors_by_name_descending(): void { $this->client->request('GET', '/authors/?sorting[name]=desc&limit=100'); - $items = $this->getItemsFromCurrentResponse(); - $names = array_map(static function (array $item): string { - return $item['name']; - }, $items); + $names = $this->getAuthorNames(); $sortedNames = $names; rsort($names); @@ -72,7 +73,7 @@ public function it_paginates_authors_by_10_by_default(): void { $this->client->request('GET', '/authors/'); - $this->assertCount(10, $this->getItemsFromCurrentResponse()); + $this->assertCount(10, $this->getAuthorNames()); } /** @test */ @@ -80,11 +81,11 @@ public function it_paginates_authors_by_5_or_15(): void { $this->client->request('GET', '/authors/?limit=5'); - $this->assertCount(5, $this->getItemsFromCurrentResponse()); + $this->assertCount(5, $this->getAuthorNames()); $this->client->request('GET', '/authors/?limit=15'); - $this->assertCount(15, $this->getItemsFromCurrentResponse()); + $this->assertCount(15, $this->getAuthorNames()); } /** @test */ @@ -95,8 +96,10 @@ public function it_filters_books_by_title(): void urlencode('Book 5'), )); - $this->assertCount(1, $this->getItemsFromCurrentResponse()); - $this->assertSame('Book 5', $this->getFirstItemFromCurrentResponse()['title']); + $titles = $this->getBookTitles(); + + $this->assertCount(1, $titles); + $this->assertSame('Book 5', $titles[0]); } /** @test */ @@ -107,8 +110,10 @@ public function it_filters_books_by_title_with_contains(): void urlencode('jurassic'), )); - $this->assertCount(1, $this->getItemsFromCurrentResponse()); - $this->assertSame('Jurassic Park', $this->getFirstItemFromCurrentResponse()['title']); + $titles = $this->getBookTitles(); + + $this->assertCount(1, $titles); + $this->assertSame('Jurassic Park', $titles[0]); } /** @test */ @@ -118,8 +123,10 @@ public function it_filters_books_by_author(): void $this->client->request('GET', sprintf('/books/?criteria[author][]=%d', $authorId)); - $this->assertCount(2, $this->getItemsFromCurrentResponse()); - $this->assertSame('Jurassic Park', $this->getFirstItemFromCurrentResponse()['title']); + $titles = $this->getBookTitles(); + + $this->assertCount(2, $titles); + $this->assertSame('Jurassic Park', $titles[0]); } /** @test */ @@ -130,8 +137,10 @@ public function it_filters_books_by_authors(): void $this->client->request('GET', sprintf('/books/?criteria[author][]=%d&criteria[author][]=%d', $firstAuthorId, $secondAuthorId)); - $this->assertCount(3, $this->getItemsFromCurrentResponse()); - $this->assertSame('A Study in Scarlet', $this->getFirstItemFromCurrentResponse()['title']); + $titles = $this->getBookTitles(); + + $this->assertCount(3, $titles); + $this->assertSame('A Study in Scarlet', $titles[0]); } /** @test */ @@ -141,8 +150,10 @@ public function it_filters_books_by_authors_nationality(): void $this->client->request('GET', sprintf('/books/?criteria[nationality]=%d', $authorNationalityId)); - $this->assertCount(2, $this->getItemsFromCurrentResponse()); - $this->assertSame('Jurassic Park', $this->getFirstItemFromCurrentResponse()['title']); + $titles = $this->getBookTitles(); + + $this->assertCount(2, $titles); + $this->assertSame('Jurassic Park', $titles[0]); } /** @test */ @@ -152,8 +163,10 @@ public function it_filters_books_by_author_and_currency(): void $this->client->request('GET', sprintf('/books/?criteria[author]=%d&criteria[currencyCode]=%s', $authorId, 'EUR')); - $this->assertCount(1, $this->getItemsFromCurrentResponse()); - $this->assertSame('Jurassic Park', $this->getFirstItemFromCurrentResponse()['title']); + $titles = $this->getBookTitles(); + + $this->assertCount(1, $titles); + $this->assertSame('Jurassic Park', $titles[0]); } /** @test */ @@ -161,10 +174,7 @@ public function it_sorts_books_ascending_by_author(): void { $this->client->request('GET', '/books/?sorting[author]=asc&limit=100'); - $items = $this->getItemsFromCurrentResponse(); - $names = array_map(static function (array $item): string { - return $item['author']['name']; - }, $items); + $names = $this->getBookAuthors(); $sortedNames = $names; sort($names); @@ -177,10 +187,7 @@ public function it_sorts_books_descending_by_authors_nationality(): void { $this->client->request('GET', '/books/?sorting[nationality]=desc&limit=100'); - $items = $this->getItemsFromCurrentResponse(); - $names = array_map(static function (array $item): string { - return $item['author']['nationality']['name']; - }, $items); + $names = $this->getBookAuthorNationalities(); $sortedNames = $names; rsort($names); @@ -195,8 +202,10 @@ public function it_filters_books_by_author_when_an_author_association_is_used_in $this->client->request('GET', sprintf('/by-american-authors/books/?criteria[author]=%d', $authorId)); - $this->assertCount(2, $this->getItemsFromCurrentResponse()); - $this->assertSame('Jurassic Park', $this->getFirstItemFromCurrentResponse()['title']); + $titles = $this->getBookTitles(); + + $this->assertCount(2, $titles); + $this->assertSame('Jurassic Park', $titles[0]); } /** @test */ @@ -204,7 +213,10 @@ public function it_sorts_authors_using_table_alias_defined_in_query_builder(): v { $this->client->request('GET', '/by-american-authors/books/?sorting[author]=asc'); - $this->assertResponse($this->client->getResponse(), 'american_authors_sorted_ascending'); + $titles = $this->getBookTitles(); + + $this->assertCount(2, $titles); + $this->assertSame('Jurassic Park', $titles[0]); } /** @test */ @@ -214,40 +226,72 @@ public function it_filters_books_by_author_when_an_author_is_used_in_join_in_que $this->client->request('GET', sprintf('/by-english-authors/books/?criteria[author]=%d', $authorId)); - $this->assertCount(1, $this->getItemsFromCurrentResponse()); - $this->assertSame('A Study in Scarlet', $this->getFirstItemFromCurrentResponse()['title']); + $titles = $this->getBookTitles(); + + $this->assertCount(1, $titles); + $this->assertSame('A Study in Scarlet', $titles[0]); } + /** @test */ public function it_includes_all_rows_even_when_sorting_by_a_nullable_path(): void { $this->client->request('GET', '/authors/'); - $totalItemsCountBeforeSorting = $this->getTotalItemsCountFromCurrentResponse(); + $totalItemsCountBeforeSorting = count($this->getAuthorNames()); $this->client->request('GET', '/authors/?sorting[nationality]=desc'); - $totalItemsCountAfterSorting = $this->getTotalItemsCountFromCurrentResponse(); + + $totalItemsCountAfterSorting = count($this->getAuthorNames()); $this->assertSame($totalItemsCountBeforeSorting, $totalItemsCountAfterSorting); } - private function getTotalItemsCountFromCurrentResponse(): int + /** @return string[] */ + private function getBookTitles(): array + { + return $this->getCrawler() + ->filter('[data-test-title]') + ->each( + fn (Crawler $node): string => $node->text(), + ); + } + + /** @return string[] */ + private function getBookAuthors(): array { - return json_decode($this->client->getResponse()->getContent(), true)['total']; + return $this->getCrawler() + ->filter('[data-test-author]') + ->each( + fn (Crawler $node): string => $node->text(), + ); } - private function getItemsFromCurrentResponse(): array + /** @return string[] */ + private function getBookAuthorNationalities(): array { - return json_decode($this->client->getResponse()->getContent(), true)['_embedded']['items']; + return $this->getCrawler() + ->filter('[data-test-nationality]') + ->each( + fn (Crawler $node): string => $node->text(), + ); } - private function getFirstItemFromCurrentResponse(): array + /** @return string[] */ + private function getAuthorNames(): array { - return current($this->getItemsFromCurrentResponse()); + return $this->getCrawler() + ->filter('[data-test-name]') + ->each( + fn (Crawler $node): string => $node->text(), + ); } - private function getLastItemFromCurrentResponse(): array + private function getCrawler(): Crawler { - $result = $this->getItemsFromCurrentResponse(); + return $this->client->getCrawler(); + } - return end($result); + protected function buildMatcher(): Matcher + { + return $this->matcherFactory->createMatcher(new VoidBacktrace()); } } diff --git a/src/Bundle/Tests/Functional/PaginationTest.php b/src/Bundle/Tests/Functional/PaginationTest.php index 1c301e6d..4633382a 100644 --- a/src/Bundle/Tests/Functional/PaginationTest.php +++ b/src/Bundle/Tests/Functional/PaginationTest.php @@ -13,9 +13,12 @@ namespace Sylius\Bundle\GridBundle\Tests\Functional; -use ApiTestCase\JsonApiTestCase; +use ApiTestCase\ApiTestCase; +use Coduo\PHPMatcher\Backtrace\VoidBacktrace; +use Coduo\PHPMatcher\Matcher; +use Symfony\Component\DomCrawler\Crawler; -final class PaginationTest extends JsonApiTestCase +final class PaginationTest extends ApiTestCase { protected function setUp(): void { @@ -29,7 +32,7 @@ public function it_returns_incorrect_amount_of_items_per_page_with_fetch_join_co { $this->client->request('GET', '/authors/with-books/with-fetch-join-collection-disabled'); - self::assertNotCount(10, $this->getItemsFromCurrentResponse()); + self::assertNotCount(10, $this->getAuthorNames()); } /** @test */ @@ -37,11 +40,26 @@ public function it_returns_correct_amount_of_items_per_page_with_fetch_join_coll { $this->client->request('GET', '/authors/with-books/with-fetch-join-collection-enabled'); - self::assertCount(10, $this->getItemsFromCurrentResponse()); + self::assertCount(10, $this->getAuthorNames()); } - private function getItemsFromCurrentResponse(): array + /** @return string[] */ + private function getAuthorNames(): array { - return json_decode($this->client->getResponse()->getContent(), true, 512, \JSON_THROW_ON_ERROR)['_embedded']['items']; + return $this->getCrawler() + ->filter('[data-test-name]') + ->each( + fn (Crawler $node): string => $node->text(), + ); + } + + private function getCrawler(): Crawler + { + return $this->client->getCrawler(); + } + + protected function buildMatcher(): Matcher + { + return $this->matcherFactory->createMatcher(new VoidBacktrace()); } } diff --git a/src/Bundle/Tests/Functional/SortingTest.php b/src/Bundle/Tests/Functional/SortingTest.php index 7fedb033..9ba04ff9 100644 --- a/src/Bundle/Tests/Functional/SortingTest.php +++ b/src/Bundle/Tests/Functional/SortingTest.php @@ -13,9 +13,13 @@ namespace Sylius\Bundle\GridBundle\Tests\Functional; -use ApiTestCase\JsonApiTestCase; +use ApiTestCase\ApiTestCase; +use Coduo\PHPMatcher\Backtrace\VoidBacktrace; +use Coduo\PHPMatcher\Matcher; +use Symfony\Component\DomCrawler\Crawler; +use Symfony\Component\HttpFoundation\Response; -final class SortingTest extends JsonApiTestCase +final class SortingTest extends ApiTestCase { private array $data; @@ -31,10 +35,9 @@ public function it_returns_error_instead_of_sorted_authors_by_book_title_with_us { $this->client->request('GET', '/authors/with-books/with-use-output-walkers-disabled?sorting[book]=asc'); - self::assertStringContainsString( - 'Cannot select distinct identifiers from query with LIMIT and ORDER BY on a column from a fetch joined to-many association. Use output walkers.', - $this->client->getResponse()->getContent(), - ); + $response = $this->client->getResponse(); + + $this->assertEquals(Response::HTTP_INTERNAL_SERVER_ERROR, $response->getStatusCode()); } /** @test */ @@ -42,7 +45,7 @@ public function it_returns_correct_amount_of_sorted_authors_by_book_title_with_u { $this->client->request('GET', '/authors/with-books/with-use-output-walkers-enabled?sorting[book]=asc'); - self::assertCount(10, $this->getItemsFromCurrentResponse()); + self::assertCount(10, $this->getAuthorNames()); } /** @test */ @@ -50,11 +53,26 @@ public function it_allows_for_sorting_by_disabled_field(): void { $this->client->request('GET', '/authors/?sorting[id]=asc'); - self::assertCount(10, $this->getItemsFromCurrentResponse()); + self::assertCount(10, $this->getAuthorNames()); + } + + /** @return string[] */ + private function getAuthorNames(): array + { + return $this->getCrawler() + ->filter('[data-test-name]') + ->each( + fn (Crawler $node): string => $node->text(), + ); + } + + private function getCrawler(): Crawler + { + return $this->client->getCrawler(); } - private function getItemsFromCurrentResponse(): array + protected function buildMatcher(): Matcher { - return json_decode($this->client->getResponse()->getContent(), true)['_embedded']['items']; + return $this->matcherFactory->createMatcher(new VoidBacktrace()); } } diff --git a/tests/Application/.env b/tests/Application/.env index afd93523..acbcc8ed 100644 --- a/tests/Application/.env +++ b/tests/Application/.env @@ -1 +1 @@ -APP_ENV=test +APP_ENV=test_grids_with_php_config diff --git a/tests/Application/config/db.sql b/tests/Application/config/db.sql deleted file mode 100644 index d322ec3a0b4c9d06f80a1fadb48828ed7fc04fd8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36864 zcmeI5TWs6b8OJHfH`ykSotty18#-wkyG&Z^LRofhmSozN?~$F@NiPm<(H3i2awy45 z^03uyhjqm;WEutp8!%+uOV?pQ(1$HsUxH!}S+Nbl3aH-tk`=oI1vX^cOFC@8jt)O7 zw5d?s%doabfb+LV{?B*L@B2uZ{w!tk^oW{O_=U8#EN6Ki)5JI&OfSzfjPnzQVchs@ z<57*jsoHpg)nWMl5#Qo5o}M0J@!pz-0}Of*?PmYNzTEI-{DeLz0ZM=ppaduZN`Mle z1So<3O9FCDO^ev-_>!86E0>~uGqVvX5)KBsJ^g_$vESzj%PT9hbLsR_Z6qdzrX)T( z)+f#I<&NaX$M}t-`F1&%O{BG1HQw>cmFn7-)>g+?2D0*8QrS3ULu+8*sZe-CG7O-` zajYq6K#K7bvFK=~8DrueaO{B>qz1>8~d|r zHmUGuL$SzUDAw*3#SVixla=vp!XtJnsp7Qbe0Y3(L<)@=Z1b9eeeqd*Z_$U@Ohrc} z!`|FV+_ZP|oK|vkNi~z$GQyT)G<9B?m6y}GRJOFVhs$0eyXSM7rljUC&(5dgk6cG& zd~9+m7Q#^Z{$W#|`Tp^k6df2NkPX@6V^Y5qlg1*_BuS3WnQzC5C2PgAm0~fHyXaVS zDjFIYImbswN2R_fM$(~H)wcNB9BU1w0uzIwNLcg-J(2FdkSG?*Kp(T(RAE~V-6*h) zDWv4Anoh|{HG8>OXD_$AYFpac9Ix&x)tP?e!w^-bTH6@wzpS>+p-Xw$oVt{}Y%>{K z7rH4In`3osO^9K)?W{~VYgz=sagKn>T*L&G*^F{AhigdL^3=5n*_NH{#U&oW&W^S1 zj@sgoYtNV98zxrFfZ?fg)0kU!78g+hYUj*PPy&`<5}*Vq0ZM=ppaduZN`Mmhj1oXjSDW+UUv9VuS(mGoY$*OU zl90vAMuw&DaJU4r*YIZs%zCl^zl*D4(4W!!=!fW=Xbq*%SrkG~pl0sh+@H8#b3ftU z;J(hSa&z1;=i~O`gXx13paduZN`Mle1SkPYfD)htC;>{~Q%PWZez1yh9%j~um1I)o zN0fzyq@wN058$mwnf1|}rYcE(AeUTBe<8D^?#%b&9RjmHq+~J*Kaf<^`9w<5cH||z zy@Oc~X{wx3cxhol(Xv;X^L=>pL1z7|8khNqoLNz{o%x79gp|o96pfdbNjo~xoDb{A z_NkXtg&&nKE84bv2yZ*YtV`Oen&JoLWi^@Hk?+MDajZyE$>uVASk|(5@;mdV^l=B2 zl(MQSs|r7?Dv8vN{7L=rA$fiY50P9=YngPaIe!9g##0-}WwQKqE|r;2H06)uZEei@ zNbU+hm{t}QZEyY<-XvlYvbHE|YF6fl)2Z}|lEgH&<$Lf>JiYU2P3FflYKkE0#v3uB zQ6(v-F7x4ZHiO?{A8*PB^}$2QRXM@O(&;&r@4}n*GwWk&GQ&^HT6||dpqr)Ss+!@4 z`LdYABsZ;SsZVrMvPz zyzMCS!6?p^jI$ZR-Ty>3ovOzby9>pN{r?B(KKcm#4*dqbhu%d$LvN$E&>QI6D34x8 zFQY3+!|&gpL+A0q^g#(w0+awHKnYL+lmI0_2~Yx*03|>PeC`Rd(q7PD5T z%jZ6U6aXba2~Yx*03|>PPy&c8Pff~hwh?vbO+r= zx6n;=1HFl^qig6YdJVmVE}<2aKo`&qnm~i77X?u#YDYZUjhav$Vz>v~eeNE2ms{uV zaJRWz+)eHV_a=9pyT)DRUgKWkE^#Ydg1f-Ya1-1h*UJUDPOhEfx!qh7SI05z1NJ_9 zkG;#Tvv=6r>@D^tdxL$Gz0O`^ud=VPFR_={6*j?MU}x9~c9895gKQ_;&hqSTwu!A{ znZ^f=_Z#mu-fdiOyn~lRACv$kKnYL+lmI0_2~Yx*044AlCQ$5Wx(9_UXa-aRy$HGj zng&e~9T1j5lb}mP`-K-lRnP?JBIp89Nl-xJMEit!&^b^U^aAKC(TMN@=<}e@fj$d* z9`qdO4Cpk`uy7Xi4AGD<1v&{D13gW&SC{}D2OR?)1sx%JN*D$m0*!)_uD1J>K)Tvk zNmm;y>1w-A3Z$!zm2|bSlCCyZ($&UFy4qMtR~swoYP(Meq^pgUbhWXPt~OTE)y7J? z+V0~5>1tyoU2UuZGOyzT>1*TXq_2(D2iv_wj|m>oPS9sSp9Vb&dIVG;+9Ny#+5y@Q zdKmOcqTRwF&?i6-f*t^EBN`NV(EXr~gSLV`2D%S)FX$ekUBYhA7SLUwJBbE_9iZDm zw}Cbj^$SfzeF6gIitqn#t9y^Z_xxA!y*-cb;cwu3^2ggQxzJ`giMJuaDL5b${f3%dNS4+)g|MeNY0F03|>PPy& zjC0?9w-5i1M%&$kVf-OTe0Q+)KZtodz22i9&(Y3q-Xr#SgFRwrQ$jiu6AKx$uglWs zx;GG>5DQuvpWiAT_%4?5d8~Xe&lR&TAlmSy%|3s(4PVOa^LTCemW{pvk_WHlJb_EH zjIT0Je_;vx_H5)`k7v0&2=}5fTtAtnXqk3MgIdN{d75G&VfOhg(+=}oH2Zv(IANX( zW}nB>2k{i6Pts2#pN+J~%|4GM7ntX~(bq@f1-q=`!93^6`0SLYZ1(vAHsW0{`@EL< zBkS`QX0fkSp8ERiq~Qf)xQLF$j_-N1&u<6kb7g#X;yr8j`7BRANc;IRK1-aC_H$;R z*YdOl-%J^wowA-b`#hHA0_!_#^o8}yiyhw?v(MjYqdcdKzK~uol~2Fo{eM66T?W77 ze+_r_>u~q}8t&4!<8J&-+;tyhn{Y?{dSjxov*AI*t%k2QoNm}t|NHtM)L*Rcu6MY9 z;r@pEy!$}i$8~SlU8xJ#)z`jX`<>ePTA}72HSg5CQZrn$z52uI?^iEX`>Xy{_4BH) zRZUer=K6!{N3NXfgsa;5E9bYI&p8h{{_6O#(%MospfIBugfwXRM(i<=dXMg_zR=hSGpMK^Q>Hy{=$gaR{2sJ zC=6p;>&7edDMH25X=iyu#^ve8?#lBN3sJK#V0rNaoP%Y2mhqs>2Fm#Clv%&o=dT>k zUy!h`ls=t{WjL5-pE2A?l80_PSR!S7mGdqZ!exAR&W4cL7p#m$EcBXv9y_l=r^@&$ zbMY5WVqYl@I!{X*q~U}y+zFC~F3V|x@3`3~+KG3}?DN?vm!2{{I~UzE&q$OQ+cvuq+pd_e>d|op?{1eWGQ#K)j=7pWiYb_>P!;K1-gE1_Ap@ zY0!CEVu31q${4OkKN~Eo8hjmQUzeSD?Pj0PvdRF|kjv)UJg`75VSEbKA+ymrcSx6#){@)xwTz815u z%g$-E%j^r-sh6E*pT`c*9Y$Y3uTMKaglsqaf|hj#`P){;XSqJ`HJg3D%C8P53r*PP z*$2OM_J{b%Y%YG8$DdRu1*{0C~`pdA1J diff --git a/tests/Application/config/packages/fos_rest.yaml b/tests/Application/config/packages/fos_rest.yaml deleted file mode 100644 index fd03639a..00000000 --- a/tests/Application/config/packages/fos_rest.yaml +++ /dev/null @@ -1,9 +0,0 @@ -fos_rest: - view: - formats: - json: true - empty_content: 204 - format_listener: - rules: - - { path: '^/admin/*', priorities: ['html'], fallback_format: html } - - { path: '^/', priorities: ['json'], fallback_format: json, prefer_extension: true } diff --git a/tests/Application/config/packages/sylius_grid.yaml b/tests/Application/config/packages/sylius_grid.yaml new file mode 100644 index 00000000..7184f8cd --- /dev/null +++ b/tests/Application/config/packages/sylius_grid.yaml @@ -0,0 +1,10 @@ +sylius_grid: + templates: + action: + apply_transition: 'grid/action/apply_transition.html.twig' + delete: 'grid/action/delete.html.twig' + show: 'grid/action/show.html.twig' + update: 'grid/action/update.html.twig' + bulk_action: + apply_transition: 'grid/bulk_action/apply_transition.html.twig' + delete: 'grid/bulk_action/delete.html.twig' diff --git a/tests/Application/config/routes.yaml b/tests/Application/config/routes.yaml index 0b4150e0..7d21acd2 100644 --- a/tests/Application/config/routes.yaml +++ b/tests/Application/config/routes.yaml @@ -3,13 +3,21 @@ app_books: alias: app.book grid: app_book only: ['index'] + templates: crud type: sylius.resource_api +app_book_show: + path: /books/{id}} + methods: [ GET ] + defaults: + _controller: app.controller.book::showAction + app_author: resource: | alias: app.author grid: app_author only: ['index'] + templates: crud type: sylius.resource_api app_books_by_american_authors: @@ -18,6 +26,7 @@ app_books_by_american_authors: section: american_authors grid: app_book_by_american_authors only: ['index'] + templates: crud type: sylius.resource_api prefix: /by-american-authors @@ -27,6 +36,7 @@ app_books_by_english_authors: section: english_authors grid: app_book_by_english_authors only: ['index'] + templates: crud type: sylius.resource_api prefix: /by-english-authors @@ -37,6 +47,7 @@ app_author_with_books_with_fetch_join_collection_disabled: _controller: app.controller.author::indexAction _sylius: grid: app_author_with_books_with_fetch_join_collection_disabled + template: crud/index.html.twig app_author_with_books_with_fetch_join_collection_enabled: path: /authors/with-books/with-fetch-join-collection-enabled @@ -45,6 +56,7 @@ app_author_with_books_with_fetch_join_collection_enabled: _controller: app.controller.author::indexAction _sylius: grid: app_author_with_books_with_fetch_join_collection_enabled + template: crud/index.html.twig app_author_with_books_with_use_output_walkers_disabled: path: /authors/with-books/with-use-output-walkers-disabled @@ -53,6 +65,7 @@ app_author_with_books_with_use_output_walkers_disabled: _controller: app.controller.author::indexAction _sylius: grid: app_author_with_books_with_use_output_walkers_disabled + template: crud/index.html.twig app_author_with_books_with_use_output_walkers_enabled: path: /authors/with-books/with-use-output-walkers-enabled @@ -61,3 +74,4 @@ app_author_with_books_with_use_output_walkers_enabled: _controller: app.controller.author::indexAction _sylius: grid: app_author_with_books_with_use_output_walkers_enabled + template: crud/index.html.twig diff --git a/tests/Application/config/sylius/grids.yaml b/tests/Application/config/sylius/grids.yaml index c969386a..beb008f6 100644 --- a/tests/Application/config/sylius/grids.yaml +++ b/tests/Application/config/sylius/grids.yaml @@ -72,7 +72,7 @@ sylius_grid: type: string label: Name sortable: nationality.name - path: nationality.name + path: nationality limits: [10, 5, 15] app_book_by_american_authors: @@ -106,9 +106,9 @@ sylius_grid: path: author.name sortable: author.name nationality: - type: nationality + type: string label: Nationality - path: na.name + path: author.nationality.name sortable: na.name limits: [10, 5, 15] @@ -145,7 +145,7 @@ sylius_grid: nationality: type: string label: Nationality - path: na.name + path: author.nationality.name sortable: na.name limits: [10, 5, 15] @@ -177,6 +177,7 @@ sylius_grid: fields: book: type: string + path: books[0].title sortable: book.title app_author_with_books_with_use_output_walkers_enabled: @@ -188,4 +189,5 @@ sylius_grid: fields: book: type: string + path: books[0].title sortable: book.title diff --git a/tests/Application/config/sylius/grids/author.php b/tests/Application/config/sylius/grids/author.php index aa60716f..89e7203f 100644 --- a/tests/Application/config/sylius/grids/author.php +++ b/tests/Application/config/sylius/grids/author.php @@ -19,24 +19,23 @@ return static function (GridConfig $grid) { $grid->addGrid( GridBuilder::create('app_author', '%app.model.author.class%') - ->addFilter(StringFilter::create('name')) - ->orderBy('name', 'asc') - ->addField( - StringField::create('id') - ->setSortable(true) - ->setEnabled(false), - ) - ->addField( - StringField::create('name') - ->setLabel('Name') - ->setSortable(true), - ) - ->addField( - StringField::create('nationality') - ->setLabel('Name') - ->setPath('nationality.name') - ->setSortable(true, 'nationality.name'), - ) - ->setLimits([10, 5, 15]), + ->addFilter(StringFilter::create('name')) + ->orderBy('name', 'asc') + ->addField( + StringField::create('id') + ->setSortable(true) + ->setEnabled(false), + ) + ->addField( + StringField::create('name') + ->setLabel('Name') + ->setSortable(true), + ) + ->addField( + StringField::create('nationality') + ->setLabel('Nationality') + ->setSortable(true, 'nationality.name'), + ) + ->setLimits([10, 5, 15]), ); }; diff --git a/tests/Application/config/sylius/grids/author_with_books_with_use_output_walkers_disabled.php b/tests/Application/config/sylius/grids/author_with_books_with_use_output_walkers_disabled.php index 79108fa3..5249c916 100644 --- a/tests/Application/config/sylius/grids/author_with_books_with_use_output_walkers_disabled.php +++ b/tests/Application/config/sylius/grids/author_with_books_with_use_output_walkers_disabled.php @@ -18,12 +18,13 @@ return static function (GridConfig $grid) { $grid->addGrid( GridBuilder::create('app_author_with_books_with_use_output_walkers_disabled') - ->extends('app_author') - ->setRepositoryMethod(["expr:service('app.authors_with_books_query_builder')", 'create']) - ->setDriverOption('pagination', ['use_output_walkers' => false]) - ->addField( - StringField::create('book') - ->setSortable(true, 'book.title'), - ), + ->extends('app_author') + ->setRepositoryMethod(["expr:service('app.authors_with_books_query_builder')", 'create']) + ->setDriverOption('pagination', ['use_output_walkers' => false]) + ->addField( + StringField::create('book') + ->setPath('books[0].title') + ->setSortable(true, 'book.title'), + ), ); }; diff --git a/tests/Application/config/sylius/grids/author_with_books_with_use_output_walkers_enabled.php b/tests/Application/config/sylius/grids/author_with_books_with_use_output_walkers_enabled.php index 4053b940..92865205 100644 --- a/tests/Application/config/sylius/grids/author_with_books_with_use_output_walkers_enabled.php +++ b/tests/Application/config/sylius/grids/author_with_books_with_use_output_walkers_enabled.php @@ -18,11 +18,12 @@ return static function (GridConfig $grid) { $grid->addGrid( GridBuilder::create('app_author_with_books_with_use_output_walkers_enabled') - ->extends('app_author') - ->setRepositoryMethod(["expr:service('app.authors_with_books_query_builder')", 'create']) - ->addField( - StringField::create('book') - ->setSortable(true, 'book.title'), - ), + ->extends('app_author') + ->setRepositoryMethod(["expr:service('app.authors_with_books_query_builder')", 'create']) + ->addField( + StringField::create('book') + ->setPath('books[0].title') + ->setSortable(true, 'book.title'), + ), ); }; diff --git a/tests/Application/config/sylius/grids/book_by_amercian_authors.php b/tests/Application/config/sylius/grids/book_by_amercian_authors.php index 2d832c15..6ab8e538 100644 --- a/tests/Application/config/sylius/grids/book_by_amercian_authors.php +++ b/tests/Application/config/sylius/grids/book_by_amercian_authors.php @@ -46,7 +46,7 @@ ->addField( StringField::create('nationality') ->setLabel('Nationality') - ->setPath('na.name') + ->setPath('author.nationality.name') ->setSortable(true, 'na.name'), ) ->setLimits([10, 5, 15]), diff --git a/tests/Application/config/sylius/grids/book_by_english_authors.php b/tests/Application/config/sylius/grids/book_by_english_authors.php index c3202f41..e2af8e7c 100644 --- a/tests/Application/config/sylius/grids/book_by_english_authors.php +++ b/tests/Application/config/sylius/grids/book_by_english_authors.php @@ -46,7 +46,7 @@ ->addField( StringField::create('nationality') ->setLabel('Nationality') - ->setPath('na.name') + ->setPath('author.nationality.name') ->setSortable(true, 'na.name'), ) ->setLimits([10, 5, 15]), diff --git a/tests/Application/src/Entity/Nationality.php b/tests/Application/src/Entity/Nationality.php index 778c03e0..cbc0221b 100644 --- a/tests/Application/src/Entity/Nationality.php +++ b/tests/Application/src/Entity/Nationality.php @@ -49,4 +49,9 @@ public function setName(?string $name): void { $this->name = $name; } + + public function __toString(): string + { + return $this->name ?? ''; + } } diff --git a/tests/Application/src/Grid/AuthorGrid.php b/tests/Application/src/Grid/AuthorGrid.php index 047fea90..f930efab 100644 --- a/tests/Application/src/Grid/AuthorGrid.php +++ b/tests/Application/src/Grid/AuthorGrid.php @@ -45,19 +45,19 @@ public function buildGrid(GridBuilderInterface $gridBuilder): void ->orderBy('name', 'asc') ->addField( StringField::create('id') - ->setSortable(true) - ->setEnabled(false), + ->setSortable(true) + ->setEnabled(false), ) ->addField( StringField::create('name') - ->setLabel('Name') - ->setSortable(true), + ->setLabel('Name') + ->setSortable(true), ) ->addField( StringField::create('nationality') - ->setLabel('Name') - ->setPath('nationality.name') - ->setSortable(true, 'nationality.name'), + ->setLabel('Name') + ->setPath('nationality') + ->setSortable(true, 'nationality.name'), ) ->setLimits([10, 5, 15]) ; diff --git a/tests/Application/src/Grid/AuthorWithBooksWithUseOutputWalkersDisabled.php b/tests/Application/src/Grid/AuthorWithBooksWithUseOutputWalkersDisabled.php index 3906e48a..e53e9aa5 100644 --- a/tests/Application/src/Grid/AuthorWithBooksWithUseOutputWalkersDisabled.php +++ b/tests/Application/src/Grid/AuthorWithBooksWithUseOutputWalkersDisabled.php @@ -39,7 +39,8 @@ public function buildGrid(GridBuilderInterface $gridBuilder): void ->setDriverOption('pagination', ['use_output_walkers' => false]) ->addField( StringField::create('book') - ->setSortable(true, 'book.title'), + ->setPath('books[0].title') + ->setSortable(true, 'book.title'), ) ; } diff --git a/tests/Application/src/Grid/AuthorWithBooksWithUseOutputWalkersEnabled.php b/tests/Application/src/Grid/AuthorWithBooksWithUseOutputWalkersEnabled.php index 178f29ee..84a6a109 100644 --- a/tests/Application/src/Grid/AuthorWithBooksWithUseOutputWalkersEnabled.php +++ b/tests/Application/src/Grid/AuthorWithBooksWithUseOutputWalkersEnabled.php @@ -38,7 +38,8 @@ public function buildGrid(GridBuilderInterface $gridBuilder): void ->setRepositoryMethod(["expr:service('app.authors_with_books_query_builder')", 'create']) ->addField( StringField::create('book') - ->setSortable(true, 'book.title'), + ->setPath('books[0].title') + ->setSortable(true, 'book.title'), ) ; } diff --git a/tests/Application/src/Grid/BookByAmericanAuthorsGrid.php b/tests/Application/src/Grid/BookByAmericanAuthorsGrid.php index 3cfbe853..e9c0efbe 100644 --- a/tests/Application/src/Grid/BookByAmericanAuthorsGrid.php +++ b/tests/Application/src/Grid/BookByAmericanAuthorsGrid.php @@ -63,7 +63,7 @@ public function buildGrid(GridBuilderInterface $gridBuilder): void ->addField( StringField::create('nationality') ->setLabel('Nationality') - ->setPath('na.name') + ->setPath('author.nationality.name') ->setSortable(true, 'na.name'), ) ->setLimits([10, 5, 15]) diff --git a/tests/Application/src/Grid/BookByEnglishAuthorsGrid.php b/tests/Application/src/Grid/BookByEnglishAuthorsGrid.php index e9a930dc..ccaa3d21 100644 --- a/tests/Application/src/Grid/BookByEnglishAuthorsGrid.php +++ b/tests/Application/src/Grid/BookByEnglishAuthorsGrid.php @@ -71,7 +71,7 @@ public function buildGrid(GridBuilderInterface $gridBuilder): void ->addField( StringField::create('nationality') ->setLabel('Nationality') - ->setPath('na.name') + ->setPath('author.nationality.name') ->setSortable(true, 'na.name'), ) ->setLimits([10, 5, 15]) diff --git a/tests/Application/src/Grid/BookGrid.php b/tests/Application/src/Grid/BookGrid.php index 83f473b7..9c0ee24c 100644 --- a/tests/Application/src/Grid/BookGrid.php +++ b/tests/Application/src/Grid/BookGrid.php @@ -93,7 +93,7 @@ public function buildGrid(GridBuilderInterface $gridBuilder): void ItemActionGroup::create( ShowAction::create([ 'link' => [ - 'route' => 'app_admin_book_show', + 'route' => 'app_book_show', ], ]), ), diff --git a/tests/Application/templates/crud/index.html.twig b/tests/Application/templates/crud/index.html.twig index e928a51f..e587e797 100644 --- a/tests/Application/templates/crud/index.html.twig +++ b/tests/Application/templates/crud/index.html.twig @@ -1,4 +1,6 @@ -

{{ (operation.resource.applicationName ~ '.ui.' ~ operation.resource.pluralName)|trans }}

+{% set metadata = resource.metadata|default(metadata) %} + +

{{ (metadata.applicationName ~ '.ui.' ~ metadata.pluralName)|trans }}

{% set grid = resources %} {% set definition = grid.definition %} @@ -20,7 +22,7 @@ {% for resource in resources.data %} {% for field in definition.enabledFields %} - {{ sylius_grid_render_field(grid, field, resource) }} + {{ sylius_grid_render_field(grid, field, resource) }} {% if definition.actionGroups.item is defined and definition.getEnabledActions('item')|length > 0 %} {% for action in definition.getEnabledActions('item') %} diff --git a/tests/Application/templates/grid/action/apply_transition.html.twig b/tests/Application/templates/grid/action/apply_transition.html.twig new file mode 100644 index 00000000..bb8c50d8 --- /dev/null +++ b/tests/Application/templates/grid/action/apply_transition.html.twig @@ -0,0 +1,12 @@ +{% set labeled = options.labeled is defined ? options.labeled : true %} + +{% if sm_can(data, options.transition, options.graph) %} +
+ + + +
+{% endif %} diff --git a/tests/Application/templates/grid/action/delete.html.twig b/tests/Application/templates/grid/action/delete.html.twig new file mode 100644 index 00000000..e40ec82a --- /dev/null +++ b/tests/Application/templates/grid/action/delete.html.twig @@ -0,0 +1,9 @@ +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('delete')), options.link.parameters|default({'id': data.id}))) %} + +
+ + + +
diff --git a/tests/Application/templates/grid/action/show.html.twig b/tests/Application/templates/grid/action/show.html.twig new file mode 100644 index 00000000..b3961e64 --- /dev/null +++ b/tests/Application/templates/grid/action/show.html.twig @@ -0,0 +1,3 @@ +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('show')), options.link.parameters|default({'id': data.id}))) %} + +Show diff --git a/tests/Application/templates/grid/action/update.html.twig b/tests/Application/templates/grid/action/update.html.twig new file mode 100644 index 00000000..e82376f0 --- /dev/null +++ b/tests/Application/templates/grid/action/update.html.twig @@ -0,0 +1,3 @@ +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('update')), options.link.parameters|default({'id': data.id}))) %} + +Edit diff --git a/tests/Application/templates/grid/bulk_action/apply_transition.html.twig b/tests/Application/templates/grid/bulk_action/apply_transition.html.twig new file mode 100644 index 00000000..a2996eda --- /dev/null +++ b/tests/Application/templates/grid/bulk_action/apply_transition.html.twig @@ -0,0 +1,15 @@ +{% set labeled = true %} +{% set message = action.label %} +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('bulk_update')), options.link.parameters|default({}))) %} + +
+ + + + + {% for resource in grid.data %} + + {% endfor %} +
diff --git a/tests/Application/templates/grid/bulk_action/delete.html.twig b/tests/Application/templates/grid/bulk_action/delete.html.twig new file mode 100644 index 00000000..bfa9becc --- /dev/null +++ b/tests/Application/templates/grid/bulk_action/delete.html.twig @@ -0,0 +1,13 @@ +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('bulk_delete')), options.link.parameters|default({}))) %} + +
+ + + + + {% for resource in grid.data %} + + {% endfor %} +
diff --git a/tests/Application/translations/messages.en.yaml b/tests/Application/translations/messages.en.yaml index 0b4ebc5f..1e722053 100644 --- a/tests/Application/translations/messages.en.yaml +++ b/tests/Application/translations/messages.en.yaml @@ -1,3 +1,5 @@ app: ui: + authors: Authors board_games: Board games + books: Books