TNL-7185: Send data, not rendered HTML to the learning MFE
Specifically, send data versions of course_expired_message and offer_html. The rendered HTML is still being sent for now, until the learning MFE is updated to consume the data objects.
This commit is contained in:
@@ -109,6 +109,7 @@ class OutlineTabSerializer(DatesBannerSerializerMixin, VerifiedModeSerializerMix
|
||||
"""
|
||||
Serializer for the Outline Tab
|
||||
"""
|
||||
access_expiration = serializers.DictField()
|
||||
course_blocks = CourseBlockSerializer()
|
||||
course_expired_html = serializers.CharField()
|
||||
course_goals = CourseGoalsSerializer()
|
||||
@@ -117,6 +118,7 @@ class OutlineTabSerializer(DatesBannerSerializerMixin, VerifiedModeSerializerMix
|
||||
enroll_alert = EnrollAlertSerializer()
|
||||
handouts_html = serializers.CharField()
|
||||
has_ended = serializers.BooleanField()
|
||||
offer = serializers.DictField()
|
||||
offer_html = serializers.CharField()
|
||||
resume_course = ResumeCourseSerializer()
|
||||
welcome_message_html = serializers.CharField()
|
||||
|
||||
@@ -22,6 +22,7 @@ from openedx.features.course_duration_limits.models import CourseDurationLimitCo
|
||||
from openedx.features.course_experience import (
|
||||
COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, DISPLAY_COURSE_SOCK_FLAG, ENABLE_COURSE_GOALS,
|
||||
)
|
||||
from openedx.features.discounts.applicability import DISCOUNT_APPLICABILITY_FLAG
|
||||
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
|
||||
@@ -165,17 +166,37 @@ class OutlineTabTestViews(BaseCourseHomeTests):
|
||||
|
||||
@override_experiment_waffle_flag(COURSE_HOME_MICROFRONTEND, active=True)
|
||||
@override_waffle_flag(COURSE_HOME_MICROFRONTEND_OUTLINE_TAB, active=True)
|
||||
@patch('lms.djangoapps.course_home_api.outline.v1.views.generate_offer_html', new=Mock(return_value='<p>Offer</p>'))
|
||||
def test_offer_html(self):
|
||||
def test_offer(self):
|
||||
CourseEnrollment.enroll(self.user, self.course.id)
|
||||
self.assertEqual(self.client.get(self.url).data['offer_html'], '<p>Offer</p>')
|
||||
|
||||
response = self.client.get(self.url)
|
||||
self.assertIsNone(response.data['offer'])
|
||||
self.assertIsNone(response.data['offer_html'])
|
||||
|
||||
with override_waffle_flag(DISCOUNT_APPLICABILITY_FLAG, active=True):
|
||||
response = self.client.get(self.url)
|
||||
self.assertIsNotNone(response.data['offer_html'])
|
||||
|
||||
# Just a quick spot check that the dictionary looks like what we expect
|
||||
self.assertEqual(response.data['offer']['code'], 'EDXWELCOME')
|
||||
|
||||
@override_experiment_waffle_flag(COURSE_HOME_MICROFRONTEND, active=True)
|
||||
@override_waffle_flag(COURSE_HOME_MICROFRONTEND_OUTLINE_TAB, active=True)
|
||||
@patch('lms.djangoapps.course_home_api.outline.v1.views.generate_course_expired_message', new=Mock(return_value='<p>Expired</p>'))
|
||||
def test_course_expired_html(self):
|
||||
CourseEnrollment.enroll(self.user, self.course.id)
|
||||
self.assertEqual(self.client.get(self.url).data['course_expired_html'], '<p>Expired</p>')
|
||||
def test_access_expiration(self):
|
||||
enrollment = CourseEnrollment.enroll(self.user, self.course.id, CourseMode.VERIFIED)
|
||||
CourseDurationLimitConfig.objects.create(enabled=True, enabled_as_of=datetime(2018, 1, 1))
|
||||
|
||||
response = self.client.get(self.url)
|
||||
self.assertIsNone(response.data['access_expiration'])
|
||||
self.assertIsNone(response.data['course_expired_html'])
|
||||
|
||||
enrollment.update_enrollment(CourseMode.AUDIT)
|
||||
response = self.client.get(self.url)
|
||||
self.assertIsNotNone(response.data['course_expired_html'])
|
||||
|
||||
# Just a quick spot check that the dictionary looks like what we expect
|
||||
deadline = enrollment.created + MIN_DURATION
|
||||
self.assertEqual(response.data['access_expiration']['expiration_date'], deadline)
|
||||
|
||||
@override_waffle_flag(ENABLE_COURSE_GOALS, active=True)
|
||||
@override_experiment_waffle_flag(COURSE_HOME_MICROFRONTEND, active=True)
|
||||
|
||||
@@ -30,14 +30,14 @@ from lms.djangoapps.courseware.courses import get_course_date_blocks, get_course
|
||||
from lms.djangoapps.courseware.date_summary import TodaysDate
|
||||
from lms.djangoapps.courseware.masquerade import setup_masquerade
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.features.course_duration_limits.access import generate_course_expired_message
|
||||
from openedx.features.course_duration_limits.access import generate_course_expired_message, get_access_expiration_data
|
||||
from openedx.features.course_experience import COURSE_ENABLE_UNENROLLED_ACCESS_FLAG
|
||||
from openedx.features.course_experience.course_tools import CourseToolsPluginManager
|
||||
from openedx.features.course_experience.course_updates import (
|
||||
dismiss_current_update_for_user, get_current_update_for_user,
|
||||
)
|
||||
from openedx.features.course_experience.utils import get_course_outline_block_tree
|
||||
from openedx.features.discounts.utils import generate_offer_html
|
||||
from openedx.features.discounts.utils import generate_offer_data, generate_offer_html
|
||||
from common.djangoapps.student.models import CourseEnrollment
|
||||
from xmodule.course_module import COURSE_VISIBILITY_PUBLIC, COURSE_VISIBILITY_PUBLIC_OUTLINE
|
||||
from xmodule.modulestore.django import modulestore
|
||||
@@ -69,6 +69,11 @@ class OutlineTabView(RetrieveAPIView):
|
||||
|
||||
Body consists of the following fields:
|
||||
|
||||
access_expiration: An object detailing when access to this course will expire
|
||||
expiration_date: (str) When the access expires, in ISO 8601 notation
|
||||
masquerading_expired_course: (bool) Whether this course is expired for the masqueraded user
|
||||
upgrade_deadline: (str) Last chance to upgrade, in ISO 8601 notation (or None if can't upgrade anymore)
|
||||
upgrade_url: (str) Upgrade linke (or None if can't upgrade anymore)
|
||||
course_blocks:
|
||||
blocks: List of serialized Course Block objects. Each serialization has the following fields:
|
||||
id: (str) The usage ID of the block.
|
||||
@@ -114,6 +119,13 @@ class OutlineTabView(RetrieveAPIView):
|
||||
extra_text: (str)
|
||||
handouts_html: (str) Raw HTML for the handouts section of the course info
|
||||
has_ended: (bool) Indicates whether course has ended
|
||||
offer: An object detailing upgrade discount information
|
||||
code: (str) Checkout code
|
||||
expiration_date: (str) Expiration of offer, in ISO 8601 notation
|
||||
original_price: (str) Full upgrade price without checkout code; includes currency symbol
|
||||
discounted_price: (str) Upgrade price with checkout code; includes currency symbol
|
||||
percentage: (int) Amount of discount
|
||||
upgrade_url: (str) Checkout URL
|
||||
resume_course:
|
||||
has_visited_course: (bool) Whether the user has ever visited the course
|
||||
url: (str) The display name of the course block to resume
|
||||
@@ -165,7 +177,9 @@ class OutlineTabView(RetrieveAPIView):
|
||||
handouts_html = get_course_info_section(request, request.user, course, 'handouts') if show_handouts else ''
|
||||
|
||||
# TODO: TNL-7185 Legacy: Refactor to return the offer & expired data and format the message in the MFE
|
||||
offer_data = show_enrolled and generate_offer_data(request.user, course_overview)
|
||||
offer_html = show_enrolled and generate_offer_html(request.user, course_overview)
|
||||
access_expiration = show_enrolled and get_access_expiration_data(request.user, course_overview)
|
||||
course_expired_html = show_enrolled and generate_course_expired_message(request.user, course_overview)
|
||||
|
||||
welcome_message_html = show_enrolled and get_current_update_for_user(request, course)
|
||||
@@ -243,6 +257,7 @@ class OutlineTabView(RetrieveAPIView):
|
||||
}
|
||||
|
||||
data = {
|
||||
'access_expiration': access_expiration or None,
|
||||
'course_blocks': course_blocks,
|
||||
'course_expired_html': course_expired_html or None,
|
||||
'course_goals': course_goals,
|
||||
@@ -251,6 +266,7 @@ class OutlineTabView(RetrieveAPIView):
|
||||
'enroll_alert': enroll_alert,
|
||||
'handouts_html': handouts_html or None,
|
||||
'has_ended': course.has_ended(),
|
||||
'offer': offer_data or None,
|
||||
'offer_html': offer_html or None,
|
||||
'resume_course': resume_course,
|
||||
'welcome_message_html': welcome_message_html or None,
|
||||
|
||||
@@ -269,8 +269,8 @@ class IndexQueryTestCase(ModuleStoreTestCase):
|
||||
NUM_PROBLEMS = 20
|
||||
|
||||
@ddt.data(
|
||||
(ModuleStoreEnum.Type.mongo, 10, 171),
|
||||
(ModuleStoreEnum.Type.split, 4, 167),
|
||||
(ModuleStoreEnum.Type.mongo, 10, 173),
|
||||
(ModuleStoreEnum.Type.split, 4, 169),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_index_query_counts(self, store_type, expected_mongo_query_count, expected_mysql_query_count):
|
||||
|
||||
Reference in New Issue
Block a user