From 3d70e8c008afd1d11209534f11132374cf2b8d0c Mon Sep 17 00:00:00 2001 From: KyryloKireiev Date: Wed, 24 Apr 2024 16:12:53 +0300 Subject: [PATCH] feat: [AXM-297] Add progress to assignments --- .../mobile_api/course_info/constants.py | 3 +- .../mobile_api/course_info/serializers.py | 15 ---------- .../mobile_api/course_info/views.py | 27 +++++++++--------- .../tests/test_course_info_views.py | 28 +++++++++++++++++++ 4 files changed, 42 insertions(+), 31 deletions(-) diff --git a/lms/djangoapps/mobile_api/course_info/constants.py b/lms/djangoapps/mobile_api/course_info/constants.py index ede7d020ba4b..67f26ca78ff1 100644 --- a/lms/djangoapps/mobile_api/course_info/constants.py +++ b/lms/djangoapps/mobile_api/course_info/constants.py @@ -1,2 +1 @@ -# BLOCK_STRUCTURE_CACHE_TIMEOUT = 60 * 60 # 1 hour -BLOCK_STRUCTURE_CACHE_TIMEOUT = 10 # 10 second +BLOCK_STRUCTURE_CACHE_TIMEOUT = 60 * 60 # 1 hour diff --git a/lms/djangoapps/mobile_api/course_info/serializers.py b/lms/djangoapps/mobile_api/course_info/serializers.py index 4337ff209913..b2bb0ce24701 100644 --- a/lms/djangoapps/mobile_api/course_info/serializers.py +++ b/lms/djangoapps/mobile_api/course_info/serializers.py @@ -14,8 +14,6 @@ from lms.djangoapps.courseware.access import administrative_accesses_to_course_for_user from lms.djangoapps.courseware.access_utils import check_course_open_for_learner from lms.djangoapps.mobile_api.users.serializers import ModeSerializer -from lms.djangoapps.mobile_api.course_info.constants import BLOCK_STRUCTURE_CACHE_TIMEOUT -from lms.djangoapps.mobile_api.course_info.utils import calculate_progress from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.features.course_duration_limits.access import get_user_course_expiration_date @@ -33,7 +31,6 @@ class CourseInfoOverviewSerializer(serializers.ModelSerializer): course_sharing_utm_parameters = serializers.SerializerMethodField() course_about = serializers.SerializerMethodField('get_course_about_url') course_modes = serializers.SerializerMethodField() - total_course_progress = serializers.SerializerMethodField() class Meta: model = CourseOverview @@ -50,7 +47,6 @@ class Meta: 'course_sharing_utm_parameters', 'course_about', 'course_modes', - 'total_course_progress', ) @staticmethod @@ -79,17 +75,6 @@ def get_course_modes(self, course_overview): for mode in course_modes ] - def get_total_course_progress(self, obj): - """ - - """ - course_progress = calculate_progress(self.context.get('user'), obj.id, BLOCK_STRUCTURE_CACHE_TIMEOUT) - - return { - 'num_points_earned': sum(map(lambda x: x.graded_total.earned if x.graded else 0, course_progress)), - 'num_points_possible': sum(map(lambda x: x.graded_total.possible if x.graded else 0, course_progress)), - } - class MobileCourseEnrollmentSerializer(serializers.ModelSerializer): """ diff --git a/lms/djangoapps/mobile_api/course_info/views.py b/lms/djangoapps/mobile_api/course_info/views.py index 77e2423ec27b..352efca9b4aa 100644 --- a/lms/djangoapps/mobile_api/course_info/views.py +++ b/lms/djangoapps/mobile_api/course_info/views.py @@ -3,7 +3,7 @@ """ import logging -from typing import Optional, Union +from typing import Dict, Optional, Union import django from django.contrib.auth import get_user_model @@ -359,6 +359,12 @@ def list(self, request, **kwargs): # pylint: disable=W0221 course_info_context = {} if requested_user := self.get_requested_user(request.user, requested_username): + self._extend_sequential_info_with_assignment_progress( + requested_user, + course_key, + response.data['blocks'], + ) + course_info_context = { 'user': requested_user } @@ -380,25 +386,18 @@ def list(self, request, **kwargs): # pylint: disable=W0221 course_data.update(CourseInfoOverviewSerializer(course_overview, context=course_info_context).data) - self._extend_sequential_info_with_assignment_progress( - requested_user, - course_id, - response.data['blocks'], - ) - response.data.update(course_data) return response + @staticmethod def _extend_sequential_info_with_assignment_progress( - self, - requested_user, - course_id, - blocks_info_data, - ): + requested_user: User, + course_id: CourseKey, + blocks_info_data: Dict[str, Dict], + ) -> None: """ - + Extends sequential xblock info with assignment's name and progress. """ - subsection_grades = calculate_progress(requested_user, course_id, BLOCK_STRUCTURE_CACHE_TIMEOUT) grades_with_locations = {str(grade.location): grade for grade in subsection_grades} diff --git a/lms/djangoapps/mobile_api/tests/test_course_info_views.py b/lms/djangoapps/mobile_api/tests/test_course_info_views.py index 67d2c79f9017..a5175626a29e 100644 --- a/lms/djangoapps/mobile_api/tests/test_course_info_views.py +++ b/lms/djangoapps/mobile_api/tests/test_course_info_views.py @@ -422,3 +422,31 @@ def test_course_modes(self): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertListEqual(response.data['course_modes'], expected_course_modes) + + def test_extend_sequential_info_with_assignment_progress_get_only_sequential(self) -> None: + response = self.verify_response(url=self.url, params={'block_types_filter': 'sequential'}) + + expected_results = ( + { + 'assignment_type': 'Lecture Sequence', + 'num_points_earned': 0.0, + 'num_points_possible': 0.0 + }, + { + 'assignment_type': None, + 'num_points_earned': 0.0, + 'num_points_possible': 0.0 + }, + ) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + for sequential_info, assignment_progress in zip(response.data['blocks'].values(), expected_results): + self.assertDictEqual(sequential_info['assignment_progress'], assignment_progress) + + @ddt.data('chapter', 'vertical', 'problem', 'video', 'html') + def test_extend_sequential_info_with_assignment_progress_for_other_types(self, block_type: 'str') -> None: + response = self.verify_response(url=self.url, params={'block_types_filter': block_type}) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + for block_info in response.data['blocks'].values(): + self.assertNotEqual('assignment_progress', block_info)