From 32e6a7d3a57b2287d55e8b8efa4e8cb7643b1720 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Fri, 6 Feb 2015 23:25:15 +0100 Subject: Replaced hardcoded URLs in admin_* tests Refs #15779. This will allow easier admin URL changes, when needed. Thanks Simon Charette for the review. --- tests/admin_views/customadmin.py | 2 +- tests/admin_views/tests.py | 1195 ++++++++++++++++++++------------------ tests/admin_views/urls.py | 4 +- 3 files changed, 620 insertions(+), 581 deletions(-) (limited to 'tests/admin_views') diff --git a/tests/admin_views/customadmin.py b/tests/admin_views/customadmin.py index 7941b7c897..644bbedae7 100644 --- a/tests/admin_views/customadmin.py +++ b/tests/admin_views/customadmin.py @@ -27,7 +27,7 @@ class Admin2(admin.AdminSite): def get_urls(self): return [ - url(r'^my_view/$', self.admin_view(self.my_view)), + url(r'^my_view/$', self.admin_view(self.my_view), name='my_view'), ] + super(Admin2, self).get_urls() def my_view(self, request): diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 7faa2d4e4f..f4a2bc77e7 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -69,11 +69,6 @@ class AdminViewBasicTestCase(TestCase): fixtures = ['admin-views-users.xml', 'admin-views-colors.xml', 'admin-views-fabrics.xml', 'admin-views-books.xml'] - # Store the bit of the URL where the admin is registered as a class - # variable. That way we can test a second AdminSite just by subclassing - # this test case and changing urlbit. - urlbit = 'admin' - def setUp(self): self.client.login(username='super', password='secret') @@ -95,10 +90,9 @@ class AdminViewBasicTest(AdminViewBasicTestCase): """ If you leave off the trailing slash, app should redirect and add it. """ - response = self.client.get('/test_admin/%s/admin_views/article/add' % self.urlbit) - self.assertRedirects(response, - '/test_admin/%s/admin_views/article/add/' % self.urlbit, - status_code=301) + add_url = reverse('admin:admin_views_article_add') + response = self.client.get(add_url[:-1]) + self.assertRedirects(response, add_url, status_code=301) def test_admin_static_template_tag(self): """ @@ -116,12 +110,12 @@ class AdminViewBasicTest(AdminViewBasicTestCase): """ A smoke test to ensure GET on the add_view works. """ - response = self.client.get('/test_admin/%s/admin_views/section/add/' % self.urlbit) + response = self.client.get(reverse('admin:admin_views_section_add')) self.assertIsInstance(response, TemplateResponse) self.assertEqual(response.status_code, 200) def test_add_with_GET_args(self): - response = self.client.get('/test_admin/%s/admin_views/section/add/' % self.urlbit, {'name': 'My Section'}) + response = self.client.get(reverse('admin:admin_views_section_add'), {'name': 'My Section'}) self.assertEqual(response.status_code, 200) self.assertContains(response, 'value="My Section"', msg_prefix="Couldn't find an input with the right value in the response") @@ -130,7 +124,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): """ A smoke test to ensure GET on the change_view works. """ - response = self.client.get('/test_admin/%s/admin_views/section/1/' % self.urlbit) + response = self.client.get(reverse('admin:admin_views_section_change', args=(1,))) self.assertIsInstance(response, TemplateResponse) self.assertEqual(response.status_code, 200) @@ -140,7 +134,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): #11191) when passing a string as the PK argument for a model with an integer PK field. """ - response = self.client.get('/test_admin/%s/admin_views/section/abc/' % self.urlbit) + response = self.client.get(reverse('admin:admin_views_section_change', args=('abc',))) self.assertEqual(response.status_code, 404) def test_basic_inheritance_GET_string_PK(self): @@ -149,7 +143,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): HTTP 404 error, see #19951) when passing a string as the PK argument for a model with an integer PK field. """ - response = self.client.get('/test_admin/%s/admin_views/supervillain/abc/' % self.urlbit) + response = self.client.get(reverse('admin:admin_views_supervillain_change', args=('abc',))) self.assertEqual(response.status_code, 404) def test_basic_add_POST(self): @@ -163,7 +157,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): "article_set-INITIAL_FORMS": "0", "article_set-MAX_NUM_FORMS": "0", } - response = self.client.post('/test_admin/%s/admin_views/section/add/' % self.urlbit, post_data) + response = self.client.post(reverse('admin:admin_views_section_add'), post_data) self.assertEqual(response.status_code, 302) # redirect somewhere def test_popup_add_POST(self): @@ -177,7 +171,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): 'date_0': '2010-09-10', 'date_1': '14:55:39', } - response = self.client.post('/test_admin/%s/admin_views/article/add/' % self.urlbit, post_data) + response = self.client.post(reverse('admin:admin_views_article_add'), post_data) self.assertEqual(response.status_code, 200) self.assertContains(response, 'dismissAddRelatedObjectPopup') self.assertContains(response, 'title with a new\\u000Aline') @@ -227,7 +221,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): """ A smoke test to ensure POST on edit_view works. """ - response = self.client.post('/test_admin/%s/admin_views/section/1/' % self.urlbit, self.inline_post_data) + response = self.client.post(reverse('admin:admin_views_section_change', args=(1,)), self.inline_post_data) self.assertEqual(response.status_code, 302) # redirect somewhere def test_edit_save_as(self): @@ -243,7 +237,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): "article_set-4-section": "1", "article_set-5-section": "1", }) - response = self.client.post('/test_admin/%s/admin_views/section/1/' % self.urlbit, post_data) + response = self.client.post(reverse('admin:admin_views_section_change', args=(1,)), post_data) self.assertEqual(response.status_code, 302) # redirect somewhere def test_edit_save_as_delete_inline(self): @@ -258,7 +252,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): "article_set-2-DELETE": "1", "article_set-3-section": "1", }) - response = self.client.post('/test_admin/%s/admin_views/section/1/' % self.urlbit, post_data) + response = self.client.post(reverse('admin:admin_views_section_change', args=(1,)), post_data) self.assertEqual(response.status_code, 302) # started with 3 articles, one was deleted. self.assertEqual(Section.objects.latest('id').article_set.count(), 2) @@ -268,7 +262,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): Ensure we can sort on a list_display field that is a callable (column 2 is callable_year in ArticleAdmin) """ - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'o': 2}) + response = self.client.get(reverse('admin:admin_views_article_changelist'), {'o': 2}) self.assertContentBefore(response, 'Oldest content', 'Middle content', "Results of sorting on callable are out of order.") self.assertContentBefore(response, 'Middle content', 'Newest content', @@ -279,7 +273,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): Ensure we can sort on a list_display field that is a Model method (column 3 is 'model_year' in ArticleAdmin) """ - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'o': '-3'}) + response = self.client.get(reverse('admin:admin_views_article_changelist'), {'o': '-3'}) self.assertContentBefore(response, 'Newest content', 'Middle content', "Results of sorting on Model method are out of order.") self.assertContentBefore(response, 'Middle content', 'Oldest content', @@ -290,7 +284,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): Ensure we can sort on a list_display field that is a ModelAdmin method (column 4 is 'modeladmin_year' in ArticleAdmin) """ - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'o': '4'}) + response = self.client.get(reverse('admin:admin_views_article_changelist'), {'o': '4'}) self.assertContentBefore(response, 'Oldest content', 'Middle content', "Results of sorting on ModelAdmin method are out of order.") self.assertContentBefore(response, 'Middle content', 'Newest content', @@ -302,14 +296,14 @@ class AdminViewBasicTest(AdminViewBasicTestCase): method in reverse order (i.e. admin_order_field uses the '-' prefix) (column 6 is 'model_year_reverse' in ArticleAdmin) """ - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'o': '6'}) + response = self.client.get(reverse('admin:admin_views_article_changelist'), {'o': '6'}) self.assertContentBefore(response, '2009', '2008', "Results of sorting on ModelAdmin method are out of order.") self.assertContentBefore(response, '2008', '2000', "Results of sorting on ModelAdmin method are out of order.") # Let's make sure the ordering is right and that we don't get a # FieldError when we change to descending order - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'o': '-6'}) + response = self.client.get(reverse('admin:admin_views_article_changelist'), {'o': '-6'}) self.assertContentBefore(response, '2000', '2008', "Results of sorting on ModelAdmin method are out of order.") self.assertContentBefore(response, '2008', '2009', @@ -324,14 +318,12 @@ class AdminViewBasicTest(AdminViewBasicTestCase): link3 = reverse('admin:admin_views_person_change', args=(p3.pk,)) # Sort by name, gender - # This hard-codes the URL because it'll fail if it runs against the - # 'admin2' custom admin (which doesn't have the Person model). - response = self.client.get('/test_admin/admin/admin_views/person/', {'o': '1.2'}) + response = self.client.get(reverse('admin:admin_views_person_changelist'), {'o': '1.2'}) self.assertContentBefore(response, link3, link1) self.assertContentBefore(response, link1, link2) # Sort by gender descending, name - response = self.client.get('/test_admin/admin/admin_views/person/', {'o': '-2.1'}) + response = self.client.get(reverse('admin:admin_views_person_changelist'), {'o': '-2.1'}) self.assertContentBefore(response, link2, link3) self.assertContentBefore(response, link3, link1) @@ -349,9 +341,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): link2 = reverse('admin:admin_views_person_change', args=(p2.pk,)) link3 = reverse('admin:admin_views_person_change', args=(p3.pk,)) - # This hard-codes the URL because it'll fail if it runs against the - # 'admin2' custom admin (which doesn't have the Person model). - response = self.client.get('/test_admin/admin/admin_views/person/', {}) + response = self.client.get(reverse('admin:admin_views_person_changelist'), {}) self.assertContentBefore(response, link3, link2) self.assertContentBefore(response, link2, link1) @@ -363,11 +353,11 @@ class AdminViewBasicTest(AdminViewBasicTestCase): link1 = reverse('admin:admin_views_language_change', args=(quote(l1.pk),)) link2 = reverse('admin:admin_views_language_change', args=(quote(l2.pk),)) - response = self.client.get('/test_admin/admin/admin_views/language/', {}) + response = self.client.get(reverse('admin:admin_views_language_changelist'), {}) self.assertContentBefore(response, link2, link1) # Test we can override with query string - response = self.client.get('/test_admin/admin/admin_views/language/', {'o': '-1'}) + response = self.client.get(reverse('admin:admin_views_language_changelist'), {'o': '-1'}) self.assertContentBefore(response, link1, link2) def test_change_list_sorting_override_model_admin(self): @@ -378,7 +368,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): link1 = reverse('admin:admin_views_podcast_change', args=(p1.pk,)) link2 = reverse('admin:admin_views_podcast_change', args=(p2.pk,)) - response = self.client.get('/test_admin/admin/admin_views/podcast/', {}) + response = self.client.get(reverse('admin:admin_views_podcast_changelist'), {}) self.assertContentBefore(response, link1, link2) def test_multiple_sort_same_field(self): @@ -390,7 +380,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): link1 = reverse('admin:admin_views_podcast_change', args=(quote(p1.pk),)) link2 = reverse('admin:admin_views_podcast_change', args=(quote(p2.pk),)) - response = self.client.get('/test_admin/admin/admin_views/podcast/', {}) + response = self.client.get(reverse('admin:admin_views_podcast_changelist'), {}) self.assertContentBefore(response, link1, link2) p1 = ComplexSortedPerson.objects.create(name="Bob", age=10) @@ -398,7 +388,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): link1 = reverse('admin:admin_views_complexsortedperson_change', args=(p1.pk,)) link2 = reverse('admin:admin_views_complexsortedperson_change', args=(p2.pk,)) - response = self.client.get('/test_admin/admin/admin_views/complexsortedperson/', {}) + response = self.client.get(reverse('admin:admin_views_complexsortedperson_changelist'), {}) # Should have 5 columns (including action checkbox col) self.assertContains(response, '', msg_prefix="Expected filter not found in changelist view") @@ -449,8 +439,8 @@ class AdminViewBasicTest(AdminViewBasicTestCase): msg_prefix="Changelist filter not correctly limited by limit_choices_to") def test_relation_spanning_filters(self): - response = self.client.get('/test_admin/%s/admin_views/chapterxtra1/' % - self.urlbit) + changelist_url = reverse('admin:admin_views_chapterxtra1_changelist') + response = self.client.get(changelist_url) self.assertEqual(response.status_code, 200) self.assertContains(response, '
') filters = { @@ -479,9 +469,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): # ensure filter link exists self.assertContains(response, '' % query_string) # ensure link works - filtered_response = self.client.get( - '/test_admin/%s/admin_views/chapterxtra1/?%s' % ( - self.urlbit, query_string)) + filtered_response = self.client.get('%s?%s' % (changelist_url, query_string)) self.assertEqual(filtered_response.status_code, 200) # ensure changelist contains only valid objects for obj in filtered_response.context['cl'].queryset.all(): @@ -489,38 +477,40 @@ class AdminViewBasicTest(AdminViewBasicTestCase): def test_incorrect_lookup_parameters(self): """Ensure incorrect lookup parameters are handled gracefully.""" - response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit, {'notarealfield': '5'}) - self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) + changelist_url = reverse('admin:admin_views_thing_changelist') + response = self.client.get(changelist_url, {'notarealfield': '5'}) + self.assertRedirects(response, '%s?e=1' % changelist_url) # Spanning relationships through a nonexistent related object (Refs #16716) - response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit, {'notarealfield__whatever': '5'}) - self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) + response = self.client.get(changelist_url, {'notarealfield__whatever': '5'}) + self.assertRedirects(response, '%s?e=1' % changelist_url) - response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit, {'color__id__exact': 'StringNotInteger!'}) - self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) + response = self.client.get(changelist_url, {'color__id__exact': 'StringNotInteger!'}) + self.assertRedirects(response, '%s?e=1' % changelist_url) # Regression test for #18530 - response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit, {'pub_date__gte': 'foo'}) - self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) + response = self.client.get(changelist_url, {'pub_date__gte': 'foo'}) + self.assertRedirects(response, '%s?e=1' % changelist_url) def test_isnull_lookups(self): """Ensure is_null is handled correctly.""" Article.objects.create(title="I Could Go Anywhere", content="Versatile", date=datetime.datetime.now()) - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit) + changelist_url = reverse('admin:admin_views_article_changelist') + response = self.client.get(changelist_url) self.assertContains(response, '4 articles') - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'section__isnull': 'false'}) + response = self.client.get(changelist_url, {'section__isnull': 'false'}) self.assertContains(response, '3 articles') - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'section__isnull': '0'}) + response = self.client.get(changelist_url, {'section__isnull': '0'}) self.assertContains(response, '3 articles') - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'section__isnull': 'true'}) + response = self.client.get(changelist_url, {'section__isnull': 'true'}) self.assertContains(response, '1 article') - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'section__isnull': '1'}) + response = self.client.get(changelist_url, {'section__isnull': '1'}) self.assertContains(response, '1 article') def test_logout_and_password_change_URLs(self): - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit) - self.assertContains(response, '' % self.urlbit) - self.assertContains(response, '' % self.urlbit) + response = self.client.get(reverse('admin:admin_views_article_changelist')) + self.assertContains(response, '' % reverse('admin:logout')) + self.assertContains(response, '' % reverse('admin:password_change')) def test_named_group_field_choices_change_list(self): """ @@ -528,9 +518,9 @@ class AdminViewBasicTest(AdminViewBasicTestCase): for rows corresponding to instances of a model in which a named group has been used in the choices option of a field. """ - link1 = reverse('admin:admin_views_fabric_change', args=(1,), current_app=self.urlbit) - link2 = reverse('admin:admin_views_fabric_change', args=(2,), current_app=self.urlbit) - response = self.client.get('/test_admin/%s/admin_views/fabric/' % self.urlbit) + link1 = reverse('admin:admin_views_fabric_change', args=(1,)) + link2 = reverse('admin:admin_views_fabric_change', args=(2,)) + response = self.client.get(reverse('admin:admin_views_fabric_changelist')) fail_msg = "Changelist table isn't showing the right human-readable values set by a model field 'choices' option named group." self.assertContains(response, 'Horizontal' % link1, msg_prefix=fail_msg, html=True) self.assertContains(response, 'Vertical' % link2, msg_prefix=fail_msg, html=True) @@ -540,7 +530,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): Ensures the filter UI shows correctly when at least one named group has been used in the choices option of a model field. """ - response = self.client.get('/test_admin/%s/admin_views/fabric/' % self.urlbit) + response = self.client.get(reverse('admin:admin_views_fabric_changelist')) fail_msg = "Changelist filter isn't showing options contained inside a model field 'choices' option named group." self.assertContains(response, '
') self.assertContains(response, @@ -550,10 +540,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): def test_change_list_null_boolean_display(self): Post.objects.create(public=None) - # This hard-codes the URl because it'll fail if it runs - # against the 'admin2' custom admin (which doesn't have the - # Post model). - response = self.client.get("/test_admin/admin/admin_views/post/") + response = self.client.get(reverse('admin:admin_views_post_changelist')) self.assertContains(response, 'icon-unknown.gif') def test_i18n_language_non_english_default(self): @@ -563,7 +550,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): is English. See #13388 and #3594 for more details. """ with self.settings(LANGUAGE_CODE='fr'), translation.override('en-us'): - response = self.client.get('/test_admin/admin/jsi18n/') + response = self.client.get(reverse('admin:jsi18n')) self.assertNotContains(response, 'Choisir une heure') def test_i18n_language_non_english_fallback(self): @@ -572,7 +559,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): in cases where the selected language cannot be found. """ with self.settings(LANGUAGE_CODE='fr'), translation.override('none'): - response = self.client.get('/test_admin/admin/jsi18n/') + response = self.client.get(reverse('admin:jsi18n')) self.assertContains(response, 'Choisir une heure') def test_L10N_deactivated(self): @@ -581,87 +568,91 @@ class AdminViewBasicTest(AdminViewBasicTestCase): return localized date/time formats. Refs #14824. """ with self.settings(LANGUAGE_CODE='ru', USE_L10N=False), translation.override('none'): - response = self.client.get('/test_admin/admin/jsi18n/') + response = self.client.get(reverse('admin:jsi18n')) self.assertNotContains(response, '%d.%m.%Y %H:%M:%S') self.assertContains(response, '%Y-%m-%d %H:%M:%S') def test_disallowed_filtering(self): with patch_logger('django.security.DisallowedModelAdminLookup', 'error') as calls: - response = self.client.get("/test_admin/admin/admin_views/album/?owner__email__startswith=fuzzy") + response = self.client.get( + "%s?owner__email__startswith=fuzzy" % reverse('admin:admin_views_album_changelist') + ) self.assertEqual(response.status_code, 400) self.assertEqual(len(calls), 1) # Filters are allowed if explicitly included in list_filter - response = self.client.get("/test_admin/admin/admin_views/thing/?color__value__startswith=red") + response = self.client.get("%s?color__value__startswith=red" % reverse('admin:admin_views_thing_changelist')) self.assertEqual(response.status_code, 200) - response = self.client.get("/test_admin/admin/admin_views/thing/?color__value=red") + response = self.client.get("%s?color__value=red" % reverse('admin:admin_views_thing_changelist')) self.assertEqual(response.status_code, 200) # Filters should be allowed if they involve a local field without the # need to whitelist them in list_filter or date_hierarchy. - response = self.client.get("/test_admin/admin/admin_views/person/?age__gt=30") + response = self.client.get("%s?age__gt=30" % reverse('admin:admin_views_person_changelist')) self.assertEqual(response.status_code, 200) e1 = Employee.objects.create(name='Anonymous', gender=1, age=22, alive=True, code='123') e2 = Employee.objects.create(name='Visitor', gender=2, age=19, alive=True, code='124') WorkHour.objects.create(datum=datetime.datetime.now(), employee=e1) WorkHour.objects.create(datum=datetime.datetime.now(), employee=e2) - response = self.client.get("/test_admin/admin/admin_views/workhour/") + response = self.client.get(reverse('admin:admin_views_workhour_changelist')) self.assertEqual(response.status_code, 200) self.assertContains(response, 'employee__person_ptr__exact') - response = self.client.get("/test_admin/admin/admin_views/workhour/?employee__person_ptr__exact=%d" % e1.pk) + response = self.client.get("%s?employee__person_ptr__exact=%d" % ( + reverse('admin:admin_views_workhour_changelist'), e1.pk) + ) self.assertEqual(response.status_code, 200) def test_disallowed_to_field(self): with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls: - response = self.client.get("/test_admin/admin/admin_views/section/", {TO_FIELD_VAR: 'missing_field'}) + response = self.client.get(reverse('admin:admin_views_section_changelist'), {TO_FIELD_VAR: 'missing_field'}) self.assertEqual(response.status_code, 400) self.assertEqual(len(calls), 1) # Specifying a field that is not referred by any other model registered # to this admin site should raise an exception. with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls: - response = self.client.get("/test_admin/admin/admin_views/section/", {TO_FIELD_VAR: 'name'}) + response = self.client.get(reverse('admin:admin_views_section_changelist'), {TO_FIELD_VAR: 'name'}) self.assertEqual(response.status_code, 400) self.assertEqual(len(calls), 1) # #23839 - Primary key should always be allowed, even if the referenced model isn't registered. - response = self.client.get("/test_admin/admin/admin_views/notreferenced/", {TO_FIELD_VAR: 'id'}) + response = self.client.get(reverse('admin:admin_views_notreferenced_changelist'), {TO_FIELD_VAR: 'id'}) self.assertEqual(response.status_code, 200) # #23915 - Specifying a field referenced by another model though a m2m should be allowed. - response = self.client.get("/test_admin/admin/admin_views/recipe/", {TO_FIELD_VAR: 'rname'}) + response = self.client.get(reverse('admin:admin_views_recipe_changelist'), {TO_FIELD_VAR: 'rname'}) self.assertEqual(response.status_code, 200) # #23604, #23915 - Specifying a field referenced through a reverse m2m relationship should be allowed. - response = self.client.get("/test_admin/admin/admin_views/ingredient/", {TO_FIELD_VAR: 'iname'}) + response = self.client.get(reverse('admin:admin_views_ingredient_changelist'), {TO_FIELD_VAR: 'iname'}) self.assertEqual(response.status_code, 200) # #23329 - Specifying a field that is not referred by any other model directly registered # to this admin site but registered through inheritance should be allowed. - response = self.client.get("/test_admin/admin/admin_views/referencedbyparent/", {TO_FIELD_VAR: 'name'}) + response = self.client.get(reverse('admin:admin_views_referencedbyparent_changelist'), {TO_FIELD_VAR: 'name'}) self.assertEqual(response.status_code, 200) # #23431 - Specifying a field that is only referred to by a inline of a registered # model should be allowed. - response = self.client.get("/test_admin/admin/admin_views/referencedbyinline/", {TO_FIELD_VAR: 'name'}) + response = self.client.get(reverse('admin:admin_views_referencedbyinline_changelist'), {TO_FIELD_VAR: 'name'}) self.assertEqual(response.status_code, 200) # We also want to prevent the add, change, and delete views from # leaking a disallowed field value. with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls: - response = self.client.post("/test_admin/admin/admin_views/section/add/", {TO_FIELD_VAR: 'name'}) + response = self.client.post(reverse('admin:admin_views_section_add'), {TO_FIELD_VAR: 'name'}) self.assertEqual(response.status_code, 400) self.assertEqual(len(calls), 1) section = Section.objects.create() with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls: - response = self.client.post("/test_admin/admin/admin_views/section/%d/" % section.pk, {TO_FIELD_VAR: 'name'}) + response = self.client.post(reverse('admin:admin_views_section_change', args=(section.pk,)), {TO_FIELD_VAR: 'name'}) self.assertEqual(response.status_code, 400) self.assertEqual(len(calls), 1) with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls: - response = self.client.post("/test_admin/admin/admin_views/section/%d/delete/" % section.pk, {TO_FIELD_VAR: 'name'}) + response = self.client.post(reverse('admin:admin_views_section_delete', args=(section.pk,)), {TO_FIELD_VAR: 'name'}) self.assertEqual(response.status_code, 400) self.assertEqual(len(calls), 1) @@ -672,7 +663,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): can break. """ # Filters should be allowed if they are defined on a ForeignKey pointing to this model - response = self.client.get("/test_admin/admin/admin_views/inquisition/?leader__name=Palin&leader__age=27") + response = self.client.get("%s?leader__name=Palin&leader__age=27" % reverse('admin:admin_views_inquisition_changelist')) self.assertEqual(response.status_code, 200) def test_popup_dismiss_related(self): @@ -680,7 +671,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): Regression test for ticket 20664 - ensure the pk is properly quoted. """ actor = Actor.objects.create(name="Palin", age=27) - response = self.client.get("/test_admin/admin/admin_views/actor/?%s" % IS_POPUP_VAR) + response = self.client.get("%s?%s" % (reverse('admin:admin_views_actor_changelist'), IS_POPUP_VAR)) self.assertContains(response, "opener.dismissRelatedLookupPopup(window, '%s')" % actor.pk) def test_hide_change_password(self): @@ -693,7 +684,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): user.set_unusable_password() user.save() - response = self.client.get('/test_admin/admin/') + response = self.client.get(reverse('admin:index')) self.assertNotContains(response, reverse('admin:password_change'), msg_prefix='The "change password" link should not be displayed if a user does not have a usable password.') @@ -704,8 +695,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): Refs #10057. """ instance = UndeletableObject.objects.create(name='foo') - response = self.client.get('/test_admin/%s/admin_views/undeletableobject/%d/' % - (self.urlbit, instance.pk)) + response = self.client.get(reverse('admin:admin_views_undeletableobject_change', args=(instance.pk,))) self.assertNotContains(response, 'deletelink') def test_allows_attributeerror_to_bubble_up(self): @@ -719,7 +709,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): """ Simple.objects.create() with self.assertRaises(AttributeError): - self.client.get('/test_admin/%s/admin_views/simple/' % self.urlbit) + self.client.get(reverse('admin:admin_views_simple_changelist')) def test_changelist_with_no_change_url(self): """ @@ -729,7 +719,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase): Regression test for #20934 """ UnchangeableObject.objects.create() - response = self.client.get('/test_admin/admin/admin_views/unchangeableobject/') + response = self.client.get(reverse('admin:admin_views_unchangeableobject_changelist')) self.assertEqual(response.status_code, 200) # Check the format of the shown object -- shouldn't contain a change link self.assertContains(response, 'UnchangeableObject object', html=True) @@ -817,7 +807,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase): Ensure that the admin/change_form.html template uses block.super in the bodyclass block. """ - response = self.client.get('/test_admin/%s/admin_views/section/add/' % self.urlbit) + response = self.client.get(reverse('admin:admin_views_section_add')) self.assertContains(response, 'bodyclass_consistency_check ') def test_extended_bodyclass_template_change_password(self): @@ -826,7 +816,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase): super in the bodyclass block. """ user = User.objects.get(username='super') - response = self.client.get('/test_admin/%s/auth/user/%s/password/' % (self.urlbit, user.id)) + response = self.client.get(reverse('admin:auth_user_password_change', args=(user.id,))) self.assertContains(response, 'bodyclass_consistency_check ') def test_extended_bodyclass_template_index(self): @@ -834,7 +824,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase): Ensure that the admin/index.html template uses block.super in the bodyclass block. """ - response = self.client.get('/test_admin/%s/' % self.urlbit) + response = self.client.get(reverse('admin:index')) self.assertContains(response, 'bodyclass_consistency_check ') def test_extended_bodyclass_change_list(self): @@ -842,7 +832,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase): Ensure that the admin/change_list.html' template uses block.super in the bodyclass block. """ - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit) + response = self.client.get(reverse('admin:admin_views_article_changelist')) self.assertContains(response, 'bodyclass_consistency_check ') def test_extended_bodyclass_template_login(self): @@ -851,7 +841,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase): bodyclass block. """ self.client.logout() - response = self.client.get('/test_admin/%s/login/' % self.urlbit) + response = self.client.get(reverse('admin:login')) self.assertContains(response, 'bodyclass_consistency_check ') def test_extended_bodyclass_template_delete_confirmation(self): @@ -860,7 +850,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase): block.super in the bodyclass block. """ group = Group.objects.create(name="foogroup") - response = self.client.get('/test_admin/%s/auth/group/%s/delete/' % (self.urlbit, group.id)) + response = self.client.get(reverse('admin:auth_group_delete', args=(group.id,))) self.assertContains(response, 'bodyclass_consistency_check ') def test_extended_bodyclass_template_delete_selected_confirmation(self): @@ -875,7 +865,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase): 'index': '0', '_selected_action': group.id } - response = self.client.post('/test_admin/%s/auth/group/' % (self.urlbit), post_data) + response = self.client.post(reverse('admin:auth_group_changelist'), post_data) self.assertEqual(response.context['site_header'], 'Django administration') self.assertContains(response, 'bodyclass_consistency_check ') @@ -884,7 +874,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase): Ensure that one can use a custom template to render an admin filter. Refs #17515. """ - response = self.client.get("/test_admin/admin/admin_views/color2/") + response = self.client.get(reverse('admin:admin_views_color2_changelist')) self.assertTemplateUsed(response, 'custom_filter_template.html') @@ -892,7 +882,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase): ROOT_URLCONF="admin_views.urls") class AdminViewFormUrlTest(TestCase): fixtures = ["admin-views-users.xml"] - urlbit = "admin3" + current_app = "admin3" def setUp(self): self.client.login(username='super', password='secret') @@ -901,7 +891,9 @@ class AdminViewFormUrlTest(TestCase): """ Tests whether change_view has form_url in response.context """ - response = self.client.get('/test_admin/%s/admin_views/section/1/' % self.urlbit) + response = self.client.get( + reverse('admin:admin_views_section_change', args=(1,), current_app=self.current_app) + ) self.assertIn('form_url', response.context, msg='form_url not present in response.context') self.assertEqual(response.context['form_url'], 'pony') @@ -912,7 +904,10 @@ class AdminViewFormUrlTest(TestCase): Usually, the initial value is set via the GET params. """ - response = self.client.get('/test_admin/%s/admin_views/restaurant/add/' % self.urlbit, {'name': 'test_value'}) + response = self.client.get( + reverse('admin:admin_views_restaurant_add', current_app=self.current_app), + {'name': 'test_value'} + ) # this would be the usual behaviour self.assertNotContains(response, 'value="test_value"') # this is the overridden behaviour @@ -934,8 +929,7 @@ class AdminJavaScriptTest(TestCase): Refs #17521. """ with override_settings(DEBUG=False): - response = self.client.get( - '/test_admin/%s/admin_views/section/add/' % 'admin') + response = self.client.get(reverse('admin:admin_views_section_add')) self.assertNotContains(response, 'jquery.js') self.assertContains(response, 'jquery.min.js') self.assertNotContains(response, 'prepopulate.js') @@ -947,8 +941,7 @@ class AdminJavaScriptTest(TestCase): self.assertNotContains(response, 'inlines.js') self.assertContains(response, 'inlines.min.js') with override_settings(DEBUG=True): - response = self.client.get( - '/test_admin/%s/admin_views/section/add/' % 'admin') + response = self.client.get(reverse('admin:admin_views_section_add')) self.assertContains(response, 'jquery.js') self.assertNotContains(response, 'jquery.min.js') self.assertContains(response, 'prepopulate.js') @@ -972,7 +965,7 @@ class SaveAsTests(TestCase): def test_save_as_duplication(self): """Ensure save as actually creates a new person""" post_data = {'_saveasnew': '', 'name': 'John M', 'gender': 1, 'age': 42} - self.client.post('/test_admin/admin/admin_views/person/1/', post_data) + self.client.post(reverse('admin:admin_views_person_change', args=(1,)), post_data) self.assertEqual(len(Person.objects.filter(name='John M')), 1) self.assertEqual(len(Person.objects.filter(id=1)), 1) @@ -982,24 +975,24 @@ class SaveAsTests(TestCase): invalid data aside save_as_new will not show us a form to overwrite the initial model. """ - response = self.client.get('/test_admin/admin/admin_views/person/1/') + change_url = reverse('admin:admin_views_person_change', args=(1,)) + response = self.client.get(change_url) self.assertTrue(response.context['save_as']) post_data = {'_saveasnew': '', 'name': 'John M', 'gender': 3, 'alive': 'checked'} - response = self.client.post('/test_admin/admin/admin_views/person/1/', post_data) - self.assertEqual(response.context['form_url'], '/test_admin/admin/admin_views/person/add/') + response = self.client.post(change_url, post_data) + self.assertEqual(response.context['form_url'], reverse('admin:admin_views_person_add')) @override_settings(ROOT_URLCONF="admin_views.urls") class CustomModelAdminTest(AdminViewBasicTestCase): - urlbit = "admin2" def test_custom_admin_site_login_form(self): self.client.logout() - response = self.client.get('/test_admin/admin2/', follow=True) + response = self.client.get(reverse('admin2:index'), follow=True) self.assertIsInstance(response, TemplateResponse) self.assertEqual(response.status_code, 200) - login = self.client.post('/test_admin/admin2/login/', { - REDIRECT_FIELD_NAME: '/test_admin/admin2/', + login = self.client.post(reverse('admin2:login'), { + REDIRECT_FIELD_NAME: reverse('admin2:index'), 'username': 'customform', 'password': 'secret', }, follow=True) @@ -1009,20 +1002,20 @@ class CustomModelAdminTest(AdminViewBasicTestCase): def test_custom_admin_site_login_template(self): self.client.logout() - response = self.client.get('/test_admin/admin2/', follow=True) + response = self.client.get(reverse('admin2:index'), follow=True) self.assertIsInstance(response, TemplateResponse) self.assertTemplateUsed(response, 'custom_admin/login.html') self.assertContains(response, 'Hello from a custom login template') def test_custom_admin_site_logout_template(self): - response = self.client.get('/test_admin/admin2/logout/') + response = self.client.get(reverse('admin2:logout')) self.assertIsInstance(response, TemplateResponse) self.assertTemplateUsed(response, 'custom_admin/logout.html') self.assertContains(response, 'Hello from a custom logout template') def test_custom_admin_site_index_view_and_template(self): try: - response = self.client.get('/test_admin/admin2/') + response = self.client.get(reverse('admin2:index')) except TypeError: self.fail('AdminSite.index_template should accept a list of template paths') self.assertIsInstance(response, TemplateResponse) @@ -1030,39 +1023,41 @@ class CustomModelAdminTest(AdminViewBasicTestCase): self.assertContains(response, 'Hello from a custom index template *bar*') def test_custom_admin_site_app_index_view_and_template(self): - response = self.client.get('/test_admin/admin2/admin_views/') + response = self.client.get(reverse('admin2:app_list', args=('admin_views',))) self.assertIsInstance(response, TemplateResponse) self.assertTemplateUsed(response, 'custom_admin/app_index.html') self.assertContains(response, 'Hello from a custom app_index template') def test_custom_admin_site_password_change_template(self): - response = self.client.get('/test_admin/admin2/password_change/') + response = self.client.get(reverse('admin2:password_change')) self.assertIsInstance(response, TemplateResponse) self.assertTemplateUsed(response, 'custom_admin/password_change_form.html') self.assertContains(response, 'Hello from a custom password change form template') def test_custom_admin_site_password_change_with_extra_context(self): - response = self.client.get('/test_admin/admin2/password_change/') + response = self.client.get(reverse('admin2:password_change')) self.assertIsInstance(response, TemplateResponse) self.assertTemplateUsed(response, 'custom_admin/password_change_form.html') self.assertContains(response, 'eggs') def test_custom_admin_site_password_change_done_template(self): - response = self.client.get('/test_admin/admin2/password_change/done/') + response = self.client.get(reverse('admin2:password_change_done')) self.assertIsInstance(response, TemplateResponse) self.assertTemplateUsed(response, 'custom_admin/password_change_done.html') self.assertContains(response, 'Hello from a custom password change done template') def test_custom_admin_site_view(self): self.client.login(username='super', password='secret') - response = self.client.get('/test_admin/%s/my_view/' % self.urlbit) + response = self.client.get(reverse('admin2:my_view')) self.assertEqual(response.content, b"Django is a magical pony!") def test_pwd_change_custom_template(self): self.client.login(username='super', password='secret') su = User.objects.get(username='super') try: - response = self.client.get('/test_admin/admin4/auth/user/%s/password/' % su.pk) + response = self.client.get( + reverse('admin4:auth_user_password_change', args=(su.pk,)) + ) except TypeError: self.fail('ModelAdmin.change_user_password_template should accept a list of template paths') self.assertEqual(response.status_code, 200) @@ -1111,48 +1106,49 @@ class AdminViewPermissionsTest(TestCase): get_permission_codename('delete', Section._meta))) # login POST dicts + self.index_url = reverse('admin:index') self.super_login = { - REDIRECT_FIELD_NAME: '/test_admin/admin/', + REDIRECT_FIELD_NAME: self.index_url, 'username': 'super', 'password': 'secret', } self.super_email_login = { - REDIRECT_FIELD_NAME: '/test_admin/admin/', + REDIRECT_FIELD_NAME: self.index_url, 'username': 'super@example.com', 'password': 'secret', } self.super_email_bad_login = { - REDIRECT_FIELD_NAME: '/test_admin/admin/', + REDIRECT_FIELD_NAME: self.index_url, 'username': 'super@example.com', 'password': 'notsecret', } self.adduser_login = { - REDIRECT_FIELD_NAME: '/test_admin/admin/', + REDIRECT_FIELD_NAME: self.index_url, 'username': 'adduser', 'password': 'secret', } self.changeuser_login = { - REDIRECT_FIELD_NAME: '/test_admin/admin/', + REDIRECT_FIELD_NAME: self.index_url, 'username': 'changeuser', 'password': 'secret', } self.deleteuser_login = { - REDIRECT_FIELD_NAME: '/test_admin/admin/', + REDIRECT_FIELD_NAME: self.index_url, 'username': 'deleteuser', 'password': 'secret', } self.nostaff_login = { - REDIRECT_FIELD_NAME: '/test_admin/has_permission_admin/', + REDIRECT_FIELD_NAME: reverse('has_permission_admin:index'), 'username': 'nostaff', 'password': 'secret', } self.joepublic_login = { - REDIRECT_FIELD_NAME: '/test_admin/admin/', + REDIRECT_FIELD_NAME: self.index_url, 'username': 'joepublic', 'password': 'secret', } self.no_username_login = { - REDIRECT_FIELD_NAME: '/test_admin/admin/', + REDIRECT_FIELD_NAME: self.index_url, 'password': 'secret', } @@ -1164,17 +1160,17 @@ class AdminViewPermissionsTest(TestCase): Unsuccessful attempts will continue to render the login page with a 200 status code. """ - login_url = reverse('admin:login') + '?next=/test_admin/admin/' + login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index')) # Super User - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertEqual(response.status_code, 302) login = self.client.post(login_url, self.super_login) - self.assertRedirects(login, '/test_admin/admin/') + self.assertRedirects(login, self.index_url) self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) # Test if user enters email address - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertEqual(response.status_code, 302) login = self.client.post(login_url, self.super_email_login) self.assertContains(login, ERROR_MESSAGE) @@ -1188,38 +1184,38 @@ class AdminViewPermissionsTest(TestCase): self.assertContains(login, ERROR_MESSAGE) # Add User - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertEqual(response.status_code, 302) login = self.client.post(login_url, self.adduser_login) - self.assertRedirects(login, '/test_admin/admin/') + self.assertRedirects(login, self.index_url) self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) # Change User - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertEqual(response.status_code, 302) login = self.client.post(login_url, self.changeuser_login) - self.assertRedirects(login, '/test_admin/admin/') + self.assertRedirects(login, self.index_url) self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) # Delete User - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertEqual(response.status_code, 302) login = self.client.post(login_url, self.deleteuser_login) - self.assertRedirects(login, '/test_admin/admin/') + self.assertRedirects(login, self.index_url) self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) # Regular User should not be able to login. - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertEqual(response.status_code, 302) login = self.client.post(login_url, self.joepublic_login) self.assertEqual(login.status_code, 200) self.assertContains(login, ERROR_MESSAGE) # Requests without username should not return 500 errors. - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertEqual(response.status_code, 302) login = self.client.post(login_url, self.no_username_login) self.assertEqual(login.status_code, 200) @@ -1228,37 +1224,37 @@ class AdminViewPermissionsTest(TestCase): def test_login_has_permission(self): # Regular User should not be able to login. - response = self.client.get('/test_admin/has_permission_admin/') + response = self.client.get(reverse('has_permission_admin:index')) self.assertEqual(response.status_code, 302) - login = self.client.post('/test_admin/has_permission_admin/login/', self.joepublic_login) + login = self.client.post(reverse('has_permission_admin:login'), self.joepublic_login) self.assertEqual(login.status_code, 200) self.assertContains(login, 'permission denied') # User with permissions should be able to login. - response = self.client.get('/test_admin/has_permission_admin/') + response = self.client.get(reverse('has_permission_admin:index')) self.assertEqual(response.status_code, 302) - login = self.client.post('/test_admin/has_permission_admin/login/', self.nostaff_login) - self.assertRedirects(login, '/test_admin/has_permission_admin/') + login = self.client.post(reverse('has_permission_admin:login'), self.nostaff_login) + self.assertRedirects(login, reverse('has_permission_admin:index')) self.assertFalse(login.context) - self.client.get('/test_admin/has_permission_admin/logout/') + self.client.get(reverse('has_permission_admin:logout')) # Staff should be able to login. - response = self.client.get('/test_admin/has_permission_admin/') + response = self.client.get(reverse('has_permission_admin:index')) self.assertEqual(response.status_code, 302) - login = self.client.post('/test_admin/has_permission_admin/login/', { - REDIRECT_FIELD_NAME: '/test_admin/has_permission_admin/', + login = self.client.post(reverse('has_permission_admin:login'), { + REDIRECT_FIELD_NAME: reverse('has_permission_admin:index'), 'username': 'deleteuser', 'password': 'secret', }) - self.assertRedirects(login, '/test_admin/has_permission_admin/') + self.assertRedirects(login, reverse('has_permission_admin:index')) self.assertFalse(login.context) - self.client.get('/test_admin/has_permission_admin/logout/') + self.client.get(reverse('has_permission_admin:logout')) def test_login_successfully_redirects_to_original_URL(self): - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertEqual(response.status_code, 302) query_string = 'the-answer=42' - redirect_url = '/test_admin/admin/?%s' % query_string + redirect_url = '%s?%s' % (self.index_url, query_string) new_next = {REDIRECT_FIELD_NAME: redirect_url} post_data = self.super_login.copy() post_data.pop(REDIRECT_FIELD_NAME) @@ -1269,14 +1265,14 @@ class AdminViewPermissionsTest(TestCase): def test_double_login_is_not_allowed(self): """Regression test for #19327""" - login_url = reverse('admin:login') + '?next=/test_admin/admin/' + login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index')) - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertEqual(response.status_code, 302) # Establish a valid admin session login = self.client.post(login_url, self.super_login) - self.assertRedirects(login, '/test_admin/admin/') + self.assertRedirects(login, self.index_url) self.assertFalse(login.context) # Logging in with non-admin user fails @@ -1286,67 +1282,67 @@ class AdminViewPermissionsTest(TestCase): # Establish a valid admin session login = self.client.post(login_url, self.super_login) - self.assertRedirects(login, '/test_admin/admin/') + self.assertRedirects(login, self.index_url) self.assertFalse(login.context) # Logging in with admin user while already logged in login = self.client.post(login_url, self.super_login) - self.assertRedirects(login, '/test_admin/admin/') + self.assertRedirects(login, self.index_url) self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) def test_add_view(self): """Test add view restricts access and actually adds items.""" - login_url = reverse('admin:login') + '?next=/test_admin/admin/' + login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index')) add_dict = {'title': 'Døm ikke', 'content': '

great article

', 'date_0': '2008-03-18', 'date_1': '10:54:39', 'section': 1} # Change User should not have access to add articles - self.client.get('/test_admin/admin/') + self.client.get(self.index_url) self.client.post(login_url, self.changeuser_login) # make sure the view removes test cookie self.assertEqual(self.client.session.test_cookie_worked(), False) - response = self.client.get('/test_admin/admin/admin_views/article/add/') + response = self.client.get(reverse('admin:admin_views_article_add')) self.assertEqual(response.status_code, 403) # Try POST just to make sure - post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict) + post = self.client.post(reverse('admin:admin_views_article_add'), add_dict) self.assertEqual(post.status_code, 403) self.assertEqual(Article.objects.all().count(), 3) - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) # Add user may login and POST to add view, then redirect to admin root - self.client.get('/test_admin/admin/') + self.client.get(self.index_url) self.client.post(login_url, self.adduser_login) - addpage = self.client.get('/test_admin/admin/admin_views/article/add/') - change_list_link = '› Articles' + addpage = self.client.get(reverse('admin:admin_views_article_add')) + change_list_link = '› Articles' % reverse('admin:admin_views_article_changelist') self.assertNotContains(addpage, change_list_link, msg_prefix='User restricted to add permission is given link to change list view in breadcrumbs.') - post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict) - self.assertRedirects(post, '/test_admin/admin/') + post = self.client.post(reverse('admin:admin_views_article_add'), add_dict) + self.assertRedirects(post, self.index_url) self.assertEqual(Article.objects.all().count(), 4) self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].subject, 'Greetings from a created object') - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) # Super can add too, but is redirected to the change list view - self.client.get('/test_admin/admin/') + self.client.get(self.index_url) self.client.post(login_url, self.super_login) - addpage = self.client.get('/test_admin/admin/admin_views/article/add/') + addpage = self.client.get(reverse('admin:admin_views_article_add')) self.assertContains(addpage, change_list_link, msg_prefix='Unrestricted user is not given link to change list view in breadcrumbs.') - post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict) - self.assertRedirects(post, '/test_admin/admin/admin_views/article/') + post = self.client.post(reverse('admin:admin_views_article_add'), add_dict) + self.assertRedirects(post, reverse('admin:admin_views_article_changelist')) self.assertEqual(Article.objects.all().count(), 5) - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) # 8509 - if a normal user is already logged in, it is possible # to change user into the superuser without error self.client.login(username='joepublic', password='secret') # Check and make sure that if user expires, data still persists - self.client.get('/test_admin/admin/') + self.client.get(self.index_url) self.client.post(login_url, self.super_login) # make sure the view removes test cookie self.assertEqual(self.client.session.test_cookie_worked(), False) @@ -1354,97 +1350,101 @@ class AdminViewPermissionsTest(TestCase): def test_change_view(self): """Change view should restrict access and allow users to edit items.""" - login_url = reverse('admin:login') + '?next=/test_admin/admin/' + login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index')) change_dict = {'title': 'Ikke fordømt', 'content': '

edited article

', 'date_0': '2008-03-18', 'date_1': '10:54:39', 'section': 1} + article_change_url = reverse('admin:admin_views_article_change', args=(1,)) + article_changelist_url = reverse('admin:admin_views_article_changelist') # add user should not be able to view the list of article or change any of them - self.client.get('/test_admin/admin/') + self.client.get(self.index_url) self.client.post(login_url, self.adduser_login) - response = self.client.get('/test_admin/admin/admin_views/article/') + response = self.client.get(article_changelist_url) self.assertEqual(response.status_code, 403) - response = self.client.get('/test_admin/admin/admin_views/article/1/') + response = self.client.get(article_change_url) self.assertEqual(response.status_code, 403) - post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict) + post = self.client.post(article_change_url, change_dict) self.assertEqual(post.status_code, 403) - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) # change user can view all items and edit them - self.client.get('/test_admin/admin/') + self.client.get(self.index_url) self.client.post(login_url, self.changeuser_login) - response = self.client.get('/test_admin/admin/admin_views/article/') + response = self.client.get(article_changelist_url) self.assertEqual(response.status_code, 200) - response = self.client.get('/test_admin/admin/admin_views/article/1/') + response = self.client.get(article_change_url) self.assertEqual(response.status_code, 200) - post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict) - self.assertRedirects(post, '/test_admin/admin/admin_views/article/') + post = self.client.post(article_change_url, change_dict) + self.assertRedirects(post, article_changelist_url) self.assertEqual(Article.objects.get(pk=1).content, '

edited article

') # one error in form should produce singular error message, multiple errors plural change_dict['title'] = '' - post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict) + post = self.client.post(article_change_url, change_dict) self.assertContains(post, 'Please correct the error below.', msg_prefix='Singular error message not found in response to post with one error') change_dict['content'] = '' - post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict) + post = self.client.post(article_change_url, change_dict) self.assertContains(post, 'Please correct the errors below.', msg_prefix='Plural error message not found in response to post with multiple errors') - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) # Test redirection when using row-level change permissions. Refs #11513. - RowLevelChangePermissionModel.objects.create(id=1, name="odd id") - RowLevelChangePermissionModel.objects.create(id=2, name="even id") + r1 = RowLevelChangePermissionModel.objects.create(id=1, name="odd id") + r2 = RowLevelChangePermissionModel.objects.create(id=2, name="even id") + change_url_1 = reverse('admin:admin_views_rowlevelchangepermissionmodel_change', args=(r1.pk,)) + change_url_2 = reverse('admin:admin_views_rowlevelchangepermissionmodel_change', args=(r2.pk,)) for login_dict in [self.super_login, self.changeuser_login, self.adduser_login, self.deleteuser_login]: self.client.post(login_url, login_dict) - response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/') + response = self.client.get(change_url_1) self.assertEqual(response.status_code, 403) - response = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', {'name': 'changed'}) + response = self.client.post(change_url_1, {'name': 'changed'}) self.assertEqual(RowLevelChangePermissionModel.objects.get(id=1).name, 'odd id') self.assertEqual(response.status_code, 403) - response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/') + response = self.client.get(change_url_2) self.assertEqual(response.status_code, 200) - response = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed'}) + response = self.client.post(change_url_2, {'name': 'changed'}) self.assertEqual(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed') - self.assertRedirects(response, '/test_admin/admin/') - self.client.get('/test_admin/admin/logout/') + self.assertRedirects(response, self.index_url) + self.client.get(reverse('admin:logout')) for login_dict in [self.joepublic_login, self.no_username_login]: self.client.post(login_url, login_dict) - response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', follow=True) + response = self.client.get(change_url_1, follow=True) self.assertEqual(response.status_code, 200) self.assertContains(response, 'login-form') - response = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', {'name': 'changed'}, follow=True) + response = self.client.post(change_url_1, {'name': 'changed'}, follow=True) self.assertEqual(RowLevelChangePermissionModel.objects.get(id=1).name, 'odd id') self.assertEqual(response.status_code, 200) self.assertContains(response, 'login-form') - response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', follow=True) + response = self.client.get(change_url_2, follow=True) self.assertEqual(response.status_code, 200) self.assertContains(response, 'login-form') - response = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed again'}, follow=True) + response = self.client.post(change_url_2, {'name': 'changed again'}, follow=True) self.assertEqual(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed') self.assertEqual(response.status_code, 200) self.assertContains(response, 'login-form') - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) def test_history_view(self): """History view should restrict access.""" - login_url = reverse('admin:login') + '?next=/test_admin/admin/' + login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index')) # add user should not be able to view the list of article or change any of them - self.client.get('/test_admin/admin/') + self.client.get(self.index_url) self.client.post(login_url, self.adduser_login) - response = self.client.get('/test_admin/admin/admin_views/article/1/history/') + response = self.client.get(reverse('admin:admin_views_article_history', args=(1,))) self.assertEqual(response.status_code, 403) - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) # change user can view all items and edit them - self.client.get('/test_admin/admin/') + self.client.get(self.index_url) self.client.post(login_url, self.changeuser_login) - response = self.client.get('/test_admin/admin/admin_views/article/1/history/') + response = self.client.get(reverse('admin:admin_views_article_history', args=(1,))) self.assertEqual(response.status_code, 200) # Test redirection when using row-level change permissions. Refs #11513. @@ -1452,33 +1452,37 @@ class AdminViewPermissionsTest(TestCase): RowLevelChangePermissionModel.objects.create(id=2, name="even id") for login_dict in [self.super_login, self.changeuser_login, self.adduser_login, self.deleteuser_login]: self.client.post(login_url, login_dict) - response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/history/') + response = self.client.get(reverse('admin:admin_views_rowlevelchangepermissionmodel_history', args=(1,))) self.assertEqual(response.status_code, 403) - response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/history/') + response = self.client.get(reverse('admin:admin_views_rowlevelchangepermissionmodel_history', args=(2,))) self.assertEqual(response.status_code, 200) - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) for login_dict in [self.joepublic_login, self.no_username_login]: self.client.post(login_url, login_dict) - response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/history/', follow=True) + response = self.client.get( + reverse('admin:admin_views_rowlevelchangepermissionmodel_history', args=(1,)), follow=True + ) self.assertEqual(response.status_code, 200) self.assertContains(response, 'login-form') - response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/history/', follow=True) + response = self.client.get( + reverse('admin:admin_views_rowlevelchangepermissionmodel_history', args=(2,)), follow=True + ) self.assertEqual(response.status_code, 200) self.assertContains(response, 'login-form') - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) def test_conditionally_show_add_section_link(self): """ The foreign key widget should only show the "add related" button if the user has permission to add that related item. """ - login_url = reverse('admin:login') + '?next=/test_admin/admin/' + login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index')) # Set up and log in user. - url = '/test_admin/admin/admin_views/article/add/' + url = reverse('admin:admin_views_article_add') add_link_text = 'add_id_section' self.client.post(login_url, self.adduser_login) # The user can't add sections yet, so they shouldn't see the "add @@ -1503,7 +1507,7 @@ class AdminViewPermissionsTest(TestCase): login_url = reverse('admin:login') # Set up and log in user. - url = '/test_admin/admin/admin_views/article/add/' + url = reverse('admin:admin_views_article_add') change_link_text = 'change_id_section' self.client.post(login_url, self.adduser_login) # The user can't change sections yet, so they shouldn't see the "change @@ -1530,9 +1534,9 @@ class AdminViewPermissionsTest(TestCase): login_url = reverse('admin:login') # Set up and log in user. - url = '/test_admin/admin/admin_views/article/add/' + url = reverse('admin:admin_views_article_add') delete_link_text = 'delete_id_sub_section' - self.client.get('/test_admin/admin/') + self.client.get(self.index_url) self.client.post(login_url, self.adduser_login) # The user can't delete sections yet, so they shouldn't see the "delete # section" link. @@ -1549,85 +1553,86 @@ class AdminViewPermissionsTest(TestCase): self.assertContains(response, delete_link_text) def test_custom_model_admin_templates(self): - login_url = reverse('admin:login') + '?next=/test_admin/admin/' - self.client.get('/test_admin/admin/') + login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index')) + self.client.get(self.index_url) self.client.post(login_url, self.super_login) # Test custom change list template with custom extra context - response = self.client.get('/test_admin/admin/admin_views/customarticle/') + response = self.client.get(reverse('admin:admin_views_customarticle_changelist')) self.assertContains(response, "var hello = 'Hello!';") self.assertTemplateUsed(response, 'custom_admin/change_list.html') # Test custom add form template - response = self.client.get('/test_admin/admin/admin_views/customarticle/add/') + response = self.client.get(reverse('admin:admin_views_customarticle_add')) self.assertTemplateUsed(response, 'custom_admin/add_form.html') # Add an article so we can test delete, change, and history views - post = self.client.post('/test_admin/admin/admin_views/customarticle/add/', { + post = self.client.post(reverse('admin:admin_views_customarticle_add'), { 'content': '

