modify completion percentage calculation to account for single component that is excluded/ignored
This commit is contained in:
@@ -470,12 +470,14 @@ def get_subsection_completion_percentage(subsection_usage_key, user):
|
|||||||
block, 'completion_mode'
|
block, 'completion_mode'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# always exclude html blocks (in addition to EXCLUDED blocks) for gating calculations
|
||||||
|
# See https://openedx.atlassian.net/browse/WL-1798
|
||||||
if completion_mode not in (CompletionMode.AGGREGATOR, CompletionMode.EXCLUDED) \
|
if completion_mode not in (CompletionMode.AGGREGATOR, CompletionMode.EXCLUDED) \
|
||||||
and not block.block_type == 'html':
|
and not block.block_type == 'html':
|
||||||
completable_blocks.append(block)
|
completable_blocks.append(block)
|
||||||
|
|
||||||
if not completable_blocks:
|
if not completable_blocks:
|
||||||
return 0
|
return 100
|
||||||
subsection_completion_total = 0
|
subsection_completion_total = 0
|
||||||
course_block_completions = BlockCompletion.get_course_completions(user, subsection_usage_key.course_key)
|
course_block_completions = BlockCompletion.get_course_completions(user, subsection_usage_key.course_key)
|
||||||
for block in completable_blocks:
|
for block in completable_blocks:
|
||||||
|
|||||||
@@ -265,6 +265,46 @@ class TestGatingApi(ModuleStoreTestCase, MilestonesTestCaseMixin):
|
|||||||
completion_percentage = gating_api.get_subsection_completion_percentage(self.seq1.location, student)
|
completion_percentage = gating_api.get_subsection_completion_percentage(self.seq1.location, student)
|
||||||
self.assertEqual(completion_percentage, expected_completion_percentage)
|
self.assertEqual(completion_percentage, expected_completion_percentage)
|
||||||
|
|
||||||
|
@data(
|
||||||
|
('discussion', None, 100),
|
||||||
|
('html', None, 100),
|
||||||
|
('html', 1, 100),
|
||||||
|
('problem', 1, 100),
|
||||||
|
('problem', 0, 0),
|
||||||
|
('openassessment', 1, 100),
|
||||||
|
('openassessment', 0, 0),
|
||||||
|
)
|
||||||
|
@unpack
|
||||||
|
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||||
|
def test_get_subsection_completion_percentage_single_component(
|
||||||
|
self,
|
||||||
|
component_type,
|
||||||
|
completed,
|
||||||
|
expected_completion_percentage
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Test if gating_api.get_subsection_completion_percentage returns expected completion percentage
|
||||||
|
when only a single component in a vertical/unit
|
||||||
|
|
||||||
|
Note:
|
||||||
|
html blocks and discussion blocks are ignored in calculations so should always return
|
||||||
|
100% complete
|
||||||
|
"""
|
||||||
|
student = UserFactory(is_staff=False)
|
||||||
|
|
||||||
|
component = ItemFactory.create(
|
||||||
|
parent_location=self.vertical.location,
|
||||||
|
category=component_type,
|
||||||
|
display_name='{} block'.format(component_type)
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch.object(BlockCompletion, 'get_course_completions') as course_block_completions_mock:
|
||||||
|
course_block_completions_mock.return_value = {
|
||||||
|
component.location: completed,
|
||||||
|
}
|
||||||
|
completion_percentage = gating_api.get_subsection_completion_percentage(self.seq1.location, student)
|
||||||
|
self.assertEqual(completion_percentage, expected_completion_percentage)
|
||||||
|
|
||||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||||
def test_compute_is_prereq_met(self):
|
def test_compute_is_prereq_met(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user