Browse Source

Improve duplicate routes check.

Instead of just checking for duplicate templates check their methods too.
ADmad 3 years ago
parent
commit
22ac2597b8
2 changed files with 60 additions and 17 deletions
  1. 28 17
      src/Command/RoutesCommand.php
  2. 32 0
      tests/TestCase/Command/RoutesCommandTest.php

+ 28 - 17
src/Command/RoutesCommand.php

@@ -44,7 +44,7 @@ class RoutesCommand extends Command
         $output = $duplicateRoutesCounter = [];
 
         foreach ($availableRoutes as $route) {
-            $methods = $route->defaults['_method'] ?? '';
+            $methods = isset($route->defaults['_method']) ? (array)$route->defaults['_method'] : [''];
 
             $item = [
                 $route->options['_name'] ?? $route->getName(),
@@ -53,7 +53,7 @@ class RoutesCommand extends Command
                 $route->defaults['prefix'] ?? '',
                 $route->defaults['controller'] ?? '',
                 $route->defaults['action'] ?? '',
-                is_string($methods) ? $methods : implode(', ', $methods),
+                implode(', ', $methods),
             ];
 
             if ($args->getOption('verbose')) {
@@ -63,10 +63,13 @@ class RoutesCommand extends Command
 
             $output[] = $item;
 
-            if (!isset($duplicateRoutesCounter[$route->template])) {
-                $duplicateRoutesCounter[$route->template] = 0;
+            foreach ($methods as $method) {
+                if (!isset($duplicateRoutesCounter[$route->template][$method])) {
+                    $duplicateRoutesCounter[$route->template][$method] = 0;
+                }
+
+                $duplicateRoutesCounter[$route->template][$method]++;
             }
-            $duplicateRoutesCounter[$route->template]++;
         }
 
         if ($args->getOption('sort')) {
@@ -83,18 +86,26 @@ class RoutesCommand extends Command
         $duplicateRoutes = [];
 
         foreach ($availableRoutes as $route) {
-            if ($duplicateRoutesCounter[$route->template] > 1) {
-                $methods = $route->defaults['_method'] ?? '';
-
-                $duplicateRoutes[] = [
-                    $route->options['_name'] ?? $route->getName(),
-                    $route->template,
-                    $route->defaults['plugin'] ?? '',
-                    $route->defaults['prefix'] ?? '',
-                    $route->defaults['controller'] ?? '',
-                    $route->defaults['action'] ?? '',
-                    is_string($methods) ? $methods : implode(', ', $methods),
-                ];
+            $methods = isset($route->defaults['_method']) ? (array)$route->defaults['_method'] : [''];
+
+            foreach ($methods as $method) {
+                if (
+                    $duplicateRoutesCounter[$route->template][$method] > 1 ||
+                    ($method === '' && count($duplicateRoutesCounter[$route->template]) > 1) ||
+                    ($method !== '' && isset($duplicateRoutesCounter[$route->template]['']))
+                ) {
+                    $duplicateRoutes[] = [
+                        $route->options['_name'] ?? $route->getName(),
+                        $route->template,
+                        $route->defaults['plugin'] ?? '',
+                        $route->defaults['prefix'] ?? '',
+                        $route->defaults['controller'] ?? '',
+                        $route->defaults['action'] ?? '',
+                        implode(', ', $methods),
+                    ];
+
+                    break;
+                }
             }
         }
 

+ 32 - 0
tests/TestCase/Command/RoutesCommandTest.php

@@ -299,6 +299,20 @@ class RoutesCommandTest extends TestCase
             new Route('/unique-path', [], ['_name' => '_bRoute'])
         );
 
+        $builder->connect(
+            new Route('/blog', ['_method' => 'GET'], ['_name' => 'blog-get'])
+        );
+        $builder->connect(
+            new Route('/blog', [], ['_name' => 'blog-all'])
+        );
+
+        $builder->connect(
+            new Route('/events', ['_method' => ['POST', 'PUT']], ['_name' => 'events-post'])
+        );
+        $builder->connect(
+            new Route('/events', ['_method' => 'GET'], ['_name' => 'events-get'])
+        );
+
         $this->exec('routes');
         $this->assertExitCode(Command::CODE_SUCCESS);
         $this->assertOutputContainsRow([
@@ -328,5 +342,23 @@ class RoutesCommandTest extends TestCase
             '',
             '',
         ]);
+        $this->assertOutputContainsRow([
+            'blog-get',
+            '/blog',
+            '',
+            '',
+            '',
+            '',
+            '',
+        ]);
+        $this->assertOutputContainsRow([
+            'blog-all',
+            '/blog',
+            '',
+            '',
+            '',
+            '',
+            '',
+        ]);
     }
 }