UPDATE
This commit is contained in:
@@ -7,6 +7,7 @@ import uuid
|
||||
from django.test import TransactionTestCase
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from farm_data.models import PlantCatalogSnapshot
|
||||
from location_data.models import NdviObservation, SoilLocation
|
||||
from weather.models import WeatherForecast
|
||||
|
||||
@@ -40,6 +41,7 @@ class IntegrationAPITestCase(TransactionTestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
self.client = APIClient()
|
||||
self._next_backend_plant_id = 100
|
||||
self.primary_boundary = square_boundary(self.primary_lat, self.primary_lon)
|
||||
self.primary_location = self.create_complete_location(
|
||||
lat=self.primary_lat,
|
||||
@@ -55,6 +57,7 @@ class IntegrationAPITestCase(TransactionTestCase):
|
||||
lat: float,
|
||||
lon: float,
|
||||
boundary: dict[str, Any] | None = None,
|
||||
**_ignored: Any,
|
||||
) -> SoilLocation:
|
||||
location = SoilLocation.objects.create(
|
||||
latitude=f"{lat:.6f}",
|
||||
@@ -126,22 +129,46 @@ class IntegrationAPITestCase(TransactionTestCase):
|
||||
return response.json()["data"]
|
||||
|
||||
def create_plant_via_api(self, name: str, **overrides: Any) -> dict[str, Any]:
|
||||
backend_plant_id = int(overrides.pop("id", self._next_backend_plant_id))
|
||||
self._next_backend_plant_id = max(self._next_backend_plant_id, backend_plant_id + 1)
|
||||
payload = {
|
||||
"id": backend_plant_id,
|
||||
"name": name,
|
||||
"icon": "leaf",
|
||||
"light": "full sun",
|
||||
"watering": "every 2 days",
|
||||
"soil": "loamy",
|
||||
"temperature": "20-28C",
|
||||
"growth_stage": "vegetative",
|
||||
"growth_stages": ["vegetative"],
|
||||
"planting_season": "spring",
|
||||
"harvest_time": "90 days",
|
||||
"spacing": "50 cm",
|
||||
"fertilizer": "balanced NPK",
|
||||
}
|
||||
payload.update(overrides)
|
||||
response = self.client.post("/api/plants/", data=payload, format="json")
|
||||
self.assertEqual(response.status_code, 201, response.json())
|
||||
return response.json()["data"]
|
||||
if "growth_stages" not in overrides:
|
||||
payload["growth_stages"] = [payload["growth_stage"]] if payload.get("growth_stage") else []
|
||||
response = self.client.post("/api/farm-data/plants/sync/", data=[payload], format="json")
|
||||
self.assertEqual(response.status_code, 200, response.json())
|
||||
|
||||
snapshot = PlantCatalogSnapshot.objects.get(backend_plant_id=backend_plant_id)
|
||||
return {
|
||||
"id": snapshot.backend_plant_id,
|
||||
"backend_plant_id": snapshot.backend_plant_id,
|
||||
"name": snapshot.name,
|
||||
"icon": snapshot.icon,
|
||||
"light": snapshot.light,
|
||||
"watering": snapshot.watering,
|
||||
"soil": snapshot.soil,
|
||||
"temperature": snapshot.temperature,
|
||||
"growth_stage": snapshot.growth_stage,
|
||||
"growth_stages": list(snapshot.growth_stages or []),
|
||||
"planting_season": snapshot.planting_season,
|
||||
"harvest_time": snapshot.harvest_time,
|
||||
"spacing": snapshot.spacing,
|
||||
"fertilizer": snapshot.fertilizer,
|
||||
}
|
||||
|
||||
def create_sensor_parameter_via_api(self, **overrides: Any) -> dict[str, Any]:
|
||||
payload = {
|
||||
|
||||
@@ -5,9 +5,8 @@ from unittest.mock import patch
|
||||
|
||||
from django.test import override_settings
|
||||
|
||||
from farm_data.models import ParameterUpdateLog, SensorData, SensorParameter
|
||||
from farm_data.models import ParameterUpdateLog, PlantCatalogSnapshot, SensorData, SensorParameter
|
||||
from integration_tests.base import IntegrationAPITestCase
|
||||
from plant.models import Plant
|
||||
|
||||
|
||||
@override_settings(ROOT_URLCONF="config.urls")
|
||||
@@ -44,88 +43,44 @@ class FarmManagementJourneyTests(IntegrationAPITestCase):
|
||||
|
||||
tomato = self.create_plant_via_api("Tomato")
|
||||
cucumber = self.create_plant_via_api("Cucumber", watering="daily")
|
||||
removable_plant = self.create_plant_via_api("Remove Plant")
|
||||
|
||||
plants_list_response = self.client.get("/api/plants/")
|
||||
self.assertEqual(plants_list_response.status_code, 200)
|
||||
returned_names = {item["name"] for item in plants_list_response.json()["data"]}
|
||||
self.assertTrue({"Tomato", "Cucumber", "Remove Plant"}.issubset(returned_names))
|
||||
|
||||
plant_catalog = self.create_plant_via_api(
|
||||
"Pepper",
|
||||
growth_stage="",
|
||||
icon="sprout",
|
||||
)
|
||||
Plant.objects.filter(pk=plant_catalog["id"]).update(growth_stage="", icon="")
|
||||
plant_names_response = self.client.get("/api/plants/names/")
|
||||
self.assertEqual(plant_names_response.status_code, 200)
|
||||
plant_names_payload = {
|
||||
item["name"]: item for item in plant_names_response.json()["data"]
|
||||
}
|
||||
self.assertEqual(plant_names_payload["Pepper"]["icon"], "leaf")
|
||||
self.assertEqual(
|
||||
plant_names_payload["Pepper"]["growth_stages"],
|
||||
["initial", "vegetative", "flowering", "fruiting", "maturity"],
|
||||
)
|
||||
pepper = Plant.objects.get(pk=plant_catalog["id"])
|
||||
self.assertEqual(
|
||||
pepper.growth_stage,
|
||||
"initial, vegetative, flowering, fruiting, maturity",
|
||||
icon="",
|
||||
)
|
||||
pepper = PlantCatalogSnapshot.objects.get(backend_plant_id=plant_catalog["id"])
|
||||
self.assertEqual(pepper.icon, "leaf")
|
||||
self.assertEqual(pepper.growth_stages, [])
|
||||
|
||||
plant_patch_response = self.client.patch(
|
||||
f"/api/plants/{tomato['id']}/",
|
||||
data={"growth_stage": "flowering", "watering": "daily"},
|
||||
format="json",
|
||||
updated_tomato = self.create_plant_via_api(
|
||||
"Tomato",
|
||||
id=tomato["id"],
|
||||
growth_stage="flowering",
|
||||
growth_stages=["flowering"],
|
||||
watering="daily",
|
||||
)
|
||||
self.assertEqual(plant_patch_response.status_code, 200)
|
||||
self.assertEqual(Plant.objects.get(pk=tomato["id"]).growth_stage, "flowering")
|
||||
|
||||
plant_put_response = self.client.put(
|
||||
f"/api/plants/{cucumber['id']}/",
|
||||
data={
|
||||
"name": "Cucumber",
|
||||
"light": "full sun",
|
||||
"watering": "every day",
|
||||
"soil": "sandy loam",
|
||||
"temperature": "18-30C",
|
||||
"growth_stage": "fruiting",
|
||||
"planting_season": "spring",
|
||||
"harvest_time": "70 days",
|
||||
"spacing": "40 cm",
|
||||
"fertilizer": "potassium rich",
|
||||
},
|
||||
format="json",
|
||||
self.assertEqual(updated_tomato["growth_stage"], "flowering")
|
||||
self.assertEqual(
|
||||
PlantCatalogSnapshot.objects.get(backend_plant_id=tomato["id"]).growth_stage,
|
||||
"flowering",
|
||||
)
|
||||
self.assertEqual(plant_put_response.status_code, 200)
|
||||
|
||||
with patch(
|
||||
"plant.views.fetch_plant_info_from_api",
|
||||
return_value={
|
||||
"name": "Tomato",
|
||||
"light": "full sun",
|
||||
"watering": "daily",
|
||||
"soil": "loamy",
|
||||
"temperature": "20-28C",
|
||||
"growth_stage": "flowering",
|
||||
"planting_season": "spring",
|
||||
"harvest_time": "90 days",
|
||||
"spacing": "50 cm",
|
||||
"fertilizer": "balanced NPK",
|
||||
},
|
||||
):
|
||||
plant_fetch_response = self.client.post(
|
||||
"/api/plants/fetch-info/",
|
||||
data={"name": "Tomato"},
|
||||
format="json",
|
||||
)
|
||||
self.assertEqual(plant_fetch_response.status_code, 200)
|
||||
self.assertEqual(plant_fetch_response.json()["data"]["name"], "Tomato")
|
||||
|
||||
plant_delete_response = self.client.delete(f"/api/plants/{removable_plant['id']}/")
|
||||
self.assertEqual(plant_delete_response.status_code, 200)
|
||||
self.assertFalse(Plant.objects.filter(pk=removable_plant["id"]).exists())
|
||||
updated_cucumber = self.create_plant_via_api(
|
||||
"Cucumber",
|
||||
id=cucumber["id"],
|
||||
light="full sun",
|
||||
watering="every day",
|
||||
soil="sandy loam",
|
||||
temperature="18-30C",
|
||||
growth_stage="fruiting",
|
||||
growth_stages=["fruiting"],
|
||||
planting_season="spring",
|
||||
harvest_time="70 days",
|
||||
spacing="40 cm",
|
||||
fertilizer="potassium rich",
|
||||
)
|
||||
self.assertEqual(updated_cucumber["watering"], "every day")
|
||||
|
||||
farm_uuid = uuid.uuid4()
|
||||
created_farm = self.upsert_farm_via_api(
|
||||
@@ -147,7 +102,7 @@ class FarmManagementJourneyTests(IntegrationAPITestCase):
|
||||
self.assertEqual(created_farm["farm_uuid"], str(farm_uuid))
|
||||
farm_record = SensorData.objects.get(farm_uuid=farm_uuid)
|
||||
self.assertCountEqual(
|
||||
list(farm_record.plants.values_list("id", flat=True)),
|
||||
list(farm_record.plant_assignments.values_list("plant__backend_plant_id", flat=True)),
|
||||
[tomato["id"], cucumber["id"]],
|
||||
)
|
||||
self.assertEqual(farm_record.irrigation_method_id, primary_method["id"])
|
||||
@@ -172,7 +127,10 @@ class FarmManagementJourneyTests(IntegrationAPITestCase):
|
||||
|
||||
farm_record.refresh_from_db()
|
||||
self.assertEqual(farm_record.irrigation_method_id, backup_method["id"])
|
||||
self.assertCountEqual(list(farm_record.plants.values_list("id", flat=True)), [tomato["id"]])
|
||||
self.assertCountEqual(
|
||||
list(farm_record.plant_assignments.values_list("plant__backend_plant_id", flat=True)),
|
||||
[tomato["id"]],
|
||||
)
|
||||
self.assertEqual(farm_record.sensor_payload["sensor-7-1"]["soil_temperature"], 23.4)
|
||||
self.assertEqual(farm_record.sensor_payload["sensor-7-1"]["soil_moisture"], 44.0)
|
||||
self.assertEqual(farm_record.sensor_payload["sensor-7-1"]["nitrogen"], 19.5)
|
||||
|
||||
@@ -11,6 +11,7 @@ from django.test import override_settings
|
||||
from crop_simulation.models import SimulationRun, SimulationScenario
|
||||
from farm_alerts.models import FarmAlertNotification
|
||||
from farm_data.models import SensorData
|
||||
from farm_data.services import assign_farm_plants_from_backend_ids
|
||||
from integration_tests.base import IntegrationAPITestCase, square_boundary
|
||||
|
||||
|
||||
@@ -79,7 +80,7 @@ class ReportingAndAiJourneyTests(IntegrationAPITestCase):
|
||||
}
|
||||
},
|
||||
)
|
||||
neighbor_sensor.plants.set([self.primary_plant["id"]])
|
||||
assign_farm_plants_from_backend_ids(neighbor_sensor, [self.primary_plant["id"]])
|
||||
|
||||
def test_reporting_endpoints_read_from_persisted_farm_context(self) -> None:
|
||||
soil_response = self.client.get(
|
||||
|
||||
Reference in New Issue
Block a user