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