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_reference(self, collection_moke): class MyReferencedDoc(Document): class Meta: collection = collection_moke class OtherDoc(Document): pass to_refer_doc = MyReferencedDoc.build_from_mongo( {'_id': ObjectId("5672d47b1d41c88dcd37ef05")}) ref = Reference(MyReferencedDoc, to_refer_doc.pk) dbref = DBRef(collection_moke.name, 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 class MySchema(Schema): ref = fields.ReferenceField(MyReferencedDoc, attribute='in_mongo_ref') d = DataProxy(MySchema()) d.load({'ref': ObjectId("5672d47b1d41c88dcd37ef05")}) d.load({'ref': "5672d47b1d41c88dcd37ef05"}) assert d.dump() == {'ref': "5672d47b1d41c88dcd37ef05"} 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_reference(self, classroom_model): teacher = classroom_model.Teacher(name='M. Strickland') teacher.commit() course = classroom_model.Course(name='Hoverboard 101', teacher=teacher) course.commit() assert isinstance(course.teacher, Reference) teacher_fetched = course.teacher.fetch() assert teacher_fetched == teacher # Change in referenced document is not seen until referenced # document is committed and referencer is reloaded teacher.name = 'Dr. Brown' assert course.teacher.fetch().name == 'M. Strickland' teacher.commit() assert course.teacher.fetch().name == 'M. Strickland' course.reload() assert course.teacher.fetch().name == 'Dr. Brown' # But we can force reload as soon as referenced document is committed # without having to reload the whole referencer teacher.name = 'M. Strickland' assert course.teacher.fetch().name == 'Dr. Brown' assert course.teacher.fetch(force_reload=True).name == 'Dr. Brown' teacher.commit() assert course.teacher.fetch().name == 'Dr. Brown' assert course.teacher.fetch(force_reload=True).name == 'M. Strickland' # Test bad ref as well course.teacher = Reference(classroom_model.Teacher, ObjectId()) with pytest.raises(exceptions.ValidationError) as exc: course.io_validate() assert exc.value.messages == { 'teacher': ['Reference not found for document Teacher.'] }
def test_complexe_list(self): class MyEmbeddedDocument(EmbeddedDocument): field = fields.IntField() class ToRefDoc(Document): pass class MySchema(Schema): embeds = fields.ListField(fields.EmbeddedField(MyEmbeddedDocument)) refs = fields.ListField(fields.ReferenceField(ToRefDoc)) obj_id1 = ObjectId() obj_id2 = ObjectId() to_ref_doc1 = ToRefDoc.build_from_mongo(data={'_id': obj_id1}) d = DataProxy(MySchema()) 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)
def test_reference(self, classroom_model): teacher = classroom_model.Teacher(name='M. Strickland') yield teacher.commit() course = classroom_model.Course(name='Hoverboard 101', teacher=teacher) yield course.commit() assert isinstance(course.teacher, Reference) teacher_fetched = yield course.teacher.fetch() assert teacher_fetched == teacher # Test bad ref as well course.teacher = Reference(classroom_model.Teacher, ObjectId()) with pytest.raises(exceptions.ValidationError) as exc: yield course.io_validate() assert exc.value.messages == {'teacher': ['Reference not found for document Teacher.']}
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') 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)
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_complex_dict(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.DictField( values=fields.EmbeddedField(MyEmbeddedDocument)) refs = fields.DictField(values=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': { 'a': MyEmbeddedDocument(field=1), 'b': { 'field': 2 }, }, 'refs': { '1': to_ref_doc1, '2': Reference(ToRefDoc, obj_id2), } }) assert d.to_mongo() == { 'embeds': { 'a': { 'field': 1 }, 'b': { 'field': 2 } }, 'refs': { '1': obj_id1, '2': obj_id2 }, } assert isinstance(d.get('embeds'), Dict) assert isinstance(d.get('refs'), Dict) for e in d.get('refs').values(): assert isinstance(e, Reference) for e in d.get('embeds').values(): assert isinstance(e, MyEmbeddedDocument) # Test dict modification as well refs_dict = d.get('refs') refs_dict.update({'3': to_ref_doc1, '4': Reference(ToRefDoc, obj_id2)}) for e in refs_dict.values(): assert isinstance(e, Reference) embeds_dict = d.get('embeds') embeds_dict.update({ 'c': MyEmbeddedDocument(field=3), 'd': { 'field': 4 } }) for e in embeds_dict.values(): assert isinstance(e, MyEmbeddedDocument) # Modifying an EmbeddedDocument inside a dict should count a dict modification d.clear_modified() d.get('refs')['1'] = obj_id2 assert d.to_mongo(update=True) == { '$set': { 'refs': { '1': obj_id2, '2': obj_id2, '3': obj_id1, '4': obj_id2 } } } d.clear_modified() d.get('embeds')['b'].field = 42 assert d.to_mongo(update=True) == { '$set': { 'embeds': { 'a': { 'field': 1 }, 'b': { 'field': 42 }, 'c': { 'field': 3 }, 'd': { 'field': 4 } } } }