def it_calls_the_fetch_field_method_when_saving(self):
        DocModel = Mock()

        class Doc(Document):
            id = fields.NumberField()
            name = fields.StringField()

            class Meta:
                backend_type = 'django'
                model = DocModel

            def map_name_field(self):
                return "mapped_name"

        # prepare the django backend
        DocModel.DoesNotExist = Exception
        DocModel.objects.get.side_effect = DocModel.DoesNotExist
        mock_doc = Mock()
        DocModel.return_value = mock_doc

        # create and save the document
        doc = Doc({'id': 1, 'name': 'docname'})

        manager = BackendManager('django')
        manager._model = DocModel
        manager.save(doc)

        # The save should have set this attribute on the django model as
        # defined by the map_field method
        eq_(True, hasattr(mock_doc, 'mapped_name'))
        # and also have the attribute set to the right value
        eq_('docname', mock_doc.mapped_name)
    def it_can_fetch_data_from_the_underlying_model(self):
        DjangoModel = Mock(name="DjangoModel")
        mock_model = Mock()
        mock_model.id = 1
        DjangoModel.objects.get.return_value = mock_model

        manager = BackendManager('django')
        # The manager needs to know which model it connects to
        # This is normally done when the Document is created.
        manager._model = DjangoModel

        doc = Mock(name="mock_document", spec=Document)
        field = fields.NumberField()
        field.name = "id"
        doc.id = 1
        doc._context = {}
        doc._get_context.return_value = {}
        doc._meta.identifier = ["id"]
        doc._identifier_state.return_value = {"id": 1}
        doc._save.return_value = {"id": 1}
        doc._meta.local_fields = [field]

        # make sure we are working with correct expectations
        eq_(DjangoBackendManager, type(manager))
        eq_({'id': 1}, manager.fetch(doc))
        eq_([('objects.get', {'id': 1})], DjangoModel.method_calls)
    def it_can_delete_resources_from_a_remote_endpoint(self):
        mock_resp = Mock(name="mock_response")
        expected = {'id': 1}
        mock_resp.content = json.dumps(expected)
        mock_resp.status_code = 204

        self.mock_request.delete.return_value = mock_resp

        manager = BackendManager('http')

        class Doc(Document):
            id = fields.NumberField()

            class Meta:
                backend_type = 'http'

            def uri(self):
                return 'http://location'

        doc = Doc({'id': 1})

        manager.delete(doc)

        # make sure we are working with correct expectations
        eq_(HttpBackendManager, type(manager))
        eq_([
            ('delete', {'url': doc.uri()})
            ],
                self.mock_request.method_calls)
    def it_can_construct_different_uris_for_different_http_verbs(self):
        class Doc(Document):
            id = fields.NumberField()

            class Meta:
                backend_type = 'http'

            def post_uri(self):
                return 'post'

            def get_uri(self):
                return 'get'

            def uri(self):
                return 'uri'

        manager = BackendManager('http')
        doc = Doc({'id': 1})

        # First make sure we can retrieve the specific uri's for this http verb
        eq_('post', manager._get_uri('post', doc))
        eq_('get', manager._get_uri('get', doc))

        # And now return the generic uri for a non specified verb
        eq_('uri', manager._get_uri('put', doc))
    def it_can_construct_a_special_uri_for_delete_operations(self):
        class Doc(Document):
            id = fields.NumberField()

            class Meta:
                backend_type = 'http'

            def uri(self):
                return 'get'

            def delete_uri(self):
                return 'delete'

        manager = BackendManager('http')
        doc = Doc({'id': 1})

        expected = {'id': 1}

        response = Mock(name='mock_http_response')
        response.status_code = 200

        # set the return value of the GET request and the DELETE request
        self.mock_request.delete.return_value = response
        response.content = json.dumps(expected)
        self.mock_request.get.return_value = response

        # now make the fetch operation
        manager.delete(doc)

        # we should have made one GET and one PUT request
        eq_([('delete', {'url': 'delete'})],
                self.mock_request.method_calls)
    def it_can_fetch_resources_from_a_remote_endpoint(self):
        mock_resp = Mock(name="mock_response")
        expected = {'id': 1}
        mock_resp.content = json.dumps(expected)
        mock_resp.status_code = 200

        self.mock_request.get.return_value = mock_resp

        manager = BackendManager('http')

        class Doc(Document):
            id = fields.NumberField()

            class Meta:
                backend_type = 'http'

            def uri(self):
                return 'http://location'

        doc = Doc({'id': 1})

        # the http manager returns the response as python dict
        content = manager.fetch(doc)

        # make sure we are working with correct expectations
        eq_(HttpBackendManager, type(manager))
        eq_(mock_resp, manager.response)
        ok_(isinstance(content, dict))
        eq_([('get', {'url': doc.uri()})],
                self.mock_request.method_calls)
    def it_can_save_data_to_the_underlying_model(self):
        DjangoModel = Mock(name="DjangoModel")
        mock_model = Mock()
        DjangoModel.objects.get_or_create.return_value = (mock_model, False)

        manager = BackendManager("django")
        # The manager needs to know which model it connects to
        # This is normally done when the Document is created.
        manager._model = DjangoModel

        # make sure we are working with correct expectations
        eq_(DjangoBackendManager, type(manager))

        doc = Mock(name="mock_document", spec=Document)
        field = fields.NumberField()
        field.name = "id"
        doc.id = 1
        doc._context = {}
        doc._get_context.return_value = {}
        doc._meta.identifier = ["id"]
        doc._identifier_state.return_value = {"id": 1}
        doc._save.return_value = {"id": 1}
        doc._meta.local_fields = [field]

        # the manager.save() method doesn't return on success
        manager.save(doc)
        eq_([("objects.get", {"id": 1})], DjangoModel.method_calls)
    def it_can_return_a_django_m2m_relationship_as_collection(self):
        DjangoModel = Mock(name="DjangoModel")
        mock_model = Mock()
        mock_model.id = 1
        mock_model.get_absolute_url.return_value = "A"

        OtherModel = Mock(name="OtherMock")
        mock1 = Mock()
        mock1.id = 1
        mock1.get_absolute_url.return_value = "1"
        mock2 = Mock()
        mock2.id = 2
        mock2.get_absolute_url.return_value = "2"

        # This mocks a many2many relation ship, its not a queryset, just a list
        mock_model.others.all.return_value = [mock1, mock2]

        x = [mock2, mock1]

        def mock_side_effect(*args, **kwargs):
            return x.pop()

        OtherModel.objects.get.side_effect = mock_side_effect
        DjangoModel.objects.get.return_value = mock_model

        # Now create a simple document setup
        class OtherDoc(Document):
            id = fields.NumberField()

            class Meta:
                backend_type = "django"
                identifier = "id"
                model = OtherModel

        class OtherCollection(Collection):
            document = OtherDoc

        class Doc(Document):
            id = fields.NumberField()
            others = fields.CollectionField(OtherCollection)

            class Meta:
                backend_type = "django"
                identifier = "id"
                model = DjangoModel

        manager = BackendManager("django")
        # The manager needs to know which model it connects to
        # This is normally done when the Document is created.
        manager._model = DjangoModel

        # make sure we are working with correct expectations
        eq_(DjangoBackendManager, type(manager))

        doc = Doc({"id": 1})
        # doc.fetch()

        expected = {"id": 1, "others": [{"id": 1}, {"id": 2}]}
        eq_(expected, manager.fetch(doc))
