PostmanCollectionWriterTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <?php
  2. namespace Knuckles\Scribe\Tests\Unit;
  3. use Illuminate\Support\Collection;
  4. use Knuckles\Scribe\Extracting\Generator;
  5. use Knuckles\Scribe\Writing\PostmanCollectionWriter;
  6. use Orchestra\Testbench\TestCase;
  7. class PostmanCollectionWriterTest extends TestCase
  8. {
  9. public function testCorrectStructureIsFollowed()
  10. {
  11. \Config::set('scribe.title', 'Test API');
  12. \Config::set('scribe.postman', [
  13. 'description' => 'A fake description',
  14. ]);
  15. $writer = new PostmanCollectionWriter();
  16. $collection = $writer->generatePostmanCollection(new Collection());
  17. $this->assertSame('Test API', $collection['info']['name']);
  18. $this->assertSame('A fake description', $collection['info']['description']);
  19. }
  20. public function testFallbackCollectionNameIsUsed()
  21. {
  22. \Config::set('app.name', 'Fake App');
  23. $writer = new PostmanCollectionWriter();
  24. $collection = $writer->generatePostmanCollection(new Collection());
  25. $this->assertSame('Fake App API', $collection['info']['name']);
  26. }
  27. public function testEndpointIsParsed()
  28. {
  29. $route = $this->createMockRouteData('some/path');
  30. // Ensure method is set correctly for assertion later
  31. $route['methods'] = ['GET'];
  32. $endpoints = $this->createMockRouteGroup([$route], 'Group');
  33. config(['scribe.base_url' => 'fake.localhost']);
  34. $writer = new PostmanCollectionWriter();
  35. $collection = $writer->generatePostmanCollection($endpoints);
  36. $this->assertSame('Group', data_get($collection, 'item.0.name'), 'Group name exists');
  37. $item = data_get($collection, 'item.0.item.0');
  38. $this->assertSame('some/path', $item['name'], 'Name defaults to path');
  39. $this->assertSame('http', data_get($item, 'request.url.protocol'), 'Protocol defaults to http');
  40. $this->assertSame('fake.localhost', data_get($item, 'request.url.host'), 'Host uses what\'s given');
  41. $this->assertSame('some/path', data_get($item, 'request.url.path'), 'Path is set correctly');
  42. $this->assertEmpty(data_get($item, 'request.url.query'), 'Query parameters are empty');
  43. $this->assertSame('GET', data_get($item, 'request.method'), 'Method is correctly resolved');
  44. $this->assertContains([
  45. 'key' => 'Accept',
  46. 'value' => 'application/json',
  47. ], data_get($item, 'request.header'), 'JSON Accept header is added');
  48. }
  49. public function testHeadersArePulledFromRoute()
  50. {
  51. $route = $this->createMockRouteData('some/path');
  52. $route['headers'] = ['X-Fake' => 'Test'];
  53. $endpoints = $this->createMockRouteGroup([$route], 'Group');
  54. config(['scribe.base_url' => 'fake.localhost']);
  55. $writer = new PostmanCollectionWriter();
  56. $collection = $writer->generatePostmanCollection($endpoints);
  57. $this->assertContains([
  58. 'key' => 'X-Fake',
  59. 'value' => 'Test',
  60. ], data_get($collection, 'item.0.item.0.request.header'));
  61. }
  62. /** @test */
  63. public function url_parameters_are_represented_properly()
  64. {
  65. $fakeRoute = $this->createMockRouteData('fake/{param}');
  66. $fakeRoute['urlParameters'] = ['param' => [
  67. 'description' => 'A test description for the test param',
  68. 'required' => true,
  69. 'value' => 'foobar',
  70. ]];
  71. $endpoints = $this->createMockRouteGroup([$fakeRoute]);
  72. config(['scribe.base_url' => 'fake.localhost']);
  73. $writer = new PostmanCollectionWriter();
  74. $collection = $writer->generatePostmanCollection($endpoints);
  75. $item = data_get($collection, 'item.0.item.0');
  76. $this->assertSame('fake/{param}', $item['name'], 'Name defaults to URL path');
  77. $this->assertSame('fake/:param', data_get($item, 'request.url.path'), 'Path is converted');
  78. $variableData = data_get($collection, 'item.0.item.0.request.url.variable');
  79. $this->assertCount(1, $variableData);
  80. $this->assertEquals([
  81. 'id' => 'param',
  82. 'key' => 'param',
  83. 'value' => 'foobar',
  84. 'description' => 'A test description for the test param',
  85. ], $variableData[0]);
  86. }
  87. /** @test */
  88. public function testQueryParametersAreDocumented()
  89. {
  90. $fakeRoute = $this->createMockRouteData('fake/path');
  91. $fakeRoute['queryParameters'] = [
  92. 'limit' => [
  93. 'description' => 'A fake limit for my fake endpoint',
  94. 'required' => true,
  95. 'value' => 5,
  96. ],
  97. 'filters.*' => [
  98. 'description' => 'Filters',
  99. 'required' => true,
  100. 'value' => '34,12',
  101. ],
  102. ];
  103. $fakeRoute['cleanQueryParameters'] = Generator::cleanParams($fakeRoute['queryParameters']);
  104. $endpoints = $this->createMockRouteGroup([$fakeRoute]);
  105. config(['scribe.base_url' => 'fake.localhost']);
  106. $writer = new PostmanCollectionWriter();
  107. $collection = $writer->generatePostmanCollection($endpoints);
  108. $variableData = data_get($collection, 'item.0.item.0.request.url.query');
  109. $this->assertCount(2, $variableData);
  110. $this->assertEquals([
  111. 'key' => 'limit',
  112. 'value' => '5',
  113. 'description' => 'A fake limit for my fake endpoint',
  114. 'disabled' => false,
  115. ], $variableData[0]);
  116. $this->assertEquals([
  117. 'key' => 'filters',
  118. 'value' => urlencode("34,12"),
  119. 'description' => 'Filters',
  120. 'disabled' => false,
  121. ], $variableData[1]);
  122. }
  123. public function testUrlParametersAreNotIncludedIfMissingFromPath()
  124. {
  125. $fakeRoute = $this->createMockRouteData('fake/path');
  126. $fakeRoute['urlParameters'] = ['limit' => [
  127. 'description' => 'A fake limit for my fake endpoint',
  128. 'required' => false,
  129. 'value' => 5,
  130. ]];
  131. $endpoints = $this->createMockRouteGroup([$fakeRoute]);
  132. config(['scribe.base_url' => 'fake.localhost']);
  133. $writer = new PostmanCollectionWriter();
  134. $collection = $writer->generatePostmanCollection($endpoints);
  135. $variableData = data_get($collection, 'item.0.item.0.request.url.query');
  136. $this->assertCount(0, $variableData);
  137. }
  138. /** @test */
  139. public function query_parameters_are_disabled_with_no_value_when_notRequired()
  140. {
  141. $fakeRoute = $this->createMockRouteData('fake/path');
  142. $fakeRoute['queryParameters'] = [
  143. 'required' => [
  144. 'description' => 'A required param with a null value',
  145. 'required' => true,
  146. 'value' => null,
  147. ],
  148. 'not_required' => [
  149. 'description' => 'A not required param with a null value',
  150. 'required' => false,
  151. 'value' => null,
  152. ],
  153. ];
  154. $fakeRoute['cleanQueryParameters'] = Generator::cleanParams($fakeRoute['queryParameters']);
  155. $endpoints = $this->createMockRouteGroup([$fakeRoute]);
  156. config(['scribe.base_url' => 'fake.localhost']);
  157. $writer = new PostmanCollectionWriter();
  158. $collection = $writer->generatePostmanCollection($endpoints);
  159. $variableData = data_get($collection, 'item.0.item.0.request.url.query');
  160. $this->assertCount(2, $variableData);
  161. $this->assertContains([
  162. 'key' => 'required',
  163. 'value' => null,
  164. 'description' => 'A required param with a null value',
  165. 'disabled' => false,
  166. ], $variableData);
  167. $this->assertContains([
  168. 'key' => 'not_required',
  169. 'value' => null,
  170. 'description' => 'A not required param with a null value',
  171. 'disabled' => true,
  172. ], $variableData);
  173. }
  174. /**
  175. * @dataProvider provideAuthConfigHeaderData
  176. */
  177. public function testAuthAutoExcludesHeaderDefinitions(array $authConfig, array $expectedRemovedHeaders)
  178. {
  179. // todo change this test to Scribe auth
  180. \Config::set('scribe.postman', ['auth' => $authConfig]);
  181. $route = $this->createMockRouteData('some/path');
  182. $route['headers'] = $expectedRemovedHeaders;
  183. $endpoints = $this->createMockRouteGroup([$route], 'Group');
  184. config('scribe.postman', ['auth' => $authConfig]);
  185. config(['scribe.base_url' => 'fake.localhost']);
  186. $writer = new PostmanCollectionWriter();
  187. $collection = $writer->generatePostmanCollection($endpoints);
  188. foreach ($expectedRemovedHeaders as $key => $value) {
  189. $this->assertNotContains(compact('key', 'value'), data_get($collection, 'item.0.item.0.request.header'));
  190. }
  191. }
  192. public function provideAuthConfigHeaderData()
  193. {
  194. yield [
  195. ['type' => 'bearer', 'bearer' => ['token' => 'Test']],
  196. ['Authorization' => 'Bearer Test'],
  197. ];
  198. yield [
  199. ['type' => 'apikey', 'apikey' => ['value' => 'Test', 'key' => 'X-Authorization']],
  200. ['X-Authorization' => 'Test'],
  201. ];
  202. }
  203. public function testApiKeyAuthIsIgnoredIfExplicitlyNotInHeader()
  204. {
  205. \Config::set('scribe.postman', [
  206. 'auth' => ['type' => 'apikey', 'apikey' => [
  207. 'value' => 'Test',
  208. 'key' => 'X-Authorization',
  209. 'in' => 'notheader',
  210. ]],
  211. ]);
  212. $route = $this->createMockRouteData('some/path');
  213. $route['headers'] = ['X-Authorization' => 'Test'];
  214. $endpoints = $this->createMockRouteGroup([$route], 'Group');
  215. config(['scribe.base_url' => 'fake.localhost']);
  216. $writer = new PostmanCollectionWriter();
  217. $collection = $writer->generatePostmanCollection($endpoints);
  218. $this->assertContains([
  219. 'key' => 'X-Authorization',
  220. 'value' => 'Test',
  221. ], data_get($collection, 'item.0.item.0.request.header'));
  222. }
  223. protected function createMockRouteData($path, $title = '')
  224. {
  225. return [
  226. 'uri' => $path,
  227. 'methods' => ['GET'],
  228. 'headers' => [],
  229. 'metadata' => [
  230. 'groupDescription' => '',
  231. 'title' => $title,
  232. ],
  233. 'urlParameters' => [],
  234. 'cleanUrlParameters' => [],
  235. 'queryParameters' => [],
  236. 'cleanQueryParameters' => [],
  237. 'bodyParameters' => [],
  238. 'cleanBodyParameters' => [],
  239. 'fileParameters' => [],
  240. 'responses' => [],
  241. 'responseFields' => [],
  242. ];
  243. }
  244. protected function createMockRouteGroup(array $routes, $groupName = 'Group')
  245. {
  246. return collect([$groupName => collect($routes)]);
  247. }
  248. }