Files
Shadowbroker/backend/tests/test_entity_trail.py
T
BigBodyCobain 4cb6492b22 Add entity trail and profile commands for OpenClaw agent dossiers.
Expose observed aircraft/vessel paths, route enrichment, VIP metadata, datalink, and nearby context so agents can reconstruct movement without full telemetry dumps.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 00:23:40 -06:00

133 lines
4.1 KiB
Python

"""Tests for entity trail resolution."""
import pytest
from unittest.mock import patch
@pytest.fixture()
def sample_store():
from services.fetchers._store import latest_data, _data_lock
with _data_lock:
backup = {"tracked_flights": list(latest_data.get("tracked_flights") or [])}
latest_data["tracked_flights"] = [
{
"callsign": "AF1",
"registration": "82-8000",
"icao24": "adfdf8",
"alert_operator": "POTUS",
"type": "B744",
"lat": 38.95,
"lng": -77.45,
},
{
"callsign": "OXE2116",
"registration": "N36NE",
"icao24": "a0f011",
"operator": "Patriots",
"type": "Boeing 767-323ER",
"lat": 39.24,
"lng": -96.96,
},
]
latest_data["ships"] = [
{
"mmsi": 366999999,
"name": "BRAVO EUGENIA",
"lat": 25.77,
"lng": -80.13,
"shipType": 37,
}
]
try:
yield
finally:
with _data_lock:
latest_data["tracked_flights"] = backup["tracked_flights"]
def test_get_entity_trail_aircraft_with_mock_trail(sample_store):
from services.entity_trail import get_entity_trail
from services.fetchers import flights
flights.flight_trails["a0f011"] = {
"points": [
[39.0, -97.0, 35000, 1000.0],
[39.2, -96.9, 36000, 1060.0],
[39.24, -96.96, 37000, 1120.0],
],
"last_seen": 1120.0,
}
result = get_entity_trail(registration="N36NE", include_datalink=False)
assert result["status"] == "trail_available"
assert result["entity_kind"] == "aircraft"
assert len(result["trail"]) == 3
assert result["movement"]["bearing_deg"] is not None
assert "Trail points are observed" in result["notes"][0]
def test_get_entity_trail_ship(sample_store):
from services.entity_trail import get_entity_trail
from services import ais_stream
ais_stream._vessel_trails[366999999] = {
"points": [
[25.7, -80.1, 12, 2000.0],
[25.8, -80.2, 12, 2120.0],
],
"last_seen": 2120.0,
}
result = get_entity_trail(mmsi="366999999", entity_type="ship", include_datalink=False)
assert result["status"] == "trail_available"
assert result["entity_kind"] == "ship"
assert len(result["trail"]) == 2
@patch("services.fetchers.route_database.lookup_route")
def test_get_entity_trail_enriches_route_from_database(mock_lookup, sample_store):
from services.entity_trail import get_entity_trail
mock_lookup.return_value = {
"orig_name": "JFK: Kennedy",
"dest_name": "LAX: Los Angeles",
"orig_loc": [-73.78, 40.64],
"dest_loc": [-118.41, 33.94],
}
result = get_entity_trail(callsign="AF1", include_datalink=False)
assert result["route"]["source"] == "route_database"
assert "Kennedy" in result["route"]["origin_name"]
def test_correlate_entity_includes_movement(sample_store, monkeypatch):
from services import telemetry
from services.fetchers import flights
flights.flight_trails["adfdf8"] = {
"points": [[38.9, -77.5, 10000, 500.0], [38.95, -77.45, 12000, 560.0]],
"last_seen": 560.0,
}
result = telemetry.correlate_entity(callsign="AF1", entity_type="aircraft", radius_km=80, limit=5)
assert result["movement"]["trail_point_count"] == 2
assert len(result["movement"]["trail"]) == 2
def test_openclaw_get_entity_trail_command(sample_store, monkeypatch):
from services.openclaw_channel import _dispatch_command
from services.fetchers import flights
flights.flight_trails["a0f011"] = {
"points": [[39.0, -97.0, 35000, 1000.0]],
"last_seen": 1000.0,
}
result = _dispatch_command(
"get_entity_trail",
{"query": "patriots jet", "compact": True},
)
assert result["ok"] is True
assert result["data"]["status"] in {"trail_available", "resolved_without_trail"}