From e0747432b7ebd473e88414e1bfcaee8d57fb44b0 Mon Sep 17 00:00:00 2001 From: NiedielnitsevIvan <81557788+NiedielnitsevIvan@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:06:17 +0200 Subject: [PATCH] feat: [AXIMST-676] Extend Sidenav endpoint with additional parameters (#2516) * feat: [AXIMST-676] Extend Sidenav endpoint with additional parameters * test: [AXIMST-676] fix tests * refactor: [AXIMST-676] change block type to 'lock' if it has a prerequisite * style: [AXIMST-676] remove extra comma --- lms/djangoapps/course_home_api/outline/serializers.py | 6 ++++++ .../course_home_api/outline/tests/test_view.py | 10 ++++++++-- lms/djangoapps/course_home_api/outline/views.py | 10 +++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lms/djangoapps/course_home_api/outline/serializers.py b/lms/djangoapps/course_home_api/outline/serializers.py index af2ec4bec6b7..14238ed4ead2 100644 --- a/lms/djangoapps/course_home_api/outline/serializers.py +++ b/lms/djangoapps/course_home_api/outline/serializers.py @@ -43,6 +43,9 @@ def get_blocks(self, block): # pylint: disable=missing-function-docstring description = block['special_exam_info'].get('short_description') icon = block['special_exam_info'].get('suggested_icon', 'fa-pencil-square-o') + if self.context.get('enable_prerequisite_block_type', False) and block.get('accessible') is False: + block_type = 'lock' + serialized = { block_key: { 'children': [child['id'] for child in children], @@ -61,6 +64,9 @@ def get_blocks(self, block): # pylint: disable=missing-function-docstring 'hide_from_toc': block.get('hide_from_toc'), }, } + if 'special_exam_info' in self.context.get('extra_fields', []) and block.get('special_exam_info'): + serialized[block_key]['special_exam_info'] = block.get('special_exam_info').get('short_description') + for child in children: serialized.update(self.get_blocks(child)) return serialized diff --git a/lms/djangoapps/course_home_api/outline/tests/test_view.py b/lms/djangoapps/course_home_api/outline/tests/test_view.py index 4b854c2174f9..1db4bdce3fd9 100644 --- a/lms/djangoapps/course_home_api/outline/tests/test_view.py +++ b/lms/djangoapps/course_home_api/outline/tests/test_view.py @@ -568,7 +568,8 @@ def test_get_unknown_course(self): assert response.status_code == 404 @patch.dict('django.conf.settings.FEATURES', {'ENABLE_SPECIAL_EXAMS': True}) - def test_proctored_exam(self): + @patch('lms.djangoapps.course_api.blocks.transformers.milestones.get_attempt_status_summary') + def test_proctored_exam(self, mock_summary): """ Test that the API returns the correct data for a proctored exam. """ @@ -596,6 +597,10 @@ def test_proctored_exam(self): sequence.is_proctored_exam = True update_outline_from_modulestore(course.id) CourseEnrollment.enroll(self.user, course.id) + mock_summary.return_value = { + 'short_description': 'My Exam', + 'suggested_icon': 'fa-foo-bar', + } url = reverse('course-home:course-sidebar-blocks', args=[course.id]) response = self.client.get(url) @@ -604,6 +609,7 @@ def test_proctored_exam(self): exam_data = response.data['blocks'][str(sequence.location)] assert not exam_data['complete'] assert exam_data['display_name'] == 'Test Proctored Exam' + assert exam_data['special_exam_info'] == 'My Exam' assert exam_data['due'] is not None def test_assignment(self): @@ -663,7 +669,7 @@ def test_hide_learning_sequences(self): assert response.status_code == 200 blocks = response.data['blocks'] - seq_block_id = next(block_id for block_id, block in blocks.items() if block['type'] == 'sequential') + seq_block_id = next(block_id for block_id, block in blocks.items() if block['type'] in ('sequential', 'lock')) # With a course outline loaded, the same sequence is removed. new_learning_seq_outline = CourseOutlineData( diff --git a/lms/djangoapps/course_home_api/outline/views.py b/lms/djangoapps/course_home_api/outline/views.py index 07c1aeb0e96e..caef3bfd6219 100644 --- a/lms/djangoapps/course_home_api/outline/views.py +++ b/lms/djangoapps/course_home_api/outline/views.py @@ -455,9 +455,17 @@ def get(self, request, *args, **kwargs): seq_data for seq_data in chapter_data['children'] if (seq_data['id'] in available_sequence_ids or seq_data['type'] != 'sequential') ] if 'children' in chapter_data else [] + accessible_sequence_ids = {str(usage_key) for usage_key in user_course_outline.accessible_sequences} + for sequence_data in chapter_data['children']: + sequence_data['accessible'] = sequence_data['id'] in accessible_sequence_ids context = self.get_serializer_context() - context['include_vertical'] = True + context.update({ + 'include_vertical': True, + 'extra_fields': ['special_exam_info'], + 'enable_prerequisite_block_type': True, + }) + serializer = self.get_serializer_class()(course_blocks, context=context) return Response(serializer.data)