vbv/server/vbv_lernwelt/self_evaluation_feedback/tests/test_api.py

464 lines
16 KiB
Python

from unittest.mock import patch
from django.urls import reverse
from rest_framework.test import APITestCase
from vbv_lernwelt.course.creators.test_utils import (
add_course_session_user,
create_circle,
create_course,
create_course_session,
create_learning_unit,
create_performance_criteria_page,
create_user,
)
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 (
CourseCompletionFeedback,
SelfEvaluationFeedback,
)
def create_self_evaluation_feedback(
learning_unit, feedback_requester_user, feedback_provider_user
):
return SelfEvaluationFeedback.objects.create(
learning_unit=learning_unit,
feedback_requester_user=feedback_requester_user,
feedback_provider_user=feedback_provider_user,
)
class SelfEvaluationFeedbackAPI(APITestCase):
def setUp(self) -> None:
self.member = create_user("member")
self.mentor = create_user("mentor")
self.course, self.course_page = create_course("Test Course")
self.course_session = create_course_session(
course=self.course, title="Test Bern 2022 a"
)
member_csu = add_course_session_user(
course_session=self.course_session,
user=self.member,
role=CourseSessionUser.Role.MEMBER,
)
self.circle, _ = create_circle(
title="Test Circle", course_page=self.course_page
)
learning_mentor = LearningMentor.objects.create(
mentor=self.mentor,
course=self.course_session.course,
)
learning_mentor.participants.add(member_csu)
@patch(
"vbv_lernwelt.notify.services.NotificationService.send_self_evaluation_feedback_request_feedback_notification"
)
def test_start_self_evaluation_feedback(self, mock_notification_service_send):
# GIVEN
learning_unit = create_learning_unit(course=self.course, circle=self.circle)
pc = create_performance_criteria_page(
course=self.course,
course_page=self.course_page,
circle=self.circle,
learning_unit=learning_unit,
)
mark_course_completion(
page=pc,
user=self.member,
course_session=self.course_session,
completion_status="SUCCESS",
)
self.client.force_login(self.member)
# WHEN
response = self.client.post(
reverse(
"start_self_evaluation_feedback",
args=[learning_unit.id],
),
{
"feedback_provider_user_id": self.mentor.id,
},
)
# make sure re-starting is a no-op
self.client.post(
reverse(
"start_self_evaluation_feedback",
args=[learning_unit.id],
),
{
"feedback_provider_user_id": self.mentor.id,
},
)
# shall be idempotent
self.client.post(
reverse(
"start_self_evaluation_feedback",
args=[learning_unit.id],
),
{
"feedback_provider_user_id": self.mentor.id,
},
)
# THEN
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data["success"], True)
self.assertEqual(
SelfEvaluationFeedback.objects.count(),
1,
)
self_evaluation_feedback = SelfEvaluationFeedback.objects.first()
self.assertEqual(self_evaluation_feedback.feedback_requester_user, self.member)
self.assertEqual(self_evaluation_feedback.feedback_provider_user, self.mentor)
self.assertEqual(self_evaluation_feedback.learning_unit, learning_unit)
mock_notification_service_send.assert_called_once_with(
self_evaluation_feedback=self_evaluation_feedback
)
def test_start_self_evaluation_feedback_not_allowed_user(self):
# GIVEN
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", args=[learning_unit.id]),
{
"feedback_provider_user_id": not_a_mentor.id,
},
)
# THEN
self.assertEqual(response.status_code, 403)
def test_get_self_evaluation_feedback_as_requester(self):
"""Tests endpoint of feedback REQUESTER"""
# 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,
)
self_evaluation_feedback = create_self_evaluation_feedback(
learning_unit=learning_unit,
feedback_requester_user=self.member,
feedback_provider_user=self.mentor,
)
CourseCompletionFeedback.objects.create(
feedback=self_evaluation_feedback,
course_completion=completion,
feedback_assessment=CourseCompletionStatus.FAIL.value,
)
self.client.force_login(self.member)
# WHEN
response = self.client.get(
reverse(
"get_self_evaluation_feedback_as_requester",
args=[learning_unit.id],
)
)
# THEN
self.assertEqual(response.status_code, 200)
feedback = response.data
self.assertEqual(feedback["learning_unit_id"], learning_unit.id)
self.assertEqual(feedback["feedback_submitted"], False)
self.assertEqual(feedback["circle_name"], self.circle.title)
provider_user = feedback["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 = feedback["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(feedback["criteria"]), 2)
first_criteria = feedback["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 = feedback["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,
)
def test_get_self_evaluation_feedback_as_provider(self):
"""Tests endpoint of feedback PROVIDER"""
# 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,
)
self_evaluation_feedback = create_self_evaluation_feedback(
learning_unit=learning_unit,
feedback_requester_user=self.member,
feedback_provider_user=self.mentor,
)
CourseCompletionFeedback.objects.create(
feedback=self_evaluation_feedback,
course_completion=completion,
feedback_assessment=CourseCompletionStatus.FAIL.value,
)
self.client.force_login(self.mentor)
# WHEN
response = self.client.get(
reverse(
"get_self_evaluation_feedback_as_provider",
args=[self_evaluation_feedback.learning_unit.id],
)
)
# THEN
self.assertEqual(response.status_code, 200)
feedback = response.data
self.assertEqual(feedback["learning_unit_id"], learning_unit.id)
self.assertEqual(feedback["title"], learning_unit.title)
self.assertEqual(feedback["feedback_submitted"], False)
self.assertEqual(feedback["circle_name"], self.circle.title)
provider_user = feedback["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 = feedback["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(feedback["criteria"]), 2)
first_criteria = feedback["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 = feedback["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,
)
def test_self_evaluation_feedback_assessment(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,
)
completion = mark_course_completion(
page=performance_criteria_1,
user=self.member,
course_session=self.course_session,
completion_status=CourseCompletionStatus.SUCCESS.value,
)
self_evaluation_feedback = create_self_evaluation_feedback(
learning_unit=learning_unit,
feedback_requester_user=self.member,
feedback_provider_user=self.mentor,
)
self.client.force_login(self.mentor)
# WHEN
response = self.client.put(
reverse(
"add_self_evaluation_feedback_assessment",
args=[self_evaluation_feedback.id],
),
{
"course_completion_id": completion.id,
"feedback_assessment": CourseCompletionStatus.FAIL.value,
},
)
# THEN
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data["success"], True)
feedback = CourseCompletionFeedback.objects.get(
feedback=self_evaluation_feedback,
course_completion=completion,
)
self.assertEqual(
feedback.feedback_assessment, CourseCompletionStatus.FAIL.value
)
@patch(
"vbv_lernwelt.notify.services.NotificationService.send_self_evaluation_feedback_received_notification"
)
def test_release_self_evaluation_feedback(self, mock_notification_service_send):
# GIVEN
learning_unit = create_learning_unit(course=self.course, circle=self.circle)
self_evaluation_feedback = create_self_evaluation_feedback(
learning_unit=learning_unit,
feedback_requester_user=self.member,
feedback_provider_user=self.mentor,
)
self.assertEqual(self_evaluation_feedback.feedback_submitted, False)
self.client.force_login(self.mentor)
# WHEN
response = self.client.put(
reverse(
"release_self_evaluation_feedback", args=[self_evaluation_feedback.id]
),
)
# shall be idempotent
response = self.client.put(
reverse(
"release_self_evaluation_feedback", args=[self_evaluation_feedback.id]
),
)
# THEN
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data["success"], True)
self.assertEqual(
SelfEvaluationFeedback.objects.get(
id=self_evaluation_feedback.id
).feedback_submitted,
True,
)
mock_notification_service_send.assert_called_once_with(
self_evaluation_feedback=self_evaluation_feedback
)
def test_get_self_evaluation_feedback_frontend_urls(self):
"""Makes sure that the frontend urls are correct (used in notifications)"""
# GIVEN
learning_unit = create_learning_unit(course=self.course, circle=self.circle)
cut = create_self_evaluation_feedback(
learning_unit=learning_unit,
feedback_requester_user=self.member,
feedback_provider_user=self.mentor,
)
# WHEN
requester_url = cut.feedback_requester_results_url
provider_url = cut.feedback_provider_evaluation_url
# THEN
_course, _circle, _learning_unit = learning_unit.get_frontend_url_parts()
# 0 -> no completions so step=0 is correct
_step = len(learning_unit.performancecriteria_set.all())
self.assertEqual(
requester_url,
f"/course/{_course}/learn/{_circle}/evaluate/{_learning_unit}?step={_step}",
)
self.assertEqual(
provider_url,
f"/course/{_course}/cockpit/mentor/self-evaluation-feedback/{learning_unit.id}",
)