Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14764 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit dceaa82dec9f97ac77754dfdc737852d8171c8a2 1 parent cd847db
Chris Beaven authored December 01, 2010
13  django/contrib/auth/tests/views.py
@@ -265,7 +265,7 @@ def test_standard_login_url(self):
265 265
         querystring = QueryDict('', mutable=True)
266 266
         querystring['next'] = '/login_required/'
267 267
         self.assertEqual(login_required_url,
268  
-             'http://testserver%s?%s' % (login_url, querystring.urlencode()))
  268
+             'http://testserver%s?%s' % (login_url, querystring.urlencode('/')))
269 269
 
270 270
     def test_remote_login_url(self):
271 271
         login_url = 'http://remote.example.com/login'
@@ -273,7 +273,7 @@ def test_remote_login_url(self):
273 273
         querystring = QueryDict('', mutable=True)
274 274
         querystring['next'] = 'http://testserver/login_required/'
275 275
         self.assertEqual(login_required_url,
276  
-                         '%s?%s' % (login_url, querystring.urlencode()))
  276
+                         '%s?%s' % (login_url, querystring.urlencode('/')))
277 277
 
278 278
     def test_https_login_url(self):
279 279
         login_url = 'https:///login/'
@@ -281,7 +281,7 @@ def test_https_login_url(self):
281 281
         querystring = QueryDict('', mutable=True)
282 282
         querystring['next'] = 'http://testserver/login_required/'
283 283
         self.assertEqual(login_required_url,
284  
-                         '%s?%s' % (login_url, querystring.urlencode()))
  284
+                         '%s?%s' % (login_url, querystring.urlencode('/')))
285 285
 
286 286
     def test_login_url_with_querystring(self):
287 287
         login_url = '/login/?pretty=1'
@@ -289,7 +289,7 @@ def test_login_url_with_querystring(self):
289 289
         querystring = QueryDict('pretty=1', mutable=True)
290 290
         querystring['next'] = '/login_required/'
291 291
         self.assertEqual(login_required_url, 'http://testserver/login/?%s' %
292  
-                         querystring.urlencode())
  292
+                         querystring.urlencode('/'))
293 293
 
294 294
     def test_remote_login_url_with_next_querystring(self):
295 295
         login_url = 'http://remote.example.com/login/'
@@ -298,8 +298,9 @@ def test_remote_login_url_with_next_querystring(self):
298 298
         querystring = QueryDict('', mutable=True)
299 299
         querystring['next'] = 'http://testserver/login_required/'
300 300
         self.assertEqual(login_required_url, '%s?%s' % (login_url,
301  
-                                                    querystring.urlencode()))
302  
-        
  301
+                                                    querystring.urlencode('/')))
  302
+
  303
+
303 304
 class LogoutTest(AuthViewsTestCase):
304 305
     urls = 'django.contrib.auth.tests.urls'
305 306
 
