RouteMatcherDingoTest.php 12 KB

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