diff --git a/CHANGES.rst b/CHANGES.rst index 26e63dc4d..85516d368 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -10,6 +10,7 @@ Unreleased Fixed ~~~~~ +- Updating a field with a nullable data relation fails when value is null (`#1159`_) - ``cerberus.schema.SchemaError`` when ``VALIDATE_FILTERS = True``. (`#1154`_) - Serializers fails when array of types is in schema. (`#1112`_) - Replace the broken ``make audit`` shortcut with ``make check``, add the @@ -52,6 +53,7 @@ Docs .. _`#1156`: https://github.com/pyeve/eve/issues/1156 .. _`#1157`: https://github.com/pyeve/eve/issues/1157 .. _`#1158`: https://github.com/pyeve/eve/issues/1158 +.. _`#1159`: https://github.com/pyeve/eve/issues/1159 Version 0.8 ----------- diff --git a/eve/io/mongo/validation.py b/eve/io/mongo/validation.py index 6f798b8ec..417ff4646 100644 --- a/eve/io/mongo/validation.py +++ b/eve/io/mongo/validation.py @@ -128,6 +128,9 @@ def _validate_data_relation(self, data_relation, field, value): 'embeddable': {'type': 'boolean', 'default': False}, 'version': {'type': 'boolean', 'default': False} }} """ + if not value and self.schema[field].get("nullable"): + return + if "version" in data_relation and data_relation["version"] is True: value_field = data_relation["field"] version_field = app.config["VERSION"] diff --git a/eve/tests/methods/post.py b/eve/tests/methods/post.py index da14beacb..201906dd7 100644 --- a/eve/tests/methods/post.py +++ b/eve/tests/methods/post.py @@ -888,6 +888,31 @@ def test_post_custom_json_content_type(self): ) self.assert201(status) + def test_post_updating_a_document_with_nullable_data_relation_does_not_fail(self): + # See #1159. + del (self.domain["contacts"]["schema"]["ref"]["required"]) + + employee = { + "employer": { + "type": "objectid", + "nullable": True, + "data_relation": {"resource": self.known_resource}, + } + } + self.app.register_resource("employee", {"schema": employee}) + + data = {"employer": None} + r, s = self.post("employee", data=data) + self.assert201(s) + + employee["employer"]["nullable"] = False + r, s = self.post("employee", data=data) + self.assert422(s) + + del (employee["employer"]["nullable"]) + r, s = self.post("employee", data=data) + self.assert422(s) + def perform_post(self, data, valid_items=[0]): r, status = self.post(self.known_resource_url, data=data) self.assert201(status)