Commit 4c934614 by Peter Fogg

Merge pull request #10512 from edx/peter-fogg/date-summary-bugfix

Fix date summary blocks for courses without an end date.
parents 7c480f93 44538623
"""
Functions for accessing and displaying courses within the
courseware.
"""
from datetime import datetime
from collections import defaultdict from collections import defaultdict
from fs.errors import ResourceNotFoundError from fs.errors import ResourceNotFoundError
import logging import logging
import inspect import inspect
from path import Path as path from path import Path as path
import pytz
from django.http import Http404 from django.http import Http404
from django.conf import settings from django.conf import settings
...@@ -334,7 +340,16 @@ def _get_course_date_summary_blocks(course, user): ...@@ -334,7 +340,16 @@ def _get_course_date_summary_blocks(course, user):
) )
blocks = (cls(course, user) for cls in block_classes) blocks = (cls(course, user) for cls in block_classes)
return sorted((b for b in blocks if b.is_enabled), key=lambda b: b.date)
def block_key_fn(block):
"""
If the block's date is None, return the maximum datetime in order
to force it to the end of the list of displayed blocks.
"""
if block.date is None:
return datetime.max.replace(tzinfo=pytz.UTC)
return block.date
return sorted((b for b in blocks if b.is_enabled), key=block_key_fn)
# TODO: Fix this such that these are pulled in as extra course-specific tabs. # TODO: Fix this such that these are pulled in as extra course-specific tabs.
......
# pylint: disable=missing-docstring
""" """
This module provides date summary blocks for the Course Info This module provides date summary blocks for the Course Info
page. Each block gives information about a particular page. Each block gives information about a particular
...@@ -20,27 +19,46 @@ from student.models import CourseEnrollment ...@@ -20,27 +19,46 @@ from student.models import CourseEnrollment
class DateSummary(object): class DateSummary(object):
"""Base class for all date summary blocks.""" """Base class for all date summary blocks."""
# The CSS class of this summary. Indicates the type of information @property
# this summary block contains, and its urgency. def css_class(self):
css_class = '' """
The CSS class of this summary. Indicates the type of information
this summary block contains, and its urgency.
"""
return ''
# The title of this summary. @property
title = '' def title(self):
"""The title of this summary."""
return ''
# The detail text displayed by this summary. @property
description = '' def description(self):
"""The detail text displayed by this summary."""
return ''
# This summary's date. @property
date = None def date(self):
"""This summary's date."""
return None
# The format to display this date in. By default, displays like Jan 01, 2015. @property
date_format = '%b %d, %Y' def date_format(self):
"""
The format to display this date in. By default, displays like Jan
01, 2015.
"""
return '%b %d, %Y'
# The location to link to for more information. @property
link = '' def link(self):
"""The location to link to for more information."""
return ''
# The text of the link. @property
link_text = '' def link_text(self):
"""The text of the link."""
return ''
def __init__(self, course, user): def __init__(self, course, user):
self.course = course self.course = course
...@@ -126,7 +144,10 @@ class CourseEndDate(DateSummary): ...@@ -126,7 +144,10 @@ class CourseEndDate(DateSummary):
""" """
css_class = 'end-date' css_class = 'end-date'
title = _('Course End') title = _('Course End')
is_enabled = True
@property
def is_enabled(self):
return self.date is not None
@property @property
def description(self): def description(self):
......
...@@ -48,11 +48,15 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): ...@@ -48,11 +48,15 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
"""Set up the course and user for this test.""" """Set up the course and user for this test."""
now = datetime.now(pytz.UTC) now = datetime.now(pytz.UTC)
self.course = CourseFactory.create( # pylint: disable=attribute-defined-outside-init self.course = CourseFactory.create( # pylint: disable=attribute-defined-outside-init
start=now + timedelta(days=days_till_start), start=now + timedelta(days=days_till_start)
end=now + timedelta(days=days_till_end),
) )
self.user = UserFactory.create() # pylint: disable=attribute-defined-outside-init self.user = UserFactory.create() # pylint: disable=attribute-defined-outside-init
if days_till_end is not None:
self.course.end = now + timedelta(days=days_till_end)
else:
self.course.end = None
if enrollment_mode is not None and days_till_upgrade_deadline is not None: if enrollment_mode is not None and days_till_upgrade_deadline is not None:
CourseModeFactory.create( CourseModeFactory.create(
course_id=self.course.id, course_id=self.course.id,
...@@ -97,6 +101,9 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): ...@@ -97,6 +101,9 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
'days_till_verification_deadline': -5, 'days_till_verification_deadline': -5,
'verification_status': 'approved'}, 'verification_status': 'approved'},
(TodaysDate, CourseEndDate)), (TodaysDate, CourseEndDate)),
# No course end date
({'days_till_end': None},
(CourseStartDate, TodaysDate, VerificationDeadlineDate, VerifiedUpgradeDeadlineDate)),
# During course run # During course run
({'days_till_start': -1}, ({'days_till_start': -1},
(TodaysDate, CourseEndDate, VerificationDeadlineDate, VerifiedUpgradeDeadlineDate)), (TodaysDate, CourseEndDate, VerificationDeadlineDate, VerifiedUpgradeDeadlineDate)),
...@@ -131,13 +138,6 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): ...@@ -131,13 +138,6 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
self.assertHTMLEqual(block.render(), html) self.assertHTMLEqual(block.render(), html)
self.assertFalse(block.is_enabled) self.assertFalse(block.is_enabled)
@freezegun.freeze_time('2015-01-02')
def test_date_render(self):
self.setup_course_and_user()
block = DateSummary(self.course, self.user)
block.date = datetime.now(pytz.UTC)
self.assertIn('Jan 02, 2015', block.render())
## TodaysDate ## TodaysDate
@freezegun.freeze_time('2015-01-02') @freezegun.freeze_time('2015-01-02')
...@@ -149,6 +149,12 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): ...@@ -149,6 +149,12 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
self.assertEqual(block.title, 'Today is Jan 02, 2015') self.assertEqual(block.title, 'Today is Jan 02, 2015')
self.assertNotIn('date-summary-date', block.render()) self.assertNotIn('date-summary-date', block.render())
@freezegun.freeze_time('2015-01-02')
def test_date_render(self):
self.setup_course_and_user()
block = TodaysDate(self.course, self.user)
self.assertIn('Jan 02, 2015', block.render())
## CourseStartDate ## CourseStartDate
def test_course_start_date(self): def test_course_start_date(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment