diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index d76b62dc06..78a94941cc 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -309,7 +309,13 @@ class CapaModule(CapaFields, XModule): d = self.get_score() score = d['score'] total = d['total'] + if total > 0: + if self.weight is not None: + # scale score and total by weight/total: + score = score * self.weight / total + total = self.weight + try: return Progress(score, total) except (TypeError, ValueError): @@ -321,11 +327,13 @@ class CapaModule(CapaFields, XModule): """ Return some html with data about the module """ + progress = self.get_progress() return self.system.render_template('problem_ajax.html', { 'element_id': self.location.html_id(), 'id': self.id, 'ajax_url': self.system.ajax_url, - 'progress': Progress.to_js_status_str(self.get_progress()) + 'progress_status': Progress.to_js_status_str(progress), + 'progress_detail': Progress.to_js_detail_str(progress), }) def check_button_name(self): @@ -485,8 +493,7 @@ class CapaModule(CapaFields, XModule): """ Return html for the problem. - Adds check, reset, save buttons as necessary based on the problem config - and state. + Adds check, reset, save buttons as necessary based on the problem config and state. """ try: @@ -516,13 +523,12 @@ class CapaModule(CapaFields, XModule): 'reset_button': self.should_show_reset_button(), 'save_button': self.should_show_save_button(), 'answer_available': self.answer_available(), - 'ajax_url': self.system.ajax_url, 'attempts_used': self.attempts, 'attempts_allowed': self.max_attempts, - 'progress': self.get_progress(), } html = self.system.render_template('problem.html', context) + if encapsulate: html = u'
Problem Content
diff --git a/common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee b/common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee index bca89b0dea..33d74e2335 100644 --- a/common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee +++ b/common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee @@ -77,6 +77,25 @@ describe 'Problem', -> [@problem.updateMathML, @stubbedJax, $('#input_example_1').get(0)] ] + describe 'renderProgressState', -> + beforeEach -> + @problem = new Problem($('.xmodule_display')) + #@renderProgressState = @problem.renderProgressState + + describe 'with a status of "none"', -> + it 'reports the number of points possible', -> + @problem.el.data('progress_status', 'none') + @problem.el.data('progress_detail', '0/1') + @problem.renderProgressState() + expect(@problem.$('.problem-progress').html()).toEqual "(1 point possible)" + + describe 'with any other valid status', -> + it 'reports the current score', -> + @problem.el.data('progress_status', 'foo') + @problem.el.data('progress_detail', '1/1') + @problem.renderProgressState() + expect(@problem.$('.problem-progress').html()).toEqual "(1/1 points)" + describe 'render', -> beforeEach -> @problem = new Problem($('.xmodule_display')) diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 601fb749ac..09a398dd7a 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -35,15 +35,34 @@ class @Problem @$('input.math').each (index, element) => MathJax.Hub.Queue [@refreshMath, null, element] + renderProgressState: => + detail = @el.data('progress_detail') + status = @el.data('progress_status') + # i18n + progress = "(#{detail} points)" + if status == 'none' and detail? and detail.indexOf('/') > 0 + a = detail.split('/') + possible = parseInt(a[1]) + if possible == 1 + # i18n + progress = "(#{possible} point possible)" + else + # i18n + progress = "(#{possible} points possible)" + @$('.problem-progress').html(progress) + updateProgress: (response) => if response.progress_changed - @el.attr progress: response.progress_status + @el.data('progress_status', response.progress_status) + @el.data('progress_detail', response.progress_detail) @el.trigger('progressChanged') + @renderProgressState() forceUpdate: (response) => - @el.attr progress: response.progress_status + @el.data('progress_status', response.progress_status) + @el.data('progress_detail', response.progress_detail) @el.trigger('progressChanged') - + @renderProgressState() queueing: => @queued_items = @$(".xqueue") @@ -113,7 +132,7 @@ class @Problem @setupInputTypes() @bind() @queueing() - + @forceUpdate response # TODO add hooks for problem types here by inspecting response.html and doing # stuff if a div w a class is found diff --git a/common/lib/xmodule/xmodule/js/src/sequence/display.coffee b/common/lib/xmodule/xmodule/js/src/sequence/display.coffee index 495b734785..bae1b89bab 100644 --- a/common/lib/xmodule/xmodule/js/src/sequence/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/sequence/display.coffee @@ -45,7 +45,7 @@ class @Sequence new_progress = "NA" _this = this $('.problems-wrapper').each (index) -> - progress = $(this).attr 'progress' + progress = $(this).data 'progress_status' new_progress = _this.mergeProgress progress, new_progress @progressTable[@position] = new_progress diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py index 0f3dfa5b85..80c4e41e8f 100644 --- a/common/lib/xmodule/xmodule/tests/test_capa_module.py +++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py @@ -1233,6 +1233,37 @@ class CapaModuleTest(unittest.TestCase): mock_log.exception.assert_called_once_with('Got bad progress') mock_log.reset_mock() + @patch('xmodule.capa_module.Progress') + def test_get_progress_calculate_progress_fraction(self, mock_progress): + """ + Check that score and total are calculated correctly for the progress fraction. + """ + module = CapaFactory.create() + module.weight = 1 + module.get_progress() + mock_progress.assert_called_with(0, 1) + + other_module = CapaFactory.create(correct=True) + other_module.weight = 1 + other_module.get_progress() + mock_progress.assert_called_with(1, 1) + + def test_get_html(self): + """ + Check that get_html() calls get_progress() with no arguments. + """ + module = CapaFactory.create() + module.get_progress = Mock(wraps=module.get_progress) + module.get_html() + module.get_progress.assert_called_once_with() + + def test_get_problem(self): + """ + Check that get_problem() returns the expected dictionary. + """ + module = CapaFactory.create() + self.assertEquals(module.get_problem("data"), {'html': module.get_problem_html(encapsulate=False)}) + class ComplexEncoderTest(unittest.TestCase): def test_default(self): diff --git a/lms/djangoapps/courseware/features/problems.feature b/lms/djangoapps/courseware/features/problems.feature index fe6a695475..b8b129bdd4 100644 --- a/lms/djangoapps/courseware/features/problems.feature +++ b/lms/djangoapps/courseware/features/problems.feature @@ -129,3 +129,45 @@ Feature: Answer problems When I press the button with the label "Hide Answer(s)" Then the button with the label "Show Answer(s)" does appear And I should not see "4.14159" anywhere on the page + + Scenario: I can see my score on a problem when I answer it and after I reset it + Given I am viewing a "