From bf26b09265787c04cbd952f8dd6ecc75286756ad Mon Sep 17 00:00:00 2001 From: Chris Dodge Date: Wed, 30 Sep 2015 10:10:23 -0400 Subject: [PATCH 1/4] update reference to edx-proctoring to account for requested iconography changes from UX team. Also update test to conform with changes --- lms/djangoapps/courseware/tests/test_module_render.py | 2 +- requirements/edx/github.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lms/djangoapps/courseware/tests/test_module_render.py b/lms/djangoapps/courseware/tests/test_module_render.py index e6b0a5c55c..4afe1e86a3 100644 --- a/lms/djangoapps/courseware/tests/test_module_render.py +++ b/lms/djangoapps/courseware/tests/test_module_render.py @@ -729,7 +729,7 @@ class TestProctoringRendering(ModuleStoreTestCase): { 'status': 'eligible', 'short_description': 'Ungraded Practice Exam', - 'suggested_icon': 'fa-pencil-square-o', + 'suggested_icon': '', 'in_completed_state': False } ), diff --git a/requirements/edx/github.txt b/requirements/edx/github.txt index 1807154724..11354377a8 100644 --- a/requirements/edx/github.txt +++ b/requirements/edx/github.txt @@ -58,7 +58,7 @@ git+https://github.com/edx/edx-lint.git@c5745631d2eee4e2efe8c31fa7b42fe2c12a0755 git+https://github.com/edx/ecommerce-api-client.git@1.1.0#egg=ecommerce-api-client==1.1.0 -e git+https://github.com/edx/edx-user-state-client.git@30c0ad4b9f57f8d48d6943eb585ec8a9205f4469#egg=edx-user-state-client git+https://github.com/edx/edx-organizations.git@release-2015-09-22#egg=edx-organizations==0.1.6 -git+https://github.com/edx/edx-proctoring.git@0.9.11#egg=edx-proctoring==0.9.11 +git+https://github.com/edx/edx-proctoring.git@0.9.14#egg=edx-proctoring==0.9.14 # Third Party XBlocks -e git+https://github.com/mitodl/edx-sga@172a90fd2738f8142c10478356b2d9ed3e55334a#egg=edx-sga From aa8ecca53628b1d65398c330b7ea9cb308c01dc5 Mon Sep 17 00:00:00 2001 From: David Baumgold Date: Tue, 29 Sep 2015 16:25:01 -0400 Subject: [PATCH 2/4] Remove the edx.org comprehensive theme There's a lot of useful things in PR #8271 that provide a framework for the comprehensive theming system. If we need to remove the edx.org theme from the codebase, we can leave most of PR #8271 in, to make it easier to build on top of and get this feature back in. --- cms/templates/widgets/header.html | 6 +- .../acceptance/pages/lms/learner_profile.py | 2 +- lms/djangoapps/branding/__init__.py | 2 +- lms/envs/aws.py | 5 +- lms/envs/common.py | 2 +- .../default-profile_120.png} | Bin .../default-profile_30.png} | Bin .../default-profile_50.png} | Bin .../default-profile_500.png} | Bin .../images/{ => default-theme}/logo-large.png | Bin .../images/{ => default-theme}/logo.png | Bin .../static/images/edx-theme}/default_120.png | Bin .../static/images/edx-theme}/default_30.png | Bin .../static/images/edx-theme}/default_50.png | Bin .../static/images/edx-theme}/default_500.png | Bin .../images/edx-theme/edx-header-logo.png | Bin .../static/images/edx-theme/edx-logo-bw.png | Bin lms/templates/courseware/course_about.html | 2 +- ...e-analytics.html => google_analytics.html} | 0 lms/templates/main.html | 52 ++++-- lms/templates/themable-footer.html | 13 -- themes/README.rst | 22 --- themes/edx.org/lms/templates/footer.html | 81 --------- themes/edx.org/lms/templates/header.html | 157 ------------------ 24 files changed, 54 insertions(+), 290 deletions(-) rename lms/static/images/{profiles/default_120.png => default-theme/default-profile_120.png} (100%) rename lms/static/images/{profiles/default_30.png => default-theme/default-profile_30.png} (100%) rename lms/static/images/{profiles/default_50.png => default-theme/default-profile_50.png} (100%) rename lms/static/images/{profiles/default_500.png => default-theme/default-profile_500.png} (100%) rename lms/static/images/{ => default-theme}/logo-large.png (100%) rename lms/static/images/{ => default-theme}/logo.png (100%) rename {themes/edx.org/lms/static/images/profiles => lms/static/images/edx-theme}/default_120.png (100%) rename {themes/edx.org/lms/static/images/profiles => lms/static/images/edx-theme}/default_30.png (100%) rename {themes/edx.org/lms/static/images/profiles => lms/static/images/edx-theme}/default_50.png (100%) rename {themes/edx.org/lms/static/images/profiles => lms/static/images/edx-theme}/default_500.png (100%) rename themes/edx.org/lms/static/images/logo.png => lms/static/images/edx-theme/edx-header-logo.png (100%) rename themes/edx.org/lms/static/images/logo-large.png => lms/static/images/edx-theme/edx-logo-bw.png (100%) rename lms/templates/{google-analytics.html => google_analytics.html} (100%) delete mode 100644 lms/templates/themable-footer.html delete mode 100644 themes/edx.org/lms/templates/footer.html delete mode 100644 themes/edx.org/lms/templates/header.html diff --git a/cms/templates/widgets/header.html b/cms/templates/widgets/header.html index 836a618c8f..9257ac5a38 100644 --- a/cms/templates/widgets/header.html +++ b/cms/templates/widgets/header.html @@ -12,7 +12,11 @@

