diff --git a/lms/djangoapps/courseware/date_summary.py b/lms/djangoapps/courseware/date_summary.py index 3479dd45b0c999b618c1be643d4bb6e8d11c2527..7ec0c406bdddce75c14797fdc61fbaa45f9c3445 100644 --- a/lms/djangoapps/courseware/date_summary.py +++ b/lms/djangoapps/courseware/date_summary.py @@ -28,7 +28,6 @@ from openedx.core.djangoapps.catalog.utils import get_course_run_details from openedx.core.djangoapps.certificates.api import can_show_certificate_available_date_field from openedx.core.djangolib.markup import HTML, Text 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 import RELATIVE_DATES_FLAG, UPGRADE_DEADLINE_MESSAGE, CourseHomeMessages from student.models import CourseEnrollment @@ -444,8 +443,6 @@ class CourseExpiredDate(DateSummary): @property def date(self): - if not CourseDurationLimitConfig.enabled_for_enrollment(self.user, self.course): - return return get_user_course_expiration_date(self.user, self.course) @property diff --git a/lms/djangoapps/experiments/utils.py b/lms/djangoapps/experiments/utils.py index 3d954da94ef2c23e190dd808679d6ce4dfe8f320..4d4ea98bbfdfd8117aa94b42a3058eb95f303206 100644 --- a/lms/djangoapps/experiments/utils.py +++ b/lms/djangoapps/experiments/utils.py @@ -21,7 +21,6 @@ from openedx.core.djangoapps.django_comment_common.models import Role from openedx.core.djangoapps.schedules.models import Schedule from openedx.core.djangoapps.waffle_utils import WaffleFlag, WaffleFlagNamespace from openedx.features.course_duration_limits.access import get_user_course_expiration_date, get_user_course_duration -from openedx.features.course_duration_limits.models import CourseDurationLimitConfig from student.models import CourseEnrollment from xmodule.partitions.partitions_service import get_all_partitions_for_course, get_user_partition_groups @@ -333,7 +332,8 @@ def get_base_experiment_metadata_context(course, user, enrollment, user_enrollme user, enrollment, course ) - deadline, duration = get_audit_access_expiration(user, course) + duration = get_user_course_duration(user, course) + deadline = duration and get_user_course_expiration_date(user, course) return { 'upgrade_link': upgrade_link, @@ -355,16 +355,6 @@ def get_base_experiment_metadata_context(course, user, enrollment, user_enrollme } -def get_audit_access_expiration(user, course): - """ - Return the expiration date and course duration for the user's audit access to this course. - """ - if not CourseDurationLimitConfig.enabled_for_enrollment(user, course): - return None, None - - return get_user_course_expiration_date(user, course), get_user_course_duration(user, course) - - # TODO: clean up as part of REVEM-199 (START) def get_program_context(course, user_enrollments): """ diff --git a/lms/djangoapps/mobile_api/users/serializers.py b/lms/djangoapps/mobile_api/users/serializers.py index f64fc52fc4f9b72df27dcd6bcce8da0279648cef..94a152b6da5fa71ebd02fdfc38d899d2f7c0abf3 100644 --- a/lms/djangoapps/mobile_api/users/serializers.py +++ b/lms/djangoapps/mobile_api/users/serializers.py @@ -10,7 +10,6 @@ from rest_framework.reverse import reverse from lms.djangoapps.courseware.access import has_access from lms.djangoapps.certificates.api import certificate_downloadable_status from openedx.features.course_duration_limits.access import get_user_course_expiration_date -from openedx.features.course_duration_limits.models import CourseDurationLimitConfig from student.models import CourseEnrollment, User from util.course import get_encoded_course_sharing_utm_params, get_link_for_about_page @@ -96,9 +95,6 @@ class CourseEnrollmentSerializer(serializers.ModelSerializer): """ Returns expiration date for a course audit expiration, if any or null """ - if not CourseDurationLimitConfig.enabled_for_enrollment(model.user, model.course): - return None - return get_user_course_expiration_date(model.user, model.course) def get_certificate(self, model): diff --git a/openedx/core/djangoapps/certificates/api.py b/openedx/core/djangoapps/certificates/api.py index 3da7de7312500fef0e2e6dc8447240569dcb9385..0ae6dec631387a559a117e1fc83bd5a1de5c0bba 100644 --- a/openedx/core/djangoapps/certificates/api.py +++ b/openedx/core/djangoapps/certificates/api.py @@ -65,33 +65,12 @@ def can_show_certificate_message(course, student, course_grade, certificates_ena has_active_enrollment = CourseEnrollment.is_enrolled(student, course.id) certificates_are_viewable = certificates_viewable_for_course(course) - # Adding a temporary logging for EDUCATOR-2017. - if six.text_type(course.id) == u'course-v1:RITx+PM9004x+3T2017': - log.info( - ( - u'can_show_certificate_message called with:' - u'course:%s, student: %s, course grade: %s,' - u'certificates_enabled_for_course: %s, certificates_viewable_for_course: %s, auto_cert_gen_enabled: %s,' - u'has_active_enrollment: %s, passed: %s, is_whitelisted: %s' - ), - course.id, - student.username, - course_grade, - certificates_enabled_for_course, - certificates_are_viewable, - auto_cert_gen_enabled, - has_active_enrollment, - course_grade.passed, - is_whitelisted - ) - if not ( + return ( (auto_cert_gen_enabled or certificates_enabled_for_course) and has_active_enrollment and certificates_are_viewable and (course_grade.passed or is_whitelisted) - ): - return False - return True + ) def can_show_certificate_available_date_field(course): diff --git a/openedx/core/djangoapps/courseware_api/views.py b/openedx/core/djangoapps/courseware_api/views.py index 3c8f9f4b85a58df7fb598a72534bf41a0c7aa1fc..adc479db6361cf179b2b0a77832d16b9bf2790f4 100644 --- a/openedx/core/djangoapps/courseware_api/views.py +++ b/openedx/core/djangoapps/courseware_api/views.py @@ -41,7 +41,9 @@ from lms.djangoapps.verify_student.services import IDVerificationService from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin from openedx.features.course_experience import DISPLAY_COURSE_SOCK_FLAG from openedx.features.content_type_gating.models import ContentTypeGatingConfig -from openedx.features.course_duration_limits.access import generate_course_expired_message +from openedx.features.course_duration_limits.access import ( + get_user_course_expiration_date, generate_course_expired_message +) from openedx.features.discounts.utils import generate_offer_html from student.models import CourseEnrollment, CourseEnrollmentCelebration, LinkedInAddToProfileConfiguration from xmodule.modulestore.django import modulestore @@ -135,8 +137,7 @@ class CoursewareMeta: @property def can_show_upgrade_sock(self): - return (DISPLAY_COURSE_SOCK_FLAG.is_enabled(self.course_key) and - can_show_verified_upgrade(self.effective_user, self.enrollment_object)) + return DISPLAY_COURSE_SOCK_FLAG.is_enabled(self.course_key) @property def license(self): @@ -181,15 +182,18 @@ class CoursewareMeta: """ Return verified mode information, or None. """ + if not can_show_verified_upgrade(self.effective_user, self.enrollment_object): + return None + mode = CourseMode.verified_mode_for_course(self.course_key) - if mode: - return { - 'price': mode.min_price, - 'currency': mode.currency.upper(), - 'currency_symbol': get_currency_symbol(mode.currency.upper()), - 'sku': mode.sku, - 'upgrade_url': verified_upgrade_deadline_link(self.effective_user, self.overview), - } + return { + 'access_expiration_date': get_user_course_expiration_date(self.effective_user, self.overview), + 'price': mode.min_price, + 'currency': mode.currency.upper(), + 'currency_symbol': get_currency_symbol(mode.currency.upper()), + 'sku': mode.sku, + 'upgrade_url': verified_upgrade_deadline_link(self.effective_user, self.overview), + } @property def notes(self): diff --git a/openedx/features/course_duration_limits/access.py b/openedx/features/course_duration_limits/access.py index cf40ef2de61646d484ce0550f7f8bcdecaf24cf6..1ae26cc381282b6948d3134ac3c4b4b2de52627c 100644 --- a/openedx/features/course_duration_limits/access.py +++ b/openedx/features/course_duration_limits/access.py @@ -62,6 +62,8 @@ def get_user_course_duration(user, course): - Course access duration is bounded by the min and max duration. - If course fields are missing, default course access duration to MIN_DURATION. """ + if not CourseDurationLimitConfig.enabled_for_enrollment(user, course): + return None enrollment = CourseEnrollment.get_enrollment(user, course.id) if enrollment is None or enrollment.mode != CourseMode.AUDIT: @@ -107,9 +109,6 @@ def check_course_expired(user, course): if get_course_masquerade(user, course.id): return ACCESS_GRANTED - if not CourseDurationLimitConfig.enabled_for_enrollment(user, course): - return ACCESS_GRANTED - expiration_date = get_user_course_expiration_date(user, course) if expiration_date and timezone.now() > expiration_date: return AuditExpiredError(user, course, expiration_date) @@ -127,9 +126,6 @@ def generate_course_expired_message(user, course): """ Generate the message for the user course expiration date if it exists. """ - if not CourseDurationLimitConfig.enabled_for_enrollment(user, course): - return - expiration_date = get_user_course_expiration_date(user, course) if not expiration_date: return diff --git a/openedx/features/course_duration_limits/tests/test_course_expiration.py b/openedx/features/course_duration_limits/tests/test_course_expiration.py index 36079976009a4de51de1d77469fcfc3f55261a3f..d05d46f0e574d12b50d9ff23efd862f61d273190 100644 --- a/openedx/features/course_duration_limits/tests/test_course_expiration.py +++ b/openedx/features/course_duration_limits/tests/test_course_expiration.py @@ -43,6 +43,7 @@ from xmodule.modulestore.tests.factories import CourseFactory from xmodule.partitions.partitions import ENROLLMENT_TRACK_PARTITION_ID +# pylint: disable=no-member @ddt.ddt class CourseExpirationTestCase(ModuleStoreTestCase, MasqueradeMixin): """Tests to verify the get_user_course_expiration_date function is working correctly""" @@ -96,6 +97,11 @@ class CourseExpirationTestCase(ModuleStoreTestCase, MasqueradeMixin): self.course.self_paced = True mock_get_course_run_details.return_value = {'weeks_to_complete': weeks_to_complete} enrollment = CourseEnrollment.enroll(self.user, self.course.id, CourseMode.AUDIT) + CourseDurationLimitConfig.objects.create( + enabled=True, + course=CourseOverview.get_from_id(self.course.id), + enabled_as_of=self.course.start, + ) result = get_user_course_expiration_date( self.user, CourseOverview.get_from_id(self.course.id), @@ -114,12 +120,18 @@ class CourseExpirationTestCase(ModuleStoreTestCase, MasqueradeMixin): start_date = now() - timedelta(weeks=10) past_course = CourseFactory(start=start_date) enrollment = CourseEnrollment.enroll(self.user, past_course.id, CourseMode.AUDIT) + CourseDurationLimitConfig.objects.create( + enabled=True, + course=CourseOverview.get_from_id(past_course.id), + enabled_as_of=past_course.start, + ) result = get_user_course_expiration_date( self.user, CourseOverview.get_from_id(past_course.id), ) self.assertEqual(result, None) + add_course_mode(past_course, mode_slug=CourseMode.AUDIT) add_course_mode(past_course, upgrade_deadline_expired=False) result = get_user_course_expiration_date( self.user, @@ -132,12 +144,18 @@ class CourseExpirationTestCase(ModuleStoreTestCase, MasqueradeMixin): start_date = now() + timedelta(weeks=10) future_course = CourseFactory(start=start_date) enrollment = CourseEnrollment.enroll(self.user, future_course.id, CourseMode.AUDIT) + CourseDurationLimitConfig.objects.create( + enabled=True, + course=CourseOverview.get_from_id(future_course.id), + enabled_as_of=past_course.start, + ) result = get_user_course_expiration_date( self.user, CourseOverview.get_from_id(future_course.id), ) self.assertEqual(result, None) + add_course_mode(future_course, mode_slug=CourseMode.AUDIT) add_course_mode(future_course, upgrade_deadline_expired=False) result = get_user_course_expiration_date( self.user, @@ -157,6 +175,12 @@ class CourseExpirationTestCase(ModuleStoreTestCase, MasqueradeMixin): start_date = now() - timedelta(weeks=10) course = CourseFactory(start=start_date) enrollment = CourseEnrollment.enroll(self.user, course.id, CourseMode.AUDIT) + CourseDurationLimitConfig.objects.create( + enabled=True, + course=CourseOverview.get_from_id(course.id), + enabled_as_of=course.start, + ) + add_course_mode(course, mode_slug=CourseMode.AUDIT) add_course_mode(course, upgrade_deadline_expired=True) result = get_user_course_expiration_date( self.user, diff --git a/scripts/thresholds.sh b/scripts/thresholds.sh index 52dac4f8b44f70bde2dc3454842177b36f716a7f..067630543258bd6cedb003763e847c6f0088798a 100755 --- a/scripts/thresholds.sh +++ b/scripts/thresholds.sh @@ -2,6 +2,6 @@ set -e export LOWER_PYLINT_THRESHOLD=1000 -export UPPER_PYLINT_THRESHOLD=2500 -export ESLINT_THRESHOLD=5530 +export UPPER_PYLINT_THRESHOLD=2430 +export ESLINT_THRESHOLD=5300 export STYLELINT_THRESHOLD=880