GeneratorPluginSystemTestCase.php 7.7 KB

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