diff --git a/common/djangoapps/student/tests/factories.py b/common/djangoapps/student/tests/factories.py index b2f4d95776..107631b17b 100644 --- a/common/djangoapps/student/tests/factories.py +++ b/common/djangoapps/student/tests/factories.py @@ -2,6 +2,7 @@ from student.models import (User, UserProfile, Registration, CourseEnrollmentAllowed, CourseEnrollment, PendingEmailChange, UserStanding, ) +from course_modes.models import CourseMode from django.contrib.auth.models import Group from datetime import datetime from factory import DjangoModelFactory, SubFactory, PostGenerationMethodCall, post_generation, Sequence @@ -36,6 +37,16 @@ class UserProfileFactory(DjangoModelFactory): goals = u'World domination' +class CourseModeFactory(DjangoModelFactory): + FACTORY_FOR = CourseMode + + course_id = None + mode_display_name = u'Honor Code', + mode_slug = 'honor' + min_price = 0 + suggested_prices = '' + currency = 'usd' + class RegistrationFactory(DjangoModelFactory): FACTORY_FOR = Registration diff --git a/common/djangoapps/student/tests/tests.py b/common/djangoapps/student/tests/tests.py index c35ad66427..b53df0bfd8 100644 --- a/common/djangoapps/student/tests/tests.py +++ b/common/djangoapps/student/tests/tests.py @@ -8,6 +8,8 @@ import logging import json import re import unittest +from datetime import datetime, timedelta +import pytz from django.conf import settings from django.test import TestCase @@ -28,8 +30,8 @@ from textwrap import dedent from student.models import unique_id_for_user, CourseEnrollment from student.views import (process_survey_link, _cert_info, password_reset, password_reset_confirm_wrapper, - change_enrollment) -from student.tests.factories import UserFactory + change_enrollment, complete_course_mode_info) +from student.tests.factories import UserFactory, CourseModeFactory from student.tests.test_email import mock_render_to_string import shoppingcart @@ -216,6 +218,45 @@ class CourseEndingTest(TestCase): }) +@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) +class DashboardTest(TestCase): + """ + Tests for dashboard utility functions + """ + # arbitrary constant + COURSE_SLUG = "100" + COURSE_NAME = "test_course" + COURSE_ORG = "EDX" + + def setUp(self): + self.course = CourseFactory.create(org=self.COURSE_ORG, display_name=self.COURSE_NAME, number=self.COURSE_SLUG) + self.assertIsNotNone(self.course) + self.user = UserFactory.create(username="jack", email="jack@fake.edx.org") + CourseModeFactory.create( + course_id=self.course.id, + mode_slug='honor', + mode_display_name='Honor Code', + ) + + def test_course_mode_info(self): + verified_mode = CourseModeFactory.create( + course_id=self.course.id, + mode_slug='verified', + mode_display_name='Verified', + expiration_date=datetime.now(pytz.UTC) + timedelta(days=1) + ) + enrollment = CourseEnrollment.enroll(self.user, self.course.id) + course_mode_info = complete_course_mode_info(self.course.id, enrollment) + self.assertTrue(course_mode_info['show_upsell']) + self.assertEquals(course_mode_info['days_for_upsell'], 1) + + verified_mode.expiration_date = datetime.now(pytz.UTC) + timedelta(days=-1) + verified_mode.save() + course_mode_info = complete_course_mode_info(self.course.id, enrollment) + self.assertFalse(course_mode_info['show_upsell']) + self.assertIsNone(course_mode_info['days_for_upsell']) + + class EnrollInCourseTest(TestCase): """Tests enrolling and unenrolling in courses.""" diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index 3172026209..4ebbcff592 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -267,6 +267,29 @@ def register_user(request, extra_context=None): return render_to_response('register.html', context) +def complete_course_mode_info(course_id, enrollment): + """ + We would like to compute some more information from the given course modes + and the user's current enrollment + + Returns the given information: + - whether to show the course upsell information + - numbers of days until they can't upsell anymore + """ + modes = CourseMode.modes_for_course_dict(course_id) + mode_info = {'show_upsell': False, 'days_for_upsell': None} + # we want to know if the user is already verified and if verified is an + # option + if 'verified' in modes and enrollment.mode != 'verified': + mode_info['show_upsell'] = True + # if there is an expiration date, find out how long from now it is + if modes['verified'].expiration_date: + today = datetime.datetime.now(UTC).date() + mode_info['days_for_upsell'] = (modes['verified'].expiration_date - today).days + + return mode_info + + @login_required @ensure_csrf_cookie def dashboard(request): @@ -300,7 +323,7 @@ def dashboard(request): show_courseware_links_for = frozenset(course.id for course, _enrollment in courses if has_access(request.user, course, 'load')) - course_modes = {course.id: CourseMode.modes_for_course_dict(course.id) for course, _enrollment in courses} + course_modes = {course.id: complete_course_mode_info(course.id, enrollment) for course, enrollment in courses} cert_statuses = {course.id: cert_info(request.user, course) for course, _enrollment in courses} # only show email settings for Mongo course and when bulk email is turned on diff --git a/lms/templates/dashboard.html b/lms/templates/dashboard.html index 1bcdd4582f..6b9981ced5 100644 --- a/lms/templates/dashboard.html +++ b/lms/templates/dashboard.html @@ -179,8 +179,8 @@ <% show_courseware_link = (course.id in show_courseware_links_for) %> <% cert_status = cert_statuses.get(course.id) %> <% show_email_settings = (course.id in show_email_settings_for) %> - <% course_modes = all_course_modes.get(course.id) %> - <%include file='dashboard/dashboard_course_listing.html' args="course=course, enrollment=enrollment, show_courseware_link=show_courseware_link, cert_status=cert_status, show_email_settings=show_email_settings, course_modes=course_modes" /> + <% course_mode_info = all_course_modes.get(course.id) %> + <%include file='dashboard/dashboard_course_listing.html' args="course=course, enrollment=enrollment, show_courseware_link=show_courseware_link, cert_status=cert_status, show_email_settings=show_email_settings, course_mode_info=course_mode_info" /> % endfor diff --git a/lms/templates/dashboard/dashboard_course_listing.html b/lms/templates/dashboard/dashboard_course_listing.html index f375ee88b1..c8a527391e 100644 --- a/lms/templates/dashboard/dashboard_course_listing.html +++ b/lms/templates/dashboard/dashboard_course_listing.html @@ -1,9 +1,8 @@ -<%page args="course, enrollment, show_courseware_link, cert_status, show_email_settings, course_modes" /> +<%page args="course, enrollment, show_courseware_link, cert_status, show_email_settings, course_mode_info" /> <%! from django.utils.translation import ugettext as _ %> <%! from django.core.urlresolvers import reverse - from datetime import date from courseware.courses import course_image_url, get_course_about_section import waffle %> @@ -109,12 +108,11 @@ % endif - %if enrollment.mode != 'verified' and 'verified' in course_modes: + %if course_mode_info['show_upsell']: