GeneratorPluginSystemTestCase.php 7.9 KB

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