Add link to exam settings page from studio (#24405)

* testing

* updates to drop down

* unit tests. env changes were copied based on other MFEs in LMS

* added exam settings link to other course settings pages

* fixed pylint errors

* updates for requested changes

* updates for requested changes, as well as changes for xss linter
This commit is contained in:
alangsto
2020-07-09 10:13:18 -04:00
committed by GitHub
parent 39dcd80211
commit 90d6b18711
10 changed files with 147 additions and 3 deletions

View File

@@ -0,0 +1,72 @@
#-*- coding: utf-8 -*-
"""
Exam Settings View Tests
"""
import ddt
from django.conf import settings
from django.test.utils import override_settings
from contentstore.tests.utils import CourseTestCase
from contentstore.utils import reverse_course_url
from util.testing import UrlResetMixin
FEATURES_WITH_CERTS_ENABLED = settings.FEATURES.copy()
FEATURES_WITH_CERTS_ENABLED['CERTIFICATES_HTML_VIEW'] = True
FEATURES_WITH_EXAM_SETTINGS_ENABLED = FEATURES_WITH_CERTS_ENABLED.copy()
FEATURES_WITH_EXAM_SETTINGS_ENABLED['ENABLE_EXAM_SETTINGS_HTML_VIEW'] = True
FEATURES_WITH_EXAM_SETTINGS_DISABLED = FEATURES_WITH_CERTS_ENABLED.copy()
FEATURES_WITH_EXAM_SETTINGS_DISABLED['ENABLE_EXAM_SETTINGS_HTML_VIEW'] = False
@ddt.ddt
class TestExamSettingsView(CourseTestCase, UrlResetMixin):
"""
Unit tests for the exam settings view.
"""
def setUp(self):
"""
Set up the for the exam settings view tests.
"""
super(TestExamSettingsView, self).setUp()
self.reset_urls()
@override_settings(FEATURES=FEATURES_WITH_EXAM_SETTINGS_DISABLED)
@ddt.data(
"certificates_list_handler",
"settings_handler",
"group_configurations_list_handler",
"grading_handler",
"advanced_settings_handler"
)
def test_view_without_exam_settings_enabled(self, handler):
"""
Tests pages should not have `Exam Settings` item
if course does not have the Exam Settings view enabled.
"""
outline_url = reverse_course_url(handler, self.course.id)
resp = self.client.get(outline_url, HTTP_ACCEPT='text/html')
self.assertEqual(resp.status_code, 200)
self.assertNotContains(resp, 'Proctored Exam Settings')
@override_settings(FEATURES=FEATURES_WITH_EXAM_SETTINGS_ENABLED)
@ddt.data(
"certificates_list_handler",
"settings_handler",
"group_configurations_list_handler",
"grading_handler",
"advanced_settings_handler"
)
def test_view_with_exam_settings_enabled(self, handler):
"""
Tests pages should have `Exam Settings` item
if course does have Exam Settings view enabled.
"""
outline_url = reverse_course_url(handler, self.course.id)
resp = self.client.get(outline_url, HTTP_ACCEPT='text/html')
self.assertEqual(resp.status_code, 200)
self.assertContains(resp, 'Proctored Exam Settings')

View File

@@ -15,6 +15,12 @@ from util.testing import UrlResetMixin
FEATURES_WITH_CERTS_ENABLED = settings.FEATURES.copy()
FEATURES_WITH_CERTS_ENABLED['CERTIFICATES_HTML_VIEW'] = True
FEATURES_WITH_EXAM_SETTINGS_ENABLED = settings.FEATURES.copy()
FEATURES_WITH_EXAM_SETTINGS_ENABLED['ENABLE_EXAM_SETTINGS_HTML_VIEW'] = True
FEATURES_WITH_EXAM_SETTINGS_DISABLED = settings.FEATURES.copy()
FEATURES_WITH_EXAM_SETTINGS_DISABLED['ENABLE_EXAM_SETTINGS_HTML_VIEW'] = False
@override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED)
class TestHeaderMenu(CourseTestCase, UrlResetMixin):
@@ -49,3 +55,25 @@ class TestHeaderMenu(CourseTestCase, UrlResetMixin):
resp = self.client.get(outline_url, HTTP_ACCEPT='text/html')
self.assertEqual(resp.status_code, 200)
self.assertContains(resp, '<li class="nav-item nav-course-settings-certificates">')
@override_settings(FEATURES=FEATURES_WITH_EXAM_SETTINGS_DISABLED)
def test_header_menu_without_exam_settings_enabled(self):
"""
Tests course header menu should not have `Exam Settings` menu item
if course does not have the Exam Settings view enabled.
"""
outline_url = reverse_course_url('course_handler', self.course.id)
resp = self.client.get(outline_url, HTTP_ACCEPT='text/html')
self.assertEqual(resp.status_code, 200)
self.assertNotContains(resp, '<li class="nav-item nav-course-settings-exams">')
@override_settings(FEATURES=FEATURES_WITH_EXAM_SETTINGS_ENABLED)
def test_header_menu_with_exam_settings_enabled(self):
"""
Tests course header menu should have `Exam Settings` menu item
if course does have Exam Settings view enabled.
"""
outline_url = reverse_course_url('course_handler', self.course.id)
resp = self.client.get(outline_url, HTTP_ACCEPT='text/html')
self.assertEqual(resp.status_code, 200)
self.assertContains(resp, '<li class="nav-item nav-course-settings-exams">')

