RouteMatcherDingoTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <?php
  2. namespace Knuckles\Scribe\Tests\Unit;
  3. use Dingo\Api\Routing\Router;
  4. use Illuminate\Support\Str;
  5. use Knuckles\Scribe\Matching\RouteMatcher;
  6. use Knuckles\Scribe\Tests\BaseLaravelTest;
  7. /**
  8. * @group dingo
  9. */
  10. class RouteMatcherDingoTest extends BaseLaravelTest
  11. {
  12. protected function getPackageProviders($app)
  13. {
  14. return [
  15. \Dingo\Api\Provider\LaravelServiceProvider::class,
  16. ];
  17. }
  18. /** @test */
  19. public function respects_domains_rule_for_dingo_router()
  20. {
  21. $this->registerDingoRoutes();
  22. $routeRules[0]['match']['versions'] = ['v1'];
  23. $routeRules[0]['match']['prefixes'] = ['*'];
  24. $routeRules[0]['match']['domains'] = ['*'];
  25. $matcher = new RouteMatcher();
  26. $routes = $matcher->getRoutes($routeRules, 'dingo');
  27. $this->assertCount(12, $routes);
  28. $routeRules[0]['match']['domains'] = ['domain1.*', 'domain2.*'];
  29. $matcher = new RouteMatcher();
  30. $routes = $matcher->getRoutes($routeRules, 'dingo');
  31. $this->assertCount(12, $routes);
  32. $routeRules[0]['match']['domains'] = ['domain1.*'];
  33. $matcher = new RouteMatcher();
  34. $routes = $matcher->getRoutes($routeRules, 'dingo');
  35. $this->assertCount(6, $routes);
  36. foreach ($routes as $route) {
  37. $this->assertStringContainsString('domain1', $route['route']->getDomain());
  38. }
  39. $routeRules[0]['match']['domains'] = ['domain2.*'];
  40. $matcher = new RouteMatcher();
  41. $routes = $matcher->getRoutes($routeRules, 'dingo');
  42. $this->assertCount(6, $routes);
  43. foreach ($routes as $route) {
  44. $this->assertStringContainsString('domain2', $route['route']->getDomain());
  45. }
  46. }
  47. /** @test */
  48. public function respects_prefixes_rule_for_dingo_router()
  49. {
  50. $this->registerDingoRoutes();
  51. $routeRules[0]['match']['versions'] = ['v1'];
  52. $routeRules[0]['match']['domains'] = ['*'];
  53. $routeRules[0]['match']['prefixes'] = ['*'];
  54. $matcher = new RouteMatcher();
  55. $routes = $matcher->getRoutes($routeRules, 'dingo');
  56. $this->assertCount(12, $routes);
  57. $routeRules[0]['match']['prefixes'] = ['prefix1/*', 'prefix2/*'];
  58. $matcher = new RouteMatcher();
  59. $routes = $matcher->getRoutes($routeRules, 'dingo');
  60. $this->assertCount(8, $routes);
  61. $routeRules[0]['match']['prefixes'] = ['prefix1/*'];
  62. $matcher = new RouteMatcher();
  63. $routes = $matcher->getRoutes($routeRules, 'dingo');
  64. $this->assertCount(4, $routes);
  65. foreach ($routes as $route) {
  66. $this->assertTrue(Str::is('prefix1/*', $route['route']->uri()));
  67. }
  68. $routeRules[0]['match']['prefixes'] = ['prefix2/*'];
  69. $matcher = new RouteMatcher();
  70. $routes = $matcher->getRoutes($routeRules, 'dingo');
  71. $this->assertCount(4, $routes);
  72. foreach ($routes as $route) {
  73. $this->assertTrue(Str::is('prefix2/*', $route['route']->uri()));
  74. }
  75. }
  76. /** @test */
  77. public function respects_versions_rule_for_dingo_router()
  78. {
  79. $this->registerDingoRoutes();
  80. $routeRules[0]['match']['versions'] = ['v2'];
  81. $routeRules[0]['match']['domains'] = ['*'];
  82. $routeRules[0]['match']['prefixes'] = ['*'];
  83. $matcher = new RouteMatcher();
  84. $routes = $matcher->getRoutes($routeRules, 'dingo');
  85. $this->assertCount(6, $routes);
  86. foreach ($routes as $route) {
  87. $this->assertNotEmpty(array_intersect($route['route']->versions(), ['v2']));
  88. }
  89. $routeRules[0]['match']['versions'] = ['v1', 'v2'];
  90. $routeRules[0]['match']['domains'] = ['*'];
  91. $routeRules[0]['match']['prefixes'] = ['*'];
  92. $matcher = new RouteMatcher();
  93. $routes = $matcher->getRoutes($routeRules, 'dingo');
  94. $this->assertCount(18, $routes);
  95. }
  96. /** @test */
  97. public function includes_route_if_listed_explicitly_for_dingo_router()
  98. {
  99. $this->registerDingoRoutes();
  100. $mustInclude = 'v2.domain2';
  101. $routeRules = [
  102. [
  103. 'match' => [
  104. 'domains' => ['domain1.*'],
  105. 'prefixes' => ['prefix1/*'],
  106. 'versions' => ['v1'],
  107. ],
  108. 'include' => [$mustInclude],
  109. ],
  110. ];
  111. $matcher = new RouteMatcher();
  112. $routes = $matcher->getRoutes($routeRules, 'dingo');
  113. $oddRuleOut = collect($routes)->filter(function ($route) use ($mustInclude) {
  114. return $route['route']->getName() === $mustInclude;
  115. });
  116. $this->assertCount(1, $oddRuleOut);
  117. }
  118. /** @test */
  119. public function includes_route_if_match_for_an_include_pattern_for_dingo_router()
  120. {
  121. $this->registerDingoRoutes();
  122. $mustInclude = ['v2.domain1', 'v2.domain2'];
  123. $includePattern = 'v2.domain*';
  124. $routeRules = [
  125. [
  126. 'match' => [
  127. 'domains' => ['domain1.*'],
  128. 'prefixes' => ['prefix1/*'],
  129. 'versions' => ['v1'],
  130. ],
  131. 'include' => [$includePattern],
  132. ],
  133. ];
  134. $matcher = new RouteMatcher();
  135. $routes = $matcher->getRoutes($routeRules, 'dingo');
  136. $oddRuleOut = collect($routes)->filter(function ($route) use ($mustInclude) {
  137. return in_array($route['route']->getName(), $mustInclude);
  138. });
  139. $this->assertCount(count($mustInclude), $oddRuleOut);
  140. }
  141. /** @test */
  142. public function excludes_route_if_listed_explicitly_for_dingo_router()
  143. {
  144. $this->registerDingoRoutes();
  145. $mustNotInclude = 'v2.domain2';
  146. $routeRules = [
  147. [
  148. 'match' => [
  149. 'domains' => ['domain2.*'],
  150. 'prefixes' => ['*'],
  151. 'versions' => ['v2'],
  152. ],
  153. 'exclude' => [$mustNotInclude],
  154. ],
  155. ];
  156. $matcher = new RouteMatcher();
  157. $routes = $matcher->getRoutes($routeRules, 'dingo');
  158. $oddRuleOut = collect($routes)->filter(function ($route) use ($mustNotInclude) {
  159. return $route['route']->getName() === $mustNotInclude;
  160. });
  161. $this->assertCount(0, $oddRuleOut);
  162. }
  163. /** @test */
  164. public function excludes_route_if_match_for_an_exclude_patter_for_dingo_router()
  165. {
  166. $this->registerDingoRoutes();
  167. $mustNotInclude = ['v2.prefix1.domain2', 'v2.prefix2.domain2'];
  168. $excludePattern = 'v2.*.domain2';
  169. $routeRules = [
  170. [
  171. 'match' => [
  172. 'domains' => ['domain2.*'],
  173. 'prefixes' => ['*'],
  174. 'versions' => ['v2'],
  175. ],
  176. 'exclude' => [$excludePattern],
  177. ],
  178. ];
  179. $matcher = new RouteMatcher();
  180. $routes = $matcher->getRoutes($routeRules, 'dingo');
  181. $oddRuleOut = collect($routes)->filter(function ($route) use ($mustNotInclude) {
  182. return in_array($route['route']->getName(), $mustNotInclude);
  183. });
  184. $this->assertCount(0, $oddRuleOut);
  185. }
  186. /** @test */
  187. public function merges_routes_from_different_rule_groups_for_dingo_router()
  188. {
  189. $this->registerDingoRoutes();
  190. $routeRules = [
  191. [
  192. 'match' => [
  193. 'domains' => ['*'],
  194. 'prefixes' => ['*'],
  195. 'versions' => ['v1'],
  196. ],
  197. ],
  198. [
  199. 'match' => [
  200. 'domains' => ['*'],
  201. 'prefixes' => ['*'],
  202. 'versions' => ['v2'],
  203. ],
  204. ],
  205. ];
  206. $matcher = new RouteMatcher();
  207. $routes = $matcher->getRoutes($routeRules, 'dingo');
  208. $this->assertCount(18, $routes);
  209. $routes = collect($routes);
  210. $firstRuleGroup = $routes->filter(function ($route) {
  211. return ! empty(array_intersect($route['route']->versions(), ['v1']));
  212. });
  213. $this->assertCount(12, $firstRuleGroup);
  214. $secondRuleGroup = $routes->filter(function ($route) {
  215. return ! empty(array_intersect($route['route']->versions(), ['v2']));
  216. });
  217. $this->assertCount(6, $secondRuleGroup);
  218. }
  219. private function registerDingoRoutes()
  220. {
  221. $api = app('api.router');
  222. $api->version('v1', function (Router $api) {
  223. $api->group(['domain' => 'domain1.app.test'], function (Router $api) {
  224. $api->post('/domain1-1', function () {
  225. return 'hi';
  226. })->name('v1.domain1-1');
  227. $api->get('domain1-2', function () {
  228. return 'hi';
  229. })->name('v1.domain1-2');
  230. $api->get('/prefix1/domain1-1', function () {
  231. return 'hi';
  232. })->name('v1.prefix1.domain1-1');
  233. $api->get('prefix1/domain1-2', function () {
  234. return 'hi';
  235. })->name('v1.prefix1.domain1-2');
  236. $api->get('/prefix2/domain1-1', function () {
  237. return 'hi';
  238. })->name('v1.prefix2.domain1-1');
  239. $api->get('prefix2/domain1-2', function () {
  240. return 'hi';
  241. })->name('v1.prefix2.domain1-2');
  242. });
  243. $api->group(['domain' => 'domain2.app.test'], function (Router $api) {
  244. $api->post('/domain2-1', function () {
  245. return 'hi';
  246. })->name('v1.domain2-1');
  247. $api->get('domain2-2', function () {
  248. return 'hi';
  249. })->name('v1.domain2-2');
  250. $api->get('/prefix1/domain2-1', function () {
  251. return 'hi';
  252. })->name('v1.prefix1.domain2-1');
  253. $api->get('prefix1/domain2-2', function () {
  254. return 'hi';
  255. })->name('v1.prefix1.domain2-2');
  256. $api->get('/prefix2/domain2-1', function () {
  257. return 'hi';
  258. })->name('v1.prefix2.domain2-1');
  259. $api->get('prefix2/domain2-2', function () {
  260. return 'hi';
  261. })->name('v1.prefix2.domain2-2');
  262. });
  263. });
  264. $api->version('v2', function (Router $api) {
  265. $api->group(['domain' => 'domain1.app.test'], function (Router $api) {
  266. $api->post('/domain1', function () {
  267. return 'hi';
  268. })->name('v2.domain1');
  269. $api->get('/prefix1/domain1', function () {
  270. return 'hi';
  271. })->name('v2.prefix1.domain1');
  272. $api->get('/prefix2/domain1', function () {
  273. return 'hi';
  274. })->name('v2.prefix2.domain1');
  275. });
  276. $api->group(['domain' => 'domain2.app.test'], function (Router $api) {
  277. $api->post('/domain2', function () {
  278. return 'hi';
  279. })->name('v2.domain2');
  280. $api->get('/prefix1/domain2', function () {
  281. return 'hi';
  282. })->name('v2.prefix1.domain2');
  283. $api->get('/prefix2/domain2', function () {
  284. return 'hi';
  285. })->name('v2.prefix2.domain2');
  286. });
  287. });
  288. }
  289. }