This commit introduces unit tests, E2E tests, and implementation updates related to edge gateway lifecycle management, including update handling, artifact validation, and rollback mechanisms. It also refines routing, component interaction, and backend methods to improve update tracking, status transitions, and artifact management.
129 lines
4.6 KiB
PHP
129 lines
4.6 KiB
PHP
<?php
|
|
|
|
app_require('classes/edge_gateway_manager.php');
|
|
app_require('classes/gateway_shelly_transport.php');
|
|
|
|
use classes\edge_gateway_manager;
|
|
use classes\gateway_shelly_transport;
|
|
|
|
class GatewayShellyTransportManagerFake extends edge_gateway_manager
|
|
{
|
|
/** @var array<int,array<string,mixed>> */
|
|
public array $statusCalls = [];
|
|
/** @var array<int,array<string,mixed>> */
|
|
public array $switchCalls = [];
|
|
public ?Exception $statusException = null;
|
|
public ?Exception $switchException = null;
|
|
|
|
public function __construct()
|
|
{
|
|
}
|
|
|
|
public function dispatchRelayStatus(int $departmentId, string $logicalRelayId): array
|
|
{
|
|
if ($this->statusException instanceof Exception) {
|
|
throw $this->statusException;
|
|
}
|
|
|
|
$this->statusCalls[] = [
|
|
'department_id' => $departmentId,
|
|
'relay_id' => $logicalRelayId,
|
|
];
|
|
|
|
return [
|
|
'online' => true,
|
|
'on' => $logicalRelayId === 'relay-machine',
|
|
'raw' => ['source' => 'status'],
|
|
];
|
|
}
|
|
|
|
public function dispatchRelaySwitch(int $departmentId, string $logicalRelayId, bool $on): array
|
|
{
|
|
if ($this->switchException instanceof Exception) {
|
|
throw $this->switchException;
|
|
}
|
|
|
|
$this->switchCalls[] = [
|
|
'department_id' => $departmentId,
|
|
'relay_id' => $logicalRelayId,
|
|
'on' => $on,
|
|
];
|
|
|
|
return [
|
|
'online' => true,
|
|
'on' => $on,
|
|
'raw' => ['source' => 'switch'],
|
|
];
|
|
}
|
|
}
|
|
|
|
it('maps gateway relay status responses into the Shelly cloud payload shape', function (): void {
|
|
$manager = new GatewayShellyTransportManagerFake();
|
|
$transport = new gateway_shelly_transport($manager);
|
|
|
|
$result = $transport->sendPostRequest('/v2/devices/api/get', [
|
|
'ids' => ['relay-machine', 'relay-cleaner'],
|
|
], 17);
|
|
|
|
expect($manager->statusCalls)->toBe([
|
|
['department_id' => 17, 'relay_id' => 'relay-machine'],
|
|
['department_id' => 17, 'relay_id' => 'relay-cleaner'],
|
|
]);
|
|
expect($result)->toBeArray();
|
|
expect($result[0]['id'])->toBe('relay-machine');
|
|
expect($result[0]['status']['switch:0']['output'])->toBeTrue();
|
|
expect($result[1]['status']['switch:0']['output'])->toBeFalse();
|
|
});
|
|
|
|
it('maps gateway relay switch responses into the Shelly cloud payload shape', function (): void {
|
|
$manager = new GatewayShellyTransportManagerFake();
|
|
$transport = new gateway_shelly_transport($manager);
|
|
|
|
$result = $transport->sendPostRequest('/v2/devices/api/set/switch', [
|
|
'id' => 'relay-machine',
|
|
'on' => false,
|
|
], 17);
|
|
|
|
expect($manager->switchCalls)->toBe([
|
|
['department_id' => 17, 'relay_id' => 'relay-machine', 'on' => false],
|
|
]);
|
|
expect($result)->toBeArray();
|
|
expect($result[0]['id'])->toBe('relay-machine');
|
|
expect($result[0]['status']['switch:0']['output'])->toBeFalse();
|
|
});
|
|
|
|
it('requires a valid department id for gateway transport requests', function (): void {
|
|
$transport = new gateway_shelly_transport(new GatewayShellyTransportManagerFake());
|
|
|
|
expect(fn() => $transport->sendPostRequest('/v2/devices/api/get', ['ids' => ['relay-machine']], null))
|
|
->toThrow(Exception::class, 'A department_id is required for gateway Shelly transport');
|
|
});
|
|
|
|
it('rejects unsupported gateway transport endpoints', function (): void {
|
|
$transport = new gateway_shelly_transport(new GatewayShellyTransportManagerFake());
|
|
|
|
expect(fn() => $transport->sendPostRequest('/v2/devices/api/unknown', [], 17))
|
|
->toThrow(Exception::class, 'Unsupported gateway Shelly transport endpoint');
|
|
});
|
|
|
|
it('surfaces binding lookup failures while resolving relay state through the gateway transport', function (): void {
|
|
$manager = new GatewayShellyTransportManagerFake();
|
|
$manager->statusException = new Exception('Relay binding missing');
|
|
$transport = new gateway_shelly_transport($manager);
|
|
|
|
expect(fn() => $transport->sendPostRequest('/v2/devices/api/get', [
|
|
'ids' => ['relay-machine'],
|
|
], 17))->toThrow(Exception::class, 'Relay binding missing');
|
|
});
|
|
|
|
it('surfaces offline gateway failures while dispatching relay switch commands', function (): void {
|
|
$manager = new GatewayShellyTransportManagerFake();
|
|
$manager->switchException = new Exception('Gateway agent is offline');
|
|
$transport = new gateway_shelly_transport($manager);
|
|
|
|
expect(fn() => $transport->sendPostRequest('/v2/devices/api/set/switch', [
|
|
'id' => 'relay-machine',
|
|
'on' => true,
|
|
], 17))->toThrow(Exception::class, 'Gateway agent is offline');
|
|
});
|