Redirect to the courseware MFE when the ‘courseware’ view is loaded
This commit is contained in:
@@ -4,6 +4,7 @@ Tests courseware views.py
|
||||
"""
|
||||
|
||||
|
||||
import logging
|
||||
import itertools
|
||||
import json
|
||||
import unittest
|
||||
@@ -36,6 +37,7 @@ from xblock.core import XBlock
|
||||
from xblock.fields import Scope, String
|
||||
|
||||
import lms.djangoapps.courseware.views.views as views
|
||||
from lms.djangoapps.courseware.toggles import REDIRECT_TO_COURSEWARE_MICROFRONTEND
|
||||
import shoppingcart
|
||||
|
||||
from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory
|
||||
@@ -68,6 +70,7 @@ from openedx.core.djangoapps.content.course_overviews.models import CourseOvervi
|
||||
from openedx.core.djangoapps.crawlers.models import CrawlersConfig
|
||||
from openedx.core.djangoapps.credit.api import set_credit_requirements
|
||||
from openedx.core.djangoapps.credit.models import CreditCourse, CreditProvider
|
||||
from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin
|
||||
from openedx.core.djangoapps.waffle_utils.testutils import WAFFLE_TABLES, override_waffle_flag
|
||||
from openedx.core.djangolib.testing.utils import get_mock_request
|
||||
from openedx.core.lib.gating import api as gating_api
|
||||
@@ -103,9 +106,10 @@ QUERY_COUNT_TABLE_BLACKLIST = WAFFLE_TABLES
|
||||
FEATURES_WITH_DISABLE_HONOR_CERTIFICATE = settings.FEATURES.copy()
|
||||
FEATURES_WITH_DISABLE_HONOR_CERTIFICATE['DISABLE_HONOR_CERTIFICATES'] = True
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ddt.ddt
|
||||
class TestJumpTo(ModuleStoreTestCase):
|
||||
class TestJumpTo(ModuleStoreTestCase, SiteMixin):
|
||||
"""
|
||||
Check the jumpto link for a course.
|
||||
"""
|
||||
@@ -250,6 +254,51 @@ class TestJumpTo(ModuleStoreTestCase):
|
||||
|
||||
self.assertEqual(expected_url, get_redirect_url(course_key, usage_key, request))
|
||||
|
||||
def test_jump_to_with_microfrontend_enabled(self):
|
||||
course = CourseFactory.create()
|
||||
chapter = ItemFactory.create(category='chapter', parent_location=course.location)
|
||||
section = ItemFactory.create(category='sequential', parent_location=chapter.location)
|
||||
unit = ItemFactory.create(category='vertical', parent_location=section.location)
|
||||
course_key = CourseKey.from_string(six.text_type(course.id))
|
||||
|
||||
# unit position is hard coded here for simplicity - is there a simple way to get it from here?
|
||||
expected = '/courses/{course_id}/courseware/{chapter_id}/{section_id}/1?{activate_block_id}'.format(
|
||||
course_id=six.text_type(course.id),
|
||||
chapter_id=chapter.url_name,
|
||||
section_id=section.url_name,
|
||||
activate_block_id=urlencode({'activate_block_id': six.text_type(unit.location)})
|
||||
)
|
||||
jumpto_url = '{0}/{1}/jump_to/{2}'.format(
|
||||
'/courses',
|
||||
six.text_type(course.id),
|
||||
six.text_type(unit.location),
|
||||
)
|
||||
|
||||
microfrontend_expected = 'http://learning-mfe/course/{course_key}/{section_id}/{unit_id}'.format(
|
||||
course_key=course_key,
|
||||
section_id=section.location,
|
||||
unit_id=unit.location
|
||||
)
|
||||
"""
|
||||
http://learning-mfe/course/org.0/course_0/Run_0/i4x://org.0/course_0/sequential/sequential_2/i4x://org.0/course_0/vertical/vertical_3',
|
||||
http://learning-mfe/course/org.0/course_0/Run_0/i4x://org.0/course_0/sequential/sequential_2/vertical_3
|
||||
"""
|
||||
|
||||
with override_waffle_flag(REDIRECT_TO_COURSEWARE_MICROFRONTEND, active=True):
|
||||
response = self.client.get(jumpto_url)
|
||||
self.assertRedirects(response, expected, status_code=302, target_status_code=302)
|
||||
|
||||
# Test with waffle flag active and site setting enabled, redirects to microfrontend
|
||||
site_domain = 'othersite.example.com'
|
||||
self.set_up_site(site_domain, {
|
||||
'SITE_NAME': site_domain,
|
||||
'ENABLE_COURSEWARE_MICROFRONTEND': True
|
||||
})
|
||||
|
||||
response = self.client.get(jumpto_url)
|
||||
LOGGER.error(response.url) # None/course/org.0/course_0/Run_0/i4x://org.0/course_0/sequential/sequential_2
|
||||
self.assertRedirects(response, microfrontend_expected, fetch_redirect_response=False, status_code=302, target_status_code=302)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class IndexQueryTestCase(ModuleStoreTestCase):
|
||||
|
||||
@@ -18,7 +18,7 @@ WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(name='courseware')
|
||||
# .. toggle_creation_date: 2020-01-29
|
||||
# .. toggle_expiration_date: 2020-12-31
|
||||
# .. toggle_warnings: Also set settings.LEARNING_MICROFRONTEND_URL and ENABLE_COURSEWARE_MICROFRONTEND.
|
||||
# .. toggle_tickets:
|
||||
# .. toggle_tickets: TNL-6982
|
||||
# .. toggle_status: supported
|
||||
REDIRECT_TO_COURSEWARE_MICROFRONTEND = CourseWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'redirect_to_microfrontend')
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.search import navigation_index, path_to_location
|
||||
from lms.djangoapps.courseware.toggles import should_redirect_to_courseware_microfrontend
|
||||
|
||||
|
||||
def get_redirect_url(course_key, usage_key, request=None):
|
||||
""" Returns the redirect url back to courseware
|
||||
|
||||
@@ -26,8 +27,8 @@ def get_redirect_url(course_key, usage_key, request=None):
|
||||
"""
|
||||
|
||||
if should_redirect_to_courseware_microfrontend(course_key):
|
||||
path = path_to_location(modulestore(), usage_key, request, full_path=True)
|
||||
return get_microfrontend_redirect_url(course_key, path)
|
||||
path = path_to_location(modulestore(), usage_key, request, full_path=True)
|
||||
return get_microfrontend_redirect_url(course_key, path)
|
||||
|
||||
(
|
||||
course_key, chapter, section, vertical_unused,
|
||||
@@ -57,8 +58,9 @@ def get_redirect_url(course_key, usage_key, request=None):
|
||||
redirect_url += "?{}".format(urlencode({'activate_block_id': six.text_type(final_target_id)}))
|
||||
return redirect_url
|
||||
|
||||
def get_microfrontend_redirect_url(course_key, path):
|
||||
"""
|
||||
|
||||
def get_microfrontend_redirect_url(course_key, path=None):
|
||||
"""
|
||||
The micro-frontend determines the user's position in the vertical via
|
||||
a separate API call, so all we need here is the course_key, section, and vertical
|
||||
IDs to format it's URL.
|
||||
@@ -68,27 +70,30 @@ def get_microfrontend_redirect_url(course_key, path):
|
||||
We're building a URL like this:
|
||||
|
||||
http://localhost:2000/course-v1:edX+DemoX+Demo_Course/block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5/block-v1:edX+DemoX+Demo_Course+type@vertical+block@4a1bba2a403f40bca5ec245e945b0d76
|
||||
"""
|
||||
"""
|
||||
|
||||
redirect_url = '{base_url}/{prefix}/{course_key}'.format(
|
||||
base_url=settings.LEARNING_MICROFRONTEND_URL,
|
||||
prefix='course/',
|
||||
course_key=course_key
|
||||
)
|
||||
|
||||
# The first four elements of the path list are the ones we care about here:
|
||||
# - course
|
||||
# - chapter
|
||||
# - sequence
|
||||
# - vertical
|
||||
# We skip course because we already have it from our argument above, and we skip chapter because the micro-frontend URL doesn't include it.
|
||||
if len(path) > 2:
|
||||
redirect_url += '/{sequence_key}'.format(
|
||||
sequence_key=path[2]
|
||||
)
|
||||
if len(path) > 3:
|
||||
redirect_url += '/{vertical_key}'.format(
|
||||
vertical_key=path[3]
|
||||
redirect_url = '{base_url}/{prefix}/{course_key}'.format(
|
||||
base_url=settings.LEARNING_MICROFRONTEND_URL,
|
||||
prefix='course',
|
||||
course_key=course_key
|
||||
)
|
||||
|
||||
return redirect_url
|
||||
if path is None:
|
||||
return redirect_url
|
||||
|
||||
# The first four elements of the path list are the ones we care about here:
|
||||
# - course
|
||||
# - chapter
|
||||
# - sequence
|
||||
# - vertical
|
||||
# We skip course because we already have it from our argument above, and we skip chapter because the micro-frontend URL doesn't include it.
|
||||
if len(path) > 2:
|
||||
redirect_url += '/{sequence_key}'.format(
|
||||
sequence_key=path[2]
|
||||
)
|
||||
if len(path) > 3:
|
||||
redirect_url += '/{vertical_key}'.format(
|
||||
vertical_key=path[3]
|
||||
)
|
||||
|
||||
return redirect_url
|
||||
|
||||
@@ -16,6 +16,7 @@ from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.views import redirect_to_login
|
||||
from django.http import Http404
|
||||
from django.shortcuts import redirect
|
||||
from django.template.context_processors import csrf
|
||||
from django.urls import reverse
|
||||
from django.utils.decorators import method_decorator
|
||||
@@ -31,6 +32,8 @@ from web_fragments.fragment import Fragment
|
||||
from edxmako.shortcuts import render_to_response, render_to_string
|
||||
from lms.djangoapps.courseware.courses import allow_public_access
|
||||
from lms.djangoapps.courseware.exceptions import CourseAccessRedirect
|
||||
from lms.djangoapps.courseware.toggles import should_redirect_to_courseware_microfrontend
|
||||
from lms.djangoapps.courseware.url_helpers import get_microfrontend_redirect_url
|
||||
from lms.djangoapps.experiments.utils import get_experiment_user_metadata_context
|
||||
from lms.djangoapps.gating.api import get_entrance_exam_score_ratio, get_entrance_exam_usage_key
|
||||
from lms.djangoapps.grades.api import CourseGradeFactory
|
||||
@@ -114,6 +117,9 @@ class CoursewareIndex(View):
|
||||
if not (request.user.is_authenticated or self.enable_unenrolled_access):
|
||||
return redirect_to_login(request.get_full_path())
|
||||
|
||||
if should_redirect_to_courseware_microfrontend(self.course_key):
|
||||
return redirect(get_microfrontend_redirect_url(self.course_key))
|
||||
|
||||
self.original_chapter_url_name = chapter
|
||||
self.original_section_url_name = section
|
||||
self.chapter_url_name = chapter
|
||||
|
||||
@@ -593,6 +593,7 @@ PDF_RECEIPT_TAX_ID_LABEL = 'Tax ID'
|
||||
PROFILE_MICROFRONTEND_URL = "http://profile-mfe/abc/"
|
||||
ORDER_HISTORY_MICROFRONTEND_URL = "http://order-history-mfe/"
|
||||
ACCOUNT_MICROFRONTEND_URL = "http://account-mfe/"
|
||||
LEARNING_MICROFRONTEND_URL = "http://learning-mfe"
|
||||
|
||||
########################## limiting dashboard courses ######################
|
||||
|
||||
|
||||
Reference in New Issue
Block a user