From eeb6cc7ca382117e4d79dc3636ccf1c40bf9b636 Mon Sep 17 00:00:00 2001 From: Michael Roytman Date: Wed, 29 Nov 2017 12:26:00 -0500 Subject: [PATCH] Add accessibility accomodation request page to studio and link to said page in footer, both behind a Waffle switch. Add tests for the new page. --- cms/djangoapps/contentstore/config/waffle.py | 18 +++++++++++++ .../contentstore/tests/test_contentstore.py | 18 +++++++++++++ cms/djangoapps/contentstore/views/public.py | 13 +++++++++- cms/envs/aws.py | 7 +++++ cms/envs/common.py | 8 ++++++ cms/templates/accessibility.html | 26 +++++++++++++++++++ cms/templates/widgets/footer.html | 8 +++++- cms/urls.py | 1 + 8 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 cms/djangoapps/contentstore/config/waffle.py create mode 100644 cms/templates/accessibility.html diff --git a/cms/djangoapps/contentstore/config/waffle.py b/cms/djangoapps/contentstore/config/waffle.py new file mode 100644 index 0000000000..fe33f85fbc --- /dev/null +++ b/cms/djangoapps/contentstore/config/waffle.py @@ -0,0 +1,18 @@ +""" +This module contains various configuration settings via +waffle switches for the contentstore app. +""" +from openedx.core.djangoapps.waffle_utils import WaffleSwitchNamespace + +# Namespace +WAFFLE_NAMESPACE = u'accessibility' + +# Switches +ENABLE_ACCESSIBILITY_POLICY_PAGE = u'enable_policy_page' + + +def waffle(): + """ + Returns the namespaced, cached, audited Waffle class for Accessibility Accomodation Request Page. + """ + return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE, log_prefix=u'Accessibility: ') diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index 195b80f849..8588932356 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -23,10 +23,12 @@ from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey, UsageKey from opaque_keys.edx.locations import AssetLocation, CourseLocator from path import Path as path +from waffle.testutils import override_switch from contentstore.tests.utils import AjaxEnabledTestClient, CourseTestCase, get_url, parse_json from contentstore.utils import delete_course, reverse_course_url, reverse_url from contentstore.views.component import ADVANCED_COMPONENT_TYPES +from contentstore.config import waffle from course_action_state.managers import CourseActionStateItemNotFoundError from course_action_state.models import CourseRerunState, CourseRerunUIStateManager from django_comment_common.utils import are_permissions_roles_seeded @@ -1054,6 +1056,16 @@ class MiscCourseTests(ContentStoreTestCase): resp = self.client.get_html('/c4x/InvalidOrg/InvalidCourse/asset/invalid.png') self.assertEqual(resp.status_code, 404) + @override_switch( + '{}.{}'.format(waffle.WAFFLE_NAMESPACE, waffle.ENABLE_ACCESSIBILITY_POLICY_PAGE), + active=False) + def test_disabled_accessibility_page(self): + """ + Test that accessibility page returns 404 when waffle switch is disabled + """ + resp = self.client.get_html('/accessibility') + self.assertEqual(resp.status_code, 404) + def test_delete_course(self): """ This test creates a course, makes a draft item, and deletes the course. This will also assert that the @@ -2151,6 +2163,12 @@ class EntryPageTestCase(TestCase): # Logout redirects. self._test_page("/logout", 302) + @override_switch( + '{}.{}'.format(waffle.WAFFLE_NAMESPACE, waffle.ENABLE_ACCESSIBILITY_POLICY_PAGE), + active=True) + def test_accessibility(self): + self._test_page('/accessibility') + class SigninPageTestCase(TestCase): """ diff --git a/cms/djangoapps/contentstore/views/public.py b/cms/djangoapps/contentstore/views/public.py index 5367971726..843ed47731 100644 --- a/cms/djangoapps/contentstore/views/public.py +++ b/cms/djangoapps/contentstore/views/public.py @@ -11,8 +11,10 @@ from django.views.decorators.csrf import ensure_csrf_cookie from edxmako.shortcuts import render_to_response from openedx.core.djangoapps.external_auth.views import redirect_with_get, ssl_get_cert_from_request, ssl_login_shortcut from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers +from waffle.decorators import waffle_switch +from contentstore.config import waffle -__all__ = ['signup', 'login_page', 'howitworks'] +__all__ = ['signup', 'login_page', 'howitworks', 'accessibility'] @ensure_csrf_cookie @@ -70,3 +72,12 @@ def howitworks(request): return redirect('/home/') else: return render_to_response('howitworks.html', {}) + + +@waffle_switch('{}.{}'.format(waffle.WAFFLE_NAMESPACE, waffle.ENABLE_ACCESSIBILITY_POLICY_PAGE)) +def accessibility(_request): + """ + Display the accessibility accommodation form. + """ + + return render_to_response('accessibility.html', {}) diff --git a/cms/envs/aws.py b/cms/envs/aws.py index 15306a30ad..c18884fe91 100644 --- a/cms/envs/aws.py +++ b/cms/envs/aws.py @@ -285,6 +285,10 @@ if FEATURES.get('AUTH_USE_CAS'): FILE_UPLOAD_STORAGE_BUCKET_NAME = ENV_TOKENS.get('FILE_UPLOAD_STORAGE_BUCKET_NAME', FILE_UPLOAD_STORAGE_BUCKET_NAME) FILE_UPLOAD_STORAGE_PREFIX = ENV_TOKENS.get('FILE_UPLOAD_STORAGE_PREFIX', FILE_UPLOAD_STORAGE_PREFIX) +# Zendesk +ZENDESK_URL = ENV_TOKENS.get('ZENDESK_URL', ZENDESK_URL) +ZENDESK_CUSTOM_FIELDS = ENV_TOKENS.get('ZENDESK_CUSTOM_FIELDS', ZENDESK_CUSTOM_FIELDS) + ################ SECURE AUTH ITEMS ############################### # Secret things: passwords, access keys, etc. with open(CONFIG_ROOT / CONFIG_PREFIX + "auth.json") as auth_file: @@ -429,6 +433,9 @@ EVENT_TRACKING_BACKENDS['segmentio']['OPTIONS']['processors'][0]['OPTIONS']['whi VIRTUAL_UNIVERSITIES = ENV_TOKENS.get('VIRTUAL_UNIVERSITIES', []) +# Zendesk +ZENDESK_OAUTH_ACCESS_TOKEN = AUTH_TOKENS.get("ZENDESK_OAUTH_ACCESS_TOKEN") + ##### ACCOUNT LOCKOUT DEFAULT PARAMETERS ##### MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED = ENV_TOKENS.get("MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED", 5) MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS = ENV_TOKENS.get("MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS", 15 * 60) diff --git a/cms/envs/common.py b/cms/envs/common.py index 00472262e4..1f7031571e 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -1459,3 +1459,11 @@ VIDEO_IMAGE_MIN_HEIGHT = 360 VIDEO_IMAGE_ASPECT_RATIO = 16 / 9.0 VIDEO_IMAGE_ASPECT_RATIO_TEXT = '16:9' VIDEO_IMAGE_ASPECT_RATIO_ERROR_MARGIN = 0.1 + + +###################### ZENDESK ###################### +ZENDESK_URL = None +ZENDESK_USER = None +ZENDESK_API_KEY = None +ZENDESK_OAUTH_ACCESS_TOKEN = None +ZENDESK_CUSTOM_FIELDS = {} diff --git a/cms/templates/accessibility.html b/cms/templates/accessibility.html new file mode 100644 index 0000000000..2a64af4e24 --- /dev/null +++ b/cms/templates/accessibility.html @@ -0,0 +1,26 @@ +<%page expression_filter="h"/> +<%inherit file="base.html" /> +<%def name="online_help_token()"><% return "accessibility" %> +<%! + from django.core.urlresolvers import reverse + from django.utils.translation import ugettext as _ + from openedx.core.djangolib.markup import HTML, Text + from openedx.core.djangolib.js_utils import js_escaped_string, dump_js_escaped_json +%> +<%block name="title">${_("Studio Accessibility Policy")} +<%block name="bodyclass">is-signedin not-signedin view-accessibility + +<%namespace name='static' file='static_content.html'/> + +<%block name="content"> + +
+
+
+
+

Accessibility Accommodation Request

+
+
+
+ + diff --git a/cms/templates/widgets/footer.html b/cms/templates/widgets/footer.html index 5862ad053b..fd1823d117 100644 --- a/cms/templates/widgets/footer.html +++ b/cms/templates/widgets/footer.html @@ -4,6 +4,7 @@ from django.core.urlresolvers import reverse from datetime import datetime from django.conf import settings import pytz +from cms.djangoapps.contentstore.config.waffle import waffle, ENABLE_ACCESSIBILITY_POLICY_PAGE %> - % if is_any_marketing_link_set(['TOS', 'PRIVACY']): + % if is_any_marketing_link_set(['TOS', 'PRIVACY']) or waffle().is_enabled(ENABLE_ACCESSIBILITY_POLICY_PAGE): % endif diff --git a/cms/urls.py b/cms/urls.py index 9683b9e67e..aa4077cd1f 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -152,6 +152,7 @@ urlpatterns = [ name='group_configurations_detail_handler'), url(r'^api/val/v0/', include('edxval.urls')), url(r'^api/tasks/v0/', include('user_tasks.urls')), + url(r'^accessibility$', contentstore.views.accessibility, name='accessibility') ] JS_INFO_DICT = {