diff --git a/src/Writing/PostmanCollectionWriter.php b/src/Writing/PostmanCollectionWriter.php index 609ca811..bb4d2129 100644 --- a/src/Writing/PostmanCollectionWriter.php +++ b/src/Writing/PostmanCollectionWriter.php @@ -54,7 +54,7 @@ public function generatePostmanCollection(array $groupedEndpoints): array return [ 'name' => $group['name'], 'description' => $group['description'], - 'item' => array_map(\Closure::fromCallable([$this, 'generateEndpointItem']), $group['endpoints']), + 'item' => $this->generateSubItem($group), ]; }, $groupedEndpoints)), 'auth' => $this->generateAuthObject(), @@ -103,6 +103,32 @@ protected function generateAuthObject(): array }; } + protected function generateSubItem(array $group): array + { + $seenSubgroups = []; + $items = []; + /** @var OutputEndpointData $endpoint */ + foreach ($group['endpoints'] as $endpoint) { + if (!$endpoint->metadata->subgroup) { + $items[] = $this->generateEndpointItem($endpoint); + } else { + if (isset($seenSubgroups[$endpoint->metadata->subgroup])) { + $subgroupIndex = $seenSubgroups[$endpoint->metadata->subgroup]; + $items[$subgroupIndex]['description'] = $items[$subgroupIndex]['description'] ?: $endpoint->metadata->subgroupDescription; + $items[$subgroupIndex]['item'] = [...$items[$subgroupIndex]['item'], $this->generateEndpointItem($endpoint)]; + } else { + $items[] = [ + 'name' => $endpoint->metadata->subgroup, + 'description' => $endpoint->metadata->subgroupDescription, + 'item' => [$this->generateEndpointItem($endpoint)], + ]; + $seenSubgroups[$endpoint->metadata->subgroup] = count($items) - 1; + } + } + } + return $items; + } + protected function generateEndpointItem(OutputEndpointData $endpoint): array { $method = $endpoint->httpMethods[0]; @@ -120,7 +146,7 @@ protected function generateEndpointItem(OutputEndpointData $endpoint): array } $endpointItem = [ - 'name' => $endpoint->metadata->title !== '' ? $endpoint->metadata->title : $endpoint->uri, + 'name' => $endpoint->metadata->title !== '' ? $endpoint->metadata->title : ($endpoint->httpMethods[0].' '.$endpoint->uri), 'request' => [ 'url' => $this->generateUrlObject($endpoint), 'method' => $method, @@ -330,7 +356,7 @@ private function getResponses(OutputEndpointData $endpoint): array foreach ($response->headers as $header => $value) { $headers[] = [ 'key' => $header, - 'value' => $value + 'value' => $value, ]; } diff --git a/tests/Fixtures/collection.json b/tests/Fixtures/collection.json index 91b6e990..8f34296e 100644 --- a/tests/Fixtures/collection.json +++ b/tests/Fixtures/collection.json @@ -138,7 +138,7 @@ "response": [] }, { - "name": "api/withQueryParameters", + "name": "GET api/withQueryParameters", "request": { "url": { "host": "{{baseUrl}}", @@ -213,7 +213,7 @@ ] }, { - "name": "api/withAuthTag", + "name": "GET api/withAuthTag", "request": { "url": { "host": "{{baseUrl}}", @@ -260,7 +260,7 @@ "description": "", "item": [ { - "name": "api/echoesUrlParameters/{param}/{param2}/{param3?}/{param4?}", + "name": "GET api/echoesUrlParameters/{param}/{param2}/{param3?}/{param4?}", "request": { "url": { "host": "{{baseUrl}}", diff --git a/tests/Unit/PostmanCollectionWriterTest.php b/tests/Unit/PostmanCollectionWriterTest.php index 4d4c3b86..dece1c07 100644 --- a/tests/Unit/PostmanCollectionWriterTest.php +++ b/tests/Unit/PostmanCollectionWriterTest.php @@ -39,7 +39,7 @@ public function endpoint_is_parsed() $this->assertSame('Group', data_get($collection, 'item.0.name'), 'Group name exists'); $item = data_get($collection, 'item.0.item.0'); - $this->assertSame('some/path', $item['name'], 'Name defaults to path'); + $this->assertSame('GET some/path', $item['name'], 'Name defaults to path'); $this->assertSame('fake.localhost', data_get($collection, 'variable.0.value')); $this->assertSame('{{baseUrl}}', data_get($item, 'request.url.host')); $this->assertSame('some/path', data_get($item, 'request.url.path'), 'Path is set correctly'); @@ -81,7 +81,7 @@ public function url_parameters_are_represented_properly() $collection = $this->generate(endpoints: [$endpoints]); $item = data_get($collection, 'item.0.item.0'); - $this->assertSame('fake/{param}', $item['name'], 'Name defaults to URL path'); + $this->assertSame('POST fake/{param}', $item['name'], 'Name defaults to URL path'); $this->assertSame('fake/:param', data_get($item, 'request.url.path'), 'Path is converted'); $variableData = data_get($collection, 'item.0.item.0.request.url.variable'); @@ -262,11 +262,35 @@ public function auth_info_is_added_correctly() $this->assertEquals(['type' => 'noauth'], $collection['item'][0]['item'][1]['request']['auth']); } + /** @test */ + public function organizes_groups_and_subgroups_correctly() + { + $endpointData1 = $this->createMockEndpointData('endpoint1'); + $endpointData1->metadata->subgroup = "Subgroup A"; + $endpointData2 = $this->createMockEndpointData('endpoint2'); + $endpointData3 = $this->createMockEndpointData('endpoint3'); + $endpointData3->metadata->subgroup = "Subgroup A"; + $endpointData3->metadata->subgroupDescription = "Subgroup A description"; + $endpoints = $this->createMockEndpointGroup([$endpointData1, $endpointData2, $endpointData3], 'Group A'); + + $config = [ + 'title' => 'Test API', + 'base_url' => 'fake.localhost', + 'auth' => [ 'enabled' => false,], + ]; + $collection = $this->generate($config, [$endpoints]); + + $this->assertEquals('Group A', $collection['item'][0]['name']); + $this->assertEquals(['Subgroup A', 'POST endpoint2'], array_map(fn($i) => $i['name'], $collection['item'][0]['item'])); + $this->assertEquals(['POST endpoint1', 'POST endpoint3'], array_map(fn($i) => $i['name'], $collection['item'][0]['item'][0]['item'])); + $this->assertEquals('Subgroup A description', $collection['item'][0]['item'][0]['description']); + } + protected function createMockEndpointData(string $path, string $title = ''): OutputEndpointData { return OutputEndpointData::create([ 'uri' => $path, - 'httpMethods' => ['GET'], + 'httpMethods' => ['POST'], 'metadata' => [ 'title' => $title, ],