Commit bd822b9d by Calen Pennington

Fix tests post-merge

parent 793bbfd3
......@@ -44,9 +44,8 @@ from collections import namedtuple
from courseware.courses import get_courses, sort_by_announcement
from courseware.access import has_access
from courseware.models import StudentModuleCache
from courseware.views import get_module_for_descriptor, jump_to
from courseware.module_render import get_instance_module
from courseware.model_data import ModelDataCache
from statsd import statsd
......@@ -1071,14 +1070,14 @@ def accept_name_change(request):
@csrf_exempt
def test_center_login(request):
# errors are returned by navigating to the error_url, adding a query parameter named "code"
# errors are returned by navigating to the error_url, adding a query parameter named "code"
# which contains the error code describing the exceptional condition.
def makeErrorURL(error_url, error_code):
log.error("generating error URL with error code {}".format(error_code))
return "{}?code={}".format(error_url, error_code);
# get provided error URL, which will be used as a known prefix for returning error messages to the
# Pearson shell.
# Pearson shell.
error_url = request.POST.get("errorURL")
# TODO: check that the parameters have not been tampered with, by comparing the code provided by Pearson
......@@ -1089,12 +1088,12 @@ def test_center_login(request):
# calculate SHA for query string
# TODO: figure out how to get the original query string, so we can hash it and compare.
if 'clientCandidateID' not in request.POST:
return HttpResponseRedirect(makeErrorURL(error_url, "missingClientCandidateID"));
client_candidate_id = request.POST.get("clientCandidateID")
# TODO: check remaining parameters, and maybe at least log if they're not matching
# expected values....
# registration_id = request.POST.get("registrationID")
......@@ -1108,12 +1107,12 @@ def test_center_login(request):
return HttpResponseRedirect(makeErrorURL(error_url, "invalidClientCandidateID"));
# find testcenter_registration that matches the provided exam code:
# Note that we could rely in future on either the registrationId or the exam code,
# or possibly both. But for now we know what to do with an ExamSeriesCode,
# Note that we could rely in future on either the registrationId or the exam code,
# or possibly both. But for now we know what to do with an ExamSeriesCode,
# while we currently have no record of RegistrationID values at all.
if 'vueExamSeriesCode' not in request.POST:
# we are not allowed to make up a new error code, according to Pearson,
# so instead of "missingExamSeriesCode", we use a valid one that is
# we are not allowed to make up a new error code, according to Pearson,
# so instead of "missingExamSeriesCode", we use a valid one that is
# inaccurate but at least distinct. (Sigh.)
log.error("missing exam series code for cand ID {}".format(client_candidate_id))
return HttpResponseRedirect(makeErrorURL(error_url, "missingPartnerID"));
......@@ -1127,11 +1126,11 @@ def test_center_login(request):
if not registrations:
log.error("not able to find exam registration for exam {} and cand ID {}".format(exam_series_code, client_candidate_id))
return HttpResponseRedirect(makeErrorURL(error_url, "noTestsAssigned"));
# TODO: figure out what to do if there are more than one registrations....
# for now, just take the first...
registration = registrations[0]
course_id = registration.course_id
course = course_from_id(course_id) # assume it will be found....
if not course:
......@@ -1149,19 +1148,19 @@ def test_center_login(request):
if not timelimit_descriptor:
log.error("cand {} on exam {} for course {}: descriptor not found for location {}".format(client_candidate_id, exam_series_code, course_id, location))
return HttpResponseRedirect(makeErrorURL(error_url, "missingClientProgram"));
timelimit_module_cache = StudentModuleCache.cache_for_descriptor_descendents(course_id, testcenteruser.user,
timelimit_descriptor, depth=None)
timelimit_module = get_module_for_descriptor(request.user, request, timelimit_descriptor,
timelimit_module_cache = ModelDataCache.cache_for_descriptor_descendents(course_id, testcenteruser.user,
timelimit_descriptor, depth=None)
timelimit_module = get_module_for_descriptor(request.user, request, timelimit_descriptor,
timelimit_module_cache, course_id, position=None)
if not timelimit_module.category == 'timelimit':
log.error("cand {} on exam {} for course {}: non-timelimit module at location {}".format(client_candidate_id, exam_series_code, course_id, location))
return HttpResponseRedirect(makeErrorURL(error_url, "missingClientProgram"));
if timelimit_module and timelimit_module.has_ended:
log.warning("cand {} on exam {} for course {}: test already over at {}".format(client_candidate_id, exam_series_code, course_id, timelimit_module.ending_at))
return HttpResponseRedirect(makeErrorURL(error_url, "allTestsTaken"));
# check if we need to provide an accommodation:
time_accommodation_mapping = {'ET12ET' : 'ADDHALFTIME',
'ET30MN' : 'ADD30MIN',
......@@ -1174,27 +1173,24 @@ def test_center_login(request):
# special, hard-coded client ID used by Pearson shell for testing:
if client_candidate_id == "edX003671291147":
time_accommodation_code = 'TESTING'
if time_accommodation_code:
timelimit_module.accommodation_code = time_accommodation_code
instance_module = get_instance_module(course_id, testcenteruser.user, timelimit_module, timelimit_module_cache)
instance_module.state = timelimit_module.get_instance_state()
instance_module.save()
log.info("cand {} on exam {} for course {}: receiving accommodation {}".format(client_candidate_id, exam_series_code, course_id, time_accommodation_code))
# UGLY HACK!!!
# Login assumes that authentication has occurred, and that there is a
# Login assumes that authentication has occurred, and that there is a
# backend annotation on the user object, indicating which backend
# against which the user was authenticated. We're authenticating here
# against the registration entry, and assuming that the request given
# this information is correct, we allow the user to be logged in
# without a password. This could all be formalized in a backend object
# that does the above checking.
# that does the above checking.
# TODO: (brian) create a backend class to do this.
# testcenteruser.user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
testcenteruser.user.backend = "%s.%s" % ("TestcenterAuthenticationModule", "TestcenterAuthenticationClass")
# testcenteruser.user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
testcenteruser.user.backend = "%s.%s" % ("TestcenterAuthenticationModule", "TestcenterAuthenticationClass")
login(request, testcenteruser.user)
# And start the test:
return jump_to(request, course_id, location)
......
......@@ -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')
......@@ -410,26 +415,11 @@ class CourseDescriptor(SequenceDescriptor):
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)
......@@ -442,7 +442,7 @@ def _adjust_start_date_for_beta_testers(user, descriptor):
NOTE: If testing manually, make sure MITX_FEATURES['DISABLE_START_DATES'] = False
in envs/dev.py!
"""
if descriptor.days_early_for_beta is None:
if descriptor.lms.days_early_for_beta is None:
# bail early if no beta testing is set up
return descriptor.lms.start
......@@ -456,12 +456,12 @@ def _adjust_start_date_for_beta_testers(user, descriptor):
# (fun fact: datetime(*a_time_struct[:6]) is the beautiful syntax for
# converting time_structs into datetimes)
start_as_datetime = datetime(*descriptor.lms.start[:6])
delta = timedelta(descriptor.days_early_for_beta)
delta = timedelta(descriptor.lms.days_early_for_beta)
effective = start_as_datetime - delta
# ...and back to time_struct
return effective.timetuple()
return descriptor.start
return descriptor.lms.start
def _has_instructor_access_to_location(user, location, course_context=None):
......
......@@ -89,7 +89,7 @@ def course_image_url(course):
"""Try to look up the image url for the course. If it's not found,
log an error and return the dead link"""
if isinstance(modulestore(), XMLModuleStore):
return '/static/' + course.metadata['data_dir'] + "/images/course_image.jpg"
return '/static/' + course.data_dir + "/images/course_image.jpg"
else:
loc = course.location._replace(tag='c4x', category='asset', name='images_course_image.jpg')
path = StaticContent.get_url_path_from_location(loc)
......
......@@ -145,7 +145,7 @@ def get_module(user, request, location, model_data_cache, course_id,
location = Location(location)
descriptor = modulestore().get_instance(course_id, location, depth=depth)
return get_module_for_descriptor(user, request, descriptor, model_data_cache, course_id,
position=position, not_found_ok=not_found_ok,
position=position,
wrap_xmodule_display=wrap_xmodule_display,
grade_bucket_type=grade_bucket_type)
except ItemNotFoundError:
......@@ -205,14 +205,14 @@ def get_module_for_descriptor(user, request, descriptor, model_data_cache, cours
Delegate to get_module. It does an access check, so may return None
"""
return get_module_for_descriptor(user, request, descriptor,
student_module_cache, course_id, position)
model_data_cache, course_id, position)
def xblock_model_data(descriptor):
return DbModel(
LmsKeyValueStore(descriptor._model_data, model_data_cache),
descriptor.module_class,
user.id,
LmsUsage(location, location)
LmsUsage(descriptor.location, descriptor.location)
)
def publish(event):
......@@ -260,7 +260,7 @@ def get_module_for_descriptor(user, request, descriptor, model_data_cache, cours
# by the replace_static_urls code below
replace_urls=partial(
static_replace.replace_static_urls,
data_directory=descriptor.metadata.get('data_dir', ''),
data_directory=descriptor.data_dir,
course_namespace=descriptor.location._replace(category=None, name=None),
),
node_path=settings.NODE_PATH,
......@@ -282,7 +282,7 @@ def get_module_for_descriptor(user, request, descriptor, model_data_cache, cours
log.exception("Error creating module from descriptor {0}".format(descriptor))
# make an ErrorDescriptor -- assuming that the descriptor's system is ok
if has_access(user, location, 'staff', course_id):
if has_access(user, descriptor.location, 'staff', course_id):
err_descriptor_class = ErrorDescriptor
else:
err_descriptor_class = NonStaffErrorDescriptor
......
......@@ -28,6 +28,7 @@ from xmodule.modulestore.django import modulestore
from xmodule.modulestore.xml import XMLModuleStore
from xmodule.x_module import XModule
from student.models import unique_id_for_user
from courseware.model_data import ModelDataCache
from open_ended_grading import open_ended_notifications
......@@ -321,10 +322,12 @@ def get_static_tab_by_slug(course, tab_slug):
return None
def get_static_tab_contents(request, cache, course, tab):
def get_static_tab_contents(request, course, tab):
loc = Location(course.location.tag, course.location.org, course.location.course, 'static_tab', tab['url_slug'])
tab_module = get_module(request.user, request, loc, cache, course.id)
model_data_cache = ModelDataCache.cache_for_descriptor_descendents(course.id,
request.user, modulestore().get_instance(course.id, loc), depth=0)
tab_module = get_module(request.user, request, loc, model_data_cache, course.id)
logging.debug('course_module = {0}'.format(tab_module))
......
......@@ -742,11 +742,11 @@ class TestViewAuth(PageLoader):
yesterday = time.time() - 24 * 3600
# toy course's hasn't started
self.toy.metadata['start'] = stringify_time(time.gmtime(tomorrow))
self.toy.lms.start = time.gmtime(tomorrow)
self.assertFalse(self.toy.has_started())
# but should be accessible for beta testers
self.toy.days_early_for_beta = 2
self.toy.lms.days_early_for_beta = 2
# student user shouldn't see it
student_user = user(self.student)
......
......@@ -443,7 +443,11 @@ def static_tab(request, course_id, tab_slug):
if tab is None:
raise Http404
contents = tabs.get_static_tab_contents(request, None, course, tab)
contents = tabs.get_static_tab_contents(
request,
course,
tab
)
if contents is None:
raise Http404
......
......@@ -18,7 +18,7 @@ class ControllerQueryService(GradingService):
Interface to staff grading backend.
"""
def __init__(self, config):
config['system'] = ModuleSystem(None, None, None, render_to_string, None)
config['system'] = ModuleSystem(None, None, None, render_to_string, None, None)
super(ControllerQueryService, self).__init__(config)
self.check_eta_url = self.url + '/get_submission_eta/'
self.is_unique_url = self.url + '/is_name_unique/'
......
......@@ -143,10 +143,10 @@ class TestPeerGradingService(ct.PageLoader):
location = "i4x://edX/toy/peergrading/init"
self.mock_service = peer_grading_service.MockPeerGradingService()
self.system = ModuleSystem(location, None, None, render_to_string, None)
self.descriptor = peer_grading_module.PeerGradingDescriptor(self.system)
self.system = ModuleSystem(location, None, None, render_to_string, None, None)
self.descriptor = peer_grading_module.PeerGradingDescriptor(self.system, location, {})
self.peer_module = peer_grading_module.PeerGradingModule(self.system, location, "<peergrading/>", self.descriptor)
self.peer_module = peer_grading_module.PeerGradingModule(self.system, location, self.descriptor, {})
self.peer_module.peer_gs = self.mock_service
self.logout()
......
......@@ -5,7 +5,7 @@
%>
<%page args="course" />
<article id="${course.id}" class="course">
%if course.is_new:
%if course.is_newish:
<span class="status">New</span>
%endif
<a href="${reverse('about_course', args=[course.id])}">
......
......@@ -18,7 +18,7 @@
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.stack.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.symbol.js')}"></script>
<script>
${progress_graph.body(grade_summary, course.grade_cutoffs, "grade-detail-graph", not course.metadata.get("no_grade", False), not course.metadata.get("no_grade", False))}
${progress_graph.body(grade_summary, course.grade_cutoffs, "grade-detail-graph", not course.no_grade, not course.no_grade)}
</script>
</%block>
......@@ -32,7 +32,7 @@ ${progress_graph.body(grade_summary, course.grade_cutoffs, "grade-detail-graph",
<h1>Course Progress</h1>
</header>
%if not course.metadata.get('disable_progress_graph',False):
%if not course.disable_progress_graph:
<div id="grade-detail-graph"></div>
%endif
......
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