ENT-2893: Updates header branding and href for Enterprise learners
This commit is contained in:
@@ -360,6 +360,8 @@ MKTG_URLS = {
|
||||
'WHAT_IS_VERIFIED_CERT': '/verified-certificate',
|
||||
}
|
||||
|
||||
ENTERPRISE_LEARNER_PORTAL_BASE_URL = 'http://localhost:8734'
|
||||
|
||||
ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS = {}
|
||||
|
||||
CREDENTIALS_SERVICE_USERNAME = 'credentials_worker'
|
||||
|
||||
@@ -8,17 +8,30 @@ from django.urls import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
from lms.djangoapps.ccx.overrides import get_current_ccx
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
from openedx.features.enterprise_support.api import get_enterprise_learner_data
|
||||
from openedx.features.enterprise_support.utils import get_enterprise_learner_generic_name, get_enterprise_learner_portals
|
||||
|
||||
# App that handles subdomain specific branding
|
||||
from branding import api as branding_api
|
||||
%>
|
||||
|
||||
<%
|
||||
enterprise_customer_links = get_enterprise_learner_portals(request)
|
||||
enterprise_customer_link = enterprise_customer_links[0] if enterprise_customer_links else None # Only want to show the first link
|
||||
%>
|
||||
|
||||
<h1 class="header-logo">
|
||||
<a href="${branding_api.get_home_url()}">
|
||||
<%block name="navigation_logo">
|
||||
<img class="logo" src="${branding_api.get_logo_url(is_secure)}" alt="${_("{platform_name} Home Page").format(platform_name=static.get_platform_name())}"/>
|
||||
</%block>
|
||||
</a>
|
||||
% if enterprise_customer_link:
|
||||
<a href="${settings.ENTERPRISE_LEARNER_PORTAL_BASE_URL}/${enterprise_customer_link.get('slug')}">
|
||||
<img class="logo" src="${enterprise_customer_link.get('logo')}" alt="${_('{name} Dashboard').format(name=enterprise_customer_link.get('name'))}"/>
|
||||
</a>
|
||||
% else:
|
||||
<a href="${branding_api.get_home_url()}">
|
||||
<%block name="navigation_logo">
|
||||
<img class="logo" src="${branding_api.get_logo_url(is_secure)}" alt="${_("{platform_name} Home Page").format(platform_name=static.get_platform_name())}"/>
|
||||
</%block>
|
||||
</a>
|
||||
% endif
|
||||
% if course:
|
||||
<div class="course-header">
|
||||
<span class="provider">${course.display_org_with_default}:</span>
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
|
||||
<%!
|
||||
import json
|
||||
|
||||
from django.conf import settings
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
@@ -10,7 +12,7 @@ from django.utils.translation import ugettext as _
|
||||
from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_image_urls_for_user
|
||||
from openedx.core.djangoapps.user_api.accounts.toggles import should_redirect_to_order_history_microfrontend
|
||||
from openedx.core.djangoapps.user_api.accounts.utils import retrieve_last_sitewide_block_completed
|
||||
from openedx.features.enterprise_support.utils import get_enterprise_learner_generic_name
|
||||
from openedx.features.enterprise_support.utils import get_enterprise_learner_generic_name, get_enterprise_learner_portals
|
||||
%>
|
||||
|
||||
<%
|
||||
@@ -20,6 +22,7 @@ profile_image_url = get_profile_image_urls_for_user(self.real_user)['medium']
|
||||
username = self.real_user.username
|
||||
resume_block = retrieve_last_sitewide_block_completed(self.real_user)
|
||||
displayname = get_enterprise_learner_generic_name(request) or username
|
||||
enterprise_customer_portals = get_enterprise_learner_portals(request)
|
||||
%>
|
||||
|
||||
<div class="nav-item hidden-mobile">
|
||||
@@ -37,7 +40,14 @@ displayname = get_enterprise_learner_generic_name(request) or username
|
||||
% if resume_block:
|
||||
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${resume_block}" role="menuitem">${_("Resume your last course")}</a></div>
|
||||
% endif
|
||||
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${reverse('dashboard')}" role="menuitem">${_("Dashboard")}</a></div>
|
||||
% if not enterprise_customer_portals:
|
||||
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${reverse('dashboard')}" role="menuitem">${_("Dashboard")}</a></div>
|
||||
% else:
|
||||
% for portal in enterprise_customer_portals:
|
||||
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${settings.ENTERPRISE_LEARNER_PORTAL_BASE_URL}/${portal.get('slug')}" role="menuitem">${_("{name} Dashboard").format(name=portal.get('name'))}</a></div>
|
||||
% endfor
|
||||
% endif
|
||||
|
||||
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${reverse('learner_profile', kwargs={'username': username})}" role="menuitem">${_("Profile")}</a></div>
|
||||
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${reverse('account_settings')}" role="menuitem">${_("Account")}</a></div>
|
||||
% if should_redirect_to_order_history_microfrontend():
|
||||
|
||||
@@ -8,7 +8,9 @@ from uuid import UUID
|
||||
import factory
|
||||
from faker import Factory as FakerFactory
|
||||
|
||||
from enterprise.models import EnterpriseCourseEnrollment, EnterpriseCustomer, EnterpriseCustomerUser
|
||||
from enterprise.models import (
|
||||
EnterpriseCourseEnrollment, EnterpriseCustomer, EnterpriseCustomerBrandingConfiguration, EnterpriseCustomerUser,
|
||||
)
|
||||
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
|
||||
|
||||
FAKER = FakerFactory.create()
|
||||
@@ -73,3 +75,22 @@ class EnterpriseCourseEnrollmentFactory(factory.django.DjangoModelFactory):
|
||||
|
||||
course_id = factory.LazyAttribute(lambda x: FAKER.slug()) # pylint: disable=no-member
|
||||
enterprise_customer_user = factory.SubFactory(EnterpriseCustomerUserFactory)
|
||||
|
||||
|
||||
class EnterpriseCustomerBrandingConfigurationFactory(factory.django.DjangoModelFactory):
|
||||
"""
|
||||
EnterpriseCustomerBrandingConfiguration factory
|
||||
|
||||
Creates an instance of EnterpriseCustomerBrandingConfiguration with minimal boilerplate.
|
||||
"""
|
||||
|
||||
class Meta(object):
|
||||
"""
|
||||
Meta for EnterpriseCustomerBrandingConfigurationFactory.
|
||||
"""
|
||||
|
||||
model = EnterpriseCustomerBrandingConfiguration
|
||||
|
||||
logo = FAKER.image_url()
|
||||
banner_background_color = FAKER.color()
|
||||
banner_border_color = FAKER.color()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Test the enterprise support utils.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
import mock
|
||||
import ddt
|
||||
|
||||
@@ -11,7 +11,11 @@ from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
|
||||
from openedx.core.djangolib.testing.utils import skip_unless_lms
|
||||
from openedx.features.enterprise_support.utils import get_enterprise_learner_portals
|
||||
from openedx.features.enterprise_support.tests import FEATURES_WITH_ENTERPRISE_ENABLED
|
||||
from openedx.features.enterprise_support.tests.factories import (
|
||||
EnterpriseCustomerBrandingConfigurationFactory, EnterpriseCustomerUserFactory,
|
||||
)
|
||||
from student.tests.factories import UserFactory
|
||||
|
||||
|
||||
@@ -43,3 +47,36 @@ class TestEnterpriseUtils(TestCase):
|
||||
) as mock_customer_request:
|
||||
self.client.get(resource)
|
||||
self.assertEqual(mock_customer_request.call_count, expected_calls)
|
||||
|
||||
def test_get_enterprise_learner_portals_uncached(self):
|
||||
"""
|
||||
Test that only enabled enterprise portals are returned
|
||||
"""
|
||||
enterprise_customer_user = EnterpriseCustomerUserFactory(active=True, user_id=self.user.id)
|
||||
EnterpriseCustomerBrandingConfigurationFactory(
|
||||
enterprise_customer=enterprise_customer_user.enterprise_customer,
|
||||
)
|
||||
enterprise_customer_user.enterprise_customer.enable_learner_portal = True
|
||||
enterprise_customer_user.enterprise_customer.save()
|
||||
|
||||
request = mock.MagicMock(session={}, user=self.user)
|
||||
portals = get_enterprise_learner_portals(request)
|
||||
self.assertEqual(len(portals), 1)
|
||||
self.assertDictEqual(portals[0], {
|
||||
'name': enterprise_customer_user.enterprise_customer.name,
|
||||
'slug': enterprise_customer_user.enterprise_customer.slug,
|
||||
'logo': enterprise_customer_user.enterprise_customer.branding_configuration.logo.url,
|
||||
})
|
||||
|
||||
def test_get_enterprise_learner_portals_cached(self):
|
||||
enterprise_customer_data = {
|
||||
'name': 'Enabled Customer',
|
||||
'slug': 'enabled_customer',
|
||||
'logo': 'https://logo.url',
|
||||
}
|
||||
request = mock.MagicMock(session={
|
||||
'enterprise_learner_portals': json.dumps([enterprise_customer_data])
|
||||
}, user=self.user)
|
||||
portals = get_enterprise_learner_portals(request)
|
||||
self.assertEqual(len(portals), 1)
|
||||
self.assertDictEqual(portals[0], enterprise_customer_data)
|
||||
|
||||
@@ -283,6 +283,41 @@ def _get_sync_learner_profile_data(enterprise_customer):
|
||||
return False
|
||||
|
||||
|
||||
def get_enterprise_learner_portals(request):
|
||||
"""
|
||||
Gets the formatted portal names and slugs that can be used
|
||||
to generate links for enabled enterprise Learner Portals.
|
||||
|
||||
Caches and returns results in/from the user's request session if provided.
|
||||
"""
|
||||
# Prevent a circular import.
|
||||
from openedx.features.enterprise_support.api import enterprise_enabled
|
||||
|
||||
if enterprise_enabled():
|
||||
# If the key exists return that value
|
||||
if 'enterprise_learner_portals' in request.session:
|
||||
return json.loads(request.session['enterprise_learner_portals'])
|
||||
|
||||
user = request.user
|
||||
# Ordering is important, this is consistent with how we decide on which
|
||||
# enterprise_customer is the selected one for an enterprise_customer
|
||||
enterprise_learner_portals = [{
|
||||
'name': enterprise_customer_user.enterprise_customer.name,
|
||||
'slug': enterprise_customer_user.enterprise_customer.slug,
|
||||
'logo': enterprise_customer_user.enterprise_customer.branding_configuration.logo.url,
|
||||
} for enterprise_customer_user in EnterpriseCustomerUser.objects.filter(
|
||||
user_id=user.id, enterprise_customer__enable_learner_portal=True
|
||||
).prefetch_related(
|
||||
'enterprise_customer', 'enterprise_customer__branding_configuration'
|
||||
).order_by('-enterprise_customer__active', '-modified')]
|
||||
|
||||
# Cache the result in the user's request session
|
||||
request.session['enterprise_learner_portals'] = json.dumps(enterprise_learner_portals)
|
||||
|
||||
return enterprise_learner_portals
|
||||
return None
|
||||
|
||||
|
||||
def get_enterprise_learner_generic_name(request):
|
||||
"""
|
||||
Get a generic name concatenating the Enterprise Customer name and 'Learner'.
|
||||
|
||||
Reference in New Issue
Block a user