# -*- coding: utf-8 -*- """Tests for course home page date summary blocks.""" from datetime import datetime, timedelta import ddt import waffle from django.contrib.messages.middleware import MessageMiddleware from django.core.urlresolvers import reverse from django.test import RequestFactory from freezegun import freeze_time from mock import patch from nose.plugins.attrib import attr from pytz import utc from course_modes.models import CourseMode from course_modes.tests.factories import CourseModeFactory from courseware.courses import get_course_date_blocks from courseware.date_summary import ( CertificateAvailableDate, CourseEndDate, CourseStartDate, TodaysDate, VerificationDeadlineDate, VerifiedUpgradeDeadlineDate ) from courseware.models import ( CourseDynamicUpgradeDeadlineConfiguration, DynamicUpgradeDeadlineConfiguration, OrgDynamicUpgradeDeadlineConfiguration ) from lms.djangoapps.commerce.models import CommerceConfiguration from lms.djangoapps.verify_student.models import VerificationDeadline from lms.djangoapps.verify_student.tests.factories import SoftwareSecurePhotoVerificationFactory from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.schedules.signals import CREATE_SCHEDULE_WAFFLE_FLAG from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory from openedx.core.djangoapps.user_api.preferences.api import set_user_preference from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag from openedx.features.course_experience import UNIFIED_COURSE_TAB_FLAG, UPGRADE_DEADLINE_MESSAGE, CourseHomeMessages from student.tests.factories import TEST_PASSWORD, CourseEnrollmentFactory, UserFactory from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory @attr(shard=1) @ddt.ddt class CourseDateSummaryTest(SharedModuleStoreTestCase): """Tests for course date summary blocks.""" def setUp(self): super(CourseDateSummaryTest, self).setUp() SelfPacedConfiguration.objects.create(enable_course_home_improvements=True) def test_course_info_feature_flag(self): SelfPacedConfiguration(enable_course_home_improvements=False).save() course = create_course_run() user = create_user() CourseEnrollmentFactory(course_id=course.id, user=user, mode=CourseMode.VERIFIED) self.client.login(username=user.username, password=TEST_PASSWORD) url = reverse('info', args=(course.id,)) response = self.client.get(url) self.assertNotIn('date-summary', response.content) def test_course_info_logged_out(self): course = create_course_run() url = reverse('info', args=(course.id,)) response = self.client.get(url) self.assertEqual(200, response.status_code) # Tests for which blocks are enabled def assert_block_types(self, course, user, expected_blocks): """Assert that the enabled block types for this course are as expected.""" blocks = get_course_date_blocks(course, user) self.assertEqual(len(blocks), len(expected_blocks)) self.assertEqual(set(type(b) for b in blocks), set(expected_blocks)) @ddt.data( # Verified enrollment with no photo-verification before course start ({}, {}, (CourseEndDate, CourseStartDate, TodaysDate, VerificationDeadlineDate)), # Verified enrollment with `approved` photo-verification after course end ({'days_till_start': -10, 'days_till_end': -5, 'days_till_upgrade_deadline': -6, 'days_till_verification_deadline': -5, }, {'verification_status': 'approved'}, (TodaysDate, CourseEndDate)), # Verified enrollment with `expired` photo-verification during course run ({'days_till_start': -10}, {'verification_status': 'expired'}, (TodaysDate, CourseEndDate, VerificationDeadlineDate)), # Verified enrollment with `approved` photo-verification during course run ({'days_till_start': -10, }, {'verification_status': 'approved'}, (TodaysDate, CourseEndDate)), # Verified enrollment with *NO* course end date ({'days_till_end': None}, {}, (CourseStartDate, TodaysDate, VerificationDeadlineDate)), # Verified enrollment with no photo-verification during course run ({'days_till_start': -1}, {}, (TodaysDate, CourseEndDate, VerificationDeadlineDate)), # Verification approved ({'days_till_start': -10, 'days_till_upgrade_deadline': -1, 'days_till_verification_deadline': 1, }, {'verification_status': 'approved'}, (TodaysDate, CourseEndDate)), # After upgrade deadline ({'days_till_start': -10, 'days_till_upgrade_deadline': -1}, {}, (TodaysDate, CourseEndDate, VerificationDeadlineDate)), # After verification deadline ({'days_till_start': -10, 'days_till_upgrade_deadline': -2, 'days_till_verification_deadline': -1}, {}, (TodaysDate, CourseEndDate, VerificationDeadlineDate)), ) @ddt.unpack def test_enabled_block_types(self, course_kwargs, user_kwargs, expected_blocks): course = create_course_run(**course_kwargs) user = create_user(**user_kwargs) CourseEnrollmentFactory(course_id=course.id, user=user, mode=CourseMode.VERIFIED) self.assert_block_types(course, user, expected_blocks) @ddt.data( # Course not started ({}, (CourseStartDate, TodaysDate, CourseEndDate)), # Course active ({'days_till_start': -1}, (TodaysDate, CourseEndDate)), # Course ended ({'days_till_start': -10, 'days_till_end': -5}, (TodaysDate, CourseEndDate)), ) @ddt.unpack def test_enabled_block_types_without_enrollment(self, course_kwargs, expected_blocks): course = create_course_run(**course_kwargs) user = create_user() self.assert_block_types(course, user, expected_blocks) def test_enabled_block_types_with_non_upgradeable_course_run(self): course = create_course_run(days_till_start=-10, days_till_verification_deadline=None) user = create_user() CourseMode.objects.get(course_id=course.id, mode_slug=CourseMode.VERIFIED).delete() CourseEnrollmentFactory(course_id=course.id, user=user, mode=CourseMode.AUDIT) self.assert_block_types(course, user, (TodaysDate, CourseEndDate)) def test_todays_date_block(self): """ Helper function to test that today's date block renders correctly and displays the correct time, accounting for daylight savings """ with freeze_time('2015-01-02'): course = create_course_run() user = create_user() block = TodaysDate(course, user) self.assertTrue(block.is_enabled) self.assertEqual(block.date, datetime.now(utc)) self.assertEqual(block.title, 'current_datetime') @ddt.data( 'info', 'openedx.course_experience.course_home', ) @override_waffle_flag(UNIFIED_COURSE_TAB_FLAG, active=True) def test_todays_date_no_timezone(self, url_name): with freeze_time('2015-01-02'): course = create_course_run() user = create_user() self.client.login(username=user.username, password=TEST_PASSWORD) html_elements = [ '