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() )