Search code examples
djangodjango-testingdjango-testsdjango-login

Access a view which is for logged in users in django testing


Im trying to create some tests for my django project. I get multiple errors when trying to do the views tests. Most of my views depend on a user to be logged in and I cant find the way to log in . Im using the deafult django built-in AUTH system.
VIEW :

@login_required
def fields(request):

    if request.user.profile.user_package == "Livestock":
        raise PermissionDenied()

    field_list = Field.objects.filter(user = request.user)
    context = {
         "title": "Fields",
         "field_list" : field_list,
     }
     template = 'agriculture/fields.html'
     return render(request, template, context)

TetCase:

class TestViews(TestCase):

    @classmethod
    @factory.django.mute_signals(signals.pre_save, signals.post_save, signals.pre_delete, signals.post_delete)
    def setUpTestData(cls):
        # Create new user 
        test_user = User.objects.create(username='test_user',password='1XISRUkwtuK')
        test_user.save()
        c = Client()
        profile = Profile.objects.get_or_create(user = test_user, user_package = 'hybrid')
        c.login(username = test_user.username, password = test_user.password)
        Field.objects.create(user=test_user,friendly_name='Arnissa')                                                                                         

    
    def test_logged_in_user(self):

        login = self.client.login(username='test_user', password='1XISRUkwtuK')
        response = self.client.get(reverse('agriculture:fields'))

        # Check our user is logged in
        self.assertEqual(str(response.context['user']), 'test_user')
        # Check that we got a response "success"
        self.assertEqual(response.status_code, 200)

path: path('fields', views.fields, name='fields')

and settings if they provide any help :

LOGIN_REDIRECT_URL = 'dashboard:index'
LOGOUT_REDIRECT_URL = 'login'
LOGIN_URL = 'login'

On my tests i get the error TypeError: 'NoneType' object is not subscriptable when im checking if user is logged in. If i try to get the response I get AssertionError: 302 != 200.


Solution

  • When creating User in Django you should not use create method of user manager, because that sets the password to plain text instead of enrypting it. Try creating user using create_user method, like that:

    test_user = User.objects.create_user(username='test_user',password='1XISRUkwtuK')
    

    And if you don't want to use this method, you can always use force_login client method to login user without having to specify login nor password like that:

    c.force_login(test_user)