Fixed #14809 -- broken login related tests after r14733.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14764 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Chris Beaven 2010-12-01 22:25:17 +00:00
parent cd847db17f
commit dceaa82dec
5 changed files with 60 additions and 16 deletions

View File

@ -265,7 +265,7 @@ class LoginURLSettings(AuthViewsTestCase):
querystring = QueryDict('', mutable=True) querystring = QueryDict('', mutable=True)
querystring['next'] = '/login_required/' querystring['next'] = '/login_required/'
self.assertEqual(login_required_url, self.assertEqual(login_required_url,
'http://testserver%s?%s' % (login_url, querystring.urlencode())) 'http://testserver%s?%s' % (login_url, querystring.urlencode('/')))
def test_remote_login_url(self): def test_remote_login_url(self):
login_url = 'http://remote.example.com/login' login_url = 'http://remote.example.com/login'
@ -273,7 +273,7 @@ class LoginURLSettings(AuthViewsTestCase):
querystring = QueryDict('', mutable=True) querystring = QueryDict('', mutable=True)
querystring['next'] = 'http://testserver/login_required/' querystring['next'] = 'http://testserver/login_required/'
self.assertEqual(login_required_url, self.assertEqual(login_required_url,
'%s?%s' % (login_url, querystring.urlencode())) '%s?%s' % (login_url, querystring.urlencode('/')))
def test_https_login_url(self): def test_https_login_url(self):
login_url = 'https:///login/' login_url = 'https:///login/'
@ -281,7 +281,7 @@ class LoginURLSettings(AuthViewsTestCase):
querystring = QueryDict('', mutable=True) querystring = QueryDict('', mutable=True)
querystring['next'] = 'http://testserver/login_required/' querystring['next'] = 'http://testserver/login_required/'
self.assertEqual(login_required_url, self.assertEqual(login_required_url,
'%s?%s' % (login_url, querystring.urlencode())) '%s?%s' % (login_url, querystring.urlencode('/')))
def test_login_url_with_querystring(self): def test_login_url_with_querystring(self):
login_url = '/login/?pretty=1' login_url = '/login/?pretty=1'
@ -289,7 +289,7 @@ class LoginURLSettings(AuthViewsTestCase):
querystring = QueryDict('pretty=1', mutable=True) querystring = QueryDict('pretty=1', mutable=True)
querystring['next'] = '/login_required/' querystring['next'] = '/login_required/'
self.assertEqual(login_required_url, 'http://testserver/login/?%s' % self.assertEqual(login_required_url, 'http://testserver/login/?%s' %
querystring.urlencode()) querystring.urlencode('/'))
def test_remote_login_url_with_next_querystring(self): def test_remote_login_url_with_next_querystring(self):
login_url = 'http://remote.example.com/login/' login_url = 'http://remote.example.com/login/'
@ -298,7 +298,8 @@ class LoginURLSettings(AuthViewsTestCase):
querystring = QueryDict('', mutable=True) querystring = QueryDict('', mutable=True)
querystring['next'] = 'http://testserver/login_required/' querystring['next'] = 'http://testserver/login_required/'
self.assertEqual(login_required_url, '%s?%s' % (login_url, self.assertEqual(login_required_url, '%s?%s' % (login_url,
querystring.urlencode())) querystring.urlencode('/')))
class LogoutTest(AuthViewsTestCase): class LogoutTest(AuthViewsTestCase):
urls = 'django.contrib.auth.tests.urls' urls = 'django.contrib.auth.tests.urls'

View File

@ -99,7 +99,7 @@ def redirect_to_login(next, login_url=None,
if redirect_field_name: if redirect_field_name:
querystring = QueryDict(login_url_parts[4], mutable=True) querystring = QueryDict(login_url_parts[4], mutable=True)
querystring[redirect_field_name] = next querystring[redirect_field_name] = next
login_url_parts[4] = querystring.urlencode() login_url_parts[4] = querystring.urlencode(safe='/')
return HttpResponseRedirect(urlparse.urlunparse(login_url_parts)) return HttpResponseRedirect(urlparse.urlunparse(login_url_parts))

View File

@ -3,7 +3,7 @@ import os
import re import re
import time import time
from pprint import pformat from pprint import pformat
from urllib import urlencode from urllib import urlencode, quote
from urlparse import urljoin from urlparse import urljoin
try: try:
from cStringIO import StringIO from cStringIO import StringIO
@ -363,11 +363,30 @@ class QueryDict(MultiValueDict):
"""Returns a mutable copy of this object.""" """Returns a mutable copy of this object."""
return self.__deepcopy__({}) return self.__deepcopy__({})
def urlencode(self): def urlencode(self, safe=None):
"""
Returns an encoded string of all query string arguments.
:arg safe: Used to specify characters which do not require quoting, for
example::
>>> q = QueryDict('', mutable=True)
>>> q['next'] = '/a&b/'
>>> q.urlencode()
'next=%2Fa%26b%2F'
>>> q.urlencode(safe='/')
'next=/a%26b/'
"""
output = [] output = []
if safe:
encode = lambda k, v: '%s=%s' % ((quote(k, safe), quote(v, safe)))
else:
encode = lambda k, v: urlencode({k: v})
for k, list_ in self.lists(): for k, list_ in self.lists():
k = smart_str(k, self.encoding) k = smart_str(k, self.encoding)
output.extend([urlencode({k: smart_str(v, self.encoding)}) for v in list_]) output.extend([encode(k, smart_str(v, self.encoding))
for v in list_])
return '&'.join(output) return '&'.join(output)
class CompatCookie(SimpleCookie): class CompatCookie(SimpleCookie):

View File

@ -434,10 +434,24 @@ In addition, ``QueryDict`` has the following methods:
>>> q.lists() >>> q.lists()
[(u'a', [u'1', u'2', u'3'])] [(u'a', [u'1', u'2', u'3'])]
.. method:: QueryDict.urlencode() .. method:: QueryDict.urlencode([safe])
Returns a string of the data in query-string format. Returns a string of the data in query-string format. Example::
Example: ``"a=2&b=3&b=5"``.
>>> q = QueryDict('a=2&b=3&b=5')
>>> q.urlencode()
'a=2&b=3&b=5'
.. versionchanged:: 1.3
The ``safe`` parameter was added.
Optionally, urlencode can be passed characters which
do not require encoding. For example::
>>> q = QueryDict('', mutable=True)
>>> q['next'] = '/a&b/'
>>> q.urlencode(safe='/')
'next=/a%26b/'
HttpResponse objects HttpResponse objects
==================== ====================

View File

@ -71,6 +71,16 @@ class QueryDictTests(unittest.TestCase):
self.assertEqual(q.urlencode(), 'foo=bar') self.assertEqual(q.urlencode(), 'foo=bar')
def test_urlencode(self):
q = QueryDict('', mutable=True)
q['next'] = '/a&b/'
self.assertEqual(q.urlencode(), 'next=%2Fa%26b%2F')
self.assertEqual(q.urlencode(safe='/'), 'next=/a%26b/')
q = QueryDict('', mutable=True)
q['next'] = u'/t\xebst&key/'
self.assertEqual(q.urlencode(), 'next=%2Ft%C3%ABst%26key%2F')
self.assertEqual(q.urlencode(safe='/'), 'next=/t%C3%ABst%26key/')
def test_mutable_copy(self): def test_mutable_copy(self):
"""A copy of a QueryDict is mutable.""" """A copy of a QueryDict is mutable."""
q = QueryDict('').copy() q = QueryDict('').copy()