GeneratorPluginSystemTestCase.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. namespace Mpociot\ApiDoc\Tests\Unit;
  3. use ReflectionClass;
  4. use ReflectionMethod;
  5. use Illuminate\Routing\Route;
  6. use Mpociot\ApiDoc\Tools\Generator;
  7. use Mpociot\ApiDoc\Strategies\Strategy;
  8. use Mpociot\ApiDoc\Tools\DocumentationConfig;
  9. use Mpociot\ApiDoc\Tests\Fixtures\TestController;
  10. use Mpociot\ApiDoc\ApiDocGeneratorServiceProvider;
  11. class GeneratorPluginSystemTestCase extends LaravelGeneratorTest
  12. {
  13. /**
  14. * @var \Mpociot\ApiDoc\Tools\Generator
  15. */
  16. protected $generator;
  17. protected function getPackageProviders($app)
  18. {
  19. return [
  20. ApiDocGeneratorServiceProvider::class,
  21. ];
  22. }
  23. /** @test */
  24. public function only_specified_strategies_are_loaded()
  25. {
  26. $config = [
  27. 'strategies' => [
  28. 'metadata' => [EmptyStrategy1::class],
  29. 'bodyParameters' => [
  30. EmptyStrategy1::class,
  31. EmptyStrategy2::class,
  32. ],
  33. 'responses' => [EmptyStrategy1::class],
  34. ],
  35. ];
  36. $route = $this->createRoute('GET', '/api/test', 'dummy', true, TestController::class);
  37. $generator = new Generator(new DocumentationConfig($config));
  38. $generator->processRoute($route);
  39. // Probably not the best way to do this, but 🤷‍♂️
  40. $this->assertTrue(EmptyStrategy1::$called['metadata']);
  41. $this->assertTrue(EmptyStrategy1::$called['bodyParameters']);
  42. $this->assertTrue(EmptyStrategy2::$called['bodyParameters']);
  43. $this->assertArrayNotHasKey('queryParameters', EmptyStrategy1::$called);
  44. $this->assertTrue(EmptyStrategy1::$called['responses']);
  45. }
  46. /** @test */
  47. public function combines_responses_from_different_strategies()
  48. {
  49. $config = [
  50. 'strategies' => [
  51. 'responses' => [DummyResponseStrategy200::class, DummyResponseStrategy400::class],
  52. ],
  53. ];
  54. $route = $this->createRoute('GET', '/api/test', 'dummy', true, TestController::class);
  55. $generator = new Generator(new DocumentationConfig($config));
  56. $parsed = $generator->processRoute($route);
  57. $this->assertTrue($parsed['showresponse']);
  58. $this->assertCount(2, $parsed['response']);
  59. $first = array_shift($parsed['response']);
  60. $this->assertTrue(is_array($first));
  61. $this->assertEquals(200, $first['status']);
  62. $this->assertEquals('dummy', $first['content']);
  63. $second = array_shift($parsed['response']);
  64. $this->assertTrue(is_array($second));
  65. $this->assertEquals(400, $second['status']);
  66. $this->assertEquals('dummy2', $second['content']);
  67. }
  68. // This is a generalized test, as opposed to the one above for responses only
  69. /** @test */
  70. public function combines_results_from_different_strategies_in_same_stage()
  71. {
  72. $config = [
  73. 'strategies' => [
  74. 'metadata' => [PartialDummyMetadataStrategy1::class, PartialDummyMetadataStrategy2::class],
  75. ],
  76. ];
  77. $route = $this->createRoute('GET', '/api/test', 'dummy', true, TestController::class);
  78. $generator = new Generator(new DocumentationConfig($config));
  79. $parsed = $generator->processRoute($route);
  80. $expectedMetadata = [
  81. 'groupName' => 'dummy',
  82. 'groupDescription' => 'dummy',
  83. 'title' => 'dummy',
  84. 'description' => 'dummy',
  85. 'authenticated' => false,
  86. ];
  87. $this->assertArraySubset($expectedMetadata, $parsed['metadata']); // Forwards-compatibility
  88. $this->assertArraySubset($expectedMetadata, $parsed); // Backwards-compatibility
  89. }
  90. /** @test */
  91. public function missing_metadata_is_filled_in()
  92. {
  93. $config = [
  94. 'strategies' => [
  95. 'metadata' => [PartialDummyMetadataStrategy2::class],
  96. ],
  97. ];
  98. $route = $this->createRoute('GET', '/api/test', 'dummy', true, TestController::class);
  99. $generator = new Generator(new DocumentationConfig($config));
  100. $parsed = $generator->processRoute($route);
  101. $expectedMetadata = [
  102. 'groupName' => '',
  103. 'groupDescription' => 'dummy',
  104. 'title' => '',
  105. 'description' => 'dummy',
  106. 'authenticated' => false,
  107. ];
  108. $this->assertArraySubset($expectedMetadata, $parsed['metadata']); // Forwards-compatibility
  109. $this->assertArraySubset($expectedMetadata, $parsed); // Backwards-compatibility
  110. }
  111. /** @test */
  112. public function overwrites_results_from_previous_strategies_in_same_stage()
  113. {
  114. $config = [
  115. 'strategies' => [
  116. 'responses' => [DummyResponseStrategy200::class, StillDummyResponseStrategyAlso200::class],
  117. ],
  118. ];
  119. $route = $this->createRoute('GET', '/api/test', 'dummy', true, TestController::class);
  120. $generator = new Generator(new DocumentationConfig($config));
  121. $parsed = $generator->processRoute($route);
  122. $this->assertTrue($parsed['showresponse']);
  123. $this->assertCount(1, $parsed['response']);
  124. $first = array_shift($parsed['response']);
  125. $this->assertTrue(is_array($first));
  126. $this->assertEquals(200, $first['status']);
  127. $this->assertEquals('stilldummy', $first['content']);
  128. $config = [
  129. 'strategies' => [
  130. 'metadata' => [NotDummyMetadataStrategy::class, PartialDummyMetadataStrategy1::class],
  131. ],
  132. ];
  133. $route = $this->createRoute('GET', '/api/test', 'dummy', true, TestController::class);
  134. $generator = new Generator(new DocumentationConfig($config));
  135. $parsed = $generator->processRoute($route);
  136. $expectedMetadata = [
  137. 'groupName' => 'dummy',
  138. 'groupDescription' => 'notdummy',
  139. 'title' => 'dummy',
  140. 'description' => 'dummy',
  141. 'authenticated' => false,
  142. ];
  143. $this->assertArraySubset($expectedMetadata, $parsed['metadata']); // Forwards-compatibility
  144. $this->assertArraySubset($expectedMetadata, $parsed); // Backwards-compatibility
  145. }
  146. public function dataResources()
  147. {
  148. return [
  149. [
  150. null,
  151. '{"data":{"id":1,"description":"Welcome on this test versions","name":"TestName"}}',
  152. ],
  153. [
  154. 'League\Fractal\Serializer\JsonApiSerializer',
  155. '{"data":{"type":null,"id":"1","attributes":{"description":"Welcome on this test versions","name":"TestName"}}}',
  156. ],
  157. ];
  158. }
  159. }
  160. class EmptyStrategy1 extends Strategy
  161. {
  162. public static $called = [];
  163. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  164. {
  165. static::$called[$this->stage] = true;
  166. }
  167. }
  168. class EmptyStrategy2 extends Strategy
  169. {
  170. public static $called = [];
  171. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  172. {
  173. static::$called[$this->stage] = true;
  174. }
  175. }
  176. class NotDummyMetadataStrategy extends Strategy
  177. {
  178. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  179. {
  180. return [
  181. 'groupName' => 'notdummy',
  182. 'groupDescription' => 'notdummy',
  183. 'title' => 'notdummy',
  184. 'description' => 'notdummy',
  185. 'authenticated' => true,
  186. ];
  187. }
  188. }
  189. class PartialDummyMetadataStrategy1 extends Strategy
  190. {
  191. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  192. {
  193. return [
  194. 'groupName' => 'dummy',
  195. 'title' => 'dummy',
  196. 'description' => 'dummy',
  197. 'authenticated' => false,
  198. ];
  199. }
  200. }
  201. class PartialDummyMetadataStrategy2 extends Strategy
  202. {
  203. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  204. {
  205. return [
  206. 'description' => 'dummy',
  207. 'groupDescription' => 'dummy',
  208. ];
  209. }
  210. }
  211. class DummyResponseStrategy200 extends Strategy
  212. {
  213. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  214. {
  215. return [200 => 'dummy'];
  216. }
  217. }
  218. class StillDummyResponseStrategyAlso200 extends Strategy
  219. {
  220. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  221. {
  222. return [200 => 'stilldummy'];
  223. }
  224. }
  225. class DummyResponseStrategy400 extends Strategy
  226. {
  227. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  228. {
  229. return [400 => 'dummy2'];
  230. }
  231. }