You've already forked Php-Template
feat: implement NotFoundResponse and ServerErrorResponse classes with corresponding tests
Some checks failed
🧪✨ Tests Workflow / 🛡️ 🔒 License Check (push) Successful in 4m16s
🧪✨ Tests Workflow / 📝 ✨ Code Lint (push) Successful in 4m17s
🧪✨ Tests Workflow / 🛡️ 🔒 Library Audit (push) Successful in 4m27s
🧪✨ Tests Workflow / 🧪 ✨ Database Migrations (push) Successful in 4m32s
🧪✨ Tests Workflow / 🐙 🔍 Code Sniffer (push) Successful in 4m15s
🧪✨ Tests Workflow / 🧪 ✅ Unit Tests (push) Failing after 3m1s
Some checks failed
🧪✨ Tests Workflow / 🛡️ 🔒 License Check (push) Successful in 4m16s
🧪✨ Tests Workflow / 📝 ✨ Code Lint (push) Successful in 4m17s
🧪✨ Tests Workflow / 🛡️ 🔒 Library Audit (push) Successful in 4m27s
🧪✨ Tests Workflow / 🧪 ✨ Database Migrations (push) Successful in 4m32s
🧪✨ Tests Workflow / 🐙 🔍 Code Sniffer (push) Successful in 4m15s
🧪✨ Tests Workflow / 🧪 ✅ Unit Tests (push) Failing after 3m1s
This commit is contained in:
@@ -6,6 +6,7 @@ return [
|
||||
|
||||
'app' => [
|
||||
'log_level' => Env::get('LOG_LEVEL', 'debug'),
|
||||
'dev_mode' => Env::get('DEV_MODE', false, 'bool'),
|
||||
],
|
||||
|
||||
/**
|
||||
|
||||
@@ -106,6 +106,7 @@ services:
|
||||
DEBUG: 1
|
||||
REDIS_HOST: redis
|
||||
DB_HOST: postgres
|
||||
DEV_MODE: 1
|
||||
|
||||
## Kafka and Zookeeper for local development
|
||||
kafka-ui:
|
||||
|
||||
25
src/Api.php
25
src/Api.php
@@ -16,9 +16,10 @@ use Siteworxpro\App\Http\JsonResponseFactory;
|
||||
use Siteworxpro\App\Http\Middleware\CorsMiddleware;
|
||||
use Siteworxpro\App\Http\Middleware\JwtMiddleware;
|
||||
use Siteworxpro\App\Http\Middleware\ScopeMiddleware;
|
||||
use Siteworxpro\App\Http\Responses\NotFoundResponse;
|
||||
use Siteworxpro\App\Http\Responses\ServerErrorResponse;
|
||||
use Siteworxpro\App\Services\Facades\Config;
|
||||
use Siteworxpro\App\Services\Facades\Logger;
|
||||
use Siteworxpro\HttpStatus\CodesEnum;
|
||||
use Spiral\RoadRunner\Http\PSR7Worker;
|
||||
use Spiral\RoadRunner\Worker;
|
||||
|
||||
@@ -112,28 +113,20 @@ class Api
|
||||
$response = $this->router->handle($request);
|
||||
$this->worker->respond($response);
|
||||
} catch (MethodNotAllowedException | NotFoundException) {
|
||||
$uri = '';
|
||||
if (isset($request)) {
|
||||
$uri = $request->getUri()->getPath();
|
||||
}
|
||||
|
||||
$this->worker->respond(
|
||||
JsonResponseFactory::createJsonResponse(
|
||||
['status_code' => 404, 'reason_phrase' => 'Not Found'],
|
||||
CodesEnum::NOT_FOUND
|
||||
)
|
||||
JsonResponseFactory::createJsonResponse(new NotFoundResponse($uri))
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
Logger::error($e->getMessage());
|
||||
Logger::error($e->getTraceAsString());
|
||||
|
||||
$json = ['status_code' => 500, 'reason_phrase' => 'Server Error'];
|
||||
if (Config::get("server.dev_mode")) {
|
||||
$json = [
|
||||
'status_code' => 500,
|
||||
'reason_phrase' => 'Server Error',
|
||||
'message' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
];
|
||||
}
|
||||
|
||||
$this->worker->respond(
|
||||
JsonResponseFactory::createJsonResponse($json, CodesEnum::INTERNAL_SERVER_ERROR)
|
||||
JsonResponseFactory::createJsonResponse(new ServerErrorResponse($e))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ class JwtMiddleware extends Middleware
|
||||
} elseif (str_contains($keyConfig, '.well-known/')) {
|
||||
$jwt = explode('.', $token);
|
||||
if (count($jwt) !== 3) {
|
||||
throw new \RuntimeException('Invalid JWT structure for JWKS key retrieval.');
|
||||
throw new InvalidTokenStructure('Invalid JWT structure for JWKS key retrieval.');
|
||||
}
|
||||
$header = json_decode(base64_decode($jwt[0]), true, 512, JSON_THROW_ON_ERROR);
|
||||
$keyId = $header['kid'] ?? '0'; // Default to '0' if no kid present
|
||||
|
||||
40
src/Http/Responses/NotFoundResponse.php
Normal file
40
src/Http/Responses/NotFoundResponse.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Siteworxpro\App\Http\Responses;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Siteworxpro\HttpStatus\CodesEnum;
|
||||
use OpenApi\Attributes as OA;
|
||||
|
||||
#[OA\Schema(
|
||||
schema: 'NotFoundResponse',
|
||||
properties: [
|
||||
new OA\Property(
|
||||
property: 'message',
|
||||
type: 'string',
|
||||
example: 'The requested resource /api/resource was not found.'
|
||||
),
|
||||
new OA\Property(property: 'status_code', type: 'integer', example: 404),
|
||||
new OA\Property(
|
||||
property: 'context',
|
||||
description: 'Additional context about the not found error.',
|
||||
type: 'object',
|
||||
example: '{}'
|
||||
),
|
||||
]
|
||||
)]
|
||||
readonly class NotFoundResponse implements Arrayable
|
||||
{
|
||||
public function __construct(private string $uri, private array $context = [])
|
||||
{
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'status_code' => CodesEnum::NOT_FOUND->value,
|
||||
'message' => 'The requested resource ' . $this->uri . ' was not found.',
|
||||
'context' => $this->context,
|
||||
];
|
||||
}
|
||||
}
|
||||
56
src/Http/Responses/ServerErrorResponse.php
Normal file
56
src/Http/Responses/ServerErrorResponse.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Siteworxpro\App\Http\Responses;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Siteworxpro\App\Services\Facades\Config;
|
||||
use Siteworxpro\HttpStatus\CodesEnum;
|
||||
use OpenApi\Attributes as OA;
|
||||
|
||||
#[OA\Schema(
|
||||
schema: 'ServerErrorResponse',
|
||||
properties: array(
|
||||
new OA\Property(property: 'message', type: 'string', example: 'An internal server error occurred.'),
|
||||
new OA\Property(property: 'status_code', type: 'integer', example: 500),
|
||||
new OA\Property(
|
||||
property: 'file',
|
||||
type: 'string',
|
||||
example: '/var/www/html/app/Http/Controllers/ExampleController.php'
|
||||
),
|
||||
new OA\Property(property: 'line', type: 'integer', example: 42),
|
||||
new OA\Property(
|
||||
property: 'trace',
|
||||
type: 'array',
|
||||
items: new OA\Items(type: 'string'),
|
||||
)
|
||||
)
|
||||
)]
|
||||
readonly class ServerErrorResponse implements Arrayable
|
||||
{
|
||||
public function __construct(private \Throwable $e, private array $context = [])
|
||||
{
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
if (Config::get('app.dev_mode')) {
|
||||
return [
|
||||
'status_code' => $this->e->getCode() != 0 ?
|
||||
$this->e->getCode() :
|
||||
CodesEnum::INTERNAL_SERVER_ERROR->value,
|
||||
'message' => $this->e->getMessage(),
|
||||
'file' => $this->e->getFile(),
|
||||
'line' => $this->e->getLine(),
|
||||
'trace' => $this->e->getTrace(),
|
||||
'context' => $this->context,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'status_code' => $this->e->getCode() != 0 ?
|
||||
$this->e->getCode() :
|
||||
CodesEnum::INTERNAL_SERVER_ERROR->value,
|
||||
'message' => 'An internal server error occurred.',
|
||||
];
|
||||
}
|
||||
}
|
||||
22
tests/Http/Responses/NotFoundResponseTest.php
Normal file
22
tests/Http/Responses/NotFoundResponseTest.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Siteworxpro\Tests\Http\Responses;
|
||||
|
||||
use Siteworxpro\App\Http\Responses\NotFoundResponse;
|
||||
use Siteworxpro\Tests\Unit;
|
||||
|
||||
class NotFoundResponseTest extends Unit
|
||||
{
|
||||
public function testToArray(): void
|
||||
{
|
||||
$response = new NotFoundResponse('/api/resource', ['key' => 'value']);
|
||||
|
||||
$expected = [
|
||||
'status_code' => 404,
|
||||
'message' => 'The requested resource /api/resource was not found.',
|
||||
'context' => ['key' => 'value'],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $response->toArray());
|
||||
}
|
||||
}
|
||||
89
tests/Http/Responses/ServerErrorResponseTest.php
Normal file
89
tests/Http/Responses/ServerErrorResponseTest.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Siteworxpro\Tests\Http\Responses;
|
||||
|
||||
use Siteworxpro\App\Http\Responses\ServerErrorResponse;
|
||||
use Siteworxpro\App\Services\Facades\Config;
|
||||
use Siteworxpro\Tests\Unit;
|
||||
|
||||
class ServerErrorResponseTest extends Unit
|
||||
{
|
||||
public function testToArrayInDevMode(): void
|
||||
{
|
||||
Config::set('app.dev_mode', true);
|
||||
|
||||
try {
|
||||
// Simulate an exception to generate a server error response
|
||||
throw new \Exception('A Test Error occurred.');
|
||||
} catch (\Exception $e) {
|
||||
$response = new ServerErrorResponse($e, ['operation' => 'data_processing']);
|
||||
|
||||
$expected = [
|
||||
'status_code' => 500,
|
||||
'message' => 'A Test Error occurred.',
|
||||
'context' => [
|
||||
'operation' => 'data_processing'
|
||||
],
|
||||
'file' => '/app/tests/Http/Responses/ServerErrorResponseTest.php',
|
||||
'line' => $e->getLine(),
|
||||
'trace' => $e->getTrace(),
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $response->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
public function testToArrayNotInDevMode(): void
|
||||
{
|
||||
try {
|
||||
throw new \Exception('A Test Error occurred.');
|
||||
} catch (\Exception $exception) {
|
||||
$response = new ServerErrorResponse($exception);
|
||||
|
||||
$expected = [
|
||||
'status_code' => 500,
|
||||
'message' => 'An internal server error occurred.',
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $response->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
public function testToArrayIfCodeIsSet(): void
|
||||
{
|
||||
try {
|
||||
throw new \Exception('A Test Error occurred.', 1234);
|
||||
} catch (\Exception $exception) {
|
||||
$response = new ServerErrorResponse($exception);
|
||||
|
||||
$expected = [
|
||||
'status_code' => 1234,
|
||||
'message' => 'An internal server error occurred.',
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $response->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
public function testToArrayIfCodeIsSetDevMode(): void
|
||||
{
|
||||
Config::set('app.dev_mode', true);
|
||||
|
||||
try {
|
||||
throw new \Exception('A Test Error occurred.', 1234);
|
||||
} catch (\Exception $exception) {
|
||||
$response = new ServerErrorResponse($exception);
|
||||
|
||||
$expected = [
|
||||
'status_code' => 1234,
|
||||
'message' => 'A Test Error occurred.',
|
||||
'file' => '/app/tests/Http/Responses/ServerErrorResponseTest.php',
|
||||
'line' => $exception->getLine(),
|
||||
'trace' => $exception->getTrace(),
|
||||
'context' => [],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $response->toArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user