Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

N11 - fix: correct relative dates flag #645

Open
wants to merge 11 commits into
base: edunext/limonero.nau
Choose a base branch
from
6 changes: 3 additions & 3 deletions lms/djangoapps/course_api/blocks/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def test_query_counts_cached(self, store_type, with_storage_backing):
self._get_blocks(
course,
expected_mongo_queries=0,
expected_sql_queries=11 if with_storage_backing else 10,
expected_sql_queries=13 if with_storage_backing else 12,
)

@ddt.data(
Expand All @@ -251,9 +251,9 @@ def test_query_counts_uncached(self, store_type_tuple, with_storage_backing):
clear_course_from_cache(course.id)

if with_storage_backing:
num_sql_queries = 21
num_sql_queries = 23
else:
num_sql_queries = 11
num_sql_queries = 13

self._get_blocks(
course,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def test_get_authenticated_user(self):
assert response.status_code == 200
assert not response.data.get('is_staff')
# 'Course', 'Wiki', 'Progress' tabs
assert len(response.data.get('tabs', [])) == 4
assert len(response.data.get('tabs', [])) == 3

def test_get_authenticated_staff_user(self):
self.client.logout()
Expand All @@ -51,7 +51,7 @@ def test_get_authenticated_staff_user(self):
assert response.data['is_staff']
# This differs for a staff user because they also receive the Instructor tab
# 'Course', 'Wiki', 'Progress', and 'Instructor' tabs
assert len(response.data.get('tabs', [])) == 5
assert len(response.data.get('tabs', [])) == 4

def test_get_masqueraded_user(self):
CourseEnrollment.enroll(self.user, self.course.id, CourseMode.VERIFIED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
CREDIT_SUPPORT_URL = 'https://support.edx.org/hc/en-us/sections/115004154688-Purchasing-Academic-Credit'


@override_waffle_flag(COURSE_HOME_MICROFRONTEND, active=True)
@override_experiment_waffle_flag(COURSE_HOME_MICROFRONTEND, active=True)
@ddt.ddt
class ProgressTabTestViews(BaseCourseHomeTests):
"""
Expand Down
19 changes: 11 additions & 8 deletions lms/djangoapps/courseware/courses.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from fs.errors import ResourceNotFound
from opaque_keys.edx.keys import UsageKey
from path import Path as path
from lms.djangoapps.certificates import api as certs_api

from openedx.core.lib.cache_utils import request_cached

Expand Down Expand Up @@ -459,13 +460,6 @@ def get_course_date_blocks(course, user, request=None, include_access=False,
Return the list of blocks to display on the course info page,
sorted by date.
"""
blocks = []
if RELATIVE_DATES_FLAG.is_enabled(course.id):
blocks.extend(get_course_assignment_date_blocks(
course, user, request, num_return=num_assignments,
include_access=include_access, include_past_dates=include_past_dates,
))

# Adding these in after the assignment blocks so in the case multiple blocks have the same date,
# these blocks will be sorted to come after the assignments. See https://openedx.atlassian.net/browse/AA-158
default_block_classes = [
Expand All @@ -477,7 +471,16 @@ def get_course_date_blocks(course, user, request=None, include_access=False,
VerificationDeadlineDate,
VerifiedUpgradeDeadlineDate,
]
blocks.extend([cls(course, user) for cls in default_block_classes])
if not course.self_paced and certs_api.get_active_web_certificate(course):
default_block_classes.insert(0, CertificateAvailableDate)

blocks = [cls(course, user) for cls in default_block_classes]
if RELATIVE_DATES_FLAG.is_enabled(course.id) and user and user.is_authenticated:
blocks.append(CourseExpiredDate(course, user))
blocks.extend(get_course_assignment_date_blocks(
course, user, request, num_return=num_assignments,
include_access=include_access, include_past_dates=include_past_dates,
))

blocks = filter(lambda b: b.is_allowed and b.date and (include_past_dates or b.is_enabled), blocks)
return sorted(blocks, key=date_block_key_fn)
Expand Down
6 changes: 6 additions & 0 deletions lms/djangoapps/courseware/tabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from openedx.core.lib.course_tabs import CourseTabPluginManager
from openedx.features.course_experience import DISABLE_UNIFIED_COURSE_TAB_FLAG, default_course_url_name
from openedx.features.course_experience.url_helpers import get_learning_mfe_home_url
from openedx.features.course_experience import RELATIVE_DATES_FLAG
from common.djangoapps.student.models import CourseEnrollment
from xmodule.tabs import CourseTab, CourseTabList, course_reverse_func_from_name_func, key_checker

Expand Down Expand Up @@ -342,6 +343,11 @@ def link_func(course, reverse_func):
tab_dict['link_func'] = link_func
super().__init__(tab_dict)

@classmethod
def is_enabled(cls, course, user=None):
"""Returns true if this tab is enabled."""
return RELATIVE_DATES_FLAG.is_enabled(course.id) and super(DatesTab, cls).is_enabled(course, user=user)


def get_course_tab_list(user, course):
"""
Expand Down
30 changes: 7 additions & 23 deletions lms/djangoapps/courseware/tests/test_date_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
DynamicUpgradeDeadlineConfiguration,
OrgDynamicUpgradeDeadlineConfiguration
)
from lms.djangoapps.experiments.testutils import override_experiment_waffle_flag
from lms.djangoapps.verify_student.models import VerificationDeadline
from lms.djangoapps.verify_student.services import IDVerificationService
from lms.djangoapps.verify_student.tests.factories import SoftwareSecurePhotoVerificationFactory
from lms.djangoapps.experiments.testutils import override_experiment_waffle_flag
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory # pylint: disable=unused-import
Expand Down Expand Up @@ -150,7 +150,7 @@ def test_enabled_block_types(self, course_kwargs, user_kwargs, expected_blocks):
CourseEnrollmentFactory(course_id=course.id, user=user, mode=CourseMode.VERIFIED)
self.assert_block_types(course, user, expected_blocks)

@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many-statements
"""
Creates a course with multiple subsections to test all of the different
Expand All @@ -172,7 +172,6 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
start=now - timedelta(days=1),
due=now + timedelta(days=6),
graded=True,
format='Homework',
)
ItemFactory.create(
category='sequential',
Expand All @@ -181,7 +180,6 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
start=now + timedelta(days=1),
due=now + timedelta(days=7),
graded=True,
format='Homework',
)
ItemFactory.create(
category='sequential',
Expand All @@ -190,7 +188,6 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
start=now + timedelta(days=1),
due=now + timedelta(days=8),
graded=True,
format='Exam',
)
ItemFactory.create(
category='sequential',
Expand All @@ -199,7 +196,6 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
start=now - timedelta(days=14),
due=now - timedelta(days=7),
graded=True,
format='Exam',
)
ItemFactory.create(
category='sequential',
Expand All @@ -216,7 +212,6 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
start=None,
due=now + timedelta(days=9),
graded=True,
format='Speech',
)
ItemFactory.create(
category='sequential',
Expand All @@ -226,7 +221,6 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
start=now - timedelta(days=14),
due=now + timedelta(days=10),
graded=True,
format=None,
)
dummy_subsection = ItemFactory.create(category='sequential', graded=True, due=now + timedelta(days=11))

Expand Down Expand Up @@ -275,41 +269,34 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
assignment_title = str(assignment.title_html) or str(assignment.title)
assert assignment_title != 'Not returned since we do not get non-graded subsections'

assignment_type = str(assignment.assignment_type)
# checking if it is _in_ the title instead of being the title since released assignments
# are actually links. Unreleased assignments are just the string of the title.
# also checking that the assignment type is returned for graded subsections
if 'Released' in assignment_title:
assert assignment_type == 'Homework'
for html_tag in assignment_title_html:
assert html_tag in assignment_title
elif assignment_title == 'Not released':
assert assignment_type == 'Homework'
for html_tag in assignment_title_html:
assert html_tag not in assignment_title
elif assignment_title == 'Third nearest assignment':
assert assignment_type == 'Exam'
# It's still not released
for html_tag in assignment_title_html:
assert html_tag not in assignment_title
elif 'Past due date' in assignment_title:
assert now > assignment.date
assert assignment_type == 'Exam'
for html_tag in assignment_title_html:
assert html_tag in assignment_title
elif 'No start date' == assignment_title:
assert assignment_type == 'Speech'
# Can't determine if it is released so it does not get a link
for html_tag in assignment_title_html:
assert html_tag not in assignment_title
# This is the item with no display name where we set one ourselves.
elif 'Assignment' in assignment_title:
assert assignment_type is None
# Can't determine if it is released so it does not get a link
for html_tag in assignment_title_html:
assert html_tag in assignment_title

@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
@ddt.data(
([], 3),
([{
Expand Down Expand Up @@ -375,7 +362,7 @@ def test_dates_with_openassessments(self, rubric_assessments, date_block_count):
blocks = get_course_date_blocks(course, user, request, include_past_dates=True)
assert len(blocks) == date_block_count

@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
def test_enabled_block_types_with_expired_course(self):
course = create_course_run(days_till_start=-100)
user = create_user()
Expand Down Expand Up @@ -544,7 +531,7 @@ def test_course_end_date_after_course(self):
{'weeks_to_complete': 7}, # Weeks to complete > time til end (end date shown)
{'weeks_to_complete': 4}, # Weeks to complete < time til end (end date not shown)
)
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
def test_course_end_date_self_paced(self, cr_details):
"""
In self-paced courses, the end date will now only show up if the learner
Expand Down Expand Up @@ -636,10 +623,7 @@ def test_certificate_available_date_defined(self):
CourseEnrollmentFactory(course_id=course.id, user=verified_user, mode=CourseMode.VERIFIED)
course.certificate_available_date = datetime.now(utc) + timedelta(days=7)
enable_course_certificates(course)
expected_blocks = [
CourseEndDate, CourseStartDate, TodaysDate, VerificationDeadlineDate, CertificateAvailableDate
]
self.assert_block_types(course, verified_user, expected_blocks)
CertificateAvailableDate(course, audit_user)
for block in (CertificateAvailableDate(course, audit_user), CertificateAvailableDate(course, verified_user)):
assert course.certificate_available_date is not None
assert block.date == course.certificate_available_date
Expand Down Expand Up @@ -727,7 +711,7 @@ def test_render_date_string_past(self, delta, expected_date_string):
)
@ddt.unpack
@override_waffle_flag(DISABLE_UNIFIED_COURSE_TAB_FLAG, active=False)
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
def test_dates_tab_link_render(self, url_name, mfe_active):
""" The dates tab link should only show for enrolled or staff users """
course = create_course_run()
Expand Down
6 changes: 3 additions & 3 deletions lms/djangoapps/courseware/tests/test_tabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ def test_get_course_tabs_list_entrance_exam_enabled(self):
milestone
)
course_tab_list = get_course_tab_list(self.user, self.course)
assert len(course_tab_list) == 2
assert len(course_tab_list) == 1
assert course_tab_list[0]['tab_id'] == 'courseware'
assert course_tab_list[0]['name'] == 'Entrance Exam'

Expand All @@ -425,7 +425,7 @@ def test_get_course_tabs_list_skipped_entrance_exam(self):
self.client.logout()
self.login(self.email, self.password)
course_tab_list = get_course_tab_list(self.user, self.course)
assert len(course_tab_list) == 5
assert len(course_tab_list) == 4

def test_course_tabs_list_for_staff_members(self):
"""
Expand All @@ -437,7 +437,7 @@ def test_course_tabs_list_for_staff_members(self):
staff_user = StaffFactory(course_key=self.course.id)
self.client.login(username=staff_user.username, password='test')
course_tab_list = get_course_tab_list(staff_user, self.course)
assert len(course_tab_list) == 5
assert len(course_tab_list) == 4


class TextBookCourseViewsTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase):
Expand Down
5 changes: 2 additions & 3 deletions lms/djangoapps/courseware/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
courseware_mfe_is_advertised,
)
from lms.djangoapps.courseware.user_state_client import DjangoXBlockUserStateClient
from lms.djangoapps.experiments.testutils import override_experiment_waffle_flag
from lms.djangoapps.grades.config.waffle import ASSUME_ZERO_GRADE_IF_ABSENT
from lms.djangoapps.grades.config.waffle import waffle_switch as grades_waffle_switch
from lms.djangoapps.verify_student.models import VerificationDeadline
Expand Down Expand Up @@ -3261,7 +3260,7 @@ def test_tab_redirects_if_not_enrolled_and_not_staff(self):
response = self._get_response(self.course)
assert response.status_code == 200

@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
@patch('edx_django_utils.monitoring.set_custom_attribute')
def test_defaults(self, mock_set_custom_attribute):
enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user, mode=CourseMode.VERIFIED)
Expand Down Expand Up @@ -3322,7 +3321,7 @@ def test_defaults(self, mock_set_custom_attribute):
# Make sure the assignment type is rendered
self.assertContains(response, 'Homework:')

@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
def test_reset_deadlines_banner_displays(self):
CourseEnrollmentFactory(course_id=self.course.id, user=self.user, mode=CourseMode.VERIFIED)
now = datetime.now(utc)
Expand Down
20 changes: 10 additions & 10 deletions lms/djangoapps/grades/tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ def test_block_structure_created_only_once(self):
assert mock_block_structure_create.call_count == 1

@ddt.data(
(ModuleStoreEnum.Type.mongo, 1, 38, True),
(ModuleStoreEnum.Type.mongo, 1, 38, False),
(ModuleStoreEnum.Type.split, 3, 38, True),
(ModuleStoreEnum.Type.split, 3, 38, False),
(ModuleStoreEnum.Type.mongo, 1, 40, True),
(ModuleStoreEnum.Type.mongo, 1, 40, False),
(ModuleStoreEnum.Type.split, 3, 40, True),
(ModuleStoreEnum.Type.split, 3, 40, False),
)
@ddt.unpack
def test_query_counts(self, default_store, num_mongo_calls, num_sql_calls, create_multiple_subsections):
Expand All @@ -177,8 +177,8 @@ def test_query_counts(self, default_store, num_mongo_calls, num_sql_calls, creat
self._apply_recalculate_subsection_grade()

@ddt.data(
(ModuleStoreEnum.Type.mongo, 1, 38),
(ModuleStoreEnum.Type.split, 3, 38),
(ModuleStoreEnum.Type.mongo, 1, 40),
(ModuleStoreEnum.Type.split, 3, 40),
)
@ddt.unpack
def test_query_counts_dont_change_with_more_content(self, default_store, num_mongo_calls, num_sql_calls):
Expand Down Expand Up @@ -223,8 +223,8 @@ def test_other_inaccessible_subsection(self, mock_subsection_signal):
)

@ddt.data(
(ModuleStoreEnum.Type.mongo, 1, 21),
(ModuleStoreEnum.Type.split, 3, 21),
(ModuleStoreEnum.Type.mongo, 1, 23),
(ModuleStoreEnum.Type.split, 3, 23),
)
@ddt.unpack
def test_persistent_grades_not_enabled_on_course(self, default_store, num_mongo_queries, num_sql_queries):
Expand All @@ -238,8 +238,8 @@ def test_persistent_grades_not_enabled_on_course(self, default_store, num_mongo_
assert len(PersistentSubsectionGrade.bulk_read_grades(self.user.id, self.course.id)) == 0

@ddt.data(
(ModuleStoreEnum.Type.mongo, 1, 39),
(ModuleStoreEnum.Type.split, 3, 39),
(ModuleStoreEnum.Type.mongo, 1, 41),
(ModuleStoreEnum.Type.split, 3, 41),
)
@ddt.unpack
def test_persistent_grades_enabled_on_course(self, default_store, num_mongo_queries, num_sql_queries):
Expand Down
Loading