Skip to content
Snippets Groups Projects
Commit 24b8ff76 authored by borzechof99's avatar borzechof99 :whale2:
Browse files

Merge branch '53-implement-start-and-end-text-model-and-their-api' into 'master'

Resolve "Implement Start and End Text Model and their API"

Closes #53

See merge request swp-unisport/team-warumkeinrust/unisport-o-mat!52
parents 1fc55036 5c3cde5c
No related branches found
No related tags found
No related merge requests found
......@@ -134,4 +134,9 @@ instead of returning Result(data), the paginator needs to be used again so it ca
return paginator.get_paginated_response(serializer.data)
```
This function already returns a fully valid Response, so it can be directly returned.
\ No newline at end of file
This function already returns a fully valid response, so it can be directly returned.
## Our Handling of REST Standards
In our usecase of the Admin Frontend, we either explicitly work on objects we chose from a list of given objects, or we create a new object all together. Because of these circumstances, it is not relevant for the PUT request to create new objects entirely, since we know that all objects currently being edited exist. This means that the PUT implementations in `views.py` do not create new objects if called with an unknown primary key. Instead, they are similar to PATCH, but require all fields to be sent along instead of just a portion of them as PATCH does.
\ No newline at end of file
# Generated by Django 3.2 on 2021-06-28 17:51
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
("quiz", "0012_merge_20210627_2254"),
]
operations = [
migrations.CreateModel(
name="GreetingEndTexts",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"greeting",
models.TextField(default="Willkommen zum Uni-Sport-O-Mat!"),
),
(
"greeting_de",
models.TextField(
default="Willkommen zum Uni-Sport-O-Mat!", null=True
),
),
(
"greeting_en",
models.TextField(
default="Willkommen zum Uni-Sport-O-Mat!", null=True
),
),
("end", models.TextField(default="Wähle deinen Sport!")),
("end_de", models.TextField(default="Wähle deinen Sport!", null=True)),
("end_en", models.TextField(default="Wähle deinen Sport!", null=True)),
],
),
migrations.AlterField(
model_name="sport",
name="last_used",
field=models.DateField(default=django.utils.timezone.localdate),
),
]
# Generated by Django 3.2 on 2021-06-28 18:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("quiz", "0013_auto_20210628_1751"),
]
operations = [
migrations.CreateModel(
name="EndText",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("text", models.TextField(default="Wähle deinen Sport!")),
("text_de", models.TextField(default="Wähle deinen Sport!", null=True)),
("text_en", models.TextField(default="Wähle deinen Sport!", null=True)),
],
),
migrations.CreateModel(
name="GreetingText",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("text", models.TextField(default="Willkommen zum Uni-Sport-O-Mat!")),
(
"text_de",
models.TextField(
default="Willkommen zum Uni-Sport-O-Mat!", null=True
),
),
(
"text_en",
models.TextField(
default="Willkommen zum Uni-Sport-O-Mat!", null=True
),
),
],
),
migrations.DeleteModel(
name="GreetingEndTexts",
),
]
......@@ -301,3 +301,27 @@ class QuestionOrderEntry(models.Model):
def __str__(self):
return f"Entry {self.order_id}: {self.type_of_slot}"
class GreetingText(models.Model):
"""
Database with only one row (if everything is done right)
Includes start text as column
"""
text = models.TextField(default="Willkommen zum Uni-Sport-O-Mat!")
def __str__(self):
return f"{self.text}"
class EndText(models.Model):
"""
Database with only one row (if everything is done right)
Includes end text as column
"""
text = models.TextField(default="Wähle deinen Sport!")
def __str__(self):
return f"{self.text}"
......@@ -204,3 +204,21 @@ class CriteriaSerializer(serializers.BaseSerializer):
criteria_list.append(criterion_dict)
return criteria_list
class GreetingEndSerializer(serializers.BaseSerializer):
"""
Serializer for GreetingText and EndText
"""
def to_representation(self, obj):
"""
Represents the object with German and English text
"""
json_obj = {
"text_de": obj.text_de,
"text_en": obj.text_en,
}
return json_obj
""" This module tests all our quiz models"""
import os
import re
import shutil
import tempfile
......@@ -549,6 +550,60 @@ class APITest(APITestCase):
self.assertEqual(response.data["currently_active"], False)
def test_greeting_view(self):
"""
Test whether the greeting behaves correctly
"""
response = self.client.get(reverse("greeting"))
self.assertEqual(response.data["text_de"], "Willkommen zum Uni-Sport-O-Mat!")
self.assertEqual(response.data["text_de"], response.data["text_en"])
# Test whether new Values change correctly
data = {"text_de": "Hallo", "text_en": "Hi"}
response = self.client.post(reverse("greeting"), format="json", data=data)
response = self.client.get(reverse("greeting"))
self.assertEqual(response.data["text_de"], "Hallo")
self.assertEqual(response.data["text_en"], "Hi")
# If the object is deleted, the default values are returned again
response = self.client.delete(reverse("greeting"))
self.assertEqual(response.data["text_de"], "Willkommen zum Uni-Sport-O-Mat!")
self.assertEqual(response.data["text_de"], response.data["text_en"])
def test_end_view(self):
"""
Test whether the end behaves correctly
"""
response = self.client.get(reverse("end"))
self.assertEqual(response.data["text_de"], "Wähle deinen Sport!")
self.assertEqual(response.data["text_de"], response.data["text_en"])
# Test whether new values change correctly
data = {"text_de": "Hallo", "text_en": "Hi"}
response = self.client.post(reverse("end"), format="json", data=data)
response = self.client.get(reverse("end"))
self.assertEqual(response.data["text_de"], "Hallo")
self.assertEqual(response.data["text_en"], "Hi")
# If the object is deleted, the default values are returned again
response = self.client.delete(reverse("end"))
self.assertEqual(response.data["text_de"], "Wähle deinen Sport!")
self.assertEqual(response.data["text_de"], response.data["text_en"])
class QuestionOrderEntry_Test(TestCase):
"""
......
......@@ -4,7 +4,7 @@ Here, every Model which needs translation fields is registered.
from modeltranslation.translator import register, TranslationOptions
from .models import Question, CallToMove, KnowledgeSnack
from .models import Question, CallToMove, KnowledgeSnack, GreetingText, EndText
@register(Question)
......@@ -41,3 +41,21 @@ class KnowledgeSnackTranslationOptions(TranslationOptions):
fields = ("text",)
required_languages = ("de",)
fallback_values = ("No Translation for this Field",)
@register(GreetingText)
class GreetingTextTranslationOptions(TranslationOptions):
"""
Translation options for GreetingText.
"""
fields = ("text",)
@register(EndText)
class EndTextTranslationOptions(TranslationOptions):
"""
Translation options for EndText.
"""
fields = ("text",)
......@@ -18,8 +18,9 @@ from .serializers import (
SingleSportSerializer,
CriteriaSerializer,
IncompleteSportSerializer,
GreetingEndSerializer,
)
from .models import Sport, Criterion, Question
from .models import Sport, Criterion, Question, GreetingText, EndText
# Create your views here.
......@@ -281,3 +282,127 @@ class CriteriaView(APIView):
response = CriteriaSerializer(data)
return Response(response.data)
class GreetingEndView(APIView):
"""
View for handling the beginning sentence
"""
given_object = None
def post(self, request):
"""
api/greeting POST
Creates a new object if none exist, otherwise forwards to PUT
"""
if self.given_object.objects.count() > 0:
return self.put(request)
sentence = self.given_object() # pylint: disable=not-callable
if "text_de" in request.data.keys():
sentence.text_de = request.data["text_de"]
if "text_en" in request.data.keys():
sentence.text_en = request.data["text_en"]
sentence.save()
return Response(GreetingEndSerializer(sentence).data)
def get(self, request):
"""
api/greeting GET
Sends out the greeting
"""
sentence = self.given_object.objects.all()
if sentence.count() == 0:
sentence = self.given_object() # pylint: disable=not-callable
else:
sentence = sentence.first()
return Response(GreetingEndSerializer(sentence).data)
def put(self, request):
"""
api/greeting PUT
Overwrites German and English beginning
"""
sentence = self.given_object.objects.all()
if sentence.count() == 0:
return Response(status=404)
sentence = sentence.first()
sentence.text_de = request.data["text_de"]
sentence.text_en = request.data["text_en"]
sentence.save()
return Response(GreetingEndSerializer(sentence).data)
def patch(self, request):
"""
api/greeting PATCH
Overwrites German and/or English beginning, if they exist
"""
sentence = self.given_object.objects.all()
if sentence.count() == 0:
return Response(status=404)
sentence = sentence.first()
if "text_de" in request.data.keys():
sentence.text_de = request.data["text_de"]
if "text_en" in request.data.keys():
sentence.text_en = request.data["text_en"]
sentence.save()
return Response(GreetingEndSerializer(sentence).data)
def delete(self, request):
"""
api/greeting DELETE
Deletes the object so default values are reinstated
"""
sentence = self.given_object.objects.all()
if sentence.count() == 0:
return Response(status=404)
sentence = sentence.first()
sentence.text_de = self.given_object._meta.get_field("text").get_default()
sentence.text_en = self.given_object._meta.get_field("text").get_default()
sentence.save()
return Response(GreetingEndSerializer(sentence).data)
class GreetingView(GreetingEndView):
"""
View for the greeting strings
Inherited CRUD from GreetingEndView
"""
given_object = GreetingText
class EndView(GreetingEndView):
"""
View for the end strings
Inherited CRUD from GreetingEndView
"""
given_object = EndText
......@@ -33,4 +33,6 @@ urlpatterns = [
name="incomplete",
),
path("api/admin/criteria/", views.CriteriaView.as_view(), name="criteria"),
path("api/admin/greeting/", views.GreetingView.as_view(), name="greeting"),
path("api/admin/end/", views.EndView.as_view(), name="end"),
]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment