Commit 4eeb8ec1 authored by Krzysztof Jurewicz's avatar Krzysztof Jurewicz Committed by Tim Graham
Browse files

Fixed #20864 -- Made the test client use common method for performing requests.

parent 4e50e406
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -317,6 +317,7 @@ answer newbie questions, and generally made Django that much better:
    Michael Josephson <http://www.sdjournal.com/>
    jpellerin@gmail.com
    junzhang.jn@gmail.com
    Krzysztof Jurewicz <krzysztof.jurewicz@gmail.com>
    Xia Kai <http://blog.xiaket.org/>
    Antti Kaihola <http://djangopeople.net/akaihola/>
    Peter van Kampen
+26 −37
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ BOUNDARY = 'BoUnDaRyStRiNg'
MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY
CONTENT_TYPE_RE = re.compile('.*; charset=([\w\d-]+);?')


class FakePayload(object):
    """
    A wrapper around BytesIO that restricts what can be read since data from
@@ -123,6 +124,7 @@ class ClientHandler(BaseHandler):

        return response


def store_rendered_templates(store, signal, sender, template, context, **kwargs):
    """
    Stores templates and contexts that are rendered.
@@ -133,6 +135,7 @@ def store_rendered_templates(store, signal, sender, template, context, **kwargs)
    store.setdefault('templates', []).append(template)
    store.setdefault('context', ContextList()).append(copy(context))


def encode_multipart(boundary, data):
    """
    Encodes multipart POST data from a dictionary of form values.
@@ -178,6 +181,7 @@ def encode_multipart(boundary, data):
    ])
    return b'\r\n'.join(lines)


def encode_file(boundary, key, file):
    to_bytes = lambda s: force_bytes(s, settings.DEFAULT_CHARSET)
    if hasattr(file, 'content_type'):
@@ -189,7 +193,7 @@ def encode_file(boundary, key, file):
        content_type = 'application/octet-stream'
    return [
        to_bytes('--%s' % boundary),
        to_bytes('Content-Disposition: form-data; name="%s"; filename="%s"' \
        to_bytes('Content-Disposition: form-data; name="%s"; filename="%s"'
                 % (key, os.path.basename(file.name))),
        to_bytes('Content-Type: %s' % content_type),
        b'',
@@ -274,14 +278,11 @@ class RequestFactory(object):
    def get(self, path, data={}, **extra):
        "Construct a GET request."

        parsed = urlparse(path)
        r = {
            'PATH_INFO':       self._get_path(parsed),
            'QUERY_STRING':    urlencode(data, doseq=True) or force_str(parsed[4]),
            'REQUEST_METHOD':  str('GET'),
            'QUERY_STRING': urlencode(data, doseq=True),
        }
        r.update(extra)
        return self.request(**r)
        return self.generic('GET', path, **r)

    def post(self, path, data={}, content_type=MULTIPART_CONTENT,
             **extra):
@@ -289,29 +290,16 @@ class RequestFactory(object):

        post_data = self._encode_data(data, content_type)

        parsed = urlparse(path)
        r = {
            'CONTENT_LENGTH': len(post_data),
            'CONTENT_TYPE':   content_type,
            'PATH_INFO':      self._get_path(parsed),
            'QUERY_STRING':   force_str(parsed[4]),
            'REQUEST_METHOD': str('POST'),
            'wsgi.input':     FakePayload(post_data),
        }
        r.update(extra)
        return self.request(**r)
        return self.generic('POST', path, post_data, content_type, **extra)

    def head(self, path, data={}, **extra):
        "Construct a HEAD request."

        parsed = urlparse(path)
        r = {
            'PATH_INFO':       self._get_path(parsed),
            'QUERY_STRING':    urlencode(data, doseq=True) or force_str(parsed[4]),
            'REQUEST_METHOD':  str('HEAD'),
            'QUERY_STRING': urlencode(data, doseq=True),
        }
        r.update(extra)
        return self.request(**r)
        return self.generic('HEAD', path, **r)

    def options(self, path, data='', content_type='application/octet-stream',
                **extra):
@@ -335,11 +323,11 @@ class RequestFactory(object):

    def generic(self, method, path,
                data='', content_type='application/octet-stream', **extra):
        """Constructs an arbitrary HTTP request."""
        parsed = urlparse(path)
        data = force_bytes(data, settings.DEFAULT_CHARSET)
        r = {
            'PATH_INFO':      self._get_path(parsed),
            'QUERY_STRING':   force_str(parsed[4]),
            'REQUEST_METHOD': str(method),
        }
        if data:
@@ -349,8 +337,12 @@ class RequestFactory(object):
                'wsgi.input':     FakePayload(data),
            })
        r.update(extra)
        # If QUERY_STRING is absent or empty, we want to extract it from the URL.
        if not r.get('QUERY_STRING'):
            r['QUERY_STRING'] = force_str(parsed[4])
        return self.request(**r)


class Client(RequestFactory):
    """
    A class that can act as a client for testing purposes.
@@ -392,7 +384,6 @@ class Client(RequestFactory):
        return {}
    session = property(_session)


    def request(self, **request):
        """
        The master request method. Composes the environment dictionary
@@ -489,8 +480,7 @@ class Client(RequestFactory):
        """
        Request a response from the server using OPTIONS.
        """
        response = super(Client, self).options(path,
                data=data, content_type=content_type, **extra)
        response = super(Client, self).options(path, data=data, content_type=content_type, **extra)
        if follow:
            response = self._handle_redirects(response, **extra)
        return response
@@ -500,8 +490,7 @@ class Client(RequestFactory):
        """
        Send a resource to the server using PUT.
        """
        response = super(Client, self).put(path,
                data=data, content_type=content_type, **extra)
        response = super(Client, self).put(path, data=data, content_type=content_type, **extra)
        if follow:
            response = self._handle_redirects(response, **extra)
        return response
@@ -522,8 +511,8 @@ class Client(RequestFactory):
        """
        Send a DELETE request to the server.
        """
        response = super(Client, self).delete(path,
                data=data, content_type=content_type, **extra)
        response = super(Client, self).delete(
            path, data=data, content_type=content_type, **extra)
        if follow:
            response = self._handle_redirects(response, **extra)
        return response