mirror of
https://github.com/alexjustesen/speedtest-tracker.git
synced 2026-06-23 02:20:09 +00:00
API requires accept json header (#2333)
Co-authored-by: Alex Justesen <1144087+alexjustesen@users.noreply.github.com> Co-authored-by: GitHub Action <actions@github.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
|
||||
|
||||
class AcceptJsonMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): SymfonyResponse
|
||||
{
|
||||
// Check if the Accept header includes application/json
|
||||
if (! $request->acceptsJson()) {
|
||||
return response()->json([
|
||||
'message' => 'This endpoint only accepts JSON. Please include "Accept: application/json" in your request headers.',
|
||||
'error' => 'Unsupported Media Type',
|
||||
], Response::HTTP_NOT_ACCEPTABLE);
|
||||
}
|
||||
|
||||
// Ensure the response is JSON
|
||||
$response = $next($request);
|
||||
|
||||
// Force JSON content type if not already set
|
||||
if (! $response->headers->has('Content-Type') ||
|
||||
! str_contains($response->headers->get('Content-Type'), 'application/json')) {
|
||||
$response->headers->set('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,9 @@ class OoklaAnnotations
|
||||
description: 'Returns an array of available Ookla speedtest servers. Requires an API token with `ookla:list-servers` scope.',
|
||||
operationId: 'listOoklaServers',
|
||||
tags: ['Servers'],
|
||||
parameters: [
|
||||
new OA\Parameter(ref: '#/components/parameters/AcceptHeader'),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: Response::HTTP_OK,
|
||||
@@ -33,6 +36,11 @@ class OoklaAnnotations
|
||||
description: 'Forbidden',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/ForbiddenError')
|
||||
),
|
||||
new OA\Response(
|
||||
response: Response::HTTP_NOT_ACCEPTABLE,
|
||||
description: 'Not Acceptable - Missing or invalid Accept header',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/NotAcceptableError')
|
||||
),
|
||||
]
|
||||
)]
|
||||
public function listServers(): void {}
|
||||
|
||||
@@ -17,6 +17,7 @@ class ResultsAnnotations
|
||||
operationId: 'listResults',
|
||||
tags: ['Results'],
|
||||
parameters: [
|
||||
new OA\Parameter(ref: '#/components/parameters/AcceptHeader'),
|
||||
new OA\Parameter(
|
||||
name: 'per_page',
|
||||
in: 'query',
|
||||
@@ -104,6 +105,11 @@ class ResultsAnnotations
|
||||
description: 'Unauthenticated',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/UnauthenticatedError')
|
||||
),
|
||||
new OA\Response(
|
||||
response: Response::HTTP_NOT_ACCEPTABLE,
|
||||
description: 'Not Acceptable - Missing or invalid Accept header',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/NotAcceptableError')
|
||||
),
|
||||
new OA\Response(
|
||||
response: Response::HTTP_UNPROCESSABLE_ENTITY,
|
||||
description: 'Validation failed',
|
||||
@@ -119,6 +125,7 @@ class ResultsAnnotations
|
||||
operationId: 'getResult',
|
||||
tags: ['Results'],
|
||||
parameters: [
|
||||
new OA\Parameter(ref: '#/components/parameters/AcceptHeader'),
|
||||
new OA\Parameter(
|
||||
name: 'id',
|
||||
in: 'path',
|
||||
@@ -143,6 +150,11 @@ class ResultsAnnotations
|
||||
description: 'Unauthenticated',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/UnauthenticatedError')
|
||||
),
|
||||
new OA\Response(
|
||||
response: Response::HTTP_NOT_ACCEPTABLE,
|
||||
description: 'Not Acceptable - Missing or invalid Accept header',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/NotAcceptableError')
|
||||
),
|
||||
new OA\Response(
|
||||
response: Response::HTTP_NOT_FOUND,
|
||||
description: 'Result not found',
|
||||
@@ -157,6 +169,9 @@ class ResultsAnnotations
|
||||
summary: 'Get the most recent result',
|
||||
operationId: 'getLatestResult',
|
||||
tags: ['Results'],
|
||||
parameters: [
|
||||
new OA\Parameter(ref: '#/components/parameters/AcceptHeader'),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: Response::HTTP_OK,
|
||||
@@ -173,6 +188,11 @@ class ResultsAnnotations
|
||||
description: 'Unauthenticated',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/UnauthenticatedError')
|
||||
),
|
||||
new OA\Response(
|
||||
response: Response::HTTP_NOT_ACCEPTABLE,
|
||||
description: 'Not Acceptable - Missing or invalid Accept header',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/NotAcceptableError')
|
||||
),
|
||||
new OA\Response(
|
||||
response: Response::HTTP_NOT_FOUND,
|
||||
description: 'No result found',
|
||||
|
||||
@@ -17,6 +17,7 @@ class SpeedtestAnnotations
|
||||
operationId: 'runSpeedtest',
|
||||
tags: ['Speedtests'],
|
||||
parameters: [
|
||||
new OA\Parameter(ref: '#/components/parameters/AcceptHeader'),
|
||||
new OA\Parameter(
|
||||
name: 'server_id',
|
||||
in: 'query',
|
||||
@@ -41,6 +42,11 @@ class SpeedtestAnnotations
|
||||
description: 'Forbidden',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/ForbiddenError')
|
||||
),
|
||||
new OA\Response(
|
||||
response: Response::HTTP_NOT_ACCEPTABLE,
|
||||
description: 'Not Acceptable - Missing or invalid Accept header',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/NotAcceptableError')
|
||||
),
|
||||
new OA\Response(
|
||||
response: Response::HTTP_UNPROCESSABLE_ENTITY,
|
||||
description: 'Validation error',
|
||||
@@ -58,6 +64,9 @@ class SpeedtestAnnotations
|
||||
summary: 'List available Ookla speedtest servers',
|
||||
operationId: 'listSpeedtestServers',
|
||||
tags: ['Speedtests'],
|
||||
parameters: [
|
||||
new OA\Parameter(ref: '#/components/parameters/AcceptHeader'),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: Response::HTTP_OK,
|
||||
@@ -77,6 +86,11 @@ class SpeedtestAnnotations
|
||||
example: ['message' => 'You do not have permission to view speedtest servers.']
|
||||
)
|
||||
),
|
||||
new OA\Response(
|
||||
response: Response::HTTP_NOT_ACCEPTABLE,
|
||||
description: 'Not Acceptable - Missing or invalid Accept header',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/NotAcceptableError')
|
||||
),
|
||||
]
|
||||
)]
|
||||
public function listServers(): void {}
|
||||
|
||||
@@ -17,6 +17,7 @@ class StatsAnnotations
|
||||
operationId: 'getStats',
|
||||
tags: ['Stats'],
|
||||
parameters: [
|
||||
new OA\Parameter(ref: '#/components/parameters/AcceptHeader'),
|
||||
new OA\Parameter(
|
||||
name: 'start_at',
|
||||
in: 'query',
|
||||
@@ -48,6 +49,11 @@ class StatsAnnotations
|
||||
description: 'Forbidden',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/ForbiddenError')
|
||||
),
|
||||
new OA\Response(
|
||||
response: Response::HTTP_NOT_ACCEPTABLE,
|
||||
description: 'Not Acceptable - Missing or invalid Accept header',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/NotAcceptableError')
|
||||
),
|
||||
new OA\Response(
|
||||
response: Response::HTTP_UNPROCESSABLE_ENTITY,
|
||||
description: 'Validation error',
|
||||
|
||||
@@ -20,11 +20,12 @@ use OpenApi\Attributes as OA;
|
||||
],
|
||||
parameters: [
|
||||
new OA\Parameter(
|
||||
parameter: 'AcceptHeader',
|
||||
name: 'Accept',
|
||||
in: 'header',
|
||||
required: true,
|
||||
schema: new OA\Schema(type: 'string', default: 'application/json'),
|
||||
description: 'Expected response format'
|
||||
description: 'Must be "application/json" - this API only accepts and returns JSON'
|
||||
),
|
||||
]
|
||||
),
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\OpenApi\Schemas;
|
||||
|
||||
use OpenApi\Attributes as OA;
|
||||
|
||||
#[OA\Schema(
|
||||
schema: 'NotAcceptableError',
|
||||
description: 'Error response when the Accept header is missing or invalid',
|
||||
type: 'object',
|
||||
properties: [
|
||||
new OA\Property(
|
||||
property: 'message',
|
||||
type: 'string',
|
||||
example: 'This endpoint only accepts JSON. Please include "Accept: application/json" in your request headers.'
|
||||
),
|
||||
new OA\Property(
|
||||
property: 'error',
|
||||
type: 'string',
|
||||
example: 'Unsupported Media Type'
|
||||
),
|
||||
]
|
||||
)]
|
||||
class NotAcceptableErrorSchema {}
|
||||
@@ -17,6 +17,7 @@ return Application::configure(basePath: dirname(__DIR__))
|
||||
$middleware->alias([
|
||||
'getting-started' => App\Http\Middleware\GettingStarted::class,
|
||||
'public-dashboard' => App\Http\Middleware\PublicDashboard::class,
|
||||
'accept-json' => App\Http\Middleware\AcceptJsonMiddleware::class,
|
||||
]);
|
||||
|
||||
$middleware->prependToGroup('api', [
|
||||
|
||||
+113
-2
@@ -17,6 +17,9 @@
|
||||
"summary": "List all results",
|
||||
"operationId": "listResults",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/components/parameters/AcceptHeader"
|
||||
},
|
||||
{
|
||||
"name": "per_page",
|
||||
"in": "query",
|
||||
@@ -156,6 +159,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"406": {
|
||||
"description": "Not Acceptable - Missing or invalid Accept header",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/NotAcceptableError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation failed",
|
||||
"content": {
|
||||
@@ -178,6 +191,9 @@
|
||||
"summary": "Fetch aggregated Speedtest statistics",
|
||||
"operationId": "getStats",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/components/parameters/AcceptHeader"
|
||||
},
|
||||
{
|
||||
"name": "start_at",
|
||||
"in": "query",
|
||||
@@ -230,6 +246,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"406": {
|
||||
"description": "Not Acceptable - Missing or invalid Accept header",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/NotAcceptableError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation error",
|
||||
"content": {
|
||||
@@ -251,6 +277,11 @@
|
||||
"summary": "List available Ookla speedtest servers",
|
||||
"description": "Returns an array of available Ookla speedtest servers. Requires an API token with `ookla:list-servers` scope.",
|
||||
"operationId": "listOoklaServers",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/components/parameters/AcceptHeader"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Servers retrieved successfully",
|
||||
@@ -281,6 +312,16 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"406": {
|
||||
"description": "Not Acceptable - Missing or invalid Accept header",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/NotAcceptableError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,6 +334,9 @@
|
||||
"summary": "Get a single result",
|
||||
"operationId": "getResult",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/components/parameters/AcceptHeader"
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
@@ -334,6 +378,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"406": {
|
||||
"description": "Not Acceptable - Missing or invalid Accept header",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/NotAcceptableError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Result not found",
|
||||
"content": {
|
||||
@@ -354,6 +408,11 @@
|
||||
],
|
||||
"summary": "Get the most recent result",
|
||||
"operationId": "getLatestResult",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/components/parameters/AcceptHeader"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
@@ -385,6 +444,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"406": {
|
||||
"description": "Not Acceptable - Missing or invalid Accept header",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/NotAcceptableError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "No result found",
|
||||
"content": {
|
||||
@@ -406,6 +475,9 @@
|
||||
"summary": "Run a new Ookla speedtest",
|
||||
"operationId": "runSpeedtest",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/components/parameters/AcceptHeader"
|
||||
},
|
||||
{
|
||||
"name": "server_id",
|
||||
"in": "query",
|
||||
@@ -447,6 +519,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"406": {
|
||||
"description": "Not Acceptable - Missing or invalid Accept header",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/NotAcceptableError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation error",
|
||||
"content": {
|
||||
@@ -467,6 +549,11 @@
|
||||
],
|
||||
"summary": "List available Ookla speedtest servers",
|
||||
"operationId": "listSpeedtestServers",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/components/parameters/AcceptHeader"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
@@ -500,6 +587,16 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"406": {
|
||||
"description": "Not Acceptable - Missing or invalid Accept header",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/NotAcceptableError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -517,6 +614,20 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"NotAcceptableError": {
|
||||
"description": "Error response when the Accept header is missing or invalid",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "This endpoint only accepts JSON. Please include \"Accept: application/json\" in your request headers."
|
||||
},
|
||||
"error": {
|
||||
"type": "string",
|
||||
"example": "Unsupported Media Type"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"NotFoundError": {
|
||||
"description": "Error when a requested result is not found",
|
||||
"properties": {
|
||||
@@ -1038,10 +1149,10 @@
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"Accept": {
|
||||
"AcceptHeader": {
|
||||
"name": "Accept",
|
||||
"in": "header",
|
||||
"description": "Expected response format",
|
||||
"description": "Must be \"application/json\" - this API only accepts and returns JSON",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
|
||||
+2
-1
@@ -20,8 +20,9 @@ Route::get('/healthcheck', function () {
|
||||
* @deprecated
|
||||
*/
|
||||
Route::get('/speedtest/latest', GetLatestController::class)
|
||||
->middleware('accept-json')
|
||||
->name('speedtest.latest');
|
||||
|
||||
Route::middleware(['auth:sanctum', 'throttle:api'])->group(function () {
|
||||
Route::middleware(['auth:sanctum', 'throttle:api', 'accept-json'])->group(function () {
|
||||
require __DIR__.'/api/v1/routes.php';
|
||||
});
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
test('AcceptJsonMiddleware accepts requests without Accept header (Laravel default)', function () {
|
||||
// Laravel's acceptsJson() returns true when no Accept header is present
|
||||
$middleware = new \App\Http\Middleware\AcceptJsonMiddleware;
|
||||
|
||||
$request = \Illuminate\Http\Request::create('/api/test', 'GET');
|
||||
|
||||
$response = $middleware->handle($request, function () {
|
||||
return response()->json(['success' => true]);
|
||||
});
|
||||
|
||||
expect($response->getStatusCode())->toBe(200);
|
||||
|
||||
$content = json_decode($response->getContent(), true);
|
||||
expect($content['success'])->toBe(true);
|
||||
});
|
||||
|
||||
test('AcceptJsonMiddleware accepts requests with Accept: application/json header', function () {
|
||||
$middleware = new \App\Http\Middleware\AcceptJsonMiddleware;
|
||||
|
||||
$request = \Illuminate\Http\Request::create('/api/test', 'GET', [], [], [], [
|
||||
'HTTP_ACCEPT' => 'application/json',
|
||||
]);
|
||||
|
||||
$response = $middleware->handle($request, function () {
|
||||
return response()->json(['success' => true]);
|
||||
});
|
||||
|
||||
expect($response->getStatusCode())->toBe(200);
|
||||
|
||||
$content = json_decode($response->getContent(), true);
|
||||
expect($content['success'])->toBe(true);
|
||||
});
|
||||
|
||||
test('AcceptJsonMiddleware rejects requests with Accept: */json header', function () {
|
||||
// Laravel's acceptsJson() returns false for */json
|
||||
$middleware = new \App\Http\Middleware\AcceptJsonMiddleware;
|
||||
|
||||
$request = \Illuminate\Http\Request::create('/api/test', 'GET', [], [], [], [
|
||||
'HTTP_ACCEPT' => '*/json',
|
||||
]);
|
||||
|
||||
$response = $middleware->handle($request, function () {
|
||||
return response()->json(['success' => true]);
|
||||
});
|
||||
|
||||
expect($response->getStatusCode())->toBe(406);
|
||||
|
||||
$content = json_decode($response->getContent(), true);
|
||||
expect($content['message'])->toBe('This endpoint only accepts JSON. Please include "Accept: application/json" in your request headers.');
|
||||
expect($content['error'])->toBe('Unsupported Media Type');
|
||||
});
|
||||
|
||||
test('AcceptJsonMiddleware accepts requests with Accept: application/* header', function () {
|
||||
$middleware = new \App\Http\Middleware\AcceptJsonMiddleware;
|
||||
|
||||
$request = \Illuminate\Http\Request::create('/api/test', 'GET', [], [], [], [
|
||||
'HTTP_ACCEPT' => 'application/*',
|
||||
]);
|
||||
|
||||
$response = $middleware->handle($request, function () {
|
||||
return response()->json(['success' => true]);
|
||||
});
|
||||
|
||||
expect($response->getStatusCode())->toBe(200);
|
||||
});
|
||||
|
||||
test('AcceptJsonMiddleware accepts requests with multiple Accept headers including application/json', function () {
|
||||
$middleware = new \App\Http\Middleware\AcceptJsonMiddleware;
|
||||
|
||||
$request = \Illuminate\Http\Request::create('/api/test', 'GET', [], [], [], [
|
||||
'HTTP_ACCEPT' => 'text/html,application/json,application/xml;q=0.9,*/*;q=0.8',
|
||||
]);
|
||||
|
||||
$response = $middleware->handle($request, function () {
|
||||
return response()->json(['success' => true]);
|
||||
});
|
||||
|
||||
expect($response->getStatusCode())->toBe(200);
|
||||
});
|
||||
|
||||
test('AcceptJsonMiddleware rejects requests with only non-JSON Accept headers', function () {
|
||||
$middleware = new \App\Http\Middleware\AcceptJsonMiddleware;
|
||||
|
||||
$request = \Illuminate\Http\Request::create('/api/test', 'GET', [], [], [], [
|
||||
'HTTP_ACCEPT' => 'text/html,application/xml',
|
||||
]);
|
||||
|
||||
$response = $middleware->handle($request, function () {
|
||||
return response()->json(['success' => true]);
|
||||
});
|
||||
|
||||
expect($response->getStatusCode())->toBe(406);
|
||||
|
||||
$content = json_decode($response->getContent(), true);
|
||||
expect($content['message'])->toBe('This endpoint only accepts JSON. Please include "Accept: application/json" in your request headers.');
|
||||
expect($content['error'])->toBe('Unsupported Media Type');
|
||||
});
|
||||
|
||||
test('AcceptJsonMiddleware sets Content-Type header to application/json when not already set', function () {
|
||||
$middleware = new \App\Http\Middleware\AcceptJsonMiddleware;
|
||||
|
||||
$request = \Illuminate\Http\Request::create('/api/test', 'GET', [], [], [], [
|
||||
'HTTP_ACCEPT' => 'application/json',
|
||||
]);
|
||||
|
||||
$response = $middleware->handle($request, function () {
|
||||
return response(['success' => true]);
|
||||
});
|
||||
|
||||
expect($response->headers->get('Content-Type'))->toBe('application/json');
|
||||
});
|
||||
|
||||
test('AcceptJsonMiddleware preserves existing application/json Content-Type header', function () {
|
||||
$middleware = new \App\Http\Middleware\AcceptJsonMiddleware;
|
||||
|
||||
$request = \Illuminate\Http\Request::create('/api/test', 'GET', [], [], [], [
|
||||
'HTTP_ACCEPT' => 'application/json',
|
||||
]);
|
||||
|
||||
$response = $middleware->handle($request, function () {
|
||||
return response()->json(['success' => true]);
|
||||
});
|
||||
|
||||
expect($response->headers->get('Content-Type'))->toContain('application/json');
|
||||
});
|
||||
|
||||
test('AcceptJsonMiddleware rejects requests that only accept HTML', function () {
|
||||
$middleware = new \App\Http\Middleware\AcceptJsonMiddleware;
|
||||
|
||||
$request = \Illuminate\Http\Request::create('/api/test', 'GET', [], [], [], [
|
||||
'HTTP_ACCEPT' => 'text/html',
|
||||
]);
|
||||
|
||||
$response = $middleware->handle($request, function () {
|
||||
return response()->json(['success' => true]);
|
||||
});
|
||||
|
||||
expect($response->getStatusCode())->toBe(406);
|
||||
|
||||
$content = json_decode($response->getContent(), true);
|
||||
expect($content['message'])->toBe('This endpoint only accepts JSON. Please include "Accept: application/json" in your request headers.');
|
||||
expect($content['error'])->toBe('Unsupported Media Type');
|
||||
});
|
||||
|
||||
test('AcceptJsonMiddleware accepts requests with */* Accept header', function () {
|
||||
// Laravel's acceptsJson() returns true for */*
|
||||
$middleware = new \App\Http\Middleware\AcceptJsonMiddleware;
|
||||
|
||||
$request = \Illuminate\Http\Request::create('/api/test', 'GET', [], [], [], [
|
||||
'HTTP_ACCEPT' => '*/*',
|
||||
]);
|
||||
|
||||
$response = $middleware->handle($request, function () {
|
||||
return response()->json(['success' => true]);
|
||||
});
|
||||
|
||||
expect($response->getStatusCode())->toBe(200);
|
||||
});
|
||||
Reference in New Issue
Block a user