Login

External service Test Client

Author:
theju
Posted:
March 4, 2010
Language:
Python
Version:
1.1
Tags:
test client httplib2
Score:
1 (after 1 ratings)

The inbuilt test client can be used to only test single domain applications ie no support for supplying absolute URLs.

But there are cases where one might like to test against URL rewrites, external domains/services like OpenID, OAuth etc.

This client has an external dependency on httplib2, to maintain the sessions (cookie-based). The API is exactly similar to the inbuilt test client.

>>> from client import TestClient
>>> c = TestClient()
>>> resp = c.get("http://www.google.com/")
>>> resp.status_code
200

Note: Unlike the built-in test client, this test client cannot access the template and context attributes from the response even if testing a local application.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import httplib2
from django.http import HttpResponse, HttpResponseRedirect, parse_cookie
from django.test.client import *

class TestHandler(BaseHandler):
    def __call__(self, environ):
        from django.core import signals

        if self._request_middleware is None:
            self.load_middleware()

        signals.request_started.send(sender=self.__class__)
        try:
            headers = {'Content-type': 'application/x-www-form-urlencoded'}
            http = httplib2.Http()
            request = WSGIRequest(environ)
            if request.COOKIES:
                headers.update({'Cookie': environ['HTTP_COOKIE']})
            request_body = getattr(request, request.method)
            resp, content = http.request(request.META["PATH_INFO"],
                                         method=request.method,
                                         body=request_body.urlencode(),
                                         headers=headers)
            if resp.status in [301, 302, 303, 307]:
                response = HttpResponseRedirect(resp['location'])
            else:
                response = HttpResponse(content=content,
                                        mimetype=None,
                                        status=resp.status,
                                        content_type=resp['content-type'])
            if resp.get('set-cookie'):
                for (key, val) in parse_cookie(resp['set-cookie']).items():
                    response.set_cookie(key, val)

            for middleware_method in self._response_middleware:
                response = middleware_method(request, response)
            response = self.apply_response_fixes(request, response)
        finally:
            signals.request_finished.disconnect(close_connection)
            signals.request_finished.send(sender=self.__class__)
            signals.request_finished.connect(close_connection)
        return response

class TestClient(Client):
    def __init__(self, **defaults):
        super(TestClient, self).__init__(**defaults)
        self.handler = TestHandler()

    def _handle_redirects(self, response):
        response.redirect_chain = []
        while response.status_code in (301, 302, 303, 307):
            url = response['Location']
            scheme, netloc, path, query, fragment = urlsplit(url)

            redirect_chain = response.redirect_chain
            redirect_chain.append((url, response.status_code))

            response = self.get(url, QueryDict(query), follow=False)
            response.redirect_chain = redirect_chain

            if response.redirect_chain[-1] in response.redirect_chain[0:-1]:
                break
        return response

    def get(self, path, data={}, follow=False, **extra):
        extra.update({'PATH_INFO': path})
        return super(TestClient, self).get(path, data=data, follow=follow, **extra)

    def post(self, path, data={}, content_type=MULTIPART_CONTENT, follow=False, **extra):
        extra.update({'PATH_INFO': path})
        return super(TestClient, self).post(path, data=data, content_type=content_type, follow=follow, **extra)

    def put(self, path, data={}, content_type=MULTIPART_CONTENT, follow=False, **extra):
        extra.update({'PATH_INFO': path})
        return super(TestClient, self).put(path, data=data, content_type=content_type, follow=follow, **extra)

    def head(self, path, data={}, follow=False, **extra):
        extra.update({'PATH_INFO': path})
        return super(TestClient, self).head(path, data=data, follow=follow, **extra)

    def options(self, path, data={}, follow=False, **extra):
        extra.update({'PATH_INFO': path})
        return super(TestClient, self).options(path, data=data, follow=follow, **extra)

    def delete(self, path, follow=False, **extra):
        extra.update({'PATH_INFO': path})
        return super(TestClient, self).delete(path, follow=follow, **extra)

More like this

  1. Automatically setup raw_id_fields ForeignKey & OneToOneField by agusmakmun 6 months, 1 week ago
  2. Crispy Form by sourabhsinha396 7 months ago
  3. ReadOnlySelect by mkoistinen 7 months, 2 weeks ago
  4. Verify events sent to your webhook endpoints by santos22 8 months, 1 week ago
  5. Django Language Middleware by agusmakmun 8 months, 3 weeks ago

Comments

jjlorenzo (on May 28, 2010):

Django and his community are amazing. This is exactly what I'am looking for.

#

Please login first before commenting.