import pytest from handlers.mqtt_handler import TalkingQMQTTService @pytest.mark.asyncio async def test_device_info_report_persists_metadata_and_periodic_location(monkeypatch): service = TalkingQMQTTService({"broker": "127.0.0.1"}) calls = [] published = [] async def fake_publish(topic, payload): published.append((topic, payload)) return True async def fake_schedule_persistence(device_id, label, coro): calls.append(("schedule", device_id, label)) await coro async def fake_insert_or_update(**kwargs): calls.append(("settings", kwargs)) async def fake_report_mqtt_device_location(**kwargs): calls.append(("location", kwargs)) return {"device_id": kwargs["device_id"], "lat": kwargs["latitude"], "lng": kwargs["longitude"]} monkeypatch.setattr(service, "_publish", fake_publish) monkeypatch.setattr(service, "_schedule_persistence", fake_schedule_persistence) monkeypatch.setattr("handlers.mqtt_handler.device_setting_service.insert_or_update", fake_insert_or_update) monkeypatch.setattr("handlers.mqtt_handler.location_service.report_mqtt_device_location", fake_report_mqtt_device_location) monkeypatch.setattr( "handlers.mqtt_handler.wechat_mp_notification_service.schedule_low_battery_notification", lambda **kwargs: None, ) await service._handle_device_info( "TalkingQ_XQSN00001005", { "msg_id": "000", "data": { "id": "TalkingQ_XQSN00001005", "power": 80, "signal": 4, "voice": 60, "imei": "861921071409242", "version": "1.0.1", "latitude": 23.1173393, "longitude": 113.2855975, "device_type": "2", }, }, ) assert published == [ ("device/TalkingQ_XQSN00001005/event_resp", {"msg_id": "000", "status": "success"}), ] assert calls == [ ("schedule", "TalkingQ_XQSN00001005", "device_info"), ( "settings", { "device_id": "TalkingQ_XQSN00001005", "power": 80, "signal_strength": 4, "version_str": "1.0.1", "volume": 60, "imei": "861921071409242", "device_type": "2", }, ), ("schedule", "TalkingQ_XQSN00001005", "device_info_location"), ( "location", { "device_id": "TalkingQ_XQSN00001005", "latitude": 23.1173393, "longitude": 113.2855975, "coord_type": None, "accuracy_m": None, "altitude_m": None, "speed_mps": None, "heading_deg": None, "source": 0, "battery_pct": 80, }, ), ] @pytest.mark.asyncio async def test_device_info_report_without_location_does_not_write_location(monkeypatch): service = TalkingQMQTTService({"broker": "127.0.0.1"}) calls = [] async def fake_publish(topic, payload): del topic, payload return True async def fake_schedule_persistence(device_id, label, coro): calls.append(label) await coro async def fake_insert_or_update(**kwargs): calls.append(("settings", kwargs["device_type"])) monkeypatch.setattr(service, "_publish", fake_publish) monkeypatch.setattr(service, "_schedule_persistence", fake_schedule_persistence) monkeypatch.setattr("handlers.mqtt_handler.device_setting_service.insert_or_update", fake_insert_or_update) monkeypatch.setattr( "handlers.mqtt_handler.wechat_mp_notification_service.schedule_low_battery_notification", lambda **kwargs: None, ) await service._handle_device_info( "TalkingQ_XQSN00001005", {"msg_id": "000", "data": {"power": 20, "signal": 2, "voice": 40, "version": "1.0.0", "device_type": 1}}, ) assert calls == ["device_info", ("settings", 1)]