- ${settings.STUDIO_NAME} + % if settings.FEATURES.get('IS_EDX_DOMAIN', False): + ${settings.STUDIO_NAME} + % else: + ${settings.STUDIO_NAME} + % endif

% if context_course: diff --git a/common/test/acceptance/pages/lms/learner_profile.py b/common/test/acceptance/pages/lms/learner_profile.py index 87325be1a7..4b2f08f1eb 100644 --- a/common/test/acceptance/pages/lms/learner_profile.py +++ b/common/test/acceptance/pages/lms/learner_profile.py @@ -175,7 +175,7 @@ class LearnerProfilePage(FieldsMixin, PageObject): """ self.wait_for_field('image') default_links = self.q(css='.image-frame').attrs('src') - return 'profiles/default' in default_links[0] if default_links else False + return 'default-profile' in default_links[0] if default_links else False def mouse_hover(self, element): """ diff --git a/lms/djangoapps/branding/__init__.py b/lms/djangoapps/branding/__init__.py index efe6c93876..e8fa35ee22 100644 --- a/lms/djangoapps/branding/__init__.py +++ b/lms/djangoapps/branding/__init__.py @@ -70,4 +70,4 @@ def get_logo_url(): elif university: return staticfiles_storage.url('images/{uni}-on-edx-logo.png'.format(uni=university)) else: - return staticfiles_storage.url('images/logo.png') + return staticfiles_storage.url('images/default-theme/logo.png') diff --git a/lms/envs/aws.py b/lms/envs/aws.py index 42caf4dd31..0ceb9f0511 100644 --- a/lms/envs/aws.py +++ b/lms/envs/aws.py @@ -682,7 +682,10 @@ PROFILE_IMAGE_BACKEND = ENV_TOKENS.get('PROFILE_IMAGE_BACKEND', PROFILE_IMAGE_BA PROFILE_IMAGE_SECRET_KEY = AUTH_TOKENS.get('PROFILE_IMAGE_SECRET_KEY', PROFILE_IMAGE_SECRET_KEY) PROFILE_IMAGE_MAX_BYTES = ENV_TOKENS.get('PROFILE_IMAGE_MAX_BYTES', PROFILE_IMAGE_MAX_BYTES) PROFILE_IMAGE_MIN_BYTES = ENV_TOKENS.get('PROFILE_IMAGE_MIN_BYTES', PROFILE_IMAGE_MIN_BYTES) -PROFILE_IMAGE_DEFAULT_FILENAME = 'images/profiles/default' +if FEATURES['IS_EDX_DOMAIN']: + PROFILE_IMAGE_DEFAULT_FILENAME = 'images/edx-theme/default-profile' +else: + PROFILE_IMAGE_DEFAULT_FILENAME = ENV_TOKENS.get('PROFILE_IMAGE_DEFAULT_FILENAME', PROFILE_IMAGE_DEFAULT_FILENAME) # EdxNotes config diff --git a/lms/envs/common.py b/lms/envs/common.py index 70e90a1ee7..d9f7675995 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -2601,7 +2601,7 @@ PROFILE_IMAGE_BACKEND = { 'base_url': os.path.join(MEDIA_URL, 'profile-images/'), }, } -PROFILE_IMAGE_DEFAULT_FILENAME = 'images/profiles/default' +PROFILE_IMAGE_DEFAULT_FILENAME = 'images/default-theme/default-profile' PROFILE_IMAGE_DEFAULT_FILE_EXTENSION = 'png' # This secret key is used in generating unguessable URLs to users' # profile images. Once it has been set, changing it will make the diff --git a/lms/static/images/profiles/default_120.png b/lms/static/images/default-theme/default-profile_120.png similarity index 100% rename from lms/static/images/profiles/default_120.png rename to lms/static/images/default-theme/default-profile_120.png diff --git a/lms/static/images/profiles/default_30.png b/lms/static/images/default-theme/default-profile_30.png similarity index 100% rename from lms/static/images/profiles/default_30.png rename to lms/static/images/default-theme/default-profile_30.png diff --git a/lms/static/images/profiles/default_50.png b/lms/static/images/default-theme/default-profile_50.png similarity index 100% rename from lms/static/images/profiles/default_50.png rename to lms/static/images/default-theme/default-profile_50.png diff --git a/lms/static/images/profiles/default_500.png b/lms/static/images/default-theme/default-profile_500.png similarity index 100% rename from lms/static/images/profiles/default_500.png rename to lms/static/images/default-theme/default-profile_500.png diff --git a/lms/static/images/logo-large.png b/lms/static/images/default-theme/logo-large.png similarity index 100% rename from lms/static/images/logo-large.png rename to lms/static/images/default-theme/logo-large.png diff --git a/lms/static/images/logo.png b/lms/static/images/default-theme/logo.png similarity index 100% rename from lms/static/images/logo.png rename to lms/static/images/default-theme/logo.png diff --git a/themes/edx.org/lms/static/images/profiles/default_120.png b/lms/static/images/edx-theme/default_120.png similarity index 100% rename from themes/edx.org/lms/static/images/profiles/default_120.png rename to lms/static/images/edx-theme/default_120.png diff --git a/themes/edx.org/lms/static/images/profiles/default_30.png b/lms/static/images/edx-theme/default_30.png similarity index 100% rename from themes/edx.org/lms/static/images/profiles/default_30.png rename to lms/static/images/edx-theme/default_30.png diff --git a/themes/edx.org/lms/static/images/profiles/default_50.png b/lms/static/images/edx-theme/default_50.png similarity index 100% rename from themes/edx.org/lms/static/images/profiles/default_50.png rename to lms/static/images/edx-theme/default_50.png diff --git a/themes/edx.org/lms/static/images/profiles/default_500.png b/lms/static/images/edx-theme/default_500.png similarity index 100% rename from themes/edx.org/lms/static/images/profiles/default_500.png rename to lms/static/images/edx-theme/default_500.png diff --git a/themes/edx.org/lms/static/images/logo.png b/lms/static/images/edx-theme/edx-header-logo.png similarity index 100% rename from themes/edx.org/lms/static/images/logo.png rename to lms/static/images/edx-theme/edx-header-logo.png diff --git a/themes/edx.org/lms/static/images/logo-large.png b/lms/static/images/edx-theme/edx-logo-bw.png similarity index 100% rename from themes/edx.org/lms/static/images/logo-large.png rename to lms/static/images/edx-theme/edx-logo-bw.png diff --git a/lms/templates/courseware/course_about.html b/lms/templates/courseware/course_about.html index c8df28da92..870d4785ed 100644 --- a/lms/templates/courseware/course_about.html +++ b/lms/templates/courseware/course_about.html @@ -17,7 +17,7 @@ from edxmako.shortcuts import marketing_link ga=microsite.get_value('google_analytics_file', 'theme-google-analytics.html') ) else: - google_analytics_file = '../google-analytics.html' + google_analytics_file = '../google_analytics.html' %> <%include file="${google_analytics_file}" /> diff --git a/lms/templates/google-analytics.html b/lms/templates/google_analytics.html similarity index 100% rename from lms/templates/google-analytics.html rename to lms/templates/google_analytics.html diff --git a/lms/templates/main.html b/lms/templates/main.html index bafffe7462..1ff63edf9d 100644 --- a/lms/templates/main.html +++ b/lms/templates/main.html @@ -61,13 +61,7 @@ from branding import api as branding_api <%static:css group='style-vendor'/> - ## route around the overwhelmingly complicated static:css nonsense - <% - application_css_path = "css/lms-main{rtl}.css".format( - rtl="-rtl" if get_language_bidi() else "", - ) - %> - + <%static:css group='style-main'/> % if disable_courseware_js: <%static:js group='base_vendor'/> @@ -90,7 +84,30 @@ from branding import api as branding_api <%block name="headextra"/> - <%static:optional_include_mako file="header-extra.html" with_microsite="True" /> +<% + if theme_enabled() and not is_microsite(): + header_extra_file = 'theme-head-extra.html' + header_file = 'theme-header.html' + google_analytics_file = 'theme-google-analytics.html' + + style_overrides_file = None + + else: + header_extra_file = microsite.get_template_path('header_extra.html') + + if settings.FEATURES['IS_EDX_DOMAIN'] and not is_microsite(): + header_file = microsite.get_template_path('navigation-edx.html') + else: + header_file = microsite.get_template_path('navigation.html') + + google_analytics_file = microsite.get_template_path('google_analytics.html') + + style_overrides_file = microsite.get_value('css_overrides_file') +%> + + % if header_extra_file: + <%include file="${header_extra_file}" /> + % endif <%include file="widgets/optimizely.html" /> <%include file="widgets/segment-io.html" /> @@ -98,7 +115,11 @@ from branding import api as branding_api - <%static:optional_include_mako file="google-analytics.html" with_microsite="True" /> + <%include file="${google_analytics_file}" /> + +% if style_overrides_file: + +% endif @@ -110,7 +131,7 @@ from branding import api as branding_api #content">${_("Skip to main content")} % if not disable_header: - <%include file="header.html" /> + <%include file="${header_file}" /> % endif
@@ -119,7 +140,16 @@ from branding import api as branding_api
% if not disable_footer: - <%include file="themable-footer.html" /> + <%block name="footer"> + ## Can be overridden by child templates wanting to hide the footer. + % if theme_enabled() and not is_microsite(): + <%include file="theme-footer.html" /> + % elif settings.FEATURES.get('IS_EDX_DOMAIN', False) and not is_microsite(): + <%include file="footer-edx-v3.html" /> + % else: + <%include file="${microsite.get_template_path('footer.html')}" /> + % endif + % endif % if not disable_window_wrap: diff --git a/lms/templates/themable-footer.html b/lms/templates/themable-footer.html deleted file mode 100644 index dc688d9f43..0000000000 --- a/lms/templates/themable-footer.html +++ /dev/null @@ -1,13 +0,0 @@ -<%! -from microsite_configuration import microsite -%> -<% -theme_enabled = settings.FEATURES.get("USE_CUSTOM_THEME", False) -is_microsite = microsite.is_request_in_microsite() -%> - -% if theme_enabled and not is_microsite: - <%include file="theme-footer.html" /> -% else: - <%include file="${microsite.get_template_path('footer.html')}" /> -% endif diff --git a/themes/README.rst b/themes/README.rst index 547c7d01f1..88fe30dc17 100644 --- a/themes/README.rst +++ b/themes/README.rst @@ -90,28 +90,6 @@ in the appropriate place, and making the changes you need. Keep in mind that in the future if you upgrade the Open edX code, you may have to update the copied template in your theme also. -Template Names -============== - -Here are the list of template names that you *should* use in your comprehensive -theme (so far): - -* ``header.html`` -* ``footer.html`` - -You should **not** use the following names in your comprehensive theme: - -* ``themable-footer.html`` - -If you look at the ``main.html`` template file, you will notice that it includes -``header.html`` and ``themable-footer.html``, rather than ``footer.html``. -You might be inclined to override ``themable-footer.html`` as a result. DO NOT -DO THIS. ``themable-footer.html`` is an additional layer of indirection that -is necessary to avoid breaking microsites, which also refers to a file named -``footer.html``. The goal is to eventually make comprehensive theming do -everything that microsites does now, and then deprecate and remove microsites -from the codebase. At that point, the ``themable-footer.html`` file will go -away, since the additional layer of indirection will no longer be necessary. Installing your theme --------------------- diff --git a/themes/edx.org/lms/templates/footer.html b/themes/edx.org/lms/templates/footer.html deleted file mode 100644 index d74638c628..0000000000 --- a/themes/edx.org/lms/templates/footer.html +++ /dev/null @@ -1,81 +0,0 @@ -## mako -<%! - from django.utils.translation import ugettext as _ - from branding.api import get_footer -%> -<% footer = get_footer(is_secure=is_secure) %> -<%namespace name='static' file='static_content.html'/> - -## WARNING: These files are specific to edx.org and are not used in installations outside of that domain. Open edX users will want to use the file "footer.html" for any changes or overrides. -
- - -
-% if include_dependencies: - <%static:js group='base_vendor'/> - <%static:css group='style-vendor'/> - <%include file="widgets/segment-io.html" /> -% endif -% if footer_css_urls: - % for url in footer_css_urls: - - % endfor -% endif -% if footer_js_url: - -% endif - diff --git a/themes/edx.org/lms/templates/header.html b/themes/edx.org/lms/templates/header.html deleted file mode 100644 index 3194120dc9..0000000000 --- a/themes/edx.org/lms/templates/header.html +++ /dev/null @@ -1,157 +0,0 @@ -## mako -<%namespace name='static' file='static_content.html'/> -<%namespace file='main.html' import="login_query"/> -<%! -from django.core.urlresolvers import reverse -from django.utils.translation import ugettext as _ - -from microsite_configuration import microsite -from microsite_configuration.templatetags.microsite import platform_name - -# App that handles subdomain specific branding -import branding -# app that handles site status messages -from status.status import get_site_status_msg -%> - -## Provide a hook for themes to inject branding on top. -<%block name="navigation_top" /> - -<%block> -<% -try: - course_id = course.id.to_deprecated_string() -except: - # can't figure out a better way to get at a possibly-defined course var - course_id = None -site_status_msg = get_site_status_msg(course_id) -%> -% if site_status_msg: -
-
- -

${site_status_msg}

-
-
-% endif - - - -% if course: - -% endif - -%if not user.is_authenticated(): - <%include file="forgot_password_modal.html" /> -%endif - -<%include file="help_modal.html"/> From 459f2e070583de7b81be60afad7168e9edddaba1 Mon Sep 17 00:00:00 2001 From: David Baumgold Date: Tue, 29 Sep 2015 19:45:58 -0400 Subject: [PATCH 3/4] Disable some tests for comprehensive theming Depends on functionality that has been temporarily reverted --- lms/djangoapps/courseware/tests/test_comp_theming.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lms/djangoapps/courseware/tests/test_comp_theming.py b/lms/djangoapps/courseware/tests/test_comp_theming.py index d2bc701238..56ebca08f8 100644 --- a/lms/djangoapps/courseware/tests/test_comp_theming.py +++ b/lms/djangoapps/courseware/tests/test_comp_theming.py @@ -1,5 +1,6 @@ """Tests of comprehensive theming.""" +import unittest from django.conf import settings from django.test import TestCase @@ -20,6 +21,7 @@ class TestComprehensiveTheming(TestCase): staticfiles.finders._finders.clear() # pylint: disable=protected-access @with_comp_theme(settings.REPO_ROOT / 'themes/red-theme') + @unittest.skip("Disabled until we can release theming to production") def test_red_footer(self): resp = self.client.get('/') self.assertEqual(resp.status_code, 200) @@ -63,6 +65,7 @@ class TestComprehensiveTheming(TestCase): do_the_test(self) + @unittest.skip("Disabled until we can release theming to production") def test_default_logo_image(self): result = staticfiles.finders.find('images/logo.png') self.assertEqual(result, settings.REPO_ROOT / 'lms/static/images/logo.png') From 42662426c31e20d5063468fcf562a0b51fbc02b0 Mon Sep 17 00:00:00 2001 From: Syed Hassan Raza Date: Wed, 30 Sep 2015 13:40:22 -0700 Subject: [PATCH 4/4] Revert "prevent delete public oprhans" This reverts commit 3849a8fa81663bccd38065ff521364956a5bc779. --- .../modulestore/split_mongo/split_draft.py | 10 -- .../tests/test_mixed_modulestore.py | 96 ------------------- 2 files changed, 106 deletions(-) diff --git a/common/lib/xmodule/xmodule/modulestore/split_mongo/split_draft.py b/common/lib/xmodule/xmodule/modulestore/split_mongo/split_draft.py index fbc32d9a09..4dcb0f4cff 100644 --- a/common/lib/xmodule/xmodule/modulestore/split_mongo/split_draft.py +++ b/common/lib/xmodule/xmodule/modulestore/split_mongo/split_draft.py @@ -198,16 +198,6 @@ class DraftVersioningModuleStore(SplitMongoModuleStore, ModuleStoreDraftAndPubli branches_to_delete = [ModuleStoreEnum.BranchName.published, ModuleStoreEnum.BranchName.draft] elif revision is None: branches_to_delete = [ModuleStoreEnum.BranchName.draft] - draft_location = location.for_branch(ModuleStoreEnum.BranchName.draft) - try: - item = self.get_item(draft_location) - if getattr(item, 'has_children', False): - # If item have has_published_version then delete published children also. - if self.has_published_version(item): - branches_to_delete.insert(0, ModuleStoreEnum.BranchName.published) - except ItemNotFoundError: - # Raises ValueError as in function description - raise ValueError("Cannot delete a block that does not exist") else: raise UnsupportedRevisionError( [ diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py index 33aa199b05..ac5895cb1b 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py @@ -2465,102 +2465,6 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup): # Verify that the signal was emitted self.assertEqual(receiver.call_count, 1) - @ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split) - def test_delete_published_item_creates_no_orphans(self, default_store): - """ - Tests delete published item dont create any oprhans in course - """ - self.initdb(default_store) - course_locator = self.course.id - - chapter = self.store.create_child( - self.user_id, self.course.location, 'chapter', block_id='section_one' - ) - - sequential = self.store.create_child( - self.user_id, chapter.location, 'sequential', block_id='subsection_one' - ) - - vertical = self.store.create_child( - self.user_id, sequential.location, 'vertical', block_id='moon_unit' - ) - - problem = self.store.create_child( - self.user_id, vertical.location, 'problem', block_id='problem' - ) - - self.store.publish(chapter.location, self.user_id) - # Verify that there are no changes - self.assertFalse(self._has_changes(chapter.location)) - self.assertFalse(self._has_changes(sequential.location)) - self.assertFalse(self._has_changes(vertical.location)) - self.assertFalse(self._has_changes(problem.location)) - - # No oprhans in course - course_orphans = self.store.get_orphans(course_locator) - self.assertEqual(len(course_orphans), 0) - self.store.delete_item(vertical.location, self.user_id) - # No oprhans in course after delete - course_orphans = self.store.get_orphans(course_locator) - self.assertEqual(len(course_orphans), 0) - - if default_store == ModuleStoreEnum.Type.split: - course_locator_publish = course_locator.for_branch(ModuleStoreEnum.BranchName.published) - # No published oprhans after delete - course_publish_orphans = self.store.get_orphans(course_locator_publish) - self.assertEqual(len(course_publish_orphans), 0) - - @ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split) - def test_delete_draft_item_creates_no_orphans(self, default_store): - """ - Tests delete draft item create no oprhans in course - """ - self.initdb(default_store) - course_locator = self.course.id - - chapter = self.store.create_child( - self.user_id, self.course.location, 'chapter', block_id='section_one' - ) - - sequential = self.store.create_child( - self.user_id, chapter.location, 'sequential', block_id='subsection_one' - ) - - vertical = self.store.create_child( - self.user_id, sequential.location, 'vertical', block_id='moon_unit' - ) - - problem = self.store.create_child( - self.user_id, vertical.location, 'problem', block_id='problem' - ) - - self.store.publish(chapter.location, self.user_id) - # Verify that there are no changes - self.assertFalse(self._has_changes(chapter.location)) - self.assertFalse(self._has_changes(sequential.location)) - self.assertFalse(self._has_changes(vertical.location)) - self.assertFalse(self._has_changes(problem.location)) - - # No oprhans in course - course_orphans = self.store.get_orphans(course_locator) - self.assertEqual(len(course_orphans), 0) - - problem.display_name = 'changed' - problem = self.store.update_item(problem, self.user_id) - self.assertTrue(self._has_changes(vertical.location)) - self.assertTrue(self._has_changes(problem.location)) - - self.store.delete_item(vertical.location, self.user_id) - # No oprhans in course after delete - course_orphans = self.store.get_orphans(course_locator) - self.assertEqual(len(course_orphans), 0) - - if default_store == ModuleStoreEnum.Type.split: - course_locator_publish = course_locator.for_branch(ModuleStoreEnum.BranchName.published) - # No published oprhans after delete - course_publish_orphans = self.store.get_orphans(course_locator_publish) - self.assertEqual(len(course_publish_orphans), 0) - @ddt.ddt @attr('mongo')