Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
 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.']
     }
Esempio n. 4
0
    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)
Esempio n. 5
0
 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.']}
Esempio n. 6
0
    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)
Esempio n. 7
0
    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
                }]
            }
        }
Esempio n. 8
0
    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
                    }
                }
            }
        }