4aeeefb488
Add tiles.py, airspace.py, wifi.join_home_wifi, portal /submit route, and rewire provision.py main loop; all tasks and quality gates pass (56 tests, ruff clean). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
124 lines
3.9 KiB
Python
124 lines
3.9 KiB
Python
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
|