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