1. Merge microsites into Comprehensive Theming

2. Add site configuration overrides to theming/helpers.py
3. Move microsite.get_value from theming/helpers to site_configuration/helpers
4. Move microsite_configuration.microsite.get_value usages to site_configuration.helpers.values
This commit is contained in:
Saleem Latif
2016-07-19 15:26:31 +05:00
parent e8c60bc6c1
commit 8ae92901ef
142 changed files with 1581 additions and 785 deletions

View File

@@ -17,13 +17,13 @@ import logging
from django.http import HttpResponse
from django.template import Context
from microsite_configuration import microsite
from edxmako import lookup_template
from edxmako.request_context import get_template_request_context
from django.conf import settings
from django.core.urlresolvers import reverse
from openedx.core.djangoapps.theming.helpers import get_template_path
from openedx.core.djangoapps.theming.helpers import get_template_path, is_request_in_themed_site
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
log = logging.getLogger(__name__)
@@ -38,7 +38,7 @@ def marketing_link(name):
# link_map maps URLs from the marketing site to the old equivalent on
# the Django site
link_map = settings.MKTG_URL_LINK_MAP
enable_mktg_site = microsite.get_value(
enable_mktg_site = configuration_helpers.get_value(
'ENABLE_MKTG_SITE',
settings.FEATURES.get('ENABLE_MKTG_SITE', False)
)
@@ -71,7 +71,7 @@ def is_marketing_link_set(name):
Returns a boolean if a given named marketing link is configured.
"""
enable_mktg_site = microsite.get_value(
enable_mktg_site = configuration_helpers.get_value(
'ENABLE_MKTG_SITE',
settings.FEATURES.get('ENABLE_MKTG_SITE', False)
)
@@ -102,13 +102,13 @@ def marketing_link_context_processor(request):
)
def microsite_footer_context_processor(request):
def footer_context_processor(request): # pylint: disable=unused-argument
"""
Checks the site name to determine whether to use the edX.org footer or the Open Source Footer.
"""
return dict(
[
("IS_REQUEST_IN_MICROSITE", microsite.is_request_in_microsite())
("IS_REQUEST_IN_MICROSITE", is_request_in_themed_site())
]
)

View File

@@ -11,7 +11,6 @@ from microsite_configuration import settings
from django.conf import settings as base_settings
from microsite_configuration import microsite
from .templatetags.microsite import page_title_breadcrumbs
class MicrositeAwareSettings(object):

View File

@@ -1,11 +0,0 @@
""" Django template ontext processors. """
from django.conf import settings
from microsite_configuration import microsite
def microsite_context(request): # pylint: disable=missing-docstring,unused-argument
return {
'platform_name': microsite.get_value('platform_name', settings.PLATFORM_NAME)
}

View File

@@ -1,76 +0,0 @@
"""
Template tags and helper functions for displaying breadcrumbs in page titles
based on the current micro site.
"""
from django import template
from django.conf import settings
from microsite_configuration import microsite
from django.templatetags.static import static
from django.contrib.staticfiles.storage import staticfiles_storage
register = template.Library()
def page_title_breadcrumbs(*crumbs, **kwargs):
"""
This function creates a suitable page title in the form:
Specific | Less Specific | General | edX
It will output the correct platform name for the request.
Pass in a `separator` kwarg to override the default of " | "
"""
separator = kwargs.get("separator", " | ")
if crumbs:
return u'{}{}{}'.format(separator.join(crumbs), separator, platform_name())
else:
return platform_name()
@register.simple_tag(name="page_title_breadcrumbs", takes_context=True)
def page_title_breadcrumbs_tag(context, *crumbs):
"""
Django template that creates breadcrumbs for page titles:
{% page_title_breadcrumbs "Specific" "Less Specific" General %}
"""
return page_title_breadcrumbs(*crumbs)
@register.simple_tag(name="platform_name")
def platform_name():
"""
Django template tag that outputs the current platform name:
{% platform_name %}
"""
return microsite.get_value('platform_name', settings.PLATFORM_NAME)
@register.simple_tag(name="favicon_path")
def favicon_path(default=getattr(settings, 'FAVICON_PATH', 'images/favicon.ico')):
"""
Django template tag that outputs the configured favicon:
{% favicon_path %}
"""
return staticfiles_storage.url(microsite.get_value('favicon_path', default))
@register.simple_tag(name="microsite_css_overrides_file")
def microsite_css_overrides_file():
"""
Django template tag that outputs the css import for a:
{% microsite_css_overrides_file %}
"""
file_path = microsite.get_value('css_overrides_file', None)
if file_path is not None:
return "<link href='{}' rel='stylesheet' type='text/css'>".format(static(file_path))
else:
return ""
@register.filter
def microsite_template_path(template_name):
"""
Django template filter to apply template overriding to microsites.
The django_templates loader does not support the leading slash, therefore
it is stripped before returning.
"""
template_name = microsite.get_template_path(template_name)
return template_name[1:] if template_name[0] == '/' else template_name

View File

@@ -30,7 +30,7 @@ class FilebasedMicrositeBackendTests(TestCase):
"""
def setUp(self):
super(FilebasedMicrositeBackendTests, self).setUp()
self.microsite_subdomain = 'testmicrosite'
self.microsite_subdomain = 'test-site'
def tearDown(self):
super(FilebasedMicrositeBackendTests, self).tearDown()
@@ -41,7 +41,7 @@ class FilebasedMicrositeBackendTests(TestCase):
Tests microsite.get_value works as expected.
"""
microsite.set_by_domain(self.microsite_subdomain)
self.assertEqual(microsite.get_value('platform_name'), 'Test Microsite')
self.assertEqual(microsite.get_value('platform_name'), 'Test Site')
def test_is_request_in_microsite(self):
"""
@@ -63,15 +63,15 @@ class FilebasedMicrositeBackendTests(TestCase):
"""
microsite.set_by_domain(self.microsite_subdomain)
self.assertEqual(
microsite.get_value_for_org('TestMicrositeX', 'platform_name'),
'Test Microsite'
microsite.get_value_for_org('TestSiteX', 'platform_name'),
'Test Site'
)
# if no config is set
microsite.clear()
with patch('django.conf.settings.MICROSITE_CONFIGURATION', False):
self.assertEqual(
microsite.get_value_for_org('TestMicrositeX', 'platform_name', 'Default Value'),
microsite.get_value_for_org('TestSiteX', 'platform_name', 'Default Value'),
'Default Value'
)
@@ -82,7 +82,7 @@ class FilebasedMicrositeBackendTests(TestCase):
microsite.set_by_domain(self.microsite_subdomain)
self.assertEqual(
microsite.get_all_orgs(),
set(['TestMicrositeX', 'LogistrationX'])
set(['TestSiteX', 'LogistrationX'])
)
# if no config is set
@@ -100,7 +100,7 @@ class FilebasedMicrositeBackendTests(TestCase):
microsite.set_by_domain(self.microsite_subdomain)
self.assertEqual(
microsite.get_value('platform_name'),
'Test Microsite'
'Test Site'
)
microsite.clear()
self.assertIsNone(microsite.get_value('platform_name'))
@@ -145,7 +145,7 @@ class FilebasedMicrositeTemplateBackendTests(ModuleStoreTestCase):
"""
def setUp(self):
super(FilebasedMicrositeTemplateBackendTests, self).setUp()
self.microsite_subdomain = 'testmicrosite'
self.microsite_subdomain = 'test-site'
self.course = CourseFactory.create()
self.user = UserFactory.create(username="Bob", email="bob@example.com", password="edx")
self.client.login(username=self.user.username, password="edx")

View File

@@ -21,7 +21,7 @@ class SiteFactory(DjangoModelFactory):
model = Site
name = "test microsite"
domain = "testmicrosite.testserver"
domain = "test-site.testserver"
class MicrositeFactory(DjangoModelFactory):
@@ -31,31 +31,31 @@ class MicrositeFactory(DjangoModelFactory):
class Meta(object):
model = Microsite
key = "test_microsite"
key = "test_site"
site = factory.SubFactory(SiteFactory)
values = {
"domain_prefix": "testmicrosite",
"university": "test_microsite",
"platform_name": "Test Microsite DB",
"logo_image_url": "test_microsite/images/header-logo.png",
"email_from_address": "test_microsite_db@edx.org",
"payment_support_email": "test_microsit_dbe@edx.org",
"domain_prefix": "test-site",
"university": "test_site",
"platform_name": "Test Site DB",
"logo_image_url": "test_site/images/header-logo.png",
"email_from_address": "test_site@edx.org",
"payment_support_email": "test_site_dbe@edx.org",
"ENABLE_MKTG_SITE": False,
"SITE_NAME": "test_microsite.localhost",
"course_org_filter": "TestMicrositeX",
"SITE_NAME": "test_site.localhost",
"course_org_filter": "TestSiteX",
"course_about_show_social_links": False,
"css_overrides_file": "test_microsite/css/test_microsite.css",
"css_overrides_file": "test_site/css/test_site.css",
"show_partners": False,
"show_homepage_promo_video": False,
"course_index_overlay_text": "This is a Test Microsite Overlay Text.",
"course_index_overlay_logo_file": "test_microsite/images/header-logo.png",
"homepage_overlay_html": "<h1>This is a Test Microsite Overlay HTML</h1>",
"course_index_overlay_text": "This is a Test Site Overlay Text.",
"course_index_overlay_logo_file": "test_site/images/header-logo.png",
"homepage_overlay_html": "<h1>This is a Test Site Overlay HTML</h1>",
"ALWAYS_REDIRECT_HOMEPAGE_TO_DASHBOARD_FOR_AUTHENTICATED_USER": False,
"COURSE_CATALOG_VISIBILITY_PERMISSION": "see_in_catalog",
"COURSE_ABOUT_VISIBILITY_PERMISSION": "see_about_page",
"ENABLE_SHOPPING_CART": True,
"ENABLE_PAID_COURSE_REGISTRATION": True,
"SESSION_COOKIE_DOMAIN": "test_microsite.localhost",
"SESSION_COOKIE_DOMAIN": "test_site.localhost",
"nested_dict": {
"key 1": "value 1",
"key 2": "value 2",

View File

@@ -35,8 +35,8 @@ class MicrositeAdminTests(DatabaseMicrositeTestCase):
Tests save action for Microsite model form.
"""
new_values = {
"domain_prefix": "testmicrosite_new",
"platform_name": "Test Microsite New"
"domain_prefix": "test-site-new",
"platform_name": "Test Site New"
}
microsite_form = self.microsite_admin.get_form(self.request)(instance=self.microsite, data={
"key": self.microsite.key,

View File

@@ -1,22 +0,0 @@
""" Tests for Django template context processors. """
from django.test import TestCase
from django.test.client import RequestFactory
from django.test.utils import override_settings
from microsite_configuration.context_processors import microsite_context
PLATFORM_NAME = 'Test Platform'
@override_settings(PLATFORM_NAME=PLATFORM_NAME)
class MicrositeContextProcessorTests(TestCase):
""" Tests for the microsite context processor. """
def setUp(self):
super(MicrositeContextProcessorTests, self).setUp()
request = RequestFactory().get('/')
self.context = microsite_context(request)
def test_platform_name(self):
""" Verify the context includes the platform name. """
self.assertEqual(self.context['platform_name'], PLATFORM_NAME)

View File

@@ -42,5 +42,5 @@ class TestMicrosites(DatabaseMicrositeTestCase):
"""
with patch('microsite_configuration.microsite.BACKEND',
get_backend(site_backend, BaseMicrositeBackend)):
value = get_value_for_org("TestMicrositeX", "university", "default_value")
self.assertEquals(value, "test_microsite")
value = get_value_for_org("TestSiteX", "university", "default_value")
self.assertEquals(value, "test_site")

View File

@@ -1,16 +1,17 @@
# -*- coding: utf-8 -*-
"""
Tests microsite_configuration templatetags and helper functions.
Tests configuration templatetags and helper functions.
"""
import logging
from mock import patch
from django.test import TestCase
from django.conf import settings
from microsite_configuration.templatetags import microsite as microsite_tags
from microsite_configuration import microsite
from microsite_configuration.backends.base import BaseMicrositeBackend
from microsite_configuration.backends.database import DatabaseMicrositeBackend
from openedx.core.djangoapps.site_configuration.templatetags import configuration as configuration_tags
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
log = logging.getLogger(__name__)
@@ -22,30 +23,30 @@ class MicrositeTests(TestCase):
def test_breadcrumbs(self):
crumbs = ['my', 'less specific', 'Page']
expected = u'my | less specific | Page | edX'
title = microsite_tags.page_title_breadcrumbs(*crumbs)
title = configuration_helpers.page_title_breadcrumbs(*crumbs)
self.assertEqual(expected, title)
def test_unicode_title(self):
crumbs = [u'øo', u'π tastes gréât', u'']
expected = u'øo | π tastes gréât | 驴 | edX'
title = microsite_tags.page_title_breadcrumbs(*crumbs)
title = configuration_helpers.page_title_breadcrumbs(*crumbs)
self.assertEqual(expected, title)
def test_platform_name(self):
pname = microsite_tags.platform_name()
pname = configuration_tags.platform_name()
self.assertEqual(pname, settings.PLATFORM_NAME)
def test_breadcrumb_tag(self):
crumbs = ['my', 'less specific', 'Page']
expected = u'my | less specific | Page | edX'
title = microsite_tags.page_title_breadcrumbs_tag(None, *crumbs)
title = configuration_tags.page_title_breadcrumbs_tag(None, *crumbs)
self.assertEqual(expected, title)
def test_microsite_template_path(self):
"""
When an unexistent path is passed to the filter, it should return the same path
"""
path = microsite_tags.microsite_template_path('footer.html')
path = configuration_tags.microsite_template_path('footer.html')
self.assertEqual("footer.html", path)
def test_get_backend_raise_error_for_invalid_class(self):

View File

@@ -51,7 +51,7 @@ class MicrositeSessionCookieTests(DatabaseMicrositeTestCase):
with patch('microsite_configuration.microsite.BACKEND',
get_backend(site_backend, BaseMicrositeBackend)):
response = self.client.get('/')
self.assertNotIn('test_microsite.localhost', str(response.cookies['sessionid']))
self.assertNotIn('test_site.localhost', str(response.cookies['sessionid']))
self.assertNotIn('Domain', str(response.cookies['sessionid']))
@ddt.data(*MICROSITE_BACKENDS)
@@ -63,7 +63,7 @@ class MicrositeSessionCookieTests(DatabaseMicrositeTestCase):
with patch('microsite_configuration.microsite.BACKEND',
get_backend(site_backend, BaseMicrositeBackend)):
response = self.client.get('/', HTTP_HOST=settings.MICROSITE_TEST_HOSTNAME)
self.assertIn('test_microsite.localhost', str(response.cookies['sessionid']))
self.assertIn('test_site.localhost', str(response.cookies['sessionid']))
@ddt.data(*MICROSITE_BACKENDS)
def test_microsite_none_cookie_domain(self, site_backend):
@@ -77,5 +77,5 @@ class MicrositeSessionCookieTests(DatabaseMicrositeTestCase):
with patch('microsite_configuration.microsite.BACKEND',
get_backend(site_backend, BaseMicrositeBackend)):
response = self.client.get('/', HTTP_HOST=settings.MICROSITE_TEST_HOSTNAME)
self.assertNotIn('test_microsite.localhost', str(response.cookies['sessionid']))
self.assertNotIn('test_site.localhost', str(response.cookies['sessionid']))
self.assertNotIn('Domain', str(response.cookies['sessionid']))

View File

@@ -22,7 +22,7 @@ class DatabaseMicrositeTestCase(TestCase):
def setUp(self):
super(DatabaseMicrositeTestCase, self).setUp()
self.microsite = MicrositeFactory.create()
MicrositeOrganizationMappingFactory.create(microsite=self.microsite, organization='TestMicrositeX')
MicrositeOrganizationMappingFactory.create(microsite=self.microsite, organization='TestSiteX')
def side_effect_for_get_value(value, return_value):

View File

@@ -6,9 +6,12 @@ from django.utils.translation import get_language_bidi
from mako.exceptions import TemplateLookupException
from openedx.core.djangolib.js_utils import js_escaped_string
from openedx.core.djangoapps.theming.helpers import (
get_page_title_breadcrumbs,
from openedx.core.djangoapps.site_configuration.helpers import (
page_title_breadcrumbs,
get_value,
)
from openedx.core.djangoapps.theming.helpers import (
get_template_path,
get_themed_template_path,
is_request_in_themed_site,
@@ -138,7 +141,7 @@ else:
<%def name="get_page_title_breadcrumbs(*args)"><%
return get_page_title_breadcrumbs(*args)
return page_title_breadcrumbs(*args)
%></%def>
<%def name="get_platform_name()"><%

View File

@@ -17,10 +17,9 @@ from django.utils.translation import ugettext_lazy as _
from django.template import loader
from django.conf import settings
from microsite_configuration import microsite
from student.models import CourseEnrollmentAllowed
from util.password_policy_validators import validate_password_strength
from openedx.core.djangoapps.theming import helpers as theming_helpers
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
class PasswordResetFormNoActive(PasswordResetForm):
@@ -54,7 +53,7 @@ class PasswordResetFormNoActive(PasswordResetForm):
email_template_name='registration/password_reset_email.html',
use_https=False,
token_generator=default_token_generator,
from_email=theming_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL),
from_email=configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL),
request=None
):
"""
@@ -66,7 +65,7 @@ class PasswordResetFormNoActive(PasswordResetForm):
from django.core.mail import send_mail
for user in self.users_cache:
if not domain_override:
site_name = microsite.get_value(
site_name = configuration_helpers.get_value(
'SITE_NAME',
settings.SITE_NAME
)
@@ -79,7 +78,7 @@ class PasswordResetFormNoActive(PasswordResetForm):
'user': user,
'token': token_generator.make_token(user),
'protocol': 'https' if use_https else 'http',
'platform_name': microsite.get_value('platform_name', settings.PLATFORM_NAME)
'platform_name': configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME)
}
subject = loader.render_to_string(subject_template_name, context)
# Email subject *must not* contain newlines

View File

@@ -51,10 +51,10 @@ from lms.djangoapps.badges.utils import badges_enabled
from certificates.models import GeneratedCertificate
from course_modes.models import CourseMode
from enrollment.api import _default_course_mode
from microsite_configuration import microsite
import lms.lib.comment_client as cc
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client, ECOMMERCE_DATE_FORMAT
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from util.model_utils import emit_field_changed_events, get_changed_fields_dict
from util.query import use_read_replica_if_available
from util.milestones_helpers import is_entrance_exams_enabled
@@ -1950,7 +1950,7 @@ class LinkedInAddToProfileConfiguration(ConfigurationModel):
target (str): An identifier for the occurrance of the button.
"""
company_identifier = microsite.get_value('LINKEDIN_COMPANY_ID', self.company_identifier)
company_identifier = configuration_helpers.get_value('LINKEDIN_COMPANY_ID', self.company_identifier)
params = OrderedDict([
('_ed', company_identifier),
('pfCertificationName', self._cert_name(course_name, cert_mode).encode('utf-8')),
@@ -1972,7 +1972,7 @@ class LinkedInAddToProfileConfiguration(ConfigurationModel):
cert_mode,
_(u"{platform_name} Certificate for {course_name}")
).format(
platform_name=microsite.get_value('platform_name', settings.PLATFORM_NAME),
platform_name=configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME),
course_name=course_name
)

View File

@@ -23,13 +23,6 @@ from student.models import LinkedInAddToProfileConfiguration
# pylint: disable=no-member
def _fake_is_request_in_microsite():
"""
Mocked version of microsite helper method to always return true
"""
return True
class CertificateDisplayTestBase(SharedModuleStoreTestCase):
"""Tests display of certificates on the student dashboard. """
@@ -163,10 +156,10 @@ class CertificateDisplayTest(CertificateDisplayTestBase):
# now we should see it
self._check_linkedin_visibility(True)
@mock.patch("microsite_configuration.microsite.is_request_in_microsite", _fake_is_request_in_microsite)
def test_post_to_linkedin_microsite(self):
@mock.patch("openedx.core.djangoapps.theming.helpers.is_request_in_themed_site", mock.Mock(return_value=True))
def test_post_to_linkedin_site_specific(self):
"""
Verifies behavior for microsites which disables the post to LinkedIn
Verifies behavior for themed sites which disables the post to LinkedIn
feature (for now)
"""
self._create_certificate('honor')
@@ -177,7 +170,7 @@ class CertificateDisplayTest(CertificateDisplayTestBase):
)
config.save()
# now we should not see it because we are in a microsite
# now we should not see it because we are in a themed site
self._check_linkedin_visibility(False)

View File

@@ -1,5 +1,5 @@
"""
Test for User Creation from Micro-Sites
Test for user creation from sites with configuration overrides.
"""
from django.test import TestCase
from student.models import UserSignupSource
@@ -8,7 +8,7 @@ import json
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
FAKE_MICROSITE = {
FAKE_SITE = {
"SITE_NAME": "openedx.localhost",
"university": "fakeuniversity",
"course_org_filter": "fakeorg",
@@ -30,7 +30,7 @@ FAKE_MICROSITE = {
def fake_site_name(name, default=None):
"""
create a fake microsite site name
Method for getting site name for a fake site.
"""
if name == 'SITE_NAME':
return 'openedx.localhost'
@@ -38,17 +38,17 @@ def fake_site_name(name, default=None):
return default
def fake_microsite_get_value(name, default=None):
def fake_get_value(name, default=None):
"""
create a fake microsite site name
Method for getting configuration override values for a fake site.
"""
return FAKE_MICROSITE.get(name, default)
return FAKE_SITE.get(name, default)
class TestMicrosite(TestCase):
"""Test for Account Creation from a white labeled Micro-Sites"""
class TestSite(TestCase):
"""Test for Account Creation from white labeled Sites"""
def setUp(self):
super(TestMicrosite, self).setUp()
super(TestSite, self).setUp()
self.username = "test_user"
self.url = reverse("create_account")
self.params = {
@@ -68,39 +68,39 @@ class TestMicrosite(TestCase):
"title": "foo"
}.items())
@mock.patch("microsite_configuration.microsite.get_value", fake_site_name)
@mock.patch("openedx.core.djangoapps.site_configuration.helpers.get_value", fake_site_name)
def test_user_signup_source(self):
"""
test to create a user form the microsite and see that it record has been
saved in the UserSignupSource Table
Test to create a user from a site with configuration overrides and see that its record has been
saved in the UserSignupSource Table.
"""
response = self.client.post(self.url, self.params)
self.assertEqual(response.status_code, 200)
self.assertGreater(len(UserSignupSource.objects.filter(site='openedx.localhost')), 0)
def test_user_signup_from_non_micro_site(self):
def test_user_signup_from_non_configured_site(self):
"""
test to create a user form the non-microsite. The record should not be saved
in the UserSignupSource Table
Test to create a user from a site without any configuration override. The record should not be saved
in UserSignupSource Table.
"""
response = self.client.post(self.url, self.params)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(UserSignupSource.objects.filter(site='openedx.localhost')), 0)
@mock.patch("microsite_configuration.microsite.get_value", fake_microsite_get_value)
@mock.patch("openedx.core.djangoapps.site_configuration.helpers.get_value", fake_get_value)
def test_user_signup_missing_enhanced_profile(self):
"""
test to create a user form the microsite but don't provide any of the microsite specific
profile information
Test to create a user from a site with configuration overrides but don't provide any overrides for
profile information.
"""
response = self.client.post(self.url, self.params)
self.assertEqual(response.status_code, 400)
@mock.patch("microsite_configuration.microsite.get_value", fake_microsite_get_value)
@mock.patch("openedx.core.djangoapps.site_configuration.helpers.get_value", fake_get_value)
def test_user_signup_including_enhanced_profile(self):
"""
test to create a user form the microsite but don't provide any of the microsite specific
profile information
Test to create a user from a site with configuration overrides with overrides for
profile information.
"""
response = self.client.post(self.url, self.extended_params)
self.assertEqual(response.status_code, 200)

View File

@@ -20,7 +20,7 @@ from django.conf import settings
from edxmako.shortcuts import render_to_string
from util.request import safe_get_host
from util.testing import EventTestMixin
from openedx.core.djangoapps.theming import helpers as theming_helpers
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.theming.tests.test_util import with_comprehensive_theme
@@ -57,7 +57,7 @@ class EmailTestMixin(object):
email_user.assert_called_with(
mock_render_to_string(subject_template, subject_context),
mock_render_to_string(body_template, body_context),
theming_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL)
configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL)
)
def append_allowed_hosts(self, hostname):
@@ -298,7 +298,7 @@ class EmailChangeRequestTests(EventTestMixin, TestCase):
send_mail.assert_called_with(
mock_render_to_string('emails/email_change_subject.txt', context),
mock_render_to_string('emails/email_change.txt', context),
theming_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL),
configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL),
[new_email]
)
self.assert_event_emitted(

View File

@@ -25,8 +25,8 @@ from student.tests.factories import UserFactory
from student.tests.test_email import mock_render_to_string
from util.testing import EventTestMixin
from .test_microsite import fake_microsite_get_value
from openedx.core.djangoapps.theming import helpers as theming_helpers
from .test_configuration_overrides import fake_get_value
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
@unittest.skipUnless(
@@ -125,7 +125,7 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
(subject, msg, from_addr, to_addrs) = send_email.call_args[0]
self.assertIn("Password reset", subject)
self.assertIn("You're receiving this e-mail because you requested a password reset", msg)
self.assertEquals(from_addr, theming_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL))
self.assertEquals(from_addr, configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL))
self.assertEquals(len(to_addrs), 1)
self.assertIn(self.user.email, to_addrs)
@@ -195,9 +195,9 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', "Test only valid in LMS")
@patch("microsite_configuration.microsite.get_value", fake_microsite_get_value)
@patch("openedx.core.djangoapps.site_configuration.helpers.get_value", fake_get_value)
@patch('django.core.mail.send_mail')
def test_reset_password_email_microsite(self, send_email):
def test_reset_password_email_configuration_override(self, send_email):
"""
Tests that the right url domain and platform name is included in
the reset password email
@@ -254,9 +254,9 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
self.assertTrue(self.user.is_active)
@patch('student.views.password_reset_confirm')
@patch("microsite_configuration.microsite.get_value", fake_microsite_get_value)
def test_reset_password_good_token_microsite(self, reset_confirm):
"""Tests password reset confirmation page for micro site"""
@patch("openedx.core.djangoapps.site_configuration.helpers.get_value", fake_get_value)
def test_reset_password_good_token_configuration_override(self, reset_confirm):
"""Tests password reset confirmation page for site configuration override."""
url = reverse(
"password_reset_confirm",
kwargs={"uidb36": self.uidb36, "token": self.token}

View File

@@ -97,7 +97,6 @@ from util.bad_request_rate_limiter import BadRequestRateLimiter
from util.milestones_helpers import (
get_pre_requisite_courses_not_completed,
)
from microsite_configuration import microsite
from util.password_policy_validators import validate_password_strength
import third_party_auth
@@ -123,6 +122,7 @@ from openedx.core.djangoapps.credit.email_utils import get_credit_provider_displ
from openedx.core.djangoapps.user_api.preferences import api as preferences_api
from openedx.core.djangoapps.programs.utils import get_programs_for_dashboard, get_display_category
from openedx.core.djangoapps.programs.models import ProgramsApiConfig
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.theming import helpers as theming_helpers
@@ -164,31 +164,33 @@ def index(request, extra_context=None, user=AnonymousUser()):
courses = get_courses(user)
if microsite.get_value("ENABLE_COURSE_SORTING_BY_START_DATE",
settings.FEATURES["ENABLE_COURSE_SORTING_BY_START_DATE"]):
if configuration_helpers.get_value(
"ENABLE_COURSE_SORTING_BY_START_DATE",
settings.FEATURES["ENABLE_COURSE_SORTING_BY_START_DATE"],
):
courses = sort_by_start_date(courses)
else:
courses = sort_by_announcement(courses)
context = {'courses': courses}
context['homepage_overlay_html'] = microsite.get_value('homepage_overlay_html')
context['homepage_overlay_html'] = configuration_helpers.get_value('homepage_overlay_html')
# This appears to be an unused context parameter, at least for the master templates...
context['show_partners'] = microsite.get_value('show_partners', True)
context['show_partners'] = configuration_helpers.get_value('show_partners', True)
# TO DISPLAY A YOUTUBE WELCOME VIDEO
# 1) Change False to True
context['show_homepage_promo_video'] = microsite.get_value('show_homepage_promo_video', False)
context['show_homepage_promo_video'] = configuration_helpers.get_value('show_homepage_promo_video', False)
# 2) Add your video's YouTube ID (11 chars, eg "123456789xX"), or specify via microsite config
# 2) Add your video's YouTube ID (11 chars, eg "123456789xX"), or specify via site configuration
# Note: This value should be moved into a configuration setting and plumbed-through to the
# context via the microsite configuration workflow, versus living here
youtube_video_id = microsite.get_value('homepage_promo_video_youtube_id', "your-youtube-id")
# context via the site configuration workflow, versus living here
youtube_video_id = configuration_helpers.get_value('homepage_promo_video_youtube_id', "your-youtube-id")
context['homepage_promo_video_youtube_id'] = youtube_video_id
# allow for microsite override of the courses list
context['courses_list'] = microsite.get_template_path('courses_list.html')
# allow for theme override of the courses list
context['courses_list'] = theming_helpers.get_template_path('courses_list.html')
# Insert additional context for use in the template
context.update(extra_context)
@@ -264,8 +266,7 @@ def get_course_enrollments(user, org_to_include, orgs_to_exclude):
Arguments:
user (User): the user in question.
org_to_include (str): for use in Microsites. If not None, ONLY courses
of this org will be returned.
org_to_include (str): If not None, ONLY courses of this org will be returned.
orgs_to_exclude (list[str]): If org_to_include is not None, this
argument is ignored. Else, courses of this org will be excluded.
@@ -285,13 +286,11 @@ def get_course_enrollments(user, org_to_include, orgs_to_exclude):
)
continue
# If we are in a Microsite, then filter out anything that is not
# attributed (by ORG) to that Microsite.
# Filter out anything that is not attributed to the current ORG.
if org_to_include and course_overview.location.org != org_to_include:
continue
# Conversely, if we are not in a Microsite, then filter out any enrollments
# with courses attributed (by ORG) to Microsites.
# Conversely, filter out any enrollments with courses attributed to current ORG.
elif course_overview.location.org in orgs_to_exclude:
continue
@@ -385,8 +384,8 @@ def _cert_info(user, course_overview, cert_status, course_mode): # pylint: disa
linkedin_config = LinkedInAddToProfileConfiguration.current()
# posting certificates to LinkedIn is not currently
# supported in microsites/White Labels
if linkedin_config.enabled and not microsite.is_request_in_microsite():
# supported in White Labels
if linkedin_config.enabled and not theming_helpers.is_request_in_themed_site():
status_dict['linked_in_url'] = linkedin_config.add_to_profile_url(
course_overview.id,
course_overview.display_name,
@@ -431,7 +430,7 @@ def signin_user(request):
# pipeline, if any.
'pipeline_running': 'true' if pipeline.running(request) else 'false',
'pipeline_url': auth_pipeline_urls(pipeline.AUTH_ENTRY_LOGIN, redirect_url=redirect_to),
'platform_name': microsite.get_value(
'platform_name': configuration_helpers.get_value(
'platform_name',
settings.PLATFORM_NAME
),
@@ -459,7 +458,7 @@ def register_user(request, extra_context=None):
'name': '',
'running_pipeline': None,
'pipeline_urls': auth_pipeline_urls(pipeline.AUTH_ENTRY_REGISTER, redirect_url=redirect_to),
'platform_name': microsite.get_value(
'platform_name': configuration_helpers.get_value(
'platform_name',
settings.PLATFORM_NAME
),
@@ -548,17 +547,17 @@ def is_course_blocked(request, redeemed_registration_codes, course_key):
def dashboard(request):
user = request.user
platform_name = microsite.get_value("platform_name", settings.PLATFORM_NAME)
platform_name = configuration_helpers.get_value("platform_name", settings.PLATFORM_NAME)
# for microsites, we want to filter and only show enrollments for courses within
# the microsites 'ORG'
course_org_filter = microsite.get_value('course_org_filter')
# we want to filter and only show enrollments for courses within
# the 'ORG' defined in configuration.
course_org_filter = configuration_helpers.get_value('course_org_filter')
# Let's filter out any courses in an "org" that has been declared to be
# in a Microsite
org_filter_out_set = microsite.get_all_orgs()
# in a configuration
org_filter_out_set = configuration_helpers.get_all_orgs()
# remove our current Microsite from the "filter out" list, if applicable
# remove our current org from the "filter out" list, if applicable
if course_org_filter:
org_filter_out_set.remove(course_org_filter)
@@ -780,7 +779,7 @@ def _create_recent_enrollment_message(course_enrollments, course_modes): # pyli
for enrollment in recently_enrolled_courses
]
platform_name = microsite.get_value('platform_name', settings.PLATFORM_NAME)
platform_name = configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME)
return render_to_string(
'enrollment/course_enrollment_message.html',
@@ -1122,7 +1121,7 @@ def login_user(request, error=""): # pylint: disable=too-many-statements,unused
third_party_auth_successful = False
trumped_by_first_party_auth = bool(request.POST.get('email')) or bool(request.POST.get('password'))
user = None
platform_name = microsite.get_value("platform_name", settings.PLATFORM_NAME)
platform_name = configuration_helpers.get_value("platform_name", settings.PLATFORM_NAME)
if third_party_auth_requested and not trumped_by_first_party_auth:
# The user has already authenticated via third-party auth and has not
@@ -1475,7 +1474,7 @@ def user_signup_handler(sender, **kwargs): # pylint: disable=unused-argument
when the user is created
"""
if 'created' in kwargs and kwargs['created']:
site = microsite.get_value('SITE_NAME')
site = configuration_helpers.get_value('SITE_NAME')
if site:
user_signup_source = UserSignupSource(user=kwargs['instance'], site=site)
user_signup_source.save()
@@ -1589,8 +1588,8 @@ def create_account_with_params(request, params):
# params is request.POST, that results in a dict containing lists of values
params = dict(params.items())
# allow for microsites to define their own set of required/optional/hidden fields
extra_fields = microsite.get_value(
# allow to define custom set of required/optional/hidden fields via configuration
extra_fields = configuration_helpers.get_value(
'REGISTRATION_EXTRA_FIELDS',
getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
)
@@ -1622,7 +1621,7 @@ def create_account_with_params(request, params):
params["password"] = eamap.internal_password
log.debug(u'In create_account with external_auth: user = %s, email=%s', params["name"], params["email"])
extended_profile_fields = microsite.get_value('extended_profile_fields', [])
extended_profile_fields = configuration_helpers.get_value('extended_profile_fields', [])
enforce_password_policy = (
settings.FEATURES.get("ENFORCE_PASSWORD_POLICY", False) and
not do_external_auth
@@ -1786,7 +1785,7 @@ def create_account_with_params(request, params):
subject = ''.join(subject.splitlines())
message = render_to_string('emails/activation_email.txt', context)
from_address = theming_helpers.get_value(
from_address = configuration_helpers.get_value(
'email_from_address',
settings.DEFAULT_FROM_EMAIL
)
@@ -2095,7 +2094,7 @@ def password_reset(request):
form = PasswordResetFormNoActive(request.POST)
if form.is_valid():
form.save(use_https=request.is_secure(),
from_email=theming_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL),
from_email=configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL),
request=request,
domain_override=request.get_host())
# When password change is complete, a "edx.user.settings.changed" event will be emitted.
@@ -2199,7 +2198,7 @@ def password_reset_confirm_wrapper(request, uidb36=None, token=None):
# convert old-style base36-encoded user id to base64
uidb64 = uidb36_to_uidb64(uidb36)
platform_name = {
"platform_name": microsite.get_value('platform_name', settings.PLATFORM_NAME)
"platform_name": configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME)
}
try:
uid_int = base36_to_int(uidb36)
@@ -2276,11 +2275,14 @@ def reactivation_email_for_user(user):
message = render_to_string('emails/activation_email.txt', context)
try:
user.email_user(subject, message, theming_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL))
user.email_user(subject, message, configuration_helpers.get_value(
'email_from_address',
settings.DEFAULT_FROM_EMAIL,
))
except Exception: # pylint: disable=broad-except
log.error(
u'Unable to send reactivation email from "%s"',
theming_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL),
configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL),
exc_info=True
)
return JsonResponse({
@@ -2340,7 +2342,7 @@ def do_email_change_request(user, new_email, activation_key=None):
message = render_to_string('emails/email_change.txt', context)
from_address = theming_helpers.get_value(
from_address = configuration_helpers.get_value(
'email_from_address',
settings.DEFAULT_FROM_EMAIL
)
@@ -2404,7 +2406,7 @@ def confirm_email_change(request, key): # pylint: disable=unused-argument
user.email_user(
subject,
message,
theming_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL)
configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL)
)
except Exception: # pylint: disable=broad-except
log.warning('Unable to send confirmation email to old address', exc_info=True)
@@ -2420,7 +2422,7 @@ def confirm_email_change(request, key): # pylint: disable=unused-argument
user.email_user(
subject,
message,
theming_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL)
configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL)
)
except Exception: # pylint: disable=broad-except
log.warning('Unable to send confirmation email to new address', exc_info=True)

