import unittest from fastapi.testclient import TestClient from app.core.database import get_db from app.main import app from tests.test_plants import FakeDb class FailingDb: def table(self, _table_name): raise RuntimeError("database unavailable") class ApiContractTest(unittest.TestCase): def setUp(self): self.db = FakeDb() app.dependency_overrides[get_db] = lambda: self.db self.client = TestClient(app, raise_server_exceptions=False) def tearDown(self): app.dependency_overrides.clear() def test_health_checks_real_database_query(self): response = self.client.get("/health") self.assertEqual(200, response.status_code) self.assertTrue(response.json()["supabase_connected"]) self.assertEqual(1, len(self.db.queries)) self.assertEqual("plants", self.db.queries[0].table_name) def test_health_returns_503_when_database_query_fails(self): app.dependency_overrides[get_db] = lambda: FailingDb() response = self.client.get("/health") self.assertEqual(503, response.status_code) self.assertEqual( "데이터베이스 연결 상태를 확인할 수 없습니다.", response.json()["detail"], ) def test_string_plant_detail_path_returns_200(self): response = self.client.get("/plants/1/nrems-03") self.assertEqual(200, response.status_code) self.assertEqual("nrems-03", response.json()["data"]["plant"]["id"]) def test_invalid_comparison_date_returns_400(self): response = self.client.get( "/plants/stats/comparison?period=day&date=2026-8-07" ) self.assertEqual(400, response.status_code) def test_invalid_month_returns_422(self): response = self.client.get( "/plants/nrems-03/stats?period=day&year=2026&month=13" ) self.assertEqual(422, response.status_code) def test_unknown_plant_stats_returns_404(self): app.dependency_overrides[get_db] = lambda: FakeDb(plant_exists=False) response = self.client.get( "/plants/missing/stats?period=day&year=2026&month=8" ) self.assertEqual(404, response.status_code) def test_openapi_declares_string_plant_id_and_response_models(self): schema = self.client.get("/openapi.json").json() detail_operation = schema["paths"]["/plants/{company_id}/{plant_id}"]["get"] plant_id_param = next( item for item in detail_operation["parameters"] if item["name"] == "plant_id" ) self.assertEqual("string", plant_id_param["schema"]["type"]) self.assertIn("200", detail_operation["responses"]) self.assertIn( "PlantDetailResponse", str(detail_operation["responses"]["200"]), ) self.assertIn( "DetailedHealthResponse", str(schema["paths"]["/health"]["get"]["responses"]["200"]), ) self.assertIn( "UploadResponse", str( schema["paths"]["/plants/{plant_id}/upload"] ["post"]["responses"]["200"] ), ) if __name__ == "__main__": unittest.main()