Only actually reset user schedule if they have missed deadlines and not missed any gated content deadlines
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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()}
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user