diff --git a/.gitignore b/.gitignore index 2b3ca5ccd809246a54baaa06da11065d05e0baa6..420718a9278aa43b1af6276b536555094ad29f05 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ backend/secfit/.vscode/ backend/secfit/*/migrations/__pycache__/ backend/secfit/*/__pycache__/ backend/secfit/db.sqlite3 +backend/secfit/htmlcov/ +backend/secfit/.coverage +backend/secfit/.coveragerc .idea diff --git a/backend/secfit/users/tests.py b/backend/secfit/users/tests.py index 7ce503c2dd97ba78597f6ff6e4393132753573f6..dff761e97b471a2699d217eec59c4aeef3897563 100644 --- a/backend/secfit/users/tests.py +++ b/backend/secfit/users/tests.py @@ -1,3 +1,44 @@ -from django.test import TestCase +from django.test import TestCase, Client +from rest_framework.test import RequestsClient +from django.contrib.auth import get_user_model +from .serializers import UserSerializer -# Create your tests here. + +class UserTestCase(TestCase): + + def setUp(self): + self.client = Client() + self.data = {'username': 'fred', + 'password': 'secret', + 'password1': 'secret', + 'email': 'test@test.test', + 'phone_number': '12345678', + 'country': 'Norway', + 'city': 'Oslo', + 'street_address': 'street1', + 'age': 20, + 'expirience': 3, + 'favorite_dicipline': 'Bench press', + 'bio': 'I love working out'} + + def test_user_object_serialized(self): + response = UserSerializer.create(self, self.data) + user = get_user_model().objects.get(username="fred") + self.assertEqual(response.username, "fred") + self.assertEqual(user.city, "Oslo") + + def test_user_object_view(self): + response = self.client.post('/api/users/', {'username': 'fred2', + 'password': 'secret', + 'password1': 'secret', + 'email': 'test@test.test', + 'phone_number': '12345678', + 'country': 'Norway', + 'city': 'Oslo', + 'street_address': 'street1', + 'age': 20, + 'expirience': 3, + 'favorite_dicipline': 'Bench press', + 'bio': 'I love working out'}) + + self.assertEqual(response.status_code, 201) diff --git a/backend/secfit/workouts/tests.py b/backend/secfit/workouts/tests.py index 7fbbf7847f5b0f201d408d4017cc865d614e2615..fc3a3be9bd464a262ab8e9bda50d759ad7686e62 100644 --- a/backend/secfit/workouts/tests.py +++ b/backend/secfit/workouts/tests.py @@ -1,6 +1,173 @@ """ Tests for the workouts application. """ -from django.test import TestCase +from django.test import TestCase, Client +from rest_framework.test import RequestsClient, APIRequestFactory, APITestCase, APIClient +from django.contrib.auth import get_user_model +from rest_framework import status +from rest_framework.authtoken.models import Token +from .serializers import WorkoutSerializer +from .permissions import IsOwner, IsOwnerOfWorkout, IsCoachAndVisibleToCoach, IsCoachOfWorkoutAndVisibleToCoach, IsPublic, IsWorkoutPublic, IsReadOnly +from .views import WorkoutDetail, ExerciseInstanceList, ExerciseInstanceDetail +from .models import Workout, ExerciseInstance, Exercise -# Create your tests here. + +class WorkoutPermissionsTestCase(APITestCase): + + def setUp(self): + self.client = APIClient() + self.factory = APIRequestFactory() + + # adding some mock data + userData = {'username': 'ola', + 'password': 'secret', + 'password1': 'secret', + 'email': 'test@test.test', + 'phone_number': '12345678', + 'country': 'Norway', + 'city': 'Oslo', + 'street_address': 'street1', + 'age': 20, + 'expirience': 3, + 'favorite_dicipline': 'Bench press', + 'bio': 'I love working out'} + workoutData = {"name": "Crossfit", + "visibility": "PR", + "exercise_instances": '[{"exercise": "http://testserver/api/exercises/1/", "number": "4", "sets": "4"}]', + "files": "", + "date": "2022-03-16T22:11:00.000Z", + "notes": "My crossfit workout."} + exerciseData = {"name": "Pull-up", + "description": "A pull up", + "duration": "10", + "calories": "100", + "muscleGroup": "Arms", + "unit": "Reps"} + + # Creating new users needed for testing permissions + self.client.post('/api/users/', userData) + userData["username"] = 'kari' + self.client.post('/api/users/', userData) + userData["username"] = 'bob' + self.client.post('/api/users/', userData) + self.userOla = get_user_model().objects.get(username="ola") + self.userKari = get_user_model().objects.get(username="kari") + self.userBob = get_user_model().objects.get(username="bob") + + # Adding a workout and exercise with IDs 1 and Ola as owner + self.client.force_authenticate(user=self.userOla) + self.client.post('/api/exercises/', exerciseData) + self.client.post('/api/workouts/', workoutData) + + # Setting Kari as Ola's coach + get_user_model().objects.filter(username="ola").update(coach=self.userKari) + + # adding a workout with CO visibility. This workout will have id 2 + coachVisibilityData = workoutData + coachVisibilityData['visibility'] = 'CO' + self.client.post('/api/workouts/', coachVisibilityData) + + # adding a workout with PU visibility with ID 3 + publicVisibilitydata = workoutData + publicVisibilitydata['visibility'] = 'PU' + self.client.post('/api/workouts/', publicVisibilitydata) + + def test_workout_isOwner(self): + # Ola making a GET request to workout with ID 1 which is owned by Ola + request = self.factory.get('/api/workouts/1/') + request.user = self.userOla + workout = Workout.objects.get(id=1) + # checking if object owner is the same as user who sends the request + # returns true if that is the case + owner = IsOwner.has_object_permission( + self, request, WorkoutDetail, workout) + # checks if it returns true which it should + self.assertEqual(owner, True) + + def test_workout_isOwnerOfWorkouts(self): + # testing GET + request = self.factory.get('/api/exercise-instances/') + request.user = self.userOla + exerciseInstance = ExerciseInstance.objects.get(id=1) + owner = IsOwnerOfWorkout.has_object_permission( + self, request, ExerciseInstanceList, exerciseInstance) + self.assertEqual(owner, True) + + # testing POST + request = self.factory.post('/api/exercise-instances/') + request.user = self.userOla + # testing with workout data + request.data = {"workout": "http://testserver/api/workouts/1/", + "exercise": "http://testserver/api/exercises/1/", "number": "4", "sets": "4"} + owner = IsOwnerOfWorkout.has_permission( + self, request, ExerciseInstanceList) + self.assertEqual(owner, True) + # testing without workout data + request.data = { + "exercise": "http://testserver/api/exercises/1/", "number": "4", "sets": "4"} + owner = IsOwnerOfWorkout.has_permission( + self, request, ExerciseInstanceList) + self.assertEqual(owner, False) + + # testing GET + request = self.factory.get('/api/exercise-instances/') + owner = IsOwnerOfWorkout.has_permission( + self, request, ExerciseInstanceList) + self.assertEqual(owner, True) + + def test_workout_IsCoachAndVisibleToCoach(self): + # Kari sedning request to view Ola's workout with CO visiblity + request = self.factory.get('/api/workouts/2/') + request.user = self.userKari + workout = Workout.objects.get(id=2) + # testing permissions + coach = IsCoachAndVisibleToCoach.has_object_permission( + self, request, WorkoutDetail, workout) + # should return true since Kari is Ola's coach + self.assertEqual(coach, True) + + def test_workout_IsCoachOfWorkoutAndVisibleToCoach(self): + request = self.factory.get('/api/exercise-instances/2/') + request.user = self.userKari + exerciseInstance = ExerciseInstance.objects.get(id=2) + # testing permissions + coach = IsCoachOfWorkoutAndVisibleToCoach.has_object_permission( + self, request, ExerciseInstanceDetail, exerciseInstance) + self.assertEqual(coach, True) + + def test_workout_isPublic(self): + # checking if workout with ID 3 has public visibility + # Bob should be able to view it since it has visibility public + request = self.factory.get('/api/workouts/3/') + request.user = self.userBob + workout = Workout.objects.get(id=3) + user = IsPublic.has_object_permission( + self, request, WorkoutDetail, workout) + self.assertEqual(user, True) + + def test_workout_IsWorkoutPublic(self): + # checking if exerciseInstance with ID 3 has workout with public visibility + # Bob should be able to view it since it has visibility public + request = self.factory.get('/api/exercise-instances/3/') + request.user = self.userBob + exerciseInstance = ExerciseInstance.objects.get(id=3) + user = IsWorkoutPublic.has_object_permission( + self, request, ExerciseInstanceDetail, exerciseInstance) + self.assertEqual(user, True) + + def test_workout_IsReadOnly(self): + # Sending a GET request is in SAFE_METHODS + request = self.factory.get('/api/exercise-instances/3/') + request.user = self.userBob + exerciseInstance = ExerciseInstance.objects.get(id=3) + user = IsReadOnly.has_object_permission( + self, request, ExerciseInstanceDetail, exerciseInstance) + self.assertEqual(user, True) + + # sending a DELETE is not in SAFE_METHODS + request = self.factory.delete('/api/exercise-instances/3/') + request.user = self.userBob + exerciseInstance = ExerciseInstance.objects.get(id=3) + user = IsReadOnly.has_object_permission( + self, request, ExerciseInstanceDetail, exerciseInstance) + self.assertEqual(user, False)