-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: handle instructor permission events
- Loading branch information
1 parent
980719c
commit 096ba43
Showing
3 changed files
with
221 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
""" | ||
Test event handlers | ||
""" | ||
import uuid | ||
from datetime import datetime, timezone | ||
|
||
import ddt | ||
from django.test import TestCase | ||
from openedx_events.data import EventsMetadata | ||
from openedx_events.learning.data import CourseAccessRoleData, UserData, UserPersonalData | ||
from openedx_events.learning.signals import COURSE_ACCESS_ROLE_ADDED, COURSE_ACCESS_ROLE_REMOVED | ||
|
||
from edx_exams.apps.core.models import CourseStaffRole, User | ||
from edx_exams.apps.core.signals.handlers import ( | ||
listen_for_course_access_role_added, | ||
listen_for_course_access_role_removed | ||
) | ||
from edx_exams.apps.core.test_utils.factories import CourseStaffRoleFactory, UserFactory | ||
|
||
|
||
@ddt.ddt | ||
class TestCourseRoleEvents(TestCase): | ||
""" | ||
Test course role events | ||
""" | ||
def setUp(self): | ||
super().setUp() | ||
self.course_id = 'course-v1:edx+test+2020' | ||
self.existing_user = UserFactory( | ||
username='test_user_exists', email='[email protected]' | ||
) | ||
self.existing_user_with_staff_role = UserFactory( | ||
username='test_user_staff', email='[email protected]' | ||
) | ||
self.existing_user_with_instructor_role = UserFactory( | ||
username='test_user_instructor', email='[email protected]' | ||
) | ||
|
||
CourseStaffRoleFactory( | ||
user=self.existing_user_with_staff_role, | ||
course_id=self.course_id, | ||
role='staff', | ||
) | ||
CourseStaffRoleFactory( | ||
user=self.existing_user_with_instructor_role, | ||
course_id=self.course_id, | ||
role='instructor', | ||
) | ||
|
||
@staticmethod | ||
def _get_event_data(course_id, username, role): | ||
""" create event data object """ | ||
return CourseAccessRoleData( | ||
org_key='edx', | ||
course_key=course_id, | ||
role=role, | ||
user=UserData( | ||
pii=UserPersonalData( | ||
username=username, | ||
email=f'{username}@example.com', | ||
), | ||
id=123, | ||
is_active=True, | ||
), | ||
) | ||
|
||
@staticmethod | ||
def _get_event_metadata(event_signal): | ||
""" create metadata object for event """ | ||
return EventsMetadata( | ||
event_type=event_signal.event_type, | ||
id=uuid.uuid4(), | ||
minorversion=0, | ||
source='openedx/lms/web', | ||
sourcehost='lms.test', | ||
time=datetime.now(timezone.utc), | ||
) | ||
|
||
@ddt.data( | ||
('test_user_1', 'staff', True), | ||
('test_user_2', 'limited_staff', True), | ||
('test_user_3', 'instructor', True), | ||
('test_user_exists', 'staff', True), | ||
('test_user_exists', 'other', False), | ||
('test_user_staff', 'staff', True), # test duplicate event | ||
('test_user_staff', 'instructor', True), # test multiple roles | ||
) | ||
@ddt.unpack | ||
def test_course_access_role_added(self, username, role, expect_staff_access): | ||
""" | ||
Test CourseStaffRole is created on receiving COURSE_ACCESS_ROLE_ADDED event | ||
with a role that grants staff access to exams | ||
""" | ||
role_event_data = self._get_event_data(self.course_id, username, role) | ||
event_metadata = self._get_event_metadata(COURSE_ACCESS_ROLE_ADDED) | ||
event_kwargs = { | ||
'course_access_role_data': role_event_data, | ||
'metadata': event_metadata, | ||
} | ||
listen_for_course_access_role_added(None, COURSE_ACCESS_ROLE_ADDED, **event_kwargs) | ||
|
||
user = User.objects.get(username=username) | ||
self.assertEqual(user.has_course_staff_permission(self.course_id), expect_staff_access) | ||
|
||
@ddt.data( | ||
('test_user_staff', 'staff', False), | ||
('test_user_instructor', 'instructor', False), | ||
('test_user_staff', 'limited_staff', True), | ||
('test_user_staff', 'other', True), | ||
('test_user_dne', 'other', False), | ||
) | ||
@ddt.unpack | ||
def test_course_access_role_removed(self, username, role, expect_staff_access): | ||
""" | ||
Test CourseStaffRole is deleted on receiving COURSE_ACCESS_ROLE_REMOVED event | ||
""" | ||
role_event_data = self._get_event_data(self.course_id, username, role) | ||
event_metadata = self._get_event_metadata(COURSE_ACCESS_ROLE_REMOVED) | ||
event_kwargs = { | ||
'course_access_role_data': role_event_data, | ||
'metadata': event_metadata, | ||
} | ||
listen_for_course_access_role_removed(None, COURSE_ACCESS_ROLE_REMOVED, **event_kwargs) | ||
|
||
if username == 'test_user_dne': | ||
# this user should not be created (and therefore has no permissions) | ||
self.assertFalse(User.objects.filter(username=username).exists()) | ||
else: | ||
user = User.objects.get(username=username) | ||
self.assertEqual(user.has_course_staff_permission(self.course_id), expect_staff_access) | ||
|
||
def test_course_access_role_remove_single_role(self): | ||
""" | ||
Test correct role is removed for user with multiple roles | ||
""" | ||
CourseStaffRoleFactory( | ||
user=self.existing_user_with_staff_role, | ||
course_id=self.course_id, | ||
role='instructor', | ||
) | ||
|
||
role_event_data = self._get_event_data(self.course_id, 'test_user_staff', 'staff') | ||
event_metadata = self._get_event_metadata(COURSE_ACCESS_ROLE_REMOVED) | ||
event_kwargs = { | ||
'course_access_role_data': role_event_data, | ||
'metadata': event_metadata, | ||
} | ||
listen_for_course_access_role_removed(None, COURSE_ACCESS_ROLE_REMOVED, **event_kwargs) | ||
|
||
roles = [ | ||
staff_role.role for staff_role in | ||
CourseStaffRole.objects.filter(user=self.existing_user_with_staff_role) | ||
] | ||
self.assertEqual( | ||
roles, | ||
['instructor'] | ||
) |