View File

@@ -1,6 +1,6 @@
"""Third party authentication. """
from microsite_configuration import microsite
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
def is_enabled():
@@ -9,7 +9,7 @@ def is_enabled():
# We do this import internally to avoid initializing settings prematurely
from django.conf import settings
return microsite.get_value(
return configuration_helpers.get_value(
"ENABLE_THIRD_PARTY_AUTH",
settings.FEATURES.get("ENABLE_THIRD_PARTY_AUTH")
)

View File

@@ -21,7 +21,7 @@ from social.backends.saml import SAMLAuth, SAMLIdentityProvider
from .lti import LTIAuthBackend, LTI_PARAMS_KEY
from social.exceptions import SocialAuthBaseException
from social.utils import module_member
from openedx.core.djangoapps.theming.helpers import get_value as get_themed_value
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
log = logging.getLogger(__name__)
@@ -454,7 +454,9 @@ class SAMLConfiguration(ConfigurationModel):
other_config = json.loads(self.other_config_str)
if name in ("TECHNICAL_CONTACT", "SUPPORT_CONTACT"):
contact = {
"givenName": "{} Support".format(get_themed_value('PLATFORM_NAME', settings.PLATFORM_NAME)),
"givenName": "{} Support".format(
configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME),
),
"emailAddress": settings.TECH_SUPPORT_EMAIL
}
contact.update(other_config.get(name, {}))

