Skip to content

Commit de4e021

Browse files
committed
test: strengthen assertions and add edge-case content negotiation tests
Add tests for JSON Content-Type with charset parameter, vendor +json suffix, and case-insensitive Content-Type matching through the responseContentType parameter. Add trait-level test for JSON response on mixed-content-type endpoint. Strengthen assertion specificity in content type mismatch tests.
1 parent 0de784b commit de4e021

2 files changed

Lines changed: 87 additions & 3 deletions

File tree

tests/Unit/OpenApiResponseValidatorTest.php

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,10 @@ public function v30_response_content_type_not_in_spec_fails(): void
369369
);
370370

371371
$this->assertFalse($result->isValid());
372-
$this->assertStringContainsString('not defined', $result->errors()[0]);
373-
$this->assertStringContainsString('text/plain', $result->errors()[0]);
372+
$this->assertStringContainsString("Response Content-Type 'text/plain' is not defined for", $result->errors()[0]);
373+
$this->assertStringContainsString('text/html', $result->errors()[0]);
374+
$this->assertStringContainsString('application/json', $result->errors()[0]);
375+
$this->assertSame('/v1/pets', $result->matchedPath());
374376
}
375377

376378
#[Test]
@@ -389,6 +391,75 @@ public function v30_response_content_type_with_charset_matches_spec(): void
389391
$this->assertSame('/v1/pets', $result->matchedPath());
390392
}
391393

394+
#[Test]
395+
public function v30_json_response_content_type_with_charset_validates_schema(): void
396+
{
397+
$result = $this->validator->validate(
398+
'petstore-3.0',
399+
'POST',
400+
'/v1/pets',
401+
409,
402+
['error' => 'Pet already exists'],
403+
'application/json; charset=utf-8',
404+
);
405+
406+
$this->assertTrue($result->isValid());
407+
$this->assertSame('/v1/pets', $result->matchedPath());
408+
}
409+
410+
#[Test]
411+
public function v30_json_response_content_type_with_charset_and_invalid_body_fails(): void
412+
{
413+
$result = $this->validator->validate(
414+
'petstore-3.0',
415+
'POST',
416+
'/v1/pets',
417+
409,
418+
['wrong_key' => 'value'],
419+
'application/json; charset=utf-8',
420+
);
421+
422+
$this->assertFalse($result->isValid());
423+
$this->assertNotEmpty($result->errors());
424+
}
425+
426+
#[Test]
427+
public function v30_vendor_json_response_content_type_validates_schema(): void
428+
{
429+
$result = $this->validator->validate(
430+
'petstore-3.0',
431+
'GET',
432+
'/v1/pets',
433+
400,
434+
[
435+
'type' => 'https://example.com/bad-request',
436+
'title' => 'Bad Request',
437+
'status' => 400,
438+
'detail' => 'Invalid query parameter',
439+
],
440+
'application/problem+json',
441+
);
442+
443+
$this->assertTrue($result->isValid());
444+
$this->assertSame('/v1/pets', $result->matchedPath());
445+
}
446+
447+
#[Test]
448+
public function v30_case_insensitive_response_content_type_matches_spec(): void
449+
{
450+
$result = $this->validator->validate(
451+
'petstore-3.0',
452+
'POST',
453+
'/v1/pets',
454+
409,
455+
null,
456+
'Text/HTML',
457+
);
458+
459+
$this->assertTrue($result->isValid());
460+
$this->assertSame('/v1/pets', $result->matchedPath());
461+
}
462+
392463
#[Test]
393464
public function v30_null_response_content_type_preserves_existing_behavior(): void
394465
{

tests/Unit/ValidatesOpenApiSchemaTest.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public function non_json_body_fails_with_content_type_mismatch(): void
169169
);
170170

171171
$this->expectException(AssertionFailedError::class);
172-
$this->expectExceptionMessage('not defined');
172+
$this->expectExceptionMessage("Response Content-Type 'text/html' is not defined for");
173173

174174
$this->assertResponseMatchesOpenApiSchema(
175175
$response,
@@ -242,6 +242,19 @@ public function missing_content_type_header_still_parses_json(): void
242242
);
243243
}
244244

245+
#[Test]
246+
public function json_content_type_in_spec_with_mixed_content_types_validates_schema(): void
247+
{
248+
$body = (string) json_encode(['error' => 'Pet already exists'], JSON_THROW_ON_ERROR);
249+
$response = $this->makeTestResponse($body, 409, ['Content-Type' => 'application/json']);
250+
251+
$this->assertResponseMatchesOpenApiSchema(
252+
$response,
253+
HttpMethod::POST,
254+
'/v1/pets',
255+
);
256+
}
257+
245258
#[Test]
246259
public function non_json_content_type_in_spec_with_mixed_content_types_passes(): void
247260
{

0 commit comments

Comments
 (0)