# -*- coding: utf-8 -*- """ CropAI Automated Test Suite for Advanced Innovation Engines: 1. Vernacular Voice AI Copilot (Chhattisgarhi, Rural Hindi, Bhojpuri) 2. Soil Health Card AI Digitizer & Stage-Specific NPK Fertilizer Optimizer """ import unittest from fastapi.testclient import TestClient from backend.main import app from backend.voice_copilot import generate_vernacular_advisory, normalize_vernacular_text, SUPPORTED_DIALECTS from backend.soil_health import digitize_and_optimize_fertilizer class TestAdvancedInnovations(unittest.TestCase): @classmethod def setUpClass(cls): cls.client = TestClient(app) # ========================================================================= # 1. Vernacular Voice AI Copilot Tests # ========================================================================= def test_voice_supported_dialects_endpoint(self): """Verify GET /api/v1/voice/supported-dialects returns Chhattisgarhi and Hindi.""" resp = self.client.get("/api/v1/voice/supported-dialects") self.assertEqual(resp.status_code, 200) data = resp.json() self.assertEqual(data["status"], "success") self.assertGreaterEqual(data["total_dialects"], 3) codes = [d["code"] for d in data["dialects"]] self.assertIn("ch-IN", codes) self.assertIn("hi-IN", codes) self.assertIn("bho-IN", codes) def test_chhattisgarhi_vernacular_normalization(self): """Verify normalization of Chhattisgarhi words like 'करपा' and 'माहू'.""" norm = normalize_vernacular_text("हमार धान म करपा लग गे हे", dialect="ch-IN") self.assertEqual(norm["standardized_crop"], "धान (Rice)") self.assertIn("Blast", norm["standardized_pathology"]) def test_voice_advisory_endpoint(self): """Verify POST /api/v1/voice/transcribe-and-advise returns dialect speech and tank dosage.""" payload = { "user_query": "हमार धान म करपा धर ले हे, का दवाई छिड़कन?", "dialect": "ch-IN", "crop": "धान (Rice)" } resp = self.client.post("/api/v1/voice/transcribe-and-advise", json=payload) self.assertEqual(resp.status_code, 200) data = resp.json() self.assertEqual(data["status"], "success") self.assertEqual(data["dialect"], "ch-IN") self.assertIn("जय जोहार", data["advisory_text"]) self.assertIn("16 लीटर", data["advisory_text"]) self.assertIn("Tricyclazole", data["tank_prescription"]["chemical_dose"]) # ========================================================================= # 2. Soil Health Card & NPK Optimizer Tests # ========================================================================= def test_soil_health_digitization_and_splits(self): """Verify 3-stage commercial fertilizer split calculations adhering to Rule 9.""" params = { "ph": 6.8, "organic_carbon_pct": 0.50, "available_n_kg_ha": 210.0, "available_p_kg_ha": 12.0, "available_k_kg_ha": 160.0, "zinc_ppm": 0.45 } result = digitize_and_optimize_fertilizer(soil_params=params, crop="Rice", area_acres=1.0) self.assertEqual(result["status"], "success") self.assertGreater(result["total_commercial_fertilizer"]["dap_kg"], 10.0) self.assertGreater(result["total_commercial_fertilizer"]["urea_kg"], 15.0) self.assertEqual(len(result["split_schedule"]), 3) self.assertIn("रोपाई", result["split_schedule"][0]["stage"]) def test_soil_health_active_blast_warning(self): """Verify Rule 9 safety check: stops urea application if crop has active blast.""" result = digitize_and_optimize_fertilizer( soil_params={"ph": 6.8}, crop="Rice", area_acres=1.0, has_active_blast=True ) self.assertIsNotNone(result["safety_alert"]) self.assertIn("यूरिया का छिड़काव तुरंत रोक दें", result["safety_alert"]) def test_soil_health_api_endpoint(self): """Verify POST /api/v1/soil/analyze-card returns bags and stage schedule.""" payload = { "crop": "Rice", "area_acres": 2.0, "ph": 6.5, "available_n_kg_ha": 200.0, "has_active_blast": False } resp = self.client.post("/api/v1/soil/analyze-card", json=payload) self.assertEqual(resp.status_code, 200) data = resp.json() self.assertEqual(data["status"], "success") self.assertGreater(data["total_commercial_fertilizer"]["urea_bags_45kg"], 0.5) if __name__ == "__main__": unittest.main()