Commit 36e77c74 by David Baumgold

Fixing pep8 issues

parent d65d3094
...@@ -285,7 +285,7 @@ def use_code_editor(action): ...@@ -285,7 +285,7 @@ def use_code_editor(action):
def perform_action_in_plugin(action): def perform_action_in_plugin(action):
# Wait for the plugin window to open. # Wait for the plugin window to open.
world.wait_for_visible('.mce-window') world.wait_for_visible('.mce-window')
# Trigger the action # Trigger the action
......
...@@ -13,7 +13,9 @@ class Content: ...@@ -13,7 +13,9 @@ class Content:
class CachingTestCase(TestCase): class CachingTestCase(TestCase):
# Tests for https://edx.lighthouseapp.com/projects/102637/tickets/112-updating-asset-does-not-refresh-the-cached-copy """
Tests for https://edx.lighthouseapp.com/projects/102637/tickets/112-updating-asset-does-not-refresh-the-cached-copy
"""
unicodeLocation = Location(u'c4x', u'mitX', u'800', u'run', u'thumbnail', u'monsters.jpg') unicodeLocation = Location(u'c4x', u'mitX', u'800', u'run', u'thumbnail', u'monsters.jpg')
# Note that some of the parts are strings instead of unicode strings # Note that some of the parts are strings instead of unicode strings
nonUnicodeLocation = Location('c4x', u'mitX', u'800', u'run', 'thumbnail', 'monsters.jpg') nonUnicodeLocation = Location('c4x', u'mitX', u'800', u'run', 'thumbnail', 'monsters.jpg')
......
...@@ -303,7 +303,7 @@ def get_component_templates(course): ...@@ -303,7 +303,7 @@ def get_component_templates(course):
# Set component types according to course policy file # Set component types according to course policy file
if isinstance(course_advanced_keys, list): if isinstance(course_advanced_keys, list):
for category in course_advanced_keys: for category in course_advanced_keys:
if category in advanced_component_types and not category in categories: if category in advanced_component_types and category not in categories:
# boilerplates not supported for advanced components # boilerplates not supported for advanced components
try: try:
component_display_name = xblock_type_display_name(category, default_display_name=category) component_display_name = xblock_type_display_name(category, default_display_name=category)
......
...@@ -1028,7 +1028,7 @@ def textbooks_list_handler(request, course_key_string): ...@@ -1028,7 +1028,7 @@ def textbooks_list_handler(request, course_key_string):
with store.bulk_operations(course_key): with store.bulk_operations(course_key):
course = _get_course_module(course_key, request.user) course = _get_course_module(course_key, request.user)
if not "application/json" in request.META.get('HTTP_ACCEPT', 'text/html'): if "application/json" not in request.META.get('HTTP_ACCEPT', 'text/html'):
# return HTML page # return HTML page
upload_asset_url = reverse_course_url('assets_handler', course_key) upload_asset_url = reverse_course_url('assets_handler', course_key)
textbook_url = reverse_course_url('textbooks_list_handler', course_key) textbook_url = reverse_course_url('textbooks_list_handler', course_key)
...@@ -1050,7 +1050,7 @@ def textbooks_list_handler(request, course_key_string): ...@@ -1050,7 +1050,7 @@ def textbooks_list_handler(request, course_key_string):
tids = set(t["id"] for t in textbooks if "id" in t) tids = set(t["id"] for t in textbooks if "id" in t)
for textbook in textbooks: for textbook in textbooks:
if not "id" in textbook: if "id" not in textbook:
tid = assign_textbook_id(textbook, tids) tid = assign_textbook_id(textbook, tids)
textbook["id"] = tid textbook["id"] = tid
tids.add(tid) tids.add(tid)
...@@ -1347,7 +1347,7 @@ def group_configurations_list_handler(request, course_key_string): ...@@ -1347,7 +1347,7 @@ def group_configurations_list_handler(request, course_key_string):
}) })
elif "application/json" in request.META.get('HTTP_ACCEPT'): elif "application/json" in request.META.get('HTTP_ACCEPT'):
if request.method == 'POST': if request.method == 'POST':
# create a new group configuration for the course # create a new group configuration for the course
try: try:
new_configuration = GroupConfiguration(request.body, course).get_user_partition() new_configuration = GroupConfiguration(request.body, course).get_user_partition()
except GroupConfigurationsValidationError as err: except GroupConfigurationsValidationError as err:
......
...@@ -158,8 +158,9 @@ filterwarnings('ignore', message='No request passed to the backend, unable to ra ...@@ -158,8 +158,9 @@ filterwarnings('ignore', message='No request passed to the backend, unable to ra
# Ignore deprecation warnings (so we don't clutter Jenkins builds/production) # Ignore deprecation warnings (so we don't clutter Jenkins builds/production)
# https://docs.python.org/2/library/warnings.html#the-warnings-filter # https://docs.python.org/2/library/warnings.html#the-warnings-filter
simplefilter('ignore') # Change to "default" to see the first instance of each hit simplefilter('ignore')
# or "error" to convert all into errors # Change to "default" to see the first instance of each hit
# or "error" to convert all into errors
################################# CELERY ###################################### ################################# CELERY ######################################
......
...@@ -64,8 +64,9 @@ class Role(models.Model): ...@@ -64,8 +64,9 @@ class Role(models.Model):
# pylint: disable=no-member # pylint: disable=no-member
return self.name + " for " + (self.course_id.to_deprecated_string() if self.course_id else "all courses") return self.name + " for " + (self.course_id.to_deprecated_string() if self.course_id else "all courses")
def inherit_permissions(self, role): # TODO the name of this method is a little bit confusing, # TODO the name of this method is a little bit confusing,
# since it's one-off and doesn't handle inheritance later # since it's one-off and doesn't handle inheritance later
def inherit_permissions(self, role):
if role.course_id and role.course_id != self.course_id: if role.course_id and role.course_id != self.course_id:
logging.warning( logging.warning(
"%s cannot inherit permissions from %s due to course_id inconsistency", "%s cannot inherit permissions from %s due to course_id inconsistency",
......
...@@ -452,50 +452,50 @@ class PasswordHistory(models.Model): ...@@ -452,50 +452,50 @@ class PasswordHistory(models.Model):
""" """
Returns whether the configuration which limits password reuse has been turned on Returns whether the configuration which limits password reuse has been turned on
""" """
return settings.FEATURES['ADVANCED_SECURITY'] and \ min_diff_pw = settings.ADVANCED_SECURITY_CONFIG.get(
settings.ADVANCED_SECURITY_CONFIG.get( 'MIN_DIFFERENT_STUDENT_PASSWORDS_BEFORE_REUSE', 0
'MIN_DIFFERENT_STUDENT_PASSWORDS_BEFORE_REUSE', 0 )
) > 0 return settings.FEATURES['ADVANCED_SECURITY'] and min_diff_pw > 0
@classmethod @classmethod
def is_staff_password_reuse_restricted(cls): def is_staff_password_reuse_restricted(cls):
""" """
Returns whether the configuration which limits password reuse has been turned on Returns whether the configuration which limits password reuse has been turned on
""" """
return settings.FEATURES['ADVANCED_SECURITY'] and \ min_diff_pw = settings.ADVANCED_SECURITY_CONFIG.get(
settings.ADVANCED_SECURITY_CONFIG.get( 'MIN_DIFFERENT_STAFF_PASSWORDS_BEFORE_REUSE', 0
'MIN_DIFFERENT_STAFF_PASSWORDS_BEFORE_REUSE', 0 )
) > 0 return settings.FEATURES['ADVANCED_SECURITY'] and min_diff_pw > 0
@classmethod @classmethod
def is_password_reset_frequency_restricted(cls): def is_password_reset_frequency_restricted(cls):
""" """
Returns whether the configuration which limits the password reset frequency has been turned on Returns whether the configuration which limits the password reset frequency has been turned on
""" """
return settings.FEATURES['ADVANCED_SECURITY'] and \ min_days_between_reset = settings.ADVANCED_SECURITY_CONFIG.get(
settings.ADVANCED_SECURITY_CONFIG.get( 'MIN_TIME_IN_DAYS_BETWEEN_ALLOWED_RESETS'
'MIN_TIME_IN_DAYS_BETWEEN_ALLOWED_RESETS', None )
) return settings.FEATURES['ADVANCED_SECURITY'] and min_days_between_reset
@classmethod @classmethod
def is_staff_forced_password_reset_enabled(cls): def is_staff_forced_password_reset_enabled(cls):
""" """
Returns whether the configuration which forces password resets to occur has been turned on Returns whether the configuration which forces password resets to occur has been turned on
""" """
return settings.FEATURES['ADVANCED_SECURITY'] and \ min_days_between_reset = settings.ADVANCED_SECURITY_CONFIG.get(
settings.ADVANCED_SECURITY_CONFIG.get( 'MIN_DAYS_FOR_STAFF_ACCOUNTS_PASSWORD_RESETS'
'MIN_DAYS_FOR_STAFF_ACCOUNTS_PASSWORD_RESETS', None )
) return settings.FEATURES['ADVANCED_SECURITY'] and min_days_between_reset
@classmethod @classmethod
def is_student_forced_password_reset_enabled(cls): def is_student_forced_password_reset_enabled(cls):
""" """
Returns whether the configuration which forces password resets to occur has been turned on Returns whether the configuration which forces password resets to occur has been turned on
""" """
return settings.FEATURES['ADVANCED_SECURITY'] and \ min_days_pw_reset = settings.ADVANCED_SECURITY_CONFIG.get(
settings.ADVANCED_SECURITY_CONFIG.get( 'MIN_DAYS_FOR_STUDENT_ACCOUNTS_PASSWORD_RESETS'
'MIN_DAYS_FOR_STUDENT_ACCOUNTS_PASSWORD_RESETS', None )
) return settings.FEATURES['ADVANCED_SECURITY'] and min_days_pw_reset
@classmethod @classmethod
def should_user_reset_password_now(cls, user): def should_user_reset_password_now(cls, user):
......
...@@ -41,13 +41,13 @@ class TestStudentDashboardEmailView(ModuleStoreTestCase): ...@@ -41,13 +41,13 @@ class TestStudentDashboardEmailView(ModuleStoreTestCase):
self.url = reverse('dashboard') self.url = reverse('dashboard')
# URL for email settings modal # URL for email settings modal
self.email_modal_link = ( self.email_modal_link = (
('<a href="#email-settings-modal" class="email-settings" rel="leanModal" ' '<a href="#email-settings-modal" class="email-settings" rel="leanModal" '
'data-course-id="{0}/{1}/{2}" data-course-number="{1}" ' 'data-course-id="{org}/{num}/{name}" data-course-number="{num}" '
'data-optout="False">Email Settings</a>').format( 'data-optout="False">Email Settings</a>'
self.course.org, ).format(
self.course.number, org=self.course.org,
self.course.display_name.replace(' ', '_') num=self.course.number,
) name=self.course.display_name.replace(' ', '_'),
) )
def tearDown(self): def tearDown(self):
...@@ -111,13 +111,13 @@ class TestStudentDashboardEmailViewXMLBacked(ModuleStoreTestCase): ...@@ -111,13 +111,13 @@ class TestStudentDashboardEmailViewXMLBacked(ModuleStoreTestCase):
# URL for email settings modal # URL for email settings modal
self.email_modal_link = ( self.email_modal_link = (
('<a href="#email-settings-modal" class="email-settings" rel="leanModal" ' '<a href="#email-settings-modal" class="email-settings" rel="leanModal" '
'data-course-id="{0}/{1}/{2}" data-course-number="{1}" ' 'data-course-id="{org}/{num}/{name}" data-course-number="{num}" '
'data-optout="False">Email Settings</a>').format( 'data-optout="False">Email Settings</a>'
'edX', ).format(
'toy', org='edX',
'2012_Fall' num='toy',
) name='2012_Fall',
) )
@patch.dict(settings.FEATURES, {'ENABLE_INSTRUCTOR_EMAIL': True, 'REQUIRE_COURSE_EMAIL_AUTH': False}) @patch.dict(settings.FEATURES, {'ENABLE_INSTRUCTOR_EMAIL': True, 'REQUIRE_COURSE_EMAIL_AUTH': False})
......
...@@ -1002,7 +1002,7 @@ def login_user(request, error=""): # pylint: disable-msg=too-many-statements,un ...@@ -1002,7 +1002,7 @@ def login_user(request, error=""): # pylint: disable-msg=too-many-statements,un
_("Use your {platform_name} username and password to log into {platform_name} below, " _("Use your {platform_name} username and password to log into {platform_name} below, "
"and then link your {platform_name} account with {provider_name} from your dashboard.").format( "and then link your {platform_name} account with {provider_name} from your dashboard.").format(
platform_name=settings.PLATFORM_NAME, provider_name=requested_provider.NAME platform_name=settings.PLATFORM_NAME, provider_name=requested_provider.NAME
) )
+ "<br/><br/>" + + "<br/><br/>" +
_("If you don't have an {platform_name} account yet, click <strong>Register Now</strong> at the top of the page.").format( _("If you don't have an {platform_name} account yet, click <strong>Register Now</strong> at the top of the page.").format(
platform_name=settings.PLATFORM_NAME platform_name=settings.PLATFORM_NAME
......
...@@ -55,7 +55,7 @@ def store_uploaded_file( ...@@ -55,7 +55,7 @@ def store_uploaded_file(
uploaded_file = request.FILES[file_key] uploaded_file = request.FILES[file_key]
try: try:
file_extension = os.path.splitext(uploaded_file.name)[1].lower() file_extension = os.path.splitext(uploaded_file.name)[1].lower()
if not file_extension in allowed_file_types: if file_extension not in allowed_file_types:
file_types = "', '".join(allowed_file_types) file_types = "', '".join(allowed_file_types)
msg = ungettext( msg = ungettext(
"The file must end with the extension '{file_types}'.", "The file must end with the extension '{file_types}'.",
......
...@@ -122,7 +122,7 @@ class CorrectMap(object): ...@@ -122,7 +122,7 @@ class CorrectMap(object):
return npoints return npoints
elif self.is_correct(answer_id): elif self.is_correct(answer_id):
return 1 return 1
# if not correct and no points have been assigned, return 0 # if not correct and no points have been assigned, return 0
return 0 return 0
def set_property(self, answer_id, property, value): def set_property(self, answer_id, property, value):
......
...@@ -44,7 +44,7 @@ class MathRenderer(object): ...@@ -44,7 +44,7 @@ class MathRenderer(object):
mathstr = re.sub(r'\$(.*)\$', r'[mathjaxinline]\1[/mathjaxinline]', xml.text) mathstr = re.sub(r'\$(.*)\$', r'[mathjaxinline]\1[/mathjaxinline]', xml.text)
mtag = 'mathjax' mtag = 'mathjax'
if not r'\displaystyle' in mathstr: if r'\displaystyle' not in mathstr:
mtag += 'inline' mtag += 'inline'
else: else:
mathstr = mathstr.replace(r'\displaystyle', '') mathstr = mathstr.replace(r'\displaystyle', '')
......
...@@ -74,5 +74,4 @@ class MathRenderTest(unittest.TestCase): ...@@ -74,5 +74,4 @@ class MathRenderTest(unittest.TestCase):
self.check_parse('$abc', '$abc') self.check_parse('$abc', '$abc')
self.check_parse(r'$\displaystyle 2+2$', '[mathjax] 2+2[/mathjax]') self.check_parse(r'$\displaystyle 2+2$', '[mathjax] 2+2[/mathjax]')
# NOTE: not testing get_html yet because I don't understand why it's doing what it's doing. # NOTE: not testing get_html yet because I don't understand why it's doing what it's doing.
...@@ -795,17 +795,30 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase): ...@@ -795,17 +795,30 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase):
'1_choiceinput_1_textinput_0': '0'} '1_choiceinput_1_textinput_0': '0'}
def setUp(self): def setUp(self):
choices = [('1_choiceinput_0bc', choices = [
[{'tail_text': '', 'type': 'text', 'value': '', 'contents': ''}, (
{'tail_text': '', 'type': 'textinput', 'value': '', 'contents': 'choiceinput_0_textinput_0'}]), '1_choiceinput_0bc',
('1_choiceinput_1bc', [{'tail_text': '', 'type': 'text', 'value': '', 'contents': ''}, [
{'tail_text': '', 'type': 'textinput', 'value': '', 'contents': 'choiceinput_1_textinput_0'}])] {'tail_text': '', 'type': 'text', 'value': '', 'contents': ''},
self.context = {'id': '1', {'tail_text': '', 'type': 'textinput', 'value': '', 'contents': 'choiceinput_0_textinput_0'},
'choices': choices, ]
'status': Status('correct'), ),
'input_type': 'radio', (
'label': 'choicetext label', '1_choiceinput_1bc',
'value': self.VALUE_DICT} [
{'tail_text': '', 'type': 'text', 'value': '', 'contents': ''},
{'tail_text': '', 'type': 'textinput', 'value': '', 'contents': 'choiceinput_1_textinput_0'},
]
)
]
self.context = {
'id': '1',
'choices': choices,
'status': Status('correct'),
'input_type': 'radio',
'label': 'choicetext label',
'value': self.VALUE_DICT,
}
super(ChoiceTextGroupTemplateTest, self).setUp() super(ChoiceTextGroupTemplateTest, self).setUp()
...@@ -885,7 +898,8 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase): ...@@ -885,7 +898,8 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase):
{'status': Status('unsubmitted'), 'input_type': 'checkbox', 'value': {}}, {'status': Status('unsubmitted'), 'input_type': 'checkbox', 'value': {}},
{'status': Status('unsubmitted'), 'input_type': 'checkbox', 'value': self.EMPTY_DICT}, {'status': Status('unsubmitted'), 'input_type': 'checkbox', 'value': self.EMPTY_DICT},
{'status': Status('unsubmitted'), 'input_type': 'checkbox', 'value': self.VALUE_DICT}, {'status': Status('unsubmitted'), 'input_type': 'checkbox', 'value': self.VALUE_DICT},
{'status': Status('unsubmitted'), 'input_type': 'checkbox', 'value': self.BOTH_CHOICE_CHECKBOX}] {'status': Status('unsubmitted'), 'input_type': 'checkbox', 'value': self.BOTH_CHOICE_CHECKBOX},
]
self.context['status'] = Status('unanswered') self.context['status'] = Status('unanswered')
......
...@@ -731,7 +731,7 @@ class StringResponseTest(ResponseTest): ...@@ -731,7 +731,7 @@ class StringResponseTest(ResponseTest):
case_sensitive=False, case_sensitive=False,
hints=hints, hints=hints,
) )
# We should get a hint for Wisconsin # We should get a hint for Wisconsin
input_dict = {'1_2_1': 'Wisconsin'} input_dict = {'1_2_1': 'Wisconsin'}
correct_map = problem.grade_answers(input_dict) correct_map = problem.grade_answers(input_dict)
self.assertEquals(correct_map.get_hint('1_2_1'), self.assertEquals(correct_map.get_hint('1_2_1'),
......
...@@ -36,7 +36,7 @@ class UtilTest(unittest.TestCase): ...@@ -36,7 +36,7 @@ class UtilTest(unittest.TestCase):
self.assertTrue(result) self.assertTrue(result)
result = compare_with_tolerance(110.1, 100.0, '10.0', False) result = compare_with_tolerance(110.1, 100.0, '10.0', False)
self.assertFalse(result) self.assertFalse(result)
# Test relative tolerance (string) # Test relative tolerance (string)
result = compare_with_tolerance(111.0, 100.0, '0.1', True) result = compare_with_tolerance(111.0, 100.0, '0.1', True)
self.assertTrue(result) self.assertTrue(result)
result = compare_with_tolerance(112.0, 100.0, '0.1', True) result = compare_with_tolerance(112.0, 100.0, '0.1', True)
...@@ -46,7 +46,7 @@ class UtilTest(unittest.TestCase): ...@@ -46,7 +46,7 @@ class UtilTest(unittest.TestCase):
self.assertTrue(result) self.assertTrue(result)
result = compare_with_tolerance(110.1, 100.0, 10.0, False) result = compare_with_tolerance(110.1, 100.0, 10.0, False)
self.assertFalse(result) self.assertFalse(result)
# Test relative tolerance (float) # Test relative tolerance (float)
result = compare_with_tolerance(111.0, 100.0, 0.1, True) result = compare_with_tolerance(111.0, 100.0, 0.1, True)
self.assertTrue(result) self.assertTrue(result)
result = compare_with_tolerance(112.0, 100.0, 0.1, True) result = compare_with_tolerance(112.0, 100.0, 0.1, True)
......
...@@ -191,7 +191,7 @@ class DragAndDrop(object): ...@@ -191,7 +191,7 @@ class DragAndDrop(object):
self.user_positions[index]['user'], flag=rule): self.user_positions[index]['user'], flag=rule):
return False return False
if not rules_executed: # no correct rules for current group if not rules_executed: # no correct rules for current group
# probably xml content mistake - wrong rules names # probably xml content mistake - wrong rules names
return False return False
return True return True
......
...@@ -90,15 +90,16 @@ class Test_DragAndDrop_Grade(unittest.TestCase): ...@@ -90,15 +90,16 @@ class Test_DragAndDrop_Grade(unittest.TestCase):
}, },
{ {
'draggables': ['up_and_down'], 'draggables': ['up_and_down'],
'targets': [ 'targets': ['s_l[s][1]', 's_r[s][1]'],
's_l[s][1]', 's_r[s][1]'
],
'rule': 'unordered_equal' 'rule': 'unordered_equal'
}, },
{ {
'draggables': ['up'], 'draggables': ['up'],
'targets': [ 'targets': [
'p_l[p][1]', 'p_l[p][3]', 'p_r[p][1]', 'p_r[p][3]' 'p_l[p][1]',
'p_l[p][3]',
'p_r[p][1]',
'p_r[p][3]',
], ],
'rule': 'unordered_equal' 'rule': 'unordered_equal'
} }
...@@ -132,15 +133,16 @@ class Test_DragAndDrop_Grade(unittest.TestCase): ...@@ -132,15 +133,16 @@ class Test_DragAndDrop_Grade(unittest.TestCase):
}, },
{ {
'draggables': ['up_and_down'], 'draggables': ['up_and_down'],
'targets': [ 'targets': ['s_l[s][1]', 's_r[s][1]'],
's_l[s][1]', 's_r[s][1]'
],
'rule': 'unordered_equal' 'rule': 'unordered_equal'
}, },
{ {
'draggables': ['up'], 'draggables': ['up'],
'targets': [ 'targets': [
'p_l[p][1]', 'p_l[p][3]', 'p_r[p][1]', 'p_r[p][3]' 'p_l[p][1]',
'p_l[p][3]',
'p_r[p][1]',
'p_r[p][3]',
], ],
'rule': 'unordered_equal' 'rule': 'unordered_equal'
} }
...@@ -173,7 +175,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): ...@@ -173,7 +175,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase):
'draggables': ['p'], 'draggables': ['p'],
'targets': [ 'targets': [
'left_side_tagret[molecule][p_target]', 'left_side_tagret[molecule][p_target]',
'right_side_tagret[molecule][p_target]' 'right_side_tagret[molecule][p_target]',
], ],
'rule': 'unordered_equal' 'rule': 'unordered_equal'
}, },
...@@ -181,7 +183,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): ...@@ -181,7 +183,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase):
'draggables': ['s'], 'draggables': ['s'],
'targets': [ 'targets': [
'left_side_tagret[molecule][s_target]', 'left_side_tagret[molecule][s_target]',
'right_side_tagret[molecule][s_target]' 'right_side_tagret[molecule][s_target]',
], ],
'rule': 'unordered_equal' 'rule': 'unordered_equal'
}, },
...@@ -189,7 +191,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): ...@@ -189,7 +191,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase):
'draggables': ['up_and_down'], 'draggables': ['up_and_down'],
'targets': [ 'targets': [
'left_side_tagret[molecule][s_target][s][1]', 'left_side_tagret[molecule][s_target][s][1]',
'right_side_tagret[molecule][s_target][s][1]' 'right_side_tagret[molecule][s_target][s][1]',
], ],
'rule': 'unordered_equal' 'rule': 'unordered_equal'
}, },
...@@ -199,7 +201,8 @@ class Test_DragAndDrop_Grade(unittest.TestCase): ...@@ -199,7 +201,8 @@ class Test_DragAndDrop_Grade(unittest.TestCase):
'left_side_tagret[molecule][p_target][p][1]', 'left_side_tagret[molecule][p_target][p][1]',
'left_side_tagret[molecule][p_target][p][3]', 'left_side_tagret[molecule][p_target][p][3]',
'right_side_tagret[molecule][p_target][p][1]', 'right_side_tagret[molecule][p_target][p][1]',
'right_side_tagret[molecule][p_target][p][3]'], 'right_side_tagret[molecule][p_target][p][3]',
],
'rule': 'unordered_equal' 'rule': 'unordered_equal'
} }
] ]
...@@ -255,15 +258,24 @@ class Test_DragAndDrop_Grade(unittest.TestCase): ...@@ -255,15 +258,24 @@ class Test_DragAndDrop_Grade(unittest.TestCase):
}, },
{ {
'draggables': ['up'], 'draggables': ['up'],
'targets': ['p_l[triple_draggable][1]', 'p_l[triple_draggable][2]', 'targets': [
'p_r[triple_draggable][2]', 'p_r[triple_draggable][3]'], 'p_l[triple_draggable][1]',
'p_l[triple_draggable][2]',
'p_r[triple_draggable][2]',
'p_r[triple_draggable][3]',
],
'rule': 'unordered_equal' 'rule': 'unordered_equal'
}, },
{ {
'draggables': ['up_and_down'], 'draggables': ['up_and_down'],
'targets': ['s_l[single_draggable][1]', 's_r[single_draggable][1]', 'targets': [
's_sigma[single_draggable][1]', 's_sigma*[single_draggable][1]', 's_l[single_draggable][1]',
'p_pi[double_draggable][1]', 'p_pi[double_draggable][2]'], 's_r[single_draggable][1]',
's_sigma[single_draggable][1]',
's_sigma*[single_draggable][1]',
'p_pi[double_draggable][1]',
'p_pi[double_draggable][2]',
],
'rule': 'unordered_equal' 'rule': 'unordered_equal'
}, },
......
...@@ -263,8 +263,11 @@ class CapaMixin(CapaFields): ...@@ -263,8 +263,11 @@ class CapaMixin(CapaFields):
msg += u'<p><pre>{tb}</pre></p>'.format( msg += u'<p><pre>{tb}</pre></p>'.format(
# just the traceback, no message - it is already present above # just the traceback, no message - it is already present above
tb=cgi.escape( tb=cgi.escape(
u''.join(['Traceback (most recent call last):\n'] + u''.join(
traceback.format_tb(sys.exc_info()[2]))) ['Traceback (most recent call last):\n'] +
traceback.format_tb(sys.exc_info()[2])
)
)
) )
# create a dummy problem with error message instead of failing # create a dummy problem with error message instead of failing
problem_text = (u'<problem><text><span class="inline-error">' problem_text = (u'<problem><text><span class="inline-error">'
...@@ -987,8 +990,8 @@ class CapaMixin(CapaFields): ...@@ -987,8 +990,8 @@ class CapaMixin(CapaFields):
# Wait time between resets: check if is too soon for submission. # Wait time between resets: check if is too soon for submission.
if self.last_submission_time is not None and self.submission_wait_seconds != 0: if self.last_submission_time is not None and self.submission_wait_seconds != 0:
# pylint: disable=maybe-no-member # pylint: disable=maybe-no-member
# pylint is unable to verify that .total_seconds() exists # pylint is unable to verify that .total_seconds() exists
if (current_time - self.last_submission_time).total_seconds() < self.submission_wait_seconds: if (current_time - self.last_submission_time).total_seconds() < self.submission_wait_seconds:
remaining_secs = int(self.submission_wait_seconds - (current_time - self.last_submission_time).total_seconds()) remaining_secs = int(self.submission_wait_seconds - (current_time - self.last_submission_time).total_seconds())
msg = _(u'You must wait at least {wait_secs} between submissions. {remaining_secs} remaining.').format( msg = _(u'You must wait at least {wait_secs} between submissions. {remaining_secs} remaining.').format(
...@@ -1126,7 +1129,7 @@ class CapaMixin(CapaFields): ...@@ -1126,7 +1129,7 @@ class CapaMixin(CapaFields):
if permutation_option is not None: if permutation_option is not None:
# Add permutation record tuple: (one of:'shuffle'/'answerpool', [as-displayed list]) # Add permutation record tuple: (one of:'shuffle'/'answerpool', [as-displayed list])
if not 'permutation' in event_info: if 'permutation' not in event_info:
event_info['permutation'] = {} event_info['permutation'] = {}
event_info['permutation'][response.answer_id] = (permutation_option, response.unmask_order()) event_info['permutation'][response.answer_id] = (permutation_option, response.unmask_order())
......
...@@ -138,7 +138,7 @@ class CapaDescriptor(CapaFields, RawDescriptor): ...@@ -138,7 +138,7 @@ class CapaDescriptor(CapaFields, RawDescriptor):
Show them only if use_latex_compiler is set to True in Show them only if use_latex_compiler is set to True in
course settings. course settings.
""" """
return (not 'latex' in template['template_id'] or course.use_latex_compiler) return ('latex' not in template['template_id'] or course.use_latex_compiler)
def get_context(self): def get_context(self):
_context = RawDescriptor.get_context(self) _context = RawDescriptor.get_context(self)
......
...@@ -184,40 +184,44 @@ class CourseFields(object): ...@@ -184,40 +184,44 @@ class CourseFields(object):
help=_("Enter the date you want to advertise as the course start date, if this date is different from the set start date. To advertise the set start date, enter null."), help=_("Enter the date you want to advertise as the course start date, if this date is different from the set start date. To advertise the set start date, enter null."),
scope=Scope.settings scope=Scope.settings
) )
grading_policy = Dict(help="Grading policy definition for this class", grading_policy = Dict(
default={"GRADER": [ help="Grading policy definition for this class",
{ default={
"type": "Homework", "GRADER": [
"min_count": 12, {
"drop_count": 2, "type": "Homework",
"short_label": "HW", "min_count": 12,
"weight": 0.15 "drop_count": 2,
}, "short_label": "HW",
{ "weight": 0.15,
"type": "Lab", },
"min_count": 12, {
"drop_count": 2, "type": "Lab",
"weight": 0.15 "min_count": 12,
}, "drop_count": 2,
{ "weight": 0.15,
"type": "Midterm Exam", },
"short_label": "Midterm", {
"min_count": 1, "type": "Midterm Exam",
"drop_count": 0, "short_label": "Midterm",
"weight": 0.3 "min_count": 1,
}, "drop_count": 0,
{ "weight": 0.3,
"type": "Final Exam", },
"short_label": "Final", {
"min_count": 1, "type": "Final Exam",
"drop_count": 0, "short_label": "Final",
"weight": 0.4 "min_count": 1,
} "drop_count": 0,
], "weight": 0.4,
"GRADE_CUTOFFS": { }
"Pass": 0.5 ],
}}, "GRADE_CUTOFFS": {
scope=Scope.content) "Pass": 0.5,
},
},
scope=Scope.content
)
show_calculator = Boolean( show_calculator = Boolean(
display_name=_("Show Calculator"), display_name=_("Show Calculator"),
help=_("Enter true or false. When true, students can see the calculator in the course."), help=_("Enter true or false. When true, students can see the calculator in the course."),
......
...@@ -113,7 +113,7 @@ class HtmlDescriptor(HtmlFields, XmlDescriptor, EditingDescriptor): ...@@ -113,7 +113,7 @@ class HtmlDescriptor(HtmlFields, XmlDescriptor, EditingDescriptor):
Show them only if use_latex_compiler is set to True in Show them only if use_latex_compiler is set to True in
course settings. course settings.
""" """
return (not 'latex' in template['template_id'] or course.use_latex_compiler) return ('latex' not in template['template_id'] or course.use_latex_compiler)
def get_context(self): def get_context(self):
""" """
......
...@@ -76,13 +76,6 @@ class SplitMongoKVS(InheritanceKeyValueStore): ...@@ -76,13 +76,6 @@ class SplitMongoKVS(InheritanceKeyValueStore):
# set the field # set the field
self._fields[key.field_name] = value self._fields[key.field_name] = value
# handle any side effects -- story STUD-624
# if key.scope == Scope.children:
# STUD-624 remove inheritance from any exchildren
# STUD-624 add inheritance to any new children
# if key.scope == Scope.settings:
# STUD-624 if inheritable, push down to children
def delete(self, key): def delete(self, key):
# handle any special cases # handle any special cases
if key.scope not in [Scope.children, Scope.settings, Scope.content]: if key.scope not in [Scope.children, Scope.settings, Scope.content]:
...@@ -94,12 +87,6 @@ class SplitMongoKVS(InheritanceKeyValueStore): ...@@ -94,12 +87,6 @@ class SplitMongoKVS(InheritanceKeyValueStore):
if key.field_name in self._fields: if key.field_name in self._fields:
del self._fields[key.field_name] del self._fields[key.field_name]
# handle any side effects
# if key.scope == Scope.children:
# STUD-624 remove inheritance from any exchildren
# if key.scope == Scope.settings:
# STUD-624 if inheritable, push down _inherited_settings value to children
def has(self, key): def has(self, key):
""" """
Is the given field explicitly set in this kvs (not inherited nor default) Is the given field explicitly set in this kvs (not inherited nor default)
......
...@@ -336,7 +336,6 @@ class ModuleStoreTestCase(TestCase): ...@@ -336,7 +336,6 @@ class ModuleStoreTestCase(TestCase):
block_info_tree = default_block_info_tree block_info_tree = default_block_info_tree
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, None): with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, None):
# with self.store.bulk_operations(self.store.make_course_key(org, course, run)):
course = self.store.create_course(org, course, run, self.user.id, fields=course_fields) course = self.store.create_course(org, course, run, self.user.id, fields=course_fields)
self.course_loc = course.location # pylint: disable=attribute-defined-outside-init self.course_loc = course.location # pylint: disable=attribute-defined-outside-init
......
...@@ -277,7 +277,7 @@ MIXED_MODULESTORE_SETUPS = ( ...@@ -277,7 +277,7 @@ MIXED_MODULESTORE_SETUPS = (
) )
DIRECT_MODULESTORE_SETUPS = ( DIRECT_MODULESTORE_SETUPS = (
MongoModulestoreBuilder(), MongoModulestoreBuilder(),
# VersioningModulestoreBuilder(), # FUTUREDO: LMS-11227 # VersioningModulestoreBuilder(), # FUTUREDO: LMS-11227
) )
MODULESTORE_SETUPS = DIRECT_MODULESTORE_SETUPS + MIXED_MODULESTORE_SETUPS MODULESTORE_SETUPS = DIRECT_MODULESTORE_SETUPS + MIXED_MODULESTORE_SETUPS
......
...@@ -89,7 +89,6 @@ class TestMongoModuleStoreBase(unittest.TestCase): ...@@ -89,7 +89,6 @@ class TestMongoModuleStoreBase(unittest.TestCase):
@classmethod @classmethod
def teardownClass(cls): def teardownClass(cls):
# cls.patcher.stop()
if cls.connection: if cls.connection:
cls.connection.drop_database(DB) cls.connection.drop_database(DB)
cls.connection.close() cls.connection.close()
......
...@@ -329,16 +329,16 @@ class OpenEndedModule(openendedchild.OpenEndedChild): ...@@ -329,16 +329,16 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
self.record_latest_post_assessment(score_msg) self.record_latest_post_assessment(score_msg)
self.child_state = self.POST_ASSESSMENT self.child_state = self.POST_ASSESSMENT
else: else:
log.error(( log.error(
"Trying to update score without existing studentmodule child_history:\n" "Trying to update score without existing studentmodule child_history:\n"
" location: {location}\n" " location: {location}\n"
" score: {score}\n" " score: {score}\n"
" grader_ids: {grader_ids}\n" " grader_ids: {grader_ids}\n"
" submission_ids: {submission_ids}").format( " submission_ids: {submission_ids}".format(
location=self.location_string, location=self.location_string,
score=new_score_msg['score'], score=new_score_msg['score'],
grader_ids=new_score_msg['grader_ids'], grader_ids=new_score_msg['grader_ids'],
submission_ids=new_score_msg['submission_ids'] submission_ids=new_score_msg['submission_ids'],
) )
) )
......
...@@ -150,7 +150,7 @@ class UserPartition(namedtuple("UserPartition", "id name description groups sche ...@@ -150,7 +150,7 @@ class UserPartition(namedtuple("UserPartition", "id name description groups sche
# If no scheme was provided, set it to the default ('random') # If no scheme was provided, set it to the default ('random')
scheme_id = UserPartition.VERSION_1_SCHEME scheme_id = UserPartition.VERSION_1_SCHEME
elif value["version"] == UserPartition.VERSION: elif value["version"] == UserPartition.VERSION:
if not "scheme" in value: if "scheme" not in value:
raise TypeError("UserPartition dict {0} missing value key 'scheme'".format(value)) raise TypeError("UserPartition dict {0} missing value key 'scheme'".format(value))
scheme_id = value["scheme"] scheme_id = value["scheme"]
else: else:
......
...@@ -121,7 +121,7 @@ class PollModule(PollFields, XModule): ...@@ -121,7 +121,7 @@ class PollModule(PollFields, XModule):
# Now we use this hack. # Now we use this hack.
temp_poll_answers = self.poll_answers temp_poll_answers = self.poll_answers
# Fill self.poll_answers, prepare data for template context. # Fill self.poll_answers, prepare data for template context.
for answer in self.answers: for answer in self.answers:
# Set default count for answer = 0. # Set default count for answer = 0.
if answer['id'] not in temp_poll_answers: if answer['id'] not in temp_poll_answers:
......
...@@ -27,10 +27,13 @@ class RawDescriptor(XmlDescriptor, XMLEditingDescriptor): ...@@ -27,10 +27,13 @@ class RawDescriptor(XmlDescriptor, XMLEditingDescriptor):
# re-raise # re-raise
lines = self.data.split('\n') lines = self.data.split('\n')
line, offset = err.position line, offset = err.position
msg = (u"Unable to create xml for module {loc}. " msg = (
"Context: '{context}'".format( u"Unable to create xml for module {loc}. "
context=lines[line - 1][offset - 40:offset + 40], u"Context: '{context}'"
loc=self.location)) ).format(
context=lines[line - 1][offset - 40:offset + 40],
loc=self.location,
)
raise SerializationError(self.location, msg) raise SerializationError(self.location, msg)
......
...@@ -870,10 +870,13 @@ class CourseTabList(List): ...@@ -870,10 +870,13 @@ class CourseTabList(List):
""" """
count = sum(1 for tab in tabs if tab.get('type') == tab_type) count = sum(1 for tab in tabs if tab.get('type') == tab_type)
if count > max_num: if count > max_num:
raise InvalidTabsException( msg = (
"Tab of type '{0}' appears {1} time(s). Expected maximum of {2} time(s).".format( "Tab of type '{type}' appears {count} time(s). "
tab_type, count, max_num "Expected maximum of {max} time(s)."
)) ).format(
type=tab_type, count=count, max=max_num,
)
raise InvalidTabsException(msg)
def to_json(self, values): def to_json(self, values):
""" """
......
...@@ -13,7 +13,7 @@ import textwrap ...@@ -13,7 +13,7 @@ import textwrap
import unittest import unittest
import ddt import ddt
from mock import Mock, patch from mock import Mock, patch, DEFAULT
import webob import webob
from webob.multidict import MultiDict from webob.multidict import MultiDict
...@@ -582,19 +582,20 @@ class CapaModuleTest(unittest.TestCase): ...@@ -582,19 +582,20 @@ class CapaModuleTest(unittest.TestCase):
module = CapaFactory.create(attempts=1) module = CapaFactory.create(attempts=1)
# Simulate that the problem is queued # Simulate that the problem is queued
with patch('capa.capa_problem.LoncapaProblem.is_queued') \ multipatch = patch.multiple(
as mock_is_queued, \ 'capa.capa_problem.LoncapaProblem',
patch('capa.capa_problem.LoncapaProblem.get_recentmost_queuetime') \ is_queued=DEFAULT,
as mock_get_queuetime: get_recentmost_queuetime=DEFAULT
)
mock_is_queued.return_value = True with multipatch as values:
mock_get_queuetime.return_value = datetime.datetime.now(UTC) values['is_queued'].return_value = True
values['get_recentmost_queuetime'].return_value = datetime.datetime.now(UTC)
get_request_dict = {CapaFactory.input_key(): '3.14'} get_request_dict = {CapaFactory.input_key(): '3.14'}
result = module.check_problem(get_request_dict) result = module.check_problem(get_request_dict)
# Expect an AJAX alert message in 'success' # Expect an AJAX alert message in 'success'
self.assertTrue('You must wait' in result['success']) self.assertIn('You must wait', result['success'])
# Expect that the number of attempts is NOT incremented # Expect that the number of attempts is NOT incremented
self.assertEqual(module.attempts, 1) self.assertEqual(module.attempts, 1)
......
...@@ -28,10 +28,18 @@ class TabsEditingDescriptorTestCase(unittest.TestCase): ...@@ -28,10 +28,18 @@ class TabsEditingDescriptorTestCase(unittest.TestCase):
'template': "tabs/codemirror-edit.html", 'template': "tabs/codemirror-edit.html",
'current': True, 'current': True,
'css': { 'css': {
'scss': [resource_string(__name__, 'scss': [
'../../test_files/test_tabseditingdescriptor.scss')], resource_string(
'css': [resource_string(__name__, __name__,
'../../test_files/test_tabseditingdescriptor.css')] '../../test_files/test_tabseditingdescriptor.scss'
)
],
'css': [
resource_string(
__name__,
'../../test_files/test_tabseditingdescriptor.css'
)
]
} }
}, },
{ {
......
...@@ -580,7 +580,7 @@ class CourseTabListTestCase(TabListTestCase): ...@@ -580,7 +580,7 @@ class CourseTabListTestCase(TabListTestCase):
)): )):
self.assertEquals(tab.type, self.course.tabs[i].type) self.assertEquals(tab.type, self.course.tabs[i].type)
# enumerate the tabs and verify textbooks and the instructor tab # enumerate the tabs and verify textbooks and the instructor tab
for i, tab in enumerate(tabs.CourseTabList.iterate_displayable( for i, tab in enumerate(tabs.CourseTabList.iterate_displayable(
self.course, self.course,
self.settings, self.settings,
......
...@@ -86,10 +86,12 @@ class WordCloudModule(WordCloudFields, XModule): ...@@ -86,10 +86,12 @@ class WordCloudModule(WordCloudFields, XModule):
"""WordCloud Xmodule""" """WordCloud Xmodule"""
js = { js = {
'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee')], 'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee')],
'js': [resource_string(__name__, 'js/src/word_cloud/d3.min.js'), 'js': [
resource_string(__name__, 'js/src/word_cloud/d3.layout.cloud.js'), resource_string(__name__, 'js/src/word_cloud/d3.min.js'),
resource_string(__name__, 'js/src/word_cloud/word_cloud.js'), resource_string(__name__, 'js/src/word_cloud/d3.layout.cloud.js'),
resource_string(__name__, 'js/src/word_cloud/word_cloud_main.js')] resource_string(__name__, 'js/src/word_cloud/word_cloud.js'),
resource_string(__name__, 'js/src/word_cloud/word_cloud_main.js'),
],
} }
css = {'scss': [resource_string(__name__, 'css/word_cloud/display.scss')]} css = {'scss': [resource_string(__name__, 'css/word_cloud/display.scss')]}
js_module_name = "WordCloud" js_module_name = "WordCloud"
......
...@@ -331,7 +331,7 @@ class XBlockWrapper(PageObject): ...@@ -331,7 +331,7 @@ class XBlockWrapper(PageObject):
grandkids.extend(descendant.children) grandkids.extend(descendant.children)
grand_locators = [grandkid.locator for grandkid in grandkids] grand_locators = [grandkid.locator for grandkid in grandkids]
return [descendant for descendant in descendants if not descendant.locator in grand_locators] return [descendant for descendant in descendants if descendant.locator not in grand_locators]
@property @property
def preview_selector(self): def preview_selector(self):
......
...@@ -305,7 +305,7 @@ class CourseOutlineChild(PageObject, CourseOutlineItem): ...@@ -305,7 +305,7 @@ class CourseOutlineChild(PageObject, CourseOutlineItem):
grandkids.extend(descendant.children) grandkids.extend(descendant.children)
grand_locators = [grandkid.locator for grandkid in grandkids] grand_locators = [grandkid.locator for grandkid in grandkids]
return [descendant for descendant in descendants if not descendant.locator in grand_locators] return [descendant for descendant in descendants if descendant.locator not in grand_locators]
class CourseOutlineUnit(CourseOutlineChild): class CourseOutlineUnit(CourseOutlineChild):
......
...@@ -324,29 +324,41 @@ class UnitPublishingTest(ContainerBase): ...@@ -324,29 +324,41 @@ class UnitPublishingTest(ContainerBase):
) )
) )
), ),
XBlockFixtureDesc('chapter', 'Unlocked Section', XBlockFixtureDesc(
metadata={'start': past_start_date.isoformat()}).add_children( 'chapter',
XBlockFixtureDesc('sequential', 'Unlocked Subsection').add_children( 'Unlocked Section',
XBlockFixtureDesc('vertical', 'Unlocked Unit').add_children( metadata={'start': past_start_date.isoformat()}
XBlockFixtureDesc('problem', '<problem></problem>', data=self.html_content) ).add_children(
) XBlockFixtureDesc('sequential', 'Unlocked Subsection').add_children(
) XBlockFixtureDesc('vertical', 'Unlocked Unit').add_children(
), XBlockFixtureDesc('problem', '<problem></problem>', data=self.html_content)
)
)
),
XBlockFixtureDesc('chapter', 'Section With Locked Unit').add_children( XBlockFixtureDesc('chapter', 'Section With Locked Unit').add_children(
XBlockFixtureDesc('sequential', 'Subsection With Locked Unit', XBlockFixtureDesc(
metadata={'start': past_start_date.isoformat()}).add_children( 'sequential',
XBlockFixtureDesc('vertical', 'Locked Unit', 'Subsection With Locked Unit',
metadata={'visible_to_staff_only': True}).add_children( metadata={'start': past_start_date.isoformat()}
XBlockFixtureDesc('discussion', '', data=self.html_content) ).add_children(
) XBlockFixtureDesc(
) 'vertical',
'Locked Unit',
metadata={'visible_to_staff_only': True}
).add_children(
XBlockFixtureDesc('discussion', '', data=self.html_content)
)
)
), ),
XBlockFixtureDesc('chapter', 'Unreleased Section', XBlockFixtureDesc(
metadata={'start': future_start_date.isoformat()}).add_children( 'chapter',
XBlockFixtureDesc('sequential', 'Unreleased Subsection').add_children( 'Unreleased Section',
XBlockFixtureDesc('vertical', 'Unreleased Unit') metadata={'start': future_start_date.isoformat()}
) ).add_children(
) XBlockFixtureDesc('sequential', 'Unreleased Subsection').add_children(
XBlockFixtureDesc('vertical', 'Unreleased Unit')
)
)
) )
def test_publishing(self): def test_publishing(self):
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
Management command which sets or gets the certificate whitelist for a given Management command which sets or gets the certificate whitelist for a given
user/course user/course
""" """
from __future__ import print_function
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from optparse import make_option from optparse import make_option
from opaque_keys import InvalidKeyError from opaque_keys import InvalidKeyError
...@@ -83,7 +84,8 @@ class Command(BaseCommand): ...@@ -83,7 +84,8 @@ class Command(BaseCommand):
cert_whitelist.save() cert_whitelist.save()
whitelist = CertificateWhitelist.objects.filter(course_id=course) whitelist = CertificateWhitelist.objects.filter(course_id=course)
print "User whitelist for course {0}:\n{1}".format(course_id, wl_users = '\n'.join(
'\n'.join(["{0} {1} {2}".format( "{u.user.username} {u.user.email} {u.whitelist}".format(u=u)
u.user.username, u.user.email, u.whitelist) for u in whitelist
for u in whitelist])) )
print("User whitelist for course {0}:\n{1}".format(course_id, wl_users))
...@@ -361,7 +361,7 @@ def add_problem_to_course(course, problem_type, extra_meta=None): ...@@ -361,7 +361,7 @@ def add_problem_to_course(course, problem_type, extra_meta=None):
# Generate the problem XML using capa.tests.response_xml_factory # Generate the problem XML using capa.tests.response_xml_factory
factory_dict = PROBLEM_DICT[problem_type] factory_dict = PROBLEM_DICT[problem_type]
problem_xml = factory_dict['factory'].build_xml(**factory_dict['kwargs']) problem_xml = factory_dict['factory'].build_xml(**factory_dict['kwargs'])
metadata = {'rerandomize': 'always'} if not 'metadata' in factory_dict else factory_dict['metadata'] metadata = {'rerandomize': 'always'} if 'metadata' not in factory_dict else factory_dict['metadata']
if extra_meta: if extra_meta:
metadata = dict(metadata, **extra_meta) metadata = dict(metadata, **extra_meta)
......
...@@ -277,8 +277,9 @@ def _grade(student, request, course, keep_raw_scores): ...@@ -277,8 +277,9 @@ def _grade(student, request, course, keep_raw_scores):
grade_summary['grade'] = letter_grade grade_summary['grade'] = letter_grade
grade_summary['totaled_scores'] = totaled_scores # make this available, eg for instructor download & debugging grade_summary['totaled_scores'] = totaled_scores # make this available, eg for instructor download & debugging
if keep_raw_scores: if keep_raw_scores:
grade_summary['raw_scores'] = raw_scores # way to get all RAW scores out to instructor # way to get all RAW scores out to instructor
# so grader can be double-checked # so grader can be double-checked
grade_summary['raw_scores'] = raw_scores
return grade_summary return grade_summary
......
...@@ -349,8 +349,8 @@ class DjangoKeyValueStore(KeyValueStore): ...@@ -349,8 +349,8 @@ class DjangoKeyValueStore(KeyValueStore):
state[field.field_name] = kv_dict[field] state[field.field_name] = kv_dict[field]
field_object.state = json.dumps(state) field_object.state = json.dumps(state)
else: else:
# The remaining scopes save fields on different rows, so # The remaining scopes save fields on different rows, so
# we don't have to worry about conflicts # we don't have to worry about conflicts
field_object.value = json.dumps(kv_dict[field]) field_object.value = json.dumps(kv_dict[field])
for field_object in field_objects: for field_object in field_objects:
......
...@@ -333,18 +333,20 @@ class TestCourseGrader(TestSubmittingProblems): ...@@ -333,18 +333,20 @@ class TestCourseGrader(TestSubmittingProblems):
""" """
grading_policy = { grading_policy = {
"GRADER": [{ "GRADER": [
"type": "Homework", {
"min_count": 1, "type": "Homework",
"drop_count": 0, "min_count": 1,
"short_label": "HW", "drop_count": 0,
"weight": 0.25 "short_label": "HW",
}, { "weight": 0.25
"type": "Final", }, {
"name": "Final Section", "type": "Final",
"short_label": "Final", "name": "Final Section",
"weight": 0.75 "short_label": "Final",
}] "weight": 0.75
}
]
} }
self.add_grading_policy(grading_policy) self.add_grading_policy(grading_policy)
...@@ -361,13 +363,14 @@ class TestCourseGrader(TestSubmittingProblems): ...@@ -361,13 +363,14 @@ class TestCourseGrader(TestSubmittingProblems):
grading_policy = { grading_policy = {
"GRADER": [ "GRADER": [
{ {
"type": "Homework", "type": "Homework",
"min_count": 3, "min_count": 3,
"drop_count": 1, "drop_count": 1,
"short_label": "HW", "short_label": "HW",
"weight": 1 "weight": 1
}] }
]
} }
self.add_grading_policy(grading_policy) self.add_grading_policy(grading_policy)
......
...@@ -118,12 +118,8 @@ class TestVideo(BaseTestXmodule): ...@@ -118,12 +118,8 @@ class TestVideo(BaseTestXmodule):
for user in self.users for user in self.users
} }
self.assertEqual( status_codes = {response.status_code for response in responses.values()}
set([ self.assertEqual(status_codes.pop(), 404)
response.status_code
for _, response in responses.items()
]).pop(),
404)
def test_handle_ajax(self): def test_handle_ajax(self):
...@@ -363,7 +359,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo): ...@@ -363,7 +359,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo):
u'end': [75], u'end': [75],
u'start': [9], u'start': [9],
u'text': [ u'text': [
u'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.' u'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.'
] ]
} }
self.assertDictEqual(json.loads(response.body), calculated_0_75) self.assertDictEqual(json.loads(response.body), calculated_0_75)
...@@ -375,7 +371,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo): ...@@ -375,7 +371,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo):
u'end': [150], u'end': [150],
u'start': [18], u'start': [18],
u'text': [ u'text': [
u'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.' u'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.'
] ]
} }
self.assertDictEqual(json.loads(response.body), calculated_1_5) self.assertDictEqual(json.loads(response.body), calculated_1_5)
...@@ -396,7 +392,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo): ...@@ -396,7 +392,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo):
u'end': [100], u'end': [100],
u'start': [12], u'start': [12],
u'text': [ u'text': [
u'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.' u'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.'
] ]
} }
self.non_en_file.seek(0) self.non_en_file.seek(0)
......
...@@ -226,12 +226,8 @@ class TestWordCloud(BaseTestXmodule): ...@@ -226,12 +226,8 @@ class TestWordCloud(BaseTestXmodule):
for user in self.users for user in self.users
} }
self.assertEqual( status_codes = {response.status_code for response in responses.values()}
set([ self.assertEqual(status_codes.pop(), 200)
response.status_code
for _, response in responses.items()
]).pop(),
200)
for user in self.users: for user in self.users:
self.assertDictEqual( self.assertDictEqual(
...@@ -239,7 +235,8 @@ class TestWordCloud(BaseTestXmodule): ...@@ -239,7 +235,8 @@ class TestWordCloud(BaseTestXmodule):
{ {
'status': 'fail', 'status': 'fail',
'error': 'Unknown Command!' 'error': 'Unknown Command!'
}) }
)
def test_word_cloud_constructor(self): def test_word_cloud_constructor(self):
"""Make sure that all parameters extracted correclty from xml""" """Make sure that all parameters extracted correclty from xml"""
......
...@@ -87,7 +87,7 @@ def switch_branch(branch, rdir): ...@@ -87,7 +87,7 @@ def switch_branch(branch, rdir):
except subprocess.CalledProcessError as ex: except subprocess.CalledProcessError as ex:
log.exception('Getting a list of remote branches failed: %r', ex.output) log.exception('Getting a list of remote branches failed: %r', ex.output)
raise GitImportError(GitImportError.CANNOT_BRANCH) raise GitImportError(GitImportError.CANNOT_BRANCH)
if not branch in output: if branch not in output:
raise GitImportError(GitImportError.REMOTE_BRANCH_MISSING) raise GitImportError(GitImportError.REMOTE_BRANCH_MISSING)
# Check it the remote branch has already been made locally # Check it the remote branch has already been made locally
cmd = ['git', 'branch', '-a', ] cmd = ['git', 'branch', '-a', ]
......
...@@ -167,7 +167,7 @@ class Users(SysadminDashboardView): ...@@ -167,7 +167,7 @@ class Users(SysadminDashboardView):
msg = u'' msg = u''
if settings.FEATURES['AUTH_USE_CERTIFICATES']: if settings.FEATURES['AUTH_USE_CERTIFICATES']:
if not '@' in uname: if '@' not in uname:
email = '{0}@{1}'.format(uname, email_domain) email = '{0}@{1}'.format(uname, email_domain)
else: else:
email = uname email = uname
...@@ -190,7 +190,7 @@ class Users(SysadminDashboardView): ...@@ -190,7 +190,7 @@ class Users(SysadminDashboardView):
email = uname email = uname
if not '@' in email: if '@' not in email:
msg += _('email address required (not username)') msg += _('email address required (not username)')
return msg return msg
new_password = password new_password = password
......
...@@ -112,8 +112,8 @@ def create_thread(request, course_id, commentable_id): ...@@ -112,8 +112,8 @@ def create_thread(request, course_id, commentable_id):
thread.save() thread.save()
#patch for backward compatibility to comments service # patch for backward compatibility to comments service
if not 'pinned' in thread.attributes: if 'pinned' not in thread.attributes:
thread['pinned'] = False thread['pinned'] = False
if post.get('auto_subscribe', 'false').lower() == 'true': if post.get('auto_subscribe', 'false').lower() == 'true':
......
...@@ -119,8 +119,8 @@ def get_threads(request, course_key, discussion_id=None, per_page=THREADS_PER_PA ...@@ -119,8 +119,8 @@ def get_threads(request, course_key, discussion_id=None, per_page=THREADS_PER_PA
threads, page, num_pages, corrected_text = cc.Thread.search(query_params) threads, page, num_pages, corrected_text = cc.Thread.search(query_params)
for thread in threads: for thread in threads:
#patch for backward compatibility to comments service # patch for backward compatibility to comments service
if not 'pinned' in thread: if 'pinned' not in thread:
thread['pinned'] = False thread['pinned'] = False
query_params['page'] = page query_params['page'] = page
...@@ -286,8 +286,8 @@ def single_thread(request, course_id, discussion_id, thread_id): ...@@ -286,8 +286,8 @@ def single_thread(request, course_id, discussion_id, thread_id):
add_courseware_context(threads, course) add_courseware_context(threads, course)
for thread in threads: for thread in threads:
#patch for backward compatibility with comments service # patch for backward compatibility with comments service
if not "pinned" in thread: if "pinned" not in thread:
thread["pinned"] = False thread["pinned"] = False
threads = [utils.prepare_content(thread, course_key, is_staff) for thread in threads] threads = [utils.prepare_content(thread, course_key, is_staff) for thread in threads]
......
...@@ -90,7 +90,7 @@ def _check_conditions_permissions(user, permissions, course_id, content): ...@@ -90,7 +90,7 @@ def _check_conditions_permissions(user, permissions, course_id, content):
if operator == "or": if operator == "or":
return True in results return True in results
elif operator == "and": elif operator == "and":
return not False in results return False not in results
return test(user, permissions, operator="or") return test(user, permissions, operator="or")
......
...@@ -23,8 +23,10 @@ class MockCommentServiceRequestHandler(BaseHTTPRequestHandler): ...@@ -23,8 +23,10 @@ class MockCommentServiceRequestHandler(BaseHTTPRequestHandler):
post_dict = json.loads(data_string) post_dict = json.loads(data_string)
# Log the request # Log the request
logger.debug("Comment Service received POST request %s to path %s" % logger.debug(
(json.dumps(post_dict), self.path)) "Comment Service received POST request {0} to path {1}"
.format(json.dumps(post_dict), self.path)
)
# Every good post has at least an API key # Every good post has at least an API key
if 'X-Edx-Api-Key' in self.headers: if 'X-Edx-Api-Key' in self.headers:
...@@ -58,8 +60,10 @@ class MockCommentServiceRequestHandler(BaseHTTPRequestHandler): ...@@ -58,8 +60,10 @@ class MockCommentServiceRequestHandler(BaseHTTPRequestHandler):
post_dict = json.loads(data_string) post_dict = json.loads(data_string)
# Log the request # Log the request
logger.debug("Comment Service received PUT request %s to path %s" % logger.debug(
(json.dumps(post_dict), self.path)) "Comment Service received PUT request {0} to path {1}"
.format(json.dumps(post_dict), self.path)
)
# Every good post has at least an API key # Every good post has at least an API key
if 'X-Edx-Api-Key' in self.headers: if 'X-Edx-Api-Key' in self.headers:
......
...@@ -649,7 +649,7 @@ def modify_access(request, course_id): ...@@ -649,7 +649,7 @@ def modify_access(request, course_id):
rolename = request.GET.get('rolename') rolename = request.GET.get('rolename')
action = request.GET.get('action') action = request.GET.get('action')
if not rolename in ['instructor', 'staff', 'beta']: if rolename not in ['instructor', 'staff', 'beta']:
return HttpResponseBadRequest(strip_tags( return HttpResponseBadRequest(strip_tags(
"unknown rolename '{}'".format(rolename) "unknown rolename '{}'".format(rolename)
)) ))
...@@ -712,7 +712,7 @@ def list_course_role_members(request, course_id): ...@@ -712,7 +712,7 @@ def list_course_role_members(request, course_id):
rolename = request.GET.get('rolename') rolename = request.GET.get('rolename')
if not rolename in ['instructor', 'staff', 'beta']: if rolename not in ['instructor', 'staff', 'beta']:
return HttpResponseBadRequest() return HttpResponseBadRequest()
def extract_user_info(user): def extract_user_info(user):
...@@ -1336,7 +1336,7 @@ def get_distribution(request, course_id): ...@@ -1336,7 +1336,7 @@ def get_distribution(request, course_id):
available_features = instructor_analytics.distributions.AVAILABLE_PROFILE_FEATURES available_features = instructor_analytics.distributions.AVAILABLE_PROFILE_FEATURES
# allow None so that requests for no feature can list available features # allow None so that requests for no feature can list available features
if not feature in available_features + (None,): if feature not in available_features + (None,):
return HttpResponseBadRequest(strip_tags( return HttpResponseBadRequest(strip_tags(
"feature '{}' not available.".format(feature) "feature '{}' not available.".format(feature)
)) ))
...@@ -1349,7 +1349,7 @@ def get_distribution(request, course_id): ...@@ -1349,7 +1349,7 @@ def get_distribution(request, course_id):
} }
p_dist = None p_dist = None
if not feature is None: if feature is not None:
p_dist = instructor_analytics.distributions.profile_distribution(course_id, feature) p_dist = instructor_analytics.distributions.profile_distribution(course_id, feature)
response_payload['feature_results'] = { response_payload['feature_results'] = {
'feature': p_dist.feature, 'feature': p_dist.feature,
...@@ -1683,7 +1683,7 @@ def list_forum_members(request, course_id): ...@@ -1683,7 +1683,7 @@ def list_forum_members(request, course_id):
return HttpResponseBadRequest("Operation requires instructor access.") return HttpResponseBadRequest("Operation requires instructor access.")
# filter out unsupported for roles # filter out unsupported for roles
if not rolename in [FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA]: if rolename not in [FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA]:
return HttpResponseBadRequest(strip_tags( return HttpResponseBadRequest(strip_tags(
"Unrecognized rolename '{}'.".format(rolename) "Unrecognized rolename '{}'.".format(rolename)
)) ))
...@@ -1807,7 +1807,7 @@ def update_forum_role_membership(request, course_id): ...@@ -1807,7 +1807,7 @@ def update_forum_role_membership(request, course_id):
if rolename == FORUM_ROLE_ADMINISTRATOR and not has_instructor_access: if rolename == FORUM_ROLE_ADMINISTRATOR and not has_instructor_access:
return HttpResponseBadRequest("Operation requires instructor access.") return HttpResponseBadRequest("Operation requires instructor access.")
if not rolename in [FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA]: if rolename not in [FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA]:
return HttpResponseBadRequest(strip_tags( return HttpResponseBadRequest(strip_tags(
"Unrecognized rolename '{}'.".format(rolename) "Unrecognized rolename '{}'.".format(rolename)
)) ))
......
...@@ -87,7 +87,7 @@ def instructor_dashboard_2(request, course_id): ...@@ -87,7 +87,7 @@ def instructor_dashboard_2(request, course_id):
if settings.FEATURES['CLASS_DASHBOARD'] and access['staff']: if settings.FEATURES['CLASS_DASHBOARD'] and access['staff']:
sections.append(_section_metrics(course, access)) sections.append(_section_metrics(course, access))
# Gate access to Ecommerce tab # Gate access to Ecommerce tab
if course_mode_has_price: if course_mode_has_price:
sections.append(_section_e_commerce(course, access)) sections.append(_section_e_commerce(course, access))
......
...@@ -339,7 +339,7 @@ def instructor_dashboard(request, course_id): ...@@ -339,7 +339,7 @@ def instructor_dashboard(request, course_id):
msg2, datatable = _do_remote_gradebook(request.user, course, 'get-membership', dict(section=section)) msg2, datatable = _do_remote_gradebook(request.user, course, 'get-membership', dict(section=section))
msg += msg2 msg += msg2
if not 'List' in action: if 'List' not in action:
students = ','.join([x['email'] for x in datatable['retdata']]) students = ','.join([x['email'] for x in datatable['retdata']])
overload = 'Overload' in action overload = 'Overload' in action
secure = request.is_secure() secure = request.is_secure()
......
...@@ -92,7 +92,7 @@ def profile_distribution(course_id, feature): ...@@ -92,7 +92,7 @@ def profile_distribution(course_id, feature):
data types are EASY_CHOICE or OPEN_CHOICE data types are EASY_CHOICE or OPEN_CHOICE
""" """
if not feature in AVAILABLE_PROFILE_FEATURES: if feature not in AVAILABLE_PROFILE_FEATURES:
raise ValueError( raise ValueError(
"unsupported feature requested for distribution '{}'".format( "unsupported feature requested for distribution '{}'".format(
feature) feature)
......
...@@ -148,7 +148,7 @@ class Command(BaseCommand): ...@@ -148,7 +148,7 @@ class Command(BaseCommand):
gname = raw_input("Add group (tab to autocomplete, empty line to end): ") gname = raw_input("Add group (tab to autocomplete, empty line to end): ")
if not gname: if not gname:
break break
if not gname in groups: if gname not in groups:
print "Unknown group %s" % gname print "Unknown group %s" % gname
continue continue
g = Group.objects.get(name=gname) g = Group.objects.get(name=gname)
......
...@@ -332,8 +332,8 @@ def take_action_on_flags(request, course_id): ...@@ -332,8 +332,8 @@ def take_action_on_flags(request, course_id):
except GradingServiceError: except GradingServiceError:
log.exception( log.exception(
u"Error taking action on flagged peer grading submissions, " u"Error taking action on flagged peer grading submissions, "
u"submission_id: {0}, action_type: {1}, grader_id: {2}".format( u"submission_id: {0}, action_type: {1}, grader_id: {2}"
submission_id, action_type, student_id) .format(submission_id, action_type, student_id)
) )
response = { response = {
'success': False, 'success': False,
......
...@@ -930,9 +930,10 @@ class PaidCourseRegistration(OrderItem): ...@@ -930,9 +930,10 @@ class PaidCourseRegistration(OrderItem):
Returns the order item Returns the order item
""" """
# First a bunch of sanity checks # First a bunch of sanity checks:
course = modulestore().get_course(course_id) # actually fetch the course to make sure it exists, use this to # actually fetch the course to make sure it exists, use this to
# throw errors if it doesn't # throw errors if it doesn't.
course = modulestore().get_course(course_id)
if not course: if not course:
log.error("User {} tried to add non-existent course {} to cart id {}" log.error("User {} tried to add non-existent course {} to cart id {}"
.format(order.user.email, course_id, order.id)) .format(order.user.email, course_id, order.id))
...@@ -1075,9 +1076,10 @@ class CourseRegCodeItem(OrderItem): ...@@ -1075,9 +1076,10 @@ class CourseRegCodeItem(OrderItem):
Returns the order item Returns the order item
""" """
# First a bunch of sanity checks # First a bunch of sanity checks:
course = modulestore().get_course(course_id) # actually fetch the course to make sure it exists, use this to # actually fetch the course to make sure it exists, use this to
# throw errors if it doesn't # throw errors if it doesn't.
course = modulestore().get_course(course_id)
if not course: if not course:
log.error("User {} tried to add non-existent course {} to cart id {}" log.error("User {} tried to add non-existent course {} to cart id {}"
.format(order.user.email, course_id, order.id)) .format(order.user.email, course_id, order.id))
......
...@@ -78,7 +78,7 @@ class PaymentFakeView(View): ...@@ -78,7 +78,7 @@ class PaymentFakeView(View):
""" """
new_status = request.body new_status = request.body
if not new_status in ["success", "failure"]: if new_status not in ["success", "failure"]:
return HttpResponseBadRequest() return HttpResponseBadRequest()
else: else:
......
...@@ -35,8 +35,8 @@ STATICFILES_DIRS = [ ...@@ -35,8 +35,8 @@ STATICFILES_DIRS = [
("handouts", DATA_DIR / "handouts"), ("handouts", DATA_DIR / "handouts"),
("subs", DATA_DIR / "subs"), ("subs", DATA_DIR / "subs"),
# This is how you would use the textbook images locally # This is how you would use the textbook images locally
# ("book", ENV_ROOT / "book_images"), # ("book", ENV_ROOT / "book_images"),
] ]
MAKO_TEMPLATES['course'] = [DATA_DIR, EDX4EDX_ROOT] MAKO_TEMPLATES['course'] = [DATA_DIR, EDX4EDX_ROOT]
...@@ -9,7 +9,7 @@ Settings for load testing. ...@@ -9,7 +9,7 @@ Settings for load testing.
from .aws import * from .aws import *
# Disable CSRF for load testing # Disable CSRF for load testing
EXCLUDE_CSRF = lambda elem: not elem in [ EXCLUDE_CSRF = lambda elem: elem not in [
'django.core.context_processors.csrf', 'django.core.context_processors.csrf',
'django.middleware.csrf.CsrfViewMiddleware' 'django.middleware.csrf.CsrfViewMiddleware'
] ]
......
...@@ -199,8 +199,9 @@ filterwarnings('ignore', message='No request passed to the backend, unable to ra ...@@ -199,8 +199,9 @@ filterwarnings('ignore', message='No request passed to the backend, unable to ra
# Ignore deprecation warnings (so we don't clutter Jenkins builds/production) # Ignore deprecation warnings (so we don't clutter Jenkins builds/production)
# https://docs.python.org/2/library/warnings.html#the-warnings-filter # https://docs.python.org/2/library/warnings.html#the-warnings-filter
simplefilter('ignore') # Change to "default" to see the first instance of each hit simplefilter('ignore')
# or "error" to convert all into errors # Change to "default" to see the first instance of each hit
# or "error" to convert all into errors
######### Third-party auth ########## ######### Third-party auth ##########
FEATURES['ENABLE_THIRD_PARTY_AUTH'] = True FEATURES['ENABLE_THIRD_PARTY_AUTH'] = True
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment