Skip to content

Commit e078777

Browse files
committed
fix(response): 🐛 assertContentType(), document(), json() considers charset and boundary directives
1 parent da7d152 commit e078777

3 files changed

Lines changed: 26 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# CHANGELOG
22

3+
## 2.0.1 - 2025-05-25
4+
### Fixed
5+
- `assertContentType(string $contentType)`, `document()` and `json()` methods don't fail when the header contains charset or boundary directives
6+
37
## 2.0.0 - 2025-05-18
48
### Changed
59
- Trait and interface names: `TestCase -> ExtendedTestCase`, `ExtendedTestCase -> ExtendedTestCaseInterface`

src/Assert/ResponseAssert.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use function explode;
1212
use function join;
1313
use function preg_split;
14+
use function strcasecmp;
1415
use function trim;
1516
use const PREG_SPLIT_NO_EMPTY;
1617

@@ -130,7 +131,8 @@ public function assertContentNotRegex(string $regex): void {
130131
* ```
131132
*/
132133
public function assertContentType(string $contentType): void {
133-
$this->assertHeaderEquals('Content-Type', $contentType);
134+
$actualType = $this->getResponseContentType();
135+
$this->test->assertEquals(0, strcasecmp($actualType, $contentType), "Expected the response to have the header \"Content-Type\" with value \"{$contentType}\", actual: \"{$actualType}\"");
134136
}
135137

136138
/**
@@ -349,10 +351,10 @@ public function assertJson(): void {
349351
public function document(bool $error = false): DocumentAssert {
350352
if ($this->doc)
351353
return $this->doc;
352-
$contentType = @$this->response->getHeader('Content-Type')[0];
353-
if ($contentType === 'text/html')
354+
$contentType = $this->getResponseContentType();
355+
if (strcasecmp($contentType, 'text/html') === 0)
354356
return $this->doc = $this->test->html($this->getResponseContents(), $error);
355-
if ($contentType === 'text/xml')
357+
if (strcasecmp($contentType, 'text/xml') === 0)
356358
return $this->doc = $this->test->xml($this->getResponseContents(), $error);
357359
$this->test->fail("Expected the response to have content-type of either \"text/html\" or \"text/xml\", actual: \"{$contentType}\"");
358360
}
@@ -368,8 +370,8 @@ public function document(bool $error = false): DocumentAssert {
368370
public function json(): JsonAssert {
369371
if ($this->json)
370372
return $this->json;
371-
$contentType = @$this->response->getHeader('Content-Type')[0];
372-
if ($contentType === 'application/json')
373+
$contentType = $this->getResponseContentType();
374+
if (strcasecmp($contentType, 'application/json') === 0)
373375
return $this->json = $this->test->json($this->getResponseContents());
374376
$this->test->fail("Expected the response to have content-type \"application/json\", actual: \"{$contentType}\"");
375377
}
@@ -389,4 +391,10 @@ private function getResponseCookies(): array {
389391
}
390392
return $result;
391393
}
394+
395+
private function getResponseContentType(): string {
396+
$values = $this->response->getHeader('Content-Type');
397+
$header = $values ? $values[0] : '';
398+
return preg_split('/\\s*;\\s*/', $header)[0];
399+
}
392400
}

test/Assert/ResponseAssertTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ public function testAssertContentType(?string $exceptionMessage, ResponseInterfa
125125
public static function dataAssertContentType(): array {
126126
return [
127127
'passed' => [null, new Response(200, ['Content-Type' => 'text/html']), 'text/html'],
128+
'passed with charset without space' => [null, new Response(200, ['content-type' => 'text/html;charset=utf-8']), 'text/html'],
129+
'passed with charset and space' => [null, new Response(200, ['content-type' => 'text/html; charset=utf-8']), 'text/html'],
130+
'passed with boundary without space' => [null, new Response(200, ['content-type' => 'text/html;boundary=----']), 'text/html'],
131+
'passed with boundary and space' => [null, new Response(200, ['content-type' => 'text/html; boundary=----']), 'text/html'],
132+
'passed with charset and boundary' => [null, new Response(200, ['content-type' => 'text/html;charset=utf-8;boundary=----']), 'text/html'],
128133
'failed' => ['Expected the response to have the header "Content-Type" with value "text/html", actual: ""', new Response(200), 'text/html'],
129134
];
130135
}
@@ -386,6 +391,8 @@ public static function dataDocument(): array {
386391
'XML failed' => ['Expected to find at least one element matching the query "//body/p"', new Response(200, ['Content-Type' => 'text/xml'], '<body></body>'), '//body/p'],
387392
'invalid content-type' => ['Expected the response to have content-type of either "text/html" or "text/xml", actual: "text/plain"', new Response(200, ['Content-Type' => 'text/plain'], '<body><p></p></body>'), '//body/p'],
388393
'no content-type' => ['Expected the response to have content-type of either "text/html" or "text/xml", actual: ""', new Response(200, [], '<body><p></p></body>'), '//body/p'],
394+
'text/html + charset' => [null, new Response(200, ['Content-Type' => 'text/html; charset=utf-8'], '<body><p></p></body>'), '//body/p'],
395+
'text/xml + charset' => [null, new Response(200, ['Content-Type' => 'text/xml; charset=utf-8'], '<body><p></p></body>'), '//body/p'],
389396
];
390397
}
391398

@@ -405,6 +412,7 @@ public static function dataJson(): array {
405412
'invalid content-type' => ['Expected the response to have content-type "application/json", actual: "text/plain"', new Response(200, ['Content-Type' => 'text/plain'], '{}'), '$.user', 2],
406413
'no content-type' => ['Expected the response to have content-type "application/json", actual: ""', new Response(200, [], '{}'), '$.user', 2],
407414
'invalid JSON' => ['string does not contain a valid JSON object', new Response(200, ['Content-Type' => 'application/json'], '{"user":'), '$.user', 2],
415+
'content-type + encoding' => [null, new Response(200, ['Content-Type' => 'application/json;charset=utf-8'], '{"user": [{}, {}]}'), '$.user[*]', 2]
408416
];
409417
}
410418

0 commit comments

Comments
 (0)