diff --git a/.gitignore b/.gitignore
index 9c82bb8ea9..05e76c4caa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,6 +26,7 @@ Gemfile.lock
conf/locale/en/LC_MESSAGES/*.po
!messages.po
lms/static/sass/*.css
+lms/static/sass/application.scss
cms/static/sass/*.css
lms/lib/comment_client/python
nosetests.xml
diff --git a/.reviewboardrc b/.reviewboardrc
new file mode 100644
index 0000000000..b79235a4a4
--- /dev/null
+++ b/.reviewboardrc
@@ -0,0 +1,2 @@
+REVIEWBOARD_URL = "https://rbcommons.com/s/edx/"
+GUESS_FIELDS = True
diff --git a/cms/djangoapps/contentstore/features/advanced-settings.py b/cms/djangoapps/contentstore/features/advanced-settings.py
index ea5b24b21f..3acebecac8 100644
--- a/cms/djangoapps/contentstore/features/advanced-settings.py
+++ b/cms/djangoapps/contentstore/features/advanced-settings.py
@@ -19,9 +19,7 @@ DISPLAY_NAME_VALUE = '"Robot Super Course"'
############### ACTIONS ####################
@step('I select the Advanced Settings$')
def i_select_advanced_settings(step):
- expand_icon_css = 'li.nav-course-settings i.icon-expand'
- if world.browser.is_element_present_by_css(expand_icon_css):
- world.css_click(expand_icon_css)
+ world.click_course_settings()
link_css = 'li.nav-course-settings-advanced a'
world.css_click(link_css)
diff --git a/cms/djangoapps/contentstore/features/checklists.py b/cms/djangoapps/contentstore/features/checklists.py
index 1c9fbf0994..9552d35036 100644
--- a/cms/djangoapps/contentstore/features/checklists.py
+++ b/cms/djangoapps/contentstore/features/checklists.py
@@ -10,9 +10,7 @@ from selenium.common.exceptions import StaleElementReferenceException
############### ACTIONS ####################
@step('I select Checklists from the Tools menu$')
def i_select_checklists(step):
- expand_icon_css = 'li.nav-course-tools i.icon-expand'
- if world.browser.is_element_present_by_css(expand_icon_css):
- world.css_click(expand_icon_css)
+ world.click_tools()
link_css = 'li.nav-course-tools-checklists a'
world.css_click(link_css)
diff --git a/cms/djangoapps/contentstore/features/course-settings.py b/cms/djangoapps/contentstore/features/course-settings.py
index d69266b7de..bd86fff9b7 100644
--- a/cms/djangoapps/contentstore/features/course-settings.py
+++ b/cms/djangoapps/contentstore/features/course-settings.py
@@ -25,9 +25,7 @@ DEFAULT_TIME = "00:00"
############### ACTIONS ####################
@step('I select Schedule and Details$')
def test_i_select_schedule_and_details(step):
- expand_icon_css = 'li.nav-course-settings i.icon-expand'
- if world.browser.is_element_present_by_css(expand_icon_css):
- world.css_click(expand_icon_css)
+ world.click_course_settings()
link_css = 'li.nav-course-settings-schedule a'
world.css_click(link_css)
diff --git a/cms/djangoapps/contentstore/features/courses.py b/cms/djangoapps/contentstore/features/courses.py
index 5da7720945..aa2e9d68f8 100644
--- a/cms/djangoapps/contentstore/features/courses.py
+++ b/cms/djangoapps/contentstore/features/courses.py
@@ -62,4 +62,4 @@ def i_am_on_tab(step, tab_name):
@step('I see a link for adding a new section$')
def i_see_new_section_link(step):
link_css = 'a.new-courseware-section-button'
- assert world.css_has_text(link_css, '+ New Section')
+ assert world.css_has_text(link_css, 'New Section')
diff --git a/cms/djangoapps/contentstore/features/section.py b/cms/djangoapps/contentstore/features/section.py
index 59c5a37b33..9a896d8ebe 100644
--- a/cms/djangoapps/contentstore/features/section.py
+++ b/cms/djangoapps/contentstore/features/section.py
@@ -62,7 +62,7 @@ def i_click_to_edit_section_name(step):
@step('I see the complete section name with a quote in the editor$')
def i_see_complete_section_name_with_quote_in_editor(step):
- css = '.edit-section-name'
+ css = '.section-name-edit input[type=text]'
assert world.is_css_present(css)
assert_equal(world.browser.find_by_css(css).value, 'Section with "Quote"')
diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py
index 7c669c80f6..a36ed76d11 100644
--- a/cms/djangoapps/contentstore/tests/test_contentstore.py
+++ b/cms/djangoapps/contentstore/tests/test_contentstore.py
@@ -34,6 +34,8 @@ from xmodule.course_module import CourseDescriptor
from xmodule.seq_module import SequenceDescriptor
from xmodule.modulestore.exceptions import ItemNotFoundError
+from django_comment_common.utils import are_permissions_roles_seeded
+
TEST_DATA_MODULESTORE = copy.deepcopy(settings.MODULESTORE)
TEST_DATA_MODULESTORE['default']['OPTIONS']['fs_root'] = path('common/test/data')
TEST_DATA_MODULESTORE['direct']['OPTIONS']['fs_root'] = path('common/test/data')
@@ -45,7 +47,7 @@ class MongoCollectionFindWrapper(object):
self.counter = 0
def find(self, query, *args, **kwargs):
- self.counter = self.counter+1
+ self.counter = self.counter + 1
return self.original(query, *args, **kwargs)
@@ -352,7 +354,7 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
clone_items = module_store.get_items(Location(['i4x', 'MITx', '999', 'vertical', None]))
self.assertGreater(len(clone_items), 0)
for descriptor in items:
- new_loc = descriptor.location._replace(org='MITx', course='999')
+ new_loc = descriptor.location.replace(org='MITx', course='999')
print "Checking {0} should now also be at {1}".format(descriptor.location.url(), new_loc.url())
resp = self.client.get(reverse('edit_unit', kwargs={'location': new_loc.url()}))
self.assertEqual(resp.status_code, 200)
@@ -375,15 +377,15 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
self.assertEqual(len(items), 0)
def verify_content_existence(self, modulestore, root_dir, location, dirname, category_name, filename_suffix=''):
- fs = OSFS(root_dir / 'test_export')
- self.assertTrue(fs.exists(dirname))
+ filesystem = OSFS(root_dir / 'test_export')
+ self.assertTrue(filesystem.exists(dirname))
query_loc = Location('i4x', location.org, location.course, category_name, None)
items = modulestore.get_items(query_loc)
for item in items:
- fs = OSFS(root_dir / ('test_export/' + dirname))
- self.assertTrue(fs.exists(item.location.name + filename_suffix))
+ filesystem = OSFS(root_dir / ('test_export/' + dirname))
+ self.assertTrue(filesystem.exists(item.location.name + filename_suffix))
def test_export_course(self):
module_store = modulestore('direct')
@@ -415,7 +417,7 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
# add private to list of children
sequential = module_store.get_item(Location(['i4x', 'edX', 'full',
'sequential', 'Administrivia_and_Circuit_Elements', None]))
- private_location_no_draft = private_vertical.location._replace(revision=None)
+ private_location_no_draft = private_vertical.location.replace(revision=None)
module_store.update_children(sequential.location, sequential.children +
[private_location_no_draft.url()])
@@ -440,20 +442,20 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
self.verify_content_existence(module_store, root_dir, location, 'custom_tags', 'custom_tag_template')
# check for graiding_policy.json
- fs = OSFS(root_dir / 'test_export/policies/6.002_Spring_2012')
- self.assertTrue(fs.exists('grading_policy.json'))
+ filesystem = OSFS(root_dir / 'test_export/policies/6.002_Spring_2012')
+ self.assertTrue(filesystem.exists('grading_policy.json'))
course = module_store.get_item(location)
# compare what's on disk compared to what we have in our course
- with fs.open('grading_policy.json', 'r') as grading_policy:
+ with filesystem.open('grading_policy.json', 'r') as grading_policy:
on_disk = loads(grading_policy.read())
self.assertEqual(on_disk, course.grading_policy)
#check for policy.json
- self.assertTrue(fs.exists('policy.json'))
+ self.assertTrue(filesystem.exists('policy.json'))
# compare what's on disk to what we have in the course module
- with fs.open('policy.json', 'r') as course_policy:
+ with filesystem.open('policy.json', 'r') as course_policy:
on_disk = loads(course_policy.read())
self.assertIn('course/6.002_Spring_2012', on_disk)
self.assertEqual(on_disk['course/6.002_Spring_2012'], own_metadata(course))
@@ -608,6 +610,14 @@ class ContentStoreTest(ModuleStoreTestCase):
data = parse_json(resp)
self.assertEqual(data['id'], 'i4x://MITx/999/course/Robot_Super_Course')
+ def test_create_course_check_forum_seeding(self):
+ """Test new course creation and verify forum seeding """
+ resp = self.client.post(reverse('create_new_course'), self.course_data)
+ self.assertEqual(resp.status_code, 200)
+ data = parse_json(resp)
+ self.assertEqual(data['id'], 'i4x://MITx/999/course/Robot_Super_Course')
+ self.assertTrue(are_permissions_roles_seeded('MITx/999/Robot_Super_Course'))
+
def test_create_course_duplicate_course(self):
"""Test new course creation - error path"""
resp = self.client.post(reverse('create_new_course'), self.course_data)
@@ -801,37 +811,37 @@ class ContentStoreTest(ModuleStoreTestCase):
self.assertEqual(200, resp.status_code)
# go look at a subsection page
- subsection_location = loc._replace(category='sequential', name='test_sequence')
+ subsection_location = loc.replace(category='sequential', name='test_sequence')
resp = self.client.get(reverse('edit_subsection',
kwargs={'location': subsection_location.url()}))
self.assertEqual(200, resp.status_code)
# go look at the Edit page
- unit_location = loc._replace(category='vertical', name='test_vertical')
+ unit_location = loc.replace(category='vertical', name='test_vertical')
resp = self.client.get(reverse('edit_unit',
kwargs={'location': unit_location.url()}))
self.assertEqual(200, resp.status_code)
# delete a component
- del_loc = loc._replace(category='html', name='test_html')
+ del_loc = loc.replace(category='html', name='test_html')
resp = self.client.post(reverse('delete_item'),
json.dumps({'id': del_loc.url()}), "application/json")
self.assertEqual(200, resp.status_code)
# delete a unit
- del_loc = loc._replace(category='vertical', name='test_vertical')
+ del_loc = loc.replace(category='vertical', name='test_vertical')
resp = self.client.post(reverse('delete_item'),
json.dumps({'id': del_loc.url()}), "application/json")
self.assertEqual(200, resp.status_code)
# delete a unit
- del_loc = loc._replace(category='sequential', name='test_sequence')
+ del_loc = loc.replace(category='sequential', name='test_sequence')
resp = self.client.post(reverse('delete_item'),
json.dumps({'id': del_loc.url()}), "application/json")
self.assertEqual(200, resp.status_code)
# delete a chapter
- del_loc = loc._replace(category='chapter', name='chapter_2')
+ del_loc = loc.replace(category='chapter', name='chapter_2')
resp = self.client.post(reverse('delete_item'),
json.dumps({'id': del_loc.url()}), "application/json")
self.assertEqual(200, resp.status_code)
diff --git a/cms/djangoapps/contentstore/tests/test_utils.py b/cms/djangoapps/contentstore/tests/test_utils.py
index 3b755b0ec2..0757992f2f 100644
--- a/cms/djangoapps/contentstore/tests/test_utils.py
+++ b/cms/djangoapps/contentstore/tests/test_utils.py
@@ -26,7 +26,7 @@ class LMSLinksTestCase(TestCase):
link = utils.get_lms_link_for_item(location, True)
self.assertEquals(
link,
- "//preview.localhost:8000/courses/mitX/101/test/jump_to/i4x://mitX/101/vertical/contacting_us"
+ "//preview/courses/mitX/101/test/jump_to/i4x://mitX/101/vertical/contacting_us"
)
diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py
index ea3e3ecd6a..35451cf7cc 100644
--- a/cms/djangoapps/contentstore/utils.py
+++ b/cms/djangoapps/contentstore/utils.py
@@ -88,7 +88,7 @@ def get_lms_link_for_item(location, preview=False, course_id=None):
if settings.LMS_BASE is not None:
if preview:
- lms_base = settings.MITX_FEATURES.get('PREVIEW_LMS_BASE', 'preview.' + settings.LMS_BASE)
+ lms_base = settings.MITX_FEATURES.get('PREVIEW_LMS_BASE')
else:
lms_base = settings.LMS_BASE
diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py
index 89b5e8bdc7..30005d4524 100644
--- a/cms/djangoapps/contentstore/views/component.py
+++ b/cms/djangoapps/contentstore/views/component.py
@@ -179,8 +179,7 @@ def edit_unit(request, location):
break
index = index + 1
- preview_lms_base = settings.MITX_FEATURES.get('PREVIEW_LMS_BASE',
- 'preview.' + settings.LMS_BASE)
+ preview_lms_base = settings.MITX_FEATURES.get('PREVIEW_LMS_BASE')
preview_lms_link = '//{preview_lms_base}/courses/{org}/{course}/{course_name}/courseware/{section}/{subsection}/{index}'.format(
preview_lms_base=preview_lms_base,
diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py
index f326764589..07f6b9669c 100644
--- a/cms/djangoapps/contentstore/views/course.py
+++ b/cms/djangoapps/contentstore/views/course.py
@@ -13,17 +13,13 @@ from django.core.urlresolvers import reverse
from mitxmako.shortcuts import render_to_response
from xmodule.modulestore.django import modulestore
-from xmodule.modulestore.exceptions \
- import ItemNotFoundError, InvalidLocationError
+
+from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError
from xmodule.modulestore import Location
-from contentstore.course_info_model \
- import get_course_updates, update_course_updates, delete_course_update
-from contentstore.utils \
- import get_lms_link_for_item, add_extra_panel_tab, \
- remove_extra_panel_tab
-from models.settings.course_details \
- import CourseDetails, CourseSettingsEncoder
+from contentstore.course_info_model import get_course_updates, update_course_updates, delete_course_update
+from contentstore.utils import get_lms_link_for_item, add_extra_panel_tab, remove_extra_panel_tab
+from models.settings.course_details import CourseDetails, CourseSettingsEncoder
from models.settings.course_grading import CourseGradingModel
from models.settings.course_metadata import CourseMetadata
from auth.authz import create_all_course_groups
@@ -35,6 +31,10 @@ from .tabs import initialize_course_tabs
from .component import OPEN_ENDED_COMPONENT_TYPES, \
NOTE_COMPONENT_TYPES, ADVANCED_COMPONENT_POLICY_KEY
+from django_comment_common.utils import seed_permissions_roles
+
+# TODO: should explicitly enumerate exports with __all__
+
__all__ = ['course_index', 'create_new_course', 'course_info',
'course_info_updates', 'get_course_settings',
'course_config_graders_page',
@@ -136,6 +136,9 @@ def create_new_course(request):
create_all_course_groups(request.user, new_course.location)
+ # seed the forums
+ seed_permissions_roles(new_course.location.course_id)
+
return HttpResponse(json.dumps({'id': new_course.location.url()}))
diff --git a/cms/djangoapps/contentstore/views/public.py b/cms/djangoapps/contentstore/views/public.py
index 0433aa9e9d..0ee228b996 100644
--- a/cms/djangoapps/contentstore/views/public.py
+++ b/cms/djangoapps/contentstore/views/public.py
@@ -8,7 +8,7 @@ from mitxmako.shortcuts import render_to_response
from external_auth.views import ssl_login_shortcut
from .user import index
-__all__ = ['signup', 'old_login_redirect', 'login_page', 'howitworks', 'ux_alerts']
+__all__ = ['signup', 'old_login_redirect', 'login_page', 'howitworks']
"""
Public views
@@ -49,10 +49,3 @@ def howitworks(request):
return index(request)
else:
return render_to_response('howitworks.html', {})
-
-
-def ux_alerts(request):
- """
- static/proof-of-concept views
- """
- return render_to_response('ux-alerts.html', {})
diff --git a/cms/djangoapps/contentstore/views/requests.py b/cms/djangoapps/contentstore/views/requests.py
index b02a13fe3f..c493441c77 100644
--- a/cms/djangoapps/contentstore/views/requests.py
+++ b/cms/djangoapps/contentstore/views/requests.py
@@ -21,7 +21,7 @@ def event(request):
A noop to swallow the analytics call so that cms methods don't spook and poor developers looking at
console logs don't get distracted :-)
'''
- return HttpResponse(True)
+ return HttpResponse(status=204)
def get_request_method(request):
diff --git a/cms/envs/acceptance.py b/cms/envs/acceptance.py
index f4b867d3c6..36616ab257 100644
--- a/cms/envs/acceptance.py
+++ b/cms/envs/acceptance.py
@@ -2,6 +2,11 @@
This config file extends the test environment configuration
so that we can run the lettuce acceptance tests.
"""
+
+# We intentionally define lots of variables that aren't used, and
+# want to import all variables from base settings files
+# pylint: disable=W0401, W0614
+
from .test import *
# You need to start the server in debug mode,
@@ -23,7 +28,7 @@ MODULESTORE_OPTIONS = {
MODULESTORE = {
'default': {
- 'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
+ 'ENGINE': 'xmodule.modulestore.mongo.DraftMongoModuleStore',
'OPTIONS': MODULESTORE_OPTIONS
},
'direct': {
diff --git a/cms/envs/aws.py b/cms/envs/aws.py
index 3cd70826da..f6064229e6 100644
--- a/cms/envs/aws.py
+++ b/cms/envs/aws.py
@@ -1,6 +1,11 @@
"""
This is the default template for our main set of AWS servers.
"""
+
+# We intentionally define lots of variables that aren't used, and
+# want to import all variables from base settings files
+# pylint: disable=W0401, W0614
+
import json
from .common import *
@@ -76,6 +81,7 @@ with open(ENV_ROOT / CONFIG_PREFIX + "env.json") as env_file:
ENV_TOKENS = json.load(env_file)
LMS_BASE = ENV_TOKENS.get('LMS_BASE')
+# Note that MITX_FEATURES['PREVIEW_LMS_BASE'] gets read in from the environment file.
SITE_NAME = ENV_TOKENS['SITE_NAME']
diff --git a/cms/envs/common.py b/cms/envs/common.py
index e150374cef..90e15186d7 100644
--- a/cms/envs/common.py
+++ b/cms/envs/common.py
@@ -19,6 +19,10 @@ Longer TODO:
multiple sites, but we do need a way to map their data assets.
"""
+# We intentionally define lots of variables that aren't used, and
+# want to import all variables from base settings files
+# pylint: disable=W0401, W0614
+
import sys
import lms.envs.common
from path import path
@@ -35,8 +39,8 @@ MITX_FEATURES = {
'STUDIO_NPS_SURVEY': True,
'SEGMENT_IO': True,
- # Enable URL that shows information about the status of variuous services
- 'ENABLE_SERVICE_STATUS': False,
+ # Enable URL that shows information about the status of various services
+ 'ENABLE_SERVICE_STATUS': False
}
ENABLE_JASMINE = False
@@ -217,7 +221,9 @@ PIPELINE_JS = {
'source_filenames': sorted(
rooted_glob(COMMON_ROOT / 'static/', 'coffee/src/**/*.js') +
rooted_glob(PROJECT_ROOT / 'static/', 'coffee/src/**/*.js')
- ) + ['js/hesitate.js', 'js/base.js'],
+ ) + ['js/hesitate.js', 'js/base.js',
+ 'js/models/feedback.js', 'js/views/feedback.js',
+ 'js/models/section.js', 'js/views/section.js'],
'output_filename': 'js/cms-application.js',
'test_order': 0
},
@@ -316,6 +322,9 @@ INSTALLED_APPS = (
'pipeline',
'staticfiles',
'static_replace',
+
+ # comment common
+ 'django_comment_common',
)
################# EDX MARKETING SITE ##################################
diff --git a/cms/envs/dev.py b/cms/envs/dev.py
index f3080c356f..e63968d338 100644
--- a/cms/envs/dev.py
+++ b/cms/envs/dev.py
@@ -1,6 +1,10 @@
"""
This config file runs the simplest dev environment"""
+# We intentionally define lots of variables that aren't used, and
+# want to import all variables from base settings files
+# pylint: disable=W0401, W0614
+
from .common import *
from logsettings import get_logger_config
@@ -51,6 +55,7 @@ DATABASES = {
}
LMS_BASE = "localhost:8000"
+MITX_FEATURES['PREVIEW_LMS_BASE'] = "localhost:8000"
REPOS = {
'edx4edx': {
@@ -123,8 +128,7 @@ CELERY_ALWAYS_EAGER = True
################################ DEBUG TOOLBAR #################################
INSTALLED_APPS += ('debug_toolbar', 'debug_toolbar_mongo')
-MIDDLEWARE_CLASSES += ('django_comment_client.utils.QueryCountDebugMiddleware',
- 'debug_toolbar.middleware.DebugToolbarMiddleware',)
+MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
INTERNAL_IPS = ('127.0.0.1',)
DEBUG_TOOLBAR_PANELS = (
diff --git a/cms/envs/dev_ike.py b/cms/envs/dev_ike.py
index 1ebf219d44..0c798b68aa 100644
--- a/cms/envs/dev_ike.py
+++ b/cms/envs/dev_ike.py
@@ -1,3 +1,7 @@
+# We intentionally define lots of variables that aren't used, and
+# want to import all variables from base settings files
+# pylint: disable=W0401, W0614
+
# dev environment for ichuang/mit
# FORCE_SCRIPT_NAME = '/cms'
diff --git a/cms/envs/dev_with_worker.py b/cms/envs/dev_with_worker.py
index c5fc256ac9..078567c493 100644
--- a/cms/envs/dev_with_worker.py
+++ b/cms/envs/dev_with_worker.py
@@ -8,6 +8,10 @@ The worker can be executed using:
django_admin.py celery worker
"""
+# We intentionally define lots of variables that aren't used, and
+# want to import all variables from base settings files
+# pylint: disable=W0401, W0614
+
from dev import *
################################# CELERY ######################################
diff --git a/cms/envs/jasmine.py b/cms/envs/jasmine.py
index 6c7cbcdcb0..a4b8292d71 100644
--- a/cms/envs/jasmine.py
+++ b/cms/envs/jasmine.py
@@ -2,6 +2,10 @@
This configuration is used for running jasmine tests
"""
+# We intentionally define lots of variables that aren't used, and
+# want to import all variables from base settings files
+# pylint: disable=W0401, W0614
+
from .test import *
from logsettings import get_logger_config
@@ -32,8 +36,13 @@ PIPELINE_JS['spec'] = {
}
JASMINE_TEST_DIRECTORY = PROJECT_ROOT + '/static/coffee'
+JASMINE_REPORT_DIR = os.environ.get('JASMINE_REPORT_DIR', 'reports/cms/jasmine')
+
+TEMPLATE_CONTEXT_PROCESSORS += ('settings_context_processor.context_processors.settings',)
+TEMPLATE_VISIBLE_SETTINGS = ('JASMINE_REPORT_DIR', )
STATICFILES_DIRS.append(REPO_ROOT/'node_modules/phantom-jasmine/lib')
+STATICFILES_DIRS.append(REPO_ROOT/'node_modules/jasmine-reporters/src')
# Remove the localization middleware class because it requires the test database
# to be sync'd and migrated in order to run the jasmine tests interactively
@@ -41,4 +50,4 @@ STATICFILES_DIRS.append(REPO_ROOT/'node_modules/phantom-jasmine/lib')
MIDDLEWARE_CLASSES = tuple(e for e in MIDDLEWARE_CLASSES \
if e != 'django.middleware.locale.LocaleMiddleware')
-INSTALLED_APPS += ('django_jasmine', )
+INSTALLED_APPS += ('django_jasmine', 'settings_context_processor')
diff --git a/cms/envs/test.py b/cms/envs/test.py
index 4cb975e2fb..8a3f9ba158 100644
--- a/cms/envs/test.py
+++ b/cms/envs/test.py
@@ -7,6 +7,11 @@ sessions. Assumes structure:
/mitx # The location of this repo
/log # Where we're going to write log files
"""
+
+# We intentionally define lots of variables that aren't used, and
+# want to import all variables from base settings files
+# pylint: disable=W0401, W0614
+
from .common import *
import os
from path import path
@@ -77,6 +82,7 @@ DATABASES = {
}
LMS_BASE = "localhost:8000"
+MITX_FEATURES['PREVIEW_LMS_BASE'] = "preview"
CACHES = {
# This is the cache used for most things. Askbot will not work without a
diff --git a/cms/static/client_templates/checklist.html b/cms/static/client_templates/checklist.html
index 6884b0e9c9..e985ab9509 100644
--- a/cms/static/client_templates/checklist.html
+++ b/cms/static/client_templates/checklist.html
@@ -11,11 +11,11 @@
<%= percentChecked %>% of checklist completed
- ▾
+
<%= checklistShortDescription %>
Tasks Completed: <%= itemsChecked %>/<%= items.length %>
- ✓
+