def test_verified_mode_for_course(self): self.create_mode('verified', 'Verified Certificate', 10) mode = CourseMode.verified_mode_for_course(self.course_key) assert mode.slug == 'verified' # verify that the professional mode is preferred self.create_mode('professional', 'Professional Education Verified Certificate', 10) mode = CourseMode.verified_mode_for_course(self.course_key) assert mode.slug == 'professional'
def test_remove_upgrade_deadline(self): """ Verify that course mode upgrade deadlines can be removed through the API. """ # First create a deadline upgrade_deadline = datetime.now(pytz.utc) + timedelta(days=1) response, __ = self._get_update_response_and_expected_data(upgrade_deadline, None) self.assertEqual(response.status_code, 200) verified_mode = CourseMode.verified_mode_for_course(self.course.id) self.assertIsNotNone(verified_mode) self.assertEqual(verified_mode.expiration_datetime.date(), upgrade_deadline.date()) # Now set the deadline to None response, __ = self._get_update_response_and_expected_data(None, None) self.assertEqual(response.status_code, 200) updated_verified_mode = CourseMode.verified_mode_for_course(self.course.id) self.assertIsNotNone(updated_verified_mode) self.assertIsNone(updated_verified_mode.expiration_datetime)
def upgrade_url(self, user, course_key): """ Returns the URL for the user to upgrade, or None if not applicable. """ verified_mode = CourseMode.verified_mode_for_course(course_key) if verified_mode: if self.is_enabled(user): return self.get_checkout_page_url(verified_mode.sku) else: return reverse('dashboard') return None
def get_group_for_user(cls, course_key, user, user_partition, **kwargs): # pylint: disable=unused-argument """ Returns the Group from the specified user partition to which the user is assigned, via enrollment mode. If a user is in a Credit mode, the Verified or Professional mode for the course is returned instead. If a course is using the Verified Track Cohorting pilot feature, this method returns None regardless of the user's enrollment mode. """ if is_course_using_cohort_instead(course_key): return None # First, check if we have to deal with masquerading. # If the current user is masquerading as a specific student, use the # same logic as normal to return that student's group. If the current # user is masquerading as a generic student in a specific group, then # return that group. if get_course_masquerade( user, course_key) and not is_masquerading_as_specific_student( user, course_key): return get_masquerading_user_group(course_key, user, user_partition) mode_slug, is_active = CourseEnrollment.enrollment_mode_for_user( user, course_key) if mode_slug and is_active: course_mode = CourseMode.mode_for_course( course_key, mode_slug, modes=CourseMode.modes_for_course(course_key, include_expired=True, only_selectable=False), ) if course_mode and CourseMode.is_credit_mode(course_mode): # We want the verified track even if the upgrade deadline has passed, since we # are determining what content to show the user, not whether the user can enroll # in the verified track. course_mode = CourseMode.verified_mode_for_course( course_key, include_expired=True) if not course_mode: course_mode = CourseMode.DEFAULT_MODE return Group(ENROLLMENT_GROUP_IDS[course_mode.slug]["id"], str(course_mode.name)) else: return None
def serialize_upgrade_info(user, course_overview, enrollment): """ Return verified mode upgrade information, or None. This is used in a few API views to provide consistent upgrade info to frontends. """ if not can_show_verified_upgrade(user, enrollment): return None mode = CourseMode.verified_mode_for_course(course=course_overview) return { 'access_expiration_date': get_user_course_expiration_date(user, course_overview), 'currency': mode.currency.upper(), 'currency_symbol': get_currency_symbol(mode.currency.upper()), 'price': mode.min_price, 'sku': mode.sku, 'upgrade_url': verified_upgrade_deadline_link(user, course_overview), }
def _calculate_upgrade_deadline(course_id, content_availability_date): # lint-amnesty, pylint: disable=missing-function-docstring upgrade_deadline = None delta = _get_upgrade_deadline_delta_setting(course_id) if delta is not None: upgrade_deadline = content_availability_date + datetime.timedelta(days=delta) if upgrade_deadline is not None: # The content availability-based deadline should never occur # after the verified mode's expiration date, if one is set. try: verified_mode = CourseMode.verified_mode_for_course(course_id) except CourseMode.DoesNotExist: pass else: if verified_mode: course_mode_upgrade_deadline = verified_mode.expiration_datetime if course_mode_upgrade_deadline is not None: upgrade_deadline = min(upgrade_deadline, course_mode_upgrade_deadline) return upgrade_deadline
def get_user_course_duration(user, course): """ Return a timedelta measuring the duration of the course for a particular user. Business Logic: - 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: return None verified_mode = CourseMode.verified_mode_for_course(course=course, include_expired=True) if not verified_mode: return None return get_expected_duration(course.id)
def get_discount_expiration_date(user, course): """ Returns the date when the discount expires for the user. Returns none if the user is not enrolled. """ # anonymous users should never get the discount if user.is_anonymous: return None course_enrollment = CourseEnrollment.objects.filter( user=user, course=course.id, mode__in=CourseMode.UPSELL_TO_VERIFIED_MODES) if len(course_enrollment) != 1: return None time_limit_start = None try: saw_banner = ExperimentData.objects.get( user=user, experiment_id=REV1008_EXPERIMENT_ID, key=str(course.id)) time_limit_start = parse_datetime(saw_banner.value) except ExperimentData.DoesNotExist: return None discount_expiration_date = time_limit_start + timedelta(weeks=1) # If the course has an upgrade deadline and discount time limit would put the discount expiration date # after the deadline, then change the expiration date to be the upgrade deadline verified_mode = CourseMode.verified_mode_for_course(course=course, include_expired=True) if not verified_mode: return None upgrade_deadline = verified_mode.expiration_datetime if upgrade_deadline and discount_expiration_date > upgrade_deadline: discount_expiration_date = upgrade_deadline return discount_expiration_date
def verified_mode(self): """ 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) 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), }