75 lines
2.9 KiB
PHP
75 lines
2.9 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/documentation', 'api/health', 'api/db-check', 'api/badge-scan', 'api/scanner',
|
|
'api/emails', 'api/compare',
|
|
'api/attendance-templates', 'api/attendance-comment-templates', 'api/administrator/attendance-templates',
|
|
];
|
|
|
|
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');
|
|
}
|
|
}
|
|
}
|