269 lines
8.9 KiB
Python
269 lines
8.9 KiB
Python
from unittest.mock import patch
|
|
|
|
from django.urls import reverse
|
|
from rest_framework import status
|
|
from rest_framework.test import APITestCase
|
|
|
|
from vbv_lernwelt.course.creators.test_utils import (
|
|
add_course_session_user,
|
|
create_course,
|
|
create_course_session,
|
|
create_user,
|
|
)
|
|
from vbv_lernwelt.course.models import CourseSessionUser
|
|
from vbv_lernwelt.learning_mentor.models import LearningMentor, MentorInvitation
|
|
from vbv_lernwelt.notify.email.email_services import EmailTemplate
|
|
|
|
|
|
class LearningMentorInvitationTest(APITestCase):
|
|
def setUp(self) -> None:
|
|
self.course, self.course_page = create_course("Test Course")
|
|
self.course_session = create_course_session(course=self.course, title="Test VV")
|
|
|
|
self.participant = create_user("participant")
|
|
|
|
def test_create_invitation_not_member(self) -> None:
|
|
# GIVEN
|
|
self.client.force_login(self.participant)
|
|
invite_url = reverse(
|
|
"create_invitation", kwargs={"course_session_id": self.course_session.id}
|
|
)
|
|
|
|
# WHEN
|
|
response = self.client.post(invite_url)
|
|
|
|
# THEN
|
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
|
|
|
@patch("vbv_lernwelt.learning_mentor.views.send_email")
|
|
def test_create_denies_self_invitation(self, mock_send_mail) -> None:
|
|
# GIVEN
|
|
self.client.force_login(self.participant)
|
|
|
|
add_course_session_user(
|
|
self.course_session,
|
|
self.participant,
|
|
role=CourseSessionUser.Role.MEMBER,
|
|
)
|
|
|
|
invite_url = reverse(
|
|
"create_invitation", kwargs={"course_session_id": self.course_session.id}
|
|
)
|
|
|
|
# WHEN
|
|
email = self.participant.email
|
|
response = self.client.post(invite_url, data={"email": email})
|
|
|
|
# THEN
|
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
|
self.assertEqual(
|
|
response.data,
|
|
{
|
|
"message": "You cannot invite yourself",
|
|
},
|
|
)
|
|
|
|
@patch("vbv_lernwelt.learning_mentor.views.send_email")
|
|
def test_create_invitation_vv(self, mock_send_mail) -> None:
|
|
self._test_create_invitation(
|
|
EmailTemplate.LEARNING_MENTOR_INVITATION, mock_send_mail
|
|
)
|
|
|
|
@patch("vbv_lernwelt.learning_mentor.views.send_email")
|
|
def test_create_invitation_uk(self, mock_send_mail) -> None:
|
|
self.course_session.course.configuration.is_uk = True
|
|
self.course_session.course.configuration.is_vv = False
|
|
self.course_session.course.configuration.save()
|
|
self._test_create_invitation(
|
|
EmailTemplate.PRAXISBILDNER_INVITATION, mock_send_mail, parameter="?uk=true"
|
|
)
|
|
|
|
def _test_create_invitation(
|
|
self, email_template, mock_send_mail, parameter=""
|
|
) -> None:
|
|
# GIVEN
|
|
self.client.force_login(self.participant)
|
|
add_course_session_user(
|
|
self.course_session,
|
|
self.participant,
|
|
role=CourseSessionUser.Role.MEMBER,
|
|
)
|
|
invite_url = reverse(
|
|
"create_invitation", kwargs={"course_session_id": self.course_session.id}
|
|
)
|
|
email = "test@example.com"
|
|
|
|
# WHEN
|
|
response = self.client.post(invite_url, data={"email": email})
|
|
|
|
# THEN
|
|
invitation_id = response.data["id"]
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
|
|
self.assertTrue(
|
|
MentorInvitation.objects.filter(
|
|
id=invitation_id,
|
|
).exists()
|
|
)
|
|
|
|
mock_send_mail.assert_called_once_with(
|
|
recipient_email=email,
|
|
template=email_template,
|
|
template_data={
|
|
"inviter_name": f"{self.participant.first_name} {self.participant.last_name}",
|
|
"inviter_email": self.participant.email,
|
|
"target_url": f"https://my.vbv-afa.ch/lernbegleitung/{self.course_session.id}/invitation/{invitation_id}{parameter}",
|
|
},
|
|
template_language=self.participant.language,
|
|
fail_silently=True,
|
|
)
|
|
|
|
def test_cannot_create_invitation_if_learning_mentor_disabled(self) -> None:
|
|
# GIVEN
|
|
self.course_session.course.configuration.enable_learning_mentor = False
|
|
self.course_session.course.configuration.save()
|
|
|
|
self.client.force_login(self.participant)
|
|
add_course_session_user(
|
|
self.course_session,
|
|
self.participant,
|
|
role=CourseSessionUser.Role.MEMBER,
|
|
)
|
|
invite_url = reverse(
|
|
"create_invitation", kwargs={"course_session_id": self.course_session.id}
|
|
)
|
|
email = "test@example.com"
|
|
# WHEN
|
|
response = self.client.post(invite_url, data={"email": email})
|
|
|
|
# THEN
|
|
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
|
|
|
def test_list_invitations(self) -> None:
|
|
# GIVEN
|
|
self.client.force_login(self.participant)
|
|
participant_cs_user = add_course_session_user(
|
|
self.course_session,
|
|
self.participant,
|
|
role=CourseSessionUser.Role.MEMBER,
|
|
)
|
|
email = "test@example.com"
|
|
|
|
MentorInvitation.objects.create(participant=participant_cs_user, email=email)
|
|
|
|
list_url = reverse(
|
|
"list_invitations", kwargs={"course_session_id": self.course_session.id}
|
|
)
|
|
|
|
# WHEN
|
|
response = self.client.get(list_url)
|
|
|
|
# THEN
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertEqual(
|
|
response.data,
|
|
[{"id": str(MentorInvitation.objects.get(email=email).id), "email": email}],
|
|
)
|
|
|
|
def test_delete_invitation(self) -> None:
|
|
# GIVEN
|
|
self.client.force_login(self.participant)
|
|
participant_cs_user = add_course_session_user(
|
|
self.course_session,
|
|
self.participant,
|
|
role=CourseSessionUser.Role.MEMBER,
|
|
)
|
|
email = "test@example.com"
|
|
|
|
invitation = MentorInvitation.objects.create(
|
|
participant=participant_cs_user, email=email
|
|
)
|
|
|
|
delete_url = reverse(
|
|
"delete_invitation",
|
|
kwargs={
|
|
"course_session_id": self.course_session.id,
|
|
"invitation_id": invitation.id,
|
|
},
|
|
)
|
|
|
|
# WHEN
|
|
response = self.client.delete(delete_url)
|
|
|
|
# THEN
|
|
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
|
self.assertFalse(MentorInvitation.objects.filter(id=invitation.id).exists())
|
|
|
|
def test_accept_invitation_invalid_course(self) -> None:
|
|
# GIVEN
|
|
other_course, _ = create_course("Other Test Course")
|
|
other_course_session = create_course_session(
|
|
course=other_course, title="Other Test Session"
|
|
)
|
|
participant_cs_user = add_course_session_user(
|
|
self.course_session,
|
|
self.participant,
|
|
role=CourseSessionUser.Role.MEMBER,
|
|
)
|
|
|
|
invitee = create_user("invitee")
|
|
invitation = MentorInvitation.objects.create(
|
|
participant=participant_cs_user, email=invitee.email
|
|
)
|
|
self.client.force_login(invitee)
|
|
|
|
accept_url = reverse(
|
|
"accept_invitation", kwargs={"course_session_id": other_course_session.id}
|
|
)
|
|
|
|
# WHEN
|
|
response = self.client.post(accept_url, data={"invitation_id": invitation.id})
|
|
|
|
# THEN
|
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
|
self.assertEqual(
|
|
response.data,
|
|
{
|
|
"message": "Invalid invitation",
|
|
"code": "invalidInvitation",
|
|
},
|
|
)
|
|
|
|
def test_accept_invitation(self) -> None:
|
|
# GIVEN
|
|
participant_cs_user = add_course_session_user(
|
|
course_session=self.course_session,
|
|
user=self.participant,
|
|
role=CourseSessionUser.Role.MEMBER,
|
|
)
|
|
|
|
invitee = create_user("invitee")
|
|
invitation = MentorInvitation.objects.create(
|
|
participant=participant_cs_user, email=invitee.email
|
|
)
|
|
|
|
self.client.force_login(invitee)
|
|
|
|
accept_url = reverse(
|
|
"accept_invitation", kwargs={"course_session_id": self.course_session.id}
|
|
)
|
|
|
|
# WHEN
|
|
response = self.client.post(accept_url, data={"invitation_id": invitation.id})
|
|
|
|
# THEN
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertFalse(MentorInvitation.objects.filter(id=invitation.id).exists())
|
|
self.assertTrue(
|
|
LearningMentor.objects.filter(
|
|
mentor=invitee,
|
|
course_session=self.course_session,
|
|
participants=participant_cs_user,
|
|
).exists()
|
|
)
|
|
|
|
user = response.data["user"]
|
|
self.assertEqual(user["id"], str(self.participant.id))
|
|
|
|
self.assertEqual(response.data["course_slug"], str(self.course.slug))
|