Commit 1d85659b by Adam Palay

Prevent instructors from accidentally downgrading enrollment modes through instructor dash TNL-804

parent 0bf0d11a
...@@ -26,9 +26,12 @@ class EmailEnrollmentState(object): ...@@ -26,9 +26,12 @@ class EmailEnrollmentState(object):
exists_user = User.objects.filter(email=email).exists() exists_user = User.objects.filter(email=email).exists()
if exists_user: if exists_user:
user = User.objects.get(email=email) user = User.objects.get(email=email)
exists_ce = CourseEnrollment.is_enrolled(user, course_id) mode, is_active = CourseEnrollment.enrollment_mode_for_user(user, course_id)
# is_active is `None` if the user is not enrolled in the course
exists_ce = is_active is not None and is_active
full_name = user.profile.name full_name = user.profile.name
else: else:
mode = None
exists_ce = False exists_ce = False
full_name = None full_name = None
ceas = CourseEnrollmentAllowed.objects.filter(course_id=course_id, email=email).all() ceas = CourseEnrollmentAllowed.objects.filter(course_id=course_id, email=email).all()
...@@ -40,6 +43,7 @@ class EmailEnrollmentState(object): ...@@ -40,6 +43,7 @@ class EmailEnrollmentState(object):
self.allowed = exists_allowed self.allowed = exists_allowed
self.auto_enroll = bool(state_auto_enroll) self.auto_enroll = bool(state_auto_enroll)
self.full_name = full_name self.full_name = full_name
self.mode = mode
def __repr__(self): def __repr__(self):
return "{}(user={}, enrollment={}, allowed={}, auto_enroll={})".format( return "{}(user={}, enrollment={}, allowed={}, auto_enroll={})".format(
...@@ -84,7 +88,7 @@ def enroll_email(course_id, student_email, auto_enroll=False, email_students=Fal ...@@ -84,7 +88,7 @@ def enroll_email(course_id, student_email, auto_enroll=False, email_students=Fal
previous_state = EmailEnrollmentState(course_id, student_email) previous_state = EmailEnrollmentState(course_id, student_email)
if previous_state.user: if previous_state.user:
CourseEnrollment.enroll_by_email(student_email, course_id) CourseEnrollment.enroll_by_email(student_email, course_id, previous_state.mode)
if email_students: if email_students:
email_params['message'] = 'enrolled_enroll' email_params['message'] = 'enrolled_enroll'
email_params['email_address'] = student_email email_params['email_address'] = student_email
......
...@@ -1050,6 +1050,38 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -1050,6 +1050,38 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
) )
) )
def test_enroll_already_enrolled_student(self):
"""
Ensure that already enrolled "verified" students cannot be downgraded
to "honor"
"""
course_enrollment = CourseEnrollment.objects.get(
user=self.enrolled_student, course_id=self.course.id
)
# make this enrollment "verified"
course_enrollment.mode = u'verified'
course_enrollment.save()
self.assertEqual(course_enrollment.mode, u'verified')
# now re-enroll the student through the instructor dash
url = reverse(
'students_update_enrollment',
kwargs={'course_id': self.course.id.to_deprecated_string()},
)
params = {
'identifiers': self.enrolled_student.email,
'action': 'enroll',
'email_students': True,
}
response = self.client.post(url, params)
self.assertEqual(response.status_code, 200)
# affirm that the student is still in "verified" mode
course_enrollment = CourseEnrollment.objects.get(
user=self.enrolled_student, course_id=self.course.id
)
self.assertEqual(course_enrollment.mode, u"verified")
@ddt.ddt @ddt.ddt
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
......
...@@ -192,10 +192,8 @@ function goto( mode) ...@@ -192,10 +192,8 @@ function goto( mode)
<div class="copy"> <div class="copy">
<p> <p>
${_("Note: some of these buttons are known to time out for larger " ${_("Note: some of these buttons are known to time out for larger "
"courses. We have temporarily disabled those features for courses " "courses. We have disabled those features for courses "
"with more than {max_enrollment} students. We are urgently working on " "with more than {max_enrollment} students.").format(
"fixing this issue. Thank you for your patience as we continue "
"working to improve the platform!").format(
max_enrollment=settings.FEATURES['MAX_ENROLLMENT_INSTR_BUTTONS'] max_enrollment=settings.FEATURES['MAX_ENROLLMENT_INSTR_BUTTONS']
)} )}
</p> </p>
...@@ -428,10 +426,8 @@ function goto( mode) ...@@ -428,10 +426,8 @@ function goto( mode)
<div class="copy"> <div class="copy">
<p> <p>
${_("Note: some of these buttons are known to time out for larger " ${_("Note: some of these buttons are known to time out for larger "
"courses. We have temporarily disabled those features for courses " "courses. We have disabled those features for courses "
"with more than {max_enrollment} students. We are urgently working on " "with more than {max_enrollment} students.").format(
"fixing this issue. Thank you for your patience as we continue "
"working to improve the platform!").format(
max_enrollment=settings.FEATURES['MAX_ENROLLMENT_INSTR_BUTTONS'] max_enrollment=settings.FEATURES['MAX_ENROLLMENT_INSTR_BUTTONS']
)} )}
</p> </p>
...@@ -461,17 +457,6 @@ function goto( mode) ...@@ -461,17 +457,6 @@ function goto( mode)
<hr width="40%" style="align:left"> <hr width="40%" style="align:left">
%endif %endif
<h2>${_("Batch Enrollment")}</h2>
<p>${_("Enroll or un-enroll one or many students: enter emails, separated by new lines or commas;")}</p>
<textarea rows="6" cols="70" name="multiple_students"></textarea>
<p>
<input type="checkbox" name="email_students"> ${_("Notify students by email")}
<p>
<input type="checkbox" name="auto_enroll"> ${_("Auto-enroll students when they activate")}
<input type="submit" name="action" value="Enroll multiple students">
<p>
<input type="submit" name="action" value="Unenroll multiple students">
%endif %endif
##----------------------------------------------------------------------------- ##-----------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment