167 lines
6.3 KiB
Python
167 lines
6.3 KiB
Python
from unittest.mock import patch
|
|
|
|
from django.test import TestCase, override_settings
|
|
from keycloak.exceptions import KeycloakDeleteError, KeycloakPostError
|
|
|
|
from vbv_lernwelt.core.models import User
|
|
from vbv_lernwelt.sso.models import SsoSyncError
|
|
from vbv_lernwelt.sso.role_sync.services import (
|
|
_filter_non_myvbv_roles,
|
|
_remove_accents,
|
|
add_roles_to_user,
|
|
create_user,
|
|
remove_roles_from_user,
|
|
sync_roles_for_user,
|
|
update_roles_for_user,
|
|
)
|
|
|
|
|
|
@override_settings(OAUTH_SYNC_ROLES=True)
|
|
class ApiTestCase(TestCase):
|
|
def setUp(self):
|
|
self.user = User(email="test@example.com", first_name="Test", last_name="User")
|
|
self.user.additional_json_data = {"intermediate_sso_id": "1234"}
|
|
self.user.save()
|
|
|
|
self.course_roles = [
|
|
("überbetriebliche-kurse", "EXPERT"),
|
|
("versicherungsvermittler-in", "MEMBER"),
|
|
]
|
|
self.expected_roles = [
|
|
{
|
|
"name": "myvbv-uberbetriebliche-kurse-expert",
|
|
"id": "c7e33cb6-d227-4764-9b8e-d42af79fb46d",
|
|
},
|
|
{
|
|
"name": "myvbv-versicherungsvermittler-in-member",
|
|
"id": "3ab4eab2-7d7c-43bb-a927-4cf54f24ccc2",
|
|
},
|
|
]
|
|
|
|
@patch("vbv_lernwelt.sso.role_sync.services.keycloak_admin")
|
|
def test_add_roles_to_user_success(self, mock_keycloak_admin):
|
|
mock_keycloak_admin.assign_realm_roles.return_value = None
|
|
|
|
result = add_roles_to_user(self.user, self.course_roles)
|
|
|
|
self.assertTrue(result)
|
|
mock_keycloak_admin.assign_realm_roles.assert_called_once_with(
|
|
user_id="1234", roles=self.expected_roles
|
|
)
|
|
|
|
@patch("vbv_lernwelt.sso.role_sync.services.keycloak_admin")
|
|
def test_add_roles_to_user_keycloak_post_error(self, mock_keycloak_admin):
|
|
mock_keycloak_admin.assign_realm_roles.side_effect = KeycloakPostError
|
|
|
|
with self.assertRaises(KeycloakPostError) as cm:
|
|
add_roles_to_user(self.user, self.course_roles)
|
|
|
|
exception = cm.exception
|
|
self.assertIsInstance(exception, KeycloakPostError)
|
|
error_obj = SsoSyncError.objects.get(user=self.user)
|
|
self.assertEqual(error_obj.data, self.expected_roles)
|
|
self.assertEqual(error_obj.action, SsoSyncError.Action.ADD)
|
|
|
|
@patch("vbv_lernwelt.sso.role_sync.services.keycloak_admin")
|
|
def test_remove_roles_to_user_success(self, mock_keycloak_admin):
|
|
mock_keycloak_admin.delete_realm_roles_of_user.return_value = None
|
|
|
|
result = remove_roles_from_user(self.user, self.course_roles)
|
|
|
|
self.assertTrue(result)
|
|
mock_keycloak_admin.delete_realm_roles_of_user.assert_called_once_with(
|
|
user_id="1234", roles=self.expected_roles
|
|
)
|
|
|
|
@patch("vbv_lernwelt.sso.role_sync.services.keycloak_admin")
|
|
def test_remove_roles_to_user_keycloak_delete_error(self, mock_keycloak_admin):
|
|
mock_keycloak_admin.delete_realm_roles_of_user.side_effect = KeycloakDeleteError
|
|
|
|
with self.assertRaises(KeycloakDeleteError) as cm:
|
|
remove_roles_from_user(self.user, self.course_roles)
|
|
|
|
exception = cm.exception
|
|
self.assertIsInstance(exception, KeycloakDeleteError)
|
|
error_obj = SsoSyncError.objects.get(user=self.user)
|
|
self.assertEqual(error_obj.data, self.expected_roles)
|
|
self.assertEqual(error_obj.action, SsoSyncError.Action.REMOVE)
|
|
|
|
@patch("vbv_lernwelt.sso.role_sync.services.remove_roles_from_user")
|
|
@patch("vbv_lernwelt.sso.role_sync.services.add_roles_to_user")
|
|
def test_update_roles_to_user(
|
|
self, mock_add_roles_to_user, mock_remove_roles_from_user
|
|
):
|
|
mock_add_roles_to_user.return_value = True
|
|
mock_remove_roles_from_user.return_value = True
|
|
|
|
update_roles_for_user(self.user, self.course_roles, self.course_roles)
|
|
mock_add_roles_to_user.assert_called_once()
|
|
mock_remove_roles_from_user.assert_called_once()
|
|
|
|
@patch("vbv_lernwelt.sso.role_sync.services.keycloak_admin")
|
|
def test_sync_roles_to_user(self, mock_keycloak_admin):
|
|
mock_keycloak_admin.get_realm_roles_of_user.return_value = (
|
|
self.expected_roles
|
|
) # just use them here as well
|
|
mock_keycloak_admin.delete_realm_roles_of_user.return_value = True
|
|
mock_keycloak_admin.assign_realm_roles.return_value = None
|
|
|
|
sync_roles_for_user(self.user, self.course_roles)
|
|
mock_keycloak_admin.get_realm_roles_of_user.assert_called_once_with(
|
|
user_id="1234"
|
|
)
|
|
mock_keycloak_admin.delete_realm_roles_of_user.assert_called_once_with(
|
|
user_id="1234", roles=self.expected_roles
|
|
)
|
|
mock_keycloak_admin.assign_realm_roles.assert_called_once_with(
|
|
user_id="1234", roles=self.expected_roles
|
|
)
|
|
|
|
@patch("vbv_lernwelt.sso.role_sync.services.keycloak_admin")
|
|
def test_create_user(self, mock_keycloak_admin):
|
|
mock_keycloak_admin.create_user.return_value = "im-an-uuid-1234"
|
|
|
|
user_data = {
|
|
"username": self.user.email,
|
|
"email": self.user.email,
|
|
"enabled": True,
|
|
"firstName": self.user.first_name,
|
|
"lastName": self.user.last_name,
|
|
}
|
|
|
|
create_user(self.user)
|
|
mock_keycloak_admin.create_user.assert_called_once_with(
|
|
user_data, exist_ok=True
|
|
)
|
|
|
|
@patch("vbv_lernwelt.sso.role_sync.services.keycloak_admin")
|
|
def test_ignore_missing_course(self, mock_keycloak_admin):
|
|
mock_keycloak_admin.assign_realm_roles.return_value = None
|
|
|
|
course_roles = [
|
|
("blabla-kurse", "EXPERT"),
|
|
]
|
|
result = add_roles_to_user(self.user, course_roles)
|
|
|
|
self.assertFalse(result)
|
|
mock_keycloak_admin.assign_realm_roles.assert_not_called()
|
|
|
|
|
|
class HelpersTestCase(TestCase):
|
|
def test_remove_accents(self):
|
|
no_accents = _remove_accents("äüöéèà")
|
|
self.assertEqual(no_accents, "auoeea")
|
|
|
|
def test_filter_non_myvbv_roles(self):
|
|
roles = [
|
|
{"name": "myvbv-uberbetriebliche-kurse-expert"},
|
|
{"name": "myvbv-versicherungsvermittler-in-member"},
|
|
{"name": "other-role"},
|
|
]
|
|
filtered_roles = [
|
|
{"name": "myvbv-uberbetriebliche-kurse-expert"},
|
|
{"name": "myvbv-versicherungsvermittler-in-member"},
|
|
]
|
|
result = _filter_non_myvbv_roles(roles)
|
|
self.assertEqual(result, filtered_roles)
|