207 lines
7.0 KiB
Python
207 lines
7.0 KiB
Python
"""
|
|
Unit tests for the Onboarding module.
|
|
|
|
Tests time-aware greetings, user identification, and registration
|
|
logic without requiring external dependencies (Qdrant mock).
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
from datetime import datetime
|
|
|
|
# Import after mocking to avoid connection errors
|
|
import sys
|
|
sys.modules['src.clients'] = MagicMock()
|
|
|
|
from src.agents.onboarding import (
|
|
OnboardingManager,
|
|
UserProfile,
|
|
UserStatus,
|
|
)
|
|
|
|
|
|
class TestGetTimeGreeting:
|
|
"""Tests for get_time_greeting() function."""
|
|
|
|
@pytest.fixture
|
|
def onboarding(self):
|
|
"""Create OnboardingManager with mocked Qdrant."""
|
|
with patch('src.agents.onboarding.get_qdrant_client'):
|
|
manager = OnboardingManager()
|
|
return manager
|
|
|
|
def test_morning_greeting(self, onboarding):
|
|
"""Should return 'Bom dia' for morning hours (5-11)."""
|
|
with patch('src.agents.onboarding.datetime') as mock_dt:
|
|
mock_dt.now.return_value = datetime(2026, 2, 2, 9, 0, 0)
|
|
|
|
result = onboarding.get_time_greeting()
|
|
|
|
assert result == "Bom dia"
|
|
|
|
def test_afternoon_greeting(self, onboarding):
|
|
"""Should return 'Boa tarde' for afternoon hours (12-17)."""
|
|
with patch('src.agents.onboarding.datetime') as mock_dt:
|
|
mock_dt.now.return_value = datetime(2026, 2, 2, 15, 30, 0)
|
|
|
|
result = onboarding.get_time_greeting()
|
|
|
|
assert result == "Boa tarde"
|
|
|
|
def test_evening_greeting(self, onboarding):
|
|
"""Should return 'Boa noite' for evening hours (18-4)."""
|
|
with patch('src.agents.onboarding.datetime') as mock_dt:
|
|
mock_dt.now.return_value = datetime(2026, 2, 2, 20, 0, 0)
|
|
|
|
result = onboarding.get_time_greeting()
|
|
|
|
assert result == "Boa noite"
|
|
|
|
def test_late_night_greeting(self, onboarding):
|
|
"""Should return 'Boa noite' for late night (2am)."""
|
|
with patch('src.agents.onboarding.datetime') as mock_dt:
|
|
mock_dt.now.return_value = datetime(2026, 2, 2, 2, 0, 0)
|
|
|
|
result = onboarding.get_time_greeting()
|
|
|
|
assert result == "Boa noite"
|
|
|
|
|
|
class TestIsKnownUser:
|
|
"""Tests for is_known_user() function."""
|
|
|
|
@pytest.fixture
|
|
def onboarding(self):
|
|
"""Create OnboardingManager with mocked Qdrant."""
|
|
with patch('src.agents.onboarding.get_qdrant_client') as mock_qdrant:
|
|
manager = OnboardingManager()
|
|
manager._qdrant = mock_qdrant.return_value
|
|
return manager
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_unknown_user_returns_false(self, onboarding):
|
|
"""Should return False for unknown telegram_id."""
|
|
onboarding._qdrant.scroll = AsyncMock(return_value=([], None))
|
|
|
|
result = await onboarding.is_known_user("999999999")
|
|
|
|
assert result is False
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_known_user_returns_true(self, onboarding):
|
|
"""Should return True for registered user."""
|
|
mock_result = MagicMock()
|
|
mock_result.payload = {
|
|
"telegram_id": "123456",
|
|
"name": "João Silva",
|
|
"company": "iT Guys",
|
|
"tenant_id": "tenant_itguys",
|
|
"status": "registered",
|
|
"first_contact": "2026-01-01T10:00:00+00:00",
|
|
"last_contact": "2026-02-02T12:00:00+00:00",
|
|
"interaction_count": 5
|
|
}
|
|
onboarding._qdrant.scroll = AsyncMock(return_value=([mock_result], None))
|
|
|
|
result = await onboarding.is_known_user("123456")
|
|
|
|
assert result is True
|
|
|
|
|
|
class TestStartRegistration:
|
|
"""Tests for start_registration() function."""
|
|
|
|
@pytest.fixture
|
|
def onboarding(self):
|
|
"""Create OnboardingManager with mocked Qdrant."""
|
|
with patch('src.agents.onboarding.get_qdrant_client'):
|
|
manager = OnboardingManager()
|
|
return manager
|
|
|
|
def test_returns_welcome_message(self, onboarding):
|
|
"""Should return welcome message with greeting."""
|
|
with patch.object(onboarding, 'get_time_greeting', return_value="Boa tarde"):
|
|
result = onboarding.start_registration("123456")
|
|
|
|
assert "Boa tarde" in result
|
|
assert "nome" in result.lower()
|
|
assert "empresa" in result.lower()
|
|
|
|
def test_marks_user_as_pending(self, onboarding):
|
|
"""Should mark user as pending registration."""
|
|
onboarding.start_registration("123456")
|
|
|
|
assert onboarding.is_pending_registration("123456") is True
|
|
|
|
def test_unknown_user_not_pending(self, onboarding):
|
|
"""Unknown user should not be pending."""
|
|
assert onboarding.is_pending_registration("999999") is False
|
|
|
|
|
|
class TestUserProfile:
|
|
"""Tests for UserProfile dataclass."""
|
|
|
|
def test_to_dict_serialization(self):
|
|
"""Should serialize to dictionary correctly."""
|
|
profile = UserProfile(
|
|
telegram_id="123",
|
|
name="João",
|
|
company="iT Guys",
|
|
tenant_id="tenant_itguys",
|
|
status=UserStatus.REGISTERED,
|
|
first_contact=datetime(2026, 1, 1, 10, 0, 0),
|
|
last_contact=datetime(2026, 2, 2, 12, 0, 0)
|
|
)
|
|
|
|
result = profile.to_dict()
|
|
|
|
assert result["telegram_id"] == "123"
|
|
assert result["status"] == "registered"
|
|
assert "2026-01-01" in result["first_contact"]
|
|
|
|
def test_from_dict_deserialization(self):
|
|
"""Should deserialize from dictionary correctly."""
|
|
data = {
|
|
"telegram_id": "123",
|
|
"name": "Maria",
|
|
"company": "OESTEPAN",
|
|
"tenant_id": None,
|
|
"status": "non_client",
|
|
"first_contact": "2026-01-15T09:00:00",
|
|
"last_contact": "2026-01-15T09:00:00"
|
|
}
|
|
|
|
profile = UserProfile.from_dict(data)
|
|
|
|
assert profile.name == "Maria"
|
|
assert profile.status == UserStatus.NON_CLIENT
|
|
assert profile.tenant_id is None
|
|
|
|
|
|
class TestBuildGreeting:
|
|
"""Tests for build_greeting() function."""
|
|
|
|
@pytest.fixture
|
|
def onboarding(self):
|
|
"""Create OnboardingManager with mocked Qdrant."""
|
|
with patch('src.agents.onboarding.get_qdrant_client'):
|
|
manager = OnboardingManager()
|
|
return manager
|
|
|
|
def test_greeting_with_first_name(self, onboarding):
|
|
"""Should greet user by first name."""
|
|
profile = UserProfile(
|
|
telegram_id="123",
|
|
name="João Carlos Silva",
|
|
company="iT Guys",
|
|
tenant_id="tenant_itguys",
|
|
status=UserStatus.REGISTERED,
|
|
first_contact=datetime.now(),
|
|
last_contact=datetime.now()
|
|
)
|
|
|
|
with patch.object(onboarding, 'get_time_greeting', return_value="Bom dia"):
|
|
result = onboarding.build_greeting(profile)
|
|
|
|
assert "Bom dia, João!" in result
|