Skip to content

Commit ef5c4bd

Browse files
committed
Add complementary tests for route model binding
1 parent 425e6d2 commit ef5c4bd

File tree

5 files changed

+123
-30
lines changed

5 files changed

+123
-30
lines changed

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,24 @@ for alternative ways to enable route model binding.
543543
public function resolveRouteBinding($value)
544544
{
545545
// Perform the logic to find the given slug in the database...
546-
return $this->where('slug->'.app()->getLocale(), $value)->firstOrFail();
546+
return $this->where($this->getRouteKeyName().'->'.app()->getLocale(), $value)->firstOrFail();
547+
}
548+
```
549+
550+
Laravel 7 and newer has an optional `$field` parameter that allows you to override the route key on specific routes:
551+
552+
```php
553+
// Use the post slug as the route parameter instead of the default ID
554+
Route::get('posts/{post:slug}', ...);
555+
```
556+
557+
The new method would then look like this:
558+
559+
```php
560+
public function resolveRouteBinding($value, $field = null)
561+
{
562+
// Perform the logic to find the given slug in the database...
563+
return $this->where($field ?? $this->getRouteKeyName().'->'.app()->getLocale(), $value)->firstOrFail();
547564
}
548565
```
549566

tests/Stubs/Model.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,17 @@ public function getSlug($locale = null)
4141
*/
4242
public function resolveRouteBinding($parameter, $field = null)
4343
{
44+
$field = $field ?: $this->getRouteKeyName();
45+
4446
// Bypass the database for testing purpose and return
4547
// the current model as if it was found in the database.
46-
if ($this->getRouteKeyName() === 'id') {
48+
if ($this->getRouteKeyName() === 'id' && $field === 'id') {
4749
return $this;
4850
}
4951

5052
// If the parameter is a slug, check if it is in the right language
5153
// and return the current model as if it was found in the database.
52-
$validSlug = $this->attributes['slug'][App::getLocale()];
54+
$validSlug = $this->attributes[$field][App::getLocale()];
5355

5456
if ($validSlug !== $parameter) {
5557
abort(404);

tests/Unit/Middleware/SetLocaleTest.php

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -98,32 +98,6 @@ public function it_sets_the_locale_for_localized_routes_within_route_groups()
9898
$this->assertEquals('nl', $response->original);
9999
}
100100

101-
/** @test */
102-
public function it_allows_for_route_model_binding_using_a_localized_route_key()
103-
{
104-
$this->setSupportedLocales(['en', 'nl']);
105-
$this->setUseLocaleMiddleware(true);
106-
107-
$model = (new Model([
108-
'slug' => [
109-
'en' => 'en-slug',
110-
'nl' => 'nl-slug',
111-
],
112-
]))->setKeyName('slug');
113-
114-
App::instance(Model::class, $model);
115-
116-
Route::localized(function () {
117-
Route::get('route/{model}', function (Model $model) {})
118-
->middleware(['web']);
119-
});
120-
121-
$this->call('GET', '/en/route/en-slug')->assertOk();
122-
$this->call('GET', '/nl/route/nl-slug')->assertOk();
123-
$this->call('GET', '/en/route/nl-slug')->assertNotFound();
124-
$this->call('GET', '/nl/route/en-slug')->assertNotFound();
125-
}
126-
127101
/** @test */
128102
public function it_detects_the_locale_with_localizer_for_non_localized_routes()
129103
{
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace CodeZero\LocalizedRoutes\Tests\Unit;
4+
5+
use CodeZero\LocalizedRoutes\Tests\Stubs\Model;
6+
use CodeZero\LocalizedRoutes\Tests\TestCase;
7+
use Illuminate\Support\Facades\App;
8+
use Illuminate\Support\Facades\Route;
9+
10+
class RouteModelBindingTest extends TestCase
11+
{
12+
/** @test */
13+
public function it_loads_a_route_with_a_localized_route_key_based_on_the_active_locale()
14+
{
15+
$this->setSupportedLocales(['en', 'nl']);
16+
$this->setUseLocaleMiddleware(true);
17+
18+
$model = (new Model([
19+
'slug' => [
20+
'en' => 'en-slug',
21+
'nl' => 'nl-slug',
22+
],
23+
]))->setKeyName('slug');
24+
25+
App::instance(Model::class, $model);
26+
27+
Route::middleware(['web'])->get('test/{model}', function (Model $model) {});
28+
29+
Route::localized(function () {
30+
Route::middleware(['web'])->get('test/{model}', function (Model $model) {});
31+
});
32+
33+
$this->setAppLocale('nl');
34+
35+
$this->get('test/nl-slug')->assertOk();
36+
$this->get('test/en-slug')->assertNotFound();
37+
38+
$this->get('nl/test/nl-slug')->assertOk();
39+
$this->get('nl/test/en-slug')->assertNotFound();
40+
41+
$this->get('en/test/en-slug')->assertOk();
42+
$this->get('en/test/nl-slug')->assertNotFound();
43+
}
44+
45+
/** @test */
46+
public function it_loads_a_route_with_a_custom_localized_route_key_based_on_the_active_locale()
47+
{
48+
$this->setSupportedLocales(['en', 'nl']);
49+
$this->setUseLocaleMiddleware(true);
50+
51+
$model = (new Model([
52+
'slug' => [
53+
'en' => 'en-slug',
54+
'nl' => 'nl-slug',
55+
],
56+
]))->setKeyName('id');
57+
58+
App::instance(Model::class, $model);
59+
60+
Route::middleware(['web'])->get('test/{model:slug}', function (Model $model) {});
61+
62+
Route::localized(function () {
63+
Route::middleware(['web'])->get('test/{model:slug}', function (Model $model) {});
64+
});
65+
66+
$this->setAppLocale('nl');
67+
68+
$this->get('test/nl-slug')->assertOk();
69+
$this->get('test/en-slug')->assertNotFound();
70+
71+
$this->get('nl/test/nl-slug')->assertOk();
72+
$this->get('nl/test/en-slug')->assertNotFound();
73+
74+
$this->get('en/test/en-slug')->assertOk();
75+
$this->get('en/test/nl-slug')->assertNotFound();
76+
}
77+
}

tests/Unit/UrlGeneratorTest.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public function it_throws_if_you_do_not_specify_a_name_for_a_localized_route()
163163
}
164164

165165
/** @test */
166-
public function it_temporarily_changes_the_app_locale_when_generating_a_route_url()
166+
public function it_generates_a_url_for_a_route_with_a_default_localized_route_key()
167167
{
168168
$this->setSupportedLocales(['en', 'nl']);
169169
$this->setAppLocale('en');
@@ -185,6 +185,29 @@ public function it_temporarily_changes_the_app_locale_when_generating_a_route_ur
185185
$this->assertEquals(url('nl/route/nl-slug'), route('route.name', [$model], true, 'nl'));
186186
}
187187

188+
/** @test */
189+
public function it_generates_a_url_for_a_route_with_a_custom_localized_route_key()
190+
{
191+
$this->setSupportedLocales(['en', 'nl']);
192+
$this->setAppLocale('en');
193+
194+
$model = (new Model([
195+
'slug' => [
196+
'en' => 'en-slug',
197+
'nl' => 'nl-slug',
198+
],
199+
]))->setKeyName('id');
200+
201+
App::instance(Model::class, $model);
202+
203+
$this->registerRoute('en/route/{model:slug}', 'en.route.name');
204+
$this->registerRoute('nl/route/{model:slug}', 'nl.route.name');
205+
206+
$this->assertEquals(url('en/route/en-slug'), route('route.name', [$model]));
207+
$this->assertEquals(url('en/route/en-slug'), route('route.name', [$model], true, 'en'));
208+
$this->assertEquals(url('nl/route/nl-slug'), route('route.name', [$model], true, 'nl'));
209+
}
210+
188211
/** @test */
189212
public function it_generates_a_signed_route_url_for_the_current_locale()
190213
{

0 commit comments

Comments
 (0)