563b0d4665
Implement wifi.py (start_ap/stop_ap/kill_wifi with subprocess and ProvisioningError), portal.py (Flask captive portal with Android/iOS/Windows probe redirects and 404 catch-all), updated provision.py provisioning loop, and full test suite (38 passing). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
55 lines
1.8 KiB
Python
55 lines
1.8 KiB
Python
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from planemapper.provisioning import ProvisioningError, wifi
|
|
|
|
|
|
def test_provisioning_error_is_exception() -> None:
|
|
assert issubclass(ProvisioningError, Exception)
|
|
|
|
|
|
def test_provisioning_error_can_be_raised_and_caught() -> None:
|
|
try:
|
|
raise ProvisioningError("test error")
|
|
except ProvisioningError as e:
|
|
assert str(e) == "test error"
|
|
|
|
|
|
def test_start_ap_raises_on_hostapd_failure() -> None:
|
|
mock_fail = MagicMock()
|
|
mock_fail.returncode = 1
|
|
with patch("planemapper.provisioning.wifi._write_hostapd_conf"):
|
|
with patch("planemapper.provisioning.wifi.subprocess.run", return_value=mock_fail):
|
|
with pytest.raises(ProvisioningError, match="hostapd failed"):
|
|
wifi.start_ap()
|
|
|
|
|
|
def test_start_ap_raises_on_dnsmasq_failure() -> None:
|
|
mock_ok = MagicMock()
|
|
mock_ok.returncode = 0
|
|
mock_fail = MagicMock()
|
|
mock_fail.returncode = 1
|
|
with patch("planemapper.provisioning.wifi._write_hostapd_conf"):
|
|
with patch(
|
|
"planemapper.provisioning.wifi.subprocess.run",
|
|
side_effect=[mock_ok, mock_fail], # hostapd OK, dnsmasq fails
|
|
):
|
|
with pytest.raises(ProvisioningError, match="dnsmasq failed"):
|
|
wifi.start_ap()
|
|
|
|
|
|
def test_kill_wifi_raises_on_rfkill_failure() -> None:
|
|
mock_fail = MagicMock()
|
|
mock_fail.returncode = 1
|
|
with patch("planemapper.provisioning.wifi.subprocess.run", return_value=mock_fail):
|
|
with pytest.raises(ProvisioningError, match="rfkill failed"):
|
|
wifi.kill_wifi()
|
|
|
|
|
|
def test_stop_ap_does_not_raise() -> None:
|
|
mock_ok = MagicMock()
|
|
mock_ok.returncode = 0
|
|
with patch("planemapper.provisioning.wifi.subprocess.run", return_value=mock_ok):
|
|
wifi.stop_ap() # should not raise
|