From 1405df6039d4b0c50717921b41bdfb4625291936 Mon Sep 17 00:00:00 2001 From: jkingsman Date: Thu, 26 Mar 2026 17:22:42 -0700 Subject: [PATCH] Beef up some noopy tests --- tests/test_fanout.py | 7 +++++ tests/test_fanout_integration.py | 18 ----------- tests/test_map_upload.py | 54 +++++++++++++++++++++++++------- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/tests/test_fanout.py b/tests/test_fanout.py index 1ca1031..9c5461c 100644 --- a/tests/test_fanout.py +++ b/tests/test_fanout.py @@ -791,6 +791,13 @@ class TestMapUploadValidation: assert config["geofence_enabled"] is False assert config["geofence_radius_km"] == 0.0 + def test_enforce_scope_map_upload_forces_raw_only(self): + """map_upload scope is always fixed regardless of what the caller passes.""" + from app.routers.fanout import _enforce_scope + + scope = _enforce_scope("map_upload", {"messages": "all", "raw_packets": "none"}) + assert scope == {"messages": "none", "raw_packets": "all"} + def test_enforce_scope_sqs_preserves_raw_packets_setting(self): from app.routers.fanout import _enforce_scope diff --git a/tests/test_fanout_integration.py b/tests/test_fanout_integration.py index 99bf0eb..e520cc8 100644 --- a/tests/test_fanout_integration.py +++ b/tests/test_fanout_integration.py @@ -1888,21 +1888,3 @@ class TestMapUploadIntegration: await manager.stop_all() - @pytest.mark.asyncio - async def test_map_upload_scope_enforced_on_create(self, integration_db): - """Scope for map_upload is always fixed to raw_packets: all, messages: none.""" - # Even if a custom scope is passed, the router enforces the correct one. - # Here we verify the DB record has the enforced scope. - cfg = await FanoutConfigRepository.create( - config_type="map_upload", - name="Map", - config={"dry_run": True, "api_url": ""}, - scope={ - "messages": "all", - "raw_packets": "none", - }, # wrong, should be overridden by router - enabled=True, - ) - # The repository stores whatever the router passes — we test the router via HTTP - # in test_api.py; here we just verify the module works with the correct scope. - assert cfg["type"] == "map_upload" diff --git a/tests/test_map_upload.py b/tests/test_map_upload.py index f739298..32b9361 100644 --- a/tests/test_map_upload.py +++ b/tests/test_map_upload.py @@ -898,35 +898,67 @@ class TestGeofence: @pytest.mark.asyncio async def test_node_at_exact_boundary_passes(self): - """Node at exactly the fence radius must be allowed (<=, not <).""" + """Node at exactly the fence radius must be allowed (> not >=). + + We compute the haversine distance to the node, then set the radius to + exactly that value. The geofence check is ``dist > radius``, so a node + sitting precisely on the boundary must pass through. + """ + fence_lat, fence_lon = 1.0, 0.0 + node_lat, node_lon = 1.9, 0.0 + exact_dist = _haversine_km(fence_lat, fence_lon, node_lat, node_lon) + mod = _make_module( { "dry_run": True, "geofence_enabled": True, - "geofence_radius_km": 100.0, + "geofence_radius_km": exact_dist, # radius == distance → must pass } ) await mod.start() - # Use a non-zero center so it's not treated as "not configured". - # Purely latitudinal haversine distance is origin-independent, so - # 0.8993° from (1.0, 0.0) gives the same ~100 km as from (0.0, 0.0). - fence_lat, fence_lon = 1.0, 0.0 - node_lat = fence_lat + 0.8993 - dist = _haversine_km(fence_lat, fence_lon, node_lat, fence_lon) - assert dist <= 100.0, f"Expected <=100 km, got {dist:.3f}" - with ( _mock_radio_runtime_with_location(fence_lat, fence_lon), patch("app.fanout.map_upload.get_private_key", return_value=_FAKE_PRIVATE), patch("app.fanout.map_upload.get_public_key", return_value=_FAKE_PUBLIC), patch("app.fanout.map_upload._get_radio_params", return_value=_FAKE_RADIO_PARAMS), ): - await mod._upload("ab" * 32, 1000, 2, "aabb", node_lat, fence_lon) + await mod._upload("ab" * 32, 1000, 2, "aabb", node_lat, node_lon) assert ("ab" * 32) in mod._seen await mod.stop() + @pytest.mark.asyncio + async def test_node_just_outside_boundary_skipped(self): + """Node one metre beyond the fence radius must be filtered. + + Companion to test_node_at_exact_boundary_passes: shrink the radius by a + tiny epsilon so the same node is now strictly outside the fence. + """ + fence_lat, fence_lon = 1.0, 0.0 + node_lat, node_lon = 1.9, 0.0 + exact_dist = _haversine_km(fence_lat, fence_lon, node_lat, node_lon) + + mod = _make_module( + { + "dry_run": True, + "geofence_enabled": True, + "geofence_radius_km": exact_dist - 0.001, # 1 metre short → must be filtered + } + ) + await mod.start() + + with ( + _mock_radio_runtime_with_location(fence_lat, fence_lon), + patch("app.fanout.map_upload.get_private_key", return_value=_FAKE_PRIVATE), + patch("app.fanout.map_upload.get_public_key", return_value=_FAKE_PUBLIC), + patch("app.fanout.map_upload._get_radio_params", return_value=_FAKE_RADIO_PARAMS), + ): + await mod._upload("ab" * 32, 1000, 2, "aabb", node_lat, node_lon) + assert ("ab" * 32) not in mod._seen + + await mod.stop() + @pytest.mark.asyncio async def test_geofence_skipped_when_lat_lon_zero(self): """geofence_enabled=True but radio (0, 0) → upload proceeds (geofence silently skipped)."""