MA-2536: get 'course_about' url in enrollment
This commit is contained in:
@@ -219,6 +219,7 @@ class CourseDetailsViewTest(CourseTestCase, MilestonesTestCaseMixin):
|
||||
(False, True, False),
|
||||
(True, True, True),
|
||||
)
|
||||
@override_settings(MKTG_URLS={'ROOT': 'dummy-root'})
|
||||
def test_visibility_of_entrance_exam_section(self, feature_flags):
|
||||
"""
|
||||
Tests entrance exam section is available if ENTRANCE_EXAMS feature is enabled no matter any other
|
||||
@@ -1161,6 +1162,7 @@ id=\"course-enrollment-end-time\" value=\"\" placeholder=\"HH:MM\" autocomplete=
|
||||
self._verify_editable(self._get_course_details_response(False))
|
||||
|
||||
@mock.patch.dict("django.conf.settings.FEATURES", {'ENABLE_MKTG_SITE': True})
|
||||
@override_settings(MKTG_URLS={'ROOT': 'dummy-root'})
|
||||
def test_course_details_with_enabled_setting_global_staff(self):
|
||||
""" Test that user enrollment end date is editable in response.
|
||||
|
||||
@@ -1170,6 +1172,7 @@ id=\"course-enrollment-end-time\" value=\"\" placeholder=\"HH:MM\" autocomplete=
|
||||
self._verify_editable(self._get_course_details_response(True))
|
||||
|
||||
@mock.patch.dict("django.conf.settings.FEATURES", {'ENABLE_MKTG_SITE': True})
|
||||
@override_settings(MKTG_URLS={'ROOT': 'dummy-root'})
|
||||
def test_course_details_with_enabled_setting_non_global_staff(self):
|
||||
""" Test that user enrollment end date is not editable in response.
|
||||
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
import collections
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import mock
|
||||
from pytz import UTC
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase
|
||||
@@ -20,53 +18,6 @@ from contentstore.tests.utils import CourseTestCase
|
||||
class LMSLinksTestCase(TestCase):
|
||||
""" Tests for LMS links. """
|
||||
|
||||
def about_page_test(self):
|
||||
""" Get URL for about page, no marketing site """
|
||||
# default for ENABLE_MKTG_SITE is False.
|
||||
self.assertEquals(self.get_about_page_link(), "//localhost:8000/courses/mitX/101/test/about")
|
||||
|
||||
@override_settings(MKTG_URLS={'ROOT': 'dummy-root'})
|
||||
def about_page_marketing_site_test(self):
|
||||
""" Get URL for about page, marketing root present. """
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': True}):
|
||||
self.assertEquals(self.get_about_page_link(), "//dummy-root/courses/mitX/101/test/about")
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': False}):
|
||||
self.assertEquals(self.get_about_page_link(), "//localhost:8000/courses/mitX/101/test/about")
|
||||
|
||||
@override_settings(MKTG_URLS={'ROOT': 'http://www.dummy'})
|
||||
def about_page_marketing_site_remove_http_test(self):
|
||||
""" Get URL for about page, marketing root present, remove http://. """
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': True}):
|
||||
self.assertEquals(self.get_about_page_link(), "//www.dummy/courses/mitX/101/test/about")
|
||||
|
||||
@override_settings(MKTG_URLS={'ROOT': 'https://www.dummy'})
|
||||
def about_page_marketing_site_remove_https_test(self):
|
||||
""" Get URL for about page, marketing root present, remove https://. """
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': True}):
|
||||
self.assertEquals(self.get_about_page_link(), "//www.dummy/courses/mitX/101/test/about")
|
||||
|
||||
@override_settings(MKTG_URLS={'ROOT': 'www.dummyhttps://x'})
|
||||
def about_page_marketing_site_https__edge_test(self):
|
||||
""" Get URL for about page, only remove https:// at the beginning of the string. """
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': True}):
|
||||
self.assertEquals(self.get_about_page_link(), "//www.dummyhttps://x/courses/mitX/101/test/about")
|
||||
|
||||
@override_settings(MKTG_URLS={})
|
||||
def about_page_marketing_urls_not_set_test(self):
|
||||
""" Error case. ENABLE_MKTG_SITE is True, but there is either no MKTG_URLS, or no MKTG_URLS Root property. """
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': True}):
|
||||
self.assertEquals(self.get_about_page_link(), None)
|
||||
|
||||
@override_settings(LMS_BASE=None)
|
||||
def about_page_no_lms_base_test(self):
|
||||
""" No LMS_BASE, nor is ENABLE_MKTG_SITE True """
|
||||
self.assertEquals(self.get_about_page_link(), None)
|
||||
|
||||
def get_about_page_link(self):
|
||||
""" create mock course and return the about page link """
|
||||
course_key = SlashSeparatedCourseKey('mitX', '101', 'test')
|
||||
return utils.get_lms_link_for_about_page(course_key)
|
||||
|
||||
def lms_link_test(self):
|
||||
""" Tests get_lms_link_for_item. """
|
||||
course_key = SlashSeparatedCourseKey('mitX', '101', 'test')
|
||||
|
||||
@@ -104,42 +104,6 @@ def get_lms_link_for_item(location, preview=False):
|
||||
)
|
||||
|
||||
|
||||
def get_lms_link_for_about_page(course_key):
|
||||
"""
|
||||
Returns the url to the course about page from the location tuple.
|
||||
"""
|
||||
|
||||
assert isinstance(course_key, CourseKey)
|
||||
|
||||
if settings.FEATURES.get('ENABLE_MKTG_SITE', False):
|
||||
if not hasattr(settings, 'MKTG_URLS'):
|
||||
log.exception("ENABLE_MKTG_SITE is True, but MKTG_URLS is not defined.")
|
||||
return None
|
||||
|
||||
marketing_urls = settings.MKTG_URLS
|
||||
|
||||
# Root will be "https://www.edx.org". The complete URL will still not be exactly correct,
|
||||
# but redirects exist from www.edx.org to get to the Drupal course about page URL.
|
||||
about_base = marketing_urls.get('ROOT', None)
|
||||
|
||||
if about_base is None:
|
||||
log.exception('There is no ROOT defined in MKTG_URLS')
|
||||
return None
|
||||
|
||||
# Strip off https:// (or http://) to be consistent with the formatting of LMS_BASE.
|
||||
about_base = re.sub(r"^https?://", "", about_base)
|
||||
|
||||
elif settings.LMS_BASE is not None:
|
||||
about_base = settings.LMS_BASE
|
||||
else:
|
||||
return None
|
||||
|
||||
return u"//{about_base_url}/courses/{course_key}/about".format(
|
||||
about_base_url=about_base,
|
||||
course_key=course_key.to_deprecated_string()
|
||||
)
|
||||
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
def get_lms_link_for_certificate_web_view(user_id, course_key, mode):
|
||||
"""
|
||||
|
||||
@@ -28,7 +28,6 @@ from .component import (
|
||||
from .item import create_xblock_info
|
||||
from .library import LIBRARIES_ENABLED
|
||||
from ccx_keys.locator import CCXLocator
|
||||
from contentstore import utils
|
||||
from contentstore.course_group_config import (
|
||||
COHORT_SCHEME,
|
||||
GroupConfiguration,
|
||||
@@ -77,6 +76,7 @@ from student.auth import has_course_author_access, has_studio_write_access, has_
|
||||
from student.roles import (
|
||||
CourseInstructorRole, CourseStaffRole, CourseCreatorRole, GlobalStaff, UserBasedRole
|
||||
)
|
||||
from util.course import get_lms_link_for_about_page
|
||||
from util.date_utils import get_default_time_display
|
||||
from util.json_request import JsonResponse, JsonResponseBadRequest, expect_json
|
||||
from util.milestones_helpers import (
|
||||
@@ -996,7 +996,7 @@ def settings_handler(request, course_key_string):
|
||||
settings_context = {
|
||||
'context_course': course_module,
|
||||
'course_locator': course_key,
|
||||
'lms_link_for_about_page': utils.get_lms_link_for_about_page(course_key),
|
||||
'lms_link_for_about_page': get_lms_link_for_about_page(course_key),
|
||||
'course_image_url': course_image_url(course_module, 'course_image'),
|
||||
'banner_image_url': course_image_url(course_module, 'banner_image'),
|
||||
'video_thumbnail_image_url': course_image_url(course_module, 'video_thumbnail_image'),
|
||||
|
||||
@@ -138,6 +138,7 @@ EMAIL_PORT = ENV_TOKENS.get('EMAIL_PORT', EMAIL_PORT)
|
||||
EMAIL_USE_TLS = ENV_TOKENS.get('EMAIL_USE_TLS', EMAIL_USE_TLS)
|
||||
|
||||
LMS_BASE = ENV_TOKENS.get('LMS_BASE')
|
||||
LMS_ROOT_URL = ENV_TOKENS.get('LMS_ROOT_URL')
|
||||
# Note that FEATURES['PREVIEW_LMS_BASE'] gets read in from the environment file.
|
||||
|
||||
SITE_NAME = ENV_TOKENS['SITE_NAME']
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
"STORAGE_TYPE": "localfs"
|
||||
},
|
||||
"LMS_BASE": "localhost:8003",
|
||||
"LMS_ROOT_URL": "http://localhost:8003",
|
||||
"LOCAL_LOGLEVEL": "INFO",
|
||||
"LOGGING_ENV": "sandbox",
|
||||
"LOG_DIR": "** OVERRIDDEN **",
|
||||
|
||||
@@ -120,6 +120,8 @@ MOCK_SEARCH_BACKING_FILE = (
|
||||
# this secret key should be the same as lms/envs/bok_choy.py's
|
||||
SECRET_KEY = "very_secret_bok_choy_key"
|
||||
|
||||
LMS_ROOT_URL = "http://localhost:8000"
|
||||
|
||||
#####################################################################
|
||||
# Lastly, see if the developer has any local overrides.
|
||||
try:
|
||||
|
||||
@@ -296,6 +296,7 @@ AUTHENTICATION_BACKENDS = (
|
||||
)
|
||||
|
||||
LMS_BASE = None
|
||||
LMS_ROOT_URL = "http://localhost:8000"
|
||||
|
||||
# These are standard regexes for pulling out info like course_ids, usage_ids, etc.
|
||||
# They are used so that URLs with deprecated-format strings still work.
|
||||
|
||||
@@ -60,6 +60,7 @@ DATABASES = {
|
||||
}
|
||||
|
||||
LMS_BASE = "localhost:8000"
|
||||
LMS_ROOT_URL = "http://{}".format(LMS_BASE)
|
||||
FEATURES['PREVIEW_LMS_BASE'] = "localhost:8000"
|
||||
|
||||
REPOS = {
|
||||
|
||||
@@ -31,6 +31,7 @@ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
################################# LMS INTEGRATION #############################
|
||||
|
||||
LMS_BASE = "localhost:8000"
|
||||
LMS_ROOT_URL = "http://{}".format(LMS_BASE)
|
||||
FEATURES['PREVIEW_LMS_BASE'] = "preview." + LMS_BASE
|
||||
|
||||
########################### PIPELINE #################################
|
||||
|
||||
@@ -141,6 +141,7 @@ if os.environ.get('DISABLE_MIGRATIONS'):
|
||||
MIGRATION_MODULES = NoOpMigrationModules()
|
||||
|
||||
LMS_BASE = "localhost:8000"
|
||||
LMS_ROOT_URL = "http://{}".format(LMS_BASE)
|
||||
FEATURES['PREVIEW_LMS_BASE'] = "preview.localhost"
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ Module with code executed during Studio startup
|
||||
from django.conf import settings
|
||||
|
||||
# Force settings to run so that the python path is modified
|
||||
|
||||
settings.INSTALLED_APPS # pylint: disable=pointless-statement
|
||||
|
||||
from openedx.core.lib.django_startup import autostartup
|
||||
@@ -18,6 +19,7 @@ from openedx.core.lib.xblock_utils import xblock_local_resource_url
|
||||
import xmodule.x_module
|
||||
import cms.lib.xblock.runtime
|
||||
|
||||
from startup_configurations.validate_config import validate_cms_config
|
||||
from openedx.core.djangoapps.theming.core import enable_theming
|
||||
from openedx.core.djangoapps.theming.helpers import is_comprehensive_theming_enabled
|
||||
|
||||
@@ -47,6 +49,9 @@ def run():
|
||||
xmodule.x_module.descriptor_global_handler_url = cms.lib.xblock.runtime.handler_url
|
||||
xmodule.x_module.descriptor_global_local_resource_url = xblock_local_resource_url
|
||||
|
||||
# validate configurations on startup
|
||||
validate_cms_config(settings)
|
||||
|
||||
|
||||
def add_mimetypes():
|
||||
"""
|
||||
|
||||
42
common/djangoapps/startup_configurations/validate_config.py
Normal file
42
common/djangoapps/startup_configurations/validate_config.py
Normal file
@@ -0,0 +1,42 @@
|
||||
"""
|
||||
Common Functions to Validate Configurations
|
||||
"""
|
||||
|
||||
|
||||
def validate_lms_config(settings):
|
||||
"""
|
||||
Validates configurations for lms and raise ValueError if not valid
|
||||
"""
|
||||
validate_common_config(settings)
|
||||
|
||||
# validate feature based configurations
|
||||
validate_marketing_site_config(settings)
|
||||
|
||||
|
||||
def validate_cms_config(settings):
|
||||
"""
|
||||
Validates configurations for lms and raise ValueError if not valid
|
||||
"""
|
||||
validate_common_config(settings)
|
||||
|
||||
# validate feature based configurations
|
||||
validate_marketing_site_config(settings)
|
||||
|
||||
|
||||
def validate_common_config(settings):
|
||||
"""
|
||||
Validates configurations common for all apps
|
||||
"""
|
||||
if not getattr(settings, 'LMS_ROOT_URL', None):
|
||||
raise ValueError("'LMS_ROOT_URL' is not defined.")
|
||||
|
||||
|
||||
def validate_marketing_site_config(settings):
|
||||
"""
|
||||
Validates 'marketing site' related configurations
|
||||
"""
|
||||
if settings.FEATURES.get('ENABLE_MKTG_SITE'):
|
||||
if not hasattr(settings, 'MKTG_URLS'):
|
||||
raise ValueError("'ENABLE_MKTG_SITE' is True, but 'MKTG_URLS' is not defined.")
|
||||
if not settings.MKTG_URLS.get('ROOT'):
|
||||
raise ValueError("There is no 'ROOT' defined in 'MKTG_URLS'.")
|
||||
28
common/djangoapps/util/course.py
Normal file
28
common/djangoapps/util/course.py
Normal file
@@ -0,0 +1,28 @@
|
||||
"""
|
||||
Utility methods related to course
|
||||
"""
|
||||
import logging
|
||||
from django.conf import settings
|
||||
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_lms_link_for_about_page(course_key):
|
||||
"""
|
||||
Returns the url to the course about page.
|
||||
"""
|
||||
assert isinstance(course_key, CourseKey)
|
||||
|
||||
if settings.FEATURES.get('ENABLE_MKTG_SITE'):
|
||||
# Root will be "https://www.edx.org". The complete URL will still not be exactly correct,
|
||||
# but redirects exist from www.edx.org to get to the Drupal course about page URL.
|
||||
about_base = settings.MKTG_URLS['ROOT']
|
||||
else:
|
||||
about_base = settings.LMS_ROOT_URL
|
||||
|
||||
return u"{about_base_url}/courses/{course_key}/about".format(
|
||||
about_base_url=about_base,
|
||||
course_key=course_key.to_deprecated_string()
|
||||
)
|
||||
36
common/djangoapps/util/tests/test_course.py
Normal file
36
common/djangoapps/util/tests/test_course.py
Normal file
@@ -0,0 +1,36 @@
|
||||
"""
|
||||
Tests for course utils.
|
||||
"""
|
||||
|
||||
from django.test import TestCase, override_settings
|
||||
import mock
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from util.course import get_lms_link_for_about_page
|
||||
|
||||
|
||||
class LmsLinksTestCase(TestCase):
|
||||
""" Tests for LMS links. """
|
||||
|
||||
def test_about_page(self):
|
||||
""" Get URL for about page, no marketing site """
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': False}):
|
||||
self.assertEquals(self.get_about_page_link(), "http://localhost:8000/courses/mitX/101/test/about")
|
||||
|
||||
@override_settings(MKTG_URLS={'ROOT': 'https://dummy-root'})
|
||||
def test_about_page_marketing_site(self):
|
||||
""" Get URL for about page, marketing root present. """
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': True}):
|
||||
self.assertEquals(self.get_about_page_link(), "https://dummy-root/courses/mitX/101/test/about")
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': False}):
|
||||
self.assertEquals(self.get_about_page_link(), "http://localhost:8000/courses/mitX/101/test/about")
|
||||
|
||||
@override_settings(MKTG_URLS={'ROOT': 'https://www.dummyhttps://x'})
|
||||
def test_about_page_marketing_site_https__edge(self):
|
||||
""" Get URL for about page """
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': True}):
|
||||
self.assertEquals(self.get_about_page_link(), "https://www.dummyhttps://x/courses/mitX/101/test/about")
|
||||
|
||||
def get_about_page_link(self):
|
||||
""" create mock course and return the about page link."""
|
||||
course_key = SlashSeparatedCourseKey('mitX', '101', 'test')
|
||||
return get_lms_link_for_about_page(course_key)
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Milestone related tests for the mobile_api
|
||||
"""
|
||||
from django.conf import settings
|
||||
from mock import patch
|
||||
|
||||
from courseware.access_response import MilestoneError
|
||||
@@ -26,14 +27,22 @@ class MobileAPIMilestonesMixin(object):
|
||||
|
||||
ALLOW_ACCESS_TO_MILESTONE_COURSE = False # pylint: disable=invalid-name
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_PREREQUISITE_COURSES': True, 'MILESTONES_APP': True})
|
||||
@patch.dict(settings.FEATURES, {
|
||||
'ENABLE_PREREQUISITE_COURSES': True,
|
||||
'MILESTONES_APP': True,
|
||||
'ENABLE_MKTG_SITE': True,
|
||||
})
|
||||
def test_unfulfilled_prerequisite_course(self):
|
||||
""" Tests the case for an unfulfilled pre-requisite course """
|
||||
self._add_prerequisite_course()
|
||||
self.init_course_access()
|
||||
self._verify_unfulfilled_milestone_response()
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_PREREQUISITE_COURSES': True, 'MILESTONES_APP': True})
|
||||
@patch.dict(settings.FEATURES, {
|
||||
'ENABLE_PREREQUISITE_COURSES': True,
|
||||
'MILESTONES_APP': True,
|
||||
'ENABLE_MKTG_SITE': True,
|
||||
})
|
||||
def test_unfulfilled_prerequisite_course_for_staff(self):
|
||||
self._add_prerequisite_course()
|
||||
self.user.is_staff = True
|
||||
@@ -41,7 +50,11 @@ class MobileAPIMilestonesMixin(object):
|
||||
self.init_course_access()
|
||||
self.api_response()
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_PREREQUISITE_COURSES': True, 'MILESTONES_APP': True})
|
||||
@patch.dict(settings.FEATURES, {
|
||||
'ENABLE_PREREQUISITE_COURSES': True,
|
||||
'MILESTONES_APP': True,
|
||||
'ENABLE_MKTG_SITE': True,
|
||||
})
|
||||
def test_fulfilled_prerequisite_course(self):
|
||||
"""
|
||||
Tests the case when a user fulfills existing pre-requisite course
|
||||
@@ -52,7 +65,11 @@ class MobileAPIMilestonesMixin(object):
|
||||
self.init_course_access()
|
||||
self.api_response()
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENTRANCE_EXAMS': True, 'MILESTONES_APP': True})
|
||||
@patch.dict(settings.FEATURES, {
|
||||
'ENTRANCE_EXAMS': True,
|
||||
'MILESTONES_APP': True,
|
||||
'ENABLE_MKTG_SITE': True,
|
||||
})
|
||||
def test_unpassed_entrance_exam(self):
|
||||
"""
|
||||
Tests the case where the user has not passed the entrance exam
|
||||
@@ -61,7 +78,11 @@ class MobileAPIMilestonesMixin(object):
|
||||
self.init_course_access()
|
||||
self._verify_unfulfilled_milestone_response()
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENTRANCE_EXAMS': True, 'MILESTONES_APP': True})
|
||||
@patch.dict(settings.FEATURES, {
|
||||
'ENTRANCE_EXAMS': True,
|
||||
'MILESTONES_APP': True,
|
||||
'ENABLE_MKTG_SITE': True,
|
||||
})
|
||||
def test_unpassed_entrance_exam_for_staff(self):
|
||||
self._add_entrance_exam()
|
||||
self.user.is_staff = True
|
||||
@@ -69,7 +90,11 @@ class MobileAPIMilestonesMixin(object):
|
||||
self.init_course_access()
|
||||
self.api_response()
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENTRANCE_EXAMS': True, 'MILESTONES_APP': True})
|
||||
@patch.dict(settings.FEATURES, {
|
||||
'ENTRANCE_EXAMS': True,
|
||||
'MILESTONES_APP': True,
|
||||
'ENABLE_MKTG_SITE': True,
|
||||
})
|
||||
def test_passed_entrance_exam(self):
|
||||
"""
|
||||
Tests access when user has passed the entrance exam
|
||||
|
||||
@@ -11,6 +11,7 @@ Test utilities for mobile API tests:
|
||||
"""
|
||||
# pylint: disable=no-member
|
||||
from datetime import timedelta
|
||||
from django.conf import settings
|
||||
|
||||
from django.utils import timezone
|
||||
import ddt
|
||||
@@ -153,6 +154,7 @@ class MobileCourseAccessTestMixin(MobileAPIMilestonesMixin):
|
||||
"""Base implementation of initializing the user for each test."""
|
||||
self.login_and_enroll(course_id)
|
||||
|
||||
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
|
||||
def test_success(self):
|
||||
self.init_course_access()
|
||||
|
||||
@@ -166,7 +168,7 @@ class MobileCourseAccessTestMixin(MobileAPIMilestonesMixin):
|
||||
response = self.api_response(expected_response_code=None, course_id=non_existent_course_id)
|
||||
self.verify_failure(response) # allow subclasses to override verification
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
|
||||
@patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False, 'ENABLE_MKTG_SITE': True})
|
||||
def test_unreleased_course(self):
|
||||
# ensure the course always starts in the future
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
@@ -184,6 +186,7 @@ class MobileCourseAccessTestMixin(MobileAPIMilestonesMixin):
|
||||
(None, False)
|
||||
)
|
||||
@ddt.unpack
|
||||
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
|
||||
def test_non_mobile_available(self, role, should_succeed):
|
||||
self.init_course_access()
|
||||
# set mobile_available to False for the test course
|
||||
@@ -202,6 +205,7 @@ class MobileCourseAccessTestMixin(MobileAPIMilestonesMixin):
|
||||
(None, False)
|
||||
)
|
||||
@ddt.unpack
|
||||
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
|
||||
def test_visible_to_staff_only_course(self, role, should_succeed):
|
||||
self.init_course_access()
|
||||
self.course.visible_to_staff_only = True
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
"""
|
||||
Serializer for user API
|
||||
"""
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from rest_framework import serializers
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
from courseware.access import has_access
|
||||
from student.models import CourseEnrollment, User
|
||||
from certificates.api import certificate_downloadable_status
|
||||
from util.course import get_lms_link_for_about_page
|
||||
|
||||
|
||||
class CourseOverviewField(serializers.RelatedField):
|
||||
@@ -50,11 +52,7 @@ class CourseOverviewField(serializers.RelatedField):
|
||||
}
|
||||
},
|
||||
'course_image': course_overview.course_image_url,
|
||||
'course_about': reverse(
|
||||
'about_course',
|
||||
kwargs={'course_id': course_id},
|
||||
request=request,
|
||||
),
|
||||
'course_about': get_lms_link_for_about_page(CourseKey.from_string(course_id)),
|
||||
'course_updates': reverse(
|
||||
'course-updates-list',
|
||||
kwargs={'course_id': course_id},
|
||||
|
||||
@@ -11,7 +11,7 @@ import pytz
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
from django.template import defaultfilters
|
||||
from django.test import RequestFactory
|
||||
from django.test import RequestFactory, override_settings
|
||||
from milestones.tests.utils import MilestonesTestCaseMixin
|
||||
from xmodule.course_module import DEFAULT_START_DATE
|
||||
from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory
|
||||
@@ -73,6 +73,7 @@ class TestUserInfoApi(MobileAPITestCase, MobileAuthTestMixin):
|
||||
|
||||
@attr('shard_2')
|
||||
@ddt.ddt
|
||||
@override_settings(MKTG_URLS={'ROOT': 'dummy-root'})
|
||||
class TestUserEnrollmentApi(UrlResetMixin, MobileAPITestCase, MobileAuthUserTestMixin,
|
||||
MobileCourseAccessTestMixin, MilestonesTestCaseMixin):
|
||||
"""
|
||||
@@ -86,7 +87,7 @@ class TestUserEnrollmentApi(UrlResetMixin, MobileAPITestCase, MobileAuthUserTest
|
||||
LAST_WEEK = datetime.datetime.now(pytz.UTC) - datetime.timedelta(days=7)
|
||||
ADVERTISED_START = "Spring 2016"
|
||||
|
||||
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
|
||||
@patch.dict(settings.FEATURES, {"ENABLE_DISCUSSION_SERVICE": True})
|
||||
def setUp(self, *args, **kwargs):
|
||||
super(TestUserEnrollmentApi, self).setUp()
|
||||
|
||||
@@ -117,6 +118,7 @@ class TestUserEnrollmentApi(UrlResetMixin, MobileAPITestCase, MobileAuthUserTest
|
||||
courses = response.data
|
||||
self.assertEqual(len(courses), 0)
|
||||
|
||||
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
|
||||
def test_sort_order(self):
|
||||
self.login()
|
||||
|
||||
@@ -134,9 +136,12 @@ class TestUserEnrollmentApi(UrlResetMixin, MobileAPITestCase, MobileAuthUserTest
|
||||
unicode(courses[num_courses - course_index - 1].id)
|
||||
)
|
||||
|
||||
@patch.dict(
|
||||
settings.FEATURES, {'ENABLE_PREREQUISITE_COURSES': True, 'MILESTONES_APP': True, 'DISABLE_START_DATES': False}
|
||||
)
|
||||
@patch.dict(settings.FEATURES, {
|
||||
'ENABLE_PREREQUISITE_COURSES': True,
|
||||
'MILESTONES_APP': True,
|
||||
'DISABLE_START_DATES': False,
|
||||
'ENABLE_MKTG_SITE': True,
|
||||
})
|
||||
def test_courseware_access(self):
|
||||
self.login()
|
||||
|
||||
@@ -181,7 +186,7 @@ class TestUserEnrollmentApi(UrlResetMixin, MobileAPITestCase, MobileAuthUserTest
|
||||
(DEFAULT_START_DATE, None, None, "empty"),
|
||||
)
|
||||
@ddt.unpack
|
||||
@patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
|
||||
@patch.dict(settings.FEATURES, {'DISABLE_START_DATES': False, 'ENABLE_MKTG_SITE': True})
|
||||
def test_start_type_and_display(self, start, advertised_start, expected_display, expected_type):
|
||||
"""
|
||||
Tests that the correct start_type and start_display are returned in the
|
||||
@@ -195,6 +200,7 @@ class TestUserEnrollmentApi(UrlResetMixin, MobileAPITestCase, MobileAuthUserTest
|
||||
self.assertEqual(response.data[0]['course']['start_type'], expected_type)
|
||||
self.assertEqual(response.data[0]['course']['start_display'], expected_display)
|
||||
|
||||
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
|
||||
def test_no_certificate(self):
|
||||
self.login_and_enroll()
|
||||
|
||||
@@ -222,21 +228,21 @@ class TestUserEnrollmentApi(UrlResetMixin, MobileAPITestCase, MobileAuthUserTest
|
||||
certificate_data = response.data[0]['certificate']
|
||||
self.assertEquals(certificate_data['url'], certificate_url)
|
||||
|
||||
@patch.dict(settings.FEATURES, {'CERTIFICATES_HTML_VIEW': False})
|
||||
@patch.dict(settings.FEATURES, {'CERTIFICATES_HTML_VIEW': False, 'ENABLE_MKTG_SITE': True})
|
||||
def test_pdf_certificate_with_html_cert_disabled(self):
|
||||
"""
|
||||
Tests PDF certificates with CERTIFICATES_HTML_VIEW set to False.
|
||||
"""
|
||||
self.verify_pdf_certificate()
|
||||
|
||||
@patch.dict(settings.FEATURES, {'CERTIFICATES_HTML_VIEW': True})
|
||||
@patch.dict(settings.FEATURES, {'CERTIFICATES_HTML_VIEW': True, 'ENABLE_MKTG_SITE': True})
|
||||
def test_pdf_certificate_with_html_cert_enabled(self):
|
||||
"""
|
||||
Tests PDF certificates with CERTIFICATES_HTML_VIEW set to True.
|
||||
"""
|
||||
self.verify_pdf_certificate()
|
||||
|
||||
@patch.dict(settings.FEATURES, {'CERTIFICATES_HTML_VIEW': True})
|
||||
@patch.dict(settings.FEATURES, {'CERTIFICATES_HTML_VIEW': True, 'ENABLE_MKTG_SITE': True})
|
||||
def test_web_certificate(self):
|
||||
CourseMode.objects.create(
|
||||
course_id=self.course.id,
|
||||
@@ -261,7 +267,7 @@ class TestUserEnrollmentApi(UrlResetMixin, MobileAPITestCase, MobileAuthUserTest
|
||||
)
|
||||
)
|
||||
|
||||
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
|
||||
@patch.dict(settings.FEATURES, {"ENABLE_DISCUSSION_SERVICE": True, 'ENABLE_MKTG_SITE': True})
|
||||
def test_discussion_url(self):
|
||||
self.login_and_enroll()
|
||||
|
||||
@@ -430,6 +436,8 @@ class TestCourseStatusPATCH(CourseStatusAPITestCase, MobileAuthUserTestMixin,
|
||||
|
||||
|
||||
@attr('shard_2')
|
||||
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
|
||||
@override_settings(MKTG_URLS={'ROOT': 'dummy-root'})
|
||||
class TestCourseEnrollmentSerializer(MobileAPITestCase, MilestonesTestCaseMixin):
|
||||
"""
|
||||
Test the course enrollment serializer
|
||||
|
||||
@@ -188,6 +188,8 @@ REGISTRATION_EMAIL_PATTERNS_ALLOWED = ENV_TOKENS.get('REGISTRATION_EMAIL_PATTERN
|
||||
EDXMKTG_LOGGED_IN_COOKIE_NAME = ENV_TOKENS.get('EDXMKTG_LOGGED_IN_COOKIE_NAME', EDXMKTG_LOGGED_IN_COOKIE_NAME)
|
||||
EDXMKTG_USER_INFO_COOKIE_NAME = ENV_TOKENS.get('EDXMKTG_USER_INFO_COOKIE_NAME', EDXMKTG_USER_INFO_COOKIE_NAME)
|
||||
|
||||
LMS_ROOT_URL = ENV_TOKENS.get('LMS_ROOT_URL')
|
||||
|
||||
ENV_FEATURES = ENV_TOKENS.get('FEATURES', {})
|
||||
for feature, value in ENV_FEATURES.items():
|
||||
FEATURES[feature] = value
|
||||
|
||||
@@ -96,6 +96,7 @@
|
||||
"JWT_SECRET_KEY": "super-secret-key"
|
||||
},
|
||||
"LMS_BASE": "localhost:8003",
|
||||
"LMS_ROOT_URL": "http://localhost:8003",
|
||||
"LOCAL_LOGLEVEL": "INFO",
|
||||
"LOGGING_ENV": "sandbox",
|
||||
"LOG_DIR": "** OVERRIDDEN **",
|
||||
|
||||
@@ -193,6 +193,8 @@ BADGING_BACKEND = 'lms.djangoapps.badges.backends.tests.dummy_backend.DummyBacke
|
||||
ECOMMERCE_API_URL = 'http://localhost:8043/api/v2/'
|
||||
ECOMMERCE_API_SIGNING_KEY = 'ecommerce-key'
|
||||
|
||||
LMS_ROOT_URL = "http://localhost:8000"
|
||||
|
||||
#####################################################################
|
||||
# Lastly, see if the developer has any local overrides.
|
||||
try:
|
||||
|
||||
@@ -60,6 +60,7 @@ DISCUSSION_SETTINGS = {
|
||||
'MAX_COMMENT_DEPTH': 2,
|
||||
}
|
||||
|
||||
LMS_ROOT_URL = "http://localhost:8000"
|
||||
|
||||
# Features
|
||||
FEATURES = {
|
||||
|
||||
@@ -27,6 +27,7 @@ FEATURES['AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING'] = True
|
||||
FEATURES['ENABLE_GRADE_DOWNLOADS'] = True
|
||||
FEATURES['ENABLE_PAYMENT_FAKE'] = True
|
||||
|
||||
LMS_ROOT_URL = "http://localhost:8000"
|
||||
|
||||
FEEDBACK_SUBMISSION_EMAIL = "dummy@example.com"
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ PLATFORM_NAME = ENV_TOKENS.get('PLATFORM_NAME', 'Devstack')
|
||||
CELERY_ALWAYS_EAGER = True
|
||||
HTTPS = 'off'
|
||||
|
||||
LMS_ROOT_URL = 'http://localhost:8000'
|
||||
|
||||
################################ LOGGERS ######################################
|
||||
|
||||
# Silence noisy logs
|
||||
|
||||
@@ -585,3 +585,5 @@ OAUTH2_PROVIDER_APPLICATION_MODEL = 'oauth2_provider.Application'
|
||||
COURSE_CATALOG_API_URL = 'https://catalog.example.com/api/v1'
|
||||
|
||||
COMPREHENSIVE_THEME_DIRS = [REPO_ROOT / "themes", REPO_ROOT / "common/test"]
|
||||
|
||||
LMS_ROOT_URL = "http://localhost:8000"
|
||||
|
||||
@@ -6,6 +6,7 @@ import django
|
||||
from django.conf import settings
|
||||
|
||||
# Force settings to run so that the python path is modified
|
||||
|
||||
settings.INSTALLED_APPS # pylint: disable=pointless-statement
|
||||
|
||||
from openedx.core.lib.django_startup import autostartup
|
||||
@@ -20,6 +21,7 @@ from monkey_patch import (
|
||||
import xmodule.x_module
|
||||
import lms_xblock.runtime
|
||||
|
||||
from startup_configurations.validate_config import validate_lms_config
|
||||
from openedx.core.djangoapps.theming.core import enable_theming
|
||||
from openedx.core.djangoapps.theming.helpers import is_comprehensive_theming_enabled
|
||||
|
||||
@@ -82,6 +84,9 @@ def run():
|
||||
xmodule.x_module.descriptor_global_handler_url = lms_xblock.runtime.handler_url
|
||||
xmodule.x_module.descriptor_global_local_resource_url = lms_xblock.runtime.local_resource_url
|
||||
|
||||
# validate configurations on startup
|
||||
validate_lms_config(settings)
|
||||
|
||||
|
||||
def add_mimetypes():
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user