Browse Source

Support matching routes on method + path

Shalvah 1 year ago
parent
commit
57b55ec1ce

+ 4 - 27
phpunit.xml

@@ -26,35 +26,12 @@
         <server name="SCRIBE_TESTS" value="1" />
     </php>
     <testsuites>
-        <testsuite name="Full Test">
-            <file>tests/GenerateDocumentation/OutputTest.php</file>
-            <file>tests/GenerateDocumentation/BehavioursTest.php</file>
-        </testsuite>
-        <testsuite name="Strategies">
+        <testsuite name="Non-Unit Tests">
+            <directory>tests/GenerateDocumentation/OutputTest.php</directory>
             <directory>tests/Strategies</directory>
         </testsuite>
-        <testsuite name="RouteMatcher Tests">
-            <file>tests/Unit/RouteMatcherDingoTest.php</file>
-            <file>tests/Unit/RouteMatcherTest.php</file>
-        </testsuite>
-        <testsuite name="Unit Tests 1">
-            <file>tests/Unit/ExtractorTest.php</file>
-            <file>tests/Unit/ExtractorPluginSystemTest.php</file>
-            <file>tests/Unit/ConfigDifferTest.php</file>
-            <file>tests/Unit/PathConfigurationTest.php</file>
-        </testsuite>
-        <testsuite name="Unit Tests 2">
-            <file>tests/Unit/ExtractedEndpointDataTest.php</file>
-            <file>tests/Unit/AnnotationParserTest.php</file>
-        </testsuite>
-        <testsuite name="Unit Tests 3">
-            <file>tests/Unit/OpenAPISpecWriterTest.php</file>
-            <file>tests/Unit/PostmanCollectionWriterTest.php</file>
-        </testsuite>
-        <testsuite name="Unit Tests 4">
-            <file>tests/Unit/ValidationRuleParsingTest.php</file>
-            <file>tests/Unit/HtmlWriterTest.php</file>
-            <file>tests/Unit/WritingUtilsTest.php</file>
+        <testsuite name="Unit Tests">
+            <directory>tests/Unit</directory>
         </testsuite>
     </testsuites>
 </phpunit>

+ 3 - 3
src/Matching/RouteMatcher.php

@@ -6,6 +6,7 @@ use Dingo\Api\Routing\RouteCollection;
 use Illuminate\Routing\Route;
 use Illuminate\Support\Facades\Route as RouteFacade;
 use Illuminate\Support\Str;
+use Knuckles\Scribe\Tools\RoutePatternMatcher;
 
 class RouteMatcher implements RouteMatcherInterface
 {
@@ -61,7 +62,7 @@ class RouteMatcher implements RouteMatcherInterface
 
     private function shouldIncludeRoute(Route $route, array $routeRule, array $mustIncludes, bool $usingDingoRouter): bool
     {
-        if (Str::is($mustIncludes, $route->getName()) || Str::is($mustIncludes, $route->uri())) {
+        if (RoutePatternMatcher::matches($route, $mustIncludes)) {
             return true;
         }
 
@@ -90,7 +91,6 @@ class RouteMatcher implements RouteMatcherInterface
             $excludes[] = 'telescope/*';
         }
 
-        return Str::is($excludes, $route->getName())
-            || Str::is($excludes, $route->uri());
+        return RoutePatternMatcher::matches($route, $excludes);
     }
 }

+ 31 - 0
src/Tools/RoutePatternMatcher.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace Knuckles\Scribe\Tools;
+
+use Illuminate\Routing\Route;
+use Illuminate\Support\Str;
+
+class RoutePatternMatcher
+{
+    public static function matches(Route $route, $patterns): bool
+    {
+        $routeName = $route->getName();
+        $routePathWithoutInitialSlash = $route->uri();
+        $routePathWithInitialSlash = "/$routePathWithoutInitialSlash";
+        $routeMethods = $route->methods();
+        if (Str::is($patterns, $routeName)
+            || Str::is($patterns, $routePathWithoutInitialSlash)
+            || Str::is($patterns, $routePathWithInitialSlash)) {
+            return true;
+        }
+
+        foreach ($routeMethods as $httpMethod) {
+            if (Str::is($patterns, "$httpMethod $routePathWithoutInitialSlash")
+                || Str::is($patterns, "$httpMethod $routePathWithInitialSlash")) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}

+ 47 - 0
tests/Unit/RoutePatternMatcherTest.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace Knuckles\Scribe\Tests\Unit;
+
+use Illuminate\Routing\Route;
+use Knuckles\Scribe\Tools\RoutePatternMatcher;
+use PHPUnit\Framework\TestCase;
+
+class RoutePatternMatcherTest extends TestCase
+{
+    /** @test */
+    public function matches_by_route_name()
+    {
+        $route = new Route(["POST"], "/abc", ['as' => 'users.show']);
+        $this->assertTrue(RoutePatternMatcher::matches($route, ['users.show']));
+        $this->assertTrue(RoutePatternMatcher::matches($route, ['users.*']));
+        $this->assertFalse(RoutePatternMatcher::matches($route, ['users.index']));
+    }
+
+    /** @test */
+    public function matches_by_route_method_and_path()
+    {
+        $route = new Route(["POST"], "/abc", ['as' => 'users.show']);
+        $this->assertTrue(RoutePatternMatcher::matches($route, ["POST /abc"]));
+        $this->assertTrue(RoutePatternMatcher::matches($route, ["POST abc"]));
+        $this->assertTrue(RoutePatternMatcher::matches($route, ["POST ab*"]));
+        $this->assertTrue(RoutePatternMatcher::matches($route, ["POST /ab*"]));
+        $this->assertTrue(RoutePatternMatcher::matches($route, ["POST *"]));
+
+        $this->assertFalse(RoutePatternMatcher::matches($route, ["GET /abc"]));
+        $this->assertFalse(RoutePatternMatcher::matches($route, ["GET abc"]));
+    }
+
+    /** @test */
+    public function matches_by_route_path()
+    {
+        $route = new Route(["POST"], "/abc", ['as' => 'users.show']);
+        $this->assertTrue(RoutePatternMatcher::matches($route, ["/abc"]));
+        $this->assertTrue(RoutePatternMatcher::matches($route, ["abc"]));
+        $this->assertTrue(RoutePatternMatcher::matches($route, ["ab*"]));
+        $this->assertTrue(RoutePatternMatcher::matches($route, ["/ab*"]));
+        $this->assertTrue(RoutePatternMatcher::matches($route, ["*"]));
+
+        $this->assertFalse(RoutePatternMatcher::matches($route, ["/d*"]));
+    }
+
+}