def test_build(self): class MySchema(EmbeddedSchema): pass strict_proxy = data_proxy_factory('My', MySchema(), strict=True) assert issubclass(strict_proxy, BaseDataProxy) non_strict_proxy = data_proxy_factory('My', MySchema(), strict=False) assert issubclass(non_strict_proxy, BaseNonStrictDataProxy)
def test_reference(self): @self.instance.register class MyReferencedDoc(Document): class Meta: collection_name = 'my_collection' @self.instance.register class OtherDoc(Document): pass to_refer_doc = MyReferencedDoc.build_from_mongo( {'_id': ObjectId("5672d47b1d41c88dcd37ef05")}) ref = Reference(MyReferencedDoc, to_refer_doc.pk) dbref = DBRef('my_collection', to_refer_doc.pk) other_doc = OtherDoc.build_from_mongo( {'_id': ObjectId("5672d47b1d41c88dcd37ef07")}) # Test reference equality assert ref == to_refer_doc assert ref == dbref assert dbref == to_refer_doc assert dbref == ref assert to_refer_doc == ref assert to_refer_doc == dbref @self.instance.register class MyDoc(Document): ref = fields.ReferenceField(MyReferencedDoc, attribute='in_mongo_ref', allow_none=True) MySchema = MyDoc.Schema MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({'ref': ObjectId("5672d47b1d41c88dcd37ef05")}) d.load({'ref': "5672d47b1d41c88dcd37ef05"}) assert d.dump() == {'ref': "5672d47b1d41c88dcd37ef05"} assert d.get('ref').document_cls == MyReferencedDoc d.set('ref', to_refer_doc) assert d.to_mongo(update=True) == {'$set': {'in_mongo_ref': to_refer_doc.pk}} assert d.get('ref') == ref d.set('ref', ref) assert d.get('ref') == ref d.set('ref', dbref) assert d.get('ref') == ref with pytest.raises(ValidationError): d.set('ref', other_doc) not_created_doc = MyReferencedDoc() with pytest.raises(ValidationError): d.set('ref', not_created_doc) bad_ref = Reference(OtherDoc, other_doc.pk) with pytest.raises(ValidationError): d.set('ref', bad_ref) d2 = MyDataProxy({'ref': None}) assert d2.to_mongo() == {'in_mongo_ref': None} d2.from_mongo({'in_mongo_ref': None}) assert d2.get('ref') is None
def test_list_default(self): class MySchema(Schema): d_list = fields.ListField(fields.IntField(), default=(1, 2, 3)) c_list = fields.ListField(fields.IntField(), default=lambda: (1, 2, 3)) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() assert d.to_mongo() == { 'd_list': [1, 2, 3], 'c_list': [1, 2, 3], } assert isinstance(d.get('d_list'), List) assert isinstance(d.get('c_list'), List) d.get('d_list').append(4) d.get('c_list').append(4) assert d.to_mongo(update=True) == { '$set': {'c_list': [1, 2, 3, 4], 'd_list': [1, 2, 3, 4]}} d.delete('d_list') d.delete('c_list') assert d.to_mongo() == { 'd_list': [1, 2, 3], 'c_list': [1, 2, 3], } assert isinstance(d.get('d_list'), List) assert isinstance(d.get('c_list'), List) assert d.to_mongo(update=True) == { '$set': {'c_list': [1, 2, 3], 'd_list': [1, 2, 3]}}
def test_dict_default(self): class MySchema(Schema): # Passing a mutable as default is a bad idea in real life d_dict = fields.DictField(default={'1': 1, '2': 2}) c_dict = fields.DictField(default=lambda: {'1': 1, '2': 2}) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() assert d.to_mongo() == { 'd_dict': {'1': 1, '2': 2}, 'c_dict': {'1': 1, '2': 2}, } assert isinstance(d.get('d_dict'), Dict) assert isinstance(d.get('c_dict'), Dict) d.get('d_dict')['3'] = 3 d.get('c_dict')['3'] = 3 d.delete('d_dict') d.delete('c_dict') assert d.to_mongo() == { 'd_dict': {'1': 1, '2': 2}, 'c_dict': {'1': 1, '2': 2}, } assert isinstance(d.get('d_dict'), Dict) assert isinstance(d.get('c_dict'), Dict)
def test_aware_datetime(self): timezone_2h = dt.timezone(dt.timedelta(hours=2), "test") class MySchema(Schema): a = fields.AwareDateTimeField() b = fields.AwareDateTimeField(default_timezone=timezone_2h) s = MySchema() data = s.load({'a': dt.datetime(2016, 8, 6, tzinfo=dt.timezone.utc)}) assert data['a'] == dt.datetime(2016, 8, 6, tzinfo=dt.timezone.utc) data = s.load({'a': "2016-08-06T00:00:00Z"}) assert data['a'] == dt.datetime(2016, 8, 6, tzinfo=dt.timezone.utc) with pytest.raises(ma.ValidationError): data = s.load({'a': "2016-08-06T00:00:00"}) with pytest.raises(ma.ValidationError): s.load({'a': "dummy"}) # Test AwareDateTimeField deserializes as aware MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.from_mongo({ 'a': dt.datetime(2016, 8, 6), 'b': dt.datetime(2016, 8, 6), }) assert d.get('a') == dt.datetime(2016, 8, 6, tzinfo=dt.timezone.utc) assert d.get('a').tzinfo == dt.timezone.utc assert d.get('b') == dt.datetime(2016, 8, 6, tzinfo=dt.timezone.utc) assert d.get('b').tzinfo == timezone_2h
def test_reference_lazy(self): @self.instance.register class MyReferencedDocLazy(Document): pass to_refer_doc = MyReferencedDocLazy.build_from_mongo( {'_id': ObjectId("5672d47b1d41c88dcd37ef05")}) @self.instance.register class MyDoc(Document): ref = fields.ReferenceField("MyReferencedDocLazy", attribute='in_mongo_ref') MySchema = MyDoc.Schema MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({'ref': ObjectId("5672d47b1d41c88dcd37ef05")}) d.load({'ref': "5672d47b1d41c88dcd37ef05"}) assert d.dump() == {'ref': "5672d47b1d41c88dcd37ef05"} assert d.get('ref').document_cls == MyReferencedDocLazy d.set('ref', to_refer_doc) assert d.to_mongo(update=True) == { '$set': { 'in_mongo_ref': to_refer_doc.pk } } assert d.get('ref').document_cls == MyReferencedDocLazy
def test_iterators(self): class MySchema(EmbeddedSchema): field_a = fields.IntField(attribute='mongo_field_a') field_b = fields.IntField(attribute='mongo_field_b') DataProxy = data_proxy_factory('My', MySchema()) d = DataProxy() d.from_mongo({'mongo_field_a': 42, 'mongo_field_b': 24}) assert set(d.keys()) == {'mongo_field_a', 'mongo_field_b'} assert set( d.keys_by_mongo_name()) == {'mongo_field_a', 'mongo_field_b'} assert set(d.values()) == {42, 24} assert set(d.items()) == {('field_a', 42), ('field_b', 24)} assert set(d.items_by_mongo_name()) == {('mongo_field_a', 42), ('mongo_field_b', 24)} d.load({'field_a': 100, 'field_b': 200}) assert set(d.keys()) == {'mongo_field_a', 'mongo_field_b'} assert set( d.keys_by_mongo_name()) == {'mongo_field_a', 'mongo_field_b'} assert set(d.values()) == {100, 200} assert set(d.items()) == {('field_a', 100), ('field_b', 200)} assert set(d.items_by_mongo_name()) == {('mongo_field_a', 100), ('mongo_field_b', 200)}
def test_modify(self): class MySchema(EmbeddedSchema): a = fields.IntField() b = fields.IntField(attribute='in_mongo_b') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() assert d.get_modified_fields() == set() assert d.get_modified_fields_by_mongo_name() == set() d.load({'a': 1, 'b': 2}) assert d.get_modified_fields() == {'a', 'b'} assert d.get_modified_fields_by_mongo_name() == {'a', 'in_mongo_b'} d.from_mongo({'a': 1, 'in_mongo_b': 2}) assert d.get_modified_fields() == set() assert d.get_modified_fields_by_mongo_name() == set() assert d.to_mongo() == {'a': 1, 'in_mongo_b': 2} assert d.to_mongo(update=True) is None d.set('a', 3) d.delete('b') assert d.to_mongo(update=True) == { '$set': { 'a': 3 }, '$unset': { 'in_mongo_b': '' } } d.clear_modified() assert d.get_modified_fields() == set() assert d.get_modified_fields_by_mongo_name() == set() assert d.to_mongo(update=True) is None assert d.to_mongo() == {'a': 3}
def test_set(self): class MySchema(EmbeddedSchema): a = fields.IntField() b = fields.IntField(attribute='in_mongo_b') c = fields.StrField( allow_none=True, validate=validate.Length(min=1, max=5) ) d = fields.StrField() MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.from_mongo({'a': 1, 'in_mongo_b': 2}) d.set('a', 3) assert d.to_mongo() == {'a': 3, 'in_mongo_b': 2} assert d.to_mongo(update=True) == {'$set': {'a': 3}} d.from_mongo({'a': 1, 'in_mongo_b': 2}) d.set('b', 3) assert d.to_mongo() == {'a': 1, 'in_mongo_b': 3} assert d.to_mongo(update=True) == {'$set': {'in_mongo_b': 3}} with pytest.raises(KeyError): d.set('in_mongo_b', 2) d.from_mongo({}) d.set('c', None) assert d.to_mongo() == {'c': None} with pytest.raises(ValidationError): d.set('c', '123456') with pytest.raises(ValidationError): d.set('d', None)
def test_objectid(self): class MySchema(Schema): objid = fields.ObjectIdField(attribute='in_mongo_objid') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({'objid': ObjectId("5672d47b1d41c88dcd37ef05")}) assert d.dump() == {'objid': "5672d47b1d41c88dcd37ef05"} assert d.to_mongo() == {'in_mongo_objid': ObjectId("5672d47b1d41c88dcd37ef05")} d.load({'objid': "5672d47b1d41c88dcd37ef05"}) assert d.dump() == {'objid': "5672d47b1d41c88dcd37ef05"} assert d.to_mongo() == {'in_mongo_objid': ObjectId("5672d47b1d41c88dcd37ef05")} assert d.get('objid') == ObjectId("5672d47b1d41c88dcd37ef05") d.set('objid', ObjectId("5672d5e71d41c88f914b77c4")) assert d.to_mongo(update=True) == { '$set': {'in_mongo_objid': ObjectId("5672d5e71d41c88f914b77c4")}} d.set('objid', ObjectId("5672d5e71d41c88f914b77c4")) assert d.to_mongo(update=True) == { '$set': {'in_mongo_objid': ObjectId("5672d5e71d41c88f914b77c4")}} d.set('objid', "5672d5e71d41c88f914b77c4") assert d.get('objid') == ObjectId("5672d5e71d41c88f914b77c4") with pytest.raises(ValidationError): d.set('objid', 'notanid')
def test_default(self): default_value = ObjectId('507f1f77bcf86cd799439011') default_callable = lambda: ObjectId('507f1f77bcf86cd799439012') class MySchema(EmbeddedSchema): no_default = fields.ObjectIdField() with_default = fields.ObjectIdField(default=default_value) with_callable_default = fields.ObjectIdField( default=default_callable) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy(data={}) assert d._data['no_default'] is missing assert d._data['with_default'] == default_value assert d._data['with_callable_default'] == default_callable() assert d.get('no_default') is missing assert d.get('with_default') == default_value assert d.get('with_callable_default') == default_callable() assert d.to_mongo() == { 'with_default': default_value, 'with_callable_default': default_callable(), } assert d.dump() == { 'with_default': str(default_value), 'with_callable_default': str(default_callable()), } d.delete('with_default') assert d._data['with_default'] == default_value assert d.get('with_default') == default_value d.delete('with_callable_default') assert d._data['with_callable_default'] == default_callable() assert d.get('with_callable_default') == default_callable()
def test_dict(self): class MySchema(Schema): dict = fields.DictField(attribute='in_mongo_dict', allow_none=True) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.from_mongo({'in_mongo_dict': {'a': 1, 'b': {'c': True}}}) with pytest.raises(KeyError): d.get('in_mongo_dict') assert d.dump() == {'dict': {'a': 1, 'b': {'c': True}}} assert d.get('dict') == {'a': 1, 'b': {'c': True}} assert d.to_mongo() == {'in_mongo_dict': {'a': 1, 'b': {'c': True}}} # Must manually set_dirty to take the changes into account dict_ = d.get('dict') dict_['a'] = 1 assert d.to_mongo(update=True) is None dict_.set_modified() assert d.to_mongo(update=True) == { '$set': { 'in_mongo_dict': { 'a': 1, 'b': { 'c': True } } } } dict_.clear_modified() assert d.to_mongo(update=True) is None d2 = MyDataProxy({'dict': {'a': 1, 'b': {'c': True}}}) assert d2.to_mongo() == {'in_mongo_dict': {'a': 1, 'b': {'c': True}}} # Empty dict is considered as missing field d2.set('dict', {}) assert d2.to_mongo() == {} assert d2.to_mongo(update=True) == {'$unset': {'in_mongo_dict': ''}} d3 = MyDataProxy() d3.from_mongo({}) assert isinstance(d3.get('dict'), Dict) assert d3.to_mongo() == {} assert d3.to_mongo(update=True) is None d3.get('dict')['field'] = 'value' assert d3.to_mongo(update=True) is None d3.get('dict').set_modified() assert d3.to_mongo(update=True) == { '$set': { 'in_mongo_dict': { 'field': 'value' } } } assert d3.to_mongo() == {'in_mongo_dict': {'field': 'value'}} d4 = MyDataProxy({'dict': None}) assert d4.to_mongo() == {'in_mongo_dict': None} d4.from_mongo({'in_mongo_dict': None}) assert d4.get('dict') is None
def test_set(self): class MySchema(EmbeddedSchema): a = fields.IntField() b = fields.IntField(attribute='in_mongo_b') c = fields.StrField(allow_none=True, validate=validate.Length(min=1, max=5)) d = fields.StrField() MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.from_mongo({'a': 1, 'in_mongo_b': 2}) d.set('a', 3) assert d.to_mongo() == {'a': 3, 'in_mongo_b': 2} assert d.to_mongo(update=True) == {'$set': {'a': 3}} d.from_mongo({'a': 1, 'in_mongo_b': 2}) d.set('b', 3) assert d.to_mongo() == {'a': 1, 'in_mongo_b': 3} assert d.to_mongo(update=True) == {'$set': {'in_mongo_b': 3}} with pytest.raises(KeyError): d.set('in_mongo_b', 2) d.from_mongo({}) d.set('c', None) assert d.to_mongo() == {'c': None} with pytest.raises(ValidationError): d.set('c', '123456') with pytest.raises(ValidationError): d.set('d', None)
def test_default(self): default_value = ObjectId('507f1f77bcf86cd799439011') default_callable = lambda: ObjectId('507f1f77bcf86cd799439012') class MySchema(EmbeddedSchema): no_default = fields.ObjectIdField() with_default = fields.ObjectIdField(default=default_value) with_callable_default = fields.ObjectIdField(default=default_callable) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy(data={}) assert d._data['no_default'] is missing assert d._data['with_default'] == default_value assert d._data['with_callable_default'] == default_callable() assert d.get('no_default') is missing assert d.get('with_default') == default_value assert d.get('with_callable_default') == default_callable() assert d.to_mongo() == { 'with_default': default_value, 'with_callable_default': default_callable(), } assert d.dump() == { 'with_default': str(default_value), 'with_callable_default': str(default_callable()), } d.delete('with_default') assert d._data['with_default'] == default_value assert d.get('with_default') == default_value d.delete('with_callable_default') assert d._data['with_callable_default'] == default_callable() assert d.get('with_callable_default') == default_callable()
def test_complex_field_clear_modified(self): @self.instance.register class MyEmbedded(EmbeddedDocument): aa = fields.IntField() class MySchema(EmbeddedSchema): # EmbeddedField need instance to retrieve implementation a = fields.EmbeddedField(MyEmbedded, instance=self.instance) b = fields.ListField(fields.IntField) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({'a': {'aa': 1}, 'b': [2, 3]}) assert d.to_mongo() == {'a': {'aa': 1}, 'b': [2, 3]} d.get('a').aa = 4 d.get('b').append(5) assert d.to_mongo(update=True) == { '$set': { 'a': { 'aa': 4 }, 'b': [2, 3, 5] } } d.clear_modified() assert d.to_mongo(update=True) is None assert not d.get('a').is_modified() assert not d.get('b').is_modified()
def test_required_validate(self): @self.instance.register class MyEmbedded(EmbeddedDocument): required = fields.IntField(required=True) class MySchema(EmbeddedSchema): # EmbeddedField need instance to retrieve implementation listed = fields.ListField( fields.EmbeddedField(MyEmbedded, instance=self.instance)) embedded = fields.EmbeddedField(MyEmbedded, instance=self.instance) required = fields.IntField(required=True) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({ 'embedded': { 'required': 42 }, 'required': 42, 'listed': [{ 'required': 42 }] }) d.required_validate() # Empty list should not trigger required if embedded field has required fields d.load({'embedded': {'required': 42}, 'required': 42}) d.required_validate() d.load({'embedded': {'required': 42}}) with pytest.raises(ValidationError) as exc: d.required_validate() assert exc.value.messages == { 'required': ['Missing data for required field.'] } # Missing embedded is valid even though some fields are required in the embedded document d.load({'required': 42}) d.required_validate() # Required fields in the embedded document are only checked if the document is not missing d.load({'embedded': {}, 'required': 42}) with pytest.raises(ValidationError) as exc: d.required_validate() assert exc.value.messages == { 'embedded': { 'required': ['Missing data for required field.'] } } d.load({'embedded': {'required': 42}, 'required': 42, 'listed': [{}]}) with pytest.raises(ValidationError) as exc: d.required_validate() assert exc.value.messages == { 'listed': { 0: { 'required': ['Missing data for required field.'] } } }
def test_decimal(self): class MySchema(Schema): price = fields.DecimalField(attribute='in_mongo_price') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({'price': Decimal128('12.5678')}) assert d.dump() == {'price': Decimal('12.5678')} assert d.to_mongo() == {'in_mongo_price': Decimal128('12.5678')} assert d.get('price') == Decimal('12.5678') d.load({'price': Decimal('12.5678')}) assert d.dump() == {'price': Decimal('12.5678')} assert d.to_mongo() == {'in_mongo_price': Decimal128("12.5678")} assert d.get('price') == Decimal('12.5678') d.load({'price': '12.5678'}) assert d.dump() == {'price': Decimal('12.5678')} assert d.to_mongo() == {'in_mongo_price': Decimal128("12.5678")} assert d.get('price') == Decimal('12.5678') d.load({'price': float('12.5678')}) assert d.dump() == {'price': Decimal('12.5678')} assert d.to_mongo() == {'in_mongo_price': Decimal128("12.5678")} assert d.get('price') == Decimal('12.5678') d.set('price', Decimal128('11.1234')) assert d.to_mongo(update=True) == { '$set': { 'in_mongo_price': Decimal128('11.1234') } } d.set('price', Decimal("10.1234")) assert d.to_mongo(update=True) == { '$set': { 'in_mongo_price': Decimal128('10.1234') } } d.set('price', "9.1234") assert d.to_mongo(update=True) == { '$set': { 'in_mongo_price': Decimal128('9.1234') } } d.set('price', 8.1234) assert d.to_mongo(update=True) == { '$set': { 'in_mongo_price': Decimal128('8.1234') } } d.from_mongo({'in_mongo_price': Decimal128('7.1234')}) assert d._data == {'in_mongo_price': Decimal('7.1234')} with pytest.raises(ma.ValidationError): d.set('price', 'str')
def test_complexe_list(self): @self.instance.register class MyEmbeddedDocument(EmbeddedDocument): field = fields.IntField() @self.instance.register class ToRefDoc(Document): pass @self.instance.register class MyDoc(Document): embeds = fields.ListField( fields.EmbeddedField(MyEmbeddedDocument)) refs = fields.ListField(fields.ReferenceField(ToRefDoc)) MySchema = MyDoc.Schema obj_id1 = ObjectId() obj_id2 = ObjectId() to_ref_doc1 = ToRefDoc.build_from_mongo(data={'_id': obj_id1}) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({ 'embeds': [MyEmbeddedDocument(field=1), {'field': 2}], 'refs': [to_ref_doc1, Reference(ToRefDoc, obj_id2)] }) assert d.to_mongo() == { 'embeds': [{'field': 1}, {'field': 2}], 'refs': [obj_id1, obj_id2] } assert isinstance(d.get('embeds'), List) assert isinstance(d.get('refs'), List) for e in d.get('refs'): assert isinstance(e, Reference) for e in d.get('embeds'): assert isinstance(e, MyEmbeddedDocument) # Test list modification as well refs_list = d.get('refs') refs_list.append(to_ref_doc1) refs_list.extend([to_ref_doc1, Reference(ToRefDoc, obj_id2)]) for e in refs_list: assert isinstance(e, Reference) embeds_list = d.get('embeds') embeds_list.append(MyEmbeddedDocument(field=3)) embeds_list.extend([{'field': 4}, {'field': 5}]) for e in embeds_list: assert isinstance(e, MyEmbeddedDocument) # Modifying an EmbeddedDocument inside a list should count a list modification d.clear_modified() d.get('refs')[0] = obj_id2 assert d.to_mongo(update=True) == {'$set': {'refs': [ obj_id2, obj_id2, obj_id1, obj_id1, obj_id2]}} d.clear_modified() d.get('embeds')[1].field = 42 assert d.to_mongo(update=True) == {'$set': {'embeds': [ {'field': 1}, {'field': 42}, {'field': 3}, {'field': 4}, {'field': 5}]}}
def test_reference(self): @self.instance.register class MyReferencedDoc(Document): class Meta: collection_name = 'my_collection' @self.instance.register class OtherDoc(Document): pass to_refer_doc = MyReferencedDoc.build_from_mongo( {'_id': ObjectId("5672d47b1d41c88dcd37ef05")}) ref = Reference(MyReferencedDoc, to_refer_doc.pk) dbref = DBRef('my_collection', to_refer_doc.pk) other_doc = OtherDoc.build_from_mongo( {'_id': ObjectId("5672d47b1d41c88dcd37ef07")}) # Test reference equality assert ref == to_refer_doc assert ref == dbref assert dbref == to_refer_doc assert dbref == ref assert to_refer_doc == ref assert to_refer_doc == dbref @self.instance.register class MyDoc(Document): ref = fields.ReferenceField(MyReferencedDoc, attribute='in_mongo_ref') MySchema = MyDoc.Schema MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({'ref': ObjectId("5672d47b1d41c88dcd37ef05")}) d.load({'ref': "5672d47b1d41c88dcd37ef05"}) assert d.dump() == {'ref': "5672d47b1d41c88dcd37ef05"} assert d.get('ref').document_cls == MyReferencedDoc d.set('ref', to_refer_doc) assert d.to_mongo(update=True) == { '$set': { 'in_mongo_ref': to_refer_doc.pk } } assert d.get('ref') == ref d.set('ref', ref) assert d.get('ref') == ref d.set('ref', dbref) assert d.get('ref') == ref with pytest.raises(ValidationError): d.set('ref', other_doc) not_created_doc = MyReferencedDoc() with pytest.raises(ValidationError): d.set('ref', not_created_doc) bad_ref = Reference(OtherDoc, other_doc.pk) with pytest.raises(ValidationError): d.set('ref', bad_ref)
def test_list_field_modify(self): class MySchema(BaseSchema): a = fields.ListField(fields.IntField()) b = fields.ListField(fields.IntField(), attribute='in_mongo_b') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() assert d.get_modified_fields() == set() d.load({'a': [1], 'b': [2, 2]}) assert d.get_modified_fields() == {'a', 'b'} d.from_mongo({'a': [1], 'in_mongo_b': [2, 2]}) assert d.get_modified_fields() == set() assert d.to_mongo() == {'a': [1], 'in_mongo_b': [2, 2]} assert d.to_mongo(update=True) is None d.set('a', [3, 3, 3]) d.delete('b') assert d.to_mongo(update=True) == { '$set': { 'a': [3, 3, 3] }, '$unset': { 'in_mongo_b': '' } } d.clear_modified() assert d.get_modified_fields() == set() assert d.to_mongo() == {'a': [3, 3, 3]} assert d.to_mongo(update=True) is None d.clear_modified() d.load({'a': [1], 'b': [2, 2]}) d._data['a'].append(1) d._data['in_mongo_b'].append(2) assert d.get_modified_fields() == {'a', 'b'} assert d.to_mongo() == {'a': [1, 1], 'in_mongo_b': [2, 2, 2]} assert d.to_mongo(update=True) == { '$set': { 'a': [1, 1], 'in_mongo_b': [2, 2, 2] } } d.clear_modified() del d._data['a'][0] del d._data['in_mongo_b'][0] assert d.get_modified_fields() == {'a', 'b'} assert d.to_mongo() == {'a': [1], 'in_mongo_b': [2, 2]} assert d.to_mongo(update=True) == { '$set': { 'a': [1], 'in_mongo_b': [2, 2] } } d.clear_modified() d._data['a'].clear() d._data['in_mongo_b'].clear() assert d.get_modified_fields() == {'a', 'b'} assert d.to_mongo() == {'a': [], 'in_mongo_b': []} assert d.to_mongo(update=True) == {'$set': {'a': [], 'in_mongo_b': []}}
def test_strictdatetime(self): class MySchema(EmbeddedSchema): a = fields.StrictDateTimeField() b = fields.StrictDateTimeField(load_as_tz_aware=False) c = fields.StrictDateTimeField(load_as_tz_aware=True) # Test _deserialize s = MySchema(strict=True) for date in ( datetime(2016, 8, 6), datetime(2016, 8, 6, tzinfo=tzutc()), "2016-08-06T00:00:00Z", "2016-08-06T00:00:00", ): data, _ = s.load({'a': date, 'b': date, 'c': date}) assert data['a'] == datetime(2016, 8, 6) assert data['b'] == datetime(2016, 8, 6) assert data['c'] == datetime(2016, 8, 6, tzinfo=tzutc()) for date in ( "2016-08-06T00:00:00+02:00", datetime(2016, 8, 6, tzinfo=tzoffset(None, 7200)), ): data, _ = s.load({'a': date, 'b': date, 'c': date}) assert data['a'] == datetime(2016, 8, 5, 22, 0) assert data['b'] == datetime(2016, 8, 5, 22, 0) assert data['c'] == datetime(2016, 8, 6, tzinfo=tzoffset(None, 7200)) with pytest.raises(ValidationError): s.load({'a': "dummy"}) # Test _deserialize_from_mongo MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() for date in ( datetime(2016, 8, 6), datetime(2016, 8, 6, tzinfo=tzutc()), ): d.from_mongo({'a': date, 'b': date, 'c': date}) assert d.get('a') == datetime(2016, 8, 6) assert d.get('b') == datetime(2016, 8, 6) assert d.get('c') == datetime(2016, 8, 6, tzinfo=tzutc()) for date in (datetime(2016, 8, 6, tzinfo=tzoffset(None, 7200)), ): d.from_mongo({'a': date, 'b': date, 'c': date}) assert d.get('a') == datetime(2016, 8, 5, 22, 0) assert d.get('b') == datetime(2016, 8, 5, 22, 0) assert d.get('c') == datetime(2016, 8, 6, tzinfo=tzoffset(None, 7200))
def test_unkown_field_in_db(self): class MySchema(EmbeddedSchema): field = fields.IntField(attribute='mongo_field') DataProxy = data_proxy_factory('My', MySchema()) d = DataProxy() d.from_mongo({'mongo_field': 42}) assert d._data == {'mongo_field': 42} with pytest.raises(exceptions.UnknownFieldInDBError): d.from_mongo({'mongo_field': 42, 'xxx': 'foo'})
def test_from_mongo(self): class MySchema(EmbeddedSchema): in_front = fields.IntField(attribute='in_mongo') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() with pytest.raises(exceptions.UnknownFieldInDBError): d.from_mongo({'in_front': 42}) d.from_mongo({'in_mongo': 42}) assert d.get('in_front') == 42
def test_generic_reference(self): @self.instance.register class ToRef1(Document): pass @self.instance.register class ToRef2(Document): pass doc1 = ToRef1.build_from_mongo({'_id': ObjectId()}) ref1 = Reference(ToRef1, doc1.pk) @self.instance.register class MyDoc(Document): gref = fields.GenericReferenceField(attribute='in_mongo_gref', allow_none=True) MySchema = MyDoc.Schema MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({'gref': {'id': ObjectId("5672d47b1d41c88dcd37ef05"), 'cls': ToRef2.__name__}}) assert d.dump() == {'gref': {'id': "5672d47b1d41c88dcd37ef05", 'cls': 'ToRef2'}} assert d.get('gref').document_cls == ToRef2 d.set('gref', doc1) assert d.to_mongo(update=True) == { '$set': {'in_mongo_gref': {'_id': doc1.pk, '_cls': 'ToRef1'}}} assert d.get('gref') == ref1 d.set('gref', ref1) assert d.get('gref') == ref1 assert d.dump() == {'gref': {'id': str(doc1.pk), 'cls': 'ToRef1'}} not_created_doc = ToRef1() with pytest.raises(ValidationError): d.set('gref', not_created_doc) # Test invalid references for v in [ {'id': ObjectId()}, # missing _cls {'cls': ToRef1.__name__}, # missing _id {'id': ObjectId(), 'cls': 'dummy!'}, # invalid _cls {'_id': ObjectId(), '_cls': ToRef1.__name__}, # bad field names {'id': ObjectId(), 'cls': ToRef1.__name__, 'e': '?'}, # too much fields ObjectId("5672d47b1d41c88dcd37ef05"), # missing cls info 42, # Are you kidding ? '', # Please stop... True # I'm outa of that ! ]: with pytest.raises(ValidationError): d.set('gref', v) d2 = MyDataProxy({'gref': None}) assert d2.to_mongo() == {'in_mongo_gref': None} d2.from_mongo({'in_mongo_gref': None}) assert d2.get('gref') is None
def test_strictdatetime(self): class MySchema(EmbeddedSchema): a = fields.StrictDateTimeField() b = fields.StrictDateTimeField(load_as_tz_aware=False) c = fields.StrictDateTimeField(load_as_tz_aware=True) # Test _deserialize s = MySchema(strict=True) for date in ( datetime(2016, 8, 6), datetime(2016, 8, 6, tzinfo=tzutc()), "2016-08-06T00:00:00Z", "2016-08-06T00:00:00", ): data, _ = s.load({'a': date, 'b': date, 'c': date}) assert data['a'] == datetime(2016, 8, 6) assert data['b'] == datetime(2016, 8, 6) assert data['c'] == datetime(2016, 8, 6, tzinfo=tzutc()) for date in ( "2016-08-06T00:00:00+02:00", datetime(2016, 8, 6, tzinfo=tzoffset(None, 7200)), ): data, _ = s.load({'a': date, 'b': date, 'c': date}) assert data['a'] == datetime(2016, 8, 5, 22, 0) assert data['b'] == datetime(2016, 8, 5, 22, 0) assert data['c'] == datetime(2016, 8, 6, tzinfo=tzoffset(None, 7200)) with pytest.raises(ValidationError): s.load({'a': "dummy"}) # Test _deserialize_from_mongo MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() for date in ( datetime(2016, 8, 6), datetime(2016, 8, 6, tzinfo=tzutc()), ): d.from_mongo({'a': date, 'b': date, 'c': date}) assert d.get('a') == datetime(2016, 8, 6) assert d.get('b') == datetime(2016, 8, 6) assert d.get('c') == datetime(2016, 8, 6, tzinfo=tzutc()) for date in ( datetime(2016, 8, 6, tzinfo=tzoffset(None, 7200)), ): d.from_mongo({'a': date, 'b': date, 'c': date}) assert d.get('a') == datetime(2016, 8, 5, 22, 0) assert d.get('b') == datetime(2016, 8, 5, 22, 0) assert d.get('c') == datetime(2016, 8, 6, tzinfo=tzoffset(None, 7200))
def test_basic(self): class MySchema(EmbeddedSchema): field_a = fields.IntField(attribute='mongo_field_a') NonStrictDataProxy = data_proxy_factory('My', MySchema(), strict=False) with pytest.raises(exceptions.ValidationError) as exc: NonStrictDataProxy({'field_a': 42, 'xxx': 'foo'}) assert exc.value.messages == {'_schema': ['Unknown field name xxx.']} d = NonStrictDataProxy() d.from_mongo({'mongo_field_a': 42, 'xxx': 'foo'}) assert d._data == {'mongo_field_a': 42} assert d._additional_data == {'xxx': 'foo'}
def test_basic(self): class MySchema(EmbeddedSchema): field_a = fields.IntField(attribute='mongo_field_a') NonStrictDataProxy = data_proxy_factory('My', MySchema(), strict=False) with pytest.raises(exceptions.ValidationError) as exc: NonStrictDataProxy({'field_a': 42, 'xxx': 'foo'}) assert exc.value.messages == {'xxx': ['Unknown field.']} d = NonStrictDataProxy() d.from_mongo({'mongo_field_a': 42, 'xxx': 'foo'}) assert d._data == {'mongo_field_a': 42} assert d._additional_data == {'xxx': 'foo'}
def test_validate(self): class MySchema(EmbeddedSchema): with_max = fields.IntField(validate=validate.Range(max=99)) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy(data={}) with pytest.raises(ValidationError) as exc: MyDataProxy(data={'with_max': 100}) assert exc.value.args[0] == {'with_max': ['Must be at most 99.']} with pytest.raises(ValidationError) as exc: d.set('with_max', 100) assert exc.value.args[0] == ['Must be at most 99.']
def test_repr(self): class MySchema(EmbeddedSchema): field_a = fields.IntField(attribute='mongo_field_a') field_b = fields.StrField() MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy({'field_a': 1, 'field_b': 'value'}) assert MyDataProxy.__name__ == 'MyDataProxy' repr_d = repr(d) assert repr_d.startswith("<MyDataProxy(") assert "'field_a': 1" in repr_d assert "'field_b': 'value'" in repr_d
def test_share_ressources(self): class MySchema(EmbeddedSchema): a = fields.IntField() b = fields.IntField(attribute='in_mongo_b') MyDataProxy = data_proxy_factory('My', MySchema()) d1 = MyDataProxy() d2 = MyDataProxy() for field in ('schema', '_fields', '_fields_from_mongo_key'): assert getattr(d1, field) is getattr(d2, field) d1.load({'a': 1}) d2.load({'b': 2}) assert d1 != d2
def test_equality(self): class MySchema(EmbeddedSchema): a = fields.IntField() b = fields.IntField(attribute='in_mongo_b') MyDataProxy = data_proxy_factory('My', MySchema()) d1 = MyDataProxy() d1.load({'a': 1, 'b': 2}) assert d1 == {'a': 1, 'in_mongo_b': 2} d2 = MyDataProxy() d2.load({'a': 1, 'b': 2}) assert d1 == d2
def test_dict(self): class MySchema(Schema): dict = fields.DictField(attribute='in_mongo_dict', allow_none=True) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.from_mongo({'in_mongo_dict': {'a': 1, 'b': {'c': True}}}) with pytest.raises(KeyError): d.get('in_mongo_dict') assert d.dump() == {'dict': {'a': 1, 'b': {'c': True}}} assert d.get('dict') == {'a': 1, 'b': {'c': True}} assert d.to_mongo() == {'in_mongo_dict': {'a': 1, 'b': {'c': True}}} # Must manually set_dirty to take the changes into account dict_ = d.get('dict') dict_['a'] = 1 assert d.to_mongo(update=True) is None dict_.set_modified() assert d.to_mongo(update=True) == {'$set': {'in_mongo_dict': {'a': 1, 'b': {'c': True}}}} dict_.clear_modified() assert d.to_mongo(update=True) is None d2 = MyDataProxy({'dict': {'a': 1, 'b': {'c': True}}}) assert d2.to_mongo() == {'in_mongo_dict': {'a': 1, 'b': {'c': True}}} d2.set('dict', {}) assert d2.to_mongo() == {'in_mongo_dict': {}} assert d2.to_mongo(update=True) == {'$set': {'in_mongo_dict': {}}} d2.delete('dict') assert d2.to_mongo() == {} assert d2.to_mongo(update=True) == {'$unset': {'in_mongo_dict': ''}} d3 = MyDataProxy() d3.from_mongo({}) assert d3.get('dict') is missing assert d3.to_mongo() == {} assert d3.to_mongo(update=True) is None d3.from_mongo({'in_mongo_dict': {}}) assert d3._data.get('in_mongo_dict') == {} d3.get('dict')['field'] = 'value' assert d3.to_mongo(update=True) is None d3.get('dict').set_modified() assert d3.to_mongo(update=True) == {'$set': {'in_mongo_dict': {'field': 'value'}}} assert d3.to_mongo() == {'in_mongo_dict': {'field': 'value'}} d4 = MyDataProxy({'dict': None}) assert d4.to_mongo() == {'in_mongo_dict': None} d4.from_mongo({'in_mongo_dict': None}) assert d4.get('dict') is None
def test_default(self): class MySchema(EmbeddedSchema): with_default = fields.StrField(default='default_value') with_missing = fields.StrField(missing='missing_value') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy(data={}) assert d._data['with_default'] is missing assert d._data['with_missing'] is 'missing_value' assert d.get('with_default') == 'default_value' assert d.get('with_missing') == 'missing_value' assert d.to_mongo() == {'with_missing': 'missing_value'} assert d.dump() == {'with_default': 'default_value', 'with_missing': 'missing_value'}
def test_decimal(self): class MySchema(Schema): price = fields.DecimalField(attribute='in_mongo_price') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({'price': Decimal128('12.5678')}) assert d.dump() == {'price': Decimal('12.5678')} assert d.to_mongo() == {'in_mongo_price': Decimal128('12.5678')} assert d.get('price') == Decimal('12.5678') d.load({'price': Decimal('12.5678')}) assert d.dump() == {'price': Decimal('12.5678')} assert d.to_mongo() == {'in_mongo_price': Decimal128("12.5678")} assert d.get('price') == Decimal('12.5678') d.load({'price': '12.5678'}) assert d.dump() == {'price': Decimal('12.5678')} assert d.to_mongo() == {'in_mongo_price': Decimal128("12.5678")} assert d.get('price') == Decimal('12.5678') d.load({'price': float('12.5678')}) assert d.dump() == {'price': Decimal('12.5678')} assert d.to_mongo() == {'in_mongo_price': Decimal128("12.5678")} assert d.get('price') == Decimal('12.5678') d.set('price', Decimal128('11.1234')) assert d.to_mongo(update=True) == { '$set': {'in_mongo_price': Decimal128('11.1234')}} d.set('price', Decimal("10.1234")) assert d.to_mongo(update=True) == { '$set': {'in_mongo_price': Decimal128('10.1234')}} d.set('price', "9.1234") assert d.to_mongo(update=True) == { '$set': {'in_mongo_price': Decimal128('9.1234')}} d.set('price', 8.1234) assert d.to_mongo(update=True) == { '$set': {'in_mongo_price': Decimal128('8.1234')}} d.from_mongo({'in_mongo_price': Decimal128('7.1234')}) assert d._data == { 'in_mongo_price': Decimal('7.1234') } with pytest.raises(ValidationError): d.set('price', 'str')
def test_set_to_missing_fields(self): class MySchema(BaseSchema): a = fields.IntField() b = fields.IntField(attribute='in_mongo_b') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy(data={'a': 1}) assert d.get('b') is ma.missing assert d._data['in_mongo_b'] is ma.missing d.set('b', 2) assert d.get('b') == 2 d.delete('b') # Can do it two time in a row without error d.delete('b') assert d._data['in_mongo_b'] is ma.missing
def test_simple(self): class MySchema(EmbeddedSchema): a = fields.IntField() b = fields.IntField() MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({'a': 1, 'b': 2}) assert d.get('a') == 1 d.set('b', 3) assert d.get('b') == 3 assert d._data == {'a': 1, 'b': 3} assert d.dump() == {'a': 1, 'b': 3} d.delete('b') assert d._data == {'a': 1, 'b': missing} assert d.dump() == {'a': 1}
def test_default(self): class MySchema(EmbeddedSchema): with_default = fields.StrField(default='default_value') with_missing = fields.StrField(missing='missing_value') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy(data={}) assert d._data['with_default'] is missing assert d._data['with_missing'] is 'missing_value' assert d.get('with_default') == 'default_value' assert d.get('with_missing') == 'missing_value' assert d.to_mongo() == {'with_missing': 'missing_value'} assert d.dump() == { 'with_default': 'default_value', 'with_missing': 'missing_value' }
def test_access_by_mongo_name(self): class MySchema(EmbeddedSchema): a = fields.IntField() b = fields.IntField(attribute='in_mongo_b') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.from_mongo({'a': 1, 'in_mongo_b': 2}) assert d.get_by_mongo_name('in_mongo_b') == 2 assert d.get_by_mongo_name('a') == 1 with pytest.raises(KeyError): d.get_by_mongo_name('b') d.set_by_mongo_name('in_mongo_b', 3) assert d.to_mongo(update=True) == {'$set': {'in_mongo_b': 3}} assert d.get_by_mongo_name('in_mongo_b') == 3 d.delete_by_mongo_name('in_mongo_b') assert d.to_mongo(update=True) == {'$unset': {'in_mongo_b': ''}}
def test_route_naming(self): class MySchema(EmbeddedSchema): in_front = fields.IntField(attribute='in_mongo') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() with pytest.raises(ValidationError): d.load({'in_mongo': 42}) d.load({'in_front': 42}) with pytest.raises(KeyError): d.get('in_mongo') assert d.get('in_front') == 42 d.set('in_front', 24) assert d._data == {'in_mongo': 24} assert d.get('in_front') == 24 assert d.dump() == {'in_front': 24} assert d.to_mongo() == {'in_mongo': 24}
def test_del(self): class MySchema(EmbeddedSchema): a = fields.IntField() b = fields.IntField(attribute='in_mongo_b') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.from_mongo({'a': 1, 'in_mongo_b': 2}) d.delete('b') assert d.to_mongo() == {'a': 1} assert d.to_mongo(update=True) == {'$unset': {'in_mongo_b': ''}} d.delete('a') assert d.to_mongo(update=True) == {'$unset': {'a': '', 'in_mongo_b': ''}} with pytest.raises(KeyError): d.delete('in_mongo_b')
def test_set_to_missing_fields(self): class MySchema(EmbeddedSchema): a = fields.IntField() b = fields.IntField(attribute='in_mongo_b') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy(data={'a': 1}) assert d.get('b') is missing assert d.get_by_mongo_name('in_mongo_b') is missing assert d._data['in_mongo_b'] is missing d.set('b', 2) assert d.get('b') == 2 d.delete('b') # Can do it two time in a row without error d.delete('b') assert d._data['in_mongo_b'] is missing
def test_dict_default(self): class MySchema(Schema): # Passing a mutable as default is a bad idea in real life d_dict = fields.DictField(values=fields.IntField, default={ '1': 1, '2': 2 }) c_dict = fields.DictField(values=fields.IntField, default=lambda: { '1': 1, '2': 2 }) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() assert d.to_mongo() == { 'd_dict': { '1': 1, '2': 2 }, 'c_dict': { '1': 1, '2': 2 }, } assert isinstance(d.get('d_dict'), Dict) assert isinstance(d.get('c_dict'), Dict) d.get('d_dict')['3'] = 3 d.get('c_dict')['3'] = 3 d.delete('d_dict') d.delete('c_dict') assert d.to_mongo() == { 'd_dict': { '1': 1, '2': 2 }, 'c_dict': { '1': 1, '2': 2 }, } assert isinstance(d.get('d_dict'), Dict) assert isinstance(d.get('c_dict'), Dict)
def test_equality(self): class MySchema(EmbeddedSchema): a = fields.IntField() b = fields.IntField(attribute='in_mongo_b') MyDataProxy = data_proxy_factory('My', MySchema()) d1 = MyDataProxy() d1.load({'a': 1, 'b': 2}) assert d1 == {'a': 1, 'in_mongo_b': 2} d2 = MyDataProxy() d2.load({'a': 1, 'b': 2}) assert d1 == d2 assert d1 != None # noqa: E711 (None comparison) assert d1 != missing assert None != d1 # noqa: E711 (None comparison) assert missing != d1
def test_order(self): """Test schema order of embedded doc preserved when serializing to mongo""" @self.instance.register class MyEmbedded(EmbeddedDocument): a = fields.IntField() b = fields.IntField() c = fields.IntField() class MySchema(BaseSchema): # EmbeddedField need instance to retrieve implementation e = fields.EmbeddedField(MyEmbedded, instance=self.instance) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({'e': {'c': 3, 'b': 2, 'a': 1}}) assert_equal_order(d.to_mongo()['e'], {'a': 1, 'b': 2, 'c': 3}) d.get('e')['b'] = 4 assert_equal_order(d.to_mongo()['e'], {'a': 1, 'b': 4, 'c': 3})
def test_date(self): class MySchema(Schema): a = fields.DateField() s = MySchema() data = s.load({'a': dt.date(2016, 8, 6)}) assert data['a'] == dt.date(2016, 8, 6) data = s.load({'a': "2016-08-06"}) assert data['a'] == dt.date(2016, 8, 6) with pytest.raises(ma.ValidationError): s.load({'a': "dummy"}) # Test _serialize_to_mongo / _deserialize_from_mongo MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.from_mongo({'a': dt.datetime(2019, 8, 6)}) assert d.get('a') == dt.date(2019, 8, 6) assert d.to_mongo() == {'a': dt.datetime(2019, 8, 6)}
def test_load(self): class MySchema(EmbeddedSchema): a = fields.IntField() b = fields.IntField(attribute='in_mongo_b') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.from_mongo({'a': 1, 'in_mongo_b': 2}) assert d.to_mongo() == {'a': 1, 'in_mongo_b': 2} d.set('a', 3) assert d.to_mongo(update=True) == {'$set': {'a': 3}} d.from_mongo({'a': 4, 'in_mongo_b': 5}) assert d.to_mongo(update=True) is None assert d.to_mongo() == {'a': 4, 'in_mongo_b': 5} d2 = MyDataProxy(data={'a': 4, 'b': 5}) assert d == d2
def test_date(self): class MySchema(EmbeddedSchema): a = fields.DateField() s = MySchema(strict=True) data, _ = s.load({'a': dt.date(2016, 8, 6)}) assert data['a'] == dt.date(2016, 8, 6) data, _ = s.load({'a': "2016-08-06"}) assert data['a'] == dt.date(2016, 8, 6) with pytest.raises(ValidationError): s.load({'a': "dummy"}) # Test _serialize_to_mongo / _deserialize_from_mongo MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.from_mongo({'a': dt.datetime(2019, 8, 6)}) assert d.get('a') == dt.date(2019, 8, 6) assert d.to_mongo() == {'a': dt.datetime(2019, 8, 6)}
def test_iterators(self): class MySchema(EmbeddedSchema): field_a = fields.IntField(attribute='mongo_field_a') field_b = fields.IntField(attribute='mongo_field_b') DataProxy = data_proxy_factory('My', MySchema()) d = DataProxy() d.from_mongo({'mongo_field_a': 42, 'mongo_field_b': 24}) assert set(d.keys()) == {'mongo_field_a', 'mongo_field_b'} assert set(d.keys_by_mongo_name()) == {'mongo_field_a', 'mongo_field_b'} assert set(d.values()) == {42, 24} assert set(d.items()) == {('field_a', 42), ('field_b', 24)} assert set(d.items_by_mongo_name()) == {('mongo_field_a', 42), ('mongo_field_b', 24)} d.load({'field_a': 100, 'field_b': 200}) assert set(d.keys()) == {'mongo_field_a', 'mongo_field_b'} assert set(d.keys_by_mongo_name()) == {'mongo_field_a', 'mongo_field_b'} assert set(d.values()) == {100, 200} assert set(d.items()) == {('field_a', 100), ('field_b', 200)} assert set(d.items_by_mongo_name()) == {('mongo_field_a', 100), ('mongo_field_b', 200)}
def test_complexe_field_clear_modified(self): @self.instance.register class MyEmbedded(EmbeddedDocument): aa = fields.IntField() class MySchema(EmbeddedSchema): # EmbeddedField need instance to retrieve implementation a = fields.EmbeddedField(MyEmbedded, instance=self.instance) b = fields.ListField(fields.IntField) MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() d.load({'a': {'aa': 1}, 'b': [2, 3]}) assert d.to_mongo() == {'a': {'aa': 1}, 'b': [2, 3]} d.get('a').aa = 4 d.get('b').append(5) assert d.to_mongo(update=True) == {'$set': {'a': {'aa': 4}, 'b': [2, 3, 5]}} d.clear_modified() assert d.to_mongo(update=True) is None assert not d.get('a').is_modified() assert not d.get('b').is_modified()
def test_modify(self): class MySchema(EmbeddedSchema): a = fields.IntField() b = fields.IntField(attribute='in_mongo_b') MyDataProxy = data_proxy_factory('My', MySchema()) d = MyDataProxy() assert d.get_modified_fields() == [] d.load({'a': 1, 'b': 2}) assert list(sorted(d.get_modified_fields())) == ['a', 'b'] d.from_mongo({'a': 1, 'in_mongo_b': 2}) assert d.get_modified_fields() == [] assert d.to_mongo() == {'a': 1, 'in_mongo_b': 2} assert d.to_mongo(update=True) is None d.set('a', 3) d.delete('b') assert d.to_mongo(update=True) == {'$set': {'a': 3}, '$unset': {'in_mongo_b': ''}} d.clear_modified() assert d.get_modified_fields() == [] assert d.to_mongo(update=True) is None assert d.to_mongo() == {'a': 3}