2  django/contrib/auth/views.py
@@ -99,7 +99,7 @@ def redirect_to_login(next, login_url=None,
99 99
     if redirect_field_name:
100 100
         querystring = QueryDict(login_url_parts[4], mutable=True)
101 101
         querystring[redirect_field_name] = next
102  
-        login_url_parts[4] = querystring.urlencode()
  102
+        login_url_parts[4] = querystring.urlencode(safe='/')
103 103
 
104 104
     return HttpResponseRedirect(urlparse.urlunparse(login_url_parts))
105 105
 
25  django/http/__init__.py
@@ -3,7 +3,7 @@
3 3
 import re
4 4
 import time
5 5
 from pprint import pformat
6  
-from urllib import urlencode
  6
+from urllib import urlencode, quote
7 7
 from urlparse import urljoin
8 8
 try:
9 9
     from cStringIO import StringIO
@@ -363,11 +363,30 @@ def copy(self):
363 363
         """Returns a mutable copy of this object."""
364 364
         return self.__deepcopy__({})
365 365
 
366  
-    def urlencode(self):
  366
+    def urlencode(self, safe=None):
  367
+        """
  368
+        Returns an encoded string of all query string arguments.
  369
+
  370
+        :arg safe: Used to specify characters which do not require quoting, for
  371
+            example::
  372
+
  373
+                >>> q = QueryDict('', mutable=True)
  374
+                >>> q['next'] = '/a&b/'
  375
+                >>> q.urlencode()
  376
+                'next=%2Fa%26b%2F'
  377
+                >>> q.urlencode(safe='/')
  378
+                'next=/a%26b/'
  379
+
  380
+        """
367 381
         output = []
  382
+        if safe:
  383
+            encode = lambda k, v: '%s=%s' % ((quote(k, safe), quote(v, safe)))
  384
+        else:
  385
+            encode = lambda k, v: urlencode({k: v})
368 386
         for k, list_ in self.lists():
369 387
             k = smart_str(k, self.encoding)
370  
-            output.extend([urlencode({k: smart_str(v, self.encoding)}) for v in list_])
  388
+            output.extend([encode(k, smart_str(v, self.encoding))
  389
+                           for v in list_])
371 390
         return '&'.join(output)
372 391
 
373 392
 class CompatCookie(SimpleCookie):
26  docs/ref/request-response.txt
@@ -430,14 +430,28 @@ In addition, ``QueryDict`` has the following methods:
430 430
     Like :meth:`items()`, except it includes all values, as a list, for each
431 431
     member of the dictionary. For example::
432 432
 
433  
-         >>> q = QueryDict('a=1&a=2&a=3')
434  
-         >>> q.lists()
435  
-         [(u'a', [u'1', u'2', u'3'])]
  433
+        >>> q = QueryDict('a=1&a=2&a=3')
  434
+        >>> q.lists()
  435
+        [(u'a', [u'1', u'2', u'3'])]
436 436
 
437  
-.. method:: QueryDict.urlencode()
  437
+.. method:: QueryDict.urlencode([safe])
438 438
 
439  
-    Returns a string of the data in query-string format.
440  
-    Example: ``"a=2&b=3&b=5"``.
  439
+    Returns a string of the data in query-string format. Example::
  440
+
  441
+        >>> q = QueryDict('a=2&b=3&b=5')
  442
+        >>> q.urlencode()
  443
+        'a=2&b=3&b=5'
  444
+
  445
+    .. versionchanged:: 1.3
  446
+       The ``safe`` parameter was added.
  447
+
  448
+    Optionally, urlencode can be passed characters which
  449
+    do not require encoding. For example::
  450
+
  451
+        >>> q = QueryDict('', mutable=True)
  452
+        >>> q['next'] = '/a&b/'
  453
+        >>> q.urlencode(safe='/')
  454
+        'next=/a%26b/'
441 455
 
442 456
 HttpResponse objects
443 457
 ====================
10  tests/regressiontests/httpwrappers/tests.py
@@ -71,6 +71,16 @@ def test_single_key_value(self):
71 71
 
72 72
         self.assertEqual(q.urlencode(), 'foo=bar')
73 73
 
  74
+    def test_urlencode(self):
  75
+        q = QueryDict('', mutable=True)
  76
+        q['next'] = '/a&b/'
  77
+        self.assertEqual(q.urlencode(), 'next=%2Fa%26b%2F')
  78
+        self.assertEqual(q.urlencode(safe='/'), 'next=/a%26b/')
  79
+        q = QueryDict('', mutable=True)
  80
+        q['next'] = u'/t\xebst&key/'
  81
+        self.assertEqual(q.urlencode(), 'next=%2Ft%C3%ABst%26key%2F')
  82
+        self.assertEqual(q.urlencode(safe='/'), 'next=/t%C3%ABst%26key/')
  83
+
74 84
     def test_mutable_copy(self):
75 85
         """A copy of a QueryDict is mutable."""
76 86
         q = QueryDict('').copy()

0 notes on commit dceaa82

Please sign in to comment.
Something went wrong with that request. Please try again.