From 9e1b15dabf80db952a1faa5b00525f0475b93fd8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 18 May 2026 00:03:52 +0800 Subject: [PATCH] fix(telegram): sync rejected polling callbacks --- apps/api/src/services/telegram_gateway.py | 21 ++++++++ .../test_telegram_gateway_polling_handoff.py | 54 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 apps/api/tests/test_telegram_gateway_polling_handoff.py diff --git a/apps/api/src/services/telegram_gateway.py b/apps/api/src/services/telegram_gateway.py index af18a3a5..7ba6fd0d 100644 --- a/apps/api/src/services/telegram_gateway.py +++ b/apps/api/src/services/telegram_gateway.py @@ -7171,6 +7171,27 @@ class TelegramGateway: username=username, execution_triggered=False, ) + try: + from src.services.incident_approval_service import ( + get_incident_approval_service, + ) + + await get_incident_approval_service().on_approval_status_change( + approval_id=str(approval_uuid), + new_status="rejected", + ) + logger.info( + "telegram_rejection_incident_synced_via_polling", + approval_id=str(approval_uuid), + incident_id=getattr(approval, "incident_id", None), + ) + except Exception as _sync_e: + logger.warning( + "telegram_rejection_incident_sync_failed_via_polling", + approval_id=str(approval_uuid), + incident_id=getattr(approval, "incident_id", None), + error=str(_sync_e), + ) elif action == "tune": logger.info( diff --git a/apps/api/tests/test_telegram_gateway_polling_handoff.py b/apps/api/tests/test_telegram_gateway_polling_handoff.py new file mode 100644 index 00000000..61b2cab3 --- /dev/null +++ b/apps/api/tests/test_telegram_gateway_polling_handoff.py @@ -0,0 +1,54 @@ +from types import SimpleNamespace +from unittest.mock import AsyncMock +from uuid import UUID + +import pytest + +from src.models.approval import ApprovalStatus +from src.services.telegram_gateway import TelegramGateway + + +@pytest.mark.asyncio +async def test_polling_reject_syncs_incident_state(monkeypatch): + approval_id = UUID("44444444-4444-4444-4444-444444444444") + approval = SimpleNamespace( + id=approval_id, + status=ApprovalStatus.REJECTED, + incident_id="INC-20260513-POLLREJ", + ) + sync_calls: list[dict] = [] + + class _FakeApprovalService: + async def reject_approval(self, **_kwargs): + return approval, "Approval rejected" + + class _FakeIncidentApprovalService: + async def on_approval_status_change(self, **kwargs): + sync_calls.append(kwargs) + + monkeypatch.setattr( + "src.services.approval_db.get_approval_service", + lambda: _FakeApprovalService(), + ) + monkeypatch.setattr( + "src.services.incident_approval_service.get_incident_approval_service", + lambda: _FakeIncidentApprovalService(), + ) + monkeypatch.setattr( + TelegramGateway, + "_notify_approval_result", + AsyncMock(return_value=None), + ) + + await TelegramGateway()._execute_approval_action( + action="reject", + approval_id=str(approval_id), + user_id=42, + username="ops", + message_id=99, + ) + + assert sync_calls == [{ + "approval_id": str(approval_id), + "new_status": "rejected", + }]