View File

@@ -3,9 +3,9 @@ import re
from django.conf import settings
from microsite_configuration import microsite
from opaque_keys import InvalidKeyError
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
# accommodates course api urls, excluding any course api routes that do not fall under v*/courses, such as v1/blocks.
COURSE_REGEX = re.compile(r'^(.*?/courses/)(?!v[0-9]+/[^/]+){}'.format(settings.COURSE_ID_PATTERN))
@@ -23,7 +23,7 @@ def safe_get_host(request):
if isinstance(settings.ALLOWED_HOSTS, (list, tuple)) and '*' not in settings.ALLOWED_HOSTS:
return request.get_host()
else:
return microsite.get_value('site_domain', settings.SITE_NAME)
return configuration_helpers.get_value('site_domain', settings.SITE_NAME)
def course_id_from_url(url):

View File

@@ -11,7 +11,7 @@ from zendesk import ZendeskError
import json
import mock
from student.tests.test_microsite import fake_microsite_get_value
from student.tests.test_configuration_overrides import fake_get_value
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_FEEDBACK_SUBMISSION": True})
@@ -193,14 +193,14 @@ class SubmitFeedbackTest(TestCase):
self.assertEqual(zendesk_mock_instance.mock_calls, expected_zendesk_calls)
self._assert_datadog_called(datadog_mock, with_tags=True)
@mock.patch("microsite_configuration.microsite.get_value", fake_microsite_get_value)
def test_valid_request_anon_user_microsite(self, zendesk_mock_class, datadog_mock):
@mock.patch("openedx.core.djangoapps.site_configuration.helpers.get_value", fake_get_value)
def test_valid_request_anon_user_configuration_override(self, zendesk_mock_class, datadog_mock):
"""
Test a valid request from an anonymous user to a mocked out microsite
Test a valid request from an anonymous user to a mocked out site with configuration override
The response should have a 200 (success) status code, and a ticket with
the given information should have been submitted via the Zendesk API with the additional
tag that will come from microsite configuration
tag that will come from site configuration override.
"""
zendesk_mock_instance = zendesk_mock_class.return_value
zendesk_mock_instance.create_ticket.return_value = 42

