everyone. I hope you're doing well. I'm a Django newbie, trying to learn the basics of RESTful development. I only know Python, so this is my best fit for the moment.
Right now I'm trying to implement Unit tests for my API. It's a simple model to implement CRUD on the names and heights of NBA players. In my models I added a class to describe this data and translated it to a view with ModelViewSets. I wanted to make this data editable only for a specific type of user (a read-write user), only readable for another (read-only user) as well as unaccesible to non-authenticated users. To do so, I created a custom User Model and translated it to my views with a custom permission. Now I want to write a few Unit tests to check that:
Here is my models.py
:
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
ROLES = [('read-only', 'read-only'), ('read-write', 'read-write'),]
role = models.CharField(max_length=32, choices=ROLES, default='read-only')
# Create your models here.
class NBAplayers(models.Model):
first_name = models.CharField(max_length=100)
h_in = models.DecimalField(max_digits=5, decimal_places=2)
h_meters = models.DecimalField(max_digits=5, decimal_places=2)
last_name = models.CharField(max_length=120)
def __str__(self):
return self.first_name
And my views.py
:
from .models import NBAplayers, User
from .serializers import NBAplayersSerializer
from rest_framework.response import Response
from rest_framework import status, viewsets, permissions
class ReadOnlyPermission(permissions.BasePermission):
def has_permission(self, request, view):
requests = ('POST', 'PUT', 'DELETE', 'PATCH')
user = request.user
role = User.role
if user.is_anonymous: # Not Authenticated
return request.method == 'GET'
else:
if role == 'read-write':
return request.method in requests + ('GET',)
else: # Read Only User
return request.method == 'GET'
class NBAPlayersViewSet(viewsets.ModelViewSet):
serializer_class = NBAplayersSerializer
queryset = NBAplayers.objects.all()
permission_classes = [ReadOnlyPermission]
And Finally, my urls.py
:
from django.contrib import admin
from django.urls import path, include
from .views import NBAPlayersViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('players', NBAPlayersViewSet, basename = 'Players list')
urlpatterns = [
#djoser basic authentication
#Routers URLs
path('', include(router.urls)),
path('players/<int:pk>/', include(router.urls)),
path('', include('djoser.urls')),
path('', include('djoser.urls.authtoken')),
]
All the code above required to add the custom user to the global settings with AUTH_USER_MODEL = 'api_basic.User'
. So, I've read the documentation and watched a few videos trying to understand how to write the proper tests, but the examples are not that close to this problem. I wanted to ask for a few pointers in the right direction, so that I can use it to build the rest of the tests. This is my first time writing unit tests.
Thank you beforehand for any help or input you can give. Cheers!
There's nothing tricky about this. For example, let's say I have a service that is only available to Admin/Staff users. It means you need to be both logged in and be an Admin.
In my test suite, I'll simply create a test_permissions
method where I'll do something like:
To give you a more concrete example, here's a snippet example with DRF. Do note that I'm using custom functions and 3rd party libraries to do some stuff, but the logic remains the same:
class TestCaseSuite(Base):
def test_permissions(self):
user = UserFactory()
admin = AdminFactory()
# 401 Not authenticated
self.api_client.logout()
response = self.api_client.post(url, data=data)
assert response.status_code == 401
# 403 Not admin
self.api_client.force_authenticate(user)
response = self.api_client.post(url, data=data)
assert response.status_code == 403
# 201 Admin
self.api_client.logout()
self.api_client.force_authenticate(admin)
response = self.api_client.post(url, data=data)
assert response.status_code == self.success_code
# ...
# other tests for that service like:
# testing custom fields
# testing a successful call and the response output
# testing side-effects, like when sending an email or whatnot
# etc
A few things to note:
setUp
method (which is triggered before EVERY test)So, if you want to test specific permissions, you simply have to create the necessary objects/users and assert your expectations:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.