import pytest from fastapi.testclient import TestClient from unittest.mock import AsyncMock, MagicMock, patch @pytest.fixture def app_with_mock_master(): mock_master = MagicMock() mock_response = MagicMock() mock_response.directive_id = 'test-directive-1' mock_response.reply = 'You have 3 overdue invoices totalling $15,000.' mock_response.agent_reports = [] mock_response.escalations = [] mock_response.actions_taken = [] mock_master.handle_message = AsyncMock(return_value=mock_response) with patch('agent_service.app_state.get_master_agent', return_value=mock_master): from agent_service.main import create_app app = create_app() yield app def test_dispatch_returns_reply(app_with_mock_master): client = TestClient(app_with_mock_master, raise_server_exceptions=False) resp = client.post('/dispatch', json={ 'user_id': '42', 'message': 'What are my overdue invoices?', 'context': {}, }) assert resp.status_code in (200, 503) def test_dispatch_rate_limit(): mock_master = MagicMock() mock_response = MagicMock() mock_response.directive_id = 'x' mock_response.reply = 'ok' mock_response.agent_reports = [] mock_response.escalations = [] mock_response.actions_taken = [] mock_master.handle_message = AsyncMock(return_value=mock_response) with patch('agent_service.app_state.get_master_agent', return_value=mock_master), \ patch('agent_service.routers.dispatch._rate_limit_store', {}): from agent_service.main import create_app app = create_app() client = TestClient(app, raise_server_exceptions=False) for _ in range(31): client.post('/dispatch', json={'user_id': 'ratelimit_user', 'message': 'test', 'context': {}}) def test_health_endpoint(): with patch('agent_service.app_state.get_master_agent', return_value=MagicMock()): from agent_service.main import create_app app = create_app() client = TestClient(app, raise_server_exceptions=False) resp = client.get('/health') assert resp.status_code == 200 data = resp.json() assert 'status' in data