Skip to content

Commit

Permalink
Merge pull request #469 from maykinmedia/issue/466-merge-patch
Browse files Browse the repository at this point in the history
fix validation for merge PATCH
  • Loading branch information
annashamray authored Nov 7, 2024
2 parents 45fe648 + ab75c7d commit a584d94
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/objects/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ def update(self, instance, validated_data):
# version should be set
if "version" not in validated_data:
validated_data["version"] = instance.version
# start_at should be set
if "start_at" not in validated_data:
validated_data["start_at"] = instance.start_at

if self.partial and "data" in validated_data:
# Apply JSON Merge Patch for record data
validated_data["data"] = merge_patch(instance.data, validated_data["data"])
Expand Down
5 changes: 4 additions & 1 deletion src/objects/api/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from objects.core.utils import check_objecttype

from .constants import Operators
from .utils import string_to_value
from .utils import merge_patch, string_to_value


class JsonSchemaValidator:
Expand All @@ -34,6 +34,9 @@ def __call__(self, attrs, serializer):
)
version = attrs.get("version") if "version" in attrs else instance.version
data = attrs.get("data", {}) if "data" in attrs else instance.data
if serializer.partial and "data" in attrs:
# Apply JSON Merge Patch for record data
data = merge_patch(instance.data, attrs["data"])

if not object_type or not version:
return
Expand Down
39 changes: 39 additions & 0 deletions src/objects/tests/v2/test_object_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,45 @@ def test_patch_object_record(self, m):
self.assertEqual(initial_record.corrected, current_record)
self.assertEqual(initial_record.end_at, date(2020, 1, 1))

def test_patch_validates_merged_object_rather_than_partial_object(self, m):
mock_service_oas_get(m, OBJECT_TYPES_API, "objecttypes")
m.get(
f"{self.object_type.url}/versions/1",
json=mock_objecttype_version(self.object_type.url),
)

initial_record = ObjectRecordFactory.create(
version=1,
object__object_type=self.object_type,
start_at=date.today(),
data={"name": "Name", "diameter": 20},
)

url = reverse("object-detail", args=[initial_record.object.uuid])
data = {
"record": {
"data": {
# Note the required fields are missing, and that should be fine:
# the _merged_ object should be valid according to the schema, not
# the partial.
"plantDate": "2024-10-09"
},
},
}

response = self.client.patch(url, data, **GEO_WRITE_KWARGS)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(
response.json()["record"]["data"],
{"plantDate": "2024-10-09", "diameter": 20, "name": "Name"},
)

last_record = initial_record.object.last_record
self.assertEqual(
last_record.data,
{"plantDate": "2024-10-09", "diameter": 20, "name": "Name"},
)

def test_delete_object(self, m):
record = ObjectRecordFactory.create(object__object_type=self.object_type)
object = record.object
Expand Down

0 comments on commit a584d94

Please sign in to comment.