Commit 61431015 by Adam Palay

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
parent 2de67bd3
...@@ -154,7 +154,7 @@ class XBlockVisibilityTestCase(ModuleStoreTestCase): ...@@ -154,7 +154,7 @@ class XBlockVisibilityTestCase(ModuleStoreTestCase):
super(XBlockVisibilityTestCase, self).setUp() super(XBlockVisibilityTestCase, self).setUp()
self.dummy_user = ModuleStoreEnum.UserID.test 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.future = datetime.now(UTC) + timedelta(days=1)
self.course = CourseFactory.create() self.course = CourseFactory.create()
......
...@@ -1182,9 +1182,7 @@ def _update_module_location(module, new_location): ...@@ -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"). # 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 # 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. # 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 # However, since XBlocks only save "dirty" fields, we need to call
# explicitly set each field to its current value before triggering the save. # XBlock's `force_save_fields_method`
if len(rekey_fields) > 0: if len(rekey_fields) > 0:
for rekey_field_name in rekey_fields: module.force_save_fields(rekey_fields)
setattr(module, rekey_field_name, getattr(module, rekey_field_name))
module.save()
...@@ -188,9 +188,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): ...@@ -188,9 +188,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts = 1 num_attempts = 1
(module, result) = self.create_and_check( (module, result) = self.create_and_check(
num_attempts=num_attempts, 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, 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 # You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented # Also, the number of attempts should not be incremented
...@@ -202,9 +202,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): ...@@ -202,9 +202,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts = 1 num_attempts = 1
(module, result) = self.create_and_check( (module, result) = self.create_and_check(
num_attempts=num_attempts, 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, 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 # You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented # Also, the number of attempts should not be incremented
...@@ -216,9 +216,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): ...@@ -216,9 +216,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts = 1 num_attempts = 1
(module, result) = self.create_and_check( (module, result) = self.create_and_check(
num_attempts=num_attempts, 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, 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 # Successfully submitted and answered
# Also, the number of attempts should increment by 1 # Also, the number of attempts should increment by 1
...@@ -230,9 +230,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): ...@@ -230,9 +230,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts = 1 num_attempts = 1
(module, result) = self.create_and_check( (module, result) = self.create_and_check(
num_attempts=num_attempts, 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, 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 # Successfully submitted and answered
# Also, the number of attempts should increment by 1 # Also, the number of attempts should increment by 1
...@@ -246,17 +246,17 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): ...@@ -246,17 +246,17 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
with self.assertRaises(xmodule.exceptions.NotFoundError): with self.assertRaises(xmodule.exceptions.NotFoundError):
(module, unused_result) = self.create_and_check( (module, unused_result) = self.create_and_check(
num_attempts=num_attempts, 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, 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 # Now try it without the check_problem
(module, unused_result) = self.create_and_check( (module, unused_result) = self.create_and_check(
num_attempts=num_attempts, 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, 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 skip_check_problem=True
) )
# Expect that number of attempts NOT incremented # Expect that number of attempts NOT incremented
...@@ -267,9 +267,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): ...@@ -267,9 +267,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts = 1 num_attempts = 1
(module, result) = self.create_and_check( (module, result) = self.create_and_check(
num_attempts=num_attempts, 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, 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 # You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented # Also, the number of attempts should not be incremented
...@@ -281,9 +281,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): ...@@ -281,9 +281,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts = 1 num_attempts = 1
(module, result) = self.create_and_check( (module, result) = self.create_and_check(
num_attempts=num_attempts, 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, 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 # You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented # Also, the number of attempts should not be incremented
...@@ -295,9 +295,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase): ...@@ -295,9 +295,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts = 1 num_attempts = 1
(module, result) = self.create_and_check( (module, result) = self.create_and_check(
num_attempts=num_attempts, 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, 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 # You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented # Also, the number of attempts should not be incremented
......
...@@ -381,9 +381,10 @@ class VideoDescriptor(VideoFields, VideoTranscriptsMixin, VideoStudioViewHandler ...@@ -381,9 +381,10 @@ class VideoDescriptor(VideoFields, VideoTranscriptsMixin, VideoStudioViewHandler
if not self.fields['download_video'].is_set_on(self): if not self.fields['download_video'].is_set_on(self):
self.download_video = True 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): if not self.fields['download_video'].is_set_on(self):
self.download_video = self.download_video self.download_video = self.download_video
self.force_save_fields(['download_video'])
# for backward compatibility. # for backward compatibility.
# If course was existed and was not re-imported by the moment of adding `download_track` field, # If course was existed and was not re-imported by the moment of adding `download_track` field,
......
...@@ -18,7 +18,7 @@ from capa.tests.response_xml_factory import ( ...@@ -18,7 +18,7 @@ from capa.tests.response_xml_factory import (
CodeResponseXMLFactory, CodeResponseXMLFactory,
) )
from courseware import grades from courseware import grades
from courseware.models import StudentModule from courseware.models import StudentModule, StudentModuleHistory
from courseware.tests.helpers import LoginEnrollmentTestCase from courseware.tests.helpers import LoginEnrollmentTestCase
from lms.djangoapps.lms_xblock.runtime import quote_slashes from lms.djangoapps.lms_xblock.runtime import quote_slashes
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
...@@ -426,6 +426,32 @@ class TestCourseGrader(TestSubmittingProblems): ...@@ -426,6 +426,32 @@ class TestCourseGrader(TestSubmittingProblems):
) )
self.assertEqual(json.loads(resp.content).get("success"), err_msg) 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): def test_none_grade(self):
""" """
Check grade is 0 to begin with. Check grade is 0 to begin with.
......
...@@ -32,7 +32,7 @@ git+https://github.com/hmarr/django-debug-toolbar-mongo.git@b0686a76f1ce3532088c ...@@ -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 -e git+https://github.com/jazkarta/ccx-keys.git@e6b03704b1bb97c1d2f31301ecb4e3a687c536ea#egg=ccx-keys
# Our libraries: # 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/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/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 -e git+https://github.com/edx/event-tracking.git@0.2.0#egg=event-tracking
......
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