diff --git a/common/djangoapps/course_modes/models.py b/common/djangoapps/course_modes/models.py index 3fc66994e2..8cdd9e9381 100644 --- a/common/djangoapps/course_modes/models.py +++ b/common/djangoapps/course_modes/models.py @@ -415,7 +415,7 @@ class CourseMode(models.Model): return None @classmethod - def verified_mode_for_course(cls, course_id, modes=None): + def verified_mode_for_course(cls, course_id, modes=None, include_expired=False): """Find a verified mode for a particular course. Since we have multiple modes that can go through the verify flow, @@ -436,7 +436,7 @@ class CourseMode(models.Model): Mode or None """ - modes_dict = cls.modes_for_course_dict(course_id, modes=modes) + modes_dict = cls.modes_for_course_dict(course_id, modes=modes, include_expired=include_expired) verified_mode = modes_dict.get('verified', None) professional_mode = modes_dict.get('professional', None) # we prefer professional over verify diff --git a/lms/djangoapps/ccx/tests/test_field_override_performance.py b/lms/djangoapps/ccx/tests/test_field_override_performance.py index f560b664ab..284f23b8c9 100644 --- a/lms/djangoapps/ccx/tests/test_field_override_performance.py +++ b/lms/djangoapps/ccx/tests/test_field_override_performance.py @@ -236,18 +236,18 @@ class TestFieldOverrideMongoPerformance(FieldOverridePerformanceTestCase): # # of sql queries to default, # # of mongo queries, # ) - ('no_overrides', 1, True, False): (16, 1), - ('no_overrides', 2, True, False): (16, 1), - ('no_overrides', 3, True, False): (16, 1), - ('ccx', 1, True, False): (16, 1), - ('ccx', 2, True, False): (16, 1), - ('ccx', 3, True, False): (16, 1), - ('no_overrides', 1, False, False): (16, 1), - ('no_overrides', 2, False, False): (16, 1), - ('no_overrides', 3, False, False): (16, 1), - ('ccx', 1, False, False): (16, 1), - ('ccx', 2, False, False): (16, 1), - ('ccx', 3, False, False): (16, 1), + ('no_overrides', 1, True, False): (17, 1), + ('no_overrides', 2, True, False): (17, 1), + ('no_overrides', 3, True, False): (17, 1), + ('ccx', 1, True, False): (17, 1), + ('ccx', 2, True, False): (17, 1), + ('ccx', 3, True, False): (17, 1), + ('no_overrides', 1, False, False): (17, 1), + ('no_overrides', 2, False, False): (17, 1), + ('no_overrides', 3, False, False): (17, 1), + ('ccx', 1, False, False): (17, 1), + ('ccx', 2, False, False): (17, 1), + ('ccx', 3, False, False): (17, 1), } @@ -259,19 +259,19 @@ class TestFieldOverrideSplitPerformance(FieldOverridePerformanceTestCase): __test__ = True TEST_DATA = { - ('no_overrides', 1, True, False): (16, 3), - ('no_overrides', 2, True, False): (16, 3), - ('no_overrides', 3, True, False): (16, 3), - ('ccx', 1, True, False): (16, 3), - ('ccx', 2, True, False): (16, 3), - ('ccx', 3, True, False): (16, 3), - ('ccx', 1, True, True): (17, 3), - ('ccx', 2, True, True): (17, 3), - ('ccx', 3, True, True): (17, 3), - ('no_overrides', 1, False, False): (16, 3), - ('no_overrides', 2, False, False): (16, 3), - ('no_overrides', 3, False, False): (16, 3), - ('ccx', 1, False, False): (16, 3), - ('ccx', 2, False, False): (16, 3), - ('ccx', 3, False, False): (16, 3), + ('no_overrides', 1, True, False): (17, 3), + ('no_overrides', 2, True, False): (17, 3), + ('no_overrides', 3, True, False): (17, 3), + ('ccx', 1, True, False): (17, 3), + ('ccx', 2, True, False): (17, 3), + ('ccx', 3, True, False): (17, 3), + ('ccx', 1, True, True): (18, 3), + ('ccx', 2, True, True): (18, 3), + ('ccx', 3, True, True): (18, 3), + ('no_overrides', 1, False, False): (17, 3), + ('no_overrides', 2, False, False): (17, 3), + ('no_overrides', 3, False, False): (17, 3), + ('ccx', 1, False, False): (17, 3), + ('ccx', 2, False, False): (17, 3), + ('ccx', 3, False, False): (17, 3), } diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index aa9b4c316b..7dad956499 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -213,8 +213,8 @@ class IndexQueryTestCase(ModuleStoreTestCase): NUM_PROBLEMS = 20 @ddt.data( - (ModuleStoreEnum.Type.mongo, 10, 145), - (ModuleStoreEnum.Type.split, 4, 145), + (ModuleStoreEnum.Type.mongo, 10, 146), + (ModuleStoreEnum.Type.split, 4, 146), ) @ddt.unpack def test_index_query_counts(self, store_type, expected_mongo_query_count, expected_mysql_query_count): @@ -1456,13 +1456,13 @@ class ProgressPageTests(ProgressPageBaseTests): """Test that query counts remain the same for self-paced and instructor-paced courses.""" SelfPacedConfiguration(enabled=self_paced_enabled).save() self.setup_course(self_paced=self_paced) - with self.assertNumQueries(34 if self_paced else 33, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST), check_mongo_calls(1): + with self.assertNumQueries(35 if self_paced else 34, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST), check_mongo_calls(1): self._get_progress_page() @patch.dict(settings.FEATURES, {'ASSUME_ZERO_GRADE_IF_ABSENT_FOR_ALL_TESTS': False}) @ddt.data( - (False, 40, 26), - (True, 33, 22) + (False, 41, 27), + (True, 34, 23) ) @ddt.unpack def test_progress_queries(self, enable_waffle, initial, subsequent): diff --git a/openedx/core/djangoapps/verified_track_content/partition_scheme.py b/openedx/core/djangoapps/verified_track_content/partition_scheme.py index d36e41237b..33f37303bb 100644 --- a/openedx/core/djangoapps/verified_track_content/partition_scheme.py +++ b/openedx/core/djangoapps/verified_track_content/partition_scheme.py @@ -75,15 +75,7 @@ class EnrollmentTrackPartitionScheme(object): If a course is using the Verified Track Cohorting pilot feature, this method returns None regardless of the user's enrollment mode. """ - def _log_for_educator_1511(log_statement): - # temporary logging for EDUCATOR-1511. Will be rolled back as soon as we have some logs - if course_key == CourseKey.from_string('course-v1:ASUx+ENG101x+2177A'): - LOGGER.warning('EDUCATOR-1511: get_group_for_user | {0}'.format(log_statement)) - - _log_for_educator_1511('Getting group for user id {0}'.format(user.id)) - if is_course_using_cohort_instead(course_key): - _log_for_educator_1511('Course is using cohort instead.') return None # First, check if we have to deal with masquerading. @@ -101,12 +93,12 @@ class EnrollmentTrackPartitionScheme(object): mode_slug, modes=CourseMode.modes_for_course(course_key, include_expired=True, only_selectable=False), ) - _log_for_educator_1511('Got enrollment for user {0}: mode slug is {1}'.format(user.id, mode_slug)) if course_mode and CourseMode.is_credit_mode(course_mode): - _log_for_educator_1511('user {0} is in credit mode, returning verified partition'.format(user.id)) - course_mode = CourseMode.verified_mode_for_course(course_key) + # We want the verified track even if the upgrade deadline has passed, since we + # are determining what content to show the user, not whether the user can enroll + # in the verified track. + course_mode = CourseMode.verified_mode_for_course(course_key, include_expired=True) if not course_mode: - _log_for_educator_1511('user {0} in track {1} added to default partition'.format(user.id, mode_slug)) course_mode = CourseMode.DEFAULT_MODE return Group(ENROLLMENT_GROUP_IDS[course_mode.slug], unicode(course_mode.name)) else: diff --git a/openedx/core/djangoapps/verified_track_content/tests/test_partition_scheme.py b/openedx/core/djangoapps/verified_track_content/tests/test_partition_scheme.py index 0e007e2697..c45716774e 100644 --- a/openedx/core/djangoapps/verified_track_content/tests/test_partition_scheme.py +++ b/openedx/core/djangoapps/verified_track_content/tests/test_partition_scheme.py @@ -146,6 +146,19 @@ class EnrollmentTrackPartitionSchemeTest(SharedModuleStoreTestCase): create_mode(self.course, CourseMode.VERIFIED, "Verified Enrollment Track", min_price=1) self.assertEqual("Verified Enrollment Track", self._get_user_group().name) + def test_credit_after_upgrade_deadline(self): + create_mode(self.course, CourseMode.CREDIT_MODE, "Credit Enrollment Track", min_price=1) + CourseEnrollment.enroll(self.student, self.course.id, mode=CourseMode.CREDIT_MODE) + + # Create a verified mode and check that it is returned for the learner enrolled in Credit. + # Make the mode "expired" to ensure that credit users can still see verified-only content after + # the upgrade deadline has passed (see EDUCATOR-1511 for why this matters). + create_mode( + self.course, CourseMode.VERIFIED, "Verified Enrollment Track", min_price=1, + expiration_datetime=datetime.now(pytz.UTC) + timedelta(days=-1) + ) + self.assertEqual("Verified Enrollment Track", self._get_user_group().name) + def test_using_verified_track_cohort(self): VerifiedTrackCohortedCourse.objects.create(course_key=self.course.id, enabled=True).save() CourseEnrollment.enroll(self.student, self.course.id) diff --git a/openedx/features/course_experience/tests/views/test_course_home.py b/openedx/features/course_experience/tests/views/test_course_home.py index 2b9eab729b..9e46e235d6 100644 --- a/openedx/features/course_experience/tests/views/test_course_home.py +++ b/openedx/features/course_experience/tests/views/test_course_home.py @@ -175,7 +175,7 @@ class TestCourseHomePage(CourseHomePageTestCase): course_home_url(self.course) # Fetch the view and verify the query counts - with self.assertNumQueries(49, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST): + with self.assertNumQueries(50, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST): with check_mongo_calls(4): url = course_home_url(self.course) self.client.get(url) diff --git a/openedx/features/course_experience/tests/views/test_course_updates.py b/openedx/features/course_experience/tests/views/test_course_updates.py index ab0bb2806c..bfb3e17611 100644 --- a/openedx/features/course_experience/tests/views/test_course_updates.py +++ b/openedx/features/course_experience/tests/views/test_course_updates.py @@ -126,7 +126,7 @@ class TestCourseUpdatesPage(SharedModuleStoreTestCase): course_updates_url(self.course) # Fetch the view and verify that the query counts haven't changed - with self.assertNumQueries(30, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST): + with self.assertNumQueries(31, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST): with check_mongo_calls(4): url = course_updates_url(self.course) self.client.get(url)