AA-173: Assignment Type on Dates Page

Appending the assignment type to each graded
assignment on the Dates Tab. Exposed the 'format'
field, which corresponds to the graded assignment type.
This commit is contained in:
Carla Duarte
2020-06-01 10:59:15 -04:00
parent cdc1c91980
commit 01b693a5c3
5 changed files with 34 additions and 5 deletions

View File

@@ -72,7 +72,8 @@ log = logging.getLogger(__name__)
# Used by get_course_assignments below. You shouldn't need to use this type directly.
_Assignment = namedtuple(
'Assignment', ['block_key', 'title', 'url', 'date', 'contains_gated_content', 'complete', 'past_due']
'Assignment', ['block_key', 'title', 'url', 'date', 'contains_gated_content', 'complete', 'past_due',
'assignment_type']
)
@@ -505,6 +506,7 @@ def get_course_assignment_date_blocks(course, user, request, num_return=None,
date_block.date = assignment.date
date_block.contains_gated_content = assignment.contains_gated_content
date_block.complete = assignment.complete
date_block.assignment_type = assignment.assignment_type
date_block.past_due = assignment.past_due
date_block.link = assignment.url
date_block.set_title(assignment.title, link=assignment.url)
@@ -520,7 +522,8 @@ def get_course_assignments(course_key, user, request, include_access=False):
"""
Returns a list of assignment (at the subsection/sequential level) due dates for the given course.
Each returned object is a namedtuple with fields: title, url, date, contains_gated_content, complete, past_due
Each returned object is a namedtuple with fields: title, url, date, contains_gated_content, complete, past_due,
assignment_type
"""
store = modulestore()
course_usage_key = store.make_course_usage_key(course_key)
@@ -539,6 +542,8 @@ def get_course_assignments(course_key, user, request, include_access=False):
subsection_key, 'contains_gated_content', False)
title = block_data.get_xblock_field(subsection_key, 'display_name', _('Assignment'))
assignment_type = block_data.get_xblock_field(subsection_key, 'format', None)
url = ''
start = block_data.get_xblock_field(subsection_key, 'start')
assignment_released = not start or start < now
@@ -549,7 +554,7 @@ def get_course_assignments(course_key, user, request, include_access=False):
complete = block_data.get_xblock_field(subsection_key, 'complete', False)
past_due = not complete and due < now
assignments.append(_Assignment(
subsection_key, title, url, due, contains_gated_content, complete, past_due
subsection_key, title, url, due, contains_gated_content, complete, past_due, assignment_type
))
return assignments

View File

@@ -165,6 +165,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
start=now - timedelta(days=1),
due=now + timedelta(days=6),
graded=True,
format='Homework',
)
ItemFactory.create(
category='sequential',
@@ -173,6 +174,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
start=now + timedelta(days=1),
due=now + timedelta(days=7),
graded=True,
format='Homework',
)
ItemFactory.create(
category='sequential',
@@ -181,6 +183,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
start=now + timedelta(days=1),
due=now + timedelta(days=8),
graded=True,
format='Exam',
)
ItemFactory.create(
category='sequential',
@@ -189,6 +192,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
start=now - timedelta(days=14),
due=now - timedelta(days=7),
graded=True,
format='Exam',
)
ItemFactory.create(
category='sequential',
@@ -205,6 +209,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
start=None,
due=now + timedelta(days=9),
graded=True,
format='Speech',
)
ItemFactory.create(
category='sequential',
@@ -214,6 +219,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
start=now - timedelta(days=14),
due=now + timedelta(days=10),
graded=True,
format=None,
)
dummy_subsection = ItemFactory.create(category='sequential', graded=True, due=now + timedelta(days=11))
@@ -257,28 +263,37 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
for assignment in assignment_blocks:
assignment_title = str(assignment.title_html) or str(assignment.title)
self.assertNotEqual(assignment_title, 'Not returned since we do not get non-graded subsections')
assignment_type = str(assignment.assignment_type)
# 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.
# also checking that the assignment type is returned for graded subsections
if 'Released' in assignment_title:
self.assertEqual(assignment_type, 'Homework')
for html_tag in assignment_title_html:
self.assertIn(html_tag, assignment_title)
elif assignment_title == 'Not released':
self.assertEqual(assignment_type, 'Homework')
for html_tag in assignment_title_html:
self.assertNotIn(html_tag, assignment_title)
elif assignment_title == 'Third nearest assignment':
self.assertEqual(assignment_type, 'Exam')
# It's still not released
for html_tag in assignment_title_html:
self.assertNotIn(html_tag, assignment_title)
elif 'Past due date' in assignment_title:
self.assertGreater(now, assignment.date)
self.assertEqual(assignment_type, 'Exam')
for html_tag in assignment_title_html:
self.assertIn(html_tag, assignment_title)
elif 'No start date' == assignment_title:
self.assertEqual(assignment_type, 'Speech')
# 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:
self.assertEqual(assignment_type, None)
# 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)

