Only actually reset user schedule if they have missed deadlines and not missed any gated content deadlines

This commit is contained in:
Calen Pennington
2020-06-04 13:38:28 -04:00
parent 15df17034a
commit c6695e0b6f
8 changed files with 28 additions and 21 deletions

View File

@@ -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))

View File

@@ -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,

View File

@@ -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),

View File

@@ -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()}

View File

@@ -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):

View File

@@ -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, '<div class="dates-banner-text"')
@RELATIVE_DATES_FLAG.override(active=True)
def test_reset_course_deadlines(self):
course = self.courses[0]
enrollment = CourseEnrollment.objects.get(course_id=course.id)
enrollment.schedule.start_date = timezone.now() - datetime.timedelta(days=30)
enrollment.schedule.save()
post_dict = {'reset_deadlines_redirect_url_id_dict': json.dumps({'course_id': str(course.id)})}
self.client.post(reverse(RESET_COURSE_DEADLINES_NAME), post_dict)
updated_schedule = Schedule.objects.get(enrollment=enrollment)
self.assertEqual(updated_schedule.start_date.date(), datetime.datetime.today().date())
def test_reset_course_deadlines_masquerade_specific_student(self):
course = self.courses[0]
student_schedule = CourseEnrollment.objects.get(course_id=course.id, user=self.user).schedule
@@ -247,7 +249,7 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase):
student_schedule.save()
staff = StaffFactory(course_key=course.id)
staff_schedule = ScheduleFactory(
start_date=timezone.now() - datetime.timedelta(1),
start_date=timezone.now() - datetime.timedelta(days=30),
enrollment__course__id=course.id,
enrollment__user=staff,
)
@@ -274,6 +276,7 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase):
updated_staff_schedule = Schedule.objects.get(id=staff_schedule.id)
self.assertEqual(updated_staff_schedule.start_date, staff_schedule.start_date)
@RELATIVE_DATES_FLAG.override(active=True)
def test_reset_course_deadlines_masquerade_generic_student(self):
course = self.courses[0]
@@ -283,7 +286,7 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase):
staff = StaffFactory(course_key=course.id)
staff_schedule = ScheduleFactory(
start_date=timezone.now() - datetime.timedelta(1),
start_date=timezone.now() - datetime.timedelta(days=30),
enrollment__course__id=course.id,
enrollment__user=staff,
)
@@ -308,7 +311,7 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase):
updated_student_schedule = Schedule.objects.get(id=student_schedule.id)
self.assertEqual(updated_student_schedule.start_date, student_schedule.start_date)
updated_staff_schedule = Schedule.objects.get(id=staff_schedule.id)
self.assertEqual(updated_staff_schedule.start_date.date(), datetime.datetime.today().date())
self.assertEqual(updated_staff_schedule.start_date.date(), datetime.date.today())
class TestCourseOutlinePageWithPrerequisites(SharedModuleStoreTestCase, MilestonesTestCaseMixin):

View File

@@ -255,7 +255,7 @@ def get_resume_block(block):
return block
def dates_banner_should_display(course_key, request):
def dates_banner_should_display(course_key, user):
"""
Return whether or not the reset banner should display,
determined by whether or not a course has any past-due,
@@ -267,7 +267,7 @@ def dates_banner_should_display(course_key, request):
missed_deadlines is True if the user has missed any graded content deadlines
missed_gated_content is True if the first content that the user missed was gated content
"""
if not RELATIVE_DATES_FLAG.is_enabled(str(course_key)):
if not RELATIVE_DATES_FLAG.is_enabled(course_key):
return False, False
course_overview = CourseOverview.objects.get(id=str(course_key))
@@ -279,12 +279,12 @@ def dates_banner_should_display(course_key, request):
return False, False
# Only display the banner for enrolled users
if not CourseEnrollment.is_enrolled(request.user, course_key):
if not CourseEnrollment.is_enrolled(user, course_key):
return False, False
# Don't display the banner for course staff
is_course_staff = bool(
request.user and course_overview and has_access(request.user, 'staff', course_overview, course_overview.id)
user and course_overview and has_access(user, 'staff', course_overview, course_overview.id)
)
if is_course_staff:
return False, False
@@ -295,7 +295,7 @@ def dates_banner_should_display(course_key, request):
store = modulestore()
course_usage_key = store.make_course_usage_key(course_key)
block_data = get_course_blocks(request.user, course_usage_key, include_completion=True)
block_data = get_course_blocks(user, course_usage_key, include_completion=True)
for section_key in block_data.get_children(course_usage_key):
for subsection_key in block_data.get_children(section_key):
subsection_due_date = block_data.get_xblock_field(subsection_key, 'due', None)

View File

@@ -84,7 +84,7 @@ class CourseOutlineFragmentView(EdxFragmentView):
xblock_display_names = self.create_xblock_id_and_name_dict(course_block_tree)
gated_content = self.get_content_milestones(request, course_key)
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['gated_content'] = gated_content
context['xblock_display_names'] = xblock_display_names