import io import unittest from fastapi.testclient import TestClient from PIL import Image from backend.main import app from backend.knowledge_base import DISEASE_KNOWLEDGE_BASE class TestCropAIGeminiBackend(unittest.TestCase): @classmethod def setUpClass(cls): cls.client = TestClient(app) def test_health_check(self): """Verify health endpoint returns status healthy, Gemini engine info, and headers.""" response = self.client.get("/health") self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(data["status"], "healthy") self.assertIn("ai_engine", data) self.assertTrue(data["gemini_active"]) self.assertGreater(data["knowledge_base_entries"], 0) self.assertIn("x-request-id", response.headers) self.assertIn("x-process-time-ms", response.headers) def test_model_info_endpoint(self): """Verify /api/v1/model-info returns Google Gemini metadata.""" response = self.client.get("/api/v1/model-info") self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(data["ai_model"], "Google Gemini 3.8 Flash") self.assertEqual(data["primary_model"], "gemini-3.8-flash") self.assertIn("Universal", data["supported_crops"]) def test_api_status(self): """Verify status endpoint returns online status and environment.""" response = self.client.get("/api/v1/status") self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["status"], "online") self.assertTrue(response.json()["gemini_active"]) def test_get_supported_crops(self): """Verify supported crops list contains Tomato, Potato, Apple, Rice, etc.""" response = self.client.get("/api/v1/crops") self.assertEqual(response.status_code, 200) data = response.json() self.assertGreaterEqual(data["total_crops"], 5) self.assertGreaterEqual(data["total_classes"], 15) crop_names = [c["crop_name"] for c in data["crops"]] self.assertIn("Tomato", crop_names) self.assertIn("Rice (Paddy)", crop_names) def test_get_disease_details(self): """Verify fetching details for a specific disease class.""" response = self.client.get("/api/v1/diseases/Tomato___Early_blight") self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(data["name"], "Tomato Early Blight") self.assertEqual(data["crop"], "Tomato") self.assertGreater(len(data["symptoms"]), 0) self.assertGreater(len(data["treatment"]["immediate_action"]), 0) def test_expert_ticket_lifecycle(self): """Test creating and retrieving expert consultation tickets.""" payload = { "farmer_name": "Ramesh Patel", "phone_number": "+919876543210", "location": "Nashik, Maharashtra", "crop": "Tomato", "disease_suspected": "Late Blight", "notes": "Leaves showing brown oily spots after 2 days of rain." } create_resp = self.client.post("/api/v1/expert-tickets", json=payload) self.assertEqual(create_resp.status_code, 200) data = create_resp.json() self.assertTrue(data["ticket_id"].startswith("TICK-")) self.assertEqual(data["status"], "PENDING_REVIEW") self.assertIn("Ramesh Patel", data["message"]) # Test listing tickets list_resp = self.client.get("/api/v1/expert-tickets?limit=5") self.assertEqual(list_resp.status_code, 200) list_data = list_resp.json() self.assertGreaterEqual(list_data["total_returned"], 1) def test_invalid_image_upload(self): """Test rejection of non-image files.""" response = self.client.post( "/api/v1/analyze", files={"file": ("notes.txt", b"not an image", "text/plain")} ) self.assertEqual(response.status_code, 400) def test_integrated_datasets_endpoint(self): """Verify /api/v1/datasets/platforms returns multi-platform Hugging Face & Indian dataset metadata.""" response = self.client.get("/api/v1/datasets/platforms") self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(data["status"], "synchronized") self.assertGreaterEqual(data["total_datasets"], 14) self.assertGreaterEqual(data["total_image_samples"], 338000) self.assertIn("Hugging Face Hub", data["platforms_supported"]) self.assertIn("IP102 Insect Recognition Benchmark", data["platforms_supported"]) self.assertIn("DeepWeeds Agricultural Herbicide Benchmark", data["platforms_supported"]) if __name__ == "__main__": unittest.main()