diff --git a/cms/djangoapps/contentstore/features/textbooks.py b/cms/djangoapps/contentstore/features/textbooks.py index 13a952287b..ca135d9725 100644 --- a/cms/djangoapps/contentstore/features/textbooks.py +++ b/cms/djangoapps/contentstore/features/textbooks.py @@ -14,6 +14,7 @@ def go_to_uploads(_step): menu_css = 'li.nav-course-courseware-textbooks' world.css_find(menu_css).click() + @step(u'I should see a message telling me to create a new textbook') def assert_create_new_textbook_msg(_step): css = ".wrapper-content .no-textbook-content" @@ -21,6 +22,7 @@ def assert_create_new_textbook_msg(_step): no_tb = world.css_find(css) assert "You haven't added any textbooks" in no_tb.text + @step(u'I upload the textbook "([^"]*)"$') def upload_file(_step, file_name): file_css = '.upload-dialog input[type=file]' @@ -31,45 +33,53 @@ def upload_file(_step, file_name): button_css = ".upload-dialog .action-upload" world.css_click(button_css) + @step(u'I click (on )?the New Textbook button') def click_new_textbook(_step, on): button_css = ".nav-actions .new-button" button = world.css_find(button_css) button.click() + @step(u'I name my textbook "([^"]*)"') def name_textbook(_step, name): input_css = ".textbook input[name=textbook-name]" world.css_fill(input_css, name) + @step(u'I name the (first|second|third) chapter "([^"]*)"') def name_chapter(_step, ordinal, name): index = ["first", "second", "third"].index(ordinal) input_css = ".textbook .chapter{i} input.chapter-name".format(i=index+1) world.css_fill(input_css, name) + @step(u'I type in "([^"]*)" for the (first|second|third) chapter asset') def asset_chapter(_step, name, ordinal): index = ["first", "second", "third"].index(ordinal) input_css = ".textbook .chapter{i} input.chapter-asset-path".format(i=index+1) world.css_fill(input_css, name) + @step(u'I click the Upload Asset link for the (first|second|third) chapter') def click_upload_asset(_step, ordinal): index = ["first", "second", "third"].index(ordinal) button_css = ".textbook .chapter{i} .action-upload".format(i=index+1) world.css_click(button_css) + @step(u'I click Add a Chapter') def click_add_chapter(_step): button_css = ".textbook .action-add-chapter" world.css_click(button_css) + @step(u'I save the textbook') def save_textbook(_step): submit_css = "form.edit-textbook button[type=submit]" world.css_click(submit_css) + @step(u'I should see a textbook named "([^"]*)" with a chapter path containing "([^"]*)"') def check_textbook(_step, textbook_name, chapter_name): title = world.css_find(".textbook h3.textbook-title") @@ -77,8 +87,9 @@ def check_textbook(_step, textbook_name, chapter_name): assert title.text == textbook_name, "{} != {}".format(title.text, textbook_name) assert chapter.text == chapter_name, "{} != {}".format(chapter.text, chapter_name) + @step(u'I should see a textbook named "([^"]*)" with (\d+) chapters') -def check_textbook(_step, textbook_name, num_chapters_str): +def check_textbook_chapters(_step, textbook_name, num_chapters_str): num_chapters = int(num_chapters_str) title = world.css_find(".textbook .view-textbook h3.textbook-title") toggle = world.css_find(".textbook .view-textbook .chapter-toggle") @@ -86,10 +97,12 @@ def check_textbook(_step, textbook_name, num_chapters_str): assert toggle.text == "{num} PDF Chapters".format(num=num_chapters), \ "Expected {num} chapters, found {real}".format(num=num_chapters, real=toggle.text) + @step(u'I click the textbook chapters') def click_chapters(_step): world.css_click(".textbook a.chapter-toggle") + @step(u'the (first|second|third) chapter should be named "([^"]*)"') def check_chapter_name(_step, ordinal, name): index = ["first", "second", "third"].index(ordinal) @@ -98,8 +111,9 @@ def check_chapter_name(_step, ordinal, name): assert element.text == name, "Expected chapter named {expected}, found chapter named {actual}".format( expected=name, actual=element.text) + @step(u'the (first|second|third) chapter should have an asset called "([^"]*)"') -def check_chapter_name(_step, ordinal, name): +def check_chapter_asset(_step, ordinal, name): index = ["first", "second", "third"].index(ordinal) chapter = world.css_find(".textbook .view-textbook ol.chapters li")[index] element = chapter.find_by_css(".chapter-asset-path") diff --git a/cms/djangoapps/contentstore/tests/test_assets.py b/cms/djangoapps/contentstore/tests/test_assets.py index 4509949170..58aee3c77d 100644 --- a/cms/djangoapps/contentstore/tests/test_assets.py +++ b/cms/djangoapps/contentstore/tests/test_assets.py @@ -1,3 +1,7 @@ +""" +Unit tests for the asset upload endpoint. +""" + import json from datetime import datetime from io import BytesIO @@ -33,6 +37,9 @@ class AssetsTestCase(CourseTestCase): class UploadTestCase(CourseTestCase): + """ + Unit tests for uploading a file + """ def setUp(self): super(UploadTestCase, self).setUp() self.url = reverse("upload_asset", kwargs={ @@ -43,9 +50,9 @@ class UploadTestCase(CourseTestCase): @skip("CorruptGridFile error on continuous integration server") def test_happy_path(self): - f = BytesIO("sample content") - f.name = "sample.txt" - resp = self.client.post(self.url, {"name": "my-name", "file": f}) + file = BytesIO("sample content") + file.name = "sample.txt" + resp = self.client.post(self.url, {"name": "my-name", "file": file}) self.assert2XX(resp.status_code) def test_no_file(self): @@ -58,6 +65,10 @@ class UploadTestCase(CourseTestCase): class AssetsToJsonTestCase(TestCase): + """ + Unit tests for transforming the results of a database call into something + we can send out to the client via JSON. + """ def test_basic(self): upload_date = datetime(2013, 6, 1, 10, 30, tzinfo=UTC) asset = { diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index dbfc797caa..8400f35171 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -1,3 +1,5 @@ +#pylint: disable=E1101 + import json import shutil import mock diff --git a/cms/djangoapps/contentstore/tests/tests.py b/cms/djangoapps/contentstore/tests/tests.py index f7f330f91e..d55a7eff55 100644 --- a/cms/djangoapps/contentstore/tests/tests.py +++ b/cms/djangoapps/contentstore/tests/tests.py @@ -10,11 +10,13 @@ from pytz import UTC class ContentStoreTestCase(ModuleStoreTestCase): - def _login(self, email, pw): - """Login. View should always return 200. The success/fail is in the - returned json""" + def _login(self, email, password): + """ + Login. View should always return 200. The success/fail is in the + returned json + """ resp = self.client.post(reverse('login_post'), - {'email': email, 'password': pw}) + {'email': email, 'password': password}) self.assertEqual(resp.status_code, 200) return resp @@ -25,12 +27,12 @@ class ContentStoreTestCase(ModuleStoreTestCase): self.assertTrue(data['success']) return resp - def _create_account(self, username, email, pw): + def _create_account(self, username, email, password): """Try to create an account. No error checking""" resp = self.client.post('/create_account', { 'username': username, 'email': email, - 'password': pw, + 'password': password, 'location': 'home', 'language': 'Franglish', 'name': 'Fred Weasley', @@ -39,9 +41,9 @@ class ContentStoreTestCase(ModuleStoreTestCase): }) return resp - def create_account(self, username, email, pw): + def create_account(self, username, email, password): """Create the account and check that it worked""" - resp = self._create_account(username, email, pw) + resp = self._create_account(username, email, password) self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertEqual(data['success'], True) @@ -88,7 +90,7 @@ class AuthTestCase(ContentStoreTestCase): reverse('signup'), ) for page in pages: - print "Checking '{0}'".format(page) + print("Checking '{0}'".format(page)) self.check_page_get(page, 200) def test_create_account_errors(self): @@ -146,17 +148,17 @@ class AuthTestCase(ContentStoreTestCase): self.client = Client() # Not logged in. Should redirect to login. - print 'Not logged in' + print('Not logged in') for page in auth_pages: - print "Checking '{0}'".format(page) + print("Checking '{0}'".format(page)) self.check_page_get(page, expected=302) # Logged in should work. self.login(self.email, self.pw) - print 'Logged in' + print('Logged in') for page in simple_auth_pages: - print "Checking '{0}'".format(page) + print("Checking '{0}'".format(page)) self.check_page_get(page, expected=200) def test_index_auth(self): diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index c9c40ab95d..452806fe64 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -1,3 +1,5 @@ +#pylint: disable=E1103, E1101 + from django.conf import settings from xmodule.modulestore import Location from xmodule.modulestore.django import modulestore diff --git a/cms/djangoapps/contentstore/views/error.py b/cms/djangoapps/contentstore/views/error.py index 5a34af36bc..56499a69ac 100644 --- a/cms/djangoapps/contentstore/views/error.py +++ b/cms/djangoapps/contentstore/views/error.py @@ -1,3 +1,5 @@ +#pylint: disable=C0111,W0613 + from django.http import (HttpResponse, HttpResponseServerError, HttpResponseNotFound) from mitxmako.shortcuts import render_to_string, render_to_response diff --git a/cms/djangoapps/models/settings/course_metadata.py b/cms/djangoapps/models/settings/course_metadata.py index 937ba56f69..5fb07fe806 100644 --- a/cms/djangoapps/models/settings/course_metadata.py +++ b/cms/djangoapps/models/settings/course_metadata.py @@ -61,19 +61,19 @@ class CourseMetadata(object): if not filter_tabs: filtered_list.remove("tabs") - for k, v in jsondict.iteritems(): + for key, val in jsondict.iteritems(): # should it be an error if one of the filtered list items is in the payload? - if k in filtered_list: + if key in filtered_list: continue - if hasattr(descriptor, k) and getattr(descriptor, k) != v: + if hasattr(descriptor, key) and getattr(descriptor, key) != val: dirty = True - value = getattr(CourseDescriptor, k).from_json(v) - setattr(descriptor, k, value) - elif hasattr(descriptor.lms, k) and getattr(descriptor.lms, k) != k: + value = getattr(CourseDescriptor, key).from_json(val) + setattr(descriptor, key, value) + elif hasattr(descriptor.lms, key) and getattr(descriptor.lms, key) != key: dirty = True - value = getattr(CourseDescriptor.lms, k).from_json(v) - setattr(descriptor.lms, k, value) + value = getattr(CourseDescriptor.lms, key).from_json(val) + setattr(descriptor.lms, key, value) if dirty: get_modulestore(course_location).update_metadata(course_location, diff --git a/cms/envs/debug_upload.py b/cms/envs/debug_upload.py index 683871a530..56e9f39bd5 100644 --- a/cms/envs/debug_upload.py +++ b/cms/envs/debug_upload.py @@ -1,3 +1,4 @@ +#pylint: disable=W0614, W0401 from .dev import * FILE_UPLOAD_HANDLERS = ( diff --git a/cms/one_time_startup.py b/cms/one_time_startup.py index 5cc74a8fd7..cbd8775d97 100644 --- a/cms/one_time_startup.py +++ b/cms/one_time_startup.py @@ -6,10 +6,10 @@ from request_cache.middleware import RequestCache from django.core.cache import get_cache -cache = get_cache('mongo_metadata_inheritance') +CACHE = get_cache('mongo_metadata_inheritance') for store_name in settings.MODULESTORE: store = modulestore(store_name) - store.metadata_inheritance_cache_subsystem = cache + store.metadata_inheritance_cache_subsystem = CACHE store.request_cache = RequestCache.get_request_cache() modulestore_update_signal = Signal(providing_args=['modulestore', 'course_id', 'location']) diff --git a/cms/urls.py b/cms/urls.py index d58272c651..56efd1a557 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -154,5 +154,6 @@ urlpatterns += (url(r'^admin/', include(admin.site.urls)),) urlpatterns = patterns(*urlpatterns) # Custom error pages +#pylint: disable=C0103 handler404 = 'contentstore.views.render_404' handler500 = 'contentstore.views.render_500' diff --git a/common/djangoapps/terrain/ui_helpers.py b/common/djangoapps/terrain/ui_helpers.py index 39856da3dc..08e2f04254 100644 --- a/common/djangoapps/terrain/ui_helpers.py +++ b/common/djangoapps/terrain/ui_helpers.py @@ -206,12 +206,14 @@ def save_the_html(path='/tmp'): with open(filename, "w") as f: f.write(html) + @world.absorb def click_course_content(): course_content_css = 'li.nav-course-courseware' if world.browser.is_element_present_by_css(course_content_css): world.css_click(course_content_css) + @world.absorb def click_course_settings(): course_settings_css = 'li.nav-course-settings'