def register_alerts(self, request, course): """ Registers an alert close to the certificate delivery date. """ is_enrolled = CourseEnrollment.get_enrollment(request.user, course.id) if not is_enrolled or not self.is_enabled or course.end > self.current_time: return if self.date > self.current_time: CourseHomeMessages.register_info_message( request, Text( _(u'If you have earned a certificate, you will be able to access it {time_remaining_string}' u' from now. You will also be able to view your certificates on your {learner_profile_link}.' ) ).format( time_remaining_string=self.time_remaining_string, learner_profile_link=HTML( u'<a href="{learner_profile_url}">{learner_profile_name}</a>' ).format( learner_profile_url=reverse( 'learner_profile', kwargs={'username': request.user.username}), learner_profile_name=_('Learner Profile'), ), ), title=Text( _('We are working on generating course certificates.')))
def post(self, request, username_or_email): """Allows support staff to alter a user's enrollment.""" try: user = User.objects.get( Q(username=username_or_email) | Q(email=username_or_email)) course_id = request.data['course_id'] course_key = CourseKey.from_string(course_id) old_mode = request.data['old_mode'] new_mode = request.data['new_mode'] reason = request.data['reason'] enrollment = CourseEnrollment.objects.get(user=user, course_id=course_key) if enrollment.mode != old_mode: return HttpResponseBadRequest( 'User {username} is not enrolled with mode {old_mode}.'. format(username=user.username, old_mode=old_mode)) except KeyError as err: return HttpResponseBadRequest('The field {} is required.'.format( str(err))) except InvalidKeyError: return HttpResponseBadRequest('Could not parse course key.') except (CourseEnrollment.DoesNotExist, User.DoesNotExist): return HttpResponseBadRequest( 'Could not find enrollment for user {username} in course {course}.' .format(username=username_or_email, course=str(course_key))) try: # Wrapped in a transaction so that we can be sure the # ManualEnrollmentAudit record is always created correctly. with transaction.atomic(): update_enrollment(user.username, course_id, mode=new_mode, include_expired=True) manual_enrollment = ManualEnrollmentAudit.create_manual_enrollment_audit( request.user, enrollment.user.email, ENROLLED_TO_ENROLLED, reason=reason, enrollment=enrollment) if new_mode == CourseMode.CREDIT_MODE: provider_ids = get_credit_provider_attribute_values( course_key, 'id') credit_provider_attr = { 'namespace': 'credit', 'name': 'provider_id', 'value': provider_ids[0], } CourseEnrollmentAttribute.add_enrollment_attr( enrollment=enrollment, data_list=[credit_provider_attr]) entitlement = CourseEntitlement.get_fulfillable_entitlement_for_user_course_run( user=user, course_run_key=course_id) if entitlement is not None and entitlement.mode == new_mode: entitlement.set_enrollment( CourseEnrollment.get_enrollment(user, course_id)) return JsonResponse( ManualEnrollmentSerializer( instance=manual_enrollment).data) except CourseModeNotFoundError as err: return HttpResponseBadRequest(str(err))
def get_expiration_banner_text(user, course, language='en'): # lint-amnesty, pylint: disable=unused-argument """ Get text for banner that messages user course expiration date for different tests that depend on it. """ upgrade_link = verified_upgrade_deadline_link(user=user, course=course) enrollment = CourseEnrollment.get_enrollment(user, course.id) expiration_date = enrollment.created + timedelta(weeks=4) upgrade_deadline = enrollment.upgrade_deadline if upgrade_deadline is None or now() < upgrade_deadline: upgrade_deadline = enrollment.course_upgrade_deadline formatted_expiration_date = strftime_localized_html(expiration_date, 'SHORT_DATE') if upgrade_deadline: formatted_upgrade_deadline = strftime_localized_html(upgrade_deadline, 'SHORT_DATE') bannerText = '<strong>Audit Access Expires {expiration_date}</strong><br>\ You lose all access to this course, including your progress, on {expiration_date}.\ <br>Upgrade by {upgrade_deadline} to get unlimited access to the course as long as it exists\ on the site. <a id="FBE_banner" href="{upgrade_link}">Upgrade now<span class="sr-only"> to retain access past\ {expiration_date}</span></a>'.format( expiration_date=formatted_expiration_date, upgrade_link=upgrade_link, upgrade_deadline=formatted_upgrade_deadline ) else: bannerText = '<strong>Audit Access Expires {expiration_date}</strong><br>\ You lose all access to this course, including your progress, on {expiration_date}.\ '.format( expiration_date=formatted_expiration_date ) return bannerText
def delete_enrollment(*args, **kwargs): """ Delete enrollment and enrollment attributes of given user in the course provided. Example: >>>delete_enrollment( { "user": user_object, "course_id": course-v1-edX-DemoX-1T2015" ) """ course_id = kwargs.pop('course_id', None) user = kwargs.get('user') try: course_key = get_valid_course_key(course_id) except InvalidKeyError: raise NotFound('No course found by course id `{}`'.format(course_id)) username = user.username LOG.info('Deleting enrollment. User: `%s` course: `%s`', username, course_id) enrollment = CourseEnrollment.get_enrollment(user, course_key) if not enrollment: raise NotFound( 'No enrollment found for user: `{}` on course_id `{}`'.format( username, course_id)) try: enrollment.delete() except Exception: raise NotFound( 'Error: Enrollment could not be deleted for user: `{}` on course_id `{}`' .format(username, course_id))
def __init__(self, course_key, request, username=''): self.request = request self.overview = course_detail( self.request, username or self.request.user.username, course_key, ) self.original_user_is_staff = has_access(self.request.user, 'staff', self.overview).has_access self.original_user_is_global_staff = self.request.user.is_staff self.course_key = course_key self.course = get_course_by_id(self.course_key) self.course_masquerade, self.effective_user = setup_masquerade( self.request, course_key, staff_access=self.original_user_is_staff, ) self.request.user = self.effective_user self.is_staff = has_access(self.effective_user, 'staff', self.overview).has_access self.enrollment_object = CourseEnrollment.get_enrollment( self.effective_user, self.course_key, select_related=['celebration', 'user__celebration']) self.can_view_legacy_courseware = courseware_legacy_is_visible( course_key=course_key, is_global_staff=self.original_user_is_global_staff, )
def post(self, request, course_key_string, *args, **kwargs): # lint-amnesty, pylint: disable=unused-argument """ Handle a POST request. """ course_key = CourseKey.from_string(course_key_string) # Check if we're masquerading as someone else. If so, we should just ignore this request. _, user = setup_masquerade( request, course_key, staff_access=has_access(request.user, 'staff', course_key), reset_masquerade_data=True, ) if user != request.user: return Response(status=202) # "Accepted" data = dict(request.data) first_section = data.pop('first_section', None) if data: return Response(status=400) # there were parameters we didn't recognize enrollment = CourseEnrollment.get_enrollment(request.user, course_key) if not enrollment: return Response(status=404) defaults = {} if first_section is not None: defaults['celebrate_first_section'] = first_section if defaults: _, created = CourseEnrollmentCelebration.objects.update_or_create(enrollment=enrollment, defaults=defaults) return Response(status=201 if created else 200) else: return Response(status=200) # just silently allow it
def add_or_update_enrollment_attr(username, course_id, attributes): """Set enrollment attributes for the enrollment of given user in the course provided. Args: course_id (str): The Course to set enrollment attributes for. username: The User to set enrollment attributes for. attributes (list): Attributes to be set. Example: >>>add_or_update_enrollment_attr( "Bob", "course-v1-edX-DemoX-1T2015", [ { "namespace": "credit", "name": "provider_id", "value": "hogwarts", }, ] ) """ course_key = CourseKey.from_string(course_id) user = _get_user(username) enrollment = CourseEnrollment.get_enrollment(user, course_key) if not _invalid_attribute(attributes) and enrollment is not None: CourseEnrollmentAttribute.add_enrollment_attr(enrollment, attributes)
def assert_enrollment(self, mode): """ Assert that the student's enrollment has the correct mode. """ enrollment = CourseEnrollment.get_enrollment(self.student, self.course.id) assert enrollment.mode == mode
def __init__(self, course_key, request, username=''): self.request = request self.overview = course_detail( self.request, username or self.request.user.username, course_key, ) # We must compute course load access *before* setting up masquerading, # else course staff (who are not enrolled) will not be able view # their course from the perspective of a learner. self.load_access = check_course_access( self.overview, self.request.user, 'load', check_if_enrolled=True, check_if_authenticated=True, ) self.original_user_is_staff = has_access(self.request.user, 'staff', self.overview).has_access self.original_user_is_global_staff = self.request.user.is_staff self.course_key = course_key self.course = get_course_by_id(self.course_key) self.course_masquerade, self.effective_user = setup_masquerade( self.request, course_key, staff_access=self.original_user_is_staff, ) self.request.user = self.effective_user self.is_staff = has_access(self.effective_user, 'staff', self.overview).has_access self.enrollment_object = CourseEnrollment.get_enrollment(self.effective_user, self.course_key, select_related=['celebration', 'user__celebration']) self.can_view_legacy_courseware = courseware_legacy_is_visible( course_key=course_key, is_global_staff=self.original_user_is_global_staff, )
def enrollment_date_for_fbe(user, course_key=None, course=None): """ Gets the enrollment date for the given user and course, if FBE is enabled. One of course_key or course must be provided. Returns: None if FBE is disabled for either this user or course The enrollment creation date if an enrollment exists now() if no enrollment. """ if user is None or (course_key is None and course is None): raise ValueError('Both user and either course_key or course must be specified if no enrollment is provided') course_key = course_key or course.id full_access_masquerade = has_full_access_role_in_masquerade(user, course_key) if full_access_masquerade: return None elif full_access_masquerade is False: user = None # we are masquerading as a generic user, not a specific one -- avoid all user checks below if user and user.id and has_staff_roles(user, course_key): return None enrollment = user and CourseEnrollment.get_enrollment(user, course_key, ['fbeenrollmentexclusion']) if is_in_holdback(enrollment): return None if not correct_modes_for_fbe(enrollment=enrollment, user=user, course_key=course_key, course=course): return None # If the user isn't enrolled, act as if the user enrolled today return enrollment.created if enrollment else timezone.now()
def is_enabled(cls, request, course_key): """ Show this tool to all learners who are eligible to upgrade. """ enrollment = CourseEnrollment.get_enrollment(request.user, course_key) if enrollment is None: return False if enrollment.dynamic_upgrade_deadline is None: return False if not enrollment.is_active: return False if enrollment.mode not in CourseMode.UPSELL_TO_VERIFIED_MODES: return False if enrollment.course_upgrade_deadline is None: return False if datetime.datetime.now( pytz.UTC) >= enrollment.course_upgrade_deadline: return False return True
def get_upgradeable_enrollments_for_entitlement(self, entitlement): """ Retrieve all the CourseEnrollments that are upgradeable for a given CourseEntitlement Arguments: entitlement: CourseEntitlement that we are requesting the CourseEnrollments for. Returns: list: List of upgradeable CourseEnrollments """ # find all course_runs within the course course_runs = get_course_runs_for_course(entitlement.course_uuid) # check if the user has enrollments for any of the course_runs upgradeable_enrollments = [] for course_run in course_runs: course_run_id = CourseKey.from_string(course_run.get('key')) enrollment = CourseEnrollment.get_enrollment( entitlement.user, course_run_id) if (enrollment and enrollment.is_active and is_course_run_entitlement_fulfillable( course_run_id, entitlement)): upgradeable_enrollments.append(enrollment) return upgradeable_enrollments
def register_alerts(self, request, course): """ Registers an alert if the end date is approaching. """ is_enrolled = CourseEnrollment.get_enrollment(request.user, course.id) if not course.start or self.current_time < course.start or not is_enrolled: return days_until_end = (course.end - self.current_time).days if course.end > self.current_time and days_until_end <= settings.COURSE_MESSAGE_ALERT_DURATION_IN_DAYS: if days_until_end > 0: CourseHomeMessages.register_info_message( request, Text(self.description), title=Text( _(u'This course is ending in {time_remaining_string} on {course_end_date}.' )).format( time_remaining_string=self.time_remaining_string, course_end_date=self.long_date_html, )) else: CourseHomeMessages.register_info_message( request, Text(self.description), title=Text( _(u'This course is ending in {time_remaining_string} at {course_end_time}.' )).format( time_remaining_string=self.time_remaining_string, course_end_time=self.short_time_html, ))
def course_run_refund_status(request, course_id): """ Get Refundable status for a course. Arguments: request: The request object. course_id (str): The unique identifier for the course. Returns: Json response. """ try: course_key = CourseKey.from_string(course_id) course_enrollment = CourseEnrollment.get_enrollment(request.user, course_key) except InvalidKeyError: logging.exception("The course key used to get refund status caused InvalidKeyError during look up.") return JsonResponse({'course_refundable_status': ''}, status=406) refundable_status = course_enrollment.refundable() logging.info(f"Course refund status for course {course_id} is {refundable_status}") return JsonResponse({'course_refundable_status': refundable_status}, status=200)
def test_change_enrollment_mode_fullfills_entitlement(self, search_string_type, mock_get_course_uuid): """ Assert that changing student's enrollment fulfills it's respective entitlement if it exists. """ assert ManualEnrollmentAudit.get_manual_enrollment_by_email(self.student.email) is None enrollment = CourseEnrollment.get_enrollment(self.student, self.course.id) entitlement = CourseEntitlementFactory.create( user=self.user, mode=CourseMode.VERIFIED, enrollment_course_run=enrollment ) mock_get_course_uuid.return_value = entitlement.course_uuid url = reverse( 'support:enrollment_list', kwargs={'username_or_email': getattr(self.student, search_string_type)} ) response = self.client.post(url, data={ 'course_id': str(self.course.id), 'old_mode': CourseMode.AUDIT, 'new_mode': CourseMode.VERIFIED, 'reason': 'Financial Assistance' }) entitlement.refresh_from_db() assert response.status_code == 200 assert ManualEnrollmentAudit.get_manual_enrollment_by_email(self.student.email) is not None assert entitlement.enrollment_course_run is not None assert entitlement.is_entitlement_redeemable() is False self.assert_enrollment(CourseMode.VERIFIED)
def register_alerts(self, request, course): """ Registers an alert if the course has not started yet. """ is_enrolled = CourseEnrollment.get_enrollment(request.user, course.id) if not course.start or not is_enrolled: return days_until_start = (course.start - self.current_time).days if course.start > self.current_time: if days_until_start > 0: CourseHomeMessages.register_info_message( request, Text(_("Don't forget to add a calendar reminder!")), title=Text( _(u"Course starts in {time_remaining_string} on {course_start_date}." )).format( time_remaining_string=self.time_remaining_string, course_start_date=self.long_date_html, )) else: CourseHomeMessages.register_info_message( request, Text( _(u"Course starts in {time_remaining_string} at {course_start_time}." )).format( time_remaining_string=self.time_remaining_string, course_start_time=self.short_time_html, ))
def get_credit_state(self, user_id, course_key_or_id, return_course_info=False): """ Return all information about the user's credit state inside of a given course. ARGS: - user_id: The PK of the User in question - course_key: The course ID (as string or CourseKey) RETURNS: NONE (user not found or is not enrolled or is not credit course) - or - { 'enrollment_mode': the mode that the user is enrolled in the course 'profile_fullname': the name that the student registered under, used for verification 'is_credit_course': if the course has been marked as a credit bearing course 'credit_requirement_status': the user's status in fulfilling those requirements 'course_name': optional display name of the course 'course_end_date': optional end date of the course } """ # This seems to need to be here otherwise we get # circular references when starting up the app from openedx.core.djangoapps.credit.api.eligibility import ( is_credit_course, get_credit_requirement_status, ) # since we have to do name matching during various # verifications, User must have a UserProfile try: user = User.objects.select_related('profile').get(id=user_id) except ObjectDoesNotExist: # bad user_id return None course_key = _get_course_key(course_key_or_id) enrollment = CourseEnrollment.get_enrollment(user, course_key) if not enrollment or not enrollment.is_active: # not enrolled return None result = { 'enrollment_mode': enrollment.mode, 'profile_fullname': user.profile.name, 'student_email': user.email, 'is_credit_course': is_credit_course(course_key), 'credit_requirement_status': get_credit_requirement_status(course_key, user.username) } if return_course_info: course = modulestore().get_course(course_key, depth=0) result.update({ 'course_name': course.display_name, 'course_end_date': course.end, }) return result
def date(self): if not self.course.self_paced: return self.course.start else: enrollment = CourseEnrollment.get_enrollment( self.user, self.course_id) return max(enrollment.created, self.course.start) if enrollment else self.course.start
def test_course_home_for_global_staff(self): """ Tests that staff user can access the course home without being enrolled in the course. """ course = self.course self.user.is_staff = True self.user.save() self.override_waffle_switch(True) CourseEnrollment.get_enrollment(self.user, course.id).delete() response = self.visit_course_home(course, start_count=1, resume_count=0) content = pq(response.content) vertical = course.children[0].children[0].children[0] assert content('.action-resume-course').attr('href').endswith( '/vertical/' + vertical.url_name)
def handle(self, *args, **options): """ Handle the send save for later reminder emails. """ reminder_email_threshold_date = datetime.now() - timedelta( days=settings.SAVE_FOR_LATER_REMINDER_EMAIL_THRESHOLD) saved_courses_ids = SavedCourse.objects.filter( reminder_email_sent=False, modified__lt=reminder_email_threshold_date).values_list('id', flat=True) total = saved_courses_ids.count() batch_size = max(1, options.get('batch_size')) num_batches = ((total - 1) / batch_size + 1) if total > 0 else 0 for batch_num in range(int(num_batches)): reminder_email_sent_ids = [] start = batch_num * batch_size end = min(start + batch_size, total) - 1 saved_courses_batch_ids = list(saved_courses_ids)[start:end + 1] query = SavedCourse.objects.filter( id__in=saved_courses_batch_ids).order_by('-modified') saved_courses = use_read_replica_if_available(query) for saved_course in saved_courses: user = User.objects.filter(email=saved_course.email).first() course_overview = CourseOverview.get_from_id( saved_course.course_id) course_data = { 'course': course_overview, 'send_to_self': None, 'user_id': saved_course.user_id, 'org_img_url': saved_course.org_img_url, 'marketing_url': saved_course.marketing_url, 'weeks_to_complete': saved_course.weeks_to_complete, 'min_effort': saved_course.min_effort, 'max_effort': saved_course.max_effort, 'type': 'course', 'reminder': True, 'braze_event': USER_SEND_SAVE_FOR_LATER_REMINDER_EMAIL, } if user: enrollment = CourseEnrollment.get_enrollment( user, saved_course.course_id) if enrollment: continue email_sent = send_email(saved_course.email, course_data) if email_sent: reminder_email_sent_ids.append(saved_course.id) else: logging.info( "Unable to send reminder email to {user} for {course} course" .format(user=str(saved_course.email), course=str(saved_course.course_id))) SavedCourse.objects.filter(id__in=reminder_email_sent_ids).update( reminder_email_sent=True)
def check_and_get_upgrade_link_and_date(user, enrollment=None, course=None): """ For an authenticated user, return a link to allow them to upgrade in the specified course. Returns the upgrade link and upgrade deadline for a user in a given course given that the user is within the window to upgrade defined by our dynamic pacing feature; otherwise, returns None for both the link and date. """ if enrollment is None and course is None: logger.warning(u'Must specify either an enrollment or a course') return (None, None, None) if enrollment: if course and enrollment.course_id != course.id: logger.warning(u'{} refers to a different course than {} which was supplied. Enrollment course id={}, ' u'repr={!r}, deprecated={}. Course id={}, repr={!r}, deprecated={}.' .format(enrollment, course, enrollment.course_id, enrollment.course_id, enrollment.course_id.deprecated, course.id, course.id, course.id.deprecated ) ) return (None, None, None) if enrollment.user_id != user.id: logger.warning(u'{} refers to a different user than {} which was supplied. ' u'Enrollment user id={}, repr={!r}. ' u'User id={}, repr={!r}.'.format(enrollment, user, enrollment.user_id, enrollment.user_id, user.id, user.id, ) ) return (None, None, None) if enrollment is None: enrollment = CourseEnrollment.get_enrollment(user, course.id) if enrollment is None: return (None, None, None) if user.is_authenticated and can_show_verified_upgrade(user, enrollment, course): return ( verified_upgrade_deadline_link(user, enrollment.course), enrollment.upgrade_deadline, enrollment.course_upgrade_deadline, ) return (None, None, enrollment.course_upgrade_deadline)
def test_create_user__course_staff(self): """ Create a user and set them as course staff """ username = '******' self.call_command([username], course=self.course_id, course_staff=True) user = self.user_model.objects.get(username=username) enrollment = CourseEnrollment.get_enrollment(user, self.course.id) assert enrollment.mode == 'audit' assert CourseStaffRole(self.course.id).has_user(user)
def test_create_user__course_staff__ignore_mode(self): """ Test that mode is ignored when --course_staff is specified """ username = '******' self.call_command([username], course=self.course_id, course_staff=True, mode='verified') user = self.user_model.objects.get(username=username) enrollment = CourseEnrollment.get_enrollment(user, self.course.id) assert enrollment.mode == 'audit' assert CourseStaffRole(self.course.id).has_user(user)
def test_create_user__mode(self): """ Create a test for a user in verified mode. """ # Create a user in verified rather than default audit username = '******' self.call_command([username], course=self.course_id, mode='verified') # Verify enrollment user = self.user_model.objects.get(username='******') enrollment = CourseEnrollment.get_enrollment(user, self.course.id) assert enrollment.mode == 'verified'
def handle_goal(goal, today, sunday_date, monday_date): """Sends an email reminder for a single CourseGoal, if it passes all our checks""" if not COURSE_GOALS_NUMBER_OF_DAYS_GOALS.is_enabled(goal.course_key): return False enrollment = CourseEnrollment.get_enrollment(goal.user, goal.course_key, select_related=['course']) # If you're not actively enrolled in the course or your enrollment was this week if not enrollment or not enrollment.is_active or enrollment.created.date( ) >= monday_date: return False audit_access_expiration_date = get_user_course_expiration_date( goal.user, enrollment.course_overview) # If an audit user's access expires this week, exclude them from the email since they may not # be able to hit their goal anyway if audit_access_expiration_date and audit_access_expiration_date.date( ) <= sunday_date: return False cert = get_certificate_for_user_id(goal.user, goal.course_key) # If a user has a downloadable certificate, we will consider them as having completed # the course and opt them out of receiving emails if cert and cert.status == CertificateStatuses.downloadable: return False # Check the number of days left to successfully hit their goal week_activity_count = UserActivity.objects.filter( user=goal.user, course_key=goal.course_key, date__gte=monday_date, ).count() required_days_left = goal.days_per_week - week_activity_count # The weekdays are 0 indexed, but we want this to be 1 to match required_days_left. # Essentially, if today is Sunday, days_left_in_week should be 1 since they have Sunday to hit their goal. days_left_in_week = SUNDAY_WEEKDAY - today.weekday() + 1 # We want to email users in the morning of their timezone user_timezone = get_user_timezone_or_last_seen_timezone_or_utc( goal.user) now_in_users_timezone = datetime.now(user_timezone) if not 9 <= now_in_users_timezone.hour < 12: return False if required_days_left == days_left_in_week: send_ace_message(goal) CourseGoalReminderStatus.objects.update_or_create( goal=goal, defaults={'email_reminder_sent': True}) return True return False
def post(self, request, username_or_email): """ Allows support staff to create a user's enrollment. """ try: course_id = request.data['course_id'] course_key = CourseKey.from_string(course_id) mode = request.data['mode'] reason = request.data['reason'] user = User.objects.get( Q(username=username_or_email) | Q(email=username_or_email)) except KeyError as err: return HttpResponseBadRequest(f'The field {str(err)} is required.') except InvalidKeyError: return HttpResponseBadRequest('Could not parse course key.') except User.DoesNotExist: return HttpResponseBadRequest( 'Could not find user {username}.'.format( username=username_or_email)) enrollment = CourseEnrollment.get_enrollment(user=user, course_key=course_key) if enrollment is not None: return HttpResponseBadRequest( f'The user {str(username_or_email)} is already enrolled in {str(course_id)}.' ) enrollment_modes = [ enrollment_mode['slug'] for enrollment_mode in self.get_course_modes(course_key) ] if mode not in enrollment_modes: return HttpResponseBadRequest( f'{str(mode)} is not a valid mode for {str(course_id)}. ' f'Possible valid modes are {str(enrollment_modes)}') enrollment = CourseEnrollment.enroll(user=user, course_key=course_key, mode=mode) # Wrapped in a transaction so that we can be sure the # ManualEnrollmentAudit record is always created correctly. with transaction.atomic(): manual_enrollment = ManualEnrollmentAudit.create_manual_enrollment_audit( request.user, enrollment.user.email, UNENROLLED_TO_ENROLLED, reason=reason, enrollment=enrollment) return JsonResponse( ManualEnrollmentSerializer(instance=manual_enrollment).data)
def test_bulk_enrollment_from_config_model(self): """ Test all users are enrolled using the config model.""" lines = "course_id,user,mode\n" for enrollment in self.enrollments: lines += str(enrollment.course.id) + "," + str(enrollment.user.username) + ",verified\n" csv_file = SimpleUploadedFile(name='test.csv', content=lines.encode('utf-8'), content_type='text/csv') BulkChangeEnrollmentConfiguration.objects.create(enabled=True, csv_file=csv_file) call_command("bulk_change_enrollment_csv", "--file_from_database") for enrollment in self.enrollments: new_enrollment = CourseEnrollment.get_enrollment(user=enrollment.user, course_key=enrollment.course) assert new_enrollment.is_active is True assert new_enrollment.mode == CourseMode.VERIFIED
def test_create_user_with_course(self): """ Create users and have them enroll in a course """ usernames = ['username1', 'username2'] self.call_command(usernames, course=self.course_id) # Check that the users exist and were enrolled in the course with the default settings users = self.user_model.objects.filter(username__in=usernames).all() assert len(users) == len(usernames) for user in users: enrollment = CourseEnrollment.get_enrollment(user, self.course.id) assert enrollment.mode == 'audit' assert not CourseStaffRole(self.course.id).has_user(user)
def get(self, request, *args, **kwargs): course_key_string = kwargs.get('course_key_string') course_key = CourseKey.from_string(course_key_string) original_user_is_staff = has_access(request.user, 'staff', course_key).has_access _, request.user = setup_masquerade( request, course_key, staff_access=has_access(request.user, 'staff', course_key), reset_masquerade_data=True, ) username = request.user.username if request.user.username else None course = course_detail(request, request.user.username, course_key) enrollment = CourseEnrollment.get_enrollment(request.user, course_key_string) user_is_enrolled = bool(enrollment and enrollment.is_active) courseware_meta = CoursewareMeta(course_key, request, request.user.username) can_load_courseware = courseware_meta.is_microfrontend_enabled_for_user( ) browser_timezone = self.request.query_params.get( 'browser_timezone', None) celebrations = get_celebrations_dict(request.user, enrollment, course, browser_timezone) data = { 'course_id': course.id, 'username': username, 'is_staff': has_access(request.user, 'staff', course_key).has_access, 'original_user_is_staff': original_user_is_staff, 'number': course.display_number_with_default, 'org': course.display_org_with_default, 'tabs': get_course_tab_list(request.user, course), 'title': course.display_name_with_default, 'is_self_paced': getattr(course, 'self_paced', False), 'is_enrolled': user_is_enrolled, 'can_load_courseware': can_load_courseware, 'celebrations': celebrations, } context = self.get_serializer_context() context['course'] = course context['course_overview'] = course context['enrollment'] = enrollment serializer = self.get_serializer_class()(data, context=context) return Response(serializer.data)
def test_bulk_enrollment(self): """ Test all users are enrolled using the command.""" lines = [ str(enrollment.course.id) + "," + str(enrollment.user.username) + ",verified\n" for enrollment in self.enrollments ] with NamedTemporaryFile() as csv: csv = self._write_test_csv(csv, lines=lines) call_command("bulk_change_enrollment_csv", f"--csv_file_path={csv.name}") for enrollment in self.enrollments: new_enrollment = CourseEnrollment.get_enrollment(user=enrollment.user, course_key=enrollment.course) assert new_enrollment.is_active is True assert new_enrollment.mode == CourseMode.VERIFIED