Update support form to make course required.
Update support form to auto select course and make course selection required to submit form. LEARNER-4254
This commit is contained in:
@@ -5,6 +5,7 @@ Middleware for the courseware app
|
||||
from django.shortcuts import redirect
|
||||
|
||||
from lms.djangoapps.courseware.exceptions import Redirect
|
||||
from util.request import COURSE_REGEX
|
||||
|
||||
|
||||
class RedirectMiddleware(object):
|
||||
@@ -17,3 +18,20 @@ class RedirectMiddleware(object):
|
||||
"""
|
||||
if isinstance(exception, Redirect):
|
||||
return redirect(exception.url)
|
||||
|
||||
|
||||
class CacheCourseIdMiddleware(object):
|
||||
"""Middleware that adds course_id to user request session."""
|
||||
|
||||
def process_request(self, request):
|
||||
"""
|
||||
Add a course_id to user request session.
|
||||
"""
|
||||
if request.user.is_authenticated():
|
||||
match = COURSE_REGEX.match(request.build_absolute_uri())
|
||||
course_id = None
|
||||
if match:
|
||||
course_id = match.group('course_id')
|
||||
|
||||
if course_id and course_id != request.session.get('course_id'):
|
||||
request.session['course_id'] = course_id
|
||||
|
||||
@@ -203,8 +203,8 @@ class IndexQueryTestCase(ModuleStoreTestCase):
|
||||
NUM_PROBLEMS = 20
|
||||
|
||||
@ddt.data(
|
||||
(ModuleStoreEnum.Type.mongo, 10, 143),
|
||||
(ModuleStoreEnum.Type.split, 4, 143),
|
||||
(ModuleStoreEnum.Type.mongo, 10, 146),
|
||||
(ModuleStoreEnum.Type.split, 4, 146),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_index_query_counts(self, store_type, expected_mongo_query_count, expected_mysql_query_count):
|
||||
@@ -1424,17 +1424,21 @@ class ProgressPageTests(ProgressPageBaseTests):
|
||||
resp = self._get_progress_page()
|
||||
self.assertContains(resp, u"Download Your Certificate")
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_progress_queries_paced_courses(self, self_paced):
|
||||
@ddt.data(
|
||||
(True, 37),
|
||||
(False, 36)
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_progress_queries_paced_courses(self, self_paced, query_count):
|
||||
"""Test that query counts remain the same for self-paced and instructor-paced courses."""
|
||||
self.setup_course(self_paced=self_paced)
|
||||
with self.assertNumQueries(34 if self_paced else 33, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST), check_mongo_calls(1):
|
||||
with self.assertNumQueries(query_count, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST), check_mongo_calls(1):
|
||||
self._get_progress_page()
|
||||
|
||||
@patch.dict(settings.FEATURES, {'ASSUME_ZERO_GRADE_IF_ABSENT_FOR_ALL_TESTS': False})
|
||||
@ddt.data(
|
||||
(False, 40, 27),
|
||||
(True, 33, 23)
|
||||
(False, 43, 27),
|
||||
(True, 36, 23)
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_progress_queries(self, enable_waffle, initial, subsequent):
|
||||
|
||||
@@ -406,8 +406,8 @@ class ViewsQueryCountTestCase(
|
||||
return inner
|
||||
|
||||
@ddt.data(
|
||||
(ModuleStoreEnum.Type.mongo, 3, 4, 32),
|
||||
(ModuleStoreEnum.Type.split, 3, 13, 32),
|
||||
(ModuleStoreEnum.Type.mongo, 3, 4, 35),
|
||||
(ModuleStoreEnum.Type.split, 3, 13, 35),
|
||||
)
|
||||
@ddt.unpack
|
||||
@count_queries
|
||||
@@ -415,8 +415,8 @@ class ViewsQueryCountTestCase(
|
||||
self.create_thread_helper(mock_request)
|
||||
|
||||
@ddt.data(
|
||||
(ModuleStoreEnum.Type.mongo, 3, 3, 28),
|
||||
(ModuleStoreEnum.Type.split, 3, 10, 28),
|
||||
(ModuleStoreEnum.Type.mongo, 3, 3, 31),
|
||||
(ModuleStoreEnum.Type.split, 3, 10, 31),
|
||||
)
|
||||
@ddt.unpack
|
||||
@count_queries
|
||||
|
||||
@@ -10,7 +10,11 @@ function LoggedInUser({ userInformation, setErrorState, zendeskApiHost, submitFo
|
||||
if (userInformation.enrollments) {
|
||||
courseElement = (<div>
|
||||
<label className="label-course" htmlFor="course">{gettext('Course Name')}</label>
|
||||
<select className="form-control select-course" id="course">
|
||||
<select className="form-control select-course" id="course" value={userInformation.course_id}>
|
||||
<option key="select-course" value="">--------</option>
|
||||
<option key="not-course-specific" value="Not specific to a course">
|
||||
{gettext('Not specific to a course')}
|
||||
</option>
|
||||
{userInformation.enrollments.map(enrollment =>
|
||||
(<option key={enrollment.course_id} value={enrollment.course_id}>
|
||||
{enrollment.course_name}
|
||||
@@ -20,7 +24,7 @@ function LoggedInUser({ userInformation, setErrorState, zendeskApiHost, submitFo
|
||||
</div>);
|
||||
} else {
|
||||
courseElement = (<div>
|
||||
<label htmlFor="course">{gettext('Course Name')}<span> {gettext('(Optional)')}</span></label>
|
||||
<label htmlFor="course">{gettext('Course Name')}</label>
|
||||
<input type="text" className="form-control" id="course" />
|
||||
</div>);
|
||||
}
|
||||
|
||||
@@ -41,9 +41,11 @@ class RenderForm extends React.Component {
|
||||
body: $('#message').val(),
|
||||
},
|
||||
tags: this.props.context.tags,
|
||||
};
|
||||
},
|
||||
errors = [];
|
||||
|
||||
let course;
|
||||
this.clearErrors();
|
||||
|
||||
data.requester = {
|
||||
email: $userInfo.data('email'),
|
||||
@@ -54,13 +56,16 @@ class RenderForm extends React.Component {
|
||||
if (!course) {
|
||||
course = $course.val();
|
||||
}
|
||||
|
||||
if (!course) {
|
||||
$('#course').closest('.form-group').addClass('has-error');
|
||||
errors.push(gettext('Select a course or select "Not specific to a course" for your support request.'));
|
||||
}
|
||||
data.custom_fields = [{
|
||||
id: this.props.context.customFields.course_id,
|
||||
value: course,
|
||||
}];
|
||||
|
||||
if (this.validateData(data)) {
|
||||
if (this.validateData(data, errors)) {
|
||||
request.open('POST', url, true);
|
||||
request.setRequestHeader('Content-type', 'application/json;charset=UTF-8');
|
||||
request.setRequestHeader('X-CSRFToken', $.cookie('csrftoken'));
|
||||
@@ -81,8 +86,12 @@ class RenderForm extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
validateData(data) {
|
||||
const errors = [];
|
||||
clearErrors() {
|
||||
this.setErrorState([]);
|
||||
$('.form-group').removeClass('has-error');
|
||||
}
|
||||
|
||||
validateData(data, errors) {
|
||||
if (!data.subject) {
|
||||
errors.push(gettext('Enter a subject for your support request.'));
|
||||
$('#subject').closest('.form-group').addClass('has-error');
|
||||
|
||||
@@ -32,6 +32,7 @@ class ContactUsView(View):
|
||||
tags.append("site_name_{site}".format(site=current_site_name))
|
||||
|
||||
if request.user.is_authenticated():
|
||||
context['course_id'] = request.session.get('course_id', '')
|
||||
context['user_enrollments'] = CourseEnrollment.enrollments_for_user_with_overviews_preload(request.user)
|
||||
enterprise_learner_data = enterprise_api.get_enterprise_learner_data(user=request.user)
|
||||
if enterprise_learner_data:
|
||||
|
||||
@@ -1288,6 +1288,7 @@ MIDDLEWARE_CLASSES = [
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
|
||||
# to redirected unenrolled students to the course info page
|
||||
'courseware.middleware.CacheCourseIdMiddleware',
|
||||
'courseware.middleware.RedirectMiddleware',
|
||||
|
||||
'course_wiki.middleware.WikiAccessMiddleware',
|
||||
|
||||
@@ -42,7 +42,8 @@ from openedx.core.djangolib.js_utils import js_escaped_string, dump_js_escaped_j
|
||||
% if user.is_authenticated():
|
||||
context['user'] = {
|
||||
'username': "${user.username | n, js_escaped_string}",
|
||||
'email': "${user.email | n, js_escaped_string}"
|
||||
'email': "${user.email | n, js_escaped_string}",
|
||||
'course_id': "${course_id | n, js_escaped_string}"
|
||||
}
|
||||
|
||||
% if user_enrollments:
|
||||
|
||||
@@ -175,7 +175,7 @@ class TestCourseHomePage(CourseHomePageTestCase):
|
||||
course_home_url(self.course)
|
||||
|
||||
# Fetch the view and verify the query counts
|
||||
with self.assertNumQueries(50, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST):
|
||||
with self.assertNumQueries(53, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST):
|
||||
with check_mongo_calls(4):
|
||||
url = course_home_url(self.course)
|
||||
self.client.get(url)
|
||||
|
||||
@@ -126,7 +126,7 @@ class TestCourseUpdatesPage(SharedModuleStoreTestCase):
|
||||
course_updates_url(self.course)
|
||||
|
||||
# Fetch the view and verify that the query counts haven't changed
|
||||
with self.assertNumQueries(30, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST):
|
||||
with self.assertNumQueries(33, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST):
|
||||
with check_mongo_calls(4):
|
||||
url = course_updates_url(self.course)
|
||||
self.client.get(url)
|
||||
|
||||
Reference in New Issue
Block a user