Merge pull request #11712 from mitocw/enhancement/aq/prevent_ccx_creation_if_CCXConnector_is_set_mitocw#189
Prevented creation of new CCX in lms, when a CCXConnector URL is set on a course
This commit is contained in:
@@ -17,6 +17,7 @@ from courseware.tests.helpers import LoginEnrollmentTestCase
|
||||
from courseware.tabs import get_course_tab_list
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse, resolve
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.timezone import UTC
|
||||
from django.test.utils import override_settings
|
||||
from django.test import RequestFactory
|
||||
@@ -264,6 +265,29 @@ class TestCoachDashboard(CcxTestCase, LoginEnrollmentTestCase):
|
||||
'<form action=".+create_ccx"',
|
||||
response.content))
|
||||
|
||||
def test_create_ccx_with_ccx_connector_set(self):
|
||||
"""
|
||||
Assert that coach cannot create ccx when ``ccx_connector`` url is set.
|
||||
"""
|
||||
course = CourseFactory.create()
|
||||
course.ccx_connector = "http://ccx.com"
|
||||
course.save()
|
||||
self.store.update_item(course, 0)
|
||||
role = CourseCcxCoachRole(course.id)
|
||||
role.add_users(self.coach)
|
||||
|
||||
url = reverse(
|
||||
'create_ccx',
|
||||
kwargs={'course_id': unicode(course.id)})
|
||||
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
error_message = _(
|
||||
"A CCX can only be created on this course through an external service."
|
||||
" Contact a course admin to give you access."
|
||||
)
|
||||
self.assertTrue(re.search(error_message, response.content))
|
||||
|
||||
def test_create_ccx(self, ccx_name='New CCX'):
|
||||
"""
|
||||
Create CCX. Follow redirect to coach dashboard, confirm we see
|
||||
|
||||
@@ -12,6 +12,7 @@ from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.validators import validate_email
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from courseware.courses import get_course_by_id
|
||||
from courseware.model_data import FieldDataCache
|
||||
@@ -34,6 +35,28 @@ from lms.djangoapps.ccx.custom_exception import CCXUserValidationException
|
||||
log = logging.getLogger("edx.ccx")
|
||||
|
||||
|
||||
def get_ccx_creation_dict(course):
|
||||
"""
|
||||
Return dict of rendering create ccx form.
|
||||
|
||||
Arguments:
|
||||
course (CourseDescriptorWithMixins): An edx course
|
||||
|
||||
Returns:
|
||||
dict: A attribute dict for view rendering
|
||||
"""
|
||||
context = {
|
||||
'course': course,
|
||||
'create_ccx_url': reverse('create_ccx', kwargs={'course_id': course.id}),
|
||||
'has_ccx_connector': "true" if hasattr(course, 'ccx_connector') and course.ccx_connector else "false",
|
||||
'use_ccx_con_error_message': _(
|
||||
"A CCX can only be created on this course through an external service."
|
||||
" Contact a course admin to give you access."
|
||||
)
|
||||
}
|
||||
return context
|
||||
|
||||
|
||||
def get_ccx_from_ccx_locator(course_id):
|
||||
""" helper function to allow querying ccx fields from templates """
|
||||
ccx_id = getattr(course_id, 'ccx', None)
|
||||
|
||||
@@ -58,6 +58,7 @@ from lms.djangoapps.ccx.utils import (
|
||||
ccx_students_enrolling_center,
|
||||
get_ccx_for_coach,
|
||||
get_ccx_by_ccx_id,
|
||||
get_ccx_creation_dict,
|
||||
get_date,
|
||||
parse_date,
|
||||
prep_course_for_grading,
|
||||
@@ -132,6 +133,7 @@ def dashboard(request, course, ccx=None):
|
||||
'course': course,
|
||||
'ccx': ccx,
|
||||
}
|
||||
context.update(get_ccx_creation_dict(course))
|
||||
|
||||
if ccx:
|
||||
ccx_locator = CCXLocator.from_course_locator(course.id, unicode(ccx.id))
|
||||
@@ -168,6 +170,13 @@ def create_ccx(request, course, ccx=None):
|
||||
"""
|
||||
name = request.POST.get('name')
|
||||
|
||||
if hasattr(course, 'ccx_connector') and course.ccx_connector:
|
||||
# if ccx connector url is set in course settings then inform user that he can
|
||||
# only create ccx by using ccx connector url.
|
||||
context = get_ccx_creation_dict(course)
|
||||
messages.error(request, context['use_ccx_con_error_message'])
|
||||
return render_to_response('ccx/coach_dashboard.html', context)
|
||||
|
||||
# prevent CCX objects from being created for deprecated course ids.
|
||||
if course.id.deprecated:
|
||||
messages.error(request, _(
|
||||
|
||||
@@ -35,11 +35,16 @@ from django.core.urlresolvers import reverse
|
||||
</ul>
|
||||
% endif
|
||||
<section>
|
||||
<form action="${create_ccx_url}" method="POST">
|
||||
<p class="request-response-error" id="ccx-create-message"></p>
|
||||
<form action="${create_ccx_url}" class="ccx-form" method="POST" onsubmit="return validateForm(this)">
|
||||
<input type="hidden" name="csrfmiddlewaretoken" value="${csrf_token}"/>
|
||||
<label class="sr" for="ccx_name">${_('Name your CCX')}</label>
|
||||
<input name="name" id="ccx_name" placeholder="${_('Name your CCX')}"/><br/>
|
||||
<button id="create-ccx">Coach a new Custom Course for EdX</button>
|
||||
<div class="field">
|
||||
<label class="sr" for="ccx_name">${_('Name your CCX')}</label>
|
||||
<input name="name" id="ccx_name" placeholder="${_('Name your CCX')}"/><br/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<button id="create-ccx" type="submit">${_('Create a new Custom Course for edX')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
%endif
|
||||
@@ -155,4 +160,22 @@ from django.core.urlresolvers import reverse
|
||||
$('#ccx_std_list_messages')[0].focus();
|
||||
}
|
||||
});
|
||||
function validateForm(form) {
|
||||
var newCCXName = $(form).find('#ccx_name').val();
|
||||
var $errorMessage = $('#ccx-create-message');
|
||||
var hasCcxConnector = ${has_ccx_connector};
|
||||
|
||||
if (!newCCXName && !hasCcxConnector) {
|
||||
$errorMessage.text("${_('Please enter a valid CCX name.')}");
|
||||
$errorMessage.show();
|
||||
return false;
|
||||
} else if (hasCcxConnector) {
|
||||
$errorMessage.html('${use_ccx_con_error_message}');
|
||||
$errorMessage.show();
|
||||
return false;
|
||||
}
|
||||
|
||||
$errorMessage.hide();
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user