diff --git a/backend/secfit/comments/permissions.py b/backend/secfit/comments/permissions.py index b863cc7782ff295afe3ca1b2cc95519c70eb48eb..9fb2e015d88dcfc40a968dbfe6bfc850b99e77cc 100644 --- a/backend/secfit/comments/permissions.py +++ b/backend/secfit/comments/permissions.py @@ -19,3 +19,4 @@ class IsCommentVisibleToUser(permissions.BasePermission): or (obj.workout.visibility == "CO" and obj.owner.coach == request.user) or obj.workout.owner == request.user ) + \ No newline at end of file diff --git a/backend/secfit/comments/views.py b/backend/secfit/comments/views.py index b74d0f208c9bcf06ee49817541d47742767f0b7d..c55e227cf17a0af1aaf9061d8fccb9a7343d99ea 100644 --- a/backend/secfit/comments/views.py +++ b/backend/secfit/comments/views.py @@ -12,7 +12,6 @@ from rest_framework.filters import OrderingFilter class CommentList( mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView ): - # queryset = Comment.objects.all() serializer_class = CommentSerializer permission_classes = [permissions.IsAuthenticated] filter_backends = [OrderingFilter] diff --git a/backend/secfit/secfit/djangoHeroku.py b/backend/secfit/secfit/djangoHeroku.py index 9046bb726b49a350ee44771dd6dca11300cf57f7..33ed96081b96ac004bc457ea0cf2ecceb583e236 100644 --- a/backend/secfit/secfit/djangoHeroku.py +++ b/backend/secfit/secfit/djangoHeroku.py @@ -1,16 +1,13 @@ -#import logging import os import dj_database_url from django.test.runner import DiscoverRunner - MAX_CONN_AGE = 600 def settings(config, *, db_colors=False, databases=True, test_runner=True, staticfiles=True, allowed_hosts=True, logging=True, secret_key=True): # Database configuration. - # TODO: support other database (e.g. TEAL, AMBER, etc, automatically.) if databases: # Integrity check. if 'DATABASES' not in config: @@ -20,30 +17,21 @@ def settings(config, *, db_colors=False, databases=True, test_runner=True, stati if db_colors: # Support all Heroku databases. - # TODO: This appears to break TestRunner. for (env, url) in os.environ.items(): if env.startswith('HEROKU_POSTGRESQL'): db_color = env[len('HEROKU_POSTGRESQL_'):].split('_')[0] - #logger.info('Adding ${} to DATABASES Django setting ({}).'.format(env, db_color)) - config['DATABASES'][db_color] = dj_database_url.parse(url, conn_max_age=conn_max_age, ssl_require=True) if 'DATABASE_URL' in os.environ: - #logger.info('Adding $DATABASE_URL to default DATABASE Django setting.') # Configure Django for DATABASE_URL environment variable. config['DATABASES']['default'] = dj_database_url.config(conn_max_age=conn_max_age, ssl_require=True) - #logger.info('Adding $DATABASE_URL to TEST default DATABASE Django setting.') - # Enable test database if found in CI environment. if 'CI' in os.environ: config['DATABASES']['default']['TEST'] = config['DATABASES']['default'] - #else: - #logger.info('$DATABASE_URL not found, falling back to previous settings!') - if test_runner: # Enable test runner if found in CI environment. if 'CI' in os.environ: @@ -51,7 +39,6 @@ def settings(config, *, db_colors=False, databases=True, test_runner=True, stati # Staticfiles configuration. if staticfiles: - #logger.info('Applying Heroku Staticfiles configuration to Django settings.') config['STATIC_ROOT'] = os.path.join(config['BASE_DIR'], 'staticfiles') config['STATIC_URL'] = '/static/' @@ -69,48 +56,10 @@ def settings(config, *, db_colors=False, databases=True, test_runner=True, stati config['STATICFILES_STORAGE'] = 'whitenoise.storage.CompressedManifestStaticFilesStorage' if allowed_hosts: - #logger.info('Applying Heroku ALLOWED_HOSTS configuration to Django settings.') config['ALLOWED_HOSTS'] = ['*'] - """ - if logging: - logger.info('Applying Heroku logging configuration to Django settings.') - - config['LOGGING'] = { - 'version': 1, - 'disable_existing_loggers': False, - 'formatters': { - 'verbose': { - 'format': ('%(asctime)s [%(process)d] [%(levelname)s] ' + - 'pathname=%(pathname)s lineno=%(lineno)s ' + - 'funcname=%(funcName)s %(message)s'), - 'datefmt': '%Y-%m-%d %H:%M:%S' - }, - 'simple': { - 'format': '%(levelname)s %(message)s' - } - }, - 'handlers': { - 'null': { - 'level': 'DEBUG', - 'class': 'logging.NullHandler', - }, - 'console': { - 'level': 'DEBUG', - 'class': 'logging.StreamHandler', - 'formatter': 'verbose' - } - }, - 'loggers': { - 'testlogger': { - 'handlers': ['console'], - 'level': 'INFO', - } - } - } - """ + # SECRET_KEY configuration. if secret_key: if 'SECRET_KEY' in os.environ: - #logger.info('Adding $SECRET_KEY to SECRET_KEY Django setting.') # Set the Django setting from the environment variable. config['SECRET_KEY'] = os.environ['SECRET_KEY'] diff --git a/backend/secfit/secfit/settings.py b/backend/secfit/secfit/settings.py index 67c0e22309e1f49bec2da6d1a8e68b47f2c36625..fff3d90033dfe01adbb05b9f6342f76e2350e700 100644 --- a/backend/secfit/secfit/settings.py +++ b/backend/secfit/secfit/settings.py @@ -106,7 +106,6 @@ if is_prod: if 'DATABASE_URL' in os.environ: import dj_database_url - print("\n\n\n\n\nHEI\n\n\n\n\n\n") DATABASES = {'default': dj_database_url.config()} else: DATABASES = { diff --git a/backend/secfit/users/admin.py b/backend/secfit/users/admin.py index fc0af23c4473e29bcc06045aebfdd0d21989d22d..60666860b2dfc658839567779109f2b1cf20ab1c 100644 --- a/backend/secfit/users/admin.py +++ b/backend/secfit/users/admin.py @@ -6,16 +6,13 @@ from .forms import CustomUserChangeForm, CustomUserCreationForm # Register your models here. - class CustomUserAdmin(UserAdmin): add_form = CustomUserCreationForm form = CustomUserChangeForm model = get_user_model() - # list_display = UserAdmin.list_display + ('coach',) fieldsets = UserAdmin.fieldsets + ((None, {"fields": ("coach",)}),) add_fieldsets = UserAdmin.add_fieldsets + ((None, {"fields": ("coach",)}),) - admin.site.register(get_user_model(), CustomUserAdmin) admin.site.register(Offer) admin.site.register(AthleteFile) diff --git a/backend/secfit/users/serializers.py b/backend/secfit/users/serializers.py index 0e1a83ba88f61b5fd0b3c8ff34ed7e9fee668b63..72a5576977154b20bd538daa4bad3a681a4d01ea 100644 --- a/backend/secfit/users/serializers.py +++ b/backend/secfit/users/serializers.py @@ -32,7 +32,6 @@ class UserSerializer(serializers.HyperlinkedModelSerializer): data = self.get_initial() password = data.get("password") - password1 = data.get("password1") try: password_validation.validate_password(password) diff --git a/backend/secfit/users/tests.py b/backend/secfit/users/tests.py deleted file mode 100644 index 1b46f65fdcb59d631e32caf40e39d0161cb6bbd5..0000000000000000000000000000000000000000 --- a/backend/secfit/users/tests.py +++ /dev/null @@ -1,178 +0,0 @@ -import json - -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, 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, 400) #should fail at blank username - - 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, 400) #should fail if email does not conatin @ - - - -### 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") - - - -### 2-way domain testing of registration ### - -test_cases = [ - {'email':'wrong', 'username':'wrong', 'password':'normal', 'password1':'normal', 'phone_number':'empty', 'country':'empty', 'city':'empty', 'street_address':'normal'}, - {'email':'wrong', 'username':'normal', 'password':'empty', 'password1':'normal', 'phone_number':'normal', 'country':'normal', 'city':'normal', 'street_address':'empty'}, - {'email':'wrong', 'username':'empty', 'password':'normal', 'password1':'empty', 'phone_number':'empty', 'country':'empty', 'city':'normal', 'street_address':'normal'}, - {'email':'wrong', 'username':'normal', 'password':'empty', 'password1':'empty', 'phone_number':'empty', 'country':'normal', 'city':'normal', 'street_address':'normal'}, - {'email':'wrong', 'username':'normal', 'password':'normal', 'password1':'normal', 'phone_number':'normal', 'country':'empty', 'city':'empty', 'street_address':'empty'}, - {'email':'normal','username':'wrong', 'password':'empty', 'password1':'normal', 'phone_number':'normal', 'country':'empty', 'city':'normal', 'street_address':'normal'}, - {'email':'normal','username':'normal', 'password':'normal', 'password1':'empty', 'phone_number':'empty', 'country':'normal', 'city':'normal', 'street_address':'empty'}, - {'email':'normal','username':'empty', 'password':'normal', 'password1':'normal', 'phone_number':'empty', 'country':'normal', 'city':'normal', 'street_address':'empty'}, - {'email':'normal','username':'wrong', 'password':'empty', 'password1':'empty', 'phone_number':'normal', 'country':'normal', 'city':'empty', 'street_address':'normal'}, - {'email':'empty', 'username':'empty', 'password':'empty', 'password1':'empty', 'phone_number':'normal', 'country':'normal', 'city':'empty', 'street_address':'normal'}, - {'email':'empty', 'username':'wrong', 'password':'normal', 'password1':'normal', 'phone_number':'empty', 'country':'normal', 'city':'normal', 'street_address':'empty'}, - {'email':'empty', 'username':'normal', 'password':'empty', 'password1':'normal', 'phone_number':'normal', 'country':'empty', 'city':'empty', 'street_address':'normal'}, - {'email':'empty', 'username':'normal', 'password':'normal', 'password1':'empty', 'phone_number':'empty', 'country':'normal', 'city':'normal', 'street_address':'empty'}, - {'email':'empty', 'username':'empty', 'password':'empty', 'password1':'normal', 'phone_number':'normal', 'country':'empty', 'city':'normal', 'street_address':'normal'}, - {'email':'empty', 'username':'wrong', 'password':'normal', 'password1':'empty', 'phone_number':'normal', 'country':'normal', 'city':'empty', 'street_address':'empty'}, - {'email':'empty', 'username':'normal', 'password':'normal', 'password1':'normal', 'phone_number':'empty', 'country':'empty', 'city':'normal', 'street_address':'normal'}, - {'email':'wrong', 'username':'wrong', 'password':'empty', 'password1':'empty', 'phone_number':'normal', 'country':'normal', 'city':'normal', 'street_address':'normal'}, - {'email':'wrong', 'username':'empty', 'password':'normal', 'password1':'normal', 'phone_number':'normal', 'country':'normal', 'city':'empty', 'street_address':'empty'}, - {'email':'wrong', 'username':'wrong', 'password':'normal', 'password1':'empty', 'phone_number':'empty', 'country':'empty', 'city':'normal', 'street_address':'normal'}, - {'email':'wrong', 'username':'empty', 'password':'normal', 'password1':'normal', 'phone_number':'empty', 'country':'empty', 'city':'empty', 'street_address':'normal'}, - {'email':'normal','username':'normal', 'password':'empty', 'password1':'normal', 'phone_number':'empty', 'country':'normal', 'city':'empty', 'street_address':'normal'}, - {'email':'normal','username':'normal', 'password':'normal', 'password1':'empty', 'phone_number':'normal', 'country':'empty', 'city':'normal', 'street_address':'empty'}, - {'email':'normal','username':'empty', 'password':'normal', 'password1':'normal', 'phone_number':'empty', 'country':'normal', 'city':'empty', 'street_address':'normal'}, - {'email':'normal','username':'wrong', 'password':'empty', 'password1':'normal', 'phone_number':'normal', 'country':'empty', 'city':'normal', 'street_address':'empty'}, - {'email':'normal','username':'normal', 'password':'normal', 'password1':'empty', 'phone_number':'normal', 'country':'normal', 'city':'empty', 'street_address':'normal'}, - {'email':'normal','username':'empty', 'password':'empty', 'password1':'normal', 'phone_number':'empty', 'country':'normal', 'city':'normal', 'street_address':'empty'}, - {'email':'normal','username':'wrong', 'password':'normal', 'password1':'empty', 'phone_number':'normal', 'country':'empty', 'city':'normal', 'street_address':'normal'} -] - -case_data = { - 'normal': { - 'email': 'test@test.no', - 'username': 'test', - 'password': 'test123', - 'password1': 'test123', - 'phone_number': 12354678, - 'country': 'Norway', - 'city': 'Trondheim', - 'street_address': 'Trondheimsvegen', - }, - 'empty': { - 'email': '', - 'username': '', - 'password': '', - 'password1': '', - 'phone_number': '', - 'country': '', - 'city': '', - 'street_address': '', - }, - 'wrong': { - 'email': 'test.no', - 'username': 'test]', - } -} - -class TwoWayDomainTestOfRegistrationTestCase(TestCase): - def setUp(self): - self.client = Client() - - def test_domainRegistration(self): - for case in test_cases: - data = {} - - for key, value in case.items(): - data[key] = case_data[value][key] - code = 201 - - if case['email'] == 'wrong' or case['username'] == 'wrong' or case['password'] == 'empty' or case['username'] == 'empty' or case['password1'] == 'empty': - code = 400 - - response = self.client.post('/api/users/', data) - self.assertEqual(response.status_code, code) \ No newline at end of file diff --git a/backend/secfit/users/tests/__init__.py b/backend/secfit/users/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c55e9171bc009b91e52d75b41583c1b64798bd19 --- /dev/null +++ b/backend/secfit/users/tests/__init__.py @@ -0,0 +1,4 @@ +from users.tests.registration import * +from users.tests.userserializer import * +from users.tests.twowaydomain import * +from users.tests.rememberme import * \ No newline at end of file diff --git a/backend/secfit/users/tests/__pycache__/__init__.cpython-39.pyc b/backend/secfit/users/tests/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6921f31b1d86262ba73498c36a1637a08351a9bd Binary files /dev/null and b/backend/secfit/users/tests/__pycache__/__init__.cpython-39.pyc differ diff --git a/backend/secfit/users/tests/__pycache__/registration.cpython-39.pyc b/backend/secfit/users/tests/__pycache__/registration.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc6227c0e731a32fab3c1a4ff7131f6f1e198459 Binary files /dev/null and b/backend/secfit/users/tests/__pycache__/registration.cpython-39.pyc differ diff --git a/backend/secfit/users/tests/__pycache__/rememberme.cpython-39.pyc b/backend/secfit/users/tests/__pycache__/rememberme.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20eb26f0d456f0966e2f57e0f32353a25dbe396c Binary files /dev/null and b/backend/secfit/users/tests/__pycache__/rememberme.cpython-39.pyc differ diff --git a/backend/secfit/users/tests/__pycache__/twowaydomain.cpython-39.pyc b/backend/secfit/users/tests/__pycache__/twowaydomain.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16babb841fce3253a4b540c322badfa015c94119 Binary files /dev/null and b/backend/secfit/users/tests/__pycache__/twowaydomain.cpython-39.pyc differ diff --git a/backend/secfit/users/tests/__pycache__/userserializer.cpython-39.pyc b/backend/secfit/users/tests/__pycache__/userserializer.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4b2288fb5c7e81515fb240ce4b75e652f3758fc0 Binary files /dev/null and b/backend/secfit/users/tests/__pycache__/userserializer.cpython-39.pyc differ diff --git a/backend/secfit/users/tests/registration.py b/backend/secfit/users/tests/registration.py new file mode 100644 index 0000000000000000000000000000000000000000..ea159533ce9ee33fa0ee5c3bb56e1b1c87362315 --- /dev/null +++ b/backend/secfit/users/tests/registration.py @@ -0,0 +1,73 @@ +import json + +from django.test import TestCase, RequestFactory, Client +from users.models import User + +url = "/api/users/" + +class RegistrationTestCase(TestCase): + """Django test for regestering a new user. + + tests: + set_up: Set up everything needed for the test + test_registration: Register new user + """ + + def setUp(self): + self.client = Client() + + def test_registration(self): + data = {"username": "Test", "email": "test@t.no", + "password": "strong_pwd", "password1": "strong_pwd", + "phone_number": "12345678", "country": "Norway", + "city": "Trondheim", "street_address": "Trondheimsvegen 123"} + + response = self.client.post(url, data) + self.assertEqual(response.status_code, 201) + + +class BoundaryValuesOfRegistrationTestCase(TestCase): + """Django test for boundary values of regestering a new user. + + tests: + set_up: Set up everything needed for the test + test_minimum_data: Register new user with as little data as possible + test_blank_password: Register new user without password + test_blank_username: Register new user without username + test_invalid_email: Register new user without valid email + """ + + def set_up(self): + self.client = Client() + + def test_minimum_data(self): + data = {"username": "t", "email": "", + "password": "1", "password1": "1", + "phone_number": "", "country": "", + "city": "", "street_address": ""} + response = self.client.post(url, data) + self.assertEqual(response.status_code, 201) + + def test_blank_password(self): + data = {"username": "test", "email": "", + "password": "", "password1": "", + "phone_number": "", "country": "", + "city": "", "street_address": ""} + response = self.client.post(url, data) + self.assertEqual(response.status_code, 400) + + def test_blank_username(self): + data = {"username": "", "email": "", + "password": "1", "password1": "1", + "phone_number": "", "country": "", + "city": "", "street_address": ""} + response = self.client.post(url, data) + self.assertEqual(response.status_code, 400) + + def test_invalid_email(self): + data = {"username": "Test", "email": "test.no", + "password": "1", "password1": "1", + "phone_number": "", "country": "", + "city": "", "street_address": ""} + response = self.client.post(url, data) + self.assertEqual(response.status_code, 400) \ No newline at end of file diff --git a/backend/secfit/users/tests/rememberme.py b/backend/secfit/users/tests/rememberme.py new file mode 100644 index 0000000000000000000000000000000000000000..476a28713415b8e97f725ebe2f5effdccde88d81 --- /dev/null +++ b/backend/secfit/users/tests/rememberme.py @@ -0,0 +1,28 @@ +import json + +from django.test import TestCase, RequestFactory, Client +from rest_framework.test import APIRequestFactory, APIClient +from users.serializers import UserSerializer +from users.models import User +from workouts.views import RememberMe + +url = '/api/remember_me/' + +class RemembermeTestCase(TestCase): + """Django test for the rememberme functionality + + tests: + set_up: Set up everything needed for the test + test_rememberme: Tests creation of rememberme for authenticated user + """ + + def setUp(self): + self.client = APIClient() + self.user = User.objects.create(username="user",password="test") + self.client.force_authenticate(user=self.user) + + def test_rememberme(self): + data = {"username": "user", "password": "test"} + response = self.client.get(url, data) + self.assertEqual(response.status_code, 200) + \ No newline at end of file diff --git a/backend/secfit/users/tests/twowaydomain.py b/backend/secfit/users/tests/twowaydomain.py new file mode 100644 index 0000000000000000000000000000000000000000..cf4375868a2595f411f582f0b1276d6fe9237ad2 --- /dev/null +++ b/backend/secfit/users/tests/twowaydomain.py @@ -0,0 +1,90 @@ +import json + +from django.test import TestCase, RequestFactory, Client +from users.serializers import UserSerializer +from users.models import User + +url = "/api/users/" + +test_cases = [ + {'email':'wrong', 'username':'wrong', 'password':'normal', 'password1':'normal', 'phone_number':'empty', 'country':'empty', 'city':'empty', 'street_address':'normal'}, + {'email':'wrong', 'username':'normal', 'password':'empty', 'password1':'normal', 'phone_number':'normal', 'country':'normal', 'city':'normal', 'street_address':'empty'}, + {'email':'wrong', 'username':'empty', 'password':'normal', 'password1':'empty', 'phone_number':'empty', 'country':'empty', 'city':'normal', 'street_address':'normal'}, + {'email':'wrong', 'username':'normal', 'password':'empty', 'password1':'empty', 'phone_number':'empty', 'country':'normal', 'city':'normal', 'street_address':'normal'}, + {'email':'wrong', 'username':'normal', 'password':'normal', 'password1':'normal', 'phone_number':'normal', 'country':'empty', 'city':'empty', 'street_address':'empty'}, + {'email':'normal','username':'wrong', 'password':'empty', 'password1':'normal', 'phone_number':'normal', 'country':'empty', 'city':'normal', 'street_address':'normal'}, + {'email':'normal','username':'normal', 'password':'normal', 'password1':'empty', 'phone_number':'empty', 'country':'normal', 'city':'normal', 'street_address':'empty'}, + {'email':'normal','username':'empty', 'password':'normal', 'password1':'normal', 'phone_number':'empty', 'country':'normal', 'city':'normal', 'street_address':'empty'}, + {'email':'normal','username':'wrong', 'password':'empty', 'password1':'empty', 'phone_number':'normal', 'country':'normal', 'city':'empty', 'street_address':'normal'}, + {'email':'empty', 'username':'empty', 'password':'empty', 'password1':'empty', 'phone_number':'normal', 'country':'normal', 'city':'empty', 'street_address':'normal'}, + {'email':'empty', 'username':'wrong', 'password':'normal', 'password1':'normal', 'phone_number':'empty', 'country':'normal', 'city':'normal', 'street_address':'empty'}, + {'email':'empty', 'username':'normal', 'password':'empty', 'password1':'normal', 'phone_number':'normal', 'country':'empty', 'city':'empty', 'street_address':'normal'}, + {'email':'empty', 'username':'normal', 'password':'normal', 'password1':'empty', 'phone_number':'empty', 'country':'normal', 'city':'normal', 'street_address':'empty'}, + {'email':'empty', 'username':'empty', 'password':'empty', 'password1':'normal', 'phone_number':'normal', 'country':'empty', 'city':'normal', 'street_address':'normal'}, + {'email':'empty', 'username':'wrong', 'password':'normal', 'password1':'empty', 'phone_number':'normal', 'country':'normal', 'city':'empty', 'street_address':'empty'}, + {'email':'empty', 'username':'normal', 'password':'normal', 'password1':'normal', 'phone_number':'empty', 'country':'empty', 'city':'normal', 'street_address':'normal'}, + {'email':'wrong', 'username':'wrong', 'password':'empty', 'password1':'empty', 'phone_number':'normal', 'country':'normal', 'city':'normal', 'street_address':'normal'}, + {'email':'wrong', 'username':'empty', 'password':'normal', 'password1':'normal', 'phone_number':'normal', 'country':'normal', 'city':'empty', 'street_address':'empty'}, + {'email':'wrong', 'username':'wrong', 'password':'normal', 'password1':'empty', 'phone_number':'empty', 'country':'empty', 'city':'normal', 'street_address':'normal'}, + {'email':'wrong', 'username':'empty', 'password':'normal', 'password1':'normal', 'phone_number':'empty', 'country':'empty', 'city':'empty', 'street_address':'normal'}, + {'email':'normal','username':'normal', 'password':'empty', 'password1':'normal', 'phone_number':'empty', 'country':'normal', 'city':'empty', 'street_address':'normal'}, + {'email':'normal','username':'normal', 'password':'normal', 'password1':'empty', 'phone_number':'normal', 'country':'empty', 'city':'normal', 'street_address':'empty'}, + {'email':'normal','username':'empty', 'password':'normal', 'password1':'normal', 'phone_number':'empty', 'country':'normal', 'city':'empty', 'street_address':'normal'}, + {'email':'normal','username':'wrong', 'password':'empty', 'password1':'normal', 'phone_number':'normal', 'country':'empty', 'city':'normal', 'street_address':'empty'}, + {'email':'normal','username':'normal', 'password':'normal', 'password1':'empty', 'phone_number':'normal', 'country':'normal', 'city':'empty', 'street_address':'normal'}, + {'email':'normal','username':'empty', 'password':'empty', 'password1':'normal', 'phone_number':'empty', 'country':'normal', 'city':'normal', 'street_address':'empty'}, + {'email':'normal','username':'wrong', 'password':'normal', 'password1':'empty', 'phone_number':'normal', 'country':'empty', 'city':'normal', 'street_address':'normal'} + ] + +case_data = { + 'normal': { + 'email': 'test@test.no', + 'username': 'test', + 'password': 'test123', + 'password1': 'test123', + 'phone_number': 12354678, + 'country': 'Norway', + 'city': 'Trondheim', + 'street_address': 'Trondheimsvegen', + }, + 'empty': { + 'email': '', + 'username': '', + 'password': '', + 'password1': '', + 'phone_number': '', + 'country': '', + 'city': '', + 'street_address': '', + }, + 'wrong': { + 'email': 'test.no', + 'username': 'test]', + } + } + +class TwoWayDomainTestOfRegistrationTestCase(TestCase): + """Django two-way domain test for registration of new user. + + tests: + set_up: Set up everything needed for the test and define test cases + test_domain_registration Tests all test cases and evalutes them against expected responses + """ + + def set_up(self): + self.client = Client() + + def test_domain_registration(self): + for case in test_cases: + data = {} + + for key, value in case.items(): + data[key] = case_data[value][key] + code = 201 + + if case['email'] == 'wrong' or case['username'] == 'wrong' or case['password'] == 'empty' or case['username'] == 'empty' or case['password1'] == 'empty': + code = 400 + + response = self.client.post(url, data) + self.assertEqual(response.status_code, code) + \ No newline at end of file diff --git a/backend/secfit/users/tests/userserializer.py b/backend/secfit/users/tests/userserializer.py new file mode 100644 index 0000000000000000000000000000000000000000..3565b9395113e1383abf5ee5b6e2b9f648e68247 --- /dev/null +++ b/backend/secfit/users/tests/userserializer.py @@ -0,0 +1,54 @@ +import json + +from django.test import TestCase, RequestFactory, Client +from users.serializers import UserSerializer +from users.models import User +from django.core.exceptions import ValidationError + +url = "/api/users/" + +class UserSerializerTestCase(TestCase): + """Django test for the UserSerializer class. + + tests: + set_up: Set up everything needed for the test + test_validate_password_valid: Test the validate password method with valid input + test_validate_password_invalid: Test the validate password mothod with invalid input + test_create: Test creating a new user with the create method + """ + + def set_up(self): + self.user1 = User.objects.create(username="user1") + self.user2 = User.objects.create(username="user2", coach=self.user1) + self.factory = RequestFactory() + + def test_validate_password_valid(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_password_invalid(self): + password = "some_very_strong_pwd" + password1 = "Some_wrong_pwd" + serializer = UserSerializer(data = {'password': password,'password1': 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") \ No newline at end of file diff --git a/backend/secfit/users/views.py b/backend/secfit/users/views.py index f5efef5c2ce82566ab380cecad344e3143c31813..56bd1be3500c682c720850c441a2d9a5e4df23a8 100644 --- a/backend/secfit/users/views.py +++ b/backend/secfit/users/views.py @@ -98,7 +98,6 @@ class OfferList( serializer.save(owner=self.request.user) def get_queryset(self): - qs = Offer.objects.none() result = Offer.objects.none() if self.request.user: diff --git a/backend/secfit/workouts/serializers.py b/backend/secfit/workouts/serializers.py index 26e6f25c6eeb3e944849ec7805d543cf188f6c4a..423a74c0cd0339df7254af96bc49c2408d4bd14a 100644 --- a/backend/secfit/workouts/serializers.py +++ b/backend/secfit/workouts/serializers.py @@ -133,10 +133,6 @@ class WorkoutSerializer(serializers.HyperlinkedModelSerializer): instance.save() # Handle ExerciseInstances - - # This updates existing exercise instances without adding or deleting object. - # zip() will yield n 2-tuples, where n is - # min(len(exercise_instance), len(exercise_instance_data)) for exercise_instance, exercise_instance_data in zip( exercise_instances.all(), exercise_instances_data ): @@ -158,13 +154,17 @@ class WorkoutSerializer(serializers.HyperlinkedModelSerializer): ExerciseInstance.objects.create( workout=instance, **exercise_instance_data ) + # Else if exercise instances have been removed from the workout, then delete them elif len(exercise_instances_data) < len(exercise_instances.all()): for i in range(len(exercise_instances_data), len(exercise_instances.all())): exercise_instances.all()[i].delete() + + self.handle_workout_files(instance, validated_data) - # Handle WorkoutFiles + return instance + def handle_workout_files(self, instance, validated_data): if "files" in validated_data: files_data = validated_data.pop("files") files = instance.files @@ -183,9 +183,8 @@ class WorkoutSerializer(serializers.HyperlinkedModelSerializer): # Else if files have been removed, delete WorkoutFiles elif len(files_data) < len(files.all()): for i in range(len(files_data), len(files.all())): - files.all()[i].delete() + files.all()[i].delete() - return instance def get_owner_username(self, obj): """Returns the owning user's username diff --git a/backend/secfit/workouts/tests.py b/backend/secfit/workouts/tests.py deleted file mode 100644 index d656a7334d960e9993453e723e16f80fb899847a..0000000000000000000000000000000000000000 --- a/backend/secfit/workouts/tests.py +++ /dev/null @@ -1,481 +0,0 @@ -import json - -from django.test import TestCase, RequestFactory, Client -from rest_framework.test import APIRequestFactory, APIClient -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 - - - -### Test boundary values of new workout ### - -class BoundaryValuesOfNewWorkout(TestCase): - def setUp(self): - self.client = APIClient() - self.user = User.objects.create(username="user",password="user") - self.client.force_authenticate(user=self.user) - self.request = json.loads('{"name": "test", "date": "2021-03-06T18:00:00.000Z", "notes": "note", "visibility": "PU", "exercise_instances": [], "filename": []}') - - def test_name(self): - self.request["name"] = "" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,400) #Blank should fail - - self.request["name"] = "test" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,201) - - self.request["name"] = "@€xrgrdh" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,201) #Wierd signs should propably fail, but app is faulty - - self.request["name"] = "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" #100 - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,201) - - self.request["name"] = "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" #101 - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,400) #More than 100 chars should fail - - - def test_date(self): - self.request["date"] = "" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,400) #Blank should fail - - self.request["date"] = "2021-32-32T18:00:00.000Z" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,400) #Not valid date should fail - - self.request["date"] = "2021-03-08T18:00:00.000Z" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,201) - - def test_notes(self): - self.request["notes"] = "" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,400) #Blank should fail - - self.request["notes"] = "test" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,201) - - # No upper value for notes - - def test_visibility(self): - self.request["visibility"] = "" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,400) #Blank should fail - - self.request["visibility"] = "XX" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,400) #Not one of the three cases should fail - - self.request["visibility"] = "PRI" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,400) #More than 2 chars should fail - - self.request["visibility"] = "PR" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,201) - - - -### 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_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, 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 = APIClient() - self.coach = User.objects.create(username="coach",password="coach") - self.athlete = User.objects.create(username="athlete",password="athlete", coach=self.coach) - self.client.force_authenticate(user=self.coach) - self.request = json.loads('{"name": "test", "date": "2021-03-06T18:00:00.000Z", "notes": "note", "visibility": "PU", "exercise_instances": [], "filename": []}') - - def test_createWorkoutAsCoach(self): - self.request["owner"] = "athlete" - request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') - self.assertEquals(request.status_code,201) - - def test_checkCoach(self): - workout = Workout.objects.create(name="test", date="2021-03-02T18:00:00Z", notes="note", owner=self.athlete, visibility="PU") - self.assertEqual(self.athlete, workout.owner) - - - -### Test categorize exercise ### - -class CategorizeExerciseTestCase(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 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_createCategorizedEcercise(self): - data = {"name": "Test", "description": "Test", - "category": "Endurance", "unit": "kg"} - - response = self.client.post("/api/exercises/", data) - self.assertEqual(response.status_code, 201) - - def test_checkCategorizedExercise(self): - exercise = Exercise.objects.create(name="test", description="test", category="Endurance", unit="kg") - self.assertEqual("Endurance", exercise.category) - - - -### 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 diff --git a/backend/secfit/workouts/tests/__init__.py b/backend/secfit/workouts/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..40c1f2dad94087bdfc5e5b7bc6918235bef0d1b1 --- /dev/null +++ b/backend/secfit/workouts/tests/__init__.py @@ -0,0 +1,5 @@ +from workouts.tests.permissions import * +from workouts.tests.workouts import * +from workouts.tests.visibility import * +from workouts.tests.features import * +from workouts.tests.workoutfiles import * diff --git a/backend/secfit/workouts/tests/__pycache__/__init__.cpython-39.pyc b/backend/secfit/workouts/tests/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf6672fde4fc32647b1984a518b592a3c3328abe Binary files /dev/null and b/backend/secfit/workouts/tests/__pycache__/__init__.cpython-39.pyc differ diff --git a/backend/secfit/workouts/tests/__pycache__/features.cpython-39.pyc b/backend/secfit/workouts/tests/__pycache__/features.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50625fcbe48c55f13915e8a6a03ae3661b62d6a5 Binary files /dev/null and b/backend/secfit/workouts/tests/__pycache__/features.cpython-39.pyc differ diff --git a/backend/secfit/workouts/tests/__pycache__/permissions.cpython-39.pyc b/backend/secfit/workouts/tests/__pycache__/permissions.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd99adea274c2087cd1054eb2b8f3af461d65fb1 Binary files /dev/null and b/backend/secfit/workouts/tests/__pycache__/permissions.cpython-39.pyc differ diff --git a/backend/secfit/workouts/tests/__pycache__/visibility.cpython-39.pyc b/backend/secfit/workouts/tests/__pycache__/visibility.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf81702d0c6ecdcfd6c2e74261229bccc49a178e Binary files /dev/null and b/backend/secfit/workouts/tests/__pycache__/visibility.cpython-39.pyc differ diff --git a/backend/secfit/workouts/tests/__pycache__/workoutfiles.cpython-39.pyc b/backend/secfit/workouts/tests/__pycache__/workoutfiles.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70699ee7da46968f6914bda16cefe9bb5e83966d Binary files /dev/null and b/backend/secfit/workouts/tests/__pycache__/workoutfiles.cpython-39.pyc differ diff --git a/backend/secfit/workouts/tests/__pycache__/workouts.cpython-39.pyc b/backend/secfit/workouts/tests/__pycache__/workouts.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..80291826b23e56c82d4f7a9ed3f78cf3e29f5fea Binary files /dev/null and b/backend/secfit/workouts/tests/__pycache__/workouts.cpython-39.pyc differ diff --git a/backend/secfit/workouts/tests/features.py b/backend/secfit/workouts/tests/features.py new file mode 100644 index 0000000000000000000000000000000000000000..b8f2de5ab141c44d632ca7584c7fdcf8091d9445 --- /dev/null +++ b/backend/secfit/workouts/tests/features.py @@ -0,0 +1,64 @@ +import json + +from django.test import TestCase, RequestFactory, Client +from rest_framework.test import APIRequestFactory, APIClient +from workouts.models import Workout, Exercise, ExerciseInstance, WorkoutFile +from users.models import User + +class CreateWorkoutForAthleteTestCase(TestCase): + """Django test for UC1 - create workout for athlete as coach + + tests: + set_up: Set up everything needed for the test + test_create_workout_as_coach: Creates a workout as coach + test_check_coach: Checks that athlete is set as owner + """ + + def setUp(self): + self.client = APIClient() + self.coach = User.objects.create(username="coach",password="coach") + self.athlete = User.objects.create(username="athlete",password="athlete", coach=self.coach) + self.client.force_authenticate(user=self.coach) + self.request = json.loads('{"name": "test", "date": "2021-03-06T18:00:00.000Z", "notes": "note", "visibility": "PU", "exercise_instances": [], "filename": []}') + + def test_create_workout_as_coach(self): + self.request["owner"] = "athlete" + request = self.client.post('/api/workouts/', json.dumps(self.request), content_type='application/json') + self.assertEquals(request.status_code,201) + + def test_check_coach(self): + workout = Workout.objects.create(name="test", date="2021-03-02T18:00:00Z", notes="note", owner=self.athlete, visibility="PU") + self.assertEqual(self.athlete, workout.owner) + +class CategorizeExerciseTestCase(TestCase): + """Django test for UC4 - categorize exercise + + tests: + set_up: Set up everything needed for the test + test_create_categorized_excercise: Creates categorized exercise + test_check_categorized_exercise: Checks category of exercise + """ + + def setUp(self): + self.client = Client() + + # Create user + self.user = User.objects.create(username="user") + self.user.set_password('user') + self.user.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_create_categorized_exercise(self): + data = {"name": "Test", "description": "Test", + "category": "Endurance", "unit": "kg"} + + response = self.client.post("/api/exercises/", data) + self.assertEqual(response.status_code, 201) + + def test_check_categorized_exercise(self): + exercise = Exercise.objects.create(name="test", description="test", category="Endurance", unit="kg") + self.assertEqual("Endurance", exercise.category) diff --git a/backend/secfit/workouts/tests/permissions.py b/backend/secfit/workouts/tests/permissions.py new file mode 100644 index 0000000000000000000000000000000000000000..5a9c1b14fd1953ea0d4f8b261f29b4358a2e7041 --- /dev/null +++ b/backend/secfit/workouts/tests/permissions.py @@ -0,0 +1,271 @@ +import json + +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 + +url_workout1 = '/api/workouts/1/' +date = "2021-03-02T18:00:00Z" + +class IsOwnerTestCase(TestCase): + """Django test for the permission-class IsOwner in workout/permissions + + tests: + set_up: Set up everything needed for the test + test_is_owner_valid: Test a input where user is owner + test_is_owner_invalid: Test a input where user is not owner + """ + + 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=date, notes="note", owner=self.user1, visibility="PU") + + def test_is_owner_valid(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_is_owner_invalid(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): + """Django test for the permission-class IsOwnerOfWorkout in workout/permissions + + tests: + set_up: Set up everything needed for the test + test_has_permission_valid: Test a input where user should have permission + test_has_permission_invalid: Input where user should not have permission + test_has_object_permission_valid: Test a input where user should have permission + test_has_object_permission_invalid: Input where user should not have permission + """ + + 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=date, notes="note", owner=self.user1, visibility="PU") + + def test_has_permission_valid(self): + request = self.factory.get('/') + request.user = self.user1 + request.data = { 'workout' : url_workout1} + has_permission = self.isOwnerOfWorkout.has_permission(request, None) + self.assertTrue(has_permission) + + request = self.factory.post('/') + request.user = self.user1 + request.data = { 'workout' : url_workout1} + has_permission = self.isOwnerOfWorkout.has_permission(request, None) + self.assertTrue(has_permission) + + def test_has_permission_invalid(self): + request = self.factory.post('/') + request.user = self.user2 + request.data = { 'workout' : url_workout1} + 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_permission_valid(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_permission_invalid(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): + """Django test for the permission-class IsCoachAndVisibleToCoach in workout/permissions + + tests: + set_up: Set up everything needed for the test + test_is_coach_and_visible_to_coach_valid: Test where user is coach and checks that it is visible + test_is_coach_and_visible_to_coach_invalid: Test where user is not coach and checks that it is not visible + """ + + 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=date, notes="note", owner=self.user1, visibility="PU") + + def test_is_coach_and_visible_to_coach_valid(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_is_coach_and_visible_to_coach_invalid(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): + """Django test for the permission-class IsCoachOfWorkoutAndVisibleToCoach in workout/permissions + + tests: + set_up: Set up everything needed for the test + test_is_coach_of_workout_and_visible_to_coach_valid: Names describes itself + test_is_coach_of_workout_and_visible_to_coach_invalid: Names describes itself + """ + + 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=date, notes="note", owner=self.user1, visibility="PU") + + def test_is_coach_of_workout_and_visible_to_coach_valid(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_is_coach_of_workout_and_visible_to_coach_invalid(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): + """Django test for the permission-class IsPublic in workout/permissions + + tests: + set_up: Set up everything needed for the test + test_is_public_valid: Test if public workout is public + test_is_public_invalid: Test if not public workout is not public + """ + + 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_is_public_valid(self): + request = self.factory.get('/') + request.user = self.user1 + workout = Workout.objects.create(name="test", date=date, notes="note", owner=self.user1, visibility="PU") + + is_public = self.isPublic.has_object_permission(request, None, workout) + self.assertTrue(is_public) + + def test_is_public_invalid(self): + request = self.factory.get('/') + request.user = self.user1 + workout = Workout.objects.create(name="test", date=date, notes="note", owner=self.user1, visibility="CO") + + is_public = self.isPublic.has_object_permission(request, None, workout) + self.assertFalse(is_public) + +class IsWorkoutPublicTestCase(TestCase): + """Django test for the permission-class IsWorkoutPublic in workout/permissions + + tests: + set_up: Set up everything needed for the test + test_is_workout_public_valid: Test if public workout is public + test_is_workout_public_invalid: Test if not public workout is not public + """ + + 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_is_workout_public_valid(self): + request = self.factory.get('/') + request.user = self.user1 + workout = Workout.objects.create(name="test", date=date, 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_is_workout_public_invalid(self): + request = self.factory.get('/') + request.user = self.user1 + workout = Workout.objects.create(name="test", date=date, 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): + """Django test for the permission-class IsWorkoutPublic in workout/permissions + + tests: + set_up: Set up everything needed for the test + test_is_read_only_valid: Test if workout is readonly not owner user + test_is_read_only_invalid: Test if workout is not readonly for owner + """ + + 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=date, notes="note", owner=self.user1, visibility="PU") + + def test_is_read_only_valid(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_is_read_only_invalid(self): + request = self.factory.post('/') + request.user = self.user1 + + is_readonly = self.isReadOnly.has_object_permission(request, None, self.workout) + self.assertFalse(is_readonly) diff --git a/backend/secfit/workouts/tests/visibility.py b/backend/secfit/workouts/tests/visibility.py new file mode 100644 index 0000000000000000000000000000000000000000..3bf86e3ec385e8e5d77f794cc68378b516431aa2 --- /dev/null +++ b/backend/secfit/workouts/tests/visibility.py @@ -0,0 +1,173 @@ +import json + +from django.test import TestCase, RequestFactory, Client +from workouts.models import Workout, Exercise, ExerciseInstance, WorkoutFile +from users.models import User +from comments.models import Comment + +url_workouts = '/api/workouts/' +url_workout_files = '/api/workout-files/' +url_comments = '/api/comments/' +url_token = '/api/token/' +url_path = '/path/' +bearer = 'Bearer ' +date = "2021-03-06T18:00:00Z" + +class AthleteAccessTestCase(TestCase): + """Django test for FR5 - visibility of details, files and comments for Athletes + + tests: + set_up: Set up everything needed for the test + test_visibility_on_private_content: Test vilibility on private content + test_visibility_on_public_content: Test visibility on public content + """ + + 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(url_token, {'username': 'user', 'password': 'user'}) + content = json.loads(response.content) + self.client.defaults['HTTP_AUTHORIZATION'] = bearer + content['access'] + + def test_visibility_on_private_content(self): + workout = Workout.objects.create(name="workout", date=date, notes="notes", owner=self.athlete, visibility="PR") + comment = Comment.objects.create(content="comment", timestamp=date, owner=self.athlete, workout=workout) + file = WorkoutFile.objects.create(file=url_path, owner=self.athlete, workout=workout) + + response = self.client.get(url_workouts+str(workout.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get(url_comments+str(comment.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get(url_workout_files+str(file.id)+'/') + self.assertEqual(response.status_code, 200) + + def test_visibility_on_public_content(self): + workout = Workout.objects.create(name="workout", date=date, notes="notes", owner=self.athlete, visibility="PU") + comment = Comment.objects.create(content="comment", timestamp=date, owner=self.athlete, workout=workout) + file = WorkoutFile.objects.create(file=url_path, owner=self.athlete, workout=workout) + + response = self.client.get(url_workouts+str(workout.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get(url_comments+str(comment.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get(url_workout_files+str(file.id)+'/') + self.assertEqual(response.status_code, 200) + +class CoachAccessTestCase(TestCase): + """Django test for FR5 - visibility of details, files and comments for Coaches + + tests: + set_up: Set up everything needed for the test + test_visibility_on_private_content: Test vilibility on private content + test_visibility_on_coach_content: Test visibility on coach content + """ + + 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(url_token, {'username': 'user1', 'password': 'user1'}) + content = json.loads(response.content) + self.client.defaults['HTTP_AUTHORIZATION'] = bearer + content['access'] + + def test_visibility_on_private_content(self): + workout = Workout.objects.create(name="workout", date=date, notes="notes", owner=self.athlete, visibility="PR") + comment = Comment.objects.create(content="comment", timestamp=date, owner=self.athlete, workout=workout) + file = WorkoutFile.objects.create(file=url_path, owner=self.athlete, workout=workout) + + response = self.client.get(url_workouts+str(workout.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get(url_comments+str(comment.id)+'/') + self.assertEqual(response.status_code, 403) + + response = self.client.get(url_workout_files+str(file.id)+'/') + self.assertEqual(response.status_code, 200) + + def test_visibility_on_coach_content(self): + workout = Workout.objects.create(name="workout", date=date, notes="notes", owner=self.athlete, visibility="CO") + comment = Comment.objects.create(content="comment", timestamp=date, owner=self.athlete, workout=workout) + file = WorkoutFile.objects.create(file=url_path, owner=self.athlete, workout=workout) + + response = self.client.get(url_workouts+str(workout.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get(url_comments+str(comment.id)+'/') + self.assertEqual(response.status_code, 200) + + response = self.client.get(url_workout_files+str(file.id)+'/') + self.assertEqual(response.status_code, 200) + +class UserAccessTestCase(TestCase): + """Django test for FR5 - visibility of details, files and comments for other users + + tests: + set_up: Set up everything needed for the test + test_visibility_on_private_content: Test vilibility on private content + test_visibility_on_coach_content: Test visibility on coach content + """ + + 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(url_token, {'username': 'user2', 'password': 'user2'}) + content = json.loads(response.content) + self.client.defaults['HTTP_AUTHORIZATION'] = bearer + content['access'] + + def test_visibility_on_private_content(self): + workout = Workout.objects.create(name="workout", date=date, notes="notes", owner=self.athlete, visibility="PR") + comment = Comment.objects.create(content="comment", timestamp=date, owner=self.athlete, workout=workout) + file = WorkoutFile.objects.create(file=url_path, owner=self.athlete, workout=workout) + + response = self.client.get(url_workouts+str(workout.id)+'/') + self.assertEqual(response.status_code, 403) + + response = self.client.get(url_comments+str(comment.id)+'/') + self.assertEqual(response.status_code, 403) + + response = self.client.get(url_workout_files+str(file.id)+'/') + self.assertEqual(response.status_code, 403) + + def test_visibility_on_coach_content(self): + workout = Workout.objects.create(name="workout", date=date, notes="notes", owner=self.athlete, visibility="CO") + comment = Comment.objects.create(content="comment", timestamp=date, owner=self.athlete, workout=workout) + file = WorkoutFile.objects.create(file=url_path, owner=self.athlete, workout=workout) + + response = self.client.get(url_workouts+str(workout.id)+'/') + self.assertEqual(response.status_code, 403) + + response = self.client.get(url_comments+str(comment.id)+'/') + self.assertEqual(response.status_code, 403) + + response = self.client.get(url_workout_files+str(file.id)+'/') + self.assertEqual(response.status_code, 403) diff --git a/backend/secfit/workouts/tests/workoutfiles.py b/backend/secfit/workouts/tests/workoutfiles.py new file mode 100644 index 0000000000000000000000000000000000000000..c56e3f8edc318244646c5cbe6142dfa5033a5f13 --- /dev/null +++ b/backend/secfit/workouts/tests/workoutfiles.py @@ -0,0 +1,34 @@ +import json + +from django.test import TestCase, RequestFactory, Client +from rest_framework.test import APIRequestFactory, APIClient +from workouts.models import Workout, Exercise, ExerciseInstance, WorkoutFile +from workouts.serializers import WorkoutSerializer +from users.models import User + +class WorkoutFilesTestCase(TestCase): + """Django test for perserving the functionality of workout-files + + tests: + set_up: Set up everything needed for the test + """ + def setUp(self): + self.user = User.objects.create(username="user") + self.workout = Workout.objects.create(name="workout", date="2021-03-06T18:00:00Z", notes="note", + owner=self.user, visibility="PU") + self.exercise = Exercise.objects.create(name="exercise", description="test", unit="test") + + def test_workout_files(self): + data = {'name': 'workout', 'notes': 'note', 'visibility': 'PU', + 'date': '2021-03-06T18:00:00.000Z', + 'exercise_instances': [{'exercise': self.exercise, 'sets':12, 'number':12}], + 'files': [{'owner': self.user, 'file':'workouts/1/document.pdf'}] + } + WorkoutSerializer(data).update(self.workout, data) + + instance = ExerciseInstance.objects.filter(workout=self.workout).first() + self.assertEqual(instance.exercise, self.exercise) + + files = WorkoutFile.objects.filter(workout=self.workout).first() + self.assertEqual(files.owner, self.user) + self.assertEqual(files.file, 'workouts/1/document.pdf') diff --git a/backend/secfit/workouts/tests/workouts.py b/backend/secfit/workouts/tests/workouts.py new file mode 100644 index 0000000000000000000000000000000000000000..01d62b1b7f7bd5990599b00914f5fbf01fcb34a9 --- /dev/null +++ b/backend/secfit/workouts/tests/workouts.py @@ -0,0 +1,87 @@ +import json + +from django.test import TestCase, RequestFactory, Client +from rest_framework.test import APIRequestFactory, APIClient +from workouts.models import Workout, Exercise, ExerciseInstance, WorkoutFile +from users.models import User + +url_workout = '/api/workouts/' +content_type = 'application/json' + +class BoundaryValuesOfNewWorkout(TestCase): + """Django test for boundary values of registering a new workout. + + tests: + set_up: Set up everything needed for the test + test_name: Test boundary values of name field + test_date: Test boundary values of date field + test_notes: Test boundary values of notes field + test_visibility: Test boundary values of visibility field + """ + + def setUp(self): + self.client = APIClient() + self.user = User.objects.create(username="user",password="user") + self.client.force_authenticate(user=self.user) + self.request = json.loads('{"name": "test", "date": "2021-03-06T18:00:00.000Z", "notes": "note", "visibility": "PU", "exercise_instances": [], "filename": []}') + + def test_name(self): + self.request["name"] = "" + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,400) + + self.request["name"] = "test" + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,201) + + self.request["name"] = "@€xrgrdh" + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,201) + + self.request["name"] = "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" #100 + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,201) + + self.request["name"] = "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" #101 + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,400) + + + def test_date(self): + self.request["date"] = "" + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,400) + + self.request["date"] = "2021-32-32T18:00:00.000Z" + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,400) + + self.request["date"] = "2021-03-08T18:00:00.000Z" + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,201) + + def test_notes(self): + self.request["notes"] = "" + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,400) + + self.request["notes"] = "test" + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,201) + + def test_visibility(self): + self.request["visibility"] = "" + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,400) + + self.request["visibility"] = "XX" + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,400) + + self.request["visibility"] = "PRI" + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,400) + + self.request["visibility"] = "PR" + request = self.client.post(url_workout, json.dumps(self.request), content_type=content_type) + self.assertEquals(request.status_code,201) diff --git a/backend/secfit/workouts/urls.py b/backend/secfit/workouts/urls.py index 7c46a3f1ff311edc25dd455bb85780c1a1644738..a337905610097c2f337db1f54c0d636e3262d965 100644 --- a/backend/secfit/workouts/urls.py +++ b/backend/secfit/workouts/urls.py @@ -6,7 +6,6 @@ from rest_framework_simplejwt.views import ( TokenRefreshView, ) -# This is a bit messy and will need to change urlpatterns = format_suffix_patterns( [ path("", views.api_root), diff --git a/backend/secfit/workouts/views.py b/backend/secfit/workouts/views.py index a4119b8c0f90698d5ffe6c721d8c5b22988bff83..bc80c843cbe9398a95df4fe894c8993e4577801c 100644 --- a/backend/secfit/workouts/views.py +++ b/backend/secfit/workouts/views.py @@ -65,17 +65,19 @@ class RememberMe( serializer_class = RememberMeSerializer + def get(self, request): if request.user.is_authenticated == False: raise PermissionDenied + else: - return Response({"remember_me": self.rememberme()}) + return Response({"remember_me": self.create_rememberme()}) def post(self, request): - cookieObject = namedtuple("Cookies", request.COOKIES.keys())( + cookie_object = namedtuple("Cookies", request.COOKIES.keys())( *request.COOKIES.values() ) - user = self.get_user(cookieObject) + user = self.get_user(cookie_object) refresh = RefreshToken.for_user(user) return Response( { @@ -84,15 +86,15 @@ class RememberMe( } ) - def get_user(self, cookieObject): - decode = base64.b64decode(cookieObject.remember_me) + def get_user(self, cookie_object): + decode = base64.b64decode(cookie_object.remember_me) user, sign = pickle.loads(decode) # Validate signature if sign == self.sign_user(user): return user - def rememberme(self): + def create_rememberme(self): creds = [self.request.user, self.sign_user(str(self.request.user))] return base64.b64encode(pickle.dumps(creds)) @@ -131,8 +133,8 @@ class WorkoutList( def perform_create(self, serializer): if(self.request.POST.get("owner")): owner = self.request.POST.get("owner") - User = get_user_model() - user = User.objects.get(username=owner) + user_model = get_user_model() + user = user_model.objects.get(username=owner) serializer.save(owner=user) else: serializer.save(owner=self.request.user)