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))