Example #9
0
    def it_can_provide_a_link_using_the_django_model(self):
        mock_model = Mock()
        mock_model.get_absolute_url.return_value = "link"

        manager = BackendManager('django')
        manager.instance = mock_model

        eq_("link", manager.uri())
        eq_(True, mock_model.get_absolute_url.called)
    def it_can_create_new_remote_resources(self):
        mock_get = Mock(name="mock_get")
        mock_get.status_code = 404
        mock_get.content = ''
        expected = {'id': 1}
        mock_post = Mock(name="mock_post")
        mock_post.status_code = 201
        mock_post.content = json.dumps(expected)

        self.mock_request.get.return_value = mock_get
        self.mock_request.post.return_value = mock_post

        manager = BackendManager('http')

        class Doc(Document):
            id = fields.NumberField()

            class Meta:
                backend_type = 'http'

            def uri(self):
                return 'http://location'

            post_uri = uri

        doc = Doc({'id': 1})

        # create a new remote resource
        manager.save(doc)

        # creating a new resource should first return a 404 on a get request,
        # then a 201 on creation
        eq_([
            ('get', {'url': 'http://location'}),
            ('post', {'url': 'http://location',
                'data': json.dumps(expected)})],
            self.mock_request.method_calls)
 def it_can_fetch_save_and_delete_to_the_specific_backend_manager(self):
     with patch("docar.backends.DjangoBackendManager") as mock:
         mock_manager = Mock()
         mock_manager = mock.return_value
         manager = BackendManager("django")
         # first assert that the manager is really mocked
         ok_(isinstance(manager, Mock))
         manager.fetch()
         manager.save()
         manager.delete()
         eq_(True, mock_manager.fetch.called)
         eq_(True, mock_manager.save.called)
         eq_(True, mock_manager.delete.called)
    def it_can_take_credentials_as_arguments(self, mock_auth):
        auth_token = HTTPBasicAuth('crito', 'secret')
        mock_auth.return_value = auth_token

        mock_resp = Mock(name="mock_response")
        expected = {'id': 1}
        mock_resp.status_code = 200
        mock_resp.content = json.dumps(expected)

        self.mock_request.get.return_value = mock_resp
        self.mock_request.delete.return_value = mock_resp
        self.mock_request.put.return_value = mock_resp

        manager = BackendManager('http')

        class Doc(Document):
            id = fields.NumberField()

            class Meta:
                backend_type = 'http'

            def uri(self):
                return 'http://location'

        doc = Doc({'id': 1})

        # the http manager returns the response as python dict
        content = manager.fetch(doc, username='******', password='******')
        manager.delete(doc, username='******', password='******')
        manager.save(doc, username='******', password='******')

        # make sure we are working with correct expectations
        eq_(HttpBackendManager, type(manager))
        eq_(mock_resp, manager.response)
        ok_(isinstance(content, dict))
        eq_([
            ('get', {'url': doc.uri(), 'auth': auth_token}),
            ('delete', {'url': doc.uri(), 'auth': auth_token}),
            ('put', {'url': doc.uri(), 'data': '{"id": 1}',
                'auth': auth_token})],
                self.mock_request.method_calls)
    def it_can_delete_the_underlying_model_instance(self):
        DjangoModel = Mock(name="DjangoModel")
        mock_model = Mock()
        mock_model.id = 1
        DjangoModel.objects.get.return_value = mock_model

        manager = BackendManager('django')
        # The manager needs to know which model it connects to
        # This is normally done when the Document is created.
        manager._model = DjangoModel

        # make sure we are working with correct expectations
        eq_(DjangoBackendManager, type(manager))

        class Doc(Document):
            id = fields.NumberField()

            class Meta:
                backend_type = 'django'
                model = DjangoModel

        doc = Doc({'id': 1})

        manager.delete(doc)

        eq_([('objects.get', {'id': 1})], DjangoModel.method_calls)
        eq_([('delete',)], mock_model.method_calls)

        # If the model does not exist, nothing happens
        DjangoModel.reset_mock()
        mock_model.reset_mock()

        DjangoModel.DoesNotExist = Exception
        DjangoModel.objects.get.side_effect = DjangoModel.DoesNotExist

        manager.delete(doc)

        eq_([('objects.get', {'id': 1})], DjangoModel.method_calls)
        # no method of the model should have been called
        eq_([], mock_model.method_calls)