Files
api/services/nginx/app/tests/Unit/Selfserve/ShellyTransportResolverTest.php
T
Jeppe Bundgaard feb9aac4f7 Handle relay command job timeouts for edge gateways
- Introduce `expireTimedOutRelayStatusCommandJobs` to clean up long-pending relay status command jobs.
- Add `TIMED_OUT` status for relay command jobs and incorporate it into job status evaluations.
- Refactor command job finalization to support timeout-specific error messaging.
- Improve handling of fast-path failures in edge broker commands.
2026-04-27 16:47:09 +02:00

109 lines
3.8 KiB
PHP

<?php
app_require('classes/edge_gateway_manager.php');
app_require('classes/shelly_transport_resolver.php');
use classes\edge_gateway_manager;
use classes\gateway_shelly_transport;
use classes\shelly_transport_resolver;
use interfaces\shelly_transport_i;
class ShellyTransportResolverManagerFake extends edge_gateway_manager
{
/** @var array<int,string> */
public array $modesByDepartment = [];
/** @var array<int,int> */
public array $calls = [];
public function __construct()
{
}
public function getDepartmentTransportMode(int $departmentId): string
{
$this->calls[] = $departmentId;
return $this->modesByDepartment[$departmentId] ?? self::TRANSPORT_MODE_CLOUD;
}
}
class ShellyTransportResolverTransportFake implements shelly_transport_i
{
public function __construct(public readonly string $name)
{
}
public function requireModuleEnabled(): void
{
}
public function requireValidSecretKey(): void
{
}
public function sendPostRequest(string $endpoint, array $data, ?int $department_id = null): array|object|null
{
return [
'name' => $this->name,
'endpoint' => $endpoint,
'department_id' => $department_id,
];
}
}
it('resolves the injected gateway transport when a department is in gateway mode', function (): void {
$manager = new ShellyTransportResolverManagerFake();
$manager->modesByDepartment[17] = edge_gateway_manager::TRANSPORT_MODE_GATEWAY;
$cloudTransport = new ShellyTransportResolverTransportFake('cloud');
$gatewayTransport = new ShellyTransportResolverTransportFake('gateway');
$resolver = new shelly_transport_resolver($manager, $cloudTransport, $gatewayTransport);
expect($resolver->resolveForDepartment(17))->toBe($gatewayTransport);
expect($manager->calls)->toBe([17]);
});
it('resolves the injected cloud transport when a department is in cloud mode', function (): void {
$manager = new ShellyTransportResolverManagerFake();
$manager->modesByDepartment[22] = edge_gateway_manager::TRANSPORT_MODE_CLOUD;
$cloudTransport = new ShellyTransportResolverTransportFake('cloud');
$gatewayTransport = new ShellyTransportResolverTransportFake('gateway');
$resolver = new shelly_transport_resolver($manager, $cloudTransport, $gatewayTransport);
expect($resolver->resolveForDepartment(22))->toBe($cloudTransport);
expect($manager->calls)->toBe([22]);
});
it('lets relay tests override the department transport without changing department mode', function (): void {
$manager = new ShellyTransportResolverManagerFake();
$manager->modesByDepartment[17] = edge_gateway_manager::TRANSPORT_MODE_CLOUD;
$cloudTransport = new ShellyTransportResolverTransportFake('cloud');
$gatewayTransport = new ShellyTransportResolverTransportFake('gateway');
$resolver = new shelly_transport_resolver($manager, $cloudTransport, $gatewayTransport);
expect($resolver->resolveForDepartment(17, 'local'))->toBe($gatewayTransport);
expect($resolver->resolveForDepartment(17, 'gateway'))->toBe($gatewayTransport);
expect($resolver->resolveForDepartment(17, 'cloud'))->toBe($cloudTransport);
expect($manager->calls)->toBe([]);
});
it('marks non-injected local and gateway overrides as local-only gateway transport', function (): void {
$manager = new ShellyTransportResolverManagerFake();
$resolver = new shelly_transport_resolver($manager);
foreach (['local', 'gateway'] as $override) {
$transport = $resolver->resolveForDepartment(17, $override);
$localOnly = new ReflectionProperty($transport, 'localOnly');
$localOnly->setAccessible(true);
expect($transport)->toBeInstanceOf(gateway_shelly_transport::class);
expect($localOnly->getValue($transport))->toBeTrue();
}
expect($manager->calls)->toBe([]);
});