Pregunta

I'm using django_webtest to test my application. I faced with problem when try to test sign-up page. This page should create user and make other initial actions, authenticate newly created user and redirect it to the page specified in next parameter of GET request.

Here is the code of view method:

def _redirect_path(referrer, restricted_paths=()):
if not referrer or referrer in (reverse(name) for name in restricted_paths):
    return reverse('home')
else:
    return referrer

...

def sign_up(request):
if request.user.is_authenticated():
    return redirect(reverse('home'))
if request.method == 'POST':
    form = forms.SignUpForm(request.POST)
    if form.is_valid():
        with transaction.commit_on_success():
            user = form.save()
            profile = Profile.objects.create(user=user)
            tokens.create_token(profile, 'unsubscribe')
            mail.send_welcome_letter(request, user)
        messages.success(request, _('You have successfully signed up. Welcome!'))
        authenticated_user = auth.authenticate(username=user.username, password=form.cleaned_data['password'])
        if authenticated_user:
            auth.login(request, authenticated_user)
            remember_user(request, authenticated_user)
            redirect_path = _redirect_path(form.clean_referrer(), ('password_reset', 'sign_up'))
            return redirect(redirect_path)
        else:
            raise Exception("Newly created user couldn't be authenticated.")
else:
    referrer = request.GET.get('next')
    form = forms.SignUpForm(initial={'referrer': referrer})

return render_to_response('sign_up.html', {'form': form}, context_instance=RequestContext(request))

Now I try to test its behavior when user entered example.com/sign_up/?next=/settings/ in his browser, fill all fields of form correctly and submit it.

View that handles /settings/ has decorator @login_required, but after user is successfully signed up, he should be authenticated, so I expect that after submit user will go to example.com/settings/ (and he goes when I test it manually).

But when I run test:

def test_user_creation_redirect_to_settings(self):
    form = self.app.get('/sign_up/', {'next': '/settings/'}).form
    self.fill_sign_up_form(form)
    submit_response = form.submit()
    self.assertRedirects(submit_response, '/settings/')

it returns "AssertionError: Couldn't retrieve redirection page '/settings/': response code was 302 (expected 200)". When I debugged, I have seen that *submit_response* is really 302 FOUND with location path /settings/. But when method assertRedirects tries to get target page, it faces with redirect again - example.com/settings/ redirects to example.com/login/?next=/settings/. So user is not logged in after submit.

OK, I tried to log in him with test client's login method:

def test_user_creation_redirect_to_settings(self):
    form = self.app.get('/sign_up/', {'next': '/settings/'}).form
    self.fill_sign_up_form(form)
    submit_response = form.submit()

    submit_response.client.login(username='User', password='secret')

    self.assertRedirects(submit_response, '/settings/')

But still the same. Seems, this method is not works:

def test_user_creation_redirect_to_settings(self):
    form = self.app.get('/sign_up/', {'next': '/settings/'}).form
    self.fill_sign_up_form(form)
    submit_response = form.submit()

    inside = self.client.login(username='User', password='secret')
    print inside and 'Login successful in self client'
    print 'Authenticated: %s' % bool('_auth_user_id' in self.client.session)

    inside = submit_response.client.login(username='User', password='secret')
    print inside and 'Login successful in response client'
    print 'Authenticated: %s' % bool('_auth_user_id' in submit_response.client.session)

prints

    Login successful in self client
    Authenticated: True
    Login successful in response client
    Authenticated: False

Could you please help me to understand why login functionality doesn't work in test case and how to log in user before redirect.

Thanks!

¿Fue útil?

Solución

Have you tried using the follow method in your tests? Doing so follows redirects.

form.submit().follow()

Otros consejos

This is a django-webtest bug that was fixed in django-webtest 1.5.3.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top