93 lines
3.5 KiB
Python
93 lines
3.5 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from django.apps import apps
|
||
|
|
from django.test import SimpleTestCase, TestCase, override_settings
|
||
|
|
|
||
|
|
from location_data.models import SoilDepthData, SoilLocation
|
||
|
|
from location_data.soil_adapters import (
|
||
|
|
DEPTHS,
|
||
|
|
MockSoilDataAdapter,
|
||
|
|
SoilGridsAdapter,
|
||
|
|
)
|
||
|
|
from location_data.tasks import fetch_soil_data_for_coordinates
|
||
|
|
|
||
|
|
|
||
|
|
class MockSoilDataAdapterTests(SimpleTestCase):
|
||
|
|
def setUp(self):
|
||
|
|
self.adapter = MockSoilDataAdapter(delay_seconds=0)
|
||
|
|
|
||
|
|
def test_same_coordinate_returns_same_values(self):
|
||
|
|
first = self.adapter.fetch_depth_fields(51.4, 35.71, "0-5cm")
|
||
|
|
second = self.adapter.fetch_depth_fields(51.4, 35.71, "0-5cm")
|
||
|
|
|
||
|
|
self.assertEqual(first, second)
|
||
|
|
|
||
|
|
def test_nearby_coordinates_produce_nearby_values(self):
|
||
|
|
first = self.adapter.fetch_depth_fields(51.4, 35.71, "0-5cm")
|
||
|
|
second = self.adapter.fetch_depth_fields(51.405, 35.715, "0-5cm")
|
||
|
|
|
||
|
|
self.assertLess(abs(first["sand"] - second["sand"]), 4.5)
|
||
|
|
self.assertLess(abs(first["clay"] - second["clay"]), 4.5)
|
||
|
|
self.assertLess(abs(first["phh2o"] - second["phh2o"]), 0.35)
|
||
|
|
self.assertLess(abs(first["wv1500"] - second["wv1500"]), 0.03)
|
||
|
|
|
||
|
|
def test_depth_profiles_follow_expected_trend(self):
|
||
|
|
shallow = self.adapter.fetch_depth_fields(51.4, 35.71, "0-5cm")
|
||
|
|
medium = self.adapter.fetch_depth_fields(51.4, 35.71, "5-15cm")
|
||
|
|
deep = self.adapter.fetch_depth_fields(51.4, 35.71, "15-30cm")
|
||
|
|
|
||
|
|
self.assertGreaterEqual(deep["bdod"], medium["bdod"])
|
||
|
|
self.assertGreaterEqual(medium["bdod"], shallow["bdod"])
|
||
|
|
self.assertLessEqual(deep["soc"], medium["soc"])
|
||
|
|
self.assertLessEqual(medium["soc"], shallow["soc"])
|
||
|
|
|
||
|
|
|
||
|
|
class SoilDataAdapterSelectionTests(SimpleTestCase):
|
||
|
|
def tearDown(self):
|
||
|
|
apps.get_app_config("location_data").__dict__.pop("soil_data_adapter", None)
|
||
|
|
|
||
|
|
@override_settings(SOIL_DATA_PROVIDER="mock", SOIL_MOCK_DELAY_SECONDS=0)
|
||
|
|
def test_app_config_returns_mock_adapter(self):
|
||
|
|
config = apps.get_app_config("location_data")
|
||
|
|
config.__dict__.pop("soil_data_adapter", None)
|
||
|
|
|
||
|
|
adapter = config.get_soil_data_adapter()
|
||
|
|
|
||
|
|
self.assertIsInstance(adapter, MockSoilDataAdapter)
|
||
|
|
|
||
|
|
@override_settings(SOIL_DATA_PROVIDER="soilgrids", SOILGRIDS_TIMEOUT_SECONDS=12)
|
||
|
|
def test_app_config_returns_live_adapter(self):
|
||
|
|
config = apps.get_app_config("location_data")
|
||
|
|
config.__dict__.pop("soil_data_adapter", None)
|
||
|
|
|
||
|
|
adapter = config.get_soil_data_adapter()
|
||
|
|
|
||
|
|
self.assertIsInstance(adapter, SoilGridsAdapter)
|
||
|
|
self.assertEqual(adapter.timeout, 12)
|
||
|
|
|
||
|
|
|
||
|
|
@override_settings(SOIL_DATA_PROVIDER="mock", SOIL_MOCK_DELAY_SECONDS=0)
|
||
|
|
class SoilDataFetchTests(TestCase):
|
||
|
|
def test_fetch_soil_data_for_coordinates_persists_three_depths(self):
|
||
|
|
result = fetch_soil_data_for_coordinates(latitude=35.71, longitude=51.4)
|
||
|
|
|
||
|
|
self.assertEqual(result["status"], "completed")
|
||
|
|
self.assertEqual(result["depths"], DEPTHS)
|
||
|
|
|
||
|
|
location = SoilLocation.objects.get(latitude="35.710000", longitude="51.400000")
|
||
|
|
self.assertEqual(location.depths.count(), 3)
|
||
|
|
self.assertTrue(location.is_complete)
|
||
|
|
self.assertCountEqual(
|
||
|
|
list(location.depths.values_list("depth_label", flat=True)),
|
||
|
|
DEPTHS,
|
||
|
|
)
|
||
|
|
self.assertTrue(
|
||
|
|
SoilDepthData.objects.filter(
|
||
|
|
soil_location=location,
|
||
|
|
depth_label="0-5cm",
|
||
|
|
sand__isnull=False,
|
||
|
|
clay__isnull=False,
|
||
|
|
wv1500__isnull=False,
|
||
|
|
).exists()
|
||
|
|
)
|