File size: 4,071 Bytes
f440f03
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""Tests for the public Hugging Face chat Space app."""

from __future__ import annotations

import importlib
import sys
from pathlib import Path

from fastapi.testclient import TestClient

REPO_ROOT = Path(__file__).resolve().parents[2]
if str(REPO_ROOT) not in sys.path:
    sys.path.insert(0, str(REPO_ROOT))

chat_space_app = importlib.import_module("huggingface_chat_space.app")


def test_chat_space_index_contains_persona_and_model_controls() -> None:
    client = TestClient(chat_space_app.app)

    response = client.get("/")

    assert response.status_code == 200
    assert 'id="model"' in response.text
    assert 'id="custom-model"' in response.text
    assert 'id="persona-list"' in response.text
    assert 'id="session-list"' in response.text
    assert "Māris AI" in response.text
    assert "Jauna saruna" in response.text
    assert "Tiešsaistē" in response.text
    assert "Māris AI chat logo" in response.text
    assert "Dzēst sesiju" in response.text


def test_chat_space_index_avoids_resending_pending_user_turn() -> None:
    client = TestClient(chat_space_app.app)

    response = client.get("/")

    assert response.status_code == 200
    assert "function historyPayloadForRequest" in response.text
    assert "function resolveRequestedModel" in response.text
    assert "historyPayloadForRequest(sessionForRequest || activeSession, message)" in response.text
    assert "model: resolveRequestedModel(sessionForRequest || activeSession)" in response.text


def test_chat_endpoint_returns_generated_payload(monkeypatch) -> None:
    client = TestClient(chat_space_app.app)

    class DummyResponse:
        def model_dump(self) -> dict[str, object]:
            return {
                "response": "Sakārtoju atbildi.",
                "model": "MarisUK/Codex",
                "persona_id": "strategist",
                "persona_title": "Systems Strategist",
                "persona_summary": "Stratēģiska persona.",
                "detected_emotion": "curious",
                "emotion_confidence": 0.82,
                "response_style": "clear_grounded",
            }

    async def fake_generate_reply(request):
        assert request.persona_id == "strategist"
        return DummyResponse()

    monkeypatch.setattr(chat_space_app, "generate_space_chat_reply", fake_generate_reply)

    response = client.post(
        "/api/chat",
        json={
            "message": "Palīdzi ar roadmap",
            "history": [],
            "model": "MarisUK/Codex",
            "persona_id": "strategist",
        },
    )

    assert response.status_code == 200
    assert response.json()["persona_title"] == "Systems Strategist"
    assert response.json()["response"] == "Sakārtoju atbildi."


def test_chat_space_exposes_api_health_and_cors() -> None:
    client = TestClient(chat_space_app.app)

    health_response = client.get("/api/health")
    assert health_response.status_code == 200
    assert health_response.json()["service"] == "maris-chat-space"

    cors_response = client.options(
        "/api/chat",
        headers={
            "Origin": "https://example.com",
            "Access-Control-Request-Method": "POST",
        },
    )
    assert cors_response.status_code == 200
    assert cors_response.headers["access-control-allow-origin"] == "*"


def test_chat_endpoint_hides_internal_stop_iteration_errors(monkeypatch) -> None:
    client = TestClient(chat_space_app.app)

    async def fake_generate_reply(request):
        del request
        raise RuntimeError("coroutine raised StopIteration")

    monkeypatch.setattr(chat_space_app, "generate_space_chat_reply", fake_generate_reply)

    response = client.post(
        "/api/chat",
        json={
            "message": "Palīdzi ar roadmap",
            "history": [],
            "model": "MarisUK/Codex",
            "persona_id": "strategist",
        },
    )

    assert response.status_code == 503
    assert response.json()["detail"] == (
        "Māris AI Space īslaicīgi nevar atbildēt. Lūdzu, mēģini vēlreiz pēc brīža."
    )