Skip to content

Commit

Permalink
Merge pull request #62 from SELab-2/tests
Browse files Browse the repository at this point in the history
Tests
  • Loading branch information
LGDTimtou authored Mar 14, 2024
2 parents 2182f3a + 1c6ba3a commit d244e99
Show file tree
Hide file tree
Showing 20 changed files with 216 additions and 105 deletions.
4 changes: 3 additions & 1 deletion api/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ class RedirectAnonymousUserMiddleware:
get_response (function): De functie die wordt aangeroepen om het verzoek te verwerken.
Returns:
HttpResponse: Een HTTP-omleiding naar de inlogpagina als de gebruiker anoniem is en het huidige pad niet de inlogpagina is.
HttpResponse: Een HTTP-omleiding naar de inlogpagina als de gebruiker anoniem is
en het huidige pad niet de inlogpagina is.
Anders wordt het verzoek verder verwerkt door de volgende middleware of de weergavefunctie.
"""

def __init__(self, get_response):
self.get_response = get_response

Expand Down
10 changes: 7 additions & 3 deletions api/models/gebruiker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ class Gebruiker(models.Model):
Model voor een gebruiker, dat zich uitbreidt op het standaardgebruikermodel van Django.
Fields:
user (OneToOneField): Een veld dat verwijst naar het standaardgebruikermodel van Django met een één-op-één-relatie. Dit veld fungeert als het primaire sleutelveld.
is_lesgever (BooleanField): Een boolean veld dat aangeeft of de gebruiker een lesgever is of niet. Standaard ingesteld op False.
user (OneToOneField): Een veld dat verwijst naar het standaardgebruikermodel van Django
met een één-op-één-relatie. Dit veld fungeert als het primaire sleutelveld.
is_lesgever (BooleanField): Een boolean veld dat aangeeft of de gebruiker een lesgever is of niet.
Standaard ingesteld op False.
Methods:
__str__(): Geeft een representatie van het model als een string terug, die de voornaam en achternaam van de gebruiker bevat.
__str__(): Geeft een representatie van het model als een string terug,
die de voornaam en achternaam van de gebruiker bevat.
"""

user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
is_lesgever = models.BooleanField(default=False)

Expand Down
12 changes: 9 additions & 3 deletions api/models/groep.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@ class Groep(models.Model):
Model voor een groep van studenten voor een project.
Fields:
groep_id (AutoField): Een automatisch gegenereerd veld dat fungeert als de primaire sleutel voor de groep.
studenten (ManyToManyField): Een Many-to-Many relatie met het 'Gebruiker' model, waarmee meerdere gebruikers aan een groep kunnen worden gekoppeld.
project (ForeignKey): Een ForeignKey relatie met het 'Project' model, waarmee wordt aangegeven tot welk project deze groep behoort. Als het bijbehorende project wordt verwijderd, worden ook de bijbehorende groepen verwijderd.
groep_id (AutoField): Een automatisch gegenereerd veld dat fungeert als
de primaire sleutel voor de groep.
studenten (ManyToManyField): Een Many-to-Many relatie met het 'Gebruiker' model,
waarmee meerdere gebruikers aan een groep kunnen worden gekoppeld.
project (ForeignKey): Een ForeignKey relatie met het 'Project' model,
waarmee wordt aangegeven tot welk project deze groep behoort.
Als het bijbehorende project wordt verwijderd,
worden ook de bijbehorende groepen verwijderd.
Methods:
__str__(): Geeft een representatie van het model als een string terug, die de groeps-ID bevat.
"""

groep_id = models.AutoField(primary_key=True)
studenten = models.ManyToManyField(
"Gebruiker", related_name="groep_studenten", blank=True
Expand Down
26 changes: 19 additions & 7 deletions api/models/indiening.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,27 @@ def upload_to(instance, filename):
Returns:
str: Het pad waar het bestand moet worden opgeslagen.
"""
return f'data/indieningen/indiening_{instance.indiening_id}/{filename}'

return f"data/indieningen/indiening_{instance.indiening_id}/{filename}"


