from ais_hub.core import merge from ais_hub.core.models import AisReport, MergedTarget def test_eager_merge_updates_dynamic_fields(): t = MergedTarget(mmsi=123) rep = AisReport( ts=100.0, source="src", kind="dynamic", mmsi=123, msg_type=1, channel="A", data={"lat": 10.5, "lon": 20.5, "sog": 7.1, "cog": 180.0}, ) changed = merge.apply(t, rep) assert changed is True assert t.lat == 10.5 assert t.sog == 7.1 assert t.last_dynamic_ts == 100.0 assert t.last_seen == 100.0 def test_stale_dynamic_report_is_ignored(): t = MergedTarget(mmsi=123) t.last_dynamic_ts = 200.0 t.lat = 1.0 older = AisReport( ts=100.0, source="src", kind="dynamic", mmsi=123, msg_type=1, data={"lat": 50.0}, ) merge.apply(t, older) assert t.lat == 1.0 # unchanged def test_static_and_dynamic_keep_separate_timestamps(): t = MergedTarget(mmsi=42) dyn = AisReport( ts=100.0, source="a", kind="dynamic", mmsi=42, msg_type=1, data={"lat": 1.0, "lon": 2.0}, ) stat = AisReport( ts=110.0, source="a", kind="static", mmsi=42, msg_type=5, data={"name": "MV TEST", "callsign": "ABCD", "imo": 9999999}, ) merge.apply(t, dyn) merge.apply(t, stat) assert t.lat == 1.0 and t.name == "MV TEST" assert t.last_dynamic_ts == 100.0 assert t.last_static_ts == 110.0 assert t.last_seen == 110.0 def test_msg24_name_and_callsign_combine(): t = MergedTarget(mmsi=7) # Msg 24A -> name merge.apply(t, AisReport( ts=10.0, source="a", kind="static", mmsi=7, msg_type=24, data={"name": "BOAT"}, )) # Msg 24B -> callsign + dims (later, must not wipe name) merge.apply(t, AisReport( ts=11.0, source="a", kind="static", mmsi=7, msg_type=24, data={"callsign": "CALL", "dim_a": 10, "dim_b": 20}, )) assert t.name == "BOAT" assert t.callsign == "CALL" assert t.dim_a == 10