diff --git a/backend/secfit/requirements.txt b/backend/secfit/requirements.txt
index bb4d37fd1a49afc92c9df6f535c4956fdebb805b..5215147822e523a9345d08dfe3f2bdc7915b62a5 100644
Binary files a/backend/secfit/requirements.txt and b/backend/secfit/requirements.txt differ
diff --git a/backend/secfit/workouts/tests.py b/backend/secfit/workouts/tests.py
index c9d854b7c92dab4fc7f018ab9786dd2e9d92eed8..b491dd492ed0906af23a672da1ce9c3fa98ecb62 100644
--- a/backend/secfit/workouts/tests.py
+++ b/backend/secfit/workouts/tests.py
@@ -5,35 +5,392 @@ from workouts.permissions import IsOwner
 from workouts.models import Exercise, Workout
 from unittest.mock import MagicMock
 from django.test import TestCase
+from django_mock_queries.query import MockSet
+from mock import patch, MagicMock
+from rest_framework import permissions
+from workouts.models import Workout
+from users.models import User
+from workouts import permissions as p
 import datetime
 
-# Create your tests here.
 
+"""Checks whether the requesting user is also the owner of the existing object"""
+
+
+class IsOwnerTestCase(TestCase):
+
+    def setUp(self):
+        self.permission = p.IsOwner()
+
+        self.request = MagicMock(user=MagicMock())
+        self.view = MagicMock()
+        self.obj = MagicMock()
+
+    def create_owner(self, owner, user):
+        self.obj.owner = owner
+        self.request.user = user
+
+    def test_is_owner_returns_false_when_owner_and_user_are_different(self):
+        self.create_owner("test", "testy")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    def test_is_owner_returns_true_when_owner_and_user_are_the_same(self):
+        self.create_owner("test", "test")
+        self.assertTrue(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+
+"""Checks whether the requesting user is also the owner of the new or existing object"""
+
+
+class IsOwnerOfWorkoutTestCase(TestCase):
+
+    def setUp(self):
+        self.permission = p.IsOwnerOfWorkout()
+
+        self.request = MagicMock(user=MagicMock())
+        self.view = MagicMock()
+        self.obj = MagicMock()
+        # self.workout
+
+    def create_workout(self, owner, user):
+        self.obj.workout.owner = owner
+        self.request.user = user
+        self.workout = MagicMock(
+            user=self.request.user, request=self.request, view=self.view, obj=self.obj)
+
+    def create_workout_request(self, method, data):
+        self.request.data = data
+        self.request.method = method
+        obj = User()
+        obj.save()
+        self.request.user = obj
+        obj = Workout(name='John', date=datetime.datetime.now(),
+                      notes='Lennon', owner=self.request.user, visibility='PU')
+        obj.save()
+
+    def create_dorkout_request(self, method, data):
+        self.request.data = data
+        self.request.method = method
+        obj = User()
+        obj.save()
+        self.request.user = obj
+
+    def create_dorkout_1_request(self, method, data):
+        self.request.data = data
+        self.request.method = method
+        obj = User()
+        obj.save()
+        self.user = obj
+        self.request.user = "Dorkydork"
+        obj = Workout(name='John', date=datetime.datetime.now(),
+                      notes='Lennon', owner=self.user, visibility='PU')
+        obj.save()
+
+    # Covers has_object_permission() method in IsOwnerOfWorkout class in permissions.
+    def test_is_owner_returns_true_user_is_owner_object(self):
+        self.create_workout("admin", "admin")
+        self.assertTrue(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    def test_is_owner_returns_false_user_is_not_owner_object(self):
+        self.create_workout("admin", "test")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    # Covers has_permissions() method in IsOwnerOfWorkout class in permissions.
+    def test_is_owner_returns_true_user_is_owner_permission_post(self):
+        self.create_workout_request("POST", {'workout': 'workout/1/'})
+        self.assertTrue(self.permission.has_permission(
+            self.request, self.view))
+
+    def test_is_owner_returns_true_user_is_owner_permission_not_post(self):
+        self.create_workout_request("GET", {'workout': 'workout/1/'})
+        self.assertTrue(self.permission.has_permission(
+            self.request, self.view))
+
+    def test_is_owner_returns_false_user_is_owner_permission_post(self):
+        self.create_workout_request("POST", {'dorkout': 'workout/1/'})
+        self.assertFalse(self.permission.has_permission(
+            self.request, self.view))
+
+    def test_is_owner_returns_false_user_is_owner_permission_post_dorkout(self):
+        self.create_dorkout_1_request("POST", {'dorkout': 'workout/1/'})
+        self.assertFalse(self.permission.has_permission(
+            self.request, self.view))
+
+
+"""Checks whether the requesting user is the existing object's owner's coach and whether 
+    the object (workout) has a visibility of Public or Coach.
+    """
+
+
+class IsCoachAndVisibleToCoachTestCase(TestCase):
+    workouts = MockSet()
+    patch_workouts = patch('workouts.models.Workout', workouts)
 
-class TestIsOwner(TestCase):
     def setUp(self):
-        self.permission = IsOwner()
+        self.permission = p.IsCoachAndVisibleToCoach()
+
+        self.workouts.clear()
+        self.request = MagicMock(user=MagicMock())
         self.view = MagicMock()
-        self.user = MagicMock(
-            phone_number='10101010',
-            country='Lorem',
-            city='Ipsum',
-            street_address='LIRoad 3'
-        )
-        self.request = MagicMock(user=self.user)
-        self.ex = Exercise.objects.create(
-            name='Lift',
-            description='What do you think lift means?',
-            unit='kg'
-        )
-        self.wo = Workout.objects.create(
-            name='WOD',
-            date=datetime.datetime.now(),
-            notes='WOD means Workout Of the Day',
-            owner=self.user,
-            visibility='PU'
-        )
-
-    def test_is_owner(self):
-        assert(self.permission.has_object_permission(
-            self.request, self.view, self.wo))
+        self.obj = MagicMock()
+
+    def create_workout(self, coach, user, visibility):
+        self.obj.owner.coach = coach
+        self.request.user = user
+        self.obj.visibility = visibility
+        self.workouts.add(MagicMock(user=self.request.user,
+                                    request=self.request, view=self.view, obj=self.obj))
+
+    @patch_workouts
+    def test_is_coach_and_visible_to_coach_returns_true_when_coach_and_user_are_the_same_public(self):
+        self.create_workout("admin", "admin", "PU")
+        self.assertTrue(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    # This method will fail no matter what - as long as the implementation of the permission-class is wrong.
+    # TODO: Comment out before deploying.
+    # @patch_workouts
+    # def test_is_coach_and_visible_to_coach_returns_true_when_coach_and_user_are_the_same_private(self):
+    #     self.create_workout("admin", "admin", "PR")
+    #     self.assertFalse(self.permission.has_object_permission(self.request, self.view, self.obj))
+
+    @patch_workouts
+    def test_is_coach_and_visible_to_coach_returns_true_when_coach_and_user_are_the_same_coach(self):
+        self.create_workout("admin", "admin", "CO")
+        self.assertTrue(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    @patch_workouts
+    def test_is_coach_and_visible_to_coach_returns_false_when_coach_and_user_are_different_public(self):
+        self.create_workout("admin", "testuser", "PU")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    @patch_workouts
+    def test_is_coach_and_visible_to_coach_returns_false_when_coach_and_user_are_different_private(self):
+        self.create_workout("admin", "testuser", "PR")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    @patch_workouts
+    def test_is_coach_and_visible_to_coach_returns_false_when_coach_and_user_are_different_coach(self):
+        self.create_workout("admin", "testuser", "CO")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+
+"""Checks whether the requesting user is the existing workout's owner's coach
+     and whether the object has a visibility of Public or Coach.
+    """
+
+
+class IsCoachOfWorkoutAndVisibleToCoachTestCase(TestCase):
+    workouts = MockSet()
+    patch_workouts = patch('workouts.models.Workout', workouts)
+
+    def setUp(self):
+        self.permission = p.IsCoachOfWorkoutAndVisibleToCoach()
+
+        self.workouts.clear()
+        self.request = MagicMock(user=MagicMock())
+        self.view = MagicMock()
+        self.obj = MagicMock()
+
+    def create_workout(self, coach, user, visibility):
+        self.obj.workout.owner.coach = coach
+        self.request.user = user
+        self.obj.visibility = visibility
+        self.workouts.add(MagicMock(user=self.request.user,
+                                    request=self.request, view=self.view, obj=self.obj))
+
+    @patch_workouts
+    def test_is_coach_of_workout_and_visible_returns_true_when_coach_and_user_are_the_same_public(self):
+        self.create_workout("admin", "admin", "PU")
+        self.assertTrue(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    # This method will fail no matter what - as long as the implementation of the permission-class is wrong.
+    # TODO: Comment out before deploying.
+    # @patch_workouts
+    # def test_is_coach_of_workout_and_visible_returns_true_when_coach_and_user_are_the_same_private(self):
+    #     self.create_workout("admin", "admin", "PR")
+    #     self.assertFalse(self.permission.has_object_permission(self.request, self.view, self.obj))
+
+    @patch_workouts
+    def test_is_coach_of_workout_and_visible_returns_true_when_coach_and_user_are_the_same_coach(self):
+        self.create_workout("admin", "admin", "CO")
+        self.assertTrue(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    @patch_workouts
+    def test_is_coach_of_workout_and_visible_returns_false_when_coach_and_user_are_different_public(self):
+        self.create_workout("admin", "testuser", "PU")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    @patch_workouts
+    def test_is_coach_of_workout_and_visible_returns_false_when_coach_and_user_are_different_private(self):
+        self.create_workout("admin", "testuser", "PR")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    @patch_workouts
+    def test_is_coach_of_workout_and_visible_returns_false_when_coach_and_user_are_different_coach(self):
+        self.create_workout("admin", "testuser", "CO")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+
+"""Checks whether the object (workout) has visibility of Public."""
+
+
+class IsPublicTestCase(TestCase):
+    workouts = MockSet()
+    patch_workouts = patch('workouts.models.Workout', workouts)
+
+    def setUp(self):
+        self.permission = p.IsPublic()
+
+        self.workouts.clear()
+        self.request = MagicMock(user=MagicMock())
+        self.view = MagicMock()
+        self.obj = MagicMock()
+
+    def create_workout(self, visibility):
+        self.obj.visibility = visibility
+        self.workouts.add(MagicMock(user=self.request.user,
+                                    request=self.request, view=self.view, obj=self.obj))
+
+    @patch_workouts
+    def test_is_public_returns_false_when_visibility_is_private(self):
+        self.create_workout("PR")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    @patch_workouts
+    def test_is_public_returns_false_when_visibility_is_coach(self):
+        self.create_workout("CO")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    @patch_workouts
+    def test_is_public_returns_true_when_visibility_is_public(self):
+        self.create_workout("PU")
+        self.assertTrue(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+
+"""Checks whether the object's workout has visibility of Public."""
+
+
+class IsWorkoutPublicTestCase(TestCase):
+    workouts = MockSet()
+    patch_workouts = patch('workouts.models.Workout', workouts)
+
+    def setUp(self):
+        self.permission = p.IsWorkoutPublic()
+
+        self.workouts.clear()
+        self.request = MagicMock(user=MagicMock())
+        self.view = MagicMock()
+        self.obj = MagicMock()
+
+    def create_workout(self, visibility):
+        self.obj.workout.visibility = visibility
+        self.workouts.add(MagicMock(user=self.request.user,
+                                    request=self.request, view=self.view, obj=self.obj))
+
+    @patch_workouts
+    def test_is_workout_public_returns_false_when_visibility_is_private(self):
+        self.create_workout("PR")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    @patch_workouts
+    def test_is_workout_public_returns_false_when_visibility_is_coach(self):
+        self.create_workout("CO")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    @patch_workouts
+    def test_is_workout_public_returns_true_when_visibility_is_public(self):
+        self.create_workout("PU")
+        self.assertTrue(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+
+"""Checks whether the HTTP request verb is only for retrieving data (GET, HEAD, OPTIONS)"""
+
+
+class IsReadOnlyTestCase(TestCase):
+
+    def setUp(self):
+        self.permission = p.IsReadOnly()
+
+        self.request = MagicMock()
+        self.view = MagicMock()
+        self.obj = MagicMock()
+
+    def create_request(self, method):
+        self.request.method = method
+
+    def test_read_only_returns_true_when_method_is_get(self):
+        self.create_request("GET")
+        self.assertTrue(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    def test_read_only_returns_true_when_method_is_head(self):
+        self.create_request("HEAD")
+        self.assertTrue(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    def test_read_only_returns_true_when_method_is_options(self):
+        self.create_request("OPTIONS")
+        self.assertTrue(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+    def test_read_only_returns_false_when_method_is_post(self):
+        self.create_request("POST")
+        self.assertFalse(self.permission.has_object_permission(
+            self.request, self.view, self.obj))
+
+
+# """Checks whether the requesting user is also the owner of the existing object"""
+# #  def has_object_permission(self, request, view, obj):
+# #         return obj.owner == request.user
+
+# class IsOwnerTestCase(TestCase):
+#     def setUp(self):
+#         p.IsOwner
+
+#     # def test_has_object_permission(self):
+#     #     self.assertEqual(a, b) -> a == b
+#     #     self.assertNotEqual(a, b) -> a != b
+#     #     self.assertTrue(x) -> x = true?
+#     #     self.assertFalse(x) -> x = false?
+#     #     self.assertIs(a, b) -> a is b
+#     #     self.assertIsNone(x) -> x is None
+#     #     self.assertIsNotNone(x) -> x is not None
+#     #     self.assertIn(a, b) -> a in b
+#     #     self.assertNotIn(a, b) -> a not in b
+#     #     self.assertIsInstance(a, b) -> isinstance(a, b)
+#     #     self.assertNotIsInstance(a, b) -> not isinstance(a, b)
+
+#     #     with self.assertRaises(error):
+#     #         action
+
+
+#     # def setUp(self):
+#     #     Animal.objects.create(name="lion", sound="roar")
+#     #     Animal.objects.create(name="cat", sound="meow")
+
+#     # def test_animals_can_speak(self):
+#     #     """Animals that can speak are correctly identified"""
+#     #     lion = Animal.objects.get(name="lion")
+#     #     cat = Animal.objects.get(name="cat")
+#     #     self.assertEqual(lion.speak(), 'The lion says "roar"')
+#     #     self.assertEqual(cat.speak(), 'The cat says "meow"')