From 462c7807d2f6b06832cfd4ceb066a477d823483a Mon Sep 17 00:00:00 2001 From: KyryloKireiev Date: Fri, 15 Dec 2023 14:10:58 +0200 Subject: [PATCH] refactor: [FC-0031] Use serializer instead of custom function --- .../mobile_api/course_info/serializers.py | 36 +++++++++++ .../mobile_api/course_info/tests.py | 2 +- .../mobile_api/course_info/views.py | 63 +++++++++---------- 3 files changed, 67 insertions(+), 34 deletions(-) create mode 100644 lms/djangoapps/mobile_api/course_info/serializers.py diff --git a/lms/djangoapps/mobile_api/course_info/serializers.py b/lms/djangoapps/mobile_api/course_info/serializers.py new file mode 100644 index 000000000000..c996d24945b2 --- /dev/null +++ b/lms/djangoapps/mobile_api/course_info/serializers.py @@ -0,0 +1,36 @@ +""" +Course Info serializers +""" +from rest_framework import serializers + +from openedx.core.djangoapps.content.course_overviews.models import CourseOverview + + +class CourseInfoOverviewSerializer(serializers.ModelSerializer): + """ + Serializer for serialize additional fields in BlocksInfoInCourseView. + """ + + name = serializers.CharField(source='display_name') + number = serializers.CharField(source='display_number_with_default') + org = serializers.CharField(source='display_org_with_default') + is_self_paced = serializers.BooleanField(source='self_paced') + media = serializers.SerializerMethodField() + + class Meta: + model = CourseOverview + fields = ( + 'name', + 'number', + 'org', + 'start', + 'start_display', + 'start_type', + 'end', + 'is_self_paced', + 'media', + ) + + @staticmethod + def get_media(obj): + return {'image': obj.image_urls} diff --git a/lms/djangoapps/mobile_api/course_info/tests.py b/lms/djangoapps/mobile_api/course_info/tests.py index 823588624289..e7552382cb3a 100644 --- a/lms/djangoapps/mobile_api/course_info/tests.py +++ b/lms/djangoapps/mobile_api/course_info/tests.py @@ -294,7 +294,7 @@ def test_additional_info_response(self, mock_certificate_downloadable_status): assert response.data['name'] == self.course.display_name assert response.data['number'] == self.course.display_number_with_default assert response.data['org'] == self.course.display_org_with_default - assert response.data['start'] == self.course.start + assert response.data['start'] == self.course.start.strftime('%Y-%m-%dT%H:%M:%SZ') assert response.data['start_display'] == 'July 17, 2015' assert response.data['start_type'] == 'timestamp' assert response.data['end'] == self.course.end diff --git a/lms/djangoapps/mobile_api/course_info/views.py b/lms/djangoapps/mobile_api/course_info/views.py index 404cc5420a7b..587da7cab4d3 100644 --- a/lms/djangoapps/mobile_api/course_info/views.py +++ b/lms/djangoapps/mobile_api/course_info/views.py @@ -16,6 +16,7 @@ from lms.djangoapps.courseware.courses import get_course_info_section_block from lms.djangoapps.course_goals.models import UserActivity from lms.djangoapps.course_api.blocks.views import BlocksInCourseView +from lms.djangoapps.mobile_api.course_info.serializers import CourseInfoOverviewSerializer from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.lib.api.view_utils import view_auth_classes from openedx.core.lib.xblock_utils import get_course_update_items @@ -209,7 +210,8 @@ class BlocksInfoInCourseView(BlocksInCourseView): **Response example** - Body consists of the following fields: + Body consists of the following fields, you received this response if you use + 'return_type=dict' in query params: root: (str) The ID of the root node of the requested course block structure.\ blocks: (dict) A dictionary or list, based on the value of the @@ -237,6 +239,22 @@ class BlocksInfoInCourseView(BlocksInCourseView): * uri: The location of the user's certificate is_self_paced: (bool) Indicates if the course is self paced + Body consists of the following fields, you received this response if you use + 'return_type=list' in query params: + + id: (str) The Course's id (Course Run key) + block_id: (str) The unique identifier for the block_id + lms_web_url: (str) The URL to the navigational container of the xBlock on the web. + legacy_web_url: (str) Like `lms_web_url`, but always directs to + the "Legacy" frontend experience. + student_view_url: (str) The URL to retrieve the HTML rendering + of this block's student view + type: (str): The type of block. Possible values the names of any + XBlock type in the system, including custom blocks. Examples are + course, chapter, sequential, vertical, html, problem, video, and + discussion. + display_name: (str) The display name of the block. + **Returns** * 200 on success with above fields. @@ -249,7 +267,16 @@ class BlocksInfoInCourseView(BlocksInCourseView): """ def get_certificate(self, request, course_id): - """Returns the information about the user's certificate in the course.""" + """ + Returns the information about the user's certificate in the course. + + Arguments: + request (Request): The request object. + course_id (str): The identifier of the course. + Returns: + (dict): A dict containing information about location of the user's certificate + or an empty dictionary, if there is no certificate. + """ if request.user.is_authenticated: certificate_info = certificate_downloadable_status(request.user, course_id) if certificate_info['is_downloadable']: @@ -260,35 +287,6 @@ def get_certificate(self, request, course_id): } return {} - @staticmethod - def compose_course_info(course_overview): - """ - Method for obtaining additional information about the course. - - Arguments: - request - Django request object - """ - - course_data = { - # identifiers - 'name': course_overview.display_name, - 'number': course_overview.display_number_with_default, - 'org': course_overview.display_org_with_default, - - # dates - 'start': course_overview.start, - 'start_display': course_overview.start_display, - 'start_type': course_overview.start_type, - 'end': course_overview.end, - - # various URLs - 'media': { - 'image': course_overview.image_urls, - }, - 'is_self_paced': course_overview.self_paced - } - return course_data - def list(self, request, **kwargs): # pylint: disable=W0221 """ REST API endpoint for listing all the blocks information in the course and @@ -308,7 +306,6 @@ def list(self, request, **kwargs): # pylint: disable=W0221 'id': course_id, 'certificate': self.get_certificate(request, course_key), } - - course_data.update(BlocksInfoInCourseView.compose_course_info(course_overview)) + course_data.update(CourseInfoOverviewSerializer(course_overview).data) response.data.update(course_data) return response