@ -5,7 +5,11 @@ from unittest.mock import AsyncMock, patch
from fastapi import HTTPException
from app . integrations . telegram_satellite_service import TelegramSatelliteService
from app . integrations . telegram_satellite_service import (
TELEGRAM_RUNTIME_BUCKET ,
TELEGRAM_RUNTIME_OWNER_ID ,
TelegramSatelliteService ,
)
from app . services . orchestration . conversation_state_store import ConversationStateStore
@ -14,6 +18,30 @@ class _DummySession:
return None
class _FakeTelegramResponse :
def __init__ ( self , payload ) :
self . payload = payload
async def __aenter__ ( self ) :
return self
async def __aexit__ ( self , exc_type , exc , tb ) :
return None
async def json ( self ) :
return self . payload
class _FakeTelegramSession :
def __init__ ( self , payload ) :
self . payload = payload
self . calls = [ ]
def post ( self , url , json ) :
self . calls . append ( ( url , json ) )
return _FakeTelegramResponse ( self . payload )
class TelegramMultimodalTests ( unittest . IsolatedAsyncioTestCase ) :
def _build_service ( self ) - > TelegramSatelliteService :
service = TelegramSatelliteService (
@ -115,6 +143,26 @@ class TelegramMultimodalTests(unittest.IsolatedAsyncioTestCase):
self . assertIn ( " marca d ' agua SysaltiIA visivel " , answer )
self . assertFalse ( orchestrator_cls . return_value . handle_message . await_count )
async def test_process_message_offloads_blocking_turn_to_worker_thread ( self ) :
service = self . _build_service ( )
with patch (
" app.integrations.telegram_satellite_service.asyncio.to_thread " ,
AsyncMock ( return_value = " ok " ) ,
) as to_thread :
answer = await service . _process_message (
text = " quero ver a frota " ,
sender = { " id " : 99 , " first_name " : " Vitor " } ,
chat_id = 99 ,
image_attachments = [ ] ,
)
self . assertEqual ( answer , " ok " )
self . assertEqual ( to_thread . await_count , 1 )
self . assertEqual ( to_thread . await_args . kwargs [ " message_text " ] , " quero ver a frota " )
self . assertEqual ( to_thread . await_args . kwargs [ " chat_id " ] , 99 )
self . assertEqual ( to_thread . await_args . kwargs [ " sender " ] [ " id " ] , 99 )
async def test_handle_update_masks_sensitive_domain_error_in_logs ( self ) :
service = self . _build_service ( )
update = {
@ -217,6 +265,71 @@ class TelegramMultimodalTests(unittest.IsolatedAsyncioTestCase):
self . assertEqual ( send_message . await_args_list [ 0 ] . kwargs [ " text " ] , " Resposta 1 " )
self . assertEqual ( send_message . await_args_list [ 1 ] . kwargs [ " text " ] , " Resposta 2 " )
async def test_initialize_offset_uses_persisted_cursor ( self ) :
service = self . _build_service ( )
service . state . set_entry (
TELEGRAM_RUNTIME_BUCKET ,
TELEGRAM_RUNTIME_OWNER_ID ,
{ " last_update_id " : 41 } ,
)
offset = await service . _initialize_offset ( session = SimpleNamespace ( ) )
self . assertEqual ( offset , 42 )
self . assertEqual ( service . _last_update_id , 41 )
async def test_initialize_offset_bootstraps_cursor_once_when_missing ( self ) :
service = self . _build_service ( )
session = _FakeTelegramSession (
{
" ok " : True ,
" result " : [
{ " update_id " : 5 } ,
{ " update_id " : 6 } ,
] ,
}
)
offset = await service . _initialize_offset ( session = session )
self . assertEqual ( offset , 7 )
self . assertEqual ( service . _last_update_id , 6 )
entry = service . state . get_entry ( TELEGRAM_RUNTIME_BUCKET , TELEGRAM_RUNTIME_OWNER_ID )
self . assertEqual ( entry [ " last_update_id " ] , 6 )
self . assertEqual ( len ( session . calls ) , 1 )
async def test_handle_update_persists_runtime_cursor ( self ) :
service = self . _build_service ( )
update = {
" update_id " : 14 ,
" message " : {
" message_id " : 88 ,
" chat " : { " id " : 99 } ,
" from " : { " id " : 99 } ,
" text " : " status do pedido " ,
} ,
}
with patch . object ( service , " _extract_image_attachments " , AsyncMock ( return_value = [ ] ) ) , patch . object (
service ,
" _process_message " ,
AsyncMock ( return_value = " Pedido encontrado. " ) ,
) , patch . object ( service , " _send_message " , AsyncMock ( ) ) :
await service . _handle_update ( session = SimpleNamespace ( ) , update = update )
entry = service . state . get_entry ( TELEGRAM_RUNTIME_BUCKET , TELEGRAM_RUNTIME_OWNER_ID )
self . assertEqual ( entry [ " last_update_id " ] , 14 )
async def test_persist_last_processed_update_id_keeps_highest_seen_value ( self ) :
service = self . _build_service ( )
service . _persist_last_processed_update_id ( 11 )
service . _persist_last_processed_update_id ( 10 )
entry = service . state . get_entry ( TELEGRAM_RUNTIME_BUCKET , TELEGRAM_RUNTIME_OWNER_ID )
self . assertEqual ( entry [ " last_update_id " ] , 11 )
self . assertEqual ( service . _last_update_id , 11 )
async def test_schedule_update_processing_allows_parallel_chats ( self ) :
service = self . _build_service ( )
release_first_chat = asyncio . Event ( )