"""Annotatable block tests"""
import unittest
from lxml import etree
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds
from xmodule.annotatable_block import AnnotatableBlock
from . import get_test_system
class AnnotatableBlockTestCase(unittest.TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
sample_xml = '''
Read the text.
Sing,
O goddess,
the anger of Achilles son of Peleus,
that brought countless ills upon the Achaeans. Many a brave soul did it send
hurrying down to Hades, and many a hero did it yield a prey to dogs and
vultures, for so were the counsels
of Jove fulfilled from the day on which the son of Atreus, king of men, and great
Achilles, first fell out with one another.
The Iliad of Homer by Samuel Butler
'''
def setUp(self):
super().setUp()
self.annotatable = AnnotatableBlock(
get_test_system(),
DictFieldData({'data': self.sample_xml}),
ScopeIds(None, None, None, BlockUsageLocator(CourseLocator('org', 'course', 'run'), 'category', 'name'))
)
def test_annotation_data_attr(self):
el = etree.fromstring('test')
expected_attr = {
'data-comment-body': {'value': 'foo', '_delete': 'body'},
'data-comment-title': {'value': 'bar', '_delete': 'title'},
'data-problem-id': {'value': '0', '_delete': 'problem'}
}
actual_attr = self.annotatable._get_annotation_data_attr(0, el) # lint-amnesty, pylint: disable=protected-access
assert isinstance(actual_attr, dict)
self.assertDictEqual(expected_attr, actual_attr)
def test_annotation_class_attr_default(self):
xml = 'test'
el = etree.fromstring(xml)
expected_attr = {'class': {'value': 'annotatable-span highlight'}}
actual_attr = self.annotatable._get_annotation_class_attr(0, el) # lint-amnesty, pylint: disable=protected-access
assert isinstance(actual_attr, dict)
self.assertDictEqual(expected_attr, actual_attr)
def test_annotation_class_attr_with_valid_highlight(self):
xml = 'test'
for color in self.annotatable.HIGHLIGHT_COLORS:
el = etree.fromstring(xml.format(highlight=color))
value = f'annotatable-span highlight highlight-{color}'
expected_attr = {
'class': {
'value': value,
'_delete': 'highlight'
}
}
actual_attr = self.annotatable._get_annotation_class_attr(0, el) # lint-amnesty, pylint: disable=protected-access
assert isinstance(actual_attr, dict)
self.assertDictEqual(expected_attr, actual_attr)
def test_annotation_class_attr_with_invalid_highlight(self):
xml = 'test'
for invalid_color in ['rainbow', 'blink', 'invisible', '', None]:
el = etree.fromstring(xml.format(highlight=invalid_color))
expected_attr = {
'class': {
'value': 'annotatable-span highlight',
'_delete': 'highlight'
}
}
actual_attr = self.annotatable._get_annotation_class_attr(0, el) # lint-amnesty, pylint: disable=protected-access
assert isinstance(actual_attr, dict)
self.assertDictEqual(expected_attr, actual_attr)
def test_render_annotation(self):
expected_html = 'z' # lint-amnesty, pylint: disable=line-too-long
expected_el = etree.fromstring(expected_html)
actual_el = etree.fromstring('z')
self.annotatable._render_annotation(0, actual_el) # lint-amnesty, pylint: disable=protected-access
assert expected_el.tag == actual_el.tag
assert expected_el.text == actual_el.text
self.assertDictEqual(dict(expected_el.attrib), dict(actual_el.attrib))
def test_render_content(self):
content = self.annotatable._render_content() # lint-amnesty, pylint: disable=protected-access
el = etree.fromstring(content)
assert 'div' == el.tag, 'root tag is a div'
expected_num_annotations = 5
actual_num_annotations = el.xpath('count(//span[contains(@class,"annotatable-span")])')
assert expected_num_annotations == actual_num_annotations, 'check number of annotations'
def test_get_html(self):
context = self.annotatable.get_html()
for key in ['display_name', 'element_id', 'content_html', 'instructions_html']:
assert key in context
def test_extract_instructions(self):
xmltree = etree.fromstring(self.sample_xml)
expected_xml = "Read the text.
"
actual_xml = self.annotatable._extract_instructions(xmltree) # lint-amnesty, pylint: disable=protected-access
assert actual_xml is not None
assert expected_xml.strip() == actual_xml.strip()
xmltree = etree.fromstring('foo')
actual = self.annotatable._extract_instructions(xmltree) # lint-amnesty, pylint: disable=protected-access
assert actual is None