class UserAgentMungingTest(TestCase): """ We need to fake up the accept headers when we deal with MSIE. Blergh. http://www.gethifi.com/blog/browser-rest-http-accept-headers """ urls = "djangorestframework.tests.accept" def setUp(self): class MockView(View): permissions = () def get(self, request): return {"a": 1, "b": 2, "c": 3} self.req = RequestFactory() self.MockView = MockView self.view = MockView.as_view() def test_munge_msie_accept_header(self): """Send MSIE user agent strings and ensure that we get an HTML response, even if we set a */* accept header.""" for user_agent in (MSIE_9_USER_AGENT, MSIE_8_USER_AGENT, MSIE_7_USER_AGENT): req = self.req.get("/", HTTP_ACCEPT="*/*", HTTP_USER_AGENT=user_agent) resp = self.view(req) self.assertEqual(resp["Content-Type"], "text/html") def test_dont_munge_msie_with_x_requested_with_header(self): """Send MSIE user agent strings, and an X-Requested-With header, and ensure that we get a JSON response if we set a */* Accept header.""" for user_agent in (MSIE_9_USER_AGENT, MSIE_8_USER_AGENT, MSIE_7_USER_AGENT): req = self.req.get( "/", HTTP_ACCEPT="*/*", HTTP_USER_AGENT=user_agent, HTTP_X_REQUESTED_WITH="XMLHttpRequest" ) resp = self.view(req) self.assertEqual(resp["Content-Type"], "application/json") def test_dont_rewrite_msie_accept_header(self): """Turn off _IGNORE_IE_ACCEPT_HEADER, send MSIE user agent strings and ensure that we get a JSON response if we set a */* accept header.""" view = self.MockView.as_view(_IGNORE_IE_ACCEPT_HEADER=False) for user_agent in (MSIE_9_USER_AGENT, MSIE_8_USER_AGENT, MSIE_7_USER_AGENT): req = self.req.get("/", HTTP_ACCEPT="*/*", HTTP_USER_AGENT=user_agent) resp = view(req) self.assertEqual(resp["Content-Type"], "application/json") def test_dont_munge_nice_browsers_accept_header(self): """Send Non-MSIE user agent strings and ensure that we get a JSON response, if we set a */* Accept header. (Other browsers will correctly set the Accept header)""" for user_agent in ( FIREFOX_4_0_USER_AGENT, CHROME_11_0_USER_AGENT, SAFARI_5_0_USER_AGENT, OPERA_11_0_MSIE_USER_AGENT, OPERA_11_0_OPERA_USER_AGENT, ): req = self.req.get("/", HTTP_ACCEPT="*/*", HTTP_USER_AGENT=user_agent) resp = self.view(req) self.assertEqual(resp["Content-Type"], "application/json")
class TestModelRead(TestModelsTestCase): """Tests on ReadModelMixin""" def setUp(self): super(TestModelRead, self).setUp() self.req = RequestFactory() def test_read(self): Group.objects.create(name='other group') group = Group.objects.create(name='my group') class GroupResource(ModelResource): model = Group request = self.req.get('/groups') mixin = ReadModelMixin() mixin.resource = GroupResource response = mixin.get(request, id=group.id) self.assertEquals(group.name, response.name) def test_read_404(self): class GroupResource(ModelResource): model = Group request = self.req.get('/groups') mixin = ReadModelMixin() mixin.resource = GroupResource self.assertRaises(ErrorResponse, mixin.get, request, id=12345)
class TestMethodOverloading(TestCase): def setUp(self): self.req = RequestFactory() def test_standard_behaviour_determines_GET(self): """GET requests identified""" view = RequestMixin() view.request = self.req.get('/') self.assertEqual(view.method, 'GET') def test_standard_behaviour_determines_POST(self): """POST requests identified""" view = RequestMixin() view.request = self.req.post('/') self.assertEqual(view.method, 'POST') def test_overloaded_POST_behaviour_determines_overloaded_method(self): """POST requests can be overloaded to another method by setting a reserved form field""" view = RequestMixin() view.request = self.req.post('/', {view._METHOD_PARAM: 'DELETE'}) self.assertEqual(view.method, 'DELETE') def test_HEAD_is_a_valid_method(self): """HEAD requests identified""" view = RequestMixin() view.request = self.req.head('/') self.assertEqual(view.method, 'HEAD')
def setUp(self): class MockView(View): permissions = () def get(self, request): return {'a': 1, 'b': 2, 'c': 3} self.req = RequestFactory() self.MockView = MockView self.view = MockView.as_view()
class UserAgentMungingTest(TestCase): """ We need to fake up the accept headers when we deal with MSIE. Blergh. http://www.gethifi.com/blog/browser-rest-http-accept-headers """ urls = 'djangorestframework.tests.accept' def setUp(self): class MockView(View): permissions = () def get(self, request): return {'a':1, 'b':2, 'c':3} self.req = RequestFactory() self.MockView = MockView self.view = MockView.as_view() def test_munge_msie_accept_header(self): """Send MSIE user agent strings and ensure that we get an HTML response, even if we set a */* accept header.""" for user_agent in (MSIE_9_USER_AGENT, MSIE_8_USER_AGENT, MSIE_7_USER_AGENT): req = self.req.get('/', HTTP_ACCEPT='*/*', HTTP_USER_AGENT=user_agent) resp = self.view(req) self.assertEqual(resp['Content-Type'], 'text/html') def test_dont_rewrite_msie_accept_header(self): """Turn off _IGNORE_IE_ACCEPT_HEADER, send MSIE user agent strings and ensure that we get a JSON response if we set a */* accept header.""" view = self.MockView.as_view(_IGNORE_IE_ACCEPT_HEADER=False) for user_agent in (MSIE_9_USER_AGENT, MSIE_8_USER_AGENT, MSIE_7_USER_AGENT): req = self.req.get('/', HTTP_ACCEPT='*/*', HTTP_USER_AGENT=user_agent) resp = view(req) self.assertEqual(resp['Content-Type'], 'application/json') def test_dont_munge_nice_browsers_accept_header(self): """Send Non-MSIE user agent strings and ensure that we get a JSON response, if we set a */* Accept header. (Other browsers will correctly set the Accept header)""" for user_agent in (FIREFOX_4_0_USER_AGENT, CHROME_11_0_USER_AGENT, SAFARI_5_0_USER_AGENT, OPERA_11_0_MSIE_USER_AGENT, OPERA_11_0_OPERA_USER_AGENT): req = self.req.get('/', HTTP_ACCEPT='*/*', HTTP_USER_AGENT=user_agent) resp = self.view(req) self.assertEqual(resp['Content-Type'], 'application/json')
class UserAgentMungingTest(TestCase): """We need to fake up the accept headers when we deal with MSIE. Blergh. http://www.gethifi.com/blog/browser-rest-http-accept-headers""" def setUp(self): class MockView(View): permissions = () def get(self, request): return {'a': 1, 'b': 2, 'c': 3} self.req = RequestFactory() self.MockView = MockView self.view = MockView.as_view() def test_munge_msie_accept_header(self): """Send MSIE user agent strings and ensure that we get an HTML response, even if we set a */* accept header.""" for user_agent in (MSIE_9_USER_AGENT, MSIE_8_USER_AGENT, MSIE_7_USER_AGENT): req = self.req.get('/', HTTP_ACCEPT='*/*', HTTP_USER_AGENT=user_agent) resp = self.view(req) self.assertEqual(resp['Content-Type'], 'text/html') def test_dont_rewrite_msie_accept_header(self): """Turn off _IGNORE_IE_ACCEPT_HEADER, send MSIE user agent strings and ensure that we get a JSON response if we set a */* accept header.""" view = self.MockView.as_view(_IGNORE_IE_ACCEPT_HEADER=False) for user_agent in (MSIE_9_USER_AGENT, MSIE_8_USER_AGENT, MSIE_7_USER_AGENT): req = self.req.get('/', HTTP_ACCEPT='*/*', HTTP_USER_AGENT=user_agent) resp = view(req) self.assertEqual(resp['Content-Type'], 'application/json') def test_dont_munge_nice_browsers_accept_header(self): """Send Non-MSIE user agent strings and ensure that we get a JSON response, if we set a */* Accept header. (Other browsers will correctly set the Accept header)""" for user_agent in (FIREFOX_4_0_USER_AGENT, CHROME_11_0_USER_AGENT, SAFARI_5_0_USER_AGENT, OPERA_11_0_MSIE_USER_AGENT, OPERA_11_0_OPERA_USER_AGENT): req = self.req.get('/', HTTP_ACCEPT='*/*', HTTP_USER_AGENT=user_agent) resp = self.view(req) self.assertEqual(resp['Content-Type'], 'application/json')
class UploadFilesTests(TestCase): """Check uploading of files""" def setUp(self): self.factory = RequestFactory() def test_upload_file(self): class FileForm(forms.Form): file = forms.FileField() class MockView(View): permissions = () form = FileForm def post(self, request, *args, **kwargs): return { 'FILE_NAME': self.CONTENT['file'].name, 'FILE_CONTENT': self.CONTENT['file'].read() } file = StringIO.StringIO('stuff') file.name = 'stuff.txt' request = self.factory.post('/', {'file': file}) view = MockView.as_view() response = view(request) self.assertEquals( response.content, '{"FILE_CONTENT": "stuff", "FILE_NAME": "stuff.txt"}')
class UploadFilesTests(TestCase): """Check uploading of files""" def setUp(self): self.factory = RequestFactory() def test_upload_file(self): class FileForm(forms.Form): file = forms.FileField() class MockView(View): permissions = () form = FileForm def post(self, request, *args, **kwargs): return {'FILE_NAME': self.CONTENT['file'].name, 'FILE_CONTENT': self.CONTENT['file'].read()} file = StringIO('stuff') file.name = 'stuff.txt' request = self.factory.post('/', {'file': file}) view = MockView.as_view() response = view(request) self.assertEquals( json.loads(response.content), json.loads('{"FILE_CONTENT": "stuff", "FILE_NAME": "stuff.txt"}') )
def setUp(self): self.csrf_client = Client(enforce_csrf_checks=True) self.username = '******' self.email = '*****@*****.**' self.password = '******' self.user = User.objects.create_user(self.username, self.email, self.password) self.req = RequestFactory()
class TestRotation(TestCase): """For the example the maximum amount of Blogposts is capped off at views.MAX_POSTS. Whenever a new Blogpost is posted the oldest one should be popped.""" def setUp(self): self.factory = RequestFactory() models.BlogPost.objects.all().delete() def test_get_to_root(self): '''Simple get to the *root* url of blogposts''' request = self.factory.get('/blog-post') view = ListOrCreateModelView.as_view(resource=urls.BlogPostResource) response = view(request) self.assertEqual(response.status_code, 200) def test_blogposts_not_exceed_MAX_POSTS(self): '''Posting blog-posts should not result in more than MAX_POSTS items stored.''' for post in range(models.MAX_POSTS + 5): form_data = { 'title': 'This is post #%s' % post, 'content': 'This is the content of post #%s' % post } request = self.factory.post('/blog-post', data=form_data) view = ListOrCreateModelView.as_view( resource=urls.BlogPostResource) view(request) self.assertEquals(len(models.BlogPost.objects.all()), models.MAX_POSTS) def test_fifo_behaviour(self): '''It's fine that the Blogposts are capped off at MAX_POSTS. But we want to make sure we see FIFO behaviour.''' for post in range(15): form_data = { 'title': '%s' % post, 'content': 'This is the content of post #%s' % post } request = self.factory.post('/blog-post', data=form_data) view = ListOrCreateModelView.as_view( resource=urls.BlogPostResource) view(request) request = self.factory.get('/blog-post') view = ListOrCreateModelView.as_view(resource=urls.BlogPostResource) response = view(request) response_posts = json.loads(response.content) response_titles = [d['title'] for d in response_posts] response_titles.reverse() self.assertEquals(response_titles, [ '%s' % i for i in range(models.MAX_POSTS - 5, models.MAX_POSTS + 5) ])
def setUp(self): class MockView(View): permissions = () def get(self, request): return {"a": 1, "b": 2, "c": 3} self.req = RequestFactory() self.MockView = MockView self.view = MockView.as_view()
def setUp(self): class MockView(View): permissions = () def get(self, request): return {'a':1, 'b':2, 'c':3} self.req = RequestFactory() self.MockView = MockView self.view = MockView.as_view()
class TestPygmentsExample(TestCase): def setUp(self): self.factory = RequestFactory() self.temp_dir = tempfile.mkdtemp() views.HIGHLIGHTED_CODE_DIR = self.temp_dir def tearDown(self): try: shutil.rmtree(self.temp_dir) except: pass def test_get_to_root(self): '''Just do a get on the base url''' request = self.factory.get('/pygments') view = views.PygmentsRoot.as_view() response = view(request) self.assertEqual(response.status_code, 200) def test_snippets_datetime_sorted(self): '''Pygments examples should be datetime sorted''' locations = [] for snippet in 'abcdefghij': # String length must not exceed views.MAX_FILES, otherwise test fails form_data = {'code': '%s' % snippet, 'style':'friendly', 'lexer':'python'} request = self.factory.post('/pygments', data=form_data) view = views.PygmentsRoot.as_view() response = view(request) locations.append(response.items()[2][1]) import time time.sleep(.1) request = self.factory.get('/pygments') view = views.PygmentsRoot.as_view() response = view(request) response_locations = json.loads(response.content) self.assertEquals(locations, response_locations)
class TestPygmentsExample(TestCase): def setUp(self): self.factory = RequestFactory() self.temp_dir = tempfile.mkdtemp() views.HIGHLIGHTED_CODE_DIR = self.temp_dir def tearDown(self): try: shutil.rmtree(self.temp_dir) except: pass def test_get_to_root(self): '''Just do a get on the base url''' request = self.factory.get('/pygments') view = views.PygmentsRoot.as_view() response = view(request) self.assertEqual(response.status_code, 200) def test_snippets_datetime_sorted(self): '''Pygments examples should be datetime sorted''' locations = [] for snippet in 'abcdefghij': # String length must not exceed views.MAX_FILES, otherwise test fails form_data = { 'code': '%s' % snippet, 'style': 'friendly', 'lexer': 'python' } request = self.factory.post('/pygments', data=form_data) view = views.PygmentsRoot.as_view() response = view(request) locations.append(response.items()[2][1]) import time time.sleep(.1) request = self.factory.get('/pygments') view = views.PygmentsRoot.as_view() response = view(request) response_locations = json.loads(response.content) self.assertEquals(locations, response_locations)
class TestRotation(TestCase): """For the example the maximum amount of Blogposts is capped off at views.MAX_POSTS. Whenever a new Blogpost is posted the oldest one should be popped.""" def setUp(self): self.factory = RequestFactory() models.BlogPost.objects.all().delete() def test_get_to_root(self): '''Simple get to the *root* url of blogposts''' request = self.factory.get('/blog-post') view = ListOrCreateModelView.as_view(resource=urls.BlogPostResource) response = view(request) self.assertEqual(response.status_code, 200) def test_blogposts_not_exceed_MAX_POSTS(self): '''Posting blog-posts should not result in more than MAX_POSTS items stored.''' for post in range(models.MAX_POSTS + 5): form_data = {'title': 'This is post #%s' % post, 'content': 'This is the content of post #%s' % post} request = self.factory.post('/blog-post', data=form_data) view = ListOrCreateModelView.as_view(resource=urls.BlogPostResource) view(request) self.assertEquals(len(models.BlogPost.objects.all()),models.MAX_POSTS) def test_fifo_behaviour(self): '''It's fine that the Blogposts are capped off at MAX_POSTS. But we want to make sure we see FIFO behaviour.''' for post in range(15): form_data = {'title': '%s' % post, 'content': 'This is the content of post #%s' % post} request = self.factory.post('/blog-post', data=form_data) view = ListOrCreateModelView.as_view(resource=urls.BlogPostResource) view(request) request = self.factory.get('/blog-post') view = ListOrCreateModelView.as_view(resource=urls.BlogPostResource) response = view(request) response_posts = json.loads(response.content) response_titles = [d['title'] for d in response_posts] response_titles.reverse() self.assertEquals(response_titles, ['%s' % i for i in range(models.MAX_POSTS - 5, models.MAX_POSTS + 5)])
def setUp(self): super(TestModelRead, self).setUp() self.req = RequestFactory()
class TestPagination(TestCase): def setUp(self): self.req = RequestFactory() def test_default_limit(self): """ Tests if pagination works without overwriting the limit """ request = self.req.get('/paginator') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.OK) self.assertEqual(MockPaginatorView.total, content['total']) self.assertEqual(MockPaginatorView.limit, content['per_page']) self.assertEqual(range(0, MockPaginatorView.limit), content['results']) def test_overwriting_limit(self): """ Tests if the limit can be overwritten """ limit = 10 request = self.req.get('/paginator') response = MockPaginatorView.as_view(limit=limit)(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.OK) self.assertEqual(content['per_page'], limit) self.assertEqual(range(0, limit), content['results']) def test_limit_param(self): """ Tests if the client can set the limit """ from math import ceil limit = 5 num_pages = int(ceil(MockPaginatorView.total / float(limit))) request = self.req.get('/paginator/?limit=%d' % limit) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.OK) self.assertEqual(MockPaginatorView.total, content['total']) self.assertEqual(limit, content['per_page']) self.assertEqual(num_pages, content['pages']) def test_exceeding_limit(self): """ Makes sure the client cannot exceed the default limit """ from math import ceil limit = MockPaginatorView.limit + 10 num_pages = int(ceil(MockPaginatorView.total / float(limit))) request = self.req.get('/paginator/?limit=%d' % limit) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.OK) self.assertEqual(MockPaginatorView.total, content['total']) self.assertNotEqual(limit, content['per_page']) self.assertNotEqual(num_pages, content['pages']) self.assertEqual(MockPaginatorView.limit, content['per_page']) def test_only_works_for_get(self): """ Pagination should only work for GET requests """ request = self.req.post('/paginator', data={'content': 'spam'}) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.CREATED) self.assertEqual(None, content.get('per_page')) self.assertEqual('OK', content['status']) def test_non_int_page(self): """ Tests that it can handle invalid values """ request = self.req.get('/paginator/?page=spam') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.NOT_FOUND) def test_page_range(self): """ Tests that the page range is handle correctly """ request = self.req.get('/paginator/?page=0') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.NOT_FOUND) request = self.req.get('/paginator/') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.OK) self.assertEqual(range(0, MockPaginatorView.limit), content['results']) num_pages = content['pages'] request = self.req.get('/paginator/?page=%d' % num_pages) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.OK) self.assertEqual(range(MockPaginatorView.limit*(num_pages-1), MockPaginatorView.total), content['results']) request = self.req.get('/paginator/?page=%d' % (num_pages + 1,)) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.NOT_FOUND)
def setUp(self): self.factory = RequestFactory()
class ThrottlingTests(TestCase): urls = 'djangorestframework.tests.throttling' def setUp(self): """ Reset the cache so that no throttles will be active """ cache.clear() self.factory = RequestFactory() 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) self.assertEqual(503, response.status_code) def set_throttle_timer(self, view, value): """ Explicitly set the timer, overriding time.time() """ view.permissions[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) self.assertEqual(503, response.status_code) # Advance the timer by one second self.set_throttle_timer(MockView, 1) response = MockView.as_view()(request) self.assertEqual(200, response.status_code) 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) self.assertEqual(expect, response.status_code) 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 test_request_throttling_is_per_view(self): """ Ensure request rate is limited globally per View for PerViewThrottles """ self.ensure_is_throttled(MockView_PerViewThrottling, 503) def test_request_throttling_is_per_resource(self): """ Ensure request rate is limited globally per Resource for PerResourceThrottles """ self.ensure_is_throttled(MockView_PerResourceThrottling, 503) def ensure_response_header_contains_proper_throttle_field(self, view, expected_headers): """ Ensure the response returns an X-Throttle 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) self.assertEquals(response['X-Throttle'], expect) def test_seconds_fields(self): """ Ensure for second based throttles. """ self.ensure_response_header_contains_proper_throttle_field(MockView, ((0, 'status=SUCCESS; next=0.33 sec'), (0, 'status=SUCCESS; next=0.50 sec'), (0, 'status=SUCCESS; next=1.00 sec'), (0, 'status=FAILURE; next=1.00 sec') )) def test_minutes_fields(self): """ Ensure for minute based throttles. """ self.ensure_response_header_contains_proper_throttle_field(MockView_MinuteThrottling, ((0, 'status=SUCCESS; next=20.00 sec'), (0, 'status=SUCCESS; next=30.00 sec'), (0, 'status=SUCCESS; next=60.00 sec'), (0, 'status=FAILURE; next=60.00 sec') )) 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, 'status=SUCCESS; next=20.00 sec'), (20, 'status=SUCCESS; next=20.00 sec'), (40, 'status=SUCCESS; next=20.00 sec'), (60, 'status=SUCCESS; next=20.00 sec'), (80, 'status=SUCCESS; next=20.00 sec') ))
def setUp(self): self.factory = RequestFactory() self.temp_dir = tempfile.mkdtemp() views.HIGHLIGHTED_CODE_DIR = self.temp_dir
class TestPagination(TestCase): def setUp(self): self.req = RequestFactory() def test_default_limit(self): """ Tests if pagination works without overwriting the limit """ request = self.req.get("/paginator") response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(MockPaginatorView.total, content["total"]) self.assertEqual(MockPaginatorView.limit, content["per_page"]) self.assertEqual(range(0, MockPaginatorView.limit), content["results"]) def test_overwriting_limit(self): """ Tests if the limit can be overwritten """ limit = 10 request = self.req.get("/paginator") response = MockPaginatorView.as_view(limit=limit)(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(content["per_page"], limit) self.assertEqual(range(0, limit), content["results"]) def test_limit_param(self): """ Tests if the client can set the limit """ from math import ceil limit = 5 num_pages = int(ceil(MockPaginatorView.total / float(limit))) request = self.req.get("/paginator/?limit=%d" % limit) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(MockPaginatorView.total, content["total"]) self.assertEqual(limit, content["per_page"]) self.assertEqual(num_pages, content["pages"]) def test_exceeding_limit(self): """ Makes sure the client cannot exceed the default limit """ from math import ceil limit = MockPaginatorView.limit + 10 num_pages = int(ceil(MockPaginatorView.total / float(limit))) request = self.req.get("/paginator/?limit=%d" % limit) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(MockPaginatorView.total, content["total"]) self.assertNotEqual(limit, content["per_page"]) self.assertNotEqual(num_pages, content["pages"]) self.assertEqual(MockPaginatorView.limit, content["per_page"]) def test_only_works_for_get(self): """ Pagination should only work for GET requests """ request = self.req.post("/paginator", data={"content": "spam"}) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(None, content.get("per_page")) self.assertEqual("OK", content["status"]) def test_non_int_page(self): """ Tests that it can handle invalid values """ request = self.req.get("/paginator/?page=spam") response = MockPaginatorView.as_view()(request) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_page_range(self): """ Tests that the page range is handle correctly """ request = self.req.get("/paginator/?page=0") response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) request = self.req.get("/paginator/") response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(range(0, MockPaginatorView.limit), content["results"]) num_pages = content["pages"] request = self.req.get("/paginator/?page=%d" % num_pages) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(range(MockPaginatorView.limit * (num_pages - 1), MockPaginatorView.total), content["results"]) request = self.req.get("/paginator/?page=%d" % (num_pages + 1,)) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_existing_query_parameters_are_preserved(self): """ Tests that existing query parameters are preserved when generating next/previous page links """ request = self.req.get("/paginator/?foo=bar&another=something") response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue("foo=bar" in content["next"]) self.assertTrue("another=something" in content["next"]) self.assertTrue("page=2" in content["next"])
class TestModelCreation(TestModelsTestCase): """Tests on CreateModelMixin""" def setUp(self): super(TestModelsTestCase, self).setUp() self.req = RequestFactory() def test_creation(self): self.assertEquals(0, Group.objects.count()) class GroupResource(ModelResource): model = Group form_data = {'name': 'foo'} request = self.req.post('/groups', data=form_data) mixin = CreateModelMixin() mixin.resource = GroupResource mixin.CONTENT = form_data response = mixin.post(request) self.assertEquals(1, Group.objects.count()) self.assertEquals('foo', response.cleaned_content.name) def test_creation_with_m2m_relation(self): class UserResource(ModelResource): model = User def url(self, instance): return "/users/%i" % instance.id group = Group(name='foo') group.save() form_data = { 'username': '******', 'password': '******', 'groups': [group.id] } request = self.req.post('/groups', data=form_data) cleaned_data = dict(form_data) cleaned_data['groups'] = [group] mixin = CreateModelMixin() mixin.resource = UserResource mixin.CONTENT = cleaned_data response = mixin.post(request) self.assertEquals(1, User.objects.count()) self.assertEquals(1, response.cleaned_content.groups.count()) self.assertEquals('foo', response.cleaned_content.groups.all()[0].name) def test_creation_with_m2m_relation_through(self): """ Tests creation where the m2m relation uses a through table """ class UserResource(ModelResource): model = CustomUser def url(self, instance): return "/customusers/%i" % instance.id form_data = {'username': '******', 'groups': []} request = self.req.post('/groups', data=form_data) cleaned_data = dict(form_data) cleaned_data['groups'] = [] mixin = CreateModelMixin() mixin.resource = UserResource mixin.CONTENT = cleaned_data response = mixin.post(request) self.assertEquals(1, CustomUser.objects.count()) self.assertEquals(0, response.cleaned_content.groups.count()) group = Group(name='foo1') group.save() form_data = {'username': '******', 'groups': [group.id]} request = self.req.post('/groups', data=form_data) cleaned_data = dict(form_data) cleaned_data['groups'] = [group] mixin = CreateModelMixin() mixin.resource = UserResource mixin.CONTENT = cleaned_data response = mixin.post(request) self.assertEquals(2, CustomUser.objects.count()) self.assertEquals(1, response.cleaned_content.groups.count()) self.assertEquals('foo1', response.cleaned_content.groups.all()[0].name) group2 = Group(name='foo2') group2.save() form_data = {'username': '******', 'groups': [group.id, group2.id]} request = self.req.post('/groups', data=form_data) cleaned_data = dict(form_data) cleaned_data['groups'] = [group, group2] mixin = CreateModelMixin() mixin.resource = UserResource mixin.CONTENT = cleaned_data response = mixin.post(request) self.assertEquals(3, CustomUser.objects.count()) self.assertEquals(2, response.cleaned_content.groups.count()) self.assertEquals('foo1', response.cleaned_content.groups.all()[0].name) self.assertEquals('foo2', response.cleaned_content.groups.all()[1].name)
class TestContentParsing(TestCase): def setUp(self): self.req = RequestFactory() def ensure_determines_no_content_GET(self, view): """Ensure view.DATA returns None for GET request with no content.""" view.request = self.req.get('/') self.assertEqual(view.DATA, None) def ensure_determines_no_content_HEAD(self, view): """Ensure view.DATA returns None for HEAD request.""" view.request = self.req.head('/') self.assertEqual(view.DATA, None) def ensure_determines_form_content_POST(self, view): """Ensure view.DATA returns content for POST request with form content.""" form_data = {'qwerty': 'uiop'} view.parsers = (FormParser, MultiPartParser) view.request = self.req.post('/', data=form_data) self.assertEqual(list(view.DATA.items()), list(form_data.items())) def ensure_determines_non_form_content_POST(self, view): """Ensure view.RAW_CONTENT returns content for POST request with non-form content.""" content = 'qwerty' content_type = 'text/plain' view.parsers = (PlainTextParser, ) view.request = self.req.post('/', content, content_type=content_type) self.assertEqual(view.DATA, content) def ensure_determines_form_content_PUT(self, view): """Ensure view.RAW_CONTENT returns content for PUT request with form content.""" form_data = {'qwerty': 'uiop'} view.parsers = (FormParser, MultiPartParser) view.request = self.req.put( '/', data=urlencode(form_data), content_type='application/x-www-form-urlencoded') self.assertEqual(view.DATA, {'qwerty': ['uiop']}) def ensure_determines_non_form_content_PUT(self, view): """Ensure view.RAW_CONTENT returns content for PUT request with non-form content.""" content = 'qwerty' content_type = 'text/plain' view.parsers = (PlainTextParser, ) view.request = self.req.post('/', content, content_type=content_type) self.assertEqual(view.DATA, content) def test_standard_behaviour_determines_no_content_GET(self): """Ensure view.DATA returns None for GET request with no content.""" self.ensure_determines_no_content_GET(RequestMixin()) def test_standard_behaviour_determines_no_content_HEAD(self): """Ensure view.DATA returns None for HEAD request.""" self.ensure_determines_no_content_HEAD(RequestMixin()) def test_standard_behaviour_determines_form_content_POST(self): """Ensure view.DATA returns content for POST request with form content.""" self.ensure_determines_form_content_POST(RequestMixin()) def test_standard_behaviour_determines_non_form_content_POST(self): """Ensure view.DATA returns content for POST request with non-form content.""" self.ensure_determines_non_form_content_POST(RequestMixin()) # def test_standard_behaviour_determines_form_content_PUT(self): # """Ensure view.DATA returns content for PUT request with form content.""" # self.ensure_determines_form_content_PUT(RequestMixin()) def test_standard_behaviour_determines_non_form_content_PUT(self): """Ensure view.DATA returns content for PUT request with non-form content.""" self.ensure_determines_non_form_content_PUT(RequestMixin()) def test_overloaded_behaviour_allows_content_tunnelling(self): """Ensure request.DATA returns content for overloaded POST request""" content = 'qwerty' content_type = 'text/plain' view = RequestMixin() form_data = { view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type } view.request = self.req.post('/', form_data) view.parsers = (PlainTextParser, ) self.assertEqual(view.DATA, content) def test_accessing_post_after_data_form(self): """Ensures request.POST can be accessed after request.DATA in form request""" form_data = {'qwerty': 'uiop'} view = RequestMixin() view.parsers = (FormParser, MultiPartParser) view.request = self.req.post('/', data=form_data) self.assertEqual(list(view.DATA.items()), list(form_data.items())) self.assertEqual(list(view.request.POST.items()), list(form_data.items())) @unittest.skip('This test was disabled some time ago for some reason') def test_accessing_post_after_data_for_json(self): """Ensures request.POST can be accessed after request.DATA in json request""" import json data = {'qwerty': 'uiop'} content = json.dumps(data) content_type = 'application/json' view = RequestMixin() view.parsers = (JSONParser, ) view.request = self.req.post('/', content, content_type=content_type) self.assertEqual(list(view.DATA.items()), list(data.items())) self.assertEqual(list(view.request.POST.items()), []) def test_accessing_post_after_data_for_overloaded_json(self): """Ensures request.POST can be accessed after request.DATA in overloaded json request""" import json data = {'qwerty': 'uiop'} content = json.dumps(data) content_type = 'application/json' view = RequestMixin() view.parsers = (JSONParser, ) form_data = { view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type } view.request = self.req.post('/', data=form_data) self.assertEqual(sorted(view.DATA.items()), sorted(data.items())) self.assertEqual(sorted(view.request.POST.items()), sorted(form_data.items())) def test_accessing_data_after_post_form(self): """Ensures request.DATA can be accessed after request.POST in form request""" form_data = {'qwerty': 'uiop'} view = RequestMixin() view.parsers = (FormParser, MultiPartParser) view.request = self.req.post('/', data=form_data) self.assertEqual(list(view.request.POST.items()), list(form_data.items())) self.assertEqual(list(view.DATA.items()), list(form_data.items())) def test_accessing_data_after_post_for_json(self): """Ensures request.DATA can be accessed after request.POST in json request""" import json data = {'qwerty': 'uiop'} content = json.dumps(data) content_type = 'application/json' view = RequestMixin() view.parsers = (JSONParser, ) view.request = self.req.post('/', content, content_type=content_type) self.assertEqual(list(view.DATA.items()), list(data.items())) def test_accessing_data_after_post_for_overloaded_json(self): """Ensures request.DATA can be accessed after request.POST in overloaded json request""" import json data = {'qwerty': 'uiop'} content = json.dumps(data) content_type = 'application/json' view = RequestMixin() view.parsers = (JSONParser, ) form_data = { view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type } view.request = self.req.post('/', data=form_data) self.assertEqual(sorted(view.request.POST.items()), sorted(form_data.items())) self.assertEqual(sorted(view.DATA.items()), sorted(data.items()))
def setUp(self): super(TestModelsTestCase, self).setUp() self.req = RequestFactory()
def setUp(self): """ Reset the cache so that no throttles will be active """ cache.clear() self.factory = RequestFactory()
def setUp(self): self.factory = RequestFactory() models.BlogPost.objects.all().delete()
class TestPagination(TestCase): def setUp(self): self.req = RequestFactory() def test_default_limit(self): """ Tests if pagination works without overwriting the limit """ request = self.req.get('/paginator') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(MockPaginatorView.total, content['total']) self.assertEqual(MockPaginatorView.limit, content['per_page']) self.assertEqual(list(range(0, MockPaginatorView.limit)), content['results']) def test_overwriting_limit(self): """ Tests if the limit can be overwritten """ limit = 10 request = self.req.get('/paginator') response = MockPaginatorView.as_view(limit=limit)(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(content['per_page'], limit) self.assertEqual(list(range(0, limit)), content['results']) def test_limit_param(self): """ Tests if the client can set the limit """ from math import ceil limit = 5 num_pages = int(ceil(MockPaginatorView.total / float(limit))) request = self.req.get('/paginator/?limit=%d' % limit) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(MockPaginatorView.total, content['total']) self.assertEqual(limit, content['per_page']) self.assertEqual(num_pages, content['pages']) def test_exceeding_limit(self): """ Makes sure the client cannot exceed the default limit """ from math import ceil limit = MockPaginatorView.limit + 10 num_pages = int(ceil(MockPaginatorView.total / float(limit))) request = self.req.get('/paginator/?limit=%d' % limit) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(MockPaginatorView.total, content['total']) self.assertNotEqual(limit, content['per_page']) self.assertNotEqual(num_pages, content['pages']) self.assertEqual(MockPaginatorView.limit, content['per_page']) def test_only_works_for_get(self): """ Pagination should only work for GET requests """ request = self.req.post('/paginator', data={'content': 'spam'}) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(None, content.get('per_page')) self.assertEqual('OK', content['status']) def test_non_int_page(self): """ Tests that it can handle invalid values """ request = self.req.get('/paginator/?page=spam') response = MockPaginatorView.as_view()(request) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_page_range(self): """ Tests that the page range is handle correctly """ request = self.req.get('/paginator/?page=0') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) request = self.req.get('/paginator/') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(list(range(0, MockPaginatorView.limit)), content['results']) num_pages = content['pages'] request = self.req.get('/paginator/?page=%d' % num_pages) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(list(range(MockPaginatorView.limit*(num_pages-1), MockPaginatorView.total)), content['results']) request = self.req.get('/paginator/?page=%d' % (num_pages + 1,)) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_existing_query_parameters_are_preserved(self): """ Tests that existing query parameters are preserved when generating next/previous page links """ request = self.req.get('/paginator/?foo=bar&another=something') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue('foo=bar' in content['next']) self.assertTrue('another=something' in content['next']) self.assertTrue('page=2' in content['next']) def test_duplicate_parameters_are_not_created(self): """ Regression: ensure duplicate "page" parameters are not added to paginated URLs. So page 1 should contain ?page=2, not ?page=1&page=2 """ request = self.req.get('/paginator/?page=1') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertTrue('page=2' in content['next']) self.assertFalse('page=1' in content['next'])
def setUp(self): self.req = RequestFactory()
class TestPagination(TestCase): def setUp(self): self.req = RequestFactory() def test_default_limit(self): """ Tests if pagination works without overwriting the limit """ request = self.req.get('/paginator') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.OK) self.assertEqual(MockPaginatorView.total, content['total']) self.assertEqual(MockPaginatorView.limit, content['per_page']) self.assertEqual(range(0, MockPaginatorView.limit), content['results']) def test_overwriting_limit(self): """ Tests if the limit can be overwritten """ limit = 10 request = self.req.get('/paginator') response = MockPaginatorView.as_view(limit=limit)(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.OK) self.assertEqual(content['per_page'], limit) self.assertEqual(range(0, limit), content['results']) def test_limit_param(self): """ Tests if the client can set the limit """ from math import ceil limit = 5 num_pages = int(ceil(MockPaginatorView.total / float(limit))) request = self.req.get('/paginator/?limit=%d' % limit) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.OK) self.assertEqual(MockPaginatorView.total, content['total']) self.assertEqual(limit, content['per_page']) self.assertEqual(num_pages, content['pages']) def test_exceeding_limit(self): """ Makes sure the client cannot exceed the default limit """ from math import ceil limit = MockPaginatorView.limit + 10 num_pages = int(ceil(MockPaginatorView.total / float(limit))) request = self.req.get('/paginator/?limit=%d' % limit) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.OK) self.assertEqual(MockPaginatorView.total, content['total']) self.assertNotEqual(limit, content['per_page']) self.assertNotEqual(num_pages, content['pages']) self.assertEqual(MockPaginatorView.limit, content['per_page']) def test_only_works_for_get(self): """ Pagination should only work for GET requests """ request = self.req.post('/paginator', data={'content': 'spam'}) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.CREATED) self.assertEqual(None, content.get('per_page')) self.assertEqual('OK', content['status']) def test_non_int_page(self): """ Tests that it can handle invalid values """ request = self.req.get('/paginator/?page=spam') response = MockPaginatorView.as_view()(request) self.assertEqual(response.status_code, status.NOT_FOUND) def test_page_range(self): """ Tests that the page range is handle correctly """ request = self.req.get('/paginator/?page=0') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.NOT_FOUND) request = self.req.get('/paginator/') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.OK) self.assertEqual(range(0, MockPaginatorView.limit), content['results']) num_pages = content['pages'] request = self.req.get('/paginator/?page=%d' % num_pages) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.OK) self.assertEqual(range(MockPaginatorView.limit*(num_pages-1), MockPaginatorView.total), content['results']) request = self.req.get('/paginator/?page=%d' % (num_pages + 1,)) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.NOT_FOUND)
class TestContentParsing(TestCase): def setUp(self): self.req = RequestFactory() def ensure_determines_no_content_GET(self, view): """Ensure view.DATA returns None for GET request with no content.""" view.request = self.req.get("/") self.assertEqual(view.DATA, None) def ensure_determines_no_content_HEAD(self, view): """Ensure view.DATA returns None for HEAD request.""" view.request = self.req.head("/") self.assertEqual(view.DATA, None) def ensure_determines_form_content_POST(self, view): """Ensure view.DATA returns content for POST request with form content.""" form_data = {"qwerty": "uiop"} view.parsers = (FormParser, MultiPartParser) view.request = self.req.post("/", data=form_data) self.assertEqual(list(view.DATA.items()), list(form_data.items())) def ensure_determines_non_form_content_POST(self, view): """Ensure view.RAW_CONTENT returns content for POST request with non-form content.""" content = "qwerty" content_type = "text/plain" view.parsers = (PlainTextParser,) view.request = self.req.post("/", content, content_type=content_type) self.assertEqual(view.DATA, content) def ensure_determines_form_content_PUT(self, view): """Ensure view.RAW_CONTENT returns content for PUT request with form content.""" form_data = {"qwerty": "uiop"} view.parsers = (FormParser, MultiPartParser) view.request = self.req.put("/", data=urlencode(form_data), content_type="application/x-www-form-urlencoded") self.assertEqual(view.DATA, {"qwerty": ["uiop"]}) def ensure_determines_non_form_content_PUT(self, view): """Ensure view.RAW_CONTENT returns content for PUT request with non-form content.""" content = "qwerty" content_type = "text/plain" view.parsers = (PlainTextParser,) view.request = self.req.post("/", content, content_type=content_type) self.assertEqual(view.DATA, content) def test_standard_behaviour_determines_no_content_GET(self): """Ensure view.DATA returns None for GET request with no content.""" self.ensure_determines_no_content_GET(RequestMixin()) def test_standard_behaviour_determines_no_content_HEAD(self): """Ensure view.DATA returns None for HEAD request.""" self.ensure_determines_no_content_HEAD(RequestMixin()) def test_standard_behaviour_determines_form_content_POST(self): """Ensure view.DATA returns content for POST request with form content.""" self.ensure_determines_form_content_POST(RequestMixin()) def test_standard_behaviour_determines_non_form_content_POST(self): """Ensure view.DATA returns content for POST request with non-form content.""" self.ensure_determines_non_form_content_POST(RequestMixin()) # def test_standard_behaviour_determines_form_content_PUT(self): # """Ensure view.DATA returns content for PUT request with form content.""" # self.ensure_determines_form_content_PUT(RequestMixin()) def test_standard_behaviour_determines_non_form_content_PUT(self): """Ensure view.DATA returns content for PUT request with non-form content.""" self.ensure_determines_non_form_content_PUT(RequestMixin()) def test_overloaded_behaviour_allows_content_tunnelling(self): """Ensure request.DATA returns content for overloaded POST request""" content = "qwerty" content_type = "text/plain" view = RequestMixin() form_data = {view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type} view.request = self.req.post("/", form_data) view.parsers = (PlainTextParser,) self.assertEqual(view.DATA, content) def test_accessing_post_after_data_form(self): """Ensures request.POST can be accessed after request.DATA in form request""" form_data = {"qwerty": "uiop"} view = RequestMixin() view.parsers = (FormParser, MultiPartParser) view.request = self.req.post("/", data=form_data) self.assertEqual(list(view.DATA.items()), list(form_data.items())) self.assertEqual(list(view.request.POST.items()), list(form_data.items())) @unittest.skip("This test was disabled some time ago for some reason") def test_accessing_post_after_data_for_json(self): """Ensures request.POST can be accessed after request.DATA in json request""" import json data = {"qwerty": "uiop"} content = json.dumps(data) content_type = "application/json" view = RequestMixin() view.parsers = (JSONParser,) view.request = self.req.post("/", content, content_type=content_type) self.assertEqual(list(view.DATA.items()), list(data.items())) self.assertEqual(list(view.request.POST.items()), []) def test_accessing_post_after_data_for_overloaded_json(self): """Ensures request.POST can be accessed after request.DATA in overloaded json request""" import json data = {"qwerty": "uiop"} content = json.dumps(data) content_type = "application/json" view = RequestMixin() view.parsers = (JSONParser,) form_data = {view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type} view.request = self.req.post("/", data=form_data) self.assertEqual(sorted(view.DATA.items()), sorted(data.items())) self.assertEqual(sorted(view.request.POST.items()), sorted(form_data.items())) def test_accessing_data_after_post_form(self): """Ensures request.DATA can be accessed after request.POST in form request""" form_data = {"qwerty": "uiop"} view = RequestMixin() view.parsers = (FormParser, MultiPartParser) view.request = self.req.post("/", data=form_data) self.assertEqual(list(view.request.POST.items()), list(form_data.items())) self.assertEqual(list(view.DATA.items()), list(form_data.items())) def test_accessing_data_after_post_for_json(self): """Ensures request.DATA can be accessed after request.POST in json request""" import json data = {"qwerty": "uiop"} content = json.dumps(data) content_type = "application/json" view = RequestMixin() view.parsers = (JSONParser,) view.request = self.req.post("/", content, content_type=content_type) self.assertEqual(list(view.DATA.items()), list(data.items())) def test_accessing_data_after_post_for_overloaded_json(self): """Ensures request.DATA can be accessed after request.POST in overloaded json request""" import json data = {"qwerty": "uiop"} content = json.dumps(data) content_type = "application/json" view = RequestMixin() view.parsers = (JSONParser,) form_data = {view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type} view.request = self.req.post("/", data=form_data) self.assertEqual(sorted(view.request.POST.items()), sorted(form_data.items())) self.assertEqual(sorted(view.DATA.items()), sorted(data.items()))
class TestContentParsing(TestCase): def setUp(self): self.req = RequestFactory() def ensure_determines_no_content_GET(self, view): """Ensure view.DATA returns None for GET request with no content.""" view.request = self.req.get('/') self.assertEqual(view.DATA, None) def ensure_determines_no_content_HEAD(self, view): """Ensure view.DATA returns None for HEAD request.""" view.request = self.req.head('/') self.assertEqual(view.DATA, None) def ensure_determines_form_content_POST(self, view): """Ensure view.DATA returns content for POST request with form content.""" form_data = {'qwerty': 'uiop'} view.parsers = (FormParser, MultiPartParser) view.request = self.req.post('/', data=form_data) self.assertEqual(view.DATA.items(), form_data.items()) def ensure_determines_non_form_content_POST(self, view): """Ensure view.RAW_CONTENT returns content for POST request with non-form content.""" content = 'qwerty' content_type = 'text/plain' view.parsers = (PlainTextParser,) view.request = self.req.post('/', content, content_type=content_type) self.assertEqual(view.DATA, content) def ensure_determines_form_content_PUT(self, view): """Ensure view.RAW_CONTENT returns content for PUT request with form content.""" form_data = {'qwerty': 'uiop'} view.parsers = (FormParser, MultiPartParser) view.request = self.req.put('/', data=form_data) self.assertEqual(view.DATA.items(), form_data.items()) def ensure_determines_non_form_content_PUT(self, view): """Ensure view.RAW_CONTENT returns content for PUT request with non-form content.""" content = 'qwerty' content_type = 'text/plain' view.parsers = (PlainTextParser,) view.request = self.req.post('/', content, content_type=content_type) self.assertEqual(view.DATA, content) def test_standard_behaviour_determines_no_content_GET(self): """Ensure view.DATA returns None for GET request with no content.""" self.ensure_determines_no_content_GET(RequestMixin()) def test_standard_behaviour_determines_no_content_HEAD(self): """Ensure view.DATA returns None for HEAD request.""" self.ensure_determines_no_content_HEAD(RequestMixin()) def test_standard_behaviour_determines_form_content_POST(self): """Ensure view.DATA returns content for POST request with form content.""" self.ensure_determines_form_content_POST(RequestMixin()) def test_standard_behaviour_determines_non_form_content_POST(self): """Ensure view.DATA returns content for POST request with non-form content.""" self.ensure_determines_non_form_content_POST(RequestMixin()) def test_standard_behaviour_determines_form_content_PUT(self): """Ensure view.DATA returns content for PUT request with form content.""" self.ensure_determines_form_content_PUT(RequestMixin()) def test_standard_behaviour_determines_non_form_content_PUT(self): """Ensure view.DATA returns content for PUT request with non-form content.""" self.ensure_determines_non_form_content_PUT(RequestMixin()) def test_overloaded_behaviour_allows_content_tunnelling(self): """Ensure request.DATA returns content for overloaded POST request""" content = 'qwerty' content_type = 'text/plain' view = RequestMixin() form_data = {view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type} view.request = self.req.post('/', form_data) view.parsers = (PlainTextParser,) self.assertEqual(view.DATA, content) def test_accessing_post_after_data_form(self): """Ensures request.POST can be accessed after request.DATA in form request""" form_data = {'qwerty': 'uiop'} view = RequestMixin() view.parsers = (FormParser, MultiPartParser) view.request = self.req.post('/', data=form_data) self.assertEqual(view.DATA.items(), form_data.items()) self.assertEqual(view.request.POST.items(), form_data.items()) def test_accessing_post_after_data_for_json(self): """Ensures request.POST can be accessed after request.DATA in json request""" from django.utils import simplejson as json data = {'qwerty': 'uiop'} content = json.dumps(data) content_type = 'application/json' view = RequestMixin() view.parsers = (JSONParser,) view.request = self.req.post('/', content, content_type=content_type) self.assertEqual(view.DATA.items(), data.items()) self.assertEqual(view.request.POST.items(), []) def test_accessing_post_after_data_for_overloaded_json(self): """Ensures request.POST can be accessed after request.DATA in overloaded json request""" from django.utils import simplejson as json data = {'qwerty': 'uiop'} content = json.dumps(data) content_type = 'application/json' view = RequestMixin() view.parsers = (JSONParser,) form_data = {view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type} view.request = self.req.post('/', data=form_data) self.assertEqual(view.DATA.items(), data.items()) self.assertEqual(view.request.POST.items(), form_data.items()) def test_accessing_data_after_post_form(self): """Ensures request.DATA can be accessed after request.POST in form request""" form_data = {'qwerty': 'uiop'} view = RequestMixin() view.parsers = (FormParser, MultiPartParser) view.request = self.req.post('/', data=form_data) self.assertEqual(view.request.POST.items(), form_data.items()) self.assertEqual(view.DATA.items(), form_data.items()) def test_accessing_data_after_post_for_json(self): """Ensures request.DATA can be accessed after request.POST in json request""" from django.utils import simplejson as json data = {'qwerty': 'uiop'} content = json.dumps(data) content_type = 'application/json' view = RequestMixin() view.parsers = (JSONParser,) view.request = self.req.post('/', content, content_type=content_type) post_items = view.request.POST.items() self.assertEqual(len(post_items), 1) self.assertEqual(len(post_items[0]), 2) self.assertEqual(post_items[0][0], content) self.assertEqual(view.DATA.items(), data.items()) def test_accessing_data_after_post_for_overloaded_json(self): """Ensures request.DATA can be accessed after request.POST in overloaded json request""" from django.utils import simplejson as json data = {'qwerty': 'uiop'} content = json.dumps(data) content_type = 'application/json' view = RequestMixin() view.parsers = (JSONParser,) form_data = {view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type} view.request = self.req.post('/', data=form_data) self.assertEqual(view.request.POST.items(), form_data.items()) self.assertEqual(view.DATA.items(), data.items())
class TestContentParsing(TestCase): def setUp(self): self.req = RequestFactory() def ensure_determines_no_content_GET(self, view): """Ensure view.DATA returns None for GET request with no content.""" view.request = self.req.get("/") self.assertEqual(view.DATA, None) def ensure_determines_no_content_HEAD(self, view): """Ensure view.DATA returns None for HEAD request.""" view.request = self.req.head("/") self.assertEqual(view.DATA, None) def ensure_determines_form_content_POST(self, view): """Ensure view.DATA returns content for POST request with form content.""" form_data = {"qwerty": "uiop"} view.parsers = (FormParser, MultiPartParser) view.request = self.req.post("/", data=form_data) self.assertEqual(view.DATA.items(), form_data.items()) def ensure_determines_non_form_content_POST(self, view): """Ensure view.RAW_CONTENT returns content for POST request with non-form content.""" content = "qwerty" content_type = "text/plain" view.parsers = (PlainTextParser,) view.request = self.req.post("/", content, content_type=content_type) self.assertEqual(view.DATA, content) def ensure_determines_form_content_PUT(self, view): """Ensure view.RAW_CONTENT returns content for PUT request with form content.""" form_data = {"qwerty": "uiop"} view.parsers = (FormParser, MultiPartParser) view.request = self.req.put("/", data=form_data) self.assertEqual(view.DATA.items(), form_data.items()) def ensure_determines_non_form_content_PUT(self, view): """Ensure view.RAW_CONTENT returns content for PUT request with non-form content.""" content = "qwerty" content_type = "text/plain" view.parsers = (PlainTextParser,) view.request = self.req.post("/", content, content_type=content_type) self.assertEqual(view.DATA, content) def test_standard_behaviour_determines_no_content_GET(self): """Ensure view.DATA returns None for GET request with no content.""" self.ensure_determines_no_content_GET(RequestMixin()) def test_standard_behaviour_determines_no_content_HEAD(self): """Ensure view.DATA returns None for HEAD request.""" self.ensure_determines_no_content_HEAD(RequestMixin()) def test_standard_behaviour_determines_form_content_POST(self): """Ensure view.DATA returns content for POST request with form content.""" self.ensure_determines_form_content_POST(RequestMixin()) def test_standard_behaviour_determines_non_form_content_POST(self): """Ensure view.DATA returns content for POST request with non-form content.""" self.ensure_determines_non_form_content_POST(RequestMixin()) def test_standard_behaviour_determines_form_content_PUT(self): """Ensure view.DATA returns content for PUT request with form content.""" self.ensure_determines_form_content_PUT(RequestMixin()) def test_standard_behaviour_determines_non_form_content_PUT(self): """Ensure view.DATA returns content for PUT request with non-form content.""" self.ensure_determines_non_form_content_PUT(RequestMixin()) def test_overloaded_behaviour_allows_content_tunnelling(self): """Ensure request.DATA returns content for overloaded POST request""" content = "qwerty" content_type = "text/plain" view = RequestMixin() form_data = {view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type} view.request = self.req.post("/", form_data) view.parsers = (PlainTextParser,) self.assertEqual(view.DATA, content) def test_accessing_post_after_data_form(self): """Ensures request.POST can be accessed after request.DATA in form request""" form_data = {"qwerty": "uiop"} view = RequestMixin() view.parsers = (FormParser, MultiPartParser) view.request = self.req.post("/", data=form_data) self.assertEqual(view.DATA.items(), form_data.items()) self.assertEqual(view.request.POST.items(), form_data.items()) def test_accessing_post_after_data_for_json(self): """Ensures request.POST can be accessed after request.DATA in json request""" from django.utils import simplejson as json data = {"qwerty": "uiop"} content = json.dumps(data) content_type = "application/json" view = RequestMixin() view.parsers = (JSONParser,) view.request = self.req.post("/", content, content_type=content_type) self.assertEqual(view.DATA.items(), data.items()) self.assertEqual(view.request.POST.items(), []) def test_accessing_post_after_data_for_overloaded_json(self): """Ensures request.POST can be accessed after request.DATA in overloaded json request""" from django.utils import simplejson as json data = {"qwerty": "uiop"} content = json.dumps(data) content_type = "application/json" view = RequestMixin() view.parsers = (JSONParser,) form_data = {view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type} view.request = self.req.post("/", data=form_data) self.assertEqual(view.DATA.items(), data.items()) self.assertEqual(view.request.POST.items(), form_data.items()) def test_accessing_data_after_post_form(self): """Ensures request.DATA can be accessed after request.POST in form request""" form_data = {"qwerty": "uiop"} view = RequestMixin() view.parsers = (FormParser, MultiPartParser) view.request = self.req.post("/", data=form_data) self.assertEqual(view.request.POST.items(), form_data.items()) self.assertEqual(view.DATA.items(), form_data.items()) def test_accessing_data_after_post_for_json(self): """Ensures request.DATA can be accessed after request.POST in json request""" from django.utils import simplejson as json data = {"qwerty": "uiop"} content = json.dumps(data) content_type = "application/json" view = RequestMixin() view.parsers = (JSONParser,) view.request = self.req.post("/", content, content_type=content_type) post_items = view.request.POST.items() self.assertEqual(len(post_items), 1) self.assertEqual(len(post_items[0]), 2) self.assertEqual(post_items[0][0], content) self.assertEqual(view.DATA.items(), data.items()) def test_accessing_data_after_post_for_overloaded_json(self): """Ensures request.DATA can be accessed after request.POST in overloaded json request""" from django.utils import simplejson as json data = {"qwerty": "uiop"} content = json.dumps(data) content_type = "application/json" view = RequestMixin() view.parsers = (JSONParser,) form_data = {view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type} view.request = self.req.post("/", data=form_data) self.assertEqual(view.request.POST.items(), form_data.items()) self.assertEqual(view.DATA.items(), data.items())
class TestPagination(TestCase): def setUp(self): self.req = RequestFactory() def test_default_limit(self): """ Tests if pagination works without overwriting the limit """ request = self.req.get('/paginator') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(MockPaginatorView.total, content['total']) self.assertEqual(MockPaginatorView.limit, content['per_page']) self.assertEqual(list(range(0, MockPaginatorView.limit)), content['results']) def test_overwriting_limit(self): """ Tests if the limit can be overwritten """ limit = 10 request = self.req.get('/paginator') response = MockPaginatorView.as_view(limit=limit)(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(content['per_page'], limit) self.assertEqual(list(range(0, limit)), content['results']) def test_limit_param(self): """ Tests if the client can set the limit """ from math import ceil limit = 5 num_pages = int(ceil(MockPaginatorView.total / float(limit))) request = self.req.get('/paginator/?limit=%d' % limit) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(MockPaginatorView.total, content['total']) self.assertEqual(limit, content['per_page']) self.assertEqual(num_pages, content['pages']) def test_exceeding_limit(self): """ Makes sure the client cannot exceed the default limit """ from math import ceil limit = MockPaginatorView.limit + 10 num_pages = int(ceil(MockPaginatorView.total / float(limit))) request = self.req.get('/paginator/?limit=%d' % limit) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(MockPaginatorView.total, content['total']) self.assertNotEqual(limit, content['per_page']) self.assertNotEqual(num_pages, content['pages']) self.assertEqual(MockPaginatorView.limit, content['per_page']) def test_only_works_for_get(self): """ Pagination should only work for GET requests """ request = self.req.post('/paginator', data={'content': 'spam'}) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(None, content.get('per_page')) self.assertEqual('OK', content['status']) def test_non_int_page(self): """ Tests that it can handle invalid values """ request = self.req.get('/paginator/?page=spam') response = MockPaginatorView.as_view()(request) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_page_range(self): """ Tests that the page range is handle correctly """ request = self.req.get('/paginator/?page=0') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) request = self.req.get('/paginator/') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(list(range(0, MockPaginatorView.limit)), content['results']) num_pages = content['pages'] request = self.req.get('/paginator/?page=%d' % num_pages) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( list( range(MockPaginatorView.limit * (num_pages - 1), MockPaginatorView.total)), content['results']) request = self.req.get('/paginator/?page=%d' % (num_pages + 1, )) response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_existing_query_parameters_are_preserved(self): """ Tests that existing query parameters are preserved when generating next/previous page links """ request = self.req.get('/paginator/?foo=bar&another=something') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue('foo=bar' in content['next']) self.assertTrue('another=something' in content['next']) self.assertTrue('page=2' in content['next']) def test_duplicate_parameters_are_not_created(self): """ Regression: ensure duplicate "page" parameters are not added to paginated URLs. So page 1 should contain ?page=2, not ?page=1&page=2 """ request = self.req.get('/paginator/?page=1') response = MockPaginatorView.as_view()(request) content = json.loads(response.content) self.assertTrue('page=2' in content['next']) self.assertFalse('page=1' in content['next'])
class TestContentParsing(TestCase): def setUp(self): self.req = RequestFactory() def ensure_determines_no_content_GET(self, view): """Ensure view.DATA returns None for GET request with no content.""" view.request = self.req.get('/') self.assertEqual(view.DATA, None) def ensure_determines_form_content_POST(self, view): """Ensure view.DATA returns content for POST request with form content.""" form_data = {'qwerty': 'uiop'} view.parsers = (FormParser, MultiPartParser) view.request = self.req.post('/', data=form_data) self.assertEqual(view.DATA.items(), form_data.items()) def ensure_determines_non_form_content_POST(self, view): """Ensure view.RAW_CONTENT returns content for POST request with non-form content.""" content = 'qwerty' content_type = 'text/plain' view.parsers = (PlainTextParser,) view.request = self.req.post('/', content, content_type=content_type) self.assertEqual(view.DATA, content) def ensure_determines_form_content_PUT(self, view): """Ensure view.RAW_CONTENT returns content for PUT request with form content.""" form_data = {'qwerty': 'uiop'} view.parsers = (FormParser, MultiPartParser) view.request = self.req.put('/', data=form_data) self.assertEqual(view.DATA.items(), form_data.items()) def ensure_determines_non_form_content_PUT(self, view): """Ensure view.RAW_CONTENT returns content for PUT request with non-form content.""" content = 'qwerty' content_type = 'text/plain' view.parsers = (PlainTextParser,) view.request = self.req.post('/', content, content_type=content_type) self.assertEqual(view.DATA, content) def test_standard_behaviour_determines_no_content_GET(self): """Ensure view.DATA returns None for GET request with no content.""" self.ensure_determines_no_content_GET(RequestMixin()) def test_standard_behaviour_determines_form_content_POST(self): """Ensure view.DATA returns content for POST request with form content.""" self.ensure_determines_form_content_POST(RequestMixin()) def test_standard_behaviour_determines_non_form_content_POST(self): """Ensure view.DATA returns content for POST request with non-form content.""" self.ensure_determines_non_form_content_POST(RequestMixin()) def test_standard_behaviour_determines_form_content_PUT(self): """Ensure view.DATA returns content for PUT request with form content.""" self.ensure_determines_form_content_PUT(RequestMixin()) def test_standard_behaviour_determines_non_form_content_PUT(self): """Ensure view.DATA returns content for PUT request with non-form content.""" self.ensure_determines_non_form_content_PUT(RequestMixin()) def test_overloaded_behaviour_allows_content_tunnelling(self): """Ensure request.DATA returns content for overloaded POST request""" content = 'qwerty' content_type = 'text/plain' view = RequestMixin() form_data = {view._CONTENT_PARAM: content, view._CONTENTTYPE_PARAM: content_type} view.request = self.req.post('/', form_data) view.parsers = (PlainTextParser,) self.assertEqual(view.DATA, content)
class TestModelCreation(TestCase): """Tests on CreateModelMixin""" def setUp(self): self.req = RequestFactory() def test_creation(self): self.assertEquals(0, Group.objects.count()) class GroupResource(ModelResource): model = Group form_data = {'name': 'foo'} request = self.req.post('/groups', data=form_data) mixin = CreateModelMixin() mixin.resource = GroupResource mixin.CONTENT = form_data response = mixin.post(request) self.assertEquals(1, Group.objects.count()) self.assertEquals('foo', response.cleaned_content.name) def test_creation_with_m2m_relation(self): class UserResource(ModelResource): model = User def url(self, instance): return "/users/%i" % instance.id group = Group(name='foo') group.save() form_data = { 'username': '******', 'password': '******', 'groups': [group.id] } request = self.req.post('/groups', data=form_data) cleaned_data = dict(form_data) cleaned_data['groups'] = [group] mixin = CreateModelMixin() mixin.resource = UserResource mixin.CONTENT = cleaned_data response = mixin.post(request) self.assertEquals(1, User.objects.count()) self.assertEquals(1, response.cleaned_content.groups.count()) self.assertEquals('foo', response.cleaned_content.groups.all()[0].name) def test_creation_with_m2m_relation_through(self): """ Tests creation where the m2m relation uses a through table """ class UserResource(ModelResource): model = CustomUser def url(self, instance): return "/customusers/%i" % instance.id form_data = {'username': '******', 'groups': []} request = self.req.post('/groups', data=form_data) cleaned_data = dict(form_data) cleaned_data['groups'] = [] mixin = CreateModelMixin() mixin.resource = UserResource mixin.CONTENT = cleaned_data response = mixin.post(request) self.assertEquals(1, CustomUser.objects.count()) self.assertEquals(0, response.cleaned_content.groups.count()) group = Group(name='foo1') group.save() form_data = {'username': '******', 'groups': [group.id]} request = self.req.post('/groups', data=form_data) cleaned_data = dict(form_data) cleaned_data['groups'] = [group] mixin = CreateModelMixin() mixin.resource = UserResource mixin.CONTENT = cleaned_data response = mixin.post(request) self.assertEquals(2, CustomUser.objects.count()) self.assertEquals(1, response.cleaned_content.groups.count()) self.assertEquals('foo1', response.cleaned_content.groups.all()[0].name) group2 = Group(name='foo2') group2.save() form_data = {'username': '******', 'groups': [group.id, group2.id]} request = self.req.post('/groups', data=form_data) cleaned_data = dict(form_data) cleaned_data['groups'] = [group, group2] mixin = CreateModelMixin() mixin.resource = UserResource mixin.CONTENT = cleaned_data response = mixin.post(request) self.assertEquals(3, CustomUser.objects.count()) self.assertEquals(2, response.cleaned_content.groups.count()) self.assertEquals('foo1', response.cleaned_content.groups.all()[0].name) self.assertEquals('foo2', response.cleaned_content.groups.all()[1].name)