fix(api): normalise version config values

This commit is contained in:
Virgil 2026-04-02 07:22:16 +00:00
parent b0549dc14e
commit 22d600e7a7
2 changed files with 107 additions and 4 deletions

View file

@ -54,6 +54,69 @@ use Illuminate\Http\Request;
*/
class ApiVersionService
{
/**
* Normalise a list of API versions to unique positive integers.
*
* @param array<int|string, mixed> $versions
* @return array<int>
*/
protected function normaliseVersions(array $versions): array
{
$normalised = [];
foreach ($versions as $version) {
if (! is_numeric($version)) {
continue;
}
$version = (int) $version;
if ($version <= 0) {
continue;
}
$normalised[] = $version;
}
return array_values(array_unique($normalised));
}
/**
* Normalise sunset dates to an integer-keyed map.
*
* @param array<int|string, mixed> $sunsets
* @return array<int, string>
*/
protected function normaliseSunsetDates(array $sunsets): array
{
$normalised = [];
foreach ($sunsets as $version => $date) {
if (! is_numeric($version)) {
continue;
}
$version = (int) $version;
if ($version <= 0) {
continue;
}
if ($date === null) {
continue;
}
$date = trim((string) $date);
if ($date === '') {
continue;
}
$normalised[$version] = $date;
}
ksort($normalised);
return $normalised;
}
/**
* Get the current API version from the request.
*
@ -116,7 +179,7 @@ class ApiVersionService
public function isDeprecated(?Request $request = null): bool
{
$current = $this->current($request);
$deprecated = config('api.versioning.deprecated', []);
$deprecated = $this->deprecatedVersions();
return $current !== null && in_array($current, $deprecated, true);
}
@ -144,7 +207,7 @@ class ApiVersionService
*/
public function supportedVersions(): array
{
return config('api.versioning.supported', [1]);
return $this->normaliseVersions((array) config('api.versioning.supported', [1]));
}
/**
@ -154,7 +217,7 @@ class ApiVersionService
*/
public function deprecatedVersions(): array
{
return config('api.versioning.deprecated', []);
return $this->normaliseVersions((array) config('api.versioning.deprecated', []));
}
/**
@ -164,7 +227,7 @@ class ApiVersionService
*/
public function sunsetDates(): array
{
return config('api.versioning.sunset', []);
return $this->normaliseSunsetDates((array) config('api.versioning.sunset', []));
}
/**

View file

@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
use Core\Front\Api\ApiVersionService;
use Illuminate\Support\Facades\Config;
beforeEach(function () {
Config::set('api.versioning.default', 1);
Config::set('api.versioning.current', 2);
Config::set('api.versioning.supported', [1, 2]);
Config::set('api.versioning.deprecated', []);
Config::set('api.versioning.sunset', []);
});
it('normalises configured versions before reading them', function () {
Config::set('api.versioning.supported', ['1', '02', '2', 'ignored', 0, -1]);
Config::set('api.versioning.deprecated', ['1', '3', '3']);
Config::set('api.versioning.sunset', [
'1' => '2025-06-01',
'02' => '2025-12-31',
'ignored' => '2026-01-01',
0 => '2024-01-01',
-1 => '2024-06-01',
3 => '',
]);
$versions = new ApiVersionService();
expect($versions->supportedVersions())->toBe([1, 2]);
expect($versions->deprecatedVersions())->toBe([1, 3]);
expect($versions->sunsetDates())->toBe([
1 => '2025-06-01',
2 => '2025-12-31',
]);
expect($versions->isSupported(1))->toBeTrue();
expect($versions->isSupported(2))->toBeTrue();
expect($versions->isSupported(3))->toBeFalse();
expect($versions->isDeprecated())->toBeFalse();
});