@ -10,8 +10,10 @@ from fastapi import HTTPException
from app . services . flows . order_flow import OrderFlowMixin
from app . services . flows . review_flow import ReviewFlowMixin
from app . integrations . telegram_satellite_service import _ensure_supported_runtime_configuration
from app . models . tool_model import ToolDefinition
from app . services . orchestration . conversation_policy import ConversationPolicy
from app . services . orchestration . entity_normalizer import EntityNormalizer
from app . services . tools . tool_registry import ToolRegistry
from app . services . tools . handlers import _parse_data_hora_revisao
@ -1207,6 +1209,39 @@ class ReviewFlowDraftTests(unittest.IsolatedAsyncioTestCase):
self . assertEqual ( draft [ " payload " ] . get ( " placa " ) , " ABC1269 " )
self . assertIn ( " a data e hora desejada para a revisao " , response )
async def test_review_flow_clears_stale_pending_confirmation_when_user_starts_new_schedule ( self ) :
state = FakeState (
entries = {
" pending_review_confirmations " : {
21 : {
" payload " : {
" placa " : " ABC9999 " ,
" data_hora " : " 14/03/2026 10:00 " ,
" modelo " : " Corolla " ,
" ano " : 2020 ,
" km " : 30000 ,
" revisao_previa_concessionaria " : True ,
} ,
" expires_at " : datetime . utcnow ( ) + timedelta ( minutes = 30 ) ,
}
}
}
)
registry = FakeRegistry ( )
flow = ReviewFlowHarness ( state = state , registry = registry )
response = await flow . _try_collect_and_schedule_review (
message = " quero agendar uma revisao " ,
user_id = 21 ,
extracted_fields = { } ,
intents = { } ,
turn_decision = { " intent " : " review_schedule " , " domain " : " review " , " action " : " collect_review_schedule " } ,
)
self . assertIsNone ( state . get_entry ( " pending_review_confirmations " , 21 ) )
self . assertIsNotNone ( state . get_entry ( " pending_review_drafts " , 21 ) )
self . assertIn ( " a placa do veiculo " , response )
async def test_review_flow_keeps_draft_and_clears_data_hora_on_retryable_error ( self ) :
state = FakeState (
entries = {
@ -1431,5 +1466,37 @@ class ContextSwitchPolicyTests(unittest.TestCase):
self . assertIsNone ( service . _get_user_context ( 9 ) . get ( " pending_switch " ) )
class ToolRegistryExecutionTests ( unittest . IsolatedAsyncioTestCase ) :
async def test_execute_ignores_extra_arguments_for_review_listing_tool ( self ) :
async def fake_listar_agendamentos_revisao (
user_id : int | None = None ,
placa : str | None = None ,
status : str | None = None ,
limite : int | None = 20 ,
) :
return [ { " user_id " : user_id , " placa " : placa , " status " : status , " limite " : limite } ]
registry = ToolRegistry . __new__ ( ToolRegistry )
registry . _tools = [
ToolDefinition (
name = " listar_agendamentos_revisao " ,
description = " " ,
parameters = { } ,
handler = fake_listar_agendamentos_revisao ,
)
]
result = await registry . execute (
" listar_agendamentos_revisao " ,
{ " placa " : " ABC1234 " , " status " : " agendado " , " limite " : 10 , " tipo " : " revisao " } ,
user_id = 21 ,
)
self . assertEqual (
result ,
[ { " user_id " : 21 , " placa " : " ABC1234 " , " status " : " agendado " , " limite " : 10 } ] ,
)
if __name__ == " __main__ " :
unittest . main ( )