Merge pull request #2242 from bagerard/fix_dictfield_validation
Fix bug introduced in 0.19 related to DictField validation
This commit is contained in:
commit
00ae6298d4
@ -8,7 +8,8 @@ Development
|
||||
- (Fill this out as you fix issues and develop your features).
|
||||
- Add Mongo 4.0 to Travis
|
||||
- Fixed a bug causing inaccurate query results, while combining ``__raw__`` and regular filters for the same field #2264
|
||||
- Add support for the `elemMatch` projection operator in .fields (e.g BlogPost.objects.fields(elemMatch__comments="test")) #2267
|
||||
- Add support for the `elemMatch` projection operator in .fields() (e.g BlogPost.objects.fields(elemMatch__comments="test")) #2267
|
||||
- DictField validate failed without default connection (bug introduced in 0.19.0) #2239
|
||||
|
||||
Changes in 0.19.1
|
||||
=================
|
||||
|
@ -1088,14 +1088,12 @@ class DictField(ComplexBaseField):
|
||||
msg = "Invalid dictionary key - documents must have only string keys"
|
||||
self.error(msg)
|
||||
|
||||
curr_mongo_ver = get_mongodb_version()
|
||||
|
||||
if curr_mongo_ver < MONGODB_36 and key_has_dot_or_dollar(value):
|
||||
self.error(
|
||||
'Invalid dictionary key name - keys may not contain "."'
|
||||
' or startswith "$" characters'
|
||||
)
|
||||
elif curr_mongo_ver >= MONGODB_36 and key_starts_with_dollar(value):
|
||||
# Following condition applies to MongoDB >= 3.6
|
||||
# older Mongo has stricter constraints but
|
||||
# it will be rejected upon insertion anyway
|
||||
# Having a validation that depends on the MongoDB version
|
||||
# is not straightforward as the field isn't aware of the connected Mongo
|
||||
if key_starts_with_dollar(value):
|
||||
self.error(
|
||||
'Invalid dictionary key name - keys may not startswith "$" characters'
|
||||
)
|
||||
|
@ -11,7 +11,7 @@ MONGODB_36 = (3, 6)
|
||||
|
||||
|
||||
def get_mongodb_version():
|
||||
"""Return the version of the connected mongoDB (first 2 digits)
|
||||
"""Return the version of the default connected mongoDB (first 2 digits)
|
||||
|
||||
:return: tuple(int, int)
|
||||
"""
|
||||
|
@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import pytest
|
||||
from bson import InvalidDocument
|
||||
|
||||
from mongoengine import *
|
||||
from mongoengine.base import BaseDict
|
||||
@ -19,22 +20,24 @@ class TestDictField(MongoDBTestCase):
|
||||
post = BlogPost(info=info).save()
|
||||
assert get_as_pymongo(post) == {"_id": post.id, "info": info}
|
||||
|
||||
def test_general_things(self):
|
||||
"""Ensure that dict types work as expected."""
|
||||
def test_validate_invalid_type(self):
|
||||
class BlogPost(Document):
|
||||
info = DictField()
|
||||
|
||||
BlogPost.drop_collection()
|
||||
|
||||
invalid_infos = ["my post", ["test", "test"], {1: "test"}]
|
||||
for invalid_info in invalid_infos:
|
||||
with pytest.raises(ValidationError):
|
||||
BlogPost(info=invalid_info).validate()
|
||||
|
||||
def test_keys_with_dots_or_dollars(self):
|
||||
class BlogPost(Document):
|
||||
info = DictField()
|
||||
|
||||
BlogPost.drop_collection()
|
||||
|
||||
post = BlogPost()
|
||||
post.info = "my post"
|
||||
with pytest.raises(ValidationError):
|
||||
post.validate()
|
||||
|
||||
post.info = ["test", "test"]
|
||||
with pytest.raises(ValidationError):
|
||||
post.validate()
|
||||
|
||||
post.info = {"$title": "test"}
|
||||
with pytest.raises(ValidationError):
|
||||
@ -48,25 +51,34 @@ class TestDictField(MongoDBTestCase):
|
||||
with pytest.raises(ValidationError):
|
||||
post.validate()
|
||||
|
||||
post.info = {1: "test"}
|
||||
with pytest.raises(ValidationError):
|
||||
post.validate()
|
||||
|
||||
post.info = {"nested": {"the.title": "test"}}
|
||||
if get_mongodb_version() < MONGODB_36:
|
||||
with pytest.raises(ValidationError):
|
||||
post.validate()
|
||||
# MongoDB < 3.6 rejects dots
|
||||
# To avoid checking the mongodb version from the DictField class
|
||||
# we rely on MongoDB to reject the data during the save
|
||||
post.validate()
|
||||
with pytest.raises(InvalidDocument):
|
||||
post.save()
|
||||
else:
|
||||
post.validate()
|
||||
|
||||
post.info = {"dollar_and_dot": {"te$st.test": "test"}}
|
||||
if get_mongodb_version() < MONGODB_36:
|
||||
with pytest.raises(ValidationError):
|
||||
post.validate()
|
||||
post.validate()
|
||||
with pytest.raises(InvalidDocument):
|
||||
post.save()
|
||||
else:
|
||||
post.validate()
|
||||
|
||||
post.info = {"title": "test"}
|
||||
def test_general_things(self):
|
||||
"""Ensure that dict types work as expected."""
|
||||
|
||||
class BlogPost(Document):
|
||||
info = DictField()
|
||||
|
||||
BlogPost.drop_collection()
|
||||
|
||||
post = BlogPost(info={"title": "test"})
|
||||
post.save()
|
||||
|
||||
post = BlogPost()
|
||||
|
Loading…
x
Reference in New Issue
Block a user