Services (daynivo-kiosk-*, daynivo-network-guard, daynivo-boot-import), programs in /usr/lib/daynivo-kiosk, folders /etc, /var/lib, /var/log and /var/cache daynivo-kiosk*, the system user daynivo, DAYNIVO_* settings, the plymouth theme, network profiles daynivo-eth0/wlan0, the image stage and its first user daynivoadmin. install.sh moves a kiosk installed up to 1.2.x over once: old services stopped and removed, folders moved (configuration, password, browser profile, logs) with symlinks under the old names, the voxip user renamed with the same uid, network profiles renamed unless a change awaits confirmation, and old leftovers removed. Tested by upgrading a configured 1.2.0 installation in a container, and running the install a second time. Old names keep working where people type or place them: voxip-config.json, voxip-authorized_keys, voxip-network-reset, voxip-kiosk-ctl, and VOXIP_DEFAULT_URL / VOXIP_DEVICE_NAME for image builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
80 lines
3.5 KiB
Python
80 lines
3.5 KiB
Python
import pytest
|
|
|
|
from daynivo_kiosk import netconfig as n
|
|
from daynivo_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") == "daynivo-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"
|