ground-zero / tests /test_iot.py
jefffffff9
Initial commit: Sahel-Agri Voice AI
76db545
"""
Unit tests for the IoT layer: IntentParser, SensorBridge (mock), VoiceResponder.
"""
from __future__ import annotations
import asyncio
import pytest
class TestIntentParser:
def setup_method(self):
from src.iot.intent_parser import IntentParser
self.parser = IntentParser()
def test_bambara_soil_intent(self):
intent = self.parser.parse("bunding nɔgɔ foro", "bam")
assert intent.action == "check_soil"
assert intent.confidence > 0
def test_bambara_water_intent(self):
intent = self.parser.parse("ji sanji foro", "bam")
assert intent.action == "irrigation_status"
def test_fula_soil_intent(self):
intent = self.parser.parse("leydi ngesa ladde", "ful")
assert intent.action == "check_soil"
def test_fula_pest_intent(self):
intent = self.parser.parse("biñ-biñ", "ful")
assert intent.action == "pest_alert"
def test_unknown_text_returns_some_intent(self):
intent = self.parser.parse("hello world", "bam")
# Should return something without crashing
assert intent.action is not None
assert intent.confidence == 0.0
def test_confidence_range(self):
intent = self.parser.parse("bunding nɔgɔ", "bam")
assert 0.0 <= intent.confidence <= 1.0
class TestSensorBridgeMock:
def setup_method(self):
from src.iot.sensor_bridge import SensorBridge
self.bridge = SensorBridge(sensor_api_url=None)
def test_mock_mode_enabled(self):
assert self.bridge._mock_mode is True
def test_get_soil_data_returns_sensor_data(self):
from src.iot.sensor_bridge import SensorData
data = asyncio.run(self.bridge.get_soil_data("field_001"))
assert isinstance(data, SensorData)
assert data.sensor_type == "soil"
assert "moisture_pct" in data.values
assert "ph" in data.values
def test_get_weather_returns_sensor_data(self):
from src.iot.sensor_bridge import SensorData
data = asyncio.run(self.bridge.get_weather("zone_a"))
assert isinstance(data, SensorData)
assert "temperature_c" in data.values
def test_fetch_dispatches_by_intent_action(self):
from src.iot.intent_parser import Intent
from src.iot.sensor_bridge import SensorData
intent = Intent(action="check_soil", entity="soil", confidence=0.8)
data = asyncio.run(self.bridge.fetch(intent))
assert isinstance(data, SensorData)
assert data.sensor_type == "soil"
class TestVoiceResponder:
def setup_method(self):
from src.iot.voice_responder import VoiceResponder
self.responder = VoiceResponder(language="fr")
def _make_intent(self, action):
from src.iot.intent_parser import Intent
return Intent(action=action, entity=action, confidence=1.0)
def _make_sensor_data(self, sensor_type, values):
from src.iot.sensor_bridge import SensorData
from datetime import datetime
return SensorData(sensor_type=sensor_type, values=values, timestamp=datetime.utcnow().isoformat())
def test_low_moisture_triggers_irrigation_warning(self):
intent = self._make_intent("check_soil")
data = self._make_sensor_data("soil", {"moisture_pct": 20.0, "ph": 6.5})
response = self.responder.generate_response(intent, data)
assert "Irrigation" in response or "irrigation" in response
def test_normal_soil_contains_moisture(self):
intent = self._make_intent("check_soil")
data = self._make_sensor_data("soil", {"moisture_pct": 45.0, "ph": 6.8})
response = self.responder.generate_response(intent, data)
assert "45" in response
def test_high_pest_level_triggers_warning(self):
intent = self._make_intent("pest_alert")
data = self._make_sensor_data("pest", {"alert_level": 3.0, "trap_count_24h": 45.0})
response = self.responder.generate_response(intent, data)
assert "Traitement" in response or "traitement" in response
def test_weather_response_contains_temperature(self):
intent = self._make_intent("check_weather")
data = self._make_sensor_data("weather", {"temperature_c": 36.0, "rain_probability_pct": 10.0})
response = self.responder.generate_response(intent, data)
assert "36" in response
def test_french_response_output(self):
intent = self._make_intent("check_weather")
data = self._make_sensor_data("weather", {"temperature_c": 30.0})
response = self.responder.generate_response(intent, data)
# Response should be in French
assert any(word in response for word in ["Température", "température", "Humidité", "Vent", "pluie"])