Files
edx-platform/lms/djangoapps/ccx/tests/test_utils.py
Michael Terry cb1bb7fa64 test: switch default test store to the split store
It's long past time that the default test modulestore was Split,
instead of Old Mongo. This commit switches the default store and
fixes some tests that now fail:
- Tests that didn't expect MFE to be enabled (because we don't
  enable MFE for Old Mongo) - opt out of MFE for those
- Tests that hardcoded old key string formats
- Lots of other random little differences

In many places, I didn't spend much time trying to figure out how to
properly fix the test, and instead just set the modulestore to Old
Mongo.

For those tests that I didn't spend time investigating, I've set
the modulestore to TEST_DATA_MONGO_AMNESTY_MODULESTORE - search for
that string to find further work.
2022-02-04 14:32:50 -05:00

346 lines
16 KiB
Python

"""
test utils
"""
import uuid
from smtplib import SMTPException
from unittest import mock
from ccx_keys.locator import CCXLocator
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from common.djangoapps.student.models import CourseEnrollment, CourseEnrollmentException
from common.djangoapps.student.roles import CourseCcxCoachRole, CourseInstructorRole, CourseStaffRole
from common.djangoapps.student.tests.factories import AdminFactory
from lms.djangoapps.ccx.tests.factories import CcxFactory
from lms.djangoapps.ccx.tests.utils import CcxTestCase
from lms.djangoapps.ccx.utils import add_master_course_staff_to_ccx, ccx_course, remove_master_course_staff_from_ccx
from lms.djangoapps.instructor.access import list_with_level
class TestGetCCXFromCCXLocator(ModuleStoreTestCase):
"""Verify that get_ccx_from_ccx_locator functions properly"""
def setUp(self):
"""Set up a course, coach, ccx and user"""
super().setUp()
self.course = CourseFactory.create()
coach = self.coach = AdminFactory.create()
role = CourseCcxCoachRole(self.course.id)
role.add_users(coach)
def call_fut(self, course_id):
"""call the function under test in this test case"""
from lms.djangoapps.ccx.utils import get_ccx_from_ccx_locator
return get_ccx_from_ccx_locator(course_id)
def test_non_ccx_locator(self):
"""verify that nothing is returned if locator is not a ccx locator
"""
result = self.call_fut(self.course.id)
assert result is None
def test_ccx_locator(self):
"""verify that the ccx is retuned if using a ccx locator
"""
ccx = CcxFactory(course_id=self.course.id, coach=self.coach)
course_key = CCXLocator.from_course_locator(self.course.id, ccx.id)
result = self.call_fut(course_key)
assert result == ccx
class TestStaffOnCCX(CcxTestCase):
"""
Tests for staff on ccx courses.
"""
def setUp(self):
super().setUp()
# Create instructor account
self.client.login(username=self.coach.username, password="test")
# create an instance of modulestore
self.mstore = modulestore()
self.make_coach()
self.ccx = self.make_ccx()
self.ccx_locator = CCXLocator.from_course_locator(self.course.id, self.ccx.id)
def test_add_master_course_staff_to_ccx(self):
"""
Test add staff of master course to ccx course
"""
# adding staff to master course.
staff = self.make_staff()
assert CourseStaffRole(self.course.id).has_user(staff)
# adding instructor to master course.
instructor = self.make_instructor()
assert CourseInstructorRole(self.course.id).has_user(instructor)
add_master_course_staff_to_ccx(self.course, self.ccx_locator, self.ccx.display_name)
# assert that staff and instructors of master course has staff and instructor roles on ccx
list_staff_master_course = list_with_level(self.course.id, 'staff')
list_instructor_master_course = list_with_level(self.course.id, 'instructor')
with ccx_course(self.ccx_locator) as course_ccx:
list_staff_ccx_course = list_with_level(course_ccx.id, 'staff')
assert len(list_staff_master_course) == len(list_staff_ccx_course)
assert list_staff_master_course[0].email == list_staff_ccx_course[0].email
list_instructor_ccx_course = list_with_level(course_ccx.id, 'instructor')
assert len(list_instructor_ccx_course) == len(list_instructor_master_course)
assert list_instructor_ccx_course[0].email == list_instructor_master_course[0].email
def test_add_master_course_staff_to_ccx_with_exception(self):
"""
When exception raise from ``enroll_email`` assert that enrollment skipped for that staff or
instructor.
"""
staff = self.make_staff()
assert CourseStaffRole(self.course.id).has_user(staff)
# adding instructor to master course.
instructor = self.make_instructor()
assert CourseInstructorRole(self.course.id).has_user(instructor)
with mock.patch.object(CourseEnrollment, 'enroll_by_email', side_effect=CourseEnrollmentException()):
add_master_course_staff_to_ccx(self.course, self.ccx_locator, self.ccx.display_name)
assert not CourseEnrollment.objects.filter(course_id=self.ccx_locator, user=staff).exists()
assert not CourseEnrollment.objects.filter(course_id=self.ccx_locator, user=instructor).exists()
with mock.patch.object(CourseEnrollment, 'enroll_by_email', side_effect=SMTPException()):
add_master_course_staff_to_ccx(self.course, self.ccx_locator, self.ccx.display_name)
assert not CourseEnrollment.objects.filter(course_id=self.ccx_locator, user=staff).exists()
assert not CourseEnrollment.objects.filter(course_id=self.ccx_locator, user=instructor).exists()
def test_remove_master_course_staff_from_ccx(self):
"""
Test remove staff of master course to ccx course
"""
staff = self.make_staff()
assert CourseStaffRole(self.course.id).has_user(staff)
# adding instructor to master course.
instructor = self.make_instructor()
assert CourseInstructorRole(self.course.id).has_user(instructor)
add_master_course_staff_to_ccx(self.course, self.ccx_locator, self.ccx.display_name, send_email=False)
list_staff_master_course = list_with_level(self.course.id, 'staff')
list_instructor_master_course = list_with_level(self.course.id, 'instructor')
with ccx_course(self.ccx_locator) as course_ccx:
list_staff_ccx_course = list_with_level(course_ccx.id, 'staff')
assert len(list_staff_master_course) == len(list_staff_ccx_course)
assert list_staff_master_course[0].email == list_staff_ccx_course[0].email
list_instructor_ccx_course = list_with_level(course_ccx.id, 'instructor')
assert len(list_instructor_ccx_course) == len(list_instructor_master_course)
assert list_instructor_ccx_course[0].email == list_instructor_master_course[0].email
# assert that role of staff and instructors of master course removed from ccx.
remove_master_course_staff_from_ccx(
self.course, self.ccx_locator, self.ccx.display_name, send_email=False
)
list_staff_ccx_course = list_with_level(course_ccx.id, 'staff')
assert len(list_staff_master_course) != len(list_staff_ccx_course)
list_instructor_ccx_course = list_with_level(course_ccx.id, 'instructor')
assert len(list_instructor_ccx_course) != len(list_instructor_master_course)
for user in list_staff_master_course:
assert user not in list_staff_ccx_course
for user in list_instructor_master_course:
assert user not in list_instructor_ccx_course
def test_remove_master_course_staff_from_ccx_idempotent(self):
"""
Test remove staff of master course from ccx course
"""
staff = self.make_staff()
assert CourseStaffRole(self.course.id).has_user(staff)
# adding instructor to master course.
instructor = self.make_instructor()
assert CourseInstructorRole(self.course.id).has_user(instructor)
outbox = self.get_outbox()
assert len(outbox) == 0
add_master_course_staff_to_ccx(self.course, self.ccx_locator, self.ccx.display_name, send_email=False)
list_staff_master_course = list_with_level(self.course.id, 'staff')
list_instructor_master_course = list_with_level(self.course.id, 'instructor')
with ccx_course(self.ccx_locator) as course_ccx:
list_staff_ccx_course = list_with_level(course_ccx.id, 'staff')
assert len(list_staff_master_course) == len(list_staff_ccx_course)
assert list_staff_master_course[0].email == list_staff_ccx_course[0].email
list_instructor_ccx_course = list_with_level(course_ccx.id, 'instructor')
assert len(list_instructor_ccx_course) == len(list_instructor_master_course)
assert list_instructor_ccx_course[0].email == list_instructor_master_course[0].email
# assert that role of staff and instructors of master course removed from ccx.
remove_master_course_staff_from_ccx(
self.course, self.ccx_locator, self.ccx.display_name, send_email=True
)
assert len(outbox) == (len(list_staff_master_course) + len(list_instructor_master_course))
list_staff_ccx_course = list_with_level(course_ccx.id, 'staff')
assert len(list_staff_master_course) != len(list_staff_ccx_course)
list_instructor_ccx_course = list_with_level(course_ccx.id, 'instructor')
assert len(list_instructor_ccx_course) != len(list_instructor_master_course)
for user in list_staff_master_course:
assert user not in list_staff_ccx_course
for user in list_instructor_master_course:
assert user not in list_instructor_ccx_course
# Run again
remove_master_course_staff_from_ccx(self.course, self.ccx_locator, self.ccx.display_name)
assert len(outbox) == (len(list_staff_master_course) + len(list_instructor_master_course))
with ccx_course(self.ccx_locator) as course_ccx:
list_staff_ccx_course = list_with_level(course_ccx.id, 'staff')
assert len(list_staff_master_course) != len(list_staff_ccx_course)
list_instructor_ccx_course = list_with_level(course_ccx.id, 'instructor')
assert len(list_instructor_ccx_course) != len(list_instructor_master_course)
for user in list_staff_master_course:
assert user not in list_staff_ccx_course
for user in list_instructor_master_course:
assert user not in list_instructor_ccx_course
def test_add_master_course_staff_to_ccx_display_name(self):
"""
Test add staff of master course to ccx course.
Specific test to check that a passed display name is in the
subject of the email sent to the enrolled users.
"""
staff = self.make_staff()
assert CourseStaffRole(self.course.id).has_user(staff)
# adding instructor to master course.
instructor = self.make_instructor()
assert CourseInstructorRole(self.course.id).has_user(instructor)
outbox = self.get_outbox()
# create a unique display name
display_name = f'custom_display_{uuid.uuid4()}'
list_staff_master_course = list_with_level(self.course.id, 'staff')
list_instructor_master_course = list_with_level(self.course.id, 'instructor')
assert len(outbox) == 0
# give access to the course staff/instructor
add_master_course_staff_to_ccx(self.course, self.ccx_locator, display_name)
assert len(outbox) == (len(list_staff_master_course) + len(list_instructor_master_course))
for email in outbox:
assert display_name in email.subject
def test_remove_master_course_staff_from_ccx_display_name(self):
"""
Test remove role of staff of master course on ccx course.
Specific test to check that a passed display name is in the
subject of the email sent to the unenrolled users.
"""
staff = self.make_staff()
assert CourseStaffRole(self.course.id).has_user(staff)
# adding instructor to master course.
instructor = self.make_instructor()
assert CourseInstructorRole(self.course.id).has_user(instructor)
outbox = self.get_outbox()
add_master_course_staff_to_ccx(self.course, self.ccx_locator, self.ccx.display_name, send_email=False)
# create a unique display name
display_name = f'custom_display_{uuid.uuid4()}'
list_staff_master_course = list_with_level(self.course.id, 'staff')
list_instructor_master_course = list_with_level(self.course.id, 'instructor')
assert len(outbox) == 0
# give access to the course staff/instructor
remove_master_course_staff_from_ccx(self.course, self.ccx_locator, display_name)
assert len(outbox) == (len(list_staff_master_course) + len(list_instructor_master_course))
for email in outbox:
assert display_name in email.subject
def test_add_master_course_staff_to_ccx_idempotent(self):
"""
Test add staff of master course to ccx course multiple time will
not result in multiple enrollments.
"""
staff = self.make_staff()
assert CourseStaffRole(self.course.id).has_user(staff)
# adding instructor to master course.
instructor = self.make_instructor()
assert CourseInstructorRole(self.course.id).has_user(instructor)
outbox = self.get_outbox()
list_staff_master_course = list_with_level(self.course.id, 'staff')
list_instructor_master_course = list_with_level(self.course.id, 'instructor')
assert len(outbox) == 0
# run the assignment the first time
add_master_course_staff_to_ccx(self.course, self.ccx_locator, self.ccx.display_name)
assert len(outbox) == (len(list_staff_master_course) + len(list_instructor_master_course))
with ccx_course(self.ccx_locator) as course_ccx:
list_staff_ccx_course = list_with_level(course_ccx.id, 'staff')
list_instructor_ccx_course = list_with_level(course_ccx.id, 'instructor')
assert len(list_staff_master_course) == len(list_staff_ccx_course)
for user in list_staff_master_course:
assert user in list_staff_ccx_course
assert len(list_instructor_master_course) == len(list_instructor_ccx_course)
for user in list_instructor_master_course:
assert user in list_instructor_ccx_course
# run the assignment again
add_master_course_staff_to_ccx(self.course, self.ccx_locator, self.ccx.display_name)
# there are no new duplicated email
assert len(outbox) == (len(list_staff_master_course) + len(list_instructor_master_course))
# there are no duplicated staffs
with ccx_course(self.ccx_locator) as course_ccx:
list_staff_ccx_course = list_with_level(course_ccx.id, 'staff')
list_instructor_ccx_course = list_with_level(course_ccx.id, 'instructor')
assert len(list_staff_master_course) == len(list_staff_ccx_course)
for user in list_staff_master_course:
assert user in list_staff_ccx_course
assert len(list_instructor_master_course) == len(list_instructor_ccx_course)
for user in list_instructor_master_course:
assert user in list_instructor_ccx_course
def test_add_master_course_staff_to_ccx_no_email(self):
"""
Test add staff of master course to ccx course without
sending enrollment email.
"""
staff = self.make_staff()
assert CourseStaffRole(self.course.id).has_user(staff)
# adding instructor to master course.
instructor = self.make_instructor()
assert CourseInstructorRole(self.course.id).has_user(instructor)
outbox = self.get_outbox()
assert len(outbox) == 0
add_master_course_staff_to_ccx(self.course, self.ccx_locator, self.ccx.display_name, send_email=False)
assert len(outbox) == 0
def test_remove_master_course_staff_from_ccx_no_email(self):
"""
Test remove role of staff of master course on ccx course without
sending enrollment email.
"""
staff = self.make_staff()
assert CourseStaffRole(self.course.id).has_user(staff)
# adding instructor to master course.
instructor = self.make_instructor()
assert CourseInstructorRole(self.course.id).has_user(instructor)
outbox = self.get_outbox()
assert len(outbox) == 0
remove_master_course_staff_from_ccx(self.course, self.ccx_locator, self.ccx.display_name, send_email=False)
assert len(outbox) == 0