diff --git a/server/vbv_lernwelt/self_evaluation_feedback/migrations/0002_rename_requester_evaluation_coursecompletionfeedback_course_completion.py b/server/vbv_lernwelt/self_evaluation_feedback/migrations/0002_rename_requester_evaluation_coursecompletionfeedback_course_completion.py new file mode 100644 index 00000000..66eea762 --- /dev/null +++ b/server/vbv_lernwelt/self_evaluation_feedback/migrations/0002_rename_requester_evaluation_coursecompletionfeedback_course_completion.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.20 on 2024-01-22 13:20 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("self_evaluation_feedback", "0001_initial"), + ] + + operations = [ + migrations.RenameField( + model_name="coursecompletionfeedback", + old_name="requester_evaluation", + new_name="course_completion", + ), + ] diff --git a/server/vbv_lernwelt/self_evaluation_feedback/models.py b/server/vbv_lernwelt/self_evaluation_feedback/models.py index cfc7477f..bf3870be 100644 --- a/server/vbv_lernwelt/self_evaluation_feedback/models.py +++ b/server/vbv_lernwelt/self_evaluation_feedback/models.py @@ -24,9 +24,9 @@ class CourseCompletionFeedback(models.Model): feedback = models.ForeignKey(SelfEvaluationFeedback, on_delete=models.CASCADE) # the course completion has to be evaluated by the feedback provider - requester_evaluation = models.ForeignKey(CourseCompletion, on_delete=models.CASCADE) + course_completion = models.ForeignKey(CourseCompletion, on_delete=models.CASCADE) - provider_evaluation_feedback = models.CharField( + feedback_assessment = models.CharField( max_length=255, choices=[(status, status.value) for status in CourseCompletionStatus], default=CourseCompletionStatus.UNKNOWN.value, diff --git a/server/vbv_lernwelt/self_evaluation_feedback/serializers.py b/server/vbv_lernwelt/self_evaluation_feedback/serializers.py index 2e1c7d72..037fa5fb 100644 --- a/server/vbv_lernwelt/self_evaluation_feedback/serializers.py +++ b/server/vbv_lernwelt/self_evaluation_feedback/serializers.py @@ -4,7 +4,11 @@ from rest_framework import serializers from vbv_lernwelt.competence.models import PerformanceCriteria from vbv_lernwelt.core.serializers import UserSerializer -from vbv_lernwelt.self_evaluation_feedback.models import SelfEvaluationFeedback +from vbv_lernwelt.course.models import CourseCompletion, CourseCompletionStatus +from vbv_lernwelt.self_evaluation_feedback.models import ( + CourseCompletionFeedback, + SelfEvaluationFeedback, +) class SelfEvaluationFeedbackSerializer(serializers.ModelSerializer): @@ -14,11 +18,14 @@ class SelfEvaluationFeedbackSerializer(serializers.ModelSerializer): learning_unit_id = serializers.PrimaryKeyRelatedField( read_only=True, source="learning_unit" ) + feedback_id = serializers.PrimaryKeyRelatedField( + read_only=True, source="course_completion_feedback" + ) class Meta: model = SelfEvaluationFeedback fields = [ - "id", + "feedback_id", "learning_unit_id", "feedback_submitted", "feedback_requester_user", @@ -31,10 +38,39 @@ class SelfEvaluationFeedbackSerializer(serializers.ModelSerializer): PerformanceCriteria ] = obj.learning_unit.performancecriteria_set.all() - return [ - { - "id": criteria.id, - "title": criteria.title, - } - for criteria in performance_criteria - ] + criteria = [] + + for pc in performance_criteria: + # requester self assessment + completion = CourseCompletion.objects.filter( + page_id=pc.id, + user=obj.feedback_requester_user, + ).first() + + self_assessment = ( + completion.completion_status + if completion + else CourseCompletionStatus.UNKNOWN.value + ) + + # provider feedback assessment + feedback = CourseCompletionFeedback.objects.filter( + course_completion=completion + ).first() + + feedback_assessment = ( + feedback.feedback_assessment + if feedback + else CourseCompletionStatus.UNKNOWN.value + ) + + criteria.append( + { + "course_completion_id": completion.id if completion else None, + "title": pc.title, + "self_assessment": self_assessment, + "feedback_assessment": feedback_assessment, + } + ) + + return criteria diff --git a/server/vbv_lernwelt/self_evaluation_feedback/tests/test_api.py b/server/vbv_lernwelt/self_evaluation_feedback/tests/test_api.py index ce5febfc..df45b741 100644 --- a/server/vbv_lernwelt/self_evaluation_feedback/tests/test_api.py +++ b/server/vbv_lernwelt/self_evaluation_feedback/tests/test_api.py @@ -10,10 +10,13 @@ from vbv_lernwelt.course.creators.test_utils import ( create_performance_criteria_page, create_user, ) -from vbv_lernwelt.course.models import CourseSessionUser +from vbv_lernwelt.course.models import CourseCompletionStatus, CourseSessionUser from vbv_lernwelt.course.services import mark_course_completion from vbv_lernwelt.learning_mentor.models import LearningMentor -from vbv_lernwelt.self_evaluation_feedback.models import SelfEvaluationFeedback +from vbv_lernwelt.self_evaluation_feedback.models import ( + CourseCompletionFeedback, + SelfEvaluationFeedback, +) def create_self_evaluation_feedback( @@ -53,8 +56,6 @@ class SelfEvaluationFeedbackAPI(APITestCase): learning_mentor.participants.add(member_csu) - self.client.force_login(self.member) - def test_start_self_evaluation_feedback(self): # GIVEN learning_unit = create_learning_unit(course=self.course, circle=self.circle) @@ -73,6 +74,8 @@ class SelfEvaluationFeedbackAPI(APITestCase): completion_status="SUCCESS", ) + self.client.force_login(self.member) + # WHEN response = self.client.post( reverse("start_self_evaluation_feedback"), @@ -103,6 +106,8 @@ class SelfEvaluationFeedbackAPI(APITestCase): learning_unit = create_learning_unit(course=self.course, circle=self.circle) not_a_mentor = create_user("not_a_mentor") + self.client.force_login(self.member) + # WHEN response = self.client.post( reverse("start_self_evaluation_feedback"), @@ -114,3 +119,87 @@ class SelfEvaluationFeedbackAPI(APITestCase): # THEN self.assertEqual(response.status_code, 403) + + def test_list_self_evaluation_feedback_provider(self): + # GIVEN + learning_unit = create_learning_unit(course=self.course, circle=self.circle) + + performance_criteria_1 = create_performance_criteria_page( + course=self.course, + course_page=self.course_page, + circle=self.circle, + learning_unit=learning_unit, + ) + + create_performance_criteria_page( + course=self.course, + course_page=self.course_page, + circle=self.circle, + learning_unit=learning_unit, + ) + + completion = mark_course_completion( + page=performance_criteria_1, + user=self.member, + course_session=self.course_session, + completion_status=CourseCompletionStatus.SUCCESS.value, + ) + + feedback = create_self_evaluation_feedback( + learning_unit=learning_unit, + feedback_requester_user=self.member, + feedback_provider_user=self.mentor, + ) + + CourseCompletionFeedback.objects.create( + feedback=feedback, + course_completion=completion, + feedback_assessment=CourseCompletionStatus.FAIL.value, + ) + + self.client.force_login(self.mentor) + + # WHEN + response = self.client.get(reverse("list_self_evaluation_feedbacks_provider")) + + # THEN + self.assertEqual(response.status_code, 200) + + self.assertEqual(len(response.data), 1) + self.assertEqual(response.data[0]["learning_unit_id"], learning_unit.id) + + provider_user = response.data[0]["feedback_provider_user"] + self.assertEqual(provider_user["id"], str(self.mentor.id)) # noqa + self.assertEqual(provider_user["first_name"], self.mentor.first_name) + self.assertEqual(provider_user["last_name"], self.mentor.last_name) + self.assertEqual(provider_user["avatar_url"], self.mentor.avatar_url) + + requester_user = response.data[0]["feedback_requester_user"] + self.assertEqual(requester_user["id"], str(self.member.id)) # noqa + self.assertEqual(requester_user["first_name"], self.member.first_name) + self.assertEqual(requester_user["last_name"], self.member.last_name) + self.assertEqual(requester_user["avatar_url"], self.member.avatar_url) + + self.assertEqual(len(response.data[0]["criteria"]), 2) + + first_criteria = response.data[0]["criteria"][0] + self.assertEqual(first_criteria["course_completion_id"], completion.id) + self.assertEqual(first_criteria["title"], performance_criteria_1.title) + self.assertEqual( + first_criteria["self_assessment"], + CourseCompletionStatus.SUCCESS.value, + ) + self.assertEqual( + first_criteria["feedback_assessment"], CourseCompletionStatus.FAIL.value + ) + + second_criteria = response.data[0]["criteria"][1] + self.assertEqual(second_criteria["course_completion_id"], None) + self.assertEqual(second_criteria["title"], performance_criteria_1.title) + self.assertEqual( + second_criteria["self_assessment"], CourseCompletionStatus.UNKNOWN.value + ) + self.assertEqual( + second_criteria["feedback_assessment"], + CourseCompletionStatus.UNKNOWN.value, + ) diff --git a/server/vbv_lernwelt/self_evaluation_feedback/urls.py b/server/vbv_lernwelt/self_evaluation_feedback/urls.py index ec1c26cf..6a14536c 100644 --- a/server/vbv_lernwelt/self_evaluation_feedback/urls.py +++ b/server/vbv_lernwelt/self_evaluation_feedback/urls.py @@ -1,11 +1,19 @@ from django.urls import path -from .views import start_self_evaluation_feedback +from vbv_lernwelt.self_evaluation_feedback.views import ( + list_self_evaluation_feedbacks_provider, + start_self_evaluation_feedback, +) urlpatterns = [ path( - "start-feedback", + "reqeuster/start-feedback", start_self_evaluation_feedback, name="start_self_evaluation_feedback", ), + path( + "provider/list-feedbacks", + list_self_evaluation_feedbacks_provider, + name="list_self_evaluation_feedbacks_provider", + ), ] diff --git a/server/vbv_lernwelt/self_evaluation_feedback/views.py b/server/vbv_lernwelt/self_evaluation_feedback/views.py index b6b5c7be..b0f85af8 100644 --- a/server/vbv_lernwelt/self_evaluation_feedback/views.py +++ b/server/vbv_lernwelt/self_evaluation_feedback/views.py @@ -8,6 +8,9 @@ from vbv_lernwelt.core.models import User from vbv_lernwelt.learning_mentor.models import LearningMentor from vbv_lernwelt.learnpath.models import LearningUnit from vbv_lernwelt.self_evaluation_feedback.models import SelfEvaluationFeedback +from vbv_lernwelt.self_evaluation_feedback.serializers import ( + SelfEvaluationFeedbackSerializer, +) @api_view(["POST"]) @@ -39,11 +42,9 @@ def start_self_evaluation_feedback(request): @api_view(["GET"]) @permission_classes([IsAuthenticated]) -def list_self_evaluation_feedback(request): +def list_self_evaluation_feedbacks_provider(request): feedbacks = SelfEvaluationFeedback.objects.filter( feedback_provider_user=request.user ) - # TODO continue here - - return Response({"success": True}) + return Response(SelfEvaluationFeedbackSerializer(feedbacks, many=True).data)