personabot-api / tests /test_models.py
GitHub Actions
Deploy a68420a
84c1ab9
# backend/tests/test_models.py
# Tests for Pydantic request/response models.
# These run instantly — no network, no mocks needed.
import pytest
from pydantic import ValidationError
from app.models.chat import ChatRequest, SourceRef, ChatResponse
VALID_UUID = "a1b2c3d4-e5f6-4789-8abc-def012345678"
class TestChatRequest:
def test_valid_request(self):
req = ChatRequest(message="What is TextOps?", session_id=VALID_UUID)
assert req.message == "What is TextOps?"
assert req.session_id == VALID_UUID
def test_message_empty_rejected(self):
with pytest.raises(ValidationError) as exc_info:
ChatRequest(message="", session_id=VALID_UUID)
assert "min_length" in str(exc_info.value).lower() or "1" in str(exc_info.value)
def test_message_too_long_rejected(self):
with pytest.raises(ValidationError):
ChatRequest(message="x" * 501, session_id=VALID_UUID)
def test_message_at_max_length_allowed(self):
req = ChatRequest(message="x" * 500, session_id=VALID_UUID)
assert len(req.message) == 500
def test_invalid_session_id_rejected(self):
# Contains spaces and special chars not in [a-zA-Z0-9_-]
with pytest.raises(ValidationError):
ChatRequest(message="hello", session_id="invalid id with spaces!")
def test_session_id_with_special_chars_rejected(self):
# @ and # are not in the allowed set [a-zA-Z0-9_-]
with pytest.raises(ValidationError):
ChatRequest(message="hello", session_id="bad@session#id")
def test_missing_message_rejected(self):
with pytest.raises(ValidationError):
ChatRequest(session_id=VALID_UUID)
def test_missing_session_id_rejected(self):
with pytest.raises(ValidationError):
ChatRequest(message="hello")
def test_message_whitespace_only_rejected(self):
# An all-whitespace string has length > 0 so passes min_length,
# but we want to document the current behaviour explicitly.
# If the model adds a strip validator later this test should be updated.
req = ChatRequest(message=" ", session_id=VALID_UUID)
assert req.message == " "
class TestSourceRef:
def test_valid_source(self):
src = SourceRef(
title="TextOps",
url="https://darshanchheda.com/projects/textops",
section="Overview",
)
assert src.title == "TextOps"
def test_missing_field_rejected(self):
with pytest.raises(ValidationError):
SourceRef(title="TextOps", url="https://example.com")
class TestChatResponse:
def test_valid_response(self):
resp = ChatResponse(
answer="TextOps is a Go-based NLP gateway.",
sources=[
SourceRef(
title="TextOps",
url="https://darshanchheda.com/projects/textops",
section="Overview",
)
],
cached=False,
latency_ms=312,
)
assert resp.cached is False
assert resp.latency_ms == 312
assert len(resp.sources) == 1