diff --git a/unisportomat/quiz/management/commands/seed_db.py b/unisportomat/quiz/management/commands/seed_db.py index 4413c59fbc77655386f9ed4da1e08fe6cae13139..d6a6d836735a50158d0857d57278b5e41df1dc1c 100644 --- a/unisportomat/quiz/management/commands/seed_db.py +++ b/unisportomat/quiz/management/commands/seed_db.py @@ -90,8 +90,6 @@ class Command(BaseCommand): # Create ratings for all sports and criterions for sport in Sport.objects.all(): for criterion in Criterion.objects.all(): - if sport.name == "Ballett" and criterion.name == "Mannschaftssport": - continue sport.rate(criterion, random.randint(1, 10)) # Create questions diff --git a/unisportomat/quiz/serializers.py b/unisportomat/quiz/serializers.py index 06ba81bfcfd47792f3bf2a41ba57379d1101a5bd..fa26fbbd7049d7d840da30ac190ddea392373896 100644 --- a/unisportomat/quiz/serializers.py +++ b/unisportomat/quiz/serializers.py @@ -113,20 +113,24 @@ class SingleSportSerializer(serializers.BaseSerializer): if "url" in request.data.keys(): sport_dictionary["url"] = request.data["url"] - # A Number of Criteria may be sent with the Sport - sport_dictionary["criteria"] = [] + # If the Sport is only now created with a POST-Request, no Criteria can be filled out for it + # This is because the Admin Frontend doesn't have a list of Criteria ready + if "criteria" in request.data.keys(): - # For every Sent Criterion, the ID of the Criterion and the Rating Value is being tested for Validity - for criterion in request.data["criteria"]: + # A Number of Criteria may be sent with the Sport + sport_dictionary["criteria"] = [] - value = criterion["value"] - try: - validate_rating(value) - crit = Criterion.objects.get(pk=criterion["id"]) - except: # pylint: disable=bare-except - return None + # For every Sent Criterion, the ID of the Criterion and the Rating Value is being tested for Validity + for criterion in request.data["criteria"]: - sport_dictionary["criteria"].append((crit, value)) + value = criterion["value"] + try: + validate_rating(value) + crit = Criterion.objects.get(pk=criterion["id"]) + except: # pylint: disable=bare-except + return None + + sport_dictionary["criteria"].append((crit, value)) return sport_dictionary diff --git a/unisportomat/quiz/tests.py b/unisportomat/quiz/tests.py index 542d2c5e8cfdd224a2307e24509f1a9717e94410..4eec6834aaa3e46e0b2f459cde3fb40b8a26e541 100644 --- a/unisportomat/quiz/tests.py +++ b/unisportomat/quiz/tests.py @@ -7,7 +7,9 @@ import tempfile from django.core.files.uploadedfile import SimpleUploadedFile from django.core.management import call_command from django.utils.translation import get_language, activate +from django.urls import reverse from django.test import TestCase, override_settings +from rest_framework.test import APITestCase from django.conf import settings from .models import ( Sport, @@ -379,3 +381,137 @@ class Modeltranslation_Two_Languages_Test(TestCase): self.assertEqual(self.question.text, self.question.text_en) self.assertNotEqual(self.question.text, self.question.text_de) + + +class APITest(APITestCase): + """Tests the Django API""" + + fixtures = ["sports.json", "criteria.json", "criterion_ratings.json"] + + def test_get_sport_returns_correct_data(self): + """Test the API endpoint /sport/{id}""" + response = self.client.get(reverse("small-sport-list-detail", kwargs={"pk": 1})) + sport_data = { + "id": 1, + "name": "Jiu Jitsu", + "url": "http://www.test.de", + "criteria": [{"id": 1, "name": "Outdoorsport", "value": 1}], + } + self.assertDictEqual(response.data, sport_data) + + def test_put_sport_makes_correct_changes(self): + """ + Test the API endpoint /sport/{id} for put requests + """ + sport_data = { + "name": "Karate", + "url": "http://www.test2.de", + "criteria": [{"id": 1, "name": "Outdoorsport", "value": 1}], + } + + response = self.client.put( + reverse("small-sport-list-detail", kwargs={"pk": 1}), + data=sport_data, + format="json", + ) + self.assertEqual(response.data["name"], sport_data["name"]) + self.assertEqual(response.data["url"], sport_data["url"]) + self.assertEqual(len(response.data["criteria"]), Criterion.objects.count()) + self.assertDictEqual( + response.data["criteria"][0], {"id": 1, "name": "Outdoorsport", "value": 1} + ) + + def test_patch_sport_makes_correct_changes(self): + """ + Test the API endpoint /sport/{id} for patch requests + """ + sport_data = { + "criteria": [{"id": 1, "value": 3}], + } + + response = self.client.patch( + reverse("small-sport-list-detail", kwargs={"pk": 1}), + data=sport_data, + format="json", + ) + self.assertEqual(response.data["name"], "Jiu Jitsu") + self.assertEqual(response.data["url"], "http://www.test.de") + self.assertEqual(len(response.data["criteria"]), Criterion.objects.count()) + self.assertDictEqual( + response.data["criteria"][0], {"id": 1, "name": "Outdoorsport", "value": 3} + ) + + def test_get_sports_returns_correct_data(self): + """Test if API endpoint /sport returns correct sports list""" + + response = self.client.get(reverse("small-sport-list-list")) + + sport_data = [ + { + "id": 1, + "is_filled": True, + "name": "Jiu Jitsu", + "url": "http://www.test.de", + } + ] + self.assertListEqual(response.data["results"], sport_data) + self.assertEqual(response.data["count"], 1) + + def test_post_sports_creates_correct_entry(self): + """Test if post to /sport creates a correct object""" + sport_data_new = { + "name": "Karate", + "url": "http://www.test2.de", + } + + response = self.client.post( + reverse("small-sport-list-list"), data=sport_data_new + ) + self.assertEqual(response.data["name"], sport_data_new["name"]) + self.assertEqual(response.data["url"], sport_data_new["url"]) + self.assertEqual(len(response.data["criteria"]), Criterion.objects.count()) + self.assertEqual(Sport.objects.count(), 2) + + def test_delete_sports_creates_correct_entry(self): + """Test if delete to /sports deletes an object""" + + response = self.client.delete( + reverse("small-sport-list-detail", kwargs={"pk": 1}) + ) + + self.assertEqual(Sport.objects.count(), 0) + + def test_get_incomplete_sport_list(self): + """ + Tests if get to /sport/incomplete/ returns a list of incomplete sports + """ + + # Set Up Incomplete Sport + response = self.client.patch( + reverse("small-sport-list-detail", kwargs={"pk": 1}), + data={"criteria": [{"id": 1, "value": -1}]}, + format="json", + ) + + response = self.client.get(reverse("incomplete")) + + self.assertEqual(len(response.data), 1) + self.assertEqual(response.data[0]["name"], "Jiu Jitsu") + + def test_get_criteria(self): + """ + Tests if get /critera/ returns a list of all criteria + """ + + # Set Up Values + response = self.client.patch( + reverse("small-sport-list-detail", kwargs={"pk": 1}), + data={"criteria": [{"id": 1, "value": 7}]}, + format="json", + ) + + response = self.client.get(reverse("criteria")) + + self.assertEqual(len(response.data), Criterion.objects.count()) + self.assertEqual(response.data[0]["number_of_sports_active"], 1) + self.assertEqual(response.data[0]["sum_of_weights"], 7) diff --git a/unisportomat/quiz/views.py b/unisportomat/quiz/views.py index ca418f78b7a0f6854756ee97b4f4181cf6d1b9fa..a860a2184f976660ec174ad501242bf1f6c24ba5 100644 --- a/unisportomat/quiz/views.py +++ b/unisportomat/quiz/views.py @@ -75,7 +75,7 @@ class SmallSportListView(viewsets.ViewSet): paginator = PageNumberWithPageSizePagination() - sports = Sport.objects.all() + sports = Sport.objects.all().order_by("name") sports = paginator.paginate_queryset(sports, request) is_filled_tuples = [] @@ -105,12 +105,6 @@ class SmallSportListView(viewsets.ViewSet): new_sport.name = request_data["name"] new_sport.url = request_data["url"] - # Before writing other Database Entries for Rating, the Sport needs to be saved once - new_sport.save() - - for criterion, value in request_data["criteria"]: - new_sport.rate(criterion, value) - new_sport.save() response = SingleSportSerializer(new_sport) diff --git a/unisportomat/unisportomat/urls.py b/unisportomat/unisportomat/urls.py index 6814e5ccff31e40f3b83e35ce4023ab016831d91..388d94e57dc1440659c8320eca2485f5bd78fee9 100644 --- a/unisportomat/unisportomat/urls.py +++ b/unisportomat/unisportomat/urls.py @@ -27,6 +27,10 @@ router.register(r"small-sport-list", views.SmallSportListView, "small-sport-list urlpatterns = [ path("admin/", admin.site.urls), path("api/admin/", include(router.urls)), - path("api/admin/sport/incomplete/", views.IncompleteSportView.as_view()), - path("api/admin/criteria/", views.CriteriaView.as_view()), + path( + "api/admin/sport/incomplete/", + views.IncompleteSportView.as_view(), + name="incomplete", + ), + path("api/admin/criteria/", views.CriteriaView.as_view(), name="criteria"), ]