View File

@@ -14,7 +14,7 @@ from django.http import (Http404, HttpResponse, HttpResponseNotAllowed,
import dogstats_wrapper as dog_stats_api
from edxmako.shortcuts import render_to_response
import zendesk
from openedx.core.djangoapps.theming.helpers import get_value as get_themed_value
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
import calc
import track.views
@@ -233,7 +233,7 @@ def _record_feedback_in_zendesk(
# Per edX support, we would like to be able to route white label feedback items
# via tagging
white_label_org = get_themed_value('course_org_filter')
white_label_org = configuration_helpers.get_value('course_org_filter')
if white_label_org:
zendesk_tags = zendesk_tags + ["whitelabel_{org}".format(org=white_label_org)]
@@ -368,7 +368,7 @@ def submit_feedback(request):
details,
tags,
additional_info,
support_email=get_themed_value('email_from_address', settings.DEFAULT_FROM_EMAIL)
support_email=configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL)
)
_record_feedback_in_datadog(tags)

View File

@@ -1 +0,0 @@
This is a copyright page for an Open edX microsite.

View File

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 155 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -19,7 +19,7 @@ def url_class(is_active):
%>
<li>
<a href="${tab.link_func(course, reverse) | h}" class="${tab_class}">
Test Microsite Tab: ${_(tab.name) | h}
Test Site Tab: ${_(tab.name) | h}
% if tab_is_active:
<span class="sr">, current location</span>
%endif

View File

@@ -10,7 +10,7 @@ from django.utils.translation import ugettext as _
<footer>
<div class="colophon">
<div class="colophon-about">
<p>This is a Test Microsite footer</p>
<p>This is a Test Site footer</p>
</div>
</div>

View File

@@ -0,0 +1 @@
This is a copyright page for an Open edX site.