PostmanCollectionWriterTest.php 12 KB

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