RouteMatcherTest.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. namespace Knuckles\Scribe\Tests\Unit;
  3. use Illuminate\Support\Facades\Route as RouteFacade;
  4. use Illuminate\Support\Str;
  5. use Knuckles\Scribe\Matching\RouteMatcher;
  6. use Knuckles\Scribe\Tests\BaseLaravelTest;
  7. class RouteMatcherTest extends BaseLaravelTest
  8. {
  9. /** @test */
  10. public function respects_domains_rule_for_laravel_router()
  11. {
  12. $this->registerLaravelRoutes();
  13. $routeRules[0]['match']['prefixes'] = ['*'];
  14. $routeRules[0]['match']['domains'] = ['*'];
  15. $this->assertCount(12, $this->matchRoutes($routeRules));
  16. $routeRules[0]['match']['domains'] = ['domain1.*', 'domain2.*'];
  17. $this->assertCount(12, $this->matchRoutes($routeRules));
  18. $routeRules[0]['match']['domains'] = ['domain1.*'];
  19. $routes = $this->matchRoutes($routeRules);
  20. $this->assertCount(6, $routes);
  21. foreach ($routes as $route) {
  22. $this->assertStringContainsString('domain1', $route['route']->getDomain());
  23. }
  24. $routeRules[0]['match']['domains'] = ['domain2.*'];
  25. $routes = $this->matchRoutes($routeRules);
  26. $this->assertCount(6, $routes);
  27. foreach ($routes as $route) {
  28. $this->assertStringContainsString('domain2', $route['route']->getDomain());
  29. }
  30. }
  31. /** @test */
  32. public function respects_prefixes_rule_for_laravel_router()
  33. {
  34. $this->registerLaravelRoutes();
  35. $routeRules[0]['match']['domains'] = ['*'];
  36. $routeRules[0]['match']['prefixes'] = ['*'];
  37. $this->assertCount(12, $this->matchRoutes($routeRules));
  38. $routeRules[0]['match']['prefixes'] = ['prefix1/*', 'prefix2/*'];
  39. $this->assertCount(8, $this->matchRoutes($routeRules));
  40. $routeRules[0]['match']['prefixes'] = ['prefix1/*'];
  41. $routes = $this->matchRoutes($routeRules);
  42. $this->assertCount(4, $routes);
  43. foreach ($routes as $route) {
  44. $this->assertTrue(Str::is('prefix1/*', $route['route']->uri()));
  45. }
  46. $routeRules[0]['match']['prefixes'] = ['prefix2/*'];
  47. $routes = $this->matchRoutes($routeRules);
  48. $this->assertCount(4, $routes);
  49. foreach ($routes as $route) {
  50. $this->assertTrue(Str::is('prefix2/*', $route['route']->uri()));
  51. }
  52. }
  53. /** @test */
  54. public function includes_route_if_listed_explicitly_for_laravel_router()
  55. {
  56. $this->registerLaravelRoutes();
  57. $mustInclude = 'domain1-1';
  58. $routeRules[0]['include'] = [$mustInclude];
  59. $routeRules[0]['match']['domains'] = ['domain1.*'];
  60. $routeRules[0]['match']['prefixes'] = ['prefix1/*'];
  61. $routes = $this->matchRoutes($routeRules);
  62. $oddRuleOut = collect($routes)->filter(fn($route) => $route['route']->getName() === $mustInclude);
  63. $this->assertCount(1, $oddRuleOut);
  64. }
  65. /** @test */
  66. public function includes_route_if_match_for_an_include_pattern_for_laravel_router()
  67. {
  68. $this->registerLaravelRoutes();
  69. $mustInclude = ['domain1-1', 'domain1-2'];
  70. $includePattern = 'domain1-*';
  71. $routeRules[0]['include'] = [$includePattern];
  72. $routeRules[0]['match']['domains'] = ['domain1.*'];
  73. $routeRules[0]['match']['prefixes'] = ['prefix1/*'];
  74. $routes = $this->matchRoutes($routeRules);
  75. $oddRuleOut = collect($routes)->filter(fn($route) => in_array($route['route']->getName(), $mustInclude));
  76. $this->assertCount(count($mustInclude), $oddRuleOut);
  77. }
  78. /** @test */
  79. public function exclude_route_if_listed_explicitly_for_laravel_router()
  80. {
  81. $this->registerLaravelRoutes();
  82. $mustNotInclude = 'prefix1.domain1-1';
  83. $routeRules[0]['exclude'] = [$mustNotInclude];
  84. $routeRules[0]['match']['domains'] = ['domain1.*'];
  85. $routeRules[0]['match']['prefixes'] = ['prefix1/*'];
  86. $routes = $this->matchRoutes($routeRules);
  87. $oddRuleOut = collect($routes)->filter(fn($route) => $route['route']->getName() === $mustNotInclude);
  88. $this->assertCount(0, $oddRuleOut);
  89. }
  90. /** @test */
  91. public function exclude_route_if_match_for_an_exclude_pattern_for_laravel_router()
  92. {
  93. $this->registerLaravelRoutes();
  94. $mustNotInclude = ['prefix1.domain1-1', 'prefix1.domain1-2'];
  95. $excludePattern = 'prefix1.domain1-*';
  96. $routeRules[0]['exclude'] = [$excludePattern];
  97. $routeRules[0]['match']['domains'] = ['domain1.*'];
  98. $routeRules[0]['match']['prefixes'] = ['prefix1/*'];
  99. $routes = $this->matchRoutes($routeRules);
  100. $oddRuleOut = collect($routes)->filter(fn($route) => in_array($route['route']->getName(), $mustNotInclude));
  101. $this->assertCount(0, $oddRuleOut);
  102. }
  103. /** @test */
  104. public function merges_routes_from_different_rule_groups_for_laravel_router()
  105. {
  106. $this->registerLaravelRoutes();
  107. $routeRules = [
  108. [
  109. 'match' => [
  110. 'domains' => ['domain1.*'],
  111. 'prefixes' => ['prefix1/*'],
  112. ],
  113. ],
  114. [
  115. 'match' => [
  116. 'domains' => ['domain2.*'],
  117. 'prefixes' => ['prefix2*'],
  118. ],
  119. ],
  120. ];
  121. $this->assertCount(4, $this->matchRoutes($routeRules));
  122. $routes = collect($this->matchRoutes($routeRules));
  123. $firstRuleGroup = $routes->filter(function ($route) {
  124. return Str::is('prefix1/*', $route['route']->uri())
  125. && Str::is('domain1.*', $route['route']->getDomain());
  126. });
  127. $this->assertCount(2, $firstRuleGroup);
  128. $secondRuleGroup = $routes->filter(function ($route) {
  129. return Str::is('prefix2/*', $route['route']->uri())
  130. && Str::is('domain2.*', $route['route']->getDomain());
  131. });
  132. $this->assertCount(2, $secondRuleGroup);
  133. }
  134. private function registerLaravelRoutes()
  135. {
  136. RouteFacade::group(['domain' => 'domain1.app.test'], function () {
  137. RouteFacade::post('/domain1-1', function () {
  138. return 'hi';
  139. })->name('domain1-1');
  140. RouteFacade::get('domain1-2', function () {
  141. return 'hi';
  142. })->name('domain1-2');
  143. RouteFacade::get('/prefix1/domain1-1', function () {
  144. return 'hi';
  145. })->name('prefix1.domain1-1');
  146. RouteFacade::get('prefix1/domain1-2', function () {
  147. return 'hi';
  148. })->name('prefix1.domain1-2');
  149. RouteFacade::get('/prefix2/domain1-1', function () {
  150. return 'hi';
  151. })->name('prefix2.domain1-1');
  152. RouteFacade::get('prefix2/domain1-2', function () {
  153. return 'hi';
  154. })->name('prefix2.domain1-2');
  155. });
  156. RouteFacade::group(['domain' => 'domain2.app.test'], function () {
  157. RouteFacade::post('/domain2-1', function () {
  158. return 'hi';
  159. })->name('domain2-1');
  160. RouteFacade::get('domain2-2', function () {
  161. return 'hi';
  162. })->name('domain2-2');
  163. RouteFacade::get('/prefix1/domain2-1', function () {
  164. return 'hi';
  165. })->name('prefix1.domain2-1');
  166. RouteFacade::get('prefix1/domain2-2', function () {
  167. return 'hi';
  168. })->name('prefix1.domain2-2');
  169. RouteFacade::get('/prefix2/domain2-1', function () {
  170. return 'hi';
  171. })->name('prefix2.domain2-1');
  172. RouteFacade::get('prefix2/domain2-2', function () {
  173. return 'hi';
  174. })->name('prefix2.domain2-2');
  175. });
  176. }
  177. protected function matchRoutes(array $routeRules): array
  178. {
  179. $matcher = new RouteMatcher();
  180. return $matcher->getRoutes($routeRules);
  181. }
  182. }