Skip to content

Commit

Permalink
Merge pull request #2786 from bagerard/2784_validate_override_embedde…
Browse files Browse the repository at this point in the history
…d_doc

2784_validate_override_embedded_doc
  • Loading branch information
bagerard authored Dec 15, 2023
2 parents 8f865ba + b7617bb commit 7b41658
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Development
- (Fill this out as you fix issues and develop your features).
- Fix for uuidRepresentation not read when provided in URI #2741
- Add tests against MongoDB 6.0 and MongoDB 7.0 in the pipeline
- Fix validate() not being called when inheritance is used in EmbeddedDocument and validate is overriden #2784

Changes in 0.27.0
=================
Expand Down
2 changes: 1 addition & 1 deletion mongoengine/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ def validate(self, value, clean=True):
"Invalid embedded document instance provided to an "
"EmbeddedDocumentField"
)
self.document_type.validate(value, clean)
value.validate(clean=clean)

def lookup_member(self, member_name):
doc_and_subclasses = [self.document_type] + self.document_type.__subclasses__()
Expand Down
43 changes: 43 additions & 0 deletions tests/fields/test_embedded_document_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
Document,
EmbeddedDocument,
EmbeddedDocumentField,
EmbeddedDocumentListField,
GenericEmbeddedDocumentField,
IntField,
InvalidQueryError,
Expand Down Expand Up @@ -61,6 +62,48 @@ class MyFailingDoc(Document):
class MyFailingdoc2(Document):
emb = EmbeddedDocumentField("MyDoc")

def test_embedded_document_field_validate_subclass(self):
class BaseItem(EmbeddedDocument):
f = IntField()

meta = {"allow_inheritance": True}

def validate(self, clean=True):
if self.f == 0:
raise Exception("can not be 0")
return super().validate(clean)

class RealItem(BaseItem):
a = IntField()

def validate(self, clean=True):
if self.f == 1:
raise Exception("can not be 1")
return super().validate(clean)

class TopLevel(Document):
item = EmbeddedDocumentField(document_type=BaseItem)
items = EmbeddedDocumentListField(document_type=BaseItem)

passing_item = RealItem(f=2, a=0)
item = TopLevel(item=passing_item, items=[passing_item])
item.validate()

failing_item = RealItem(f=1, a=0)
item = TopLevel(item=failing_item)
with pytest.raises(Exception, match="can not be 1"):
item.validate()

item = TopLevel(items=[failing_item])
with pytest.raises(Exception, match="can not be 1"):
item.validate()

# verify that super calls the parent
failing_item_in_base = RealItem(f=0, a=0)
item = TopLevel(item=failing_item_in_base)
with pytest.raises(Exception, match="can not be 0"):
item.validate()

def test_query_embedded_document_attribute(self):
class AdminSettings(EmbeddedDocument):
foo1 = StringField()
Expand Down

0 comments on commit 7b41658

Please sign in to comment.