Make APIClient.force_authenticate() work with user=None (#8212)

* Fix testing with token

* Add unit test

* Split unit test into 3

* Fix linting error
This commit is contained in:
willbeaufoy 2022-09-15 09:35:48 +01:00 committed by GitHub
parent acf6582de4
commit 354ae73ffb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 10 deletions

View File

@ -277,7 +277,7 @@ class APIClient(APIRequestFactory, DjangoClient):
""" """
self.handler._force_user = user self.handler._force_user = user
self.handler._force_token = token self.handler._force_token = token
if user is None: if user is None and token is None:
self.logout() # Also clear any possible session info if required self.logout() # Also clear any possible session info if required
def request(self, **kwargs): def request(self, **kwargs):

View File

@ -10,6 +10,7 @@ from django.test import TestCase, override_settings
from django.urls import path from django.urls import path
from rest_framework import fields, serializers from rest_framework import fields, serializers
from rest_framework.authtoken.models import Token
from rest_framework.decorators import api_view from rest_framework.decorators import api_view
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.test import ( from rest_framework.test import (
@ -19,10 +20,12 @@ from rest_framework.test import (
@api_view(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']) @api_view(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'])
def view(request): def view(request):
return Response({ data = {'auth': request.META.get('HTTP_AUTHORIZATION', b'')}
'auth': request.META.get('HTTP_AUTHORIZATION', b''), if request.user:
'user': request.user.username data['user'] = request.user.username
}) if request.auth:
data['token'] = request.auth.key
return Response(data)
@api_view(['GET', 'POST']) @api_view(['GET', 'POST'])
@ -78,14 +81,46 @@ class TestAPITestClient(TestCase):
response = self.client.get('/view/') response = self.client.get('/view/')
assert response.data['auth'] == 'example' assert response.data['auth'] == 'example'
def test_force_authenticate(self): def test_force_authenticate_with_user(self):
""" """
Setting `.force_authenticate()` forcibly authenticates each request. Setting `.force_authenticate()` with a user forcibly authenticates each
request with that user.
""" """
user = User.objects.create_user('example', 'example@example.com') user = User.objects.create_user('example', 'example@example.com')
self.client.force_authenticate(user)
self.client.force_authenticate(user=user)
response = self.client.get('/view/') response = self.client.get('/view/')
assert response.data['user'] == 'example' assert response.data['user'] == 'example'
assert 'token' not in response.data
def test_force_authenticate_with_token(self):
"""
Setting `.force_authenticate()` with a token forcibly authenticates each
request with that token.
"""
user = User.objects.create_user('example', 'example@example.com')
token = Token.objects.create(key='xyz', user=user)
self.client.force_authenticate(token=token)
response = self.client.get('/view/')
assert response.data['token'] == 'xyz'
assert 'user' not in response.data
def test_force_authenticate_with_user_and_token(self):
"""
Setting `.force_authenticate()` with a user and token forcibly
authenticates each request with that user and token.
"""
user = User.objects.create_user('example', 'example@example.com')
token = Token.objects.create(key='xyz', user=user)
self.client.force_authenticate(user=user, token=token)
response = self.client.get('/view/')
assert response.data['user'] == 'example'
assert response.data['token'] == 'xyz'
def test_force_authenticate_with_sessions(self): def test_force_authenticate_with_sessions(self):
""" """
@ -102,8 +137,9 @@ class TestAPITestClient(TestCase):
response = self.client.get('/session-view/') response = self.client.get('/session-view/')
assert response.data['active_session'] is True assert response.data['active_session'] is True
# Force authenticating as `None` should also logout the user session. # Force authenticating with `None` user and token should also logout
self.client.force_authenticate(None) # the user session.
self.client.force_authenticate(user=None, token=None)
response = self.client.get('/session-view/') response = self.client.get('/session-view/')
assert response.data['active_session'] is False assert response.data['active_session'] is False