Files
api/services/nginx/app/tests/Unit/Workfeed/DepartmentWeatherStatusTargetsTest.php
T
Jeppe B 2a6a86c9c3 Resolve backend Qodana critical and high findings (#314)
Resolve recommended-profile Critical and High findings, retain narrow analyzer exceptions, and update the edge-broker WebSocket dependency to a non-vulnerable release.
2026-07-17 05:44:16 +02:00

167 lines
5.1 KiB
PHP

<?php
app_require('routes/moduleWeatherAPIRoute.php');
use routes\moduleWeatherAPIRoute;
function weather_status_targets_invoke_private(moduleWeatherAPIRoute $route, string $method, array $args = []): mixed
{
$reflection = new ReflectionClass($route);
$target = $reflection->getMethod($method);
return $target->invokeArgs($route, $args);
}
beforeEach(function (): void {
$_SERVER['REQUEST_URI'] = '/departments/weather';
});
it('evaluates healthy degraded and unhealthy statuses from configured department targets', function (): void {
$route = new moduleWeatherAPIRoute();
$targets = [
'degraded_threshold' => 1.0,
'healthy_threshold' => 1.3,
];
$healthy = weather_status_targets_invoke_private($route, 'calculateStatus', [13, 10.0, true, $targets]);
$degraded = weather_status_targets_invoke_private($route, 'calculateStatus', [10, 10.0, true, $targets]);
$unhealthy = weather_status_targets_invoke_private($route, 'calculateStatus', [9, 10.0, true, $targets]);
expect($healthy)->toBe('healthy');
expect($degraded)->toBe('degraded');
expect($unhealthy)->toBe('unhealthy');
});
it('returns unknown when configured targets are missing for department status evaluation', function (): void {
$route = new moduleWeatherAPIRoute();
$status = weather_status_targets_invoke_private($route, 'calculateStatus', [10, 10.0, true, null]);
expect($status)->toBe('unknown');
});
it('aggregates multi-department slot statuses using worst severity when any department is unhealthy', function (): void {
$route = new moduleWeatherAPIRoute();
$slotKey = '2026-03-24 10:00';
$targets = [
1 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
2 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
];
$worst = weather_status_targets_invoke_private($route, 'calculateAggregatedDepartmentStatus', [
[1, 2],
[
1 => [$slotKey => 14],
2 => [$slotKey => 8],
],
[
1 => [$slotKey => 10.0],
2 => [$slotKey => 10.0],
],
$slotKey,
true,
$targets,
]);
expect($worst)->toBe('unhealthy');
});
it('aggregates all-unhealthy multi-department slot statuses as unhealthy', function (): void {
$route = new moduleWeatherAPIRoute();
$slotKey = '2026-03-24 10:00';
$targets = [
1 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
2 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
];
$worst = weather_status_targets_invoke_private($route, 'calculateAggregatedDepartmentStatus', [
[1, 2],
[
1 => [$slotKey => 3],
2 => [$slotKey => 4],
],
[
1 => [$slotKey => 10.0],
2 => [$slotKey => 10.0],
],
$slotKey,
true,
$targets,
]);
expect($worst)->toBe('unhealthy');
});
it('returns unknown when aggregated multi-department slot targets are missing', function (): void {
$route = new moduleWeatherAPIRoute();
$slotKey = '2026-03-24 10:00';
$missingTargets = weather_status_targets_invoke_private($route, 'calculateAggregatedDepartmentStatus', [
[1, 2],
[
1 => [$slotKey => 14],
2 => [$slotKey => 8],
],
[
1 => [$slotKey => 10.0],
2 => [$slotKey => 10.0],
],
$slotKey,
true,
[
1 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
],
]);
expect($missingTargets)->toBe('unknown');
});
it('returns unknown when aggregated multi-department slot has no evaluable hours', function (): void {
$route = new moduleWeatherAPIRoute();
$slotKey = '2026-03-24 10:00';
$targets = [
1 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
2 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
];
$noEvaluableHours = weather_status_targets_invoke_private($route, 'calculateAggregatedDepartmentStatus', [
[1, 2],
[
1 => [$slotKey => 0],
2 => [$slotKey => 0],
],
[
1 => [$slotKey => 0.0],
2 => [$slotKey => 0.0],
],
$slotKey,
true,
$targets,
]);
expect($noEvaluableHours)->toBe('unknown');
});
it('returns unknown when aggregated multi-department slot has not started yet', function (): void {
$route = new moduleWeatherAPIRoute();
$slotKey = '2026-03-24 10:00';
$targets = [
1 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
2 => ['degraded_threshold' => 1.0, 'healthy_threshold' => 1.3],
];
$futureSlot = weather_status_targets_invoke_private($route, 'calculateAggregatedDepartmentStatus', [
[1, 2],
[
1 => [$slotKey => 14],
2 => [$slotKey => 8],
],
[
1 => [$slotKey => 10.0],
2 => [$slotKey => 10.0],
],
$slotKey,
false,
$targets,
]);
expect($futureSlot)->toBe('unknown');
});