aboutsummaryrefslogtreecommitdiffstats
path: root/djangorestframework/tests
diff options
context:
space:
mode:
Diffstat (limited to 'djangorestframework/tests')
-rw-r--r--djangorestframework/tests/__init__.py13
-rw-r--r--djangorestframework/tests/accept.py86
-rw-r--r--djangorestframework/tests/authentication.py105
-rw-r--r--djangorestframework/tests/breadcrumbs.py67
-rw-r--r--djangorestframework/tests/content.py233
-rw-r--r--djangorestframework/tests/description.py111
-rw-r--r--djangorestframework/tests/files.py32
-rw-r--r--djangorestframework/tests/methods.py32
-rw-r--r--djangorestframework/tests/mixins.py291
-rw-r--r--djangorestframework/tests/models.py28
-rw-r--r--djangorestframework/tests/modelviews.py90
-rw-r--r--djangorestframework/tests/oauthentication.py212
-rw-r--r--djangorestframework/tests/package.py11
-rw-r--r--djangorestframework/tests/parsers.py210
-rw-r--r--djangorestframework/tests/renderers.py412
-rw-r--r--djangorestframework/tests/response.py19
-rw-r--r--djangorestframework/tests/reverse.py52
-rw-r--r--djangorestframework/tests/serializer.py160
-rw-r--r--djangorestframework/tests/status.py12
-rw-r--r--djangorestframework/tests/testcases.py63
-rw-r--r--djangorestframework/tests/throttling.py148
-rw-r--r--djangorestframework/tests/validators.py325
-rw-r--r--djangorestframework/tests/views.py137
23 files changed, 0 insertions, 2849 deletions
diff --git a/djangorestframework/tests/__init__.py b/djangorestframework/tests/__init__.py
deleted file mode 100644
index f664c5c1..00000000
--- a/djangorestframework/tests/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-"""Force import of all modules in this package in order to get the standard test runner to pick up the tests. Yowzers."""
-import os
-
-modules = [filename.rsplit('.', 1)[0]
- for filename in os.listdir(os.path.dirname(__file__))
- if filename.endswith('.py') and not filename.startswith('_')]
-__test__ = dict()
-
-for module in modules:
- exec("from djangorestframework.tests.%s import __doc__ as module_doc" % module)
- exec("from djangorestframework.tests.%s import *" % module)
- __test__[module] = module_doc or ""
-
diff --git a/djangorestframework/tests/accept.py b/djangorestframework/tests/accept.py
deleted file mode 100644
index 7f4eb320..00000000
--- a/djangorestframework/tests/accept.py
+++ /dev/null
@@ -1,86 +0,0 @@
-from django.conf.urls.defaults import patterns, url, include
-from django.test import TestCase
-from djangorestframework.compat import RequestFactory
-from djangorestframework.views import View
-
-
-# See: http://www.useragentstring.com/
-MSIE_9_USER_AGENT = 'Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US))'
-MSIE_8_USER_AGENT = 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)'
-MSIE_7_USER_AGENT = 'Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)'
-FIREFOX_4_0_USER_AGENT = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)'
-CHROME_11_0_USER_AGENT = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/11.0.655.0 Safari/534.17'
-SAFARI_5_0_USER_AGENT = 'Mozilla/5.0 (X11; U; Linux x86_64; en-ca) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/531.2+'
-OPERA_11_0_MSIE_USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 8.0; X11; Linux x86_64; pl) Opera 11.00'
-OPERA_11_0_OPERA_USER_AGENT = 'Opera/9.80 (X11; Linux x86_64; U; pl) Presto/2.7.62 Version/11.00'
-
-
-urlpatterns = patterns('',
- url(r'^api', include('djangorestframework.urls', namespace='djangorestframework'))
-)
-
-
-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')
-
diff --git a/djangorestframework/tests/authentication.py b/djangorestframework/tests/authentication.py
deleted file mode 100644
index 3dac7ee3..00000000
--- a/djangorestframework/tests/authentication.py
+++ /dev/null
@@ -1,105 +0,0 @@
-from django.conf.urls.defaults import patterns
-from django.contrib.auth.models import User
-from django.test import Client, TestCase
-
-from django.utils import simplejson as json
-
-from djangorestframework.views import View
-from djangorestframework import permissions
-
-import base64
-
-
-class MockView(View):
- permissions = (permissions.IsAuthenticated,)
-
- def post(self, request):
- return {'a': 1, 'b': 2, 'c': 3}
-
- def put(self, request):
- return {'a': 1, 'b': 2, 'c': 3}
-
-urlpatterns = patterns('',
- (r'^$', MockView.as_view()),
-)
-
-
-class BasicAuthTests(TestCase):
- """Basic authentication"""
- urls = 'djangorestframework.tests.authentication'
-
- def setUp(self):
- self.csrf_client = Client(enforce_csrf_checks=True)
- self.username = 'john'
- self.email = 'lennon@thebeatles.com'
- self.password = 'password'
- self.user = User.objects.create_user(self.username, self.email, self.password)
-
- def test_post_form_passing_basic_auth(self):
- """Ensure POSTing json over basic auth with correct credentials passes and does not require CSRF"""
- auth = 'Basic %s' % base64.encodestring('%s:%s' % (self.username, self.password)).strip()
- response = self.csrf_client.post('/', {'example': 'example'}, HTTP_AUTHORIZATION=auth)
- self.assertEqual(response.status_code, 200)
-
- def test_post_json_passing_basic_auth(self):
- """Ensure POSTing form over basic auth with correct credentials passes and does not require CSRF"""
- auth = 'Basic %s' % base64.encodestring('%s:%s' % (self.username, self.password)).strip()
- response = self.csrf_client.post('/', json.dumps({'example': 'example'}), 'application/json', HTTP_AUTHORIZATION=auth)
- self.assertEqual(response.status_code, 200)
-
- def test_post_form_failing_basic_auth(self):
- """Ensure POSTing form over basic auth without correct credentials fails"""
- response = self.csrf_client.post('/', {'example': 'example'})
- self.assertEqual(response.status_code, 403)
-
- def test_post_json_failing_basic_auth(self):
- """Ensure POSTing json over basic auth without correct credentials fails"""
- response = self.csrf_client.post('/', json.dumps({'example': 'example'}), 'application/json')
- self.assertEqual(response.status_code, 403)
-
-
-class SessionAuthTests(TestCase):
- """User session authentication"""
- urls = 'djangorestframework.tests.authentication'
-
- def setUp(self):
- self.csrf_client = Client(enforce_csrf_checks=True)
- self.non_csrf_client = Client(enforce_csrf_checks=False)
- self.username = 'john'
- self.email = 'lennon@thebeatles.com'
- self.password = 'password'
- self.user = User.objects.create_user(self.username, self.email, self.password)
-
- def tearDown(self):
- self.csrf_client.logout()
-
- def test_post_form_session_auth_failing_csrf(self):
- """
- Ensure POSTing form over session authentication without CSRF token fails.
- """
- self.csrf_client.login(username=self.username, password=self.password)
- response = self.csrf_client.post('/', {'example': 'example'})
- self.assertEqual(response.status_code, 403)
-
- def test_post_form_session_auth_passing(self):
- """
- Ensure POSTing form over session authentication with logged in user and CSRF token passes.
- """
- self.non_csrf_client.login(username=self.username, password=self.password)
- response = self.non_csrf_client.post('/', {'example': 'example'})
- self.assertEqual(response.status_code, 200)
-
- # def test_put_form_session_auth_passing(self):
- # """
- # Ensure PUTting form over session authentication with logged in user and CSRF token passes.
- # """
- # self.non_csrf_client.login(username=self.username, password=self.password)
- # response = self.non_csrf_client.put('/', {'example': 'example'})
- # self.assertEqual(response.status_code, 200)
-
- def test_post_form_session_auth_failing(self):
- """
- Ensure POSTing form over session authentication without logged in user fails.
- """
- response = self.csrf_client.post('/', {'example': 'example'})
- self.assertEqual(response.status_code, 403)
diff --git a/djangorestframework/tests/breadcrumbs.py b/djangorestframework/tests/breadcrumbs.py
deleted file mode 100644
index d7473c6a..00000000
--- a/djangorestframework/tests/breadcrumbs.py
+++ /dev/null
@@ -1,67 +0,0 @@
-from django.conf.urls.defaults import patterns, url
-from django.test import TestCase
-from djangorestframework.utils.breadcrumbs import get_breadcrumbs
-from djangorestframework.views import View
-
-class Root(View):
- pass
-
-class ResourceRoot(View):
- pass
-
-class ResourceInstance(View):
- pass
-
-class NestedResourceRoot(View):
- pass
-
-class NestedResourceInstance(View):
- pass
-
-urlpatterns = patterns('',
- url(r'^$', Root.as_view()),
- url(r'^resource/$', ResourceRoot.as_view()),
- url(r'^resource/(?P<key>[0-9]+)$', ResourceInstance.as_view()),
- url(r'^resource/(?P<key>[0-9]+)/$', NestedResourceRoot.as_view()),
- url(r'^resource/(?P<key>[0-9]+)/(?P<other>[A-Za-z]+)$', NestedResourceInstance.as_view()),
-)
-
-
-class BreadcrumbTests(TestCase):
- """Tests the breadcrumb functionality used by the HTML renderer."""
-
- urls = 'djangorestframework.tests.breadcrumbs'
-
- def test_root_breadcrumbs(self):
- url = '/'
- self.assertEqual(get_breadcrumbs(url), [('Root', '/')])
-
- def test_resource_root_breadcrumbs(self):
- url = '/resource/'
- self.assertEqual(get_breadcrumbs(url), [('Root', '/'),
- ('Resource Root', '/resource/')])
-
- def test_resource_instance_breadcrumbs(self):
- url = '/resource/123'
- self.assertEqual(get_breadcrumbs(url), [('Root', '/'),
- ('Resource Root', '/resource/'),
- ('Resource Instance', '/resource/123')])
-
- def test_nested_resource_breadcrumbs(self):
- url = '/resource/123/'
- self.assertEqual(get_breadcrumbs(url), [('Root', '/'),
- ('Resource Root', '/resource/'),
- ('Resource Instance', '/resource/123'),
- ('Nested Resource Root', '/resource/123/')])
-
- def test_nested_resource_instance_breadcrumbs(self):
- url = '/resource/123/abc'
- self.assertEqual(get_breadcrumbs(url), [('Root', '/'),
- ('Resource Root', '/resource/'),
- ('Resource Instance', '/resource/123'),
- ('Nested Resource Root', '/resource/123/'),
- ('Nested Resource Instance', '/resource/123/abc')])
-
- def test_broken_url_breadcrumbs_handled_gracefully(self):
- url = '/foobar'
- self.assertEqual(get_breadcrumbs(url), [('Root', '/')])
diff --git a/djangorestframework/tests/content.py b/djangorestframework/tests/content.py
deleted file mode 100644
index e5d98e32..00000000
--- a/djangorestframework/tests/content.py
+++ /dev/null
@@ -1,233 +0,0 @@
-"""
-Tests for content parsing, and form-overloaded content parsing.
-"""
-from django.conf.urls.defaults import patterns
-from django.contrib.auth.models import User
-from django.test import TestCase, Client
-from djangorestframework import status
-from djangorestframework.authentication import UserLoggedInAuthentication
-from djangorestframework.compat import RequestFactory, unittest
-from djangorestframework.mixins import RequestMixin
-from djangorestframework.parsers import FormParser, MultiPartParser, \
- PlainTextParser, JSONParser
-from djangorestframework.response import Response
-from djangorestframework.views import View
-
-class MockView(View):
- authentication = (UserLoggedInAuthentication,)
- def post(self, request):
- if request.POST.get('example') is not None:
- return Response(status.HTTP_200_OK)
-
- return Response(status.INTERNAL_SERVER_ERROR)
-
-urlpatterns = patterns('',
- (r'^$', MockView.as_view()),
-)
-
-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())
-
- @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"""
- 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 TestContentParsingWithAuthentication(TestCase):
- urls = 'djangorestframework.tests.content'
-
- def setUp(self):
- self.csrf_client = Client(enforce_csrf_checks=True)
- self.username = 'john'
- self.email = 'lennon@thebeatles.com'
- self.password = 'password'
- self.user = User.objects.create_user(self.username, self.email, self.password)
- self.req = RequestFactory()
-
- def test_user_logged_in_authentication_has_post_when_not_logged_in(self):
- """Ensures request.POST exists after UserLoggedInAuthentication when user doesn't log in"""
- content = {'example': 'example'}
-
- response = self.client.post('/', content)
- self.assertEqual(status.HTTP_200_OK, response.status_code, "POST data is malformed")
-
- response = self.csrf_client.post('/', content)
- self.assertEqual(status.HTTP_200_OK, response.status_code, "POST data is malformed")
-
- # def test_user_logged_in_authentication_has_post_when_logged_in(self):
- # """Ensures request.POST exists after UserLoggedInAuthentication when user does log in"""
- # self.client.login(username='john', password='password')
- # self.csrf_client.login(username='john', password='password')
- # content = {'example': 'example'}
-
- # response = self.client.post('/', content)
- # self.assertEqual(status.OK, response.status_code, "POST data is malformed")
-
- # response = self.csrf_client.post('/', content)
- # self.assertEqual(status.OK, response.status_code, "POST data is malformed")
diff --git a/djangorestframework/tests/description.py b/djangorestframework/tests/description.py
deleted file mode 100644
index 212b4ca4..00000000
--- a/djangorestframework/tests/description.py
+++ /dev/null
@@ -1,111 +0,0 @@
-from django.test import TestCase
-from djangorestframework.views import View
-from djangorestframework.compat import apply_markdown
-
-# We check that docstrings get nicely un-indented.
-DESCRIPTION = """an example docstring
-====================
-
-* list
-* list
-
-another header
---------------
-
- code block
-
-indented
-
-# hash style header #"""
-
-# If markdown is installed we also test it's working
-# (and that our wrapped forces '=' to h2 and '-' to h3)
-
-# We support markdown < 2.1 and markdown >= 2.1
-MARKED_DOWN_lt_21 = """<h2>an example docstring</h2>
-<ul>
-<li>list</li>
-<li>list</li>
-</ul>
-<h3>another header</h3>
-<pre><code>code block
-</code></pre>
-<p>indented</p>
-<h2 id="hash_style_header">hash style header</h2>"""
-
-MARKED_DOWN_gte_21 = """<h2 id="an-example-docstring">an example docstring</h2>
-<ul>
-<li>list</li>
-<li>list</li>
-</ul>
-<h3 id="another-header">another header</h3>
-<pre><code>code block
-</code></pre>
-<p>indented</p>
-<h2 id="hash-style-header">hash style header</h2>"""
-
-
-class TestViewNamesAndDescriptions(TestCase):
- def test_resource_name_uses_classname_by_default(self):
- """Ensure Resource names are based on the classname by default."""
- class MockView(View):
- pass
- self.assertEquals(MockView().get_name(), 'Mock')
-
- def test_resource_name_can_be_set_explicitly(self):
- """Ensure Resource names can be set using the 'get_name' method."""
- example = 'Some Other Name'
- class MockView(View):
- def get_name(self):
- return example
- self.assertEquals(MockView().get_name(), example)
-
- def test_resource_description_uses_docstring_by_default(self):
- """Ensure Resource names are based on the docstring by default."""
- class MockView(View):
- """an example docstring
- ====================
-
- * list
- * list
-
- another header
- --------------
-
- code block
-
- indented
-
- # hash style header #"""
-
- self.assertEquals(MockView().get_description(), DESCRIPTION)
-
- def test_resource_description_can_be_set_explicitly(self):
- """Ensure Resource descriptions can be set using the 'get_description' method."""
- example = 'Some other description'
- class MockView(View):
- """docstring"""
- def get_description(self):
- return example
- self.assertEquals(MockView().get_description(), example)
-
- def test_resource_description_does_not_require_docstring(self):
- """Ensure that empty docstrings do not affect the Resource's description if it has been set using the 'get_description' method."""
- example = 'Some other description'
- class MockView(View):
- def get_description(self):
- return example
- self.assertEquals(MockView().get_description(), example)
-
- def test_resource_description_can_be_empty(self):
- """Ensure that if a resource has no doctring or 'description' class attribute, then it's description is the empty string."""
- class MockView(View):
- pass
- self.assertEquals(MockView().get_description(), '')
-
- def test_markdown(self):
- """Ensure markdown to HTML works as expected"""
- if apply_markdown:
- gte_21_match = apply_markdown(DESCRIPTION) == MARKED_DOWN_gte_21
- lt_21_match = apply_markdown(DESCRIPTION) == MARKED_DOWN_lt_21
- self.assertTrue(gte_21_match or lt_21_match)
diff --git a/djangorestframework/tests/files.py b/djangorestframework/tests/files.py
deleted file mode 100644
index d3b1cc56..00000000
--- a/djangorestframework/tests/files.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from django.test import TestCase
-from django import forms
-from djangorestframework.compat import RequestFactory
-from djangorestframework.views import View
-from djangorestframework.resources import FormResource
-import StringIO
-
-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"}')
-
diff --git a/djangorestframework/tests/methods.py b/djangorestframework/tests/methods.py
deleted file mode 100644
index 4b90a21f..00000000
--- a/djangorestframework/tests/methods.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from django.test import TestCase
-from djangorestframework.compat import RequestFactory
-from djangorestframework.mixins import RequestMixin
-
-
-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')
diff --git a/djangorestframework/tests/mixins.py b/djangorestframework/tests/mixins.py
deleted file mode 100644
index 8268fdca..00000000
--- a/djangorestframework/tests/mixins.py
+++ /dev/null
@@ -1,291 +0,0 @@
-"""Tests for the mixin module"""
-from django.test import TestCase
-from django.utils import simplejson as json
-from djangorestframework import status
-from djangorestframework.compat import RequestFactory
-from django.contrib.auth.models import Group, User
-from djangorestframework.mixins import CreateModelMixin, PaginatorMixin, ReadModelMixin
-from djangorestframework.resources import ModelResource
-from djangorestframework.response import Response, ErrorResponse
-from djangorestframework.tests.models import CustomUser
-from djangorestframework.tests.testcases import TestModelsTestCase
-from djangorestframework.views import View
-
-
-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 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': 'bar',
- 'password': 'baz',
- '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': 'bar0', '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': 'bar1', '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': 'bar2', '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 MockPaginatorView(PaginatorMixin, View):
- total = 60
-
- def get(self, request):
- return range(0, self.total)
-
- def post(self, request):
- return Response(status.HTTP_201_CREATED, {'status': 'OK'})
-
-
-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'])
-
- 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'])
diff --git a/djangorestframework/tests/models.py b/djangorestframework/tests/models.py
deleted file mode 100644
index 4cae68b6..00000000
--- a/djangorestframework/tests/models.py
+++ /dev/null
@@ -1,28 +0,0 @@
-from django.db import models
-from django.contrib.auth.models import Group
-
-class CustomUser(models.Model):
- """
- A custom user model, which uses a 'through' table for the foreign key
- """
- username = models.CharField(max_length=255, unique=True)
- groups = models.ManyToManyField(
- to=Group, blank=True, null=True, through='UserGroupMap'
- )
-
- @models.permalink
- def get_absolute_url(self):
- return ('custom_user', (), {
- 'pk': self.id
- })
-
-
-class UserGroupMap(models.Model):
- user = models.ForeignKey(to=CustomUser)
- group = models.ForeignKey(to=Group)
-
- @models.permalink
- def get_absolute_url(self):
- return ('user_group_map', (), {
- 'pk': self.id
- })
diff --git a/djangorestframework/tests/modelviews.py b/djangorestframework/tests/modelviews.py
deleted file mode 100644
index ccd8513f..00000000
--- a/djangorestframework/tests/modelviews.py
+++ /dev/null
@@ -1,90 +0,0 @@
-from django.conf.urls.defaults import patterns, url
-from django.forms import ModelForm
-from django.contrib.auth.models import Group, User
-from djangorestframework.resources import ModelResource
-from djangorestframework.views import ListOrCreateModelView, InstanceModelView
-from djangorestframework.tests.models import CustomUser
-from djangorestframework.tests.testcases import TestModelsTestCase
-
-
-class GroupResource(ModelResource):
- model = Group
-
-
-class UserForm(ModelForm):
- class Meta:
- model = User
- exclude = ('last_login', 'date_joined')
-
-
-class UserResource(ModelResource):
- model = User
- form = UserForm
-
-
-class CustomUserResource(ModelResource):
- model = CustomUser
-
-urlpatterns = patterns('',
- url(r'^users/$', ListOrCreateModelView.as_view(resource=UserResource), name='users'),
- url(r'^users/(?P<id>[0-9]+)/$', InstanceModelView.as_view(resource=UserResource)),
- url(r'^customusers/$', ListOrCreateModelView.as_view(resource=CustomUserResource), name='customusers'),
- url(r'^customusers/(?P<id>[0-9]+)/$', InstanceModelView.as_view(resource=CustomUserResource)),
- url(r'^groups/$', ListOrCreateModelView.as_view(resource=GroupResource), name='groups'),
- url(r'^groups/(?P<id>[0-9]+)/$', InstanceModelView.as_view(resource=GroupResource)),
-)
-
-
-class ModelViewTests(TestModelsTestCase):
- """Test the model views djangorestframework provides"""
- urls = 'djangorestframework.tests.modelviews'
-
- def test_creation(self):
- """Ensure that a model object can be created"""
- self.assertEqual(0, Group.objects.count())
-
- response = self.client.post('/groups/', {'name': 'foo'})
-
- self.assertEqual(response.status_code, 201)
- self.assertEqual(1, Group.objects.count())
- self.assertEqual('foo', Group.objects.all()[0].name)
-
- def test_creation_with_m2m_relation(self):
- """Ensure that a model object with a m2m relation can be created"""
- group = Group(name='foo')
- group.save()
- self.assertEqual(0, User.objects.count())
-
- response = self.client.post('/users/', {'username': 'bar', 'password': 'baz', 'groups': [group.id]})
-
- self.assertEqual(response.status_code, 201)
- self.assertEqual(1, User.objects.count())
-
- user = User.objects.all()[0]
- self.assertEqual('bar', user.username)
- self.assertEqual('baz', user.password)
- self.assertEqual(1, user.groups.count())
-
- group = user.groups.all()[0]
- self.assertEqual('foo', group.name)
-
- def test_creation_with_m2m_relation_through(self):
- """
- Ensure that a model object with a m2m relation can be created where that
- relation uses a through table
- """
- group = Group(name='foo')
- group.save()
- self.assertEqual(0, User.objects.count())
-
- response = self.client.post('/customusers/', {'username': 'bar', 'groups': [group.id]})
-
- self.assertEqual(response.status_code, 201)
- self.assertEqual(1, CustomUser.objects.count())
-
- user = CustomUser.objects.all()[0]
- self.assertEqual('bar', user.username)
- self.assertEqual(1, user.groups.count())
-
- group = user.groups.all()[0]
- self.assertEqual('foo', group.name)
diff --git a/djangorestframework/tests/oauthentication.py b/djangorestframework/tests/oauthentication.py
deleted file mode 100644
index 29f2c44e..00000000
--- a/djangorestframework/tests/oauthentication.py
+++ /dev/null
@@ -1,212 +0,0 @@
-import time
-
-from django.conf.urls.defaults import patterns, url, include
-from django.contrib.auth.models import User
-from django.test import Client, TestCase
-
-from djangorestframework.views import View
-
-# Since oauth2 / django-oauth-plus are optional dependancies, we don't want to
-# always run these tests.
-
-# Unfortunatly we can't skip tests easily until 2.7, se we'll just do this for now.
-try:
- import oauth2 as oauth
- from oauth_provider.decorators import oauth_required
- from oauth_provider.models import Resource, Consumer, Token
-
-except ImportError:
- pass
-
-else:
- # Alrighty, we're good to go here.
- class ClientView(View):
- def get(self, request):
- return {'resource': 'Protected!'}
-
- urlpatterns = patterns('',
- url(r'^$', oauth_required(ClientView.as_view())),
- url(r'^oauth/', include('oauth_provider.urls')),
- url(r'^restframework/', include('djangorestframework.urls', namespace='djangorestframework')),
- )
-
-
- class OAuthTests(TestCase):
- """
- OAuth authentication:
- * the user would like to access his API data from a third-party website
- * the third-party website proposes a link to get that API data
- * the user is redirected to the API and must log in if not authenticated
- * the API displays a webpage to confirm that the user trusts the third-party website
- * if confirmed, the user is redirected to the third-party website through the callback view
- * the third-party website is able to retrieve data from the API
- """
- urls = 'djangorestframework.tests.oauthentication'
-
- def setUp(self):
- self.client = Client()
- self.username = 'john'
- self.email = 'lennon@thebeatles.com'
- self.password = 'password'
- self.user = User.objects.create_user(self.username, self.email, self.password)
-
- # OAuth requirements
- self.resource = Resource(name='data', url='/')
- self.resource.save()
- self.CONSUMER_KEY = 'dpf43f3p2l4k3l03'
- self.CONSUMER_SECRET = 'kd94hf93k423kf44'
- self.consumer = Consumer(key=self.CONSUMER_KEY, secret=self.CONSUMER_SECRET,
- name='api.example.com', user=self.user)
- self.consumer.save()
-
- def test_oauth_invalid_and_anonymous_access(self):
- """
- Verify that the resource is protected and the OAuth authorization view
- require the user to be logged in.
- """
- response = self.client.get('/')
- self.assertEqual(response.content, 'Invalid request parameters.')
- self.assertEqual(response.status_code, 401)
- response = self.client.get('/oauth/authorize/', follow=True)
- self.assertRedirects(response, '/accounts/login/?next=/oauth/authorize/')
-
- def test_oauth_authorize_access(self):
- """
- Verify that once logged in, the user can access the authorization page
- but can't display the page because the request token is not specified.
- """
- self.client.login(username=self.username, password=self.password)
- response = self.client.get('/oauth/authorize/', follow=True)
- self.assertEqual(response.content, 'No request token specified.')
-
- def _create_request_token_parameters(self):
- """
- A shortcut to create request's token parameters.
- """
- return {
- 'oauth_consumer_key': self.CONSUMER_KEY,
- 'oauth_signature_method': 'PLAINTEXT',
- 'oauth_signature': '%s&' % self.CONSUMER_SECRET,
- 'oauth_timestamp': str(int(time.time())),
- 'oauth_nonce': 'requestnonce',
- 'oauth_version': '1.0',
- 'oauth_callback': 'http://api.example.com/request_token_ready',
- 'scope': 'data',
- }
-
- def test_oauth_request_token_retrieval(self):
- """
- Verify that the request token can be retrieved by the server.
- """
- response = self.client.get("/oauth/request_token/",
- self._create_request_token_parameters())
- self.assertEqual(response.status_code, 200)
- token = list(Token.objects.all())[-1]
- self.failIf(token.key not in response.content)
- self.failIf(token.secret not in response.content)
-
- def test_oauth_user_request_authorization(self):
- """
- Verify that the user can access the authorization page once logged in
- and the request token has been retrieved.
- """
- # Setup
- response = self.client.get("/oauth/request_token/",
- self._create_request_token_parameters())
- token = list(Token.objects.all())[-1]
-
- # Starting the test here
- self.client.login(username=self.username, password=self.password)
- parameters = {'oauth_token': token.key,}
- response = self.client.get("/oauth/authorize/", parameters)
- self.assertEqual(response.status_code, 200)
- self.failIf(not response.content.startswith('Fake authorize view for api.example.com with params: oauth_token='))
- self.assertEqual(token.is_approved, 0)
- parameters['authorize_access'] = 1 # fake authorization by the user
- response = self.client.post("/oauth/authorize/", parameters)
- self.assertEqual(response.status_code, 302)
- self.failIf(not response['Location'].startswith('http://api.example.com/request_token_ready?oauth_verifier='))
- token = Token.objects.get(key=token.key)
- self.failIf(token.key not in response['Location'])
- self.assertEqual(token.is_approved, 1)
-
- def _create_access_token_parameters(self, token):
- """
- A shortcut to create access' token parameters.
- """
- return {
- 'oauth_consumer_key': self.CONSUMER_KEY,
- 'oauth_token': token.key,
- 'oauth_signature_method': 'PLAINTEXT',
- 'oauth_signature': '%s&%s' % (self.CONSUMER_SECRET, token.secret),
- 'oauth_timestamp': str(int(time.time())),
- 'oauth_nonce': 'accessnonce',
- 'oauth_version': '1.0',
- 'oauth_verifier': token.verifier,
- 'scope': 'data',
- }
-
- def test_oauth_access_token_retrieval(self):
- """
- Verify that the request token can be retrieved by the server.
- """
- # Setup
- response = self.client.get("/oauth/request_token/",
- self._create_request_token_parameters())
- token = list(Token.objects.all())[-1]
- self.client.login(username=self.username, password=self.password)
- parameters = {'oauth_token': token.key,}
- response = self.client.get("/oauth/authorize/", parameters)
- parameters['authorize_access'] = 1 # fake authorization by the user
- response = self.client.post("/oauth/authorize/", parameters)
- token = Token.objects.get(key=token.key)
-
- # Starting the test here
- response = self.client.get("/oauth/access_token/", self._create_access_token_parameters(token))
- self.assertEqual(response.status_code, 200)
- self.failIf(not response.content.startswith('oauth_token_secret='))
- access_token = list(Token.objects.filter(token_type=Token.ACCESS))[-1]
- self.failIf(access_token.key not in response.content)
- self.failIf(access_token.secret not in response.content)
- self.assertEqual(access_token.user.username, 'john')
-
- def _create_access_parameters(self, access_token):
- """
- A shortcut to create access' parameters.
- """
- parameters = {
- 'oauth_consumer_key': self.CONSUMER_KEY,
- 'oauth_token': access_token.key,
- 'oauth_signature_method': 'HMAC-SHA1',
- 'oauth_timestamp': str(int(time.time())),
- 'oauth_nonce': 'accessresourcenonce',
- 'oauth_version': '1.0',
- }
- oauth_request = oauth.Request.from_token_and_callback(access_token,
- http_url='http://testserver/', parameters=parameters)
- signature_method = oauth.SignatureMethod_HMAC_SHA1()
- signature = signature_method.sign(oauth_request, self.consumer, access_token)
- parameters['oauth_signature'] = signature
- return parameters
-
- def test_oauth_protected_resource_access(self):
- """
- Verify that the request token can be retrieved by the server.
- """
- # Setup
- response = self.client.get("/oauth/request_token/",
- self._create_request_token_parameters())
- token = list(Token.objects.all())[-1]
- self.client.login(username=self.username, password=self.password)
- parameters = {'oauth_token': token.key,}
- response = self.client.get("/oauth/authorize/", parameters)
- parameters['authorize_access'] = 1 # fake authorization by the user
- response = self.client.post("/oauth/authorize/", parameters)
- token = Token.objects.get(key=token.key)
- response = self.client.get("/oauth/access_token/", self._create_access_token_parameters(token))
- access_token = list(Token.objects.filter(token_type=Token.ACCESS))[-1]
-
- # Starting the test here
- response = self.client.get("/", self._create_access_token_parameters(access_token))
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.content, '{"resource": "Protected!"}')
diff --git a/djangorestframework/tests/package.py b/djangorestframework/tests/package.py
deleted file mode 100644
index d18128f7..00000000
--- a/djangorestframework/tests/package.py
+++ /dev/null
@@ -1,11 +0,0 @@
-"""Tests for the djangorestframework package setup."""
-from django.test import TestCase
-import djangorestframework
-
-class TestVersion(TestCase):
- """Simple sanity test to check the VERSION exists"""
-
- def test_version(self):
- """Ensure the VERSION exists."""
- djangorestframework.VERSION
-
diff --git a/djangorestframework/tests/parsers.py b/djangorestframework/tests/parsers.py
deleted file mode 100644
index 1ecc1760..00000000
--- a/djangorestframework/tests/parsers.py
+++ /dev/null
@@ -1,210 +0,0 @@
-# """
-# ..
-# >>> from djangorestframework.parsers import FormParser
-# >>> from djangorestframework.compat import RequestFactory
-# >>> from djangorestframework.views import View
-# >>> from StringIO import StringIO
-# >>> from urllib import urlencode
-# >>> req = RequestFactory().get('/')
-# >>> some_view = View()
-# >>> some_view.request = req # Make as if this request had been dispatched
-#
-# FormParser
-# ============
-#
-# Data flatening
-# ----------------
-#
-# Here is some example data, which would eventually be sent along with a post request :
-#
-# >>> inpt = urlencode([
-# ... ('key1', 'bla1'),
-# ... ('key2', 'blo1'), ('key2', 'blo2'),
-# ... ])
-#
-# Default behaviour for :class:`parsers.FormParser`, is to return a single value for each parameter :
-#
-# >>> (data, files) = FormParser(some_view).parse(StringIO(inpt))
-# >>> data == {'key1': 'bla1', 'key2': 'blo1'}
-# True
-#
-# However, you can customize this behaviour by subclassing :class:`parsers.FormParser`, and overriding :meth:`parsers.FormParser.is_a_list` :
-#
-# >>> class MyFormParser(FormParser):
-# ...
-# ... def is_a_list(self, key, val_list):
-# ... return len(val_list) > 1
-#
-# This new parser only flattens the lists of parameters that contain a single value.
-#
-# >>> (data, files) = MyFormParser(some_view).parse(StringIO(inpt))
-# >>> data == {'key1': 'bla1', 'key2': ['blo1', 'blo2']}
-# True
-#
-# .. note:: The same functionality is available for :class:`parsers.MultiPartParser`.
-#
-# Submitting an empty list
-# --------------------------
-#
-# When submitting an empty select multiple, like this one ::
-#
-# <select multiple="multiple" name="key2"></select>
-#
-# The browsers usually strip the parameter completely. A hack to avoid this, and therefore being able to submit an empty select multiple, is to submit a value that tells the server that the list is empty ::
-#
-# <select multiple="multiple" name="key2"><option value="_empty"></select>
-#
-# :class:`parsers.FormParser` provides the server-side implementation for this hack. Considering the following posted data :
-#
-# >>> inpt = urlencode([
-# ... ('key1', 'blo1'), ('key1', '_empty'),
-# ... ('key2', '_empty'),
-# ... ])
-#
-# :class:`parsers.FormParser` strips the values ``_empty`` from all the lists.
-#
-# >>> (data, files) = MyFormParser(some_view).parse(StringIO(inpt))
-# >>> data == {'key1': 'blo1'}
-# True
-#
-# Oh ... but wait a second, the parameter ``key2`` isn't even supposed to be a list, so the parser just stripped it.
-#
-# >>> class MyFormParser(FormParser):
-# ...
-# ... def is_a_list(self, key, val_list):
-# ... return key == 'key2'
-# ...
-# >>> (data, files) = MyFormParser(some_view).parse(StringIO(inpt))
-# >>> data == {'key1': 'blo1', 'key2': []}
-# True
-#
-# Better like that. Note that you can configure something else than ``_empty`` for the empty value by setting :attr:`parsers.FormParser.EMPTY_VALUE`.
-# """
-# import httplib, mimetypes
-# from tempfile import TemporaryFile
-# from django.test import TestCase
-# from djangorestframework.compat import RequestFactory
-# from djangorestframework.parsers import MultiPartParser
-# from djangorestframework.views import View
-# from StringIO import StringIO
-#
-# def encode_multipart_formdata(fields, files):
-# """For testing multipart parser.
-# fields is a sequence of (name, value) elements for regular form fields.
-# files is a sequence of (name, filename, value) elements for data to be uploaded as files
-# Return (content_type, body)."""
-# BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
-# CRLF = '\r\n'
-# L = []
-# for (key, value) in fields:
-# L.append('--' + BOUNDARY)
-# L.append('Content-Disposition: form-data; name="%s"' % key)
-# L.append('')
-# L.append(value)
-# for (key, filename, value) in files:
-# L.append('--' + BOUNDARY)
-# L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
-# L.append('Content-Type: %s' % get_content_type(filename))
-# L.append('')
-# L.append(value)
-# L.append('--' + BOUNDARY + '--')
-# L.append('')
-# body = CRLF.join(L)
-# content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
-# return content_type, body
-#
-# def get_content_type(filename):
-# return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
-#
-#class TestMultiPartParser(TestCase):
-# def setUp(self):
-# self.req = RequestFactory()
-# self.content_type, self.body = encode_multipart_formdata([('key1', 'val1'), ('key1', 'val2')],
-# [('file1', 'pic.jpg', 'blablabla'), ('file1', 't.txt', 'blobloblo')])
-#
-# def test_multipartparser(self):
-# """Ensure that MultiPartParser can parse multipart/form-data that contains a mix of several files and parameters."""
-# post_req = RequestFactory().post('/', self.body, content_type=self.content_type)
-# view = View()
-# view.request = post_req
-# (data, files) = MultiPartParser(view).parse(StringIO(self.body))
-# self.assertEqual(data['key1'], 'val1')
-# self.assertEqual(files['file1'].read(), 'blablabla')
-
-from StringIO import StringIO
-from cgi import parse_qs
-from django import forms
-from django.test import TestCase
-from djangorestframework.parsers import FormParser
-from djangorestframework.parsers import XMLParser
-import datetime
-
-class Form(forms.Form):
- field1 = forms.CharField(max_length=3)
- field2 = forms.CharField()
-
-class TestFormParser(TestCase):
- def setUp(self):
- self.string = "field1=abc&field2=defghijk"
-
- def test_parse(self):
- """ Make sure the `QueryDict` works OK """
- parser = FormParser(None)
-
- stream = StringIO(self.string)
- (data, files) = parser.parse(stream)
-
- self.assertEqual(Form(data).is_valid(), True)
-
-class TestXMLParser(TestCase):
- def setUp(self):
- self._input = StringIO(
- '<?xml version="1.0" encoding="utf-8"?>'
- '<root>'
- '<field_a>121.0</field_a>'
- '<field_b>dasd</field_b>'
- '<field_c></field_c>'
- '<field_d>2011-12-25 12:45:00</field_d>'
- '</root>'
- )
- self._data = {
- 'field_a': 121,
- 'field_b': 'dasd',
- 'field_c': None,
- 'field_d': datetime.datetime(2011, 12, 25, 12, 45, 00)
- }
- self._complex_data_input = StringIO(
- '<?xml version="1.0" encoding="utf-8"?>'
- '<root>'
- '<creation_date>2011-12-25 12:45:00</creation_date>'
- '<sub_data_list>'
- '<list-item><sub_id>1</sub_id><sub_name>first</sub_name></list-item>'
- '<list-item><sub_id>2</sub_id><sub_name>second</sub_name></list-item>'
- '</sub_data_list>'
- '<name>name</name>'
- '</root>'
- )
- self._complex_data = {
- "creation_date": datetime.datetime(2011, 12, 25, 12, 45, 00),
- "name": "name",
- "sub_data_list": [
- {
- "sub_id": 1,
- "sub_name": "first"
- },
- {
- "sub_id": 2,
- "sub_name": "second"
- }
- ]
- }
-
- def test_parse(self):
- parser = XMLParser(None)
- (data, files) = parser.parse(self._input)
- self.assertEqual(data, self._data)
-
- def test_complex_data_parse(self):
- parser = XMLParser(None)
- (data, files) = parser.parse(self._complex_data_input)
- self.assertEqual(data, self._complex_data)
diff --git a/djangorestframework/tests/renderers.py b/djangorestframework/tests/renderers.py
deleted file mode 100644
index 3ed5ab28..00000000
--- a/djangorestframework/tests/renderers.py
+++ /dev/null
@@ -1,412 +0,0 @@
-import re
-
-from django.conf.urls.defaults import patterns, url, include
-from django.test import TestCase
-
-from djangorestframework import status
-from djangorestframework.views import View
-from djangorestframework.compat import View as DjangoView
-from djangorestframework.renderers import BaseRenderer, JSONRenderer, YAMLRenderer, \
- XMLRenderer, JSONPRenderer, DocumentingHTMLRenderer
-from djangorestframework.parsers import JSONParser, YAMLParser, XMLParser
-from djangorestframework.mixins import ResponseMixin
-from djangorestframework.response import Response
-
-from StringIO import StringIO
-import datetime
-from decimal import Decimal
-
-DUMMYSTATUS = status.HTTP_200_OK
-DUMMYCONTENT = 'dummycontent'
-
-RENDERER_A_SERIALIZER = lambda x: 'Renderer A: %s' % x
-RENDERER_B_SERIALIZER = lambda x: 'Renderer B: %s' % x
-
-
-class RendererA(BaseRenderer):
- media_type = 'mock/renderera'
- format = "formata"
-
- def render(self, obj=None, media_type=None):
- return RENDERER_A_SERIALIZER(obj)
-
-
-class RendererB(BaseRenderer):
- media_type = 'mock/rendererb'
- format = "formatb"
-
- def render(self, obj=None, media_type=None):
- return RENDERER_B_SERIALIZER(obj)
-
-
-class MockView(ResponseMixin, DjangoView):
- renderers = (RendererA, RendererB)
-
- def get(self, request, **kwargs):
- response = Response(DUMMYSTATUS, DUMMYCONTENT)
- return self.render(response)
-
-
-class MockGETView(View):
-
- def get(self, request, **kwargs):
- return {'foo': ['bar', 'baz']}
-
-
-class HTMLView(View):
- renderers = (DocumentingHTMLRenderer, )
-
- def get(self, request, **kwargs):
- return 'text'
-
-
-class HTMLView1(View):
- renderers = (DocumentingHTMLRenderer, JSONRenderer)
-
- def get(self, request, **kwargs):
- return 'text'
-
-urlpatterns = patterns('',
- url(r'^.*\.(?P<format>.+)$', MockView.as_view(renderers=[RendererA, RendererB])),
- url(r'^$', MockView.as_view(renderers=[RendererA, RendererB])),
- url(r'^jsonp/jsonrenderer$', MockGETView.as_view(renderers=[JSONRenderer, JSONPRenderer])),
- url(r'^jsonp/nojsonrenderer$', MockGETView.as_view(renderers=[JSONPRenderer])),
- url(r'^html$', HTMLView.as_view()),
- url(r'^html1$', HTMLView1.as_view()),
- url(r'^api', include('djangorestframework.urls', namespace='djangorestframework'))
-)
-
-
-class RendererIntegrationTests(TestCase):
- """
- End-to-end testing of renderers using an RendererMixin on a generic view.
- """
-
- urls = 'djangorestframework.tests.renderers'
-
- def test_default_renderer_serializes_content(self):
- """If the Accept header is not set the default renderer should serialize the response."""
- resp = self.client.get('/')
- self.assertEquals(resp['Content-Type'], RendererA.media_type)
- self.assertEquals(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT))
- self.assertEquals(resp.status_code, DUMMYSTATUS)
-
- def test_head_method_serializes_no_content(self):
- """No response must be included in HEAD requests."""
- resp = self.client.head('/')
- self.assertEquals(resp.status_code, DUMMYSTATUS)
- self.assertEquals(resp['Content-Type'], RendererA.media_type)
- self.assertEquals(resp.content, '')
-
- def test_default_renderer_serializes_content_on_accept_any(self):
- """If the Accept header is set to */* the default renderer should serialize the response."""
- resp = self.client.get('/', HTTP_ACCEPT='*/*')
- self.assertEquals(resp['Content-Type'], RendererA.media_type)
- self.assertEquals(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT))
- self.assertEquals(resp.status_code, DUMMYSTATUS)
-
- def test_specified_renderer_serializes_content_default_case(self):
- """If the Accept header is set the specified renderer should serialize the response.
- (In this case we check that works for the default renderer)"""
- resp = self.client.get('/', HTTP_ACCEPT=RendererA.media_type)
- self.assertEquals(resp['Content-Type'], RendererA.media_type)
- self.assertEquals(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT))
- self.assertEquals(resp.status_code, DUMMYSTATUS)
-
- def test_specified_renderer_serializes_content_non_default_case(self):
- """If the Accept header is set the specified renderer should serialize the response.
- (In this case we check that works for a non-default renderer)"""
- resp = self.client.get('/', HTTP_ACCEPT=RendererB.media_type)
- self.assertEquals(resp['Content-Type'], RendererB.media_type)
- self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
- self.assertEquals(resp.status_code, DUMMYSTATUS)
-
- def test_specified_renderer_serializes_content_on_accept_query(self):
- """The '_accept' query string should behave in the same way as the Accept header."""
- resp = self.client.get('/?_accept=%s' % RendererB.media_type)
- self.assertEquals(resp['Content-Type'], RendererB.media_type)
- self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
- self.assertEquals(resp.status_code, DUMMYSTATUS)
-
- def test_unsatisfiable_accept_header_on_request_returns_406_status(self):
- """If the Accept header is unsatisfiable we should return a 406 Not Acceptable response."""
- resp = self.client.get('/', HTTP_ACCEPT='foo/bar')
- self.assertEquals(resp.status_code, status.HTTP_406_NOT_ACCEPTABLE)
-
- def test_specified_renderer_serializes_content_on_format_query(self):
- """If a 'format' query is specified, the renderer with the matching
- format attribute should serialize the response."""
- resp = self.client.get('/?format=%s' % RendererB.format)
- self.assertEquals(resp['Content-Type'], RendererB.media_type)
- self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
- self.assertEquals(resp.status_code, DUMMYSTATUS)
-
- def test_specified_renderer_serializes_content_on_format_kwargs(self):
- """If a 'format' keyword arg is specified, the renderer with the matching
- format attribute should serialize the response."""
- resp = self.client.get('/something.formatb')
- self.assertEquals(resp['Content-Type'], RendererB.media_type)
- self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
- self.assertEquals(resp.status_code, DUMMYSTATUS)
-
- def test_specified_renderer_is_used_on_format_query_with_matching_accept(self):
- """If both a 'format' query and a matching Accept header specified,
- the renderer with the matching format attribute should serialize the response."""
- resp = self.client.get('/?format=%s' % RendererB.format,
- HTTP_ACCEPT=RendererB.media_type)
- self.assertEquals(resp['Content-Type'], RendererB.media_type)
- self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
- self.assertEquals(resp.status_code, DUMMYSTATUS)
-
- def test_conflicting_format_query_and_accept_ignores_accept(self):
- """If a 'format' query is specified that does not match the Accept
- header, we should only honor the 'format' query string."""
- resp = self.client.get('/?format=%s' % RendererB.format,
- HTTP_ACCEPT='dummy')
- self.assertEquals(resp['Content-Type'], RendererB.media_type)
- self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
- self.assertEquals(resp.status_code, DUMMYSTATUS)
-
- def test_bla(self):
- resp = self.client.get('/?format=formatb',
- HTTP_ACCEPT='text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8')
- self.assertEquals(resp['Content-Type'], RendererB.media_type)
- self.assertEquals(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
- self.assertEquals(resp.status_code, DUMMYSTATUS)
-
-_flat_repr = '{"foo": ["bar", "baz"]}'
-_indented_repr = '{\n "foo": [\n "bar",\n "baz"\n ]\n}'
-
-
-def strip_trailing_whitespace(content):
- """
- Seems to be some inconsistencies re. trailing whitespace with
- different versions of the json lib.
- """
- return re.sub(' +\n', '\n', content)
-
-class JSONRendererTests(TestCase):
- """
- Tests specific to the JSON Renderer
- """
-
- def test_without_content_type_args(self):
- """
- Test basic JSON rendering.
- """
- obj = {'foo': ['bar', 'baz']}
- renderer = JSONRenderer(None)
- content = renderer.render(obj, 'application/json')
- # Fix failing test case which depends on version of JSON library.
- self.assertEquals(content, _flat_repr)
-
- def test_with_content_type_args(self):
- """
- Test JSON rendering with additional content type arguments supplied.
- """
- obj = {'foo': ['bar', 'baz']}
- renderer = JSONRenderer(None)
- content = renderer.render(obj, 'application/json; indent=2')
- self.assertEquals(strip_trailing_whitespace(content), _indented_repr)
-
- def test_render_and_parse(self):
- """
- Test rendering and then parsing returns the original object.
- IE obj -> render -> parse -> obj.
- """
- obj = {'foo': ['bar', 'baz']}
-
- renderer = JSONRenderer(None)
- parser = JSONParser(None)
-
- content = renderer.render(obj, 'application/json')
- (data, files) = parser.parse(StringIO(content))
- self.assertEquals(obj, data)
-
-
-class JSONPRendererTests(TestCase):
- """
- Tests specific to the JSONP Renderer
- """
-
- urls = 'djangorestframework.tests.renderers'
-
- def test_without_callback_with_json_renderer(self):
- """
- Test JSONP rendering with View JSON Renderer.
- """
- resp = self.client.get('/jsonp/jsonrenderer',
- HTTP_ACCEPT='application/json-p')
- self.assertEquals(resp.status_code, 200)
- self.assertEquals(resp['Content-Type'], 'application/json-p')
- self.assertEquals(resp.content, 'callback(%s);' % _flat_repr)
-
- def test_without_callback_without_json_renderer(self):
- """
- Test JSONP rendering without View JSON Renderer.
- """
- resp = self.client.get('/jsonp/nojsonrenderer',
- HTTP_ACCEPT='application/json-p')
- self.assertEquals(resp.status_code, 200)
- self.assertEquals(resp['Content-Type'], 'application/json-p')
- self.assertEquals(resp.content, 'callback(%s);' % _flat_repr)
-
- def test_with_callback(self):
- """
- Test JSONP rendering with callback function name.
- """
- callback_func = 'myjsonpcallback'
- resp = self.client.get('/jsonp/nojsonrenderer?callback=' + callback_func,
- HTTP_ACCEPT='application/json-p')
- self.assertEquals(resp.status_code, 200)
- self.assertEquals(resp['Content-Type'], 'application/json-p')
- self.assertEquals(resp.content, '%s(%s);' % (callback_func, _flat_repr))
-
-
-if YAMLRenderer:
- _yaml_repr = 'foo: [bar, baz]\n'
-
- class YAMLRendererTests(TestCase):
- """
- Tests specific to the JSON Renderer
- """
-
- def test_render(self):
- """
- Test basic YAML rendering.
- """
- obj = {'foo': ['bar', 'baz']}
- renderer = YAMLRenderer(None)
- content = renderer.render(obj, 'application/yaml')
- self.assertEquals(content, _yaml_repr)
-
- def test_render_and_parse(self):
- """
- Test rendering and then parsing returns the original object.
- IE obj -> render -> parse -> obj.
- """
- obj = {'foo': ['bar', 'baz']}
-
- renderer = YAMLRenderer(None)
- parser = YAMLParser(None)
-
- content = renderer.render(obj, 'application/yaml')
- (data, files) = parser.parse(StringIO(content))
- self.assertEquals(obj, data)
-
-
-
-class XMLRendererTestCase(TestCase):
- """
- Tests specific to the XML Renderer
- """
-
- _complex_data = {
- "creation_date": datetime.datetime(2011, 12, 25, 12, 45, 00),
- "name": "name",
- "sub_data_list": [
- {
- "sub_id": 1,
- "sub_name": "first"
- },
- {
- "sub_id": 2,
- "sub_name": "second"
- }
- ]
- }
-
- def test_render_string(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render({'field': 'astring'}, 'application/xml')
- self.assertXMLContains(content, '<field>astring</field>')
-
- def test_render_integer(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render({'field': 111}, 'application/xml')
- self.assertXMLContains(content, '<field>111</field>')
-
- def test_render_datetime(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render({
- 'field': datetime.datetime(2011, 12, 25, 12, 45, 00)
- }, 'application/xml')
- self.assertXMLContains(content, '<field>2011-12-25 12:45:00</field>')
-
- def test_render_float(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render({'field': 123.4}, 'application/xml')
- self.assertXMLContains(content, '<field>123.4</field>')
-
- def test_render_decimal(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render({'field': Decimal('111.2')}, 'application/xml')
- self.assertXMLContains(content, '<field>111.2</field>')
-
- def test_render_none(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render({'field': None}, 'application/xml')
- self.assertXMLContains(content, '<field></field>')
-
- def test_render_complex_data(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render(self._complex_data, 'application/xml')
- self.assertXMLContains(content, '<sub_name>first</sub_name>')
- self.assertXMLContains(content, '<sub_name>second</sub_name>')
-
- def test_render_and_parse_complex_data(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = StringIO(renderer.render(self._complex_data, 'application/xml'))
-
- parser = XMLParser(None)
- complex_data_out, dummy = parser.parse(content)
- error_msg = "complex data differs!IN:\n %s \n\n OUT:\n %s" % (repr(self._complex_data), repr(complex_data_out))
- self.assertEqual(self._complex_data, complex_data_out, error_msg)
-
- def assertXMLContains(self, xml, string):
- self.assertTrue(xml.startswith('<?xml version="1.0" encoding="utf-8"?>\n<root>'))
- self.assertTrue(xml.endswith('</root>'))
- self.assertTrue(string in xml, '%r not in %r' % (string, xml))
-
-
-class Issue122Tests(TestCase):
- """
- Tests that covers #122.
- """
- urls = 'djangorestframework.tests.renderers'
-
- def test_only_html_renderer(self):
- """
- Test if no infinite recursion occurs.
- """
- resp = self.client.get('/html')
-
- def test_html_renderer_is_first(self):
- """
- Test if no infinite recursion occurs.
- """
- resp = self.client.get('/html1')
diff --git a/djangorestframework/tests/response.py b/djangorestframework/tests/response.py
deleted file mode 100644
index d973deb4..00000000
--- a/djangorestframework/tests/response.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Right now we expect this test to fail - I'm just going to leave it commented out.
-# Looking forward to actually being able to raise ExpectedFailure sometime!
-#
-#from django.test import TestCase
-#from djangorestframework.response import Response
-#
-#
-#class TestResponse(TestCase):
-#
-# # Interface tests
-#
-# # This is mainly to remind myself that the Response interface needs to change slightly
-# def test_response_interface(self):
-# """Ensure the Response interface is as expected."""
-# response = Response()
-# getattr(response, 'status')
-# getattr(response, 'content')
-# getattr(response, 'headers')
-
diff --git a/djangorestframework/tests/reverse.py b/djangorestframework/tests/reverse.py
deleted file mode 100644
index 01ba19b9..00000000
--- a/djangorestframework/tests/reverse.py
+++ /dev/null
@@ -1,52 +0,0 @@
-from django.conf.urls.defaults import patterns, url
-from django.test import TestCase
-from django.utils import simplejson as json
-
-from djangorestframework.renderers import JSONRenderer
-from djangorestframework.reverse import reverse, reverse_lazy
-from djangorestframework.views import View
-
-
-class ReverseView(View):
- """
- Mock resource which simply returns a URL, so that we can ensure
- that reversed URLs are fully qualified.
- """
- renderers = (JSONRenderer, )
-
- def get(self, request):
- return reverse('reverse', request=request)
-
-
-class LazyView(View):
- """
- Mock resource which simply returns a URL, so that we can ensure
- that reversed URLs are fully qualified.
- """
- renderers = (JSONRenderer, )
-
- def get(self, request):
- return reverse_lazy('lazy', request=request)
-
-
-urlpatterns = patterns('',
- url(r'^reverse$', ReverseView.as_view(), name='reverse'),
- url(r'^lazy$', LazyView.as_view(), name='lazy'),
-)
-
-
-class ReverseTests(TestCase):
- """
- Tests for fully qualifed URLs when using `reverse`.
- """
- urls = 'djangorestframework.tests.reverse'
-
- def test_reversed_urls_are_fully_qualified(self):
- response = self.client.get('/reverse')
- self.assertEqual(json.loads(response.content),
- 'http://testserver/reverse')
-
- #def test_reversed_lazy_urls_are_fully_qualified(self):
- # response = self.client.get('/lazy')
- # self.assertEqual(json.loads(response.content),
- # 'http://testserver/lazy')
diff --git a/djangorestframework/tests/serializer.py b/djangorestframework/tests/serializer.py
deleted file mode 100644
index 1a4eaa10..00000000
--- a/djangorestframework/tests/serializer.py
+++ /dev/null
@@ -1,160 +0,0 @@
-"""Tests for the resource module"""
-from django.db import models
-from django.test import TestCase
-from django.utils.translation import ugettext_lazy
-from djangorestframework.serializer import Serializer
-
-import datetime
-import decimal
-
-class TestObjectToData(TestCase):
- """
- Tests for the Serializer class.
- """
-
- def setUp(self):
- self.serializer = Serializer()
- self.serialize = self.serializer.serialize
-
- def test_decimal(self):
- """Decimals need to be converted to a string representation."""
- self.assertEquals(self.serialize(decimal.Decimal('1.5')), decimal.Decimal('1.5'))
-
- def test_function(self):
- """Functions with no arguments should be called."""
- def foo():
- return 1
- self.assertEquals(self.serialize(foo), 1)
-
- def test_method(self):
- """Methods with only a ``self`` argument should be called."""
- class Foo(object):
- def foo(self):
- return 1
- self.assertEquals(self.serialize(Foo().foo), 1)
-
- def test_datetime(self):
- """datetime objects are left as-is."""
- now = datetime.datetime.now()
- self.assertEquals(self.serialize(now), now)
-
- def test_dict_method_name_collision(self):
- """dict with key that collides with dict method name"""
- self.assertEquals(self.serialize({'items': 'foo'}), {'items': u'foo'})
- self.assertEquals(self.serialize({'keys': 'foo'}), {'keys': u'foo'})
- self.assertEquals(self.serialize({'values': 'foo'}), {'values': u'foo'})
-
- def test_ugettext_lazy(self):
- self.assertEquals(self.serialize(ugettext_lazy('foobar')), u'foobar')
-
-
-class TestFieldNesting(TestCase):
- """
- Test nesting the fields in the Serializer class
- """
- def setUp(self):
- self.serializer = Serializer()
- self.serialize = self.serializer.serialize
-
- class M1(models.Model):
- field1 = models.CharField(max_length=256)
- field2 = models.CharField(max_length=256)
-
- class M2(models.Model):
- field = models.OneToOneField(M1)
-
- class M3(models.Model):
- field = models.ForeignKey(M1)
-
- self.m1 = M1(field1='foo', field2='bar')
- self.m2 = M2(field=self.m1)
- self.m3 = M3(field=self.m1)
-
-
- def test_tuple_nesting(self):
- """
- Test tuple nesting on `fields` attr
- """
- class SerializerM2(Serializer):
- fields = (('field', ('field1',)),)
-
- class SerializerM3(Serializer):
- fields = (('field', ('field2',)),)
-
- self.assertEqual(SerializerM2().serialize(self.m2), {'field': {'field1': u'foo'}})
- self.assertEqual(SerializerM3().serialize(self.m3), {'field': {'field2': u'bar'}})
-
-
- def test_serializer_class_nesting(self):
- """
- Test related model serialization
- """
- class NestedM2(Serializer):
- fields = ('field1', )
-
- class NestedM3(Serializer):
- fields = ('field2', )
-
- class SerializerM2(Serializer):
- fields = [('field', NestedM2)]
-
- class SerializerM3(Serializer):
- fields = [('field', NestedM3)]
-
- self.assertEqual(SerializerM2().serialize(self.m2), {'field': {'field1': u'foo'}})
- self.assertEqual(SerializerM3().serialize(self.m3), {'field': {'field2': u'bar'}})
-
- # def test_serializer_no_fields(self):
- # """
- # Test related serializer works when the fields attr isn't present. Fix for
- # #178.
- # """
- # class NestedM2(Serializer):
- # fields = ('field1', )
-
- # class NestedM3(Serializer):
- # fields = ('field2', )
-
- # class SerializerM2(Serializer):
- # include = [('field', NestedM2)]
- # exclude = ('id', )
-
- # class SerializerM3(Serializer):
- # fields = [('field', NestedM3)]
-
- # self.assertEqual(SerializerM2().serialize(self.m2), {'field': {'field1': u'foo'}})
- # self.assertEqual(SerializerM3().serialize(self.m3), {'field': {'field2': u'bar'}})
-
- def test_serializer_classname_nesting(self):
- """
- Test related model serialization
- """
- class SerializerM2(Serializer):
- fields = [('field', 'NestedM2')]
-
- class SerializerM3(Serializer):
- fields = [('field', 'NestedM3')]
-
- class NestedM2(Serializer):
- fields = ('field1', )
-
- class NestedM3(Serializer):
- fields = ('field2', )
-
- self.assertEqual(SerializerM2().serialize(self.m2), {'field': {'field1': u'foo'}})
- self.assertEqual(SerializerM3().serialize(self.m3), {'field': {'field2': u'bar'}})
-
- def test_serializer_overridden_hook_method(self):
- """
- Test serializing a model instance which overrides a class method on the
- serializer. Checks for correct behaviour in odd edge case.
- """
- class SerializerM2(Serializer):
- fields = ('overridden', )
-
- def overridden(self):
- return False
-
- self.m2.overridden = True
- self.assertEqual(SerializerM2().serialize_model(self.m2),
- {'overridden': True})
diff --git a/djangorestframework/tests/status.py b/djangorestframework/tests/status.py
deleted file mode 100644
index 53ecae11..00000000
--- a/djangorestframework/tests/status.py
+++ /dev/null
@@ -1,12 +0,0 @@
-"""Tests for the status module"""
-from django.test import TestCase
-from djangorestframework import status
-
-
-class TestStatus(TestCase):
- """Simple sanity test to check the status module"""
-
- def test_status(self):
- """Ensure the status module is present and correct."""
- self.assertEquals(200, status.HTTP_200_OK)
- self.assertEquals(404, status.HTTP_404_NOT_FOUND)
diff --git a/djangorestframework/tests/testcases.py b/djangorestframework/tests/testcases.py
deleted file mode 100644
index 51b4afbc..00000000
--- a/djangorestframework/tests/testcases.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# http://djangosnippets.org/snippets/1011/
-from django.conf import settings
-from django.core.management import call_command
-from django.db.models import loading
-from django.test import TestCase
-
-NO_SETTING = ('!', None)
-
-class TestSettingsManager(object):
- """
- A class which can modify some Django settings temporarily for a
- test and then revert them to their original values later.
-
- Automatically handles resyncing the DB if INSTALLED_APPS is
- modified.
-
- """
- def __init__(self):
- self._original_settings = {}
-
- def set(self, **kwargs):
- for k,v in kwargs.iteritems():
- self._original_settings.setdefault(k, getattr(settings, k,
- NO_SETTING))
- setattr(settings, k, v)
- if 'INSTALLED_APPS' in kwargs:
- self.syncdb()
-
- def syncdb(self):
- loading.cache.loaded = False
- call_command('syncdb', verbosity=0)
-
- def revert(self):
- for k,v in self._original_settings.iteritems():
- if v == NO_SETTING:
- delattr(settings, k)
- else:
- setattr(settings, k, v)
- if 'INSTALLED_APPS' in self._original_settings:
- self.syncdb()
- self._original_settings = {}
-
-
-class SettingsTestCase(TestCase):
- """
- A subclass of the Django TestCase with a settings_manager
- attribute which is an instance of TestSettingsManager.
-
- Comes with a tearDown() method that calls
- self.settings_manager.revert().
-
- """
- def __init__(self, *args, **kwargs):
- super(SettingsTestCase, self).__init__(*args, **kwargs)
- self.settings_manager = TestSettingsManager()
-
- def tearDown(self):
- self.settings_manager.revert()
-
-class TestModelsTestCase(SettingsTestCase):
- def setUp(self, *args, **kwargs):
- installed_apps = tuple(settings.INSTALLED_APPS) + ('djangorestframework.tests',)
- self.settings_manager.set(INSTALLED_APPS=installed_apps)
diff --git a/djangorestframework/tests/throttling.py b/djangorestframework/tests/throttling.py
deleted file mode 100644
index 7fdc6491..00000000
--- a/djangorestframework/tests/throttling.py
+++ /dev/null
@@ -1,148 +0,0 @@
-"""
-Tests for the throttling implementations in the permissions module.
-"""
-
-from django.test import TestCase
-from django.contrib.auth.models import User
-from django.core.cache import cache
-
-from djangorestframework.compat import RequestFactory
-from djangorestframework.views import View
-from djangorestframework.permissions import PerUserThrottling, PerViewThrottling, PerResourceThrottling
-from djangorestframework.resources import FormResource
-
-class MockView(View):
- permissions = ( PerUserThrottling, )
- throttle = '3/sec'
-
- def get(self, request):
- return 'foo'
-
-class MockView_PerViewThrottling(MockView):
- permissions = ( PerViewThrottling, )
-
-class MockView_PerResourceThrottling(MockView):
- permissions = ( PerResourceThrottling, )
- resource = FormResource
-
-class MockView_MinuteThrottling(MockView):
- throttle = '3/min'
-
-
-
-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='a')
- for dummy in range(3):
- view.as_view()(request)
- request.user = User.objects.create(username='b')
- 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')
- ))
diff --git a/djangorestframework/tests/validators.py b/djangorestframework/tests/validators.py
deleted file mode 100644
index 15d92231..00000000
--- a/djangorestframework/tests/validators.py
+++ /dev/null
@@ -1,325 +0,0 @@
-from django import forms
-from django.db import models
-from django.test import TestCase
-from djangorestframework.resources import FormResource, ModelResource
-from djangorestframework.response import ErrorResponse
-from djangorestframework.views import View
-
-
-class TestDisabledValidations(TestCase):
- """Tests on FormValidator with validation disabled by setting form to None"""
-
- def test_disabled_form_validator_returns_content_unchanged(self):
- """If the view's form attribute is None then FormValidator(view).validate_request(content, None)
- should just return the content unmodified."""
- class DisabledFormResource(FormResource):
- form = None
-
- class MockView(View):
- resource = DisabledFormResource
-
- view = MockView()
- content = {'qwerty': 'uiop'}
- self.assertEqual(FormResource(view).validate_request(content, None), content)
-
- def test_disabled_form_validator_get_bound_form_returns_none(self):
- """If the view's form attribute is None on then
- FormValidator(view).get_bound_form(content) should just return None."""
- class DisabledFormResource(FormResource):
- form = None
-
- class MockView(View):
- resource = DisabledFormResource
-
- view = MockView()
- content = {'qwerty': 'uiop'}
- self.assertEqual(FormResource(view).get_bound_form(content), None)
-
- def test_disabled_model_form_validator_returns_content_unchanged(self):
- """If the view's form is None and does not have a Resource with a model set then
- ModelFormValidator(view).validate_request(content, None) should just return the content unmodified."""
-
- class DisabledModelFormView(View):
- resource = ModelResource
-
- view = DisabledModelFormView()
- content = {'qwerty': 'uiop'}
- self.assertEqual(ModelResource(view).get_bound_form(content), None)
-
- def test_disabled_model_form_validator_get_bound_form_returns_none(self):
- """If the form attribute is None on FormValidatorMixin then get_bound_form(content) should just return None."""
- class DisabledModelFormView(View):
- resource = ModelResource
-
- view = DisabledModelFormView()
- content = {'qwerty': 'uiop'}
- self.assertEqual(ModelResource(view).get_bound_form(content), None)
-
-
-class TestNonFieldErrors(TestCase):
- """Tests against form validation errors caused by non-field errors. (eg as might be caused by some custom form validation)"""
-
- def test_validate_failed_due_to_non_field_error_returns_appropriate_message(self):
- """If validation fails with a non-field error, ensure the response a non-field error"""
- class MockForm(forms.Form):
- field1 = forms.CharField(required=False)
- field2 = forms.CharField(required=False)
- ERROR_TEXT = 'You may not supply both field1 and field2'
-
- def clean(self):
- if 'field1' in self.cleaned_data and 'field2' in self.cleaned_data:
- raise forms.ValidationError(self.ERROR_TEXT)
- return self.cleaned_data
-
- class MockResource(FormResource):
- form = MockForm
-
- class MockView(View):
- pass
-
- view = MockView()
- content = {'field1': 'example1', 'field2': 'example2'}
- try:
- MockResource(view).validate_request(content, None)
- except ErrorResponse, exc:
- self.assertEqual(exc.response.raw_content, {'errors': [MockForm.ERROR_TEXT]})
- else:
- self.fail('ErrorResponse was not raised')
-
-
-class TestFormValidation(TestCase):
- """Tests which check basic form validation.
- Also includes the same set of tests with a ModelFormValidator for which the form has been explicitly set.
- (ModelFormValidator should behave as FormValidator if a form is set rather than relying on the default ModelForm)"""
- def setUp(self):
- class MockForm(forms.Form):
- qwerty = forms.CharField(required=True)
-
- class MockFormResource(FormResource):
- form = MockForm
-
- class MockModelResource(ModelResource):
- form = MockForm
-
- class MockFormView(View):
- resource = MockFormResource
-
- class MockModelFormView(View):
- resource = MockModelResource
-
- self.MockFormResource = MockFormResource
- self.MockModelResource = MockModelResource
- self.MockFormView = MockFormView
- self.MockModelFormView = MockModelFormView
-
- def validation_returns_content_unchanged_if_already_valid_and_clean(self, validator):
- """If the content is already valid and clean then validate(content) should just return the content unmodified."""
- content = {'qwerty': 'uiop'}
- self.assertEqual(validator.validate_request(content, None), content)
-
- def validation_failure_raises_response_exception(self, validator):
- """If form validation fails a ResourceException 400 (Bad Request) should be raised."""
- content = {}
- self.assertRaises(ErrorResponse, validator.validate_request, content, None)
-
- def validation_does_not_allow_extra_fields_by_default(self, validator):
- """If some (otherwise valid) content includes fields that are not in the form then validation should fail.
- It might be okay on normal form submission, but for Web APIs we oughta get strict, as it'll help show up
- broken clients more easily (eg submitting content with a misnamed field)"""
- content = {'qwerty': 'uiop', 'extra': 'extra'}
- self.assertRaises(ErrorResponse, validator.validate_request, content, None)
-
- def validation_allows_extra_fields_if_explicitly_set(self, validator):
- """If we include an allowed_extra_fields paramater on _validate, then allow fields with those names."""
- content = {'qwerty': 'uiop', 'extra': 'extra'}
- validator._validate(content, None, allowed_extra_fields=('extra',))
-
- def validation_allows_unknown_fields_if_explicitly_allowed(self, validator):
- """If we set ``unknown_form_fields`` on the form resource, then don't
- raise errors on unexpected request data"""
- content = {'qwerty': 'uiop', 'extra': 'extra'}
- validator.allow_unknown_form_fields = True
- self.assertEqual({'qwerty': u'uiop'},
- validator.validate_request(content, None),
- "Resource didn't accept unknown fields.")
- validator.allow_unknown_form_fields = False
-
- def validation_does_not_require_extra_fields_if_explicitly_set(self, validator):
- """If we include an allowed_extra_fields paramater on _validate, then do not fail if we do not have fields with those names."""
- content = {'qwerty': 'uiop'}
- self.assertEqual(validator._validate(content, None, allowed_extra_fields=('extra',)), content)
-
- def validation_failed_due_to_no_content_returns_appropriate_message(self, validator):
- """If validation fails due to no content, ensure the response contains a single non-field error"""
- content = {}
- try:
- validator.validate_request(content, None)
- except ErrorResponse, exc:
- self.assertEqual(exc.response.raw_content, {'field_errors': {'qwerty': ['This field is required.']}})
- else:
- self.fail('ResourceException was not raised')
-
- def validation_failed_due_to_field_error_returns_appropriate_message(self, validator):
- """If validation fails due to a field error, ensure the response contains a single field error"""
- content = {'qwerty': ''}
- try:
- validator.validate_request(content, None)
- except ErrorResponse, exc:
- self.assertEqual(exc.response.raw_content, {'field_errors': {'qwerty': ['This field is required.']}})
- else:
- self.fail('ResourceException was not raised')
-
- def validation_failed_due_to_invalid_field_returns_appropriate_message(self, validator):
- """If validation fails due to an invalid field, ensure the response contains a single field error"""
- content = {'qwerty': 'uiop', 'extra': 'extra'}
- try:
- validator.validate_request(content, None)
- except ErrorResponse, exc:
- self.assertEqual(exc.response.raw_content, {'field_errors': {'extra': ['This field does not exist.']}})
- else:
- self.fail('ResourceException was not raised')
-
- def validation_failed_due_to_multiple_errors_returns_appropriate_message(self, validator):
- """If validation for multiple reasons, ensure the response contains each error"""
- content = {'qwerty': '', 'extra': 'extra'}
- try:
- validator.validate_request(content, None)
- except ErrorResponse, exc:
- self.assertEqual(exc.response.raw_content, {'field_errors': {'qwerty': ['This field is required.'],
- 'extra': ['This field does not exist.']}})
- else:
- self.fail('ResourceException was not raised')
-
- # Tests on FormResource
-
- def test_form_validation_returns_content_unchanged_if_already_valid_and_clean(self):
- validator = self.MockFormResource(self.MockFormView())
- self.validation_returns_content_unchanged_if_already_valid_and_clean(validator)
-
- def test_form_validation_failure_raises_response_exception(self):
- validator = self.MockFormResource(self.MockFormView())
- self.validation_failure_raises_response_exception(validator)
-
- def test_validation_does_not_allow_extra_fields_by_default(self):
- validator = self.MockFormResource(self.MockFormView())
- self.validation_does_not_allow_extra_fields_by_default(validator)
-
- def test_validation_allows_extra_fields_if_explicitly_set(self):
- validator = self.MockFormResource(self.MockFormView())
- self.validation_allows_extra_fields_if_explicitly_set(validator)
-
- def test_validation_allows_unknown_fields_if_explicitly_allowed(self):
- validator = self.MockFormResource(self.MockFormView())
- self.validation_allows_unknown_fields_if_explicitly_allowed(validator)
-
- def test_validation_does_not_require_extra_fields_if_explicitly_set(self):
- validator = self.MockFormResource(self.MockFormView())
- self.validation_does_not_require_extra_fields_if_explicitly_set(validator)
-
- def test_validation_failed_due_to_no_content_returns_appropriate_message(self):
- validator = self.MockFormResource(self.MockFormView())
- self.validation_failed_due_to_no_content_returns_appropriate_message(validator)
-
- def test_validation_failed_due_to_field_error_returns_appropriate_message(self):
- validator = self.MockFormResource(self.MockFormView())
- self.validation_failed_due_to_field_error_returns_appropriate_message(validator)
-
- def test_validation_failed_due_to_invalid_field_returns_appropriate_message(self):
- validator = self.MockFormResource(self.MockFormView())
- self.validation_failed_due_to_invalid_field_returns_appropriate_message(validator)
-
- def test_validation_failed_due_to_multiple_errors_returns_appropriate_message(self):
- validator = self.MockFormResource(self.MockFormView())
- self.validation_failed_due_to_multiple_errors_returns_appropriate_message(validator)
-
- # Same tests on ModelResource
-
- def test_modelform_validation_returns_content_unchanged_if_already_valid_and_clean(self):
- validator = self.MockModelResource(self.MockModelFormView())
- self.validation_returns_content_unchanged_if_already_valid_and_clean(validator)
-
- def test_modelform_validation_failure_raises_response_exception(self):
- validator = self.MockModelResource(self.MockModelFormView())
- self.validation_failure_raises_response_exception(validator)
-
- def test_modelform_validation_does_not_allow_extra_fields_by_default(self):
- validator = self.MockModelResource(self.MockModelFormView())
- self.validation_does_not_allow_extra_fields_by_default(validator)
-
- def test_modelform_validation_allows_extra_fields_if_explicitly_set(self):
- validator = self.MockModelResource(self.MockModelFormView())
- self.validation_allows_extra_fields_if_explicitly_set(validator)
-
- def test_modelform_validation_does_not_require_extra_fields_if_explicitly_set(self):
- validator = self.MockModelResource(self.MockModelFormView())
- self.validation_does_not_require_extra_fields_if_explicitly_set(validator)
-
- def test_modelform_validation_failed_due_to_no_content_returns_appropriate_message(self):
- validator = self.MockModelResource(self.MockModelFormView())
- self.validation_failed_due_to_no_content_returns_appropriate_message(validator)
-
- def test_modelform_validation_failed_due_to_field_error_returns_appropriate_message(self):
- validator = self.MockModelResource(self.MockModelFormView())
- self.validation_failed_due_to_field_error_returns_appropriate_message(validator)
-
- def test_modelform_validation_failed_due_to_invalid_field_returns_appropriate_message(self):
- validator = self.MockModelResource(self.MockModelFormView())
- self.validation_failed_due_to_invalid_field_returns_appropriate_message(validator)
-
- def test_modelform_validation_failed_due_to_multiple_errors_returns_appropriate_message(self):
- validator = self.MockModelResource(self.MockModelFormView())
- self.validation_failed_due_to_multiple_errors_returns_appropriate_message(validator)
-
-
-class TestModelFormValidator(TestCase):
- """Tests specific to ModelFormValidatorMixin"""
-
- def setUp(self):
- """Create a validator for a model with two fields and a property."""
- class MockModel(models.Model):
- qwerty = models.CharField(max_length=256)
- uiop = models.CharField(max_length=256, blank=True)
-
- @property
- def readonly(self):
- return 'read only'
-
- class MockResource(ModelResource):
- model = MockModel
-
- class MockView(View):
- resource = MockResource
-
- self.validator = MockResource(MockView)
-
- def test_property_fields_are_allowed_on_model_forms(self):
- """Validation on ModelForms may include property fields that exist on the Model to be included in the input."""
- content = {'qwerty': 'example', 'uiop': 'example', 'readonly': 'read only'}
- self.assertEqual(self.validator.validate_request(content, None), content)
-
- def test_property_fields_are_not_required_on_model_forms(self):
- """Validation on ModelForms does not require property fields that exist on the Model to be included in the input."""
- content = {'qwerty': 'example', 'uiop': 'example'}
- self.assertEqual(self.validator.validate_request(content, None), content)
-
- def test_extra_fields_not_allowed_on_model_forms(self):
- """If some (otherwise valid) content includes fields that are not in the form then validation should fail.
- It might be okay on normal form submission, but for Web APIs we oughta get strict, as it'll help show up
- broken clients more easily (eg submitting content with a misnamed field)"""
- content = {'qwerty': 'example', 'uiop': 'example', 'readonly': 'read only', 'extra': 'extra'}
- self.assertRaises(ErrorResponse, self.validator.validate_request, content, None)
-
- def test_validate_requires_fields_on_model_forms(self):
- """If some (otherwise valid) content includes fields that are not in the form then validation should fail.
- It might be okay on normal form submission, but for Web APIs we oughta get strict, as it'll help show up
- broken clients more easily (eg submitting content with a misnamed field)"""
- content = {'readonly': 'read only'}
- self.assertRaises(ErrorResponse, self.validator.validate_request, content, None)
-
- def test_validate_does_not_require_blankable_fields_on_model_forms(self):
- """Test standard ModelForm validation behaviour - fields with blank=True are not required."""
- content = {'qwerty': 'example', 'readonly': 'read only'}
- self.validator.validate_request(content, None)
-
- def test_model_form_validator_uses_model_forms(self):
- self.assertTrue(isinstance(self.validator.get_bound_form(), forms.ModelForm))
diff --git a/djangorestframework/tests/views.py b/djangorestframework/tests/views.py
deleted file mode 100644
index 418b4b16..00000000
--- a/djangorestframework/tests/views.py
+++ /dev/null
@@ -1,137 +0,0 @@
-from django.core.urlresolvers import reverse
-from django.conf.urls.defaults import patterns, url, include
-from django.http import HttpResponse
-from django.test import TestCase
-from django.test import Client
-from django import forms
-from django.db import models
-
-from djangorestframework.views import View
-from djangorestframework.parsers import JSONParser
-from djangorestframework.resources import ModelResource
-from djangorestframework.views import ListOrCreateModelView, InstanceModelView
-
-from StringIO import StringIO
-
-
-class MockView(View):
- """This is a basic mock view"""
- pass
-
-
-class MockViewFinal(View):
- """View with final() override"""
-
- def final(self, request, response, *args, **kwargs):
- return HttpResponse('{"test": "passed"}', content_type="application/json")
-
-class ResourceMockView(View):
- """This is a resource-based mock view"""
-
- class MockForm(forms.Form):
- foo = forms.BooleanField(required=False)
- bar = forms.IntegerField(help_text='Must be an integer.')
- baz = forms.CharField(max_length=32)
-
- form = MockForm
-
-class MockResource(ModelResource):
- """This is a mock model-based resource"""
-
- class MockResourceModel(models.Model):
- foo = models.BooleanField()
- bar = models.IntegerField(help_text='Must be an integer.')
- baz = models.CharField(max_length=32, help_text='Free text. Max length 32 chars.')
-
- model = MockResourceModel
- fields = ('foo', 'bar', 'baz')
-
-urlpatterns = patterns('',
- url(r'^mock/$', MockView.as_view()),
- url(r'^mock/final/$', MockViewFinal.as_view()),
- url(r'^resourcemock/$', ResourceMockView.as_view()),
- url(r'^model/$', ListOrCreateModelView.as_view(resource=MockResource)),
- url(r'^model/(?P<pk>[^/]+)/$', InstanceModelView.as_view(resource=MockResource)),
- url(r'^restframework/', include('djangorestframework.urls', namespace='djangorestframework')),
-)
-
-class BaseViewTests(TestCase):
- """Test the base view class of djangorestframework"""
- urls = 'djangorestframework.tests.views'
-
- def test_view_call_final(self):
- response = self.client.options('/mock/final/')
- self.assertEqual(response['Content-Type'].split(';')[0], "application/json")
- parser = JSONParser(None)
- (data, files) = parser.parse(StringIO(response.content))
- self.assertEqual(data['test'], 'passed')
-
- def test_options_method_simple_view(self):
- response = self.client.options('/mock/')
- self._verify_options_response(response,
- name='Mock',
- description='This is a basic mock view')
-
- def test_options_method_resource_view(self):
- response = self.client.options('/resourcemock/')
- self._verify_options_response(response,
- name='Resource Mock',
- description='This is a resource-based mock view',
- fields={'foo':'BooleanField',
- 'bar':'IntegerField',
- 'baz':'CharField',
- })
-
- def test_options_method_model_resource_list_view(self):
- response = self.client.options('/model/')
- self._verify_options_response(response,
- name='Mock List',
- description='This is a mock model-based resource',
- fields={'foo':'BooleanField',
- 'bar':'IntegerField',
- 'baz':'CharField',
- })
-
- def test_options_method_model_resource_detail_view(self):
- response = self.client.options('/model/0/')
- self._verify_options_response(response,
- name='Mock Instance',
- description='This is a mock model-based resource',
- fields={'foo':'BooleanField',
- 'bar':'IntegerField',
- 'baz':'CharField',
- })
-
- def _verify_options_response(self, response, name, description, fields=None, status=200,
- mime_type='application/json'):
- self.assertEqual(response.status_code, status)
- self.assertEqual(response['Content-Type'].split(';')[0], mime_type)
- parser = JSONParser(None)
- (data, files) = parser.parse(StringIO(response.content))
- self.assertTrue('application/json' in data['renders'])
- self.assertEqual(name, data['name'])
- self.assertEqual(description, data['description'])
- if fields is None:
- self.assertFalse(hasattr(data, 'fields'))
- else:
- self.assertEqual(data['fields'], fields)
-
-
-class ExtraViewsTests(TestCase):
- """Test the extra views djangorestframework provides"""
- urls = 'djangorestframework.tests.views'
-
- def test_login_view(self):
- """Ensure the login view exists"""
- response = self.client.get(reverse('djangorestframework:login'))
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response['Content-Type'].split(';')[0], 'text/html')
-
- def test_logout_view(self):
- """Ensure the logout view exists"""
- response = self.client.get(reverse('djangorestframework:logout'))
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response['Content-Type'].split(';')[0], 'text/html')
-
- # TODO: Add login/logout behaviour tests
-