UseResponseAttributesTest.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <?php
  2. namespace Knuckles\Scribe\Tests\Strategies\Responses;
  3. use Illuminate\Routing\Route;
  4. use Knuckles\Camel\Extraction\ExtractedEndpointData;
  5. use Knuckles\Scribe\Attributes\Response;
  6. use Knuckles\Scribe\Attributes\ResponseFromApiResource;
  7. use Knuckles\Scribe\Attributes\ResponseFromFile;
  8. use Knuckles\Scribe\Attributes\ResponseFromTransformer;
  9. use Knuckles\Scribe\Extracting\Strategies\Responses\UseResponseAttributes;
  10. use Knuckles\Scribe\ScribeServiceProvider;
  11. use Knuckles\Scribe\Tests\BaseLaravelTest;
  12. use Knuckles\Scribe\Tests\Fixtures\TestModel;
  13. use Knuckles\Scribe\Tests\Fixtures\TestPet;
  14. use Knuckles\Scribe\Tests\Fixtures\TestTransformer;
  15. use Knuckles\Scribe\Tests\Fixtures\TestUser;
  16. use Knuckles\Scribe\Tests\Fixtures\TestUserApiResource;
  17. use Knuckles\Scribe\Tools\DocumentationConfig;
  18. use Knuckles\Scribe\Tools\Utils;
  19. use League\Fractal\Pagination\IlluminatePaginatorAdapter;
  20. use ReflectionClass;
  21. class UseResponseAttributesTest extends BaseLaravelTest
  22. {
  23. protected function getPackageProviders($app)
  24. {
  25. $providers = parent::getPackageProviders($app);
  26. if (class_exists(\Illuminate\Database\Eloquent\LegacyFactoryServiceProvider::class)) {
  27. $providers[] = \Illuminate\Database\Eloquent\LegacyFactoryServiceProvider ::class;
  28. }
  29. return $providers;
  30. }
  31. public function setUp(): void
  32. {
  33. parent::setUp();
  34. $this->setConfig(['database_connections_to_transact' => []]);
  35. $factory = app(\Illuminate\Database\Eloquent\Factory::class);
  36. $factory->define(TestUser::class, function () {
  37. return [
  38. 'id' => 4,
  39. 'first_name' => 'Tested',
  40. 'last_name' => 'Again',
  41. 'email' => 'a@b.com',
  42. ];
  43. });
  44. $factory->state(TestUser::class, 'state1', ["state1" => true]);
  45. $factory->state(TestUser::class, 'random-state', ["random-state" => true]);
  46. $factory->define(TestPet::class, function () {
  47. return [
  48. 'id' => 1,
  49. 'name' => 'Mephistopheles',
  50. 'species' => 'dog',
  51. ];
  52. });
  53. }
  54. /** @test */
  55. public function can_parse_plain_response_attributes()
  56. {
  57. $results = $this->fetch($this->endpoint("plainResponseAttributes"));
  58. $this->assertArraySubset([
  59. [
  60. 'status' => 200,
  61. 'content' => json_encode(["all" => "good"]),
  62. "description" => "Success"
  63. ],
  64. [
  65. 'status' => 201,
  66. 'content' => json_encode(["all" => "good"]),
  67. ],
  68. ], $results);
  69. }
  70. /** @test */
  71. public function can_parse_responsefile_attributes()
  72. {
  73. $results = $this->fetch($this->endpoint("responseFileAttributes"));
  74. $this->assertArraySubset([
  75. [
  76. 'status' => 401,
  77. 'content' => json_encode(["message" => "Unauthorized", "merge" => "this"]),
  78. ],
  79. ], $results);
  80. }
  81. /** @test */
  82. public function can_parse_apiresource_attributes()
  83. {
  84. $factory = app(\Illuminate\Database\Eloquent\Factory::class);
  85. $factory->afterMaking(TestUser::class, function (TestUser $user, $faker) {
  86. if ($user->id === 4) {
  87. $child = Utils::getModelFactory(TestUser::class)->make(['id' => 5, 'parent_id' => 4]);
  88. $user->setRelation('children', collect([$child]));
  89. }
  90. });
  91. $results = $this->fetch($this->endpoint("apiResourceAttributes"));
  92. $this->assertArraySubset([
  93. [
  94. 'status' => 200,
  95. 'content' => json_encode([
  96. 'data' => [
  97. [
  98. 'id' => 4,
  99. 'name' => 'Tested Again',
  100. 'email' => 'a@b.com',
  101. 'children' => [
  102. [
  103. 'id' => 5,
  104. 'name' => 'Tested Again',
  105. 'email' => 'a@b.com',
  106. ],
  107. ],
  108. 'state1' => true,
  109. 'random-state' => true,
  110. ],
  111. ],
  112. 'links' => [
  113. "first" => '/?page=1',
  114. "last" => null,
  115. "prev" => null,
  116. "next" => '/?page=2',
  117. ],
  118. "meta" => [
  119. "current_page" => 1,
  120. "from" => 1,
  121. "path" => '/',
  122. "per_page" => 1,
  123. "to" => 1,
  124. ],
  125. "a" => "b",
  126. ]),
  127. ],
  128. ], $results);
  129. }
  130. /** @test */
  131. public function can_parse_apiresource_attributes_with_no_model_specified()
  132. {
  133. $factory = app(\Illuminate\Database\Eloquent\Factory::class);
  134. $factory->afterMaking(TestUser::class, function (TestUser $user, $faker) {
  135. if ($user->id === 4) {
  136. $child = Utils::getModelFactory(TestUser::class)->make(['id' => 5, 'parent_id' => 4]);
  137. $user->setRelation('children', collect([$child]));
  138. }
  139. });
  140. $results = $this->fetch($this->endpoint("apiResourceAttributesWithNoModel"));
  141. $this->assertArraySubset([
  142. [
  143. 'status' => 200,
  144. 'content' => json_encode([
  145. 'data' => [
  146. [
  147. 'id' => 4,
  148. 'name' => 'Tested Again',
  149. 'email' => 'a@b.com',
  150. 'children' => [
  151. [
  152. 'id' => 5,
  153. 'name' => 'Tested Again',
  154. 'email' => 'a@b.com',
  155. ],
  156. ],
  157. 'state1' => true,
  158. 'random-state' => true,
  159. ],
  160. ],
  161. 'links' => [
  162. "first" => '/?page=1',
  163. "last" => null,
  164. "prev" => null,
  165. "next" => '/?page=2',
  166. ],
  167. "meta" => [
  168. "current_page" => 1,
  169. "from" => 1,
  170. "path" => '/',
  171. "per_page" => 1,
  172. "to" => 1,
  173. ],
  174. "a" => "b",
  175. ]),
  176. ],
  177. ], $results);
  178. }
  179. /** @test */
  180. public function can_parse_transformer_attributes()
  181. {
  182. $results = $this->fetch($this->endpoint("transformerAttributes"));
  183. $this->assertArraySubset([
  184. [
  185. 'status' => 200,
  186. 'content' => json_encode([
  187. "data" => [
  188. [
  189. "id" => 1,
  190. "description" => "Welcome on this test versions",
  191. "name" => "TestName",
  192. ],
  193. ],
  194. 'meta' => [
  195. "pagination" => [
  196. "total" => 2,
  197. "count" => 1,
  198. "per_page" => 1,
  199. "current_page" => 1,
  200. "total_pages" => 2,
  201. "links" => ["next" => "/?page=2"],
  202. ],
  203. ],
  204. ]),
  205. ],
  206. ], $results);
  207. }
  208. protected function fetch($endpoint): array
  209. {
  210. $strategy = new UseResponseAttributes(new DocumentationConfig([]));
  211. return $strategy($endpoint, []);
  212. }
  213. protected function endpoint(string $method): ExtractedEndpointData
  214. {
  215. $endpoint = new class extends ExtractedEndpointData {
  216. public function __construct(array $parameters = []) {}
  217. };
  218. $endpoint->controller = new ReflectionClass(ResponseAttributesTestController::class);
  219. $endpoint->method = $endpoint->controller->getMethod($method);
  220. $endpoint->route = new Route(['POST'], "/somethingRandom", ['uses' => [ResponseAttributesTestController::class, $method]]);
  221. return $endpoint;
  222. }
  223. }
  224. class ResponseAttributesTestController
  225. {
  226. #[Response(["all" => "good"], 200, "Success")]
  227. #[Response('{"all":"good"}', 201)]
  228. public function plainResponseAttributes()
  229. {
  230. }
  231. #[ResponseFromFile("tests/Fixtures/response_error_test.json", 401, ["merge" => "this"])]
  232. public function responseFileAttributes()
  233. {
  234. }
  235. #[ResponseFromApiResource(TestUserApiResource::class, TestUser::class, collection: true,
  236. factoryStates: ["state1", "random-state"], simplePaginate: 1, additional: ["a" => "b"])]
  237. public function apiResourceAttributes()
  238. {
  239. }
  240. #[ResponseFromApiResource(TestUserApiResource::class, collection: true,
  241. factoryStates: ["state1", "random-state"], simplePaginate: 1, additional: ["a" => "b"])]
  242. public function apiResourceAttributesWithNoModel()
  243. {
  244. }
  245. #[ResponseFromTransformer(TestTransformer::class, TestModel::class, collection: true,
  246. paginate: [IlluminatePaginatorAdapter::class, 1])]
  247. public function transformerAttributes()
  248. {
  249. }
  250. }