Merge pull request #30958 from openedx/jhynes/APER-1922_route-to-lr-mfe-from-program-dash
feat: Add configuration option to route `View Records` button to the Learner Record MFE
This commit is contained in:
@@ -4887,14 +4887,21 @@ LEARNING_MICROFRONTEND_URL = None
|
||||
# waffle flag.
|
||||
ORA_GRADING_MICROFRONTEND_URL = None
|
||||
# .. setting_name: DISCUSSIONS_MICROFRONTEND_URL
|
||||
# .. setting_description: Base URL of the micro-frontend-based discussions page.
|
||||
# .. setting_default: None
|
||||
# .. setting_description: Base URL of the micro-frontend-based discussions page.
|
||||
# .. setting_warning: Also set site's courseware.discussions_mfe waffle flag.
|
||||
DISCUSSIONS_MICROFRONTEND_URL = None
|
||||
# .. setting_name: DISCUSSIONS_MFE_FEEDBACK_URL = None
|
||||
# .. setting_name: DISCUSSIONS_MFE_FEEDBACK_URL
|
||||
# .. setting_default: None
|
||||
# .. setting_description: Base URL of the discussions micro-frontend google form based feedback.
|
||||
DISCUSSIONS_MFE_FEEDBACK_URL = None
|
||||
# .. setting_name: LEARNER_RECORD_MFE_URL
|
||||
# .. setting_default: None
|
||||
# .. setting_description: Base URL of the micro-frontend responsible for displaying Learner Record and Program record
|
||||
# pages. This MFE replaces the legacy frontend originally offered in the Credentials IDA.
|
||||
# .. setting_warning: In order to route requests to the MFE correctly you must also create and enable the credentials
|
||||
# app's `USE_LEARNER_RECORD_MFE` waffle flag. See openedx/core/djangoapps/credentials/config.py.
|
||||
LEARNER_RECORD_MICROFRONTEND_URL = None
|
||||
# .. toggle_name: ENABLE_AUTHN_RESET_PASSWORD_HIBP_POLICY
|
||||
# .. toggle_implementation: DjangoSetting
|
||||
# .. toggle_default: False
|
||||
|
||||
@@ -362,6 +362,7 @@ ACCOUNT_MICROFRONTEND_URL = 'http://localhost:1997'
|
||||
COMMUNICATIONS_MICROFRONTEND_URL = 'http://localhost:1984'
|
||||
AUTHN_MICROFRONTEND_URL = 'http://localhost:1999'
|
||||
AUTHN_MICROFRONTEND_DOMAIN = 'localhost:1999'
|
||||
LEARNER_RECORD_MICROFRONTEND_URL = 'http://localhost:1990'
|
||||
|
||||
################### FRONTEND APPLICATION DISCUSSIONS ###################
|
||||
DISCUSSIONS_MICROFRONTEND_URL = 'http://localhost:2002'
|
||||
|
||||
17
openedx/core/djangoapps/credentials/config.py
Normal file
17
openedx/core/djangoapps/credentials/config.py
Normal file
@@ -0,0 +1,17 @@
|
||||
"""
|
||||
This module contains various configuration settings via waffle switches for the Credentials app.
|
||||
"""
|
||||
|
||||
from edx_toggles.toggles import WaffleSwitch
|
||||
|
||||
# Namespace
|
||||
WAFFLE_NAMESPACE = 'credentials'
|
||||
|
||||
# .. toggle_name: credentials.use_learner_record_mfe
|
||||
# .. toggle_implementation: WaffleSwitch
|
||||
# .. toggle_default: False
|
||||
# .. toggle_description: This toggle will inform the Program Dashboard to route to the Learner Record MFE over the
|
||||
# legacy frontend of the Credentials IDA.
|
||||
# .. toggle_use_cases: open_edx
|
||||
# .. toggle_creation_date: 2022-09-07
|
||||
USE_LEARNER_RECORD_MFE = WaffleSwitch(f"{WAFFLE_NAMESPACE}.use_learner_record_mfe", __name__)
|
||||
@@ -1,14 +1,15 @@
|
||||
"""Tests covering Credentials utilities."""
|
||||
|
||||
|
||||
import uuid
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from django.test import override_settings
|
||||
from edx_toggles.toggles.testutils import override_waffle_switch
|
||||
|
||||
from openedx.core.djangoapps.credentials.config import USE_LEARNER_RECORD_MFE
|
||||
from openedx.core.djangoapps.credentials.models import CredentialsApiConfig
|
||||
from openedx.core.djangoapps.credentials.tests import factories
|
||||
from openedx.core.djangoapps.credentials.tests.mixins import CredentialsApiConfigMixin
|
||||
from openedx.core.djangoapps.credentials.utils import get_credentials
|
||||
from openedx.core.djangoapps.credentials.utils import get_credentials, get_credentials_records_url
|
||||
from openedx.core.djangoapps.oauth_dispatch.tests.factories import ApplicationFactory
|
||||
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_unless_lms
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
@@ -17,7 +18,6 @@ UTILS_MODULE = 'openedx.core.djangoapps.credentials.utils'
|
||||
|
||||
|
||||
@skip_unless_lms
|
||||
@mock.patch(UTILS_MODULE + '.get_api_data')
|
||||
class TestGetCredentials(CredentialsApiConfigMixin, CacheIsolationTestCase):
|
||||
""" Tests for credentials utility functions. """
|
||||
|
||||
@@ -31,6 +31,7 @@ class TestGetCredentials(CredentialsApiConfigMixin, CacheIsolationTestCase):
|
||||
self.credentials_config = self.create_credentials_config(cache_ttl=1)
|
||||
self.user = UserFactory()
|
||||
|
||||
@mock.patch(UTILS_MODULE + '.get_api_data')
|
||||
def test_get_many(self, mock_get_edx_api_data):
|
||||
expected = factories.UserCredential.create_batch(3)
|
||||
mock_get_edx_api_data.return_value = expected
|
||||
@@ -52,6 +53,7 @@ class TestGetCredentials(CredentialsApiConfigMixin, CacheIsolationTestCase):
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@mock.patch(UTILS_MODULE + '.get_api_data')
|
||||
def test_get_one(self, mock_get_edx_api_data):
|
||||
expected = factories.UserCredential()
|
||||
mock_get_edx_api_data.return_value = expected
|
||||
@@ -75,6 +77,7 @@ class TestGetCredentials(CredentialsApiConfigMixin, CacheIsolationTestCase):
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@mock.patch(UTILS_MODULE + '.get_api_data')
|
||||
def test_type_filter(self, mock_get_edx_api_data):
|
||||
get_credentials(self.user, credential_type='program')
|
||||
|
||||
@@ -89,3 +92,70 @@ class TestGetCredentials(CredentialsApiConfigMixin, CacheIsolationTestCase):
|
||||
'type': 'program',
|
||||
}
|
||||
assert kwargs['querystring'] == querystring
|
||||
|
||||
@override_settings(LEARNER_RECORD_MICROFRONTEND_URL=None)
|
||||
@override_settings(CREDENTIALS_PUBLIC_SERVICE_URL="http://foo")
|
||||
def test_get_credentials_records_url(self):
|
||||
"""
|
||||
A test that verifies the functionality of the `get_credentials_records_url`.
|
||||
"""
|
||||
result = get_credentials_records_url()
|
||||
assert result == "http://foo/records/"
|
||||
|
||||
result = get_credentials_records_url("abcdefgh-ijkl-mnop-qrst-uvwxyz123456")
|
||||
assert result == "http://foo/records/programs/abcdefghijklmnopqrstuvwxyz123456/"
|
||||
|
||||
@override_settings(LEARNER_RECORD_MICROFRONTEND_URL="http://blah")
|
||||
@override_settings(CREDENTIALS_PUBLIC_SERVICE_URL="http://foo")
|
||||
@override_waffle_switch(USE_LEARNER_RECORD_MFE, False)
|
||||
def test_get_credentials_records_mfe_url_waffle_disabled(self):
|
||||
"""
|
||||
A test that verifies the results of the `get_credentials_records_url` function when the
|
||||
LEARNER_RECORD_MICROFRONTEND_URL setting exists but the USE_LEARNER_RECORD_MFE waffle flag is disabled.
|
||||
"""
|
||||
result = get_credentials_records_url()
|
||||
assert result == "http://foo/records/"
|
||||
|
||||
result = get_credentials_records_url("abcdefgh-ijkl-mnop-qrst-uvwxyz123456")
|
||||
assert result == "http://foo/records/programs/abcdefghijklmnopqrstuvwxyz123456/"
|
||||
|
||||
@override_settings(LEARNER_RECORD_MICROFRONTEND_URL="http://blah")
|
||||
@override_settings(CREDENTIALS_PUBLIC_SERVICE_URL="http://foo")
|
||||
@override_waffle_switch(USE_LEARNER_RECORD_MFE, True)
|
||||
def test_get_credentials_records_mfe_url_waffle_enabled(self):
|
||||
"""
|
||||
A test that verifies the results of the `get_credentials_records_url` function when the
|
||||
LEARNER_RECORD_MICROFRONTEND_URL setting exists but the USE_LEARNER_RECORD_MFE waffle flag is enabled.
|
||||
"""
|
||||
result = get_credentials_records_url()
|
||||
assert result == "http://blah/"
|
||||
|
||||
result = get_credentials_records_url("abcdefgh-ijkl-mnop-qrst-uvwxyz123456")
|
||||
assert result == "http://blah/abcdefghijklmnopqrstuvwxyz123456/"
|
||||
|
||||
@override_settings(CREDENTIALS_PUBLIC_SERVICE_URL=None)
|
||||
@override_settings(LEARNER_RECORD_MICROFRONTEND_URL=None)
|
||||
def test_get_credentials_records_url_expect_none(self):
|
||||
"""
|
||||
A test that verifieis the results of the `get_credentials_records_url` function when the system is configured
|
||||
to use neither the Credentials IDA or the Learner Record MFE.
|
||||
"""
|
||||
result = get_credentials_records_url()
|
||||
assert result is None
|
||||
|
||||
result = get_credentials_records_url("abcdefgh-ijkl-mnop-qrst-uvwxyz123456")
|
||||
assert result is None
|
||||
|
||||
@override_settings(LEARNER_RECORD_MICROFRONTEND_URL="http://blah")
|
||||
@override_settings(CREDENTIALS_PUBLIC_SERVICE_URL=None)
|
||||
@override_waffle_switch(USE_LEARNER_RECORD_MFE, True)
|
||||
def test_get_credentials_records_url_only_mfe_configured(self):
|
||||
"""
|
||||
A test that verifieis the results of the `get_credentials_records_url` function when the system is configured
|
||||
to use only the Learner Record MFE.
|
||||
"""
|
||||
result = get_credentials_records_url()
|
||||
assert result == "http://blah/"
|
||||
|
||||
result = get_credentials_records_url("abcdefgh-ijkl-mnop-qrst-uvwxyz123456")
|
||||
assert result == "http://blah/abcdefghijklmnopqrstuvwxyz123456/"
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
import requests
|
||||
from edx_rest_api_client.auth import SuppliedJwtAuth
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from openedx.core.djangoapps.credentials.config import USE_LEARNER_RECORD_MFE
|
||||
from openedx.core.djangoapps.credentials.models import CredentialsApiConfig
|
||||
from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user
|
||||
from openedx.core.lib.edx_api_utils import get_api_data
|
||||
@@ -15,13 +18,27 @@ def get_credentials_records_url(program_uuid=None):
|
||||
Arguments:
|
||||
program_uuid (str): Optional program uuid to link for a program records URL
|
||||
"""
|
||||
base_url = CredentialsApiConfig.current().public_records_url
|
||||
if base_url is None:
|
||||
base_url = settings.CREDENTIALS_PUBLIC_SERVICE_URL
|
||||
learner_record_mfe_base_url = settings.LEARNER_RECORD_MICROFRONTEND_URL
|
||||
use_learner_record_mfe = USE_LEARNER_RECORD_MFE.is_enabled() and learner_record_mfe_base_url
|
||||
|
||||
if not base_url and not use_learner_record_mfe:
|
||||
return None
|
||||
|
||||
# If we have a program uuid we build a link to the appropriate Program Record page in Credentials (or the Learner
|
||||
# Record MFE)
|
||||
if program_uuid:
|
||||
# Credentials expects the uuid without dashes so we are converting here
|
||||
return base_url + 'programs/{}/'.format(program_uuid.replace('-', ''))
|
||||
return base_url
|
||||
# Credentials expects the UUID without dashes so we strip them here
|
||||
stripped_program_uuid = program_uuid.replace('-', '')
|
||||
if use_learner_record_mfe:
|
||||
return f"{learner_record_mfe_base_url}/{stripped_program_uuid}/"
|
||||
return f"{base_url}/records/programs/{stripped_program_uuid}/"
|
||||
else:
|
||||
# Otherwise, build a link to the appropriate Learner Record index page
|
||||
if use_learner_record_mfe:
|
||||
return f"{learner_record_mfe_base_url}/"
|
||||
else:
|
||||
return f"{base_url}/records/"
|
||||
|
||||
|
||||
def get_credentials_api_client(user):
|
||||
|
||||
Reference in New Issue
Block a user