diff --git a/backend/secfit/users/tests.py b/backend/secfit/users/tests.py index fb0e9c2cb47bcd29d057ff14598dc40e55a36108..f27d2cab6f40927a8c6e243e67cdd5d339e0742e 100644 --- a/backend/secfit/users/tests.py +++ b/backend/secfit/users/tests.py @@ -1,42 +1,109 @@ -from rest_framework import status -from rest_framework.test import APITestCase +import json -# Tests new registration, boundary values and 2-way domain -class RegistrationTestCase(APITestCase): - def test_boundaryValuesOfRegistrationInvalid(self): +from django.test import TestCase, RequestFactory, Client +from users.serializers import UserSerializer +from users.models import User +from django.core.exceptions import ValidationError + + +class RegistrationTestCase(TestCase): + def setUp(self): + self.client = Client() + + def test_registration(self): + data = {"username": "Test", "email": "test@test.no", + "password": "strong_pwd", "password1": "strong_pwd", + "phone_number": "12345678", "country": "Norway", + "city": "Trondheim", "street_address": "Trondheimsvegen 1"} + + response = self.client.post('/api/users/', data) + self.assertEqual(response.status_code, 201) + + +### Test boundary values of registration ### +class BoundaryValuesOfRegistrationTestCase(TestCase): + def setUp(self): + self.client = Client() + + def test_minimumData(self): + data = {"username": "t", "email": "", + "password": "1", "password1": "1", + "phone_number": "", "country": "", + "city": "", "street_address": ""} + response = self.client.post("/api/users/", data) + self.assertEqual(response.status_code, 201) #should work at one char pwd and username + + def test_blankPassword(self): data = {"username": "test", "email": "", "password": "", "password1": "", "phone_number": "", "country": "", "city": "", "street_address": ""} response = self.client.post("/api/users/", data) - self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) #should fail at blank pwd + self.assertEqual(response.status_code, 400) #should fail at blank pwd + def test_blankUsername(self): data = {"username": "", "email": "", "password": "1", "password1": "1", "phone_number": "", "country": "", "city": "", "street_address": ""} response = self.client.post("/api/users/", data) - self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) #should fail at blank username + self.assertEqual(response.status_code, 400) #should fail at blank username - # Seem to be no upper value and no restrictions to the other fields - - def test_boundaryValuesOfRegistrationValid(self): - data = {"username": "t", "email": "", + def test_invalidEmail(self): + data = {"username": "Test", "email": "test.no", "password": "1", "password1": "1", "phone_number": "", "country": "", "city": "", "street_address": ""} response = self.client.post("/api/users/", data) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) #should work at one char pwd and username + self.assertEqual(response.status_code, 400) #should fail if email does not conatin @ + + +### 2-way domain testing of registration ### + +class TwoWayDomainTestOfRegistrationTestCase(TestCase): + def setUp(self): + self.client = Client() def test_domainRegistration(self): "2-way domain tests to test the register page" -# Tests new functionality in UC-2 -class Statistics(APITestCase): - def test_renderStatistics(self): - "test that the statistics are rendered" - def test_correctStatistics(self): - "Check that statistics are correctly calculated" +### Test the class UserSerializer ### + +class UserSerializerTestCase(TestCase): + def setUp(self): + self.user1 = User.objects.create(username="user1") + self.user2 = User.objects.create(username="user2", coach=self.user1) + self.factory = RequestFactory() + + def test_validate_passwordValid(self): + password = "some_very_strong_pwd" + serializer = UserSerializer(data = {'password': password,'password1': password}) + + validated_password = serializer.validate_password(password) + self.assertEqual(validated_password, password) + + def test_validate_passwordInValid(self): + password = "some_very_strong_pwd" + password1 = "Some_wrong_pwd" + serializer = UserSerializer(data = {'password': password,'password1': password}) + + validated_password = serializer.validate_password(password1) + self.assertRaises(ValidationError) + + def test_create(self): + data = {"username": "Test", "email": "test@test.no", + "password": "strong_pwd", "password1": "strong_pwd", + "phone_number": "12345678", "country": "Norway", + "city": "Trondheim", "street_address": "Trondheimsvegen 1"} + + serializer = UserSerializer(data) + user = serializer.create(data) + self.assertEqual(user.username, "Test") + self.assertEqual(user.email, "test@test.no") + self.assertEqual(user.phone_number, "12345678") + self.assertEqual(user.country, "Norway") + self.assertEqual(user.city, "Trondheim") + self.assertEqual(user.street_address, "Trondheimsvegen 1") diff --git a/backend/secfit/workouts/tests.py b/backend/secfit/workouts/tests.py index b1e5a7759301123b7640be2bad89804d04acdc3d..f5573bc51b8cb7f90dd0ca2615b390ab21e829e1 100644 --- a/backend/secfit/workouts/tests.py +++ b/backend/secfit/workouts/tests.py @@ -1,60 +1,423 @@ import json -from django.contrib.auth.models import User -from django.urls import reverse -from rest_framework import status -from rest_framework.authtoken.models import Token -from rest_framework.test import APITestCase +from django.test import TestCase, RequestFactory, Client +from workouts.permissions import ( + IsOwner, + IsOwnerOfWorkout, + IsCoachAndVisibleToCoach, + IsCoachOfWorkoutAndVisibleToCoach, + IsPublic, + IsWorkoutPublic, + IsReadOnly +) +from workouts.models import Workout, Exercise, ExerciseInstance, WorkoutFile +from users.models import User +from comments.models import Comment -from users.serializers import UserSerializer -from workouts.serializers import WorkoutSerializer -from workouts.models import Workout - -# Tests new workout and boundary values -class NewWorkoutTestCase(APITestCase): - # Følger denne: https://www.youtube.com/watch?v=1FqxfnlQPi8&ab_channel=pymike00 - # men skjønner ikke helt feilmeldinga som kommer nå, setup funker ikke - +class NewWorkoutTestCase(TestCase): def setUp(self): - self.user = User.objects.create_user(username="test", - password="strong_pwd") - self.token = Token.object.create(user=self.user) - self.api_authentication() + self.client = Client() - def api_authentication(self): - self.client.credentials(HTTP_AUTHORIZATION="Token " + self.token.key) + # Create user + self.athlete = User.objects.create(username="user") + self.athlete.set_password('user') + self.athlete.save() + + # Authenticate user + response = self.client.post('/api/token/', {'username': 'user', 'password': 'user'}) + content = json.loads(response.content) + self.client.defaults['HTTP_AUTHORIZATION'] = 'Bearer ' + content['access'] def test_newWorkoutRegistration(self): - data = {"name": "test", "date": "2019-09-25 06:00", - "notes": "test", "owner": "", - "visibility": "Public"} + """ + data = {"name": "test", "date": "2021-03-06T12:11:30", + "notes": "note", "visibility": "PU", + "owner": self.user} + response = self.client.post("/api/workouts/", data) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) #should work + self.assertEqual(response.status_code, 201) #should work + """ + + +### Test boundary values of new workout ### + +class BoundaryValuesOfNewWorkout(TestCase): + def setUp(self): + "" def test_boundaryValuesOfNewWorkout(self): "test boundary values of new workout" -# Tests FR5 -class WorkoutDetails(APITestCase): - def test_viewDetails(self): - "Test that user can view all details" - def test_viewFiles(self): - "Test that user can view all files" +### Test FR5 - Visibility of details, files and comments for Athletes, Coaches and other users### + +class AthleteAccessTestCase(TestCase): + def setUp(self): + self.client = Client() + + # Create user + self.athlete = User.objects.create(username="user") + self.athlete.set_password('user') + self.athlete.save() + + # Authenticate athlete + response = self.client.post('/api/token/', {'username': 'user', 'password': 'user'}) + content = json.loads(response.content) + self.client.defaults['HTTP_AUTHORIZATION'] = 'Bearer ' + content['access'] + + def test_visibilityOnPrivateContent(self): + workout = Workout.objects.create(name="workout", date="2021-03-06T18:00:00Z", notes="notes", owner=self.athlete, visibility="PR") + comment = Comment.objects.create(content="comment", timestamp="2021-03-06T18:00:00Z", owner=self.athlete, workout=workout) + file = WorkoutFile.objects.create(file='/path/', owner=self.athlete, workout=workout) + + response = self.client.get('/api/workouts/'+str(workout.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get('/api/comments/'+str(comment.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get('/api/workout-files/'+str(file.id)+'/') + self.assertEqual(response.status_code, 200) + + def test_visibilityOnPublicContent(self): + workout = Workout.objects.create(name="workout", date="2021-03-06T18:00:00Z", notes="notes", owner=self.athlete, visibility="PU") + comment = Comment.objects.create(content="comment", timestamp="2021-03-06T18:00:00Z", owner=self.athlete, workout=workout) + file = WorkoutFile.objects.create(file='/path/', owner=self.athlete, workout=workout) + + response = self.client.get('/api/workouts/'+str(workout.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get('/api/comments/'+str(comment.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get('/api/workout-files/'+str(file.id)+'/') + self.assertEqual(response.status_code, 200) + + +class CoachAccessTestCase(TestCase): + def setUp(self): + self.client = Client() + + # Create coach + self.coach = User.objects.create(username="user1") + self.coach.set_password('user1') + self.coach.save() + + # Create user + self.athlete = User.objects.create(username="user2", coach = self.coach) + self.athlete.set_password('user2') + self.athlete.save() + + # Authenticate coach + response = self.client.post('/api/token/', {'username': 'user1', 'password': 'user1'}) + content = json.loads(response.content) + self.client.defaults['HTTP_AUTHORIZATION'] = 'Bearer ' + content['access'] - def test_viewComments(self): - "Test that user can view all comments" + def test_visibilityOnPrivateContent(self): + workout = Workout.objects.create(name="workout", date="2021-03-06T18:00:00Z", notes="notes", owner=self.athlete, visibility="PR") + comment = Comment.objects.create(content="comment", timestamp="2021-03-06T18:00:00Z", owner=self.athlete, workout=workout) + file = WorkoutFile.objects.create(file='/path/', owner=self.athlete, workout=workout) -# Tests new functionality in UC-3 and UC-4 -class Categories(APITestCase): - def test_categorizeExercise(self): - "test that categorizing exercise works" + response = self.client.get('/api/workouts/'+str(workout.id)+'/') + self.assertEqual(response.status_code, 200) - def test_sortExercise(self): - "test that sorting exercise works" + response = self.client.get('/api/comments/'+str(comment.id)+'/') + self.assertEqual(response.status_code, 403) + + response = self.client.get('/api/workout-files/'+str(file.id)+'/') + self.assertEqual(response.status_code, 200) + + def test_visibilityOnCoachContent(self): + workout = Workout.objects.create(name="workout", date="2021-03-06T18:00:00Z", notes="notes", owner=self.athlete, visibility="CO") + comment = Comment.objects.create(content="comment", timestamp="2021-03-06T18:00:00Z", owner=self.athlete, workout=workout) + file = WorkoutFile.objects.create(file='/path/', owner=self.athlete, workout=workout) + + response = self.client.get('/api/workouts/'+str(workout.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get('/api/comments/'+str(comment.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get('/api/workout-files/'+str(file.id)+'/') + self.assertEqual(response.status_code, 200) + + +class UserAccessTestCase(TestCase): + def setUp(self): + self.client = Client() + + # Create user + self.athlete = User.objects.create(username="user1") + self.athlete.set_password('user1') + self.athlete.save() + + self.other = User.objects.create(username="user2") + self.other.set_password('user2') + self.other.save() + + # Authenticate user + response = self.client.post('/api/token/', {'username': 'user2', 'password': 'user2'}) + content = json.loads(response.content) + self.client.defaults['HTTP_AUTHORIZATION'] = 'Bearer ' + content['access'] + + def test_visibilityOnPrivateContent(self): + workout = Workout.objects.create(name="workout", date="2021-03-06T18:00:00Z", notes="notes", owner=self.athlete, visibility="PR") + comment = Comment.objects.create(content="comment", timestamp="2021-03-06T18:00:00Z", owner=self.athlete, workout=workout) + file = WorkoutFile.objects.create(file='/path/', owner=self.athlete, workout=workout) + + response = self.client.get('/api/workouts/'+str(workout.id)+'/') + self.assertEqual(response.status_code, 403) + + response = self.client.get('/api/comments/'+str(comment.id)+'/') + self.assertEqual(response.status_code, 403) + + response = self.client.get('/api/workout-files/'+str(file.id)+'/') + self.assertEqual(response.status_code, 403) + + def test_visibilityOnCoachContent(self): + workout = Workout.objects.create(name="workout", date="2021-03-06T18:00:00Z", notes="notes", owner=self.athlete, visibility="CO") + comment = Comment.objects.create(content="comment", timestamp="2021-03-06T18:00:00Z", owner=self.athlete, workout=workout) + file = WorkoutFile.objects.create(file='/path/', owner=self.athlete, workout=workout) + + response = self.client.get('/api/workouts/'+str(workout.id)+'/') + self.assertEqual(response.status_code, 403) + + response = self.client.get('/api/comments/'+str(comment.id)+'/') + self.assertEqual(response.status_code, 403) + + response = self.client.get('/api/workout-files/'+str(file.id)+'/') + self.assertEqual(response.status_code, 403) + + +### Test create workout for athlete as coach ### + +class CreateWorkoutForAthleteTestCase(TestCase): + def setUp(self): + self.client = Client() + + # Create user + self.user = User.objects.create(username="user") + self.user.set_password('user') + self.user.save() + + # Authenticate athlete + response = self.client.post('/api/token/', {'username': 'user', 'password': 'user'}) + content = json.loads(response.content) + self.client.defaults['HTTP_AUTHORIZATION'] = 'Bearer ' + content['access'] -# Tests new functionality in UC-1 -class NewWorkoutAsCoach(APITestCase): def test_createWorkoutAsCoach(self): - "Check that a workout can be created as a coach" \ No newline at end of file + "" + + +### Test categorize exercise ### + +class CategorizeExerciseTestCase(TestCase): + def setUp(self): + self.user = User.objects.create(username="user") + self.factory = RequestFactory() + + def test_createCategorizedEcercise(self): + data = {"name": "Test", "description": "Test", + "category": "Endurance", "unit": "kg"} + + + + +### Test permission-classes in workout/permissions ### + +class IsOwnerTestCase(TestCase): + def setUp(self): + self.user1 = User.objects.create(username="user1") + self.user2 = User.objects.create(username="user2") + self.factory = RequestFactory() + self.isOwner = IsOwner() + self.workout = Workout.objects.create(name="test", date="2021-03-02T18:00:00Z", notes="note", owner=self.user1, visibility="PU") + + def test_isOwnerValid(self): + request = self.factory.get('/') + request.user = self.user1 + has_permission = self.isOwner.has_object_permission(request, None, self.workout) + self.assertTrue(has_permission) + + def test_isOwnerInValid(self): + request = self.factory.get('/') + request.user = self.user2 + has_permission = self.isOwner.has_object_permission(request, None, self.workout) + self.assertFalse(has_permission) + + +class IsOwnerOfWorkoutTestCase(TestCase): + def setUp(self): + self.user1 = User.objects.create(username="user1") + self.user2 = User.objects.create(username="user2") + self.factory = RequestFactory() + self.isOwnerOfWorkout = IsOwnerOfWorkout() + self.workout = Workout.objects.create(name="test", date="2021-03-02T18:00:00Z", notes="note", owner=self.user1, visibility="PU") + + def test_has_permissionValid(self): + request = self.factory.get('/') + request.user = self.user1 + request.data = { 'workout' : '/api/workouts/1/'} + has_permission = self.isOwnerOfWorkout.has_permission(request, None) + self.assertTrue(has_permission) + + request = self.factory.post('/') + request.user = self.user1 + request.data = { 'workout' : '/api/workouts/1/'} + has_permission = self.isOwnerOfWorkout.has_permission(request, None) + self.assertTrue(has_permission) + + def test_has_permissionInValid(self): + request = self.factory.post('/') + request.user = self.user2 + request.data = { 'workout' : '/api/workouts/1/'} + has_permission = self.isOwnerOfWorkout.has_permission(request, None) + self.assertFalse(has_permission) + + request = self.factory.post('/') + request.user = self.user1 + request.data = { 'workout' : None} + has_permission = self.isOwnerOfWorkout.has_permission(request, None) + self.assertFalse(has_permission) + + def test_has_object_permissionValid(self): + request = self.factory.get('/') + request.user = self.user1 + exercise = Exercise.objects.create(name="Test", description="Test", unit="Test") + instance = ExerciseInstance.objects.create(workout=self.workout, exercise=exercise, sets=1, number=1) + + has_permission = self.isOwnerOfWorkout.has_object_permission(request, None, instance) + self.assertTrue(has_permission) + + def test_has_object_permissionInValid(self): + request = self.factory.get('/') + request.user = self.user2 + exercise = Exercise.objects.create(name="Test", description="Test", unit="Test") + instance = ExerciseInstance.objects.create(workout=self.workout, exercise=exercise, sets=1, number=1) + has_permission = self.isOwnerOfWorkout.has_object_permission(request, None, instance) + self.assertFalse(has_permission) + + +class IsCoachAndVisibleToCoachTestCase(TestCase): + def setUp(self): + self.user3 = User.objects.create(username="user3") + self.user2 = User.objects.create(username="user2") + self.user1 = User.objects.create(username="user1", coach=self.user2) + + self.factory = RequestFactory() + self.isCoachAndVisibleToCoach = IsCoachAndVisibleToCoach() + self.workout = Workout.objects.create(name="test", date="2021-03-02T18:00:00Z", notes="note", owner=self.user1, visibility="PU") + + def test_IsCoachAndVisibleToCoachValid(self): + request = self.factory.get('/') + request.user = self.user2 + has_permission = self.isCoachAndVisibleToCoach.has_object_permission(request, None, self.workout) + self.assertTrue(has_permission) + + def test_IsCoachAndVisibleToCoachInValid(self): + request = self.factory.get('/') + request.user = self.user3 + has_permission = self.isCoachAndVisibleToCoach.has_object_permission(request, None, self.workout) + self.assertFalse(has_permission) + +class IsCoachOfWorkoutAndVisibleToCoachTestCase(TestCase): + def setUp(self): + self.user3 = User.objects.create(username="user3") + self.user2 = User.objects.create(username="user2") + self.user1 = User.objects.create(username="user1", coach=self.user2) + + self.factory = RequestFactory() + self.isCoachOfWorkoutAndVisibleToCoach = IsCoachOfWorkoutAndVisibleToCoach() + self.workout = Workout.objects.create(name="test", date="2021-03-02T18:00:00Z", notes="note", owner=self.user1, visibility="PU") + + def test_IsCoachOfWorkoutAndVisibleToCoachValid(self): + request = self.factory.get('/') + request.user = self.user2 + exercise = Exercise.objects.create(name="Test", description="Test", unit="Test") + instance = ExerciseInstance.objects.create(workout=self.workout, exercise=exercise, sets=1, number=1) + has_permission = self.isCoachOfWorkoutAndVisibleToCoach.has_object_permission(request, None, instance) + self.assertTrue(has_permission) + + def test_IsCoachOfWorkoutAndVisibleToCoachInValid(self): + request = self.factory.get('/') + request.user = self.user3 + exercise = Exercise.objects.create(name="Test", description="Test", unit="Test") + instance = ExerciseInstance.objects.create(workout=self.workout, exercise=exercise, sets=1, number=1) + has_permission = self.isCoachOfWorkoutAndVisibleToCoach.has_object_permission(request, None, instance) + self.assertFalse(has_permission) + +class IsPublicTestCase(TestCase): + def setUp(self): + self.user1 = User.objects.create(username="user1") + self.user2 = User.objects.create(username="user2") + + self.factory = RequestFactory() + self.isPublic = IsPublic() + + def test_isPublicValid(self): + request = self.factory.get('/') + request.user = self.user1 + workout = Workout.objects.create(name="test", date="2021-03-02T18:00:00Z", notes="note", owner=self.user1, visibility="PU") + + is_public = self.isPublic.has_object_permission(request, None, workout) + self.assertTrue(is_public) + + def test_isPublicInValid(self): + request = self.factory.get('/') + request.user = self.user1 + workout = Workout.objects.create(name="test", date="2021-03-02T18:00:00Z", notes="note", owner=self.user1, visibility="CO") + + is_public = self.isPublic.has_object_permission(request, None, workout) + self.assertFalse(is_public) + +class IsWorkoutPublicTestCase(TestCase): + def setUp(self): + self.user1 = User.objects.create(username="user1") + self.user2 = User.objects.create(username="user2") + + self.factory = RequestFactory() + self.isWorkoutPublic = IsWorkoutPublic() + + def test_isWorkoutPublicValid(self): + request = self.factory.get('/') + request.user = self.user1 + workout = Workout.objects.create(name="test", date="2021-03-02T18:00:00Z", notes="note", owner=self.user1, visibility="PU") + exercise = Exercise.objects.create(name="Test", description="Test", unit="Test") + instance = ExerciseInstance.objects.create(workout=workout, exercise=exercise, sets=1, number=1) + + is_public = self.isWorkoutPublic.has_object_permission(request, None, instance) + self.assertTrue(is_public) + + def test_isWorkoutPublicInValid(self): + request = self.factory.get('/') + request.user = self.user1 + workout = Workout.objects.create(name="test", date="2021-03-02T18:00:00Z", notes="note", owner=self.user1, visibility="CO") + exercise = Exercise.objects.create(name="Test", description="Test", unit="Test") + instance = ExerciseInstance.objects.create(workout=workout, exercise=exercise, sets=1, number=1) + + is_public = self.isWorkoutPublic.has_object_permission(request, None, instance) + self.assertFalse(is_public) + +class IsReadOnlyTestCase(TestCase): + def setUp(self): + self.user1 = User.objects.create(username="user1") + self.user2 = User.objects.create(username="user2") + + self.factory = RequestFactory() + self.isReadOnly = IsReadOnly() + self.workout = Workout.objects.create(name="test", date="2021-03-02T18:00:00Z", notes="note", owner=self.user1, visibility="PU") + + def test_isReadOnlyValid(self): + request = self.factory.get('/') + request.user = self.user1 + + is_readonly = self.isReadOnly.has_object_permission(request, None, self.workout) + self.assertTrue(is_readonly) + + def test_isReadOnlyInValid(self): + request = self.factory.post('/') + request.user = self.user1 + + is_readonly = self.isReadOnly.has_object_permission(request, None, self.workout) + self.assertFalse(is_readonly) \ No newline at end of file