diff --git a/app/locale/en.coffee b/app/locale/en.coffee index e11434609..55a5383d1 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -1367,7 +1367,6 @@ earliest_incomplete: "Earliest incomplete level" latest_complete: "Latest completed level" enroll_student: "Enroll student" - revoke_enrollment: "Revoke Enrollment" adding_students: "Adding students" course_progress: "Course Progress" not_applicable: "N/A" @@ -1438,8 +1437,6 @@ status_expired: "Expired on {{date}}" status_not_enrolled: "Not Enrolled" status_enrolled: "Expires on {{date}}" - revoke_confirm: "Are you sure you want to revoke enrollment from {{student_name}}?" - revoking: "Revoking..." classes: archmage_title: "Archmage" diff --git a/app/models/Prepaid.coffee b/app/models/Prepaid.coffee index f1432986c..360a21f50 100644 --- a/app/models/Prepaid.coffee +++ b/app/models/Prepaid.coffee @@ -40,10 +40,3 @@ module.exports = class Prepaid extends CocoModel options.data ?= {} options.data.userID = user.id or user @fetch(options) - - revoke: (user, options={}) -> - options.url = _.result(@, 'url')+'/redeemers' - options.type = 'DELETE' - options.data ?= {} - options.data.userID = user.id or user - @fetch(options) diff --git a/app/styles/courses/teacher-class-view.sass b/app/styles/courses/teacher-class-view.sass index d2e4b5a8c..70ba4d654 100644 --- a/app/styles/courses/teacher-class-view.sass +++ b/app/styles/courses/teacher-class-view.sass @@ -308,7 +308,5 @@ width: 300px .enroll-col width: 140px - .revoke-col - width: 170px td vertical-align: middle diff --git a/app/templates/courses/teacher-class-view.jade b/app/templates/courses/teacher-class-view.jade index 002f89ae6..11c689eea 100644 --- a/app/templates/courses/teacher-class-view.jade +++ b/app/templates/courses/teacher-class-view.jade @@ -419,6 +419,3 @@ mixin enrollmentStatusTab td.enroll-col if status !== 'enrolled' button.enroll-student-button.btn.btn-navy(data-i18n="teacher.enroll_student", data-user-id=student.id) - td.revoke-col - if status === 'enrolled' - button.revoke-student-button.btn.btn-burgandy-alt(data-i18n="teacher.revoke_enrollment", data-user-id=student.id) diff --git a/app/views/courses/TeacherClassView.coffee b/app/views/courses/TeacherClassView.coffee index ad1a3b0de..723d50562 100644 --- a/app/views/courses/TeacherClassView.coffee +++ b/app/views/courses/TeacherClassView.coffee @@ -35,7 +35,6 @@ module.exports = class TeacherClassView extends RootView 'click .remove-student-link': 'onClickRemoveStudentLink' 'click .assign-student-button': 'onClickAssignStudentButton' 'click .enroll-student-button': 'onClickEnrollStudentButton' - 'click .revoke-student-button': 'onClickRevokeStudentButton' 'click .assign-to-selected-students': 'onClickBulkAssign' 'click .enroll-selected-students': 'onClickBulkEnroll' 'click .export-student-progress-btn': 'onClickExportStudentProgress' @@ -372,23 +371,6 @@ module.exports = class TeacherClassView extends RootView } null - onClickRevokeStudentButton: (e) -> - button = $(e.currentTarget) - userID = button.data('user-id') - user = @students.get(userID) - s = $.i18n.t('teacher.revoke_confirm').replace('{{student_name}}', user.broadName()) - return unless confirm(s) - prepaid = user.makeCoursePrepaid() - button.text($.i18n.t('teacher.revoking')) - prepaid.revoke(user, { - success: => - user.unset('coursePrepaid') - error: (prepaid, jqxhr) => - msg = jqxhr.responseJSON.message - noty text: msg, layout: 'center', type: 'error', killer: true, timeout: 3000 - complete: => @render() - }) - onClickSelectAll: (e) -> e.preventDefault() checkboxes = @$('.student-checkbox input') diff --git a/server/middleware/prepaids.coffee b/server/middleware/prepaids.coffee index 7cce231cd..14742fc04 100644 --- a/server/middleware/prepaids.coffee +++ b/server/middleware/prepaids.coffee @@ -90,49 +90,7 @@ module.exports = redeemers.push({ date: new Date(), userID: user._id }) prepaid.set('redeemers', redeemers) res.status(201).send(prepaid.toObject({req: req})) - - - revoke: wrap (req, res) -> - if not req.user?.isTeacher() - throw new errors.Forbidden('Must be a teacher to use enrollments') - prepaid = yield database.getDocFromHandle(req, Prepaid) - if not prepaid - throw new errors.NotFound('Prepaid not found.') - - unless prepaid.get('creator').equals(req.user._id) - throw new errors.Forbidden('You may not revoke enrollments you do not own.') - unless prepaid.get('type') is 'course' - throw new errors.Forbidden('This prepaid is not of type "course".') - if prepaid.get('endDate') and new Date(prepaid.get('endDate')) < new Date() - throw new errors.Forbidden('This prepaid is expired.') - - user = yield User.findById(req.body?.userID) - if not user - throw new errors.NotFound('User not found.') - - if not user.isEnrolled() - throw new errors.UnprocessableEntity('User to revoke must be enrolled first.') - if not _.any(prepaid.get('redeemers'), (obj) -> obj.userID.equals(user._id)) - throw new errors.UnprocessableEntity('User was not enrolled with this set of enrollments') - - query = - _id: prepaid._id - 'redeemers.userID': { $eq: user._id } - update = { $pull: { redeemers : { userID: user._id } }} - result = yield Prepaid.update(query, update) - if result.nModified is 0 - @logError(req.user, "POST prepaid redeemer lost race on maxRedeemers") - throw new errors.UnprocessableEntity('User was not enrolled with this set of enrollments (race)') - - user.set('coursePrepaid', undefined) - yield user.save() - - # return prepaid with new redeemer added locally - prepaid.set('redeemers', _.filter(prepaid.get('redeemers') or [], (obj) -> not obj.userID.equals(user._id))) - res.status(200).send(prepaid.toObject({req: req})) - - fetchByCreator: wrap (req, res, next) -> creator = req.query.creator return next() if not creator diff --git a/server/routes/index.coffee b/server/routes/index.coffee index 1a66bd12b..08a8552cb 100644 --- a/server/routes/index.coffee +++ b/server/routes/index.coffee @@ -91,7 +91,6 @@ module.exports.setup = (app) -> app.get('/db/prepaid', mw.auth.checkLoggedIn(), mw.prepaids.fetchByCreator) app.post('/db/prepaid', mw.auth.checkHasPermission(['admin']), mw.prepaids.post) app.post('/db/prepaid/:handle/redeemers', mw.prepaids.redeem) - app.delete('/db/prepaid/:handle/redeemers', mw.prepaids.revoke) app.get '/db/products', require('./db/product').get diff --git a/test/app/views/teachers/TeacherClassView.spec.coffee b/test/app/views/teachers/TeacherClassView.spec.coffee index 855de44aa..57a5af175 100644 --- a/test/app/views/teachers/TeacherClassView.spec.coffee +++ b/test/app/views/teachers/TeacherClassView.spec.coffee @@ -113,25 +113,3 @@ describe 'TeacherClassView', -> users = @view.enrollStudents.calls.argsFor(0)[0] expect(users.size()).toBe(1) expect(users.first().id).toBe(@view.students.first().id) - - describe 'Revoke button', -> - it 'opens a confirm modal once clicked', -> - spyOn(window, 'confirm').and.returnValue(true) - @view.$('.revoke-student-button:first').click() - expect(window.confirm).toHaveBeenCalled() - - describe 'once the prepaid is successfully revoked', -> - beforeEach -> - spyOn(window, 'confirm').and.returnValue(true) - button = @view.$('.revoke-student-button:first') - @revokedUser = @view.students.get(button.data('user-id')) - @view.$('.revoke-student-button:first').click() - request = jasmine.Ajax.requests.mostRecent() - request.respondWith({ - status: 200 - responseText: '{}' - }) - - it 'updates the user and rerenders the page', -> - if @view.$(".enroll-student-button[data-user-id='#{@revokedUser.id}']").length isnt 1 - fail('Could not find enroll student button for user whose enrollment was revoked')