Add unit tests for legacy schema compatibility, property gate commands, lane state transitions, and relay synchronization. Extend relay logic with demo relay handling, dynamic image updates, phone normalization, and machine relay hard set methods.

This commit is contained in:
Jeppe Bundgaard
2026-03-26 11:11:34 +01:00
parent 76729f1b99
commit f148b39a85
22 changed files with 891 additions and 149 deletions
@@ -290,6 +290,12 @@ class moduleSelfServeRoute
case selfserve_lane_command::RESET:
self::requirePermission('modules_selfserve_lane_command_execute_reset');
break;
case selfserve_lane_command::OPEN_PROPERTY_ACCESS_GATE:
self::requirePermission('modules_selfserve_lane_command_execute_open_property_access_gate');
break;
case selfserve_lane_command::OPEN_PROPERTY_EXIT_GATE:
self::requirePermission('modules_selfserve_lane_command_execute_open_property_exit_gate');
break;
}
// Execute the command
try {
@@ -320,6 +326,8 @@ class moduleSelfServeRoute
'modules_selfserve_lane_command_execute_reserve' => 'Execute self-serve lane RESERVE command',
'modules_selfserve_lane_command_execute_release' => 'Execute self-serve lane RELEASE command (Release the lane reservation and reset its state)',
'modules_selfserve_lane_command_execute_reset' => 'Execute self-serve lane RESET command',
'modules_selfserve_lane_command_execute_open_property_access_gate' => 'Execute self-serve lane OPEN_PROPERTY_ACCESS_GATE command',
'modules_selfserve_lane_command_execute_open_property_exit_gate' => 'Execute self-serve lane OPEN_PROPERTY_EXIT_GATE command',
'modules_selfserve_lane_command_bypass_customer_number_validation' => 'Bypass customer number validation when executing commands',
]
);
@@ -368,8 +376,12 @@ class moduleSelfServeRoute
}
}
// Persist on lane cache (overwrites previous allowed services)
$lane->setLaneCache($lane_id, $lane::CACHE_SELFSERVE_LANE_KEY_ALLOWED_SERVICES, $allowed_services);
$response->success(['lane_id' => $lane_id, 'allowed_services' => $allowed_services]);
$relay_sync = $lane->syncMachineRelayFromVisibleServices($allowed_services, true);
$response->success([
'lane_id' => $lane_id,
'allowed_services' => $allowed_services,
'relay_sync' => $relay_sync,
]);
}, [
'modules_selfserve_lane_services_set_allowed' => 'Set allowed services for a lane based on currently shown tasks (post-Q&A)'
]);
@@ -582,9 +594,19 @@ class moduleSelfServeRoute
$lane->setMachineRelayStatus((bool)$on);
// Keep lane cache state aligned with the latest explicit relay action
try {
$machine_relay_id = '';
if (!empty($lane->department_lane) && !empty($lane->department_lane->relay_machine_id)) {
$machine_relay_id = trim((string)$lane->department_lane->relay_machine_id->value());
}
$is_demo_machine_relay = str_starts_with(strtolower($machine_relay_id), 'demo-');
$lane->setLaneState((bool)$on
? \modules\selfserve\helpers\selfserve_lane_state::MACHINE_RELAY_ON
: \modules\selfserve\helpers\selfserve_lane_state::MACHINE_RELAY_OFF);
? ($is_demo_machine_relay
? \modules\selfserve\helpers\selfserve_lane_state::MACHINE_RELAY_ON_QUEUED
: \modules\selfserve\helpers\selfserve_lane_state::MACHINE_RELAY_ON)
: ($is_demo_machine_relay
? \modules\selfserve\helpers\selfserve_lane_state::MACHINE_RELAY_OFF_QUEUED
: \modules\selfserve\helpers\selfserve_lane_state::MACHINE_RELAY_OFF)
);
} catch (\Throwable $ignored) {}
$status = $lane->getMachineRelayStatus();
@@ -672,7 +694,7 @@ class moduleSelfServeRoute
}
$lane = $selfserve->lane($lane_id);
try {
$lane->turnOnRelay(selfserve_lane_relay::MACHINE, $duration);
$lane->turnOnRelay(selfserve_lane_relay::MACHINE);
// A started wash should also turn on cleaner when configured.
try {
if (
@@ -834,7 +856,18 @@ class moduleSelfServeRoute
// Force enable the machine relay (bypass gating)
$lane->forceTurnOnMachineRelay($duration);
// Reflect relay state explicitly
try { $lane->setLaneState(\modules\selfserve\helpers\selfserve_lane_state::MACHINE_RELAY_ON); } catch (\Throwable $ignored) {}
try {
$machine_relay_id = '';
if (!empty($lane->department_lane) && !empty($lane->department_lane->relay_machine_id)) {
$machine_relay_id = trim((string)$lane->department_lane->relay_machine_id->value());
}
$is_demo_machine_relay = str_starts_with(strtolower($machine_relay_id), 'demo-');
$lane->setLaneState(
$is_demo_machine_relay
? \modules\selfserve\helpers\selfserve_lane_state::MACHINE_RELAY_ON_QUEUED
: \modules\selfserve\helpers\selfserve_lane_state::MACHINE_RELAY_ON
);
} catch (\Throwable $ignored) {}
$response->success([
'lane_id' => $lane_id,
'forced' => true,
@@ -890,7 +923,18 @@ class moduleSelfServeRoute
// Turn off the machine relay (do not swallow errors)
$lane->forceTurnOffMachineRelay();
// Reflect relay state explicitly
try { $lane->setLaneState(\modules\selfserve\helpers\selfserve_lane_state::MACHINE_RELAY_OFF); } catch (\Throwable $ignored) {}
try {
$machine_relay_id = '';
if (!empty($lane->department_lane) && !empty($lane->department_lane->relay_machine_id)) {
$machine_relay_id = trim((string)$lane->department_lane->relay_machine_id->value());
}
$is_demo_machine_relay = str_starts_with(strtolower($machine_relay_id), 'demo-');
$lane->setLaneState(
$is_demo_machine_relay
? \modules\selfserve\helpers\selfserve_lane_state::MACHINE_RELAY_OFF_QUEUED
: \modules\selfserve\helpers\selfserve_lane_state::MACHINE_RELAY_OFF
);
} catch (\Throwable $ignored) {}
$response->success([
'lane_id' => $lane_id,
'forced' => true,