UPDATE
This commit is contained in:
+117
-5
@@ -1,15 +1,17 @@
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import TestCase, override_settings
|
||||
from rest_framework.test import APIRequestFactory, force_authenticate
|
||||
from unittest.mock import patch
|
||||
|
||||
from access_control.models import AccessFeature, AccessRule, FarmAccessProfile, SubscriptionPlan
|
||||
from access_control.services import build_farm_access_profile
|
||||
from access_control.views import FarmAccessProfileView
|
||||
from crop_zoning.models import CropArea
|
||||
from external_api_adapter.adapter import AdapterResponse
|
||||
from farm_hub.models import FarmHub, FarmType, Product
|
||||
from farm_hub.serializers import FarmHubSerializer
|
||||
from farm_hub.seeds import seed_admin_farm
|
||||
from farm_hub.views import FarmListCreateView, FarmTypeListView, FarmTypeProductsView
|
||||
from farm_hub.views import FarmDetailView, FarmListCreateView, FarmTypeListView, FarmTypeProductsView
|
||||
from sensor_catalog.models import SensorCatalog
|
||||
|
||||
|
||||
@@ -33,6 +35,7 @@ AREA_GEOJSON = {
|
||||
@override_settings(
|
||||
USE_EXTERNAL_API_MOCK=True,
|
||||
CROP_ZONE_CHUNK_AREA_SQM=200000,
|
||||
FARM_DATA_API_KEY="farm-data-key",
|
||||
)
|
||||
class FarmListCreateViewTests(TestCase):
|
||||
def setUp(self):
|
||||
@@ -52,7 +55,9 @@ class FarmListCreateViewTests(TestCase):
|
||||
defaults={"supported_power_sources": ["solar", "direct_power"]},
|
||||
)
|
||||
|
||||
def test_create_farm_with_area_geojson_creates_crop_zoning_payload(self):
|
||||
@patch("farm_hub.services.external_api_request")
|
||||
def test_create_farm_with_area_geojson_creates_crop_zoning_payload(self, mock_external_api_request):
|
||||
mock_external_api_request.return_value = AdapterResponse(status_code=201, data={})
|
||||
physical_device_uuid = "33333333-3333-3333-3333-333333333333"
|
||||
request = self.factory.post(
|
||||
"/api/farm-hub/",
|
||||
@@ -94,8 +99,26 @@ class FarmListCreateViewTests(TestCase):
|
||||
CropArea.objects.get().zone_count,
|
||||
)
|
||||
self.assertEqual(CropArea.objects.count(), 1)
|
||||
mock_external_api_request.assert_called_once_with(
|
||||
"ai",
|
||||
"/api/farm-data/",
|
||||
method="POST",
|
||||
payload={
|
||||
"farm_uuid": response.data["data"]["farm_uuid"],
|
||||
"farm_boundary": AREA_GEOJSON["geometry"],
|
||||
"plant_ids": [self.wheat.id],
|
||||
},
|
||||
headers={
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"X-API-Key": "farm-data-key",
|
||||
"Authorization": "Api-Key farm-data-key",
|
||||
},
|
||||
)
|
||||
|
||||
def test_create_farm_ignores_client_farm_uuid_and_generates_new_one(self):
|
||||
@patch("farm_hub.services.external_api_request")
|
||||
def test_create_farm_ignores_client_farm_uuid_and_generates_new_one(self, mock_external_api_request):
|
||||
mock_external_api_request.return_value = AdapterResponse(status_code=201, data={})
|
||||
request = self.factory.post(
|
||||
"/api/farm-hub/",
|
||||
{
|
||||
@@ -114,7 +137,9 @@ class FarmListCreateViewTests(TestCase):
|
||||
self.assertNotEqual(response.data["data"]["farm_uuid"], "11111111-1111-1111-1111-111111111111")
|
||||
self.assertIsNotNone(response.data["data"]["area_uuid"])
|
||||
|
||||
def test_create_farm_rejects_unknown_sensor_catalog_uuid(self):
|
||||
@patch("farm_hub.services.external_api_request")
|
||||
def test_create_farm_rejects_unknown_sensor_catalog_uuid(self, mock_external_api_request):
|
||||
mock_external_api_request.return_value = AdapterResponse(status_code=201, data={})
|
||||
request = self.factory.post(
|
||||
"/api/farm-hub/",
|
||||
{
|
||||
@@ -137,7 +162,9 @@ class FarmListCreateViewTests(TestCase):
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertIn("sensor_catalog_uuid", response.data["sensors"][0])
|
||||
|
||||
def test_create_farm_defaults_to_gold_plan_when_not_provided(self):
|
||||
@patch("farm_hub.services.external_api_request")
|
||||
def test_create_farm_defaults_to_gold_plan_when_not_provided(self, mock_external_api_request):
|
||||
mock_external_api_request.return_value = AdapterResponse(status_code=201, data={})
|
||||
request = self.factory.post(
|
||||
"/api/farm-hub/",
|
||||
{
|
||||
@@ -154,6 +181,91 @@ class FarmListCreateViewTests(TestCase):
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertEqual(response.data["data"]["subscription_plan"]["code"], "gold")
|
||||
|
||||
def test_create_farm_rejects_non_object_sensor_payload(self):
|
||||
request = self.factory.post(
|
||||
"/api/farm-hub/",
|
||||
{
|
||||
"name": "farm-invalid-sensor-payload",
|
||||
"farm_type_uuid": str(self.farm_type.uuid),
|
||||
"product_uuids": [str(self.wheat.uuid)],
|
||||
"sensor_payload": ["invalid"],
|
||||
},
|
||||
format="json",
|
||||
)
|
||||
force_authenticate(request, user=self.user)
|
||||
|
||||
response = FarmListCreateView.as_view()(request)
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertEqual(response.data["sensor_payload"], ["`sensor_payload` must be an object."])
|
||||
|
||||
@patch("farm_hub.services.external_api_request")
|
||||
def test_patch_farm_forwards_farm_data_fields(self, mock_external_api_request):
|
||||
mock_external_api_request.return_value = AdapterResponse(status_code=201, data={})
|
||||
farm = FarmHub.objects.create(
|
||||
owner=self.user,
|
||||
farm_type=self.farm_type,
|
||||
subscription_plan=self.plan,
|
||||
name="patch-target",
|
||||
)
|
||||
farm.products.add(self.wheat)
|
||||
|
||||
request = self.factory.patch(
|
||||
f"/api/farm-hub/{farm.farm_uuid}/",
|
||||
{
|
||||
"farm_boundary": {
|
||||
"corners": [
|
||||
{"lat": 35.70, "lon": 51.39},
|
||||
{"lat": 35.70, "lon": 51.41},
|
||||
{"lat": 35.72, "lon": 51.41},
|
||||
{"lat": 35.72, "lon": 51.39},
|
||||
]
|
||||
},
|
||||
"sensor_payload": {"soil_moisture": 45.2},
|
||||
"irrigation_method_id": 3,
|
||||
},
|
||||
format="json",
|
||||
)
|
||||
force_authenticate(request, user=self.user)
|
||||
|
||||
response = FarmDetailView.as_view()(request, farm_uuid=farm.farm_uuid)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
farm.refresh_from_db()
|
||||
self.assertIsNotNone(farm.current_crop_area)
|
||||
mock_external_api_request.assert_called_once_with(
|
||||
"ai",
|
||||
"/api/farm-data/",
|
||||
method="POST",
|
||||
payload={
|
||||
"farm_uuid": str(farm.farm_uuid),
|
||||
"farm_boundary": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[51.39, 35.7],
|
||||
[51.41, 35.7],
|
||||
[51.41, 35.72],
|
||||
[51.39, 35.72],
|
||||
[51.39, 35.7],
|
||||
]
|
||||
],
|
||||
},
|
||||
"sensor_key": "sensor-7-1",
|
||||
"sensor_payload": {
|
||||
"sensor-7-1": {"soil_moisture": 45.2},
|
||||
},
|
||||
"plant_ids": [self.wheat.id],
|
||||
"irrigation_method_id": 3,
|
||||
},
|
||||
headers={
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"X-API-Key": "farm-data-key",
|
||||
"Authorization": "Api-Key farm-data-key",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@override_settings(
|
||||
USE_EXTERNAL_API_MOCK=True,
|
||||
|
||||
Reference in New Issue
Block a user