Commit 6cfc3a02 by cewing

MIT: CCX. Implement individual student enrollments

parent 630d1ce0
......@@ -185,6 +185,8 @@ class TestCoachDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.assertEqual(str(course_start)[:-9], u'2014-11-20 00:00')
def test_enroll_member_student(self):
"""enroll a list of students who are members of the class
"""
self.make_coach()
poc = self.make_poc()
enrollment = CourseEnrollmentFactory(course_id=self.course.id)
......@@ -213,6 +215,8 @@ class TestCoachDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase):
)
def test_unenroll_member_student(self):
"""unenroll a list of students who are members of the class
"""
self.make_coach()
poc = self.make_poc()
enrollment = CourseEnrollmentFactory(course_id=self.course.id)
......@@ -243,6 +247,8 @@ class TestCoachDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase):
)
def test_enroll_non_user_student(self):
"""enroll a list of students who are not users yet
"""
test_email = "nobody@nowhere.com"
self.make_coach()
poc = self.make_poc()
......@@ -271,6 +277,8 @@ class TestCoachDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase):
)
def test_unenroll_non_user_student(self):
"""unenroll a list of students who are not users yet
"""
test_email = "nobody@nowhere.com"
self.make_coach()
poc = self.make_poc()
......@@ -299,8 +307,71 @@ class TestCoachDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase):
).exists()
)
def test_manage_add_single_student(self):
"""enroll a single student who is a member of the class already
"""
self.make_coach()
poc = self.make_poc()
enrollment = CourseEnrollmentFactory(course_id=self.course.id)
student = enrollment.user
# no emails have been sent so far
outbox = self.get_outbox()
self.assertEqual(len(outbox), 0)
url = reverse(
'poc_manage_student',
kwargs={'course_id': self.course.id.to_deprecated_string()}
)
data = {
'student-action': 'add',
'student-id': u','.join([student.email, ]),
}
response = self.client.post(url, data=data, follow=True)
self.assertEqual(response.status_code, 200)
# we were redirected to our current location
self.assertEqual(len(response.redirect_chain), 1)
self.assertTrue(302 in response.redirect_chain[0])
self.assertEqual(len(outbox), 0)
# a PocMembership exists for this student
self.assertTrue(
PocMembership.objects.filter(poc=poc, student=student).exists()
)
def test_manage_remove_single_student(self):
"""unenroll a single student who is a member of the class already
"""
self.make_coach()
poc = self.make_poc()
enrollment = CourseEnrollmentFactory(course_id=self.course.id)
student = enrollment.user
PocMembershipFactory(poc=poc, student=student)
# no emails have been sent so far
outbox = self.get_outbox()
self.assertEqual(len(outbox), 0)
url = reverse(
'poc_manage_student',
kwargs={'course_id': self.course.id.to_deprecated_string()}
)
data = {
'student-action': 'revoke',
'student-id': u','.join([student.email, ]),
}
response = self.client.post(url, data=data, follow=True)
self.assertEqual(response.status_code, 200)
# we were redirected to our current location
self.assertEqual(len(response.redirect_chain), 1)
self.assertTrue(302 in response.redirect_chain[0])
self.assertEqual(len(outbox), 0)
# a PocMembership exists for this student
self.assertFalse(
PocMembership.objects.filter(poc=poc, student=student).exists()
)
USER_COUNT = 2
class TestPocGrades(ModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Tests for Personal Online Courses views.
......
......@@ -253,6 +253,37 @@ def poc_invite(request, course):
return redirect(url)
@ensure_csrf_cookie
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
@coach_dashboard
def poc_student_management(request, course):
"""Manage the enrollment of individual students in a POC
"""
poc = get_poc_for_coach(course, request.user)
action = request.POST.get('student-action', None)
student_id = request.POST.get('student-id', '')
user = email = None
try:
user = get_student_from_identifier(student_id)
except User.DoesNotExist:
email = student_id
else:
email = user.email
try:
validate_email(email)
if action == 'add':
# by decree, no emails sent to students added this way
enroll_email(poc, email, email_students=False)
elif action == 'revoke':
unenroll_email(poc, email, email_students=False)
except ValidationError:
pass # XXX: log, report?
url = reverse('poc_coach_dashboard', kwargs={'course_id': course.id})
return redirect(url)
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
@coach_dashboard
def poc_gradebook(request, course):
......@@ -324,4 +355,3 @@ def poc_grades_csv(request, course):
writer.writerow(row)
return HttpResponse(buffer.getvalue(), content_type='text/csv')
......@@ -81,7 +81,56 @@
}
}
function setup_management_form() {
$(".member-lists-management form").on("submit", function (event) {
var target, action;
target = $(event.target);
if (target.serialize().indexOf('student-action') < 0) {
action = $('<input />', {
type: 'hidden',
name: 'student-action',
value: 'add'
});
target.append(action);
}
});
$(".member-lists-management form .add, .member-lists-management form .revoke").on("click", function(event) {
var target, form, action, studentId, selectedStudent;
event.preventDefault();
target = $(event.target);
form = target.parents('form').first();
if (target.hasClass('add')) {
// adding a new student, add the student-action input and submit
action = $('<input />', {
type: 'hidden',
name: 'student-action',
// this is untenable, tied to a translated value. Fix it.
value: 'add'
});
form.append(action).submit();
} else if (target.hasClass('revoke')) {
// revoking access for a student, get set form values and submit
// get the email address of the student, since they might not be 'enrolled' yet.
selectedStudent = target.parent('td').siblings().last().text();
action = $('<input />', {
type: 'hidden',
name: 'student-action',
value: 'revoke'
});
studentId = $('<input />', {
type: 'hidden',
name: 'student-id',
value: selectedStudent
});
form.append(action, studentId).submit();
}
});
}
$(setup_tabs);
$(setup_management_form)
</script>
......@@ -46,6 +46,8 @@
</div>
<div class="member-lists-management" style="float:left;width:50%">
<form method="POST" action="poc_manage_student">
<input type="hidden" name="csrfmiddlewaretoken" value="${ csrf_token }">
<div class="auth-list-container active">
<div class="member-list-widget">
<div class="member-list">
......@@ -70,9 +72,10 @@
</table>
</div>
<div class="bottom-bar">
<input name="add-field" class="add-field" placeholder="Enter username or email" type="text">
<input name="add" class="add" value="Add Student" type="button">
<input name="student-id" class="add-field" placeholder="Enter username or email" type="text">
<input name="student-action" class="add" value="Add Student" type="button">
</div>
</div>
</div>
</form>
</div>
......@@ -351,11 +351,12 @@ if settings.COURSEWARE_ENABLED:
'pocs.views.save_poc', name='save_poc'),
url(r'^courses/{}/poc_invite$'.format(settings.COURSE_ID_PATTERN),
'pocs.views.poc_invite', name='poc_invite'),
url(r'^courses/{}/poc_manage_student$'.format(settings.COURSE_ID_PATTERN),
'pocs.views.poc_student_management', name='poc_manage_student'),
url(r'^courses/{}/poc_gradebook$'.format(settings.COURSE_ID_PATTERN),
'pocs.views.poc_gradebook', name='poc_gradebook'),
url(r'^courses/{}/poc_grades.csv$'.format(settings.COURSE_ID_PATTERN),
'pocs.views.poc_grades_csv', name='poc_grades_csv'),
url(r'^courses/{}/set_course_mode_price$'.format(settings.COURSE_ID_PATTERN),
'instructor.views.instructor_dashboard.set_course_mode_price', name="set_course_mode_price"),
url(r'^courses/{}/instructor/api/'.format(settings.COURSE_ID_PATTERN),
......
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