feat: remove course_home_welcome upsell link (REV-2131) (#27603)
This commit is contained in:
@@ -63,9 +63,6 @@ from openedx.features.course_experience.course_tools import HttpMethod
|
||||
</header>
|
||||
<div class="page-content">
|
||||
<div class="page-content-main">
|
||||
% if offer_banner_fragment:
|
||||
${HTML(offer_banner_fragment.content)}
|
||||
% endif
|
||||
% if course_expiration_fragment:
|
||||
${HTML(course_expiration_fragment.content)}
|
||||
% endif
|
||||
@@ -194,7 +191,6 @@ from openedx.features.course_experience.course_tools import HttpMethod
|
||||
|
||||
var personalizedLearnerSchedulesLink = $(".personalized_learner_schedules_button");
|
||||
var fbeLink = $("#FBE_banner");
|
||||
var welcomeLink = $("#welcome");
|
||||
var sockLink = $("#sock");
|
||||
var upgradeDateLink = $("#course_home_dates");
|
||||
var GreenUpgradeLink = $("#green_upgrade");
|
||||
@@ -213,12 +209,6 @@ from openedx.features.course_experience.course_tools import HttpMethod
|
||||
linkCategory: "FBE_banner"
|
||||
});
|
||||
|
||||
TrackECommerceEvents.trackUpsellClick(welcomeLink, 'course_home_welcome', {
|
||||
pageName: "course_home",
|
||||
linkType: "link",
|
||||
linkCategory: "welcome"
|
||||
});
|
||||
|
||||
TrackECommerceEvents.trackUpsellClick(sockLink, 'course_home_sock', {
|
||||
pageName: "course_home",
|
||||
linkType: "button",
|
||||
|
||||
@@ -25,13 +25,10 @@ from common.djangoapps.student.tests.factories import InstructorFactory
|
||||
from common.djangoapps.student.tests.factories import OrgInstructorFactory
|
||||
from common.djangoapps.student.tests.factories import OrgStaffFactory
|
||||
from common.djangoapps.student.tests.factories import StaffFactory
|
||||
from common.djangoapps.util.date_utils import strftime_localized_html
|
||||
from lms.djangoapps.experiments.models import ExperimentData
|
||||
from lms.djangoapps.commerce.models import CommerceConfiguration
|
||||
from lms.djangoapps.commerce.utils import EcommerceService
|
||||
from lms.djangoapps.course_goals.api import add_course_goal, get_course_goal
|
||||
from lms.djangoapps.courseware.tests.helpers import get_expiration_banner_text
|
||||
from lms.djangoapps.courseware.utils import verified_upgrade_deadline_link
|
||||
from lms.djangoapps.discussion.django_comment_client.tests.factories import RoleFactory
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.djangoapps.django_comment_common.models import (
|
||||
@@ -53,8 +50,6 @@ from openedx.features.course_experience import (
|
||||
)
|
||||
from openedx.features.course_experience.tests import BaseCourseUpdatesTestCase
|
||||
from openedx.features.course_experience.tests.views.helpers import add_course_mode, remove_course_mode
|
||||
from openedx.features.discounts.applicability import get_discount_expiration_date
|
||||
from openedx.features.discounts.utils import REV1008_EXPERIMENT_ID, format_strikeout_price
|
||||
from common.djangoapps.student.models import CourseEnrollment, FBEEnrollmentExclusion
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
from common.djangoapps.util.date_utils import strftime_localized
|
||||
@@ -204,7 +199,7 @@ class TestCourseHomePage(CourseHomePageTestCase): # lint-amnesty, pylint: disab
|
||||
|
||||
# Fetch the view and verify the query counts
|
||||
# TODO: decrease query count as part of REVO-28
|
||||
with self.assertNumQueries(79, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST):
|
||||
with self.assertNumQueries(72, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST):
|
||||
with check_mongo_calls(4):
|
||||
url = course_home_url(self.course)
|
||||
self.client.get(url)
|
||||
@@ -389,50 +384,6 @@ class TestCourseHomePageAccess(CourseHomePageTestCase):
|
||||
)
|
||||
self.assertRedirects(response, expected_url)
|
||||
|
||||
@mock.patch('openedx.features.discounts.utils.discount_percentage')
|
||||
@mock.patch('openedx.features.discounts.utils.can_receive_discount')
|
||||
@ddt.data(
|
||||
[True, 15],
|
||||
[True, 13],
|
||||
[True, 0],
|
||||
[False, 15])
|
||||
@ddt.unpack
|
||||
def test_first_purchase_offer_banner_display(self,
|
||||
applicability,
|
||||
percentage,
|
||||
can_receive_discount_mock,
|
||||
discount_percentage_mock):
|
||||
"""
|
||||
Ensure first purchase offer banner displays correctly
|
||||
"""
|
||||
can_receive_discount_mock.return_value = applicability
|
||||
discount_percentage_mock.return_value = percentage
|
||||
user = self.create_user_for_course(self.course, CourseUserType.ENROLLED)
|
||||
now_time = datetime.now(tz=UTC).strftime("%Y-%m-%d %H:%M:%S%z")
|
||||
ExperimentData.objects.create(
|
||||
user=user, experiment_id=REV1008_EXPERIMENT_ID, key=str(self.course.id), value=now_time
|
||||
)
|
||||
self.client.login(username=user.username, password=self.TEST_PASSWORD)
|
||||
url = course_home_url(self.course)
|
||||
response = self.client.get(url)
|
||||
expiration_date = strftime_localized_html(get_discount_expiration_date(user, self.course), 'SHORT_DATE')
|
||||
upgrade_link = verified_upgrade_deadline_link(user=user, course=self.course)
|
||||
bannerText = '''<div class="first-purchase-offer-banner" role="note">
|
||||
<span class="first-purchase-offer-banner-bold"><b>
|
||||
Upgrade by {discount_expiration_date} and save {percentage}% [{strikeout_price}]</b></span>
|
||||
<br>Use code <b>EDXWELCOME</b> at checkout! <a id="welcome" href="{upgrade_link}">Upgrade Now</a>
|
||||
</div>'''.format(
|
||||
discount_expiration_date=expiration_date,
|
||||
percentage=percentage,
|
||||
strikeout_price=HTML(format_strikeout_price(user, self.course)[0]),
|
||||
upgrade_link=upgrade_link
|
||||
)
|
||||
|
||||
if applicability:
|
||||
self.assertContains(response, bannerText, html=True)
|
||||
else:
|
||||
self.assertNotContains(response, bannerText, html=True)
|
||||
|
||||
@mock.patch.dict(settings.FEATURES, {'DISABLE_START_DATES': False})
|
||||
def test_course_does_not_expire_for_verified_user(self):
|
||||
"""
|
||||
|
||||
@@ -43,7 +43,6 @@ from openedx.features.course_experience.views.course_outline import CourseOutlin
|
||||
from openedx.features.course_experience.views.course_sock import CourseSockFragmentView
|
||||
from openedx.features.course_experience.views.latest_update import LatestUpdateFragmentView
|
||||
from openedx.features.course_experience.views.welcome_message import WelcomeMessageFragmentView
|
||||
from openedx.features.discounts.utils import get_first_purchase_offer_banner_fragment
|
||||
from openedx.features.discounts.utils import format_strikeout_price
|
||||
from common.djangoapps.student.models import CourseEnrollment
|
||||
from common.djangoapps.util.views import ensure_valid_course_key
|
||||
@@ -137,7 +136,6 @@ class CourseHomeFragmentView(EdxFragmentView):
|
||||
outline_fragment = None
|
||||
update_message_fragment = None
|
||||
course_sock_fragment = None
|
||||
offer_banner_fragment = None
|
||||
course_expiration_fragment = None
|
||||
has_visited_course = None
|
||||
resume_course_url = None
|
||||
@@ -161,10 +159,6 @@ class CourseHomeFragmentView(EdxFragmentView):
|
||||
)
|
||||
has_visited_course, resume_course_url = self._get_resume_course_info(request, course_id)
|
||||
handouts_html = self._get_course_handouts(request, course)
|
||||
offer_banner_fragment = get_first_purchase_offer_banner_fragment(
|
||||
request.user,
|
||||
course_overview
|
||||
)
|
||||
course_expiration_fragment = generate_course_expired_fragment(
|
||||
request.user,
|
||||
course_overview
|
||||
@@ -227,7 +221,6 @@ class CourseHomeFragmentView(EdxFragmentView):
|
||||
'outline_fragment': outline_fragment,
|
||||
'handouts_html': handouts_html,
|
||||
'course_home_message_fragment': course_home_message_fragment,
|
||||
'offer_banner_fragment': offer_banner_fragment,
|
||||
'course_expiration_fragment': course_expiration_fragment,
|
||||
'has_visited_course': has_visited_course,
|
||||
'resume_course_url': resume_course_url,
|
||||
|
||||
@@ -7,15 +7,11 @@ from datetime import datetime
|
||||
import pytz
|
||||
from django.utils.translation import get_language
|
||||
from django.utils.translation import ugettext as _
|
||||
from edx_django_utils.cache import RequestCache
|
||||
from web_fragments.fragment import Fragment
|
||||
|
||||
from common.djangoapps.course_modes.models import format_course_price, get_course_prices
|
||||
from common.djangoapps.util.date_utils import strftime_localized_html
|
||||
from lms.djangoapps.experiments.models import ExperimentData
|
||||
from lms.djangoapps.courseware.utils import verified_upgrade_deadline_link
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
from openedx.core.djangolib.markup import HTML
|
||||
from openedx.features.discounts.applicability import (
|
||||
REV1008_EXPERIMENT_ID,
|
||||
can_receive_discount,
|
||||
@@ -32,9 +28,7 @@ def offer_banner_wrapper(user, block, view, frag, context): # pylint: disable=W
|
||||
if block.category != 'vertical':
|
||||
return frag
|
||||
|
||||
offer_banner_fragment = get_first_purchase_offer_banner_fragment_from_key(
|
||||
user, block.course_id
|
||||
)
|
||||
offer_banner_fragment = None
|
||||
|
||||
if not offer_banner_fragment:
|
||||
return frag
|
||||
@@ -155,75 +149,3 @@ def format_strikeout_price(user, course):
|
||||
return HTML("<span class='price'>{}</span>").format(original_price), False
|
||||
else:
|
||||
return _format_discounted_price(original_price, discounted_price), True
|
||||
|
||||
|
||||
def generate_offer_html(user, course):
|
||||
"""
|
||||
Create the actual HTML object with the offer text in it.
|
||||
|
||||
Returns a openedx.core.djangolib.markup.HTML object, or None if the user
|
||||
should not be shown an offer message.
|
||||
"""
|
||||
data = generate_offer_data(user, course)
|
||||
if not data:
|
||||
return None
|
||||
|
||||
# Translator: xgettext:no-python-format
|
||||
offer_message = _('{banner_open} Upgrade by {discount_expiration_date} and save {percentage}% '
|
||||
'[{strikeout_price}]{span_close}{br}Use code {b_open}{code}{b_close} at checkout! '
|
||||
'{a_open}Upgrade Now{a_close}{div_close}')
|
||||
|
||||
message_html = HTML(offer_message).format(
|
||||
a_open=HTML('<a id="welcome" href="{upgrade_link}">').format(upgrade_link=data['upgrade_url']),
|
||||
a_close=HTML('</a>'),
|
||||
b_open=HTML('<b>'),
|
||||
code=Text(data['code']),
|
||||
b_close=HTML('</b>'),
|
||||
br=HTML('<br>'),
|
||||
banner_open=HTML(
|
||||
'<div class="first-purchase-offer-banner" role="note">'
|
||||
'<span class="first-purchase-offer-banner-bold"><b>'
|
||||
),
|
||||
discount_expiration_date=strftime_localized_html(data['expiration_date'], 'SHORT_DATE'),
|
||||
percentage=data['percentage'],
|
||||
span_close=HTML('</b></span>'),
|
||||
div_close=HTML('</div>'),
|
||||
strikeout_price=_format_discounted_price(data['original_price'], data['discounted_price']),
|
||||
)
|
||||
return message_html
|
||||
|
||||
|
||||
def get_first_purchase_offer_banner_fragment(user, course):
|
||||
"""
|
||||
Return an HTML Fragment with First Purcahse Discount message,
|
||||
which has the discount_expiration_date, price,
|
||||
discount percentage and a link to upgrade.
|
||||
"""
|
||||
offer_html = generate_offer_html(user, course)
|
||||
if offer_html is None:
|
||||
return None
|
||||
return Fragment(offer_html)
|
||||
|
||||
|
||||
def get_first_purchase_offer_banner_fragment_from_key(user, course_key):
|
||||
"""
|
||||
Like `get_first_purchase_offer_banner_fragment`, but using a CourseKey
|
||||
instead of a CourseOverview and using request-level caching.
|
||||
|
||||
Either returns WebFragment to inject XBlock content into, or None if we
|
||||
shouldn't show a first purchase offer message for this user.
|
||||
"""
|
||||
request_cache = RequestCache('get_first_purchase_offer_banner_fragment_from_key')
|
||||
cache_key = f'html:{user.id},{course_key}'
|
||||
cache_response = request_cache.get_cached_response(cache_key)
|
||||
if cache_response.is_found:
|
||||
cached_html = cache_response.value
|
||||
if cached_html is None:
|
||||
return None
|
||||
return Fragment(cached_html)
|
||||
|
||||
course = CourseOverview.get_from_id(course_key)
|
||||
offer_html = generate_offer_html(user, course)
|
||||
request_cache.set(cache_key, offer_html)
|
||||
|
||||
return Fragment(offer_html)
|
||||
|
||||
Reference in New Issue
Block a user