From 9db1964038b86740e371c602a048daa6f24cd1e5 Mon Sep 17 00:00:00 2001 From: Jeppe Bundgaard Date: Wed, 1 Jul 2026 10:51:14 +0200 Subject: [PATCH] Fix edge agent CI setup --- scripts/edge-gateway-e2e.mjs | 13 +++++++ .../EdgeGatewayExpectedRelayStatesApiTest.php | 1 + .../app/tests/Support/Api/ApiFixtures.php | 35 +++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/scripts/edge-gateway-e2e.mjs b/scripts/edge-gateway-e2e.mjs index 94595991..3dea4055 100644 --- a/scripts/edge-gateway-e2e.mjs +++ b/scripts/edge-gateway-e2e.mjs @@ -94,6 +94,11 @@ function directCaddyBaseUrl(baseUrl) { return normalizeBaseUrl(url.toString()); } +function isLocalHost(hostname) { + const normalized = String(hostname || "").toLowerCase().replace(/^\[|\]$/g, ""); + return normalized === "localhost" || normalized === "127.0.0.1" || normalized === "::1"; +} + function resolveBrokerWebSocketUrl(rawUrl, apiBaseUrl) { const websocketUrl = new URL(String(rawUrl)); const apiUrl = new URL(normalizeBaseUrl(apiBaseUrl)); @@ -104,6 +109,14 @@ function resolveBrokerWebSocketUrl(rawUrl, apiBaseUrl) { websocketUrl.pathname = websocketUrl.pathname.replace(/^\/edge-broker(?=\/|$)/, "") || "/"; } + if (isLocalHost(apiUrl.hostname) && ["caddy", "edge-broker"].includes(websocketUrl.hostname)) { + const brokerPath = websocketUrl.pathname.replace(/^\/edge-broker(?=\/|$)/, "") || "/"; + websocketUrl.protocol = apiUrl.protocol === "https:" ? "wss:" : "ws:"; + websocketUrl.hostname = apiUrl.hostname; + websocketUrl.port = apiUrl.port; + websocketUrl.pathname = `/api/edge-broker${brokerPath}`; + } + return websocketUrl.toString(); } diff --git a/services/nginx/app/tests/Api/EdgeGatewayExpectedRelayStatesApiTest.php b/services/nginx/app/tests/Api/EdgeGatewayExpectedRelayStatesApiTest.php index aa660897..8cba7bdd 100644 --- a/services/nginx/app/tests/Api/EdgeGatewayExpectedRelayStatesApiTest.php +++ b/services/nginx/app/tests/Api/EdgeGatewayExpectedRelayStatesApiTest.php @@ -19,6 +19,7 @@ it('serves whole-department expected relay states and records successful physica ]); $departmentId = (int)$scenario['department']['id']; $laneId = (int)$scenario['lane']['id']; + api_fixtures()->setDepartmentShellyTransportMode($departmentId, 'gateway'); $session = api_fixtures()->createEdgeOperatorSession($departmentId, [ 'modules_selfserve_lane_relay_machine_status_set', 'modules_selfserve_lane_relay_machine_cleaner_status_set', diff --git a/services/nginx/app/tests/Support/Api/ApiFixtures.php b/services/nginx/app/tests/Support/Api/ApiFixtures.php index f2b69ba5..c245c0dd 100644 --- a/services/nginx/app/tests/Support/Api/ApiFixtures.php +++ b/services/nginx/app/tests/Support/Api/ApiFixtures.php @@ -175,6 +175,41 @@ final class ApiFixtures $this->cleanup->add(fn() => $this->deleteById('department_variables', $variableId)); } + public function setDepartmentShellyTransportMode(int $departmentId, string $mode): void + { + if ($departmentId <= 0) { + throw new RuntimeException('Department Shelly transport fixtures require a positive department id.'); + } + + $mode = strtolower(trim($mode)); + if (!in_array($mode, ['cloud', 'gateway'], true)) { + throw new RuntimeException('Invalid Shelly transport fixture mode.'); + } + + $this->cleanupDeleteWhere('department_variables', [ + 'department_id' => $departmentId, + 'variable' => 'shelly_transport_mode', + ]); + + $existingIds = $this->fetchIntColumnWhere('department_variables', 'id', [ + 'department_id' => $departmentId, + 'variable' => 'shelly_transport_mode', + ]); + if ($existingIds !== []) { + $this->updateById('department_variables', (int)$existingIds[0], [ + 'value' => $mode, + ]); + return; + } + + $variableId = $this->insertRowWithExistingColumns('department_variables', [ + 'department_id' => $departmentId, + 'variable' => 'shelly_transport_mode', + 'value' => $mode, + ]); + $this->cleanup->add(fn() => $this->deleteById('department_variables', $variableId)); + } + public function setLaneSelfServeEnabled(int $laneId, bool $enabled): void { if ($laneId <= 0) {