diff --git a/common/djangoapps/course_modes/tests/test_views.py b/common/djangoapps/course_modes/tests/test_views.py
index 30b242671b..ec0e16dc63 100644
--- a/common/djangoapps/course_modes/tests/test_views.py
+++ b/common/djangoapps/course_modes/tests/test_views.py
@@ -31,6 +31,7 @@ class CourseModeViewTest(ModuleStoreTestCase):
self.user = UserFactory.create(username="Bob", email="bob@example.com", password="edx")
self.client.login(username=self.user.username, password="edx")
+ @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
@ddt.data(
# is_active?, enrollment_mode, upgrade?, redirect?
(True, 'verified', True, False), # User has an active verified enrollment and is trying to upgrade
diff --git a/common/djangoapps/course_modes/views.py b/common/djangoapps/course_modes/views.py
index b70e9e3028..eb0e5c4816 100644
--- a/common/djangoapps/course_modes/views.py
+++ b/common/djangoapps/course_modes/views.py
@@ -26,10 +26,10 @@ class ChooseModeView(View):
When a get request is used, shows the selection page.
- When a post request is used, assumes that it is a form submission
+ When a post request is used, assumes that it is a form submission
from the selection page, parses the response, and then sends user
to the next step in the flow.
-
+
"""
@method_decorator(login_required)
@@ -50,7 +50,7 @@ class ChooseModeView(View):
"""
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(request.user, course_key)
-
+
upgrade = request.GET.get('upgrade', False)
request.session['attempting_upgrade'] = upgrade
diff --git a/common/djangoapps/enrollment/data.py b/common/djangoapps/enrollment/data.py
index f72c5fcb01..82db6734fa 100644
--- a/common/djangoapps/enrollment/data.py
+++ b/common/djangoapps/enrollment/data.py
@@ -73,7 +73,7 @@ def update_course_enrollment(student_id, course_id, mode=None, is_active=None):
course_key = CourseKey.from_string(course_id)
student = User.objects.get(username=student_id)
if not CourseEnrollment.is_enrolled(student, course_key):
- enrollment = CourseEnrollment.enroll(student, course_key)
+ enrollment = CourseEnrollment.enroll(student, course_key, check_access=True)
else:
enrollment = CourseEnrollment.objects.get(user=student, course_id=course_key)
diff --git a/common/djangoapps/enrollment/views.py b/common/djangoapps/enrollment/views.py
index 9546403c27..eea296ce4f 100644
--- a/common/djangoapps/enrollment/views.py
+++ b/common/djangoapps/enrollment/views.py
@@ -10,7 +10,7 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
from enrollment import api
-from student.models import NonExistentCourseError
+from student.models import NonExistentCourseError, CourseEnrollmentException
class EnrollmentUserThrottle(UserRateThrottle):
@@ -74,3 +74,5 @@ def get_course_enrollment(request, course_id=None):
return Response(status=status.HTTP_400_BAD_REQUEST)
except api.EnrollmentNotFoundError:
return Response(status=status.HTTP_400_BAD_REQUEST)
+ except CourseEnrollmentException:
+ return Response(status=status.HTTP_400_BAD_REQUEST)
diff --git a/lms/envs/common.py b/lms/envs/common.py
index 588abf375b..b62672c1fd 100644
--- a/lms/envs/common.py
+++ b/lms/envs/common.py
@@ -1028,6 +1028,7 @@ instructor_dash_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/ins
student_account_js = [
'js/common_helpers/rwd_header_footer.js',
'js/common_helpers/edx.utils.validate.js',
+ 'js/student_account/enrollment_interface.js',
'js/student_account/models/LoginModel.js',
'js/student_account/models/RegisterModel.js',
'js/student_account/models/PasswordResetModel.js',
diff --git a/lms/static/js/spec/main.js b/lms/static/js/spec/main.js
index 20e41a02a5..b246460f92 100644
--- a/lms/static/js/spec/main.js
+++ b/lms/static/js/spec/main.js
@@ -260,7 +260,10 @@
exports: 'NotificationView',
deps: ['backbone', 'jquery', 'underscore']
},
-
+ 'js/student_account/enrollment_interface': {
+ exports: 'js/student_account/enrollment_interface',
+ deps: ['jquery', 'underscore', 'gettext']
+ },
// Student account registration/login
// Loaded explicitly until these are converted to RequireJS
'js/student_account/views/FormView': {
@@ -310,7 +313,7 @@
'js/student_account/views/RegisterView',
'underscore.string'
]
- },
+ }
},
});
@@ -327,6 +330,7 @@
'lms/include/js/spec/student_account/login_spec.js',
'lms/include/js/spec/student_account/register_spec.js',
'lms/include/js/spec/student_account/password_reset_spec.js',
+ 'lms/include/js/spec/student_account/enrollment_interface_spec.js',
'lms/include/js/spec/student_profile/profile.js',
]);
diff --git a/lms/static/js/spec/student_account/access_spec.js b/lms/static/js/spec/student_account/access_spec.js
index ecba86b2fe..9915060819 100644
--- a/lms/static/js/spec/student_account/access_spec.js
+++ b/lms/static/js/spec/student_account/access_spec.js
@@ -1,5 +1,5 @@
define(['js/common_helpers/template_helpers', 'js/student_account/views/AccessView'],
- function(TemplateHelpers) {
+ function(TemplateHelpers, AccessView) {
describe('edx.student.account.AccessView', function() {
'use strict';
diff --git a/lms/static/js/spec/student_account/enrollment_interface_spec.js b/lms/static/js/spec/student_account/enrollment_interface_spec.js
new file mode 100644
index 0000000000..eb0d98d022
--- /dev/null
+++ b/lms/static/js/spec/student_account/enrollment_interface_spec.js
@@ -0,0 +1,22 @@
+define(['js/common_helpers/template_helpers', 'js/student_account/enrollment_interface'],
+ function(TemplateHelpers, EnrollmentInterface) {
+ describe("edx.student.account.EnrollmentInterface", function() {
+ 'use strict';
+
+ it("find course modes using modeInArray ", function() {
+ var course_modes = [
+ {
+ slug: 'honor'
+ },
+ {
+ slug: 'professional'
+ }
+ ],
+
+ expect(EnrollmentInterface.modeInArray('professional')).toBe(true);
+ expect(EnrollmentInterface.modeInArray('audit')).toBe(false);
+
+ });
+ });
+ }
+);
diff --git a/lms/static/js/spec/student_account/login_spec.js b/lms/static/js/spec/student_account/login_spec.js
index 190972acb9..9f8ff48f2b 100644
--- a/lms/static/js/spec/student_account/login_spec.js
+++ b/lms/static/js/spec/student_account/login_spec.js
@@ -39,6 +39,10 @@ define(['js/common_helpers/template_helpers', 'js/student_account/views/LoginVie
it("allows the user to navigate to the password assistance form", function() {
// TODO
});
+
+ it("enrolls the student into the right location and forwards them properly", function() {
+ // TODO
+ });
});
}
);
diff --git a/lms/static/js/student_account/enrollment_interface.js b/lms/static/js/student_account/enrollment_interface.js
new file mode 100644
index 0000000000..09aa02360d
--- /dev/null
+++ b/lms/static/js/student_account/enrollment_interface.js
@@ -0,0 +1,78 @@
+var edx = edx || {};
+
+(function($, _, gettext) {
+ 'use strict';
+
+ edx.student = edx.student || {};
+ edx.student.account = edx.student.account || {};
+
+ edx.student.account.EnrollmentInterface = {
+ courseUrl: '/enrollment/v0/course/',
+ studentUrl: '/enrollment/v0/student',
+ trackSelectionUrl: '/course_modes/choose/',
+ headers: {
+ 'X-CSRFToken': $.cookie('csrftoken')
+ },
+
+ studentInformation: function(course_key) {
+ // retrieve student enrollment information
+ },
+
+ courseInformation: function(course_key) {
+ // retrieve course information from the enrollment API
+ },
+
+ modeInArray: function(mode_slug, course_modes) {
+ // finds whether or not a particular course mode slug exists
+ // in an array of course modes
+ var result = _.find(course_modes, function(mode){ return mode.slug === mode_slug; });
+ return result != undefined;
+ },
+
+ enroll: function(course_key, forward_url){
+ var me = this;
+ // attempt to enroll a student in a course
+ $.ajax({
+ url: this.courseUrl + course_key,
+ type: 'POST',
+ data: {},
+ headers: this.headers
+ }).done(function(data){
+ me.postEnrollmentHandler(course_key, data, forward_url);
+ }
+ ).fail(function(data, textStatus) {
+ me.enrollmentFailureHandler(course_key, data, forward_url);
+ });
+ },
+
+ enrollmentFailureHandler: function(course_key, data, forward_url) {
+ // handle failures to enroll via the API
+ if(data.status == 400) {
+ // This status code probably means we don't have permissions to register for this course.
+ // look at the contents of the response
+ var course = $.parseJSON(data.responseText);
+ // see if it's a professional ed course
+ if('course_modes' in course && this.modeInArray('professional', course.course_modes)) {
+ // forward appropriately
+ forward_url = this.trackSelectionUrl + course_key;
+ }
+ }
+ // TODO: if we have a paid registration mode, add item to the cart and send them along
+
+ // TODO: we should figure out how to handle errors here eventually
+ window.location.href = forward_url;
+ },
+
+ postEnrollmentHandler: function(course_key, data, forward_url) {
+ // Determine whether or not the course needs to be redirected to
+ // a particular page.
+ var course = data.course,
+ course_modes = course.course_modes;
+
+ // send the user to the track selection page, because it will do the right thing
+ forward_url = this.trackSelectionUrl + course_key;
+
+ window.location.href = forward_url;
+ }
+ };
+})(jQuery, _, gettext);
diff --git a/lms/static/js/student_account/models/LoginModel.js b/lms/static/js/student_account/models/LoginModel.js
index 22f46db41a..f852d01c71 100644
--- a/lms/static/js/student_account/models/LoginModel.js
+++ b/lms/static/js/student_account/models/LoginModel.js
@@ -6,6 +6,7 @@ var edx = edx || {};
edx.student = edx.student || {};
edx.student.account = edx.student.account || {};
+
edx.student.account.LoginModel = Backbone.Model.extend({
defaults: {
@@ -32,17 +33,31 @@ var edx = edx || {};
headers: headers
})
.done(function() {
- var query = window.location.search,
- url = '/dashboard';
+ var enrollment = edx.student.account.EnrollmentInterface,
+ query = new URI(window.location.search),
+ url = '/dashboard',
+ query_map = query.search(true),
+ next = '';
+
+ // check for forwarding url
+ if("next" in query_map) {
+ next = query_map['next'];
+ if(!window.isExternal(next)){
+ url = next;
+ }
+ }
model.trigger('sync');
- // If query string in url go back to that page
- if ( query.length > 1 ) {
- url = query.substring( query.indexOf('=') + 1 );
+ // if we need to enroll in the course, mark as enrolled
+ if('enrollment_action' in query_map && query_map['enrollment_action'] === 'enroll'){
+ enrollment.enroll(query_map['course_id'], url);
+ }
+ else {
+ window.location.href = url;
}
- window.location.href = url;
+
})
.fail( function( error ) {
model.trigger('error', error);
diff --git a/lms/static/js/student_account/models/RegisterModel.js b/lms/static/js/student_account/models/RegisterModel.js
index b5f93774b7..3e36e9b727 100644
--- a/lms/static/js/student_account/models/RegisterModel.js
+++ b/lms/static/js/student_account/models/RegisterModel.js
@@ -39,17 +39,29 @@ var edx = edx || {};
headers: headers
})
.done(function() {
- var query = window.location.search,
- url = '/dashboard';
+ var enrollment = edx.student.account.EnrollmentInterface,
+ query = new URI(window.location.search),
+ url = '/dashboard',
+ query_map = query.search(true),
+ next = '';
+
+ // check for forwarding url
+ if("next" in query_map) {
+ next = query_map['next'];
+ if(!window.isExternal(next)){
+ url = next;
+ }
+ }
model.trigger('sync');
- // If query string in url go back to that page
- if ( query.length > 1 ) {
- url = query.substring( query.indexOf('=') + 1 );
+ // if we need to enroll in the course, mark as enrolled
+ if('enrollment_action' in query_map && query_map['enrollment_action'] === 'enroll'){
+ enrollment.enroll(query_map['course_id'], url);
+ }
+ else {
+ window.location.href = url;
}
-
- window.location.href = url;
})
.fail( function( error ) {
model.trigger('error', error);
diff --git a/lms/templates/student_account/login_and_register.html b/lms/templates/student_account/login_and_register.html
index 6cc9dcf12b..debe7910fe 100644
--- a/lms/templates/student_account/login_and_register.html
+++ b/lms/templates/student_account/login_and_register.html
@@ -8,6 +8,7 @@
<%block name="js_extra">
+
<%static:js group='student_account'/>
%block>