From ad0e494165416fa4c71598adc913b4dc146942a7 Mon Sep 17 00:00:00 2001 From: borzechof99 <borzechof99@mi.fu-berlin.de> Date: Sat, 26 Jun 2021 14:21:54 +0200 Subject: [PATCH] Add last_used and currently_active to Sports model, Views, and Tests --- .../migrations/0007_auto_20210626_1130.py | 30 +++++++++++++++++++ .../migrations/0008_alter_sport_last_used.py | 22 ++++++++++++++ .../migrations/0009_alter_sport_last_used.py | 22 ++++++++++++++ .../migrations/0010_alter_sport_last_used.py | 22 ++++++++++++++ .../migrations/0011_alter_sport_last_used.py | 19 ++++++++++++ unisportomat/quiz/models.py | 17 +++++++++++ unisportomat/quiz/serializers.py | 5 ++++ unisportomat/quiz/tests.py | 27 +++++++++++++++++ unisportomat/quiz/views.py | 29 +++++++++++++++--- 9 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 unisportomat/quiz/migrations/0007_auto_20210626_1130.py create mode 100644 unisportomat/quiz/migrations/0008_alter_sport_last_used.py create mode 100644 unisportomat/quiz/migrations/0009_alter_sport_last_used.py create mode 100644 unisportomat/quiz/migrations/0010_alter_sport_last_used.py create mode 100644 unisportomat/quiz/migrations/0011_alter_sport_last_used.py diff --git a/unisportomat/quiz/migrations/0007_auto_20210626_1130.py b/unisportomat/quiz/migrations/0007_auto_20210626_1130.py new file mode 100644 index 0000000..d9c59df --- /dev/null +++ b/unisportomat/quiz/migrations/0007_auto_20210626_1130.py @@ -0,0 +1,30 @@ +# Generated by Django 3.2 on 2021-06-26 11:30 + +import datetime +from django.db import migrations, models +import quiz.models + + +class Migration(migrations.Migration): + + dependencies = [ + ("quiz", "0006_auto_20210612_1230"), + ] + + operations = [ + migrations.AddField( + model_name="sport", + name="currently_active", + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name="sport", + name="last_used", + field=models.DateField(default=datetime.date(2021, 6, 26)), + ), + migrations.AlterField( + model_name="criterionrating", + name="rating", + field=models.IntegerField(validators=[quiz.models.validate_rating]), + ), + ] diff --git a/unisportomat/quiz/migrations/0008_alter_sport_last_used.py b/unisportomat/quiz/migrations/0008_alter_sport_last_used.py new file mode 100644 index 0000000..5a5e06b --- /dev/null +++ b/unisportomat/quiz/migrations/0008_alter_sport_last_used.py @@ -0,0 +1,22 @@ +# Generated by Django 3.2 on 2021-06-26 11:32 + +import datetime +from django.db import migrations, models +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ("quiz", "0007_auto_20210626_1130"), + ] + + operations = [ + migrations.AlterField( + model_name="sport", + name="last_used", + field=models.DateField( + default=datetime.datetime(2021, 6, 26, 11, 32, 52, 231135, tzinfo=utc) + ), + ), + ] diff --git a/unisportomat/quiz/migrations/0009_alter_sport_last_used.py b/unisportomat/quiz/migrations/0009_alter_sport_last_used.py new file mode 100644 index 0000000..fdff24a --- /dev/null +++ b/unisportomat/quiz/migrations/0009_alter_sport_last_used.py @@ -0,0 +1,22 @@ +# Generated by Django 3.2 on 2021-06-26 11:33 + +import datetime +from django.db import migrations, models +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ("quiz", "0008_alter_sport_last_used"), + ] + + operations = [ + migrations.AlterField( + model_name="sport", + name="last_used", + field=models.DateField( + default=datetime.datetime(2021, 6, 26, 11, 33, 26, 967602, tzinfo=utc) + ), + ), + ] diff --git a/unisportomat/quiz/migrations/0010_alter_sport_last_used.py b/unisportomat/quiz/migrations/0010_alter_sport_last_used.py new file mode 100644 index 0000000..cf01355 --- /dev/null +++ b/unisportomat/quiz/migrations/0010_alter_sport_last_used.py @@ -0,0 +1,22 @@ +# Generated by Django 3.2 on 2021-06-26 11:39 + +import datetime +from django.db import migrations, models +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ("quiz", "0009_alter_sport_last_used"), + ] + + operations = [ + migrations.AlterField( + model_name="sport", + name="last_used", + field=models.DateTimeField( + default=datetime.datetime(2021, 6, 26, 11, 39, 12, 106108, tzinfo=utc) + ), + ), + ] diff --git a/unisportomat/quiz/migrations/0011_alter_sport_last_used.py b/unisportomat/quiz/migrations/0011_alter_sport_last_used.py new file mode 100644 index 0000000..798a235 --- /dev/null +++ b/unisportomat/quiz/migrations/0011_alter_sport_last_used.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2 on 2021-06-26 11:39 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ("quiz", "0010_alter_sport_last_used"), + ] + + operations = [ + migrations.AlterField( + model_name="sport", + name="last_used", + field=models.DateField(default=django.utils.timezone.now), + ), + ] diff --git a/unisportomat/quiz/models.py b/unisportomat/quiz/models.py index 2a0fd62..5ddc375 100644 --- a/unisportomat/quiz/models.py +++ b/unisportomat/quiz/models.py @@ -2,6 +2,7 @@ from django.core.exceptions import ValidationError from django.db import models +from django.utils import timezone def validate_rating(value): @@ -43,6 +44,8 @@ class SportManager(models.Manager): Creates new Sport Object and every CriterionRating for it """ sport = self.create(**kwargs) + sport.currently_active = True + sport.last_used = timezone.localdate() for crit in Criterion.objects.iterator(): sport.rate(crit, -1) @@ -61,6 +64,13 @@ class Sport(models.Model): url = models.URLField() criteria_ratings = models.ManyToManyField("Criterion", through="CriterionRating") + # The Date Field last_used is set to now-time everytime a sport is activated + # either through manual activation or activation through the scraper + last_used = models.DateField(default=timezone.localdate) + + # Boolean currently_active states whether the sport is in the archive or not + currently_active = models.BooleanField(default=True) + objects = SportManager() def __str__(self): @@ -91,6 +101,13 @@ class Sport(models.Model): return True + def reactivate(self): + """ + Sets currently_active to True and updates the last_used Date + """ + self.currently_active = True + self.last_used = timezone.localdate() + class CriterionManager(models.Manager): """ diff --git a/unisportomat/quiz/serializers.py b/unisportomat/quiz/serializers.py index 0b8605d..fd53a48 100644 --- a/unisportomat/quiz/serializers.py +++ b/unisportomat/quiz/serializers.py @@ -76,6 +76,8 @@ class SingleSportSerializer(serializers.BaseSerializer): serialized_data["id"] = sport.pk serialized_data["name"] = sport.name serialized_data["url"] = sport.url + serialized_data["currently_active"] = sport.currently_active + serialized_data["last_used"] = sport.last_used criteria = [] @@ -113,6 +115,9 @@ class SingleSportSerializer(serializers.BaseSerializer): if "url" in request.data.keys(): sport_dictionary["url"] = request.data["url"] + if "currently_active" in request.data.keys(): + sport_dictionary["currently_active"] = request.data["currently_active"] + # 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(): diff --git a/unisportomat/quiz/tests.py b/unisportomat/quiz/tests.py index 4eec683..6a9d64f 100644 --- a/unisportomat/quiz/tests.py +++ b/unisportomat/quiz/tests.py @@ -7,6 +7,7 @@ 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.utils import timezone from django.urls import reverse from django.test import TestCase, override_settings from rest_framework.test import APITestCase @@ -395,6 +396,8 @@ class APITest(APITestCase): "id": 1, "name": "Jiu Jitsu", "url": "http://www.test.de", + "currently_active": True, + "last_used": timezone.localdate(), "criteria": [{"id": 1, "name": "Outdoorsport", "value": 1}], } self.assertDictEqual(response.data, sport_data) @@ -406,6 +409,7 @@ class APITest(APITestCase): sport_data = { "name": "Karate", "url": "http://www.test2.de", + "currently_active": True, "criteria": [{"id": 1, "name": "Outdoorsport", "value": 1}], } @@ -414,8 +418,12 @@ class APITest(APITestCase): data=sport_data, format="json", ) + + response = self.client.get(reverse("small-sport-list-detail", kwargs={"pk": 1})) + self.assertEqual(response.data["name"], sport_data["name"]) self.assertEqual(response.data["url"], sport_data["url"]) + self.assertEqual(response.data["currently_active"], True) self.assertEqual(len(response.data["criteria"]), Criterion.objects.count()) self.assertDictEqual( response.data["criteria"][0], {"id": 1, "name": "Outdoorsport", "value": 1} @@ -434,6 +442,9 @@ class APITest(APITestCase): data=sport_data, format="json", ) + + response = self.client.get(reverse("small-sport-list-detail", kwargs={"pk": 1})) + 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()) @@ -515,3 +526,19 @@ class APITest(APITestCase): 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) + + def test_currently_active(self): + """ + Tests if PATCHing the "currently_active" value to false correctly changes the sport + """ + + # Set Up Values + response = self.client.patch( + reverse("small-sport-list-detail", kwargs={"pk": 1}), + data={"currently_active": False}, + format="json", + ) + + response = self.client.get(reverse("small-sport-list-detail", kwargs={"pk": 1})) + + self.assertEqual(response.data["currently_active"], False) diff --git a/unisportomat/quiz/views.py b/unisportomat/quiz/views.py index a860a21..079f7aa 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().order_by("name") + sports = Sport.objects.filter(currently_active=True).order_by("name") sports = paginator.paginate_queryset(sports, request) is_filled_tuples = [] @@ -146,10 +146,18 @@ class SmallSportListView(viewsets.ViewSet): sport.name = request_data["name"] sport.url = request_data["url"] + if request_data["currently_active"] is True and sport.currently_active is False: + # If the Sport is just now being activated, update the Date + sport.reactivate() + else: + sport.currently_active = request_data["currently_active"] + # Overwrite Criterion Ratings for criterion, value in request_data["criteria"]: sport.rate(criterion, value) + sport.save() + # Re-Serialize changed Sport and Send it back response = SingleSportSerializer(sport) @@ -180,9 +188,22 @@ class SmallSportListView(viewsets.ViewSet): if "url" in request_data.keys(): sport.url = request_data["url"] + if "currently_active" in request_data.keys(): + if ( + request_data["currently_active"] is True + and sport.currently_active is False + ): + # If the Sport is just now being activated, update the Date + sport.reactivate() + else: + sport.currently_active = request_data["currently_active"] + # Overwrite Criterion Ratings - for criterion, value in request_data["criteria"]: - sport.rate(criterion, value) + if "criteria" in request_data.keys(): + for criterion, value in request_data["criteria"]: + sport.rate(criterion, value) + + sport.save() # Re-Serialize changed Sport and Send it back response = SingleSportSerializer(sport) @@ -220,7 +241,7 @@ class IncompleteSportView(APIView): incomplete_sport_list = [] - for sport in Sport.objects.iterator(): + for sport in Sport.objects.filter(currently_active=True).iterator(): if not sport.is_filled(): incomplete_sport_list.append(sport) -- GitLab