From aaf77c1676e44019abe544911ff7a06eb2690295 Mon Sep 17 00:00:00 2001 From: Ramiro Morales Date: Tue, 20 Sep 2011 18:30:06 +0000 Subject: Converted internal link generation in the admin and admin document generator to use named URLs. Thanks to Florian Apolloner for both the initial patch and his final push to get this fixed, to Dario Ocles for his great work on the admin templates and switching the admin_doc application to also use named URLs, to Mikko Hellsing for his comments and to Jannis and Julien for their review and design guidance. Fixes #15294. git-svn-id: http://code.djangoproject.com/svn/django/trunk@16857 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- .../regressiontests/admin_custom_urls/__init__.py | 1 + .../admin_custom_urls/fixtures/actions.json | 44 +++++++++++++ .../admin_custom_urls/fixtures/users.json | 20 ++++++ tests/regressiontests/admin_custom_urls/models.py | 50 +++++++++++++++ tests/regressiontests/admin_custom_urls/tests.py | 72 ++++++++++++++++++++++ tests/regressiontests/admin_custom_urls/urls.py | 7 +++ tests/regressiontests/admin_views/tests.py | 4 +- tests/urls.py | 4 +- 8 files changed, 199 insertions(+), 3 deletions(-) create mode 100644 tests/regressiontests/admin_custom_urls/__init__.py create mode 100644 tests/regressiontests/admin_custom_urls/fixtures/actions.json create mode 100644 tests/regressiontests/admin_custom_urls/fixtures/users.json create mode 100644 tests/regressiontests/admin_custom_urls/models.py create mode 100644 tests/regressiontests/admin_custom_urls/tests.py create mode 100644 tests/regressiontests/admin_custom_urls/urls.py (limited to 'tests') diff --git a/tests/regressiontests/admin_custom_urls/__init__.py b/tests/regressiontests/admin_custom_urls/__init__.py new file mode 100644 index 0000000000..792d600548 --- /dev/null +++ b/tests/regressiontests/admin_custom_urls/__init__.py @@ -0,0 +1 @@ +# diff --git a/tests/regressiontests/admin_custom_urls/fixtures/actions.json b/tests/regressiontests/admin_custom_urls/fixtures/actions.json new file mode 100644 index 0000000000..d803393a12 --- /dev/null +++ b/tests/regressiontests/admin_custom_urls/fixtures/actions.json @@ -0,0 +1,44 @@ +[ + { + "pk": "delete", + "model": "admin_custom_urls.action", + "fields": { + "description": "Remove things." + } + }, + { + "pk": "rename", + "model": "admin_custom_urls.action", + "fields": { + "description": "Gives things other names." + } + }, + { + "pk": "add", + "model": "admin_custom_urls.action", + "fields": { + "description": "Add things." + } + }, + { + "pk": "path/to/file/", + "model": "admin_custom_urls.action", + "fields": { + "description": "An action with '/' in its name." + } + }, + { + "pk": "path/to/html/document.html", + "model": "admin_custom_urls.action", + "fields": { + "description": "An action with a name similar to a HTML doc path." + } + }, + { + "pk": "javascript:alert('Hello world');\">Click here", + "model": "admin_custom_urls.action", + "fields": { + "description": "An action with a name suspected of being a XSS attempt" + } + } +] \ No newline at end of file diff --git a/tests/regressiontests/admin_custom_urls/fixtures/users.json b/tests/regressiontests/admin_custom_urls/fixtures/users.json new file mode 100644 index 0000000000..72d86d70ad --- /dev/null +++ b/tests/regressiontests/admin_custom_urls/fixtures/users.json @@ -0,0 +1,20 @@ +[ + { + "pk": 100, + "model": "auth.user", + "fields": { + "username": "super", + "first_name": "Super", + "last_name": "User", + "is_active": true, + "is_superuser": true, + "is_staff": true, + "last_login": "2007-05-30 13:20:10", + "groups": [], + "user_permissions": [], + "password": "sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158", + "email": "super@example.com", + "date_joined": "2007-05-30 13:20:10" + } + } +] diff --git a/tests/regressiontests/admin_custom_urls/models.py b/tests/regressiontests/admin_custom_urls/models.py new file mode 100644 index 0000000000..f8c83a9024 --- /dev/null +++ b/tests/regressiontests/admin_custom_urls/models.py @@ -0,0 +1,50 @@ +from functools import update_wrapper + +from django.contrib import admin +from django.db import models + + +class Action(models.Model): + name = models.CharField(max_length=50, primary_key=True) + description = models.CharField(max_length=70) + + def __unicode__(self): + return self.name + + +class ActionAdmin(admin.ModelAdmin): + """ + A ModelAdmin for the Action model that changes the URL of the add_view + to '//!add/' + The Action model has a CharField PK. + """ + + list_display = ('name', 'description') + + def remove_url(self, name): + """ + Remove all entries named 'name' from the ModelAdmin instance URL + patterns list + """ + return filter(lambda e: e.name != name, super(ActionAdmin, self).get_urls()) + + def get_urls(self): + # Add the URL of our custom 'add_view' view to the front of the URLs + # list. Remove the existing one(s) first + from django.conf.urls.defaults import patterns, url + + def wrap(view): + def wrapper(*args, **kwargs): + return self.admin_site.admin_view(view)(*args, **kwargs) + return update_wrapper(wrapper, view) + + info = self.model._meta.app_label, self.model._meta.module_name + + view_name = '%s_%s_add' % info + + return patterns('', + url(r'^!add/$', wrap(self.add_view), name=view_name), + ) + self.remove_url(view_name) + + +admin.site.register(Action, ActionAdmin) diff --git a/tests/regressiontests/admin_custom_urls/tests.py b/tests/regressiontests/admin_custom_urls/tests.py new file mode 100644 index 0000000000..cfc6b8583e --- /dev/null +++ b/tests/regressiontests/admin_custom_urls/tests.py @@ -0,0 +1,72 @@ +from django.core.urlresolvers import reverse +from django.template.response import TemplateResponse +from django.test import TestCase + +from models import Action + + +class AdminCustomUrlsTest(TestCase): + fixtures = ['users.json', 'actions.json'] + + def setUp(self): + self.client.login(username='super', password='secret') + + def tearDown(self): + self.client.logout() + + def testBasicAddGet(self): + """ + A smoke test to ensure GET on the add_view works. + """ + response = self.client.get('/custom_urls/admin/admin_custom_urls/action/!add/') + self.assertIsInstance(response, TemplateResponse) + self.assertEqual(response.status_code, 200) + + def testAddWithGETArgs(self): + response = self.client.get('/custom_urls/admin/admin_custom_urls/action/!add/', {'name': 'My Action'}) + self.assertEqual(response.status_code, 200) + self.assertTrue( + 'value="My Action"' in response.content, + "Couldn't find an input with the right value in the response." + ) + + def testBasicAddPost(self): + """ + A smoke test to ensure POST on add_view works. + """ + post_data = { + '_popup': u'1', + "name": u'Action added through a popup', + "description": u"Description of added action", + } + response = self.client.post('/custom_urls/admin/admin_custom_urls/action/!add/', post_data) + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'dismissAddAnotherPopup') + self.assertContains(response, 'Action added through a popup') + + def testAdminUrlsNoClash(self): + """ + Test that some admin URLs work correctly. The model has a CharField + PK and the add_view URL has been customized. + """ + # Should get the change_view for model instance with PK 'add', not show + # the add_view + response = self.client.get('/custom_urls/admin/admin_custom_urls/action/add/') + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'Change action') + + # Ditto, but use reverse() to build the URL + path = reverse('admin:%s_action_change' % Action._meta.app_label, + args=('add',)) + response = self.client.get(path) + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'Change action') + + # Should correctly get the change_view for the model instance with the + # funny-looking PK + path = reverse('admin:%s_action_change' % Action._meta.app_label, + args=("path/to/html/document.html",)) + response = self.client.get(path) + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'Change action') + self.assertContains(response, 'value="path/to/html/document.html"') diff --git a/tests/regressiontests/admin_custom_urls/urls.py b/tests/regressiontests/admin_custom_urls/urls.py new file mode 100644 index 0000000000..6c2761a222 --- /dev/null +++ b/tests/regressiontests/admin_custom_urls/urls.py @@ -0,0 +1,7 @@ +from django.conf.urls.defaults import * +from django.contrib import admin + +urlpatterns = patterns('', + (r'^admin/', include(admin.site.urls)), +) + diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index 668c71076e..78457d97ab 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -595,7 +595,7 @@ class SaveAsTests(TestCase): 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'], '../add/') + self.assertEqual(response.context['form_url'], '/test_admin/admin/admin_views/person/add/') class CustomModelAdminTest(AdminViewBasicTest): urls = "regressiontests.admin_views.urls" @@ -842,7 +842,7 @@ class AdminViewPermissionsTest(TestCase): self.client.post('/test_admin/admin/', self.adduser_login) addpage = self.client.get('/test_admin/admin/admin_views/article/add/') self.assertEqual(addpage.status_code, 200) - change_list_link = 'Articles ›' + change_list_link = '› Articles' self.assertFalse(change_list_link in addpage.content, '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) diff --git a/tests/urls.py b/tests/urls.py index 044395039d..e7c23e5144 100644 --- a/tests/urls.py +++ b/tests/urls.py @@ -1,6 +1,5 @@ from django.conf.urls import patterns, include - urlpatterns = patterns('', # test_client modeltest urls (r'^test_client/', include('modeltests.test_client.urls')), @@ -25,4 +24,7 @@ urlpatterns = patterns('', # admin widget tests (r'widget_admin/', include('regressiontests.admin_widgets.urls')), + # admin custom URL tests + (r'^custom_urls/', include('regressiontests.admin_custom_urls.urls')), + ) -- cgit v1.3