Skip to content
Snippets Groups Projects
Unverified Commit eb32aa97 authored by Jeff LaJoie's avatar Jeff LaJoie Committed by GitHub
Browse files

Merge pull request #24361 from edx/jlajoie/ENT-2893

ENT-2893: Updates header branding and href for Enterprise learners
parents 0741c383 bf11b68f
No related branches found
No related tags found
No related merge requests found
......@@ -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'.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment