From c6695e0b6f30434d002abf373571efbc61176a93 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Thu, 4 Jun 2020 13:38:28 -0400 Subject: [PATCH] Only actually reset user schedule if they have missed deadlines and not missed any gated content deadlines --- common/djangoapps/util/views.py | 6 +++++- .../course_home_api/dates/v1/views.py | 2 +- lms/djangoapps/courseware/views/views.py | 4 ++-- lms/templates/dates_banner.html | 2 +- .../block_structure/block_structure.py | 2 +- .../tests/views/test_course_outline.py | 21 +++++++++++-------- openedx/features/course_experience/utils.py | 10 ++++----- .../course_experience/views/course_outline.py | 2 +- 8 files changed, 28 insertions(+), 21 deletions(-) diff --git a/common/djangoapps/util/views.py b/common/djangoapps/util/views.py index a11e17da61..af4e115b52 100644 --- a/common/djangoapps/util/views.py +++ b/common/djangoapps/util/views.py @@ -21,6 +21,7 @@ from six.moves import map from lms.djangoapps.courseware.access import has_access from lms.djangoapps.courseware.masquerade import setup_masquerade from openedx.core.djangoapps.schedules.utils import reset_self_paced_schedule +from openedx.features.course_experience.utils import dates_banner_should_display import track.views from edxmako.shortcuts import render_to_response @@ -218,7 +219,10 @@ def reset_course_deadlines(request): user = masquerade_user else: user = request.user - reset_self_paced_schedule(user, course_key) + + missed_deadlines, missed_gated_content = dates_banner_should_display(course_key, user) + if missed_deadlines and not missed_gated_content: + reset_self_paced_schedule(user, course_key) if redirect_url == RENDER_XBLOCK_NAME: detail_id_dict.pop('course_id') return redirect(reverse(redirect_url, kwargs=detail_id_dict)) diff --git a/lms/djangoapps/course_home_api/dates/v1/views.py b/lms/djangoapps/course_home_api/dates/v1/views.py index a248838f71..2dbea61418 100644 --- a/lms/djangoapps/course_home_api/dates/v1/views.py +++ b/lms/djangoapps/course_home_api/dates/v1/views.py @@ -73,7 +73,7 @@ class DatesTabView(RetrieveAPIView): course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=False) blocks = get_course_date_blocks(course, request.user, request, include_access=True, include_past_dates=True) - missed_deadlines, missed_gated_content = dates_banner_should_display(course_key, request) + missed_deadlines, missed_gated_content = dates_banner_should_display(course_key, request.user) learner_is_full_access = not ContentTypeGatingConfig.enabled_for_enrollment( user=request.user, diff --git a/lms/djangoapps/courseware/views/views.py b/lms/djangoapps/courseware/views/views.py index cd118ea29a..3fba89aeee 100644 --- a/lms/djangoapps/courseware/views/views.py +++ b/lms/djangoapps/courseware/views/views.py @@ -1060,7 +1060,7 @@ def dates(request, course_id): user_timezone = user_timezone_locale['user_timezone'] user_language = user_timezone_locale['user_language'] - missed_deadlines, missed_gated_content = dates_banner_should_display(course_key, request) + missed_deadlines, missed_gated_content = dates_banner_should_display(course_key, request.user) context = { 'course': course, @@ -1664,7 +1664,7 @@ def render_xblock(request, usage_key_string, check_if_enrolled=True): 'mark-completed-on-view-after-delay': completion_service.get_complete_on_view_delay_ms() } - missed_deadlines, missed_gated_content = dates_banner_should_display(course_key, request) + missed_deadlines, missed_gated_content = dates_banner_should_display(course_key, request.user) context = { 'fragment': block.render('student_view', context=student_view_context), diff --git a/lms/templates/dates_banner.html b/lms/templates/dates_banner.html index 2c4220f043..b6f127c5a2 100644 --- a/lms/templates/dates_banner.html +++ b/lms/templates/dates_banner.html @@ -96,7 +96,7 @@ additional_styling_class = 'on-mobile' if is_mobile_app else 'has-button' % if on_dates_tab and content_type_gating_enabled and not missed_deadlines: ${upgrade_to_complete_graded_banner()} % elif missed_deadlines: - % if content_type_gating_enabled and missed_gated_content: + % if missed_gated_content: ${upgrade_to_reset_banner()} % else: ${reset_dates_banner()} diff --git a/openedx/core/djangoapps/content/block_structure/block_structure.py b/openedx/core/djangoapps/content/block_structure/block_structure.py index 612c9dd584..c3568d3563 100644 --- a/openedx/core/djangoapps/content/block_structure/block_structure.py +++ b/openedx/core/djangoapps/content/block_structure/block_structure.py @@ -482,7 +482,7 @@ class BlockStructureBlockData(BlockStructure): override_data (object) - The data you want to set """ - block_data = self._block_data_map.get(usage_key) + block_data = self._get_or_create_block(usage_key) setattr(block_data, field_name, override_data) def get_transformer_data(self, transformer, key, default=None): diff --git a/openedx/features/course_experience/tests/views/test_course_outline.py b/openedx/features/course_experience/tests/views/test_course_outline.py index 3ba4996347..0690a63cd7 100644 --- a/openedx/features/course_experience/tests/views/test_course_outline.py +++ b/openedx/features/course_experience/tests/views/test_course_outline.py @@ -32,6 +32,7 @@ from gating import api as lms_gating_api from lms.djangoapps.course_api.blocks.transformers.milestones import MilestonesAndSpecialExamsTransformer from openedx.core.djangoapps.schedules.models import Schedule from openedx.core.djangoapps.schedules.tests.factories import ScheduleFactory +from openedx.core.djangoapps.course_date_signals.models import SelfPacedRelativeDatesConfig from openedx.core.lib.gating import api as gating_api from openedx.features.course_experience import RELATIVE_DATES_FLAG from openedx.features.content_type_gating.models import ContentTypeGatingConfig @@ -58,11 +59,16 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase): """ Test the course outline view. """ + + ENABLED_SIGNALS = ['course_published'] + @classmethod def setUpClass(cls): """ Set up an array of various courses to be tested. """ + SelfPacedRelativeDatesConfig.objects.create(enabled=True) + # setUpClassAndTestData() already calls setUpClass on SharedModuleStoreTestCase # pylint: disable=super-method-not-called with super(TestCourseOutlinePage, cls).setUpClassAndTestData(): @@ -207,7 +213,7 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase): ): ContentTypeGatingConfig.objects.create( enabled=True, - enabled_as_of=datetime.datetime(2018, 1, 1), + enabled_as_of=datetime.datetime(2017, 1, 1), ) course = self.courses[0] for mode in course_modes: @@ -229,17 +235,13 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase): else: self.assertNotContains(response, '