Spaces:
Running
Running
Download tests/test_dreams.py from Rthur2003/crowncode-backend: direct link, hf CLI and curl.
- Browser
- Download file 4.48 kB
-
https://huggingface.co/spaces/Rthur2003/crowncode-backend/resolve/main/tests/test_dreams.py
- Command line
-
hf download hf://spaces/Rthur2003/crowncode-backend/tests/test_dreams.py
-
curl -L -o test_dreams.py https://huggingface.co/spaces/Rthur2003/crowncode-backend/resolve/main/tests/test_dreams.py
4.48 kB
| """Tests for /api/dreams/analyze endpoint.""" | |
| from __future__ import annotations | |
| import json | |
| from unittest.mock import MagicMock, patch | |
| import pytest | |
| from fastapi.testclient import TestClient | |
| from app.routes.dreams import _rate_store | |
| def _reset_rate_limiter(): | |
| _rate_store.clear() | |
| yield | |
| _rate_store.clear() | |
| def _mock_gemini_response(**overrides: object) -> MagicMock: | |
| defaults = { | |
| "emotions": ["fear", "wonder"], | |
| "themes": ["being chased"], | |
| "symbols": ["water"], | |
| "interpretation": "This reflects anxiety about a real-life situation.", | |
| "lucidityIndicator": False, | |
| } | |
| defaults.update(overrides) | |
| response = MagicMock() | |
| response.text = json.dumps(defaults) | |
| return response | |
| def test_analyze_valid_dream_returns_structured_result(client: TestClient) -> None: | |
| mock_client = MagicMock() | |
| mock_client.models.generate_content.return_value = _mock_gemini_response() | |
| with patch("app.services.dream_analyzer._get_client", return_value=mock_client): | |
| response = client.post( | |
| "/api/dreams/analyze", | |
| json={"dreamText": "I was being chased through a dark forest and found a river.", "language": "English"}, | |
| ) | |
| assert response.status_code == 200 | |
| body = response.json() | |
| assert body["emotions"] == ["fear", "wonder"] | |
| assert body["themes"] == ["being chased"] | |
| assert body["lucidityIndicator"] is False | |
| def test_analyze_rejects_too_short_dream(client: TestClient) -> None: | |
| response = client.post("/api/dreams/analyze", json={"dreamText": "hi"}) | |
| assert response.status_code == 400 | |
| assert response.json()["detail"]["code"] == "dream_too_short" | |
| def test_analyze_rejects_empty_dream_text(client: TestClient) -> None: | |
| response = client.post("/api/dreams/analyze", json={"dreamText": ""}) | |
| assert response.status_code == 422 | |
| def test_analyze_rejects_missing_dream_text(client: TestClient) -> None: | |
| response = client.post("/api/dreams/analyze", json={}) | |
| assert response.status_code == 422 | |
| def test_analyze_handles_missing_api_key(client: TestClient) -> None: | |
| with patch("app.services.dream_analyzer._get_client", side_effect=ValueError("DREAMS_GEMINI_API_KEY required")): | |
| response = client.post( | |
| "/api/dreams/analyze", | |
| json={"dreamText": "A perfectly normal dream about flying over mountains."}, | |
| ) | |
| assert response.status_code == 503 | |
| assert response.json()["detail"]["code"] == "service_not_configured" | |
| def test_analyze_handles_malformed_gemini_output(client: TestClient) -> None: | |
| mock_client = MagicMock() | |
| bad_response = MagicMock() | |
| bad_response.text = "I refuse to analyze this." | |
| mock_client.models.generate_content.return_value = bad_response | |
| with patch("app.services.dream_analyzer._get_client", return_value=mock_client): | |
| response = client.post( | |
| "/api/dreams/analyze", | |
| json={"dreamText": "A perfectly normal dream about flying over mountains."}, | |
| ) | |
| assert response.status_code == 502 | |
| assert response.json()["detail"]["code"] == "analysis_failed" | |
| def test_analyze_filters_invalid_emotions_from_gemini(client: TestClient) -> None: | |
| """Gemini could hallucinate an emotion outside the allowed set — the | |
| service must filter it rather than pass it straight through.""" | |
| mock_client = MagicMock() | |
| mock_client.models.generate_content.return_value = _mock_gemini_response( | |
| emotions=["fear", "not_a_real_emotion", "joy"] | |
| ) | |
| with patch("app.services.dream_analyzer._get_client", return_value=mock_client): | |
| response = client.post( | |
| "/api/dreams/analyze", | |
| json={"dreamText": "A perfectly normal dream about flying over mountains."}, | |
| ) | |
| assert response.status_code == 200 | |
| assert "not_a_real_emotion" not in response.json()["emotions"] | |
| def test_analyze_enforces_rate_limit(client: TestClient) -> None: | |
| mock_client = MagicMock() | |
| mock_client.models.generate_content.return_value = _mock_gemini_response() | |
| with patch("app.services.dream_analyzer._get_client", return_value=mock_client): | |
| last_status = 200 | |
| for _ in range(10): | |
| r = client.post( | |
| "/api/dreams/analyze", | |
| json={"dreamText": "A perfectly normal dream about flying over mountains."}, | |
| ) | |
| last_status = r.status_code | |
| assert last_status == 429 | |