Reputation: 729
When trying to access a page that requires a User to be logged in, a user should be redirected to a login page to enter their user credentials. However, when the test is ran on that case, I'm getting the AssertionError: 301 != 200 : Couldn't retrieve redirection page '/accounts/sign_in'.
I'm not clear on what is going on for this happen? Why am I getting a 301 and not a 302?
class LoginRedirectRequest(TestCase):
'''Verify that a user is redirected to
a login page if they are not logged in.'''
@classmethod
def setUpTestData(cls):
User.objects.create_user(
username="testuser",
password='*Dh&M3h36v*$J*'
)
def test_redirect_to_login_from_edit_profile_view(self):
response = self.client.get(
reverse("accounts:edit_profile", kwargs={'user_id': 1})
)
self.assertRedirects(response, '/accounts/sign_in/?next=/accounts/profile_edit/1/')
@login_required(login_url="/accounts/sign_in")
def edit_profile(request, user_id):
user = request.user
user_data = model_to_dict(
user,
fields=['username', 'first_name', 'last_name', 'email', 'verify_email']
)
current_profile = Profile.objects.get(user=user)
profile_data = model_to_dict(
current_profile, fields=['birth', 'bio', 'avatar']
)
if request.method == "POST":
user_form = EditUserForm(
request.POST, initial=user_data, instance=user
)
profile_form = ProfileForm(
request.POST, request.FILES,
initial=profile_data, instance=current_profile
)
if profile_form.is_valid() and user_form.is_valid():
profile_form.save()
user_form.save()
if any(data.has_changed() for data in [profile_form, user_form]):
messages.success(request, "Your profile is updated!")
else:
messages.success(request, "No profile changes applied...")
return HttpResponseRedirect(
reverse("accounts:profile", kwargs={'user_id': user_id})
)
else:
profile_form = ProfileForm(initial=profile_data)
user_form = EditUserForm(initial=user_data)
return render(
request, 'accounts/edit_profile.html',
{'profile_form': profile_form,
'user_form': user_form,
'username': user}
)
Upvotes: 3
Views: 1885
Reputation: 832
The code for the assertRedirects
method shows that the error message:
AssertionError: 301 != 200 : Couldn't retrieve redirection page '/accounts/sign_in'
is shown after the assertion method tries to follow the initial redirect to the login page. It expects the response status code to that second call to be whatever the target_status_code
method parameter is set to (it defaults to 200
).
You can stop the assertion error by either setting the target_status_code
method parameter to 301
, or by setting the parameter fetch_redirect_response=False
which will stop the attempt to follow the initial redirect.
Upvotes: 3
Reputation: 1909
While the 302 / 301 reasoning is explained in the notes, the reason the test is failing in the first place may be because your LOGIN_URL path is missing the trailing slash:
LOGIN_URL = '/account/login/'
Without a trailing slash, django will attempt to redirect due to the default setting of APPEND_SLASH.
This will result in the test failing for the reason described.
Upvotes: 3