File size: 3,530 Bytes
bbe01fe
 
 
 
 
 
 
c44df3b
bbe01fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84c1ab9
bbe01fe
84c1ab9
bbe01fe
84c1ab9
 
bbe01fe
84c1ab9
bbe01fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c44df3b
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# 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
from app.models.speech import SynthesizeRequest

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


class TestSynthesizeRequest:
    def test_default_voice_is_male(self):
        req = SynthesizeRequest(text="hello")
        assert req.voice == "am_adam"

    def test_voice_too_long_rejected(self):
        with pytest.raises(ValidationError):
            SynthesizeRequest(text="hello", voice="x" * 33)