UPDATE
This commit is contained in:
@@ -11,6 +11,10 @@ from django.test import TestCase
|
||||
from rest_framework.test import APIRequestFactory
|
||||
|
||||
from .models import SimulationRun, SimulationScenario
|
||||
from farm_data.models import PlantCatalogSnapshot, SensorData
|
||||
from irrigation.models import IrrigationMethod
|
||||
from location_data.models import SoilLocation
|
||||
from weather.models import WeatherForecast
|
||||
from .services import CropSimulationService, CropSimulationError, PcseSimulationManager
|
||||
from .views import PlantGrowthSimulationView
|
||||
|
||||
@@ -366,3 +370,97 @@ class CropSimulationPcseIntegrationTests(TestCase):
|
||||
self.assertEqual(result["result"]["engine"], "pcse")
|
||||
self.assertIsNotNone(result["result"]["metrics"]["yield_estimate"])
|
||||
self.assertIsNotNone(result["result"]["metrics"]["biomass"])
|
||||
|
||||
|
||||
class CropSimulationCanonicalSnapshotTests(TestCase):
|
||||
def setUp(self):
|
||||
self.location = SoilLocation.objects.create(latitude="35.700000", longitude="51.400000")
|
||||
self.weather = WeatherForecast.objects.create(
|
||||
location=self.location,
|
||||
forecast_date=date(2026, 4, 10),
|
||||
temperature_min=12.0,
|
||||
temperature_max=24.0,
|
||||
temperature_mean=18.0,
|
||||
humidity_mean=55.0,
|
||||
precipitation=1.0,
|
||||
et0=3.5,
|
||||
)
|
||||
self.plant = PlantCatalogSnapshot.objects.create(backend_plant_id=401, name="wheat")
|
||||
self.irrigation_method = IrrigationMethod.objects.create(name="drip")
|
||||
self.farm = SensorData.objects.create(
|
||||
farm_uuid="550e8400-e29b-41d4-a716-446655440000",
|
||||
center_location=self.location,
|
||||
weather_forecast=self.weather,
|
||||
irrigation_method=self.irrigation_method,
|
||||
)
|
||||
self.farm.plants.add(self.plant)
|
||||
|
||||
@patch("crop_simulation.services.build_ai_farm_snapshot")
|
||||
def test_build_simulation_payload_from_farm_uses_aggregated_metrics(self, mock_snapshot):
|
||||
from crop_simulation.services import build_simulation_payload_from_farm
|
||||
|
||||
mock_snapshot.return_value = {
|
||||
"farm_uuid": str(self.farm.farm_uuid),
|
||||
"farm_metrics": {
|
||||
"resolved_metrics": {
|
||||
"soil_moisture": 36.0,
|
||||
"ndwi": 0.31,
|
||||
"nitrogen": 21.0,
|
||||
"phosphorus": 11.0,
|
||||
"potassium": 17.0,
|
||||
"soil_ph": 6.8,
|
||||
"electrical_conductivity": 1.4,
|
||||
}
|
||||
},
|
||||
"source_metadata": {
|
||||
"farm_metrics": {
|
||||
"canonical_source": "farmer_block_aggregated_snapshot",
|
||||
"aggregation_strategy": "farmer_block_mean",
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
payload = build_simulation_payload_from_farm(farm_uuid=str(self.farm.farm_uuid), plant_name="wheat")
|
||||
|
||||
self.assertEqual(payload["soil"]["soil_moisture"], 36.0)
|
||||
self.assertEqual(payload["site_parameters"]["NAVAILI"], 21.0)
|
||||
self.assertEqual(payload["soil"]["phosphorus"], 11.0)
|
||||
self.assertEqual(payload["source_metadata"]["farm_metrics"]["canonical_source"], "farmer_block_aggregated_snapshot")
|
||||
|
||||
@patch("crop_simulation.services.build_ai_farm_snapshot")
|
||||
def test_build_simulation_payload_from_farm_handles_missing_block_metrics(self, mock_snapshot):
|
||||
from crop_simulation.services import build_simulation_payload_from_farm
|
||||
|
||||
mock_snapshot.return_value = {
|
||||
"farm_uuid": str(self.farm.farm_uuid),
|
||||
"farm_metrics": {"resolved_metrics": {}},
|
||||
"source_metadata": {"farm_metrics": {"status": "missing"}},
|
||||
}
|
||||
|
||||
payload = build_simulation_payload_from_farm(farm_uuid=str(self.farm.farm_uuid), plant_name="wheat")
|
||||
|
||||
self.assertEqual(payload["site_parameters"]["WAV"], 40.0)
|
||||
self.assertEqual(payload["source_metadata"]["farm_metrics"]["status"], "missing")
|
||||
|
||||
@patch("crop_simulation.services.build_ai_farm_snapshot")
|
||||
def test_run_single_simulation_stores_weather_provenance(self, mock_snapshot):
|
||||
mock_snapshot.return_value = {
|
||||
"farm_uuid": str(self.farm.farm_uuid),
|
||||
"farm_metrics": {"resolved_metrics": {"soil_moisture": 35.0, "ndwi": 0.3}},
|
||||
"source_metadata": {
|
||||
"farm_metrics": {"canonical_source": "farmer_block_aggregated_snapshot"},
|
||||
"weather": {"policy": "center_location_latest_forecast"},
|
||||
},
|
||||
}
|
||||
service = CropSimulationService()
|
||||
|
||||
with patch.object(service.manager, "run_simulation", return_value={"engine": "pcse", "metrics": {}, "daily_output": [], "summary_output": [], "terminal_output": []}):
|
||||
result = service.run_single_simulation(
|
||||
farm_uuid=str(self.farm.farm_uuid),
|
||||
plant_name="wheat",
|
||||
agromanagement=build_agromanagement(),
|
||||
)
|
||||
|
||||
self.assertEqual(result["result"]["source_metadata"]["weather"]["policy"], "center_location_latest_forecast")
|
||||
run = SimulationRun.objects.get()
|
||||
self.assertEqual(run.result_payload["source_metadata"]["farm_metrics"]["canonical_source"], "farmer_block_aggregated_snapshot")
|
||||
|
||||
Reference in New Issue
Block a user