summaryrefslogtreecommitdiff
path: root/tests/view_tests
diff options
context:
space:
mode:
authordjango-bot <ops@djangoproject.com>2022-02-03 20:24:19 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-02-07 20:37:05 +0100
commit9c19aff7c7561e3a82978a272ecdaad40dda5c00 (patch)
treef0506b668a013d0063e5fba3dbf4863b466713ba /tests/view_tests
parentf68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff)
downloaddjango-9c19aff7c7561e3a82978a272ecdaad40dda5c00.tar.gz
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'tests/view_tests')
-rw-r--r--tests/view_tests/default_urls.py2
-rw-r--r--tests/view_tests/generic_urls.py36
-rw-r--r--tests/view_tests/models.py8
-rw-r--r--tests/view_tests/regression_21530_urls.py2
-rw-r--r--tests/view_tests/tests/test_csrf.py106
-rw-r--r--tests/view_tests/tests/test_debug.py1122
-rw-r--r--tests/view_tests/tests/test_defaults.py170
-rw-r--r--tests/view_tests/tests/test_i18n.py438
-rw-r--r--tests/view_tests/tests/test_json.py21
-rw-r--r--tests/view_tests/tests/test_specials.py7
-rw-r--r--tests/view_tests/tests/test_static.py145
-rw-r--r--tests/view_tests/urls.py105
-rw-r--r--tests/view_tests/views.py132
13 files changed, 1292 insertions, 1002 deletions
diff --git a/tests/view_tests/default_urls.py b/tests/view_tests/default_urls.py
index beb2bdc1d4..983d0c0db7 100644
--- a/tests/view_tests/default_urls.py
+++ b/tests/view_tests/default_urls.py
@@ -3,5 +3,5 @@ from django.urls import path
urlpatterns = [
# This is the same as in the default project template
- path('admin/', admin.site.urls),
+ path("admin/", admin.site.urls),
]
diff --git a/tests/view_tests/generic_urls.py b/tests/view_tests/generic_urls.py
index 8befa86ff5..247e8ba740 100644
--- a/tests/view_tests/generic_urls.py
+++ b/tests/view_tests/generic_urls.py
@@ -6,39 +6,45 @@ from . import views
from .models import Article, DateArticle
date_based_info_dict = {
- 'queryset': Article.objects.all(),
- 'date_field': 'date_created',
- 'month_format': '%m',
+ "queryset": Article.objects.all(),
+ "date_field": "date_created",
+ "month_format": "%m",
}
object_list_dict = {
- 'queryset': Article.objects.all(),
- 'paginate_by': 2,
+ "queryset": Article.objects.all(),
+ "paginate_by": 2,
}
object_list_no_paginate_by = {
- 'queryset': Article.objects.all(),
+ "queryset": Article.objects.all(),
}
-numeric_days_info_dict = dict(date_based_info_dict, day_format='%d')
+numeric_days_info_dict = dict(date_based_info_dict, day_format="%d")
-date_based_datefield_info_dict = dict(date_based_info_dict, queryset=DateArticle.objects.all())
+date_based_datefield_info_dict = dict(
+ date_based_info_dict, queryset=DateArticle.objects.all()
+)
urlpatterns = [
- path('accounts/login/', auth_views.LoginView.as_view(template_name='login.html')),
- path('accounts/logout/', auth_views.LogoutView.as_view()),
-
+ path("accounts/login/", auth_views.LoginView.as_view(template_name="login.html")),
+ path("accounts/logout/", auth_views.LogoutView.as_view()),
# Special URLs for particular regression cases.
- path('中文/target/', views.index_page),
+ path("中文/target/", views.index_page),
]
# redirects, both temporary and permanent, with non-ASCII targets
urlpatterns += [
- path('nonascii_redirect/', RedirectView.as_view(url='/中文/target/', permanent=False)),
- path('permanent_nonascii_redirect/', RedirectView.as_view(url='/中文/target/', permanent=True)),
+ path(
+ "nonascii_redirect/", RedirectView.as_view(url="/中文/target/", permanent=False)
+ ),
+ path(
+ "permanent_nonascii_redirect/",
+ RedirectView.as_view(url="/中文/target/", permanent=True),
+ ),
]
# json response
urlpatterns += [
- path('json/response/', views.json_response_view),
+ path("json/response/", views.json_response_view),
]
diff --git a/tests/view_tests/models.py b/tests/view_tests/models.py
index a9c0b358b4..17d7dad215 100644
--- a/tests/view_tests/models.py
+++ b/tests/view_tests/models.py
@@ -9,7 +9,7 @@ class Author(models.Model):
name = models.CharField(max_length=100)
def get_absolute_url(self):
- return '/authors/%s/' % self.id
+ return "/authors/%s/" % self.id
class BaseArticle(models.Model):
@@ -17,6 +17,7 @@ class BaseArticle(models.Model):
An abstract article Model so that we can create article models with and
without a get_absolute_url method (for create_update generic views tests).
"""
+
title = models.CharField(max_length=100)
slug = models.SlugField()
author = models.ForeignKey(Author, models.CASCADE)
@@ -33,10 +34,12 @@ class UrlArticle(BaseArticle):
"""
An Article class with a get_absolute_url defined.
"""
+
date_created = models.DateTimeField()
def get_absolute_url(self):
- return '/urlarticles/%s/' % self.slug
+ return "/urlarticles/%s/" % self.slug
+
get_absolute_url.purge = True
@@ -45,4 +48,5 @@ class DateArticle(BaseArticle):
An article Model with a DateField instead of DateTimeField,
for testing #7602
"""
+
date_created = models.DateField()
diff --git a/tests/view_tests/regression_21530_urls.py b/tests/view_tests/regression_21530_urls.py
index c30cd1ed37..7179f2d71f 100644
--- a/tests/view_tests/regression_21530_urls.py
+++ b/tests/view_tests/regression_21530_urls.py
@@ -3,5 +3,5 @@ from django.urls import path
from . import views
urlpatterns = [
- path('index/', views.index_page, name='index'),
+ path("index/", views.index_page, name="index"),
]
diff --git a/tests/view_tests/tests/test_csrf.py b/tests/view_tests/tests/test_csrf.py
index 7afed336ea..c0f812431d 100644
--- a/tests/view_tests/tests/test_csrf.py
+++ b/tests/view_tests/tests/test_csrf.py
@@ -1,14 +1,11 @@
from django.template import TemplateDoesNotExist
-from django.test import (
- Client, RequestFactory, SimpleTestCase, override_settings,
-)
+from django.test import Client, RequestFactory, SimpleTestCase, override_settings
from django.utils.translation import override
from django.views.csrf import CSRF_FAILURE_TEMPLATE_NAME, csrf_failure
-@override_settings(ROOT_URLCONF='view_tests.urls')
+@override_settings(ROOT_URLCONF="view_tests.urls")
class CsrfViewTests(SimpleTestCase):
-
def setUp(self):
super().setUp()
self.client = Client(enforce_csrf_checks=True)
@@ -16,50 +13,54 @@ class CsrfViewTests(SimpleTestCase):
@override_settings(
USE_I18N=True,
MIDDLEWARE=[
- 'django.middleware.locale.LocaleMiddleware',
- 'django.middleware.common.CommonMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
+ "django.middleware.locale.LocaleMiddleware",
+ "django.middleware.common.CommonMiddleware",
+ "django.middleware.csrf.CsrfViewMiddleware",
],
)
def test_translation(self):
"""An invalid request is rejected with a localized error message."""
- response = self.client.post('/')
- self.assertContains(response, 'Forbidden', status_code=403)
- self.assertContains(response, 'CSRF verification failed. Request aborted.', status_code=403)
+ response = self.client.post("/")
+ self.assertContains(response, "Forbidden", status_code=403)
+ self.assertContains(
+ response, "CSRF verification failed. Request aborted.", status_code=403
+ )
- with self.settings(LANGUAGE_CODE='nl'), override('en-us'):
- response = self.client.post('/')
- self.assertContains(response, 'Verboden', status_code=403)
- self.assertContains(response, 'CSRF-verificatie mislukt. Verzoek afgebroken.', status_code=403)
+ with self.settings(LANGUAGE_CODE="nl"), override("en-us"):
+ response = self.client.post("/")
+ self.assertContains(response, "Verboden", status_code=403)
+ self.assertContains(
+ response,
+ "CSRF-verificatie mislukt. Verzoek afgebroken.",
+ status_code=403,
+ )
- @override_settings(
- SECURE_PROXY_SSL_HEADER=('HTTP_X_FORWARDED_PROTO', 'https')
- )
+ @override_settings(SECURE_PROXY_SSL_HEADER=("HTTP_X_FORWARDED_PROTO", "https"))
def test_no_referer(self):
"""
Referer header is strictly checked for POST over HTTPS. Trigger the
exception by sending an incorrect referer.
"""
- response = self.client.post('/', HTTP_X_FORWARDED_PROTO='https')
+ response = self.client.post("/", HTTP_X_FORWARDED_PROTO="https")
self.assertContains(
response,
- 'You are seeing this message because this HTTPS site requires a '
- '“Referer header” to be sent by your web browser, but '
- 'none was sent.',
+ "You are seeing this message because this HTTPS site requires a "
+ "“Referer header” to be sent by your web browser, but "
+ "none was sent.",
status_code=403,
)
self.assertContains(
response,
- 'If you have configured your browser to disable “Referer” '
- 'headers, please re-enable them, at least for this site, or for '
- 'HTTPS connections, or for “same-origin” requests.',
+ "If you have configured your browser to disable “Referer” "
+ "headers, please re-enable them, at least for this site, or for "
+ "HTTPS connections, or for “same-origin” requests.",
status_code=403,
)
self.assertContains(
response,
- 'If you are using the &lt;meta name=&quot;referrer&quot; '
- 'content=&quot;no-referrer&quot;&gt; tag or including the '
- '“Referrer-Policy: no-referrer” header, please remove them.',
+ "If you are using the &lt;meta name=&quot;referrer&quot; "
+ "content=&quot;no-referrer&quot;&gt; tag or including the "
+ "“Referrer-Policy: no-referrer” header, please remove them.",
status_code=403,
)
@@ -68,13 +69,13 @@ class CsrfViewTests(SimpleTestCase):
The CSRF cookie is checked for POST. Failure to send this cookie should
provide a nice error message.
"""
- response = self.client.post('/')
+ response = self.client.post("/")
self.assertContains(
response,
- 'You are seeing this message because this site requires a CSRF '
- 'cookie when submitting forms. This cookie is required for '
- 'security reasons, to ensure that your browser is not being '
- 'hijacked by third parties.',
+ "You are seeing this message because this site requires a CSRF "
+ "cookie when submitting forms. This cookie is required for "
+ "security reasons, to ensure that your browser is not being "
+ "hijacked by third parties.",
status_code=403,
)
@@ -83,27 +84,34 @@ class CsrfViewTests(SimpleTestCase):
"""
The CSRF view doesn't depend on the TEMPLATES configuration (#24388).
"""
- response = self.client.post('/')
- self.assertContains(response, 'Forbidden', status_code=403)
+ response = self.client.post("/")
+ self.assertContains(response, "Forbidden", status_code=403)
- @override_settings(TEMPLATES=[{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'OPTIONS': {
- 'loaders': [
- ('django.template.loaders.locmem.Loader', {
- CSRF_FAILURE_TEMPLATE_NAME: 'Test template for CSRF failure'
- }),
- ],
- },
- }])
+ @override_settings(
+ TEMPLATES=[
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "OPTIONS": {
+ "loaders": [
+ (
+ "django.template.loaders.locmem.Loader",
+ {
+ CSRF_FAILURE_TEMPLATE_NAME: "Test template for CSRF failure"
+ },
+ ),
+ ],
+ },
+ }
+ ]
+ )
def test_custom_template(self):
"""A custom CSRF_FAILURE_TEMPLATE_NAME is used."""
- response = self.client.post('/')
- self.assertContains(response, 'Test template for CSRF failure', status_code=403)
+ response = self.client.post("/")
+ self.assertContains(response, "Test template for CSRF failure", status_code=403)
def test_custom_template_does_not_exist(self):
"""An exception is raised if a nonexistent template is supplied."""
factory = RequestFactory()
- request = factory.post('/')
+ request = factory.post("/")
with self.assertRaises(TemplateDoesNotExist):
- csrf_failure(request, template_name='nonexistent.html')
+ csrf_failure(request, template_name="nonexistent.html")
diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py
index 1484c071c5..1bf395ce37 100644
--- a/tests/view_tests/tests/test_debug.py
+++ b/tests/view_tests/tests/test_debug.py
@@ -23,35 +23,45 @@ from django.utils.functional import SimpleLazyObject
from django.utils.regex_helper import _lazy_re_compile
from django.utils.safestring import mark_safe
from django.views.debug import (
- CallableSettingWrapper, ExceptionCycleWarning, ExceptionReporter,
- Path as DebugPath, SafeExceptionReporterFilter, default_urlconf,
- get_default_exception_reporter_filter, technical_404_response,
- technical_500_response,
+ CallableSettingWrapper,
+ ExceptionCycleWarning,
+ ExceptionReporter,
)
-from django.views.decorators.debug import (
- sensitive_post_parameters, sensitive_variables,
+from django.views.debug import Path as DebugPath
+from django.views.debug import (
+ SafeExceptionReporterFilter,
+ default_urlconf,
+ get_default_exception_reporter_filter,
+ technical_404_response,
+ technical_500_response,
)
+from django.views.decorators.debug import sensitive_post_parameters, sensitive_variables
from ..views import (
- custom_exception_reporter_filter_view, index_page,
- multivalue_dict_key_error, non_sensitive_view, paranoid_view,
- sensitive_args_function_caller, sensitive_kwargs_function_caller,
- sensitive_method_view, sensitive_view,
+ custom_exception_reporter_filter_view,
+ index_page,
+ multivalue_dict_key_error,
+ non_sensitive_view,
+ paranoid_view,
+ sensitive_args_function_caller,
+ sensitive_kwargs_function_caller,
+ sensitive_method_view,
+ sensitive_view,
)
class User:
def __str__(self):
- return 'jacob'
+ return "jacob"
class WithoutEmptyPathUrls:
- urlpatterns = [path('url/', index_page, name='url')]
+ urlpatterns = [path("url/", index_page, name="url")]
class CallableSettingWrapperTests(SimpleTestCase):
- """ Unittests for CallableSettingWrapper
- """
+ """Unittests for CallableSettingWrapper"""
+
def test_repr(self):
class WrappedCallable:
def __repr__(self):
@@ -64,64 +74,74 @@ class CallableSettingWrapperTests(SimpleTestCase):
self.assertEqual(actual, "repr from the wrapped callable")
-@override_settings(DEBUG=True, ROOT_URLCONF='view_tests.urls')
+@override_settings(DEBUG=True, ROOT_URLCONF="view_tests.urls")
class DebugViewTests(SimpleTestCase):
-
def test_files(self):
- with self.assertLogs('django.request', 'ERROR'):
- response = self.client.get('/raises/')
+ with self.assertLogs("django.request", "ERROR"):
+ response = self.client.get("/raises/")
self.assertEqual(response.status_code, 500)
data = {
- 'file_data.txt': SimpleUploadedFile('file_data.txt', b'haha'),
+ "file_data.txt": SimpleUploadedFile("file_data.txt", b"haha"),
}
- with self.assertLogs('django.request', 'ERROR'):
- response = self.client.post('/raises/', data)
- self.assertContains(response, 'file_data.txt', status_code=500)
- self.assertNotContains(response, 'haha', status_code=500)
+ with self.assertLogs("django.request", "ERROR"):
+ response = self.client.post("/raises/", data)
+ self.assertContains(response, "file_data.txt", status_code=500)
+ self.assertNotContains(response, "haha", status_code=500)
def test_400(self):
# When DEBUG=True, technical_500_template() is called.
- with self.assertLogs('django.security', 'WARNING'):
- response = self.client.get('/raises400/')
+ with self.assertLogs("django.security", "WARNING"):
+ response = self.client.get("/raises400/")
self.assertContains(response, '<div class="context" id="', status_code=400)
def test_400_bad_request(self):
# When DEBUG=True, technical_500_template() is called.
- with self.assertLogs('django.request', 'WARNING') as cm:
- response = self.client.get('/raises400_bad_request/')
+ with self.assertLogs("django.request", "WARNING") as cm:
+ response = self.client.get("/raises400_bad_request/")
self.assertContains(response, '<div class="context" id="', status_code=400)
self.assertEqual(
cm.records[0].getMessage(),
- 'Malformed request syntax: /raises400_bad_request/',
+ "Malformed request syntax: /raises400_bad_request/",
)
# Ensure no 403.html template exists to test the default case.
- @override_settings(TEMPLATES=[{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- }])
+ @override_settings(
+ TEMPLATES=[
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ }
+ ]
+ )
def test_403(self):
- response = self.client.get('/raises403/')
- self.assertContains(response, '<h1>403 Forbidden</h1>', status_code=403)
+ response = self.client.get("/raises403/")
+ self.assertContains(response, "<h1>403 Forbidden</h1>", status_code=403)
# Set up a test 403.html template.
- @override_settings(TEMPLATES=[{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'OPTIONS': {
- 'loaders': [
- ('django.template.loaders.locmem.Loader', {
- '403.html': 'This is a test template for a 403 error ({{ exception }}).',
- }),
- ],
- },
- }])
+ @override_settings(
+ TEMPLATES=[
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "OPTIONS": {
+ "loaders": [
+ (
+ "django.template.loaders.locmem.Loader",
+ {
+ "403.html": "This is a test template for a 403 error ({{ exception }}).",
+ },
+ ),
+ ],
+ },
+ }
+ ]
+ )
def test_403_template(self):
- response = self.client.get('/raises403/')
- self.assertContains(response, 'test template', status_code=403)
- self.assertContains(response, '(Insufficient Permissions).', status_code=403)
+ response = self.client.get("/raises403/")
+ self.assertContains(response, "test template", status_code=403)
+ self.assertContains(response, "(Insufficient Permissions).", status_code=403)
def test_404(self):
- response = self.client.get('/raises404/')
+ response = self.client.get("/raises404/")
self.assertNotContains(
response,
'<pre class="exception_value">',
@@ -129,30 +149,34 @@ class DebugViewTests(SimpleTestCase):
)
self.assertContains(
response,
- '<p>The current path, <code>not-in-urls</code>, didn’t match any '
- 'of these.</p>',
+ "<p>The current path, <code>not-in-urls</code>, didn’t match any "
+ "of these.</p>",
status_code=404,
html=True,
)
def test_404_not_in_urls(self):
- response = self.client.get('/not-in-urls')
+ response = self.client.get("/not-in-urls")
self.assertNotContains(response, "Raised by:", status_code=404)
self.assertNotContains(
response,
'<pre class="exception_value">',
status_code=404,
)
- self.assertContains(response, "Django tried these URL patterns", status_code=404)
+ self.assertContains(
+ response, "Django tried these URL patterns", status_code=404
+ )
self.assertContains(
response,
- '<p>The current path, <code>not-in-urls</code>, didn’t match any '
- 'of these.</p>',
+ "<p>The current path, <code>not-in-urls</code>, didn’t match any "
+ "of these.</p>",
status_code=404,
html=True,
)
# Pattern and view name of a RegexURLPattern appear.
- self.assertContains(response, r"^regex-post/(?P&lt;pk&gt;[0-9]+)/$", status_code=404)
+ self.assertContains(
+ response, r"^regex-post/(?P&lt;pk&gt;[0-9]+)/$", status_code=404
+ )
self.assertContains(response, "[name='regex-post']", status_code=404)
# Pattern and view name of a RoutePattern appear.
self.assertContains(response, r"path-post/&lt;int:pk&gt;/", status_code=404)
@@ -160,16 +184,16 @@ class DebugViewTests(SimpleTestCase):
@override_settings(ROOT_URLCONF=WithoutEmptyPathUrls)
def test_404_empty_path_not_in_urls(self):
- response = self.client.get('/')
+ response = self.client.get("/")
self.assertContains(
response,
- '<p>The empty path didn’t match any of these.</p>',
+ "<p>The empty path didn’t match any of these.</p>",
status_code=404,
html=True,
)
def test_technical_404(self):
- response = self.client.get('/technical404/')
+ response = self.client.get("/technical404/")
self.assertContains(
response,
'<pre class="exception_value">Testing technical 404.</pre>',
@@ -179,57 +203,57 @@ class DebugViewTests(SimpleTestCase):
self.assertContains(response, "Raised by:", status_code=404)
self.assertContains(
response,
- '<td>view_tests.views.technical404</td>',
+ "<td>view_tests.views.technical404</td>",
status_code=404,
)
self.assertContains(
response,
- '<p>The current path, <code>technical404/</code>, matched the '
- 'last one.</p>',
+ "<p>The current path, <code>technical404/</code>, matched the "
+ "last one.</p>",
status_code=404,
html=True,
)
def test_classbased_technical_404(self):
- response = self.client.get('/classbased404/')
+ response = self.client.get("/classbased404/")
self.assertContains(
response,
- '<th>Raised by:</th><td>view_tests.views.Http404View</td>',
+ "<th>Raised by:</th><td>view_tests.views.Http404View</td>",
status_code=404,
html=True,
)
def test_technical_500(self):
- with self.assertLogs('django.request', 'ERROR'):
- response = self.client.get('/raises500/')
+ with self.assertLogs("django.request", "ERROR"):
+ response = self.client.get("/raises500/")
self.assertContains(
response,
- '<th>Raised during:</th><td>view_tests.views.raises500</td>',
+ "<th>Raised during:</th><td>view_tests.views.raises500</td>",
status_code=500,
html=True,
)
- with self.assertLogs('django.request', 'ERROR'):
- response = self.client.get('/raises500/', HTTP_ACCEPT='text/plain')
+ with self.assertLogs("django.request", "ERROR"):
+ response = self.client.get("/raises500/", HTTP_ACCEPT="text/plain")
self.assertContains(
response,
- 'Raised during: view_tests.views.raises500',
+ "Raised during: view_tests.views.raises500",
status_code=500,
)
def test_classbased_technical_500(self):
- with self.assertLogs('django.request', 'ERROR'):
- response = self.client.get('/classbased500/')
+ with self.assertLogs("django.request", "ERROR"):
+ response = self.client.get("/classbased500/")
self.assertContains(
response,
- '<th>Raised during:</th><td>view_tests.views.Raises500View</td>',
+ "<th>Raised during:</th><td>view_tests.views.Raises500View</td>",
status_code=500,
html=True,
)
- with self.assertLogs('django.request', 'ERROR'):
- response = self.client.get('/classbased500/', HTTP_ACCEPT='text/plain')
+ with self.assertLogs("django.request", "ERROR"):
+ response = self.client.get("/classbased500/", HTTP_ACCEPT="text/plain")
self.assertContains(
response,
- 'Raised during: view_tests.views.Raises500View',
+ "Raised during: view_tests.views.Raises500View",
status_code=500,
)
@@ -238,48 +262,51 @@ class DebugViewTests(SimpleTestCase):
Numeric IDs and fancy traceback context blocks line numbers shouldn't be localized.
"""
with self.settings(DEBUG=True):
- with self.assertLogs('django.request', 'ERROR'):
- response = self.client.get('/raises500/')
+ with self.assertLogs("django.request", "ERROR"):
+ response = self.client.get("/raises500/")
# We look for a HTML fragment of the form
# '<div class="context" id="c38123208">', not '<div class="context" id="c38,123,208"'
self.assertContains(response, '<div class="context" id="', status_code=500)
- match = re.search(b'<div class="context" id="(?P<id>[^"]+)">', response.content)
+ match = re.search(
+ b'<div class="context" id="(?P<id>[^"]+)">', response.content
+ )
self.assertIsNotNone(match)
- id_repr = match['id']
+ id_repr = match["id"]
self.assertFalse(
- re.search(b'[^c0-9]', id_repr),
- "Numeric IDs in debug response HTML page shouldn't be localized (value: %s)." % id_repr.decode()
+ re.search(b"[^c0-9]", id_repr),
+ "Numeric IDs in debug response HTML page shouldn't be localized (value: %s)."
+ % id_repr.decode(),
)
def test_template_exceptions(self):
- with self.assertLogs('django.request', 'ERROR'):
+ with self.assertLogs("django.request", "ERROR"):
try:
- self.client.get(reverse('template_exception'))
+ self.client.get(reverse("template_exception"))
except Exception:
raising_loc = inspect.trace()[-1][-2][0].strip()
self.assertNotEqual(
raising_loc.find('raise Exception("boom")'),
-1,
"Failed to find 'raise Exception' in last frame of "
- "traceback, instead found: %s" % raising_loc
+ "traceback, instead found: %s" % raising_loc,
)
@skipIf(
- sys.platform == 'win32',
- 'Raises OSError instead of TemplateDoesNotExist on Windows.',
+ sys.platform == "win32",
+ "Raises OSError instead of TemplateDoesNotExist on Windows.",
)
def test_safestring_in_exception(self):
- with self.assertLogs('django.request', 'ERROR'):
- response = self.client.get('/safestring_exception/')
+ with self.assertLogs("django.request", "ERROR"):
+ response = self.client.get("/safestring_exception/")
self.assertNotContains(
response,
- '<script>alert(1);</script>',
+ "<script>alert(1);</script>",
status_code=500,
html=True,
)
self.assertContains(
response,
- '&lt;script&gt;alert(1);&lt;/script&gt;',
+ "&lt;script&gt;alert(1);&lt;/script&gt;",
count=3,
status_code=500,
html=True,
@@ -291,17 +318,31 @@ class DebugViewTests(SimpleTestCase):
with tempfile.NamedTemporaryFile(prefix=template_name) as tmpfile:
tempdir = os.path.dirname(tmpfile.name)
template_path = os.path.join(tempdir, template_name)
- with override_settings(TEMPLATES=[{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [tempdir],
- }]), self.assertLogs('django.request', 'ERROR'):
- response = self.client.get(reverse('raises_template_does_not_exist', kwargs={"path": template_name}))
- self.assertContains(response, "%s (Source does not exist)" % template_path, status_code=500, count=2)
+ with override_settings(
+ TEMPLATES=[
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "DIRS": [tempdir],
+ }
+ ]
+ ), self.assertLogs("django.request", "ERROR"):
+ response = self.client.get(
+ reverse(
+ "raises_template_does_not_exist", kwargs={"path": template_name}
+ )
+ )
+ self.assertContains(
+ response,
+ "%s (Source does not exist)" % template_path,
+ status_code=500,
+ count=2,
+ )
# Assert as HTML.
self.assertContains(
response,
- '<li><code>django.template.loaders.filesystem.Loader</code>: '
- '%s (Source does not exist)</li>' % os.path.join(tempdir, 'notfound.html'),
+ "<li><code>django.template.loaders.filesystem.Loader</code>: "
+ "%s (Source does not exist)</li>"
+ % os.path.join(tempdir, "notfound.html"),
status_code=500,
html=True,
)
@@ -310,23 +351,22 @@ class DebugViewTests(SimpleTestCase):
"""
Make sure if you don't specify a template, the debug view doesn't blow up.
"""
- with self.assertLogs('django.request', 'ERROR'):
+ with self.assertLogs("django.request", "ERROR"):
with self.assertRaises(TemplateDoesNotExist):
- self.client.get('/render_no_template/')
+ self.client.get("/render_no_template/")
- @override_settings(ROOT_URLCONF='view_tests.default_urls')
+ @override_settings(ROOT_URLCONF="view_tests.default_urls")
def test_default_urlconf_template(self):
"""
Make sure that the default URLconf template is shown instead of the
technical 404 page, if the user has not altered their URLconf yet.
"""
- response = self.client.get('/')
+ response = self.client.get("/")
self.assertContains(
- response,
- "<h1>The install worked successfully! Congratulations!</h1>"
+ response, "<h1>The install worked successfully! Congratulations!</h1>"
)
- @override_settings(ROOT_URLCONF='view_tests.regression_21530_urls')
+ @override_settings(ROOT_URLCONF="view_tests.regression_21530_urls")
def test_regression_21530(self):
"""
Regression test for bug #21530.
@@ -336,11 +376,9 @@ class DebugViewTests(SimpleTestCase):
The bug here was that an AttributeError caused a 500 response.
"""
- response = self.client.get('/')
+ response = self.client.get("/")
self.assertContains(
- response,
- "Page not found <span>(404)</span>",
- status_code=404
+ response, "Page not found <span>(404)</span>", status_code=404
)
def test_template_encoding(self):
@@ -349,48 +387,52 @@ class DebugViewTests(SimpleTestCase):
should be opened as utf-8 charset as is the default specified on
template engines.
"""
- with mock.patch.object(DebugPath, 'open') as m:
+ with mock.patch.object(DebugPath, "open") as m:
default_urlconf(None)
- m.assert_called_once_with(encoding='utf-8')
+ m.assert_called_once_with(encoding="utf-8")
m.reset_mock()
technical_404_response(mock.MagicMock(), mock.Mock())
- m.assert_called_once_with(encoding='utf-8')
+ m.assert_called_once_with(encoding="utf-8")
def test_technical_404_converter_raise_404(self):
- with mock.patch.object(IntConverter, 'to_python', side_effect=Http404):
- response = self.client.get('/path-post/1/')
- self.assertContains(response, 'Page not found', status_code=404)
+ with mock.patch.object(IntConverter, "to_python", side_effect=Http404):
+ response = self.client.get("/path-post/1/")
+ self.assertContains(response, "Page not found", status_code=404)
def test_exception_reporter_from_request(self):
- with self.assertLogs('django.request', 'ERROR'):
- response = self.client.get('/custom_reporter_class_view/')
- self.assertContains(response, 'custom traceback text', status_code=500)
+ with self.assertLogs("django.request", "ERROR"):
+ response = self.client.get("/custom_reporter_class_view/")
+ self.assertContains(response, "custom traceback text", status_code=500)
- @override_settings(DEFAULT_EXCEPTION_REPORTER='view_tests.views.CustomExceptionReporter')
+ @override_settings(
+ DEFAULT_EXCEPTION_REPORTER="view_tests.views.CustomExceptionReporter"
+ )
def test_exception_reporter_from_settings(self):
- with self.assertLogs('django.request', 'ERROR'):
- response = self.client.get('/raises500/')
- self.assertContains(response, 'custom traceback text', status_code=500)
+ with self.assertLogs("django.request", "ERROR"):
+ response = self.client.get("/raises500/")
+ self.assertContains(response, "custom traceback text", status_code=500)
- @override_settings(DEFAULT_EXCEPTION_REPORTER='view_tests.views.TemplateOverrideExceptionReporter')
+ @override_settings(
+ DEFAULT_EXCEPTION_REPORTER="view_tests.views.TemplateOverrideExceptionReporter"
+ )
def test_template_override_exception_reporter(self):
- with self.assertLogs('django.request', 'ERROR'):
- response = self.client.get('/raises500/')
+ with self.assertLogs("django.request", "ERROR"):
+ response = self.client.get("/raises500/")
self.assertContains(
response,
- '<h1>Oh no, an error occurred!</h1>',
+ "<h1>Oh no, an error occurred!</h1>",
status_code=500,
html=True,
)
- with self.assertLogs('django.request', 'ERROR'):
- response = self.client.get('/raises500/', HTTP_ACCEPT='text/plain')
- self.assertContains(response, 'Oh dear, an error occurred!', status_code=500)
+ with self.assertLogs("django.request", "ERROR"):
+ response = self.client.get("/raises500/", HTTP_ACCEPT="text/plain")
+ self.assertContains(response, "Oh dear, an error occurred!", status_code=500)
class DebugViewQueriesAllowedTests(SimpleTestCase):
# May need a query to initialize MySQL connection
- databases = {'default'}
+ databases = {"default"}
def test_handle_db_exception(self):
"""
@@ -399,53 +441,56 @@ class DebugViewQueriesAllowedTests(SimpleTestCase):
"""
with connection.cursor() as cursor:
try:
- cursor.execute('INVALID SQL')
+ cursor.execute("INVALID SQL")
except DatabaseError:
exc_info = sys.exc_info()
rf = RequestFactory()
- response = technical_500_response(rf.get('/'), *exc_info)
- self.assertContains(response, 'OperationalError at /', status_code=500)
+ response = technical_500_response(rf.get("/"), *exc_info)
+ self.assertContains(response, "OperationalError at /", status_code=500)
@override_settings(
DEBUG=True,
- ROOT_URLCONF='view_tests.urls',
+ ROOT_URLCONF="view_tests.urls",
# No template directories are configured, so no templates will be found.
- TEMPLATES=[{
- 'BACKEND': 'django.template.backends.dummy.TemplateStrings',
- }],
+ TEMPLATES=[
+ {
+ "BACKEND": "django.template.backends.dummy.TemplateStrings",
+ }
+ ],
)
class NonDjangoTemplatesDebugViewTests(SimpleTestCase):
-
def test_400(self):
# When DEBUG=True, technical_500_template() is called.
- with self.assertLogs('django.security', 'WARNING'):
- response = self.client.get('/raises400/')
+ with self.assertLogs("django.security", "WARNING"):
+ response = self.client.get("/raises400/")
self.assertContains(response, '<div class="context" id="', status_code=400)
def test_400_bad_request(self):
# When DEBUG=True, technical_500_template() is called.
- with self.assertLogs('django.request', 'WARNING') as cm:
- response = self.client.get('/raises400_bad_request/')
+ with self.assertLogs("django.request", "WARNING") as cm:
+ response = self.client.get("/raises400_bad_request/")
self.assertContains(response, '<div class="context" id="', status_code=400)
self.assertEqual(
cm.records[0].getMessage(),
- 'Malformed request syntax: /raises400_bad_request/',
+ "Malformed request syntax: /raises400_bad_request/",
)
def test_403(self):
- response = self.client.get('/raises403/')
- self.assertContains(response, '<h1>403 Forbidden</h1>', status_code=403)
+ response = self.client.get("/raises403/")
+ self.assertContains(response, "<h1>403 Forbidden</h1>", status_code=403)
def test_404(self):
- response = self.client.get('/raises404/')
+ response = self.client.get("/raises404/")
self.assertEqual(response.status_code, 404)
def test_template_not_found_error(self):
# Raises a TemplateDoesNotExist exception and shows the debug view.
- url = reverse('raises_template_does_not_exist', kwargs={"path": "notfound.html"})
- with self.assertLogs('django.request', 'ERROR'):
+ url = reverse(
+ "raises_template_does_not_exist", kwargs={"path": "notfound.html"}
+ )
+ with self.assertLogs("django.request", "ERROR"):
response = self.client.get(url)
self.assertContains(response, '<div class="context" id="', status_code=500)
@@ -456,25 +501,27 @@ class ExceptionReporterTests(SimpleTestCase):
def test_request_and_exception(self):
"A simple exception report can be generated"
try:
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
request.user = User()
raise ValueError("Can't find my keys")
except ValueError:
exc_type, exc_value, tb = sys.exc_info()
reporter = ExceptionReporter(request, exc_type, exc_value, tb)
html = reporter.get_traceback_html()
- self.assertInHTML('<h1>ValueError at /test_view/</h1>', html)
- self.assertIn('<pre class="exception_value">Can&#x27;t find my keys</pre>', html)
- self.assertIn('<th>Request Method:</th>', html)
- self.assertIn('<th>Request URL:</th>', html)
+ self.assertInHTML("<h1>ValueError at /test_view/</h1>", html)
+ self.assertIn(
+ '<pre class="exception_value">Can&#x27;t find my keys</pre>', html
+ )
+ self.assertIn("<th>Request Method:</th>", html)
+ self.assertIn("<th>Request URL:</th>", html)
self.assertIn('<h3 id="user-info">USER</h3>', html)
- self.assertIn('<p>jacob</p>', html)
- self.assertIn('<th>Exception Type:</th>', html)
- self.assertIn('<th>Exception Value:</th>', html)
- self.assertIn('<h2>Traceback ', html)
- self.assertIn('<h2>Request information</h2>', html)
- self.assertNotIn('<p>Request data not supplied</p>', html)
- self.assertIn('<p>No POST data</p>', html)
+ self.assertIn("<p>jacob</p>", html)
+ self.assertIn("<th>Exception Type:</th>", html)
+ self.assertIn("<th>Exception Value:</th>", html)
+ self.assertIn("<h2>Traceback ", html)
+ self.assertIn("<h2>Request information</h2>", html)
+ self.assertNotIn("<p>Request data not supplied</p>", html)
+ self.assertIn("<p>No POST data</p>", html)
def test_no_request(self):
"An exception report can be generated without request"
@@ -484,20 +531,22 @@ class ExceptionReporterTests(SimpleTestCase):
exc_type, exc_value, tb = sys.exc_info()
reporter = ExceptionReporter(None, exc_type, exc_value, tb)
html = reporter.get_traceback_html()
- self.assertInHTML('<h1>ValueError</h1>', html)
- self.assertIn('<pre class="exception_value">Can&#x27;t find my keys</pre>', html)
- self.assertNotIn('<th>Request Method:</th>', html)
- self.assertNotIn('<th>Request URL:</th>', html)
+ self.assertInHTML("<h1>ValueError</h1>", html)
+ self.assertIn(
+ '<pre class="exception_value">Can&#x27;t find my keys</pre>', html
+ )
+ self.assertNotIn("<th>Request Method:</th>", html)
+ self.assertNotIn("<th>Request URL:</th>", html)
self.assertNotIn('<h3 id="user-info">USER</h3>', html)
- self.assertIn('<th>Exception Type:</th>', html)
- self.assertIn('<th>Exception Value:</th>', html)
- self.assertIn('<h2>Traceback ', html)
- self.assertIn('<h2>Request information</h2>', html)
- self.assertIn('<p>Request data not supplied</p>', html)
+ self.assertIn("<th>Exception Type:</th>", html)
+ self.assertIn("<th>Exception Value:</th>", html)
+ self.assertIn("<h2>Traceback ", html)
+ self.assertIn("<h2>Request information</h2>", html)
+ self.assertIn("<p>Request data not supplied</p>", html)
def test_sharing_traceback(self):
try:
- raise ValueError('Oops')
+ raise ValueError("Oops")
except ValueError:
exc_type, exc_value, tb = sys.exc_info()
reporter = ExceptionReporter(None, exc_type, exc_value, tb)
@@ -510,10 +559,10 @@ class ExceptionReporterTests(SimpleTestCase):
def test_eol_support(self):
"""The ExceptionReporter supports Unix, Windows and Macintosh EOL markers"""
- LINES = ['print %d' % i for i in range(1, 6)]
+ LINES = ["print %d" % i for i in range(1, 6)]
reporter = ExceptionReporter(None, None, None, None)
- for newline in ['\n', '\r\n', '\r']:
+ for newline in ["\n", "\r\n", "\r"]:
fd, filename = tempfile.mkstemp(text=False)
os.write(fd, (newline.join(LINES) + newline).encode())
os.close(fd)
@@ -521,25 +570,27 @@ class ExceptionReporterTests(SimpleTestCase):
try:
self.assertEqual(
reporter._get_lines_from_file(filename, 3, 2),
- (1, LINES[1:3], LINES[3], LINES[4:])
+ (1, LINES[1:3], LINES[3], LINES[4:]),
)
finally:
os.unlink(filename)
def test_no_exception(self):
"An exception report can be generated for just a request"
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
reporter = ExceptionReporter(request, None, None, None)
html = reporter.get_traceback_html()
- self.assertInHTML('<h1>Report at /test_view/</h1>', html)
- self.assertIn('<pre class="exception_value">No exception message supplied</pre>', html)
- self.assertIn('<th>Request Method:</th>', html)
- self.assertIn('<th>Request URL:</th>', html)
- self.assertNotIn('<th>Exception Type:</th>', html)
- self.assertNotIn('<th>Exception Value:</th>', html)
- self.assertNotIn('<h2>Traceback ', html)
- self.assertIn('<h2>Request information</h2>', html)
- self.assertNotIn('<p>Request data not supplied</p>', html)
+ self.assertInHTML("<h1>Report at /test_view/</h1>", html)
+ self.assertIn(
+ '<pre class="exception_value">No exception message supplied</pre>', html
+ )
+ self.assertIn("<th>Request Method:</th>", html)
+ self.assertIn("<th>Request URL:</th>", html)
+ self.assertNotIn("<th>Exception Type:</th>", html)
+ self.assertNotIn("<th>Exception Value:</th>", html)
+ self.assertNotIn("<h2>Traceback ", html)
+ self.assertIn("<h2>Request information</h2>", html)
+ self.assertNotIn("<p>Request data not supplied</p>", html)
def test_suppressed_context(self):
try:
@@ -552,21 +603,23 @@ class ExceptionReporterTests(SimpleTestCase):
reporter = ExceptionReporter(None, exc_type, exc_value, tb)
html = reporter.get_traceback_html()
- self.assertInHTML('<h1>ValueError</h1>', html)
- self.assertIn('<pre class="exception_value">Can&#x27;t find my keys</pre>', html)
- self.assertIn('<th>Exception Type:</th>', html)
- self.assertIn('<th>Exception Value:</th>', html)
- self.assertIn('<h2>Traceback ', html)
- self.assertIn('<h2>Request information</h2>', html)
- self.assertIn('<p>Request data not supplied</p>', html)
- self.assertNotIn('During handling of the above exception', html)
+ self.assertInHTML("<h1>ValueError</h1>", html)
+ self.assertIn(
+ '<pre class="exception_value">Can&#x27;t find my keys</pre>', html
+ )
+ self.assertIn("<th>Exception Type:</th>", html)
+ self.assertIn("<th>Exception Value:</th>", html)
+ self.assertIn("<h2>Traceback ", html)
+ self.assertIn("<h2>Request information</h2>", html)
+ self.assertIn("<p>Request data not supplied</p>", html)
+ self.assertNotIn("During handling of the above exception", html)
def test_innermost_exception_without_traceback(self):
try:
try:
- raise RuntimeError('Oops')
+ raise RuntimeError("Oops")
except Exception as exc:
- new_exc = RuntimeError('My context')
+ new_exc = RuntimeError("My context")
exc.__context__ = new_exc
raise
except Exception:
@@ -576,111 +629,119 @@ class ExceptionReporterTests(SimpleTestCase):
frames = reporter.get_traceback_frames()
self.assertEqual(len(frames), 2)
html = reporter.get_traceback_html()
- self.assertInHTML('<h1>RuntimeError</h1>', html)
+ self.assertInHTML("<h1>RuntimeError</h1>", html)
self.assertIn('<pre class="exception_value">Oops</pre>', html)
- self.assertIn('<th>Exception Type:</th>', html)
- self.assertIn('<th>Exception Value:</th>', html)
- self.assertIn('<h2>Traceback ', html)
- self.assertIn('<h2>Request information</h2>', html)
- self.assertIn('<p>Request data not supplied</p>', html)
+ self.assertIn("<th>Exception Type:</th>", html)
+ self.assertIn("<th>Exception Value:</th>", html)
+ self.assertIn("<h2>Traceback ", html)
+ self.assertIn("<h2>Request information</h2>", html)
+ self.assertIn("<p>Request data not supplied</p>", html)
self.assertIn(
- 'During handling of the above exception (My context), another '
- 'exception occurred',
+ "During handling of the above exception (My context), another "
+ "exception occurred",
html,
)
self.assertInHTML('<li class="frame user">None</li>', html)
- self.assertIn('Traceback (most recent call last):\n None', html)
+ self.assertIn("Traceback (most recent call last):\n None", html)
text = reporter.get_traceback_text()
- self.assertIn('Exception Type: RuntimeError', text)
- self.assertIn('Exception Value: Oops', text)
- self.assertIn('Traceback (most recent call last):\n None', text)
+ self.assertIn("Exception Type: RuntimeError", text)
+ self.assertIn("Exception Value: Oops", text)
+ self.assertIn("Traceback (most recent call last):\n None", text)
self.assertIn(
- 'During handling of the above exception (My context), another '
- 'exception occurred',
+ "During handling of the above exception (My context), another "
+ "exception occurred",
text,
)
def test_mid_stack_exception_without_traceback(self):
try:
try:
- raise RuntimeError('Inner Oops')
+ raise RuntimeError("Inner Oops")
except Exception as exc:
- new_exc = RuntimeError('My context')
+ new_exc = RuntimeError("My context")
new_exc.__context__ = exc
- raise RuntimeError('Oops') from new_exc
+ raise RuntimeError("Oops") from new_exc
except Exception:
exc_type, exc_value, tb = sys.exc_info()
reporter = ExceptionReporter(None, exc_type, exc_value, tb)
html = reporter.get_traceback_html()
- self.assertInHTML('<h1>RuntimeError</h1>', html)
+ self.assertInHTML("<h1>RuntimeError</h1>", html)
self.assertIn('<pre class="exception_value">Oops</pre>', html)
- self.assertIn('<th>Exception Type:</th>', html)
- self.assertIn('<th>Exception Value:</th>', html)
- self.assertIn('<h2>Traceback ', html)
+ self.assertIn("<th>Exception Type:</th>", html)
+ self.assertIn("<th>Exception Value:</th>", html)
+ self.assertIn("<h2>Traceback ", html)
self.assertInHTML('<li class="frame user">Traceback: None</li>', html)
self.assertIn(
- 'During handling of the above exception (Inner Oops), another '
- 'exception occurred:\n Traceback: None',
+ "During handling of the above exception (Inner Oops), another "
+ "exception occurred:\n Traceback: None",
html,
)
text = reporter.get_traceback_text()
- self.assertIn('Exception Type: RuntimeError', text)
- self.assertIn('Exception Value: Oops', text)
- self.assertIn('Traceback (most recent call last):', text)
+ self.assertIn("Exception Type: RuntimeError", text)
+ self.assertIn("Exception Value: Oops", text)
+ self.assertIn("Traceback (most recent call last):", text)
self.assertIn(
- 'During handling of the above exception (Inner Oops), another '
- 'exception occurred:\n Traceback: None',
+ "During handling of the above exception (Inner Oops), another "
+ "exception occurred:\n Traceback: None",
text,
)
def test_reporting_of_nested_exceptions(self):
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
try:
try:
- raise AttributeError(mark_safe('<p>Top level</p>'))
+ raise AttributeError(mark_safe("<p>Top level</p>"))
except AttributeError as explicit:
try:
- raise ValueError(mark_safe('<p>Second exception</p>')) from explicit
+ raise ValueError(mark_safe("<p>Second exception</p>")) from explicit
except ValueError:
- raise IndexError(mark_safe('<p>Final exception</p>'))
+ raise IndexError(mark_safe("<p>Final exception</p>"))
except Exception:
# Custom exception handler, just pass it into ExceptionReporter
exc_type, exc_value, tb = sys.exc_info()
- explicit_exc = 'The above exception ({0}) was the direct cause of the following exception:'
- implicit_exc = 'During handling of the above exception ({0}), another exception occurred:'
+ explicit_exc = (
+ "The above exception ({0}) was the direct cause of the following exception:"
+ )
+ implicit_exc = (
+ "During handling of the above exception ({0}), another exception occurred:"
+ )
reporter = ExceptionReporter(request, exc_type, exc_value, tb)
html = reporter.get_traceback_html()
# Both messages are twice on page -- one rendered as html,
# one as plain text (for pastebin)
- self.assertEqual(2, html.count(explicit_exc.format('&lt;p&gt;Top level&lt;/p&gt;')))
- self.assertEqual(2, html.count(implicit_exc.format('&lt;p&gt;Second exception&lt;/p&gt;')))
- self.assertEqual(10, html.count('&lt;p&gt;Final exception&lt;/p&gt;'))
+ self.assertEqual(
+ 2, html.count(explicit_exc.format("&lt;p&gt;Top level&lt;/p&gt;"))
+ )
+ self.assertEqual(
+ 2, html.count(implicit_exc.format("&lt;p&gt;Second exception&lt;/p&gt;"))
+ )
+ self.assertEqual(10, html.count("&lt;p&gt;Final exception&lt;/p&gt;"))
text = reporter.get_traceback_text()
- self.assertIn(explicit_exc.format('<p>Top level</p>'), text)
- self.assertIn(implicit_exc.format('<p>Second exception</p>'), text)
- self.assertEqual(3, text.count('<p>Final exception</p>'))
+ self.assertIn(explicit_exc.format("<p>Top level</p>"), text)
+ self.assertIn(implicit_exc.format("<p>Second exception</p>"), text)
+ self.assertEqual(3, text.count("<p>Final exception</p>"))
def test_reporting_frames_without_source(self):
try:
source = "def funcName():\n raise Error('Whoops')\nfuncName()"
namespace = {}
- code = compile(source, 'generated', 'exec')
+ code = compile(source, "generated", "exec")
exec(code, namespace)
except Exception:
exc_type, exc_value, tb = sys.exc_info()
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
reporter = ExceptionReporter(request, exc_type, exc_value, tb)
frames = reporter.get_traceback_frames()
last_frame = frames[-1]
- self.assertEqual(last_frame['context_line'], '<source code not available>')
- self.assertEqual(last_frame['filename'], 'generated')
- self.assertEqual(last_frame['function'], 'funcName')
- self.assertEqual(last_frame['lineno'], 2)
+ self.assertEqual(last_frame["context_line"], "<source code not available>")
+ self.assertEqual(last_frame["filename"], "generated")
+ self.assertEqual(last_frame["function"], "funcName")
+ self.assertEqual(last_frame["lineno"], 2)
html = reporter.get_traceback_html()
self.assertIn(
'<span class="fname">generated</span>, line 2, in funcName',
@@ -704,22 +765,22 @@ class ExceptionReporterTests(SimpleTestCase):
try:
source = "def funcName():\n raise Error('Whoops')\nfuncName()"
namespace = {}
- code = compile(source, 'generated', 'exec')
+ code = compile(source, "generated", "exec")
exec(code, namespace)
except Exception:
exc_type, exc_value, tb = sys.exc_info()
with mock.patch(
- 'django.views.debug.ExceptionReporter._get_source',
- return_value=['wrong source'],
+ "django.views.debug.ExceptionReporter._get_source",
+ return_value=["wrong source"],
):
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
reporter = ExceptionReporter(request, exc_type, exc_value, tb)
frames = reporter.get_traceback_frames()
last_frame = frames[-1]
- self.assertEqual(last_frame['context_line'], '<source code not available>')
- self.assertEqual(last_frame['filename'], 'generated')
- self.assertEqual(last_frame['function'], 'funcName')
- self.assertEqual(last_frame['lineno'], 2)
+ self.assertEqual(last_frame["context_line"], "<source code not available>")
+ self.assertEqual(last_frame["filename"], "generated")
+ self.assertEqual(last_frame["function"], "funcName")
+ self.assertEqual(last_frame["lineno"], 2)
html = reporter.get_traceback_html()
self.assertIn(
'<span class="fname">generated</span>, line 2, in funcName',
@@ -741,15 +802,17 @@ class ExceptionReporterTests(SimpleTestCase):
def test_reporting_frames_for_cyclic_reference(self):
try:
+
def test_func():
try:
- raise RuntimeError('outer') from RuntimeError('inner')
+ raise RuntimeError("outer") from RuntimeError("inner")
except RuntimeError as exc:
raise exc.__cause__
+
test_func()
except Exception:
exc_type, exc_value, tb = sys.exc_info()
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
reporter = ExceptionReporter(request, exc_type, exc_value, tb)
def generate_traceback_frames(*args, **kwargs):
@@ -772,75 +835,86 @@ class ExceptionReporterTests(SimpleTestCase):
# reporter.get_traceback_frames() exit early.
exc_value.__traceback__ = exc_value.__context__ = exc_value.__cause__ = None
tb_generator.join()
- self.fail('Cyclic reference in Exception Reporter.get_traceback_frames()')
+ self.fail("Cyclic reference in Exception Reporter.get_traceback_frames()")
if tb_frames is None:
# can happen if the thread generating traceback got killed
# or exception while generating the traceback
- self.fail('Traceback generation failed')
+ self.fail("Traceback generation failed")
last_frame = tb_frames[-1]
- self.assertIn('raise exc.__cause__', last_frame['context_line'])
- self.assertEqual(last_frame['filename'], __file__)
- self.assertEqual(last_frame['function'], 'test_func')
+ self.assertIn("raise exc.__cause__", last_frame["context_line"])
+ self.assertEqual(last_frame["filename"], __file__)
+ self.assertEqual(last_frame["function"], "test_func")
def test_request_and_message(self):
"A message can be provided in addition to a request"
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
reporter = ExceptionReporter(request, None, "I'm a little teapot", None)
html = reporter.get_traceback_html()
- self.assertInHTML('<h1>Report at /test_view/</h1>', html)
- self.assertIn('<pre class="exception_value">I&#x27;m a little teapot</pre>', html)
- self.assertIn('<th>Request Method:</th>', html)
- self.assertIn('<th>Request URL:</th>', html)
- self.assertNotIn('<th>Exception Type:</th>', html)
- self.assertNotIn('<th>Exception Value:</th>', html)
- self.assertIn('<h2>Traceback ', html)
- self.assertIn('<h2>Request information</h2>', html)
- self.assertNotIn('<p>Request data not supplied</p>', html)
+ self.assertInHTML("<h1>Report at /test_view/</h1>", html)
+ self.assertIn(
+ '<pre class="exception_value">I&#x27;m a little teapot</pre>', html
+ )
+ self.assertIn("<th>Request Method:</th>", html)
+ self.assertIn("<th>Request URL:</th>", html)
+ self.assertNotIn("<th>Exception Type:</th>", html)
+ self.assertNotIn("<th>Exception Value:</th>", html)
+ self.assertIn("<h2>Traceback ", html)
+ self.assertIn("<h2>Request information</h2>", html)
+ self.assertNotIn("<p>Request data not supplied</p>", html)
def test_message_only(self):
reporter = ExceptionReporter(None, None, "I'm a little teapot", None)
html = reporter.get_traceback_html()
- self.assertInHTML('<h1>Report</h1>', html)
- self.assertIn('<pre class="exception_value">I&#x27;m a little teapot</pre>', html)
- self.assertNotIn('<th>Request Method:</th>', html)
- self.assertNotIn('<th>Request URL:</th>', html)
- self.assertNotIn('<th>Exception Type:</th>', html)
- self.assertNotIn('<th>Exception Value:</th>', html)
- self.assertIn('<h2>Traceback ', html)
- self.assertIn('<h2>Request information</h2>', html)
- self.assertIn('<p>Request data not supplied</p>', html)
+ self.assertInHTML("<h1>Report</h1>", html)
+ self.assertIn(
+ '<pre class="exception_value">I&#x27;m a little teapot</pre>', html
+ )
+ self.assertNotIn("<th>Request Method:</th>", html)
+ self.assertNotIn("<th>Request URL:</th>", html)
+ self.assertNotIn("<th>Exception Type:</th>", html)
+ self.assertNotIn("<th>Exception Value:</th>", html)
+ self.assertIn("<h2>Traceback ", html)
+ self.assertIn("<h2>Request information</h2>", html)
+ self.assertIn("<p>Request data not supplied</p>", html)
def test_non_utf8_values_handling(self):
"Non-UTF-8 exceptions/values should not make the output generation choke."
try:
+
class NonUtf8Output(Exception):
def __repr__(self):
- return b'EXC\xe9EXC'
- somevar = b'VAL\xe9VAL' # NOQA
+ return b"EXC\xe9EXC"
+
+ somevar = b"VAL\xe9VAL" # NOQA
raise NonUtf8Output()
except Exception:
exc_type, exc_value, tb = sys.exc_info()
reporter = ExceptionReporter(None, exc_type, exc_value, tb)
html = reporter.get_traceback_html()
- self.assertIn('VAL\\xe9VAL', html)
- self.assertIn('EXC\\xe9EXC', html)
+ self.assertIn("VAL\\xe9VAL", html)
+ self.assertIn("EXC\\xe9EXC", html)
def test_local_variable_escaping(self):
"""Safe strings in local variables are escaped."""
try:
- local = mark_safe('<p>Local variable</p>')
+ local = mark_safe("<p>Local variable</p>")
raise ValueError(local)
except Exception:
exc_type, exc_value, tb = sys.exc_info()
html = ExceptionReporter(None, exc_type, exc_value, tb).get_traceback_html()
- self.assertIn('<td class="code"><pre>&#x27;&lt;p&gt;Local variable&lt;/p&gt;&#x27;</pre></td>', html)
+ self.assertIn(
+ '<td class="code"><pre>&#x27;&lt;p&gt;Local variable&lt;/p&gt;&#x27;</pre></td>',
+ html,
+ )
def test_unprintable_values_handling(self):
"Unprintable values should not make the output generation choke."
try:
+
class OomOutput:
def __repr__(self):
- raise MemoryError('OOM')
+ raise MemoryError("OOM")
+
oomvalue = OomOutput() # NOQA
raise ValueError()
except Exception:
@@ -852,11 +926,13 @@ class ExceptionReporterTests(SimpleTestCase):
def test_too_large_values_handling(self):
"Large values should not create a large HTML."
large = 256 * 1024
- repr_of_str_adds = len(repr(''))
+ repr_of_str_adds = len(repr(""))
try:
+
class LargeOutput:
def __repr__(self):
- return repr('A' * large)
+ return repr("A" * large)
+
largevalue = LargeOutput() # NOQA
raise ValueError()
except Exception:
@@ -864,7 +940,9 @@ class ExceptionReporterTests(SimpleTestCase):
reporter = ExceptionReporter(None, exc_type, exc_value, tb)
html = reporter.get_traceback_html()
self.assertEqual(len(html) // 1024 // 128, 0) # still fit in 128Kb
- self.assertIn('&lt;trimmed %d bytes string&gt;' % (large + repr_of_str_adds,), html)
+ self.assertIn(
+ "&lt;trimmed %d bytes string&gt;" % (large + repr_of_str_adds,), html
+ )
def test_encoding_error(self):
"""
@@ -872,14 +950,14 @@ class ExceptionReporterTests(SimpleTestCase):
safe strings is escaped.
"""
try:
- mark_safe('abcdefghijkl<p>mnὀp</p>qrstuwxyz').encode('ascii')
+ mark_safe("abcdefghijkl<p>mnὀp</p>qrstuwxyz").encode("ascii")
except Exception:
exc_type, exc_value, tb = sys.exc_info()
reporter = ExceptionReporter(None, exc_type, exc_value, tb)
html = reporter.get_traceback_html()
- self.assertIn('<h2>Unicode error hint</h2>', html)
- self.assertIn('The string that could not be encoded/decoded was: ', html)
- self.assertIn('<strong>&lt;p&gt;mnὀp&lt;/p&gt;</strong>', html)
+ self.assertIn("<h2>Unicode error hint</h2>", html)
+ self.assertIn("The string that could not be encoded/decoded was: ", html)
+ self.assertIn("<strong>&lt;p&gt;mnὀp&lt;/p&gt;</strong>", html)
def test_unfrozen_importlib(self):
"""
@@ -887,26 +965,27 @@ class ExceptionReporterTests(SimpleTestCase):
results in an ImportError. Refs #21443.
"""
try:
- request = self.rf.get('/test_view/')
- importlib.import_module('abc.def.invalid.name')
+ request = self.rf.get("/test_view/")
+ importlib.import_module("abc.def.invalid.name")
except Exception:
exc_type, exc_value, tb = sys.exc_info()
reporter = ExceptionReporter(request, exc_type, exc_value, tb)
html = reporter.get_traceback_html()
- self.assertInHTML('<h1>ModuleNotFoundError at /test_view/</h1>', html)
+ self.assertInHTML("<h1>ModuleNotFoundError at /test_view/</h1>", html)
def test_ignore_traceback_evaluation_exceptions(self):
"""
Don't trip over exceptions generated by crafted objects when
evaluating them while cleansing (#24455).
"""
+
class BrokenEvaluation(Exception):
pass
def broken_setup():
raise BrokenEvaluation
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
broken_lazy = SimpleLazyObject(broken_setup)
try:
bool(broken_lazy)
@@ -916,13 +995,13 @@ class ExceptionReporterTests(SimpleTestCase):
self.assertIn(
"BrokenEvaluation",
ExceptionReporter(request, exc_type, exc_value, tb).get_traceback_html(),
- "Evaluation exception reason not mentioned in traceback"
+ "Evaluation exception reason not mentioned in traceback",
)
- @override_settings(ALLOWED_HOSTS='example.com')
+ @override_settings(ALLOWED_HOSTS="example.com")
def test_disallowed_host(self):
"An exception report can be generated even for a disallowed host."
- request = self.rf.get('/', HTTP_HOST='evil.com')
+ request = self.rf.get("/", HTTP_HOST="evil.com")
reporter = ExceptionReporter(request, None, None, None)
html = reporter.get_traceback_html()
self.assertIn("http://evil.com/", html)
@@ -934,59 +1013,62 @@ class ExceptionReporterTests(SimpleTestCase):
"""
value = '<td>items</td><td class="code"><pre>&#x27;Oops&#x27;</pre></td>'
# GET
- request = self.rf.get('/test_view/?items=Oops')
+ request = self.rf.get("/test_view/?items=Oops")
reporter = ExceptionReporter(request, None, None, None)
html = reporter.get_traceback_html()
self.assertInHTML(value, html)
# POST
- request = self.rf.post('/test_view/', data={'items': 'Oops'})
+ request = self.rf.post("/test_view/", data={"items": "Oops"})
reporter = ExceptionReporter(request, None, None, None)
html = reporter.get_traceback_html()
self.assertInHTML(value, html)
# FILES
- fp = StringIO('filecontent')
- request = self.rf.post('/test_view/', data={'name': 'filename', 'items': fp})
+ fp = StringIO("filecontent")
+ request = self.rf.post("/test_view/", data={"name": "filename", "items": fp})
reporter = ExceptionReporter(request, None, None, None)
html = reporter.get_traceback_html()
self.assertInHTML(
'<td>items</td><td class="code"><pre>&lt;InMemoryUploadedFile: '
- 'items (application/octet-stream)&gt;</pre></td>',
- html
+ "items (application/octet-stream)&gt;</pre></td>",
+ html,
)
# COOKIES
rf = RequestFactory()
- rf.cookies['items'] = 'Oops'
- request = rf.get('/test_view/')
+ rf.cookies["items"] = "Oops"
+ request = rf.get("/test_view/")
reporter = ExceptionReporter(request, None, None, None)
html = reporter.get_traceback_html()
- self.assertInHTML('<td>items</td><td class="code"><pre>&#x27;Oops&#x27;</pre></td>', html)
+ self.assertInHTML(
+ '<td>items</td><td class="code"><pre>&#x27;Oops&#x27;</pre></td>', html
+ )
def test_exception_fetching_user(self):
"""
The error page can be rendered if the current user can't be retrieved
(such as when the database is unavailable).
"""
+
class ExceptionUser:
def __str__(self):
raise Exception()
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
request.user = ExceptionUser()
try:
- raise ValueError('Oops')
+ raise ValueError("Oops")
except ValueError:
exc_type, exc_value, tb = sys.exc_info()
reporter = ExceptionReporter(request, exc_type, exc_value, tb)
html = reporter.get_traceback_html()
- self.assertInHTML('<h1>ValueError at /test_view/</h1>', html)
+ self.assertInHTML("<h1>ValueError at /test_view/</h1>", html)
self.assertIn('<pre class="exception_value">Oops</pre>', html)
self.assertIn('<h3 id="user-info">USER</h3>', html)
- self.assertIn('<p>[unable to retrieve the current user]</p>', html)
+ self.assertIn("<p>[unable to retrieve the current user]</p>", html)
text = reporter.get_traceback_text()
- self.assertIn('USER: [unable to retrieve the current user]', text)
+ self.assertIn("USER: [unable to retrieve the current user]", text)
def test_template_encoding(self):
"""
@@ -995,20 +1077,20 @@ class ExceptionReporterTests(SimpleTestCase):
template engines.
"""
reporter = ExceptionReporter(None, None, None, None)
- with mock.patch.object(DebugPath, 'open') as m:
+ with mock.patch.object(DebugPath, "open") as m:
reporter.get_traceback_html()
- m.assert_called_once_with(encoding='utf-8')
+ m.assert_called_once_with(encoding="utf-8")
m.reset_mock()
reporter.get_traceback_text()
- m.assert_called_once_with(encoding='utf-8')
+ m.assert_called_once_with(encoding="utf-8")
- @override_settings(ALLOWED_HOSTS=['example.com'])
+ @override_settings(ALLOWED_HOSTS=["example.com"])
def test_get_raw_insecure_uri(self):
- factory = RequestFactory(HTTP_HOST='evil.com')
+ factory = RequestFactory(HTTP_HOST="evil.com")
tests = [
- ('////absolute-uri', 'http://evil.com//absolute-uri'),
- ('/?foo=bar', 'http://evil.com/?foo=bar'),
- ('/path/with:colons', 'http://evil.com/path/with:colons'),
+ ("////absolute-uri", "http://evil.com//absolute-uri"),
+ ("/?foo=bar", "http://evil.com/?foo=bar"),
+ ("/path/with:colons", "http://evil.com/path/with:colons"),
]
for url, expected in tests:
with self.subTest(url=url):
@@ -1023,23 +1105,23 @@ class PlainTextReportTests(SimpleTestCase):
def test_request_and_exception(self):
"A simple exception report can be generated"
try:
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
request.user = User()
raise ValueError("Can't find my keys")
except ValueError:
exc_type, exc_value, tb = sys.exc_info()
reporter = ExceptionReporter(request, exc_type, exc_value, tb)
text = reporter.get_traceback_text()
- self.assertIn('ValueError at /test_view/', text)
+ self.assertIn("ValueError at /test_view/", text)
self.assertIn("Can't find my keys", text)
- self.assertIn('Request Method:', text)
- self.assertIn('Request URL:', text)
- self.assertIn('USER: jacob', text)
- self.assertIn('Exception Type:', text)
- self.assertIn('Exception Value:', text)
- self.assertIn('Traceback (most recent call last):', text)
- self.assertIn('Request information:', text)
- self.assertNotIn('Request data not supplied', text)
+ self.assertIn("Request Method:", text)
+ self.assertIn("Request URL:", text)
+ self.assertIn("USER: jacob", text)
+ self.assertIn("Exception Type:", text)
+ self.assertIn("Exception Value:", text)
+ self.assertIn("Traceback (most recent call last):", text)
+ self.assertIn("Request information:", text)
+ self.assertNotIn("Request data not supplied", text)
def test_no_request(self):
"An exception report can be generated without request"
@@ -1049,46 +1131,48 @@ class PlainTextReportTests(SimpleTestCase):
exc_type, exc_value, tb = sys.exc_info()
reporter = ExceptionReporter(None, exc_type, exc_value, tb)
text = reporter.get_traceback_text()
- self.assertIn('ValueError', text)
+ self.assertIn("ValueError", text)
self.assertIn("Can't find my keys", text)
- self.assertNotIn('Request Method:', text)
- self.assertNotIn('Request URL:', text)
- self.assertNotIn('USER:', text)
- self.assertIn('Exception Type:', text)
- self.assertIn('Exception Value:', text)
- self.assertIn('Traceback (most recent call last):', text)
- self.assertIn('Request data not supplied', text)
+ self.assertNotIn("Request Method:", text)
+ self.assertNotIn("Request URL:", text)
+ self.assertNotIn("USER:", text)
+ self.assertIn("Exception Type:", text)
+ self.assertIn("Exception Value:", text)
+ self.assertIn("Traceback (most recent call last):", text)
+ self.assertIn("Request data not supplied", text)
def test_no_exception(self):
"An exception report can be generated for just a request"
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
reporter = ExceptionReporter(request, None, None, None)
reporter.get_traceback_text()
def test_request_and_message(self):
"A message can be provided in addition to a request"
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
reporter = ExceptionReporter(request, None, "I'm a little teapot", None)
reporter.get_traceback_text()
@override_settings(DEBUG=True)
def test_template_exception(self):
- request = self.rf.get('/test_view/')
+ request = self.rf.get("/test_view/")
try:
- render(request, 'debug/template_error.html')
+ render(request, "debug/template_error.html")
except Exception:
exc_type, exc_value, tb = sys.exc_info()
reporter = ExceptionReporter(request, exc_type, exc_value, tb)
text = reporter.get_traceback_text()
- templ_path = Path(Path(__file__).parents[1], 'templates', 'debug', 'template_error.html')
+ templ_path = Path(
+ Path(__file__).parents[1], "templates", "debug", "template_error.html"
+ )
self.assertIn(
- 'Template error:\n'
- 'In template %(path)s, error at line 2\n'
- ' \'cycle\' tag requires at least two arguments\n'
- ' 1 : Template with error:\n'
- ' 2 : {%% cycle %%} \n'
- ' 3 : ' % {'path': templ_path},
- text
+ "Template error:\n"
+ "In template %(path)s, error at line 2\n"
+ " 'cycle' tag requires at least two arguments\n"
+ " 1 : Template with error:\n"
+ " 2 : {%% cycle %%} \n"
+ " 3 : " % {"path": templ_path},
+ text,
)
def test_request_with_items_key(self):
@@ -1097,25 +1181,25 @@ class PlainTextReportTests(SimpleTestCase):
request GET, POST, FILES, or COOKIES QueryDicts.
"""
# GET
- request = self.rf.get('/test_view/?items=Oops')
+ request = self.rf.get("/test_view/?items=Oops")
reporter = ExceptionReporter(request, None, None, None)
text = reporter.get_traceback_text()
self.assertIn("items = 'Oops'", text)
# POST
- request = self.rf.post('/test_view/', data={'items': 'Oops'})
+ request = self.rf.post("/test_view/", data={"items": "Oops"})
reporter = ExceptionReporter(request, None, None, None)
text = reporter.get_traceback_text()
self.assertIn("items = 'Oops'", text)
# FILES
- fp = StringIO('filecontent')
- request = self.rf.post('/test_view/', data={'name': 'filename', 'items': fp})
+ fp = StringIO("filecontent")
+ request = self.rf.post("/test_view/", data={"name": "filename", "items": fp})
reporter = ExceptionReporter(request, None, None, None)
text = reporter.get_traceback_text()
- self.assertIn('items = <InMemoryUploadedFile:', text)
+ self.assertIn("items = <InMemoryUploadedFile:", text)
# COOKIES
rf = RequestFactory()
- rf.cookies['items'] = 'Oops'
- request = rf.get('/test_view/')
+ rf.cookies["items"] = "Oops"
+ request = rf.get("/test_view/")
reporter = ExceptionReporter(request, None, None, None)
text = reporter.get_traceback_text()
self.assertIn("items = 'Oops'", text)
@@ -1124,10 +1208,10 @@ class PlainTextReportTests(SimpleTestCase):
reporter = ExceptionReporter(None, None, "I'm a little teapot", None)
reporter.get_traceback_text()
- @override_settings(ALLOWED_HOSTS='example.com')
+ @override_settings(ALLOWED_HOSTS="example.com")
def test_disallowed_host(self):
"An exception report can be generated even for a disallowed host."
- request = self.rf.get('/', HTTP_HOST='evil.com')
+ request = self.rf.get("/", HTTP_HOST="evil.com")
reporter = ExceptionReporter(request, None, None, None)
text = reporter.get_traceback_text()
self.assertIn("http://evil.com/", text)
@@ -1137,69 +1221,72 @@ class ExceptionReportTestMixin:
# Mixin used in the ExceptionReporterFilterTests and
# AjaxResponseExceptionReporterFilter tests below
breakfast_data = {
- 'sausage-key': 'sausage-value',
- 'baked-beans-key': 'baked-beans-value',
- 'hash-brown-key': 'hash-brown-value',
- 'bacon-key': 'bacon-value',
+ "sausage-key": "sausage-value",
+ "baked-beans-key": "baked-beans-value",
+ "hash-brown-key": "hash-brown-value",
+ "bacon-key": "bacon-value",
}
- def verify_unsafe_response(self, view, check_for_vars=True,
- check_for_POST_params=True):
+ def verify_unsafe_response(
+ self, view, check_for_vars=True, check_for_POST_params=True
+ ):
"""
Asserts that potentially sensitive info are displayed in the response.
"""
- request = self.rf.post('/some_url/', self.breakfast_data)
+ request = self.rf.post("/some_url/", self.breakfast_data)
response = view(request)
if check_for_vars:
# All variables are shown.
- self.assertContains(response, 'cooked_eggs', status_code=500)
- self.assertContains(response, 'scrambled', status_code=500)
- self.assertContains(response, 'sauce', status_code=500)
- self.assertContains(response, 'worcestershire', status_code=500)
+ self.assertContains(response, "cooked_eggs", status_code=500)
+ self.assertContains(response, "scrambled", status_code=500)
+ self.assertContains(response, "sauce", status_code=500)
+ self.assertContains(response, "worcestershire", status_code=500)
if check_for_POST_params:
for k, v in self.breakfast_data.items():
# All POST parameters are shown.
self.assertContains(response, k, status_code=500)
self.assertContains(response, v, status_code=500)
- def verify_safe_response(self, view, check_for_vars=True,
- check_for_POST_params=True):
+ def verify_safe_response(
+ self, view, check_for_vars=True, check_for_POST_params=True
+ ):
"""
Asserts that certain sensitive info are not displayed in the response.
"""
- request = self.rf.post('/some_url/', self.breakfast_data)
+ request = self.rf.post("/some_url/", self.breakfast_data)
response = view(request)
if check_for_vars:
# Non-sensitive variable's name and value are shown.
- self.assertContains(response, 'cooked_eggs', status_code=500)
- self.assertContains(response, 'scrambled', status_code=500)
+ self.assertContains(response, "cooked_eggs", status_code=500)
+ self.assertContains(response, "scrambled", status_code=500)
# Sensitive variable's name is shown but not its value.
- self.assertContains(response, 'sauce', status_code=500)
- self.assertNotContains(response, 'worcestershire', status_code=500)
+ self.assertContains(response, "sauce", status_code=500)
+ self.assertNotContains(response, "worcestershire", status_code=500)
if check_for_POST_params:
for k in self.breakfast_data:
# All POST parameters' names are shown.
self.assertContains(response, k, status_code=500)
# Non-sensitive POST parameters' values are shown.
- self.assertContains(response, 'baked-beans-value', status_code=500)
- self.assertContains(response, 'hash-brown-value', status_code=500)
+ self.assertContains(response, "baked-beans-value", status_code=500)
+ self.assertContains(response, "hash-brown-value", status_code=500)
# Sensitive POST parameters' values are not shown.
- self.assertNotContains(response, 'sausage-value', status_code=500)
- self.assertNotContains(response, 'bacon-value', status_code=500)
+ self.assertNotContains(response, "sausage-value", status_code=500)
+ self.assertNotContains(response, "bacon-value", status_code=500)
- def verify_paranoid_response(self, view, check_for_vars=True,
- check_for_POST_params=True):
+ def verify_paranoid_response(
+ self, view, check_for_vars=True, check_for_POST_params=True
+ ):
"""
Asserts that no variables or POST parameters are displayed in the response.
"""
- request = self.rf.post('/some_url/', self.breakfast_data)
+ request = self.rf.post("/some_url/", self.breakfast_data)
response = view(request)
if check_for_vars:
# Show variable names but not their values.
- self.assertContains(response, 'cooked_eggs', status_code=500)
- self.assertNotContains(response, 'scrambled', status_code=500)
- self.assertContains(response, 'sauce', status_code=500)
- self.assertNotContains(response, 'worcestershire', status_code=500)
+ self.assertContains(response, "cooked_eggs", status_code=500)
+ self.assertNotContains(response, "scrambled", status_code=500)
+ self.assertContains(response, "sauce", status_code=500)
+ self.assertNotContains(response, "worcestershire", status_code=500)
if check_for_POST_params:
for k, v in self.breakfast_data.items():
# All POST parameters' names are shown.
@@ -1211,26 +1298,26 @@ class ExceptionReportTestMixin:
"""
Asserts that potentially sensitive info are displayed in the email report.
"""
- with self.settings(ADMINS=[('Admin', 'admin@fattie-breakie.com')]):
+ with self.settings(ADMINS=[("Admin", "admin@fattie-breakie.com")]):
mail.outbox = [] # Empty outbox
- request = self.rf.post('/some_url/', self.breakfast_data)
+ request = self.rf.post("/some_url/", self.breakfast_data)
view(request)
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
# Frames vars are never shown in plain text email reports.
body_plain = str(email.body)
- self.assertNotIn('cooked_eggs', body_plain)
- self.assertNotIn('scrambled', body_plain)
- self.assertNotIn('sauce', body_plain)
- self.assertNotIn('worcestershire', body_plain)
+ self.assertNotIn("cooked_eggs", body_plain)
+ self.assertNotIn("scrambled", body_plain)
+ self.assertNotIn("sauce", body_plain)
+ self.assertNotIn("worcestershire", body_plain)
# Frames vars are shown in html email reports.
body_html = str(email.alternatives[0][0])
- self.assertIn('cooked_eggs', body_html)
- self.assertIn('scrambled', body_html)
- self.assertIn('sauce', body_html)
- self.assertIn('worcestershire', body_html)
+ self.assertIn("cooked_eggs", body_html)
+ self.assertIn("scrambled", body_html)
+ self.assertIn("sauce", body_html)
+ self.assertIn("worcestershire", body_html)
if check_for_POST_params:
for k, v in self.breakfast_data.items():
@@ -1244,58 +1331,58 @@ class ExceptionReportTestMixin:
"""
Asserts that certain sensitive info are not displayed in the email report.
"""
- with self.settings(ADMINS=[('Admin', 'admin@fattie-breakie.com')]):
+ with self.settings(ADMINS=[("Admin", "admin@fattie-breakie.com")]):
mail.outbox = [] # Empty outbox
- request = self.rf.post('/some_url/', self.breakfast_data)
+ request = self.rf.post("/some_url/", self.breakfast_data)
view(request)
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
# Frames vars are never shown in plain text email reports.
body_plain = str(email.body)
- self.assertNotIn('cooked_eggs', body_plain)
- self.assertNotIn('scrambled', body_plain)
- self.assertNotIn('sauce', body_plain)
- self.assertNotIn('worcestershire', body_plain)
+ self.assertNotIn("cooked_eggs", body_plain)
+ self.assertNotIn("scrambled", body_plain)
+ self.assertNotIn("sauce", body_plain)
+ self.assertNotIn("worcestershire", body_plain)
# Frames vars are shown in html email reports.
body_html = str(email.alternatives[0][0])
- self.assertIn('cooked_eggs', body_html)
- self.assertIn('scrambled', body_html)
- self.assertIn('sauce', body_html)
- self.assertNotIn('worcestershire', body_html)
+ self.assertIn("cooked_eggs", body_html)
+ self.assertIn("scrambled", body_html)
+ self.assertIn("sauce", body_html)
+ self.assertNotIn("worcestershire", body_html)
if check_for_POST_params:
for k in self.breakfast_data:
# All POST parameters' names are shown.
self.assertIn(k, body_plain)
# Non-sensitive POST parameters' values are shown.
- self.assertIn('baked-beans-value', body_plain)
- self.assertIn('hash-brown-value', body_plain)
- self.assertIn('baked-beans-value', body_html)
- self.assertIn('hash-brown-value', body_html)
+ self.assertIn("baked-beans-value", body_plain)
+ self.assertIn("hash-brown-value", body_plain)
+ self.assertIn("baked-beans-value", body_html)
+ self.assertIn("hash-brown-value", body_html)
# Sensitive POST parameters' values are not shown.
- self.assertNotIn('sausage-value', body_plain)
- self.assertNotIn('bacon-value', body_plain)
- self.assertNotIn('sausage-value', body_html)
- self.assertNotIn('bacon-value', body_html)
+ self.assertNotIn("sausage-value", body_plain)
+ self.assertNotIn("bacon-value", body_plain)
+ self.assertNotIn("sausage-value", body_html)
+ self.assertNotIn("bacon-value", body_html)
def verify_paranoid_email(self, view):
"""
Asserts that no variables or POST parameters are displayed in the email report.
"""
- with self.settings(ADMINS=[('Admin', 'admin@fattie-breakie.com')]):
+ with self.settings(ADMINS=[("Admin", "admin@fattie-breakie.com")]):
mail.outbox = [] # Empty outbox
- request = self.rf.post('/some_url/', self.breakfast_data)
+ request = self.rf.post("/some_url/", self.breakfast_data)
view(request)
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
# Frames vars are never shown in plain text email reports.
body = str(email.body)
- self.assertNotIn('cooked_eggs', body)
- self.assertNotIn('scrambled', body)
- self.assertNotIn('sauce', body)
- self.assertNotIn('worcestershire', body)
+ self.assertNotIn("cooked_eggs", body)
+ self.assertNotIn("scrambled", body)
+ self.assertNotIn("sauce", body)
+ self.assertNotIn("worcestershire", body)
for k, v in self.breakfast_data.items():
# All POST parameters' names are shown.
self.assertIn(k, body)
@@ -1303,11 +1390,14 @@ class ExceptionReportTestMixin:
self.assertNotIn(v, body)
-@override_settings(ROOT_URLCONF='view_tests.urls')
-class ExceptionReporterFilterTests(ExceptionReportTestMixin, LoggingCaptureMixin, SimpleTestCase):
+@override_settings(ROOT_URLCONF="view_tests.urls")
+class ExceptionReporterFilterTests(
+ ExceptionReportTestMixin, LoggingCaptureMixin, SimpleTestCase
+):
"""
Sensitive information can be filtered out of error reports (#14614).
"""
+
rf = RequestFactory()
def test_non_sensitive_request(self):
@@ -1380,11 +1470,15 @@ class ExceptionReporterFilterTests(ExceptionReportTestMixin, LoggingCaptureMixin
The sensitive_variables decorator works with object methods.
"""
with self.settings(DEBUG=True):
- self.verify_unsafe_response(sensitive_method_view, check_for_POST_params=False)
+ self.verify_unsafe_response(
+ sensitive_method_view, check_for_POST_params=False
+ )
self.verify_unsafe_email(sensitive_method_view, check_for_POST_params=False)
with self.settings(DEBUG=False):
- self.verify_safe_response(sensitive_method_view, check_for_POST_params=False)
+ self.verify_safe_response(
+ sensitive_method_view, check_for_POST_params=False
+ )
self.verify_safe_email(sensitive_method_view, check_for_POST_params=False)
def test_sensitive_function_arguments(self):
@@ -1398,8 +1492,12 @@ class ExceptionReporterFilterTests(ExceptionReportTestMixin, LoggingCaptureMixin
self.verify_unsafe_email(sensitive_args_function_caller)
with self.settings(DEBUG=False):
- self.verify_safe_response(sensitive_args_function_caller, check_for_POST_params=False)
- self.verify_safe_email(sensitive_args_function_caller, check_for_POST_params=False)
+ self.verify_safe_response(
+ sensitive_args_function_caller, check_for_POST_params=False
+ )
+ self.verify_safe_email(
+ sensitive_args_function_caller, check_for_POST_params=False
+ )
def test_sensitive_function_keyword_arguments(self):
"""
@@ -1412,24 +1510,33 @@ class ExceptionReporterFilterTests(ExceptionReportTestMixin, LoggingCaptureMixin
self.verify_unsafe_email(sensitive_kwargs_function_caller)
with self.settings(DEBUG=False):
- self.verify_safe_response(sensitive_kwargs_function_caller, check_for_POST_params=False)
- self.verify_safe_email(sensitive_kwargs_function_caller, check_for_POST_params=False)
+ self.verify_safe_response(
+ sensitive_kwargs_function_caller, check_for_POST_params=False
+ )
+ self.verify_safe_email(
+ sensitive_kwargs_function_caller, check_for_POST_params=False
+ )
def test_callable_settings(self):
"""
Callable settings should not be evaluated in the debug page (#21345).
"""
+
def callable_setting():
return "This should not be displayed"
+
with self.settings(DEBUG=True, FOOBAR=callable_setting):
- response = self.client.get('/raises500/')
- self.assertNotContains(response, "This should not be displayed", status_code=500)
+ response = self.client.get("/raises500/")
+ self.assertNotContains(
+ response, "This should not be displayed", status_code=500
+ )
def test_callable_settings_forbidding_to_set_attributes(self):
"""
Callable settings which forbid to set attributes should not break
the debug page (#23070).
"""
+
class CallableSettingWithSlots:
__slots__ = []
@@ -1437,8 +1544,10 @@ class ExceptionReporterFilterTests(ExceptionReportTestMixin, LoggingCaptureMixin
return "This should not be displayed"
with self.settings(DEBUG=True, WITH_SLOTS=CallableSettingWithSlots()):
- response = self.client.get('/raises500/')
- self.assertNotContains(response, "This should not be displayed", status_code=500)
+ response = self.client.get("/raises500/")
+ self.assertNotContains(
+ response, "This should not be displayed", status_code=500
+ )
def test_dict_setting_with_non_str_key(self):
"""
@@ -1446,8 +1555,8 @@ class ExceptionReporterFilterTests(ExceptionReportTestMixin, LoggingCaptureMixin
debug page (#12744).
"""
with self.settings(DEBUG=True, FOOBAR={42: None}):
- response = self.client.get('/raises500/')
- self.assertContains(response, 'FOOBAR', status_code=500)
+ response = self.client.get("/raises500/")
+ self.assertContains(response, "FOOBAR", status_code=500)
def test_sensitive_settings(self):
"""
@@ -1455,16 +1564,18 @@ class ExceptionReporterFilterTests(ExceptionReportTestMixin, LoggingCaptureMixin
(password, secret key, ...).
"""
sensitive_settings = [
- 'SECRET_KEY',
- 'SECRET_KEY_FALLBACKS',
- 'PASSWORD',
- 'API_KEY',
- 'AUTH_TOKEN',
+ "SECRET_KEY",
+ "SECRET_KEY_FALLBACKS",
+ "PASSWORD",
+ "API_KEY",
+ "AUTH_TOKEN",
]
for setting in sensitive_settings:
with self.settings(DEBUG=True, **{setting: "should not be displayed"}):
- response = self.client.get('/raises500/')
- self.assertNotContains(response, 'should not be displayed', status_code=500)
+ response = self.client.get("/raises500/")
+ self.assertNotContains(
+ response, "should not be displayed", status_code=500
+ )
def test_settings_with_sensitive_keys(self):
"""
@@ -1472,53 +1583,55 @@ class ExceptionReporterFilterTests(ExceptionReportTestMixin, LoggingCaptureMixin
dict settings.
"""
sensitive_settings = [
- 'SECRET_KEY',
- 'SECRET_KEY_FALLBACKS',
- 'PASSWORD',
- 'API_KEY',
- 'AUTH_TOKEN',
+ "SECRET_KEY",
+ "SECRET_KEY_FALLBACKS",
+ "PASSWORD",
+ "API_KEY",
+ "AUTH_TOKEN",
]
for setting in sensitive_settings:
FOOBAR = {
setting: "should not be displayed",
- 'recursive': {setting: "should not be displayed"},
+ "recursive": {setting: "should not be displayed"},
}
with self.settings(DEBUG=True, FOOBAR=FOOBAR):
- response = self.client.get('/raises500/')
- self.assertNotContains(response, 'should not be displayed', status_code=500)
+ response = self.client.get("/raises500/")
+ self.assertNotContains(
+ response, "should not be displayed", status_code=500
+ )
def test_cleanse_setting_basic(self):
reporter_filter = SafeExceptionReporterFilter()
- self.assertEqual(reporter_filter.cleanse_setting('TEST', 'TEST'), 'TEST')
+ self.assertEqual(reporter_filter.cleanse_setting("TEST", "TEST"), "TEST")
self.assertEqual(
- reporter_filter.cleanse_setting('PASSWORD', 'super_secret'),
+ reporter_filter.cleanse_setting("PASSWORD", "super_secret"),
reporter_filter.cleansed_substitute,
)
def test_cleanse_setting_ignore_case(self):
reporter_filter = SafeExceptionReporterFilter()
self.assertEqual(
- reporter_filter.cleanse_setting('password', 'super_secret'),
+ reporter_filter.cleanse_setting("password", "super_secret"),
reporter_filter.cleansed_substitute,
)
def test_cleanse_setting_recurses_in_dictionary(self):
reporter_filter = SafeExceptionReporterFilter()
- initial = {'login': 'cooper', 'password': 'secret'}
+ initial = {"login": "cooper", "password": "secret"}
self.assertEqual(
- reporter_filter.cleanse_setting('SETTING_NAME', initial),
- {'login': 'cooper', 'password': reporter_filter.cleansed_substitute},
+ reporter_filter.cleanse_setting("SETTING_NAME", initial),
+ {"login": "cooper", "password": reporter_filter.cleansed_substitute},
)
def test_cleanse_setting_recurses_in_dictionary_with_non_string_key(self):
reporter_filter = SafeExceptionReporterFilter()
- initial = {('localhost', 8000): {'login': 'cooper', 'password': 'secret'}}
+ initial = {("localhost", 8000): {"login": "cooper", "password": "secret"}}
self.assertEqual(
- reporter_filter.cleanse_setting('SETTING_NAME', initial),
+ reporter_filter.cleanse_setting("SETTING_NAME", initial),
{
- ('localhost', 8000): {
- 'login': 'cooper',
- 'password': reporter_filter.cleansed_substitute,
+ ("localhost", 8000): {
+ "login": "cooper",
+ "password": reporter_filter.cleansed_substitute,
},
},
)
@@ -1527,64 +1640,66 @@ class ExceptionReporterFilterTests(ExceptionReportTestMixin, LoggingCaptureMixin
reporter_filter = SafeExceptionReporterFilter()
initial = [
{
- 'login': 'cooper',
- 'password': 'secret',
- 'apps': (
- {'name': 'app1', 'api_key': 'a06b-c462cffae87a'},
- {'name': 'app2', 'api_key': 'a9f4-f152e97ad808'},
+ "login": "cooper",
+ "password": "secret",
+ "apps": (
+ {"name": "app1", "api_key": "a06b-c462cffae87a"},
+ {"name": "app2", "api_key": "a9f4-f152e97ad808"},
),
- 'tokens': ['98b37c57-ec62-4e39', '8690ef7d-8004-4916'],
+ "tokens": ["98b37c57-ec62-4e39", "8690ef7d-8004-4916"],
},
- {'SECRET_KEY': 'c4d77c62-6196-4f17-a06b-c462cffae87a'},
+ {"SECRET_KEY": "c4d77c62-6196-4f17-a06b-c462cffae87a"},
]
cleansed = [
{
- 'login': 'cooper',
- 'password': reporter_filter.cleansed_substitute,
- 'apps': (
- {'name': 'app1', 'api_key': reporter_filter.cleansed_substitute},
- {'name': 'app2', 'api_key': reporter_filter.cleansed_substitute},
+ "login": "cooper",
+ "password": reporter_filter.cleansed_substitute,
+ "apps": (
+ {"name": "app1", "api_key": reporter_filter.cleansed_substitute},
+ {"name": "app2", "api_key": reporter_filter.cleansed_substitute},
),
- 'tokens': reporter_filter.cleansed_substitute,
+ "tokens": reporter_filter.cleansed_substitute,
},
- {'SECRET_KEY': reporter_filter.cleansed_substitute},
+ {"SECRET_KEY": reporter_filter.cleansed_substitute},
]
self.assertEqual(
- reporter_filter.cleanse_setting('SETTING_NAME', initial),
+ reporter_filter.cleanse_setting("SETTING_NAME", initial),
cleansed,
)
self.assertEqual(
- reporter_filter.cleanse_setting('SETTING_NAME', tuple(initial)),
+ reporter_filter.cleanse_setting("SETTING_NAME", tuple(initial)),
tuple(cleansed),
)
def test_request_meta_filtering(self):
- request = self.rf.get('/', HTTP_SECRET_HEADER='super_secret')
+ request = self.rf.get("/", HTTP_SECRET_HEADER="super_secret")
reporter_filter = SafeExceptionReporterFilter()
self.assertEqual(
- reporter_filter.get_safe_request_meta(request)['HTTP_SECRET_HEADER'],
+ reporter_filter.get_safe_request_meta(request)["HTTP_SECRET_HEADER"],
reporter_filter.cleansed_substitute,
)
def test_exception_report_uses_meta_filtering(self):
- response = self.client.get('/raises500/', HTTP_SECRET_HEADER='super_secret')
- self.assertNotIn(b'super_secret', response.content)
+ response = self.client.get("/raises500/", HTTP_SECRET_HEADER="super_secret")
+ self.assertNotIn(b"super_secret", response.content)
response = self.client.get(
- '/raises500/',
- HTTP_SECRET_HEADER='super_secret',
- HTTP_ACCEPT='application/json',
+ "/raises500/",
+ HTTP_SECRET_HEADER="super_secret",
+ HTTP_ACCEPT="application/json",
)
- self.assertNotIn(b'super_secret', response.content)
+ self.assertNotIn(b"super_secret", response.content)
class CustomExceptionReporterFilter(SafeExceptionReporterFilter):
- cleansed_substitute = 'XXXXXXXXXXXXXXXXXXXX'
- hidden_settings = _lazy_re_compile('API|TOKEN|KEY|SECRET|PASS|SIGNATURE|DATABASE_URL', flags=re.I)
+ cleansed_substitute = "XXXXXXXXXXXXXXXXXXXX"
+ hidden_settings = _lazy_re_compile(
+ "API|TOKEN|KEY|SECRET|PASS|SIGNATURE|DATABASE_URL", flags=re.I
+ )
@override_settings(
- ROOT_URLCONF='view_tests.urls',
- DEFAULT_EXCEPTION_REPORTER_FILTER='%s.CustomExceptionReporterFilter' % __name__,
+ ROOT_URLCONF="view_tests.urls",
+ DEFAULT_EXCEPTION_REPORTER_FILTER="%s.CustomExceptionReporterFilter" % __name__,
)
class CustomExceptionReporterFilterTests(SimpleTestCase):
def setUp(self):
@@ -1602,19 +1717,21 @@ class CustomExceptionReporterFilterTests(SimpleTestCase):
def test_cleansed_substitute_override(self):
reporter_filter = get_default_exception_reporter_filter()
self.assertEqual(
- reporter_filter.cleanse_setting('password', 'super_secret'),
+ reporter_filter.cleanse_setting("password", "super_secret"),
reporter_filter.cleansed_substitute,
)
def test_hidden_settings_override(self):
reporter_filter = get_default_exception_reporter_filter()
self.assertEqual(
- reporter_filter.cleanse_setting('database_url', 'super_secret'),
+ reporter_filter.cleanse_setting("database_url", "super_secret"),
reporter_filter.cleansed_substitute,
)
-class NonHTMLResponseExceptionReporterFilter(ExceptionReportTestMixin, LoggingCaptureMixin, SimpleTestCase):
+class NonHTMLResponseExceptionReporterFilter(
+ ExceptionReportTestMixin, LoggingCaptureMixin, SimpleTestCase
+):
"""
Sensitive information can be filtered out of error reports.
@@ -1624,7 +1741,8 @@ class NonHTMLResponseExceptionReporterFilter(ExceptionReportTestMixin, LoggingCa
response content because they're not included in these error pages.
Refs #14614.
"""
- rf = RequestFactory(HTTP_ACCEPT='application/json')
+
+ rf = RequestFactory(HTTP_ACCEPT="application/json")
def test_non_sensitive_request(self):
"""
@@ -1665,35 +1783,41 @@ class NonHTMLResponseExceptionReporterFilter(ExceptionReportTestMixin, LoggingCa
the request to bypass the one set in DEFAULT_EXCEPTION_REPORTER_FILTER.
"""
with self.settings(DEBUG=True):
- self.verify_unsafe_response(custom_exception_reporter_filter_view, check_for_vars=False)
+ self.verify_unsafe_response(
+ custom_exception_reporter_filter_view, check_for_vars=False
+ )
with self.settings(DEBUG=False):
- self.verify_unsafe_response(custom_exception_reporter_filter_view, check_for_vars=False)
+ self.verify_unsafe_response(
+ custom_exception_reporter_filter_view, check_for_vars=False
+ )
- @override_settings(DEBUG=True, ROOT_URLCONF='view_tests.urls')
+ @override_settings(DEBUG=True, ROOT_URLCONF="view_tests.urls")
def test_non_html_response_encoding(self):
- response = self.client.get('/raises500/', HTTP_ACCEPT='application/json')
- self.assertEqual(response.headers['Content-Type'], 'text/plain; charset=utf-8')
+ response = self.client.get("/raises500/", HTTP_ACCEPT="application/json")
+ self.assertEqual(response.headers["Content-Type"], "text/plain; charset=utf-8")
class DecoratorsTests(SimpleTestCase):
def test_sensitive_variables_not_called(self):
msg = (
- 'sensitive_variables() must be called to use it as a decorator, '
- 'e.g., use @sensitive_variables(), not @sensitive_variables.'
+ "sensitive_variables() must be called to use it as a decorator, "
+ "e.g., use @sensitive_variables(), not @sensitive_variables."
)
with self.assertRaisesMessage(TypeError, msg):
+
@sensitive_variables
def test_func(password):
pass
def test_sensitive_post_parameters_not_called(self):
msg = (
- 'sensitive_post_parameters() must be called to use it as a '
- 'decorator, e.g., use @sensitive_post_parameters(), not '
- '@sensitive_post_parameters.'
+ "sensitive_post_parameters() must be called to use it as a "
+ "decorator, e.g., use @sensitive_post_parameters(), not "
+ "@sensitive_post_parameters."
)
with self.assertRaisesMessage(TypeError, msg):
+
@sensitive_post_parameters
def test_func(request):
return index_page(request)
diff --git a/tests/view_tests/tests/test_defaults.py b/tests/view_tests/tests/test_defaults.py
index 94255e517c..0c4fc7c7da 100644
--- a/tests/view_tests/tests/test_defaults.py
+++ b/tests/view_tests/tests/test_defaults.py
@@ -6,63 +6,82 @@ from django.template import TemplateDoesNotExist
from django.test import RequestFactory, TestCase
from django.test.utils import override_settings
from django.views.defaults import (
- bad_request, page_not_found, permission_denied, server_error,
+ bad_request,
+ page_not_found,
+ permission_denied,
+ server_error,
)
from ..models import Article, Author, UrlArticle
-@override_settings(ROOT_URLCONF='view_tests.urls')
+@override_settings(ROOT_URLCONF="view_tests.urls")
class DefaultsTests(TestCase):
"""Test django views in django/views/defaults.py"""
+
nonexistent_urls = [
- '/nonexistent_url/', # this is in urls.py
- '/other_nonexistent_url/', # this NOT in urls.py
+ "/nonexistent_url/", # this is in urls.py
+ "/other_nonexistent_url/", # this NOT in urls.py
]
request_factory = RequestFactory()
@classmethod
def setUpTestData(cls):
- author = Author.objects.create(name='Boris')
+ author = Author.objects.create(name="Boris")
Article.objects.create(
- title='Old Article', slug='old_article', author=author,
- date_created=datetime.datetime(2001, 1, 1, 21, 22, 23)
+ title="Old Article",
+ slug="old_article",
+ author=author,
+ date_created=datetime.datetime(2001, 1, 1, 21, 22, 23),
)
Article.objects.create(
- title='Current Article', slug='current_article', author=author,
- date_created=datetime.datetime(2007, 9, 17, 21, 22, 23)
+ title="Current Article",
+ slug="current_article",
+ author=author,
+ date_created=datetime.datetime(2007, 9, 17, 21, 22, 23),
)
Article.objects.create(
- title='Future Article', slug='future_article', author=author,
- date_created=datetime.datetime(3000, 1, 1, 21, 22, 23)
+ title="Future Article",
+ slug="future_article",
+ author=author,
+ date_created=datetime.datetime(3000, 1, 1, 21, 22, 23),
)
cls.urlarticle = UrlArticle.objects.create(
- title='Old Article', slug='old_article', author=author,
- date_created=datetime.datetime(2001, 1, 1, 21, 22, 23)
+ title="Old Article",
+ slug="old_article",
+ author=author,
+ date_created=datetime.datetime(2001, 1, 1, 21, 22, 23),
)
- Site(id=1, domain='testserver', name='testserver').save()
+ Site(id=1, domain="testserver", name="testserver").save()
def test_page_not_found(self):
"A 404 status is returned by the page_not_found view"
for url in self.nonexistent_urls:
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
- self.assertIn(b'<h1>Not Found</h1>', response.content)
+ self.assertIn(b"<h1>Not Found</h1>", response.content)
self.assertIn(
- b'<p>The requested resource was not found on this server.</p>',
+ b"<p>The requested resource was not found on this server.</p>",
response.content,
)
- @override_settings(TEMPLATES=[{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'OPTIONS': {
- 'loaders': [
- ('django.template.loaders.locmem.Loader', {
- '404.html': '{{ csrf_token }}',
- }),
- ],
- },
- }])
+ @override_settings(
+ TEMPLATES=[
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "OPTIONS": {
+ "loaders": [
+ (
+ "django.template.loaders.locmem.Loader",
+ {
+ "404.html": "{{ csrf_token }}",
+ },
+ ),
+ ],
+ },
+ }
+ ]
+ )
def test_csrf_token_in_404(self):
"""
The 404 page should have the csrf_token available in the context
@@ -70,81 +89,94 @@ class DefaultsTests(TestCase):
# See ticket #14565
for url in self.nonexistent_urls:
response = self.client.get(url)
- self.assertNotEqual(response.content, b'NOTPROVIDED')
- self.assertNotEqual(response.content, b'')
+ self.assertNotEqual(response.content, b"NOTPROVIDED")
+ self.assertNotEqual(response.content, b"")
def test_server_error(self):
"The server_error view raises a 500 status"
- response = self.client.get('/server_error/')
- self.assertContains(response, b'<h1>Server Error (500)</h1>', status_code=500)
+ response = self.client.get("/server_error/")
+ self.assertContains(response, b"<h1>Server Error (500)</h1>", status_code=500)
def test_bad_request(self):
- request = self.request_factory.get('/')
+ request = self.request_factory.get("/")
response = bad_request(request, Exception())
- self.assertContains(response, b'<h1>Bad Request (400)</h1>', status_code=400)
-
- @override_settings(TEMPLATES=[{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'OPTIONS': {
- 'loaders': [
- ('django.template.loaders.locmem.Loader', {
- '404.html': 'This is a test template for a 404 error '
- '(path: {{ request_path }}, exception: {{ exception }}).',
- '500.html': 'This is a test template for a 500 error.',
- }),
- ],
- },
- }])
+ self.assertContains(response, b"<h1>Bad Request (400)</h1>", status_code=400)
+
+ @override_settings(
+ TEMPLATES=[
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "OPTIONS": {
+ "loaders": [
+ (
+ "django.template.loaders.locmem.Loader",
+ {
+ "404.html": "This is a test template for a 404 error "
+ "(path: {{ request_path }}, exception: {{ exception }}).",
+ "500.html": "This is a test template for a 500 error.",
+ },
+ ),
+ ],
+ },
+ }
+ ]
+ )
def test_custom_templates(self):
"""
404.html and 500.html templates are picked by their respective handler.
"""
- response = self.client.get('/server_error/')
+ response = self.client.get("/server_error/")
self.assertContains(response, "test template for a 500 error", status_code=500)
- response = self.client.get('/no_such_url/')
- self.assertContains(response, 'path: /no_such_url/', status_code=404)
- self.assertContains(response, 'exception: Resolver404', status_code=404)
- response = self.client.get('/technical404/')
- self.assertContains(response, 'exception: Testing technical 404.', status_code=404)
+ response = self.client.get("/no_such_url/")
+ self.assertContains(response, "path: /no_such_url/", status_code=404)
+ self.assertContains(response, "exception: Resolver404", status_code=404)
+ response = self.client.get("/technical404/")
+ self.assertContains(
+ response, "exception: Testing technical 404.", status_code=404
+ )
def test_get_absolute_url_attributes(self):
"A model can set attributes on the get_absolute_url method"
- self.assertTrue(getattr(UrlArticle.get_absolute_url, 'purge', False),
- 'The attributes of the original get_absolute_url must be added.')
+ self.assertTrue(
+ getattr(UrlArticle.get_absolute_url, "purge", False),
+ "The attributes of the original get_absolute_url must be added.",
+ )
article = UrlArticle.objects.get(pk=self.urlarticle.pk)
- self.assertTrue(getattr(article.get_absolute_url, 'purge', False),
- 'The attributes of the original get_absolute_url must be added.')
+ self.assertTrue(
+ getattr(article.get_absolute_url, "purge", False),
+ "The attributes of the original get_absolute_url must be added.",
+ )
def test_custom_templates_wrong(self):
"""
Default error views should raise TemplateDoesNotExist when passed a
template that doesn't exist.
"""
- request = self.request_factory.get('/')
+ request = self.request_factory.get("/")
with self.assertRaises(TemplateDoesNotExist):
- bad_request(request, Exception(), template_name='nonexistent')
+ bad_request(request, Exception(), template_name="nonexistent")
with self.assertRaises(TemplateDoesNotExist):
- permission_denied(request, Exception(), template_name='nonexistent')
+ permission_denied(request, Exception(), template_name="nonexistent")
with self.assertRaises(TemplateDoesNotExist):
- page_not_found(request, Http404(), template_name='nonexistent')
+ page_not_found(request, Http404(), template_name="nonexistent")
with self.assertRaises(TemplateDoesNotExist):
- server_error(request, template_name='nonexistent')
+ server_error(request, template_name="nonexistent")
def test_error_pages(self):
- request = self.request_factory.get('/')
+ request = self.request_factory.get("/")
for response, title in (
- (bad_request(request, Exception()), b'Bad Request (400)'),
- (permission_denied(request, Exception()), b'403 Forbidden'),
- (page_not_found(request, Http404()), b'Not Found'),
- (server_error(request), b'Server Error (500)'),
+ (bad_request(request, Exception()), b"Bad Request (400)"),
+ (permission_denied(request, Exception()), b"403 Forbidden"),
+ (page_not_found(request, Http404()), b"Not Found"),
+ (server_error(request), b"Server Error (500)"),
):
with self.subTest(title=title):
- self.assertIn(b'<!doctype html>', response.content)
+ self.assertIn(b"<!doctype html>", response.content)
self.assertIn(b'<html lang="en">', response.content)
- self.assertIn(b'<head>', response.content)
- self.assertIn(b'<title>%s</title>' % title, response.content)
- self.assertIn(b'<body>', response.content)
+ self.assertIn(b"<head>", response.content)
+ self.assertIn(b"<title>%s</title>" % title, response.content)
+ self.assertIn(b"<body>", response.content)
diff --git a/tests/view_tests/tests/test_i18n.py b/tests/view_tests/tests/test_i18n.py
index 26a415ec48..6c8e0f8c91 100644
--- a/tests/view_tests/tests/test_i18n.py
+++ b/tests/view_tests/tests/test_i18n.py
@@ -4,7 +4,10 @@ from os import path
from django.conf import settings
from django.test import (
- RequestFactory, SimpleTestCase, TestCase, modify_settings,
+ RequestFactory,
+ SimpleTestCase,
+ TestCase,
+ modify_settings,
override_settings,
)
from django.test.selenium import SeleniumTestCase
@@ -15,14 +18,16 @@ from django.views.i18n import JavaScriptCatalog, get_formats
from ..urls import locale_dir
-@override_settings(ROOT_URLCONF='view_tests.urls')
+@override_settings(ROOT_URLCONF="view_tests.urls")
class SetLanguageTests(TestCase):
"""Test the django.views.i18n.set_language view."""
def _get_inactive_language_code(self):
"""Return language code for a language which is not activated."""
current_language = get_language()
- return [code for code, name in settings.LANGUAGES if code != current_language][0]
+ return [code for code, name in settings.LANGUAGES if code != current_language][
+ 0
+ ]
def test_setlang(self):
"""
@@ -31,18 +36,20 @@ class SetLanguageTests(TestCase):
The user is redirected to the 'next' argument if provided.
"""
lang_code = self._get_inactive_language_code()
- post_data = {'language': lang_code, 'next': '/'}
- response = self.client.post('/i18n/setlang/', post_data, HTTP_REFERER='/i_should_not_be_used/')
- self.assertRedirects(response, '/')
+ post_data = {"language": lang_code, "next": "/"}
+ response = self.client.post(
+ "/i18n/setlang/", post_data, HTTP_REFERER="/i_should_not_be_used/"
+ )
+ self.assertRedirects(response, "/")
# The language is set in a cookie.
language_cookie = self.client.cookies[settings.LANGUAGE_COOKIE_NAME]
self.assertEqual(language_cookie.value, lang_code)
- self.assertEqual(language_cookie['domain'], '')
- self.assertEqual(language_cookie['path'], '/')
- self.assertEqual(language_cookie['max-age'], '')
- self.assertEqual(language_cookie['httponly'], '')
- self.assertEqual(language_cookie['samesite'], '')
- self.assertEqual(language_cookie['secure'], '')
+ self.assertEqual(language_cookie["domain"], "")
+ self.assertEqual(language_cookie["path"], "/")
+ self.assertEqual(language_cookie["max-age"], "")
+ self.assertEqual(language_cookie["httponly"], "")
+ self.assertEqual(language_cookie["samesite"], "")
+ self.assertEqual(language_cookie["secure"], "")
def test_setlang_unsafe_next(self):
"""
@@ -50,10 +57,12 @@ class SetLanguageTests(TestCase):
"safe".
"""
lang_code = self._get_inactive_language_code()
- post_data = {'language': lang_code, 'next': '//unsafe/redirection/'}
- response = self.client.post('/i18n/setlang/', data=post_data)
- self.assertEqual(response.url, '/')
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
+ post_data = {"language": lang_code, "next": "//unsafe/redirection/"}
+ response = self.client.post("/i18n/setlang/", data=post_data)
+ self.assertEqual(response.url, "/")
+ self.assertEqual(
+ self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code
+ )
def test_setlang_http_next(self):
"""
@@ -61,16 +70,22 @@ class SetLanguageTests(TestCase):
"safe" and its scheme is HTTPS if the request was sent over HTTPS.
"""
lang_code = self._get_inactive_language_code()
- non_https_next_url = 'http://testserver/redirection/'
- post_data = {'language': lang_code, 'next': non_https_next_url}
+ non_https_next_url = "http://testserver/redirection/"
+ post_data = {"language": lang_code, "next": non_https_next_url}
# Insecure URL in POST data.
- response = self.client.post('/i18n/setlang/', data=post_data, secure=True)
- self.assertEqual(response.url, '/')
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
+ response = self.client.post("/i18n/setlang/", data=post_data, secure=True)
+ self.assertEqual(response.url, "/")
+ self.assertEqual(
+ self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code
+ )
# Insecure URL in HTTP referer.
- response = self.client.post('/i18n/setlang/', secure=True, HTTP_REFERER=non_https_next_url)
- self.assertEqual(response.url, '/')
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
+ response = self.client.post(
+ "/i18n/setlang/", secure=True, HTTP_REFERER=non_https_next_url
+ )
+ self.assertEqual(response.url, "/")
+ self.assertEqual(
+ self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code
+ )
def test_setlang_redirect_to_referer(self):
"""
@@ -78,10 +93,12 @@ class SetLanguageTests(TestCase):
there isn't a "next" parameter.
"""
lang_code = self._get_inactive_language_code()
- post_data = {'language': lang_code}
- response = self.client.post('/i18n/setlang/', post_data, HTTP_REFERER='/i18n/')
- self.assertRedirects(response, '/i18n/', fetch_redirect_response=False)
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
+ post_data = {"language": lang_code}
+ response = self.client.post("/i18n/setlang/", post_data, HTTP_REFERER="/i18n/")
+ self.assertRedirects(response, "/i18n/", fetch_redirect_response=False)
+ self.assertEqual(
+ self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code
+ )
def test_setlang_default_redirect(self):
"""
@@ -89,10 +106,12 @@ class SetLanguageTests(TestCase):
"next" parameter.
"""
lang_code = self._get_inactive_language_code()
- post_data = {'language': lang_code}
- response = self.client.post('/i18n/setlang/', post_data)
- self.assertRedirects(response, '/')
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
+ post_data = {"language": lang_code}
+ response = self.client.post("/i18n/setlang/", post_data)
+ self.assertRedirects(response, "/")
+ self.assertEqual(
+ self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code
+ )
def test_setlang_performs_redirect_for_ajax_if_explicitly_requested(self):
"""
@@ -100,10 +119,14 @@ class SetLanguageTests(TestCase):
not accepting HTML response content.
"""
lang_code = self._get_inactive_language_code()
- post_data = {'language': lang_code, 'next': '/'}
- response = self.client.post('/i18n/setlang/', post_data, HTTP_ACCEPT='application/json')
- self.assertRedirects(response, '/')
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
+ post_data = {"language": lang_code, "next": "/"}
+ response = self.client.post(
+ "/i18n/setlang/", post_data, HTTP_ACCEPT="application/json"
+ )
+ self.assertRedirects(response, "/")
+ self.assertEqual(
+ self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code
+ )
def test_setlang_doesnt_perform_a_redirect_to_referer_for_ajax(self):
"""
@@ -111,11 +134,13 @@ class SetLanguageTests(TestCase):
the request doesn't accept HTML response content.
"""
lang_code = self._get_inactive_language_code()
- post_data = {'language': lang_code}
- headers = {'HTTP_REFERER': '/', 'HTTP_ACCEPT': 'application/json'}
- response = self.client.post('/i18n/setlang/', post_data, **headers)
+ post_data = {"language": lang_code}
+ headers = {"HTTP_REFERER": "/", "HTTP_ACCEPT": "application/json"}
+ response = self.client.post("/i18n/setlang/", post_data, **headers)
self.assertEqual(response.status_code, 204)
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
+ self.assertEqual(
+ self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code
+ )
def test_setlang_doesnt_perform_a_default_redirect_for_ajax(self):
"""
@@ -123,10 +148,14 @@ class SetLanguageTests(TestCase):
HTML response content.
"""
lang_code = self._get_inactive_language_code()
- post_data = {'language': lang_code}
- response = self.client.post('/i18n/setlang/', post_data, HTTP_ACCEPT='application/json')
+ post_data = {"language": lang_code}
+ response = self.client.post(
+ "/i18n/setlang/", post_data, HTTP_ACCEPT="application/json"
+ )
self.assertEqual(response.status_code, 204)
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
+ self.assertEqual(
+ self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code
+ )
def test_setlang_unsafe_next_for_ajax(self):
"""
@@ -134,38 +163,42 @@ class SetLanguageTests(TestCase):
not accepting HTML response content.
"""
lang_code = self._get_inactive_language_code()
- post_data = {'language': lang_code, 'next': '//unsafe/redirection/'}
- response = self.client.post('/i18n/setlang/', post_data, HTTP_ACCEPT='application/json')
- self.assertEqual(response.url, '/')
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
+ post_data = {"language": lang_code, "next": "//unsafe/redirection/"}
+ response = self.client.post(
+ "/i18n/setlang/", post_data, HTTP_ACCEPT="application/json"
+ )
+ self.assertEqual(response.url, "/")
+ self.assertEqual(
+ self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code
+ )
def test_setlang_reversal(self):
- self.assertEqual(reverse('set_language'), '/i18n/setlang/')
+ self.assertEqual(reverse("set_language"), "/i18n/setlang/")
def test_setlang_cookie(self):
# we force saving language to a cookie rather than a session
# by excluding session middleware and those which do require it
test_settings = {
- 'MIDDLEWARE': ['django.middleware.common.CommonMiddleware'],
- 'LANGUAGE_COOKIE_NAME': 'mylanguage',
- 'LANGUAGE_COOKIE_AGE': 3600 * 7 * 2,
- 'LANGUAGE_COOKIE_DOMAIN': '.example.com',
- 'LANGUAGE_COOKIE_PATH': '/test/',
- 'LANGUAGE_COOKIE_HTTPONLY': True,
- 'LANGUAGE_COOKIE_SAMESITE': 'Strict',
- 'LANGUAGE_COOKIE_SECURE': True,
+ "MIDDLEWARE": ["django.middleware.common.CommonMiddleware"],
+ "LANGUAGE_COOKIE_NAME": "mylanguage",
+ "LANGUAGE_COOKIE_AGE": 3600 * 7 * 2,
+ "LANGUAGE_COOKIE_DOMAIN": ".example.com",
+ "LANGUAGE_COOKIE_PATH": "/test/",
+ "LANGUAGE_COOKIE_HTTPONLY": True,
+ "LANGUAGE_COOKIE_SAMESITE": "Strict",
+ "LANGUAGE_COOKIE_SECURE": True,
}
with self.settings(**test_settings):
- post_data = {'language': 'pl', 'next': '/views/'}
- response = self.client.post('/i18n/setlang/', data=post_data)
- language_cookie = response.cookies.get('mylanguage')
- self.assertEqual(language_cookie.value, 'pl')
- self.assertEqual(language_cookie['domain'], '.example.com')
- self.assertEqual(language_cookie['path'], '/test/')
- self.assertEqual(language_cookie['max-age'], 3600 * 7 * 2)
- self.assertIs(language_cookie['httponly'], True)
- self.assertEqual(language_cookie['samesite'], 'Strict')
- self.assertIs(language_cookie['secure'], True)
+ post_data = {"language": "pl", "next": "/views/"}
+ response = self.client.post("/i18n/setlang/", data=post_data)
+ language_cookie = response.cookies.get("mylanguage")
+ self.assertEqual(language_cookie.value, "pl")
+ self.assertEqual(language_cookie["domain"], ".example.com")
+ self.assertEqual(language_cookie["path"], "/test/")
+ self.assertEqual(language_cookie["max-age"], 3600 * 7 * 2)
+ self.assertIs(language_cookie["httponly"], True)
+ self.assertEqual(language_cookie["samesite"], "Strict")
+ self.assertIs(language_cookie["secure"], True)
def test_setlang_decodes_http_referer_url(self):
"""
@@ -173,81 +206,104 @@ class SetLanguageTests(TestCase):
encoded query string.
"""
# The URL & view must exist for this to work as a regression test.
- self.assertEqual(reverse('with_parameter', kwargs={'parameter': 'x'}), '/test-setlang/x/')
+ self.assertEqual(
+ reverse("with_parameter", kwargs={"parameter": "x"}), "/test-setlang/x/"
+ )
lang_code = self._get_inactive_language_code()
# %C3%A4 decodes to ä, %26 to &.
- encoded_url = '/test-setlang/%C3%A4/?foo=bar&baz=alpha%26omega'
- response = self.client.post('/i18n/setlang/', {'language': lang_code}, HTTP_REFERER=encoded_url)
+ encoded_url = "/test-setlang/%C3%A4/?foo=bar&baz=alpha%26omega"
+ response = self.client.post(
+ "/i18n/setlang/", {"language": lang_code}, HTTP_REFERER=encoded_url
+ )
self.assertRedirects(response, encoded_url, fetch_redirect_response=False)
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
+ self.assertEqual(
+ self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code
+ )
- @modify_settings(MIDDLEWARE={
- 'append': 'django.middleware.locale.LocaleMiddleware',
- })
+ @modify_settings(
+ MIDDLEWARE={
+ "append": "django.middleware.locale.LocaleMiddleware",
+ }
+ )
def test_lang_from_translated_i18n_pattern(self):
response = self.client.post(
- '/i18n/setlang/', data={'language': 'nl'},
- follow=True, HTTP_REFERER='/en/translated/'
+ "/i18n/setlang/",
+ data={"language": "nl"},
+ follow=True,
+ HTTP_REFERER="/en/translated/",
)
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, 'nl')
- self.assertRedirects(response, '/nl/vertaald/')
+ self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, "nl")
+ self.assertRedirects(response, "/nl/vertaald/")
# And reverse
response = self.client.post(
- '/i18n/setlang/', data={'language': 'en'},
- follow=True, HTTP_REFERER='/nl/vertaald/'
+ "/i18n/setlang/",
+ data={"language": "en"},
+ follow=True,
+ HTTP_REFERER="/nl/vertaald/",
)
- self.assertRedirects(response, '/en/translated/')
+ self.assertRedirects(response, "/en/translated/")
-@override_settings(ROOT_URLCONF='view_tests.urls')
+@override_settings(ROOT_URLCONF="view_tests.urls")
class I18NViewTests(SimpleTestCase):
"""Test django.views.i18n views other than set_language."""
- @override_settings(LANGUAGE_CODE='de')
+
+ @override_settings(LANGUAGE_CODE="de")
def test_get_formats(self):
formats = get_formats()
# Test 3 possible types in get_formats: integer, string, and list.
- self.assertEqual(formats['FIRST_DAY_OF_WEEK'], 1)
- self.assertEqual(formats['DECIMAL_SEPARATOR'], ',')
- self.assertEqual(formats['TIME_INPUT_FORMATS'], ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'])
+ self.assertEqual(formats["FIRST_DAY_OF_WEEK"], 1)
+ self.assertEqual(formats["DECIMAL_SEPARATOR"], ",")
+ self.assertEqual(
+ formats["TIME_INPUT_FORMATS"], ["%H:%M:%S", "%H:%M:%S.%f", "%H:%M"]
+ )
def test_jsi18n(self):
"""The javascript_catalog can be deployed with language settings"""
- for lang_code in ['es', 'fr', 'ru']:
+ for lang_code in ["es", "fr", "ru"]:
with override(lang_code):
- catalog = gettext.translation('djangojs', locale_dir, [lang_code])
- trans_txt = catalog.gettext('this is to be translated')
- response = self.client.get('/jsi18n/')
- self.assertEqual(response.headers['Content-Type'], 'text/javascript; charset="utf-8"')
+ catalog = gettext.translation("djangojs", locale_dir, [lang_code])
+ trans_txt = catalog.gettext("this is to be translated")
+ response = self.client.get("/jsi18n/")
+ self.assertEqual(
+ response.headers["Content-Type"], 'text/javascript; charset="utf-8"'
+ )
# response content must include a line like:
# "this is to be translated": <value of trans_txt Python variable>
# json.dumps() is used to be able to check Unicode strings.
self.assertContains(response, json.dumps(trans_txt), 1)
- if lang_code == 'fr':
+ if lang_code == "fr":
# Message with context (msgctxt)
self.assertContains(response, '"month name\\u0004May": "mai"', 1)
@override_settings(USE_I18N=False)
def test_jsi18n_USE_I18N_False(self):
- response = self.client.get('/jsi18n/')
+ response = self.client.get("/jsi18n/")
# default plural function
- self.assertContains(response, 'django.pluralidx = function(count) { return (count == 1) ? 0 : 1; };')
- self.assertNotContains(response, 'var newcatalog =')
+ self.assertContains(
+ response,
+ "django.pluralidx = function(count) { return (count == 1) ? 0 : 1; };",
+ )
+ self.assertNotContains(response, "var newcatalog =")
def test_jsoni18n(self):
"""
The json_catalog returns the language catalog and settings as JSON.
"""
- with override('de'):
- response = self.client.get('/jsoni18n/')
+ with override("de"):
+ response = self.client.get("/jsoni18n/")
data = json.loads(response.content.decode())
- self.assertIn('catalog', data)
- self.assertIn('formats', data)
- self.assertEqual(data['formats']['TIME_INPUT_FORMATS'], ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'])
- self.assertEqual(data['formats']['FIRST_DAY_OF_WEEK'], 1)
- self.assertIn('plural', data)
- self.assertEqual(data['catalog']['month name\x04May'], 'Mai')
- self.assertIn('DATETIME_FORMAT', data['formats'])
- self.assertEqual(data['plural'], '(n != 1)')
+ self.assertIn("catalog", data)
+ self.assertIn("formats", data)
+ self.assertEqual(
+ data["formats"]["TIME_INPUT_FORMATS"],
+ ["%H:%M:%S", "%H:%M:%S.%f", "%H:%M"],
+ )
+ self.assertEqual(data["formats"]["FIRST_DAY_OF_WEEK"], 1)
+ self.assertIn("plural", data)
+ self.assertEqual(data["catalog"]["month name\x04May"], "Mai")
+ self.assertIn("DATETIME_FORMAT", data["formats"])
+ self.assertEqual(data["plural"], "(n != 1)")
def test_jsi18n_with_missing_en_files(self):
"""
@@ -259,33 +315,33 @@ class I18NViewTests(SimpleTestCase):
languages and you've set settings.LANGUAGE_CODE to some other language
than English.
"""
- with self.settings(LANGUAGE_CODE='es'), override('en-us'):
- response = self.client.get('/jsi18n/')
- self.assertNotContains(response, 'esto tiene que ser traducido')
+ with self.settings(LANGUAGE_CODE="es"), override("en-us"):
+ response = self.client.get("/jsi18n/")
+ self.assertNotContains(response, "esto tiene que ser traducido")
def test_jsoni18n_with_missing_en_files(self):
"""
Same as above for the json_catalog view. Here we also check for the
expected JSON format.
"""
- with self.settings(LANGUAGE_CODE='es'), override('en-us'):
- response = self.client.get('/jsoni18n/')
+ with self.settings(LANGUAGE_CODE="es"), override("en-us"):
+ response = self.client.get("/jsoni18n/")
data = json.loads(response.content.decode())
- self.assertIn('catalog', data)
- self.assertIn('formats', data)
- self.assertIn('plural', data)
- self.assertEqual(data['catalog'], {})
- self.assertIn('DATETIME_FORMAT', data['formats'])
- self.assertIsNone(data['plural'])
+ self.assertIn("catalog", data)
+ self.assertIn("formats", data)
+ self.assertIn("plural", data)
+ self.assertEqual(data["catalog"], {})
+ self.assertIn("DATETIME_FORMAT", data["formats"])
+ self.assertIsNone(data["plural"])
def test_jsi18n_fallback_language(self):
"""
Let's make sure that the fallback language is still working properly
in cases where the selected language cannot be found.
"""
- with self.settings(LANGUAGE_CODE='fr'), override('fi'):
- response = self.client.get('/jsi18n/')
- self.assertContains(response, 'il faut le traduire')
+ with self.settings(LANGUAGE_CODE="fr"), override("fi"):
+ response = self.client.get("/jsi18n/")
+ self.assertContains(response, "il faut le traduire")
self.assertNotContains(response, "Untranslated string")
def test_i18n_fallback_language_plural(self):
@@ -293,33 +349,33 @@ class I18NViewTests(SimpleTestCase):
The fallback to a language with less plural forms maintains the real
language's number of plural forms and correct translations.
"""
- with self.settings(LANGUAGE_CODE='pt'), override('ru'):
- response = self.client.get('/jsi18n/')
+ with self.settings(LANGUAGE_CODE="pt"), override("ru"):
+ response = self.client.get("/jsi18n/")
self.assertEqual(
- response.context['catalog']['{count} plural3'],
- ['{count} plural3 p3', '{count} plural3 p3s', '{count} plural3 p3t']
+ response.context["catalog"]["{count} plural3"],
+ ["{count} plural3 p3", "{count} plural3 p3s", "{count} plural3 p3t"],
)
self.assertEqual(
- response.context['catalog']['{count} plural2'],
- ['{count} plural2', '{count} plural2s', '']
+ response.context["catalog"]["{count} plural2"],
+ ["{count} plural2", "{count} plural2s", ""],
)
- with self.settings(LANGUAGE_CODE='ru'), override('pt'):
- response = self.client.get('/jsi18n/')
+ with self.settings(LANGUAGE_CODE="ru"), override("pt"):
+ response = self.client.get("/jsi18n/")
self.assertEqual(
- response.context['catalog']['{count} plural3'],
- ['{count} plural3', '{count} plural3s']
+ response.context["catalog"]["{count} plural3"],
+ ["{count} plural3", "{count} plural3s"],
)
self.assertEqual(
- response.context['catalog']['{count} plural2'],
- ['{count} plural2', '{count} plural2s']
+ response.context["catalog"]["{count} plural2"],
+ ["{count} plural2", "{count} plural2s"],
)
def test_i18n_english_variant(self):
- with override('en-gb'):
- response = self.client.get('/jsi18n/')
+ with override("en-gb"):
+ response = self.client.get("/jsi18n/")
self.assertIn(
'"this color is to be translated": "this colour is to be translated"',
- response.context['catalog_str']
+ response.context["catalog_str"],
)
def test_i18n_language_non_english_default(self):
@@ -329,46 +385,46 @@ class I18NViewTests(SimpleTestCase):
is English and there is not 'en' translation available. See #13388,
#3594 and #13726 for more details.
"""
- with self.settings(LANGUAGE_CODE='fr'), override('en-us'):
- response = self.client.get('/jsi18n/')
- self.assertNotContains(response, 'Choisir une heure')
+ with self.settings(LANGUAGE_CODE="fr"), override("en-us"):
+ response = self.client.get("/jsi18n/")
+ self.assertNotContains(response, "Choisir une heure")
- @modify_settings(INSTALLED_APPS={'append': 'view_tests.app0'})
+ @modify_settings(INSTALLED_APPS={"append": "view_tests.app0"})
def test_non_english_default_english_userpref(self):
"""
Same as above with the difference that there IS an 'en' translation
available. The JavaScript i18n view must return a NON empty language catalog
with the proper English translations. See #13726 for more details.
"""
- with self.settings(LANGUAGE_CODE='fr'), override('en-us'):
- response = self.client.get('/jsi18n_english_translation/')
- self.assertContains(response, 'this app0 string is to be translated')
+ with self.settings(LANGUAGE_CODE="fr"), override("en-us"):
+ response = self.client.get("/jsi18n_english_translation/")
+ self.assertContains(response, "this app0 string is to be translated")
def test_i18n_language_non_english_fallback(self):
"""
Makes sure that the fallback language is still working properly
in cases where the selected language cannot be found.
"""
- with self.settings(LANGUAGE_CODE='fr'), override('none'):
- response = self.client.get('/jsi18n/')
- self.assertContains(response, 'Choisir une heure')
+ with self.settings(LANGUAGE_CODE="fr"), override("none"):
+ response = self.client.get("/jsi18n/")
+ self.assertContains(response, "Choisir une heure")
def test_escaping(self):
# Force a language via GET otherwise the gettext functions are a noop!
- response = self.client.get('/jsi18n_admin/?language=de')
- self.assertContains(response, '\\x04')
+ response = self.client.get("/jsi18n_admin/?language=de")
+ self.assertContains(response, "\\x04")
- @modify_settings(INSTALLED_APPS={'append': ['view_tests.app5']})
+ @modify_settings(INSTALLED_APPS={"append": ["view_tests.app5"]})
def test_non_BMP_char(self):
"""
Non-BMP characters should not break the javascript_catalog (#21725).
"""
- with self.settings(LANGUAGE_CODE='en-us'), override('fr'):
- response = self.client.get('/jsi18n/app5/')
- self.assertContains(response, 'emoji')
- self.assertContains(response, '\\ud83d\\udca9')
+ with self.settings(LANGUAGE_CODE="en-us"), override("fr"):
+ response = self.client.get("/jsi18n/app5/")
+ self.assertContains(response, "emoji")
+ self.assertContains(response, "\\ud83d\\udca9")
- @modify_settings(INSTALLED_APPS={'append': ['view_tests.app1', 'view_tests.app2']})
+ @modify_settings(INSTALLED_APPS={"append": ["view_tests.app1", "view_tests.app2"]})
def test_i18n_language_english_default(self):
"""
Check if the JavaScript i18n view returns a complete language catalog
@@ -377,69 +433,74 @@ class I18NViewTests(SimpleTestCase):
translations of multiple Python packages is requested. See #13388,
#3594 and #13514 for more details.
"""
- base_trans_string = 'il faut traduire cette cha\\u00eene de caract\\u00e8res de '
- app1_trans_string = base_trans_string + 'app1'
- app2_trans_string = base_trans_string + 'app2'
- with self.settings(LANGUAGE_CODE='en-us'), override('fr'):
- response = self.client.get('/jsi18n_multi_packages1/')
+ base_trans_string = (
+ "il faut traduire cette cha\\u00eene de caract\\u00e8res de "
+ )
+ app1_trans_string = base_trans_string + "app1"
+ app2_trans_string = base_trans_string + "app2"
+ with self.settings(LANGUAGE_CODE="en-us"), override("fr"):
+ response = self.client.get("/jsi18n_multi_packages1/")
self.assertContains(response, app1_trans_string)
self.assertContains(response, app2_trans_string)
- response = self.client.get('/jsi18n/app1/')
+ response = self.client.get("/jsi18n/app1/")
self.assertContains(response, app1_trans_string)
self.assertNotContains(response, app2_trans_string)
- response = self.client.get('/jsi18n/app2/')
+ response = self.client.get("/jsi18n/app2/")
self.assertNotContains(response, app1_trans_string)
self.assertContains(response, app2_trans_string)
- @modify_settings(INSTALLED_APPS={'append': ['view_tests.app3', 'view_tests.app4']})
+ @modify_settings(INSTALLED_APPS={"append": ["view_tests.app3", "view_tests.app4"]})
def test_i18n_different_non_english_languages(self):
"""
Similar to above but with neither default or requested language being
English.
"""
- with self.settings(LANGUAGE_CODE='fr'), override('es-ar'):
- response = self.client.get('/jsi18n_multi_packages2/')
- self.assertContains(response, 'este texto de app3 debe ser traducido')
+ with self.settings(LANGUAGE_CODE="fr"), override("es-ar"):
+ response = self.client.get("/jsi18n_multi_packages2/")
+ self.assertContains(response, "este texto de app3 debe ser traducido")
def test_i18n_with_locale_paths(self):
extended_locale_paths = settings.LOCALE_PATHS + [
path.join(
path.dirname(path.dirname(path.abspath(__file__))),
- 'app3',
- 'locale',
+ "app3",
+ "locale",
),
]
- with self.settings(LANGUAGE_CODE='es-ar', LOCALE_PATHS=extended_locale_paths):
- with override('es-ar'):
- response = self.client.get('/jsi18n/')
- self.assertContains(response, 'este texto de app3 debe ser traducido')
+ with self.settings(LANGUAGE_CODE="es-ar", LOCALE_PATHS=extended_locale_paths):
+ with override("es-ar"):
+ response = self.client.get("/jsi18n/")
+ self.assertContains(response, "este texto de app3 debe ser traducido")
def test_i18n_unknown_package_error(self):
view = JavaScriptCatalog.as_view()
- request = RequestFactory().get('/')
- msg = 'Invalid package(s) provided to JavaScriptCatalog: unknown_package'
+ request = RequestFactory().get("/")
+ msg = "Invalid package(s) provided to JavaScriptCatalog: unknown_package"
with self.assertRaisesMessage(ValueError, msg):
- view(request, packages='unknown_package')
- msg += ',unknown_package2'
+ view(request, packages="unknown_package")
+ msg += ",unknown_package2"
with self.assertRaisesMessage(ValueError, msg):
- view(request, packages='unknown_package+unknown_package2')
+ view(request, packages="unknown_package+unknown_package2")
-@override_settings(ROOT_URLCONF='view_tests.urls')
+@override_settings(ROOT_URLCONF="view_tests.urls")
class I18nSeleniumTests(SeleniumTestCase):
# The test cases use fixtures & translations from these apps.
available_apps = [
- 'django.contrib.admin', 'django.contrib.auth',
- 'django.contrib.contenttypes', 'view_tests',
+ "django.contrib.admin",
+ "django.contrib.auth",
+ "django.contrib.contenttypes",
+ "view_tests",
]
- @override_settings(LANGUAGE_CODE='de')
+ @override_settings(LANGUAGE_CODE="de")
def test_javascript_gettext(self):
from selenium.webdriver.common.by import By
- self.selenium.get(self.live_server_url + '/jsi18n_template/')
+
+ self.selenium.get(self.live_server_url + "/jsi18n_template/")
elem = self.selenium.find_element(By.ID, "gettext")
self.assertEqual(elem.text, "Entfernen")
elem = self.selenium.find_element(By.ID, "ngettext_sing")
@@ -457,15 +518,20 @@ class I18nSeleniumTests(SeleniumTestCase):
elem = self.selenium.find_element(By.ID, "formats")
self.assertEqual(
elem.text,
- "DATE_INPUT_FORMATS is an object; DECIMAL_SEPARATOR is a string; FIRST_DAY_OF_WEEK is a number;"
+ "DATE_INPUT_FORMATS is an object; DECIMAL_SEPARATOR is a string; FIRST_DAY_OF_WEEK is a number;",
)
- @modify_settings(INSTALLED_APPS={'append': ['view_tests.app1', 'view_tests.app2']})
- @override_settings(LANGUAGE_CODE='fr')
+ @modify_settings(INSTALLED_APPS={"append": ["view_tests.app1", "view_tests.app2"]})
+ @override_settings(LANGUAGE_CODE="fr")
def test_multiple_catalogs(self):
from selenium.webdriver.common.by import By
- self.selenium.get(self.live_server_url + '/jsi18n_multi_catalogs/')
- elem = self.selenium.find_element(By.ID, 'app1string')
- self.assertEqual(elem.text, 'il faut traduire cette chaîne de caractères de app1')
- elem = self.selenium.find_element(By.ID, 'app2string')
- self.assertEqual(elem.text, 'il faut traduire cette chaîne de caractères de app2')
+
+ self.selenium.get(self.live_server_url + "/jsi18n_multi_catalogs/")
+ elem = self.selenium.find_element(By.ID, "app1string")
+ self.assertEqual(
+ elem.text, "il faut traduire cette chaîne de caractères de app1"
+ )
+ elem = self.selenium.find_element(By.ID, "app2string")
+ self.assertEqual(
+ elem.text, "il faut traduire cette chaîne de caractères de app2"
+ )
diff --git a/tests/view_tests/tests/test_json.py b/tests/view_tests/tests/test_json.py
index e1074bf630..145e6e05a4 100644
--- a/tests/view_tests/tests/test_json.py
+++ b/tests/view_tests/tests/test_json.py
@@ -3,17 +3,18 @@ import json
from django.test import SimpleTestCase, override_settings
-@override_settings(ROOT_URLCONF='view_tests.generic_urls')
+@override_settings(ROOT_URLCONF="view_tests.generic_urls")
class JsonResponseTests(SimpleTestCase):
-
def test_json_response(self):
- response = self.client.get('/json/response/')
+ response = self.client.get("/json/response/")
self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.headers["content-type"], "application/json")
self.assertEqual(
- response.headers['content-type'], 'application/json')
- self.assertEqual(json.loads(response.content.decode()), {
- 'a': [1, 2, 3],
- 'foo': {'bar': 'baz'},
- 'timestamp': '2013-05-19T20:00:00',
- 'value': '3.14',
- })
+ json.loads(response.content.decode()),
+ {
+ "a": [1, 2, 3],
+ "foo": {"bar": "baz"},
+ "timestamp": "2013-05-19T20:00:00",
+ "value": "3.14",
+ },
+ )
diff --git a/tests/view_tests/tests/test_specials.py b/tests/view_tests/tests/test_specials.py
index 70ffb1d23e..d1bedf45b9 100644
--- a/tests/view_tests/tests/test_specials.py
+++ b/tests/view_tests/tests/test_specials.py
@@ -1,23 +1,24 @@
from django.test import SimpleTestCase, override_settings
-@override_settings(ROOT_URLCONF='view_tests.generic_urls')
+@override_settings(ROOT_URLCONF="view_tests.generic_urls")
class URLHandling(SimpleTestCase):
"""
Tests for URL handling in views and responses.
"""
+
redirect_target = "/%E4%B8%AD%E6%96%87/target/"
def test_nonascii_redirect(self):
"""
A non-ASCII argument to HttpRedirect is handled properly.
"""
- response = self.client.get('/nonascii_redirect/')
+ response = self.client.get("/nonascii_redirect/")
self.assertRedirects(response, self.redirect_target)
def test_permanent_nonascii_redirect(self):
"""
A non-ASCII argument to HttpPermanentRedirect is handled properly.
"""
- response = self.client.get('/permanent_nonascii_redirect/')
+ response = self.client.get("/permanent_nonascii_redirect/")
self.assertRedirects(response, self.redirect_target, status_code=301)
diff --git a/tests/view_tests/tests/test_static.py b/tests/view_tests/tests/test_static.py
index a5e811e5d6..5ec054bf30 100644
--- a/tests/view_tests/tests/test_static.py
+++ b/tests/view_tests/tests/test_static.py
@@ -14,27 +14,32 @@ from .. import urls
from ..urls import media_dir
-@override_settings(DEBUG=True, ROOT_URLCONF='view_tests.urls')
+@override_settings(DEBUG=True, ROOT_URLCONF="view_tests.urls")
class StaticTests(SimpleTestCase):
"""Tests django views in django/views/static.py"""
- prefix = 'site_media'
+ prefix = "site_media"
def test_serve(self):
"The static view can serve static media"
- media_files = ['file.txt', 'file.txt.gz', '%2F.txt']
+ media_files = ["file.txt", "file.txt.gz", "%2F.txt"]
for filename in media_files:
- response = self.client.get('/%s/%s' % (self.prefix, quote(filename)))
- response_content = b''.join(response)
+ response = self.client.get("/%s/%s" % (self.prefix, quote(filename)))
+ response_content = b"".join(response)
file_path = path.join(media_dir, filename)
- with open(file_path, 'rb') as fp:
+ with open(file_path, "rb") as fp:
self.assertEqual(fp.read(), response_content)
- self.assertEqual(len(response_content), int(response.headers['Content-Length']))
- self.assertEqual(mimetypes.guess_type(file_path)[1], response.get('Content-Encoding', None))
+ self.assertEqual(
+ len(response_content), int(response.headers["Content-Length"])
+ )
+ self.assertEqual(
+ mimetypes.guess_type(file_path)[1],
+ response.get("Content-Encoding", None),
+ )
def test_chunked(self):
"The static view should stream files in chunks to avoid large memory usage"
- response = self.client.get('/%s/%s' % (self.prefix, 'long-line.txt'))
+ response = self.client.get("/%s/%s" % (self.prefix, "long-line.txt"))
first_chunk = next(response.streaming_content)
self.assertEqual(len(first_chunk), FileResponse.block_size)
second_chunk = next(response.streaming_content)
@@ -43,32 +48,32 @@ class StaticTests(SimpleTestCase):
self.assertEqual(len(second_chunk.strip()), 1449)
def test_unknown_mime_type(self):
- response = self.client.get('/%s/file.unknown' % self.prefix)
- self.assertEqual('application/octet-stream', response.headers['Content-Type'])
+ response = self.client.get("/%s/file.unknown" % self.prefix)
+ self.assertEqual("application/octet-stream", response.headers["Content-Type"])
response.close()
def test_copes_with_empty_path_component(self):
- file_name = 'file.txt'
- response = self.client.get('/%s//%s' % (self.prefix, file_name))
- response_content = b''.join(response)
- with open(path.join(media_dir, file_name), 'rb') as fp:
+ file_name = "file.txt"
+ response = self.client.get("/%s//%s" % (self.prefix, file_name))
+ response_content = b"".join(response)
+ with open(path.join(media_dir, file_name), "rb") as fp:
self.assertEqual(fp.read(), response_content)
def test_is_modified_since(self):
- file_name = 'file.txt'
+ file_name = "file.txt"
response = self.client.get(
- '/%s/%s' % (self.prefix, file_name),
- HTTP_IF_MODIFIED_SINCE='Thu, 1 Jan 1970 00:00:00 GMT'
+ "/%s/%s" % (self.prefix, file_name),
+ HTTP_IF_MODIFIED_SINCE="Thu, 1 Jan 1970 00:00:00 GMT",
)
- response_content = b''.join(response)
- with open(path.join(media_dir, file_name), 'rb') as fp:
+ response_content = b"".join(response)
+ with open(path.join(media_dir, file_name), "rb") as fp:
self.assertEqual(fp.read(), response_content)
def test_not_modified_since(self):
- file_name = 'file.txt'
+ file_name = "file.txt"
response = self.client.get(
- '/%s/%s' % (self.prefix, file_name),
- HTTP_IF_MODIFIED_SINCE='Mon, 18 Jan 2038 05:14:07 GMT'
+ "/%s/%s" % (self.prefix, file_name),
+ HTTP_IF_MODIFIED_SINCE="Mon, 18 Jan 2038 05:14:07 GMT"
# This is 24h before max Unix time. Remember to fix Django and
# update this test well before 2038 :)
)
@@ -80,14 +85,15 @@ class StaticTests(SimpleTestCase):
Assume that a file is modified since an invalid timestamp as per RFC
2616, section 14.25.
"""
- file_name = 'file.txt'
- invalid_date = 'Mon, 28 May 999999999999 28:25:26 GMT'
- response = self.client.get('/%s/%s' % (self.prefix, file_name),
- HTTP_IF_MODIFIED_SINCE=invalid_date)
- response_content = b''.join(response)
- with open(path.join(media_dir, file_name), 'rb') as fp:
+ file_name = "file.txt"
+ invalid_date = "Mon, 28 May 999999999999 28:25:26 GMT"
+ response = self.client.get(
+ "/%s/%s" % (self.prefix, file_name), HTTP_IF_MODIFIED_SINCE=invalid_date
+ )
+ response_content = b"".join(response)
+ with open(path.join(media_dir, file_name), "rb") as fp:
self.assertEqual(fp.read(), response_content)
- self.assertEqual(len(response_content), int(response.headers['Content-Length']))
+ self.assertEqual(len(response_content), int(response.headers["Content-Length"]))
def test_invalid_if_modified_since2(self):
"""Handle even more bogus If-Modified-Since values gracefully
@@ -95,75 +101,86 @@ class StaticTests(SimpleTestCase):
Assume that a file is modified since an invalid timestamp as per RFC
2616, section 14.25.
"""
- file_name = 'file.txt'
- invalid_date = ': 1291108438, Wed, 20 Oct 2010 14:05:00 GMT'
- response = self.client.get('/%s/%s' % (self.prefix, file_name),
- HTTP_IF_MODIFIED_SINCE=invalid_date)
- response_content = b''.join(response)
- with open(path.join(media_dir, file_name), 'rb') as fp:
+ file_name = "file.txt"
+ invalid_date = ": 1291108438, Wed, 20 Oct 2010 14:05:00 GMT"
+ response = self.client.get(
+ "/%s/%s" % (self.prefix, file_name), HTTP_IF_MODIFIED_SINCE=invalid_date
+ )
+ response_content = b"".join(response)
+ with open(path.join(media_dir, file_name), "rb") as fp:
self.assertEqual(fp.read(), response_content)
- self.assertEqual(len(response_content), int(response.headers['Content-Length']))
+ self.assertEqual(len(response_content), int(response.headers["Content-Length"]))
def test_404(self):
- response = self.client.get('/%s/nonexistent_resource' % self.prefix)
+ response = self.client.get("/%s/nonexistent_resource" % self.prefix)
self.assertEqual(404, response.status_code)
def test_index(self):
- response = self.client.get('/%s/' % self.prefix)
- self.assertContains(response, 'Index of ./')
+ response = self.client.get("/%s/" % self.prefix)
+ self.assertContains(response, "Index of ./")
# Directories have a trailing slash.
- self.assertIn('subdir/', response.context['file_list'])
+ self.assertIn("subdir/", response.context["file_list"])
def test_index_subdir(self):
- response = self.client.get('/%s/subdir/' % self.prefix)
- self.assertContains(response, 'Index of subdir/')
+ response = self.client.get("/%s/subdir/" % self.prefix)
+ self.assertContains(response, "Index of subdir/")
# File with a leading dot (e.g. .hidden) aren't displayed.
- self.assertEqual(response.context['file_list'], ['visible'])
-
- @override_settings(TEMPLATES=[{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'OPTIONS': {
- 'loaders': [
- ('django.template.loaders.locmem.Loader', {
- 'static/directory_index.html': 'Test index',
- }),
- ],
- },
- }])
+ self.assertEqual(response.context["file_list"], ["visible"])
+
+ @override_settings(
+ TEMPLATES=[
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "OPTIONS": {
+ "loaders": [
+ (
+ "django.template.loaders.locmem.Loader",
+ {
+ "static/directory_index.html": "Test index",
+ },
+ ),
+ ],
+ },
+ }
+ ]
+ )
def test_index_custom_template(self):
- response = self.client.get('/%s/' % self.prefix)
- self.assertEqual(response.content, b'Test index')
+ response = self.client.get("/%s/" % self.prefix)
+ self.assertEqual(response.content, b"Test index")
class StaticHelperTest(StaticTests):
"""
Test case to make sure the static URL pattern helper works as expected
"""
+
def setUp(self):
super().setUp()
self._old_views_urlpatterns = urls.urlpatterns[:]
- urls.urlpatterns += static('media/', document_root=media_dir)
+ urls.urlpatterns += static("media/", document_root=media_dir)
def tearDown(self):
super().tearDown()
urls.urlpatterns = self._old_views_urlpatterns
def test_prefix(self):
- self.assertEqual(static('test')[0].pattern.regex.pattern, '^test(?P<path>.*)$')
+ self.assertEqual(static("test")[0].pattern.regex.pattern, "^test(?P<path>.*)$")
@override_settings(DEBUG=False)
def test_debug_off(self):
"""No URLs are served if DEBUG=False."""
- self.assertEqual(static('test'), [])
+ self.assertEqual(static("test"), [])
def test_empty_prefix(self):
- with self.assertRaisesMessage(ImproperlyConfigured, 'Empty static prefix not permitted'):
- static('')
+ with self.assertRaisesMessage(
+ ImproperlyConfigured, "Empty static prefix not permitted"
+ ):
+ static("")
def test_special_prefix(self):
"""No URLs are served if prefix contains a netloc part."""
- self.assertEqual(static('http://example.org'), [])
- self.assertEqual(static('//example.org'), [])
+ self.assertEqual(static("http://example.org"), [])
+ self.assertEqual(static("//example.org"), [])
class StaticUtilsTests(unittest.TestCase):
diff --git a/tests/view_tests/urls.py b/tests/view_tests/urls.py
index 159f353ee6..cec156b5da 100644
--- a/tests/view_tests/urls.py
+++ b/tests/view_tests/urls.py
@@ -9,70 +9,81 @@ from django.views import defaults, i18n, static
from . import views
base_dir = os.path.dirname(os.path.abspath(__file__))
-media_dir = os.path.join(base_dir, 'media')
-locale_dir = os.path.join(base_dir, 'locale')
+media_dir = os.path.join(base_dir, "media")
+locale_dir = os.path.join(base_dir, "locale")
urlpatterns = [
- path('', views.index_page),
-
+ path("", views.index_page),
# Default views
- path('nonexistent_url/', partial(defaults.page_not_found, exception=None)),
- path('server_error/', defaults.server_error),
-
+ path("nonexistent_url/", partial(defaults.page_not_found, exception=None)),
+ path("server_error/", defaults.server_error),
# a view that raises an exception for the debug view
- path('raises/', views.raises),
-
- path('raises400/', views.raises400),
- path('raises400_bad_request/', views.raises400_bad_request),
- path('raises403/', views.raises403),
- path('raises404/', views.raises404),
- path('raises500/', views.raises500),
- path('custom_reporter_class_view/', views.custom_reporter_class_view),
-
- path('technical404/', views.technical404, name='my404'),
- path('classbased404/', views.Http404View.as_view()),
- path('classbased500/', views.Raises500View.as_view()),
-
+ path("raises/", views.raises),
+ path("raises400/", views.raises400),
+ path("raises400_bad_request/", views.raises400_bad_request),
+ path("raises403/", views.raises403),
+ path("raises404/", views.raises404),
+ path("raises500/", views.raises500),
+ path("custom_reporter_class_view/", views.custom_reporter_class_view),
+ path("technical404/", views.technical404, name="my404"),
+ path("classbased404/", views.Http404View.as_view()),
+ path("classbased500/", views.Raises500View.as_view()),
# i18n views
- path('i18n/', include('django.conf.urls.i18n')),
- path('jsi18n/', i18n.JavaScriptCatalog.as_view(packages=['view_tests'])),
- path('jsi18n/app1/', i18n.JavaScriptCatalog.as_view(packages=['view_tests.app1'])),
- path('jsi18n/app2/', i18n.JavaScriptCatalog.as_view(packages=['view_tests.app2'])),
- path('jsi18n/app5/', i18n.JavaScriptCatalog.as_view(packages=['view_tests.app5'])),
- path('jsi18n_english_translation/', i18n.JavaScriptCatalog.as_view(packages=['view_tests.app0'])),
- path('jsi18n_multi_packages1/',
- i18n.JavaScriptCatalog.as_view(packages=['view_tests.app1', 'view_tests.app2'])),
- path('jsi18n_multi_packages2/',
- i18n.JavaScriptCatalog.as_view(packages=['view_tests.app3', 'view_tests.app4'])),
- path('jsi18n_admin/',
- i18n.JavaScriptCatalog.as_view(packages=['django.contrib.admin', 'view_tests'])),
- path('jsi18n_template/', views.jsi18n),
- path('jsi18n_multi_catalogs/', views.jsi18n_multi_catalogs),
- path('jsoni18n/', i18n.JSONCatalog.as_view(packages=['view_tests'])),
-
+ path("i18n/", include("django.conf.urls.i18n")),
+ path("jsi18n/", i18n.JavaScriptCatalog.as_view(packages=["view_tests"])),
+ path("jsi18n/app1/", i18n.JavaScriptCatalog.as_view(packages=["view_tests.app1"])),
+ path("jsi18n/app2/", i18n.JavaScriptCatalog.as_view(packages=["view_tests.app2"])),
+ path("jsi18n/app5/", i18n.JavaScriptCatalog.as_view(packages=["view_tests.app5"])),
+ path(
+ "jsi18n_english_translation/",
+ i18n.JavaScriptCatalog.as_view(packages=["view_tests.app0"]),
+ ),
+ path(
+ "jsi18n_multi_packages1/",
+ i18n.JavaScriptCatalog.as_view(packages=["view_tests.app1", "view_tests.app2"]),
+ ),
+ path(
+ "jsi18n_multi_packages2/",
+ i18n.JavaScriptCatalog.as_view(packages=["view_tests.app3", "view_tests.app4"]),
+ ),
+ path(
+ "jsi18n_admin/",
+ i18n.JavaScriptCatalog.as_view(packages=["django.contrib.admin", "view_tests"]),
+ ),
+ path("jsi18n_template/", views.jsi18n),
+ path("jsi18n_multi_catalogs/", views.jsi18n_multi_catalogs),
+ path("jsoni18n/", i18n.JSONCatalog.as_view(packages=["view_tests"])),
# Static views
- re_path(r'^site_media/(?P<path>.*)$', static.serve, {'document_root': media_dir, 'show_indexes': True}),
+ re_path(
+ r"^site_media/(?P<path>.*)$",
+ static.serve,
+ {"document_root": media_dir, "show_indexes": True},
+ ),
]
urlpatterns += i18n_patterns(
- re_path(_(r'^translated/$'), views.index_page, name='i18n_prefixed'),
+ re_path(_(r"^translated/$"), views.index_page, name="i18n_prefixed"),
)
urlpatterns += [
path(
- 'safestring_exception/',
+ "safestring_exception/",
views.safestring_in_template_exception,
- name='safestring_exception',
+ name="safestring_exception",
),
- path('template_exception/', views.template_exception, name='template_exception'),
+ path("template_exception/", views.template_exception, name="template_exception"),
path(
- 'raises_template_does_not_exist/<path:path>',
+ "raises_template_does_not_exist/<path:path>",
views.raises_template_does_not_exist,
- name='raises_template_does_not_exist'
+ name="raises_template_does_not_exist",
+ ),
+ path("render_no_template/", views.render_no_template, name="render_no_template"),
+ re_path(
+ r"^test-setlang/(?P<parameter>[^/]+)/$",
+ views.with_parameter,
+ name="with_parameter",
),
- path('render_no_template/', views.render_no_template, name='render_no_template'),
- re_path(r'^test-setlang/(?P<parameter>[^/]+)/$', views.with_parameter, name='with_parameter'),
# Patterns to test the technical 404.
- re_path(r'^regex-post/(?P<pk>[0-9]+)/$', views.index_page, name='regex-post'),
- path('path-post/<int:pk>/', views.index_page, name='path-post'),
+ re_path(r"^regex-post/(?P<pk>[0-9]+)/$", views.index_page, name="regex-post"),
+ path("path-post/<int:pk>/", views.index_page, name="path-post"),
]
diff --git a/tests/view_tests/views.py b/tests/view_tests/views.py
index 8cf9ab4dde..43057af3a1 100644
--- a/tests/view_tests/views.py
+++ b/tests/view_tests/views.py
@@ -4,31 +4,29 @@ import logging
import sys
from pathlib import Path
-from django.core.exceptions import (
- BadRequest, PermissionDenied, SuspiciousOperation,
-)
+from django.core.exceptions import BadRequest, PermissionDenied, SuspiciousOperation
from django.http import Http404, HttpResponse, JsonResponse
from django.shortcuts import render
from django.template import Context, Template, TemplateDoesNotExist
from django.urls import get_resolver
from django.views import View
from django.views.debug import (
- ExceptionReporter, SafeExceptionReporterFilter, technical_500_response,
-)
-from django.views.decorators.debug import (
- sensitive_post_parameters, sensitive_variables,
+ ExceptionReporter,
+ SafeExceptionReporterFilter,
+ technical_500_response,
)
+from django.views.decorators.debug import sensitive_post_parameters, sensitive_variables
-TEMPLATES_PATH = Path(__file__).resolve().parent / 'templates'
+TEMPLATES_PATH = Path(__file__).resolve().parent / "templates"
def index_page(request):
"""Dummy index page"""
- return HttpResponse('<html><body>Dummy page</body></html>')
+ return HttpResponse("<html><body>Dummy page</body></html>")
def with_parameter(request, parameter):
- return HttpResponse('ok')
+ return HttpResponse("ok")
def raises(request):
@@ -36,6 +34,7 @@ def raises(request):
# local vars won't hijack the technical 500 response (#15025).
def callable():
raise Exception
+
try:
raise Exception
except Exception:
@@ -64,7 +63,7 @@ def raises400(request):
def raises400_bad_request(request):
- raise BadRequest('Malformed request syntax')
+ raise BadRequest("Malformed request syntax")
def raises403(request):
@@ -73,7 +72,7 @@ def raises403(request):
def raises404(request):
resolver = get_resolver(None)
- resolver.resolve('/not-in-urls')
+ resolver.resolve("/not-in-urls")
def technical404(request):
@@ -86,7 +85,7 @@ class Http404View(View):
def template_exception(request):
- return render(request, 'debug/template_exception.html')
+ return render(request, "debug/template_exception.html")
def safestring_in_template_exception(request):
@@ -102,14 +101,14 @@ def safestring_in_template_exception(request):
def jsi18n(request):
- return render(request, 'jsi18n.html')
+ return render(request, "jsi18n.html")
def jsi18n_multi_catalogs(request):
- return render(request, 'jsi18n-multi-catalogs.html')
+ return render(request, "jsi18n-multi-catalogs.html")
-def raises_template_does_not_exist(request, path='i_dont_exist.html'):
+def raises_template_does_not_exist(request, path="i_dont_exist.html"):
# We need to inspect the HTML generated by the fancy 500 debug view but
# the test client ignores it, so we send it explicitly.
try:
@@ -125,22 +124,22 @@ def render_no_template(request):
def send_log(request, exc_info):
- logger = logging.getLogger('django')
+ logger = logging.getLogger("django")
# The default logging config has a logging filter to ensure admin emails are
# only sent with DEBUG=False, but since someone might choose to remove that
# filter, we still want to be able to test the behavior of error emails
# with DEBUG=True. So we need to remove the filter temporarily.
admin_email_handler = [
- h for h in logger.handlers
- if h.__class__.__name__ == "AdminEmailHandler"
+ h for h in logger.handlers if h.__class__.__name__ == "AdminEmailHandler"
][0]
orig_filters = admin_email_handler.filters
admin_email_handler.filters = []
admin_email_handler.include_html = True
logger.error(
- 'Internal Server Error: %s', request.path,
+ "Internal Server Error: %s",
+ request.path,
exc_info=exc_info,
- extra={'status_code': 500, 'request': request},
+ extra={"status_code": 500, "request": request},
)
admin_email_handler.filters = orig_filters
@@ -149,8 +148,10 @@ def non_sensitive_view(request):
# Do not just use plain strings for the variables' values in the code
# so that the tests don't return false positives when the function's source
# is displayed in the exception report.
- cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
- sauce = ''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']) # NOQA
+ cooked_eggs = "".join(["s", "c", "r", "a", "m", "b", "l", "e", "d"]) # NOQA
+ sauce = "".join(
+ ["w", "o", "r", "c", "e", "s", "t", "e", "r", "s", "h", "i", "r", "e"]
+ ) # NOQA
try:
raise Exception
except Exception:
@@ -159,14 +160,16 @@ def non_sensitive_view(request):
return technical_500_response(request, *exc_info)
-@sensitive_variables('sauce')
-@sensitive_post_parameters('bacon-key', 'sausage-key')
+@sensitive_variables("sauce")
+@sensitive_post_parameters("bacon-key", "sausage-key")
def sensitive_view(request):
# Do not just use plain strings for the variables' values in the code
# so that the tests don't return false positives when the function's source
# is displayed in the exception report.
- cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
- sauce = ''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']) # NOQA
+ cooked_eggs = "".join(["s", "c", "r", "a", "m", "b", "l", "e", "d"]) # NOQA
+ sauce = "".join(
+ ["w", "o", "r", "c", "e", "s", "t", "e", "r", "s", "h", "i", "r", "e"]
+ ) # NOQA
try:
raise Exception
except Exception:
@@ -181,8 +184,10 @@ def paranoid_view(request):
# Do not just use plain strings for the variables' values in the code
# so that the tests don't return false positives when the function's source
# is displayed in the exception report.
- cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
- sauce = ''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']) # NOQA
+ cooked_eggs = "".join(["s", "c", "r", "a", "m", "b", "l", "e", "d"]) # NOQA
+ sauce = "".join(
+ ["w", "o", "r", "c", "e", "s", "t", "e", "r", "s", "h", "i", "r", "e"]
+ ) # NOQA
try:
raise Exception
except Exception:
@@ -193,37 +198,45 @@ def paranoid_view(request):
def sensitive_args_function_caller(request):
try:
- sensitive_args_function(''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']))
+ sensitive_args_function(
+ "".join(
+ ["w", "o", "r", "c", "e", "s", "t", "e", "r", "s", "h", "i", "r", "e"]
+ )
+ )
except Exception:
exc_info = sys.exc_info()
send_log(request, exc_info)
return technical_500_response(request, *exc_info)
-@sensitive_variables('sauce')
+@sensitive_variables("sauce")
def sensitive_args_function(sauce):
# Do not just use plain strings for the variables' values in the code
# so that the tests don't return false positives when the function's source
# is displayed in the exception report.
- cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
+ cooked_eggs = "".join(["s", "c", "r", "a", "m", "b", "l", "e", "d"]) # NOQA
raise Exception
def sensitive_kwargs_function_caller(request):
try:
- sensitive_kwargs_function(''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']))
+ sensitive_kwargs_function(
+ "".join(
+ ["w", "o", "r", "c", "e", "s", "t", "e", "r", "s", "h", "i", "r", "e"]
+ )
+ )
except Exception:
exc_info = sys.exc_info()
send_log(request, exc_info)
return technical_500_response(request, *exc_info)
-@sensitive_variables('sauce')
+@sensitive_variables("sauce")
def sensitive_kwargs_function(sauce=None):
# Do not just use plain strings for the variables' values in the code
# so that the tests don't return false positives when the function's source
# is displayed in the exception report.
- cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
+ cooked_eggs = "".join(["s", "c", "r", "a", "m", "b", "l", "e", "d"]) # NOQA
raise Exception
@@ -245,8 +258,10 @@ def custom_exception_reporter_filter_view(request):
# Do not just use plain strings for the variables' values in the code
# so that the tests don't return false positives when the function's source
# is displayed in the exception report.
- cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
- sauce = ''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']) # NOQA
+ cooked_eggs = "".join(["s", "c", "r", "a", "m", "b", "l", "e", "d"]) # NOQA
+ sauce = "".join(
+ ["w", "o", "r", "c", "e", "s", "t", "e", "r", "s", "h", "i", "r", "e"]
+ ) # NOQA
request.exception_reporter_filter = UnsafeExceptionReporterFilter()
try:
raise Exception
@@ -257,15 +272,15 @@ def custom_exception_reporter_filter_view(request):
class CustomExceptionReporter(ExceptionReporter):
- custom_traceback_text = 'custom traceback text'
+ custom_traceback_text = "custom traceback text"
def get_traceback_html(self):
return self.custom_traceback_text
class TemplateOverrideExceptionReporter(ExceptionReporter):
- html_template_path = TEMPLATES_PATH / 'my_technical_500.html'
- text_template_path = TEMPLATES_PATH / 'my_technical_500.txt'
+ html_template_path = TEMPLATES_PATH / "my_technical_500.html"
+ text_template_path = TEMPLATES_PATH / "my_technical_500.txt"
def custom_reporter_class_view(request):
@@ -278,14 +293,15 @@ def custom_reporter_class_view(request):
class Klass:
-
- @sensitive_variables('sauce')
+ @sensitive_variables("sauce")
def method(self, request):
# Do not just use plain strings for the variables' values in the code
# so that the tests don't return false positives when the function's
# source is displayed in the exception report.
- cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
- sauce = ''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']) # NOQA
+ cooked_eggs = "".join(["s", "c", "r", "a", "m", "b", "l", "e", "d"]) # NOQA
+ sauce = "".join(
+ ["w", "o", "r", "c", "e", "s", "t", "e", "r", "s", "h", "i", "r", "e"]
+ ) # NOQA
try:
raise Exception
except Exception:
@@ -298,13 +314,15 @@ def sensitive_method_view(request):
return Klass().method(request)
-@sensitive_variables('sauce')
-@sensitive_post_parameters('bacon-key', 'sausage-key')
+@sensitive_variables("sauce")
+@sensitive_post_parameters("bacon-key", "sausage-key")
def multivalue_dict_key_error(request):
- cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd']) # NOQA
- sauce = ''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']) # NOQA
+ cooked_eggs = "".join(["s", "c", "r", "a", "m", "b", "l", "e", "d"]) # NOQA
+ sauce = "".join(
+ ["w", "o", "r", "c", "e", "s", "t", "e", "r", "s", "h", "i", "r", "e"]
+ ) # NOQA
try:
- request.POST['bar']
+ request.POST["bar"]
except Exception:
exc_info = sys.exc_info()
send_log(request, exc_info)
@@ -312,10 +330,12 @@ def multivalue_dict_key_error(request):
def json_response_view(request):
- return JsonResponse({
- 'a': [1, 2, 3],
- 'foo': {'bar': 'baz'},
- # Make sure datetime and Decimal objects would be serialized properly
- 'timestamp': datetime.datetime(2013, 5, 19, 20),
- 'value': decimal.Decimal('3.14'),
- })
+ return JsonResponse(
+ {
+ "a": [1, 2, 3],
+ "foo": {"bar": "baz"},
+ # Make sure datetime and Decimal objects would be serialized properly
+ "timestamp": datetime.datetime(2013, 5, 19, 20),
+ "value": decimal.Decimal("3.14"),
+ }
+ )