from __future__ import annotations import logging import pathlib from unittest.mock import MagicMock, patch import pytest from PIL import Image from planemapper.display import NullDisplay from planemapper.fetcher import FileFixtureFetcher from planemapper.main import _run_one_cycle from planemapper.renderer.projection import MapBounds from planemapper.renderer.renderer import Renderer FIXTURE_DIR = pathlib.Path(__file__).parent / "fixtures" @pytest.fixture def renderer(monkeypatch: pytest.MonkeyPatch) -> Renderer: monkeypatch.setattr( "planemapper.renderer.airspace.AIRSPACE_PATH", FIXTURE_DIR / "airspace_sample.geojson", ) base_map = Image.new("RGB", (800, 480), color=(255, 255, 255)) bounds = MapBounds(home_lat=53.0, home_lon=-6.0, radius_nm=100.0) return Renderer(base_map, bounds) def test_run_one_cycle_calls_display_show(renderer: Renderer) -> None: fetcher = FileFixtureFetcher(FIXTURE_DIR / "aircraft_sample.json") display = NullDisplay() display_mock = MagicMock(wraps=display) _run_one_cycle(renderer, fetcher, display_mock) display_mock.show.assert_called_once() def test_run_one_cycle_logs_warning_when_slow( renderer: Renderer, caplog: pytest.LogCaptureFixture ) -> None: fetcher = FileFixtureFetcher(FIXTURE_DIR / "aircraft_sample.json") display = NullDisplay() # Simulate 43s total: t0=0, t1=1, t2=2, t3=43 with patch("planemapper.main.time.monotonic", side_effect=[0.0, 1.0, 2.0, 43.0]): with caplog.at_level(logging.WARNING, logger="planemapper.main"): _run_one_cycle(renderer, fetcher, display) assert any("render slow" in r.message for r in caplog.records) def test_provision_main_exits_if_already_provisioned() -> None: with patch("planemapper.provisioning.config.read", return_value={"provisioned": True}): with patch("planemapper.provisioning.wifi.start_ap") as mock_ap: from planemapper.provision import main as provision_main provision_main() mock_ap.assert_not_called()