164 lines
5.7 KiB
PHP
164 lines
5.7 KiB
PHP
<?php
|
|
|
|
app_require('modules/selfserve/traits/selfserve_lane_command_t.php');
|
|
app_require('modules/selfserve/classes/selfserve_lane_command_arguments.php');
|
|
app_require('modules/selfserve/helpers/selfserve_lane_port.php');
|
|
app_require('modules/selfserve/helpers/selfserve_lane_state.php');
|
|
|
|
use modules\selfserve\classes\selfserve_lane_command_arguments;
|
|
use modules\selfserve\helpers\selfserve_lane_port;
|
|
use modules\selfserve\helpers\selfserve_lane_state;
|
|
use modules\selfserve\traits\selfserve_lane_command_t;
|
|
|
|
class SelfserveLaneStartEntranceTimeoutHarness
|
|
{
|
|
use selfserve_lane_command_t;
|
|
|
|
public int $id = 771;
|
|
/** @var array<int,selfserve_lane_port> */
|
|
public array $openCalls = [];
|
|
public ?\Throwable $openThrowable = null;
|
|
public ?\Throwable $reportedTimeout = null;
|
|
public ?selfserve_lane_state $laneState = null;
|
|
public int $cleanerRelayCalls = 0;
|
|
public int $programPickerRelayCalls = 0;
|
|
public int $machineRelayCalls = 0;
|
|
/** @var array<int,string> */
|
|
public array $relayEvents = [];
|
|
|
|
public function open(selfserve_lane_port $port, ?int $toggle_after_seconds = null): bool
|
|
{
|
|
unset($toggle_after_seconds);
|
|
$this->openCalls[] = $port;
|
|
if ($this->openThrowable !== null) {
|
|
throw $this->openThrowable;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function setLaneState(selfserve_lane_state $state): void
|
|
{
|
|
$this->laneState = $state;
|
|
}
|
|
|
|
protected function reportWashStartEntranceTimeout(\Throwable $e): void
|
|
{
|
|
$this->reportedTimeout = $e;
|
|
}
|
|
|
|
protected function turnOnCleanerRelayForWashStart(): void
|
|
{
|
|
$this->cleanerRelayCalls++;
|
|
$this->relayEvents[] = 'cleaner:on';
|
|
}
|
|
|
|
protected function setProgramPickerRelayStatusFromSelectedServiceForWashStart(?selfserve_lane_command_arguments $arguments = null): void
|
|
{
|
|
unset($arguments);
|
|
$this->programPickerRelayCalls++;
|
|
$this->relayEvents[] = 'program_picker:selected_service';
|
|
}
|
|
|
|
protected function setProgramPickerRelayStatusForWashStart(?selfserve_lane_command_arguments $arguments = null): void
|
|
{
|
|
unset($arguments);
|
|
$this->programPickerRelayCalls++;
|
|
$this->relayEvents[] = 'program_picker:eligibility_sync';
|
|
}
|
|
|
|
protected function setMachineRelayStatusForWashStart(?selfserve_lane_command_arguments $arguments = null): void
|
|
{
|
|
unset($arguments);
|
|
$this->machineRelayCalls++;
|
|
$this->relayEvents[] = 'machine:sync';
|
|
}
|
|
|
|
public function runEntranceOpenForStart(): void
|
|
{
|
|
$this->openEntrancePortForWashStart();
|
|
}
|
|
|
|
public function runStartRelaySideEffects(bool $defer): void
|
|
{
|
|
$arguments = (new selfserve_lane_command_arguments())->setDeferRelaySideEffects($defer);
|
|
$this->runRelaySideEffectsForWashStart($arguments);
|
|
}
|
|
}
|
|
|
|
it('continues start when entrance relay dispatch times out ambiguously', function (): void {
|
|
$lane = new SelfserveLaneStartEntranceTimeoutHarness();
|
|
$timeout = new \RuntimeException('Edge gateway command timed out');
|
|
$lane->openThrowable = $timeout;
|
|
|
|
$lane->runEntranceOpenForStart();
|
|
|
|
expect($lane->openCalls)->toBe([selfserve_lane_port::ENTRANCE]);
|
|
expect($lane->reportedTimeout)->toBe($timeout);
|
|
});
|
|
|
|
it('still fails start for non-timeout entrance relay errors', function (): void {
|
|
$lane = new SelfserveLaneStartEntranceTimeoutHarness();
|
|
$lane->openThrowable = new \RuntimeException('Invalid relay ID for port ENTRANCE');
|
|
|
|
expect(fn() => $lane->runEntranceOpenForStart())
|
|
->toThrow(\RuntimeException::class, 'Invalid relay ID');
|
|
expect($lane->reportedTimeout)->toBeNull();
|
|
});
|
|
|
|
it('parses deferred relay side effects on start command arguments', function (): void {
|
|
$arguments = (new selfserve_lane_command_arguments())->setParameters([
|
|
'license_plate' => 'ab12345',
|
|
'customer_number' => 12345679,
|
|
'wash_type' => 'Manual',
|
|
'defer_relay_side_effects' => true,
|
|
]);
|
|
|
|
expect($arguments->license_plate)->toBe('AB12345');
|
|
expect($arguments->customer_number)->toBe(12345679);
|
|
expect($arguments->wash_mode)->toBe('manual');
|
|
expect($arguments->defer_relay_side_effects)->toBeTrue();
|
|
});
|
|
|
|
it('parses wash mode aliases on start command arguments', function (): void {
|
|
$arguments = (new selfserve_lane_command_arguments())->setParameters([
|
|
'wash_mode' => 'machine',
|
|
]);
|
|
|
|
expect($arguments->wash_mode)->toBe('machine');
|
|
});
|
|
|
|
it('rejects invalid wash types on start command arguments', function (): void {
|
|
expect(fn() => (new selfserve_lane_command_arguments())->setParameters([
|
|
'wash_type' => 'automatic',
|
|
]))->toThrow(\InvalidArgumentException::class, 'Invalid wash type: automatic');
|
|
});
|
|
|
|
it('only syncs program picker from selected service when start asks to defer machine side effects', function (): void {
|
|
$lane = new SelfserveLaneStartEntranceTimeoutHarness();
|
|
|
|
$lane->runStartRelaySideEffects(true);
|
|
|
|
expect($lane->cleanerRelayCalls)->toBe(0);
|
|
expect($lane->programPickerRelayCalls)->toBe(1);
|
|
expect($lane->machineRelayCalls)->toBe(0);
|
|
expect($lane->relayEvents)->toBe([
|
|
'program_picker:selected_service',
|
|
]);
|
|
});
|
|
|
|
it('keeps cleaner, program picker and machine relay side effects in order for normal start commands', function (): void {
|
|
$lane = new SelfserveLaneStartEntranceTimeoutHarness();
|
|
|
|
$lane->runStartRelaySideEffects(false);
|
|
|
|
expect($lane->cleanerRelayCalls)->toBe(1);
|
|
expect($lane->programPickerRelayCalls)->toBe(1);
|
|
expect($lane->machineRelayCalls)->toBe(1);
|
|
expect($lane->relayEvents)->toBe([
|
|
'cleaner:on',
|
|
'program_picker:eligibility_sync',
|
|
'machine:sync',
|
|
]);
|
|
});
|