Files
Ai/irrigation/test_water_stress_api.py
T

91 lines
3.3 KiB
Python
Raw Normal View History

2026-04-25 17:22:41 +03:30
from __future__ import annotations
from types import SimpleNamespace
from unittest.mock import patch
from django.test import TestCase, override_settings
from rest_framework.test import APIClient
from irrigation.indicators import WaterStressService
@override_settings(ROOT_URLCONF="irrigation.urls")
class WaterStressApiTests(TestCase):
def setUp(self):
self.client = APIClient()
@patch("irrigation.views.apps.get_app_config")
def test_water_stress_api_returns_payload(self, mock_get_app_config):
mock_service = SimpleNamespace(
get_water_stress=lambda **_kwargs: {
"farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
"waterStressIndex": 12,
"level": "پایین",
"sourceMetric": {"soilMoisture": 46.0},
}
)
mock_get_app_config.return_value = SimpleNamespace(
get_water_stress_service=lambda: mock_service
)
response = self.client.post(
"/water-stress/",
data={"farm_uuid": "550e8400-e29b-41d4-a716-446655440000"},
format="json",
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json()["data"]["waterStressIndex"], 12)
class WaterStressServiceTests(TestCase):
@patch("irrigation.indicators.apps.get_app_config")
@patch("irrigation.indicators.SensorData.objects.filter")
def test_service_uses_crop_simulation_water_stress(self, mock_filter, mock_get_app_config):
mock_filter.return_value.first.return_value = SimpleNamespace(
farm_uuid="550e8400-e29b-41d4-a716-446655440000",
soil_moisture=46.0,
)
mock_service = SimpleNamespace(
get_water_stress=lambda **_kwargs: {
"farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
"plant_name": "Tomato",
"waterStressIndex": 37,
"level": "متوسط",
"sourceMetric": {"engine": "crop_simulation"},
}
)
mock_get_app_config.return_value = SimpleNamespace(
get_water_stress_service=lambda: mock_service
)
payload = WaterStressService().get_water_stress(
farm_uuid="550e8400-e29b-41d4-a716-446655440000"
)
self.assertEqual(payload["waterStressIndex"], 37)
self.assertEqual(payload["sourceMetric"]["engine"], "crop_simulation")
@patch("irrigation.indicators.apps.get_app_config")
@patch("irrigation.indicators.SensorData.objects.filter")
def test_service_falls_back_when_crop_simulation_fails(self, mock_filter, mock_get_app_config):
mock_filter.return_value.first.return_value = SimpleNamespace(
farm_uuid="550e8400-e29b-41d4-a716-446655440000",
soil_moisture=46.0,
)
class BrokenService:
def get_water_stress(self, **_kwargs):
raise RuntimeError("simulation offline")
mock_get_app_config.return_value = SimpleNamespace(
get_water_stress_service=lambda: BrokenService()
)
payload = WaterStressService().get_water_stress(
farm_uuid="550e8400-e29b-41d4-a716-446655440000"
)
self.assertEqual(payload["sourceMetric"]["engine"], "sensor_fallback")
self.assertEqual(payload["sourceMetric"]["fallbackReason"], "simulation offline")