Introduces a NotFoundException to standardize error handling for missing entities.
81 lines
3.1 KiB
PHP
81 lines
3.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Integration\Presentation\Api;
|
|
|
|
use Application\Exceptions\NotFoundException;
|
|
use Illuminate\Http\Request;
|
|
use Presentation\Api\Exceptions\ApiExceptionDispatcher;
|
|
use Presentation\Api\V1\Exceptions\ApiExceptionRenderer as V1ApiExceptionRenderer;
|
|
|
|
covers(ApiExceptionDispatcher::class);
|
|
|
|
describe('API Exception Dispatcher Integration', function (): void {
|
|
it('returns null for non-API web requests that do not accept JSON', function (): void {
|
|
// GIVEN
|
|
$dispatcher = new ApiExceptionDispatcher(new V1ApiExceptionRenderer());
|
|
$request = Request::create('/some-web-route', 'GET');
|
|
$exception = new NotFoundException('Not found');
|
|
|
|
// WHEN
|
|
$response = $dispatcher->render($exception, $request);
|
|
|
|
// THEN
|
|
expect($response)->toBeNull();
|
|
});
|
|
|
|
it('dispatches api/v1 requests to V1ApiExceptionRenderer', function (): void {
|
|
// GIVEN
|
|
$dispatcher = new ApiExceptionDispatcher(new V1ApiExceptionRenderer());
|
|
$request = Request::create('http://localhost/api/v1/employees/999', 'GET');
|
|
$exception = new NotFoundException('Employee not found');
|
|
|
|
// WHEN
|
|
$response = $dispatcher->render($exception, $request);
|
|
|
|
// THEN
|
|
expect($response)->not->toBeNull()
|
|
->and($response?->getStatusCode())->toBe(404)
|
|
->and($response?->headers->get('Content-Type'))->toBe('application/problem+json');
|
|
|
|
/** @var array<string, mixed> $data */
|
|
$data = json_decode((string) $response?->getContent(), true);
|
|
expect($data['status'])->toBe(404)
|
|
->and($data['title'])->toBe('Resource Not Found')
|
|
->and($data['detail'])->toBe('Employee not found');
|
|
});
|
|
|
|
it('falls back to V1ApiExceptionRenderer for unversioned api requests', function (): void {
|
|
// GIVEN
|
|
$dispatcher = new ApiExceptionDispatcher(new V1ApiExceptionRenderer());
|
|
$request = Request::create('http://localhost/api/ping', 'GET');
|
|
$exception = new \DomainException('Domain invariant error');
|
|
|
|
// WHEN
|
|
$response = $dispatcher->render($exception, $request);
|
|
|
|
// THEN
|
|
expect($response)->not->toBeNull()
|
|
->and($response?->getStatusCode())->toBe(422);
|
|
|
|
/** @var array<string, mixed> $data */
|
|
$data = json_decode((string) $response?->getContent(), true);
|
|
expect($data['status'])->toBe(422)
|
|
->and($data['detail'])->toBe('Domain invariant error');
|
|
});
|
|
|
|
it('dispatches to V1ApiExceptionRenderer when request accepts JSON even on non-api path', function (): void {
|
|
// GIVEN
|
|
$dispatcher = new ApiExceptionDispatcher(new V1ApiExceptionRenderer());
|
|
$request = Request::create('http://localhost/custom-endpoint', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/json']);
|
|
$exception = new NotFoundException('Custom endpoint not found');
|
|
|
|
// WHEN
|
|
$response = $dispatcher->render($exception, $request);
|
|
|
|
// THEN
|
|
expect($response)->not->toBeNull()
|
|
->and($response?->getStatusCode())->toBe(404);
|
|
});
|
|
});
|