AA-383: add verified mode info to course_home outline API
Adds can_show_course_sock and verified_mode values to the outline API serialization. And adds a utility method to generate the verified_mode dictionary, shared with the courseware API.
This commit is contained in:
@@ -20,7 +20,6 @@ from lms.djangoapps.courseware.masquerade import setup_masquerade
|
||||
from lms.djangoapps.course_home_api.dates.v1.serializers import DatesTabSerializer
|
||||
from lms.djangoapps.course_home_api.toggles import course_home_mfe_dates_tab_is_active
|
||||
from openedx.core.lib.api.authentication import BearerAuthenticationAllowInactiveUser
|
||||
from openedx.features.course_experience.utils import dates_banner_should_display
|
||||
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
|
||||
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
Course Home Mixins.
|
||||
"""
|
||||
|
||||
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from rest_framework import serializers
|
||||
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
|
||||
from lms.djangoapps.courseware.date_summary import verified_upgrade_deadline_link
|
||||
from lms.djangoapps.courseware.utils import verified_upgrade_deadline_link
|
||||
from openedx.core.djangoapps.courseware_api.utils import serialize_upgrade_info
|
||||
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
|
||||
from openedx.features.course_experience import DISPLAY_COURSE_SOCK_FLAG
|
||||
from openedx.features.course_experience.utils import dates_banner_should_display
|
||||
|
||||
|
||||
@@ -42,3 +42,24 @@ class DatesBannerSerializerMixin(serializers.Serializer):
|
||||
)
|
||||
info['verified_upgrade_link'] = verified_upgrade_deadline_link(request.user, course_id=course_key)
|
||||
return info
|
||||
|
||||
|
||||
class VerifiedModeSerializerMixin(serializers.Serializer):
|
||||
"""
|
||||
Serializer Mixin for displaying verified mode upgrade information.
|
||||
|
||||
Requires 'course_overview', 'enrollment', and 'request' from self.context.
|
||||
"""
|
||||
can_show_upgrade_sock = serializers.SerializerMethodField()
|
||||
verified_mode = serializers.SerializerMethodField()
|
||||
|
||||
def get_can_show_upgrade_sock(self, _):
|
||||
course_overview = self.context['course_overview']
|
||||
return DISPLAY_COURSE_SOCK_FLAG.is_enabled(course_overview.id)
|
||||
|
||||
def get_verified_mode(self, _):
|
||||
"""Return verified mode information, or None."""
|
||||
course_overview = self.context['course_overview']
|
||||
enrollment = self.context['enrollment']
|
||||
request = self.context['request']
|
||||
return serialize_upgrade_info(request.user, course_overview, enrollment)
|
||||
|
||||
@@ -6,7 +6,7 @@ from django.utils.translation import ngettext
|
||||
from rest_framework import serializers
|
||||
|
||||
from lms.djangoapps.course_home_api.dates.v1.serializers import DateSummarySerializer
|
||||
from lms.djangoapps.course_home_api.mixins import DatesBannerSerializerMixin
|
||||
from lms.djangoapps.course_home_api.mixins import DatesBannerSerializerMixin, VerifiedModeSerializerMixin
|
||||
|
||||
|
||||
class CourseBlockSerializer(serializers.Serializer):
|
||||
@@ -74,8 +74,8 @@ class CourseToolSerializer(serializers.Serializer):
|
||||
url = serializers.SerializerMethodField()
|
||||
|
||||
def get_url(self, tool):
|
||||
course_key = self.context.get('course_key')
|
||||
url = tool.url(course_key)
|
||||
course_overview = self.context.get('course_overview')
|
||||
url = tool.url(course_overview.id)
|
||||
request = self.context.get('request')
|
||||
return request.build_absolute_uri(url)
|
||||
|
||||
@@ -105,7 +105,7 @@ class ResumeCourseSerializer(serializers.Serializer):
|
||||
url = serializers.URLField()
|
||||
|
||||
|
||||
class OutlineTabSerializer(DatesBannerSerializerMixin, serializers.Serializer):
|
||||
class OutlineTabSerializer(DatesBannerSerializerMixin, VerifiedModeSerializerMixin, serializers.Serializer):
|
||||
"""
|
||||
Serializer for the Outline Tab
|
||||
"""
|
||||
|
||||
@@ -6,18 +6,22 @@ import itertools
|
||||
from datetime import datetime
|
||||
|
||||
import ddt
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
from django.conf import settings
|
||||
from django.urls import reverse
|
||||
from mock import Mock, patch
|
||||
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
from lms.djangoapps.course_home_api.tests.utils import BaseCourseHomeTests
|
||||
from lms.djangoapps.course_home_api.toggles import COURSE_HOME_MICROFRONTEND, COURSE_HOME_MICROFRONTEND_OUTLINE_TAB
|
||||
from lms.djangoapps.experiments.testutils import override_experiment_waffle_flag
|
||||
from openedx.core.djangoapps.course_date_signals.utils import MIN_DURATION
|
||||
from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
|
||||
from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory
|
||||
from openedx.features.course_experience import COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, ENABLE_COURSE_GOALS
|
||||
from openedx.features.course_duration_limits.models import CourseDurationLimitConfig
|
||||
from openedx.features.course_experience import (
|
||||
COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, DISPLAY_COURSE_SOCK_FLAG, ENABLE_COURSE_GOALS,
|
||||
)
|
||||
from common.djangoapps.student.models import CourseEnrollment
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
from xmodule.course_module import COURSE_VISIBILITY_PUBLIC, COURSE_VISIBILITY_PUBLIC_OUTLINE
|
||||
@@ -307,3 +311,27 @@ class OutlineTabTestViews(BaseCourseHomeTests):
|
||||
self.assertEqual(data['offer_html'] is not None, show_enrolled)
|
||||
self.assertEqual(data['course_expired_html'] is not None, show_enrolled)
|
||||
self.assertEqual(data['resume_course']['url'] is not None, show_enrolled)
|
||||
|
||||
@override_experiment_waffle_flag(COURSE_HOME_MICROFRONTEND, active=True)
|
||||
@override_waffle_flag(COURSE_HOME_MICROFRONTEND_OUTLINE_TAB, active=True)
|
||||
@ddt.data(True, False)
|
||||
def test_can_show_upgrade_sock(self, sock_enabled):
|
||||
with override_waffle_flag(DISPLAY_COURSE_SOCK_FLAG, active=sock_enabled):
|
||||
response = self.client.get(self.url)
|
||||
self.assertEqual(response.data['can_show_upgrade_sock'], sock_enabled)
|
||||
|
||||
@override_experiment_waffle_flag(COURSE_HOME_MICROFRONTEND, active=True)
|
||||
@override_waffle_flag(COURSE_HOME_MICROFRONTEND_OUTLINE_TAB, active=True)
|
||||
def test_verified_mode(self):
|
||||
enrollment = CourseEnrollment.enroll(self.user, self.course.id)
|
||||
CourseDurationLimitConfig.objects.create(enabled=True, enabled_as_of=datetime(2018, 1, 1))
|
||||
|
||||
response = self.client.get(self.url)
|
||||
self.assertEqual(response.data['verified_mode'], {
|
||||
'access_expiration_date': enrollment.created + MIN_DURATION,
|
||||
'currency': 'USD',
|
||||
'currency_symbol': '$',
|
||||
'price': 149,
|
||||
'sku': 'ABCD1234',
|
||||
'upgrade_url': '/dashboard',
|
||||
})
|
||||
|
||||
@@ -256,8 +256,9 @@ class OutlineTabView(RetrieveAPIView):
|
||||
'welcome_message_html': welcome_message_html or None,
|
||||
}
|
||||
context = self.get_serializer_context()
|
||||
context['course_key'] = course_key
|
||||
context['course_overview'] = course_overview
|
||||
context['enable_links'] = show_enrolled or allow_public
|
||||
context['enrollment'] = enrollment
|
||||
serializer = self.get_serializer_class()(data, context=context)
|
||||
|
||||
return Response(serializer.data)
|
||||
|
||||
@@ -41,7 +41,9 @@ class BaseCourseHomeTests(ModuleStoreTestCase, MasqueradeMixin):
|
||||
CourseModeFactory(
|
||||
course_id=self.course.id,
|
||||
mode_slug=CourseMode.VERIFIED,
|
||||
expiration_datetime=datetime(2028, 1, 1)
|
||||
expiration_datetime=datetime(2028, 1, 1),
|
||||
min_price=149,
|
||||
sku='ABCD1234',
|
||||
)
|
||||
VerificationDeadline.objects.create(course_key=self.course.id, deadline=datetime(2028, 1, 1))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user