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)