UseResponseAttributesTest.php 9.5 KB

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