feat: Adds the bulk_email tab for staff level users in CourseInformationSerializer v2 serializer.

Rename v2 InstructorTaskSerializer to InstructorTaskSerializerV2

Rename v2 CourseInformationSerializer to CourseInformationSerializerV2
This commit is contained in:
Brian Buck
2025-12-03 11:56:52 -07:00
parent baaa666435
commit 88f2856c82
4 changed files with 42 additions and 12 deletions

View File

@@ -347,6 +347,41 @@ class CourseMetadataViewTest(SharedModuleStoreTestCase):
tab_ids = [tab['tab_id'] for tab in tabs]
self.assertIn('certificates', tab_ids)
@patch('lms.djangoapps.instructor.views.serializers_v2.is_bulk_email_feature_enabled')
@ddt.data('staff', 'instructor', 'admin')
def test_bulk_email_tab_when_enabled(self, user_attribute, mock_bulk_email_enabled):
"""
Test that the bulk_email tab appears for all staff-level users when is_bulk_email_feature_enabled is True.
"""
mock_bulk_email_enabled.return_value = True
user = getattr(self, user_attribute)
tabs = self._get_tabs_from_response(user)
tab_ids = [tab['tab_id'] for tab in tabs]
self.assertIn('bulk_email', tab_ids)
@patch('lms.djangoapps.instructor.views.serializers_v2.is_bulk_email_feature_enabled')
@ddt.data(
(False, 'staff'),
(False, 'instructor'),
(False, 'admin'),
(True, 'data_researcher'),
)
@ddt.unpack
def test_bulk_email_tab_not_visible(self, feature_enabled, user_attribute, mock_bulk_email_enabled):
"""
Test that the bulk_email tab does not appear when is_bulk_email_feature_enabled is False or the user is not
a user with staff permissions.
"""
mock_bulk_email_enabled.return_value = feature_enabled
user = getattr(self, user_attribute)
tabs = self._get_tabs_from_response(user)
tab_ids = [tab['tab_id'] for tab in tabs]
self.assertNotIn('bulk_email', tab_ids)
def test_tabs_have_sort_order(self):
"""
Test that all tabs include a sort_order field.

View File

@@ -2448,7 +2448,7 @@ class ListEmailContent(APIView):
return JsonResponse(response_payload)
class InstructorTaskSerializer(serializers.Serializer): # pylint: disable=abstract-method
class InstructorTaskSerializerV2(serializers.Serializer): # pylint: disable=abstract-method
"""
Serializer that describes the format of a single instructor task.
"""
@@ -2467,16 +2467,13 @@ class InstructorTaskSerializer(serializers.Serializer): # pylint: disable=abstr
duration_sec = serializers.CharField(help_text=_("Task duration information, if known"))
task_message = serializers.CharField(help_text=_("User-friendly task status information, if available."))
class Meta:
ref_name = "instructor.InstructorTask.v1"
class InstructorTasksListSerializer(serializers.Serializer): # pylint: disable=abstract-method
"""
Serializer to describe the response of the instructor tasks list API.
"""
tasks = serializers.ListSerializer(
child=InstructorTaskSerializer(),
child=InstructorTaskSerializerV2(),
help_text=_("List of instructor tasks.")
)

View File

@@ -29,7 +29,7 @@ from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
from openedx.core.lib.courses import get_course_by_id
from .serializers_v2 import (
InstructorTaskListSerializer,
CourseInformationSerializer,
CourseInformationSerializerV2,
BlockDueDateSerializerV2,
)
from .tools import (
@@ -125,7 +125,7 @@ class CourseMetadataView(DeveloperErrorViewMixin, APIView):
),
],
responses={
200: CourseInformationSerializer,
200: CourseInformationSerializerV2,
401: "The requesting user is not authenticated.",
403: "The requesting user lacks instructor access to the course.",
404: "The requested course does not exist.",
@@ -216,7 +216,7 @@ class CourseMetadataView(DeveloperErrorViewMixin, APIView):
'user': request.user,
'request': request
}
serializer = CourseInformationSerializer(context)
serializer = CourseInformationSerializerV2(context)
return Response(serializer.data, status=status.HTTP_200_OK)

View File

@@ -34,7 +34,7 @@ from xmodule.modulestore.django import modulestore
from .tools import get_student_from_identifier, parse_datetime, DashboardError
class CourseInformationSerializer(serializers.Serializer):
class CourseInformationSerializerV2(serializers.Serializer):
"""
Serializer for comprehensive course information.
@@ -208,6 +208,7 @@ class CourseInformationSerializer(serializers.Serializer):
'open_responses',
'certificates',
'cohorts',
'bulk_email',
'special_exams',
]
order_index = {tab: i for i, tab in enumerate(tabs_order)}
@@ -370,9 +371,6 @@ class InstructorTaskSerializer(serializers.Serializer):
task_input = serializers.CharField()
task_output = serializers.CharField(allow_null=True)
class Meta:
ref_name = "instructor.InstructorTask.v2"
class InstructorTaskListSerializer(serializers.Serializer):
tasks = InstructorTaskSerializer(many=True)