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_token = token
if user is None:
if user is None and token is None:
self.logout() # Also clear any possible session info if required
def request(self, **kwargs):

View File

@ -10,6 +10,7 @@ from django.test import TestCase, override_settings
from django.urls import path
from rest_framework import fields, serializers
from rest_framework.authtoken.models import Token
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.test import (
@ -19,10 +20,12 @@ from rest_framework.test import (
@api_view(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'])
def view(request):
return Response({
'auth': request.META.get('HTTP_AUTHORIZATION', b''),
'user': request.user.username
})
data = {'auth': request.META.get('HTTP_AUTHORIZATION', b'')}
if request.user:
data['user'] = request.user.username
if request.auth:
data['token'] = request.auth.key
return Response(data)
@api_view(['GET', 'POST'])
@ -78,14 +81,46 @@ class TestAPITestClient(TestCase):
response = self.client.get('/view/')
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')
self.client.force_authenticate(user)
self.client.force_authenticate(user=user)
response = self.client.get('/view/')
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):
"""
@ -102,8 +137,9 @@ class TestAPITestClient(TestCase):
response = self.client.get('/session-view/')
assert response.data['active_session'] is True
# Force authenticating as `None` should also logout the user session.
self.client.force_authenticate(None)
# Force authenticating with `None` user and token should also logout
# the user session.
self.client.force_authenticate(user=None, token=None)
response = self.client.get('/session-view/')
assert response.data['active_session'] is False