from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def read(path: str) -> str: return (ROOT / path).read_text(encoding="utf-8") def test_opportunity_linking_uses_conversation_as_strong_match_and_contact_as_weak_match(): service = read("app/opportunity_service.py") assert "_find_open_opportunity_by_conversation" in service assert "conversation_id = :conversation_id" in service assert "contact_id_unique_recent" in service assert "CONTACT_MATCH_RECENT_DAYS = 45" in service assert "len(_open_opportunities_for_contact(task.get(\"contact_id\"), limit=2)) > 1" in service assert "find_open_opportunity_for_task" in service old_risky_pattern = "AND ({' OR '.join(filters)})" assert old_risky_pattern not in service def test_ambiguous_contact_match_does_not_create_new_opportunity_and_marks_task_for_review(): service = read("app/opportunity_service.py") assert "has_ambiguous_opportunity_match(task)" in service assert "mark_task_opportunity_link_ambiguous" in service assert "multiple_recent_open_opportunities_for_chatwoot_contact" in service assert "return None" in service def test_task_detail_does_not_link_chatwoot_contact_id_as_local_customer(): tasks_page = read("app/admin_ui/pages/tasks.py") task_service = read("app/task_service.py") assert "linked_customer_id" in task_service assert "LEFT JOIN customers cu ON cu.id = o.local_customer_id" in task_service assert "safe_customer_id" in tasks_page assert "Ver cliente fiscal" in tasks_page assert 'href="/customers/{esc(contact_id)}"' not in tasks_page assert "Contacto Chatwoot" in tasks_page def test_operations_surfaces_ambiguous_opportunity_linking_as_operator_work(): ops = read("app/operations_service.py") operations_page = read("app/admin_ui/pages/operations.py") assert "opportunity_linking_status" in ops assert "ASSOCIATE_OPPORTUNITY" in ops assert "Confirmar associação da oportunidade" in ops assert "Associar oportunidade" in operations_page