From 707371e1d759d74ac6e50158e8a43f3a03d66e7c Mon Sep 17 00:00:00 2001 From: Gregory Martin Date: Thu, 3 Nov 2016 11:44:49 -0400 Subject: [PATCH] Refactor info.html page datetime rendering --- lms/djangoapps/courseware/courses.py | 13 +- lms/djangoapps/courseware/date_summary.py | 32 +--- .../courseware/tests/test_date_summary.py | 139 ++++++++---------- lms/templates/courseware/date_summary.html | 18 --- lms/templates/courseware/info.html | 52 +++++-- 5 files changed, 111 insertions(+), 143 deletions(-) delete mode 100644 lms/templates/courseware/date_summary.html diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py index da6e88153c..4d3a84c6ee 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -294,18 +294,7 @@ def get_course_info_section(request, user, course, section_key): return html -def get_course_date_summary(course, user): - """ - Return the snippet of HTML to be included on the course info page - in the 'Date Summary' section. - """ - blocks = _get_course_date_summary_blocks(course, user) - return '\n'.join( - b.render() for b in blocks - ) - - -def _get_course_date_summary_blocks(course, user): +def get_course_date_blocks(course, user): """ Return the list of blocks to display on the course info page, sorted by date. diff --git a/lms/djangoapps/courseware/date_summary.py b/lms/djangoapps/courseware/date_summary.py index e6aaf5524f..c0f92b92a8 100644 --- a/lms/djangoapps/courseware/date_summary.py +++ b/lms/djangoapps/courseware/date_summary.py @@ -11,14 +11,12 @@ from django.core.urlresolvers import reverse from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy from django.utils.translation import to_locale, get_language -from edxmako.shortcuts import render_to_string from lazy import lazy from course_modes.models import CourseMode from lms.djangoapps.commerce.utils import EcommerceService from lms.djangoapps.verify_student.models import VerificationDeadline, SoftwareSecurePhotoVerification from student.models import CourseEnrollment -from openedx.core.lib.time_zone_utils import get_time_zone_abbr class DateSummary(object): @@ -78,24 +76,8 @@ class DateSummary(object): self.course = course self.user = user - def get_context(self): - """Return the template context used to render this summary block.""" - return { - 'title': self.title, - 'date': self._format_date(), - 'description': self.description, - 'css_class': self.css_class, - 'link': self.link, - 'link_text': self.link_text, - } - - def render(self): - """ - Return an HTML representation of this summary block. - """ - return render_to_string('courseware/date_summary.html', self.get_context()) - - def _format_date(self): + @property + def relative_datestring(self): """ Return this block's date in a human-readable format. If the date is None, returns the empty string. @@ -121,7 +103,7 @@ class DateSummary(object): date_format = _(u"{relative} ago - {absolute}") if date_has_passed else _(u"in {relative} - {absolute}") return date_format.format( relative=relative_date, - absolute=self.date.astimezone(self.time_zone).strftime(self.date_format.encode('utf-8')).decode('utf-8'), + absolute='{date}', ) @property @@ -151,10 +133,6 @@ class TodaysDate(DateSummary): css_class = 'todays-date' is_enabled = True - @property - def date_format(self): - return u'%b %d, %Y (%H:%M {tz_abbr})'.format(tz_abbr=get_time_zone_abbr(self.time_zone)) - # The date is shown in the title, no need to display it again. def get_context(self): context = super(TodaysDate, self).get_context() @@ -167,9 +145,7 @@ class TodaysDate(DateSummary): @property def title(self): - return _(u'Today is {date}').format( - date=self.date.astimezone(self.time_zone).strftime(self.date_format.encode('utf-8')).decode('utf-8') - ) + return 'current_datetime' class CourseStartDate(DateSummary): diff --git a/lms/djangoapps/courseware/tests/test_date_summary.py b/lms/djangoapps/courseware/tests/test_date_summary.py index 7676a9367b..ec123683b4 100644 --- a/lms/djangoapps/courseware/tests/test_date_summary.py +++ b/lms/djangoapps/courseware/tests/test_date_summary.py @@ -11,7 +11,7 @@ from pytz import utc from commerce.models import CommerceConfiguration from course_modes.tests.factories import CourseModeFactory from course_modes.models import CourseMode -from courseware.courses import _get_course_date_summary_blocks +from courseware.courses import get_course_date_blocks from courseware.date_summary import ( CourseEndDate, CourseStartDate, @@ -55,7 +55,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): self.course = CourseFactory.create( # pylint: disable=attribute-defined-outside-init start=now + timedelta(days=days_till_start) ) - self.user = UserFactory.create() # pylint: disable=attribute-defined-outside-init + self.user = UserFactory.create(username='mrrobot', password='test') # pylint: disable=attribute-defined-outside-init if days_till_end is not None: self.course.end = now + timedelta(days=days_till_end) @@ -92,10 +92,9 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): self.assertNotIn('date-summary', response.content) # Tests for which blocks are enabled - def assert_block_types(self, expected_blocks): """Assert that the enabled block types for this course are as expected.""" - blocks = _get_course_date_summary_blocks(self.course, self.user) + blocks = get_course_date_blocks(self.course, self.user) self.assertEqual(len(blocks), len(expected_blocks)) self.assertEqual(set(type(b) for b in blocks), set(expected_blocks)) @@ -163,64 +162,58 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): self.setup_course_and_user(**course_options) self.assert_block_types(expected_blocks) - # Specific block type tests - - ## Base DateSummary -- test empty defaults - - def test_date_summary(self): - self.setup_course_and_user() - block = DateSummary(self.course, self.user) - html = '
' - self.assertHTMLEqual(block.render(), html) - self.assertFalse(block.is_enabled) - - ## TodaysDate - - def _today_date_helper(self, expected_display_date): + @freeze_time('2015-01-02') + 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 """ self.setup_course_and_user() - set_user_preference(self.user, "time_zone", "America/Los_Angeles") block = TodaysDate(self.course, self.user) self.assertTrue(block.is_enabled) self.assertEqual(block.date, datetime.now(utc)) - self.assertEqual(block.title, 'Today is {date}'.format(date=expected_display_date)) - self.assertNotIn('date-summary-date', block.render()) - - @freeze_time('2015-11-01 08:59:00') - def test_todays_date_time_zone_daylight(self): - """ - Test today's date block displays correctly during - daylight savings hours - """ - self._today_date_helper('Nov 01, 2015 (01:59 PDT)') - - @freeze_time('2015-11-01 09:00:00') - def test_todays_date_time_zone_normal(self): - """ - Test today's date block displays correctly during - normal daylight hours - """ - self._today_date_helper('Nov 01, 2015 (01:00 PST)') + self.assertEqual(block.title, 'current_datetime') @freeze_time('2015-01-02') - def test_todays_date_render(self): + def test_todays_date_no_timezone(self): self.setup_course_and_user() - block = TodaysDate(self.course, self.user) - self.assertIn('Jan 02, 2015', block.render()) + self.client.login(username='mrrobot', password='test') + + html_elements = [ + '

