from fastapi.testclient import TestClient import services.sales_service.app as sales_module def _methods(path: str) -> set[str]: result: set[str] = set() for route in sales_module.app.routes: if getattr(route, "path", None) == path: result.update(getattr(route, "methods", set())) return result def test_sales_frontend_contract_routes_are_registered(): expected = { "/api/v1/deals/{deal_id}/change-stage": {"POST"}, "/api/v1/deals/{deal_id}/notes/{note_id}": {"PATCH"}, "/api/v1/deals/{deal_id}/switch-channel": {"POST"}, "/api/v1/communications/{communication_id}/switch-channel": {"POST"}, "/api/v1/calls/{call_id}/transcript": {"GET", "POST"}, "/api/v1/deals/{deal_id}/offers": {"GET", "POST"}, "/api/v1/deals/{deal_id}/documents": {"GET", "POST"}, "/api/v1/deals/{deal_id}/invoices": {"GET", "POST"}, "/api/v1/deals/{deal_id}/conditions": {"GET", "POST", "PATCH", "PUT"}, "/api/v1/deals/{deal_id}/conditions/confirm": {"POST"}, "/api/v1/deals/{deal_id}/escalations": {"GET", "POST"}, "/api/v1/automation-tasks": {"GET"}, "/api/v1/deals/{deal_id}/automation-tasks": {"GET"}, "/api/v1/automation-tasks/{task_id}/cancel": {"POST"}, "/api/v1/automation-tasks/{task_id}/run-now": {"POST"}, "/api/v1/leads": {"GET", "POST"}, "/api/v1/leads/{lead_id}": {"GET", "PATCH"}, "/api/v1/leads/{lead_id}/enrich": {"POST"}, "/api/v1/leads/{lead_id}/convert-to-deal": {"POST"}, "/api/v1/customers": {"GET"}, "/api/v1/customers/{customer_id}": {"GET", "PATCH"}, "/api/v1/customers/{customer_id}/deals": {"GET"}, "/api/v1/customers/{customer_id}/communications": {"GET"}, "/api/v1/customers/{customer_id}/documents": {"GET"}, "/api/v1/customers/{customer_id}/invoices": {"GET"}, "/api/v1/customers/{customer_id}/payments": {"GET"}, } for path, methods in expected.items(): assert methods.issubset(_methods(path)) def test_tenant_automation_tasks_route_accepts_registry_filters(): client = TestClient(sales_module.app) response = client.get( "/api/v1/automation-tasks", params={ "status": "pending", "run_at": "future", "pending_only": "true", "deal_search": "demo", }, headers={"X-User": "admin", "X-Role": "admin", "X-Tenant-ID": "tenant_contract"}, ) assert response.status_code == 200 assert isinstance(response.json(), list) def test_leads_route_accepts_registry_filters(): client = TestClient(sales_module.app) response = client.get( "/api/v1/leads", params={ "search": "demo", "status": "new_qualified_lead", "lead_temperature": "warm", "source_channel": "telegram", "source_type": "crm", "customer_type": "b2b", "preferred_channel": "telegram", "limit": "25", "offset": "0", }, headers={"X-User": "admin", "X-Role": "admin", "X-Tenant-ID": "tenant_contract"}, ) assert response.status_code == 200 assert isinstance(response.json(), list) def test_customers_route_accepts_registry_filters(): client = TestClient(sales_module.app) response = client.get( "/api/v1/customers", params={"search": "demo", "limit": "25", "offset": "0"}, headers={"X-User": "admin", "X-Role": "admin", "X-Tenant-ID": "tenant_contract"}, ) assert response.status_code == 200 assert isinstance(response.json(), list)