Commit 0646b5f5 by Greg Price

Refactor registration views to avoid shim

This also changes the registration API contract to use the course_id
parameter for analytics instead of an extra analytics parameter.
parent 291004de
...@@ -261,12 +261,8 @@ define([ ...@@ -261,12 +261,8 @@ define([
submitForm( true ); submitForm( true );
// Verify that the client sent the course ID for analytics // Verify that the client sent the course ID for analytics
var expectedData = {}; var expectedData = {course_id: COURSE_ID};
$.extend(expectedData, USER_DATA, { $.extend(expectedData, USER_DATA);
analytics: JSON.stringify({
enroll_course_id: COURSE_ID
})
});
AjaxHelpers.expectRequest( AjaxHelpers.expectRequest(
requests, 'POST', requests, 'POST',
......
...@@ -32,20 +32,17 @@ var edx = edx || {}; ...@@ -32,20 +32,17 @@ var edx = edx || {};
sync: function(method, model) { sync: function(method, model) {
var headers = { 'X-CSRFToken': $.cookie('csrftoken') }, var headers = { 'X-CSRFToken': $.cookie('csrftoken') },
data = {}, data = {},
analytics,
courseId = $.url( '?course_id' ); courseId = $.url( '?course_id' );
// If there is a course ID in the query string param, // If there is a course ID in the query string param,
// send that to the server as well so it can be included // send that to the server as well so it can be included
// in analytics events. // in analytics events.
if ( courseId ) { if ( courseId ) {
analytics = JSON.stringify({ data.course_id = decodeURIComponent(courseId);
enroll_course_id: decodeURIComponent( courseId )
});
} }
// Include all form fields and analytics info in the data sent to the server // Include all form fields and analytics info in the data sent to the server
$.extend( data, model.attributes, { analytics: analytics }); $.extend( data, model.attributes);
$.ajax({ $.ajax({
url: model.urlRoot, url: model.urlRoot,
......
...@@ -374,16 +374,6 @@ def shim_student_view(view_func, check_logged_in=False): ...@@ -374,16 +374,6 @@ def shim_student_view(view_func, check_logged_in=False):
) )
) )
# Backwards compatibility: the student view expects both
# terms of service and honor code values. Since we're combining
# these into a single checkbox, the only value we may get
# from the new view is "honor_code".
# Longer term, we will need to make this more flexible to support
# open source installations that may have separate checkboxes
# for TOS, privacy policy, etc.
if request.POST.get("honor_code") is not None and request.POST.get("terms_of_service") is None:
request.POST["terms_of_service"] = request.POST.get("honor_code")
# Call the original view to generate a response. # Call the original view to generate a response.
# We can safely modify the status code or content # We can safely modify the status code or content
# of the response, but to be safe we won't mess # of the response, but to be safe we won't mess
......
...@@ -1233,6 +1233,7 @@ class RegistrationViewTest(ApiTestCase): ...@@ -1233,6 +1233,7 @@ class RegistrationViewTest(ApiTestCase):
"honor_code": "true", "honor_code": "true",
}) })
self.assertHttpOK(response) self.assertHttpOK(response)
self.assertIn(settings.EDXMKTG_COOKIE_NAME, self.client.cookies)
# Verify that the user exists # Verify that the user exists
self.assertEqual( self.assertEqual(
......
...@@ -8,7 +8,7 @@ from django.conf import settings ...@@ -8,7 +8,7 @@ from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.http import HttpResponse from django.http import HttpResponse
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect
...@@ -25,7 +25,9 @@ from django_comment_common.models import Role ...@@ -25,7 +25,9 @@ from django_comment_common.models import Role
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
from edxmako.shortcuts import marketing_link from edxmako.shortcuts import marketing_link
from student.views import create_account_with_params, set_marketing_cookie
from util.authentication import SessionAuthenticationAllowInactiveUser from util.authentication import SessionAuthenticationAllowInactiveUser
from util.json_request import JsonResponse
from .api import account as account_api, profile as profile_api from .api import account as account_api, profile as profile_api
from .helpers import FormDescription, shim_student_view, require_post_params from .helpers import FormDescription, shim_student_view, require_post_params
from .models import UserPreference, UserProfile from .models import UserPreference, UserProfile
...@@ -232,10 +234,8 @@ class RegistrationView(APIView): ...@@ -232,10 +234,8 @@ class RegistrationView(APIView):
You must send all required form fields with the request. You must send all required form fields with the request.
You can optionally send an `analytics` param with a JSON-encoded You can optionally send a "course_id" param to indicate in analytics
object with additional info to include in the registration analytics event. events that the user registered while enrolling in a particular course.
Currently, the only supported field is "enroll_course_id" to indicate
that the user registered while enrolling in a particular course.
Arguments: Arguments:
request (HTTPRequest) request (HTTPRequest)
...@@ -243,11 +243,13 @@ class RegistrationView(APIView): ...@@ -243,11 +243,13 @@ class RegistrationView(APIView):
Returns: Returns:
HttpResponse: 200 on success HttpResponse: 200 on success
HttpResponse: 400 if the request is not valid. HttpResponse: 400 if the request is not valid.
HttpResponse: 302 if redirecting to another page. HttpResponse: 409 if an account with the given username or email
address already exists
""" """
email = request.POST.get('email') data = request.POST.copy()
username = request.POST.get('username')
email = data.get('email')
username = data.get('username')
# Handle duplicate email/username # Handle duplicate email/username
conflicts = account_api.check_account_exists(email=email, username=username) conflicts = account_api.check_account_exists(email=email, username=username)
...@@ -278,10 +280,29 @@ class RegistrationView(APIView): ...@@ -278,10 +280,29 @@ class RegistrationView(APIView):
content_type="text/plain" content_type="text/plain"
) )
# For the initial implementation, shim the existing login view # Backwards compatibility: the student view expects both
# from the student Django app. # terms of service and honor code values. Since we're combining
from student.views import create_account # these into a single checkbox, the only value we may get
return shim_student_view(create_account)(request) # from the new view is "honor_code".
# Longer term, we will need to make this more flexible to support
# open source installations that may have separate checkboxes
# for TOS, privacy policy, etc.
if data.get("honor_code") and "terms_of_service" not in data:
data["terms_of_service"] = data["honor_code"]
try:
create_account_with_params(request, data)
except ValidationError as err:
error_list = next(err.message_dict.itervalues())
return HttpResponse(
status=400,
content=error_list[0],
content_type="text/plain"
)
response = JsonResponse({"success": True})
set_marketing_cookie(request, response)
return response
def _add_email_field(self, form_desc, required=True): def _add_email_field(self, form_desc, required=True):
"""Add an email field to a form description. """Add an email field to a form description.
......
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