"""Tests for SatelliteDataManager (F04) and mercator utils (H06).""" import asyncio import numpy as np import pytest from gps_denied.core.satellite import SatelliteDataManager from gps_denied.schemas import GPSPoint from gps_denied.utils import mercator def test_latlon_to_tile(): # Kyiv coordinates lat = 50.4501 lon = 30.5234 zoom = 15 coords = mercator.latlon_to_tile(lat, lon, zoom) assert coords.zoom == 15 assert coords.x > 0 assert coords.y > 0 def test_tile_to_latlon(): x, y, zoom = 19131, 10927, 15 gps = mercator.tile_to_latlon(x, y, zoom) assert 50.0 < gps.lat < 52.0 assert 30.0 < gps.lon < 31.0 def test_tile_bounds(): coords = mercator.TileCoords(x=19131, y=10927, zoom=15) bounds = mercator.compute_tile_bounds(coords) # Northwest should be "higher" lat and "lower" lon than Southeast assert bounds.nw.lat > bounds.se.lat assert bounds.nw.lon < bounds.se.lon assert bounds.gsd > 0 @pytest.fixture def satellite_manager(tmp_path): # Use tmp_path for cache so we don't pollute workspace sm = SatelliteDataManager(cache_dir=str(tmp_path / "cache"), max_size_gb=0.1) yield sm sm.cache.close() asyncio.run(sm.http_client.aclose()) @pytest.mark.asyncio async def test_satellite_fetch_and_cache(satellite_manager): lat = 48.0 lon = 37.0 zoom = 12 flight_id = "test_flight" # We won't test the actual HTTP Google API in CI to avoid blocks/bans, # but we can test the cache mechanism directly. coords = satellite_manager.compute_tile_coords(lat, lon, zoom) # Create a fake image (blue square 256x256) fake_img = np.zeros((256, 256, 3), dtype=np.uint8) fake_img[:] = [255, 0, 0] # BGR # Save to cache success = satellite_manager.cache_tile(flight_id, coords, fake_img) assert success is True # Read from cache cached = satellite_manager.get_cached_tile(flight_id, coords) assert cached is not None assert cached.shape == (256, 256, 3) # Clear cache satellite_manager.clear_flight_cache(flight_id) assert satellite_manager.get_cached_tile(flight_id, coords) is None def test_grid_calculations(satellite_manager): # Test 3x3 grid (9 tiles) center = mercator.TileCoords(x=100, y=100, zoom=15) grid = satellite_manager.get_tile_grid(center, 9) assert len(grid) == 9 # Ensure center is in grid assert any(c.x == 100 and c.y == 100 for c in grid) # Test expansion 9 -> 25 new_tiles = satellite_manager.expand_search_grid(center, 9, 25) assert len(new_tiles) == 16 # 25 - 9