Files
edx-platform/common/djangoapps/course_modes/tests/test_signals.py
2021-03-18 12:23:52 +05:00

122 lines
4.9 KiB
Python

"""
Unit tests for the course_mode signals
"""
from datetime import datetime, timedelta
from unittest.mock import patch
import ddt
from django.conf import settings
from pytz import UTC
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.course_modes.signals import _listen_for_course_publish
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.partitions.partitions import ENROLLMENT_TRACK_PARTITION_ID
@ddt.ddt
class CourseModeSignalTest(ModuleStoreTestCase):
"""
Tests for the course_mode course_published signal.
"""
def setUp(self):
super().setUp()
self.end = datetime.now(tz=UTC).replace(microsecond=0) + timedelta(days=7)
self.course = CourseFactory.create(end=self.end)
CourseMode.objects.all().delete()
def create_mode(
self,
mode_slug,
mode_name,
min_price=0,
suggested_prices='',
currency='usd',
expiration_datetime=None,
):
"""
Create a new course mode
"""
return CourseMode.objects.get_or_create(
course_id=self.course.id,
mode_display_name=mode_name,
mode_slug=mode_slug,
min_price=min_price,
suggested_prices=suggested_prices,
currency=currency,
_expiration_datetime=expiration_datetime,
)
def test_no_verified_mode(self):
""" Verify expiration not updated by signal for non-verified mode. """
course_mode, __ = self.create_mode('honor', 'honor')
_listen_for_course_publish('store', self.course.id)
course_mode.refresh_from_db()
assert course_mode.expiration_datetime is None
@ddt.data(1, 14, 30)
def test_verified_mode(self, verification_window):
""" Verify signal updates expiration to configured time period before course end for verified mode. """
course_mode, __ = self.create_mode('verified', 'verified', 10)
assert course_mode.expiration_datetime is None
with patch('common.djangoapps.course_modes.models.CourseModeExpirationConfig.current') as config:
instance = config.return_value
instance.verification_window = timedelta(days=verification_window)
_listen_for_course_publish('store', self.course.id)
course_mode.refresh_from_db()
assert course_mode.expiration_datetime == (self.end - timedelta(days=verification_window))
@ddt.data(1, 14, 30)
def test_verified_mode_explicitly_set(self, verification_window):
""" Verify signal does not update expiration for verified mode with explicitly set expiration. """
course_mode, __ = self.create_mode('verified', 'verified', 10)
course_mode.expiration_datetime_is_explicit = True
assert course_mode.expiration_datetime is None
with patch('common.djangoapps.course_modes.models.CourseModeExpirationConfig.current') as config:
instance = config.return_value
instance.verification_window = timedelta(days=verification_window)
_listen_for_course_publish('store', self.course.id)
course_mode.refresh_from_db()
assert course_mode.expiration_datetime == (self.end - timedelta(days=verification_window))
def test_masters_mode(self):
# create an xblock with verified group access
AUDIT_ID = settings.COURSE_ENROLLMENT_MODES['audit']['id']
VERIFIED_ID = settings.COURSE_ENROLLMENT_MODES['verified']['id']
MASTERS_ID = settings.COURSE_ENROLLMENT_MODES['masters']['id']
verified_section = ItemFactory.create(
category="sequential",
metadata={'group_access': {ENROLLMENT_TRACK_PARTITION_ID: [VERIFIED_ID]}}
)
# and a section with no restriction
section2 = ItemFactory.create(
category="sequential",
)
section3 = ItemFactory.create(
category='sequential',
metadata={'group_access': {ENROLLMENT_TRACK_PARTITION_ID: [AUDIT_ID]}}
)
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
# create the master's mode. signal will add masters to the verified section
self.create_mode('masters', 'masters')
verified_section_ret = self.store.get_item(verified_section.location)
section2_ret = self.store.get_item(section2.location)
section3_ret = self.store.get_item(section3.location)
# the verified section will now also be visible to master's
assert verified_section_ret.group_access[ENROLLMENT_TRACK_PARTITION_ID] == [VERIFIED_ID, MASTERS_ID]
assert section2_ret.group_access == {}
assert section3_ret.group_access == {ENROLLMENT_TRACK_PARTITION_ID: [AUDIT_ID]}