Merge pull request #14787 from edx/asadiqbal08/ENT-287
asadiqbal08/ENT-287 -- Enterprise messaging only for catalog courses on track selection page
This commit is contained in:
@@ -1263,3 +1263,7 @@ USER_TASKS_MAX_AGE = timedelta(days=7)
|
||||
############## Settings for the Enterprise App ######################
|
||||
|
||||
ENTERPRISE_ENROLLMENT_API_URL = LMS_ROOT_URL + "/api/enrollment/v1/"
|
||||
|
||||
############## Settings for the Discovery App ######################
|
||||
|
||||
COURSE_CATALOG_API_URL = None
|
||||
|
||||
@@ -27,13 +27,14 @@ from student.tests.factories import CourseEnrollmentFactory, UserFactory
|
||||
from util.testing import UrlResetMixin
|
||||
from openedx.core.djangoapps.theming.tests.test_util import with_comprehensive_theme
|
||||
from util.tests.mixins.enterprise import EnterpriseServiceMockMixin
|
||||
from util.tests.mixins.discovery import CourseCatalogServiceMockMixin
|
||||
from util import organizations_helpers as organizations_api
|
||||
|
||||
|
||||
@attr(shard=3)
|
||||
@ddt.ddt
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase, EnterpriseServiceMockMixin):
|
||||
class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase, EnterpriseServiceMockMixin, CourseCatalogServiceMockMixin):
|
||||
"""
|
||||
Course Mode View tests
|
||||
"""
|
||||
@@ -156,6 +157,10 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase, EnterpriseServiceMo
|
||||
|
||||
self.mock_enterprise_learner_api()
|
||||
|
||||
self.mock_course_discovery_api_for_catalog_contains(
|
||||
catalog_id=1, course_run_ids=[str(self.course.id)]
|
||||
)
|
||||
|
||||
# User visits the track selection page directly without ever enrolling
|
||||
url = reverse('course_modes_choose', args=[unicode(self.course.id)])
|
||||
response = self.client.get(url)
|
||||
@@ -181,6 +186,9 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase, EnterpriseServiceMo
|
||||
CourseModeFactory.create(mode_slug=mode, course_id=self.course.id)
|
||||
|
||||
self.mock_enterprise_learner_api()
|
||||
self.mock_course_discovery_api_for_catalog_contains(
|
||||
catalog_id=1, course_run_ids=[str(self.course.id)]
|
||||
)
|
||||
|
||||
# Creating organization
|
||||
for i in xrange(2):
|
||||
|
||||
@@ -20,6 +20,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
from lms.djangoapps.commerce.utils import EcommerceService
|
||||
from openedx.core.djangoapps.api_admin.utils import course_discovery_api_client
|
||||
from course_modes.models import CourseMode
|
||||
from courseware.access import has_access
|
||||
from edxmako.shortcuts import render_to_response
|
||||
@@ -132,11 +133,11 @@ class ChooseModeView(View):
|
||||
CourseMode.is_credit_mode(mode) for mode
|
||||
in CourseMode.modes_for_course(course_key, only_selectable=False)
|
||||
)
|
||||
|
||||
course_id = course_key.to_deprecated_string()
|
||||
context = {
|
||||
"course_modes_choose_url": reverse(
|
||||
"course_modes_choose",
|
||||
kwargs={'course_id': course_key.to_deprecated_string()}
|
||||
kwargs={'course_id': course_id}
|
||||
),
|
||||
"modes": modes,
|
||||
"has_credit_upsell": has_credit_upsell,
|
||||
@@ -149,18 +150,35 @@ class ChooseModeView(View):
|
||||
"nav_hidden": True,
|
||||
}
|
||||
|
||||
title_content = _("Congratulations! You are now enrolled in {course_name}").format(
|
||||
course_name=course.display_name_with_default_escaped
|
||||
)
|
||||
enterprise_learner_data = enterprise_api.get_enterprise_learner_data(site=request.site, user=request.user)
|
||||
if enterprise_learner_data:
|
||||
context["show_enterprise_context"] = True
|
||||
context["partner_names"] = partner_name = course.display_organization \
|
||||
if course.display_organization else course.org
|
||||
context["enterprise_name"] = enterprise_learner_data[0]['enterprise_customer']['name']
|
||||
context["username"] = request.user.username
|
||||
organizations = organization_api.get_course_organizations(course_id=course.id)
|
||||
if organizations:
|
||||
context["partner_names"] = ' and '.join([
|
||||
org.get('name', partner_name) for org in organizations
|
||||
])
|
||||
is_course_in_enterprise_catalog = enterprise_api.is_course_in_enterprise_catalog(
|
||||
site=request.site,
|
||||
course_id=course_id,
|
||||
user=request.user,
|
||||
enterprise_catalog_id=enterprise_learner_data[0]['enterprise_customer']['catalog']
|
||||
)
|
||||
|
||||
if is_course_in_enterprise_catalog:
|
||||
partner_names = partner_name = course.display_organization \
|
||||
if course.display_organization else course.org
|
||||
enterprise_name = enterprise_learner_data[0]['enterprise_customer']['name']
|
||||
organizations = organization_api.get_course_organizations(course_id=course.id)
|
||||
if organizations:
|
||||
partner_names = ' and '.join([org.get('name', partner_name) for org in organizations])
|
||||
|
||||
title_content = _("Welcome, {username}! You are about to enroll in {course_name},"
|
||||
" from {partner_names}, sponsored by {enterprise_name}. Please select your enrollment"
|
||||
" information below.").format(
|
||||
username=request.user.username,
|
||||
course_name=course.display_name_with_default_escaped,
|
||||
partner_names=partner_names,
|
||||
enterprise_name=enterprise_name
|
||||
)
|
||||
context["title_content"] = title_content
|
||||
|
||||
if "verified" in modes:
|
||||
verified_mode = modes["verified"]
|
||||
|
||||
@@ -20,6 +20,10 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
from slumber.exceptions import SlumberBaseException
|
||||
from requests.exceptions import ConnectionError, Timeout
|
||||
from openedx.core.djangoapps.api_admin.utils import course_discovery_api_client
|
||||
|
||||
from openedx.core.lib.token_utils import JwtBuilder
|
||||
from slumber.exceptions import HttpClientError, HttpServerError
|
||||
import hashlib
|
||||
@@ -442,3 +446,41 @@ def get_dashboard_consent_notification(request, user, course_enrollments):
|
||||
}
|
||||
)
|
||||
return ''
|
||||
|
||||
|
||||
def is_course_in_enterprise_catalog(site, course_id, user, enterprise_catalog_id):
|
||||
"""
|
||||
Verify that the provided course id exists in the site base list of course
|
||||
run keys from the provided enterprise course catalog.
|
||||
|
||||
Arguments:
|
||||
course_id (str): The course ID.
|
||||
site: (django.contrib.sites.Site) site instance
|
||||
enterprise_catalog_id (Int): Course catalog id of enterprise
|
||||
|
||||
Returns:
|
||||
Boolean
|
||||
|
||||
"""
|
||||
cache_key = get_cache_key(
|
||||
site_domain=site.domain,
|
||||
resource='catalogs.contains',
|
||||
course_id=course_id,
|
||||
catalog_id=enterprise_catalog_id
|
||||
)
|
||||
response = cache.get(cache_key)
|
||||
if not response:
|
||||
try:
|
||||
# GET: /api/v1/catalogs/{catalog_id}/contains?course_run_id={course_run_ids}
|
||||
response = course_discovery_api_client(user=user).catalogs(enterprise_catalog_id).contains.get(
|
||||
course_run_id=course_id
|
||||
)
|
||||
cache.set(cache_key, response, settings.COURSES_API_CACHE_TIMEOUT)
|
||||
except (ConnectionError, SlumberBaseException, Timeout):
|
||||
LOGGER.exception('Unable to connect to Course Catalog service for catalog contains endpoint.')
|
||||
return False
|
||||
|
||||
try:
|
||||
return response['courses'][course_id]
|
||||
except KeyError:
|
||||
return False
|
||||
|
||||
43
common/djangoapps/util/tests/mixins/discovery.py
Normal file
43
common/djangoapps/util/tests/mixins/discovery.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
Mixins for the CourseDiscoveryApiClient.
|
||||
"""
|
||||
import json
|
||||
|
||||
import httpretty
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
|
||||
|
||||
class CourseCatalogServiceMockMixin(object):
|
||||
"""
|
||||
Mocks for the Open edX service 'Course Catalog Service' responses.
|
||||
"""
|
||||
COURSE_DISCOVERY_CATALOGS_URL = '{}/catalogs/'.format(
|
||||
settings.COURSE_CATALOG_API_URL,
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super(CourseCatalogServiceMockMixin, self).setUp()
|
||||
cache.clear()
|
||||
|
||||
def mock_course_discovery_api_for_catalog_contains(self, catalog_id=1, course_run_ids=None):
|
||||
"""
|
||||
Helper function to register course catalog contains API endpoint.
|
||||
"""
|
||||
course_run_ids = course_run_ids or []
|
||||
courses = {course_run_id: True for course_run_id in course_run_ids}
|
||||
|
||||
course_discovery_api_response = {
|
||||
'courses': courses
|
||||
}
|
||||
course_discovery_api_response_json = json.dumps(course_discovery_api_response)
|
||||
catalog_contains_uri = '{}{}/contains/?course_run_id={}'.format(
|
||||
self.COURSE_DISCOVERY_CATALOGS_URL, catalog_id, ','.join(course_run_ids)
|
||||
)
|
||||
|
||||
httpretty.register_uri(
|
||||
method=httpretty.GET,
|
||||
uri=catalog_contains_uri,
|
||||
body=course_discovery_api_response_json,
|
||||
content_type='application/json'
|
||||
)
|
||||
@@ -916,3 +916,7 @@ ENTERPRISE_ENROLLMENT_API_URL = ENV_TOKENS.get(
|
||||
'ENTERPRISE_ENROLLMENT_API_URL',
|
||||
ENTERPRISE_ENROLLMENT_API_URL
|
||||
)
|
||||
|
||||
|
||||
# Discovery App config
|
||||
COURSES_API_CACHE_TIMEOUT = ENV_TOKENS.get('COURSES_API_CACHE_TIMEOUT', COURSES_API_CACHE_TIMEOUT)
|
||||
|
||||
@@ -3081,3 +3081,7 @@ COURSE_ENROLLMENT_MODES = {
|
||||
"credit": 5,
|
||||
"honor": 6,
|
||||
}
|
||||
|
||||
############## Settings for the Discovery App ######################
|
||||
|
||||
COURSES_API_CACHE_TIMEOUT = 3600 # Value is in seconds
|
||||
|
||||
@@ -73,13 +73,7 @@ from openedx.core.djangolib.markup import HTML, Text
|
||||
<article class="register-choose content-main">
|
||||
<header class="page-header content-main">
|
||||
<h3 class="title">
|
||||
% if show_enterprise_context:
|
||||
${_("Welcome, {username}! You are about to enroll in {course_name}, from "
|
||||
"{partner_names}, sponsored by {enterprise_name}. Please select your enrollment"
|
||||
" information below.").format(username=username, course_name=course_name, partner_names=partner_names, enterprise_name=enterprise_name)}
|
||||
% else:
|
||||
${_("Congratulations! You are now enrolled in {course_name}").format(course_name=course_name)}
|
||||
% endif
|
||||
${title_content}
|
||||
</h3>
|
||||
</header>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user