2011-04-14 7 views
39

¿Cómo puedo comprobar que un usuario está conectado después de enviar el formulario de registro?Probar que el usuario haya iniciado sesión con éxito

Intenté lo siguiente pero devuelve True incluso antes de agregar la lógica de inicio de sesión a mi vista de registro.

def test_that_user_gets_logged_in(self): 
    response = self.client.post(reverse('auth-registration'), 
           { 'username':'foo', 
            'password1':'bar', 
            'password2':'bar' }) 

    user = User.objects.get(username='foo') 
    assert user.is_authenticated() 

El código que está siendo probado:

class RegistrationView(CreateView): 
    template_name = 'auth/registration.html' 
    form_class = UserCreationForm 
    success_url = '/' 

    def auth_login(self, request, username, password): 
     ''' 
     Authenticate always needs to be called before login because it 
     adds which backend did the authentication which is required by login. 
     ''' 

     user = authenticate(username=username, password=password) 
     login(request, user) 

    def form_valid(self, form): 
     ''' 
     Overwrite form_valid to login. 
     ''' 

     #save the user 
     response = super(RegistrationView, self).form_valid(form) 

     #Get the user creditials 
     username = form.cleaned_data['username'] 
     password = form.cleaned_data['password1'] 

     #authenticate and login 
     self.auth_login(self.request, username, password) 

     return response 
+0

¿Ha intentado 'response.request.user.is_authenticated()'? –

+0

Lo hice, pero el objeto de solicitud no tiene un objeto de usuario. – Pickels

Respuesta

62

Esta no es la mejor respuesta. Ver https://stackoverflow.com/a/35871564/307511

Chronial ha dado un excelente ejemplo de cómo hacer esta afirmación a continuación. Su respuesta mejor que la mía para el código de hoy en día.


El método más sencillo para comprobar si se registra un usuario en está probando el objeto Cliente:

self.assertIn('_auth_user_id', self.client.session) 

También podría comprobar si un determinado usuario se registra en:

self.assertEqual(int(self.client.session['_auth_user_id']), user.pk) 

Como información adicional, el objeto response.request no es un objeto HttpRequest; en su lugar, es un dict común con alguna información sobre la solicitud real, por lo que no tendrá el atributo user de todos modos.

Además, probar el objeto response.context no es seguro porque no siempre tiene un contexto.

+10

Al igual que una garantía adicional, puede hacer la misma prueba pero utilizando el valor de la variable 'SESSION_KEY'. De esta manera: ' de django.contrib.auth SESSION_KEY' importación ' self.assertTrue (session_key en self.client.session) ' se puede ver esta siendo utilizado en la aplicación de autenticación en el marco de Django: [GitHub. ..test/views.py] (https://github.com/django/django/blob/master/django/contrib/auth/tests/views.py#L51) También tienen una función de conveniencia para probar eso un usuario ha cerrado la sesión: [github ... test/views.py] (https://github.com/django/django/blob/master/django/contrib/auth/tests/views.py#L429) – bobc

+0

Gracias para complementar, no estaba enterado de eso. :) – emyller

+2

El primer enlace de comentario está roto - aquí es donde está alojado ahora - https://github.com/django/django-old/blob/master/django/contrib/auth/tests/views.py –

5

El método is_authenticated() en el modelo User siempre devuelve True. False se devuelve para request.user.is_authenticated() en el caso de que request.user es una instancia de AnonymousUser, cuyo método is_authenticated() siempre devuelve False. Durante la prueba, puede echar un vistazo al response.context['request'].user.is_authenticated().

También puede tratar de acceder a otra página de prueba que requiere que estar conectado, y ver si vuelve response.status200 o 302 (redirección desde login_required).

+0

¿Cuál podría ser el motivo por el que no tengo un objeto response.request.user? Este es el aspecto del dict de solicitud {'CONTENT_LENGTH': 244, 'wsgi.input': , 'REQUEST_METHOD': 'POST', 'PATH_INFO': '/ register/',' CONTENT_TYPE ':' multipart/form-data; boundary = BoUnDaRyStRiNg ',' QUERY_STRING ':' '} – Pickels

+0

Agregué el código que estoy probando. – Pickels

+0

¿Estás usando 'django.contrib.auth.middleware.AuthenticationMiddleware'? –

1

¿Dónde está inicializando su self.client? ¿Qué más hay en su método setUp? Tengo una prueba similar y tu código debería funcionar bien. Así es como lo hago:

from django.contrib.auth.models import User 
from django.test import TestCase 
from django.test.client import Client 


class UserTestCase(TestCase): 

    def setUp(self): 
     self.client = Client() 

    def testLogin(self): 
     print User.objects.all() # returns [] 
     response = self.client.post(reverse('auth-registration'), 
          { 'username':'foo', 
           'password1':'bar', 
           'password2':'bar' }) 
     print User.objects.all() # returns one user 
     print User.objects.all()[0].is_authenticated() # returns True 

EDITAR

Si comento hacia fuera mi lógica de inicio de sesión, no consigo ningún usuario después de self.client.post(. Si realmente desea verificar si el usuario ha sido autenticado, use el self.client para acceder a otra URL que requiere autenticación de usuario. Continuando con lo anterior, el acceso otra página:

response = self.client.get(reverse('another-page-which-requires-authentication')) 
print response.status_code 

Lo anterior debe devolver 200 para confirmar que el usuario se ha autenticado. Cualquier otra cosa, redirigirá a la página de inicio de sesión con un código 302.

+2

print User.objects.all() [0] .is_authenticated() ¿Intentó probarlo antes de implementar su lógica de inicio de sesión? Porque lo que entiendo por lo que dijeron los otros es que eso siempre volverá a ser cierto. Necesita el request.user.is_authenticated. Además, el django TestCase viene con un objeto Client ya inicializado, por lo que no es necesario hacerlo dos veces. – Pickels

+0

Ver respuesta editada. –

8

TestClient de Django tiene un login method que devuelve True si el usuario se registra con éxito en.

+2

Excepto que no es la prueba la que realiza la llamada de inicio de sesión(). – Manur

37

Usted puede utilizar el método del módulo authget_user. Dice que quiere una solicitud como parámetro, pero solo usa el atributo session de la solicitud. Y sucede que nuestro Client tiene ese atributo.

from django.contrib import auth 
user = auth.get_user(self.client) 
assert user.is_authenticated() 
+0

¿Estás seguro de que funcionará en un contexto de caso de prueba? – emyller

+0

Bueno, ahí es donde lo estoy usando :) – Chronial

+0

+1 esta es una gran respuesta y haría una afirmación útil: https://gist.github.com/bengolder/c9dc7006f9d6b4d17d5af5465115df73 – BenjaminGolder

0

Hay otra manera sucinta, utilizando wsgi_request en response:

response = self.client.post('/signup', data) 
assert response.wsgi_request.user.is_authenticated() 

y manera @Chronial 's también está disponible con wsgi_request:

from django.contrib import auth 
user = auth.get_user(response.wsgi_request) 
assert user.is_authenticated() 

Debido response.wsgi_request objeto tiene un session atributo.

Sin embargo, creo que usar response.wsgi_request.user es más simple.

Cuestiones relacionadas