class Indiening(models.Model):
"""
Model voor een indiening van een groep.
Fields:
indiening_id (AutoField): Een automatisch gegenereerd veld dat fungeert als de primaire sleutel voor de indiening.
groep (ForeignKey): Een ForeignKey relatie met het 'Groep' model, waarmee wordt aangegeven tot welke groep deze indiening behoort. Als de bijbehorende groep wordt verwijderd, worden ook de bijbehorende indieningen verwijderd.
tijdstip (DateTimeField): Een veld dat automatisch het tijdstip registreert waarop de indiening is aangemaakt.
indiening_id (AutoField): Een automatisch gegenereerd veld dat fungeert
als de primaire sleutel voor de indiening.
groep (ForeignKey): Een ForeignKey relatie met het 'Groep' model,
waarmee wordt aangegeven tot welke groep deze indiening behoort.
Als de bijbehorende groep wordt verwijderd, worden ook de bijbehorende
indieningen verwijderd.
tijdstip (DateTimeField): Een veld dat automatisch het tijdstip
registreert waarop de indiening is aangemaakt.
Methods:
__str__(): Geeft een representatie van het model als een string terug, die de ID van de indiening bevat.
"""

indiening_id = models.AutoField(primary_key=True)
groep = models.ForeignKey("Groep", on_delete=models.CASCADE)
tijdstip = models.DateTimeField(auto_now_add=True)
Expand All @@ -39,13 +46,18 @@ class IndieningBestand(models.Model):
Model voor een bestand dat aan een indiening is gekoppeld.
Fields:
indiening_bestand_id (AutoField): Een automatisch gegenereerd veld dat fungeert als de primaire sleutel voor het bestand.
indiening (ForeignKey): Een ForeignKey relatie met het 'Indiening' model, waarmee wordt aangegeven tot welke indiening dit bestand behoort. Als de bijbehorende indiening wordt verwijderd, wordt ook het bijbehorende bestand verwijderd.
indiening_bestand_id (AutoField): Een automatisch gegenereerd veld dat fungeert als
de primaire sleutel voor het bestand.
indiening (ForeignKey): Een ForeignKey relatie met het 'Indiening' model,
waarmee wordt aangegeven tot welke indiening dit bestand behoort.
Als de bijbehorende indiening wordt verwijderd,
wordt ook het bijbehorende bestand verwijderd.
bestand (FileField): Een veld voor het uploaden van het bestand.
Methods:
__str__(): Geeft een representatie van het model als een string terug, die de bestandsnaam bevat.
"""

indiening_bestand_id = models.AutoField(primary_key=True)
indiening = models.ForeignKey("Indiening", on_delete=models.CASCADE)
bestand = models.FileField(upload_to=upload_to)
Expand Down
17 changes: 12 additions & 5 deletions api/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,22 @@ class Project(models.Model):
project_id (AutoField): Een automatisch gegenereerd veld dat fungeert als de primaire sleutel voor het project.
titel (CharField): Titel van het project.
beschrijving (TextField): Beschrijving van het project.
opgave_bestand (FileField): Een veld voor het uploaden van het opgavebestand voor het project. (eventueel uit te breiden tot meerdere bestanden mogelijk)
vak (ForeignKey): Een ForeignKey relatie met het 'Vak' model, waarmee wordt aangegeven tot welk vak dit project behoort. Als het bijbehorende vak wordt verwijderd, worden ook de bijbehorende projecten verwijderd.
deadline (DateTimeField): Een veld voor het instellen van de deadline voor het project. Kan optioneel zijn (null=True).
max_score (IntegerField): Een veld voor het instellen van de maximale score voor het project. Standaard ingesteld op 20.
opgave_bestand (FileField): Een veld voor het uploaden van het opgavebestand voor het project.
(eventueel uit te breiden tot meerdere bestanden mogelijk)
vak (ForeignKey): Een ForeignKey relatie met het 'Vak' model,
waarmee wordt aangegeven tot welk vak dit project behoort.
Als het bijbehorende vak wordt verwijderd, worden ook de bijbehorende projecten verwijderd.
deadline (DateTimeField): Een veld voor het instellen van de deadline voor het project.
Kan optioneel zijn (null=True).
max_score (IntegerField): Een veld voor het instellen van de maximale score voor het project.
Standaard ingesteld op 20.
# indiening restricties (TODO): Restricties/tests bij indiening moeten nog toegevoegd worden.
Methods:
__str__(): Geeft een representatie van het model als een string terug, die de titel van het project bevat.
__str__(): Geeft een representatie van het model als een string terug,
die de titel van het project bevat.
"""

