From 5199de1d66d571cfc34d9ec1301662c4b2b52456 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Fri, 8 Sep 2023 16:40:09 +0100 Subject: [PATCH 1/2] Fixes index views on nested model route bindings --- src/Pipeline/MatchWildcardDirectories.php | 15 +++++++--- tests/Feature/Console/ListCommandTest.php | 9 ++++-- tests/Feature/Fixtures/Movie.php | 17 +++++++++++ tests/Feature/Fixtures/User.php | 5 ++++ tests/Feature/ModelBindingTest.php | 30 +++++++++++++++++++ .../index.blade.php | 3 ++ 6 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 tests/Feature/Fixtures/Movie.php create mode 100644 tests/Feature/resources/views/pages/users/movies/[.Tests.Feature.Fixtures.User]/[.Tests.Feature.Fixtures.Movie]/index.blade.php diff --git a/src/Pipeline/MatchWildcardDirectories.php b/src/Pipeline/MatchWildcardDirectories.php index 350dc4a..7973a1f 100644 --- a/src/Pipeline/MatchWildcardDirectories.php +++ b/src/Pipeline/MatchWildcardDirectories.php @@ -13,16 +13,23 @@ class MatchWildcardDirectories */ public function __invoke(State $state, Closure $next): mixed { - if (! $state->onLastUriSegment() && - $directory = $this->findWildcardDirectory($state->currentDirectory())) { - return new ContinueIterating($state->withData( + if ($directory = $this->findWildcardDirectory($state->currentDirectory())) { + $state = $state->withData( Str::of($directory) ->basename() ->match('/\[(.*)\]/')->value(), $state->currentUriSegment(), )->replaceCurrentUriSegmentWith( Str::of($directory)->basename() - )); + ); + + if (! $state->onLastUriSegment()) { + return new ContinueIterating($state); + } + + if (file_exists($path = $state->currentUriSegmentDirectory().'/index.blade.php')) { + return new MatchedView($path, $state->data); + } } return $next($state); diff --git a/tests/Feature/Console/ListCommandTest.php b/tests/Feature/Console/ListCommandTest.php index dd08667..9e23b8e 100644 --- a/tests/Feature/Console/ListCommandTest.php +++ b/tests/Feature/Console/ListCommandTest.php @@ -41,10 +41,11 @@ GET /podcasts/{podcast}/comments/{comment:id} podcasts/[.Tests.Feature.Fixtures.Podcast]/comments/[.Tests.Feature.Fixtures.Comment-id].blad… GET /posts/{lowerCase}/{upperCase}/{podcast}/{user:email}/show posts.show › posts/[lowerCase]/[UpperCase]/[Podcast]/[User-email]/show.bla… GET /users/articles/{user:wrongColumn} ........................................ user.articles › users/articles/[User-wrong_column].blade.php + GET /users/movies/{user}/{movie} ............... users/movies/[.Tests.Feature.Fixtures.User]/[.Tests.Feature.Fixtures.Movie]/index.blade.php GET /users/nuno .......................................................................................... users.nuno › users/nuno.blade.php GET /users/{id} .......................................................................................... users.show › users/[id].blade.php - Showing [17] routes + Showing [18] routes EOF); @@ -128,10 +129,11 @@ GET /non-routables/{nonRoutable} ............................................. non-routables/[.Tests.Feature.Fixtures.NonRoutable].blade.php GET /posts/{lowerCase}/{upperCase}/{podcast}/{user:email}/show posts.show › posts/[lowerCase]/[UpperCase]/[Podcast]/[User-email]/show.bla… GET /users/articles/{user:wrongColumn} ........................................ user.articles › users/articles/[User-wrong_column].blade.php + GET /users/movies/{user}/{movie} ............... users/movies/[.Tests.Feature.Fixtures.User]/[.Tests.Feature.Fixtures.Movie]/index.blade.php GET /users/nuno .......................................................................................... users.nuno › users/nuno.blade.php GET /users/{id} .......................................................................................... users.show › users/[id].blade.php - Showing [12] routes + Showing [13] routes EOF); @@ -230,12 +232,13 @@ GET /podcasts/{podcast}/comments/{comment:id} tests/Feature/resources/views/pages/podcasts/[.Tests.Feature.Fixtures.Podcast]/comments/[.Tes… GET /posts/{lowerCase}/{upperCase}/{podcast}/{user:email}/show posts.show › tests/Feature/resources/views/pages/posts/[lowerCase]/[UpperC… GET /users/articles/{user:wrongColumn} .... user.articles › tests/Feature/resources/views/pages/users/articles/[User-wrong_column].blade.php + GET /users/movies/{user}/{movie} tests/Feature/resources/views/pages/users/movies/[.Tests.Feature.Fixtures.User]/[.Tests.Feature.Fixtures.M… GET /users/nuno ...................................................... users.nuno › tests/Feature/resources/views/pages/users/nuno.blade.php GET /users/{id} ...................................................... users.show › tests/Feature/resources/views/pages/users/[id].blade.php GET /{...user} ................................................................ tests/Feature/resources/views/more-pages/[...User].blade.php GET /{...user}/detail ......................... more-pages.user.detail › tests/Feature/resources/views/more-pages/[...User]/detail.blade.php - Showing [20] routes + Showing [21] routes EOF); diff --git a/tests/Feature/Fixtures/Movie.php b/tests/Feature/Fixtures/Movie.php new file mode 100644 index 0000000..de3288d --- /dev/null +++ b/tests/Feature/Fixtures/Movie.php @@ -0,0 +1,17 @@ +belongsTo(User::class, 'user_id'); + } +} diff --git a/tests/Feature/Fixtures/User.php b/tests/Feature/Fixtures/User.php index d0d1a43..47deb3d 100644 --- a/tests/Feature/Fixtures/User.php +++ b/tests/Feature/Fixtures/User.php @@ -9,6 +9,11 @@ class User extends BaseUser { protected $guarded = []; + public function movies(): HasMany + { + return $this->hasMany(Movie::class); + } + public function books(): HasMany { return $this->hasMany(Book::class); diff --git a/tests/Feature/ModelBindingTest.php b/tests/Feature/ModelBindingTest.php index 6481e06..1e730f4 100644 --- a/tests/Feature/ModelBindingTest.php +++ b/tests/Feature/ModelBindingTest.php @@ -5,8 +5,23 @@ use Laravel\Folio\Pipeline\PotentiallyBindablePathSegment; use Tests\Feature\Fixtures\Event; use Tests\Feature\Fixtures\Podcast; +use Tests\Feature\Fixtures\User; beforeEach(function () { + Schema::create('users', function ($table) { + $table->id(); + $table->string('name'); + $table->string('email')->unique(); + $table->timestamps(); + }); + + Schema::create('movies', function ($table) { + $table->id(); + $table->foreignId('user_id'); + $table->string('name'); + $table->timestamps(); + }); + Schema::create('podcasts', function ($table) { $table->id(); $table->string('name'); @@ -79,6 +94,21 @@ $this->get('/podcasts/missing-id')->assertNotFound(); }); +test('child implicit bindings are resolved', function () { + $user = User::create([ + 'name' => 'test-name', + 'email' => 'test-email@gmail.com', + ]); + + $movie = $user->movies()->create([ + 'name' => 'test-movie-name', + ]); + + $this->get('/users/movies/'.$user->id.'/'.$movie->id)->assertSee( + 'test-name: test-movie-name.', + ); +}); + test('child implicit bindings are scoped to the parent if field is present', function () { $podcast = Podcast::create([ 'name' => 'test-podcast-name', diff --git a/tests/Feature/resources/views/pages/users/movies/[.Tests.Feature.Fixtures.User]/[.Tests.Feature.Fixtures.Movie]/index.blade.php b/tests/Feature/resources/views/pages/users/movies/[.Tests.Feature.Fixtures.User]/[.Tests.Feature.Fixtures.Movie]/index.blade.php new file mode 100644 index 0000000..11a1d38 --- /dev/null +++ b/tests/Feature/resources/views/pages/users/movies/[.Tests.Feature.Fixtures.User]/[.Tests.Feature.Fixtures.Movie]/index.blade.php @@ -0,0 +1,3 @@ +
+ {{ $user->name }}: {{ $movie->name }}. +
From 32b6e4344bd3a09205e60f8926db36ea46c32975 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Fri, 8 Sep 2023 16:44:01 +0100 Subject: [PATCH 2/2] Updates test --- tests/Feature/ModelBindingTest.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/Feature/ModelBindingTest.php b/tests/Feature/ModelBindingTest.php index 1e730f4..7612f9c 100644 --- a/tests/Feature/ModelBindingTest.php +++ b/tests/Feature/ModelBindingTest.php @@ -100,12 +100,16 @@ 'email' => 'test-email@gmail.com', ]); - $movie = $user->movies()->create([ + $user->movies()->create([ 'name' => 'test-movie-name', ]); + $movie = $user->movies()->create([ + 'name' => 'test-movie-name-2', + ]); + $this->get('/users/movies/'.$user->id.'/'.$movie->id)->assertSee( - 'test-name: test-movie-name.', + 'test-name: test-movie-name-2.', ); });