AA-4: Extreme defensiveness over any fields accessed from modulestore
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from six import unichr # pylint: disable=W0622
|
||||
from six import unichr
|
||||
|
||||
from contentstore.views.helpers import event as cms_user_track
|
||||
|
||||
@@ -20,7 +20,7 @@ class CMSLogTest(TestCase):
|
||||
"""
|
||||
requests = [
|
||||
{"event": "my_event", "event_type": "my_event_type", "page": "my_page"},
|
||||
{"event": "{'json': 'object'}", "event_type": unichr(512), "page": "my_page"} # pylint: disable=unicode-format-string
|
||||
{"event": "{'json': 'object'}", "event_type": unichr(512), "page": "my_page"}
|
||||
]
|
||||
for request_params in requests:
|
||||
response = self.client.post(reverse(cms_user_track), request_params)
|
||||
|
||||
@@ -15,6 +15,7 @@ from django.conf import settings
|
||||
from django.db.models import Prefetch
|
||||
from django.http import Http404, QueryDict
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
from edx_django_utils.monitoring import function_trace
|
||||
from edx_when.api import get_dates_for_course
|
||||
from fs.errors import ResourceNotFound
|
||||
@@ -442,11 +443,12 @@ def get_course_assignment_due_dates(course, user, request, num_return=None, incl
|
||||
|
||||
block_url = None
|
||||
now = datetime.now().replace(tzinfo=pytz.UTC)
|
||||
assignment_released = item.start < now
|
||||
assignment_released = item.start < now if item.start else None
|
||||
if assignment_released:
|
||||
block_url = reverse('jump_to', args=[course.id, block_key])
|
||||
block_url = request.build_absolute_uri(block_url) if request else None
|
||||
date_block.set_title(item.display_name, block_url)
|
||||
assignment_title = item.display_name if item.display_name else _('Assignment')
|
||||
date_block.set_title(assignment_title, block_url)
|
||||
|
||||
date_blocks.append(date_block)
|
||||
date_blocks = sorted((b for b in date_blocks if b.is_enabled or include_past_dates), key=date_block_key_fn)
|
||||
|
||||
@@ -62,6 +62,11 @@ class DateSummary(object):
|
||||
"""The title of this summary."""
|
||||
return ''
|
||||
|
||||
@property
|
||||
def title_html(self):
|
||||
"""The title as html for this summary."""
|
||||
return ''
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
"""The detail text displayed by this summary."""
|
||||
@@ -340,6 +345,7 @@ class CourseAssignmentDate(DateSummary):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.assignment_date = None
|
||||
self.assignment_title = None
|
||||
self.assignment_title_html = None
|
||||
|
||||
@property
|
||||
def date(self):
|
||||
@@ -353,13 +359,17 @@ class CourseAssignmentDate(DateSummary):
|
||||
def title(self):
|
||||
return self.assignment_title
|
||||
|
||||
@property
|
||||
def title_html(self):
|
||||
return self.assignment_title_html
|
||||
|
||||
def set_title(self, title, link=None):
|
||||
""" Used to set the title_html and title properties for the assignment date block """
|
||||
if link:
|
||||
self.assignment_title = HTML(
|
||||
self.assignment_title_html = HTML(
|
||||
'<a href="{assignment_link}">{assignment_title}</a>'
|
||||
).format(assignment_link=link, assignment_title=title)
|
||||
else:
|
||||
self.assignment_title = title
|
||||
self.assignment_title = title
|
||||
|
||||
|
||||
class CourseExpiredDate(DateSummary):
|
||||
|
||||
@@ -132,7 +132,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
CourseEnrollmentFactory(course_id=course.id, user=user, mode=CourseMode.VERIFIED)
|
||||
self.assert_block_types(course, user, expected_blocks)
|
||||
|
||||
def test_enabled_block_types_with_assignments(self):
|
||||
def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many-statements
|
||||
"""
|
||||
Creates a course with multiple subsections to test all of the different
|
||||
cases for assignment dates showing up. Mocks out calling the edx-when
|
||||
@@ -187,6 +187,24 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
due=now - timedelta(days=7),
|
||||
graded=False,
|
||||
)
|
||||
subsection_6 = ItemFactory.create(
|
||||
category='sequential',
|
||||
display_name='No start date',
|
||||
parent_location=section.location,
|
||||
start=None,
|
||||
due=now + timedelta(days=9),
|
||||
graded=True,
|
||||
)
|
||||
subsection_7 = ItemFactory.create(
|
||||
category='sequential',
|
||||
# Setting display name to None should set the assignment title to 'Assignment'
|
||||
display_name=None,
|
||||
parent_location=section.location,
|
||||
start=now - timedelta(days=14),
|
||||
due=now + timedelta(days=10),
|
||||
graded=True,
|
||||
)
|
||||
dummy_subsection = ItemFactory.create(category='sequential')
|
||||
|
||||
with patch('lms.djangoapps.courseware.courses.get_dates_for_course') as mock_get_dates:
|
||||
mock_get_dates.return_value = {
|
||||
@@ -200,6 +218,12 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
(subsection_4.location, 'start'): subsection_4.start,
|
||||
(subsection_5.location, 'due'): subsection_5.due,
|
||||
(subsection_5.location, 'start'): subsection_5.start,
|
||||
(subsection_6.location, 'due'): subsection_6.due,
|
||||
(subsection_7.location, 'due'): subsection_7.due,
|
||||
(subsection_7.location, 'start'): subsection_7.start,
|
||||
# Adding this in for the case where we return a block that
|
||||
# doesn't actually exist as part of the course. Should just be ignored.
|
||||
(dummy_subsection.location, 'due'): dummy_subsection.due,
|
||||
}
|
||||
# Standard widget case where we restrict the number of assignments.
|
||||
expected_blocks = (
|
||||
@@ -210,7 +234,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
self.assertEqual(set(type(b) for b in blocks), set(expected_blocks))
|
||||
assignment_blocks = filter(lambda b: isinstance(b, CourseAssignmentDate), blocks)
|
||||
for assignment in assignment_blocks:
|
||||
assignment_title = str(assignment.title)
|
||||
assignment_title = str(assignment.title_html) or str(assignment.title)
|
||||
self.assertNotEqual(assignment_title, 'Third nearest assignment')
|
||||
self.assertNotEqual(assignment_title, 'Past due date')
|
||||
self.assertNotEqual(assignment_title, 'Not returned since we do not get non-graded subsections')
|
||||
@@ -226,14 +250,15 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
# No restrictions on number of assignments to return
|
||||
expected_blocks = (
|
||||
CourseStartDate, TodaysDate, CourseAssignmentDate, CourseAssignmentDate, CourseAssignmentDate,
|
||||
CourseAssignmentDate, CourseEndDate, VerificationDeadlineDate
|
||||
CourseAssignmentDate, CourseAssignmentDate, CourseAssignmentDate, CourseEndDate,
|
||||
VerificationDeadlineDate
|
||||
)
|
||||
blocks = get_course_date_blocks(course, user, request, include_past_dates=True)
|
||||
self.assertEqual(len(blocks), len(expected_blocks))
|
||||
self.assertEqual(set(type(b) for b in blocks), set(expected_blocks))
|
||||
assignment_blocks = filter(lambda b: isinstance(b, CourseAssignmentDate), blocks)
|
||||
for assignment in assignment_blocks:
|
||||
assignment_title = str(assignment.title)
|
||||
assignment_title = str(assignment.title_html) or str(assignment.title)
|
||||
self.assertNotEqual(assignment_title, 'Not returned since we do not get non-graded subsections')
|
||||
# checking if it is _in_ the title instead of being the title since released assignments
|
||||
# are actually links. Unreleased assignments are just the string of the title.
|
||||
@@ -251,6 +276,15 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
self.assertGreater(now, assignment.date)
|
||||
for html_tag in assignment_title_html:
|
||||
self.assertIn(html_tag, assignment_title)
|
||||
elif 'No start date' == assignment_title:
|
||||
# Can't determine if it is released so it does not get a link
|
||||
for html_tag in assignment_title_html:
|
||||
self.assertNotIn(html_tag, assignment_title)
|
||||
# This is the item with no display name where we set one ourselves.
|
||||
elif 'Assignment' in assignment_title:
|
||||
# Can't determine if it is released so it does not get a link
|
||||
for html_tag in assignment_title_html:
|
||||
self.assertIn(html_tag, assignment_title)
|
||||
|
||||
def test_enabled_block_types_with_expired_course(self):
|
||||
course = create_course_run(days_till_start=-100)
|
||||
|
||||
@@ -10,7 +10,9 @@ from django.utils.translation import ugettext as _
|
||||
% if course_date.date:
|
||||
<p class="hd hd-6 date localized-datetime" data-format="shortDate" data-datetime="${course_date.date}" data-timezone="${user_timezone}" data-language="${user_language}"></p>
|
||||
% endif
|
||||
% if course_date.title:
|
||||
% if course_date.title_html:
|
||||
<div class="hd hd-6 heading">${course_date.title_html}</div>
|
||||
% elif course_date.title:
|
||||
<div class="hd hd-6 heading">${course_date.title}</div>
|
||||
% endif
|
||||
% if course_date.description:
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
set -e
|
||||
|
||||
export LOWER_PYLINT_THRESHOLD=1000
|
||||
export UPPER_PYLINT_THRESHOLD=2005
|
||||
export UPPER_PYLINT_THRESHOLD=1993
|
||||
export ESLINT_THRESHOLD=5530
|
||||
export STYLELINT_THRESHOLD=880
|
||||
|
||||
Reference in New Issue
Block a user