diff --git a/src/objects/api/fields.py b/src/objects/api/fields.py index 1e4a2da1..ab781ca0 100644 --- a/src/objects/api/fields.py +++ b/src/objects/api/fields.py @@ -1,8 +1,10 @@ -from django.core.exceptions import ObjectDoesNotExist +from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.utils.encoding import smart_str from django.utils.translation import gettext_lazy as _ from rest_framework import serializers +from vng_api_common.utils import get_uuid_from_path +from zgw_consumers.models import Service from objects.core.models import ObjectRecord @@ -42,7 +44,23 @@ def to_internal_value(self, data): try: return self.get_queryset().get_by_url(data) except ObjectDoesNotExist: - self.fail("does_not_exist", value=smart_str(data)) + # if service is configured, but objec_type is missing + # let's try to create an ObjectType + service = Service.get_service(data) + if not service: + self.fail("does_not_exist", value=smart_str(data)) + + uuid = get_uuid_from_path(data) + object_type = self.get_queryset().model(service=service, uuid=uuid) + + try: + object_type.clean() + except ValidationError: + self.fail("does_not_exist", value=smart_str(data)) + + object_type.save() + return object_type + except (TypeError, ValueError): self.fail("invalid") diff --git a/src/objects/tests/v2/test_auth.py b/src/objects/tests/v2/test_auth.py index 7e3c9d92..819bb877 100644 --- a/src/objects/tests/v2/test_auth.py +++ b/src/objects/tests/v2/test_auth.py @@ -4,6 +4,7 @@ from rest_framework import status from rest_framework.test import APITestCase +from objects.core.models import ObjectType from objects.core.tests.factories import ( ObjectFactory, ObjectRecordFactory, @@ -376,6 +377,52 @@ def test_create_superuser(self, m): self.assertEqual(response.status_code, status.HTTP_201_CREATED) + def test_create_superuser_no_service(self): + url = reverse("object-list") + data = { + "type": f"{OBJECT_TYPES_API}objecttypes/8be76be2-6567-4f5c-a17b-05217ab6d7b2", + "record": { + "typeVersion": 1, + "data": {"plantDate": "2020-04-12", "diameter": 30}, + "startAt": "2020-01-01", + }, + } + + response = self.client.post(url, data, **GEO_WRITE_KWARGS) + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + + @requests_mock.Mocker() + def test_create_superuser_no_object_type(self, m): + objecttype_url = ( + f"{OBJECT_TYPES_API}objecttypes/8be76be2-6567-4f5c-a17b-05217ab6d7b2" + ) + service = ServiceFactory.create(api_root=OBJECT_TYPES_API) + url = reverse("object-list") + data = { + "type": objecttype_url, + "record": { + "typeVersion": 1, + "data": {"plantDate": "2020-04-12", "diameter": 30}, + "startAt": "2020-01-01", + }, + } + # mocks + mock_service_oas_get(m, OBJECT_TYPES_API, "objecttypes") + m.get(objecttype_url, json=mock_objecttype(objecttype_url)) + m.get( + f"{objecttype_url}/versions/1", + json=mock_objecttype_version(objecttype_url), + ) + + response = self.client.post(url, data, **GEO_WRITE_KWARGS) + + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # check created object type + object_type = ObjectType.objects.get() + self.assertEqual(object_type.service, service) + self.assertEqual(object_type.url, objecttype_url) + @requests_mock.Mocker() def test_update_superuser(self, m): object_type = ObjectTypeFactory(service__api_root=OBJECT_TYPES_API)