ldc-arcadia-api/tests/Integration/Presentation/Api/ApiExceptionDispatcherTest.php

83 lines
3.3 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Integration\Presentation\Api;
use Application\Arcadia\Config\AppConfig;
use Illuminate\Http\Request;
use Presentation\Api\Exceptions\ApiExceptionDispatcher;
use Presentation\Api\V1\Exceptions\ApiExceptionRenderer as V1ApiExceptionRenderer;
use Shared\DDD\Exception\NotFoundException;
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
$config = resolve(AppConfig::class);
$renderer = new V1ApiExceptionRenderer($config);
$dispatcher = new ApiExceptionDispatcher($renderer);
$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
$config = resolve(AppConfig::class);
$renderer = new V1ApiExceptionRenderer($config);
$dispatcher = new ApiExceptionDispatcher($renderer);
$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');
});
it('falls back to V1ApiExceptionRenderer for unversioned api requests', function (): void {
// GIVEN
$config = resolve(AppConfig::class);
$renderer = new V1ApiExceptionRenderer($config);
$dispatcher = new ApiExceptionDispatcher($renderer);
$request = Request::create('http://localhost/api/unknown-endpoint', 'GET');
$request->headers->set('Accept', 'application/json');
$exception = new NotFoundException('Resource 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');
});
it('dispatches to V1ApiExceptionRenderer when request accepts JSON even on non-api path', function (): void {
// GIVEN
$config = resolve(AppConfig::class);
$renderer = new V1ApiExceptionRenderer($config);
$dispatcher = new ApiExceptionDispatcher($renderer);
$request = Request::create('http://localhost/something-else', 'GET');
$request->headers->set('Accept', 'application/json');
$exception = new NotFoundException('Something 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');
});
});