This commit is contained in:
2026-05-10 22:49:07 +03:30
parent 2d1f7da89e
commit 2a6321a263
15 changed files with 2667 additions and 162 deletions
+6
View File
@@ -0,0 +1,6 @@
from django.urls import include, path
urlpatterns = [
path("api/location-data/", include("location_data.urls")),
]
@@ -0,0 +1,98 @@
from __future__ import annotations
from datetime import date
from types import SimpleNamespace
from unittest.mock import patch
import uuid
from django.test import override_settings
from farm_data.models import SensorData
from integration_tests.base import IntegrationAPITestCase
from location_data.models import AnalysisGridCell, AnalysisGridObservation, RemoteSensingRun
@override_settings(ROOT_URLCONF="integration_tests.location_data_urls")
class RemoteSensingApiFlowTests(IntegrationAPITestCase):
def setUp(self) -> None:
super().setUp()
self.farm_uuid = uuid.UUID("11111111-1111-1111-1111-111111111111")
self.farm = SensorData.objects.create(
farm_uuid=self.farm_uuid,
center_location=self.primary_location,
sensor_payload={},
)
self.temporal_end = date(2026, 5, 9)
self.temporal_start = date(2026, 4, 9)
@patch("location_data.views.timezone.localdate", return_value=date(2026, 5, 10))
@patch("location_data.views.run_remote_sensing_analysis_task.delay")
def test_remote_sensing_post_and_status_flow(self, mock_delay, _mock_localdate) -> None:
task_id = uuid.UUID("9e7f3aaa-6d34-4428-a196-478af7a2d7f6")
mock_delay.return_value = SimpleNamespace(id=str(task_id))
enqueue_response = self.client.post(
"/api/location-data/remote-sensing/",
data={
"farm_uuid": str(self.farm_uuid),
"force_refresh": False,
},
format="json",
)
self.assertEqual(enqueue_response.status_code, 202, enqueue_response.json())
enqueue_payload = enqueue_response.json()["data"]
self.assertEqual(enqueue_payload["status"], "processing")
self.assertEqual(enqueue_payload["source"], "processing")
self.assertEqual(enqueue_payload["task_id"], str(task_id))
self.assertEqual(enqueue_payload["temporal_extent"]["start_date"], "2026-04-09")
self.assertEqual(enqueue_payload["temporal_extent"]["end_date"], "2026-05-09")
run = RemoteSensingRun.objects.get(pk=enqueue_payload["run"]["id"])
self.assertEqual(run.status, RemoteSensingRun.STATUS_PENDING)
self.assertEqual(run.temporal_start, self.temporal_start)
self.assertEqual(run.temporal_end, self.temporal_end)
self.assertEqual(run.metadata["task_id"], str(task_id))
mock_delay.assert_called_once()
status_response = self.client.get(f"/api/location-data/remote-sensing/runs/{task_id}/status/")
self.assertEqual(status_response.status_code, 200, status_response.json())
status_payload = status_response.json()["data"]
self.assertEqual(status_payload["status"], "pending")
self.assertEqual(status_payload["run"]["pipeline_status"], "pending")
cell = AnalysisGridCell.objects.create(
soil_location=self.primary_location,
block_code="",
cell_code="cell-1",
chunk_size_sqm=900,
geometry=self.primary_boundary,
centroid_lat=f"{self.primary_lat:.6f}",
centroid_lon=f"{self.primary_lon:.6f}",
)
AnalysisGridObservation.objects.create(
cell=cell,
run=run,
temporal_start=self.temporal_start,
temporal_end=self.temporal_end,
ndvi=0.61,
ndwi=0.22,
lst_c=24.5,
soil_vv=0.13,
soil_vv_db=-8.860566,
dem_m=1550.0,
slope_deg=4.2,
metadata={"backend_name": "openeo"},
)
run.status = RemoteSensingRun.STATUS_SUCCESS
run.metadata = {**(run.metadata or {}), "stage": "completed", "selected_features": ["ndvi", "ndwi"]}
run.save(update_fields=["status", "metadata", "updated_at"])
completed_response = self.client.get(f"/api/location-data/remote-sensing/runs/{task_id}/status/")
self.assertEqual(completed_response.status_code, 200, completed_response.json())
completed_payload = completed_response.json()["data"]
self.assertEqual(completed_payload["status"], "completed")
self.assertEqual(completed_payload["summary"]["cell_count"], 1)
self.assertEqual(completed_payload["summary"]["ndvi_mean"], 0.61)
self.assertEqual(len(completed_payload["cells"]), 1)
self.assertEqual(completed_payload["cells"][0]["cell_code"], "cell-1")