This commit is contained in:
2026-05-05 01:46:10 +03:30
parent 2016aa2058
commit 5301071df5
23 changed files with 962 additions and 136 deletions
+71 -9
View File
@@ -6,9 +6,9 @@ from django.test import TestCase
from rest_framework.test import APIClient
from location_data.models import SoilDepthData, SoilLocation
from farm_data.models import SensorData
from farm_data.models import PlantCatalogSnapshot, SensorData, SensorParameter
from farm_data.services import assign_farm_plants_from_backend_ids
from irrigation.models import IrrigationMethod
from plant.models import Plant
from weather.models import WeatherForecast
from farm_data.services import resolve_center_location_from_boundary
@@ -59,8 +59,8 @@ class FarmDetailApiTests(TestCase):
precipitation=1.2,
humidity_mean=52.0,
)
self.plant1 = Plant.objects.create(name="گوجه‌فرنگی")
self.plant2 = Plant.objects.create(name="خیار")
self.plant1 = PlantCatalogSnapshot.objects.create(backend_plant_id=101, name="گوجه‌فرنگی")
self.plant2 = PlantCatalogSnapshot.objects.create(backend_plant_id=102, name="خیار")
self.irrigation_method = IrrigationMethod.objects.create(name="آبیاری قطره‌ای")
self.farm_uuid = uuid.uuid4()
self.farm = SensorData.objects.create(
@@ -75,7 +75,7 @@ class FarmDetailApiTests(TestCase):
}
},
)
self.farm.plants.set([self.plant2, self.plant1])
assign_farm_plants_from_backend_ids(self.farm, [self.plant2.backend_plant_id, self.plant1.backend_plant_id])
def test_returns_farm_detail_and_prioritizes_sensor_metrics_over_soil(self):
response = self.client.get(f"/api/farm-data/{self.farm_uuid}/detail/")
@@ -90,6 +90,8 @@ class FarmDetailApiTests(TestCase):
payload["sensor_payload"]["sensor-7-1"]["soil_moisture"],
33.5,
)
self.assertIn("sensor_schema", payload)
self.assertEqual(payload["sensor_schema"]["sensor-7-1"][0]["code"], "nitrogen")
resolved_metrics = payload["soil"]["resolved_metrics"]
metric_sources = payload["soil"]["metric_sources"]
@@ -100,12 +102,13 @@ class FarmDetailApiTests(TestCase):
self.assertEqual(resolved_metrics["clay"], 22.0)
self.assertEqual(metric_sources["clay"], "soil")
self.assertEqual(len(payload["soil"]["depths"]), 2)
self.assertCountEqual(payload["plant_ids"], [self.plant1.id, self.plant2.id])
self.assertCountEqual(payload["plant_ids"], [self.plant1.backend_plant_id, self.plant2.backend_plant_id])
self.assertEqual(len(payload["plants"]), 2)
returned_plants = {item["id"]: item for item in payload["plants"]}
self.assertEqual(returned_plants[self.plant1.id]["name"], self.plant1.name)
self.assertEqual(returned_plants[self.plant2.id]["name"], self.plant2.name)
self.assertIn("light", returned_plants[self.plant1.id])
self.assertEqual(returned_plants[self.plant1.backend_plant_id]["name"], self.plant1.name)
self.assertEqual(returned_plants[self.plant2.backend_plant_id]["name"], self.plant2.name)
self.assertIn("light", returned_plants[self.plant1.backend_plant_id])
self.assertEqual(len(payload["plant_assignments"]), 2)
self.assertEqual(payload["irrigation_method_id"], self.irrigation_method.id)
self.assertEqual(payload["irrigation_method"]["name"], self.irrigation_method.name)
@@ -147,6 +150,28 @@ class FarmDetailApiTests(TestCase):
self.assertEqual(resolved_metrics["status"], ["ok", "needs-check"])
self.assertEqual(metric_sources["status"]["strategy"], "distinct_values")
def test_detail_auto_registers_unknown_sensor_parameters(self):
self.farm.sensor_payload = {
"leaf-sensor": {
"leaf_wetness": 11.0,
"leaf_temperature": 19.8,
}
}
self.farm.save(update_fields=["sensor_payload"])
response = self.client.get(f"/api/farm-data/{self.farm_uuid}/detail/")
self.assertEqual(response.status_code, 200)
payload = response.json()["data"]
leaf_schema = payload["sensor_schema"]["leaf-sensor"]
self.assertCountEqual(
[item["code"] for item in leaf_schema],
["leaf_temperature", "leaf_wetness"],
)
self.assertTrue(
SensorParameter.objects.filter(sensor_key="leaf-sensor", code="leaf_wetness").exists()
)
class FarmDataUpsertApiTests(TestCase):
def setUp(self):
@@ -212,6 +237,43 @@ class FarmDataUpsertApiTests(TestCase):
farm.sensor_payload["sensor-7-1"]["soil_moisture"],
31.2,
)
self.assertTrue(
SensorParameter.objects.filter(sensor_key="sensor-7-1", code="soil_moisture").exists()
)
def test_post_auto_registers_new_sensor_without_manual_parameter_creation(self):
farm_uuid = uuid.uuid4()
response = self.client.post(
"/api/farm-data/",
data={
"farm_uuid": str(farm_uuid),
"farm_boundary": self.boundary,
"sensor_payload": {
"canopy-sensor-v2": {
"leaf_wetness": 12.4,
"leaf_temperature": 21.6,
"disease_pressure_index": 0.41,
}
},
},
format="json",
)
self.assertEqual(response.status_code, 201)
self.assertTrue(
SensorParameter.objects.filter(
sensor_key="canopy-sensor-v2",
code="leaf_wetness",
).exists()
)
detail_response = self.client.get(f"/api/farm-data/{farm_uuid}/detail/")
self.assertEqual(detail_response.status_code, 200)
schema = detail_response.json()["data"]["sensor_schema"]["canopy-sensor-v2"]
self.assertCountEqual(
[item["code"] for item in schema],
["disease_pressure_index", "leaf_temperature", "leaf_wetness"],
)
def test_post_requires_farm_uuid_in_request_body(self):
response = self.client.post(