Merge pull request #7453 from edx/will/ecom-1198
ECOM-1198: Login/Registration page can skip track selection.
This commit is contained in:
@@ -246,12 +246,25 @@ class StudentAccountLoginAndRegistrationTest(UrlResetMixin, ModuleStoreTestCase)
|
||||
'course_id': 'edX/DemoX/Demo_Course'
|
||||
}
|
||||
|
||||
# The response should have a "Sign In" button with the URL
|
||||
# that preserves the querystring params
|
||||
with mock.patch.dict(settings.FEATURES, {'IS_EDX_DOMAIN': is_edx_domain}):
|
||||
response = self.client.get(reverse(url_name), params)
|
||||
self.assertContains(response, "login?course_id=edX%2FDemoX%2FDemo_Course&enrollment_action=enroll")
|
||||
|
||||
# Add an additional "course mode" parameter
|
||||
params['course_mode'] = 'honor'
|
||||
|
||||
# Verify that this parameter is also preserved
|
||||
with mock.patch.dict(settings.FEATURES, {'IS_EDX_DOMAIN': is_edx_domain}):
|
||||
response = self.client.get(reverse(url_name), params)
|
||||
|
||||
# The response should have a "Sign In" button with the URL
|
||||
# that preserves the querystring params
|
||||
self.assertContains(response, "login?course_id=edX%2FDemoX%2FDemo_Course&enrollment_action=enroll")
|
||||
expected_url = (
|
||||
"login?course_id=edX%2FDemoX%2FDemo_Course"
|
||||
"&enrollment_action=enroll"
|
||||
"&course_mode=honor"
|
||||
)
|
||||
self.assertContains(response, expected_url)
|
||||
|
||||
@mock.patch.dict(settings.FEATURES, {"ENABLE_THIRD_PARTY_AUTH": False})
|
||||
@ddt.data("account_login", "account_register")
|
||||
|
||||
@@ -91,7 +91,8 @@ def login_and_registration_form(request, initial_mode="login"):
|
||||
# We need to pass these parameters so that the header's
|
||||
# "Sign In" button preserves the querystring params.
|
||||
'enrollment_action': request.GET.get('enrollment_action'),
|
||||
'course_id': request.GET.get('course_id')
|
||||
'course_id': request.GET.get('course_id'),
|
||||
'course_mode': request.GET.get('course_mode'),
|
||||
}
|
||||
|
||||
return render_to_response('student_account/login_and_register.html', context)
|
||||
|
||||
@@ -166,7 +166,52 @@ define([
|
||||
view.subview.login.trigger('auth-complete');
|
||||
|
||||
// Expect that the view tried to enroll the student
|
||||
expect( EnrollmentInterface.enroll ).toHaveBeenCalledWith( COURSE_KEY );
|
||||
expect( EnrollmentInterface.enroll ).toHaveBeenCalledWith(
|
||||
COURSE_KEY,
|
||||
'/course_modes/choose/' + COURSE_KEY + '/'
|
||||
);
|
||||
});
|
||||
|
||||
it('sends the user to the payment flow when the course mode is not honor', function() {
|
||||
ajaxSpyAndInitialize(this, 'login');
|
||||
|
||||
// Simulate providing enrollment query string params
|
||||
// AND specifying a course mode.
|
||||
setFakeQueryParams({
|
||||
'?enrollment_action': 'enroll',
|
||||
'?course_id': COURSE_KEY,
|
||||
'?course_mode': 'verified'
|
||||
});
|
||||
|
||||
// Trigger auth complete on the login view
|
||||
view.subview.login.trigger('auth-complete');
|
||||
|
||||
// Expect that the view tried to auto-enroll the student
|
||||
// with a redirect into the payment flow.
|
||||
expect( EnrollmentInterface.enroll ).toHaveBeenCalledWith(
|
||||
COURSE_KEY,
|
||||
'/verify_student/start-flow/' + COURSE_KEY + '/'
|
||||
);
|
||||
});
|
||||
|
||||
it('sends the user to the student dashboard when the course mode is honor', function() {
|
||||
ajaxSpyAndInitialize(this, 'login');
|
||||
|
||||
// Simulate providing enrollment query string params
|
||||
// AND specifying a course mode.
|
||||
setFakeQueryParams({
|
||||
'?enrollment_action': 'enroll',
|
||||
'?course_id': COURSE_KEY,
|
||||
'?course_mode': 'honor'
|
||||
});
|
||||
|
||||
// Trigger auth complete on the login view
|
||||
view.subview.login.trigger('auth-complete');
|
||||
|
||||
// Expect that the view tried auto-enrolled the student
|
||||
// and sent the student to the dashboard
|
||||
// (skipping the payment flow).
|
||||
expect( EnrollmentInterface.enroll ).toHaveBeenCalledWith(COURSE_KEY, '/dashboard');
|
||||
});
|
||||
|
||||
it('adds a white-label course to the shopping cart on auth complete', function() {
|
||||
|
||||
@@ -19,7 +19,7 @@ define(['js/common_helpers/ajax_helpers', 'js/student_account/enrollment'],
|
||||
var requests = AjaxHelpers.requests( this );
|
||||
|
||||
// Attempt to enroll the user
|
||||
EnrollmentInterface.enroll( COURSE_KEY );
|
||||
EnrollmentInterface.enroll( COURSE_KEY, FORWARD_URL );
|
||||
|
||||
// Expect that the correct request was made to the server
|
||||
AjaxHelpers.expectRequest(
|
||||
@@ -41,7 +41,7 @@ define(['js/common_helpers/ajax_helpers', 'js/student_account/enrollment'],
|
||||
var requests = AjaxHelpers.requests( this );
|
||||
|
||||
// Attempt to enroll the user
|
||||
EnrollmentInterface.enroll( COURSE_KEY );
|
||||
EnrollmentInterface.enroll( COURSE_KEY, FORWARD_URL );
|
||||
|
||||
// Simulate an error response from the server
|
||||
AjaxHelpers.respondWithError(requests);
|
||||
@@ -55,7 +55,7 @@ define(['js/common_helpers/ajax_helpers', 'js/student_account/enrollment'],
|
||||
var requests = AjaxHelpers.requests( this );
|
||||
|
||||
// Attempt to enroll the user
|
||||
EnrollmentInterface.enroll( COURSE_KEY );
|
||||
EnrollmentInterface.enroll( COURSE_KEY, FORWARD_URL );
|
||||
|
||||
// Simulate an error response (403) from the server
|
||||
// with a "user_message_url" parameter for the redirect.
|
||||
|
||||
@@ -10,7 +10,6 @@ var edx = edx || {};
|
||||
|
||||
urls: {
|
||||
orders: '/commerce/orders/',
|
||||
trackSelection: '/course_modes/choose/'
|
||||
},
|
||||
|
||||
headers: {
|
||||
@@ -18,11 +17,11 @@ var edx = edx || {};
|
||||
},
|
||||
|
||||
/**
|
||||
* Enroll a user in a course, then redirect the user
|
||||
* to the track selection page.
|
||||
* Enroll a user in a course, then redirect the user.
|
||||
* @param {string} courseKey Slash-separated course key.
|
||||
* @param {string} redirectUrl The URL to redirect to once enrollment completes.
|
||||
*/
|
||||
enroll: function( courseKey ) {
|
||||
enroll: function( courseKey, redirectUrl ) {
|
||||
var data_obj = {course_id: courseKey},
|
||||
data = JSON.stringify(data_obj);
|
||||
|
||||
@@ -42,30 +41,22 @@ var edx = edx || {};
|
||||
// If so, redirect to a page explaining to the user
|
||||
// why they were blocked.
|
||||
this.redirect( responseData.user_message_url );
|
||||
}
|
||||
else {
|
||||
// Otherwise, go to the track selection page as usual.
|
||||
// This can occur, for example, when a course does not
|
||||
// have a free enrollment mode, so we can't auto-enroll.
|
||||
this.redirect( this.trackSelectionUrl( courseKey ) );
|
||||
} else {
|
||||
// Otherwise, redirect the user to the next page.
|
||||
if ( redirectUrl ) {
|
||||
this.redirect( redirectUrl );
|
||||
}
|
||||
}
|
||||
})
|
||||
.done(function() {
|
||||
// If we successfully enrolled, go to the track selection
|
||||
// page to allow the user to choose a paid enrollment mode.
|
||||
this.redirect( this.trackSelectionUrl( courseKey ) );
|
||||
// If we successfully enrolled, redirect the user
|
||||
// to the next page (usually the student dashboard or payment flow)
|
||||
if ( redirectUrl ) {
|
||||
this.redirect( redirectUrl );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Construct the URL to the track selection page for a course.
|
||||
* @param {string} courseKey Slash-separated course key.
|
||||
* @return {string} The URL to the track selection page.
|
||||
*/
|
||||
trackSelectionUrl: function( courseKey ) {
|
||||
return this.urls.trackSelection + courseKey + '/';
|
||||
},
|
||||
|
||||
/**
|
||||
* Redirect to a URL. Mainly useful for mocking out in tests.
|
||||
* @param {string} url The URL to redirect to.
|
||||
|
||||
@@ -29,6 +29,12 @@ var edx = edx || {};
|
||||
passwordHelp: {}
|
||||
},
|
||||
|
||||
urls: {
|
||||
dashboard: '/dashboard',
|
||||
payment: '/verify_student/start-flow/',
|
||||
trackSelection: '/course_modes/choose/'
|
||||
},
|
||||
|
||||
// The form currently loaded
|
||||
activeForm: '',
|
||||
|
||||
@@ -243,15 +249,37 @@ var edx = edx || {};
|
||||
enrollment: function() {
|
||||
var enrollment = edx.student.account.EnrollmentInterface,
|
||||
shoppingcart = edx.student.account.ShoppingCartInterface,
|
||||
redirectUrl = '/dashboard',
|
||||
redirectUrl = this.urls.dashboard,
|
||||
queryParams = this.queryParams();
|
||||
|
||||
if ( queryParams.enrollmentAction === 'enroll' && queryParams.courseId) {
|
||||
/*
|
||||
If we need to enroll in a course, mark as enrolled.
|
||||
The enrollment interface will redirect the student once enrollment completes.
|
||||
*/
|
||||
enrollment.enroll( decodeURIComponent( queryParams.courseId ) );
|
||||
if ( queryParams.enrollmentAction === 'enroll' && queryParams.courseId ) {
|
||||
var courseId = decodeURIComponent( queryParams.courseId );
|
||||
|
||||
// Determine where to redirect the user after auto-enrollment.
|
||||
if ( !queryParams.courseMode ) {
|
||||
/* Backwards compatibility with the original course details page.
|
||||
The old implementation did not specify the course mode for enrollment,
|
||||
so we'd always send the user to the "track selection" page.
|
||||
The track selection page would allow the user to select the course mode
|
||||
("verified", "honor", etc.) -- or, if the only course mode was "honor",
|
||||
it would redirect the user to the dashboard. */
|
||||
redirectUrl = this.urls.trackSelection + courseId + '/';
|
||||
} else if ( queryParams.courseMode === 'honor' || queryParams.courseMode === 'audit' ) {
|
||||
/* The newer version of the course details page allows the user
|
||||
to specify which course mode to enroll as. If the student has
|
||||
chosen "honor", we send them immediately to the dashboard
|
||||
rather than the payment flow. The user may decide to upgrade
|
||||
from the dashboard later. */
|
||||
redirectUrl = this.urls.dashboard;
|
||||
} else {
|
||||
/* If the user selected any other kind of course mode, send them
|
||||
to the payment/verification flow. */
|
||||
redirectUrl = this.urls.payment + courseId + '/';
|
||||
}
|
||||
|
||||
/* Attempt to auto-enroll the user in a free mode of the course,
|
||||
then redirect to the next location. */
|
||||
enrollment.enroll( courseId, redirectUrl );
|
||||
} else if ( queryParams.enrollmentAction === 'add_to_cart' && queryParams.courseId) {
|
||||
/*
|
||||
If this is a paid course, add it to the shopping cart and redirect
|
||||
@@ -298,6 +326,7 @@ var edx = edx || {};
|
||||
next: $.url( '?next' ),
|
||||
enrollmentAction: $.url( '?enrollment_action' ),
|
||||
courseId: $.url( '?course_id' ),
|
||||
courseMode: $.url( '?course_mode' ),
|
||||
emailOptIn: $.url( '?email_opt_in')
|
||||
};
|
||||
},
|
||||
|
||||
@@ -173,9 +173,13 @@
|
||||
</html>
|
||||
|
||||
<%def name="login_query()">${
|
||||
u"?course_id={0}&enrollment_action={1}{email_opt_in}".format(
|
||||
u"?course_id={0}&enrollment_action={1}{course_mode}{email_opt_in}".format(
|
||||
urlquote_plus(course_id),
|
||||
urlquote_plus(enrollment_action),
|
||||
course_mode=(
|
||||
u"&course_mode=" + urlquote_plus(course_mode)
|
||||
if course_mode else ""
|
||||
),
|
||||
email_opt_in=(
|
||||
u"&email_opt_in=" + urlquote_plus(email_opt_in)
|
||||
if email_opt_in else ""
|
||||
|
||||
Reference in New Issue
Block a user