GetFromFormRequestTest.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. namespace Knuckles\Scribe\Tests\Strategies;
  3. use Knuckles\Scribe\Extracting\Strategies\BodyParameters;
  4. use Knuckles\Scribe\Extracting\Strategies\QueryParameters;
  5. use Knuckles\Scribe\Tests\BaseLaravelTest;
  6. use Knuckles\Scribe\Tests\Fixtures\TestController;
  7. use Knuckles\Scribe\Tests\Fixtures\TestRequest;
  8. use Knuckles\Scribe\Tests\Fixtures\TestRequestQueryParams;
  9. use Knuckles\Scribe\Tools\DocumentationConfig;
  10. use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
  11. use Knuckles\Scribe\Tools\Globals;
  12. use PHPUnit\Framework\Assert;
  13. class GetFromFormRequestTest extends BaseLaravelTest
  14. {
  15. use ArraySubsetAsserts;
  16. /** @test */
  17. public function can_fetch_bodyparams_from_form_request()
  18. {
  19. $method = new \ReflectionMethod(TestController::class, 'withFormRequestParameter');
  20. $results = $this->fetchViaBodyParams($method);
  21. $this->assertArraySubset([
  22. 'user_id' => [
  23. 'type' => 'integer',
  24. 'required' => true,
  25. 'description' => 'The id of the user.',
  26. 'example' => 9,
  27. ],
  28. 'room_id' => [
  29. 'type' => 'string',
  30. 'required' => false,
  31. 'description' => 'The id of the room.',
  32. ],
  33. 'forever' => [
  34. 'type' => 'boolean',
  35. 'required' => false,
  36. 'description' => 'Whether to ban the user forever.',
  37. 'example' => false,
  38. ],
  39. 'another_one' => [
  40. 'type' => 'number',
  41. 'required' => false,
  42. 'description' => 'Just need something here.',
  43. ],
  44. 'no_example_attribute' => [
  45. 'type' => 'number',
  46. 'required' => false,
  47. 'description' => 'Attribute without example.',
  48. 'example' => null,
  49. ],
  50. 'even_more_param' => [
  51. 'type' => 'object',
  52. 'required' => false,
  53. 'description' => '',
  54. 'example' => [],
  55. ],
  56. 'book' => [
  57. 'type' => 'object',
  58. 'description' => '',
  59. 'required' => false,
  60. 'example' => [],
  61. ],
  62. 'book.name' => [
  63. 'type' => 'string',
  64. 'description' => '',
  65. 'required' => false,
  66. ],
  67. 'book.author_id' => [
  68. 'type' => 'integer',
  69. 'description' => '',
  70. 'required' => false,
  71. ],
  72. 'book.pages_count' => [
  73. 'type' => 'integer',
  74. 'description' => '',
  75. 'required' => false,
  76. ],
  77. 'ids' => [
  78. 'type' => 'integer[]',
  79. 'description' => '',
  80. 'required' => false,
  81. ],
  82. 'users' => [
  83. 'type' => 'object[]',
  84. 'description' => '',
  85. 'required' => false,
  86. 'example' => [[]],
  87. ],
  88. 'users[].first_name' => [
  89. 'type' => 'string',
  90. 'description' => 'The first name of the user.',
  91. 'required' => false,
  92. 'example' => 'John',
  93. ],
  94. 'users[].last_name' => [
  95. 'type' => 'string',
  96. 'description' => 'The last name of the user.',
  97. 'required' => false,
  98. 'example' => 'Doe',
  99. ],
  100. ], $results);
  101. $this->assertIsArray($results['ids']['example']);
  102. $this->assertIsInt($results['ids']['example'][0]);
  103. }
  104. /** @test */
  105. public function can_fetch_queryparams_from_form_request()
  106. {
  107. $method = new \ReflectionMethod(TestController::class, 'withFormRequestParameterQueryParams');
  108. $results = $this->fetchViaQueryParams($method);
  109. $this->assertArraySubset([
  110. 'q_param' => [
  111. 'type' => 'integer',
  112. 'description' => 'The param.',
  113. 'required' => true,
  114. 'example' => 9,
  115. ],
  116. ], $results);
  117. $method = new \ReflectionMethod(TestController::class, 'withFormRequestParameterQueryParamsComment');
  118. $results = $this->fetchViaQueryParams($method);
  119. $this->assertArraySubset([
  120. 'type' => 'integer',
  121. 'description' => '',
  122. 'required' => true,
  123. ], $results['q_param']);
  124. }
  125. /** @test */
  126. public function will_ignore_not_relevant_form_request()
  127. {
  128. $method = new \ReflectionMethod(TestController::class, 'withFormRequestParameter');
  129. $this->assertEquals([], $this->fetchViaQueryParams($method));
  130. $method = new \ReflectionMethod(TestController::class, 'withFormRequestParameterQueryParams');
  131. $this->assertEquals([], $this->fetchViaBodyParams($method));
  132. $method = new \ReflectionMethod(TestController::class, 'withFormRequestParameterQueryParamsComment');
  133. $this->assertEquals([], $this->fetchViaBodyParams($method));
  134. }
  135. /** @test */
  136. public function sets_examples_from_parent_if_set()
  137. {
  138. $strategy = new BodyParameters\GetFromFormRequest(new DocumentationConfig([]));
  139. $dataExample = [
  140. 'title' => 'Things Fall Apart',
  141. 'meta' => ['tags' => ['epic']],
  142. ];
  143. $parametersFromFormRequest = $strategy->getParametersFromValidationRules(
  144. [
  145. 'data' => 'array|required',
  146. 'data.title' => 'string|required',
  147. 'data.meta' => 'array',
  148. 'data.meta.tags' => 'array',
  149. 'data.meta.tags.*' => 'string',
  150. ],
  151. [
  152. 'data' => [
  153. 'example' => $dataExample,
  154. ],
  155. ],
  156. );
  157. $parsed = $strategy->normaliseArrayAndObjectParameters($parametersFromFormRequest);
  158. $this->assertEquals($dataExample, $parsed['data']['example']);
  159. $this->assertEquals($dataExample['title'], $parsed['data.title']['example']);
  160. $this->assertEquals($dataExample['meta'], $parsed['data.meta']['example']);
  161. $this->assertEquals($dataExample['meta']['tags'], $parsed['data.meta.tags']['example']);
  162. }
  163. /** @test */
  164. public function creates_missing_parent_fields()
  165. {
  166. $strategy = new BodyParameters\GetFromFormRequest(new DocumentationConfig([]));
  167. $parametersFromFormRequest = $strategy->getParametersFromValidationRules(
  168. [
  169. 'cars.*.dogs.*.*' => 'array',
  170. 'thing1.thing2.*.thing3.thing4' => 'int',
  171. ],
  172. [],
  173. );
  174. $expected = [
  175. 'cars' => ['type' => 'object[]'],
  176. 'cars[].dogs' => ['type' => 'object[][]'],
  177. 'thing1' => ['type' => 'object'],
  178. 'thing1.thing2' => ['type' => 'object[]'],
  179. 'thing1.thing2[].thing3' => ['type' => 'object'],
  180. 'thing1.thing2[].thing3.thing4' => ['type' => 'integer'],
  181. ];
  182. $parsed = $strategy->normaliseArrayAndObjectParameters($parametersFromFormRequest);
  183. $this->assertArraySubset($expected, $parsed);
  184. }
  185. /** @test */
  186. public function allows_customisation_of_form_request_instantiation()
  187. {
  188. $controllerMethod = new \ReflectionMethod(TestController::class, 'withFormRequestParameter');
  189. Globals::$__instantiateFormRequestUsing = function ($className, $route, $method) use (&$controllerMethod) {
  190. Assert::assertEquals(TestRequest::class, $className);
  191. Assert::assertEquals(null, $route);
  192. Assert::assertEquals($controllerMethod, $method);
  193. return new TestRequestQueryParams;
  194. };
  195. $this->fetchViaBodyParams($controllerMethod);
  196. Globals::$__instantiateFormRequestUsing = null;
  197. }
  198. protected function fetchViaBodyParams(\ReflectionMethod $method): array
  199. {
  200. $strategy = new BodyParameters\GetFromFormRequest(new DocumentationConfig([]));
  201. return $strategy->getParametersFromFormRequest($method);
  202. }
  203. protected function fetchViaQueryParams(\ReflectionMethod $method): array
  204. {
  205. $strategy = new QueryParameters\GetFromFormRequest(new DocumentationConfig([]));
  206. return $strategy->getParametersFromFormRequest($method);
  207. }
  208. }