Skip to content

Commit 869b949

Browse files
committed
relax assertions for forward compatibility with Symfony 7.4
1 parent 73e634e commit 869b949

File tree

1 file changed

+114
-137
lines changed

1 file changed

+114
-137
lines changed

Tests/Functional/ApiAttributesTest.php

Lines changed: 114 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;
1313

14+
use Symfony\Component\DomCrawler\Crawler;
1415
use Symfony\Component\HttpFoundation\JsonResponse;
1516
use Symfony\Component\HttpFoundation\Request;
1617
use Symfony\Component\HttpFoundation\Response;
@@ -89,15 +90,14 @@ public static function mapQueryStringProvider(): iterable
8990
/**
9091
* @dataProvider mapRequestPayloadProvider
9192
*/
92-
public function testMapRequestPayload(string $format, array $parameters, ?string $content, string $expectedResponse, int $expectedStatusCode)
93+
public function testMapRequestPayload(string $format, array $parameters, ?string $content, callable $responseAssertion, int $expectedStatusCode)
9394
{
9495
$client = self::createClient(['test_case' => 'ApiAttributesTest']);
9596

96-
[$acceptHeader, $assertion] = [
97-
'html' => ['text/html', self::assertStringContainsString(...)],
98-
'json' => ['application/json', self::assertJsonStringEqualsJsonString(...)],
99-
'xml' => ['text/xml', self::assertXmlStringEqualsXmlString(...)],
100-
'dummy' => ['application/dummy', self::assertStringContainsString(...)],
97+
$acceptHeader = [
98+
'json' => 'application/json',
99+
'xml' => 'text/xml',
100+
'dummy' => 'application/dummy',
101101
][$format];
102102

103103
$client->request(
@@ -111,12 +111,7 @@ public function testMapRequestPayload(string $format, array $parameters, ?string
111111

112112
$response = $client->getResponse();
113113
$responseContent = $response->getContent();
114-
115-
if ($expectedResponse) {
116-
$assertion($expectedResponse, $responseContent);
117-
} else {
118-
self::assertSame('', $responseContent);
119-
}
114+
$responseAssertion($responseContent);
120115

121116
self::assertSame($expectedStatusCode, $response->getStatusCode());
122117
}
@@ -127,7 +122,9 @@ public static function mapRequestPayloadProvider(): iterable
127122
'format' => 'json',
128123
'parameters' => [],
129124
'content' => '',
130-
'expectedResponse' => '',
125+
'responseAssertion' => static function (string $response) {
126+
self::assertSame('', $response);
127+
},
131128
'expectedStatusCode' => 204,
132129
];
133130

@@ -140,12 +137,16 @@ public static function mapRequestPayloadProvider(): iterable
140137
"approved": false
141138
}
142139
JSON,
143-
'expectedResponse' => <<<'JSON'
144-
{
145-
"comment": "Hello everyone!",
146-
"approved": false
147-
}
148-
JSON,
140+
'responseAssertion' => static function (string $response) {
141+
self::assertJsonStringEqualsJsonString(<<<'JSON'
142+
{
143+
"comment": "Hello everyone!",
144+
"approved": false
145+
}
146+
JSON,
147+
$response
148+
);
149+
},
149150
'expectedStatusCode' => 200,
150151
];
151152

@@ -158,22 +159,28 @@ public static function mapRequestPayloadProvider(): iterable
158159
"approved": false,
159160
}
160161
JSON,
161-
'expectedResponse' => <<<'JSON'
162-
{
163-
"type": "https:\/\/tools.ietf.org\/html\/rfc2616#section-10",
164-
"title": "An error occurred",
165-
"status": 400,
166-
"detail": "Bad Request"
167-
}
168-
JSON,
162+
'responseAssertion' => static function (string $response) {
163+
self::assertJsonStringEqualsJsonString(<<<'JSON'
164+
{
165+
"type": "https:\/\/tools.ietf.org\/html\/rfc2616#section-10",
166+
"title": "An error occurred",
167+
"status": 400,
168+
"detail": "Bad Request"
169+
}
170+
JSON,
171+
$response
172+
);
173+
},
169174
'expectedStatusCode' => 400,
170175
];
171176

172177
yield 'unsupported format' => [
173178
'format' => 'dummy',
174179
'parameters' => [],
175180
'content' => 'Hello',
176-
'expectedResponse' => '415 Unsupported Media Type',
181+
'responseAssertion' => static function (string $response) {
182+
self::assertStringContainsString('415 Unsupported Media Type', $response);
183+
},
177184
'expectedStatusCode' => 415,
178185
];
179186

