Browse Source

Fix bug in normalizing URL

shalvah 2 years ago
parent
commit
d0e7e3a4b2

+ 8 - 4
src/Extracting/Shared/UrlParamsNormalizer.php

@@ -30,7 +30,7 @@ class UrlParamsNormalizer
         $uri = $route->uri;
         preg_match_all('#\{(\w+?)}#', $uri, $params);
 
-        $resourceRouteNames = [".index", ".show", ".update", ".destroy"];
+        $resourceRouteNames = [".index", ".show", ".update", ".destroy", ".store"];
 
         $typeHintedEloquentModels = self::getTypeHintedEloquentModels($method);
         $routeName = $route->action['as'] ?? '';
@@ -42,7 +42,11 @@ class UrlParamsNormalizer
             $alreadyFoundResourceParam = false;
             foreach (array_reverse($pluralResources) as $pluralResource) {
                 $singularResource = Str::singular($pluralResource);
-                $singularResourceParam = str_replace('-', '_', $singularResource); // URL parameters are often declared with _ in Laravel but - outside
+
+                // Laravel turns hyphens in parameters to underscores
+                // (`cool-things/{cool-thing}` to `cool-things/{cool_thing_id}`)
+                // so we do the same
+                $singularResourceParam = str_replace('-', '_', $singularResource);
 
                 $urlPatternsToSearchFor = [
                     "{$pluralResource}/{{$singularResourceParam}}",
@@ -63,10 +67,10 @@ class UrlParamsNormalizer
                 } else {
                     // Other resource parameters will be `params/{<param>_id}`
                     $replaceWith = [
-                        "{$pluralResource}/{{$singularResource}_{$binding}}",
                         "{$pluralResource}/{{$singularResourceParam}_{$binding}}",
-                        "{$pluralResource}/{{$singularResource}_{$binding}?}",
+                        "{$pluralResource}/{{$singularResource}_{$binding}}",
                         "{$pluralResource}/{{$singularResourceParam}_{$binding}?}",
+                        "{$pluralResource}/{{$singularResource}_{$binding}?}",
                     ];
                 }
                 $uri = str_replace($urlPatternsToSearchFor, $replaceWith, $uri);

+ 6 - 0
tests/Unit/ExtractedEndpointDataTest.php

@@ -59,6 +59,12 @@ class ExtractedEndpointDataTest extends BaseLaravelTest
 
         $this->assertEquals('audio-things/{audio_thing}', $this->originalUri($route));
         $this->assertEquals('audio-things/{id}', $this->expectedUri($route));
+
+        Route::apiResource('big-users.audio-things.things', TestController::class)->only('store');
+        $route = $this->getRoute(['prefixes' => '*big-users*']);
+
+        $this->assertEquals('big-users/{big_user}/audio-things/{audio_thing}/things', $this->originalUri($route));
+        $this->assertEquals('big-users/{big_user_id}/audio-things/{audio_thing_id}/things', $this->expectedUri($route));
     }
 
     /** @test */