timelaps-api/music/tests.py
2019-04-18 00:58:59 +02:00

329 lines
10 KiB
Python

import json
from django.urls import reverse
from django.contrib.auth.models import User
from rest_framework.test import APITestCase, APIClient
from rest_framework.views import status
from .models import Songs
from .serializers import SongsSerializer
# tests for models
class SongsModelTest(APITestCase):
def setUp(self):
self.a_song = Songs.objects.create(
title="Ugandan anthem",
artist="George William Kakoma"
)
def test_song(self):
""""
This test ensures that the song created in the setup
exists
"""
self.assertEqual(self.a_song.title, "Ugandan anthem")
self.assertEqual(self.a_song.artist, "George William Kakoma")
self.assertEqual(str(self.a_song), "Ugandan anthem - George William Kakoma")
# tests for views
class BaseViewTest(APITestCase):
client = APIClient()
@staticmethod
def create_song(title="", artist=""):
"""
Create a song in the db
:param title:
:param artist:
:return:
"""
if title != "" and artist != "":
Songs.objects.create(title=title, artist=artist)
def make_a_request(self, kind="post", **kwargs):
"""
Make a post request to create a song
:param kind: HTTP VERB
:return:
"""
if kind == "post":
return self.client.post(
reverse(
"songs-list-create",
kwargs={
"version": kwargs["version"]
}
),
data=json.dumps(kwargs["data"]),
content_type='application/json'
)
elif kind == "put":
return self.client.put(
reverse(
"songs-detail",
kwargs={
"version": kwargs["version"],
"pk": kwargs["id"]
}
),
data=json.dumps(kwargs["data"]),
content_type='application/json'
)
else:
return None
def fetch_a_song(self, pk=0):
return self.client.get(
reverse(
"songs-detail",
kwargs={
"version": "v1",
"pk": pk
}
)
)
def delete_a_song(self, pk=0):
return self.client.delete(
reverse(
"songs-detail",
kwargs={
"version": "v1",
"pk": pk
}
)
)
def login_a_user(self, username="", password=""):
url = reverse(
"auth-login",
kwargs={
"version": "v1"
}
)
return self.client.post(
url,
data=json.dumps({
"username": username,
"password": password
}),
content_type="application/json"
)
def login_client(self, username="", password=""):
# get a token from DRF
response = self.client.post(
reverse("create-token"),
data=json.dumps(
{
'username': username,
'password': password
}
),
content_type='application/json'
)
self.token = response.data['token']
# set the token in the header
self.client.credentials(
HTTP_AUTHORIZATION='Bearer ' + self.token
)
self.client.login(username=username, password=password)
return self.token
def register_a_user(self, username="", password="", email=""):
return self.client.post(
reverse(
"auth-register",
kwargs={
"version": "v1"
}
),
data=json.dumps(
{
"username": username,
"password": password,
"email": email
}
),
content_type='application/json'
)
def setUp(self):
# create a admin user
self.user = User.objects.create_superuser(
username="test_user",
email="test@mail.com",
password="testing",
first_name="test",
last_name="user",
)
# add test data
self.create_song("like glue", "sean paul")
self.create_song("simple song", "konshens")
self.create_song("love is wicked", "brick and lace")
self.create_song("jam rock", "damien marley")
self.valid_data = {
"title": "test song",
"artist": "test artist"
}
self.invalid_data = {
"title": "",
"artist": ""
}
self.valid_song_id = 1
self.invalid_song_id = 100
class GetAllSongsTest(BaseViewTest):
def test_get_all_songs(self):
"""
This test ensures that all songs added in the setUp method
exist when we make a GET request to the songs/ endpoint
"""
self.login_client('test_user', 'testing')
# hit the API endpoint
response = self.client.get(
reverse("songs-list-create", kwargs={"version": "v1"})
)
# fetch the data from db
expected = Songs.objects.all()
serialized = SongsSerializer(expected, many=True)
self.assertEqual(response.data, serialized.data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
class GetASingleSongsTest(BaseViewTest):
def test_get_a_song(self):
"""
This test ensures that a single song of a given id is
returned
"""
self.login_client('test_user', 'testing')
# hit the API endpoint
response = self.fetch_a_song(self.valid_song_id)
# fetch the data from db
expected = Songs.objects.get(pk=self.valid_song_id)
serialized = SongsSerializer(expected)
self.assertEqual(response.data, serialized.data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
# test with a song that does not exist
response = self.fetch_a_song(self.invalid_song_id)
self.assertEqual(
response.data["message"],
"Song with id: 100 does not exist"
)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
class AddSongsTest(BaseViewTest):
def test_create_a_song(self):
"""
This test ensures that a single song can be added
"""
self.login_client('test_user', 'testing')
# hit the API endpoint
response = self.make_a_request(
kind="post",
version="v1",
data=self.valid_data
)
self.assertEqual(response.data, self.valid_data)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
# test with invalid data
response = self.make_a_request(
kind="post",
version="v1",
data=self.invalid_data
)
self.assertEqual(
response.data["message"],
"Both title and artist are required to add a song"
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
class UpdateSongsTest(BaseViewTest):
def test_update_a_song(self):
"""
This test ensures that a single song can be updated. In this
test we update the second song in the db with valid data and
the third song with invalid data and make assertions
"""
self.login_client('test_user', 'testing')
# hit the API endpoint
response = self.make_a_request(
kind="put",
version="v1",
id=2,
data=self.valid_data
)
self.assertEqual(response.data, self.valid_data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
# test with invalid data
response = self.make_a_request(
kind="put",
version="v1",
id=3,
data=self.invalid_data
)
self.assertEqual(
response.data["message"],
"Both title and artist are required to add a song"
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
class DeleteSongsTest(BaseViewTest):
def test_delete_a_song(self):
"""
This test ensures that when a song of given id can be deleted
"""
self.login_client('test_user', 'testing')
# hit the API endpoint
response = self.delete_a_song(1)
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
# test with invalid data
response = self.delete_a_song(100)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
class AuthLoginUserTest(BaseViewTest):
"""
Tests for the auth/login/ endpoint
"""
def test_login_user_with_valid_credentials(self):
# test login with valid credentials
response = self.login_a_user("test_user", "testing")
# assert token key exists
self.assertIn("token", response.data)
# assert status code is 200 OK
self.assertEqual(response.status_code, status.HTTP_200_OK)
# test login with invalid credentials
response = self.login_a_user("anonymous", "pass")
# assert status code is 401 UNAUTHORIZED
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
class AuthRegisterUserTest(BaseViewTest):
"""
Tests for auth/register/ endpoint
"""
def test_register_a_user(self):
response = self.register_a_user("new_user", "new_pass", "new_user@mail.com")
# assert status code is 201 CREATED
self.assertEqual(response.data["username"], "new_user")
self.assertEqual(response.data["email"], "new_user@mail.com")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
# test with invalid data
response = self.register_a_user()
# assert status code
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)