HuLu ViCa
HuLu ViCa

Reputation: 5456

Can I avoid the need for authentication when testing Django Rest Framework

I am trying to use DRF testing for the first time, so I created the following TestCase:

class TestInventoryActionInputNoSeriable(TestCase):
    def setUp(self):
        self.repository = create_repository()
        self.not_seriable_product = create_not_seriable_product()

    def test_post_inventory_input_not_seriable(self):
        client = APIClient()

        response = client.post('/api/inventory/execute_action/', {
            'action': 'input',
            'repository': self.repository.id,
            'product': self.not_seriable_product.id,
            'amount': 1,
        })
        self.assertEqual(response.status_code, 200)

        inventory_actions = models.InventoryAction.objects.all()
        inventory_inputs = models.InventoryInput.objects.all()
        kardexs = models.Kardex.objects.all()

        self.assertEqual(len(inventory_actions), 1)
        self.assertEqual(len(inventory_inputs), 1)
        self.assertEqual(len(kardexs), 1)

        inventory_action = inventory_actions.first()
        inventory_input = inventory_inputs.first()
        kardex = kardexs.first()

        self.assertEqual(inventory_action.action_content_type.model, 'inventoryinput')
        self.assertEqual(inventory_action.action_object_id, inventory_input.id)
        self.assertEqual(kardex.type, models.KARDEX_INPUT)
        self.assertEqual(kardex.repository_id, self.repository_id)
        self.assertEqual(kardex.product_id, self.not_seriable_product.id)
        self.assertEqual(kardex.amount, 1)
        self.assertEqual(kardex.stock, 1)

But I get the following result:

(TCDigitalVenv) MacBook-Pro-de-Hugo:TCDigital hugovillalobos$ python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test_post_inventory_input_not_seriable (inventory.tests.TestInventoryActionInputNoSeriable)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/hugovillalobos/Documents/Code/TCDigitalProject/TCDigitalBackend/TCDigital/inventory/tests.py", line 31, in test_post_inventory_input_not_seriable
    self.assertEqual(response.status_code, 200)
AssertionError: 401 != 200

----------------------------------------------------------------------
Ran 1 test in 0.083s

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

Which means that the request was rejected because of authentication failure. I followed DRF authentication documentation:

def test_post_inventory_input_not_seriable(self):
        token = Token.objects.get(user__username='admin')
        client = APIClient()
        client.credentials(HTTP_AUTHORIZATION='token '+token.key)

        response = client.post('/api/inventory/execute_action/', {
            'action': 'input',
            'repository': self.repository.id,
            'product': self.not_seriable_product.id,
            'amount': 1,
        })
        self.assertEqual(response.status_code, 200)
        ...

But I get this error:

(TCDigitalVenv) MacBook-Pro-de-Hugo:TCDigital hugovillalobos$ python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
E
======================================================================
ERROR: test_post_inventory_input_not_seriable (inventory.tests.TestInventoryActionInputNoSeriable)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/hugovillalobos/Documents/Code/TCDigitalProject/TCDigitalBackend/TCDigital/inventory/tests.py", line 23, in test_post_inventory_input_not_seriable
    token = Token.objects.get(user__username='admin')
  File "/Users/hugovillalobos/Documents/Code/TCDigitalProject/TCDigitalBackend/TCDigitalVenv/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/hugovillalobos/Documents/Code/TCDigitalProject/TCDigitalBackend/TCDigitalVenv/lib/python3.7/site-packages/django/db/models/query.py", line 408, in get
    self.model._meta.object_name
rest_framework.authtoken.models.Token.DoesNotExist: Token matching query does not exist.

----------------------------------------------------------------------
Ran 1 test in 0.046s

FAILED (errors=1)
Destroying test database for alias 'default'...

I don't know if I have to create the user everytime I run the test, of wether there is a way to avoid the need for authentication for testing.

Upvotes: 1

Views: 1134

Answers (1)

Artur Shyshko
Artur Shyshko

Reputation: 153

You should create user for each of your test cases to be able to login somebody. But, you can login him much easier:

admin = User.objects.create_user(...)
self.client.force_login(admin)
response = client.post(...)

This will forcibly login user during your test and api will consider him logged in (no need to send headers and stuff with request).

self.client is basically APIClient() for current TestCase.

Upvotes: 2

Related Questions