This completes the work started in https://github.com/edx/edx-platform/pull/19453 to use the LMS login and registration for Studio, rather than Studio providing its own implementation. LMS login/registration are being used for the following reasons: 1. LMS logistration properly handles all SSO integrations. 2. A single logistration is simpler to maintain and understand. 3. Allows Studio to work more like all other IDAs that use LMS logistration. The original switch to use LMS logistration for Studio also added the toggle `DISABLE_STUDIO_SSO_OVER_LMS` to provide the community some additional time for switching. This commit removes this toggle, which at this point means all deployments will use the LMS logistration. This change requires sharing cookies across LMS and Studio. Should that prove to be a problem for certain Open edX instances, there are discussions of possible alternative solutions. See https://github.com/edx/edx-platform/pull/19845#issuecomment-559154256 Detailed changes: * Fix some Studio links that still went to old Studio signin and signup. * Remove DISABLE_STUDIO_SSO_OVER_LMS feature toggle. * Remove old studio signin and signup pages and templates. * Fix url name "login", which had different meanings for Studio and LMS. * Use the following settings: LOGIN_URL, FRONTEND_LOGIN_URL, FRONTEND_LOGOUT_URL, and FRONTEND_REGISTER_URL. * Redirect /signin and /signup to the LMS logistration. * Add custom metric `uses_pattern_library`. * Add custom metric `student_activate_account`. * Add Django Settings to allow /signin, /signup, and /login_post to be disabled once ready. This work also relates to ARCH-218 and DEPR-6. ARCH-1253
163 lines
7.1 KiB
Python
163 lines
7.1 KiB
Python
from __future__ import absolute_import
|
|
|
|
import unittest
|
|
|
|
import ddt
|
|
from django.conf import settings
|
|
from django.http import HttpResponse
|
|
from django.test import TestCase
|
|
from django.test.client import RequestFactory
|
|
from django.test.utils import override_settings
|
|
from django.urls import reverse
|
|
from edx_django_utils.cache import RequestCache
|
|
from mock import Mock, patch
|
|
|
|
from edxmako import LOOKUP, add_lookup
|
|
from edxmako.request_context import get_template_request_context
|
|
from edxmako.shortcuts import is_any_marketing_link_set, is_marketing_link_set, marketing_link, render_to_string
|
|
from student.tests.factories import UserFactory
|
|
from util.testing import UrlResetMixin
|
|
|
|
|
|
@ddt.ddt
|
|
class ShortcutsTests(UrlResetMixin, TestCase):
|
|
"""
|
|
Test the edxmako shortcuts file
|
|
"""
|
|
@override_settings(MKTG_URLS={'ROOT': 'https://dummy-root', 'ABOUT': '/about-us'})
|
|
def test_marketing_link(self):
|
|
with override_settings(MKTG_URL_LINK_MAP={'ABOUT': self._get_test_url_name()}):
|
|
# test marketing site on
|
|
with patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': True}):
|
|
expected_link = 'https://dummy-root/about-us'
|
|
link = marketing_link('ABOUT')
|
|
self.assertEquals(link, expected_link)
|
|
# test marketing site off
|
|
with patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': False}):
|
|
expected_link = reverse(self._get_test_url_name())
|
|
link = marketing_link('ABOUT')
|
|
self.assertEquals(link, expected_link)
|
|
|
|
@override_settings(MKTG_URLS={'ROOT': 'https://dummy-root', 'ABOUT': '/about-us'})
|
|
def test_is_marketing_link_set(self):
|
|
with override_settings(MKTG_URL_LINK_MAP={'ABOUT': self._get_test_url_name()}):
|
|
# test marketing site on
|
|
with patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': True}):
|
|
self.assertTrue(is_marketing_link_set('ABOUT'))
|
|
self.assertFalse(is_marketing_link_set('NOT_CONFIGURED'))
|
|
# test marketing site off
|
|
with patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': False}):
|
|
self.assertTrue(is_marketing_link_set('ABOUT'))
|
|
self.assertFalse(is_marketing_link_set('NOT_CONFIGURED'))
|
|
|
|
@override_settings(MKTG_URLS={'ROOT': 'https://dummy-root', 'ABOUT': '/about-us'})
|
|
def test_is_any_marketing_link_set(self):
|
|
with override_settings(MKTG_URL_LINK_MAP={'ABOUT': self._get_test_url_name()}):
|
|
# test marketing site on
|
|
with patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': True}):
|
|
self.assertTrue(is_any_marketing_link_set(['ABOUT']))
|
|
self.assertTrue(is_any_marketing_link_set(['ABOUT', 'NOT_CONFIGURED']))
|
|
self.assertFalse(is_any_marketing_link_set(['NOT_CONFIGURED']))
|
|
# test marketing site off
|
|
with patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': False}):
|
|
self.assertTrue(is_any_marketing_link_set(['ABOUT']))
|
|
self.assertTrue(is_any_marketing_link_set(['ABOUT', 'NOT_CONFIGURED']))
|
|
self.assertFalse(is_any_marketing_link_set(['NOT_CONFIGURED']))
|
|
|
|
def _get_test_url_name(self):
|
|
if settings.ROOT_URLCONF == 'lms.urls':
|
|
# return any lms url name
|
|
return 'dashboard'
|
|
else:
|
|
# return any cms url name
|
|
return 'organizations'
|
|
|
|
|
|
class AddLookupTests(TestCase):
|
|
"""
|
|
Test the `add_lookup` function.
|
|
"""
|
|
@patch('edxmako.LOOKUP', {})
|
|
def test_with_package(self):
|
|
add_lookup('test', 'management', __name__)
|
|
dirs = LOOKUP['test'].directories
|
|
self.assertEqual(len(dirs), 1)
|
|
self.assertTrue(dirs[0].endswith('management'))
|
|
|
|
|
|
class MakoRequestContextTest(TestCase):
|
|
"""
|
|
Test MakoMiddleware.
|
|
"""
|
|
|
|
def setUp(self):
|
|
super(MakoRequestContextTest, self).setUp()
|
|
self.user = UserFactory.create()
|
|
self.url = "/"
|
|
self.request = RequestFactory().get(self.url)
|
|
self.request.user = self.user
|
|
self.response = Mock(spec=HttpResponse)
|
|
|
|
self.addCleanup(RequestCache.clear_all_namespaces)
|
|
|
|
def test_with_current_request(self):
|
|
"""
|
|
Test that if get_current_request returns a request, then get_template_request_context
|
|
returns a RequestContext.
|
|
"""
|
|
|
|
with patch('edxmako.request_context.get_current_request', return_value=self.request):
|
|
# requestcontext should not be None.
|
|
self.assertIsNotNone(get_template_request_context())
|
|
|
|
def test_without_current_request(self):
|
|
"""
|
|
Test that if get_current_request returns None, then get_template_request_context
|
|
returns None.
|
|
"""
|
|
with patch('edxmako.request_context.get_current_request', return_value=None):
|
|
# requestcontext should be None.
|
|
self.assertIsNone(get_template_request_context())
|
|
|
|
def test_request_context_caching(self):
|
|
"""
|
|
Test that the RequestContext is cached in the RequestCache.
|
|
"""
|
|
with patch('edxmako.request_context.get_current_request', return_value=None):
|
|
# requestcontext should be None, because the cache isn't filled
|
|
self.assertIsNone(get_template_request_context())
|
|
|
|
with patch('edxmako.request_context.get_current_request', return_value=self.request):
|
|
# requestcontext should not be None, and should fill the cache
|
|
self.assertIsNotNone(get_template_request_context())
|
|
|
|
mock_get_current_request = Mock()
|
|
with patch('edxmako.request_context.get_current_request'):
|
|
with patch('edxmako.request_context.RequestContext.__init__') as mock_context_init:
|
|
# requestcontext should not be None, because the cache is filled
|
|
self.assertIsNotNone(get_template_request_context())
|
|
mock_context_init.assert_not_called()
|
|
mock_get_current_request.assert_not_called()
|
|
|
|
RequestCache.clear_all_namespaces()
|
|
|
|
with patch('edxmako.request_context.get_current_request', return_value=None):
|
|
# requestcontext should be None, because the cache isn't filled
|
|
self.assertIsNone(get_template_request_context())
|
|
|
|
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
|
def test_render_to_string_when_no_global_context_lms(self):
|
|
"""
|
|
Test render_to_string() when makomiddleware has not initialized
|
|
the threadlocal REQUEST_CONTEXT.context. This is meant to run in LMS.
|
|
"""
|
|
self.assertIn("this module is temporarily unavailable", render_to_string("courseware/error-message.html", None))
|
|
|
|
@unittest.skipUnless(settings.ROOT_URLCONF == 'cms.urls', 'Test only valid in cms')
|
|
def test_render_to_string_when_no_global_context_cms(self):
|
|
"""
|
|
Test render_to_string() when makomiddleware has not initialized
|
|
the threadlocal REQUEST_CONTEXT.context. This is meant to run in CMS.
|
|
"""
|
|
self.assertIn("We're having trouble rendering your component", render_to_string("html_error.html", None))
|