def test_is_enterprise_learner(self): with mock.patch('django.core.cache.cache.set') as mock_cache_set: EnterpriseCustomerUserFactory.create(active=True, user_id=self.user.id) assert is_enterprise_learner(self.user) assert is_enterprise_learner(self.user.id) assert mock_cache_set.called
def test_is_enterprise_learner_no_enterprise_user(self): with mock.patch( 'django.core.cache.cache.set' ) as mock_cache_set: assert not is_enterprise_learner(self.user) assert not mock_cache_set.called
def can_show_streak_discount_experiment_coupon(user, course): """ Check whether this combination of user and course can receive the AA-759 experiment discount. """ # Course end date needs to be in the future if course.has_ended(): return False # Course needs to have a non-expired verified mode modes_dict = CourseMode.modes_for_course_dict(course=course, include_expired=False) if 'verified' not in modes_dict: return False # Learner needs to be in an upgradeable mode try: enrollment = CourseEnrollment.objects.get( user=user, course=course.id, ) except CourseEnrollment.DoesNotExist: return False if not is_mode_upsellable(user, enrollment): return False # We can't import this at Django load time within the openedx tests settings context from openedx.features.enterprise_support.utils import is_enterprise_learner # Don't give discount to enterprise users if is_enterprise_learner(user): return False return True
def can_receive_discount(user, course, discount_expiration_date=None): """ Check all the business logic about whether this combination of user and course can receive a discount. """ # Always disable discounts until we are ready to enable this feature with impersonate(user): if not DISCOUNT_APPLICABILITY_FLAG.is_enabled(): return False # TODO: Add additional conditions to return False here # anonymous users should never get the discount if user.is_anonymous: return False # Check if discount has expired if not discount_expiration_date: discount_expiration_date = get_discount_expiration_date(user, course) if discount_expiration_date is None: return False if discount_expiration_date < timezone.now(): return False # Course end date needs to be in the future if course.has_ended(): return False # Course needs to have a non-expired verified mode modes_dict = CourseMode.modes_for_course_dict(course=course, include_expired=False) verified_mode = modes_dict.get('verified', None) if not verified_mode: return False # Site, Partner, Course or Course Run not excluded from lms-controlled discounts if DiscountRestrictionConfig.disabled_for_course_stacked_config(course): return False # Don't allow users who have enrolled in any courses in non-upsellable # modes if CourseEnrollment.objects.filter(user=user).exclude(mode__in=CourseMode.UPSELL_TO_VERIFIED_MODES).exists(): return False # Don't allow any users who have entitlements (past or present) if CourseEntitlement.objects.filter(user=user).exists(): return False # We can't import this at Django load time within the openedx tests settings context from openedx.features.enterprise_support.utils import is_enterprise_learner # Don't give discount to enterprise users if is_enterprise_learner(user): return False # Excute holdback if _is_in_holdback(user): return False return True
def is_secondary_email_feature_enabled_for_user(user): """ Checks to see if secondary email feature is enabled for the given user. Returns: Boolean value representing the status of secondary email feature. """ # import is placed here to avoid cyclic import. from openedx.features.enterprise_support.utils import is_enterprise_learner return is_secondary_email_feature_enabled() and is_enterprise_learner(user)
def is_secondary_email_feature_enabled_for_user(user): """ Checks to see if secondary email feature is enabled for the given user. Returns: Boolean value representing the status of secondary email feature. """ # import is placed here to avoid cyclic import. from openedx.features.enterprise_support.utils import is_enterprise_learner return is_secondary_email_feature_enabled() and is_enterprise_learner(user)
def handle_enterprise_learner_passing_grade(sender, user, course_id, **kwargs): # pylint: disable=unused-argument """ Listen for a learner passing a course, transmit data to relevant integrated channel """ if enterprise_enabled() and is_enterprise_learner(user): kwargs = { 'username': six.text_type(user.username), 'course_run_id': six.text_type(course_id) } transmit_single_learner_data.apply_async(kwargs=kwargs)
def show_user_demographics(user, enrollments=None, entitlements=None): """ Check if the user should be shown demographics collection fields. Currently limited to MicroBachlors Programs' learners who aren't part of an enterprise. """ is_user_in_microbachelors_program = is_user_enrolled_in_program_type( user, "microbachelors", enrollments=enrollments, entitlements=entitlements) return is_user_in_microbachelors_program and not is_enterprise_learner( user)
def handle_enterprise_learner_subsection(sender, user, course_id, subsection_id, subsection_grade, **kwargs): # pylint: disable=unused-argument """ Listen for an enterprise learner completing a subsection, transmit data to relevant integrated channel. """ if enterprise_enabled() and is_enterprise_learner(user): kwargs = { 'username': str(user.username), 'course_run_id': str(course_id), 'subsection_id': str(subsection_id), 'grade': str(subsection_grade), } transmit_single_subsection_learner_data.apply_async(kwargs=kwargs)
def get_enterprise_event_context(user_id, course_id): """ Creates an enterprise context from a `course_id` anf `user_id`. Example Returned Context:: { 'enterprise_uuid': '1a0fbcbe-49e5-42f1-8e83-4cddfa592f22' } Arguments: user_id: id of user object. course_id: id of course object. Returns: dict: A dictionary representing the enterprise uuid. """ # Prevent a circular import. from openedx.features.enterprise_support.utils import is_enterprise_learner context = {} if is_enterprise_learner(user_id): uuids = EnterpriseCourseEnrollment.get_enterprise_uuids_with_user_and_course( str(user_id), str(course_id)) if uuids: context.update({"enterprise_uuid": str(uuids[0])}) return context
def test_is_enterprise_learner_no_enterprise_user(self): with mock.patch('django.core.cache.cache.set') as mock_cache_set: self.assertFalse(is_enterprise_learner(self.user)) self.assertFalse(mock_cache_set.called)
def test_is_enterprise_learner_enterprise_disabled(self, _, mock_cache_get, mock_cache_set): assert not is_enterprise_learner(self.user) assert not is_enterprise_learner(self.user.id) assert not mock_cache_get.called assert not mock_cache_set.called
def activate_account(request, key): """ When link in activation e-mail is clicked """ # If request is in Studio call the appropriate view if theming_helpers.get_project_root_name().lower() == 'cms': monitoring_utils.set_custom_attribute('student_activate_account', 'cms') return activate_account_studio(request, key) # TODO: Use custom attribute to determine if there are any `activate_account` calls for cms in Production. # If not, the templates wouldn't be needed for cms, but we still need a way to activate for cms tests. monitoring_utils.set_custom_attribute('student_activate_account', 'lms') activation_message_type = None invalid_message = HTML( _('{html_start}Your account could not be activated{html_end}' 'Something went wrong, please <a href="{support_url}">contact support</a> to resolve this issue.' )).format( support_url=configuration_helpers.get_value( 'ACTIVATION_EMAIL_SUPPORT_LINK', settings.ACTIVATION_EMAIL_SUPPORT_LINK) or settings.SUPPORT_SITE_LINK, html_start=HTML('<p class="message-title">'), html_end=HTML('</p>'), ) try: registration = Registration.objects.get(activation_key=key) except (Registration.DoesNotExist, Registration.MultipleObjectsReturned): activation_message_type = 'error' messages.error(request, invalid_message, extra_tags='account-activation aa-icon') else: if request.user.is_authenticated and request.user.id != registration.user.id: activation_message_type = 'error' messages.error(request, invalid_message, extra_tags='account-activation aa-icon') elif registration.user.is_active: activation_message_type = 'info' messages.info( request, HTML( _('{html_start}This account has already been activated.{html_end}' )).format( html_start=HTML('<p class="message-title">'), html_end=HTML('</p>'), ), extra_tags='account-activation aa-icon', ) else: registration.activate() # Success message for logged in users. message = _( '{html_start}Success{html_end} You have activated your account.' ) tracker.emit( USER_ACCOUNT_ACTIVATED, { "user_id": registration.user.id, "activation_timestamp": registration.activation_timestamp }) if not request.user.is_authenticated: # Success message for logged out users message = _( '{html_start}Success! You have activated your account.{html_end}' 'You will now receive email updates and alerts from us related to' ' the courses you are enrolled in. Sign In to continue.') # Add message for later use. activation_message_type = 'success' messages.success( request, HTML(message).format( html_start=HTML('<p class="message-title">'), html_end=HTML('</p>'), ), extra_tags='account-activation aa-icon', ) # If a safe `next` parameter is provided in the request # and it's not the same as the dashboard, redirect there. # The `get_next_url_for_login_page()` function will only return a safe redirect URL. # If the provided `next` URL is not safe, that function will fill `redirect_to` # with a value of `reverse('dashboard')`. redirect_url = None if request.GET.get('next'): redirect_to, root_login_url = get_next_url_for_login_page( request, include_host=True) # Don't automatically redirect authenticated users to the redirect_url # if the `next` value is either: # 1. "/dashboard" or # 2. "https://{LMS_ROOT_URL}/dashboard" (which we might provide as a value from the AuthN MFE) if redirect_to not in (root_login_url + reverse('dashboard'), reverse('dashboard')): redirect_url = get_redirect_url_with_host(root_login_url, redirect_to) if should_redirect_to_authn_microfrontend( ) and not request.user.is_authenticated: params = {'account_activation_status': activation_message_type} if redirect_url: params['next'] = redirect_url url_path = '/login?{}'.format(urllib.parse.urlencode(params)) return redirect(settings.AUTHN_MICROFRONTEND_URL + url_path) return redirect(redirect_url) if redirect_url and is_enterprise_learner( request.user) else redirect('dashboard')