diff options
author | Tim Graham <timograham@gmail.com> | 2015-03-06 12:45:53 -0500 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2015-03-30 19:07:17 -0400 |
commit | 845817b039fc059955bb1eafa5fd78565a49159d (patch) | |
tree | 038fa095e76e824f0128d43da829fa9cbaa4cbff /tests | |
parent | b86abbceb9a96d7a0fe18047c8fcd6fca90a2f3e (diff) | |
download | django-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.py | 21 | ||||
-rw-r--r-- | tests/admin_inlines/tests.py | 12 | ||||
-rw-r--r-- | tests/admin_views/tests.py | 25 | ||||
-rw-r--r-- | tests/admin_widgets/tests.py | 14 |
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' ) |