GeneratorPluginSystemTestCase.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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['responses']);
  59. $first = array_shift($parsed['responses']);
  60. $this->assertTrue(is_array($first));
  61. $this->assertEquals(200, $first['status']);
  62. $this->assertEquals('dummy', $first['content']);
  63. $second = array_shift($parsed['responses']);
  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_metadat_from_previous_strategies_in_same_stage()
  113. {
  114. $config = [
  115. 'strategies' => [
  116. 'metadata' => [NotDummyMetadataStrategy::class, PartialDummyMetadataStrategy1::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. $expectedMetadata = [
  123. 'groupName' => 'dummy',
  124. 'groupDescription' => 'notdummy',
  125. 'title' => 'dummy',
  126. 'description' => 'dummy',
  127. 'authenticated' => false,
  128. ];
  129. $this->assertArraySubset($expectedMetadata, $parsed['metadata']); // Forwards-compatibility
  130. $this->assertArraySubset($expectedMetadata, $parsed); // Backwards-compatibility
  131. }
  132. public function dataResources()
  133. {
  134. return [
  135. [
  136. null,
  137. '{"data":{"id":1,"description":"Welcome on this test versions","name":"TestName"}}',
  138. ],
  139. [
  140. 'League\Fractal\Serializer\JsonApiSerializer',
  141. '{"data":{"type":null,"id":"1","attributes":{"description":"Welcome on this test versions","name":"TestName"}}}',
  142. ],
  143. ];
  144. }
  145. }
  146. class EmptyStrategy1 extends Strategy
  147. {
  148. public static $called = [];
  149. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  150. {
  151. static::$called[$this->stage] = true;
  152. }
  153. }
  154. class EmptyStrategy2 extends Strategy
  155. {
  156. public static $called = [];
  157. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  158. {
  159. static::$called[$this->stage] = true;
  160. }
  161. }
  162. class NotDummyMetadataStrategy extends Strategy
  163. {
  164. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  165. {
  166. return [
  167. 'groupName' => 'notdummy',
  168. 'groupDescription' => 'notdummy',
  169. 'title' => 'notdummy',
  170. 'description' => 'notdummy',
  171. 'authenticated' => true,
  172. ];
  173. }
  174. }
  175. class PartialDummyMetadataStrategy1 extends Strategy
  176. {
  177. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  178. {
  179. return [
  180. 'groupName' => 'dummy',
  181. 'title' => 'dummy',
  182. 'description' => 'dummy',
  183. 'authenticated' => false,
  184. ];
  185. }
  186. }
  187. class PartialDummyMetadataStrategy2 extends Strategy
  188. {
  189. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  190. {
  191. return [
  192. 'description' => 'dummy',
  193. 'groupDescription' => 'dummy',
  194. ];
  195. }
  196. }
  197. class DummyResponseStrategy200 extends Strategy
  198. {
  199. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  200. {
  201. return [['status' => 200, 'content' => 'dummy']];
  202. }
  203. }
  204. class DummyResponseStrategy400 extends Strategy
  205. {
  206. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  207. {
  208. return [['status' => 400, 'content' => 'dummy2']];
  209. }
  210. }