From bc4f419927efdfd80ba8bef47dc6e65d75d2a8cf Mon Sep 17 00:00:00 2001 From: "Jokob @NetAlertX" <96159884+jokob-sk@users.noreply.github.com> Date: Mon, 2 Mar 2026 10:42:36 +0000 Subject: [PATCH] Enhance device MAC address handling in tests to ensure lowercase normalization and skip tests when web protection is disabled --- test/api_endpoints/test_device_endpoints.py | 4 ++-- test/db/test_devices_view.py | 23 ++++++++++++++------- test/ui/test_ui_login.py | 19 ++++++++++++++++- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/test/api_endpoints/test_device_endpoints.py b/test/api_endpoints/test_device_endpoints.py index 007fbf0f..4314fd2a 100644 --- a/test/api_endpoints/test_device_endpoints.py +++ b/test/api_endpoints/test_device_endpoints.py @@ -99,9 +99,9 @@ def test_copy_device(client, api_token, test_mac): ) assert resp.status_code == 200 - # Step 2: Generate a target MAC + # Step 2: Generate a target MAC (lowercase to match DB trigger normalisation) target_mac = "aa:bb:cc:" + ":".join( - f"{random.randint(0, 255):02X}" for _ in range(3) + f"{random.randint(0, 255):02x}" for _ in range(3) ) # Step 3: Copy device diff --git a/test/db/test_devices_view.py b/test/db/test_devices_view.py index 60792de7..8ff9e7f4 100644 --- a/test/db/test_devices_view.py +++ b/test/db/test_devices_view.py @@ -78,7 +78,8 @@ class TestAlertDownNullCoercion: "SELECT devMac FROM DevicesView WHERE devAlertDown != 0 AND devPresentLastScan = 0" ) macs = [r["devMac"] for r in cur.fetchall()] - assert "AA:BB:CC:DD:EE:03" in macs + # DevicesView returns LOWER(devMac), so compare against lowercase + assert "aa:bb:cc:dd:ee:03" in macs def test_online_device_not_in_down_event_query(self): """An online device (devPresentLastScan=1) should never fire a down event.""" @@ -116,7 +117,8 @@ class TestIsSleepingSuppression: ) conn.commit() - cur.execute("SELECT devIsSleeping FROM DevicesView WHERE devMac = 'BB:BB:BB:BB:BB:01'") + # DevicesView returns LOWER(devMac); query must use lowercase + cur.execute("SELECT devIsSleeping FROM DevicesView WHERE devMac = 'bb:bb:bb:bb:bb:01'") row = cur.fetchone() assert row["devIsSleeping"] == 1 @@ -138,7 +140,8 @@ class TestIsSleepingSuppression: AND devPresentLastScan = 0 """) macs = [r["devMac"] for r in cur.fetchall()] - assert "BB:BB:BB:BB:BB:02" not in macs + # DevicesView returns LOWER(devMac) + assert "bb:bb:bb:bb:bb:02" not in macs def test_expired_sleep_window_fires_down(self): """After the sleep window expires, the device must appear as Down.""" @@ -151,7 +154,8 @@ class TestIsSleepingSuppression: ) conn.commit() - cur.execute("SELECT devIsSleeping FROM DevicesView WHERE devMac = 'BB:BB:BB:BB:BB:03'") + # DevicesView returns LOWER(devMac); query must use lowercase + cur.execute("SELECT devIsSleeping FROM DevicesView WHERE devMac = 'bb:bb:bb:bb:bb:03'") assert cur.fetchone()["devIsSleeping"] == 0 cur.execute(""" @@ -161,7 +165,7 @@ class TestIsSleepingSuppression: AND devPresentLastScan = 0 """) macs = [r["devMac"] for r in cur.fetchall()] - assert "BB:BB:BB:BB:BB:03" in macs + assert "bb:bb:bb:bb:bb:03" in macs def test_can_sleep_zero_device_is_not_sleeping(self): """devCanSleep=0 device recently offline → devIsSleeping must be 0.""" @@ -174,7 +178,8 @@ class TestIsSleepingSuppression: ) conn.commit() - cur.execute("SELECT devIsSleeping FROM DevicesView WHERE devMac = 'BB:BB:BB:BB:BB:04'") + # DevicesView returns LOWER(devMac); query must use lowercase + cur.execute("SELECT devIsSleeping FROM DevicesView WHERE devMac = 'bb:bb:bb:bb:bb:04'") assert cur.fetchone()["devIsSleeping"] == 0 def test_devstatus_sleeping(self): @@ -188,7 +193,8 @@ class TestIsSleepingSuppression: ) conn.commit() - cur.execute("SELECT devStatus FROM DevicesView WHERE devMac = 'BB:BB:BB:BB:BB:05'") + # DevicesView returns LOWER(devMac); query must use lowercase + cur.execute("SELECT devStatus FROM DevicesView WHERE devMac = 'bb:bb:bb:bb:bb:05'") assert cur.fetchone()["devStatus"] == "Sleeping" def test_devstatus_down_after_window_expires(self): @@ -202,5 +208,6 @@ class TestIsSleepingSuppression: ) conn.commit() - cur.execute("SELECT devStatus FROM DevicesView WHERE devMac = 'BB:BB:BB:BB:BB:06'") + # DevicesView returns LOWER(devMac); query must use lowercase + cur.execute("SELECT devStatus FROM DevicesView WHERE devMac = 'bb:bb:bb:bb:bb:06'") assert cur.fetchone()["devStatus"] == "Down" diff --git a/test/ui/test_ui_login.py b/test/ui/test_ui_login.py index bc79611a..faccdb58 100644 --- a/test/ui/test_ui_login.py +++ b/test/ui/test_ui_login.py @@ -8,6 +8,7 @@ import sys import os import time +import pytest from selenium.webdriver.common.by import By # Add test directory to path @@ -73,6 +74,16 @@ def get_login_password(): return None +def require_login_page(driver): + """Skip the test if the login form is not present (web protection disabled).""" + fields = driver.find_elements(By.NAME, "loginpassword") + if not fields: + pytest.skip( + "Web protection is disabled (SETPWD_enable_password != true); " + "login page is not shown on this instance" + ) + + def perform_login(driver, password=None): """Helper function to perform login with optional password fallback @@ -83,6 +94,7 @@ def perform_login(driver, password=None): if password is None: password = "123456" # Default test password + require_login_page(driver) password_input = driver.find_element(By.NAME, "loginpassword") password_input.send_keys(password) @@ -100,7 +112,9 @@ def test_login_page_loads(driver): driver.get(f"{BASE_URL}/index.php") wait_for_page_load(driver) - # Check that login form is present + # Skip if web protection is disabled (page redirected away from login form) + require_login_page(driver) + password_field = driver.find_element(By.NAME, "loginpassword") assert password_field, "Password field should be present" @@ -230,6 +244,9 @@ def test_url_hash_hidden_input_present(driver): driver.get(f"{BASE_URL}/index.php") wait_for_page_load(driver) + # Skip if web protection is disabled (login form not shown) + require_login_page(driver) + # Verify the hidden input field exists url_hash_input = driver.find_element(By.ID, "url_hash") assert url_hash_input, "Hidden url_hash input field should be present"