diff --git a/lms/djangoapps/courseware/features/registration.feature b/lms/djangoapps/courseware/features/registration.feature index fe270a3f85..60b094de48 100644 --- a/lms/djangoapps/courseware/features/registration.feature +++ b/lms/djangoapps/courseware/features/registration.feature @@ -11,13 +11,3 @@ Feature: LMS.Register for a course When I register for the course "6.002x" Then I should see the course numbered "6.002x" in my dashboard And a "edx.course.enrollment.activated" server event is emitted - - Scenario: I can unenroll from a course - Given I am registered for the course "6.002x" - And I visit the dashboard - Then I should see the course numbered "6.002x" in my dashboard - When I unenroll from the course numbered "6.002x" - Then I should be on the dashboard page - And I should see an empty dashboard message - And I should NOT see the course numbered "6.002x" in my dashboard - And a "edx.course.enrollment.deactivated" server event is emitted diff --git a/lms/static/js/dashboard/legacy.js b/lms/static/js/dashboard/legacy.js index 80402ec519..a2c3a4a4db 100644 --- a/lms/static/js/dashboard/legacy.js +++ b/lms/static/js/dashboard/legacy.js @@ -191,20 +191,6 @@ $('#unenroll-modal').css('position', 'fixed'); }); - $('#unenroll_form').on('ajax:complete', function(event, xhr) { - if (xhr.status === 200) { - location.href = urls.dashboard; - } else if (xhr.status === 403) { - location.href = urls.signInUser + '?course_id=' + - encodeURIComponent($('#unenroll_course_id').val()) + '&enrollment_action=unenroll'; - } else { - $('#unenroll_error').text( - xhr.responseText ? xhr.responseText : gettext('An error occurred. Please try again later.') - ).stop() - .css('display', 'block'); - } - }); - $('#email_settings_form').submit(function() { $.ajax({ type: 'POST', diff --git a/lms/static/js/learner_dashboard/unenrollment_factory.js b/lms/static/js/learner_dashboard/unenrollment_factory.js new file mode 100644 index 0000000000..4afca20bbb --- /dev/null +++ b/lms/static/js/learner_dashboard/unenrollment_factory.js @@ -0,0 +1,13 @@ +(function(define) { + 'use strict'; + + define([ + 'js/learner_dashboard/views/unenroll_view' + ], + function(UnenrollView) { + return function(options) { + var Unenroll = new UnenrollView(options); + return Unenroll; + }; + }); +}).call(this, define || RequireJS.define); diff --git a/lms/static/js/learner_dashboard/views/unenroll_view.js b/lms/static/js/learner_dashboard/views/unenroll_view.js new file mode 100644 index 0000000000..ab52dfe83e --- /dev/null +++ b/lms/static/js/learner_dashboard/views/unenroll_view.js @@ -0,0 +1,78 @@ +(function(define) { + 'use strict'; + define(['backbone', + 'jquery', + 'underscore', + 'gettext', + 'edx-ui-toolkit/js/utils/html-utils' + ], + function( + Backbone, + $, + _, + gettext, + HtmlUtils + ) { + return Backbone.View.extend({ + el: '.unenroll-modal', + + switchToSlideOne: function() { + var survey, i, + reasonsSurvey = HtmlUtils.HTML($('.reasons_survey')); + // Randomize survey option order + survey = document.querySelector('.options'); + for (i = survey.children.length - 1; i >= 0; i--) { + survey.appendChild(survey.children[Math.random() * i | 0]); + } + $('.inner-wrapper header').hide(); + $('#unenroll_form').after(HtmlUtils.ensureHtml(reasonsSurvey).toString()).hide(); + $('.reasons_survey .slide1').removeClass('hidden'); + }, + + switchToSlideTwo: function() { + var reason = $(".reasons_survey input[name='reason']:checked").attr('val'); + if (reason === 'Other') { + reason = $('.other_text').val(); + } + if (reason) { + window.analytics.track('unenrollment_reason.selected', { + category: 'user-engagement', + label: reason, + displayName: 'v1' + }); + } + HtmlUtils.setHtml($('.reasons_survey'), HtmlUtils.HTML($('.slide2').html())); + $('.reasons_survey .return_to_dashboard').attr('href', this.urls.dashboard); + $('.reasons_survey .browse_courses').attr('href', this.urls.browseCourses); + }, + + unenrollComplete: function(event, xhr) { + if (xhr.status === 200) { + if (!this.isEdx) { + location.href = this.urls.dashboard; + } else { + this.switchToSlideOne(); + $('.submit_reasons').click(this.switchToSlideTwo.bind(this)); + } + } else if (xhr.status === 403) { + location.href = this.urls.signInUser + '?course_id=' + + encodeURIComponent($('#unenroll_course_id').val()) + '&enrollment_action=unenroll'; + } else { + $('#unenroll_error').text( + gettext('Unable to determine whether we should give you a refund because' + + ' of System Error. Please try again later.') + ).stop() + .css('display', 'block'); + } + }, + + initialize: function(options) { + this.urls = options.urls; + this.isEdx = options.isEdx; + + $('#unenroll_form').on('ajax:complete', this.unenrollComplete.bind(this)); + } + }); + } + ); +}).call(this, define || RequireJS.define); diff --git a/lms/static/js/spec/learner_dashboard/unenroll_view_spec.js b/lms/static/js/spec/learner_dashboard/unenroll_view_spec.js new file mode 100644 index 0000000000..1aa0c8efc9 --- /dev/null +++ b/lms/static/js/spec/learner_dashboard/unenroll_view_spec.js @@ -0,0 +1,46 @@ +define([ + 'backbone', + 'js/learner_dashboard/views/unenroll_view' +], function(Backbone, UnenrollView) { + 'use strict'; + + describe('Unenroll View', function() { + var view = null, + options = { + urls: { + dashboard: '/dashboard', + browseCourses: '/courses' + }, + isEdx: true + }, + initView; + + initView = function() { + return new UnenrollView(options); + }; + + beforeEach(function() { + setFixtures('
'); // eslint-disable-line max-len + }); + + afterEach(function() { + view.remove(); + }); + + it('should exist', function() { + view = initView(); + expect(view).toBeDefined(); + }); + + it('switch between slides', function() { + view = initView(); + expect($('.slide1').hasClass('hidden')).toEqual(true); + view.switchToSlideOne(); + expect($('.slide1').hasClass('hidden')).toEqual(false); + expect($('.slide2').hasClass('hidden')).toEqual(true); + view.switchToSlideTwo(); + expect($('.slide2').hasClass('hidden')).toEqual(true); + }); + }); +} +); diff --git a/lms/static/lms/js/build.js b/lms/static/lms/js/build.js index c2141007e0..b4a74f5a52 100644 --- a/lms/static/lms/js/build.js +++ b/lms/static/lms/js/build.js @@ -32,6 +32,7 @@ 'js/groups/views/cohorts_dashboard_factory', 'js/discussions_management/views/discussions_dashboard_factory', 'js/header_factory', + 'js/learner_dashboard/unenrollment_factory', 'js/learner_dashboard/program_details_factory', 'js/learner_dashboard/program_list_factory', 'js/student_account/logistration_factory', diff --git a/lms/static/lms/js/spec/main.js b/lms/static/lms/js/spec/main.js index e377f28e31..954a962606 100644 --- a/lms/static/lms/js/spec/main.js +++ b/lms/static/lms/js/spec/main.js @@ -759,6 +759,7 @@ 'js/spec/learner_dashboard/program_details_header_spec.js', 'js/spec/learner_dashboard/program_details_view_spec.js', 'js/spec/learner_dashboard/program_details_sidebar_view_spec.js', + 'js/spec/learner_dashboard/unenroll_view_spec.js', 'js/spec/learner_dashboard/course_card_view_spec.js', 'js/spec/learner_dashboard/course_enroll_view_spec.js', 'js/spec/markdown_editor_spec.js', diff --git a/lms/static/sass/multicourse/_dashboard.scss b/lms/static/sass/multicourse/_dashboard.scss index 0b3c9e4752..d27b5be8af 100644 --- a/lms/static/sass/multicourse/_dashboard.scss +++ b/lms/static/sass/multicourse/_dashboard.scss @@ -1498,3 +1498,55 @@ a.fade-cover{ } } } + +#unenroll-modal { + margin-top: -60px; +} + +.reasons_survey { + padding: 20px; + + .options { + list-style: none; + padding: 0; + } + + .option { + margin-bottom: 10px; + display: block; + } + + input { + margin-right: 10px; + } + + .unenroll-header { + background-image: none; + } + + .other_text { + margin-top: 0; + } + + .other_radio { + margin-top: 10px; + } + + .submit_reasons { + margin-top: 10px; + } + + .survey_button { + width: 30%; + margin-top: 10px; + margin-left: 2.5%; + margin-right: 2.5%; + color: $white; + } + + .survey_button:visited, .survey_button:hover, .survey_button:focus { + color: $white; + text-decoration: none; + } + +} diff --git a/lms/templates/dashboard.html b/lms/templates/dashboard.html index 552d815e3b..13765bdd02 100644 --- a/lms/templates/dashboard.html +++ b/lms/templates/dashboard.html @@ -42,6 +42,17 @@ from openedx.core.djangolib.markup import HTML, Text }); }); + <%static:require_module module_name="js/learner_dashboard/unenrollment_factory" class_name="UnenrollmentFactory"> + UnenrollmentFactory({ + urls: { + dashboard: "${reverse('dashboard') | n, js_escaped_string}", + signInUser: "${reverse('signin_user') | n, js_escaped_string}", + changeEmailSettings: "${reverse('change_email_settings') | n, js_escaped_string}", + browseCourses: "${marketing_link('COURSES') | n, js_escaped_string}" + }, + isEdx: false + }); + %static:require_module> % if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'): <%static:require_module module_name="course_search/js/dashboard_search_factory" class_name="DashboardSearchFactory"> DashboardSearchFactory(); @@ -244,7 +255,7 @@ from openedx.core.djangolib.markup import HTML, Text -