Typically, Django unit tests do not require a secure connection, however, every once in a while your app tests for a secure connection. An example of this would be the OAuth app we have that utilizes oauthlib. oauthlib checks that a request is over a secure connection:
if self.enforce_ssl and not request.uri.lower().startswith("https://"): raise ValueError("Insecure transport, only HTTPS is allowed.")
While it is possible to change the “enforce_ssl” attribute to be False during testing, it is safer to avoid having code that can weaken this type of check.
Fortunately, there is an easy way to have your unit test and have it work too: have the unit test client make a secure connection. The solution is to use a secure client:
from django.test.client import Client class SecureClient(Client): """ Django test client using a "secure" connection. """ def __init__(self, *args, **kwargs): kwargs = kwargs.copy() kwargs.update({'SERVER_PORT': 443, 'wsgi.url_scheme': 'https'}) super(SecureClient, self).__init__(*args, **kwargs)
OK. It is not really a secure connection, but it is not really a connection in the first place. 🙂
Let us see the environment of the test client as seen from a unit test. First, the unit test:
from django.test import TestCase class SecureTestCase(TestCase): client_class = SecureClient def test_client(self): from pprint import pprint pprint(self.client._base_environ())
Next, the output:
Creating test database for alias 'default'... {'HTTP_COOKIE': '', 'PATH_INFO': '/', 'REMOTE_ADDR': '127.0.0.1', 'REQUEST_METHOD': 'GET', 'SCRIPT_NAME': '', 'SERVER_NAME': 'testserver', 'SERVER_PORT': 443, 'SERVER_PROTOCOL': 'HTTP/1.1', 'wsgi.errors': <cStringIO.StringO object at 0x808e479d0>, 'wsgi.input': <django.test.client.FakePayload object at 0x808d27310>, 'wsgi.multiprocess': True, 'wsgi.multithread': False, 'wsgi.run_once': False, 'wsgi.url_scheme': 'https', 'wsgi.version': (1, 0)} . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK Destroying test database for alias 'default'...
As you can see, the URL scheme is now https and the port is 443. Changing the port is overkill since oauthlib does not, and should not, check the port number but only whether the connection is secure or not.