- Extend relay switch logic to include `toggle_after` parameter for timed toggles. - Update unit tests in `SelfserveLanePortControllerTest` and `SelfserveRouteWiringTest` to validate timer behavior. - Adjust Shelly API calls and assertions to handle timer values in both RPC and legacy endpoints.
185 lines
5.3 KiB
PHP
185 lines
5.3 KiB
PHP
<?php
|
|
|
|
app_require('modules/selfserve/traits/selfserve_lane_port_controller_t.php');
|
|
app_require('modules/selfserve/helpers/selfserve_lane_port.php');
|
|
app_require('modules/selfserve/helpers/selfserve_lane_state.php');
|
|
app_require('modules/selfserve/helpers/selfserve_lane_status.php');
|
|
app_require('modules/shelly/helpers/shelly_device_switch.php');
|
|
|
|
use modules\selfserve\helpers\selfserve_lane_port;
|
|
use modules\selfserve\helpers\selfserve_lane_state;
|
|
use modules\selfserve\helpers\selfserve_lane_status;
|
|
use modules\selfserve\traits\selfserve_lane_port_controller_t;
|
|
use modules\shelly\helpers\shelly_device_switch;
|
|
|
|
class SelfserveLanePortValueFake
|
|
{
|
|
public function __construct(private readonly string $value) {}
|
|
|
|
public function value(): string
|
|
{
|
|
return $this->value;
|
|
}
|
|
}
|
|
|
|
class SelfserveLanePortDepartmentLaneFake
|
|
{
|
|
public SelfserveLanePortValueFake $relay_in_id;
|
|
public SelfserveLanePortValueFake $relay_out_id;
|
|
|
|
public function __construct(string $relayInId, string $relayOutId)
|
|
{
|
|
$this->relay_in_id = new SelfserveLanePortValueFake($relayInId);
|
|
$this->relay_out_id = new SelfserveLanePortValueFake($relayOutId);
|
|
}
|
|
}
|
|
|
|
class SelfserveLanePortSwitchFake extends shelly_device_switch
|
|
{
|
|
/** @var array<int,array{id:string,on:bool,toggle_after:int}> */
|
|
public array $switchCalls = [];
|
|
|
|
public function switch(bool $on, ?bool $skip_toggle_after = false): array|object|null
|
|
{
|
|
$this->switchCalls[] = [
|
|
'id' => $this->id,
|
|
'on' => $on,
|
|
'toggle_after' => $this->toggle_after,
|
|
];
|
|
return ['ok' => true];
|
|
}
|
|
}
|
|
|
|
class SelfservePortSwitchOutputFake extends shelly_device_switch
|
|
{
|
|
/** @var array<int,array> */
|
|
public array $switchCalls = [];
|
|
|
|
protected function sendShellySwitchRequest(array $parameters): array|object|null
|
|
{
|
|
$this->switchCalls[] = $parameters;
|
|
return ['ok' => true];
|
|
}
|
|
}
|
|
|
|
class SelfserveLanePortControllerHarness
|
|
{
|
|
use selfserve_lane_port_controller_t;
|
|
|
|
public int $id = 55;
|
|
public object $department_lane;
|
|
public SelfserveLanePortSwitchFake $switchFake;
|
|
public selfserve_lane_status $laneStatus;
|
|
public selfserve_lane_state $laneState;
|
|
|
|
public function __construct(string $relayInId, string $relayOutId)
|
|
{
|
|
$this->department_lane = new SelfserveLanePortDepartmentLaneFake($relayInId, $relayOutId);
|
|
$this->switchFake = new SelfserveLanePortSwitchFake();
|
|
$this->laneStatus = selfserve_lane_status::AVAILABLE;
|
|
$this->laneState = selfserve_lane_state::IDLE;
|
|
}
|
|
|
|
protected function createShellySwitchDevice(): shelly_device_switch
|
|
{
|
|
return $this->switchFake;
|
|
}
|
|
|
|
public function getLaneStatus(): selfserve_lane_status
|
|
{
|
|
return $this->laneStatus;
|
|
}
|
|
|
|
public function setLaneState(selfserve_lane_state $state): void
|
|
{
|
|
$this->laneState = $state;
|
|
}
|
|
|
|
public function logLaneAction(...$args): void {}
|
|
}
|
|
|
|
it('opens exit port by switching relay_out_id on', function (): void {
|
|
$lane = new SelfserveLanePortControllerHarness(
|
|
relayInId: 'relay-in-123',
|
|
relayOutId: 'relay-out-123'
|
|
);
|
|
|
|
$result = $lane->shellyOpenPort(selfserve_lane_port::EXIT);
|
|
|
|
expect($result)->toBeTrue();
|
|
expect($lane->switchFake->switchCalls)->toBe([
|
|
[
|
|
'id' => 'relay-out-123',
|
|
'on' => true,
|
|
'toggle_after' => 1,
|
|
],
|
|
]);
|
|
});
|
|
|
|
it('opens entrance port by switching relay_in_id on', function (): void {
|
|
$lane = new SelfserveLanePortControllerHarness(
|
|
relayInId: 'relay-in-123',
|
|
relayOutId: 'relay-out-123'
|
|
);
|
|
|
|
$result = $lane->shellyOpenPort(selfserve_lane_port::ENTRANCE);
|
|
|
|
expect($result)->toBeTrue();
|
|
expect($lane->switchFake->switchCalls)->toBe([
|
|
[
|
|
'id' => 'relay-in-123',
|
|
'on' => true,
|
|
'toggle_after' => 1,
|
|
],
|
|
]);
|
|
});
|
|
|
|
it('passes explicit timer values when opening lane gates', function (): void {
|
|
$lane = new SelfserveLanePortControllerHarness(
|
|
relayInId: 'relay-in-123',
|
|
relayOutId: 'relay-out-123'
|
|
);
|
|
|
|
$result = $lane->open(selfserve_lane_port::ENTRANCE, 4);
|
|
|
|
expect($result)->toBeTrue();
|
|
expect($lane->switchFake->switchCalls)->toBe([
|
|
[
|
|
'id' => 'relay-in-123',
|
|
'on' => true,
|
|
'toggle_after' => 4,
|
|
],
|
|
]);
|
|
});
|
|
|
|
it('keeps demo relay gate-open queued but skips Shelly switch calls', function (): void {
|
|
$lane = new SelfserveLanePortControllerHarness(
|
|
relayInId: 'demo-relay-in',
|
|
relayOutId: 'demo-relay-out'
|
|
);
|
|
|
|
$result = $lane->open(selfserve_lane_port::EXIT);
|
|
|
|
expect($result)->toBeTrue();
|
|
expect($lane->laneState)->toBe(selfserve_lane_state::EXIT_PORT_OPEN_QUEUED);
|
|
expect($lane->switchFake->switchCalls)->toBe([]);
|
|
});
|
|
|
|
it('does not print Shelly switch responses to output', function (): void {
|
|
$switch = new SelfservePortSwitchOutputFake();
|
|
$switch->id = 'relay-port-123';
|
|
|
|
ob_start();
|
|
$switch->switch(true);
|
|
$output = (string)ob_get_clean();
|
|
|
|
expect($output)->toBe('');
|
|
expect($switch->switchCalls)->toHaveCount(1);
|
|
expect($switch->switchCalls[0])->toMatchArray([
|
|
'id' => 'relay-port-123',
|
|
'channel' => 0,
|
|
'on' => true,
|
|
'toggle_after' => 1,
|
|
]);
|
|
});
|