Files
daynivo-kiosk-os/tests/test_netconfig.py
T
rothmanandClaude Opus 5.5 a33c4822bf
CI / test-bookworm (push) Failing after 11s
CI / test-latest (push) Successful in 1m27s
VoxIP Kiosk OS 1.0.0: Raspberry Pi kiosk with web management
Chromium kiosk without a desktop for the Raspberry Pi 3, a Flask web
interface on port 8080 (kiosk, system and network management), a
restricted root helper, network changes with automatic rollback, a
healthcheck timer, install/update/uninstall scripts and a pi-gen image
build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 21:38:49 +01:00

80 lines
3.5 KiB
Python

import pytest
from voxip_kiosk import netconfig as n
from voxip_kiosk.validation import ValidationError
def test_validate_static_ethernet():
req = n.validate_request({"interface": "eth0", "method": "static", "address": "192.168.1.50/24",
"gateway": "192.168.1.1", "dns": "1.1.1.1, 9.9.9.9"})
assert req == {"interface": "eth0", "method": "static", "address": "192.168.1.50/24", "gateway": "192.168.1.1", "dns": ["1.1.1.1", "9.9.9.9"]}
@pytest.mark.parametrize("payload, fragment", [
({"interface": "eth1", "method": "dhcp"}, "interface"),
({"interface": "eth0", "method": "manual"}, "DHCP"),
({"interface": "eth0", "method": "static", "address": "192.168.1.50/24", "gateway": "10.0.0.1", "dns": "1.1.1.1"}, "subnet"),
({"interface": "eth0", "method": "static", "address": "192.168.1.50/24", "gateway": "192.168.1.1", "dns": ""}, "DNS"),
({"interface": "wlan0", "method": "dhcp"}, "Wifi"),
("not a dict", "Ongeldig"),
])
def test_validate_rejects(payload, fragment):
with pytest.raises(ValidationError, match=fragment):
n.validate_request(payload)
def test_keyfile_static_ethernet():
req = n.validate_request({"interface": "eth0", "method": "static", "address": "10.1.2.3/16", "gateway": "10.1.0.1", "dns": ["10.1.0.1"]})
text = n.build_keyfile(req, uuid="11111111-2222-3333-4444-555555555555")
kf = n.read_keyfile(text)
assert kf.get("connection", "id") == "voxip-eth0"
assert kf.get("connection", "type") == "ethernet"
assert kf.get("connection", "autoconnect-priority") == "100"
assert kf.get("ipv4", "method") == "manual"
assert kf.get("ipv4", "address1") == "10.1.2.3/16,10.1.0.1"
assert kf.get("ipv4", "dns") == "10.1.0.1;"
assert kf.get("ipv4", "ignore-auto-dns") == "true"
def test_keyfile_wifi_escapes_values():
req = n.validate_request({"interface": "wlan0", "method": "dhcp", "dns": "",
"wifi": {"ssid": " Café\\Net", "psk": "p\\ss word!", "hidden": True}})
text = n.build_keyfile(req, psk=req["wifi"]["psk"])
kf = n.read_keyfile(text)
assert n.unescape(kf.get("wifi", "ssid")) == " Café\\Net"
assert kf.get("wifi", "ssid").startswith("\\s")
assert n.unescape(kf.get("wifi-security", "psk")) == "p\\ss word!"
assert kf.get("wifi", "hidden") == "true"
assert kf.get("ipv4", "method") == "auto"
assert not kf.has_option("ipv4", "dns")
def test_keyfile_open_wifi_has_no_security_section():
req = n.validate_request({"interface": "wlan0", "method": "dhcp", "wifi": {"ssid": "Gasten", "open": True}})
assert "[wifi-security]" not in n.build_keyfile(req)
def test_keyfile_requires_psk_for_protected_wifi():
req = n.validate_request({"interface": "wlan0", "method": "dhcp", "wifi": {"ssid": "Kantoor"}})
with pytest.raises(ValidationError):
n.build_keyfile(req, psk="")
def test_split_terse_handles_escapes():
assert n.split_terse(r"*:My\:Net:80:WPA2") == ["*", "My:Net", "80", "WPA2"]
assert n.split_terse(r" :back\\slash:40:") == [" ", "back\\slash", "40", ""]
def test_parse_wifi_scan_dedupes_and_sorts():
out = "\n".join([
" :Buren:40:WPA2",
" :Kantoor:55:WPA2",
"*:Kantoor:70:WPA2",
" ::90:WPA2", # hidden network without SSID
" :Gasten:80:",
])
nets = n.parse_wifi_scan(out)
assert [x["ssid"] for x in nets] == ["Kantoor", "Gasten", "Buren"]
assert nets[0]["in_use"] is True and nets[0]["signal"] == 70
assert nets[1]["security"] == "open"