def test_request_factory_url_arguments(self): """ This is a non regression test against #1461 """ factory = APIRequestFactory() request = factory.get('/view/?demo=test') assert dict(request.GET) == {'demo': ['test']} request = factory.get('/view/', {'demo': 'test'}) assert dict(request.GET) == {'demo': ['test']}
def _resolve_urlpatterns(self, urlpatterns, test_paths, allowed=None): factory = APIRequestFactory() try: urlpatterns = format_suffix_patterns(urlpatterns, allowed=allowed) except Exception: self.fail( "Failed to apply `format_suffix_patterns` on the supplied urlpatterns" ) resolver = make_url_resolver(r'^/', urlpatterns) for test_path in test_paths: try: test_path, expected_resolved = test_path except (TypeError, ValueError): expected_resolved = True request = factory.get(test_path.path) try: callback, callback_args, callback_kwargs = resolver.resolve( request.path_info) except Resolver404: callback, callback_args, callback_kwargs = (None, None, None) if expected_resolved: raise except Exception: self.fail("Failed to resolve URL: %s" % request.path_info) if not expected_resolved: assert callback is None continue assert callback_args == test_path.args assert callback_kwargs == test_path.kwargs
def test_document_with_link_named_data(self): """ Ref #5395: Doc's `document.data` would fail with a Link named "data". As per #4972, use templatetag instead. """ document = coreapi.Document(title='Data Endpoint API', url='https://api.example.org/', content={ 'data': coreapi.Link( url='/data/', action='get', fields=[], description='Return data.') }) factory = APIRequestFactory() request = factory.get('/') renderer = DocumentationRenderer() html = renderer.render(document, accepted_media_type="text/html", renderer_context={"request": request}) assert '<h1>Data Endpoint API</h1>' in html
def test_force_authenticate(self): """ Setting `force_authenticate()` forcibly authenticates the request. """ user = User.objects.create_user('example', '*****@*****.**') factory = APIRequestFactory() request = factory.get('/view') force_authenticate(request, user=user) response = view(request) assert response.data['user'] == 'example'
def test_schemajs_output(self): """ Test output of the SchemaJS renderer as per #5608. Django 2.0 on Py3 prints binary data as b'xyz' in templates, and the base64 encoding used by SchemaJSRenderer outputs base64 as binary. Test fix. """ factory = APIRequestFactory() request = factory.get('/') renderer = SchemaJSRenderer() output = renderer.render('data', renderer_context={"request": request}) assert "'ImRhdGEi'" in output assert "'b'ImRhdGEi''" not in output
def test_get_result_url_no_result(self): factory = APIRequestFactory() class DummyView(APIView): lookup_field = 'test' # get the view instance instead of the view function view = DummyView.as_view() request = factory.get('/') response = view(request) view = response.renderer_context['view'] self.assertIsNone(self.renderer.get_result_url({'test': 1}, view)) self.assertIsNone(self.renderer.get_result_url({}, view))
def test_render_dict_with_iteritems_key(self): factory = APIRequestFactory() class DummyView(APIView): renderer_classes = (AdminRenderer, ) def get(self, request): return Response({'iteritems': 'a string'}) view = DummyView.as_view() request = factory.get('/') response = view(request) response.render() self.assertContains(response, '<tr><th>Iteritems</th><td>a string</td></tr>', html=True)
def test_get_result_url(self): factory = APIRequestFactory() class DummyGenericViewsetLike(APIView): lookup_field = 'test' def reverse_action(view, *args, **kwargs): self.assertEqual(kwargs['kwargs']['test'], 1) return '/example/' # get the view instance instead of the view function view = DummyGenericViewsetLike.as_view() request = factory.get('/') response = view(request) view = response.renderer_context['view'] self.assertEqual(self.renderer.get_result_url({'test': 1}, view), '/example/') self.assertIsNone(self.renderer.get_result_url({}, view))
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])
from __future__ import unicode_literals from django.conf.urls import url from django.test import TestCase, override_settings from mind_core import serializers from mind_core.test import APIRequestFactory from tests.models import (ForeignKeySource, ForeignKeyTarget, ManyToManySource, ManyToManyTarget, NullableForeignKeySource, NullableOneToOneSource, OneToOneTarget) factory = APIRequestFactory() request = factory.get( '/') # Just to ensure we have a request in the serializer context def dummy_view(request, pk): pass urlpatterns = [ url(r'^dummyurl/(?P<pk>[0-9]+)/$', dummy_view, name='dummy-url'), url(r'^manytomanysource/(?P<pk>[0-9]+)/$', dummy_view, name='manytomanysource-detail'), url(r'^manytomanytarget/(?P<pk>[0-9]+)/$', dummy_view, name='manytomanytarget-detail'), url(r'^foreignkeysource/(?P<pk>[0-9]+)/$', dummy_view, name='foreignkeysource-detail'),
class DecoratorTestCase(TestCase): def setUp(self): self.factory = APIRequestFactory() def _finalize_response(self, request, response, *args, **kwargs): response.request = request return APIView.finalize_response(self, request, response, *args, **kwargs) def test_api_view_incorrect(self): """ If @api_view is not applied correct, we should raise an assertion. """ @api_view def view(request): return Response() request = self.factory.get('/') self.assertRaises(AssertionError, view, request) def test_api_view_incorrect_arguments(self): """ If @api_view is missing arguments, we should raise an assertion. """ with self.assertRaises(AssertionError): @api_view('GET') def view(request): return Response() def test_calling_method(self): @api_view(['GET']) def view(request): return Response({}) request = self.factory.get('/') response = view(request) assert response.status_code == status.HTTP_200_OK request = self.factory.post('/') response = view(request) assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED def test_calling_put_method(self): @api_view(['GET', 'PUT']) def view(request): return Response({}) request = self.factory.put('/') response = view(request) assert response.status_code == status.HTTP_200_OK request = self.factory.post('/') response = view(request) assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED def test_calling_patch_method(self): @api_view(['GET', 'PATCH']) def view(request): return Response({}) request = self.factory.patch('/') response = view(request) assert response.status_code == status.HTTP_200_OK request = self.factory.post('/') response = view(request) assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED def test_renderer_classes(self): @api_view(['GET']) @renderer_classes([JSONRenderer]) def view(request): return Response({}) request = self.factory.get('/') response = view(request) assert isinstance(response.accepted_renderer, JSONRenderer) def test_parser_classes(self): @api_view(['GET']) @parser_classes([JSONParser]) def view(request): assert len(request.parsers) == 1 assert isinstance(request.parsers[0], JSONParser) return Response({}) request = self.factory.get('/') view(request) def test_authentication_classes(self): @api_view(['GET']) @authentication_classes([BasicAuthentication]) def view(request): assert len(request.authenticators) == 1 assert isinstance(request.authenticators[0], BasicAuthentication) return Response({}) request = self.factory.get('/') view(request) def test_permission_classes(self): @api_view(['GET']) @permission_classes([IsAuthenticated]) def view(request): return Response({}) request = self.factory.get('/') response = view(request) assert response.status_code == status.HTTP_403_FORBIDDEN def test_throttle_classes(self): class OncePerDayUserThrottle(UserRateThrottle): rate = '1/day' @api_view(['GET']) @throttle_classes([OncePerDayUserThrottle]) def view(request): return Response({}) request = self.factory.get('/') response = view(request) assert response.status_code == status.HTTP_200_OK response = view(request) assert response.status_code == status.HTTP_429_TOO_MANY_REQUESTS def test_schema(self): """ Checks CustomSchema class is set on view """ class CustomSchema(AutoSchema): pass @api_view(['GET']) @schema(CustomSchema()) def view(request): return Response({}) assert isinstance(view.cls.schema, CustomSchema)
class ThrottlingTests(TestCase): def setUp(self): """ Reset the cache so that no throttles will be active """ cache.clear() self.factory = APIRequestFactory() def test_requests_are_throttled(self): """ Ensure request rate is limited """ request = self.factory.get('/') for dummy in range(4): response = MockView.as_view()(request) assert response.status_code == 429 def set_throttle_timer(self, view, value): """ Explicitly set the timer, overriding time.time() """ view.throttle_classes[0].timer = lambda self: value def test_request_throttling_expires(self): """ Ensure request rate is limited for a limited duration only """ self.set_throttle_timer(MockView, 0) request = self.factory.get('/') for dummy in range(4): response = MockView.as_view()(request) assert response.status_code == 429 # Advance the timer by one second self.set_throttle_timer(MockView, 1) response = MockView.as_view()(request) assert response.status_code == 200 def ensure_is_throttled(self, view, expect): request = self.factory.get('/') request.user = User.objects.create(username='******') for dummy in range(3): view.as_view()(request) request.user = User.objects.create(username='******') response = view.as_view()(request) assert response.status_code == expect def test_request_throttling_is_per_user(self): """ Ensure request rate is only limited per user, not globally for PerUserThrottles """ self.ensure_is_throttled(MockView, 200) def ensure_response_header_contains_proper_throttle_field( self, view, expected_headers): """ Ensure the response returns an Retry-After field with status and next attributes set properly. """ request = self.factory.get('/') for timer, expect in expected_headers: self.set_throttle_timer(view, timer) response = view.as_view()(request) if expect is not None: assert response['Retry-After'] == expect else: assert not 'Retry-After' in response def test_seconds_fields(self): """ Ensure for second based throttles. """ self.ensure_response_header_contains_proper_throttle_field( MockView, ((0, None), (0, None), (0, None), (0, '1'))) def test_minutes_fields(self): """ Ensure for minute based throttles. """ self.ensure_response_header_contains_proper_throttle_field( MockView_MinuteThrottling, ((0, None), (0, None), (0, None), (0, '60'))) def test_next_rate_remains_constant_if_followed(self): """ If a client follows the recommended next request rate, the throttling rate should stay constant. """ self.ensure_response_header_contains_proper_throttle_field( MockView_MinuteThrottling, ((0, None), (20, None), (40, None), (60, None), (80, None))) def test_non_time_throttle(self): """ Ensure for second based throttles. """ request = self.factory.get('/') self.assertFalse( hasattr(MockView_NonTimeThrottling.throttle_classes[0], 'called')) response = MockView_NonTimeThrottling.as_view()(request) self.assertFalse('Retry-After' in response) self.assertTrue(MockView_NonTimeThrottling.throttle_classes[0].called) response = MockView_NonTimeThrottling.as_view()(request) self.assertFalse('Retry-After' in response)
class ScopedRateThrottleTests(TestCase): """ Tests for ScopedRateThrottle. """ def setUp(self): self.throttle = ScopedRateThrottle() class XYScopedRateThrottle(ScopedRateThrottle): TIMER_SECONDS = 0 THROTTLE_RATES = {'x': '3/min', 'y': '1/min'} def timer(self): return self.TIMER_SECONDS class XView(APIView): throttle_classes = (XYScopedRateThrottle, ) throttle_scope = 'x' def get(self, request): return Response('x') class YView(APIView): throttle_classes = (XYScopedRateThrottle, ) throttle_scope = 'y' def get(self, request): return Response('y') class UnscopedView(APIView): throttle_classes = (XYScopedRateThrottle, ) def get(self, request): return Response('y') self.throttle_class = XYScopedRateThrottle self.factory = APIRequestFactory() self.x_view = XView.as_view() self.y_view = YView.as_view() self.unscoped_view = UnscopedView.as_view() def increment_timer(self, seconds=1): self.throttle_class.TIMER_SECONDS += seconds def test_scoped_rate_throttle(self): request = self.factory.get('/') # Should be able to hit x view 3 times per minute. response = self.x_view(request) assert response.status_code == 200 self.increment_timer() response = self.x_view(request) assert response.status_code == 200 self.increment_timer() response = self.x_view(request) assert response.status_code == 200 self.increment_timer() response = self.x_view(request) assert response.status_code == 429 # Should be able to hit y view 1 time per minute. self.increment_timer() response = self.y_view(request) assert response.status_code == 200 self.increment_timer() response = self.y_view(request) assert response.status_code == 429 # Ensure throttles properly reset by advancing the rest of the minute self.increment_timer(55) # Should still be able to hit x view 3 times per minute. response = self.x_view(request) assert response.status_code == 200 self.increment_timer() response = self.x_view(request) assert response.status_code == 200 self.increment_timer() response = self.x_view(request) assert response.status_code == 200 self.increment_timer() response = self.x_view(request) assert response.status_code == 429 # Should still be able to hit y view 1 time per minute. self.increment_timer() response = self.y_view(request) assert response.status_code == 200 self.increment_timer() response = self.y_view(request) assert response.status_code == 429 def test_unscoped_view_not_throttled(self): request = self.factory.get('/') for idx in range(10): self.increment_timer() response = self.unscoped_view(request) assert response.status_code == 200 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_factory_url_arguments_with_unicode(self): factory = APIRequestFactory() request = factory.get('/view/?demo=testé') assert dict(request.GET) == {'demo': ['testé']} request = factory.get('/view/', {'demo': 'testé'}) assert dict(request.GET) == {'demo': ['testé']}