Add signal tests, add LearningMentor
This commit is contained in:
parent
e6eae79171
commit
eb931c86c8
|
|
@ -945,12 +945,10 @@ def create_or_update_student(data: Dict[str, Any]):
|
|||
)
|
||||
|
||||
user.language = data["Sprache"]
|
||||
update_user_json_data(user, data)
|
||||
user.save()
|
||||
|
||||
# create user in intermediate sso i.e. Keycloak
|
||||
sso_data = {"intermediate_sso_id": create_user(user)}
|
||||
update_user_json_data(user, sso_data)
|
||||
data["intermediate_sso_id"] = create_user(user)
|
||||
user.update_additional_json_data(data)
|
||||
user.save()
|
||||
|
||||
# general expert handling
|
||||
import_id = data["Durchführungen"]
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import structlog
|
||||
from django.db.models.signals import m2m_changed, post_delete, pre_save
|
||||
from django.db.models.signals import m2m_changed, post_delete, pre_delete, pre_save
|
||||
from django.dispatch import receiver
|
||||
from keycloak.exceptions import KeycloakDeleteError, KeycloakError, KeycloakPostError
|
||||
|
||||
from vbv_lernwelt.core.models import User
|
||||
from vbv_lernwelt.course.models import CourseSessionUser
|
||||
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
|
||||
from vbv_lernwelt.learning_mentor.models import LearningMentor
|
||||
from vbv_lernwelt.sso.role_sync.services import (
|
||||
add_roles_to_user,
|
||||
remove_roles_from_user,
|
||||
|
|
@ -18,7 +19,13 @@ logger = structlog.get_logger(__name__)
|
|||
# CourseSessionUser
|
||||
@receiver(post_delete, sender=CourseSessionUser, dispatch_uid="delete_sso_roles_in_cs")
|
||||
def remove_sso_roles_in_cs(sender, instance, **kwargs):
|
||||
_remove_sso_role(instance.user, instance.course_session.course.slug, instance.role)
|
||||
# check if the user has any other roles in the course
|
||||
if not CourseSessionUser.objects.filter(
|
||||
user=instance.user, course_session__course=instance.course_session.course
|
||||
).exists():
|
||||
_remove_sso_role(
|
||||
instance.user, instance.course_session.course.slug, instance.role
|
||||
)
|
||||
|
||||
|
||||
@receiver(pre_save, sender=CourseSessionUser, dispatch_uid="update_sso_roles_in_cs")
|
||||
|
|
@ -44,9 +51,7 @@ def update_sso_roles_in_cs(sender, instance: CourseSessionUser, **kwargs):
|
|||
|
||||
|
||||
# CourseSessionGroup
|
||||
@receiver(
|
||||
post_delete, sender=CourseSessionGroup, dispatch_uid="delete_sso_roles_in_csg"
|
||||
)
|
||||
@receiver(pre_delete, sender=CourseSessionGroup, dispatch_uid="delete_sso_roles_in_csg")
|
||||
def remove_sso_roles_in_csg(sender, instance: CourseSessionGroup, **kwargs):
|
||||
for user in instance.supervisor.all():
|
||||
_remove_sso_role(user, instance.course.slug, "SUPERVISOR")
|
||||
|
|
@ -69,6 +74,25 @@ def update_sso_roles_in_csg(sender, instance, action, reverse, model, pk_set, **
|
|||
_remove_sso_role(user, instance.course.slug, "SUPERVISOR")
|
||||
|
||||
|
||||
# LearningMentor
|
||||
@receiver(post_delete, sender=LearningMentor, dispatch_uid="delete_sso_roles_in_lm")
|
||||
def remove_sso_roles_in_lm(sender, instance: LearningMentor, **kwargs):
|
||||
if not LearningMentor.objects.filter(
|
||||
mentor=instance.mentor, course_session__course=instance.course_session.course
|
||||
).exists():
|
||||
_remove_sso_role(
|
||||
instance.mentor, instance.course_session.course.slug, "LEARNING_MENTOR"
|
||||
)
|
||||
|
||||
|
||||
@receiver(pre_save, sender=LearningMentor, dispatch_uid="update_sso_roles_in_lm")
|
||||
def update_sso_roles_in_lm(sender, instance: LearningMentor, **kwargs):
|
||||
if not instance.pk:
|
||||
_add_sso_role(
|
||||
instance.mentor, instance.course_session.course.slug, "LEARNING_MENTOR"
|
||||
)
|
||||
|
||||
|
||||
def _remove_sso_role(user: User, course_slug: str, role: str):
|
||||
try:
|
||||
logger.debug(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,246 @@
|
|||
from unittest.mock import call, patch
|
||||
|
||||
from django.db.models.signals import pre_save
|
||||
from django.dispatch import Signal
|
||||
from django.test import TestCase
|
||||
|
||||
from vbv_lernwelt.core.constants import (
|
||||
TEST_COURSE_SESSION_BERN_ID,
|
||||
TEST_COURSE_SESSION_ZURICH_ID,
|
||||
TEST_STUDENT1_USER_ID,
|
||||
TEST_STUDENT2_USER_ID,
|
||||
TEST_SUPERVISOR1_USER_ID,
|
||||
TEST_TRAINER1_USER_ID,
|
||||
)
|
||||
from vbv_lernwelt.core.create_default_users import create_default_users
|
||||
from vbv_lernwelt.core.models import User
|
||||
from vbv_lernwelt.course.consts import COURSE_TEST_ID
|
||||
from vbv_lernwelt.course.creators.test_course import create_test_course
|
||||
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 Course, CourseSessionUser
|
||||
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
|
||||
from vbv_lernwelt.learning_mentor.models import LearningMentor
|
||||
from vbv_lernwelt.sso.signals import update_sso_roles_in_cs
|
||||
|
||||
|
||||
class CourseSessionUserTests(TestCase):
|
||||
def setUp(self):
|
||||
create_default_users()
|
||||
create_test_course(include_uk=True, with_sessions=True)
|
||||
|
||||
self.student1 = User.objects.get(id=TEST_STUDENT1_USER_ID)
|
||||
self.csu1_student1 = CourseSessionUser.objects.get(
|
||||
user=self.student1, course_session__id=TEST_COURSE_SESSION_BERN_ID
|
||||
)
|
||||
self.student2 = User.objects.get(id=TEST_STUDENT2_USER_ID)
|
||||
self.csu1_student2 = CourseSessionUser.objects.get(
|
||||
user=self.student2, course_session__id=TEST_COURSE_SESSION_ZURICH_ID
|
||||
)
|
||||
|
||||
# Disconnect the actual signal handler to avoid side effects during testing
|
||||
pre_save.disconnect(receiver=update_sso_roles_in_cs, sender=CourseSessionUser)
|
||||
|
||||
# Connect a mock signal handler
|
||||
self.mock_pre_save_signal = Signal()
|
||||
self.mock_pre_save_signal.connect(
|
||||
receiver=update_sso_roles_in_cs, sender=CourseSessionUser
|
||||
)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.remove_roles_from_user")
|
||||
def test_remove_roles_for_single_role_in_cs(self, mock_remove_roles_from_user):
|
||||
mock_remove_roles_from_user.return_value = None
|
||||
|
||||
self.csu1_student1.delete()
|
||||
|
||||
self.assertEqual(mock_remove_roles_from_user.call_count, 1)
|
||||
|
||||
mock_remove_roles_from_user.assert_called_with(
|
||||
self.student1, [(self.csu1_student1.course_session.course.slug, "MEMBER")]
|
||||
)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.remove_roles_from_user")
|
||||
def test_dont_remove_roles_for_multiple_roles_in_cs(
|
||||
self, mock_remove_roles_from_user
|
||||
):
|
||||
mock_remove_roles_from_user.return_value = None
|
||||
|
||||
self.csu1_student2.delete()
|
||||
|
||||
self.assertFalse(mock_remove_roles_from_user.called)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.add_roles_to_user")
|
||||
def test_add_role_for_user_on_creation(self, mock_add_roles_from_user):
|
||||
mock_add_roles_from_user.return_value = None
|
||||
self.csu1_student1.delete()
|
||||
csu = CourseSessionUser.objects.create(
|
||||
user=self.student1,
|
||||
course_session=self.csu1_student1.course_session,
|
||||
role="MEMBER",
|
||||
)
|
||||
|
||||
self.mock_pre_save_signal.send(sender=CourseSessionUser, instance=csu)
|
||||
|
||||
self.assertEqual(mock_add_roles_from_user.call_count, 1)
|
||||
|
||||
mock_add_roles_from_user.assert_called_with(
|
||||
self.student1, [(self.csu1_student1.course_session.course.slug, "MEMBER")]
|
||||
)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.update_roles_for_user")
|
||||
def test_update_role_for_user_on_creation(self, mock_update_roles_for_user):
|
||||
mock_update_roles_for_user.return_value = None
|
||||
self.csu1_student1.role = "TRAINER"
|
||||
|
||||
self.mock_pre_save_signal.send(
|
||||
sender=CourseSessionUser, instance=self.csu1_student1
|
||||
)
|
||||
|
||||
self.assertEqual(mock_update_roles_for_user.call_count, 1)
|
||||
|
||||
mock_update_roles_for_user.assert_called_with(
|
||||
self.student1,
|
||||
add_course_roles=[
|
||||
(self.csu1_student1.course_session.course.slug, "TRAINER")
|
||||
],
|
||||
remove_course_roles=[
|
||||
(self.csu1_student1.course_session.course.slug, "MEMBER")
|
||||
],
|
||||
)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.update_roles_for_user")
|
||||
def test_dont_update_role_for_user_on_creation(self, mock_update_roles_for_user):
|
||||
mock_update_roles_for_user.return_value = None
|
||||
self.csu1_student1.role = "MEMBER"
|
||||
|
||||
self.mock_pre_save_signal.send(
|
||||
sender=CourseSessionUser, instance=self.csu1_student1
|
||||
)
|
||||
|
||||
self.assertEqual(mock_update_roles_for_user.call_count, 0)
|
||||
|
||||
|
||||
class CourseSessionGroupTests(TestCase):
|
||||
def setUp(self):
|
||||
create_default_users()
|
||||
create_test_course(include_uk=True, with_sessions=True)
|
||||
|
||||
self.csg = CourseSessionGroup.objects.get(
|
||||
name="Region 1",
|
||||
)
|
||||
course = Course.objects.get(id=COURSE_TEST_ID)
|
||||
self.slug = course.slug
|
||||
|
||||
self.trainer = User.objects.get(id=TEST_TRAINER1_USER_ID)
|
||||
self.supervisor = User.objects.get(id=TEST_SUPERVISOR1_USER_ID)
|
||||
|
||||
# m2m_changed.disconnect(receiver=update_sso_roles_in_csg, sender=CourseSessionGroup.supervisor.through)
|
||||
#
|
||||
# # Connect a mock signal handler
|
||||
# self.mock_signal = Signal()
|
||||
# self.mock_signal.connect(receiver=update_sso_roles_in_csg, sender=CourseSessionGroup.supervisor.through)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.remove_roles_from_user")
|
||||
def test_remove_roles_for_csg_supervisors(self, mock_remove_roles_from_user):
|
||||
mock_remove_roles_from_user.return_value = None
|
||||
self.csg.supervisor.set([self.trainer, self.supervisor])
|
||||
self.csg.delete()
|
||||
|
||||
expected_calls = [
|
||||
call(self.supervisor, [(self.slug, "SUPERVISOR")]),
|
||||
call(self.trainer, [(self.slug, "SUPERVISOR")]),
|
||||
]
|
||||
mock_remove_roles_from_user.assert_has_calls(expected_calls, any_order=True)
|
||||
self.assertEqual(mock_remove_roles_from_user.call_count, 2)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.remove_roles_from_user")
|
||||
@patch("vbv_lernwelt.sso.signals.add_roles_to_user")
|
||||
def test_add_supervisors_to_csg(
|
||||
self, mock_add_roles_to_user, mock_remove_roles_from_user
|
||||
):
|
||||
mock_remove_roles_from_user.return_value = None
|
||||
mock_add_roles_to_user.return_value = None
|
||||
|
||||
self.csg.supervisor.add(self.trainer)
|
||||
|
||||
self.assertEqual(mock_add_roles_to_user.call_count, 1)
|
||||
self.assertEqual(mock_remove_roles_from_user.call_count, 0)
|
||||
|
||||
mock_add_roles_to_user.assert_called_with(
|
||||
self.trainer, [(self.slug, "SUPERVISOR")]
|
||||
)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.remove_roles_from_user")
|
||||
@patch("vbv_lernwelt.sso.signals.add_roles_to_user")
|
||||
def test_remove_supervisors_to_csg(
|
||||
self, mock_add_roles_to_user, mock_remove_roles_from_user
|
||||
):
|
||||
mock_remove_roles_from_user.return_value = None
|
||||
mock_add_roles_to_user.return_value = None
|
||||
|
||||
self.csg.supervisor.remove(self.supervisor)
|
||||
|
||||
self.assertEqual(mock_add_roles_to_user.call_count, 0)
|
||||
self.assertEqual(mock_remove_roles_from_user.call_count, 1)
|
||||
|
||||
mock_remove_roles_from_user.assert_called_with(
|
||||
self.supervisor, [(self.slug, "SUPERVISOR")]
|
||||
)
|
||||
|
||||
|
||||
class LearningMentorTests(TestCase):
|
||||
def setUp(self):
|
||||
self.course, self.course_page = create_course("Test Course")
|
||||
self.course_session = create_course_session(course=self.course, title="Test VV")
|
||||
|
||||
self.user = create_user("mentor")
|
||||
self.mentor = LearningMentor.objects.create(
|
||||
mentor=self.user, course_session=self.course_session
|
||||
)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.remove_roles_from_user")
|
||||
def test_remove_roles_for_learning_mentor_on_delete(
|
||||
self, mock_remove_roles_from_user
|
||||
):
|
||||
mock_remove_roles_from_user.return_value = None
|
||||
|
||||
self.mentor.delete()
|
||||
|
||||
self.assertEqual(mock_remove_roles_from_user.call_count, 1)
|
||||
|
||||
mock_remove_roles_from_user.assert_called_with(
|
||||
self.user, [(self.course.slug, "LEARNING_MENTOR")]
|
||||
)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.add_roles_to_user")
|
||||
def test_add_roles_for_learning_mentor_on_create(self, mock_add_roles_from_user):
|
||||
mock_add_roles_from_user.return_value = None
|
||||
self.mentor.delete()
|
||||
|
||||
LearningMentor.objects.create(
|
||||
mentor=self.user, course_session=self.course_session
|
||||
)
|
||||
|
||||
self.assertEqual(mock_add_roles_from_user.call_count, 1)
|
||||
|
||||
mock_add_roles_from_user.assert_called_with(
|
||||
self.user, [(self.course.slug, "LEARNING_MENTOR")]
|
||||
)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.add_roles_to_user")
|
||||
def test_no_add_roles_for_learning_mentor_on_update(self, mock_add_roles_from_user):
|
||||
mock_add_roles_from_user.return_value = None
|
||||
|
||||
participant_1 = add_course_session_user(
|
||||
self.course_session,
|
||||
create_user("participant_1"),
|
||||
role=CourseSessionUser.Role.MEMBER,
|
||||
)
|
||||
|
||||
mock_add_roles_from_user.reset_mock()
|
||||
self.mentor.participants.set([participant_1])
|
||||
self.assertEqual(mock_add_roles_from_user.call_count, 0)
|
||||
Loading…
Reference in New Issue