[py3] Fixed admin_views tests

Also changed several occurrences of 'request' to 'response'.
This commit is contained in:
Claude Paroz 2012-08-14 14:36:11 +02:00
parent d6b8b125fb
commit c2d59e5564
6 changed files with 163 additions and 192 deletions

View File

@ -17,7 +17,7 @@ class AdminLogNode(template.Node):
user_id = self.user user_id = self.user
if not user_id.isdigit(): if not user_id.isdigit():
user_id = context[self.user].id user_id = context[self.user].id
context[self.varname] = LogEntry.objects.filter(user__id__exact=user_id).select_related('content_type', 'user')[:self.limit] context[self.varname] = LogEntry.objects.filter(user__id__exact=user_id).select_related('content_type', 'user')[:int(self.limit)]
return '' return ''
@register.tag @register.tag

View File

@ -148,7 +148,7 @@ class ChangeList(object):
if remove is None: remove = [] if remove is None: remove = []
p = self.params.copy() p = self.params.copy()
for r in remove: for r in remove:
for k in p.keys(): for k in list(p.keys()):
if k.startswith(r): if k.startswith(r):
del p[k] del p[k]
for k, v in new_params.items(): for k, v in new_params.items():

View File

@ -855,7 +855,7 @@ class Model(six.with_metaclass(ModelBase, object)):
} }
# unique_together # unique_together
else: else:
field_labels = map(lambda f: capfirst(opts.get_field(f).verbose_name), unique_check) field_labels = [capfirst(opts.get_field(f).verbose_name) for f in unique_check]
field_labels = get_text_list(field_labels, _('and')) field_labels = get_text_list(field_labels, _('and'))
return _("%(model_name)s with this %(field_label)s already exists.") % { return _("%(model_name)s with this %(field_label)s already exists.") % {
'model_name': six.text_type(model_name), 'model_name': six.text_type(model_name),

View File

@ -66,7 +66,7 @@ def patch_cache_control(response, **kwargs):
# max-age, use the minimum of the two ages. In practice this happens when # max-age, use the minimum of the two ages. In practice this happens when
# a decorator and a piece of middleware both operate on a given view. # a decorator and a piece of middleware both operate on a given view.
if 'max-age' in cc and 'max_age' in kwargs: if 'max-age' in cc and 'max_age' in kwargs:
kwargs['max_age'] = min(cc['max-age'], kwargs['max_age']) kwargs['max_age'] = min(int(cc['max-age']), kwargs['max_age'])
# Allow overriding private caching and vice versa # Allow overriding private caching and vice versa
if 'private' in cc and 'public' in kwargs: if 'private' in cc and 'public' in kwargs:

View File

@ -287,7 +287,7 @@ ustring_re = re.compile("([\u0080-\uffff])")
def javascript_quote(s, quote_double_quotes=False): def javascript_quote(s, quote_double_quotes=False):
def fix(match): def fix(match):
return b"\u%04x" % ord(match.group(1)) return "\\u%04x" % ord(match.group(1))
if type(s) == bytes: if type(s) == bytes:
s = s.decode('utf-8') s = s.decode('utf-8')

View File

@ -30,7 +30,7 @@ from django.template.response import TemplateResponse
from django.test import TestCase from django.test import TestCase
from django.utils import formats, translation, unittest from django.utils import formats, translation, unittest
from django.utils.cache import get_max_age from django.utils.cache import get_max_age
from django.utils.encoding import iri_to_uri from django.utils.encoding import iri_to_uri, smart_bytes
from django.utils.html import escape from django.utils.html import escape
from django.utils.http import urlencode from django.utils.http import urlencode
from django.utils import six from django.utils import six
@ -78,12 +78,22 @@ class AdminViewBasicTest(TestCase):
self.client.logout() self.client.logout()
formats.reset_format_cache() formats.reset_format_cache()
def assertContentBefore(self, response, text1, text2, failing_msg=None):
"""
Testing utility asserting that text1 appears before text2 in response
content.
"""
self.assertEqual(response.status_code, 200)
self.assertTrue(response.content.index(smart_bytes(text1)) < response.content.index(smart_bytes(text2)),
failing_msg
)
def testTrailingSlashRequired(self): def testTrailingSlashRequired(self):
""" """
If you leave off the trailing slash, app should redirect and add it. If you leave off the trailing slash, app should redirect and add it.
""" """
request = self.client.get('/test_admin/%s/admin_views/article/add' % self.urlbit) response = self.client.get('/test_admin/%s/admin_views/article/add' % self.urlbit)
self.assertRedirects(request, self.assertRedirects(response,
'/test_admin/%s/admin_views/article/add/' % self.urlbit, status_code=301 '/test_admin/%s/admin_views/article/add/' % self.urlbit, status_code=301
) )
@ -219,12 +229,10 @@ class AdminViewBasicTest(TestCase):
(column 2 is callable_year in ArticleAdmin) (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('/test_admin/%s/admin_views/article/' % self.urlbit, {'o': 2})
self.assertEqual(response.status_code, 200) self.assertContentBefore(response, 'Oldest content', 'Middle content',
self.assertTrue( "Results of sorting on callable are out of order.")
response.content.index('Oldest content') < response.content.index('Middle content') and self.assertContentBefore(response, 'Middle content', 'Newest content',
response.content.index('Middle content') < response.content.index('Newest content'), "Results of sorting on callable are out of order.")
"Results of sorting on callable are out of order."
)
def testChangeListSortingModel(self): def testChangeListSortingModel(self):
""" """
@ -232,12 +240,10 @@ class AdminViewBasicTest(TestCase):
(colunn 3 is 'model_year' in ArticleAdmin) (colunn 3 is 'model_year' in ArticleAdmin)
""" """
response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'o': '-3'}) response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'o': '-3'})
self.assertEqual(response.status_code, 200) self.assertContentBefore(response, 'Newest content', 'Middle content',
self.assertTrue( "Results of sorting on Model method are out of order.")
response.content.index('Newest content') < response.content.index('Middle content') and self.assertContentBefore(response, 'Middle content', 'Oldest content',
response.content.index('Middle content') < response.content.index('Oldest content'), "Results of sorting on Model method are out of order.")
"Results of sorting on Model method are out of order."
)
def testChangeListSortingModelAdmin(self): def testChangeListSortingModelAdmin(self):
""" """
@ -245,12 +251,10 @@ class AdminViewBasicTest(TestCase):
(colunn 4 is 'modeladmin_year' in ArticleAdmin) (colunn 4 is 'modeladmin_year' in ArticleAdmin)
""" """
response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'o': '4'}) response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'o': '4'})
self.assertEqual(response.status_code, 200) self.assertContentBefore(response, 'Oldest content', 'Middle content',
self.assertTrue( "Results of sorting on ModelAdmin method are out of order.")
response.content.index('Oldest content') < response.content.index('Middle content') and self.assertContentBefore(response, 'Middle content', 'Newest content',
response.content.index('Middle content') < response.content.index('Newest content'), "Results of sorting on ModelAdmin method are out of order.")
"Results of sorting on ModelAdmin method are out of order."
)
def testChangeListSortingMultiple(self): def testChangeListSortingMultiple(self):
p1 = Person.objects.create(name="Chris", gender=1, alive=True) p1 = Person.objects.create(name="Chris", gender=1, alive=True)
@ -262,19 +266,13 @@ class AdminViewBasicTest(TestCase):
# This hard-codes the URL because it'll fail if it runs against the # This hard-codes the URL because it'll fail if it runs against the
# 'admin2' custom admin (which doesn't have the Person model). # '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('/test_admin/admin/admin_views/person/', {'o': '1.2'})
self.assertEqual(response.status_code, 200) self.assertContentBefore(response, link % p3.id, link % p1.id)
self.assertTrue( self.assertContentBefore(response, link % p1.id, link % p2.id)
response.content.index(link % p3.id) < response.content.index(link % p1.id) and
response.content.index(link % p1.id) < response.content.index(link % p2.id)
)
# Sort by gender descending, name # Sort by gender descending, name
response = self.client.get('/test_admin/admin/admin_views/person/', {'o': '-2.1'}) response = self.client.get('/test_admin/admin/admin_views/person/', {'o': '-2.1'})
self.assertEqual(response.status_code, 200) self.assertContentBefore(response, link % p2.id, link % p3.id)
self.assertTrue( self.assertContentBefore(response, link % p3.id, link % p1.id)
response.content.index(link % p2.id) < response.content.index(link % p3.id) and
response.content.index(link % p3.id) < response.content.index(link % p1.id)
)
def testChangeListSortingPreserveQuerySetOrdering(self): def testChangeListSortingPreserveQuerySetOrdering(self):
""" """
@ -291,11 +289,8 @@ class AdminViewBasicTest(TestCase):
# This hard-codes the URL because it'll fail if it runs against the # This hard-codes the URL because it'll fail if it runs against the
# 'admin2' custom admin (which doesn't have the Person model). # 'admin2' custom admin (which doesn't have the Person model).
response = self.client.get('/test_admin/admin/admin_views/person/', {}) response = self.client.get('/test_admin/admin/admin_views/person/', {})
self.assertEqual(response.status_code, 200) self.assertContentBefore(response, link % p3.id, link % p2.id)
self.assertTrue( self.assertContentBefore(response, link % p2.id, link % p1.id)
response.content.index(link % p3.id) < response.content.index(link % p2.id) and
response.content.index(link % p2.id) < response.content.index(link % p1.id)
)
def testChangeListSortingModelMeta(self): def testChangeListSortingModelMeta(self):
# Test ordering on Model Meta is respected # Test ordering on Model Meta is respected
@ -305,17 +300,11 @@ class AdminViewBasicTest(TestCase):
link = '<a href="%s/' link = '<a href="%s/'
response = self.client.get('/test_admin/admin/admin_views/language/', {}) response = self.client.get('/test_admin/admin/admin_views/language/', {})
self.assertEqual(response.status_code, 200) self.assertContentBefore(response, link % l2.pk, link % l1.pk)
self.assertTrue(
response.content.index(link % l2.pk) < response.content.index(link % l1.pk)
)
# Test we can override with query string # Test we can override with query string
response = self.client.get('/test_admin/admin/admin_views/language/', {'o':'-1'}) response = self.client.get('/test_admin/admin/admin_views/language/', {'o':'-1'})
self.assertEqual(response.status_code, 200) self.assertContentBefore(response, link % l1.pk, link % l2.pk)
self.assertTrue(
response.content.index(link % l1.pk) < response.content.index(link % l2.pk)
)
def testChangeListSortingOverrideModelAdmin(self): def testChangeListSortingOverrideModelAdmin(self):
# Test ordering on Model Admin is respected, and overrides Model Meta # Test ordering on Model Admin is respected, and overrides Model Meta
@ -325,10 +314,7 @@ class AdminViewBasicTest(TestCase):
link = '<a href="%s/' link = '<a href="%s/'
response = self.client.get('/test_admin/admin/admin_views/podcast/', {}) response = self.client.get('/test_admin/admin/admin_views/podcast/', {})
self.assertEqual(response.status_code, 200) self.assertContentBefore(response, link % p1.pk, link % p2.pk)
self.assertTrue(
response.content.index(link % p1.pk) < response.content.index(link % p2.pk)
)
def testMultipleSortSameField(self): def testMultipleSortSameField(self):
# Check that we get the columns we expect if we have two columns # Check that we get the columns we expect if we have two columns
@ -339,17 +325,13 @@ class AdminViewBasicTest(TestCase):
link = '<a href="%s/' link = '<a href="%s/'
response = self.client.get('/test_admin/admin/admin_views/podcast/', {}) response = self.client.get('/test_admin/admin/admin_views/podcast/', {})
self.assertEqual(response.status_code, 200) self.assertContentBefore(response, link % p1.pk, link % p2.pk)
self.assertTrue(
response.content.index(link % p1.pk) < response.content.index(link % p2.pk)
)
p1 = ComplexSortedPerson.objects.create(name="Bob", age=10) p1 = ComplexSortedPerson.objects.create(name="Bob", age=10)
p2 = ComplexSortedPerson.objects.create(name="Amy", age=20) p2 = ComplexSortedPerson.objects.create(name="Amy", age=20)
link = '<a href="%s/' link = '<a href="%s/'
response = self.client.get('/test_admin/admin/admin_views/complexsortedperson/', {}) response = self.client.get('/test_admin/admin/admin_views/complexsortedperson/', {})
self.assertEqual(response.status_code, 200)
# Should have 5 columns (including action checkbox col) # Should have 5 columns (including action checkbox col)
self.assertContains(response, '<th scope="col"', count=5) self.assertContains(response, '<th scope="col"', count=5)
@ -357,14 +339,10 @@ class AdminViewBasicTest(TestCase):
self.assertContains(response, 'Colored name') self.assertContains(response, 'Colored name')
# Check order # Check order
self.assertTrue( self.assertContentBefore(response, 'Name', 'Colored name')
response.content.index('Name') < response.content.index('Colored name')
)
# Check sorting - should be by name # Check sorting - should be by name
self.assertTrue( self.assertContentBefore(response, link % p2.id, link % p1.id)
response.content.index(link % p2.id) < response.content.index(link % p1.id)
)
def testSortIndicatorsAdminOrder(self): def testSortIndicatorsAdminOrder(self):
""" """
@ -389,8 +367,8 @@ class AdminViewBasicTest(TestCase):
# the implicit 'action_checkbox' and 1 being the column 'stuff'. # the implicit 'action_checkbox' and 1 being the column 'stuff'.
self.assertEqual(response.context['cl'].get_ordering_field_columns(), {2: 'asc'}) self.assertEqual(response.context['cl'].get_ordering_field_columns(), {2: 'asc'})
# Check order of records. # Check order of records.
self.assertTrue(response.content.index('The First Item') < self.assertContentBefore(response, 'The First Item', 'The Middle Item')
response.content.index('The Middle Item') < response.content.index('The Last Item')) self.assertContentBefore(response, 'The Middle Item', 'The Last Item')
def testLimitedFilter(self): def testLimitedFilter(self):
"""Ensure admin changelist filters do not contain objects excluded via limit_choices_to. """Ensure admin changelist filters do not contain objects excluded via limit_choices_to.
@ -480,12 +458,9 @@ class AdminViewBasicTest(TestCase):
has been used in the choices option of a field. has been used in the choices option of a field.
""" """
response = self.client.get('/test_admin/%s/admin_views/fabric/' % self.urlbit) response = self.client.get('/test_admin/%s/admin_views/fabric/' % self.urlbit)
self.assertEqual(response.status_code, 200) fail_msg = "Changelist table isn't showing the right human-readable values set by a model field 'choices' option named group."
self.assertTrue( self.assertContains(response, '<a href="1/">Horizontal</a>', msg_prefix=fail_msg, html=True)
'<a href="1/">Horizontal</a>' in response.content and self.assertContains(response, '<a href="2/">Vertical</a>', msg_prefix=fail_msg, html=True)
'<a href="2/">Vertical</a>' in response.content,
"Changelist table isn't showing the right human-readable values set by a model field 'choices' option named group."
)
def testNamedGroupFieldChoicesFilter(self): def testNamedGroupFieldChoicesFilter(self):
""" """
@ -493,13 +468,12 @@ class AdminViewBasicTest(TestCase):
been used in the choices option of a model field. 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('/test_admin/%s/admin_views/fabric/' % self.urlbit)
self.assertEqual(response.status_code, 200) fail_msg = "Changelist filter isn't showing options contained inside a model field 'choices' option named group."
self.assertContains(response, '<div id="changelist-filter">') self.assertContains(response, '<div id="changelist-filter">')
self.assertTrue( self.assertContains(response,
'<a href="?surface__exact=x">Horizontal</a>' in response.content and '<a href="?surface__exact=x">Horizontal</a>', msg_prefix=fail_msg, html=True)
'<a href="?surface__exact=y">Vertical</a>' in response.content, self.assertContains(response,
"Changelist filter isn't showing options contained inside a model field 'choices' option named group." '<a href="?surface__exact=y">Vertical</a>', msg_prefix=fail_msg, html=True)
)
def testChangeListNullBooleanDisplay(self): def testChangeListNullBooleanDisplay(self):
Post.objects.create(public=None) Post.objects.create(public=None)
@ -590,8 +564,8 @@ class AdminViewBasicTest(TestCase):
user.save() user.save()
response = self.client.get('/test_admin/admin/') response = self.client.get('/test_admin/admin/')
self.assertFalse(reverse('admin:password_change') in response.content, self.assertNotContains(response, reverse('admin:password_change'),
msg='The "change password" link should not be displayed if a user does not have a usable password.') msg_prefix='The "change password" link should not be displayed if a user does not have a usable password.')
def test_change_view_with_show_delete_extra_context(self): def test_change_view_with_show_delete_extra_context(self):
""" """
@ -618,7 +592,7 @@ class AdminViewFormUrlTest(TestCase):
def testChangeFormUrlHasCorrectValue(self): def testChangeFormUrlHasCorrectValue(self):
""" """
Tests whether change_view has form_url in request.context 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('/test_admin/%s/admin_views/section/1/' % self.urlbit)
self.assertTrue('form_url' in response.context, msg='form_url not present in response.context') self.assertTrue('form_url' in response.context, msg='form_url not present in response.context')
@ -755,34 +729,34 @@ class CustomModelAdminTest(AdminViewBasicTest):
def testCustomAdminSiteLoginTemplate(self): def testCustomAdminSiteLoginTemplate(self):
self.client.logout() self.client.logout()
request = self.client.get('/test_admin/admin2/') response = self.client.get('/test_admin/admin2/')
self.assertIsInstance(request, TemplateResponse) self.assertIsInstance(response, TemplateResponse)
self.assertTemplateUsed(request, 'custom_admin/login.html') self.assertTemplateUsed(response, 'custom_admin/login.html')
self.assertTrue('Hello from a custom login template' in request.content) self.assertContains(response, 'Hello from a custom login template')
def testCustomAdminSiteLogoutTemplate(self): def testCustomAdminSiteLogoutTemplate(self):
request = self.client.get('/test_admin/admin2/logout/') response = self.client.get('/test_admin/admin2/logout/')
self.assertIsInstance(request, TemplateResponse) self.assertIsInstance(response, TemplateResponse)
self.assertTemplateUsed(request, 'custom_admin/logout.html') self.assertTemplateUsed(response, 'custom_admin/logout.html')
self.assertTrue('Hello from a custom logout template' in request.content) self.assertContains(response, 'Hello from a custom logout template')
def testCustomAdminSiteIndexViewAndTemplate(self): def testCustomAdminSiteIndexViewAndTemplate(self):
request = self.client.get('/test_admin/admin2/') response = self.client.get('/test_admin/admin2/')
self.assertIsInstance(request, TemplateResponse) self.assertIsInstance(response, TemplateResponse)
self.assertTemplateUsed(request, 'custom_admin/index.html') self.assertTemplateUsed(response, 'custom_admin/index.html')
self.assertTrue('Hello from a custom index template *bar*' in request.content) self.assertContains(response, 'Hello from a custom index template *bar*')
def testCustomAdminSitePasswordChangeTemplate(self): def testCustomAdminSitePasswordChangeTemplate(self):
request = self.client.get('/test_admin/admin2/password_change/') response = self.client.get('/test_admin/admin2/password_change/')
self.assertIsInstance(request, TemplateResponse) self.assertIsInstance(response, TemplateResponse)
self.assertTemplateUsed(request, 'custom_admin/password_change_form.html') self.assertTemplateUsed(response, 'custom_admin/password_change_form.html')
self.assertTrue('Hello from a custom password change form template' in request.content) self.assertContains(response, 'Hello from a custom password change form template')
def testCustomAdminSitePasswordChangeDoneTemplate(self): def testCustomAdminSitePasswordChangeDoneTemplate(self):
request = self.client.get('/test_admin/admin2/password_change/done/') response = self.client.get('/test_admin/admin2/password_change/done/')
self.assertIsInstance(request, TemplateResponse) self.assertIsInstance(response, TemplateResponse)
self.assertTemplateUsed(request, 'custom_admin/password_change_done.html') self.assertTemplateUsed(response, 'custom_admin/password_change_done.html')
self.assertTrue('Hello from a custom password change done template' in request.content) self.assertContains(response, 'Hello from a custom password change done template')
def testCustomAdminSiteView(self): def testCustomAdminSiteView(self):
self.client.login(username='super', password='secret') self.client.login(username='super', password='secret')
@ -885,16 +859,16 @@ class AdminViewPermissionsTest(TestCase):
a 200 status code. a 200 status code.
""" """
# Super User # Super User
request = self.client.get('/test_admin/admin/') response = self.client.get('/test_admin/admin/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/', self.super_login) login = self.client.post('/test_admin/admin/', self.super_login)
self.assertRedirects(login, '/test_admin/admin/') self.assertRedirects(login, '/test_admin/admin/')
self.assertFalse(login.context) self.assertFalse(login.context)
self.client.get('/test_admin/admin/logout/') self.client.get('/test_admin/admin/logout/')
# Test if user enters e-mail address # Test if user enters e-mail address
request = self.client.get('/test_admin/admin/') response = self.client.get('/test_admin/admin/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/', self.super_email_login) login = self.client.post('/test_admin/admin/', self.super_email_login)
self.assertContains(login, "Your e-mail address is not your username") self.assertContains(login, "Your e-mail address is not your username")
# only correct passwords get a username hint # only correct passwords get a username hint
@ -907,47 +881,47 @@ class AdminViewPermissionsTest(TestCase):
self.assertContains(login, ERROR_MESSAGE) self.assertContains(login, ERROR_MESSAGE)
# Add User # Add User
request = self.client.get('/test_admin/admin/') response = self.client.get('/test_admin/admin/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/', self.adduser_login) login = self.client.post('/test_admin/admin/', self.adduser_login)
self.assertRedirects(login, '/test_admin/admin/') self.assertRedirects(login, '/test_admin/admin/')
self.assertFalse(login.context) self.assertFalse(login.context)
self.client.get('/test_admin/admin/logout/') self.client.get('/test_admin/admin/logout/')
# Change User # Change User
request = self.client.get('/test_admin/admin/') response = self.client.get('/test_admin/admin/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/', self.changeuser_login) login = self.client.post('/test_admin/admin/', self.changeuser_login)
self.assertRedirects(login, '/test_admin/admin/') self.assertRedirects(login, '/test_admin/admin/')
self.assertFalse(login.context) self.assertFalse(login.context)
self.client.get('/test_admin/admin/logout/') self.client.get('/test_admin/admin/logout/')
# Delete User # Delete User
request = self.client.get('/test_admin/admin/') response = self.client.get('/test_admin/admin/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/', self.deleteuser_login) login = self.client.post('/test_admin/admin/', self.deleteuser_login)
self.assertRedirects(login, '/test_admin/admin/') self.assertRedirects(login, '/test_admin/admin/')
self.assertFalse(login.context) self.assertFalse(login.context)
self.client.get('/test_admin/admin/logout/') self.client.get('/test_admin/admin/logout/')
# Regular User should not be able to login. # Regular User should not be able to login.
request = self.client.get('/test_admin/admin/') response = self.client.get('/test_admin/admin/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/', self.joepublic_login) login = self.client.post('/test_admin/admin/', self.joepublic_login)
self.assertEqual(login.status_code, 200) self.assertEqual(login.status_code, 200)
self.assertContains(login, ERROR_MESSAGE) self.assertContains(login, ERROR_MESSAGE)
# Requests without username should not return 500 errors. # Requests without username should not return 500 errors.
request = self.client.get('/test_admin/admin/') response = self.client.get('/test_admin/admin/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/', self.no_username_login) login = self.client.post('/test_admin/admin/', self.no_username_login)
self.assertEqual(login.status_code, 200) self.assertEqual(login.status_code, 200)
form = login.context[0].get('form') form = login.context[0].get('form')
self.assertEqual(form.errors['username'][0], 'This field is required.') self.assertEqual(form.errors['username'][0], 'This field is required.')
def testLoginSuccessfullyRedirectsToOriginalUrl(self): def testLoginSuccessfullyRedirectsToOriginalUrl(self):
request = self.client.get('/test_admin/admin/') response = self.client.get('/test_admin/admin/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
query_string = 'the-answer=42' query_string = 'the-answer=42'
redirect_url = '/test_admin/admin/?%s' % query_string redirect_url = '/test_admin/admin/?%s' % query_string
new_next = {REDIRECT_FIELD_NAME: redirect_url} new_next = {REDIRECT_FIELD_NAME: redirect_url}
@ -967,8 +941,8 @@ class AdminViewPermissionsTest(TestCase):
self.client.post('/test_admin/admin/', self.changeuser_login) self.client.post('/test_admin/admin/', self.changeuser_login)
# make sure the view removes test cookie # make sure the view removes test cookie
self.assertEqual(self.client.session.test_cookie_worked(), False) self.assertEqual(self.client.session.test_cookie_worked(), False)
request = self.client.get('/test_admin/admin/admin_views/article/add/') response = self.client.get('/test_admin/admin/admin_views/article/add/')
self.assertEqual(request.status_code, 403) self.assertEqual(response.status_code, 403)
# Try POST just to make sure # Try POST just to make sure
post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict) post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict)
self.assertEqual(post.status_code, 403) self.assertEqual(post.status_code, 403)
@ -979,10 +953,9 @@ class AdminViewPermissionsTest(TestCase):
self.client.get('/test_admin/admin/') self.client.get('/test_admin/admin/')
self.client.post('/test_admin/admin/', self.adduser_login) self.client.post('/test_admin/admin/', self.adduser_login)
addpage = self.client.get('/test_admin/admin/admin_views/article/add/') addpage = self.client.get('/test_admin/admin/admin_views/article/add/')
self.assertEqual(addpage.status_code, 200)
change_list_link = '&rsaquo; <a href="/test_admin/admin/admin_views/article/">Articles</a>' change_list_link = '&rsaquo; <a href="/test_admin/admin/admin_views/article/">Articles</a>'
self.assertFalse(change_list_link in addpage.content, self.assertNotContains(addpage, change_list_link,
'User restricted to add permission is given link to change list view in breadcrumbs.') 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) post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict)
self.assertRedirects(post, '/test_admin/admin/') self.assertRedirects(post, '/test_admin/admin/')
self.assertEqual(Article.objects.all().count(), 4) self.assertEqual(Article.objects.all().count(), 4)
@ -994,9 +967,8 @@ class AdminViewPermissionsTest(TestCase):
self.client.get('/test_admin/admin/') self.client.get('/test_admin/admin/')
self.client.post('/test_admin/admin/', self.super_login) self.client.post('/test_admin/admin/', self.super_login)
addpage = self.client.get('/test_admin/admin/admin_views/article/add/') addpage = self.client.get('/test_admin/admin/admin_views/article/add/')
self.assertEqual(addpage.status_code, 200) self.assertContains(addpage, change_list_link,
self.assertFalse(change_list_link not in addpage.content, msg_prefix='Unrestricted user is not given link to change list view in breadcrumbs.')
'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) post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict)
self.assertRedirects(post, '/test_admin/admin/admin_views/article/') self.assertRedirects(post, '/test_admin/admin/admin_views/article/')
self.assertEqual(Article.objects.all().count(), 5) self.assertEqual(Article.objects.all().count(), 5)
@ -1022,10 +994,10 @@ class AdminViewPermissionsTest(TestCase):
# add user shoud not be able to view the list of article or change any of them # add user shoud not be able to view the list of article or change any of them
self.client.get('/test_admin/admin/') self.client.get('/test_admin/admin/')
self.client.post('/test_admin/admin/', self.adduser_login) self.client.post('/test_admin/admin/', self.adduser_login)
request = self.client.get('/test_admin/admin/admin_views/article/') response = self.client.get('/test_admin/admin/admin_views/article/')
self.assertEqual(request.status_code, 403) self.assertEqual(response.status_code, 403)
request = self.client.get('/test_admin/admin/admin_views/article/1/') response = self.client.get('/test_admin/admin/admin_views/article/1/')
self.assertEqual(request.status_code, 403) self.assertEqual(response.status_code, 403)
post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict) post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict)
self.assertEqual(post.status_code, 403) self.assertEqual(post.status_code, 403)
self.client.get('/test_admin/admin/logout/') self.client.get('/test_admin/admin/logout/')
@ -1033,10 +1005,10 @@ class AdminViewPermissionsTest(TestCase):
# change user can view all items and edit them # change user can view all items and edit them
self.client.get('/test_admin/admin/') self.client.get('/test_admin/admin/')
self.client.post('/test_admin/admin/', self.changeuser_login) self.client.post('/test_admin/admin/', self.changeuser_login)
request = self.client.get('/test_admin/admin/admin_views/article/') response = self.client.get('/test_admin/admin/admin_views/article/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
request = self.client.get('/test_admin/admin/admin_views/article/1/') response = self.client.get('/test_admin/admin/admin_views/article/1/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict) post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict)
self.assertRedirects(post, '/test_admin/admin/admin_views/article/') self.assertRedirects(post, '/test_admin/admin/admin_views/article/')
self.assertEqual(Article.objects.get(pk=1).content, '<p>edited article</p>') self.assertEqual(Article.objects.get(pk=1).content, '<p>edited article</p>')
@ -1058,33 +1030,33 @@ class AdminViewPermissionsTest(TestCase):
RowLevelChangePermissionModel.objects.create(id=2, name="even id") RowLevelChangePermissionModel.objects.create(id=2, name="even id")
for login_dict in [self.super_login, self.changeuser_login, self.adduser_login, self.deleteuser_login]: for login_dict in [self.super_login, self.changeuser_login, self.adduser_login, self.deleteuser_login]:
self.client.post('/test_admin/admin/', login_dict) self.client.post('/test_admin/admin/', login_dict)
request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/') response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/')
self.assertEqual(request.status_code, 403) self.assertEqual(response.status_code, 403)
request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', {'name': 'changed'}) response = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', {'name': 'changed'})
self.assertEqual(RowLevelChangePermissionModel.objects.get(id=1).name, 'odd id') self.assertEqual(RowLevelChangePermissionModel.objects.get(id=1).name, 'odd id')
self.assertEqual(request.status_code, 403) self.assertEqual(response.status_code, 403)
request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/') response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed'}) response = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed'})
self.assertEqual(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed') self.assertEqual(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed')
self.assertRedirects(request, '/test_admin/admin/') self.assertRedirects(response, '/test_admin/admin/')
self.client.get('/test_admin/admin/logout/') self.client.get('/test_admin/admin/logout/')
for login_dict in [self.joepublic_login, self.no_username_login]: for login_dict in [self.joepublic_login, self.no_username_login]:
self.client.post('/test_admin/admin/', login_dict) self.client.post('/test_admin/admin/', login_dict)
request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/') response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertContains(request, 'login-form') self.assertContains(response, 'login-form')
request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', {'name': 'changed'}) response = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', {'name': 'changed'})
self.assertEqual(RowLevelChangePermissionModel.objects.get(id=1).name, 'odd id') self.assertEqual(RowLevelChangePermissionModel.objects.get(id=1).name, 'odd id')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertContains(request, 'login-form') self.assertContains(response, 'login-form')
request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/') response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertContains(request, 'login-form') self.assertContains(response, 'login-form')
request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed again'}) response = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed again'})
self.assertEqual(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed') self.assertEqual(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertContains(request, 'login-form') self.assertContains(response, 'login-form')
self.client.get('/test_admin/admin/logout/') self.client.get('/test_admin/admin/logout/')
def testConditionallyShowAddSectionLink(self): def testConditionallyShowAddSectionLink(self):
@ -1114,14 +1086,13 @@ class AdminViewPermissionsTest(TestCase):
self.client.post('/test_admin/admin/', self.super_login) self.client.post('/test_admin/admin/', self.super_login)
# Test custom change list template with custom extra context # Test custom change list template with custom extra context
request = self.client.get('/test_admin/admin/admin_views/customarticle/') response = self.client.get('/test_admin/admin/admin_views/customarticle/')
self.assertEqual(request.status_code, 200) self.assertContains(response, "var hello = 'Hello!';")
self.assertTrue("var hello = 'Hello!';" in request.content) self.assertTemplateUsed(response, 'custom_admin/change_list.html')
self.assertTemplateUsed(request, 'custom_admin/change_list.html')
# Test custom add form template # Test custom add form template
request = self.client.get('/test_admin/admin/admin_views/customarticle/add/') response = self.client.get('/test_admin/admin/admin_views/customarticle/add/')
self.assertTemplateUsed(request, 'custom_admin/add_form.html') self.assertTemplateUsed(response, 'custom_admin/add_form.html')
# Add an article so we can test delete, change, and history views # 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('/test_admin/admin/admin_views/customarticle/add/', {
@ -1135,18 +1106,18 @@ class AdminViewPermissionsTest(TestCase):
# Test custom delete, change, and object history templates # Test custom delete, change, and object history templates
# Test custom change form template # Test custom change form template
request = self.client.get('/test_admin/admin/admin_views/customarticle/%d/' % article_pk) response = self.client.get('/test_admin/admin/admin_views/customarticle/%d/' % article_pk)
self.assertTemplateUsed(request, 'custom_admin/change_form.html') self.assertTemplateUsed(response, 'custom_admin/change_form.html')
request = self.client.get('/test_admin/admin/admin_views/customarticle/%d/delete/' % article_pk) response = self.client.get('/test_admin/admin/admin_views/customarticle/%d/delete/' % article_pk)
self.assertTemplateUsed(request, 'custom_admin/delete_confirmation.html') self.assertTemplateUsed(response, 'custom_admin/delete_confirmation.html')
request = self.client.post('/test_admin/admin/admin_views/customarticle/', data={ response = self.client.post('/test_admin/admin/admin_views/customarticle/', data={
'index': 0, 'index': 0,
'action': ['delete_selected'], 'action': ['delete_selected'],
'_selected_action': ['1'], '_selected_action': ['1'],
}) })
self.assertTemplateUsed(request, 'custom_admin/delete_selected_confirmation.html') self.assertTemplateUsed(response, 'custom_admin/delete_selected_confirmation.html')
request = self.client.get('/test_admin/admin/admin_views/customarticle/%d/history/' % article_pk) response = self.client.get('/test_admin/admin/admin_views/customarticle/%d/history/' % article_pk)
self.assertTemplateUsed(request, 'custom_admin/object_history.html') self.assertTemplateUsed(response, 'custom_admin/object_history.html')
self.client.get('/test_admin/admin/logout/') self.client.get('/test_admin/admin/logout/')
@ -1158,8 +1129,8 @@ class AdminViewPermissionsTest(TestCase):
# add user shoud not be able to delete articles # add user shoud not be able to delete articles
self.client.get('/test_admin/admin/') self.client.get('/test_admin/admin/')
self.client.post('/test_admin/admin/', self.adduser_login) self.client.post('/test_admin/admin/', self.adduser_login)
request = self.client.get('/test_admin/admin/admin_views/article/1/delete/') response = self.client.get('/test_admin/admin/admin_views/article/1/delete/')
self.assertEqual(request.status_code, 403) self.assertEqual(response.status_code, 403)
post = self.client.post('/test_admin/admin/admin_views/article/1/delete/', delete_dict) post = self.client.post('/test_admin/admin/admin_views/article/1/delete/', delete_dict)
self.assertEqual(post.status_code, 403) self.assertEqual(post.status_code, 403)
self.assertEqual(Article.objects.all().count(), 3) self.assertEqual(Article.objects.all().count(), 3)
@ -1246,9 +1217,9 @@ class AdminViewDeletedObjectsTest(TestCase):
Objects should be nested to display the relationships that Objects should be nested to display the relationships that
cause them to be scheduled for deletion. cause them to be scheduled for deletion.
""" """
pattern = re.compile(r"""<li>Plot: <a href=".+/admin_views/plot/1/">World Domination</a>\s*<ul>\s*<li>Plot details: <a href=".+/admin_views/plotdetails/1/">almost finished</a>""") pattern = re.compile(br"""<li>Plot: <a href=".+/admin_views/plot/1/">World Domination</a>\s*<ul>\s*<li>Plot details: <a href=".+/admin_views/plotdetails/1/">almost finished</a>""")
response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(1)) response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(1))
self.assertTrue(pattern.search(response.content)) self.assertRegexpMatches(response.content, pattern)
def test_cyclic(self): def test_cyclic(self):
""" """
@ -1407,9 +1378,9 @@ class AdminViewStringPrimaryKeyTest(TestCase):
logentry.content_type = None logentry.content_type = None
logentry.save() logentry.save()
counted_presence_before = response.content.count(should_contain) counted_presence_before = response.content.count(smart_bytes(should_contain))
response = self.client.get('/test_admin/admin/') response = self.client.get('/test_admin/admin/')
counted_presence_after = response.content.count(should_contain) counted_presence_after = response.content.count(smart_bytes(should_contain))
self.assertEqual(counted_presence_before - 1, self.assertEqual(counted_presence_before - 1,
counted_presence_after) counted_presence_after)
@ -1512,8 +1483,8 @@ class SecureViewTests(TestCase):
self.assertTemplateUsed(response, 'admin/login.html') self.assertTemplateUsed(response, 'admin/login.html')
def test_secure_view_login_successfully_redirects_to_original_url(self): def test_secure_view_login_successfully_redirects_to_original_url(self):
request = self.client.get('/test_admin/admin/secure-view/') response = self.client.get('/test_admin/admin/secure-view/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
query_string = 'the-answer=42' query_string = 'the-answer=42'
redirect_url = '/test_admin/admin/secure-view/?%s' % query_string redirect_url = '/test_admin/admin/secure-view/?%s' % query_string
new_next = {REDIRECT_FIELD_NAME: redirect_url} new_next = {REDIRECT_FIELD_NAME: redirect_url}
@ -1529,8 +1500,8 @@ class SecureViewTests(TestCase):
a 200 status code. a 200 status code.
""" """
# Super User # Super User
request = self.client.get('/test_admin/admin/secure-view/') response = self.client.get('/test_admin/admin/secure-view/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/secure-view/', self.super_login) login = self.client.post('/test_admin/admin/secure-view/', self.super_login)
self.assertRedirects(login, '/test_admin/admin/secure-view/') self.assertRedirects(login, '/test_admin/admin/secure-view/')
self.assertFalse(login.context) self.assertFalse(login.context)
@ -1539,8 +1510,8 @@ class SecureViewTests(TestCase):
self.assertEqual(self.client.session.test_cookie_worked(), False) self.assertEqual(self.client.session.test_cookie_worked(), False)
# Test if user enters e-mail address # Test if user enters e-mail address
request = self.client.get('/test_admin/admin/secure-view/') response = self.client.get('/test_admin/admin/secure-view/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/secure-view/', self.super_email_login) login = self.client.post('/test_admin/admin/secure-view/', self.super_email_login)
self.assertContains(login, "Your e-mail address is not your username") self.assertContains(login, "Your e-mail address is not your username")
# only correct passwords get a username hint # only correct passwords get a username hint
@ -1553,32 +1524,32 @@ class SecureViewTests(TestCase):
self.assertContains(login, ERROR_MESSAGE) self.assertContains(login, ERROR_MESSAGE)
# Add User # Add User
request = self.client.get('/test_admin/admin/secure-view/') response = self.client.get('/test_admin/admin/secure-view/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/secure-view/', self.adduser_login) login = self.client.post('/test_admin/admin/secure-view/', self.adduser_login)
self.assertRedirects(login, '/test_admin/admin/secure-view/') self.assertRedirects(login, '/test_admin/admin/secure-view/')
self.assertFalse(login.context) self.assertFalse(login.context)
self.client.get('/test_admin/admin/logout/') self.client.get('/test_admin/admin/logout/')
# Change User # Change User
request = self.client.get('/test_admin/admin/secure-view/') response = self.client.get('/test_admin/admin/secure-view/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/secure-view/', self.changeuser_login) login = self.client.post('/test_admin/admin/secure-view/', self.changeuser_login)
self.assertRedirects(login, '/test_admin/admin/secure-view/') self.assertRedirects(login, '/test_admin/admin/secure-view/')
self.assertFalse(login.context) self.assertFalse(login.context)
self.client.get('/test_admin/admin/logout/') self.client.get('/test_admin/admin/logout/')
# Delete User # Delete User
request = self.client.get('/test_admin/admin/secure-view/') response = self.client.get('/test_admin/admin/secure-view/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/secure-view/', self.deleteuser_login) login = self.client.post('/test_admin/admin/secure-view/', self.deleteuser_login)
self.assertRedirects(login, '/test_admin/admin/secure-view/') self.assertRedirects(login, '/test_admin/admin/secure-view/')
self.assertFalse(login.context) self.assertFalse(login.context)
self.client.get('/test_admin/admin/logout/') self.client.get('/test_admin/admin/logout/')
# Regular User should not be able to login. # Regular User should not be able to login.
request = self.client.get('/test_admin/admin/secure-view/') response = self.client.get('/test_admin/admin/secure-view/')
self.assertEqual(request.status_code, 200) self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/secure-view/', self.joepublic_login) login = self.client.post('/test_admin/admin/secure-view/', self.joepublic_login)
self.assertEqual(login.status_code, 200) self.assertEqual(login.status_code, 200)
# Login.context is a list of context dicts we just need to check the first one. # Login.context is a list of context dicts we just need to check the first one.
@ -2107,7 +2078,7 @@ class AdminInheritedInlinesTest(TestCase):
foo_user = "foo username" foo_user = "foo username"
bar_user = "bar username" bar_user = "bar username"
name_re = re.compile('name="(.*?)"') name_re = re.compile(b'name="(.*?)"')
# test the add case # test the add case
response = self.client.get('/test_admin/admin/admin_views/persona/add/') response = self.client.get('/test_admin/admin/admin_views/persona/add/')
@ -2214,7 +2185,7 @@ class AdminActionsTest(TestCase):
confirmation = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data) confirmation = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data)
self.assertIsInstance(confirmation, TemplateResponse) self.assertIsInstance(confirmation, TemplateResponse)
self.assertContains(confirmation, "Are you sure you want to delete the selected subscribers?") self.assertContains(confirmation, "Are you sure you want to delete the selected subscribers?")
self.assertTrue(confirmation.content.count(ACTION_CHECKBOX_NAME) == 2) self.assertContains(confirmation, ACTION_CHECKBOX_NAME, count=2)
response = self.client.post('/test_admin/admin/admin_views/subscriber/', delete_confirmation_data) response = self.client.post('/test_admin/admin/admin_views/subscriber/', delete_confirmation_data)
self.assertEqual(Subscriber.objects.count(), 0) self.assertEqual(Subscriber.objects.count(), 0)
@ -2514,7 +2485,7 @@ class AdminInlineFileUploadTest(TestCase):
# to use a NamedTemporaryFile. # to use a NamedTemporaryFile.
tdir = tempfile.gettempdir() tdir = tempfile.gettempdir()
file1 = tempfile.NamedTemporaryFile(suffix=".file1", dir=tdir) file1 = tempfile.NamedTemporaryFile(suffix=".file1", dir=tdir)
file1.write('a' * (2 ** 21)) file1.write(b'a' * (2 ** 21))
filename = file1.name filename = file1.name
file1.close() file1.close()
self.gallery = Gallery(name="Test Gallery") self.gallery = Gallery(name="Test Gallery")
@ -3197,9 +3168,9 @@ class RawIdFieldsTest(TestCase):
country="Spain") country="Spain")
response = self.client.get('/test_admin/admin/admin_views/sketch/add/') response = self.client.get('/test_admin/admin/admin_views/sketch/add/')
# Find the link # Find the link
m = re.search(r'<a href="([^"]*)"[^>]* id="lookup_id_inquisition"', response.content) m = re.search(br'<a href="([^"]*)"[^>]* id="lookup_id_inquisition"', response.content)
self.assertTrue(m) # Got a match self.assertTrue(m) # Got a match
popup_url = m.groups()[0].replace("&amp;", "&") popup_url = m.groups()[0].decode().replace("&amp;", "&")
# Handle relative links # Handle relative links
popup_url = urljoin(response.request['PATH_INFO'], popup_url) popup_url = urljoin(response.request['PATH_INFO'], popup_url)