Skip to content

Commit a4084a4

Browse files
authored
Merge pull request #48 from AntonBelet/array-of-required-serializers-fix
BodySerializer. Array of serializers fix.
2 parents 4e7f35e + af9a8ec commit a4084a4

File tree

6 files changed

+292
-6
lines changed

6 files changed

+292
-6
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## [6.0.2] - 2021-08-12
8+
### Fixed
9+
- The array of serializers in BodySerializer depends on both requests and responses content type
10+
711
## [6.0.1] - 2021-07-27
812
### Fixed
913
- Fix preg_match pattern by adding a slash (/) as a delimiter.

example/test-example.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
$client = $factory->create($client);
2121

2222
$request = new FindPetsByStatusRequest();
23-
$request->setStatus('sold');
23+
$request->setStatus('pending');
2424
$result = $client->findPetsByStatus($request);
2525
if ($result === null || $result->count() === 0) {
2626
sprintf('findPetsByStatus failed, result: %s', json_encode($result, JSON_THROW_ON_ERROR)) || exit(1);

src/Entity/Response.php

+29-1
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,38 @@
22

33
namespace DoclerLabs\ApiClientGenerator\Entity;
44

5+
use DoclerLabs\ApiClientGenerator\Input\InvalidSpecificationException;
6+
use DoclerLabs\ApiClientGenerator\Output\Copy\Serializer\ContentType\FormUrlencodedContentTypeSerializer;
7+
use DoclerLabs\ApiClientGenerator\Output\Copy\Serializer\ContentType\JsonContentTypeSerializer;
8+
use DoclerLabs\ApiClientGenerator\Output\Copy\Serializer\ContentType\VdnApiJsonContentTypeSerializer;
9+
use DoclerLabs\ApiClientGenerator\Output\Copy\Serializer\ContentType\XmlContentTypeSerializer;
10+
511
class Response
612
{
13+
private const ALLOWED_CONTENT_TYPES = [
14+
JsonContentTypeSerializer::MIME_TYPE,
15+
FormUrlencodedContentTypeSerializer::MIME_TYPE,
16+
XmlContentTypeSerializer::MIME_TYPE,
17+
VdnApiJsonContentTypeSerializer::MIME_TYPE,
18+
];
19+
720
private int $statusCode;
821
private ?Field $body;
22+
private array $bodyContentTypes;
923

10-
public function __construct(int $statusCode, Field $body = null)
24+
public function __construct(int $statusCode, Field $body = null, array $bodyContentTypes = [])
1125
{
1226
$this->statusCode = $statusCode;
1327
$this->body = $body;
28+
29+
$unsupportedContentTypes = array_diff($bodyContentTypes, static::ALLOWED_CONTENT_TYPES);
30+
if (!empty($unsupportedContentTypes)) {
31+
throw new InvalidSpecificationException(
32+
sprintf('Response content-type %s is not currently supported.', json_encode($unsupportedContentTypes))
33+
);
34+
}
35+
36+
$this->bodyContentTypes = $bodyContentTypes;
1437
}
1538

1639
public function getStatusCode(): int
@@ -22,4 +45,9 @@ public function getBody(): ?Field
2245
{
2346
return $this->body;
2447
}
48+
49+
public function getBodyContentTypes(): array
50+
{
51+
return $this->bodyContentTypes;
52+
}
2553
}

src/Input/Factory/ResponseFactory.php

+6-4
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ public function createSuccessful(string $operationName, array $openApiResponses)
3434
return new Response((int)$code, null);
3535
}
3636

37-
$schema = null;
38-
foreach ($response->content as $content) {
37+
$contentTypes = [];
38+
$schema = null;
39+
foreach ($response->content as $contentType => $content) {
3940
if ($schema !== null && !Parity::isEqualTo($content->schema, $schema)) {
4041
throw new InvalidSpecificationException('Multiple schemas per response is not currently supported.');
4142
}
42-
$schema = $content->schema;
43+
$schema = $content->schema;
44+
$contentTypes[] = $contentType;
4345
}
4446

4547
$schemaName = SchemaNaming::getClassName($schema, ucfirst($operationName) . 'ResponseBody');
@@ -52,7 +54,7 @@ public function createSuccessful(string $operationName, array $openApiResponses)
5254
$schemaName
5355
);
5456

55-
return new Response((int)$code, $body);
57+
return new Response((int)$code, $body, $contentTypes);
5658
}
5759
}
5860

src/Input/Specification.php

+3
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ public function getAllContentTypes(): array
9191
foreach ($operation->getRequest()->getBodyContentTypes() as $contentType) {
9292
$allContentTypes[$contentType] = true;
9393
}
94+
foreach ($operation->getSuccessfulResponse()->getBodyContentTypes() as $contentType) {
95+
$allContentTypes[$contentType] = true;
96+
}
9497
}
9598

