From 3d4851a3c55878a5fe8631b17a6180c33a2ca508 Mon Sep 17 00:00:00 2001 From: Jacob Baker-Kretzmar Date: Fri, 7 Jan 2022 17:35:50 -0500 Subject: [PATCH 1/4] Add failing test --- tests/js/route.test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/js/route.test.js b/tests/js/route.test.js index ddd93cc2..2e041430 100644 --- a/tests/js/route.test.js +++ b/tests/js/route.test.js @@ -525,6 +525,10 @@ describe('route()', () => { same(route('pages.optionalExtension', '.html'), 'https://ziggy.dev/download/file.html'); same(route('pages.optionalExtension', { extension: '.pdf' }), 'https://ziggy.dev/download/file.pdf'); }); + + test('can skip encoding slashes inside last parameter when explicitly allowed', () => { + same(route('optional', ['1', 'foo/bar']), 'https://ziggy.dev/optional/1/foo/bar') + }); }); describe('has()', () => { From 34225436be4676471f991124636bc8bad9cd40ae Mon Sep 17 00:00:00 2001 From: Jacob Baker-Kretzmar Date: Fri, 14 Jan 2022 13:10:14 -0500 Subject: [PATCH 2/4] Add/update failing tests --- tests/Unit/CommandRouteGeneratorTest.php | 3 ++- tests/Unit/ZiggyTest.php | 24 ++++++++++++++++++++++++ tests/fixtures/ziggy.js | 2 +- tests/js/route.test.js | 17 ++++++++++++----- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/tests/Unit/CommandRouteGeneratorTest.php b/tests/Unit/CommandRouteGeneratorTest.php index 49fd980a..5a9be47e 100644 --- a/tests/Unit/CommandRouteGeneratorTest.php +++ b/tests/Unit/CommandRouteGeneratorTest.php @@ -4,7 +4,6 @@ use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\URL; -use Illuminate\Support\Str; use Tests\TestCase; class CommandRouteGeneratorTest extends TestCase @@ -44,6 +43,7 @@ public function can_generate_file_with_named_routes() { $router = app('router'); $router->get('posts/{post}/comments', $this->noop())->name('postComments.index'); + $router->get('slashes/{slug}', $this->noop())->where('slug', '.*')->name('slashes'); $router->getRoutes()->refreshNameLookups(); Artisan::call('ziggy:generate'); @@ -83,6 +83,7 @@ public function can_generate_file_with_config_applied() config(['ziggy.except' => ['admin.*']]); $router = app('router'); $router->get('posts/{post}/comments', $this->noop())->name('postComments.index'); + $router->get('slashes/{slug}', $this->noop())->where('slug', '.*')->name('slashes'); $router->get('admin', $this->noop())->name('admin.dashboard'); // Excluded, should NOT be present in file $router->getRoutes()->refreshNameLookups(); diff --git a/tests/Unit/ZiggyTest.php b/tests/Unit/ZiggyTest.php index dd1856e3..0c92101f 100644 --- a/tests/Unit/ZiggyTest.php +++ b/tests/Unit/ZiggyTest.php @@ -311,6 +311,27 @@ public function can_include_port() ]); } + /** @test */ + public function can_include_wheres() + { + app('router')->post('slashes/{slug}', function () { + return response()->json(new Ziggy); + })->where('slug', '.*')->name('slashes'); + app('router')->getRoutes()->refreshNameLookups(); + + $this->post('http://ziggy.dev/slashes/foo/bar') + ->assertJson([ + 'routes' => [ + 'slashes' => [ + 'uri' => 'slashes/{slug}', + 'wheres' => [ + 'slug' => '.*', + ], + ], + ], + ]); + } + /** @test */ public function can_include_only_middleware_set_in_config() { @@ -396,6 +417,9 @@ public function can_order_fallback_routes_last() $expected['fallback'] = [ 'uri' => '{fallbackPlaceholder}', 'methods' => ['GET', 'HEAD'], + 'wheres' => [ + 'fallbackPlaceholder' => '.*', + ], ]; $this->assertSame($expected, $routes); diff --git a/tests/fixtures/ziggy.js b/tests/fixtures/ziggy.js index c3a25ba8..5191927e 100644 --- a/tests/fixtures/ziggy.js +++ b/tests/fixtures/ziggy.js @@ -1,4 +1,4 @@ -const Ziggy = {"url":"http:\/\/ziggy.dev","port":null,"defaults":{},"routes":{"postComments.index":{"uri":"posts\/{post}\/comments","methods":["GET","HEAD"]}}}; +const Ziggy = {"url":"http:\/\/ziggy.dev","port":null,"defaults":{},"routes":{"postComments.index":{"uri":"posts\/{post}\/comments","methods":["GET","HEAD"]},"slashes":{"uri":"slashes\/{slug}","methods":["GET","HEAD"],"wheres":{"slug":".*"}}}}; if (typeof window !== 'undefined' && typeof window.Ziggy !== 'undefined') { Object.assign(Ziggy.routes, window.Ziggy.routes); diff --git a/tests/js/route.test.js b/tests/js/route.test.js index 2e041430..e0407451 100644 --- a/tests/js/route.test.js +++ b/tests/js/route.test.js @@ -16,7 +16,7 @@ const defaultZiggy = { port: null, defaults: { locale: 'en' }, routes: { - 'home': { + home: { uri: '/', methods: ['GET', 'HEAD'], }, @@ -96,11 +96,11 @@ const defaultZiggy = { uri: 'subscribers/{subscriber}/conversations/{type}/{conversation_id?}', methods: ['GET', 'HEAD'], }, - 'optional': { + optional: { uri: 'optional/{id}/{slug?}', methods: ['GET', 'HEAD'], }, - 'optionalId': { + optionalId: { uri: 'optionalId/{type}/{id?}', methods: ['GET', 'HEAD'], }, @@ -134,10 +134,17 @@ const defaultZiggy = { uri: 'strict-download/file{extension}', methods: ['GET', 'HEAD'], }, - 'pages': { + pages: { uri: '{page}', methods: ['GET', 'HEAD'], }, + slashes: { + uri: 'slashes/{encoded}/{slug}', + methods: ['GET', 'HEAD'], + wheres: { + slug: '.*', + }, + }, }, }; @@ -527,7 +534,7 @@ describe('route()', () => { }); test('can skip encoding slashes inside last parameter when explicitly allowed', () => { - same(route('optional', ['1', 'foo/bar']), 'https://ziggy.dev/optional/1/foo/bar') + same(route('slashes', ['one/two', 'three/four']), 'https://ziggy.dev/slashes/one%2Ftwo/three/four') }); }); From 93f84fc349021f7d7b2360e4053230a7b900338c Mon Sep 17 00:00:00 2001 From: Jacob Baker-Kretzmar Date: Fri, 14 Jan 2022 13:11:45 -0500 Subject: [PATCH 3/4] Add support for not URI-encoding last route parameter when it has a wildcard regex --- src/Ziggy.php | 2 +- src/js/Route.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Ziggy.php b/src/Ziggy.php index 8bf7af45..b5756f6a 100644 --- a/src/Ziggy.php +++ b/src/Ziggy.php @@ -109,7 +109,7 @@ private function nameKeyedRoutes() return $routes->merge($fallbacks) ->map(function ($route) use ($bindings) { - return collect($route)->only(['uri', 'methods']) + return collect($route)->only(['uri', 'methods', 'wheres']) ->put('domain', $route->domain()) ->put('bindings', $bindings[$route->getName()] ?? []) ->when($middleware = config('ziggy.middleware'), function ($collection) use ($middleware, $route) { diff --git a/src/js/Route.js b/src/js/Route.js index 29e9e66a..70ccdbd5 100644 --- a/src/js/Route.js +++ b/src/js/Route.js @@ -11,6 +11,7 @@ export default class Route { this.name = name; this.definition = definition; this.bindings = definition.bindings ?? {}; + this.wheres = definition.wheres ?? {}; this.config = config; } @@ -85,6 +86,10 @@ export default class Route { throw new Error(`Ziggy error: '${segment}' parameter is required for route '${this.name}'.`) } + if (this.parameterSegments[this.parameterSegments.length - 1].name === segment && this.wheres[segment] === '.*') { + return params[segment] ?? ''; + } + return encodeURIComponent(params[segment] ?? ''); }).replace(/\/+$/, ''); } From 19b0a11e5b9b4c5dfd1ce138cdf31374aea468f2 Mon Sep 17 00:00:00 2001 From: Jacob Baker-Kretzmar Date: Fri, 14 Jan 2022 13:11:48 -0500 Subject: [PATCH 4/4] Wip --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 9499261c..8914cbe3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules/ vendor/ +*.cache *.log composer.lock phpunit.xml