From cde6f4b773edbad9fec712a4e0270d0bd56f250a Mon Sep 17 00:00:00 2001 From: Asad Azam Date: Wed, 4 Oct 2017 12:57:19 +0500 Subject: [PATCH] Fixed score update on rescore --- common/lib/xmodule/xmodule/capa_base.py | 12 +++--- .../xmodule/xmodule/tests/test_capa_module.py | 39 ++++++++++++++++++- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/common/lib/xmodule/xmodule/capa_base.py b/common/lib/xmodule/xmodule/capa_base.py index 118fcfcee1..280656960b 100644 --- a/common/lib/xmodule/xmodule/capa_base.py +++ b/common/lib/xmodule/xmodule/capa_base.py @@ -1126,16 +1126,18 @@ class CapaMixin(ScorableXBlockMixin, CapaFields): return answers - def publish_grade(self, only_if_higher=None): + def publish_grade(self, score=None, only_if_higher=None): """ Publishes the student's current grade to the system as an event """ + if not score: + score = self.score self.runtime.publish( self, 'grade', { - 'value': self.score.raw_earned, - 'max_value': self.score.raw_possible, + 'value': score.raw_earned, + 'max_value': score.raw_possible, 'only_if_higher': only_if_higher, } ) @@ -1615,7 +1617,6 @@ class CapaMixin(ScorableXBlockMixin, CapaFields): orig_score = self.get_score() event_info['orig_score'] = orig_score.raw_earned event_info['orig_total'] = orig_score.raw_possible - try: calculated_score = self.calculate_score() @@ -1633,8 +1634,7 @@ class CapaMixin(ScorableXBlockMixin, CapaFields): # rescoring should have no effect on attempts, so don't # need to increment here, or mark done. Just save. self.set_state_from_lcp() - self.set_score(calculated_score) - self.publish_grade(only_if_higher) + self.publish_grade(score=calculated_score, only_if_higher=only_if_higher) event_info['new_score'] = calculated_score.raw_earned event_info['new_total'] = calculated_score.raw_possible diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py index e05c64ea31..14c4e9621f 100644 --- a/common/lib/xmodule/xmodule/tests/test_capa_module.py +++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py @@ -1043,7 +1043,7 @@ class CapaModuleTest(unittest.TestCase): def test_rescore_problem_correct(self): - module = CapaFactory.create(attempts=1, done=True) + module = CapaFactory.create(attempts=0, done=True) # Simulate that all answers are marked correct, no matter # what the input is, by patching LoncapaResponse.evaluate_answers() @@ -1053,6 +1053,12 @@ class CapaModuleTest(unittest.TestCase): correctness='correct', npoints=1, ) + with patch('capa.correctmap.CorrectMap.is_correct') as mock_is_correct: + mock_is_correct.return_value = True + + # Check the problem + get_request_dict = {CapaFactory.input_key(): '1'} + module.submit_problem(get_request_dict) module.rescore(only_if_higher=False) # Expect that the problem is marked correct @@ -1061,6 +1067,37 @@ class CapaModuleTest(unittest.TestCase): # Expect that the number of attempts is not incremented self.assertEqual(module.attempts, 1) + def test_rescore_problem_additional_correct(self): + # make sure it also works when new correct answer has been added + module = CapaFactory.create(attempts=0) + + # Simulate that all answers are marked correct, no matter + # what the input is, by patching CorrectMap.is_correct() + with patch('capa.correctmap.CorrectMap.is_correct') as mock_is_correct: + mock_is_correct.return_value = True + + # Check the problem + get_request_dict = {CapaFactory.input_key(): '1'} + result = module.submit_problem(get_request_dict) + + # Expect that the problem is marked correct + self.assertEqual(result['success'], 'correct') + # Expect that the number of attempts is incremented + self.assertEqual(module.attempts, 1) + self.assertEqual(module.get_score(), (1, 1)) + + # Simulate that after adding a new correct answer the new calculated score is (0,1) + # by patching CapaMixin.calculate_score() + # In case of rescore with only_if_higher=True it should not update score of module + # if previous score was higher + with patch('xmodule.capa_base.CapaMixin.calculate_score') as mock_calculate_score: + mock_calculate_score.return_value = Score(raw_earned=0, raw_possible=1) + module.rescore(only_if_higher=True) + self.assertEqual(module.get_score(), (1, 1)) + + # Expect that the number of attempts is not incremented + self.assertEqual(module.attempts, 1) + def test_rescore_problem_incorrect(self): # make sure it also works when attempts have been reset, # so add this to the test: