"""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." )