# -*- coding: utf-8 -*- import unittest from datetime import datetime from mongoengine import * from tests.utils import MongoDBTestCase class TestValidatorError(MongoDBTestCase): def test_to_dict(self): """Ensure a ValidationError handles error to_dict correctly. """ error = ValidationError("root") self.assertEqual(error.to_dict(), {}) # 1st level error schema error.errors = {"1st": ValidationError("bad 1st")} self.assertIn("1st", error.to_dict()) self.assertEqual(error.to_dict()["1st"], "bad 1st") # 2nd level error schema error.errors = { "1st": ValidationError( "bad 1st", errors={"2nd": ValidationError("bad 2nd")} ) } self.assertIn("1st", error.to_dict()) self.assertIsInstance(error.to_dict()["1st"], dict) self.assertIn("2nd", error.to_dict()["1st"]) self.assertEqual(error.to_dict()["1st"]["2nd"], "bad 2nd") # moar levels error.errors = { "1st": ValidationError( "bad 1st", errors={ "2nd": ValidationError( "bad 2nd", errors={ "3rd": ValidationError( "bad 3rd", errors={"4th": ValidationError("Inception")} ) }, ) }, ) } self.assertIn("1st", error.to_dict()) self.assertIn("2nd", error.to_dict()["1st"]) self.assertIn("3rd", error.to_dict()["1st"]["2nd"]) self.assertIn("4th", error.to_dict()["1st"]["2nd"]["3rd"]) self.assertEqual(error.to_dict()["1st"]["2nd"]["3rd"]["4th"], "Inception") self.assertEqual(error.message, "root(2nd.3rd.4th.Inception: ['1st'])") def test_model_validation(self): class User(Document): username = StringField(primary_key=True) name = StringField(required=True) try: User().validate() except ValidationError as e: self.assertIn("User:None", e.message) self.assertEqual( e.to_dict(), {"username": "Field is required", "name": "Field is required"}, ) user = User(username="RossC0", name="Ross").save() user.name = None try: user.save() except ValidationError as e: self.assertIn("User:RossC0", e.message) self.assertEqual(e.to_dict(), {"name": "Field is required"}) def test_fields_rewrite(self): class BasePerson(Document): name = StringField() age = IntField() meta = {"abstract": True} class Person(BasePerson): name = StringField(required=True) p = Person(age=15) self.assertRaises(ValidationError, p.validate) def test_embedded_document_validation(self): """Ensure that embedded documents may be validated. """ class Comment(EmbeddedDocument): date = DateTimeField() content = StringField(required=True) comment = Comment() self.assertRaises(ValidationError, comment.validate) comment.content = "test" comment.validate() comment.date = 4 self.assertRaises(ValidationError, comment.validate) comment.date = datetime.now() comment.validate() self.assertEqual(comment._instance, None) def test_embedded_db_field_validate(self): class SubDoc(EmbeddedDocument): val = IntField(required=True) class Doc(Document): id = StringField(primary_key=True) e = EmbeddedDocumentField(SubDoc, db_field="eb") try: Doc(id="bad").validate() except ValidationError as e: self.assertIn("SubDoc:None", e.message) self.assertEqual( e.to_dict(), {"e": {"val": "OK could not be converted to int"}} ) Doc.drop_collection() Doc(id="test", e=SubDoc(val=15)).save() doc = Doc.objects.first() keys = doc._data.keys() self.assertEqual(2, len(keys)) self.assertIn("e", keys) self.assertIn("id", keys) doc.e.val = "OK" try: doc.save() except ValidationError as e: self.assertIn("Doc:test", e.message) self.assertEqual( e.to_dict(), {"e": {"val": "OK could not be converted to int"}} ) def test_embedded_weakref(self): class SubDoc(EmbeddedDocument): val = IntField(required=True) class Doc(Document): e = EmbeddedDocumentField(SubDoc, db_field="eb") Doc.drop_collection() d1 = Doc() d2 = Doc() s = SubDoc() self.assertRaises(ValidationError, s.validate) d1.e = s d2.e = s del d1 self.assertRaises(ValidationError, d2.validate) def test_parent_reference_in_child_document(self): """ Test to ensure a ReferenceField can store a reference to a parent class when inherited. Issue #954. """ class Parent(Document): meta = {"allow_inheritance": True} reference = ReferenceField("self") class Child(Parent): pass parent = Parent() parent.save() child = Child(reference=parent) # Saving child should not raise a ValidationError try: child.save() except ValidationError as e: self.fail("ValidationError raised: %s" % e.message) def test_parent_reference_set_as_attribute_in_child_document(self): """ Test to ensure a ReferenceField can store a reference to a parent class when inherited and when set via attribute. Issue #954. """ class Parent(Document): meta = {"allow_inheritance": True} reference = ReferenceField("self") class Child(Parent): pass parent = Parent() parent.save() child = Child() child.reference = parent # Saving the child should not raise a ValidationError try: child.save() except ValidationError as e: self.fail("ValidationError raised: %s" % e.message) if __name__ == "__main__": unittest.main()