View File

@@ -412,6 +412,9 @@ ENABLE_JASMINE = False
# IDA for which the social auth flow uses DOT (Django OAuth Toolkit).
IDA_LOGOUT_URI_LIST = []
############################# MICROFRONTENDS ###################################
COURSE_AUTHORING_MICROFRONTEND_URL = None
############################# SOCIAL MEDIA SHARING #############################
SOCIAL_SHARING_SETTINGS = {
# Note: Ensure 'CUSTOM_COURSE_URLS' has a matching value in lms/envs/common.py

View File

@@ -135,6 +135,8 @@ LMS_BASE = "localhost:8000"
LMS_ROOT_URL = "http://{}".format(LMS_BASE)
FEATURES['PREVIEW_LMS_BASE'] = "preview.localhost"
COURSE_AUTHORING_MICROFRONTEND_URL = "http://course-authoring-mfe/"
CACHES = {
# This is the cache used for most things. Askbot will not work without a
# functioning cache -- it relies on caching to load its settings in places.

View File

@@ -106,6 +106,9 @@ CMS.User.isGlobalStaff = '${is_global_staff | n, js_escaped_string}'=='True' ? t
grading_url = utils.reverse_course_url('grading_handler', context_course.id)
course_team_url = utils.reverse_course_url('course_team_handler', context_course.id)
advanced_settings_url = utils.reverse_course_url('advanced_settings_handler', context_course.id)
exams_url = ''
if settings.FEATURES.get('ENABLE_EXAM_SETTINGS_HTML_VIEW'):
exams_url = settings.COURSE_AUTHORING_MICROFRONTEND_URL
%>
<h2 class="title-3">${_("Other Course Settings")}</h2>
<nav class="nav-related" aria-label="${_('Other Course Settings')}">
@@ -115,6 +118,9 @@ CMS.User.isGlobalStaff = '${is_global_staff | n, js_escaped_string}'=='True' ? t
<li class="nav-item"><a href="${course_team_url}">${_("Course Team")}</a></li>
<li class="nav-item"><a href="${advanced_settings_url}">${_("Advanced Settings")}</a></li>
<li class="nav-item"><a href="${utils.reverse_course_url('group_configurations_list_handler', context_course.id)}">${_("Group Configurations")}</a></li>
% if exams_url:
<li class="nav-item"><a href="${exams_url}">${_("Proctored Exam Settings")}</a></li>
% endif
</ul>
</nav>
% endif

View File

@@ -117,6 +117,9 @@ from openedx.core.djangolib.markup import HTML, Text
grading_url = utils.reverse_course_url('grading_handler', context_course.id)
course_team_url = utils.reverse_course_url('course_team_handler', context_course.id)
advanced_settings_url = utils.reverse_course_url('advanced_settings_handler', context_course.id)
exams_url = ''
if settings.FEATURES.get('ENABLE_EXAM_SETTINGS_HTML_VIEW'):
exams_url = settings.COURSE_AUTHORING_MICROFRONTEND_URL
%>
<h3 class="title-3">${_("Other Course Settings")}</h3>
<nav class="nav-related" aria-label="${_('Other Course Settings')}">
@@ -125,6 +128,9 @@ from openedx.core.djangolib.markup import HTML, Text
<li class="nav-item"><a href="${grading_url}">${_("Grading")}</a></li>
<li class="nav-item"><a href="${course_team_url}">${_("Course Team")}</a></li>
<li class="nav-item"><a href="${advanced_settings_url}">${_("Advanced Settings")}</a></li>
% if exams_url:
<li class="nav-item"><a href="${exams_url}">${_("Proctored Exam Settings")}</a></li>
% endif
</ul>
</nav>
% endif

View File

@@ -658,6 +658,9 @@ CMS.URL.UPLOAD_ASSET = '${upload_asset_url | n, js_escaped_string}'
course_team_url = utils.reverse_course_url('course_team_handler', context_course.id)
grading_config_url = utils.reverse_course_url('grading_handler', context_course.id)
advanced_config_url = utils.reverse_course_url('advanced_settings_handler', context_course.id)
exams_url = ''
if settings.FEATURES.get('ENABLE_EXAM_SETTINGS_HTML_VIEW'):
exams_url = settings.COURSE_AUTHORING_MICROFRONTEND_URL
%>
<h3 class="title-3">${_("Other Course Settings")}</h3>
<nav class="nav-related" aria-label="${_('Other Course Settings')}">
@@ -666,6 +669,9 @@ CMS.URL.UPLOAD_ASSET = '${upload_asset_url | n, js_escaped_string}'
<li class="nav-item"><a href="${course_team_url}">${_("Course Team")}</a></li>
<li class="nav-item"><a href="${utils.reverse_course_url('group_configurations_list_handler', context_course.id)}">${_("Group Configurations")}</a></li>
<li class="nav-item"><a href="${advanced_config_url}">${_("Advanced Settings")}</a></li>
% if exams_url:
<li class="nav-item"><a href="${exams_url}">${_("Proctored Exam Settings")}</a></li>
% endif
</ul>
</nav>
% endif

View File

@@ -98,6 +98,9 @@
details_url = utils.reverse_course_url('settings_handler', context_course.id)
grading_url = utils.reverse_course_url('grading_handler', context_course.id)
course_team_url = utils.reverse_course_url('course_team_handler', context_course.id)
exams_url = ''
if settings.FEATURES.get('ENABLE_EXAM_SETTINGS_HTML_VIEW'):
exams_url = settings.COURSE_AUTHORING_MICROFRONTEND_URL
%>
<h3 class="title-3">${_("Other Course Settings")}</h3>
<nav class="nav-related" aria-label="${_('Other Course Settings')}">
@@ -106,6 +109,9 @@
<li class="nav-item"><a href="${grading_url}">${_("Grading")}</a></li>
<li class="nav-item"><a href="${course_team_url}">${_("Course Team")}</a></li>
<li class="nav-item"><a href="${utils.reverse_course_url('group_configurations_list_handler', context_course.id)}">${_("Group Configurations")}</a></li>
% if exams_url:
<li class="nav-item"><a href="${exams_url}">${_("Proctored Exam Settings")}</a></li>
% endif
</ul>
</nav>
% endif

View File

@@ -1,3 +1,4 @@
<%page expression_filter="h"/>
<%inherit file="base.html" />
<%def name="online_help_token()"><% return "grading" %></%def>
<%block name="title">${_("Grading Settings")}</%block>
@@ -28,7 +29,7 @@
<%block name="requirejs">
require(["js/factories/settings_graders"], function(SettingsGradersFactory) {
SettingsGradersFactory(
_.extend(${dump_js_escaped_json(course_details, cls=CourseSettingsEncoder) | n},
_.extend(${dump_js_escaped_json(course_details, cls=CourseSettingsEncoder) | n, decode.utf8},
{is_credit_course: ${is_credit_course | n, dump_js_escaped_json}}),
"${grading_url | n, js_escaped_string}"
);
@@ -105,7 +106,7 @@
<section class="group-settings grade-rules">
<header>
<h2 class="title-2">${_("Grading Rules &amp; Policies")}</h2>
<h2 class="title-2">${_("Grading Rules & Policies")}</h2>
<span class="tip">${_("Deadlines, requirements, and logistics around grading student work")}</span>
</header>
@@ -154,14 +155,20 @@
detailed_settings_url = utils.reverse_course_url('settings_handler', context_course.id)
course_team_url = utils.reverse_course_url('course_team_handler', context_course.id)
advanced_settings_url = utils.reverse_course_url('advanced_settings_handler', context_course.id)
exams_url = ''
if settings.FEATURES.get('ENABLE_EXAM_SETTINGS_HTML_VIEW'):
exams_url = settings.COURSE_AUTHORING_MICROFRONTEND_URL
%>
<h3 class="title-3">${_("Other Course Settings")}</h3>
<nav class="nav-related" aria-label="${_('Other Course Settings')}">
<ul>
<li class="nav-item"><a href="${detailed_settings_url}">${_("Details &amp; Schedule")}</a></li>
<li class="nav-item"><a href="${detailed_settings_url}">${_("Details & Schedule")}</a></li>
<li class="nav-item"><a href="${course_team_url}">${_("Course Team")}</a></li>
<li class="nav-item"><a href="${utils.reverse_course_url('group_configurations_list_handler', context_course.id)}">${_("Group Configurations")}</a></li>
<li class="nav-item"><a href="${advanced_settings_url}">${_("Advanced Settings")}</a></li>
% if exams_url:
<li class="nav-item"><a href="${exams_url}">${_("Proctored Exam Settings")}</a></li>
% endif
</ul>
</nav>
% endif

View File

@@ -37,6 +37,9 @@
certificates_url = ''
if settings.FEATURES.get("CERTIFICATES_HTML_VIEW") and context_course.cert_html_view_enabled:
certificates_url = reverse('certificates_list_handler', kwargs={'course_key_string': six.text_type(course_key)})
exams_url = ''
if settings.FEATURES.get("ENABLE_EXAM_SETTINGS_HTML_VIEW"):
exams_url = settings.COURSE_AUTHORING_MICROFRONTEND_URL
checklists_url = reverse('checklists_handler', kwargs={'course_key_string': six.text_type(course_key)})
%>
@@ -100,6 +103,11 @@
<li class="nav-item nav-course-settings-group-configurations">
<a href="${reverse('group_configurations_list_handler', kwargs={'course_key_string': six.text_type(course_key)})}">${_("Group Configurations")}</a>
</li>
% if exams_url:
<li class="nav-item nav-course-settings-exams">
<a href="${exams_url}">${_("Proctored Exam Settings")}</a>
</li>
% endif
<li class="nav-item nav-course-settings-advanced">
<a href="${advanced_settings_url}">${_("Advanced Settings")}</a>
</li>