diff --git a/common/djangoapps/student/tests/test_views.py b/common/djangoapps/student/tests/test_views.py index 21f803107e5fca72b89bb13f66671b1fa118b604..0cbc6436801815b5732ae6efcc21db0f69686818 100644 --- a/common/djangoapps/student/tests/test_views.py +++ b/common/djangoapps/student/tests/test_views.py @@ -397,6 +397,69 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin): response = self.client.get(self.path) self.assertEqual(response.content.count('<li class="course-item">'), 0) + @patch('student.views.get_course_runs_for_course') + @patch.object(CourseOverview, 'get_from_id') + @patch('opaque_keys.edx.keys.CourseKey.from_string') + def test_sessions_for_entitlement_course_runs(self, mock_course_key, mock_course_overview, mock_course_runs): + """ + When a learner has a fulfilled entitlement for a course run in the past, there should be no availableSession + data passed to the JS view. When a learner has a fulfilled entitlement for a course run enrollment ending in the + future, there should not be an empty availableSession variable. When a learner has a fulfilled entitlement + for a course that doesn't have an enrollment ending, there should not be an empty availableSession variable. + """ + # Test an enrollment end in the past + mocked_course_overview = CourseOverviewFactory.create( + start=self.TOMORROW, self_paced=True, enrollment_end=self.THREE_YEARS_AGO + ) + mock_course_overview.return_value = mocked_course_overview + mock_course_key.return_value = mocked_course_overview.id + course_enrollment = CourseEnrollmentFactory(user=self.user, course_id=unicode(mocked_course_overview.id)) + mock_course_runs.return_value = [ + { + 'key': mocked_course_overview.id, + 'enrollment_end': mocked_course_overview.enrollment_end, + 'pacing_type': 'self_paced', + 'type': 'verified' + } + ] + CourseEntitlementFactory(user=self.user, enrollment_course_run=course_enrollment) + response = self.client.get(self.path) + self.assertIn("availableSessions: '[]'", response.content) + + # Test an enrollment end in the future sets an availableSession + mocked_course_overview.enrollment_end = self.TOMORROW + mocked_course_overview.save() + + mock_course_overview.return_value = mocked_course_overview + mock_course_key.return_value = mocked_course_overview.id + mock_course_runs.return_value = [ + { + 'key': mocked_course_overview.id, + 'enrollment_end': mocked_course_overview.enrollment_end, + 'pacing_type': 'self_paced', + 'type': 'verified' + } + ] + response = self.client.get(self.path) + self.assertNotIn("availableSessions: '[]'", response.content) + + # Test an enrollment end that doesn't exist sets an availableSession + mocked_course_overview.enrollment_end = None + mocked_course_overview.save() + + mock_course_overview.return_value = mocked_course_overview + mock_course_key.return_value = mocked_course_overview.id + mock_course_runs.return_value = [ + { + 'key': mocked_course_overview.id, + 'enrollment_end': mocked_course_overview.enrollment_end, + 'pacing_type': 'self_paced', + 'type': 'verified' + } + ] + response = self.client.get(self.path) + self.assertNotIn("availableSessions: '[]'", response.content) + @patch('openedx.core.djangoapps.programs.utils.get_programs') @patch('student.views.get_course_runs_for_course') @patch.object(CourseOverview, 'get_from_id') diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index 5c07b4585d310a1df4ccf86ace3249f26d959664..5e3bf342fe3ccd39ba8612bf80285f851f1087fc 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -702,8 +702,16 @@ def dashboard(request): course_entitlement_available_sessions = {} for course_entitlement in course_entitlements: course_entitlement.update_expired_at() - course_entitlement_available_sessions[str(course_entitlement.uuid)] = \ - get_course_runs_for_course(str(course_entitlement.course_uuid)) + # Filter only the course runs that do not have an enrollment_end date set, or have one set in the future + course_runs_for_course = get_course_runs_for_course(str(course_entitlement.course_uuid)) + enrollable_course_runs = [] + + for course_run in course_runs_for_course: + enrollment_end = course_run.get('enrollment_end') + if not enrollment_end or enrollment_end > datetime.datetime.now(UTC): + enrollable_course_runs.append(course_run) + + course_entitlement_available_sessions[str(course_entitlement.uuid)] = enrollable_course_runs # Record how many courses there are so that we can get a better # understanding of usage patterns on prod.