Skip to content

Commit

Permalink
Merge pull request #97 from SELab-2/score-visibility
Browse files Browse the repository at this point in the history
Score visibility
  • Loading branch information
francisvaut authored Mar 12, 2024
2 parents c9c7ad0 + 50f2ebd commit 700e7eb
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 5.0.2 on 2024-03-12 09:49

import django.utils.timezone
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0005_alter_project_max_score'),
]

operations = [
migrations.AddField(
model_name='project',
name='score_visible',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='project',
name='start_date',
field=models.DateTimeField(blank=True, default=django.utils.timezone.now),
),
migrations.AlterField(
model_name='submission',
name='submission_number',
field=models.PositiveIntegerField(blank=True, null=True),
),
]
3 changes: 3 additions & 0 deletions backend/api/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ class Project(models.Model):
default=20
)

# Score already visible to students
score_visible = models.BooleanField(default=False)

# Size of the groups than can be formed
group_size = models.PositiveSmallIntegerField(
blank=False,
Expand Down
14 changes: 14 additions & 0 deletions backend/api/serializers/group_serializer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.utils.translation import gettext
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from api.permissions.role_permissions import is_student
from api.models.group import Group
from api.models.student import Student
from api.serializers.student_serializer import StudentIDSerializer
Expand All @@ -25,6 +26,19 @@ class Meta:
model = Group
fields = ["id", "project", "students", "score", "submissions"]

def to_representation(self, instance):
data = super().to_representation(instance)

# If you are not a student, you can always see the score
if is_student(self.context["request"].user):
# Student can not see the score if they are not part of the group, or it is not visible yet
if not instance.students.filter(id=self.context["request"].user.student.id).exists() or\
not instance.project.score_visible:

data.pop("score")

return data

def validate(self, data):
# Make sure the score of the group is lower or equal to the maximum score
group: Group = self.instance
Expand Down
1 change: 1 addition & 0 deletions backend/api/serializers/project_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Meta:
"start_date",
"deadline",
"max_score",
"score_visible",
"group_size",
"structure_checks",
"extra_checks",
Expand Down
59 changes: 57 additions & 2 deletions backend/api/tests/test_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ def create_course(name, academic_startyear, description=None, parent_course=None
)


def create_project(name, description, days, course, group_size=2, max_score=20):
def create_project(name, description, days, course, group_size=2, max_score=20, score_visible=True):
"""Create a Project with the given arguments."""
deadline = timezone.now() + timedelta(days=days)
return Project.objects.create(
name=name, description=description, deadline=deadline, course=course,
group_size=group_size, max_score=max_score
group_size=group_size, max_score=max_score, score_visible=score_visible
)


Expand Down Expand Up @@ -496,3 +496,58 @@ def test_try_to_update_score_of_group(self):

group.refresh_from_db()
self.assertEqual(group.score, 10)

def test_group_score_visibility(self):
"""Only able to retrieve the score of a group if it is visible, and the student is part of the group."""
course = create_course(name="sel2", academic_startyear=2023)

project = create_project(
name="Project 1", description="Description 1", days=7, course=course, score_visible=True
)
group = create_group(project=project, score=10)
course.students.add(self.user)

response = self.client.get(
reverse("group-detail", args=[str(group.id)]), follow=True
)

self.assertEqual(response.status_code, 200)

content_json = json.loads(response.content.decode("utf-8"))

# Make sure that score is not included, because the student is not part of the group
self.assertNotIn("score", content_json)

# Add the student to the group
group.students.add(self.user)

# Set the visibility of the score to False, to make sure the score is not included if it is not visible
project.score_visible = False
project.save()

response = self.client.get(
reverse("group-detail", args=[str(group.id)]), follow=True
)

self.assertEqual(response.status_code, 200)

content_json = json.loads(response.content.decode("utf-8"))

# Make sure that score is not included, because the teacher has set the visibility of the score to False
self.assertNotIn("score", content_json)

# Update that the score is visible
project.score_visible = True
project.save()

self.assertEqual(response.status_code, 200)

response = self.client.get(
reverse("group-detail", args=[str(group.id)]), follow=True
)

self.assertEqual(response.status_code, 200)
content_json = json.loads(response.content.decode("utf-8"))

# Make sure the score is included now
self.assertIn("score", content_json)
2 changes: 1 addition & 1 deletion backend/api/tests/test_submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def create_project(name, description, days, course):
"""Create a Project with the given arguments."""
deadline = timezone.now() + timedelta(days=days)
return Project.objects.create(
name=name, description=description, deadline=deadline, course=course
name=name, description=description, deadline=deadline, course=course, score_visible=True
)


Expand Down

0 comments on commit 700e7eb

Please sign in to comment.