218 lines
6.1 KiB
Python
218 lines
6.1 KiB
Python
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
|
|
child.save()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|