summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2015-03-06 12:45:53 -0500
committerTim Graham <timograham@gmail.com>2015-03-30 19:07:17 -0400
commit845817b039fc059955bb1eafa5fd78565a49159d (patch)
tree038fa095e76e824f0128d43da829fa9cbaa4cbff /tests
parentb86abbceb9a96d7a0fe18047c8fcd6fca90a2f3e (diff)
downloaddjango-845817b039fc059955bb1eafa5fd78565a49159d.tar.gz
Fixed #24466 -- Added JavaScript escaping in a couple places in the admin.
Thanks Aymeric Augustin and Florian Apolloner for work on the patch.
Diffstat (limited to 'tests')
-rw-r--r--tests/admin_inlines/test_templates.py21
-rw-r--r--tests/admin_inlines/tests.py12
-rw-r--r--tests/admin_views/tests.py25
-rw-r--r--tests/admin_widgets/tests.py14
4 files changed, 62 insertions, 10 deletions
diff --git a/tests/admin_inlines/test_templates.py b/tests/admin_inlines/test_templates.py
new file mode 100644
index 0000000000..1ed52c9115
--- /dev/null
+++ b/tests/admin_inlines/test_templates.py
@@ -0,0 +1,21 @@
+from __future__ import unicode_literals
+
+from django.template.loader import render_to_string
+from django.test import SimpleTestCase
+
+
+class TestTemplates(SimpleTestCase):
+ def test_javascript_escaping(self):
+ context = {
+ 'inline_admin_formset': {
+ 'formset': {'prefix': 'my-prefix'},
+ 'opts': {'verbose_name': 'verbose name\\'},
+ },
+ }
+ output = render_to_string('admin/edit_inline/stacked.html', context)
+ self.assertIn('prefix: "my\\u002Dprefix",', output)
+ self.assertIn('addText: "Add another Verbose name\\u005C"', output)
+
+ output = render_to_string('admin/edit_inline/tabular.html', context)
+ self.assertIn('prefix: "my\\u002Dprefix",', output)
+ self.assertIn('addText: "Add another Verbose name\\u005C"', output)
diff --git a/tests/admin_inlines/tests.py b/tests/admin_inlines/tests.py
index c262de7d27..19260baf4d 100644
--- a/tests/admin_inlines/tests.py
+++ b/tests/admin_inlines/tests.py
@@ -78,7 +78,7 @@ class TestInline(TestDataMixin, TestCase):
# The heading for the m2m inline block uses the right text
self.assertContains(response, '<h2>Author-book relationships</h2>')
# The "add another" label is correct
- self.assertContains(response, 'Add another Author-book relationship')
+ self.assertContains(response, 'Add another Author\\u002Dbook relationship')
# The '+' is dropped from the autogenerated form prefix (Author_books+)
self.assertContains(response, 'id="id_Author_books-TOTAL_FORMS"')
@@ -524,7 +524,7 @@ class TestInlinePermissions(TestCase):
response = self.client.get(reverse('admin:admin_inlines_author_add'))
# No change permission on books, so no inline
self.assertNotContains(response, '<h2>Author-book relationships</h2>')
- self.assertNotContains(response, 'Add another Author-Book Relationship')
+ self.assertNotContains(response, 'Add another Author\\u002DBook Relationship')
self.assertNotContains(response, 'id="id_Author_books-TOTAL_FORMS"')
def test_inline_add_fk_noperm(self):
@@ -538,7 +538,7 @@ class TestInlinePermissions(TestCase):
response = self.client.get(self.author_change_url)
# No change permission on books, so no inline
self.assertNotContains(response, '<h2>Author-book relationships</h2>')
- self.assertNotContains(response, 'Add another Author-Book Relationship')
+ self.assertNotContains(response, 'Add another Author\\u002DBook Relationship')
self.assertNotContains(response, 'id="id_Author_books-TOTAL_FORMS"')
def test_inline_change_fk_noperm(self):
@@ -554,7 +554,7 @@ class TestInlinePermissions(TestCase):
response = self.client.get(reverse('admin:admin_inlines_author_add'))
# No change permission on Books, so no inline
self.assertNotContains(response, '<h2>Author-book relationships</h2>')
- self.assertNotContains(response, 'Add another Author-Book Relationship')
+ self.assertNotContains(response, 'Add another Author\\u002DBook Relationship')
self.assertNotContains(response, 'id="id_Author_books-TOTAL_FORMS"')
def test_inline_add_fk_add_perm(self):
@@ -573,7 +573,7 @@ class TestInlinePermissions(TestCase):
response = self.client.get(self.author_change_url)
# No change permission on books, so no inline
self.assertNotContains(response, '<h2>Author-book relationships</h2>')
- self.assertNotContains(response, 'Add another Author-Book Relationship')
+ self.assertNotContains(response, 'Add another Author\\u002DBook Relationship')
self.assertNotContains(response, 'id="id_Author_books-TOTAL_FORMS"')
self.assertNotContains(response, 'id="id_Author_books-0-DELETE"')
@@ -583,7 +583,7 @@ class TestInlinePermissions(TestCase):
response = self.client.get(self.author_change_url)
# We have change perm on books, so we can add/change/delete inlines
self.assertContains(response, '<h2>Author-book relationships</h2>')
- self.assertContains(response, 'Add another Author-book relationship')
+ self.assertContains(response, 'Add another Author\\u002Dbook relationship')
self.assertContains(response, '<input type="hidden" id="id_Author_books-TOTAL_FORMS" '
'value="4" name="Author_books-TOTAL_FORMS" />', html=True)
self.assertContains(response, '<input type="hidden" id="id_Author_books-0-id" '
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index 6bb44c0a8c..8ead8ee93c 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -24,6 +24,7 @@ from django.core.checks import Error
from django.core.files import temp as tempfile
from django.core.urlresolvers import NoReverseMatch, resolve, reverse
from django.forms.utils import ErrorList
+from django.template.loader import render_to_string
from django.template.response import TemplateResponse
from django.test import (
TestCase, modify_settings, override_settings, skipUnlessDBFeature,
@@ -3490,6 +3491,30 @@ action)</option>
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name, 'admin/popup_response.html')
+ def test_popup_template_escaping(self):
+ context = {
+ 'new_value': 'new_value\\',
+ 'obj': 'obj\\',
+ 'value': 'value\\',
+ }
+ output = render_to_string('admin/popup_response.html', context)
+ self.assertIn(
+ 'opener.dismissAddRelatedObjectPopup(window, "value\\u005C", "obj\\u005C");', output
+ )
+
+ context['action'] = 'change'
+ output = render_to_string('admin/popup_response.html', context)
+ self.assertIn(
+ 'opener.dismissChangeRelatedObjectPopup(window, '
+ '"value\\u005C", "obj\\u005C", "new_value\\u005C");', output
+ )
+
+ context['action'] = 'delete'
+ output = render_to_string('admin/popup_response.html', context)
+ self.assertIn(
+ 'opener.dismissDeleteRelatedObjectPopup(window, "value\\u005C");', output
+ )
+
@override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'],
ROOT_URLCONF="admin_views.urls")
diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py
index 5083295c46..1f0ec00eed 100644
--- a/tests/admin_widgets/tests.py
+++ b/tests/admin_widgets/tests.py
@@ -264,17 +264,23 @@ class AdminForeignKeyRawIdWidget(TestDataMixin, DjangoTestCase):
class FilteredSelectMultipleWidgetTest(DjangoTestCase):
def test_render(self):
- w = widgets.FilteredSelectMultiple('test', False)
+ # Backslash in verbose_name to ensure it is JavaScript escaped.
+ w = widgets.FilteredSelectMultiple('test\\', False)
self.assertHTMLEqual(
w.render('test', 'test'),
- '<select multiple="multiple" name="test" class="selectfilter">\n</select><script type="text/javascript">addEvent(window, "load", function(e) {SelectFilter.init("id_test", "test", 0); });</script>\n'
+ '<select multiple="multiple" name="test" class="selectfilter">\n</select>'
+ '<script type="text/javascript">addEvent(window, "load", function(e) '
+ '{SelectFilter.init("id_test", "test\\u005C", 0); });</script>\n'
)
def test_stacked_render(self):
- w = widgets.FilteredSelectMultiple('test', True)
+ # Backslash in verbose_name to ensure it is JavaScript escaped.
+ w = widgets.FilteredSelectMultiple('test\\', True)
self.assertHTMLEqual(
w.render('test', 'test'),
- '<select multiple="multiple" name="test" class="selectfilterstacked">\n</select><script type="text/javascript">addEvent(window, "load", function(e) {SelectFilter.init("id_test", "test", 1); });</script>\n'
+ '<select multiple="multiple" name="test" class="selectfilterstacked">\n</select>'
+ '<script type="text/javascript">addEvent(window, "load", function(e) '
+ '{SelectFilter.init("id_test", "test\\u005C", 1); });</script>\n'
)