project_id = models.AutoField(primary_key=True)
titel = models.CharField(max_length=100)
beschrijving = models.TextField()
Expand Down
6 changes: 5 additions & 1 deletion api/models/score.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ class Score(models.Model):
Fields:
score_id (AutoField): Een automatisch gegenereerd veld dat fungeert als de primaire sleutel voor de score.
score (SmallIntegerField): Een veld om de scorewaarde op te slaan.
indiening (ForeignKey): Een ForeignKey relatie met het 'Indiening' model, waarmee wordt aangegeven tot welke indiening deze score behoort. Als de bijbehorende indiening wordt verwijderd, wordt ook de bijbehorende score verwijderd.
indiening (ForeignKey): Een ForeignKey relatie met het 'Indiening' model,
waarmee wordt aangegeven tot welke indiening deze score behoort.
Als de bijbehorende indiening wordt verwijderd,
wordt ook de bijbehorende score verwijderd.
Methods:
__str__(): Geeft een representatie van het model als een string terug, die de score-ID bevat.
"""

score_id = models.AutoField(primary_key=True)
score = models.SmallIntegerField()
indiening = models.ForeignKey("Indiening", on_delete=models.CASCADE)
Expand Down
7 changes: 5 additions & 2 deletions api/models/vak.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ class Vak(models.Model):
Fields:
vak_id (AutoField): Een automatisch gegenereerd veld dat fungeert als de primaire sleutel voor het vak.
naam (CharField): Een veld om de naam van het vak op te slaan.
studenten (ManyToManyField): Een Many-to-Many relatie met het 'Gebruiker' model, waarmee meerdere gebruikers aan het vak kunnen worden gekoppeld als studenten.
lesgevers (ManyToManyField): Een Many-to-Many relatie met het 'Gebruiker' model, waarmee meerdere gebruikers aan het vak kunnen worden gekoppeld als lesgevers.
studenten (ManyToManyField): Een Many-to-Many relatie met het 'Gebruiker' model,
waarmee meerdere gebruikers aan het vak kunnen worden gekoppeld als studenten.
lesgevers (ManyToManyField): Een Many-to-Many relatie met het 'Gebruiker' model,
waarmee meerdere gebruikers aan het vak kunnen worden gekoppeld als lesgevers.
Methods:
__str__(): Geeft een representatie van het model als een string terug, die de naam van het vak bevat.
"""

