diff --git a/backend/app/adapters/device_client.py b/backend/app/adapters/device_client.py index 15ac20c..4c2ae90 100644 --- a/backend/app/adapters/device_client.py +++ b/backend/app/adapters/device_client.py @@ -446,7 +446,7 @@ class MockDeviceClient(DeviceClient): return dict(self._system_config) def read_time_sync_config(self) -> Dict[str, str]: - return {"time_sync": str(self._system_config.get("time_sync", ""))} + return {"time_sync": datetime.now().strftime("%Y-%m-%d %H:%M:%S")} def read_net_config(self, nic: str) -> Dict[str, Any]: for item in self._net_config: diff --git a/backend/tests/test_api.py b/backend/tests/test_api.py index aeb5158..cd8a18b 100644 --- a/backend/tests/test_api.py +++ b/backend/tests/test_api.py @@ -1,4 +1,5 @@ -from datetime import datetime +import asyncio +from datetime import datetime, timedelta from fastapi.testclient import TestClient @@ -11,11 +12,17 @@ from app.repositories.alarm_repo import AlarmRepository from app.repositories.json_config_repo import JsonConfigRepository from app.schemas.platform import AlarmEvent, LineData, RealtimeData, ValueGroup from app.services.platform_service import platform_service +from app.ws.manager import ws_manager client = TestClient(app) +def _assert_time_sync_in_window(value: str, before: datetime, after: datetime) -> None: + parsed = datetime.strptime(value, "%Y-%m-%d %H:%M:%S") + assert before - timedelta(seconds=1) <= parsed <= after + timedelta(seconds=1) + + def test_healthcheck() -> None: response = client.get("/") assert response.status_code == 200 @@ -169,7 +176,9 @@ def test_config_query_endpoints(tmp_path) -> None: line_alarm_response = client.get("/api/config/line_alarm_setting", headers=headers, params={"line_no": 1}) ai_alarm_response = client.get("/api/config/ai_alarm_setting", headers=headers) system_response = client.get("/api/config/system", headers=headers) + before_time_sync = datetime.now() time_sync_response = client.get("/api/config/time-sync", headers=headers) + after_time_sync = datetime.now() assert device_response.status_code == 200 assert net_response.status_code == 200 @@ -190,7 +199,7 @@ def test_config_query_endpoints(tmp_path) -> None: assert line_alarm_response.json()["data"]["transformer_change"][0]["category"] == "PT变化" assert ai_alarm_response.json()["data"][0]["channel_no"] == 1 assert system_response.json()["data"]["time_sync"] == "2026-05-25 12:34:56" - assert time_sync_response.json()["data"]["time_sync"] == "2026-05-25 12:34:56" + _assert_time_sync_in_window(time_sync_response.json()["data"]["time_sync"], before_time_sync, after_time_sync) finally: platform_service.device_client = old_client platform_service.config_repo = old_repo @@ -257,7 +266,9 @@ def test_protocol_config_endpoints_read_and_write_device_only(tmp_path) -> None: headers=headers, json={"time_sync": "2026-05-25 14:00:00"}, ) + before_query_time_sync = datetime.now() query_time_sync = client.get("/api/config/time-sync", headers=headers) + after_query_time_sync = datetime.now() assert channel_response.status_code == 200 assert line_response.status_code == 200 @@ -271,7 +282,8 @@ def test_protocol_config_endpoints_read_and_write_device_only(tmp_path) -> None: assert query_system.json()["data"]["brightness"] == 88 assert query_net.json()["data"]["ip"] == "172.16.2.10" assert query_net.json()["data"]["gateway"] == "172.16.2.1" - assert query_time_sync.json()["data"]["time_sync"] == "2026-05-25 14:00:00" + assert time_sync_response.json()["data"]["time_sync"] == "2026-05-25 14:00:00" + _assert_time_sync_in_window(query_time_sync.json()["data"]["time_sync"], before_query_time_sync, after_query_time_sync) assert platform_service.config_repo.read_setting_config() == {} assert platform_service.config_repo.read_device_config() == {} finally: @@ -279,6 +291,31 @@ def test_protocol_config_endpoints_read_and_write_device_only(tmp_path) -> None: platform_service.config_repo = old_repo +def test_mock_time_sync_ws_payload_uses_system_time() -> None: + old_client = platform_service.device_client + platform_service.device_client = MockDeviceClient() + captured: dict = {} + + async def fake_broadcast(channel: str, payload: dict) -> None: + captured["channel"] = channel + captured["payload"] = payload + + original_broadcast = ws_manager.broadcast + ws_manager.broadcast = fake_broadcast + + try: + before = datetime.now() + asyncio.run(platform_service.poll_time_sync_once()) + after = datetime.now() + finally: + ws_manager.broadcast = original_broadcast + platform_service.device_client = old_client + + assert captured["channel"] == "time-sync" + assert captured["payload"]["type"] == "time_sync" + _assert_time_sync_in_window(captured["payload"]["data"]["time_sync"], before, after) + + def test_save_device_net_and_uart_by_key(tmp_path) -> None: old_repo = platform_service.config_repo old_client = platform_service.device_client