Spaces:
Running
Running
| # 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 | |