mirror of
https://github.com/Quad4-Software/MeshChatX.git
synced 2026-08-18 09:49:09 -04:00
182 lines
6.2 KiB
Python
182 lines
6.2 KiB
Python
# SPDX-License-Identifier: 0BSD
|
|
|
|
from meshchatx.src.backend.interface_editor import InterfaceEditor
|
|
|
|
|
|
def test_update_value_add():
|
|
details = {"type": "TCPClientInterface"}
|
|
InterfaceEditor.update_value(details, {"host": "1.2.3.4"}, "host")
|
|
assert details["host"] == "1.2.3.4"
|
|
|
|
|
|
def test_update_value_update():
|
|
details = {"host": "1.2.3.4"}
|
|
InterfaceEditor.update_value(details, {"host": "8.8.8.8"}, "host")
|
|
assert details["host"] == "8.8.8.8"
|
|
|
|
|
|
def test_update_value_remove_on_none():
|
|
details = {"host": "1.2.3.4"}
|
|
InterfaceEditor.update_value(details, {"host": None}, "host")
|
|
assert "host" not in details
|
|
|
|
|
|
def test_update_value_remove_on_empty_string():
|
|
details = {"host": "1.2.3.4"}
|
|
InterfaceEditor.update_value(details, {"host": ""}, "host")
|
|
assert "host" not in details
|
|
|
|
|
|
def test_coerce_rnode_frequency_hz_integer_hz():
|
|
assert InterfaceEditor.coerce_rnode_frequency_hz(868825000) == 868825000
|
|
assert InterfaceEditor.coerce_rnode_frequency_hz("868825000") == 868825000
|
|
|
|
|
|
def test_coerce_rnode_frequency_hz_mhz_decimal():
|
|
assert InterfaceEditor.coerce_rnode_frequency_hz(868.825) == 868825000
|
|
assert InterfaceEditor.coerce_rnode_frequency_hz("868.825000000") == 868825000
|
|
assert InterfaceEditor.coerce_rnode_frequency_hz("868.825000000 MHz") == 868825000
|
|
|
|
|
|
def test_coerce_rnode_frequency_hz_integer_mhz():
|
|
assert InterfaceEditor.coerce_rnode_frequency_hz(868) == 868000000
|
|
|
|
|
|
def test_coerce_rnode_frequency_hz_leaves_midrange_hz():
|
|
assert InterfaceEditor.coerce_rnode_frequency_hz(125000) == 125000
|
|
|
|
|
|
def test_normalize_rnode_txpower_integer():
|
|
assert InterfaceEditor.normalize_rnode_txpower(7) == 7
|
|
assert InterfaceEditor.normalize_rnode_txpower("14") == 14
|
|
assert InterfaceEditor.normalize_rnode_txpower("7.0") == 7
|
|
|
|
|
|
def test_validate_rnode_txpower_accepts_reticulum_range():
|
|
assert InterfaceEditor.validate_rnode_txpower(0) is None
|
|
assert InterfaceEditor.validate_rnode_txpower(22) is None
|
|
assert InterfaceEditor.validate_rnode_txpower(37) is None
|
|
|
|
|
|
def test_validate_rnode_txpower_rejects_out_of_range():
|
|
assert InterfaceEditor.validate_rnode_txpower(-9) is not None
|
|
assert InterfaceEditor.validate_rnode_txpower(38) is not None
|
|
assert InterfaceEditor.validate_rnode_txpower("bad") is not None
|
|
assert InterfaceEditor.validate_rnode_txpower(None) is not None
|
|
|
|
|
|
def test_normalize_rnode_tcp_port_host_only():
|
|
assert (
|
|
InterfaceEditor.normalize_rnode_tcp_port("tcp://10.0.0.5") == "tcp://10.0.0.5"
|
|
)
|
|
|
|
|
|
def test_normalize_rnode_tcp_port_strips_legacy_ipv4_port():
|
|
assert (
|
|
InterfaceEditor.normalize_rnode_tcp_port("tcp://10.0.0.5:7633")
|
|
== "tcp://10.0.0.5"
|
|
)
|
|
|
|
|
|
def test_normalize_rnode_tcp_port_strips_trailing_colons():
|
|
assert (
|
|
InterfaceEditor.normalize_rnode_tcp_port("tcp://10.0.0.5:") == "tcp://10.0.0.5"
|
|
)
|
|
|
|
|
|
def test_normalize_rnode_tcp_port_bracket_ipv6_with_port():
|
|
assert (
|
|
InterfaceEditor.normalize_rnode_tcp_port("tcp://[2001:db8::1]:7633")
|
|
== "tcp://[2001:db8::1]"
|
|
)
|
|
|
|
|
|
def test_normalize_rnode_tcp_port_non_tcp_unchanged():
|
|
assert InterfaceEditor.normalize_rnode_tcp_port("/dev/ttyUSB0") == "/dev/ttyUSB0"
|
|
|
|
|
|
def test_normalize_interface_mode_aliases():
|
|
assert InterfaceEditor.normalize_interface_mode("internal") == "internal"
|
|
assert InterfaceEditor.normalize_interface_mode("GW") == "gateway"
|
|
assert InterfaceEditor.normalize_interface_mode("ap") == "access_point"
|
|
assert InterfaceEditor.normalize_interface_mode("evil") is None
|
|
assert InterfaceEditor.normalize_interface_mode("") is None
|
|
|
|
|
|
def test_apply_interface_mode_rejects_unknown():
|
|
details = {}
|
|
err = InterfaceEditor.apply_interface_mode(details, {"mode": "not-a-mode"})
|
|
assert err is not None
|
|
assert "mode" not in details
|
|
|
|
|
|
def test_apply_interface_mode_canonicalizes():
|
|
details = {}
|
|
assert InterfaceEditor.apply_interface_mode(details, {"mode": "internal"}) is None
|
|
assert details["mode"] == "internal"
|
|
assert InterfaceEditor.apply_interface_mode(details, {"mode": "gw"}) is None
|
|
assert details["mode"] == "gateway"
|
|
|
|
|
|
def test_apply_yes_no_option_recursive_prs():
|
|
details = {}
|
|
assert (
|
|
InterfaceEditor.apply_yes_no_option(
|
|
details, {"recursive_prs": True}, "recursive_prs"
|
|
)
|
|
is None
|
|
)
|
|
assert details["recursive_prs"] == "yes"
|
|
assert (
|
|
InterfaceEditor.apply_yes_no_option(
|
|
details,
|
|
{"announces_from_internal": False},
|
|
"announces_from_internal",
|
|
)
|
|
is None
|
|
)
|
|
assert details["announces_from_internal"] == "no"
|
|
|
|
|
|
def test_sanitize_imported_gravity_and_announces_to_internal():
|
|
body = {
|
|
"gravity": "3",
|
|
"announces_to_internal": True,
|
|
}
|
|
assert InterfaceEditor.sanitize_imported_rns_options(body) is None
|
|
assert body["gravity"] == 3
|
|
assert body["announces_to_internal"] == "yes"
|
|
|
|
|
|
def test_validate_location_cmd_rejects_shell_metacharacters():
|
|
assert InterfaceEditor.validate_location_cmd("/usr/bin/true") is None
|
|
assert InterfaceEditor.validate_location_cmd("~/bin/gps.sh") is None
|
|
assert InterfaceEditor.validate_location_cmd("relative/path") is not None
|
|
assert InterfaceEditor.validate_location_cmd("/tmp/evil;rm -rf /") is not None
|
|
assert InterfaceEditor.validate_location_cmd("/tmp/$(id)") is not None
|
|
assert InterfaceEditor.validate_location_cmd("/tmp/../etc/passwd") is not None
|
|
|
|
|
|
def test_apply_location_cmd_normalizes_home():
|
|
details = {}
|
|
err = InterfaceEditor.apply_location_cmd(details, {"location_cmd": "~/gps-loc"})
|
|
assert err is None
|
|
assert details["location_cmd"].endswith("gps-loc")
|
|
assert details["location_cmd"].startswith("/")
|
|
|
|
|
|
def test_sanitize_imported_rns_options_rejects_bad_mode():
|
|
body = {"mode": "warehouse"}
|
|
assert InterfaceEditor.sanitize_imported_rns_options(body) is not None
|
|
|
|
|
|
def test_sanitize_imported_rns_options_accepts_internal():
|
|
body = {
|
|
"mode": "internal",
|
|
"recursive_prs": "yes",
|
|
"announces_from_internal": "no",
|
|
}
|
|
assert InterfaceEditor.sanitize_imported_rns_options(body) is None
|
|
assert body["mode"] == "internal"
|
|
assert body["recursive_prs"] == "yes"
|
|
assert body["announces_from_internal"] == "no"
|