简体   繁体   中英

Django Testing for Login and token collection

Trying to write test for Django login. I want to request to login, collect token and access different view functions. How do I write a test in python for this.

It depends on your authentication system , if you use Django default auth, you can just use its helper method login(**credentials) or force_login https://docs.djangoproject.com/en/4.1/topics/testing/tools/#django.test.Client.login

If you use Django Rest Framework with additional 3rd auth system you can use its testing class

from rest_framework.test import APITestCase


class TestMyProtectedView(APITestCase):
     def setUp(self) -> None:
         self.client.login(user, password)

     def test_view(self):
         # now you can access your view with logged-in user in setUp
         response = self.client.get('/api/views/')

Just like described in Django and DRF documentations. It would be something like:

tests.py

from django.test import TestCase
from django.urls import reverse
from django.contrib.auth import get_user_model

from rest_framework.authtoken.models import Token
from rest_framework.test import APIClient
from rest_framework import status


# Create your tests here.
class UserLoginTestCase(TestCase):

    def setUp(self):
        self.client = APIClient()
        self.admin_user = get_user_model().objects.create_superuser(
            email='admin@example.com',
            password='testpass123',
        )

    def test_user_create_or_collect_token(self):
        """User check token created if in post save signal format"""
        token = Token.objects.get(user__email=self.admin_user.email)
        self.assertTrue(token.key)

    def test_user_authenticated(self):
        """Check if user is authenticated"""
        token = Token.objects.get(user__email=self.admin_user.email)
        self.client.credentials(HTTP_AUTHORIZATION='Token ' + token.key)
        r = self.client.get(reverse('user:me'))
        self.assertEqual(r.status_code, status.HTTP_200_OK)

    def test_user_login(self):
        """test user login"""
        url = reverse('user:login')
        data = {
                'username': 'admin@example.com',
                'password': 'testpass123'
            }
        r = self.client.post(url, data, format='json')
        self.assertEqual(r.status_code, status.HTTP_200_OK)
        self.assertTrue(r.data['token'])

urls.py

from .api.views import CustomAuthToken, UserAuthenticated
from django.urls import path

app_name = 'user'

urlpatterns = [
    path('login/', CustomAuthToken.as_view(), name='login'),
    path('me/', UserAuthenticated.as_view(), name='me'),
]

views.py

from rest_framework.views import APIView
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from rest_framework import authentication, permissions

from core.models import User

class CustomAuthToken(ObtainAuthToken):

    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data,
                                           context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        return Response({
            'token': token.key,
            'user_name': user.name,
            'email': user.email
        })

class UserAuthenticated(APIView):
    queryset = User.objects.all()

    authentication_classes = [authentication.TokenAuthentication]
    permission_classes = [permissions.IsAdminUser]

    def get(self, request):
        """ Check if user is authenticated by checking token against db """
        is_authenticated = True
        return Response({'isAuthenticated': is_authenticated})

Usually, tests are written for both positive and negative outcomes.

Note that in this case in particular I have a custom user model, and also extended the built-in ObtainAuthToken view.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM