On publish, add evenly spaced dates to self-paced courses
This commit is contained in:
@@ -21,13 +21,12 @@ from lms.djangoapps.courseware.utils import verified_upgrade_deadline_link
|
||||
from lms.djangoapps.courseware.masquerade import get_course_masquerade, is_masquerading_as_specific_student
|
||||
from openedx.core.djangoapps.catalog.utils import get_course_run_details
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.djangoapps.course_date_signals.utils import get_expected_duration
|
||||
from openedx.core.djangolib.markup import HTML
|
||||
from openedx.features.course_duration_limits.models import CourseDurationLimitConfig
|
||||
from student.models import CourseEnrollment
|
||||
from util.date_utils import strftime_localized
|
||||
|
||||
MIN_DURATION = timedelta(weeks=4)
|
||||
MAX_DURATION = timedelta(weeks=18)
|
||||
EXPIRATION_DATE_FORMAT_STR = u'%b %-d, %Y'
|
||||
|
||||
|
||||
@@ -64,28 +63,11 @@ def get_user_course_duration(user, course):
|
||||
- If course fields are missing, default course access duration to MIN_DURATION.
|
||||
"""
|
||||
|
||||
access_duration = MIN_DURATION
|
||||
|
||||
verified_mode = CourseMode.verified_mode_for_course(course=course, include_expired=True)
|
||||
|
||||
if not verified_mode:
|
||||
return None
|
||||
|
||||
enrollment = CourseEnrollment.get_enrollment(user, course.id)
|
||||
if enrollment is None or enrollment.mode != CourseMode.AUDIT:
|
||||
return None
|
||||
|
||||
# The user course expiration date is the content availability date
|
||||
# plus the weeks_to_complete field from course-discovery.
|
||||
discovery_course_details = get_course_run_details(course.id, ['weeks_to_complete'])
|
||||
expected_weeks = discovery_course_details.get('weeks_to_complete')
|
||||
if expected_weeks:
|
||||
access_duration = timedelta(weeks=expected_weeks)
|
||||
|
||||
# Course access duration is bounded by the min and max duration.
|
||||
access_duration = max(MIN_DURATION, min(MAX_DURATION, access_duration))
|
||||
|
||||
return access_duration
|
||||
return get_expected_duration(course)
|
||||
|
||||
|
||||
def get_user_course_expiration_date(user, course):
|
||||
|
||||
@@ -25,6 +25,7 @@ from lms.djangoapps.courseware.tests.factories import (
|
||||
)
|
||||
from lms.djangoapps.discussion.django_comment_client.tests.factories import RoleFactory
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.djangoapps.course_date_signals.utils import MAX_DURATION, MIN_DURATION
|
||||
from openedx.core.djangoapps.django_comment_common.models import (
|
||||
FORUM_ROLE_ADMINISTRATOR,
|
||||
FORUM_ROLE_COMMUNITY_TA,
|
||||
@@ -33,7 +34,7 @@ from openedx.core.djangoapps.django_comment_common.models import (
|
||||
)
|
||||
from openedx.core.djangoapps.schedules.tests.factories import ScheduleFactory
|
||||
from openedx.features.content_type_gating.helpers import CONTENT_GATING_PARTITION_ID, CONTENT_TYPE_GATE_GROUP_IDS
|
||||
from openedx.features.course_duration_limits.access import MAX_DURATION, MIN_DURATION, get_user_course_expiration_date
|
||||
from openedx.features.course_duration_limits.access import get_user_course_expiration_date
|
||||
from openedx.features.course_duration_limits.models import CourseDurationLimitConfig
|
||||
from openedx.features.course_experience.tests.views.helpers import add_course_mode
|
||||
from student.models import CourseEnrollment, FBEEnrollmentExclusion
|
||||
@@ -68,7 +69,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase):
|
||||
result = get_user_course_expiration_date(self.user, CourseOverview.get_from_id(self.course.id))
|
||||
self.assertEqual(result, None)
|
||||
|
||||
@mock.patch("openedx.features.course_duration_limits.access.get_course_run_details")
|
||||
@mock.patch("openedx.core.djangoapps.course_date_signals.utils.get_course_run_details")
|
||||
@ddt.data(
|
||||
[int(MIN_DURATION.days / 7) - 1, MIN_DURATION, False],
|
||||
[7, timedelta(weeks=7), False],
|
||||
@@ -102,7 +103,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase):
|
||||
)
|
||||
self.assertEqual(result, enrollment.created + access_duration)
|
||||
|
||||
@mock.patch("openedx.features.course_duration_limits.access.get_course_run_details")
|
||||
@mock.patch("openedx.core.djangoapps.course_date_signals.utils.get_course_run_details")
|
||||
def test_content_availability_date(self, mock_get_course_run_details):
|
||||
"""
|
||||
Content availability date is course start date or enrollment date, whichever is later.
|
||||
@@ -146,7 +147,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase):
|
||||
content_availability_date = start_date.replace(microsecond=0)
|
||||
self.assertEqual(result, content_availability_date + access_duration)
|
||||
|
||||
@mock.patch("openedx.features.course_duration_limits.access.get_course_run_details")
|
||||
@mock.patch("openedx.core.djangoapps.course_date_signals.utils.get_course_run_details")
|
||||
def test_expired_upgrade_deadline(self, mock_get_course_run_details):
|
||||
"""
|
||||
The expiration date still exists if the upgrade deadline has passed
|
||||
@@ -165,7 +166,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase):
|
||||
content_availability_date = enrollment.created
|
||||
self.assertEqual(result, content_availability_date + access_duration)
|
||||
|
||||
@mock.patch("openedx.features.course_duration_limits.access.get_course_run_details")
|
||||
@mock.patch("openedx.core.djangoapps.course_date_signals.utils.get_course_run_details")
|
||||
@ddt.data(
|
||||
({'user_partition_id': CONTENT_GATING_PARTITION_ID,
|
||||
'group_id': CONTENT_TYPE_GATE_GROUP_IDS['limited_access']}, True),
|
||||
@@ -245,7 +246,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
return response
|
||||
|
||||
@mock.patch("openedx.features.course_duration_limits.access.get_course_run_details")
|
||||
@mock.patch("openedx.core.djangoapps.course_date_signals.utils.get_course_run_details")
|
||||
def test_masquerade_in_holdback(self, mock_get_course_run_details):
|
||||
mock_get_course_run_details.return_value = {'weeks_to_complete': 12}
|
||||
audit_student = UserFactory(username='audit')
|
||||
@@ -279,7 +280,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase):
|
||||
banner_text = 'You lose all access to this course, including your progress,'
|
||||
self.assertNotContains(response, banner_text)
|
||||
|
||||
@mock.patch("openedx.features.course_duration_limits.access.get_course_run_details")
|
||||
@mock.patch("openedx.core.djangoapps.course_date_signals.utils.get_course_run_details")
|
||||
def test_masquerade_expired(self, mock_get_course_run_details):
|
||||
mock_get_course_run_details.return_value = {'weeks_to_complete': 1}
|
||||
|
||||
@@ -315,7 +316,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase):
|
||||
banner_text = 'This learner does not have access to this course. Their access expired on'
|
||||
self.assertContains(response, banner_text)
|
||||
|
||||
@mock.patch("openedx.features.course_duration_limits.access.get_course_run_details")
|
||||
@mock.patch("openedx.core.djangoapps.course_date_signals.utils.get_course_run_details")
|
||||
@ddt.data(
|
||||
InstructorFactory,
|
||||
StaffFactory,
|
||||
@@ -366,7 +367,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase):
|
||||
banner_text = 'This learner does not have access to this course. Their access expired on'
|
||||
self.assertNotContains(response, banner_text)
|
||||
|
||||
@mock.patch("openedx.features.course_duration_limits.access.get_course_run_details")
|
||||
@mock.patch("openedx.core.djangoapps.course_date_signals.utils.get_course_run_details")
|
||||
@ddt.data(
|
||||
FORUM_ROLE_COMMUNITY_TA,
|
||||
FORUM_ROLE_GROUP_MODERATOR,
|
||||
|
||||
Reference in New Issue
Block a user