def get_pages(self, url): """ Given a URL return a tuple of: (previous page, current page, next page, previous url, next url) """ request = Request(factory.get(url)) queryset = self.pagination.paginate_queryset(self.queryset, request) current = [item['created'] for item in queryset] next_url = self.pagination.get_next_link() previous_url = self.pagination.get_previous_link() if next_url is not None: request = Request(factory.get(next_url)) queryset = self.pagination.paginate_queryset( self.queryset, request) next = [item['created'] for item in queryset] else: next = None if previous_url is not None: request = Request(factory.get(previous_url)) queryset = self.pagination.paginate_queryset( self.queryset, request) previous = [item['created'] for item in queryset] else: previous = None return (previous, current, next, previous_url, next_url)
def test_standard_behaviour_determines_form_content_PUT(self): """ Ensure request.data returns content for PUT request with form content. """ data = {'qwerty': 'uiop'} request = Request(factory.put('/', data)) request.parsers = (FormParser(), MultiPartParser()) assert list(request.data.items()) == list(data.items())
def test_request_POST_with_form_content(self): """ Ensure request.POST returns content for POST request with form content. """ data = {'qwerty': 'uiop'} request = Request(factory.post('/', data)) request.parsers = (FormParser(), MultiPartParser()) assert list(request.POST.items()) == list(data.items())
def test_request_type(self): request = Request(factory.get('/')) message = ( 'The `request` argument must be an instance of ' '`django.http.HttpRequest`, not `mind_core.request.Request`.') with self.assertRaisesMessage(AssertionError, message): Request(request)
def test_request_POST_with_files(self): """ Ensure request.POST returns no content for POST request with file content. """ upload = SimpleUploadedFile("file.txt", b"file_content") request = Request(factory.post('/', {'upload': upload})) request.parsers = (FormParser(), MultiPartParser()) assert list(request.POST) == [] assert list(request.FILES) == ['upload']
def test_standard_behaviour_determines_non_form_content_PUT(self): """ Ensure request.data returns content for PUT request with non-form content. """ content = six.b('qwerty') content_type = 'text/plain' request = Request(factory.put('/', content, content_type=content_type)) request.parsers = (PlainTextParser(), ) assert request.data == content
def test_get_cache_key_returns_correct_key_if_user_is_authenticated(self): class DummyView(object): throttle_scope = 'user' request = Request(HttpRequest()) user = User.objects.create(username='******') force_authenticate(request, user) request.user = user self.throttle.allow_request(request, DummyView()) cache_key = self.throttle.get_cache_key(request, view=DummyView()) assert cache_key == 'throttle_user_%s' % user.pk
def test_request_DATA_with_text_content(self): """ Ensure request.data returns content for POST request with non-form content. """ content = six.b('qwerty') content_type = 'text/plain' request = Request(factory.post('/', content, content_type=content_type)) request.parsers = (PlainTextParser(), ) assert request.data == content
def test_attribute_access_proxy(self): http_request = factory.get('/') request = Request(http_request) inner_sentinel = object() http_request.inner_property = inner_sentinel assert request.inner_property is inner_sentinel outer_sentinel = object() request.inner_property = outer_sentinel assert request.inner_property is outer_sentinel
def test_second_page(self): request = Request(factory.get('/', {'page': 2})) queryset = self.paginate_queryset(request) content = self.get_paginated_content(queryset) context = self.get_html_context() assert queryset == [6, 7, 8, 9, 10] assert content == { 'results': [6, 7, 8, 9, 10], 'previous': 'http://testserver/', 'next': 'http://testserver/?page=3', 'count': 100 } assert context == { 'previous_url': 'http://testserver/', 'next_url': 'http://testserver/?page=3', 'page_links': [ PageLink('http://testserver/', 1, False, False), PageLink('http://testserver/?page=2', 2, True, False), PageLink('http://testserver/?page=3', 3, False, False), PAGE_BREAK, PageLink('http://testserver/?page=20', 20, False, False), ] }
def test_static_renderer_with_exception(self): context = { 'response': Response(status=500, exception=True), 'request': Request(HttpRequest()) } result = self.renderer.render({}, renderer_context=context) assert result == '500 Internal Server Error'
def test_calling_user_fails_when_attribute_error_is_raised(self): """ This proves that when an AttributeError is raised inside of the request.user property, that we can handle this and report the true, underlying error. """ class AuthRaisesAttributeError(object): def authenticate(self, request): self.MISSPELLED_NAME_THAT_DOESNT_EXIST request = Request(self.wrapped_request, authenticators=(AuthRaisesAttributeError(), )) # The middleware processes the underlying Django request, sets anonymous user assert self.wrapped_request.user.is_anonymous # The DRF request object does not have a user and should run authenticators expected = r"no attribute 'MISSPELLED_NAME_THAT_DOESNT_EXIST'" with pytest.raises(WrappedAttributeError, match=expected): request.user # python 2 hasattr fails for *any* exception, not just AttributeError if six.PY2: return with pytest.raises(WrappedAttributeError, match=expected): hasattr(request, 'user') with pytest.raises(WrappedAttributeError, match=expected): login(request, self.user)
def test_ending_offset(self): request = Request(factory.get('/', {'limit': 5, 'offset': 95})) queryset = self.paginate_queryset(request) content = self.get_paginated_content(queryset) context = self.get_html_context() assert queryset == [96, 97, 98, 99, 100] assert content == { 'results': [96, 97, 98, 99, 100], 'previous': 'http://testserver/?limit=5&offset=90', 'next': None, 'count': 100 } assert context == { 'previous_url': 'http://testserver/?limit=5&offset=90', 'next_url': None, 'page_links': [ PageLink('http://testserver/?limit=5', 1, False, False), PAGE_BREAK, PageLink('http://testserver/?limit=5&offset=85', 18, False, False), PageLink('http://testserver/?limit=5&offset=90', 19, False, False), PageLink('http://testserver/?limit=5&offset=95', 20, True, False), ] }
def test_invalid_offset(self): """ An invalid offset query param should be treated as 0. """ request = Request(factory.get('/', {'limit': 5, 'offset': 'invalid'})) queryset = self.paginate_queryset(request) assert queryset == [1, 2, 3, 4, 5]
def test_single_offset(self): """ When the offset is not a multiple of the limit we get some edge cases: * The first page should still be offset zero. * We may end up displaying an extra page in the pagination control. """ request = Request(factory.get('/', {'limit': 5, 'offset': 1})) queryset = self.paginate_queryset(request) content = self.get_paginated_content(queryset) context = self.get_html_context() assert queryset == [2, 3, 4, 5, 6] assert content == { 'results': [2, 3, 4, 5, 6], 'previous': 'http://testserver/?limit=5', 'next': 'http://testserver/?limit=5&offset=6', 'count': 100 } assert context == { 'previous_url': 'http://testserver/?limit=5', 'next_url': 'http://testserver/?limit=5&offset=6', 'page_links': [ PageLink('http://testserver/?limit=5', 1, False, False), PageLink('http://testserver/?limit=5&offset=1', 2, True, False), PageLink('http://testserver/?limit=5&offset=6', 3, False, False), PAGE_BREAK, PageLink('http://testserver/?limit=5&offset=96', 21, False, False), ] }
def test_middle_offset(self): request = Request(factory.get('/', {'limit': 5, 'offset': 10})) queryset = self.paginate_queryset(request) content = self.get_paginated_content(queryset) context = self.get_html_context() assert queryset == [11, 12, 13, 14, 15] assert content == { 'results': [11, 12, 13, 14, 15], 'previous': 'http://testserver/?limit=5&offset=5', 'next': 'http://testserver/?limit=5&offset=15', 'count': 100 } assert context == { 'previous_url': 'http://testserver/?limit=5&offset=5', 'next_url': 'http://testserver/?limit=5&offset=15', 'page_links': [ PageLink('http://testserver/?limit=5', 1, False, False), PageLink('http://testserver/?limit=5&offset=5', 2, False, False), PageLink('http://testserver/?limit=5&offset=10', 3, True, False), PageLink('http://testserver/?limit=5&offset=15', 4, False, False), PAGE_BREAK, PageLink('http://testserver/?limit=5&offset=95', 20, False, False), ] }
def test_no_offset(self): request = Request(factory.get('/', {'limit': 5})) queryset = self.paginate_queryset(request) content = self.get_paginated_content(queryset) context = self.get_html_context() assert queryset == [1, 2, 3, 4, 5] assert content == { 'results': [1, 2, 3, 4, 5], 'previous': None, 'next': 'http://testserver/?limit=5&offset=5', 'count': 100 } assert context == { 'previous_url': None, 'next_url': 'http://testserver/?limit=5&offset=5', 'page_links': [ PageLink('http://testserver/?limit=5', 1, True, False), PageLink('http://testserver/?limit=5&offset=5', 2, False, False), PageLink('http://testserver/?limit=5&offset=10', 3, False, False), PAGE_BREAK, PageLink('http://testserver/?limit=5&offset=95', 20, False, False), ] } assert self.pagination.display_page_controls assert isinstance(self.pagination.to_html(), six.text_type)
def test_pagination_not_applied_if_limit_or_default_limit_not_set(self): class MockPagination(pagination.LimitOffsetPagination): default_limit = None request = Request(factory.get('/')) queryset = MockPagination().paginate_queryset(self.queryset, request) assert queryset is None
def test_client_specifies_parameter(self): request = Request( factory.get('/', HTTP_ACCEPT='application/openapi+json;version=2.0')) accepted_renderer, accepted_media_type = self.select_renderer(request) assert accepted_media_type == 'application/openapi+json;version=2.0' assert accepted_renderer.format == 'swagger'
def test_last_page(self): request = Request(factory.get('/', {'page': 'last'})) queryset = self.paginate_queryset(request) content = self.get_paginated_content(queryset) context = self.get_html_context() assert queryset == [96, 97, 98, 99, 100] assert content == { 'results': [96, 97, 98, 99, 100], 'previous': 'http://testserver/?page=19', 'next': None, 'count': 100 } assert context == { 'previous_url': 'http://testserver/?page=19', 'next_url': None, 'page_links': [ PageLink('http://testserver/', 1, False, False), PAGE_BREAK, PageLink('http://testserver/?page=18', 18, False, False), PageLink('http://testserver/?page=19', 19, False, False), PageLink('http://testserver/?page=20', 20, True, False), ] }
def test_exception_proxy(self): # ensure the exception message is not for the underlying WSGIRequest http_request = factory.get('/') request = Request(http_request) message = "'Request' object has no attribute 'inner_property'" with self.assertRaisesMessage(AttributeError, message): request.inner_property
def test_post_accessed_in_put_method(self): django_request = self.factory.put('/', {'foo': 'bar'}) request = Request(django_request, parsers=[FormParser(), MultiPartParser()]) django_request.POST assert request.POST == {'foo': ['bar']} assert request.data == {'foo': ['bar']}
def test_use_with_ordering_filter(self): class MockView: filter_backends = (filters.OrderingFilter, ) ordering_fields = ['username', 'created'] ordering = 'created' request = Request(factory.get('/', {'ordering': 'username'})) ordering = self.pagination.get_ordering(request, [], MockView()) assert ordering == ('username', ) request = Request(factory.get('/', {'ordering': '-username'})) ordering = self.pagination.get_ordering(request, [], MockView()) assert ordering == ('-username', ) request = Request(factory.get('/', {'ordering': 'invalid'})) ordering = self.pagination.get_ordering(request, [], MockView()) assert ordering == ('created', )
def test_render_when_resource_created(self): class DummyView(APIView): renderer_classes = (AdminRenderer, ) request = Request(HttpRequest()) request.build_absolute_uri = lambda: 'http://example.com' response = Response(status=201, headers={'Location': '/test'}) context = { 'view': DummyView(), 'request': request, 'response': response } result = self.renderer.render(data={'test': 'test'}, renderer_context=context) assert result == '' assert response.status_code == status.HTTP_303_SEE_OTHER assert response['Location'] == 'http://example.com'
def setUp(self): # Pass request object through session middleware so session is # available to login and logout functions self.wrapped_request = factory.get('/') self.request = Request(self.wrapped_request) SessionMiddleware().process_request(self.wrapped_request) AuthenticationMiddleware().process_request(self.wrapped_request) User.objects.create_user('ringo', '*****@*****.**', 'yellow') self.user = authenticate(username='******', password='******')
def test_request_read_before_parsing(self): django_request = self.factory.put('/', {'foo': 'bar'}) request = Request(django_request, parsers=[FormParser(), MultiPartParser()]) django_request.read() with pytest.raises(RawPostDataException): request.POST with pytest.raises(RawPostDataException): request.POST request.data
def initialize_request(self, request, *args, **kwargs): """ Returns the initial request object. """ parser_context = self.get_parser_context(request) return Request(request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context)
def test_zero_limit(self): """ An zero limit query param should be ignored in favor of the default. """ request = Request(factory.get('/', {'limit': 0, 'offset': 0})) queryset = self.paginate_queryset(request) content = self.get_paginated_content(queryset) next_limit = self.pagination.default_limit next_offset = self.pagination.default_limit next_url = 'http://testserver/?limit={0}&offset={1}'.format( next_limit, next_offset) assert queryset == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] assert content.get('next') == next_url
def test_get_context_result_urls(self): factory = APIRequestFactory() class DummyView(APIView): lookup_field = 'test' def reverse_action(view, url_name, args=None, kwargs=None): return '/%s/%d' % (url_name, kwargs['test']) # get the view instance instead of the view function view = DummyView.as_view() request = factory.get('/') response = view(request) data = [ { 'test': 1 }, { 'url': '/example', 'test': 2 }, { 'url': None, 'test': 3 }, {}, ] context = { 'view': DummyView(), 'request': Request(request), 'response': response } context = self.renderer.get_context(data, None, context) results = context['results'] self.assertEqual(len(results), 4) self.assertEqual(results[0]['url'], '/detail/1') self.assertEqual(results[1]['url'], '/example') self.assertEqual(results[2]['url'], None) self.assertNotIn('url', results[3])
def test_max_limit(self): """ The limit defaults to the max_limit when there is a max_limit and the requested limit is greater than the max_limit """ offset = 50 request = Request( factory.get('/', { 'limit': '11235', 'offset': offset })) queryset = self.paginate_queryset(request) content = self.get_paginated_content(queryset) max_limit = self.pagination.max_limit next_offset = offset + max_limit prev_offset = offset - max_limit base_url = 'http://testserver/?limit={0}'.format(max_limit) next_url = base_url + '&offset={0}'.format(next_offset) prev_url = base_url + '&offset={0}'.format(prev_offset) assert queryset == list(range(51, 66)) assert content.get('next') == next_url assert content.get('previous') == prev_url