great article

', 'date_0': '2008-03-18', 'date_1': '10:54:39' }) - self.assertRedirects(post, '/test_admin/admin/admin_views/customarticle/') + self.assertRedirects(post, reverse('admin:admin_views_customarticle_changelist')) self.assertEqual(CustomArticle.objects.all().count(), 1) article_pk = CustomArticle.objects.all()[0].pk # Test custom delete, change, and object history templates # Test custom change form template - response = self.client.get('/test_admin/admin/admin_views/customarticle/%d/' % article_pk) + response = self.client.get(reverse('admin:admin_views_customarticle_change', args=(article_pk,))) self.assertTemplateUsed(response, 'custom_admin/change_form.html') - response = self.client.get('/test_admin/admin/admin_views/customarticle/%d/delete/' % article_pk) + response = self.client.get(reverse('admin:admin_views_customarticle_delete', args=(article_pk,))) self.assertTemplateUsed(response, 'custom_admin/delete_confirmation.html') - response = self.client.post('/test_admin/admin/admin_views/customarticle/', data={ + response = self.client.post(reverse('admin:admin_views_customarticle_changelist'), data={ 'index': 0, 'action': ['delete_selected'], '_selected_action': ['1'], }) self.assertTemplateUsed(response, 'custom_admin/delete_selected_confirmation.html') - response = self.client.get('/test_admin/admin/admin_views/customarticle/%d/history/' % article_pk) + response = self.client.get(reverse('admin:admin_views_customarticle_history', args=(article_pk,))) self.assertTemplateUsed(response, 'custom_admin/object_history.html') - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) def test_delete_view(self): """Delete view should restrict access and actually delete items.""" - login_url = reverse('admin:login') + '?next=/test_admin/admin/' + login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index')) delete_dict = {'post': 'yes'} + delete_url = reverse('admin:admin_views_article_delete', args=(1,)) # add user should not be able to delete articles - self.client.get('/test_admin/admin/') + self.client.get(self.index_url) self.client.post(login_url, self.adduser_login) - response = self.client.get('/test_admin/admin/admin_views/article/1/delete/') + response = self.client.get(delete_url) self.assertEqual(response.status_code, 403) - post = self.client.post('/test_admin/admin/admin_views/article/1/delete/', delete_dict) + post = self.client.post(delete_url, delete_dict) self.assertEqual(post.status_code, 403) self.assertEqual(Article.objects.all().count(), 3) - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) # Delete user can delete - self.client.get('/test_admin/admin/') + self.client.get(self.index_url) self.client.post(login_url, self.deleteuser_login) - response = self.client.get('/test_admin/admin/admin_views/section/1/delete/') + response = self.client.get(reverse('admin:admin_views_section_delete', args=(1,))) self.assertContains(response, "

