In my Django project I create custom admin page (NOT admin from Django). I have 2 login pages. One for admin, second for other users.
Here below you can see urls.py file for admin. I test it and it works fine. After successful login Django redirect user to url which was next parameter (/administration/dashboard/
).
I wrote unit test and it raise error. From error I understand that Django redirect to default url (/accounts/profile/
). Why unit test dont use settings which I did in urls.py file (next parameter)?
How to fix this problem?
Right now I notice that problem disappear only if I use this code LOGIN_REDIRECT_URL = '/administration/dashboard/'
in settings.py. I cant use it cause in the future I will use LOGIN_REDIRECT_URL
to my other login page.
I would be grateful for any help!
urls.py:
from django.contrib.auth import views as authentication_views
urlpatterns = [
# Administration Login
url(r'^login/$',
authentication_views.login,
{
'template_name': 'administration/login.html',
'authentication_form': AdministrationAuthenticationForm,
'extra_context': {
'next': reverse_lazy('administration:dashboard'),
},
'redirect_authenticated_user': True
},
name='administration_login'),
]
tests.py:
class AdministrationViewTestCase(TestCase):
def setUp(self):
self.client = Client()
self.credentials = {'username': 'user', 'password': 'password'}
self.user = User.objects.create_user(self.credentials, is_staff=True)
self.data = dict(
self.credentials,
next=reverse("administration:dashboard")
)
def test_administration_authorization(self):
self.assertTrue(self.user)
# logged_in = self.client.login(**self.credentials)
# self.assertTrue(logged_in)
response = self.client.post(
reverse("administration:administration_login"),
self.data,
follow=True
)
# self.assertEqual(response.status_code, 302)
self.assertRedirects(
response,
reverse("administration:dashboard"),
status_code=302,
target_status_code=200
)
ERROR:
Traceback (most recent call last):
File "/home/nurzhan/CA/administration/tests.py", line 51, in test_administration_authorization
reverse("administration:dashboard"),
File "/srv/envs/py27/lib/python2.7/site-packages/django/test/testcases.py", line 271, in assertRedirects
% (response.status_code, status_code)
AssertionError: Response didn't redirect as expected: Response code was 200 (expected 302)
forms.py:
from django import forms
from django.contrib.auth.forms import AuthenticationForm
from django.utils.translation import ugettext_lazy as _
class AdministrationAuthenticationForm(AuthenticationForm):
"""
A custom authentication form used in the administration application.
"""
error_messages = {
'invalid_login': (
_("ERROR MESSAGE.")
),
}
required_css_class = 'required'
def confirm_login_allowed(self, user):
if not user.is_active or not user.is_staff:
raise forms.ValidationError(
self.error_messages['invalid_login'],
code='invalid_login',
params={
'username': self.username_field.verbose_name
}
)
login.html:
<form action="{% url 'administration:administration_login' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
<input type="hidden" name="next" value="{{ next }}"/>
</form>
Have you tried removing the
follow=True
in the POST request. You are checking for a redirection but you are telling therequests
modules to follow the redirection, so your response will be directly the page and not the302
redirection HTTP response.To be more explicit. You are sending a request with
requests.post(follow=True)
, that will follow the302
redirection to the destination page and yourresponse
will be a HTTP 200 with the destination page. Even if the destination page is the one you want, the test assertion will fail because is looking for a HTTP 302 code in your response and you've already followed the redirection.