Search code examples
djangounit-testingdjango-rest-frameworkdjango-viewsdjango-testing

Unauthorized User Error in Django Unit test


I am writing a unit test case for a website, The website has a basic function of address update, the address update requires an authentic user login, so I am using the temporary token for that purpose in query-param (as a part of website functionality).

from django.test import TestCase
from accounts.models import Address, User, Business, Employment
from accounts.controllers import AddressController

class Test_Cases_AddressController(TestCase):
    user= User.objects.create_user( birth_year=1996, birth_month= 8, birth_day = 15, marital_status= "married", \
         reset_password_token = "xxxxy", confirmation_token = "xxxx", password_reset_at= "2022-01-12 13:12:13", \
             confirmed_at= "2022-01-12 13:12:13", email= "[email protected]", username = "testuser123")

    def test_update_address(self):
        address1 = Address.objects.create(street_1="abc abc abc", city="lahore", state="punjab", zip="54000", type="abcdef")
        API_LOGIN_URL = '/addresses/1/?_t=xxxx/'
        response= self.client.put(API_LOGIN_URL, {"street_1": "xyz xyz xyz"}, content_type='application/json' )
        self.assertEquals(response.status_code, 201)
    
    def test_get_address(self):
        API_LOGIN_URL = '/addresses/1/?_t=xxxx/'
        response= self.client.get(API_LOGIN_URL)
        self.assertEquals(response.status_code, 200)

But I am still getting the same unauthorized error:

PS C:\Users\Lenovo\web> docker-compose run --rm api sh -c "python manage.py test accounts"
Creating web_api_run ... done
Creating test database for alias 'default'...
System check identified some issues:

WARNINGS:
accounts.User.privacy: (postgres.E003) JSONField default should be a callable instead of an instance so that it's not shared between all field instances.
        HINT: Use a callable instead, e.g., use `dict` instead of `{}`.
main.NonProfit.website: (fields.W340) null has no effect on ManyToManyField.

System check identified 2 issues (0 silenced).
.:::token:::
xxxx/
============token_attribute===confirmation_token
=============xxxx/
===========confirmed_at
error :::
:::token:::
xxxx/
============token_attribute===reset_password_token
=============xxxx/
===========password_reset_at
error :::
WARNING:django.request:Unauthorized: /addresses/1/
F:::token:::
xxxx/
============token_attribute===confirmation_token
=============xxxx/
===========confirmed_at
error :::
:::token:::
xxxx/
============token_attribute===reset_password_token
=============xxxx/
===========password_reset_at
error :::
WARNING:django.request:Unauthorized: /addresses/1/
F
======================================================================
FAIL: test_get_address (accounts.tests.Test_Cases_AddressController)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/src/app/web/accounts/tests.py", line 26, in test_get_address
    self.assertEquals(response.status_code, 200)
AssertionError: 401 != 200

======================================================================
FAIL: test_update_address (accounts.tests.Test_Cases_AddressController)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/src/app/web/accounts/tests.py", line 21, in test_update_address
    self.assertEquals(response.status_code, 201)
AssertionError: 401 != 201

----------------------------------------------------------------------
Ran 3 tests in 0.147s

FAILED (failures=2)
Destroying test database for alias 'default'...
ERROR: 1

Here is the user model:

class User(AbstractUser, BaseModelMixin):
    birth_year = models.IntegerField(default=1900)
    birth_month = models.IntegerField(default=1)
    birth_day = models.IntegerField(default=1)
    marital_status = models.CharField(max_length=255, blank=True, default="")
    reset_password_token = models.CharField(
        max_length=32, blank=True, default="")
    password_reset_at = models.DateTimeField(null=True, blank=True)
    reset_password_sent_at = models.DateTimeField(null=True, blank=True)
    confirmation_token = models.CharField(
        max_length=32, blank=True, default="")
    confirmed_at = models.DateTimeField(null=True, blank=True)
    confirmation_sent_at = models.DateTimeField(null=True, blank=True)
    employers = models.ManyToManyField(Business, through="Employment")
    address = models.ForeignKey(
        Address, null=True, blank=True, on_delete=models.CASCADE)
    email = models.EmailField("Email Address", blank=True, unique=True)
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']


Here is the url:

url(r'^addresses/(?P<address>[^/]+)/?$', AddressController()),

Solution

  • I think you should create a test user in test force authenticate your request

    self.client.force_authenticate(user=self.your_created_user)