from __future__ import annotations import asyncio import json import unittest from unittest.mock import AsyncMock, patch from fastapi.responses import JSONResponse from app import create_app from settings import get_settings class AppTestCase(unittest.TestCase): def setUp(self) -> None: get_settings.cache_clear() self.app = create_app() def tearDown(self) -> None: get_settings.cache_clear() def _get_route_response(self, path: str) -> JSONResponse: route = next(route for route in self.app.routes if getattr(route, "path", None) == path) return asyncio.run(route.endpoint()) def test_health(self) -> None: response = self._get_route_response("/health") self.assertEqual(response.status_code, 200) self.assertEqual(json.loads(response.body), {"status": "ok"}) def test_prototype_payload_shape(self) -> None: payload = { "hero": {"title": "Robot U"}, "featured_courses": [], "recent_posts": [], "recent_discussions": [], "upcoming_events": [], "source_of_truth": [], } with patch("app.build_live_prototype_payload", new=AsyncMock(return_value=payload)): response = self._get_route_response("/api/prototype") payload = json.loads(response.body) self.assertEqual(response.status_code, 200) self.assertIn("hero", payload) self.assertIn("featured_courses", payload) self.assertIn("recent_posts", payload) self.assertIn("recent_discussions", payload) self.assertIn("upcoming_events", payload) self.assertIn("source_of_truth", payload) if __name__ == "__main__": unittest.main()