diff --git a/cms/djangoapps/contentstore/tests/test_course_settings.py b/cms/djangoapps/contentstore/tests/test_course_settings.py
index 5a9af58427..8c15b1ae95 100644
--- a/cms/djangoapps/contentstore/tests/test_course_settings.py
+++ b/cms/djangoapps/contentstore/tests/test_course_settings.py
@@ -76,6 +76,23 @@ class CourseDetailsTestCase(CourseTestCase):
self.assertIsNone(jsondetails['intro_video'], "intro_video somehow initialized")
self.assertIsNone(jsondetails['effort'], "effort somehow initialized")
+ def test_ooc_encoder(self):
+ """
+ Test the encoder out of its original constrained purpose to see if it functions for general use
+ """
+ details = {'location': Location(['tag', 'org', 'course', 'category', 'name']),
+ 'number': 1,
+ 'string': 'string',
+ 'datetime': datetime.datetime.now(UTC())}
+ jsondetails = json.dumps(details, cls=CourseSettingsEncoder)
+ jsondetails = json.loads(jsondetails)
+
+ self.assertIn('location', jsondetails)
+ self.assertIn('org', jsondetails['location'])
+ self.assertEquals('org', jsondetails['location'][1])
+ self.assertEquals(1, jsondetails['number'])
+ self.assertEqual(jsondetails['string'], 'string')
+
def test_update_and_fetch(self):
# # NOTE: I couldn't figure out how to validly test time setting w/ all the conversions
jsondetails = CourseDetails.fetch(self.course_location)
@@ -153,11 +170,7 @@ class CourseDetailsViewTest(CourseTestCase):
date = Date()
if field in encoded and encoded[field] is not None:
dt1 = date.from_json(encoded[field])
-
- if isinstance(details[field], datetime.datetime):
- dt2 = details[field]
- else:
- dt2 = date.from_json(details[field])
+ dt2 = details[field]
expected_delta = datetime.timedelta(0)
self.assertEqual(dt1 - dt2, expected_delta, str(dt1) + "!=" + str(dt2) + " at " + context)
diff --git a/common/djangoapps/tests.py b/common/djangoapps/tests.py
new file mode 100644
index 0000000000..8e78ee7f37
--- /dev/null
+++ b/common/djangoapps/tests.py
@@ -0,0 +1,49 @@
+'''
+Created on Jun 6, 2013
+
+@author: dmitchell
+'''
+from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
+from student.tests.factories import AdminFactory
+from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+import xmodule_modifiers
+import datetime
+from pytz import UTC
+from xmodule.modulestore.tests import factories
+
+class TestXmoduleModfiers(ModuleStoreTestCase):
+
+ # FIXME disabled b/c start date inheritance is not occuring and render_... in get_html is failing due
+ # to middleware.lookup['main'] not being defined
+ def _test_add_histogram(self):
+ instructor = AdminFactory.create()
+ self.client.login(username=instructor.username, password='test')
+
+ course = CourseFactory.create(org='test',
+ number='313', display_name='histogram test')
+ section = ItemFactory.create(
+ parent_location=course.location, display_name='chapter hist',
+ template='i4x://edx/templates/chapter/Empty')
+ problem = ItemFactory.create(
+ parent_location=section.location, display_name='problem hist 1',
+ template='i4x://edx/templates/problem/Blank_Common_Problem')
+ problem.has_score = False # don't trip trying to retrieve db data
+
+ late_problem = ItemFactory.create(
+ parent_location=section.location, display_name='problem hist 2',
+ template='i4x://edx/templates/problem/Blank_Common_Problem')
+ late_problem.lms.start = datetime.datetime.now(UTC) + datetime.timedelta(days=32)
+ late_problem.has_score = False
+
+
+ problem_module = factories.get_test_xmodule_for_descriptor(problem)
+ problem_module.get_html = xmodule_modifiers.add_histogram(lambda:'', problem_module, instructor)
+
+ self.assertRegexpMatches(
+ problem_module.get_html(), r'.*Not yet.*')
+
+ problem_module = factories.get_test_xmodule_for_descriptor(late_problem)
+ problem_module.get_html = xmodule_modifiers.add_histogram(lambda: '', problem_module, instructor)
+
+ self.assertRegexpMatches(
+ problem_module.get_html(), r'.*Yes!.*')
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index 0215f2c872..b0f4303d1e 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -747,7 +747,7 @@ class CapaModule(CapaFields, XModule):
# Problem queued. Students must wait a specified waittime before they are allowed to submit
if self.lcp.is_queued():
- current_time = datetime.datetime.now(UTC)
+ current_time = datetime.datetime.now(UTC())
prev_submit_time = self.lcp.get_recentmost_queuetime()
waittime_between_requests = self.system.xqueue['waittime']
if (current_time - prev_submit_time).total_seconds() < waittime_between_requests:
diff --git a/common/lib/xmodule/xmodule/fields.py b/common/lib/xmodule/xmodule/fields.py
index 3164c062bb..8e0294b74a 100644
--- a/common/lib/xmodule/xmodule/fields.py
+++ b/common/lib/xmodule/xmodule/fields.py
@@ -74,6 +74,8 @@ class Timedelta(ModelType):
Returns a datetime.timedelta parsed from the string
"""
+ if time_str is None:
+ return None
parts = TIMEDELTA_REGEX.match(time_str)
if not parts:
return
diff --git a/common/lib/xmodule/xmodule/modulestore/tests/factories.py b/common/lib/xmodule/xmodule/modulestore/tests/factories.py
index 8cf148f742..99c5ec2c91 100644
--- a/common/lib/xmodule/xmodule/modulestore/tests/factories.py
+++ b/common/lib/xmodule/xmodule/modulestore/tests/factories.py
@@ -4,6 +4,11 @@ from uuid import uuid4
from xmodule.modulestore import Location
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.inheritance import own_metadata
+from xmodule.x_module import ModuleSystem
+from mitxmako.shortcuts import render_to_string
+from xblock.runtime import InvalidScopeError
+import datetime
+from pytz import UTC
class XModuleCourseFactory(Factory):
@@ -35,7 +40,7 @@ class XModuleCourseFactory(Factory):
if display_name is not None:
new_course.display_name = display_name
- new_course.lms.start = gmtime()
+ new_course.lms.start = datetime.datetime.now(UTC)
new_course.tabs = kwargs.get(
'tabs',
[
@@ -159,3 +164,32 @@ class ItemFactory(XModuleItemFactory):
@lazy_attribute_sequence
def display_name(attr, n):
return "{} {}".format(attr.category.title(), n)
+
+
+def get_test_xmodule_for_descriptor(descriptor):
+ """
+ Attempts to create an xmodule which responds usually correctly from the descriptor. Not guaranteed.
+
+ :param descriptor:
+ """
+ module_sys = ModuleSystem(
+ ajax_url='',
+ track_function=None,
+ get_module=None,
+ render_template=render_to_string,
+ replace_urls=None,
+ xblock_model_data=_test_xblock_model_data_accessor(descriptor)
+ )
+ return descriptor.xmodule(module_sys)
+
+def _test_xblock_model_data_accessor(descriptor):
+ simple_map = {}
+ for field in descriptor.fields:
+ try:
+ simple_map[field.name] = getattr(descriptor, field.name)
+ except InvalidScopeError:
+ simple_map[field.name] = field.default
+ for field in descriptor.module_class.fields:
+ if field.name not in simple_map:
+ simple_map[field.name] = field.default
+ return lambda o: simple_map