Source code for geonode.harvesting.tests.test_api_serializers

from unittest import mock
from urllib.parse import urlparse

from django.contrib.auth import get_user_model
from django.utils.timezone import now
from rest_framework.exceptions import ValidationError
from rest_framework.test import (
    APIRequestFactory,
)

from geonode.tests.base import GeoNodeBaseTestSupport

from .. import models
from ..api import serializers


[docs] _REQUEST_FACTORY = APIRequestFactory()
[docs] class BriefHarvesterSerializerTestCase(GeoNodeBaseTestSupport):
[docs] remote_url = "test.com"
[docs] name = "This is geonode harvester"
[docs] user = get_user_model().objects.get(username="AnonymousUser")
[docs] harvester_type = "geonode.harvesting.harvesters.geonodeharvester.GeonodeUnifiedHarvesterWorker"
@classmethod
[docs] def setUpTestData(cls): cls.harvester = models.Harvester.objects.create( remote_url=cls.remote_url, name=cls.name, default_owner=cls.user, harvester_type=cls.harvester_type )
[docs] def test_serializer_is_able_to_serialize_model_instance(self): api_endpoint = "/api/v2/harvesters/" request = _REQUEST_FACTORY.get(api_endpoint) serializer = serializers.BriefHarvesterSerializer(self.harvester, context={"request": request}) serialized = serializer.data self.assertEqual(serialized["remote_url"], self.harvester.remote_url) self.assertEqual(serialized["name"], self.harvester.name) self.assertEqual(urlparse(serialized["links"]["self"]).path, f"{api_endpoint}{self.harvester.pk}/") self.assertIsNotNone(serialized["links"]["harvestable_resources"])
[docs] class HarvesterSerializerTestCase(GeoNodeBaseTestSupport):
[docs] remote_url = "test.com"
[docs] name = "This is geonode harvester"
[docs] user = get_user_model().objects.get(username="AnonymousUser")
[docs] harvester_type = "geonode.harvesting.harvesters.geonodeharvester.GeonodeUnifiedHarvesterWorker"
@classmethod
[docs] def setUpTestData(cls): cls.harvester = models.Harvester.objects.create( remote_url=cls.remote_url, name=cls.name, default_owner=cls.user, harvester_type=cls.harvester_type )
[docs] def test_serializer_is_able_to_serialize_model_instance(self): api_endpoint = "/api/v2/harvesters/" request = _REQUEST_FACTORY.get(api_endpoint) serializer = serializers.BriefHarvesterSerializer(self.harvester, context={"request": request}) serialized = serializer.data self.assertEqual(serialized["remote_url"], self.harvester.remote_url) self.assertEqual(serialized["name"], self.harvester.name) self.assertEqual(urlparse(serialized["links"]["self"]).path, f"{api_endpoint}{self.harvester.pk}/") self.assertIsNotNone(serialized["links"]["harvestable_resources"])
@mock.patch("geonode.harvesting.models.validate_worker_configuration")
[docs] def test_validate_also_validates_worker_specific_config(self, mock_validate_config): input_data = { "name": "phony", "remote_url": "http://fake.com", "user": 1, "harvester_type": "geonode.harvesting.harvesters.geonodeharvester.GeonodeUnifiedHarvesterWorker", "harvester_type_specific_configuration": {"something": "fake config"}, } request = _REQUEST_FACTORY.post("/api/v2/harvesters/") request.user = self.user serializer = serializers.HarvesterSerializer(data=input_data, context={"request": request}) serializer.is_valid(raise_exception=True) mock_validate_config.assert_called()
[docs] def test_validate_does_not_allow_changing_status_and_worker_specific_config(self): input_data = { "name": "phony", "remote_url": "http://fake.com", "user": 1, "harvester_type_specific_configuration": {"something": "fake config"}, "status": "updating-harvestable-resources", } request = _REQUEST_FACTORY.post("/api/v2/harvesters/") request.user = self.user serializer = serializers.HarvesterSerializer(data=input_data, context={"request": request}) with self.assertRaises(ValidationError): serializer.is_valid(raise_exception=True)
[docs] def test_create_does_not_allow_setting_custom_status(self): input_data = { "name": "phony", "remote_url": "http://fake.com", "user": 1, "status": "updating-harvestable-resources", } request = _REQUEST_FACTORY.post("/api/v2/harvesters/") request.user = self.user serializer = serializers.HarvesterSerializer(data=input_data, context={"request": request}) serializer.is_valid(raise_exception=True) with self.assertRaises(ValidationError): serializer.save()
[docs] def test_create(self): input_data = { "name": "phony", "remote_url": "http://fake.com", "user": 1, } request = _REQUEST_FACTORY.post("/api/v2/harvesters/") request.user = self.user serializer = serializers.HarvesterSerializer(data=input_data, context={"request": request}) serializer.is_valid(raise_exception=True) harvester = serializer.save() self.assertEqual(harvester.name, input_data["name"])
[docs] def test_update_errors_out_if_current_status_is_not_ready(self): request = _REQUEST_FACTORY.patch(f"/api/v2/harvesters/{self.harvester.pk}") self.assertEqual(self.harvester.status, models.Harvester.STATUS_READY) serializer = serializers.HarvesterSerializer( self.harvester, data={"status": "updating-harvestable-resources"}, context={"request": request}, partial=True, ) serializer.is_valid(raise_exception=True) self.harvester.status = models.Harvester.STATUS_UPDATING_HARVESTABLE_RESOURCES self.harvester.save() with self.assertRaises(ValidationError): serializer.save()
[docs] def test_update_errors_out_when_client_tries_to_set_status_ready(self): request = _REQUEST_FACTORY.patch(f"/api/v2/harvesters/{self.harvester.pk}") self.assertEqual(self.harvester.status, models.Harvester.STATUS_READY) serializer = serializers.HarvesterSerializer( self.harvester, data={"status": models.Harvester.STATUS_READY}, context={"request": request}, partial=True, ) serializer.is_valid(raise_exception=True) with self.assertRaises(ValidationError): serializer.save()
@mock.patch("geonode.harvesting.api.serializers.tasks")
[docs] def test_update_calls_update_harvestable_resources_task(self, mock_tasks): request = _REQUEST_FACTORY.patch(f"/api/v2/harvesters/{self.harvester.pk}") self.assertEqual(self.harvester.status, models.Harvester.STATUS_READY) serializer = serializers.HarvesterSerializer( self.harvester, data={"status": models.Harvester.STATUS_UPDATING_HARVESTABLE_RESOURCES}, context={"request": request}, partial=True, ) serializer.is_valid(raise_exception=True) serializer.save() mock_tasks.update_harvestable_resources.signature.assert_called() mock_tasks.update_harvestable_resources.signature.return_value.apply_async.assert_called()
@mock.patch("geonode.harvesting.api.serializers.tasks")
[docs] def test_update_calls_harvesting_dispatcher_task(self, mock_tasks): request = _REQUEST_FACTORY.patch(f"/api/v2/harvesters/{self.harvester.pk}") self.assertEqual(self.harvester.status, models.Harvester.STATUS_READY) serializer = serializers.HarvesterSerializer( self.harvester, data={"status": models.Harvester.STATUS_PERFORMING_HARVESTING}, context={"request": request}, partial=True, ) serializer.is_valid(raise_exception=True) serializer.save() called_args = mock_tasks.harvesting_dispatcher.signature.call_args_list[0].kwargs["args"] called_session_pk = called_args[0] session = models.AsynchronousHarvestingSession.objects.get(pk=called_session_pk) self.assertEqual(session.harvester.pk, self.harvester.pk) mock_tasks.harvesting_dispatcher.signature.return_value.apply_async.assert_called()
@mock.patch("geonode.harvesting.api.serializers.tasks")
[docs] def test_update_calls_update_harvester_availability_task(self, mock_tasks): request = _REQUEST_FACTORY.patch(f"/api/v2/harvesters/{self.harvester.pk}") self.assertEqual(self.harvester.status, models.Harvester.STATUS_READY) serializer = serializers.HarvesterSerializer( self.harvester, data={"status": models.Harvester.STATUS_CHECKING_AVAILABILITY}, context={"request": request}, partial=True, ) serializer.is_valid(raise_exception=True) serializer.save() mock_tasks.check_harvester_available.signature.assert_called_with(args=(self.harvester.pk,)) mock_tasks.check_harvester_available.signature.return_value.apply_async.assert_called()
@mock.patch("geonode.harvesting.api.serializers.tasks")
[docs] def test_update_updates_harvestable_resources_whenever_worker_config_changes(self, mock_tasks): request = _REQUEST_FACTORY.patch(f"/api/v2/harvesters/{self.harvester.pk}") self.assertEqual(self.harvester.status, models.Harvester.STATUS_READY) self.assertEqual(len(self.harvester.harvester_type_specific_configuration), 0) serializer = serializers.HarvesterSerializer( self.harvester, data={"harvester_type_specific_configuration": {"harvest_datasets": False}}, context={"request": request}, partial=True, ) serializer.is_valid(raise_exception=True) serializer.save() mock_tasks.update_harvestable_resources.signature.assert_called_with(args=(self.harvester.pk,)) mock_tasks.update_harvestable_resources.signature.return_value.apply_async.assert_called()
[docs] class BriefAsynchronousHarvestingSessionSerializerTestCase(GeoNodeBaseTestSupport):
[docs] harvester: models.Harvester
@classmethod
[docs] def setUpTestData(cls): remote_url = "test.com" name = "This is geonode harvester" user = get_user_model().objects.get(username="AnonymousUser") harvester_type = "geonode.harvesting.harvesters.geonodeharvester.GeonodeUnifiedHarvesterWorker" cls.harvester = models.Harvester.objects.create( remote_url=remote_url, name=name, default_owner=user, harvester_type=harvester_type ) cls.harvesting_session = models.AsynchronousHarvestingSession.objects.create( harvester=cls.harvester, session_type=models.AsynchronousHarvestingSession.TYPE_HARVESTING )
[docs] def test_serializer_is_able_to_serialize_model_instance(self): api_endpoint = "/api/v2/harvesting-sessions/" request = _REQUEST_FACTORY.get(api_endpoint) serializer = serializers.BriefAsynchronousHarvestingSessionSerializer( self.harvesting_session, context={"request": request} ) serialized = serializer.data self.assertIsNotNone(serialized["started"])
[docs] class HarvestableResourceSerializerTestCase(GeoNodeBaseTestSupport):
[docs] unique_identifier = "some-identifier"
[docs] title = "something"
[docs] remote_resource_type = "documents"
[docs] default_should_be_harvested = False
@classmethod
[docs] def setUpTestData(cls): cls.harvester = models.Harvester.objects.create( remote_url="test.com", name="This is geonode harvester", default_owner=get_user_model().objects.get(username="AnonymousUser"), harvester_type="geonode.harvesting.harvesters.geonodeharvester.GeonodeUnifiedHarvesterWorker", ) cls.harvestable_resource = models.HarvestableResource.objects.create( unique_identifier=cls.unique_identifier, title=cls.title, harvester=cls.harvester, should_be_harvested=cls.default_should_be_harvested, remote_resource_type=cls.remote_resource_type, last_refreshed=now(), )
[docs] def test_serializer_is_able_to_serialize_model_instance(self): api_endpoint = f"/api/v2/harvesters/{self.harvester.id}/harvestable-resources/" request = _REQUEST_FACTORY.get(api_endpoint) serializer = serializers.HarvestableResourceSerializer(self.harvestable_resource, context={"request": request}) serialized = serializer.data self.assertIsNotNone(serialized["unique_identifier"], self.unique_identifier) self.assertIsNotNone(serialized["title"], self.title) self.assertIsNotNone(serialized["remote_resource_type"], self.remote_resource_type) self.assertIsNotNone(serialized["should_be_harvested"], self.default_should_be_harvested)
[docs] def test_serializer_is_allowed_to_change_instance_should_be_harvested_attribute(self): self.assertEqual(self.harvestable_resource.should_be_harvested, self.default_should_be_harvested) api_endpoint = f"/api/v2/harvesters/{self.harvester.id}/harvestable-resources/" request = _REQUEST_FACTORY.patch(api_endpoint) serializer = serializers.HarvestableResourceSerializer( data={ "unique_identifier": self.unique_identifier, "should_be_harvested": not self.default_should_be_harvested, }, context={ "request": request, "harvester": self.harvester, }, ) serializer.is_valid(raise_exception=True) print(f"validated_data: {serializer.validated_data}") serializer.save() self.harvestable_resource.refresh_from_db() self.assertEqual(self.harvestable_resource.should_be_harvested, not self.default_should_be_harvested)