- Replace all mock tools with real ERPNext Healthcare operations - ERPNextHealthcare class: patients, practitioners, appointments, schedules - check_availability queries real practitioner schedules from ERPNext - create_appointment finds/creates patient + validates conflicts + books in ERPNext - Add /api/v1/config/test endpoint to validate all service connections - Add scripts/validate_setup.py for CLI validation of Meta/OpenAI/ERPNext/DB - Add scripts/seed_knowledge.py with full SKEEN catalog (services, products, packages, FAQ) - Add tests for webhook, health, and WhatsApp client - Update main.py to include config router
62 lines
2.1 KiB
Python
62 lines
2.1 KiB
Python
"""Tests for WhatsApp API client."""
|
|
|
|
import pytest
|
|
import respx
|
|
from httpx import Response
|
|
|
|
from src.infrastructure.whatsapp.client import WhatsAppClient
|
|
|
|
|
|
class TestWhatsAppClient:
|
|
"""Test Meta WhatsApp Business API client."""
|
|
|
|
@pytest.fixture
|
|
def client(self):
|
|
return WhatsAppClient()
|
|
|
|
@respx.mock
|
|
async def test_send_text_message(self, client):
|
|
"""Successfully send text message."""
|
|
route = respx.post(
|
|
"https://graph.facebook.com/v18.0/123456789012345/messages"
|
|
).mock(return_value=Response(200, json={
|
|
"messages": [{"id": "wamid.sent123"}],
|
|
"contacts": [{"wa_id": "5216641234567"}],
|
|
}))
|
|
|
|
result = await client.send_text_message("5216641234567", "Hola SKEEN")
|
|
assert result["messages"][0]["id"] == "wamid.sent123"
|
|
assert route.called
|
|
|
|
@respx.mock
|
|
async def test_send_text_message_too_long(self, client):
|
|
"""Truncate text over 4096 chars."""
|
|
respx.post(
|
|
"https://graph.facebook.com/v18.0/123456789012345/messages"
|
|
).mock(return_value=Response(200, json={"messages": [{"id": "x"}]}))
|
|
|
|
long_text = "A" * 5000
|
|
await client.send_text_message("5216641234567", long_text)
|
|
# Should not raise
|
|
|
|
@respx.mock
|
|
async def test_mark_as_read(self, client):
|
|
"""Mark message as read."""
|
|
route = respx.post(
|
|
"https://graph.facebook.com/v18.0/123456789012345/messages"
|
|
).mock(return_value=Response(200, json={"success": True}))
|
|
|
|
result = await client.mark_as_read("wamid.test123")
|
|
assert result["success"] is True
|
|
assert route.called
|
|
|
|
async def test_button_limit(self, client):
|
|
"""More than 3 buttons raises ValueError."""
|
|
with pytest.raises(ValueError, match="Maximum 3 buttons"):
|
|
await client.send_interactive_buttons(
|
|
"5216641234567",
|
|
"Choose:",
|
|
[{"id": "1", "title": "A"}, {"id": "2", "title": "B"},
|
|
{"id": "3", "title": "C"}, {"id": "4", "title": "D"}],
|
|
)
|