Fix tests post-merge
This commit is contained in:
@@ -190,7 +190,7 @@ class CombinedOpenEndedDescriptor(XmlDescriptor, EditingDescriptor):
|
||||
}
|
||||
"""
|
||||
|
||||
return {'xml_string' : etree.tostring(xml_object), 'metadata' : xml_object.attrib}
|
||||
return {'xml_string' : etree.tostring(xml_object), 'metadata' : xml_object.attrib}, []
|
||||
|
||||
|
||||
def definition_to_xml(self, resource_fs):
|
||||
|
||||
@@ -696,7 +696,7 @@ class CombinedOpenEndedV1Descriptor(XmlDescriptor, EditingDescriptor):
|
||||
"""Assumes that xml_object has child k"""
|
||||
return xml_object.xpath(k)[0]
|
||||
|
||||
return {'task_xml': parse_task('task'), 'prompt': parse('prompt'), 'rubric': parse('rubric')}
|
||||
return {'task_xml': parse_task('task'), 'prompt': parse('prompt'), 'rubric': parse('rubric')}, []
|
||||
|
||||
|
||||
def definition_to_xml(self, resource_fs):
|
||||
|
||||
@@ -4,6 +4,7 @@ import logging
|
||||
from xmodule.x_module import XModule
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.seq_module import SequenceDescriptor
|
||||
from xblock.core import String, Scope
|
||||
|
||||
from pkg_resources import resource_string
|
||||
|
||||
@@ -34,6 +35,7 @@ class ConditionalModule(XModule):
|
||||
js_module_name = "Conditional"
|
||||
css = {'scss': [resource_string(__name__, 'css/capa/display.scss')]}
|
||||
|
||||
condition = String(help="Condition for this module", default='', scope=Scope.settings)
|
||||
|
||||
def __init__(self, system, location, definition, descriptor, instance_state=None, shared_state=None, **kwargs):
|
||||
"""
|
||||
@@ -44,7 +46,6 @@ class ConditionalModule(XModule):
|
||||
"""
|
||||
XModule.__init__(self, system, location, definition, descriptor, instance_state, shared_state, **kwargs)
|
||||
self.contents = None
|
||||
self.condition = self.metadata.get('condition', '')
|
||||
self._get_required_modules()
|
||||
children = self.get_display_items()
|
||||
if children:
|
||||
@@ -128,16 +129,18 @@ class ConditionalDescriptor(SequenceDescriptor):
|
||||
stores_state = True
|
||||
has_score = False
|
||||
|
||||
required = String(help="List of required xmodule locations, separated by &", default='', scope=Scope.settings)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ConditionalDescriptor, self).__init__(*args, **kwargs)
|
||||
|
||||
required_module_list = [tuple(x.split('/', 1)) for x in self.metadata.get('required', '').split('&')]
|
||||
required_module_list = [tuple(x.split('/', 1)) for x in self.required.split('&')]
|
||||
self.required_module_locations = []
|
||||
for rm in required_module_list:
|
||||
try:
|
||||
(tag, name) = rm
|
||||
except Exception as err:
|
||||
msg = "Specification of required module in conditional is broken: %s" % self.metadata.get('required')
|
||||
msg = "Specification of required module in conditional is broken: %s" % self.required
|
||||
log.warning(msg)
|
||||
self.system.error_tracker(msg)
|
||||
continue
|
||||
|
||||
@@ -169,6 +169,11 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
computed_default=lambda c: {'General': {'id': c.location.html_id()}},
|
||||
)
|
||||
testcenter_info = Object(help="Dictionary of Test Center info", scope=Scope.settings)
|
||||
announcement = Date(help="Date this course is announced", scope=Scope.settings)
|
||||
cohort_config = Object(help="Dictionary defining cohort configuration", scope=Scope.settings)
|
||||
is_new = Boolean(help="Whether this course should be flagged as new", scope=Scope.settings)
|
||||
no_grade = Boolean(help="True if this course isn't graded", default=False, scope=Scope.settings)
|
||||
disable_progress_graph = Boolean(help="True if this course shouldn't display the progress graph", default=False, scope=Scope.settings)
|
||||
has_children = True
|
||||
|
||||
info_sidebar_name = String(scope=Scope.settings, default='Course Handouts')
|
||||
@@ -409,27 +414,12 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
def lowest_passing_grade(self):
|
||||
return min(self._grading_policy['GRADE_CUTOFFS'].values())
|
||||
|
||||
@property
|
||||
def tabs(self):
|
||||
"""
|
||||
Return the tabs config, as a python object, or None if not specified.
|
||||
"""
|
||||
return self.metadata.get('tabs')
|
||||
|
||||
@tabs.setter
|
||||
def tabs(self, value):
|
||||
self.metadata['tabs'] = value
|
||||
|
||||
@property
|
||||
def show_calculator(self):
|
||||
return self.metadata.get("show_calculator", None) == "Yes"
|
||||
|
||||
@property
|
||||
def is_cohorted(self):
|
||||
"""
|
||||
Return whether the course is cohorted.
|
||||
"""
|
||||
config = self.metadata.get("cohort_config")
|
||||
config = self.cohort_config
|
||||
if config is None:
|
||||
return False
|
||||
|
||||
@@ -440,7 +430,7 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
"""
|
||||
Return list of topic ids defined in course policy.
|
||||
"""
|
||||
topics = self.metadata.get("discussion_topics", {})
|
||||
topics = self.discussion_topics
|
||||
return [d["id"] for d in topics.values()]
|
||||
|
||||
|
||||
@@ -451,7 +441,7 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
the empty set. Note that all inline discussions are automatically
|
||||
cohorted based on the course's is_cohorted setting.
|
||||
"""
|
||||
config = self.metadata.get("cohort_config")
|
||||
config = self.cohort_config
|
||||
if config is None:
|
||||
return set()
|
||||
|
||||
@@ -460,13 +450,13 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
|
||||
|
||||
@property
|
||||
def is_new(self):
|
||||
def is_newish(self):
|
||||
"""
|
||||
Returns if the course has been flagged as new in the metadata. If
|
||||
Returns if the course has been flagged as new. If
|
||||
there is no flag, return a heuristic value considering the
|
||||
announcement and the start dates.
|
||||
"""
|
||||
flag = self.metadata.get('is_new', None)
|
||||
flag = self.is_new
|
||||
if flag is None:
|
||||
# Use a heuristic if the course has not been flagged
|
||||
announcement, start, now = self._sorting_dates()
|
||||
@@ -512,12 +502,10 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
def to_datetime(timestamp):
|
||||
return datetime(*timestamp[:6])
|
||||
|
||||
def get_date(field):
|
||||
timetuple = self._try_parse_time(field)
|
||||
return to_datetime(timetuple) if timetuple else None
|
||||
|
||||
announcement = get_date('announcement')
|
||||
start = get_date('advertised_start') or to_datetime(self.start)
|
||||
announcement = self.announcement
|
||||
if announcement is not None:
|
||||
announcement = to_datetime(announcement)
|
||||
start = self.advertised_start or to_datetime(self.start)
|
||||
now = to_datetime(time.gmtime())
|
||||
|
||||
return announcement, start, now
|
||||
@@ -719,7 +707,7 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
def get_test_center_exam(self, exam_series_code):
|
||||
exams = [exam for exam in self.test_center_exams if exam.exam_series_code == exam_series_code]
|
||||
return exams[0] if len(exams) == 1 else None
|
||||
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
return self.display_name
|
||||
|
||||
@@ -177,7 +177,7 @@ class GraphicalSliderToolDescriptor(MakoModuleDescriptor, XmlDescriptor):
|
||||
return {
|
||||
'render': parse('render'),
|
||||
'configuration': parse('configuration')
|
||||
}
|
||||
}, []
|
||||
|
||||
def definition_to_xml(self, resource_fs):
|
||||
'''Return an xml element representing this definition.'''
|
||||
|
||||
@@ -456,6 +456,9 @@ class XMLModuleStore(ModuleStoreBase):
|
||||
def _load_extra_content(self, system, course_descriptor, category, path, course_dir):
|
||||
|
||||
for filepath in glob.glob(path / '*'):
|
||||
if not os.path.isfile(filepath):
|
||||
continue
|
||||
|
||||
with open(filepath) as f:
|
||||
try:
|
||||
html = f.read().decode('utf-8')
|
||||
|
||||
@@ -199,16 +199,13 @@ def import_from_xml(store, data_dir, course_dirs=None,
|
||||
course_items = []
|
||||
for course_id in module_store.modules.keys():
|
||||
|
||||
course_data_path = None
|
||||
course_location = None
|
||||
|
||||
# Import course modules first, because importing some of the children requires the course to exist
|
||||
for module in module_store.modules[course_id].itervalues():
|
||||
if module.category == 'course':
|
||||
import_course_from_xml(
|
||||
store,
|
||||
static_content_store,
|
||||
course_data_path,
|
||||
data_dir / module.data_dir,
|
||||
module,
|
||||
target_location_namespace,
|
||||
verbose=verbose
|
||||
@@ -220,7 +217,7 @@ def import_from_xml(store, data_dir, course_dirs=None,
|
||||
import_module_from_xml(
|
||||
store,
|
||||
static_content_store,
|
||||
course_data_path,
|
||||
data_dir / module.data_dir,
|
||||
module,
|
||||
target_location_namespace,
|
||||
verbose=verbose
|
||||
|
||||
@@ -20,7 +20,6 @@ import capa.xqueue_interface as xqueue_interface
|
||||
|
||||
from pkg_resources import resource_string
|
||||
|
||||
from .capa_module import only_one, ComplexEncoder
|
||||
from .editing_module import EditingDescriptor
|
||||
from .html_checker import check_html
|
||||
from progress import Progress
|
||||
@@ -656,7 +655,7 @@ class OpenEndedDescriptor(XmlDescriptor, EditingDescriptor):
|
||||
"""Assumes that xml_object has child k"""
|
||||
return xml_object.xpath(k)[0]
|
||||
|
||||
return {'oeparam': parse('openendedparam'), }
|
||||
return {'oeparam': parse('openendedparam')}, []
|
||||
|
||||
|
||||
def definition_to_xml(self, resource_fs):
|
||||
|
||||
@@ -32,6 +32,7 @@ from .stringify import stringify_children
|
||||
from .x_module import XModule
|
||||
from .xml_module import XmlDescriptor
|
||||
from xmodule.modulestore import Location
|
||||
from xblock.core import Scope, Object, Integer, Boolean, String
|
||||
|
||||
from peer_grading_service import peer_grading_service, GradingServiceError
|
||||
|
||||
@@ -56,32 +57,26 @@ class PeerGradingModule(XModule):
|
||||
|
||||
css = {'scss': [resource_string(__name__, 'css/combinedopenended/display.scss')]}
|
||||
|
||||
def __init__(self, system, location, definition, descriptor,
|
||||
instance_state=None, shared_state=None, **kwargs):
|
||||
XModule.__init__(self, system, location, definition, descriptor,
|
||||
instance_state, shared_state, **kwargs)
|
||||
student_data_for_location = Object(scope=Scope.student_state)
|
||||
max_grade = Integer(default=MAX_SCORE, scope=Scope.student_state)
|
||||
use_for_single_location = Boolean(default=USE_FOR_SINGLE_LOCATION, scope=Scope.settings)
|
||||
is_graded = Boolean(default=IS_GRADED, scope=Scope.settings)
|
||||
link_to_location = String(default=LINK_TO_LOCATION, scope=Scope.settings)
|
||||
|
||||
# Load instance state
|
||||
if instance_state is not None:
|
||||
instance_state = json.loads(instance_state)
|
||||
else:
|
||||
instance_state = {}
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PeerGradingModule, self).__init__(*args, **kwargs)
|
||||
|
||||
#We need to set the location here so the child modules can use it
|
||||
system.set('location', location)
|
||||
self.system = system
|
||||
self.system.set('location', self.location)
|
||||
self.peer_gs = peer_grading_service(self.system)
|
||||
|
||||
self.use_for_single_location = self.metadata.get('use_for_single_location', USE_FOR_SINGLE_LOCATION)
|
||||
if isinstance(self.use_for_single_location, basestring):
|
||||
self.use_for_single_location = (self.use_for_single_location in TRUE_DICT)
|
||||
|
||||
self.is_graded = self.metadata.get('is_graded', IS_GRADED)
|
||||
if isinstance(self.is_graded, basestring):
|
||||
self.is_graded = (self.is_graded in TRUE_DICT)
|
||||
|
||||
self.link_to_location = self.metadata.get('link_to_location', USE_FOR_SINGLE_LOCATION)
|
||||
if self.use_for_single_location == True:
|
||||
if self.use_for_single_location:
|
||||
#This will raise an exception if the location is invalid
|
||||
link_to_location_object = Location(self.link_to_location)
|
||||
|
||||
@@ -89,8 +84,6 @@ class PeerGradingModule(XModule):
|
||||
if not self.ajax_url.endswith("/"):
|
||||
self.ajax_url = self.ajax_url + "/"
|
||||
|
||||
self.student_data_for_location = instance_state.get('student_data_for_location', {})
|
||||
self.max_grade = instance_state.get('max_grade', MAX_SCORE)
|
||||
if not isinstance(self.max_grade, (int, long)):
|
||||
#This could result in an exception, but not wrapping in a try catch block so it moves up the stack
|
||||
self.max_grade = int(self.max_grade)
|
||||
@@ -521,7 +514,7 @@ class PeerGradingDescriptor(XmlDescriptor, EditingDescriptor):
|
||||
"""Assumes that xml_object has child k"""
|
||||
return xml_object.xpath(k)[0]
|
||||
|
||||
return {}
|
||||
return {}, []
|
||||
|
||||
|
||||
def definition_to_xml(self, resource_fs):
|
||||
|
||||
@@ -58,10 +58,10 @@ class SelfAssessmentModule(openendedchild.OpenEndedChild):
|
||||
|
||||
# Used for progress / grading. Currently get credit just for
|
||||
# completion (doesn't matter if you self-assessed correct/incorrect).
|
||||
max_score = Integer(scope=Scope.settings, default=MAX_SCORE)
|
||||
max_score = Integer(scope=Scope.settings, default=openendedchild.MAX_SCORE)
|
||||
max_attempts = Integer(scope=Scope.settings, default=openendedchild.MAX_ATTEMPTS)
|
||||
|
||||
attempts = Integer(scope=Scope.student_state, default=0)
|
||||
max_attempts = Integer(scope=Scope.settings, default=MAX_ATTEMPTS)
|
||||
rubric = String(scope=Scope.content)
|
||||
prompt = String(scope=Scope.content)
|
||||
submitmessage = String(scope=Scope.content)
|
||||
@@ -318,9 +318,9 @@ class SelfAssessmentDescriptor(XmlDescriptor, EditingDescriptor):
|
||||
|
||||
# Used for progress / grading. Currently get credit just for
|
||||
# completion (doesn't matter if you self-assessed correct/incorrect).
|
||||
max_score = Integer(scope=Scope.settings, default=MAX_SCORE)
|
||||
max_score = Integer(scope=Scope.settings, default=openendedchild.MAX_SCORE)
|
||||
|
||||
max_attempts = Integer(scope=Scope.settings, default=MAX_ATTEMPTS)
|
||||
max_attempts = Integer(scope=Scope.settings, default=openendedchild.MAX_ATTEMPTS)
|
||||
rubric = String(scope=Scope.content)
|
||||
prompt = String(scope=Scope.content)
|
||||
submitmessage = String(scope=Scope.content)
|
||||
|
||||
@@ -94,26 +94,26 @@ class IsNewCourseTestCase(unittest.TestCase):
|
||||
|
||||
|
||||
@patch('xmodule.course_module.time.gmtime')
|
||||
def test_is_new(self, gmtime_mock):
|
||||
def test_is_newish(self, gmtime_mock):
|
||||
gmtime_mock.return_value = NOW
|
||||
|
||||
descriptor = self.get_dummy_course(start='2012-12-02T12:00', is_new=True)
|
||||
assert(descriptor.is_new is True)
|
||||
assert(descriptor.is_newish is True)
|
||||
|
||||
descriptor = self.get_dummy_course(start='2013-02-02T12:00', is_new=False)
|
||||
assert(descriptor.is_new is False)
|
||||
|
||||
descriptor = self.get_dummy_course(start='2013-02-02T12:00', is_new=True)
|
||||
assert(descriptor.is_new is True)
|
||||
assert(descriptor.is_newish is True)
|
||||
|
||||
descriptor = self.get_dummy_course(start='2013-01-15T12:00')
|
||||
assert(descriptor.is_new is True)
|
||||
assert(descriptor.is_newish is True)
|
||||
|
||||
descriptor = self.get_dummy_course(start='2013-03-00T12:00')
|
||||
assert(descriptor.is_new is True)
|
||||
assert(descriptor.is_newish is True)
|
||||
|
||||
descriptor = self.get_dummy_course(start='2012-10-15T12:00')
|
||||
assert(descriptor.is_new is False)
|
||||
assert(descriptor.is_newish is False)
|
||||
|
||||
descriptor = self.get_dummy_course(start='2012-12-31T12:00')
|
||||
assert(descriptor.is_new is True)
|
||||
assert(descriptor.is_newish is True)
|
||||
|
||||
Reference in New Issue
Block a user