@@ -186,12 +193,16 @@ public static function mapRequestPayloadProvider(): iterable
186193
<approved>true</approved>
187194
</request>
188195
XML,
189-
'expectedResponse' => <<<'XML'
190-
<response>
191-
<comment>Hello everyone!</comment>
192-
<approved>1</approved>
193-
</response>
194-
XML,
196+
'responseAssertion' => static function (string $response) {
197+
self::assertXmlStringEqualsXmlString(<<<'XML'
198+
<response>
199+
<comment>Hello everyone!</comment>
200+
<approved>1</approved>
201+
</response>
202+
XML,
203+
$response
204+
);
205+
},
195206
'expectedStatusCode' => 200,
196207
];
197208

@@ -204,24 +215,28 @@ public static function mapRequestPayloadProvider(): iterable
204215
"approved": "string instead of bool"
205216
}
206217
JSON,
207-
'expectedResponse' => <<<'JSON'
208-
{
209-
"type": "https:\/\/symfony.com\/errors\/validation",
210-
"title": "Validation Failed",
211-
"status": 422,
212-
"detail": "approved: This value should be of type bool.",
213-
"violations": [
214-
{
215-
"propertyPath": "approved",
216-
"title": "This value should be of type bool.",
217-
"template": "This value should be of type {{ type }}.",
218-
"parameters": {
219-
"{{ type }}": "bool"
218+
'responseAssertion' => static function (string $response) {
219+
self::assertJsonStringEqualsJsonString(<<<'JSON'
220+
{
221+
"type": "https:\/\/symfony.com\/errors\/validation",
222+
"title": "Validation Failed",
223+
"status": 422,
224+
"detail": "approved: This value should be of type bool.",
225+
"violations": [
226+
{
227+
"propertyPath": "approved",
228+
"title": "This value should be of type bool.",
229+
"template": "This value should be of type {{ type }}.",
230+
"parameters": {
231+
"{{ type }}": "bool"
232+
}
220233
}
221-
}
222-
]
223-
}
224-
JSON,
234+
]
235+
}
236+
JSON,
237+
$response
238+
);
239+
},
225240
'expectedStatusCode' => 422,
226241
];
227242

@@ -234,36 +249,20 @@ public static function mapRequestPayloadProvider(): iterable
234249
"approved": true
235250
}
236251
JSON,
237-
'expectedResponse' => <<<'JSON'
238-
{
239-
"type": "https:\/\/symfony.com\/errors\/validation",
240-
"title": "Validation Failed",
241-
"status": 422,
242-
"detail": "comment: This value should not be blank.\ncomment: This value is too short. It should have 10 characters or more.",
243-
"violations": [
244-
{
245-
"propertyPath": "comment",
246-
"title": "This value should not be blank.",
247-
"template": "This value should not be blank.",
248-
"parameters": {
249-
"{{ value }}": "\"\""
250-
},
251-
"type": "urn:uuid:c1051bb4-d103-4f74-8988-acbcafc7fdc3"
252-
},
253-
{
254-
"propertyPath": "comment",
255-
"title": "This value is too short. It should have 10 characters or more.",
256-
"template": "This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.",
257-
"parameters": {
258-
"{{ value }}": "\"\"",
259-
"{{ limit }}": "10",
260-
"{{ value_length }}": "0"
261-
},
262-
"type": "urn:uuid:9ff3fdc4-b214-49db-8718-39c315e33d45"
263-
}
264-
]
265-
}
266-
JSON,
252+
'responseAssertion' => static function (string $response) {
253+
self::assertJson($response);
254+
255+
$json = json_decode($response, true);
256+
257+
self::assertSame('https://symfony.com/errors/validation', $json['type'] ?? null);
258+
self::assertSame('Validation Failed', $json['title'] ?? null);
259+
self::assertSame(422, $json['status'] ?? null);
260+
self::assertSame("comment: This value should not be blank.\ncomment: This value is too short. It should have 10 characters or more.", $json['detail'] ?? null);
261+
self::assertIsArray($json['violations'] ?? null);
262+
self::assertCount(2, $json['violations']);
263+
self::assertSame('urn:uuid:c1051bb4-d103-4f74-8988-acbcafc7fdc3', $json['violations'][0]['type'] ?? null);
264+
self::assertSame('urn:uuid:9ff3fdc4-b214-49db-8718-39c315e33d45', $json['violations'][1]['type'] ?? null);
265+
},
267266
'expectedStatusCode' => 422,
268267
];
269268