vak_id = models.AutoField(primary_key=True)
naam = models.CharField(max_length=100)
studenten = models.ManyToManyField(
Expand Down
6 changes: 4 additions & 2 deletions api/serializers/gebruiker.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ class GebruikerSerializer(serializers.ModelSerializer):
Fields:
Meta.model (Gebruiker): Het model waarop de serializer is gebaseerd.
Meta.fields (tuple): De velden die moeten worden opgenomen in de serializer. Hier wordt '__all__' gebruikt om alle velden op te nemen.
Meta.fields (tuple): De velden die moeten worden opgenomen in de serializer.
Hier wordt '__all__' gebruikt om alle velden op te nemen.
Methods:
create(self, validated_data): Maakt een nieuwe gebruiker aan en voegt deze toe aan de database.
update(self, instance, validated_data): Werkt een bestaande gebruiker bij in de database.
"""

class Meta:
model = Gebruiker
fields = "__all__"
Expand All @@ -38,6 +40,6 @@ def update(self, instance, validated_data):
Returns:
Gebruiker: De bijgewerkte gebruiker.
"""
instance.is_lesgever = validated_data.pop('is_lesgever')
instance.is_lesgever = validated_data.pop("is_lesgever")
instance.save()
return instance
48 changes: 34 additions & 14 deletions api/serializers/groep.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,36 @@ class GroepSerializer(serializers.ModelSerializer):
Fields:
Meta.model (Groep): Het model waarop de serializer is gebaseerd.
Meta.fields (tuple): De velden die moeten worden opgenomen in de serializer. Hier wordt '__all__' gebruikt om alle velden op te nemen.
Meta.fields (tuple): De velden die moeten worden opgenomen in de serializer.
Hier wordt '__all__' gebruikt om alle velden op te nemen.
Methods:
create(self, validated_data): Maakt een nieuwe groep aan en voegt deze toe aan de database.
update(self, instance, validated_data): Werkt een bestaande groep bij in de database.
create(self, validated_data): Maakt een nieuwe groep
aan en voegt deze toe aan de database.
update(self, instance, validated_data): Werkt een bestaande groep bij
in de database.
"""

class Meta:
model = Groep
fields = "__all__"

def create(self, validated_data):

"""
Args:
validated_data (dict): Gevalideerde gegevens over de groep.
Returns:
Groep: De aangemaakte groep.
"""
students_data = validated_data.pop('studenten')
validate_students(students_data, validated_data['project'])
students_data = validated_data.pop("studenten")
validate_students(students_data, validated_data["project"])
instance = Groep.objects.create(**validated_data)
instance.studenten.set(students_data)

return instance

def update(self, instance, validated_data):

"""
Args:
instance (Groep): De groep die moet worden bijgewerkt.
Expand All @@ -45,33 +47,51 @@ def update(self, instance, validated_data):
Returns:
Groep: De bijgewerkte groep.
"""
students_data = validated_data.pop('studenten')
validate_students(students_data, validated_data['project'])
students_data = validated_data.pop("studenten")
validate_students(
students_data, validated_data["project"], current_group=instance
)
super().update(instance=instance, validated_data=validated_data)
instance.studenten.set(students_data)
instance.save()

return instance



def validate_students(students_data, project):
def validate_students(students_data, project, current_group=None):
"""
Controleert of de opgegeven gebruikers studenten zijn en of ze al in een andere groep voor dit project zitten.
Args:
students_data (list): Een lijst met gebruikers die aan de groep moeten worden toegevoegd.
project (Project): Het project waartoe de groep behoort.
current_groep (Groep): De huidige groep waartoe de studenten behoren.
Raises:
serializers.ValidationError: Als een gebruiker geen student is of al in een andere groep voor dit project zit.
"""
groepen = Groep.objects.filter(project=project)

student_counts = Counter(students_data)
for student, count in student_counts.items():
if count > 1:
raise serializers.ValidationError(
f"Student {student} zit al in deze groep!"
)

for student in students_data:
if student.is_lesgever:
raise serializers.ValidationError("Alle gebruikers in 'studenten' moeten studenten zijn!")
raise serializers.ValidationError(
"Alle gebruikers in 'studenten' moeten studenten zijn!"
)

for groep in groepen:
if groep.studenten.contains(student):
raise serializers.ValidationError(f"Gebruiker {student.user.id} zit al in een groep voor dit project")
if (
current_group
and groep.groep_id != current_group.groep_id
and student in groep.studenten.all()
):
raise serializers.ValidationError(
f"Gebruiker {student} zit al in een andere groep voor dit project!"
)
2 changes: 2 additions & 0 deletions api/serializers/indiening.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class IndieningSerializer(serializers.ModelSerializer):
Meta.fields (tuple): De velden die moeten worden opgenomen in de serializer. Hier worden alle velden opgenomen.
"""

class Meta:
model = Indiening
fields = "__all__"
Expand All @@ -25,6 +26,7 @@ class IndieningBestandSerializer(serializers.ModelSerializer):
Meta.fields (tuple): De velden die moeten worden opgenomen in de serializer. Hier worden alle velden opgenomen.
"""

class Meta:
model = IndieningBestand
fields = "__all__"
8 changes: 5 additions & 3 deletions api/serializers/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ class ProjectSerializer(serializers.ModelSerializer):
Fields:
Meta.model (Project): Het model waarop de serializer is gebaseerd.
Meta.fields (tuple): De velden die moeten worden opgenomen in de serializer. Hier wordt '__all__' gebruikt om alle velden op te nemen.
Meta.fields (tuple): De velden die moeten worden opgenomen in de serializer.
Hier wordt '__all__' gebruikt om alle velden op te nemen.
Methods:
create(self, validated_data): Maakt een nieuw project aan en voegt deze toe aan de database.
update(self, instance, validated_data): Werkt een bestaand project bij in de database.
"""

class Meta:
model = Project
fields = "__all__"
Expand All @@ -27,7 +29,7 @@ def create(self, validated_data):
Returns:
Project: Het aangemaakte project.
"""
deadline = validated_data.pop('deadline')
deadline = validated_data.pop("deadline")
validate_deadline(deadline)

project = Project.objects.create(**validated_data)
Expand All @@ -44,7 +46,7 @@ def update(self, instance, validated_data):
Returns:
Project: Het bijgewerkte project.
"""
deadline = validated_data.pop('deadline')
deadline = validated_data.pop("deadline")
validate_deadline(deadline)

super().update(instance=instance, validated_data=validated_data)
Expand Down
Loading

0 comments on commit d244e99

Please sign in to comment.