displaying title of sequence item in tooltip instead of children

This commit is contained in:
Sanford Student
2016-04-05 08:28:15 -04:00
parent 393e885e4b
commit bbcec0cf40
12 changed files with 176 additions and 140 deletions

View File

@@ -218,13 +218,9 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
rendered_child = child.render(STUDENT_VIEW, context)
fragment.add_frag_resources(rendered_child)
# `titles` is a list of titles to inject into the sequential tooltip display.
# We omit any blank titles to avoid blank lines in the tooltip display.
titles = [title.strip() for title in child.get_content_titles() if title.strip()]
childinfo = {
'content': rendered_child.content,
'title': "\n".join(titles),
'page_title': titles[0] if titles else '',
'page_title': getattr(child, 'tooltip_title', ''),
'progress_status': Progress.to_js_status_str(progress),
'progress_detail': Progress.to_js_detail_str(progress),
'type': child.get_icon_class(),
@@ -232,8 +228,7 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
'bookmarked': is_bookmarked,
'path': " > ".join(display_names + [child.display_name_with_default]),
}
if childinfo['title'] == '':
childinfo['title'] = child.display_name_with_default_escaped
contents.append(childinfo)
params = {

View File

@@ -356,6 +356,10 @@ class SplitTestModule(SplitTestFields, XModule, StudioEditableModule):
return (group.name, group.id)
return (None, None)
@property
def tooltip_title(self):
return getattr(self.child, 'tooltip_title', '')
def validate(self):
"""
Message for either error or warning validation message/s.
@@ -695,3 +699,5 @@ class SplitTestDescriptor(SplitTestFields, SequenceDescriptor, StudioEditableDes
)
self.children.append(dest_usage_key) # pylint: disable=no-member
self.group_id_to_child[unicode(group.id)] = dest_usage_key
tooltip_title = module_attr('tooltip_title')

View File

@@ -161,3 +161,8 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
lambda course_key, block_location, child: block_location,
)
self.assertEquals(actual_next_sequence_location, expected_prev_sequence_location)
def test_tooltip(self):
html = self._get_rendered_student_view(self.sequence_3_1, requested_child=None)
for child in self.sequence_3_1.children:
self.assertIn("'page_title': '{}'".format(child.name), html)

View File

@@ -365,6 +365,13 @@ class XModuleMixin(XModuleFields, XBlock):
"""
return course_metadata_utils.display_name_with_default_escaped(self)
@property
def tooltip_title(self):
"""
Return the title for the sequence item containing this xmodule as its top level item.
"""
return self.display_name_with_default
@property
def xblock_kvs(self):
"""

View File

@@ -103,20 +103,20 @@ class CourseNavPage(PageObject):
self.q(css=subsection_css).first.click()
self._on_section_promise(section_title, subsection_title).fulfill()
def go_to_sequential(self, sequential_title):
def go_to_vertical(self, vertical_title):
"""
Within a section/subsection, navigate to the sequential with `sequential_title`.
Within a section/subsection, navigate to the vertical with `vertical_title`.
"""
# Get the index of the item in the sequence
all_items = self.sequence_items
try:
seq_index = all_items.index(sequential_title)
seq_index = all_items.index(vertical_title)
except ValueError:
msg = "Could not find sequential '{0}'. Available sequentials: [{1}]".format(
sequential_title, ", ".join(all_items)
vertical_title, ", ".join(all_items)
)
self.warning(msg)

View File

@@ -212,7 +212,7 @@ class CertificateProgressPageTest(UniqueCourseTest):
self.course_nav.go_to_section('Test Section', 'Test Subsection')
# Navigate to Test Problem 1
self.course_nav.go_to_sequential('Test Problem 1')
self.course_nav.go_to_vertical('Test Problem 1')
# Select correct value for from select menu
self.course_nav.q(css='select option[value="{}"]'.format('blue')).first.click()
@@ -232,7 +232,7 @@ class CertificateProgressPageTest(UniqueCourseTest):
self.course_nav.go_to_section('Test Section 2', 'Test Subsection 2')
# Navigate to Test Problem 2
self.course_nav.go_to_sequential('Test Problem 2')
self.course_nav.go_to_vertical('Test Problem 2')
# Fill in the answer of the problem
self.course_nav.q(css='input[id^=input_][id$=_2_1]').fill('A*x^2 + sqrt(y)')

View File

@@ -824,13 +824,13 @@ class VisibleToStaffOnlyTest(UniqueCourseTest):
self.assertEqual(3, len(self.course_nav.sections['Test Section']))
self.course_nav.go_to_section("Test Section", "Subsection With Locked Unit")
self.assertEqual(["Html Child in locked unit", "Html Child in unlocked unit"], self.course_nav.sequence_items)
self.assertEqual([u'Locked Unit', u'Unlocked Unit'], self.course_nav.sequence_items)
self.course_nav.go_to_section("Test Section", "Unlocked Subsection")
self.assertEqual(["Html Child in visible unit"], self.course_nav.sequence_items)
self.assertEqual([u'Test Unit'], self.course_nav.sequence_items)
self.course_nav.go_to_section("Test Section", "Locked Subsection")
self.assertEqual(["Html Child in locked subsection"], self.course_nav.sequence_items)
self.assertEqual([u'Test Unit'], self.course_nav.sequence_items)
def test_visible_to_student(self):
"""
@@ -846,10 +846,10 @@ class VisibleToStaffOnlyTest(UniqueCourseTest):
self.assertEqual(2, len(self.course_nav.sections['Test Section']))
self.course_nav.go_to_section("Test Section", "Subsection With Locked Unit")
self.assertEqual(["Html Child in unlocked unit"], self.course_nav.sequence_items)
self.assertEqual([u'Unlocked Unit'], self.course_nav.sequence_items)
self.course_nav.go_to_section("Test Section", "Unlocked Subsection")
self.assertEqual(["Html Child in visible unit"], self.course_nav.sequence_items)
self.assertEqual([u'Test Unit'], self.course_nav.sequence_items)
@attr('shard_1')

View File

@@ -61,7 +61,7 @@ class VideoBaseTest(UniqueCourseTest):
self.metadata = None
self.assets = []
self.verticals = None
self.contents_of_verticals = None
self.youtube_configuration = {}
self.user_info = {}
@@ -102,28 +102,28 @@ class VideoBaseTest(UniqueCourseTest):
:return: a list of XBlockFixtureDesc
"""
xblock_verticals = []
_verticals = self.verticals
_contents_of_verticals = self.contents_of_verticals
# Video tests require at least one vertical with a single video.
if not _verticals:
_verticals = [[{'display_name': 'Video', 'metadata': self.metadata}]]
if not _contents_of_verticals:
_contents_of_verticals = [[{'display_name': 'Video', 'metadata': self.metadata}]]
for vertical_index, vertical in enumerate(_verticals):
for vertical_index, vertical in enumerate(_contents_of_verticals):
xblock_verticals.append(self._create_single_vertical(vertical, vertical_index))
return xblock_verticals
def _create_single_vertical(self, vertical, vertical_index):
def _create_single_vertical(self, vertical_contents, vertical_index):
"""
Create a single course vertical of type XBlockFixtureDesc with category `vertical`.
A single course vertical can contain single or multiple video modules.
:param vertical: vertical data list
:param vertical_contents: a list of items for the vertical to contain
:param vertical_index: index for the vertical display name
:return: XBlockFixtureDesc
"""
xblock_course_vertical = XBlockFixtureDesc('vertical', 'Test Vertical-{0}'.format(vertical_index))
for video in vertical:
for video in vertical_contents:
xblock_course_vertical.add_children(
XBlockFixtureDesc('video', video['display_name'], metadata=video.get('metadata')))
@@ -512,13 +512,13 @@ class YouTubeVideoTest(VideoBaseTest):
data_c = {'track': 'http://example.org/', 'download_track': True}
html5_c_metadata = self.metadata_for_mode('html5', additional_data=data_c)
self.verticals = [
self.contents_of_verticals = [
[{'display_name': 'A', 'metadata': youtube_a_metadata}],
[{'display_name': 'B', 'metadata': youtube_b_metadata}],
[{'display_name': 'C', 'metadata': html5_c_metadata}]
]
# open the section with videos (open video "A")
# open the section with videos (open vertical containing video "A")
self.navigate_to_video()
# check if we can download transcript in "srt" format that has text "00:00:00,260"
@@ -530,14 +530,14 @@ class YouTubeVideoTest(VideoBaseTest):
# check if we can download transcript in "txt" format that has text "Welcome to edX."
self.assertTrue(self.video.downloaded_transcript_contains_text('txt', 'Welcome to edX.'))
# open video "B"
self.course_nav.go_to_sequential('B')
# open vertical containing video "B"
self.course_nav.go_to_vertical('Test Vertical-1')
# check if we can download transcript in "txt" format that has text "Equal transcripts"
self.assertTrue(self.video.downloaded_transcript_contains_text('txt', 'Equal transcripts'))
# open video "C"
self.course_nav.go_to_sequential('C')
# open vertical containing video "C"
self.course_nav.go_to_vertical('Test Vertical-2')
# menu "download_transcript" doesn't exist
self.assertFalse(self.video.is_menu_present('download_transcript'))
@@ -635,7 +635,7 @@ class YouTubeVideoTest(VideoBaseTest):
Given it has videos "A,B" in "Youtube" mode in position "1" of sequential
And videos "C,D" in "Youtube" mode in position "2" of sequential
"""
self.verticals = [
self.contents_of_verticals = [
[{'display_name': 'A'}, {'display_name': 'B'}],
[{'display_name': 'C'}, {'display_name': 'D'}]
]
@@ -675,7 +675,9 @@ class YouTubeVideoTest(VideoBaseTest):
And a video "B" in "Youtube" mode in position "2" of sequential
And a video "C" in "HTML5" mode in position "3" of sequential
"""
self.verticals = [
# vertical titles are created in VideoBaseTest._create_single_vertical
# and are of the form Test Vertical-{_} where _ is the index in self.contents_of_verticals
self.contents_of_verticals = [
[{'display_name': 'A'}], [{'display_name': 'B'}],
[{'display_name': 'C', 'metadata': self.metadata_for_mode('html5')}]
]
@@ -683,17 +685,17 @@ class YouTubeVideoTest(VideoBaseTest):
self.navigate_to_video()
# select the "2.0" speed on video "A"
self.course_nav.go_to_sequential('A')
self.course_nav.go_to_vertical('Test Vertical-0')
self.video.wait_for_video_player_render()
self.video.speed = '2.0'
# select the "0.50" speed on video "B"
self.course_nav.go_to_sequential('B')
self.course_nav.go_to_vertical('Test Vertical-1')
self.video.wait_for_video_player_render()
self.video.speed = '0.50'
# open video "C"
self.course_nav.go_to_sequential('C')
self.course_nav.go_to_vertical('Test Vertical-2')
self.video.wait_for_video_player_render()
# Since the playback speed was set to .5 in "B", this video will also be impacted
@@ -701,8 +703,8 @@ class YouTubeVideoTest(VideoBaseTest):
# does not have a .5 playback option, so the closest possible (.75) should be selected.
self.video.verify_speed_changed('0.75x')
# open video "A"
self.course_nav.go_to_sequential('A')
# go to the vertical containing video "A"
self.course_nav.go_to_vertical('Test Vertical-0')
# Video "A" should still play at speed 2.0 because it was explicitly set to that.
self.assertEqual(self.video.speed, '2.0x')
@@ -710,8 +712,8 @@ class YouTubeVideoTest(VideoBaseTest):
# reload the page
self.video.reload_page()
# open video "A"
self.course_nav.go_to_sequential('A')
# go to the vertical containing video "A"
self.course_nav.go_to_vertical('Test Vertical-0')
# check if video "A" should start playing at speed "2.0"
self.assertEqual(self.video.speed, '2.0x')
@@ -719,14 +721,14 @@ class YouTubeVideoTest(VideoBaseTest):
# select the "1.0" speed on video "A"
self.video.speed = '1.0'
# open video "B"
self.course_nav.go_to_sequential('B')
# go to the vertical containing "B"
self.course_nav.go_to_vertical('Test Vertical-1')
# Video "B" should still play at speed .5 because it was explicitly set to that.
self.assertEqual(self.video.speed, '0.50x')
# open video "C"
self.course_nav.go_to_sequential('C')
# go to the vertical containing video "C"
self.course_nav.go_to_vertical('Test Vertical-2')
# The change of speed for Video "A" should impact Video "C" because it still has
# not been explicitly set to a speed.
@@ -882,7 +884,7 @@ class YouTubeVideoTest(VideoBaseTest):
}
}
self.verticals = [
self.contents_of_verticals = [
[{'display_name': 'A'}, {'display_name': 'B', 'metadata': self.metadata_for_mode('html5')}],
[{'display_name': 'C'}]
]