@@ -276,76 +275,54 @@ public static function mapRequestPayloadProvider(): iterable
276275
<approved>false</approved>
277276
</request>
278277
XML,
279-
'expectedResponse' => <<<'XML'
280-
<?xml version="1.0"?>
281-
<response>
282-
<type>https://symfony.com/errors/validation</type>
283-
<title>Validation Failed</title>
284-
<status>422</status>
285-
<detail>comment: This value is too short. It should have 10 characters or more.</detail>
286-
<violations>
287-
<propertyPath>comment</propertyPath>
288-
<title>This value is too short. It should have 10 characters or more.</title>
289-
<template>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</template>
290-
<parameters>
291-
<item key="{{ value }}">"H"</item>
292-
<item key="{{ limit }}">10</item>
293-
<item key="{{ value_length }}">1</item>
294-
</parameters>
295-
<type>urn:uuid:9ff3fdc4-b214-49db-8718-39c315e33d45</type>
296-
</violations>
297-
</response>
298-
XML,
278+
'responseAssertion' => static function (string $response) {
279+
$crawler = new Crawler($response);
280+
281+
self::assertSame('https://symfony.com/errors/validation', $crawler->filterXPath('response/type')->text());
282+
self::assertSame('Validation Failed', $crawler->filterXPath('response/title')->text());
283+
self::assertSame('422', $crawler->filterXPath('response/status')->text());
284+
self::assertSame('comment: This value is too short. It should have 10 characters or more.', $crawler->filterXPath('response/detail')->text());
285+
self::assertCount(1, $crawler->filterXPath('response/violations'));
286+
self::assertSame('urn:uuid:9ff3fdc4-b214-49db-8718-39c315e33d45', $crawler->filterXPath('response/violations/type')->text());
287+
},
299288
'expectedStatusCode' => 422,
300289
];
301290

302291
yield 'valid input' => [
303292
'format' => 'json',
304293
'input' => ['comment' => 'Hello everyone!', 'approved' => '0'],
305294
'content' => null,
306-
'expectedResponse' => <<<'JSON'
307-
{
308-
"comment": "Hello everyone!",
309-
"approved": false
310-
}
311-
JSON,
295+
'responseAssertion' => static function (string $response) {
296+
self::assertJsonStringEqualsJsonString(<<<'JSON'
297+
{
298+
"comment": "Hello everyone!",
299+
"approved": false
300+
}
301+
JSON,
302+
$response
303+
);
304+
},
312305
'expectedStatusCode' => 200,
313306
];
314307

315308
yield 'validation error input' => [
316309
'format' => 'json',
317310
'input' => ['comment' => '', 'approved' => '1'],
318311
'content' => null,
319-
'expectedResponse' => <<<'JSON'
320-
{
321-
"type": "https:\/\/symfony.com\/errors\/validation",
322-
"title": "Validation Failed",
323-
"status": 422,
324-
"detail": "comment: This value should not be blank.\ncomment: This value is too short. It should have 10 characters or more.",
325-
"violations": [
326-
{
327-
"propertyPath": "comment",
328-
"title": "This value should not be blank.",
329-
"template": "This value should not be blank.",
330-
"parameters": {
331-
"{{ value }}": "\"\""
332-
},
333-
"type": "urn:uuid:c1051bb4-d103-4f74-8988-acbcafc7fdc3"
334-
},
335-
{
336-
"propertyPath": "comment",
337-
"title": "This value is too short. It should have 10 characters or more.",
338-
"template": "This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.",
339-
"parameters": {
340-
"{{ value }}": "\"\"",
341-
"{{ limit }}": "10",
342-
"{{ value_length }}": "0"
343-
},
344-
"type": "urn:uuid:9ff3fdc4-b214-49db-8718-39c315e33d45"
345-
}
346-
]
347-
}
348-
JSON,
312+
'responseAssertion' => static function (string $response) {
313+
self::assertJson($response);
314+
315+
$json = json_decode($response, true);
316+
317+
self::assertSame('https://symfony.com/errors/validation', $json['type'] ?? null);
318+
self::assertSame('Validation Failed', $json['title'] ?? null);
319+
self::assertSame(422, $json['status'] ?? null);
320+
self::assertSame("comment: This value should not be blank.\ncomment: This value is too short. It should have 10 characters or more.", $json['detail'] ?? null);
321+
self::assertIsArray($json['violations'] ?? null);
322+
self::assertCount(2, $json['violations']);
323+
self::assertSame('urn:uuid:c1051bb4-d103-4f74-8988-acbcafc7fdc3', $json['violations'][0]['type'] ?? null);
324+
self::assertSame('urn:uuid:9ff3fdc4-b214-49db-8718-39c315e33d45', $json['violations'][1]['type'] ?? null);
325+
},
349326
'expectedStatusCode' => 422,
350327
];
351328
}

0 commit comments

Comments
 (0)