Wrong Behaviour doing tests on Django
<p>I'm having problems to do test on Django. I've been reading the documentation <a href="https://docs.djangoproject.com/en/1.10/topics/testing/tools/#testing-responses" rel="nofollow">of the responses</a> and I can't do the same as they explain on the documentation.</p>

<p>When I get the response, I only have access to <code>response.status_code</code> and can't access to <code>context</code> or <code>redirect_chain</code> when I write <code>response.(and now PyCharm shows all available options)</code>.</p>

<p>I've checked on <code>settings.py</code> and I've <code>'BACKEND': 'django.template.backends.django.DjangoTemplates'</code> to be sure that I'm using Django templates so I don't know why don't work the test. I need configure something?</p>

<p>The code of the test I'm trying to do it's:</p>

<pre><code>from django.test import TestCase
from django.test.client import Client


class Test(TestCase):
    def testLogin(self):
        client = Client()
        headers = {'X-OpenAM-Username': 'user', 'X-OpenAM-Password': 'password', 'Content-Type': 'application/json'}
        data = {}
        response = self.client.post('/login/', headers=headers, data=data, secure=True, follow=True)
        assert (response.status_code == 200)
        # self.assertRedirects(response, '/menu/', status_code=301, target_status_code=200)
</code></pre>

<p>I'm not using Django authentication, the login form sends the data to an IDP and if the IDP sends with a correct answer, the "login" it's successful:</p>

<pre><code>def login(request):
    logout(request)
    message = None
    if request.method == "POST":
        form = LoginForm(request.POST)
        if form.is_valid():
            username = request.POST['username']
            password = request.POST['password']
            headers = {'X-OpenAM-Username': username, 'X-OpenAM-Password': password, 'Content-Type': 'application/json'}
            data = {}
            req = requests.post('http://openam.idp.com:8090/openamIDP/json/authenticate', headers=headers, params=data)
            if req.status_code == 200:
                    respJson = json.loads(req.content)
                    tokenIdJson = respJson['tokenId']
                    request.session['tokenId'] = tokenIdJson
                    return render_to_response('menu/menu.html', request)
            elif req.status_code == 401:
                message = "Invalid username and/or password. Please, try again"
    else:
        form = LoginForm()
    return render_to_response('registration/login.html', {'message': message, 'form': form},
                             context_instance=RequestContext(request)) 
</code></pre>

<p>The redirect assert it's commented because now it fails, when I do the debug I see an empty <code>redirect_chain</code>. I don't understand why happens this because running the web everything works, all views redirect as expected.</p>

<p>Why I only can check <code>status_code</code>? I'm doing something wrong when I redirect after a successful login that on a normal use it works but on the test not?</p>

<p>Thanks.</p>

<p>The remote authentication url expects the credentials as headers, but your local login view expects them as <code>POST</code> data. Your test passes the credentials as headers to your local view.</p>

<p>As a result, the form is passed an empty dictionary (<code>request.POST</code> contains no actual data), and the form is invalid. You get an empty form as a response, without any redirects. </p>

<p>You have to simply pass the credentials as post data to your local view:</p>

<pre><code>def testLogin(self):
    client = Client()
    data = {'username': 'user', 'password': 'password'}
    response = self.client.post('/login/', data=data, secure=True, follow=True)
    assert (response.status_code == 200)
    self.assertRedirects(response, '/menu/', status_code=301, target_status_code=200)
</code></pre>

python django django-testing