Important Course Dates

', + '
', + '
', + '

Important Course Dates

', + '
', + '
', + '

-
- % if title: -

${title}

- % endif - % if date: -

${date}

- % endif - % if description: -

${description}

- % endif - % if link and link_text: - - ${link_text} - - % endif -
-

diff --git a/lms/templates/courseware/info.html b/lms/templates/courseware/info.html index 94dcb85b13..8bf2ae859f 100644 --- a/lms/templates/courseware/info.html +++ b/lms/templates/courseware/info.html @@ -3,10 +3,12 @@ <%def name="online_help_token()"><% return "courseinfo" %> <%namespace name='static' file='../static_content.html'/> <%! +from datetime import datetime +from pytz import timezone, utc + from django.utils.translation import ugettext as _ -from courseware.courses import get_course_info_section, get_course_date_summary - +from courseware.courses import get_course_info_section, get_course_date_blocks from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangolib.markup import HTML, Text %> @@ -89,15 +91,40 @@ from openedx.core.djangolib.markup import HTML, Text % endif
- % if SelfPacedConfiguration.current().enable_course_home_improvements: -

${_("Important Course Dates")}

- ${HTML(get_course_date_summary(course, user))} - % endif -

${_(course.info_sidebar_name)}

- ${HTML(get_course_info_section(request, masquerade_user, course, 'handouts'))} + % if SelfPacedConfiguration.current().enable_course_home_improvements: +

${_("Important Course Dates")}

+ ## Should be organized by date, last date appearing at the bottom + + % for course_date in get_course_date_blocks(course, user): +
+
+ % if course_date.title: + % if course_date.title == 'current_datetime': +

+ % else: +

${course_date.title}

+ % endif + % endif + % if course_date.date and course_date.title != 'current_datetime': +

+ % endif + % if course_date.description: +

${course_date.description}

+ % endif + % if course_date.link and course_date.link_text: + + ${course_date.link_text} + + % endif +
+
+ % endfor + % endif +

${_(course.info_sidebar_name)}

+ ${HTML(get_course_info_section(request, masquerade_user, course, 'handouts'))}
- % else: + % else:

${_("Course Updates and News")}

${HTML(get_course_info_section(request, masquerade_user, course, 'guest_updates'))} @@ -106,7 +133,12 @@ from openedx.core.djangolib.markup import HTML, Text

${_("Course Handouts")}

${HTML(get_course_info_section(request, masquerade_user, course, 'guest_handouts'))}
- % endif + + % endif
+ +<%static:require_module_async module_name="js/dateutil_factory" class_name="DateUtilFactory"> + DateUtilFactory.transform(iterationKey=".localized-datetime"); +