From 61431015c2d6f5cba6ee9087f5fba3ac0ba077f5 Mon Sep 17 00:00:00 2001 From: Adam Palay Date: Mon, 22 Jun 2015 17:19:53 -0400 Subject: [PATCH] update xblock only to mark field values as dirty if they've changed (TNL-2475) force save "download_video" field if not set set timezone to UTC explicitly --- .../contentstore/tests/test_utils.py | 2 +- .../xmodule/modulestore/xml_importer.py | 8 ++--- .../tests/test_delay_between_attempts.py | 36 +++++++++---------- .../xmodule/video_module/video_module.py | 3 +- .../tests/test_submitting_problems.py | 28 ++++++++++++++- requirements/edx/github.txt | 2 +- 6 files changed, 52 insertions(+), 27 deletions(-) diff --git a/cms/djangoapps/contentstore/tests/test_utils.py b/cms/djangoapps/contentstore/tests/test_utils.py index c29231b2ea..194e5859d2 100644 --- a/cms/djangoapps/contentstore/tests/test_utils.py +++ b/cms/djangoapps/contentstore/tests/test_utils.py @@ -154,7 +154,7 @@ class XBlockVisibilityTestCase(ModuleStoreTestCase): super(XBlockVisibilityTestCase, self).setUp() self.dummy_user = ModuleStoreEnum.UserID.test - self.past = datetime(1970, 1, 1) + self.past = datetime(1970, 1, 1, tzinfo=UTC) self.future = datetime.now(UTC) + timedelta(days=1) self.course = CourseFactory.create() diff --git a/common/lib/xmodule/xmodule/modulestore/xml_importer.py b/common/lib/xmodule/xmodule/modulestore/xml_importer.py index dd9fb95cf1..9aa0e08432 100644 --- a/common/lib/xmodule/xmodule/modulestore/xml_importer.py +++ b/common/lib/xmodule/xmodule/modulestore/xml_importer.py @@ -1182,9 +1182,7 @@ def _update_module_location(module, new_location): # in which one component of the key is the XBlock's location (equivalent to "scope_ids"). # Since we've changed the XBlock's location, we need to re-save # all the XBlock's fields so they will be stored using the new location in the key. - # However, since XBlocks only save "dirty" fields, we need to first - # explicitly set each field to its current value before triggering the save. + # However, since XBlocks only save "dirty" fields, we need to call + # XBlock's `force_save_fields_method` if len(rekey_fields) > 0: - for rekey_field_name in rekey_fields: - setattr(module, rekey_field_name, getattr(module, rekey_field_name)) - module.save() + module.force_save_fields(rekey_fields) diff --git a/common/lib/xmodule/xmodule/tests/test_delay_between_attempts.py b/common/lib/xmodule/xmodule/tests/test_delay_between_attempts.py index 9a239f0860..7deabf8756 100644 --- a/common/lib/xmodule/xmodule/tests/test_delay_between_attempts.py +++ b/common/lib/xmodule/xmodule/tests/test_delay_between_attempts.py @@ -188,9 +188,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): num_attempts = 1 (module, result) = self.create_and_check( num_attempts=num_attempts, - last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36), + last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=180, - considered_now=datetime.datetime(2013, 12, 6, 0, 18, 36) + considered_now=datetime.datetime(2013, 12, 6, 0, 18, 36, tzinfo=UTC) ) # You should get a dialog that tells you to wait 2 minutes # Also, the number of attempts should not be incremented @@ -202,9 +202,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): num_attempts = 1 (module, result) = self.create_and_check( num_attempts=num_attempts, - last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36), + last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=180, - considered_now=datetime.datetime(2013, 12, 6, 0, 20, 35) + considered_now=datetime.datetime(2013, 12, 6, 0, 20, 35, tzinfo=UTC) ) # You should get a dialog that tells you to wait 2 minutes # Also, the number of attempts should not be incremented @@ -216,9 +216,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): num_attempts = 1 (module, result) = self.create_and_check( num_attempts=num_attempts, - last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36), + last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=180, - considered_now=datetime.datetime(2013, 12, 6, 0, 20, 36) + considered_now=datetime.datetime(2013, 12, 6, 0, 20, 36, tzinfo=UTC) ) # Successfully submitted and answered # Also, the number of attempts should increment by 1 @@ -230,9 +230,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): num_attempts = 1 (module, result) = self.create_and_check( num_attempts=num_attempts, - last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36), + last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=180, - considered_now=datetime.datetime(2013, 12, 6, 0, 24, 0) + considered_now=datetime.datetime(2013, 12, 6, 0, 24, 0, tzinfo=UTC) ) # Successfully submitted and answered # Also, the number of attempts should increment by 1 @@ -246,17 +246,17 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): with self.assertRaises(xmodule.exceptions.NotFoundError): (module, unused_result) = self.create_and_check( num_attempts=num_attempts, - last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36), + last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=180, - considered_now=datetime.datetime(2013, 12, 6, 0, 24, 0) + considered_now=datetime.datetime(2013, 12, 6, 0, 24, 0, tzinfo=UTC) ) # Now try it without the check_problem (module, unused_result) = self.create_and_check( num_attempts=num_attempts, - last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36), + last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=180, - considered_now=datetime.datetime(2013, 12, 6, 0, 24, 0), + considered_now=datetime.datetime(2013, 12, 6, 0, 24, 0, tzinfo=UTC), skip_check_problem=True ) # Expect that number of attempts NOT incremented @@ -267,9 +267,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): num_attempts = 1 (module, result) = self.create_and_check( num_attempts=num_attempts, - last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36), + last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=60 * 60 * 2, - considered_now=datetime.datetime(2013, 12, 6, 2, 15, 35) + considered_now=datetime.datetime(2013, 12, 6, 2, 15, 35, tzinfo=UTC) ) # You should get a dialog that tells you to wait 2 minutes # Also, the number of attempts should not be incremented @@ -281,9 +281,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): num_attempts = 1 (module, result) = self.create_and_check( num_attempts=num_attempts, - last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36), + last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=60 * 60 * 2 + 63, - considered_now=datetime.datetime(2013, 12, 6, 1, 15, 40) + considered_now=datetime.datetime(2013, 12, 6, 1, 15, 40, tzinfo=UTC) ) # You should get a dialog that tells you to wait 2 minutes # Also, the number of attempts should not be incremented @@ -295,9 +295,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): num_attempts = 1 (module, result) = self.create_and_check( num_attempts=num_attempts, - last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36), + last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=60, - considered_now=datetime.datetime(2013, 12, 6, 0, 17, 36) + considered_now=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC) ) # You should get a dialog that tells you to wait 2 minutes # Also, the number of attempts should not be incremented diff --git a/common/lib/xmodule/xmodule/video_module/video_module.py b/common/lib/xmodule/xmodule/video_module/video_module.py index 72c8c82aba..fc76bb6c0c 100644 --- a/common/lib/xmodule/xmodule/video_module/video_module.py +++ b/common/lib/xmodule/xmodule/video_module/video_module.py @@ -381,9 +381,10 @@ class VideoDescriptor(VideoFields, VideoTranscriptsMixin, VideoStudioViewHandler if not self.fields['download_video'].is_set_on(self): self.download_video = True - # Set download_video field to default value if its not explicitly set for backward compatibility. + # Force download_video field to default value if it's not explicitly set for backward compatibility. if not self.fields['download_video'].is_set_on(self): self.download_video = self.download_video + self.force_save_fields(['download_video']) # for backward compatibility. # If course was existed and was not re-imported by the moment of adding `download_track` field, diff --git a/lms/djangoapps/courseware/tests/test_submitting_problems.py b/lms/djangoapps/courseware/tests/test_submitting_problems.py index 34fa3d8161..dab16c4657 100644 --- a/lms/djangoapps/courseware/tests/test_submitting_problems.py +++ b/lms/djangoapps/courseware/tests/test_submitting_problems.py @@ -18,7 +18,7 @@ from capa.tests.response_xml_factory import ( CodeResponseXMLFactory, ) from courseware import grades -from courseware.models import StudentModule +from courseware.models import StudentModule, StudentModuleHistory from courseware.tests.helpers import LoginEnrollmentTestCase from lms.djangoapps.lms_xblock.runtime import quote_slashes from student.tests.factories import UserFactory @@ -426,6 +426,32 @@ class TestCourseGrader(TestSubmittingProblems): ) self.assertEqual(json.loads(resp.content).get("success"), err_msg) + def test_show_answer_doesnt_write_to_csm(self): + self.basic_setup() + self.submit_question_answer('p1', {'2_1': u'Correct'}) + + # Now fetch the state entry for that problem. + student_module = StudentModule.objects.get( + course_id=self.course.id, + student=self.student_user + ) + # count how many state history entries there are + baseline = StudentModuleHistory.objects.filter( + student_module=student_module + ) + baseline_count = baseline.count() + self.assertEqual(baseline_count, 3) + + # now click "show answer" + self.show_question_answer('p1') + + # check that we don't have more state history entries + csmh = StudentModuleHistory.objects.filter( + student_module=student_module + ) + current_count = csmh.count() + self.assertEqual(current_count, 3) + def test_none_grade(self): """ Check grade is 0 to begin with. diff --git a/requirements/edx/github.txt b/requirements/edx/github.txt index 8926e31496..82f790cdad 100644 --- a/requirements/edx/github.txt +++ b/requirements/edx/github.txt @@ -32,7 +32,7 @@ git+https://github.com/hmarr/django-debug-toolbar-mongo.git@b0686a76f1ce3532088c -e git+https://github.com/jazkarta/ccx-keys.git@e6b03704b1bb97c1d2f31301ecb4e3a687c536ea#egg=ccx-keys # Our libraries: --e git+https://github.com/edx/XBlock.git@e1831fa86bff778ffe1308e00d8ed51b26f7c047#egg=XBlock +-e git+https://github.com/edx/XBlock.git@9fc3367b64a7baa4986f5681ea588d0ffe724a0f#egg=XBlock -e git+https://github.com/edx/codejail.git@6b17c33a89bef0ac510926b1d7fea2748b73aadd#egg=codejail -e git+https://github.com/edx/js-test-tool.git@v0.1.6#egg=js_test_tool -e git+https://github.com/edx/event-tracking.git@0.2.0#egg=event-tracking