test(ApiV1Middlewares): add feature tests for middlewares behavior

Includes tests for ETag handling and content negotiation.
This commit is contained in:
Jérémy Munsch 2026-08-14 16:47:58 +02:00
parent 0a1d56fc69
commit b0cd8d25a3
Signed by: forge-joniko
GPG key ID: D7EFE2F5CB6CC0E4

View file

@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
namespace Tests\Feature\Api\V1;
use Presentation\Api\V1\Http\Middlewares\EnsureApiV1AcceptsJson;
use Presentation\Api\V1\Http\Middlewares\SetApiV1Etag;
covers(
EnsureApiV1AcceptsJson::class,
SetApiV1Etag::class
);
describe('API V1 Middlewares Feature Tests', function (): void {
it('returns ETag header on 200 GET requests and 304 Not Modified when If-None-Match matches', function (): void {
// GIVEN
/** @var \Tests\TestCase $this */
$response = $this->getJson('/api/v1/employees');
// THEN
$response->assertStatus(200);
$etag = $response->headers->get('ETag');
expect($etag)->toBeString()->and($etag)->not->toBeEmpty();
// WHEN: Sending conditional GET with matching ETag
$conditionalResponse = $this->withHeaders([
'If-None-Match' => (string) $etag,
])->getJson('/api/v1/employees');
// THEN: Returns 304 Not Modified
$conditionalResponse->assertStatus(304);
expect($conditionalResponse->getContent())->toBeEmpty();
});
it('returns 406 Not Acceptable when Accept header explicitly excludes JSON', function (): void {
// GIVEN
/** @var \Tests\TestCase $this */
$response = $this->withHeaders([
'Accept' => 'text/html',
])->get('/api/v1/employees');
// THEN
$response->assertStatus(406)
->assertHeader('Content-Type', 'application/problem+json');
/** @var array<string, mixed> $data */
$data = json_decode((string) $response->getContent(), true);
expect($data['status'])->toBe(406)
->and($data['title'])->toBe('Not Acceptable');
});
it('allows GET /api/v1/openapi route to return YAML spec without forcing JSON or returning 406', function (): void {
// GIVEN
/** @var \Tests\TestCase $this */
$response = $this->withHeaders([
'Accept' => 'application/yaml',
])->get('/api/v1/openapi');
// THEN
$response->assertStatus(200)
->assertHeader('Content-Type', 'application/yaml');
$etag = $response->headers->get('ETag');
expect($etag)->toBeString()->and($etag)->not->toBeEmpty();
});
});