I've checked the DRF official documentation, have read the below posts and copy-pasted code from some answers to avoid any typo, but I still can't authenticate in my unit tests. I always get a 401 response code.
I have a custom User model that just has a couple of none required fields so far.
Can anyone see any logic issue, or error in the code? Could the issue originate from having a proper local DB and a testing DB and the authentication mixing both up somehow?
I've had to use self.client.force_authenticate(user=self.user, token=None) to bypass the authentication issue. But that defeats the purpose of the tests.
Checked posts that did not solve the problem:
So here's my code.
Unit test
from django.test.testcases import SimpleTestCase
from django.urls import reverse, resolve
from rest_framework import status
from rest_framework.test import APITestCase
from rest_framework.authtoken.models import Token
from test_project.models.user import *
from test_project.views import UserViewSet
# from django.contrib.auth.models import User
from test_project.models import *
class UserAPIViewTests(APITestCase):
  def setUp(self) -> None:
    self.users_list_url = reverse('user-list')
    self.users_detail_url = reverse('user-detail', args=[1])
    self.user =User.objects.create(
      username="admin",
      password="admin",
      email="test@necktie.com",
      first_name="test first name",
      last_name="test last name",
      is_superuser=True,
      is_staff=True,
      is_active=True
    )
    self.token = Token.objects.create(user=user)
    self.client.credentials(HTTP_AUTHORIZATION='Bearer ' + self.token.key)
  # The testing DB is automatically torn down, no implementation required for those tests
  def tearDown(self) -> None:
    pass
  def test_get_users_authenticated(self):
    """
    Test that an authenticated user can get the users' list
    """
    response = self.client.get(self.users_list_url)
    self.assertEquals(response.status_code, status.HTTP_200_OK)
User model
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils.translation import gettext_lazy as _
class User(AbstractUser):
  """auth/login-related fields"""
  gender = models.CharField(_('gender'), max_length=50, null=True)
  nationality = models.CharField(_('nationality'), max_length=50, null=True)
  def __str__(self):
    return "{} {}".format(self.first_name, self.last_name)
User View
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import permissions
from ..models.user import User
from ..serializers.user import *
from ..permissions import *
class UserViewSet(viewsets.ModelViewSet):
  """
  This viewset automatically provides `list`, `create`, `retrieve`,
  `update` and `destroy` actions.
  """
  queryset = User.objects.all()
  serializer_class = UserSerializer
  def get_permissions(self):
    """
    Method to apply permissions depending on request type (GET, PUT etc.)
    """
    if self.request.method == 'GET':
      return [permissions.IsAuthenticated(), IsStaff()]
    else:
      return [permissions.IsAuthenticated(), IsSuperuser()]
User serializers
from rest_framework import serializers
from ..models.user import User
class UserSerializer(serializers.ModelSerializer):
  """
  Serializer for all actions on User model
  """
  class Meta:
    model = User
    fields = [
      'id',
      'username',
      'first_name',
      'last_name',
      'is_staff',
      'is_superuser',
      'is_active',
      'date_joined'
    ]
Thanks for the help!