Summary

") self.assertContains(response, "
  • Articles: 3
  • ") # test response contains link to related Article self.assertContains(response, "admin_views/article/1/") - response = self.client.get('/test_admin/admin/admin_views/article/1/delete/') + response = self.client.get(delete_url) self.assertContains(response, "admin_views/article/1/") self.assertContains(response, "

    Summary

    ") self.assertContains(response, "
  • Articles: 1
  • ") self.assertEqual(response.status_code, 200) - post = self.client.post('/test_admin/admin/admin_views/article/1/delete/', delete_dict) - self.assertRedirects(post, '/test_admin/admin/') + post = self.client.post(delete_url, delete_dict) + self.assertRedirects(post, self.index_url) self.assertEqual(Article.objects.all().count(), 2) self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].subject, 'Greetings from a deleted object') article_ct = ContentType.objects.get_for_model(Article) logged = LogEntry.objects.get(content_type=article_ct, action_flag=DELETION) self.assertEqual(logged.object_id, '1') - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) def test_disabled_permissions_when_logged_in(self): self.client.login(username='super', password='secret') @@ -1635,11 +1640,11 @@ class AdminViewPermissionsTest(TestCase): superuser.is_active = False superuser.save() - response = self.client.get('/test_admin/admin/', follow=True) + response = self.client.get(self.index_url, follow=True) self.assertContains(response, 'id="login-form"') self.assertNotContains(response, 'Log out') - response = self.client.get('/test_admin/admin/secure-view/', follow=True) + response = self.client.get(reverse('secure_view'), follow=True) self.assertContains(response, 'id="login-form"') def test_disabled_staff_permissions_when_logged_in(self): @@ -1648,11 +1653,11 @@ class AdminViewPermissionsTest(TestCase): superuser.is_staff = False superuser.save() - response = self.client.get('/test_admin/admin/', follow=True) + response = self.client.get(self.index_url, follow=True) self.assertContains(response, 'id="login-form"') self.assertNotContains(response, 'Log out') - response = self.client.get('/test_admin/admin/secure-view/', follow=True) + response = self.client.get(reverse('secure_view'), follow=True) self.assertContains(response, 'id="login-form"') def test_app_index_fail_early(self): @@ -1660,7 +1665,7 @@ class AdminViewPermissionsTest(TestCase): If a user has no module perms, avoid iterating over all the modeladmins in the registry. """ - login_url = reverse('admin:login') + '?next=/test_admin/admin/' + login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index')) opts = Article._meta change_user = User.objects.get(username='changeuser') permission = get_perm(Article, get_permission_codename('change', opts)) @@ -1669,12 +1674,12 @@ class AdminViewPermissionsTest(TestCase): # the user has no module permissions, because this module doesn't exist change_user.user_permissions.remove(permission) - response = self.client.get('/test_admin/admin/admin_views/') + response = self.client.get(reverse('admin:app_list', args=('admin_views',))) self.assertEqual(response.status_code, 403) # the user now has module permissions change_user.user_permissions.add(permission) - response = self.client.get('/test_admin/admin/admin_views/') + response = self.client.get(reverse('admin:app_list', args=('admin_views',))) self.assertEqual(response.status_code, 200) def test_shortcut_view_only_available_to_staff(self): @@ -1683,7 +1688,7 @@ class AdminViewPermissionsTest(TestCase): """ model_ctype = ContentType.objects.get_for_model(ModelWithStringPrimaryKey) obj = ModelWithStringPrimaryKey.objects.create(string_pk='foo') - shortcut_url = "/test_admin/admin/r/%s/%s/" % (model_ctype.pk, obj.pk) + shortcut_url = reverse('admin:view_on_site', args=(model_ctype.pk, obj.pk)) # Not logged in: we should see the login page. response = self.client.get(shortcut_url, follow=True) @@ -1703,31 +1708,31 @@ class AdminViewPermissionsTest(TestCase): have any permission for that module (add, change, or delete), so that the module is displayed on the admin index page. """ - login_url = reverse('admin:login') + '?next=/test_admin/admin/' + login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index')) self.client.post(login_url, self.super_login) - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertContains(response, 'admin_views') self.assertContains(response, 'Articles') - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) self.client.post(login_url, self.adduser_login) - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertContains(response, 'admin_views') self.assertContains(response, 'Articles') - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) self.client.post(login_url, self.changeuser_login) - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertContains(response, 'admin_views') self.assertContains(response, 'Articles') - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) self.client.post(login_url, self.deleteuser_login) - response = self.client.get('/test_admin/admin/') + response = self.client.get(self.index_url) self.assertContains(response, 'admin_views') self.assertContains(response, 'Articles') - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) def test_overriding_has_module_permission(self): """ @@ -1735,31 +1740,32 @@ class AdminViewPermissionsTest(TestCase): In this case, it always returns False, so the module should not be displayed on the admin index page for any users. """ - login_url = reverse('admin:login') + '?next=/test_admin/admin7/' + login_url = '%s?next=%s' % (reverse('admin7:login'), reverse('admin7:index')) + index_url = reverse('admin7:index') self.client.post(login_url, self.super_login) - response = self.client.get('/test_admin/admin7/') + response = self.client.get(index_url) self.assertNotContains(response, 'admin_views') self.assertNotContains(response, 'Articles') - self.client.get('/test_admin/admin7/logout/') + self.client.get(reverse('admin7:logout')) self.client.post(login_url, self.adduser_login) - response = self.client.get('/test_admin/admin7/') + response = self.client.get(index_url) self.assertNotContains(response, 'admin_views') self.assertNotContains(response, 'Articles') - self.client.get('/test_admin/admin7/logout/') + self.client.get(reverse('admin7:logout')) self.client.post(login_url, self.changeuser_login) - response = self.client.get('/test_admin/admin7/') + response = self.client.get(index_url) self.assertNotContains(response, 'admin_views') self.assertNotContains(response, 'Articles') - self.client.get('/test_admin/admin7/logout/') + self.client.get(reverse('admin7:logout')) self.client.post(login_url, self.deleteuser_login) - response = self.client.get('/test_admin/admin7/') + response = self.client.get(index_url) self.assertNotContains(response, 'admin_views') self.assertNotContains(response, 'Articles') - self.client.get('/test_admin/admin7/logout/') + self.client.get(reverse('admin7:logout')) @override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'], @@ -1778,19 +1784,19 @@ class AdminViewsNoUrlTest(TestCase): # login POST dict self.changeuser_login = { - REDIRECT_FIELD_NAME: '/test_admin/admin/', + REDIRECT_FIELD_NAME: reverse('admin:index'), 'username': 'changeuser', 'password': 'secret', } def test_no_standard_modeladmin_urls(self): """Admin index views don't break when user's ModelAdmin removes standard urls""" - self.client.get('/test_admin/admin/') + self.client.get(reverse('admin:index')) r = self.client.post(reverse('admin:login'), self.changeuser_login) - r = self.client.get('/test_admin/admin/') + r = self.client.get(reverse('admin:index')) # we shouldn't get a 500 error caused by a NoReverseMatch self.assertEqual(r.status_code, 200) - self.client.get('/test_admin/admin/logout/') + self.client.get(reverse('admin:logout')) @skipUnlessDBFeature('can_defer_constraint_checks') @@ -1807,8 +1813,12 @@ class AdminViewDeletedObjectsTest(TestCase): Objects should be nested to display the relationships that cause them to be scheduled for deletion. """ - pattern = re.compile(br"""
  • Plot: World Domination\s*
      \s*
    • Plot details: almost finished""") - response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(1)) + pattern = re.compile(force_bytes( + r'
    • Plot: World Domination\s*
        \s*
      • Plot details: almost finished' % ( + reverse('admin:admin_views_plot_change', args=(1,)), + reverse('admin:admin_views_plotdetails_change', args=(1,))) + )) + response = self.client.get(reverse('admin:admin_views_villain_delete', args=(1,))) six.assertRegex(self, response.content, pattern) def test_cyclic(self): @@ -1817,9 +1827,13 @@ class AdminViewDeletedObjectsTest(TestCase): listed once. """ - one = """
      • Cyclic one: I am recursive""" - two = """
      • Cyclic two: I am recursive too""" - response = self.client.get('/test_admin/admin/admin_views/cyclicone/%s/delete/' % quote(1)) + one = '
      • Cyclic one: I am recursive' % ( + reverse('admin:admin_views_cyclicone_change', args=(1,)), + ) + two = '
      • Cyclic two: I am recursive too' % ( + reverse('admin:admin_views_cyclictwo_change', args=(1,)), + ) + response = self.client.get(reverse('admin:admin_views_cyclicone_delete', args=(1,))) self.assertContains(response, one, 1) self.assertContains(response, two, 1) @@ -1833,7 +1847,7 @@ class AdminViewDeletedObjectsTest(TestCase): self.assertTrue(self.client.login(username='deleteuser', password='secret')) - response = self.client.get('/test_admin/admin/admin_views/plot/%s/delete/' % quote(1)) + response = self.client.get(reverse('admin:admin_views_plot_delete', args=(1,))) self.assertContains(response, "your account doesn't have permission to delete the following types of objects") self.assertContains(response, "
      • plot details
      • ") @@ -1842,14 +1856,20 @@ class AdminViewDeletedObjectsTest(TestCase): a1 = Answer.objects.create(question=q, answer="Because.") a2 = Answer.objects.create(question=q, answer="Yes.") - response = self.client.get("/test_admin/admin/admin_views/question/%s/delete/" % quote(q.pk)) + response = self.client.get(reverse('admin:admin_views_question_delete', args=(q.pk,))) self.assertContains(response, "would require deleting the following protected related objects") - self.assertContains(response, '
      • Answer: Because.
      • ' % a1.pk) - self.assertContains(response, '
      • Answer: Yes.
      • ' % a2.pk) + self.assertContains( + response, + '
      • Answer: Because.
      • ' % reverse('admin:admin_views_answer_change', args=(a1.pk,)) + ) + self.assertContains( + response, + '
      • Answer: Yes.
      • ' % reverse('admin:admin_views_answer_change', args=(a2.pk,)) + ) def test_not_registered(self): should_contain = """
      • Secret hideout: underground bunker""" - response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(1)) + response = self.client.get(reverse('admin:admin_views_villain_delete', args=(1,))) self.assertContains(response, should_contain, 1) def test_multiple_fkeys_to_same_model(self): @@ -1859,10 +1879,12 @@ class AdminViewDeletedObjectsTest(TestCase): objects to delete. """ - should_contain = """
      • Plot: World Domination""" - response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(1)) + should_contain = '
      • Plot: World Domination' % reverse( + 'admin:admin_views_plot_change', args=(1,) + ) + response = self.client.get(reverse('admin:admin_views_villain_delete', args=(1,))) self.assertContains(response, should_contain) - response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(2)) + response = self.client.get(reverse('admin:admin_views_villain_delete', args=(2,))) self.assertContains(response, should_contain) def test_multiple_fkeys_to_same_instance(self): @@ -1872,8 +1894,10 @@ class AdminViewDeletedObjectsTest(TestCase): once. """ - should_contain = """
      • Plot: World Peace
      • """ - response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(2)) + should_contain = '
      • Plot: World Peace
      • ' % reverse( + 'admin:admin_views_plot_change', args=(2,) + ) + response = self.client.get(reverse('admin:admin_views_villain_delete', args=(2,))) self.assertContains(response, should_contain, 1) def test_inheritance(self): @@ -1884,15 +1908,15 @@ class AdminViewDeletedObjectsTest(TestCase): """ should_contain = [ - """
      • Villain: Bob""", - """
      • Super villain: Bob""", - """
      • Secret hideout: floating castle""", - """
      • Super secret hideout: super floating castle!""" + '
      • Villain: Bob' % reverse('admin:admin_views_villain_change', args=(3,)), + '
      • Super villain: Bob' % reverse('admin:admin_views_supervillain_change', args=(3,)), + '
      • Secret hideout: floating castle', + '
      • Super secret hideout: super floating castle!', ] - response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(3)) + response = self.client.get(reverse('admin:admin_views_villain_delete', args=(3,))) for should in should_contain: self.assertContains(response, should, 1) - response = self.client.get('/test_admin/admin/admin_views/supervillain/%s/delete/' % quote(3)) + response = self.client.get(reverse('admin:admin_views_supervillain_delete', args=(3,))) for should in should_contain: self.assertContains(response, should, 1) @@ -1904,8 +1928,9 @@ class AdminViewDeletedObjectsTest(TestCase): """ plot = Plot.objects.get(pk=3) tag = FunkyTag.objects.create(content_object=plot, name='hott') - should_contain = """
      • Funky tag: hott""" % tag.id - response = self.client.get('/test_admin/admin/admin_views/plot/%s/delete/' % quote(3)) + should_contain = '
      • Funky tag: hott' % reverse( + 'admin:admin_views_funkytag_change', args=(tag.id,)) + response = self.client.get(reverse('admin:admin_views_plot_delete', args=(3,))) self.assertContains(response, should_contain) @@ -1920,7 +1945,7 @@ class TestGenericRelations(TestCase): def test_generic_content_object_in_list_display(self): plot = Plot.objects.get(pk=3) FunkyTag.objects.create(content_object=plot, name='hott') - response = self.client.get('/test_admin/admin/admin_views/funkytag/') + response = self.client.get(reverse('admin:admin_views_funkytag_changelist')) self.assertContains(response, "%s" % plot) @@ -1944,36 +1969,38 @@ class AdminViewStringPrimaryKeyTest(TestCase): key should work. Refs #12349, #18550. """ - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/history/' % quote(self.pk)) + response = self.client.get(reverse('admin:admin_views_modelwithstringprimarykey_history', args=(self.pk,))) self.assertContains(response, escape(self.pk)) self.assertContains(response, 'Changed something') self.assertEqual(response.status_code, 200) def test_get_change_view(self): "Retrieving the object using urlencoded form of primary key should work" - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(self.pk)) + response = self.client.get(reverse('admin:admin_views_modelwithstringprimarykey_change', args=(self.pk,))) self.assertContains(response, escape(self.pk)) self.assertEqual(response.status_code, 200) def test_changelist_to_changeform_link(self): "Link to the changeform of the object in changelist should use reverse() and be quoted -- #18072" - prefix = '/test_admin/admin/admin_views/modelwithstringprimarykey/' - response = self.client.get(prefix) + response = self.client.get(reverse('admin:admin_views_modelwithstringprimarykey_changelist')) # this URL now comes through reverse(), thus url quoting and iri_to_uri encoding pk_final_url = escape(iri_to_uri(quote(self.pk))) - should_contain = """%s""" % (prefix, pk_final_url, escape(self.pk)) + change_url = reverse( + 'admin:admin_views_modelwithstringprimarykey_change', args=('__fk__',) + ).replace('__fk__', pk_final_url) + should_contain = '%s' % (change_url, escape(self.pk)) self.assertContains(response, should_contain) def test_recentactions_link(self): "The link from the recent actions list referring to the changeform of the object should be quoted" - response = self.client.get('/test_admin/admin/') + response = self.client.get(reverse('admin:index')) link = reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(self.pk),)) should_contain = """%s""" % (escape(link), escape(self.pk)) self.assertContains(response, should_contain) def test_recentactions_without_content_type(self): "If a LogEntry is missing content_type it will not display it in span tag under the hyperlink." - response = self.client.get('/test_admin/admin/') + response = self.client.get(reverse('admin:index')) link = reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(self.pk),)) should_contain = """%s""" % (escape(link), escape(self.pk)) self.assertContains(response, should_contain) @@ -1987,7 +2014,7 @@ class AdminViewStringPrimaryKeyTest(TestCase): logentry.save() counted_presence_before = response.content.count(force_bytes(should_contain)) - response = self.client.get('/test_admin/admin/') + response = self.client.get(reverse('admin:index')) counted_presence_after = response.content.count(force_bytes(should_contain)) self.assertEqual(counted_presence_before - 1, counted_presence_after) @@ -1996,25 +2023,31 @@ class AdminViewStringPrimaryKeyTest(TestCase): "LogEntry.get_admin_url returns a URL to edit the entry's object or None for non-existent (possibly deleted) models" log_entry_model = "modelwithstringprimarykey" # capitalized in Recent Actions logentry = LogEntry.objects.get(content_type__model__iexact=log_entry_model) - model = "modelwithstringprimarykey" - desired_admin_url = "/test_admin/admin/admin_views/%s/%s/" % (model, iri_to_uri(quote(self.pk))) + desired_admin_url = reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(self.pk),)) + self.assertEqual(logentry.get_admin_url(), desired_admin_url) + self.assertIn(iri_to_uri(quote(self.pk)), logentry.get_admin_url()) logentry.content_type.model = "non-existent" self.assertEqual(logentry.get_admin_url(), None) def test_deleteconfirmation_link(self): "The link from the delete confirmation page referring back to the changeform of the object should be quoted" - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/delete/' % quote(self.pk)) + response = self.client.get(reverse('admin:admin_views_modelwithstringprimarykey_delete', args=(quote(self.pk),))) # this URL now comes through reverse(), thus url quoting and iri_to_uri encoding - should_contain = """/%s/">%s""" % (escape(iri_to_uri(quote(self.pk))), escape(self.pk)) + change_url = reverse( + 'admin:admin_views_modelwithstringprimarykey_change', args=('__fk__',) + ).replace('__fk__', escape(iri_to_uri(quote(self.pk)))) + should_contain = '%s' % (change_url, escape(self.pk)) self.assertContains(response, should_contain) def test_url_conflicts_with_add(self): "A model with a primary key that ends with add should be visible" add_model = ModelWithStringPrimaryKey(pk="i have something to add") add_model.save() - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(add_model.pk)) + response = self.client.get( + reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(add_model.pk),)) + ) should_contain = """

        Change model with string primary key

        """ self.assertContains(response, should_contain) @@ -2022,7 +2055,9 @@ class AdminViewStringPrimaryKeyTest(TestCase): "A model with a primary key that ends with delete should be visible" delete_model = ModelWithStringPrimaryKey(pk="delete") delete_model.save() - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(delete_model.pk)) + response = self.client.get( + reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(delete_model.pk),)) + ) should_contain = """

        Change model with string primary key

        """ self.assertContains(response, should_contain) @@ -2030,7 +2065,9 @@ class AdminViewStringPrimaryKeyTest(TestCase): "A model with a primary key that ends with history should be visible" history_model = ModelWithStringPrimaryKey(pk="history") history_model.save() - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(history_model.pk)) + response = self.client.get( + reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(history_model.pk),)) + ) should_contain = """

        Change model with string primary key

        """ self.assertContains(response, should_contain) @@ -2038,7 +2075,9 @@ class AdminViewStringPrimaryKeyTest(TestCase): "'View on site should' work properly with char fields" model = ModelWithStringPrimaryKey(pk='abc_123') model.save() - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(model.pk)) + response = self.client.get( + reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(model.pk),)) + ) should_contain = '/%s/" class="viewsitelink">' % model.pk self.assertContains(response, should_contain) @@ -2062,7 +2101,7 @@ class AdminViewStringPrimaryKeyTest(TestCase): like slash or underscore, these characters must be escaped (see #22266) """ response = self.client.post( - '/test_admin/admin/admin_views/modelwithstringprimarykey/add/', + reverse('admin:admin_views_modelwithstringprimarykey_add'), { 'string_pk': '123/history', "_continue": "1", # Save and continue editing @@ -2070,13 +2109,7 @@ class AdminViewStringPrimaryKeyTest(TestCase): ) self.assertEqual(response.status_code, 302) # temporary redirect - self.assertEqual( - response['location'], - ( - 'http://testserver/test_admin/admin/admin_views/' - 'modelwithstringprimarykey/123_2Fhistory/' # PK is quoted - ) - ) + self.assertIn('/123_2Fhistory/', response['location']) # PK is quoted @override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'], @@ -2091,7 +2124,7 @@ class SecureViewTests(TestCase): """ Ensure that we see the admin login form. """ - secure_url = '/test_admin/admin/secure-view/' + secure_url = reverse('secure_view') response = self.client.get(secure_url) self.assertRedirects(response, '%s?next=%s' % (reverse('admin:login'), secure_url)) response = self.client.get(secure_url, follow=True) @@ -2137,7 +2170,7 @@ class AdminViewUnicodeTest(TestCase): "chapter_set-5-content": "", } - response = self.client.post('/test_admin/admin/admin_views/book/1/', post_data) + response = self.client.post(reverse('admin:admin_views_book_change', args=(1,)), post_data) self.assertEqual(response.status_code, 302) # redirect somewhere def test_unicode_delete(self): @@ -2145,10 +2178,11 @@ class AdminViewUnicodeTest(TestCase): Ensure that the delete_view handles non-ASCII characters """ delete_dict = {'post': 'yes'} - response = self.client.get('/test_admin/admin/admin_views/book/1/delete/') + delete_url = reverse('admin:admin_views_book_delete', args=(1,)) + response = self.client.get(delete_url) self.assertEqual(response.status_code, 200) - response = self.client.post('/test_admin/admin/admin_views/book/1/delete/', delete_dict) - self.assertRedirects(response, '/test_admin/admin/admin_views/book/') + response = self.client.post(delete_url, delete_dict) + self.assertRedirects(response, reverse('admin:admin_views_book_changelist')) @override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'], @@ -2162,21 +2196,21 @@ class AdminViewListEditable(TestCase): def test_inheritance(self): Podcast.objects.create(name="This Week in Django", release_date=datetime.date.today()) - response = self.client.get('/test_admin/admin/admin_views/podcast/') + response = self.client.get(reverse('admin:admin_views_podcast_changelist')) self.assertEqual(response.status_code, 200) def test_inheritance_2(self): Vodcast.objects.create(name="This Week in Django", released=True) - response = self.client.get('/test_admin/admin/admin_views/vodcast/') + response = self.client.get(reverse('admin:admin_views_vodcast_changelist')) self.assertEqual(response.status_code, 200) def test_custom_pk(self): Language.objects.create(iso='en', name='English', english_name='English') - response = self.client.get('/test_admin/admin/admin_views/language/') + response = self.client.get(reverse('admin:admin_views_language_changelist')) self.assertEqual(response.status_code, 200) def test_changelist_input_html(self): - response = self.client.get('/test_admin/admin/admin_views/person/') + response = self.client.get(reverse('admin:admin_views_person_changelist')) # 2 inputs per object(the field and the hidden id field) = 6 # 4 management hidden fields = 4 # 4 action inputs (3 regular checkboxes, 1 checkbox to select all) @@ -2209,7 +2243,7 @@ class AdminViewListEditable(TestCase): "_save": "Save", } - response = self.client.post('/test_admin/admin/admin_views/person/', + response = self.client.post(reverse('admin:admin_views_person_changelist'), data, follow=True) self.assertEqual(len(response.context['messages']), 1) @@ -2231,7 +2265,7 @@ class AdminViewListEditable(TestCase): "_save": "Save", } - self.client.post('/test_admin/admin/admin_views/person/', data) + self.client.post(reverse('admin:admin_views_person_changelist'), data) self.assertEqual(Person.objects.get(name="John Mauchly").alive, False) self.assertEqual(Person.objects.get(name="Grace Hopper").gender, 2) @@ -2252,7 +2286,7 @@ class AdminViewListEditable(TestCase): "_save": "Save", } - self.client.post('/test_admin/admin/admin_views/person/?gender__exact=1', data) + self.client.post(reverse('admin:admin_views_person_changelist') + '?gender__exact=1', data) self.assertEqual(Person.objects.get(name="John Mauchly").alive, True) @@ -2267,7 +2301,7 @@ class AdminViewListEditable(TestCase): "_save": "Save", } - self.client.post('/test_admin/admin/admin_views/person/?q=john', data) + self.client.post(reverse('admin:admin_views_person_changelist') + '?q=john', data) self.assertEqual(Person.objects.get(name="John Mauchly").alive, False) @@ -2302,8 +2336,14 @@ class AdminViewListEditable(TestCase): "_save": "Save", } - response = self.client.post('/test_admin/admin/admin_views/fooddelivery/', data) - self.assertContains(response, '
        • Food delivery with this Driver and Restaurant already exists.
        ', 1, html=True) + response = self.client.post(reverse('admin:admin_views_fooddelivery_changelist'), data) + self.assertContains( + response, + '
        • Food delivery ' + 'with this Driver and Restaurant already exists.
        ', + 1, + html=True + ) data = { "form-TOTAL_FORMS": "3", @@ -2329,8 +2369,14 @@ class AdminViewListEditable(TestCase): "_save": "Save", } - response = self.client.post('/test_admin/admin/admin_views/fooddelivery/', data) - self.assertContains(response, '
        • Food delivery with this Driver and Restaurant already exists.
        ', 2, html=True) + response = self.client.post(reverse('admin:admin_views_fooddelivery_changelist'), data) + self.assertContains( + response, + '
        • Food delivery ' + 'with this Driver and Restaurant already exists.
        ', + 2, + html=True + ) def test_non_form_errors(self): # test if non-form errors are handled; ticket #12716 @@ -2347,7 +2393,7 @@ class AdminViewListEditable(TestCase): # and not an action "Go". "_save": "Save", } - response = self.client.post('/test_admin/admin/admin_views/person/', data) + response = self.client.post(reverse('admin:admin_views_person_changelist'), data) self.assertContains(response, "Grace is not a Zombie") def test_non_form_errors_is_errorlist(self): @@ -2363,7 +2409,7 @@ class AdminViewListEditable(TestCase): "_save": "Save", } - response = self.client.post('/test_admin/admin/admin_views/person/', data) + response = self.client.post(reverse('admin:admin_views_person_changelist'), data) non_form_errors = response.context['cl'].formset.non_form_errors() self.assertIsInstance(non_form_errors, ErrorList) self.assertEqual(str(non_form_errors), str(ErrorList(["Grace is not a Zombie"]))) @@ -2402,7 +2448,7 @@ class AdminViewListEditable(TestCase): # and not an action "Go". "_save": "Save", } - response = self.client.post('/test_admin/admin/admin_views/category/', data) + response = self.client.post(reverse('admin:admin_views_category_changelist'), data) # Successful post will redirect self.assertEqual(response.status_code, 302) @@ -2420,11 +2466,11 @@ class AdminViewListEditable(TestCase): UnorderedObject.objects.create(id=1, name='Unordered object #1') UnorderedObject.objects.create(id=2, name='Unordered object #2') UnorderedObject.objects.create(id=3, name='Unordered object #3') - response = self.client.get('/test_admin/admin/admin_views/unorderedobject/') + response = self.client.get(reverse('admin:admin_views_unorderedobject_changelist')) self.assertContains(response, 'Unordered object #3') self.assertContains(response, 'Unordered object #2') self.assertNotContains(response, 'Unordered object #1') - response = self.client.get('/test_admin/admin/admin_views/unorderedobject/?p=1') + response = self.client.get(reverse('admin:admin_views_unorderedobject_changelist') + '?p=1') self.assertNotContains(response, 'Unordered object #3') self.assertNotContains(response, 'Unordered object #2') self.assertContains(response, 'Unordered object #1') @@ -2451,7 +2497,7 @@ class AdminViewListEditable(TestCase): "_selected_action": ['3'], "action": ['', 'delete_selected'], } - self.client.post('/test_admin/admin/admin_views/person/', data) + self.client.post(reverse('admin:admin_views_person_changelist'), data) self.assertEqual(Person.objects.get(name="John Mauchly").alive, True) self.assertEqual(Person.objects.get(name="Grace Hopper").gender, 1) @@ -2478,7 +2524,7 @@ class AdminViewListEditable(TestCase): "_selected_action": ['1'], "action": ['', 'delete_selected'], } - self.client.post('/test_admin/admin/admin_views/person/', data) + self.client.post(reverse('admin:admin_views_person_changelist'), data) self.assertEqual(Person.objects.get(name="John Mauchly").alive, False) self.assertEqual(Person.objects.get(name="Grace Hopper").gender, 2) @@ -2487,9 +2533,9 @@ class AdminViewListEditable(TestCase): """ Fields should not be list-editable in popups. """ - response = self.client.get('/test_admin/admin/admin_views/person/') + response = self.client.get(reverse('admin:admin_views_person_changelist')) self.assertNotEqual(response.context['cl'].list_editable, ()) - response = self.client.get('/test_admin/admin/admin_views/person/?%s' % IS_POPUP_VAR) + response = self.client.get(reverse('admin:admin_views_person_changelist') + '?%s' % IS_POPUP_VAR) self.assertEqual(response.context['cl'].list_editable, ()) def test_pk_hidden_fields(self): @@ -2501,7 +2547,7 @@ class AdminViewListEditable(TestCase): """ story1 = Story.objects.create(title='The adventures of Guido', content='Once upon a time in Djangoland...') story2 = Story.objects.create(title='Crouching Tiger, Hidden Python', content='The Python was sneaking into...') - response = self.client.get('/test_admin/admin/admin_views/story/') + response = self.client.get(reverse('admin:admin_views_story_changelist')) self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table. self.assertContains(response, 'id="id_form-1-id"', 1) self.assertContains(response, '
        \n\n
        ' % (story2.id, story1.id), html=True) @@ -2517,7 +2563,7 @@ class AdminViewListEditable(TestCase): story2 = OtherStory.objects.create(title='Crouching Tiger, Hidden Python', content='The Python was sneaking into...') link1 = reverse('admin:admin_views_otherstory_change', args=(story1.pk,)) link2 = reverse('admin:admin_views_otherstory_change', args=(story2.pk,)) - response = self.client.get('/test_admin/admin/admin_views/otherstory/') + response = self.client.get(reverse('admin:admin_views_otherstory_changelist')) self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table. self.assertContains(response, 'id="id_form-1-id"', 1) self.assertContains(response, '
        \n\n
        ' % (story2.id, story1.id), html=True) @@ -2536,34 +2582,35 @@ class AdminSearchTest(TestCase): def test_search_on_sibling_models(self): "Check that a search that mentions sibling models" - response = self.client.get('/test_admin/admin/admin_views/recommendation/?q=bar') + response = self.client.get(reverse('admin:admin_views_recommendation_changelist') + '?q=bar') # confirm the search returned 1 object self.assertContains(response, "\n1 recommendation\n") def test_with_fk_to_field(self): - """Ensure that the to_field GET parameter is preserved when a search + """ + Ensure that the to_field GET parameter is preserved when a search is performed. Refs #10918. """ - response = self.client.get('/test_admin/admin/auth/user/?q=joe&%s=id' % TO_FIELD_VAR) + response = self.client.get(reverse('admin:auth_user_changelist') + '?q=joe&%s=id' % TO_FIELD_VAR) self.assertContains(response, "\n1 user\n") self.assertContains(response, '' % TO_FIELD_VAR, html=True) def test_exact_matches(self): - response = self.client.get('/test_admin/admin/admin_views/recommendation/?q=bar') + response = self.client.get(reverse('admin:admin_views_recommendation_changelist') + '?q=bar') # confirm the search returned one object self.assertContains(response, "\n1 recommendation\n") - response = self.client.get('/test_admin/admin/admin_views/recommendation/?q=ba') + response = self.client.get(reverse('admin:admin_views_recommendation_changelist') + '?q=ba') # confirm the search returned zero objects self.assertContains(response, "\n0 recommendations\n") def test_beginning_matches(self): - response = self.client.get('/test_admin/admin/admin_views/person/?q=Gui') + response = self.client.get(reverse('admin:admin_views_person_changelist') + '?q=Gui') # confirm the search returned one object self.assertContains(response, "\n1 person\n") self.assertContains(response, "Guido") - response = self.client.get('/test_admin/admin/admin_views/person/?q=uido') + response = self.client.get(reverse('admin:admin_views_person_changelist') + '?q=uido') # confirm the search returned zero objects self.assertContains(response, "\n0 persons\n") self.assertNotContains(response, "Guido") @@ -2572,12 +2619,12 @@ class AdminSearchTest(TestCase): PluggableSearchPerson.objects.create(name="Bob", age=10) PluggableSearchPerson.objects.create(name="Amy", age=20) - response = self.client.get('/test_admin/admin/admin_views/pluggablesearchperson/?q=Bob') + response = self.client.get(reverse('admin:admin_views_pluggablesearchperson_changelist') + '?q=Bob') # confirm the search returned one object self.assertContains(response, "\n1 pluggable search person\n") self.assertContains(response, "Bob") - response = self.client.get('/test_admin/admin/admin_views/pluggablesearchperson/?q=20') + response = self.client.get(reverse('admin:admin_views_pluggablesearchperson_changelist') + '?q=20') # confirm the search returned one object self.assertContains(response, "\n1 pluggable search person\n") self.assertContains(response, "Amy") @@ -2590,7 +2637,7 @@ class AdminSearchTest(TestCase): # + 1 for filtered result + 1 for filtered count # + 1 for total count with self.assertNumQueries(5): - response = self.client.get('/test_admin/admin/admin_views/person/?q=Gui') + response = self.client.get(reverse('admin:admin_views_person_changelist') + '?q=Gui') self.assertContains(response, """1 result (3 total)""", html=True) @@ -2603,7 +2650,7 @@ class AdminSearchTest(TestCase): # 1 query for session + 1 for fetching user # + 1 for filtered result + 1 for filtered count with self.assertNumQueries(4): - response = self.client.get('/test_admin/admin/admin_views/recommendation/?q=bar') + response = self.client.get(reverse('admin:admin_views_recommendation_changelist') + '?q=bar') self.assertContains(response, """1 result (Show all)""", html=True) @@ -2626,7 +2673,7 @@ class AdminInheritedInlinesTest(TestCase): name_re = re.compile(b'name="(.*?)"') # test the add case - response = self.client.get('/test_admin/admin/admin_views/persona/add/') + response = self.client.get(reverse('admin:admin_views_persona_add')) names = name_re.findall(response.content) # make sure we have no duplicate HTML names self.assertEqual(len(names), len(set(names))) @@ -2645,7 +2692,7 @@ class AdminInheritedInlinesTest(TestCase): "accounts-2-0-username": bar_user, } - response = self.client.post('/test_admin/admin/admin_views/persona/add/', post_data) + response = self.client.post(reverse('admin:admin_views_persona_add'), post_data) self.assertEqual(response.status_code, 302) # redirect somewhere self.assertEqual(Persona.objects.count(), 1) self.assertEqual(FooAccount.objects.count(), 1) @@ -2660,7 +2707,7 @@ class AdminInheritedInlinesTest(TestCase): # test the edit case - response = self.client.get('/test_admin/admin/admin_views/persona/%d/' % persona_id) + response = self.client.get(reverse('admin:admin_views_persona_change', args=(persona_id,))) names = name_re.findall(response.content) # make sure we have no duplicate HTML names self.assertEqual(len(names), len(set(names))) @@ -2684,7 +2731,7 @@ class AdminInheritedInlinesTest(TestCase): "accounts-2-0-account_ptr": str(bar_id), "accounts-2-0-persona": str(persona_id), } - response = self.client.post('/test_admin/admin/admin_views/persona/%d/' % persona_id, post_data) + response = self.client.post(reverse('admin:admin_views_persona_change', args=(persona_id,)), post_data) self.assertEqual(response.status_code, 302) self.assertEqual(Persona.objects.count(), 1) self.assertEqual(FooAccount.objects.count(), 1) @@ -2709,7 +2756,7 @@ class AdminActionsTest(TestCase): 'action': 'mail_admin', 'index': 0, } - self.client.post('/test_admin/admin/admin_views/subscriber/', action_data) + self.client.post(reverse('admin:admin_views_subscriber_changelist'), action_data) self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].subject, 'Greetings from a ModelAdmin action') @@ -2725,14 +2772,14 @@ class AdminActionsTest(TestCase): 'action': 'delete_selected', 'post': 'yes', } - confirmation = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data) + confirmation = self.client.post(reverse('admin:admin_views_subscriber_changelist'), action_data) self.assertIsInstance(confirmation, TemplateResponse) self.assertContains(confirmation, "Are you sure you want to delete the selected subscribers?") self.assertContains(confirmation, "

        Summary

        ") self.assertContains(confirmation, "
      • Subscribers: 3
      • ") self.assertContains(confirmation, "
      • External subscribers: 1
      • ") self.assertContains(confirmation, ACTION_CHECKBOX_NAME, count=2) - self.client.post('/test_admin/admin/admin_views/subscriber/', delete_confirmation_data) + self.client.post(reverse('admin:admin_views_subscriber_changelist'), delete_confirmation_data) self.assertEqual(Subscriber.objects.count(), 0) @override_settings(USE_THOUSAND_SEPARATOR=True, USE_L10N=True) @@ -2749,7 +2796,7 @@ class AdminActionsTest(TestCase): 'action': 'delete_selected', 'index': 0, } - response = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data) + response = self.client.post(reverse('admin:admin_views_subscriber_changelist'), action_data) self.assertTemplateUsed(response, 'admin/delete_selected_confirmation.html') self.assertContains(response, 'value="9999"') # Instead of 9,999 self.assertContains(response, 'value="2"') @@ -2770,11 +2817,19 @@ class AdminActionsTest(TestCase): 'index': 0, } - response = self.client.post("/test_admin/admin/admin_views/question/", action_data) + response = self.client.post(reverse('admin:admin_views_question_changelist'), action_data) self.assertContains(response, "would require deleting the following protected related objects") - self.assertContains(response, '
      • Answer: Because.
      • ' % a1.pk, html=True) - self.assertContains(response, '
      • Answer: Yes.
      • ' % a2.pk, html=True) + self.assertContains( + response, + '
      • Answer: Because.
      • ' % reverse('admin:admin_views_answer_change', args=(a1.pk,)), + html=True + ) + self.assertContains( + response, + '
      • Answer: Yes.
      • ' % reverse('admin:admin_views_answer_change', args=(a2.pk,)), + html=True + ) def test_model_admin_default_delete_action_no_change_url(self): """ @@ -2788,7 +2843,7 @@ class AdminActionsTest(TestCase): "action": "delete_selected", "index": "0", } - response = self.client.post('/test_admin/admin/admin_views/unchangeableobject/', action_data) + response = self.client.post(reverse('admin:admin_views_unchangeableobject_changelist'), action_data) # No 500 caused by NoReverseMatch self.assertEqual(response.status_code, 200) # The page shouldn't display a link to the nonexistent change page @@ -2801,7 +2856,7 @@ class AdminActionsTest(TestCase): 'action': 'external_mail', 'index': 0, } - self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data) + self.client.post(reverse('admin:admin_views_externalsubscriber_changelist'), action_data) self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].subject, 'Greetings from a function action') @@ -2812,7 +2867,7 @@ class AdminActionsTest(TestCase): 'action': 'redirect_to', 'index': 0, } - response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data) + response = self.client.post(reverse('admin:admin_views_externalsubscriber_changelist'), action_data) self.assertEqual(response.status_code, 302) def test_default_redirect(self): @@ -2826,7 +2881,7 @@ class AdminActionsTest(TestCase): 'action': 'external_mail', 'index': 0, } - url = '/test_admin/admin/admin_views/externalsubscriber/?o=1' + url = reverse('admin:admin_views_externalsubscriber_changelist') + '?o=1' response = self.client.post(url, action_data) self.assertRedirects(response, url) @@ -2837,7 +2892,7 @@ class AdminActionsTest(TestCase): 'action': 'download', 'index': 0, } - response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data) + response = self.client.post(reverse('admin:admin_views_externalsubscriber_changelist'), action_data) content = b''.join(response.streaming_content) self.assertEqual(content, b'This is the content of the file') self.assertEqual(response.status_code, 200) @@ -2849,7 +2904,7 @@ class AdminActionsTest(TestCase): 'action': 'no_perm', 'index': 0, } - response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data) + response = self.client.post(reverse('admin:admin_views_externalsubscriber_changelist'), action_data) self.assertEqual(response.status_code, 403) self.assertEqual(response.content, b'No permission to perform this action') @@ -2858,7 +2913,7 @@ class AdminActionsTest(TestCase): Ensure that actions are ordered as expected. Refs #15964. """ - response = self.client.get('/test_admin/admin/admin_views/externalsubscriber/') + response = self.client.get(reverse('admin:admin_views_externalsubscriber_changelist')) self.assertContains(response, '''