Files
alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiClientCompatibilityVersioningContractTest.php
T
2026-06-09 01:25:14 -04:00

73 lines
2.8 KiB
PHP

<?php
namespace Tests\Feature\Api\V1\FullSurface;
use Illuminate\Support\Facades\Route;
use Tests\Feature\Api\V1\FullSurface\Support\FullSurfaceE2EContractCase;
class ApiClientCompatibilityVersioningContractTest extends FullSurfaceE2EContractCase
{
public function test_publicly_registered_api_routes_remain_versioned_or_explicitly_legacy(): void
{
$allowedUnversioned = [
'api/login', 'api/logout', 'api/user', 'api/register', 'api/forgot-password', 'api/reset-password',
'api/docs', 'api/health', 'api/db-check', 'api/badge-scan', 'api/scanner',
];
foreach ($this->apiRoutes() as $route) {
$uri = $route->uri();
if (str_starts_with($uri, 'api/v1/')) {
$this->assertTrue(true);
continue;
}
$isAllowed = false;
foreach ($allowedUnversioned as $allowed) {
if (str_starts_with($uri, $allowed)) {
$isAllowed = true;
break;
}
}
$this->assertTrue(
$isAllowed,
$uri.' is an unversioned API route. If this is deliberate legacy support, add it to the explicit allow-list.'
);
}
}
public function test_route_names_are_unique_enough_for_client_generation(): void
{
$seen = [];
foreach (Route::getRoutes()->getRoutes() as $route) {
$name = $route->getName();
if ($name === null || ! str_starts_with($route->uri(), 'api/')) {
continue;
}
$key = $name.'|'.$this->primaryMethod($route);
$this->assertArrayNotHasKey($key, $seen, 'Duplicate API route name/method pair: '.$key.' for '.$route->uri().' and '.($seen[$key] ?? 'unknown'));
$seen[$key] = $route->uri();
}
}
public function test_legacy_and_current_auth_contracts_return_compatible_failure_shapes(): void
{
$pairs = [
['/api/login', '/api/v1/auth/login'],
['/user/login', '/api/v1/auth/login'],
];
foreach ($pairs as [$legacy, $current]) {
$legacyResponse = $this->postJson($legacy, ['email' => 'bad@example.test', 'password' => 'wrong']);
$currentResponse = $this->postJson($current, ['email' => 'bad@example.test', 'password' => 'wrong']);
$this->assertNoServerError($legacyResponse, $legacy.' legacy auth failure');
$this->assertNoServerError($currentResponse, $current.' current auth failure');
$this->assertStatusIn($legacyResponse, [400, 401, 403, 419, 422], $legacy.' legacy auth failure');
$this->assertStatusIn($currentResponse, [400, 401, 403, 419, 422], $current.' current auth failure');
}
}
}