from unittest.mock import patch import pytest from planemapper.provisioning import ProvisioningError from planemapper.provisioning.portal import app @pytest.fixture def client(): app.config["TESTING"] = True with app.test_client() as c: yield c def test_index_returns_200(client) -> None: resp = client.get("/") assert resp.status_code == 200 def test_index_contains_form_fields(client) -> None: resp = client.get("/") data = resp.data.decode() assert 'name="location"' in data assert 'name="radius"' in data assert 'name="wifi_ssid"' in data assert 'name="wifi_password"' in data assert "Find location" in data assert "Set up device" in data def test_generate_204_redirects_to_index(client) -> None: resp = client.get("/generate_204") assert resp.status_code in (301, 302) assert resp.headers["Location"].endswith("/") def test_hotspot_detect_redirects_to_index(client) -> None: resp = client.get("/hotspot-detect.html") assert resp.status_code in (301, 302) def test_ncsi_redirects_to_index(client) -> None: resp = client.get("/ncsi.txt") assert resp.status_code in (301, 302) def test_unknown_route_redirects_to_index(client) -> None: resp = client.get("/some/random/path") assert resp.status_code in (301, 302) def test_find_location_success(client) -> None: mock_resolve = patch( "planemapper.provisioning.portal.location.resolve", return_value=(51.5, -0.1, "London") ) with mock_resolve: resp = client.post("/find-location", data={"location": "EGLL", "radius": "100"}) assert resp.status_code == 200 data = resp.data.decode() assert "London" in data assert "51.5" in data def test_find_location_error(client) -> None: with patch( "planemapper.provisioning.portal.location.resolve", side_effect=ValueError("ICAO code not found — try an address instead"), ): resp = client.post("/find-location", data={"location": "ZZZZ", "radius": "100"}) assert resp.status_code == 200 assert "ICAO code not found" in resp.data.decode() def test_submit_success(client) -> None: with ( patch("planemapper.provisioning.portal.wifi.join_home_wifi"), patch("planemapper.provisioning.portal.tiles.download_and_composite"), patch("planemapper.provisioning.portal.airspace.download"), patch("planemapper.provisioning.portal.tiles.validate_cache"), patch("planemapper.provisioning.portal.config.write"), patch("planemapper.provisioning.portal.wifi.kill_wifi"), ): resp = client.post( "/submit", data={ "confirmed_lat": "51.5", "confirmed_lon": "-0.1", "confirmed_name": "London", "radius": "100", "wifi_ssid": "HomeNet", "wifi_password": "secret", }, ) assert resp.status_code == 200 assert b"Setup complete" in resp.data def test_submit_validation_failure(client) -> None: with ( patch("planemapper.provisioning.portal.wifi.join_home_wifi"), patch("planemapper.provisioning.portal.tiles.download_and_composite"), patch("planemapper.provisioning.portal.airspace.download"), patch( "planemapper.provisioning.portal.tiles.validate_cache", side_effect=ProvisioningError("bad png"), ), patch("planemapper.provisioning.portal.config.write"), patch("planemapper.provisioning.portal.wifi.kill_wifi"), ): resp = client.post( "/submit", data={ "confirmed_lat": "51.5", "confirmed_lon": "-0.1", "confirmed_name": "London", "radius": "100", "wifi_ssid": "HomeNet", "wifi_password": "secret", }, ) assert resp.status_code == 200 assert b"Try again" in resp.data