View File

@@ -3117,6 +3117,7 @@ class DatesTabTestCase(ModuleStoreTestCase):
start=now - timedelta(days=1),
due=now + timedelta(days=1), # Setting this to tomorrow so it'll show the 'Due Next' pill
graded=True,
format='Homework',
)
vertical = ItemFactory.create(category='vertical', parent_location=subsection.location)
ItemFactory.create(category='problem', parent_location=vertical.location)
@@ -3135,6 +3136,8 @@ class DatesTabTestCase(ModuleStoreTestCase):
self.assertContains(response, '<div class="pill due-next">')
# No pills for verified enrollments
self.assertNotContains(response, '<div class="pill verified">')
# Make sure the assignment type is rendered
self.assertContains(response, 'Homework:')
enrollment.delete()
enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user, mode=CourseMode.AUDIT)
@@ -3158,6 +3161,8 @@ class DatesTabTestCase(ModuleStoreTestCase):
self.assertNotContains(response, '<div class="pill due-next">')
# Should have verified pills for audit enrollments
self.assertContains(response, '<div class="pill verified">')
# Make sure the assignment type is rendered
self.assertContains(response, 'Homework:')
@RELATIVE_DATES_FLAG.override(active=True)
def test_reset_deadlines_banner_displays(self):

View File

@@ -33,6 +33,7 @@ from openedx.core.djangolib.markup import HTML, Text
<% learner_has_access = not block_is_verified or learner_is_full_access %>
<% access_class = '' if learner_has_access else 'no-access' %>
<% is_assignment = isinstance(block, CourseAssignmentDate) %>
<% assignment_type = is_assignment and block.assignment_type %>
<% todays_date = 'todays-date' if isinstance(block, TodaysDate) else '' %>
<% past_date = 'past-date' if block.date and block.date < block.current_time else '' %>
<% past_due = 'past-due' if learner_is_full_access and is_assignment and block.past_due else '' %>
@@ -69,6 +70,9 @@ from openedx.core.djangolib.markup import HTML, Text
</div>
% if not todays_date:
<div class="timeline-title ${access_class} ${not_released}">
% if assignment_type:
${assignment_type}:&nbsp;
% endif
% if block.title_html and is_assignment and learner_has_access:
${block.title_html}
% else:

View File

@@ -33,10 +33,10 @@ class TestIcsGeneration(TestCase):
def make_assigment(
self, block_key=None, title=None, url=None, date=None, contains_gated_content=False, complete=False,
past_due=False
past_due=False, assignment_type=None
):
""" Bundles given info into a namedtupled like get_course_assignments returns """
return _Assignment(block_key, title, url, date, contains_gated_content, complete, past_due)
return _Assignment(block_key, title, url, date, contains_gated_content, complete, past_due, assignment_type)
def expected_ics(self, *assignments):
""" Returns hardcoded expected ics strings for given assignments """