9699
return array_keys(array_filter($allContentTypes));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DoclerLabs\ApiClientGenerator\Test\Functional\Input;
6+
7+
use DoclerLabs\ApiClientGenerator\Input\Parser;
8+
use DoclerLabs\ApiClientGenerator\ServiceProvider;
9+
use PHPUnit\Framework\TestCase;
10+
use Pimple\Container;
11+
12+
/**
13+
* @covers \DoclerLabs\ApiClientGenerator\Input\Parser
14+
*/
15+
class SpecificationTest extends TestCase
16+
{
17+
protected Parser $sut;
18+
19+
/**
20+
* @dataProvider contentTypesTestProvider
21+
*/
22+
public function testAllContentTypesArrayPopulatedCorrectly(array $data, array $expectedResult): void
23+
{
24+
$specification = $this->sut->parse($data, '/openapi.yaml');
25+
static::assertSame($specification->getAllContentTypes(), $expectedResult);
26+
}
27+
28+
public function contentTypesTestProvider(): array
29+
{
30+
return [
31+
'No serializers required' => [
32+
[
33+
'openapi' => '3.0.0',
34+
'info' => [
35+
'title' => 'Sample API',
36+
'version' => '1.0.0',
37+
],
38+
'paths' => [
39+
'/users/{userId}' => [
40+
'parameters' => [
41+
[
42+
'in' => 'path',
43+
'required' => true,
44+
'name' => 'userId',
45+
'schema' => [
46+
'type' => 'integer',
47+
],
48+
],
49+
],
50+
'delete' => [
51+
'operationId' => 'deleteUser',
52+
'responses' => [
53+
'204' => [
54+
'description' => 'OK',
55+
],
56+
],
57+
],
58+
],
59+
],
60+
],
61+
[],
62+
],
63+
'Serializer specified in request' => [
64+
[
65+
'openapi' => '3.0.0',
66+
'info' => [
67+
'title' => 'Sample API',
68+
'version' => '1.0.0',
69+
],
70+
'paths' => [
71+
'/users' => [
72+
'post' => [
73+
'operationId' => 'createUser',
74+
'requestBody' => [
75+
'required' => true,
76+
'content' => [
77+
'application/x-www-form-urlencoded' => [
78+
'schema' => [
79+
'type' => 'object',
80+
'properties' => [
81+
'name' => [
82+
'type' => 'string',
83+
],
84+
],
85+
],
86+
],
87+
'application/xml' => [
88+
'schema' => [
89+
'type' => 'object',
90+
'properties' => [
91+
'name' => [
92+
'type' => 'string',
93+
],
94+
],
95+
],
96+
],
97+
],
98+
],
99+
'responses' => [
100+
'201' => [
101+
'description' => 'Created',
102+
],
103+
],
104+
],
105+
],
106+
],
107+
],
108+
[
109+
'application/xml',
110+
'application/x-www-form-urlencoded',
111+
],
112+
],
113+
'Serializer specified in response' => [
114+
[
115+
'openapi' => '3.0.0',
116+
'info' => [
117+
'title' => 'Sample API',
118+
'version' => '1.0.0',
119+
],
120+
'paths' => [
121+
'/users' => [
122+
'get' => [
123+
'operationId' => 'createUser',
124+
'responses' => [
125+
'200' => [
126+
'description' => 'Array of users',
127+
'content' => [
128+
'application/json' => [
129+
'schema' => [
130+
'type' => 'object',
131+
'properties' => [
132+
'name' => [
133+
'type' => 'string',
134+
],
135+
],
136+
],
137+
],
138+
'application/xml' => [
139+
'schema' => [
140+
'type' => 'object',
141+
'properties' => [
142+
'name' => [
143+
'type' => 'string',
144+
],
145+
],
146+
],
147+
],
148+
],
149+
],
150+
],
151+
],
152+
],
153+
],
154+
],
155+
[
156+
'application/xml',
157+
'application/json',
158+
],
159+
],
160+
'Serializer specified in request and response' => [
161+
[
162+
'openapi' => '3.0.0',
163+
'info' => [
164+
'title' => 'Sample API',
165+
'version' => '1.0.0',
166+
],
167+
'paths' => [
168+
'/users/{userId}' => [
169+
'parameters' => [
170+
[
171+
'in' => 'path',
172+
'required' => true,
173+
'name' => 'userId',
174+
'schema' => [
175+
'type' => 'integer',
176+
],
177+
],
178+
],
179+
'patch' => [
180+
'operationId' => 'createUser',
181+
'requestBody' => [
182+
'required' => true,
183+
'content' => [
184+
'application/x-www-form-urlencoded' => [
185+
'schema' => [
186+
'type' => 'object',
187+
'properties' => [
188+
'name' => [
189+
'type' => 'string',
190+
],
191+
],
192+
],
193+
],
194+
'application/xml' => [
195+
'schema' => [
196+
'type' => 'object',
197+
'properties' => [
198+
'name' => [
199+
'type' => 'string',
200+
],
201+
],
202+
],
203+
],
204+
],
205+
],
206+
'responses' => [
207+
'200' => [
208+
'description' => 'Modified user',
209+
'content' => [
210+
'application/json' => [
211+
'schema' => [
212+
'type' => 'object',
213+
'properties' => [
214+
'name' => [
215+
'type' => 'string',
216+
],
217+
],
218+
],
219+
],
220+
],
221+
],
222+
],
223+
],
224+
],
225+
],
226+
],
227+
[
228+
'application/xml',
229+
'application/x-www-form-urlencoded',
230+
'application/json',
231+
],
232+
]
233+
];
234+
}
235+
236+
protected function setUp(): void
237+
{
238+
$container = new Container();
239+
$container->register(new ServiceProvider());
240+
241+
set_error_handler(
242+
static function (int $code, string $message) {
243+
},
244+
E_USER_WARNING
245+
);
246+
247+
$this->sut = $container[Parser::class];
248+
}
249+
}

0 commit comments

Comments
 (0)