feat: mentor cockpit self evaluation feedback
This commit is contained in:
parent
654ccb0d47
commit
864a00107e
|
|
@ -0,0 +1,23 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import AssignmentItem from "@/components/cockpit/mentor/AssignmentItem.vue";
|
||||||
|
import type { RouteLocationRaw } from "vue-router";
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
taskTitle: string;
|
||||||
|
circleTitle: string;
|
||||||
|
pendingTasks: number;
|
||||||
|
taskLink: RouteLocationRaw;
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AssignmentItem
|
||||||
|
:task-title="`${$t('a.Selbsteinschätzung')}: ${taskTitle}`"
|
||||||
|
:circle-title="circleTitle"
|
||||||
|
:pending-tasks="pendingTasks"
|
||||||
|
:task-link="taskLink"
|
||||||
|
:pending-tasks-label="$t('a.Selbsteinschätzung geteilt')"
|
||||||
|
:task-link-pending-label="$t('a.Fremdeinschätzung vornehmen')"
|
||||||
|
:task-link-label="$t('a.Selbsteinschätzung anzeigen')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
@ -6,6 +6,7 @@ import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
||||||
import { computed, type Ref, ref } from "vue";
|
import { computed, type Ref, ref } from "vue";
|
||||||
import PraxisAssignmentItem from "@/components/cockpit/mentor/PraxisAssignmentItem.vue";
|
import PraxisAssignmentItem from "@/components/cockpit/mentor/PraxisAssignmentItem.vue";
|
||||||
import { useTranslation } from "i18next-vue";
|
import { useTranslation } from "i18next-vue";
|
||||||
|
import SelfAssignmentFeedbackAssignmentItem from "@/components/cockpit/mentor/SelfAssignmentFeedbackAssignmentItem.vue";
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const courseSession = useCurrentCourseSession();
|
const courseSession = useCurrentCourseSession();
|
||||||
|
|
@ -80,6 +81,16 @@ const filteredAssignments: Ref<PraxisAssignment[]> = computed(() => {
|
||||||
}"
|
}"
|
||||||
:task-title="item.title"
|
:task-title="item.title"
|
||||||
/>
|
/>
|
||||||
|
<SelfAssignmentFeedbackAssignmentItem
|
||||||
|
v-else-if="item.type === 'self_evaluation_feedback'"
|
||||||
|
:circle-title="mentorCockpitStore.getCircleTitleById(item.circle_id)"
|
||||||
|
:pending-tasks="item.pending_evaluations"
|
||||||
|
:task-link="{
|
||||||
|
name: 'mentorCockpitPraxisAssignments',
|
||||||
|
params: { praxisAssignmentId: item.id },
|
||||||
|
}"
|
||||||
|
:task-title="item.title"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,18 @@ from typing import List, Set, Tuple
|
||||||
|
|
||||||
from vbv_lernwelt.assignment.models import (
|
from vbv_lernwelt.assignment.models import (
|
||||||
Assignment,
|
Assignment,
|
||||||
AssignmentCompletion,
|
|
||||||
AssignmentCompletionStatus,
|
AssignmentCompletionStatus,
|
||||||
AssignmentType,
|
AssignmentType,
|
||||||
|
AssignmentCompletion,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.core.models import User
|
from vbv_lernwelt.core.models import User
|
||||||
from vbv_lernwelt.course.models import CourseSession
|
from vbv_lernwelt.course.models import CourseSession
|
||||||
from vbv_lernwelt.course_session.models import CourseSessionAssignment
|
from vbv_lernwelt.course_session.models import CourseSessionAssignment
|
||||||
from vbv_lernwelt.learning_mentor.entities import (
|
from vbv_lernwelt.learning_mentor.entities import (
|
||||||
CompletionStatus,
|
MentorCompletionStatus,
|
||||||
PraxisAssignmentCompletion,
|
MentorAssignmentCompletion,
|
||||||
PraxisAssignmentStatus,
|
MentorAssignmentStatus,
|
||||||
|
MentorAssignmentStatusType,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -21,7 +22,7 @@ def get_assignment_completions(
|
||||||
assignment: Assignment,
|
assignment: Assignment,
|
||||||
participants: List[User],
|
participants: List[User],
|
||||||
evaluation_user: User,
|
evaluation_user: User,
|
||||||
) -> List[PraxisAssignmentCompletion]:
|
) -> List[MentorAssignmentCompletion]:
|
||||||
evaluation_results = AssignmentCompletion.objects.filter(
|
evaluation_results = AssignmentCompletion.objects.filter(
|
||||||
assignment_user__in=participants,
|
assignment_user__in=participants,
|
||||||
course_session=course_session,
|
course_session=course_session,
|
||||||
|
|
@ -34,14 +35,14 @@ def get_assignment_completions(
|
||||||
completion_status = result["completion_status"]
|
completion_status = result["completion_status"]
|
||||||
|
|
||||||
if completion_status == AssignmentCompletionStatus.EVALUATION_SUBMITTED.value:
|
if completion_status == AssignmentCompletionStatus.EVALUATION_SUBMITTED.value:
|
||||||
status = CompletionStatus.EVALUATED
|
status = MentorCompletionStatus.EVALUATED
|
||||||
elif completion_status in [
|
elif completion_status in [
|
||||||
AssignmentCompletionStatus.SUBMITTED.value,
|
AssignmentCompletionStatus.SUBMITTED.value,
|
||||||
AssignmentCompletionStatus.EVALUATION_IN_PROGRESS.value,
|
AssignmentCompletionStatus.EVALUATION_IN_PROGRESS.value,
|
||||||
]:
|
]:
|
||||||
status = CompletionStatus.SUBMITTED
|
status = MentorCompletionStatus.SUBMITTED
|
||||||
else:
|
else:
|
||||||
status = CompletionStatus.UNKNOWN
|
status = MentorCompletionStatus.UNKNOWN
|
||||||
|
|
||||||
user_status_map[result["assignment_user"]] = (
|
user_status_map[result["assignment_user"]] = (
|
||||||
status,
|
status,
|
||||||
|
|
@ -49,25 +50,25 @@ def get_assignment_completions(
|
||||||
)
|
)
|
||||||
|
|
||||||
status_priority = {
|
status_priority = {
|
||||||
CompletionStatus.SUBMITTED: 1,
|
MentorCompletionStatus.SUBMITTED: 1,
|
||||||
CompletionStatus.EVALUATED: 2,
|
MentorCompletionStatus.EVALUATED: 2,
|
||||||
CompletionStatus.UNKNOWN: 3,
|
MentorCompletionStatus.UNKNOWN: 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
sorted_participants = sorted(
|
sorted_participants = sorted(
|
||||||
participants,
|
participants,
|
||||||
key=lambda u: (
|
key=lambda u: (
|
||||||
status_priority.get(
|
status_priority.get(
|
||||||
user_status_map.get(u.id, (CompletionStatus.UNKNOWN, ""))[0]
|
user_status_map.get(u.id, (MentorCompletionStatus.UNKNOWN, ""))[0]
|
||||||
),
|
),
|
||||||
user_status_map.get(u.id, ("", u.last_name))[1],
|
user_status_map.get(u.id, ("", u.last_name))[1],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
PraxisAssignmentCompletion(
|
MentorAssignmentCompletion(
|
||||||
status=user_status_map.get(
|
status=user_status_map.get(
|
||||||
user.id, (CompletionStatus.UNKNOWN, user.last_name)
|
user.id, (MentorCompletionStatus.UNKNOWN, user.last_name)
|
||||||
)[0],
|
)[0],
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
last_name=user.last_name,
|
last_name=user.last_name,
|
||||||
|
|
@ -78,7 +79,7 @@ def get_assignment_completions(
|
||||||
|
|
||||||
def get_praxis_assignments(
|
def get_praxis_assignments(
|
||||||
course_session: CourseSession, participants: List[User], evaluation_user: User
|
course_session: CourseSession, participants: List[User], evaluation_user: User
|
||||||
) -> Tuple[List[PraxisAssignmentStatus], Set[int]]:
|
) -> Tuple[List[MentorAssignmentStatus], Set[int]]:
|
||||||
records = []
|
records = []
|
||||||
circle_ids = set()
|
circle_ids = set()
|
||||||
|
|
||||||
|
|
@ -104,19 +105,20 @@ def get_praxis_assignments(
|
||||||
[
|
[
|
||||||
completion
|
completion
|
||||||
for completion in completions
|
for completion in completions
|
||||||
if completion.status == CompletionStatus.SUBMITTED
|
if completion.status == MentorCompletionStatus.SUBMITTED
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
circle_id = learning_content.get_circle().id
|
circle_id = learning_content.get_circle().id
|
||||||
|
|
||||||
records.append(
|
records.append(
|
||||||
PraxisAssignmentStatus(
|
MentorAssignmentStatus(
|
||||||
id=course_session_assignment.id,
|
id=course_session_assignment.id,
|
||||||
title=learning_content.content_assignment.title,
|
title=learning_content.content_assignment.title,
|
||||||
circle_id=circle_id,
|
circle_id=circle_id,
|
||||||
pending_evaluations=submitted_count,
|
pending_evaluations=submitted_count,
|
||||||
completions=completions,
|
completions=completions,
|
||||||
|
type=MentorAssignmentStatusType.PRAXIS_ASSIGNMENT,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
from typing import List, Set, Tuple
|
||||||
|
|
||||||
|
from django.db.models import Prefetch
|
||||||
|
|
||||||
|
from vbv_lernwelt.core.models import User
|
||||||
|
from vbv_lernwelt.learning_mentor.entities import (
|
||||||
|
MentorCompletionStatus,
|
||||||
|
MentorAssignmentStatus,
|
||||||
|
MentorAssignmentCompletion,
|
||||||
|
MentorAssignmentStatusType,
|
||||||
|
)
|
||||||
|
from vbv_lernwelt.self_evaluation_feedback.models import SelfEvaluationFeedback
|
||||||
|
|
||||||
|
|
||||||
|
def create_blank_completions_non_requesters(
|
||||||
|
completions: List[MentorAssignmentCompletion],
|
||||||
|
participants: List[User],
|
||||||
|
) -> List[MentorAssignmentCompletion]:
|
||||||
|
non_requester_completions = []
|
||||||
|
|
||||||
|
participants_ids = set([str(p.id) for p in participants])
|
||||||
|
completion_seen_user_ids = set([str(c.user_id) for c in completions])
|
||||||
|
|
||||||
|
user_by_id = {str(p.id): p for p in participants}
|
||||||
|
for non_requester_user_id in participants_ids - completion_seen_user_ids:
|
||||||
|
non_requester_user = user_by_id[non_requester_user_id]
|
||||||
|
|
||||||
|
non_requester_completions.append(
|
||||||
|
MentorAssignmentCompletion(
|
||||||
|
status=MentorCompletionStatus.UNKNOWN,
|
||||||
|
user_id=non_requester_user.id,
|
||||||
|
last_name=non_requester_user.last_name,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return non_requester_completions
|
||||||
|
|
||||||
|
|
||||||
|
def get_self_feedback_evaluation(
|
||||||
|
participants: List[User], evaluation_user: User
|
||||||
|
) -> Tuple[List[MentorAssignmentStatus], Set[int]]:
|
||||||
|
records: List[MentorAssignmentStatus] = []
|
||||||
|
circle_ids: Set[int] = set()
|
||||||
|
|
||||||
|
if not participants:
|
||||||
|
return records, circle_ids
|
||||||
|
|
||||||
|
feedbacks = SelfEvaluationFeedback.objects.prefetch_related(
|
||||||
|
Prefetch("learning_unit")
|
||||||
|
).filter(
|
||||||
|
feedback_requester_user__in=participants,
|
||||||
|
feedback_provider_user=evaluation_user,
|
||||||
|
)
|
||||||
|
|
||||||
|
feedback_by_learning_unit = {}
|
||||||
|
|
||||||
|
for feedback in feedbacks:
|
||||||
|
feedback_by_learning_unit.setdefault(feedback.learning_unit, []).append(
|
||||||
|
feedback
|
||||||
|
)
|
||||||
|
|
||||||
|
for learning_unit, feedbacks in feedback_by_learning_unit.items():
|
||||||
|
circle_id = learning_unit.get_circle().id
|
||||||
|
circle_ids.add(circle_id)
|
||||||
|
|
||||||
|
pending_evaluations = len([f for f in feedbacks if not f.feedback_submitted])
|
||||||
|
|
||||||
|
completions = [
|
||||||
|
MentorAssignmentCompletion(
|
||||||
|
# feedback_submitted as seen from the perspective of the evaluation user (feedback provider)
|
||||||
|
# means that the feedback has been evaluated by the feedback provider, hence the status is EVALUATED
|
||||||
|
status=MentorCompletionStatus.EVALUATED
|
||||||
|
if f.feedback_submitted
|
||||||
|
else MentorCompletionStatus.SUBMITTED,
|
||||||
|
user_id=f.feedback_requester_user.id,
|
||||||
|
last_name=f.feedback_requester_user.last_name,
|
||||||
|
)
|
||||||
|
for f in feedbacks
|
||||||
|
]
|
||||||
|
|
||||||
|
# requesting feedback is optional, so we need to add blank completions
|
||||||
|
# for those mentees who did not request a feedback
|
||||||
|
completions += create_blank_completions_non_requesters(
|
||||||
|
completions=completions,
|
||||||
|
participants=participants,
|
||||||
|
)
|
||||||
|
|
||||||
|
records.append(
|
||||||
|
MentorAssignmentStatus(
|
||||||
|
id=learning_unit.id,
|
||||||
|
title=learning_unit.title,
|
||||||
|
circle_id=circle_id,
|
||||||
|
pending_evaluations=pending_evaluations,
|
||||||
|
completions=completions,
|
||||||
|
type=MentorAssignmentStatusType.SELF_EVALUATION_FEEDBACK,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return records, circle_ids
|
||||||
|
|
@ -3,23 +3,29 @@ from enum import Enum
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
|
|
||||||
class CompletionStatus(str, Enum):
|
class MentorCompletionStatus(str, Enum):
|
||||||
UNKNOWN = "UNKNOWN"
|
UNKNOWN = "UNKNOWN"
|
||||||
SUBMITTED = "SUBMITTED"
|
SUBMITTED = "SUBMITTED"
|
||||||
EVALUATED = "EVALUATED"
|
EVALUATED = "EVALUATED"
|
||||||
|
|
||||||
|
|
||||||
|
class MentorAssignmentStatusType(str, Enum):
|
||||||
|
PRAXIS_ASSIGNMENT = "praxis_assignment"
|
||||||
|
SELF_EVALUATION_FEEDBACK = "self_evaluation_feedback"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PraxisAssignmentCompletion:
|
class MentorAssignmentCompletion:
|
||||||
status: CompletionStatus
|
status: MentorCompletionStatus
|
||||||
user_id: str
|
user_id: str
|
||||||
last_name: str
|
last_name: str
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PraxisAssignmentStatus:
|
class MentorAssignmentStatus:
|
||||||
id: str
|
id: str
|
||||||
title: str
|
title: str
|
||||||
circle_id: str
|
circle_id: str
|
||||||
pending_evaluations: int
|
pending_evaluations: int
|
||||||
completions: List[PraxisAssignmentCompletion]
|
completions: List[MentorAssignmentCompletion]
|
||||||
|
type: MentorAssignmentStatusType
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ from vbv_lernwelt.core.serializers import UserSerializer
|
||||||
from vbv_lernwelt.learning_mentor.models import LearningMentor, MentorInvitation
|
from vbv_lernwelt.learning_mentor.models import LearningMentor, MentorInvitation
|
||||||
|
|
||||||
|
|
||||||
class PraxisAssignmentCompletionSerializer(serializers.Serializer):
|
class MentorAssignmentCompletionSerializer(serializers.Serializer):
|
||||||
status = serializers.SerializerMethodField()
|
status = serializers.SerializerMethodField()
|
||||||
user_id = serializers.CharField()
|
user_id = serializers.CharField()
|
||||||
last_name = serializers.CharField()
|
last_name = serializers.CharField()
|
||||||
|
|
@ -14,13 +14,13 @@ class PraxisAssignmentCompletionSerializer(serializers.Serializer):
|
||||||
return obj.status.value
|
return obj.status.value
|
||||||
|
|
||||||
|
|
||||||
class PraxisAssignmentStatusSerializer(serializers.Serializer):
|
class MentorAssignmentStatusSerializer(serializers.Serializer):
|
||||||
id = serializers.CharField()
|
id = serializers.CharField()
|
||||||
title = serializers.CharField()
|
title = serializers.CharField()
|
||||||
circle_id = serializers.CharField()
|
circle_id = serializers.CharField()
|
||||||
pending_evaluations = serializers.IntegerField()
|
pending_evaluations = serializers.IntegerField()
|
||||||
completions = PraxisAssignmentCompletionSerializer(many=True)
|
completions = MentorAssignmentCompletionSerializer(many=True)
|
||||||
type = serializers.ReadOnlyField(default="praxis_assignment")
|
type = serializers.ReadOnlyField()
|
||||||
|
|
||||||
|
|
||||||
class InvitationSerializer(serializers.ModelSerializer):
|
class InvitationSerializer(serializers.ModelSerializer):
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ from vbv_lernwelt.learning_mentor.content.praxis_assignment import (
|
||||||
get_assignment_completions,
|
get_assignment_completions,
|
||||||
get_praxis_assignments,
|
get_praxis_assignments,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.learning_mentor.entities import CompletionStatus
|
from vbv_lernwelt.learning_mentor.entities import MentorCompletionStatus
|
||||||
|
|
||||||
|
|
||||||
class AttendanceServicesTestCase(TestCase):
|
class AttendanceServicesTestCase(TestCase):
|
||||||
|
|
@ -74,10 +74,10 @@ class AttendanceServicesTestCase(TestCase):
|
||||||
# THEN
|
# THEN
|
||||||
expected_order = ["Beta", "Alpha", "Gamma", "Kappa"]
|
expected_order = ["Beta", "Alpha", "Gamma", "Kappa"]
|
||||||
expected_statuses = {
|
expected_statuses = {
|
||||||
"Alpha": CompletionStatus.EVALUATED, # user1
|
"Alpha": MentorCompletionStatus.EVALUATED, # user1
|
||||||
"Beta": CompletionStatus.SUBMITTED, # user2
|
"Beta": MentorCompletionStatus.SUBMITTED, # user2
|
||||||
"Gamma": CompletionStatus.UNKNOWN, # user4 (no AssignmentCompletion)
|
"Gamma": MentorCompletionStatus.UNKNOWN, # user4 (no AssignmentCompletion)
|
||||||
"Kappa": CompletionStatus.UNKNOWN, # user3 (IN_PROGRESS should be PENDING)
|
"Kappa": MentorCompletionStatus.UNKNOWN, # user3 (IN_PROGRESS should be PENDING)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.assertEqual(len(results), len(participants))
|
self.assertEqual(len(results), len(participants))
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from typing import List, Optional, Dict
|
||||||
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.test import APITestCase
|
from rest_framework.test import APITestCase
|
||||||
|
|
@ -7,6 +9,7 @@ from vbv_lernwelt.assignment.models import (
|
||||||
AssignmentCompletionStatus,
|
AssignmentCompletionStatus,
|
||||||
AssignmentType,
|
AssignmentType,
|
||||||
)
|
)
|
||||||
|
from vbv_lernwelt.core.admin import User
|
||||||
from vbv_lernwelt.course.creators.test_utils import (
|
from vbv_lernwelt.course.creators.test_utils import (
|
||||||
add_course_session_user,
|
add_course_session_user,
|
||||||
create_assignment,
|
create_assignment,
|
||||||
|
|
@ -16,9 +19,20 @@ from vbv_lernwelt.course.creators.test_utils import (
|
||||||
create_course_session,
|
create_course_session,
|
||||||
create_course_session_assignment,
|
create_course_session_assignment,
|
||||||
create_user,
|
create_user,
|
||||||
|
create_learning_unit,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.course.models import CourseSessionUser
|
from vbv_lernwelt.course.models import CourseSessionUser
|
||||||
from vbv_lernwelt.learning_mentor.models import LearningMentor
|
from vbv_lernwelt.learning_mentor.models import LearningMentor
|
||||||
|
from vbv_lernwelt.self_evaluation_feedback.models import SelfEvaluationFeedback
|
||||||
|
|
||||||
|
|
||||||
|
def get_completion_for_user(
|
||||||
|
completions: List[Dict[str, str]], user: User
|
||||||
|
) -> Optional[Dict[str, str]]:
|
||||||
|
for completion in completions:
|
||||||
|
if completion["user_id"] == str(user.id):
|
||||||
|
return completion
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class LearningMentorAPITest(APITestCase):
|
class LearningMentorAPITest(APITestCase):
|
||||||
|
|
@ -28,15 +42,6 @@ class LearningMentorAPITest(APITestCase):
|
||||||
|
|
||||||
self.circle, _ = create_circle(title="Circle", course_page=self.course_page)
|
self.circle, _ = create_circle(title="Circle", course_page=self.course_page)
|
||||||
|
|
||||||
self.assignment = create_assignment(
|
|
||||||
course=self.course, assignment_type=AssignmentType.PRAXIS_ASSIGNMENT
|
|
||||||
)
|
|
||||||
|
|
||||||
lca = create_assignment_learning_content(self.circle, self.assignment)
|
|
||||||
create_course_session_assignment(
|
|
||||||
course_session=self.course_session, learning_content_assignment=lca
|
|
||||||
)
|
|
||||||
|
|
||||||
self.mentor = create_user("mentor")
|
self.mentor = create_user("mentor")
|
||||||
self.participant_1 = add_course_session_user(
|
self.participant_1 = add_course_session_user(
|
||||||
self.course_session,
|
self.course_session,
|
||||||
|
|
@ -109,7 +114,7 @@ class LearningMentorAPITest(APITestCase):
|
||||||
self.assertEqual(participant_1["first_name"], "Test")
|
self.assertEqual(participant_1["first_name"], "Test")
|
||||||
self.assertEqual(participant_1["last_name"], "Participant_1")
|
self.assertEqual(participant_1["last_name"], "Participant_1")
|
||||||
|
|
||||||
def test_api_praxis_assignments(self) -> None:
|
def test_api_self_evaluation_feedback(self) -> None:
|
||||||
# GIVEN
|
# GIVEN
|
||||||
participants = [self.participant_1, self.participant_2, self.participant_3]
|
participants = [self.participant_1, self.participant_2, self.participant_3]
|
||||||
self.client.force_login(self.mentor)
|
self.client.force_login(self.mentor)
|
||||||
|
|
@ -118,12 +123,97 @@ class LearningMentorAPITest(APITestCase):
|
||||||
mentor=self.mentor,
|
mentor=self.mentor,
|
||||||
course=self.course_session.course,
|
course=self.course_session.course,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
mentor.participants.set(participants)
|
||||||
|
|
||||||
|
learning_unit = create_learning_unit(
|
||||||
|
circle=self.circle,
|
||||||
|
course=self.course,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 1: we already evaluated
|
||||||
|
SelfEvaluationFeedback.objects.create(
|
||||||
|
feedback_requester_user=self.participant_1.user,
|
||||||
|
feedback_provider_user=self.mentor,
|
||||||
|
learning_unit=learning_unit,
|
||||||
|
feedback_submitted=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 2: we have not evaluated yet
|
||||||
|
SelfEvaluationFeedback.objects.create(
|
||||||
|
feedback_requester_user=self.participant_2.user,
|
||||||
|
feedback_provider_user=self.mentor,
|
||||||
|
learning_unit=learning_unit,
|
||||||
|
feedback_submitted=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 3: did not request feedback
|
||||||
|
# ...
|
||||||
|
|
||||||
|
# WHEN
|
||||||
|
response = self.client.get(self.url)
|
||||||
|
|
||||||
|
# THEN
|
||||||
|
assignments = response.data["assignments"]
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
response.data["circles"],
|
||||||
|
[{"id": self.circle.id, "title": self.circle.title}],
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(len(assignments), 1)
|
||||||
|
assignment = assignments[0]
|
||||||
|
|
||||||
|
self.assertEqual(assignment["type"], "self_evaluation_feedback")
|
||||||
|
self.assertEqual(assignment["pending_evaluations"], 1)
|
||||||
|
|
||||||
|
completions = assignment["completions"]
|
||||||
|
self.assertEqual(
|
||||||
|
len(completions),
|
||||||
|
3,
|
||||||
|
)
|
||||||
|
|
||||||
|
completion_1 = get_completion_for_user(completions, self.participant_1.user)
|
||||||
|
self.assertEqual(completion_1["status"], "EVALUATED")
|
||||||
|
self.assertEqual(completion_1["last_name"], "Participant_1")
|
||||||
|
self.assertEqual(completion_1["user_id"], str(self.participant_1.user.id))
|
||||||
|
|
||||||
|
completion_2 = get_completion_for_user(completions, self.participant_2.user)
|
||||||
|
self.assertEqual(completion_2["status"], "SUBMITTED")
|
||||||
|
self.assertEqual(completion_2["last_name"], "Participant_2")
|
||||||
|
self.assertEqual(completion_2["user_id"], str(self.participant_2.user.id))
|
||||||
|
|
||||||
|
completion_3 = get_completion_for_user(completions, self.participant_3.user)
|
||||||
|
self.assertEqual(completion_3["status"], "UNKNOWN")
|
||||||
|
self.assertEqual(completion_3["last_name"], "Participant_3")
|
||||||
|
self.assertEqual(completion_3["user_id"], str(self.participant_3.user.id))
|
||||||
|
|
||||||
|
def test_api_praxis_assignments(self) -> None:
|
||||||
|
# GIVEN
|
||||||
|
self.client.force_login(self.mentor)
|
||||||
|
|
||||||
|
assignment = create_assignment(
|
||||||
|
course=self.course, assignment_type=AssignmentType.PRAXIS_ASSIGNMENT
|
||||||
|
)
|
||||||
|
|
||||||
|
lca = create_assignment_learning_content(self.circle, assignment)
|
||||||
|
create_course_session_assignment(
|
||||||
|
course_session=self.course_session, learning_content_assignment=lca
|
||||||
|
)
|
||||||
|
|
||||||
|
mentor = LearningMentor.objects.create(
|
||||||
|
mentor=self.mentor,
|
||||||
|
course=self.course_session.course,
|
||||||
|
)
|
||||||
|
|
||||||
|
participants = [self.participant_1, self.participant_2, self.participant_3]
|
||||||
mentor.participants.set(participants)
|
mentor.participants.set(participants)
|
||||||
|
|
||||||
AssignmentCompletion.objects.create(
|
AssignmentCompletion.objects.create(
|
||||||
assignment_user=self.participant_1.user,
|
assignment_user=self.participant_1.user,
|
||||||
course_session=self.course_session,
|
course_session=self.course_session,
|
||||||
assignment=self.assignment,
|
assignment=assignment,
|
||||||
completion_status=AssignmentCompletionStatus.EVALUATION_SUBMITTED.value,
|
completion_status=AssignmentCompletionStatus.EVALUATION_SUBMITTED.value,
|
||||||
evaluation_user=self.mentor,
|
evaluation_user=self.mentor,
|
||||||
)
|
)
|
||||||
|
|
@ -131,7 +221,7 @@ class LearningMentorAPITest(APITestCase):
|
||||||
AssignmentCompletion.objects.create(
|
AssignmentCompletion.objects.create(
|
||||||
assignment_user=self.participant_3.user,
|
assignment_user=self.participant_3.user,
|
||||||
course_session=self.course_session,
|
course_session=self.course_session,
|
||||||
assignment=self.assignment,
|
assignment=assignment,
|
||||||
completion_status=AssignmentCompletionStatus.SUBMITTED.value,
|
completion_status=AssignmentCompletionStatus.SUBMITTED.value,
|
||||||
evaluation_user=self.mentor,
|
evaluation_user=self.mentor,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,14 @@ from vbv_lernwelt.iam.permissions import has_role_in_course, is_course_session_m
|
||||||
from vbv_lernwelt.learning_mentor.content.praxis_assignment import (
|
from vbv_lernwelt.learning_mentor.content.praxis_assignment import (
|
||||||
get_praxis_assignments,
|
get_praxis_assignments,
|
||||||
)
|
)
|
||||||
|
from vbv_lernwelt.learning_mentor.content.self_evaluation_feedback import (
|
||||||
|
get_self_feedback_evaluation,
|
||||||
|
)
|
||||||
from vbv_lernwelt.learning_mentor.models import LearningMentor, MentorInvitation
|
from vbv_lernwelt.learning_mentor.models import LearningMentor, MentorInvitation
|
||||||
from vbv_lernwelt.learning_mentor.serializers import (
|
from vbv_lernwelt.learning_mentor.serializers import (
|
||||||
InvitationSerializer,
|
InvitationSerializer,
|
||||||
MentorSerializer,
|
MentorSerializer,
|
||||||
PraxisAssignmentStatusSerializer,
|
MentorAssignmentStatusSerializer,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.learnpath.models import Circle
|
from vbv_lernwelt.learnpath.models import Circle
|
||||||
from vbv_lernwelt.notify.email.email_services import EmailTemplate, send_email
|
from vbv_lernwelt.notify.email.email_services import EmailTemplate, send_email
|
||||||
|
|
@ -37,24 +40,39 @@ def mentor_summary(request, course_session_id: int):
|
||||||
assignments = []
|
assignments = []
|
||||||
circle_ids = set()
|
circle_ids = set()
|
||||||
|
|
||||||
praxis_assignments, _circle_ids = get_praxis_assignments(
|
praxis_assignments, praxis_assignments_circle_ids = get_praxis_assignments(
|
||||||
course_session=course_session, participants=users, evaluation_user=request.user
|
course_session=course_session,
|
||||||
|
participants=users,
|
||||||
|
evaluation_user=request.user, # noqa
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
self_evaluation_feedbacks,
|
||||||
|
self_evaluation_feedback_circle_ids,
|
||||||
|
) = get_self_feedback_evaluation(
|
||||||
|
participants=users,
|
||||||
|
evaluation_user=request.user, # noqa
|
||||||
|
)
|
||||||
|
|
||||||
|
circle_ids.update(praxis_assignments_circle_ids)
|
||||||
|
circle_ids.update(self_evaluation_feedback_circle_ids)
|
||||||
|
|
||||||
|
assignments.extend(
|
||||||
|
MentorAssignmentStatusSerializer(praxis_assignments, many=True).data
|
||||||
)
|
)
|
||||||
assignments.extend(
|
assignments.extend(
|
||||||
PraxisAssignmentStatusSerializer(praxis_assignments, many=True).data
|
MentorAssignmentStatusSerializer(self_evaluation_feedbacks, many=True).data
|
||||||
)
|
)
|
||||||
circle_ids.update(_circle_ids)
|
|
||||||
|
|
||||||
circles = Circle.objects.filter(id__in=circle_ids).values("id", "title")
|
|
||||||
|
|
||||||
assignments.sort(
|
assignments.sort(
|
||||||
key=lambda x: (-x.get("pending_evaluations", 0), x.get("title", "").lower())
|
key=lambda x: (-x.get("pending_evaluations", 0), x.get("title", "").lower())
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
{
|
{
|
||||||
"participants": [UserSerializer(user).data for user in users],
|
"participants": [UserSerializer(user).data for user in users],
|
||||||
"circles": list(circles),
|
"circles": list(
|
||||||
|
Circle.objects.filter(id__in=circle_ids).values("id", "title")
|
||||||
|
),
|
||||||
"assignments": assignments,
|
"assignments": assignments,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue