224 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # -*- coding: utf-8 -*-
 | |
| import unittest
 | |
| from datetime import datetime
 | |
| 
 | |
| import pytest
 | |
| 
 | |
| 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")
 | |
|         assert error.to_dict() == {}
 | |
| 
 | |
|         # 1st level error schema
 | |
|         error.errors = {"1st": ValidationError("bad 1st")}
 | |
|         assert "1st" in error.to_dict()
 | |
|         assert error.to_dict()["1st"] == "bad 1st"
 | |
| 
 | |
|         # 2nd level error schema
 | |
|         error.errors = {
 | |
|             "1st": ValidationError(
 | |
|                 "bad 1st", errors={"2nd": ValidationError("bad 2nd")}
 | |
|             )
 | |
|         }
 | |
|         assert "1st" in error.to_dict()
 | |
|         assert isinstance(error.to_dict()["1st"], dict)
 | |
|         assert "2nd" in error.to_dict()["1st"]
 | |
|         assert 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")}
 | |
|                             )
 | |
|                         },
 | |
|                     )
 | |
|                 },
 | |
|             )
 | |
|         }
 | |
|         assert "1st" in error.to_dict()
 | |
|         assert "2nd" in error.to_dict()["1st"]
 | |
|         assert "3rd" in error.to_dict()["1st"]["2nd"]
 | |
|         assert "4th" in error.to_dict()["1st"]["2nd"]["3rd"]
 | |
|         assert error.to_dict()["1st"]["2nd"]["3rd"]["4th"] == "Inception"
 | |
| 
 | |
|         assert 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:
 | |
|             assert "User:None" in e.message
 | |
|             assert 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:
 | |
|             assert "User:RossC0" in e.message
 | |
|             assert 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)
 | |
|         with pytest.raises(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()
 | |
|         with pytest.raises(ValidationError):
 | |
|             comment.validate()
 | |
| 
 | |
|         comment.content = "test"
 | |
|         comment.validate()
 | |
| 
 | |
|         comment.date = 4
 | |
|         with pytest.raises(ValidationError):
 | |
|             comment.validate()
 | |
| 
 | |
|         comment.date = datetime.now()
 | |
|         comment.validate()
 | |
|         assert comment._instance is 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:
 | |
|             assert "SubDoc:None" in e.message
 | |
|             assert 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()
 | |
|         assert 2 == len(keys)
 | |
|         assert "e" in keys
 | |
|         assert "id" in keys
 | |
| 
 | |
|         doc.e.val = "OK"
 | |
|         try:
 | |
|             doc.save()
 | |
|         except ValidationError as e:
 | |
|             assert "Doc:test" in e.message
 | |
|             assert 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()
 | |
| 
 | |
|         with pytest.raises(ValidationError):
 | |
|             s.validate()
 | |
| 
 | |
|         d1.e = s
 | |
|         d2.e = s
 | |
| 
 | |
|         del d1
 | |
| 
 | |
|         with pytest.raises(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()
 |