Fixed #9351 -- Modified the test client to pass on URL encoded parameters to the underlying views. Thanks to sime for the suggestion.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@9398 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
a53ccc8297
commit
95d8c0619a
|
@ -1,4 +1,5 @@
|
||||||
import urllib
|
import urllib
|
||||||
|
from urlparse import urlparse, urlunparse
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
try:
|
try:
|
||||||
|
@ -260,10 +261,11 @@ class Client(object):
|
||||||
"""
|
"""
|
||||||
Requests a response from the server using GET.
|
Requests a response from the server using GET.
|
||||||
"""
|
"""
|
||||||
|
parsed = urlparse(path)
|
||||||
r = {
|
r = {
|
||||||
'CONTENT_TYPE': 'text/html; charset=utf-8',
|
'CONTENT_TYPE': 'text/html; charset=utf-8',
|
||||||
'PATH_INFO': urllib.unquote(path),
|
'PATH_INFO': urllib.unquote(parsed.path),
|
||||||
'QUERY_STRING': urlencode(data, doseq=True),
|
'QUERY_STRING': urlencode(data, doseq=True) or parsed.query,
|
||||||
'REQUEST_METHOD': 'GET',
|
'REQUEST_METHOD': 'GET',
|
||||||
'wsgi.input': FakePayload('')
|
'wsgi.input': FakePayload('')
|
||||||
}
|
}
|
||||||
|
@ -280,10 +282,12 @@ class Client(object):
|
||||||
else:
|
else:
|
||||||
post_data = data
|
post_data = data
|
||||||
|
|
||||||
|
parsed = urlparse(path)
|
||||||
r = {
|
r = {
|
||||||
'CONTENT_LENGTH': len(post_data),
|
'CONTENT_LENGTH': len(post_data),
|
||||||
'CONTENT_TYPE': content_type,
|
'CONTENT_TYPE': content_type,
|
||||||
'PATH_INFO': urllib.unquote(path),
|
'PATH_INFO': urllib.unquote(parsed.path),
|
||||||
|
'QUERY_STRING': parsed.query,
|
||||||
'REQUEST_METHOD': 'POST',
|
'REQUEST_METHOD': 'POST',
|
||||||
'wsgi.input': FakePayload(post_data),
|
'wsgi.input': FakePayload(post_data),
|
||||||
}
|
}
|
||||||
|
@ -295,10 +299,11 @@ class Client(object):
|
||||||
"""
|
"""
|
||||||
Request a response from the server using HEAD.
|
Request a response from the server using HEAD.
|
||||||
"""
|
"""
|
||||||
|
parsed = urlparse(path)
|
||||||
r = {
|
r = {
|
||||||
'CONTENT_TYPE': 'text/html; charset=utf-8',
|
'CONTENT_TYPE': 'text/html; charset=utf-8',
|
||||||
'PATH_INFO': urllib.unquote(path),
|
'PATH_INFO': urllib.unquote(parsed.path),
|
||||||
'QUERY_STRING': urlencode(data, doseq=True),
|
'QUERY_STRING': urlencode(data, doseq=True) or parsed.query,
|
||||||
'REQUEST_METHOD': 'HEAD',
|
'REQUEST_METHOD': 'HEAD',
|
||||||
'wsgi.input': FakePayload('')
|
'wsgi.input': FakePayload('')
|
||||||
}
|
}
|
||||||
|
@ -310,9 +315,10 @@ class Client(object):
|
||||||
"""
|
"""
|
||||||
Request a response from the server using OPTIONS.
|
Request a response from the server using OPTIONS.
|
||||||
"""
|
"""
|
||||||
|
parsed = urlparse(path)
|
||||||
r = {
|
r = {
|
||||||
'PATH_INFO': urllib.unquote(path),
|
'PATH_INFO': urllib.unquote(parsed.path),
|
||||||
'QUERY_STRING': urlencode(data, doseq=True),
|
'QUERY_STRING': urlencode(data, doseq=True) or parsed.query,
|
||||||
'REQUEST_METHOD': 'OPTIONS',
|
'REQUEST_METHOD': 'OPTIONS',
|
||||||
'wsgi.input': FakePayload('')
|
'wsgi.input': FakePayload('')
|
||||||
}
|
}
|
||||||
|
@ -328,11 +334,13 @@ class Client(object):
|
||||||
post_data = encode_multipart(BOUNDARY, data)
|
post_data = encode_multipart(BOUNDARY, data)
|
||||||
else:
|
else:
|
||||||
post_data = data
|
post_data = data
|
||||||
|
|
||||||
|
parsed = urlparse(path)
|
||||||
r = {
|
r = {
|
||||||
'CONTENT_LENGTH': len(post_data),
|
'CONTENT_LENGTH': len(post_data),
|
||||||
'CONTENT_TYPE': content_type,
|
'CONTENT_TYPE': content_type,
|
||||||
'PATH_INFO': urllib.unquote(path),
|
'PATH_INFO': urllib.unquote(parsed.path),
|
||||||
'QUERY_STRING': urlencode(data, doseq=True),
|
'QUERY_STRING': urlencode(data, doseq=True) or parsed.query,
|
||||||
'REQUEST_METHOD': 'PUT',
|
'REQUEST_METHOD': 'PUT',
|
||||||
'wsgi.input': FakePayload(post_data),
|
'wsgi.input': FakePayload(post_data),
|
||||||
}
|
}
|
||||||
|
@ -344,9 +352,10 @@ class Client(object):
|
||||||
"""
|
"""
|
||||||
Send a DELETE request to the server.
|
Send a DELETE request to the server.
|
||||||
"""
|
"""
|
||||||
|
parsed = urlparse(path)
|
||||||
r = {
|
r = {
|
||||||
'PATH_INFO': urllib.unquote(path),
|
'PATH_INFO': urllib.unquote(parsed.path),
|
||||||
'QUERY_STRING': urlencode(data, doseq=True),
|
'QUERY_STRING': urlencode(data, doseq=True) or parsed.query,
|
||||||
'REQUEST_METHOD': 'DELETE',
|
'REQUEST_METHOD': 'DELETE',
|
||||||
'wsgi.input': FakePayload('')
|
'wsgi.input': FakePayload('')
|
||||||
}
|
}
|
||||||
|
|
|
@ -493,6 +493,18 @@ arguments at time of construction:
|
||||||
|
|
||||||
/customers/details/?name=fred&age=7
|
/customers/details/?name=fred&age=7
|
||||||
|
|
||||||
|
.. versionadded:: development
|
||||||
|
|
||||||
|
If you already have the GET arguments in URL-encoded form, you can
|
||||||
|
use that encoding instead of using the data argument. For example,
|
||||||
|
the previous GET request could also be posed as::
|
||||||
|
|
||||||
|
>>> c = Client()
|
||||||
|
>>> c.get('/customers/details/?name=fred&age=7')
|
||||||
|
|
||||||
|
If you provide URL both an encoded GET data and a data argument,
|
||||||
|
the data argument will take precedence.
|
||||||
|
|
||||||
.. method:: Client.post(path, data={}, content_type=MULTIPART_CONTENT)
|
.. method:: Client.post(path, data={}, content_type=MULTIPART_CONTENT)
|
||||||
|
|
||||||
Makes a POST request on the provided ``path`` and returns a
|
Makes a POST request on the provided ``path`` and returns a
|
||||||
|
@ -544,6 +556,18 @@ arguments at time of construction:
|
||||||
Note that you should manually close the file after it has been provided
|
Note that you should manually close the file after it has been provided
|
||||||
to ``post()``.
|
to ``post()``.
|
||||||
|
|
||||||
|
.. versionadded:: development
|
||||||
|
|
||||||
|
If the URL you request with a POST contains encoded parameters, these
|
||||||
|
parameters will be made available in the request.GET data. For example,
|
||||||
|
if you were to make the request::
|
||||||
|
|
||||||
|
>>> c.post('/login/?vistor=true', {'name': 'fred', 'passwd': 'secret'})
|
||||||
|
|
||||||
|
... the view handling this request could interrogate request.POST
|
||||||
|
to retrieve the username and password, and could interrogate request.GET
|
||||||
|
to determine if the user was a visitor.
|
||||||
|
|
||||||
.. method:: Client.head(path, data={})
|
.. method:: Client.head(path, data={})
|
||||||
|
|
||||||
.. versionadded:: development
|
.. versionadded:: development
|
||||||
|
|
|
@ -421,3 +421,54 @@ class RequestMethodTests(TestCase):
|
||||||
response = self.client.delete('/test_client_regress/request_methods/')
|
response = self.client.delete('/test_client_regress/request_methods/')
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(response.content, 'request method: DELETE')
|
self.assertEqual(response.content, 'request method: DELETE')
|
||||||
|
|
||||||
|
class QueryStringTests(TestCase):
|
||||||
|
def test_get_like_requests(self):
|
||||||
|
for method_name in ('get','head','options','put','delete'):
|
||||||
|
# A GET-like request can pass a query string as data
|
||||||
|
method = getattr(self.client, method_name)
|
||||||
|
response = method("/test_client_regress/request_data/", data={'foo':'whiz'})
|
||||||
|
self.assertEqual(response.context['get-foo'], 'whiz')
|
||||||
|
self.assertEqual(response.context['request-foo'], 'whiz')
|
||||||
|
|
||||||
|
# A GET-like request can pass a query string as part of the URL
|
||||||
|
response = method("/test_client_regress/request_data/?foo=whiz")
|
||||||
|
self.assertEqual(response.context['get-foo'], 'whiz')
|
||||||
|
self.assertEqual(response.context['request-foo'], 'whiz')
|
||||||
|
|
||||||
|
# Data provided in the URL to a GET-like request is overridden by actual form data
|
||||||
|
response = method("/test_client_regress/request_data/?foo=whiz", data={'foo':'bang'})
|
||||||
|
self.assertEqual(response.context['get-foo'], 'bang')
|
||||||
|
self.assertEqual(response.context['request-foo'], 'bang')
|
||||||
|
|
||||||
|
response = method("/test_client_regress/request_data/?foo=whiz", data={'bar':'bang'})
|
||||||
|
self.assertEqual(response.context['get-foo'], None)
|
||||||
|
self.assertEqual(response.context['get-bar'], 'bang')
|
||||||
|
self.assertEqual(response.context['request-foo'], None)
|
||||||
|
self.assertEqual(response.context['request-bar'], 'bang')
|
||||||
|
|
||||||
|
def test_post_like_requests(self):
|
||||||
|
# A POST-like request can pass a query string as data
|
||||||
|
response = self.client.post("/test_client_regress/request_data/", data={'foo':'whiz'})
|
||||||
|
self.assertEqual(response.context['get-foo'], None)
|
||||||
|
self.assertEqual(response.context['post-foo'], 'whiz')
|
||||||
|
|
||||||
|
# A POST-like request can pass a query string as part of the URL
|
||||||
|
response = self.client.post("/test_client_regress/request_data/?foo=whiz")
|
||||||
|
self.assertEqual(response.context['get-foo'], 'whiz')
|
||||||
|
self.assertEqual(response.context['post-foo'], None)
|
||||||
|
self.assertEqual(response.context['request-foo'], 'whiz')
|
||||||
|
|
||||||
|
# POST data provided in the URL augments actual form data
|
||||||
|
response = self.client.post("/test_client_regress/request_data/?foo=whiz", data={'foo':'bang'})
|
||||||
|
self.assertEqual(response.context['get-foo'], 'whiz')
|
||||||
|
self.assertEqual(response.context['post-foo'], 'bang')
|
||||||
|
self.assertEqual(response.context['request-foo'], 'bang')
|
||||||
|
|
||||||
|
response = self.client.post("/test_client_regress/request_data/?foo=whiz", data={'bar':'bang'})
|
||||||
|
self.assertEqual(response.context['get-foo'], 'whiz')
|
||||||
|
self.assertEqual(response.context['get-bar'], None)
|
||||||
|
self.assertEqual(response.context['post-foo'], None)
|
||||||
|
self.assertEqual(response.context['post-bar'], 'bang')
|
||||||
|
self.assertEqual(response.context['request-foo'], 'whiz')
|
||||||
|
self.assertEqual(response.context['request-bar'], 'bang')
|
||||||
|
|
|
@ -5,6 +5,7 @@ urlpatterns = patterns('',
|
||||||
(r'^no_template_view/$', views.no_template_view),
|
(r'^no_template_view/$', views.no_template_view),
|
||||||
(r'^staff_only/$', views.staff_only_view),
|
(r'^staff_only/$', views.staff_only_view),
|
||||||
(r'^get_view/$', views.get_view),
|
(r'^get_view/$', views.get_view),
|
||||||
|
(r'^request_data/$', views.request_data),
|
||||||
url(r'^arg_view/(?P<name>.+)/$', views.view_with_argument, name='arg_view'),
|
url(r'^arg_view/(?P<name>.+)/$', views.view_with_argument, name='arg_view'),
|
||||||
(r'^login_protected_redirect_view/$', views.login_protected_redirect_view),
|
(r'^login_protected_redirect_view/$', views.login_protected_redirect_view),
|
||||||
(r'^set_session/$', views.set_session_view),
|
(r'^set_session/$', views.set_session_view),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
from django.core.exceptions import SuspiciousOperation
|
from django.core.exceptions import SuspiciousOperation
|
||||||
|
from django.shortcuts import render_to_response
|
||||||
|
|
||||||
def no_template_view(request):
|
def no_template_view(request):
|
||||||
"A simple view that expects a GET request, and returns a rendered template"
|
"A simple view that expects a GET request, and returns a rendered template"
|
||||||
|
@ -18,6 +19,17 @@ def get_view(request):
|
||||||
return HttpResponse("Hello world")
|
return HttpResponse("Hello world")
|
||||||
get_view = login_required(get_view)
|
get_view = login_required(get_view)
|
||||||
|
|
||||||
|
def request_data(request):
|
||||||
|
"A simple view that returns the request data in the context"
|
||||||
|
return render_to_response('base.html', {
|
||||||
|
'get-foo':request.GET.get('foo',None),
|
||||||
|
'get-bar':request.GET.get('bar',None),
|
||||||
|
'post-foo':request.POST.get('foo',None),
|
||||||
|
'post-bar':request.POST.get('bar',None),
|
||||||
|
'request-foo':request.REQUEST.get('foo',None),
|
||||||
|
'request-bar':request.REQUEST.get('bar',None),
|
||||||
|
})
|
||||||
|
|
||||||
def view_with_argument(request, name):
|
def view_with_argument(request, name):
|
||||||
"""A view that takes a string argument
|
"""A view that takes a string argument
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue