9
9
from django.core import mail
10
10
from django.core.exceptions import ImproperlyConfigured
11
11
from django.core.files import temp as tempfile
12
from django.core.urlresolvers import reverse
12
from django.core.urlresolvers import get_script_prefix, reverse, set_script_prefix
13
13
# Register auth models with the admin.
14
14
from django.contrib import admin
15
15
from django.contrib.auth import get_permission_codename
16
16
from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
17
17
from django.contrib.admin.models import LogEntry, DELETION
18
18
from django.contrib.admin.sites import LOGIN_FORM_KEY
19
from django.contrib.admin.templatetags.admin_urls import add_preserved_filters
20
from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase
19
21
from django.contrib.admin.util import quote
20
22
from django.contrib.admin.validation import ModelAdminValidator
21
23
from django.contrib.admin.views.main import IS_POPUP_VAR
22
from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase
23
24
from django.contrib.auth import REDIRECT_FIELD_NAME
24
25
from django.contrib.auth.models import Group, User, Permission
25
26
from django.contrib.contenttypes.models import ContentType
33
34
from django.utils import translation
34
35
from django.utils import unittest
35
36
from django.utils.cache import get_max_age
36
from django.utils.encoding import iri_to_uri, force_bytes
37
from django.utils.encoding import iri_to_uri, force_bytes, force_text
37
38
from django.utils.html import escape
38
39
from django.utils.http import urlencode, urlquote
39
from django.utils.six.moves.urllib.parse import urljoin
40
from django.utils.six.moves.urllib.parse import parse_qsl, urljoin, urlparse
40
41
from django.utils._os import upath
41
42
from django.utils import six
4224
4225
def tearDown(self):
4225
4226
self.client.logout()
4227
def get_changelist_filters_querystring(self):
4228
def assertURLEqual(self, url1, url2):
4230
Assert that two URLs are equal despite the ordering
4231
of their querystring. Refs #22360.
4233
parsed_url1 = urlparse(url1)
4234
path1 = parsed_url1.path
4235
parsed_qs1 = dict(parse_qsl(parsed_url1.query))
4237
parsed_url2 = urlparse(url2)
4238
path2 = parsed_url2.path
4239
parsed_qs2 = dict(parse_qsl(parsed_url2.query))
4241
for parsed_qs in [parsed_qs1, parsed_qs2]:
4242
if '_changelist_filters' in parsed_qs:
4243
changelist_filters = parsed_qs['_changelist_filters']
4244
parsed_filters = dict(parse_qsl(changelist_filters))
4245
parsed_qs['_changelist_filters'] = parsed_filters
4247
self.assertEqual(path1, path2)
4248
self.assertEqual(parsed_qs1, parsed_qs2)
4250
def test_assert_url_equal(self):
4252
self.assertURLEqual(
4253
'http://testserver/test_admin/admin/auth/user/105/?_changelist_filters=is_staff__exact%3D0%26is_superuser__exact%3D0',
4254
'http://testserver/test_admin/admin/auth/user/105/?_changelist_filters=is_staff__exact%3D0%26is_superuser__exact%3D0'
4258
with self.assertRaises(AssertionError):
4259
self.assertURLEqual(
4260
'http://testserver/test_admin/admin/auth/user/105/?_changelist_filters=is_staff__exact%3D0%26is_superuser__exact%3D0',
4261
'http://testserver/test_admin/admin/auth/user/105/?_changelist_filters=is_staff__exact%3D1%26is_superuser__exact%3D1'
4264
# Ignore scheme and host.
4265
self.assertURLEqual(
4266
'http://testserver/test_admin/admin/auth/user/105/?_changelist_filters=is_staff__exact%3D0%26is_superuser__exact%3D0',
4267
'/test_admin/admin/auth/user/105/?_changelist_filters=is_staff__exact%3D0%26is_superuser__exact%3D0'
4270
# Ignore ordering of querystring.
4271
self.assertURLEqual(
4272
'/test_admin/admin/auth/user/?is_staff__exact=0&is_superuser__exact=0',
4273
'/test_admin/admin/auth/user/?is_superuser__exact=0&is_staff__exact=0'
4276
# Ignore ordering of _changelist_filters.
4277
self.assertURLEqual(
4278
'/test_admin/admin/auth/user/105/?_changelist_filters=is_staff__exact%3D0%26is_superuser__exact%3D0',
4279
'/test_admin/admin/auth/user/105/?_changelist_filters=is_superuser__exact%3D0%26is_staff__exact%3D0'
4282
def get_changelist_filters(self):
4229
4284
'is_superuser__exact': 0,
4230
4285
'is_staff__exact': 0,
4288
def get_changelist_filters_querystring(self):
4289
return urlencode(self.get_changelist_filters())
4233
4291
def get_preserved_filters_querystring(self):
4234
4292
return urlencode({
4284
4342
self.assertEqual(response.status_code, 200)
4286
4344
# Check the `change_view` link has the correct querystring.
4287
detail_link = """<a href="%s">joepublic</a>""" % self.get_change_url()
4288
self.assertContains(response, detail_link, count=1)
4345
detail_link = re.search(
4346
'<a href="(.*?)">joepublic</a>',
4347
force_text(response.content)
4349
self.assertURLEqual(detail_link.group(1), self.get_change_url())
4290
4351
def test_change_view(self):
4291
4352
# Get the `change_view`.
4293
4354
self.assertEqual(response.status_code, 200)
4295
4356
# Check the form action.
4296
form_action = """<form enctype="multipart/form-data" action="?%s" method="post" id="user_form">""" % self.get_preserved_filters_querystring()
4297
self.assertContains(response, form_action, count=1)
4357
form_action = re.search(
4358
'<form enctype="multipart/form-data" action="(.*?)" method="post" id="user_form".*?>',
4359
force_text(response.content)
4361
self.assertURLEqual(form_action.group(1), '?%s' % self.get_preserved_filters_querystring())
4299
4363
# Check the history link.
4300
history_link = """<a href="%s" class="historylink">History</a>""" % self.get_history_url()
4301
self.assertContains(response, history_link, count=1)
4364
history_link = re.search(
4365
'<a href="(.*?)" class="historylink">History</a>',
4366
force_text(response.content)
4368
self.assertURLEqual(history_link.group(1), self.get_history_url())
4303
4370
# Check the delete link.
4304
delete_link = """<a href="%s" class="deletelink">Delete</a>""" % (self.get_delete_url())
4305
self.assertContains(response, delete_link, count=1)
4371
delete_link = re.search(
4372
'<a href="(.*?)" class="deletelink">Delete</a>',
4373
force_text(response.content)
4375
self.assertURLEqual(delete_link.group(1), self.get_delete_url())
4307
4377
# Test redirect on "Save".
4316
4386
post_data['_save'] = 1
4317
4387
response = self.client.post(self.get_change_url(), data=post_data)
4318
self.assertRedirects(response, self.get_changelist_url())
4388
self.assertEqual(response.status_code, 302)
4389
self.assertURLEqual(
4391
self.get_changelist_url()
4319
4393
post_data.pop('_save')
4321
4395
# Test redirect on "Save and continue".
4322
4396
post_data['_continue'] = 1
4323
4397
response = self.client.post(self.get_change_url(), data=post_data)
4324
self.assertRedirects(response, self.get_change_url())
4398
self.assertEqual(response.status_code, 302)
4399
self.assertURLEqual(
4401
self.get_change_url()
4325
4403
post_data.pop('_continue')
4327
4405
# Test redirect on "Save and add new".
4328
4406
post_data['_addanother'] = 1
4329
4407
response = self.client.post(self.get_change_url(), data=post_data)
4330
self.assertRedirects(response, self.get_add_url())
4408
self.assertEqual(response.status_code, 302)
4409
self.assertURLEqual(
4331
4413
post_data.pop('_addanother')
4333
4415
def test_add_view(self):
4336
4418
self.assertEqual(response.status_code, 200)
4338
4420
# Check the form action.
4339
form_action = """<form enctype="multipart/form-data" action="?%s" method="post" id="user_form">""" % self.get_preserved_filters_querystring()
4340
self.assertContains(response, form_action, count=1)
4421
form_action = re.search(
4422
'<form enctype="multipart/form-data" action="(.*?)" method="post" id="user_form".*?>',
4423
force_text(response.content)
4425
self.assertURLEqual(form_action.group(1), '?%s' % self.get_preserved_filters_querystring())
4342
# Test redirect on "Save".
4344
4428
'username': 'dummy',
4345
4429
'password1': 'test',
4346
4430
'password2': 'test',
4433
# Test redirect on "Save".
4349
4434
post_data['_save'] = 1
4350
4435
response = self.client.post(self.get_add_url(), data=post_data)
4351
self.assertRedirects(response, self.get_change_url(User.objects.latest('pk').pk))
4436
self.assertEqual(response.status_code, 302)
4437
self.assertURLEqual(
4439
self.get_change_url(User.objects.latest('pk').pk)
4352
4441
post_data.pop('_save')
4354
4443
# Test redirect on "Save and continue".
4355
4444
post_data['username'] = 'dummy2'
4356
4445
post_data['_continue'] = 1
4357
4446
response = self.client.post(self.get_add_url(), data=post_data)
4358
self.assertRedirects(response, self.get_change_url(User.objects.latest('pk').pk))
4447
self.assertEqual(response.status_code, 302)
4448
self.assertURLEqual(
4450
self.get_change_url(User.objects.latest('pk').pk)
4359
4452
post_data.pop('_continue')
4361
4454
# Test redirect on "Save and add new".
4362
4455
post_data['username'] = 'dummy3'
4363
4456
post_data['_addanother'] = 1
4364
4457
response = self.client.post(self.get_add_url(), data=post_data)
4365
self.assertRedirects(response, self.get_add_url())
4458
self.assertEqual(response.status_code, 302)
4459
self.assertURLEqual(
4366
4463
post_data.pop('_addanother')
4368
4465
def test_delete_view(self):
4369
4466
# Test redirect on "Delete".
4370
4467
response = self.client.post(self.get_delete_url(), {'post': 'yes'})
4371
self.assertRedirects(response, self.get_changelist_url())
4468
self.assertEqual(response.status_code, 302)
4469
self.assertURLEqual(
4471
self.get_changelist_url()
4474
def test_url_prefix(self):
4476
'preserved_filters': self.get_preserved_filters_querystring(),
4480
url = reverse('admin:auth_user_changelist', current_app=self.admin_site.name)
4481
self.assertURLEqual(
4482
self.get_changelist_url(),
4483
add_preserved_filters(context, url),
4486
original_prefix = get_script_prefix()
4488
set_script_prefix('/prefix/')
4489
url = reverse('admin:auth_user_changelist', current_app=self.admin_site.name)
4490
self.assertURLEqual(
4491
self.get_changelist_url(),
4492
add_preserved_filters(context, url),
4495
set_script_prefix(original_prefix)
4373
4498
class NamespacedAdminKeepChangeListFiltersTests(AdminKeepChangeListFiltersTests):
4374
4499
admin_site = site2