refactor: rename descriptor -> block within xmodule/tests

Co-authored-by: Agrendalath <piotr@surowiec.it>
This commit is contained in:
Pooja Kulkarni
2023-01-05 14:29:02 -05:00
committed by Agrendalath
parent 537cfe4e0f
commit ce94d896cf
14 changed files with 318 additions and 318 deletions

View File

@@ -191,7 +191,7 @@ def prepare_block_runtime(
add_get_block=False,
):
"""
Sets properties in the runtime of the specified descriptor that is
Sets properties in the runtime of the specified block that is
required for tests.
"""

View File

@@ -2492,22 +2492,22 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
</problem>
""")
def _create_descriptor(self, xml, name=None):
def _create_block(self, xml, name=None):
""" Creates a ProblemBlock to run test against """
descriptor = CapaFactory.create()
descriptor.data = xml
block = CapaFactory.create()
block.data = xml
if name:
descriptor.display_name = name
return descriptor
block.display_name = name
return block
@ddt.data(*sorted(responsetypes.registry.registered_tags()))
def test_all_response_types(self, response_tag):
""" Tests that every registered response tag is correctly returned """
xml = "<problem><{response_tag}></{response_tag}></problem>".format(response_tag=response_tag)
name = "Some Capa Problem"
descriptor = self._create_descriptor(xml, name=name)
assert descriptor.problem_types == {response_tag}
assert descriptor.index_dictionary() ==\
block = self._create_block(xml, name=name)
assert block.problem_types == {response_tag}
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': [response_tag],
'content': {'display_name': name, 'capa_content': ''}}
@@ -2528,9 +2528,9 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
</problem>
""")
name = "Test Capa Problem"
descriptor = self._create_descriptor(xml, name=name)
assert descriptor.problem_types == {'multiplechoiceresponse'}
assert descriptor.index_dictionary() ==\
block = self._create_block(xml, name=name)
assert block.problem_types == {'multiplechoiceresponse'}
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['multiplechoiceresponse'],
'content': {'display_name': name, 'capa_content': ' Label Some comment Apple Banana Chocolate Donut '}}
@@ -2556,14 +2556,14 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
</problem>
""")
name = "Other Test Capa Problem"
descriptor = self._create_descriptor(xml, name=name)
assert descriptor.problem_types == {'multiplechoiceresponse', 'optionresponse'}
block = self._create_block(xml, name=name)
assert block.problem_types == {'multiplechoiceresponse', 'optionresponse'}
# We are converting problem_types to a set to compare it later without taking into account the order
# the reasoning behind is that the problem_types (property) is represented by dict and when it is converted
# to list its ordering is different everytime.
indexing_result = descriptor.index_dictionary()
indexing_result = block.index_dictionary()
indexing_result['problem_types'] = set(indexing_result['problem_types'])
self.assertDictEqual(
indexing_result, {
@@ -2608,15 +2608,15 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
</problem>
""")
name = "Blank Common Capa Problem"
descriptor = self._create_descriptor(xml, name=name)
assert descriptor.index_dictionary() ==\
block = self._create_block(xml, name=name)
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': [],
'content': {'display_name': name, 'capa_content': ' '}}
def test_indexing_checkboxes(self):
name = "Checkboxes"
descriptor = self._create_descriptor(self.sample_checkbox_problem_xml, name=name)
block = self._create_block(self.sample_checkbox_problem_xml, name=name)
capa_content = textwrap.dedent("""
Title
Description
@@ -2629,30 +2629,30 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
Hungarian
Note: Make sure you select all of the correct options—there may be more than one!
""")
assert descriptor.problem_types == {'choiceresponse'}
assert descriptor.index_dictionary() ==\
assert block.problem_types == {'choiceresponse'}
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['choiceresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_dropdown(self):
name = "Dropdown"
descriptor = self._create_descriptor(self.sample_dropdown_problem_xml, name=name)
block = self._create_block(self.sample_dropdown_problem_xml, name=name)
capa_content = textwrap.dedent("""
Dropdown problems allow learners to select only one option from a list of options.
Description
You can use the following example problem as a model.
Which of the following countries celebrates its independence on August 15? 'India','Spain','China','Bermuda'
""")
assert descriptor.problem_types == {'optionresponse'}
assert descriptor.index_dictionary() ==\
assert block.problem_types == {'optionresponse'}
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['optionresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_multiple_choice(self):
name = "Multiple Choice"
descriptor = self._create_descriptor(self.sample_multichoice_problem_xml, name=name)
block = self._create_block(self.sample_multichoice_problem_xml, name=name)
capa_content = textwrap.dedent("""
Multiple choice problems allow learners to select only one option.
When you add the problem, be sure to select Settings to specify a Display Name and other values.
@@ -2663,15 +2663,15 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
Indonesia
Russia
""")
assert descriptor.problem_types == {'multiplechoiceresponse'}
assert descriptor.index_dictionary() ==\
assert block.problem_types == {'multiplechoiceresponse'}
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['multiplechoiceresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_numerical_input(self):
name = "Numerical Input"
descriptor = self._create_descriptor(self.sample_numerical_input_problem_xml, name=name)
block = self._create_block(self.sample_numerical_input_problem_xml, name=name)
capa_content = textwrap.dedent("""
In a numerical input problem, learners enter numbers or a specific and relatively simple mathematical
expression. Learners enter the response in plain text, and the system then converts the text to a symbolic
@@ -2685,15 +2685,15 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
How many miles away from Earth is the sun? Use scientific notation to answer.
The square of what number is -100?
""")
assert descriptor.problem_types == {'numericalresponse'}
assert descriptor.index_dictionary() ==\
assert block.problem_types == {'numericalresponse'}
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['numericalresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_text_input(self):
name = "Text Input"
descriptor = self._create_descriptor(self.sample_text_input_problem_xml, name=name)
block = self._create_block(self.sample_text_input_problem_xml, name=name)
capa_content = textwrap.dedent("""
In text input problems, also known as "fill-in-the-blank" problems, learners enter text into a response
field. The text can include letters and characters such as punctuation marks. The text that the learner
@@ -2704,8 +2704,8 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
You can use the following example problem as a model.
What was the first post-secondary school in China to allow both male and female students?
""")
assert descriptor.problem_types == {'stringresponse'}
assert descriptor.index_dictionary() ==\
assert block.problem_types == {'stringresponse'}
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['stringresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
@@ -2718,15 +2718,15 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
</problem>
""")
name = "Non latin Input"
descriptor = self._create_descriptor(sample_text_input_problem_xml, name=name)
block = self._create_block(sample_text_input_problem_xml, name=name)
capa_content = " Δοκιμή με μεταβλητές με Ελληνικούς χαρακτήρες μέσα σε python: $FX1_VAL "
descriptor_dict = descriptor.index_dictionary()
assert descriptor_dict['content']['capa_content'] == smart_str(capa_content)
block_dict = block.index_dictionary()
assert block_dict['content']['capa_content'] == smart_str(capa_content)
def test_indexing_checkboxes_with_hints_and_feedback(self):
name = "Checkboxes with Hints and Feedback"
descriptor = self._create_descriptor(self.sample_checkboxes_with_hints_and_feedback_problem_xml, name=name)
block = self._create_block(self.sample_checkboxes_with_hints_and_feedback_problem_xml, name=name)
capa_content = textwrap.dedent("""
You can provide feedback for each option in a checkbox problem, with distinct feedback depending on
whether or not the learner selects that option.
@@ -2742,15 +2742,15 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
potato
tomato
""")
assert descriptor.problem_types == {'choiceresponse'}
assert descriptor.index_dictionary() ==\
assert block.problem_types == {'choiceresponse'}
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['choiceresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_dropdown_with_hints_and_feedback(self):
name = "Dropdown with Hints and Feedback"
descriptor = self._create_descriptor(self.sample_dropdown_with_hints_and_feedback_problem_xml, name=name)
block = self._create_block(self.sample_dropdown_with_hints_and_feedback_problem_xml, name=name)
capa_content = textwrap.dedent("""
You can provide feedback for each available option in a dropdown problem.
You can also add hints for learners.
@@ -2762,15 +2762,15 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
potato
tomato
""")
assert descriptor.problem_types == {'optionresponse'}
assert descriptor.index_dictionary() ==\
assert block.problem_types == {'optionresponse'}
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['optionresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_multiple_choice_with_hints_and_feedback(self):
name = "Multiple Choice with Hints and Feedback"
descriptor = self._create_descriptor(self.sample_multichoice_with_hints_and_feedback_problem_xml, name=name)
block = self._create_block(self.sample_multichoice_with_hints_and_feedback_problem_xml, name=name)
capa_content = textwrap.dedent("""
You can provide feedback for each option in a multiple choice problem.
You can also add hints for learners.
@@ -2782,15 +2782,15 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
potato
tomato
""")
assert descriptor.problem_types == {'multiplechoiceresponse'}
assert descriptor.index_dictionary() ==\
assert block.problem_types == {'multiplechoiceresponse'}
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['multiplechoiceresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_numerical_input_with_hints_and_feedback(self):
name = "Numerical Input with Hints and Feedback"
descriptor = self._create_descriptor(self.sample_numerical_input_with_hints_and_feedback_problem_xml, name=name)
block = self._create_block(self.sample_numerical_input_with_hints_and_feedback_problem_xml, name=name)
capa_content = textwrap.dedent("""
You can provide feedback for correct answers in numerical input problems. You cannot provide feedback
for incorrect answers.
@@ -2800,15 +2800,15 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
Use the following example problem as a model.
What is the arithmetic mean for the following set of numbers? (1, 5, 6, 3, 5)
""")
assert descriptor.problem_types == {'numericalresponse'}
assert descriptor.index_dictionary() ==\
assert block.problem_types == {'numericalresponse'}
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['numericalresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_text_input_with_hints_and_feedback(self):
name = "Text Input with Hints and Feedback"
descriptor = self._create_descriptor(self.sample_text_input_with_hints_and_feedback_problem_xml, name=name)
block = self._create_block(self.sample_text_input_with_hints_and_feedback_problem_xml, name=name)
capa_content = textwrap.dedent("""
You can provide feedback for the correct answer in text input problems, as well as for specific
incorrect answers.
@@ -2818,8 +2818,8 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
Use the following example problem as a model.
Which U.S. state has the largest land area?
""")
assert descriptor.problem_types == {'stringresponse'}
assert descriptor.index_dictionary() ==\
assert block.problem_types == {'stringresponse'}
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['stringresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
@@ -2840,12 +2840,12 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
</problem>
""")
name = "Mixed business"
descriptor = self._create_descriptor(sample_problem_xml, name=name)
block = self._create_block(sample_problem_xml, name=name)
capa_content = textwrap.dedent("""
This has HTML comment in it.
HTML end.
""")
assert descriptor.index_dictionary() ==\
assert block.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': [],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
@@ -2860,7 +2860,7 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
</proble-oh no my finger broke and I can't close the problem tag properly...
""")
with pytest.raises(etree.XMLSyntaxError):
self._create_descriptor(sample_invalid_xml, name="Invalid XML")
self._create_block(sample_invalid_xml, name="Invalid XML")
def test_invalid_dropdown_xml(self):
"""
@@ -3226,29 +3226,29 @@ class ProblemBlockReportGenerationTest(unittest.TestCase):
scope=None,
)
def _get_descriptor(self): # lint-amnesty, pylint: disable=missing-function-docstring
def _get_block(self): # lint-amnesty, pylint: disable=missing-function-docstring
scope_ids = Mock(block_type='problem')
descriptor = ProblemBlock(get_test_system(), scope_ids=scope_ids)
descriptor.runtime = Mock()
descriptor.data = '<problem/>'
return descriptor
block = ProblemBlock(get_test_system(), scope_ids=scope_ids)
block.runtime = Mock()
block.data = '<problem/>'
return block
def test_generate_report_data_not_implemented(self):
scope_ids = Mock(block_type='noproblem')
descriptor = ProblemBlock(get_test_system(), scope_ids=scope_ids)
block = ProblemBlock(get_test_system(), scope_ids=scope_ids)
with pytest.raises(NotImplementedError):
next(descriptor.generate_report_data(iter([])))
next(block.generate_report_data(iter([])))
def test_generate_report_data_limit_responses(self):
descriptor = self._get_descriptor()
report_data = list(descriptor.generate_report_data(self._mock_user_state_generator(), 2))
block = self._get_block()
report_data = list(block.generate_report_data(self._mock_user_state_generator(), 2))
assert 2 == len(report_data)
def test_generate_report_data_dont_limit_responses(self):
descriptor = self._get_descriptor()
block = self._get_block()
user_count = 5
response_count = 10
report_data = list(descriptor.generate_report_data(
report_data = list(block.generate_report_data(
self._mock_user_state_generator(
user_count=user_count,
response_count=response_count,
@@ -3257,17 +3257,17 @@ class ProblemBlockReportGenerationTest(unittest.TestCase):
assert (user_count * response_count) == len(report_data)
def test_generate_report_data_skip_dynamath(self):
descriptor = self._get_descriptor()
block = self._get_block()
iterator = iter([self._user_state(suffix='_dynamath')])
report_data = list(descriptor.generate_report_data(iterator))
report_data = list(block.generate_report_data(iterator))
assert 0 == len(report_data)
def test_generate_report_data_report_loncapa_error(self):
#Test to make sure reports continue despite loncappa errors, and write them into the report.
descriptor = self._get_descriptor()
block = self._get_block()
with patch('xmodule.capa_block.LoncapaProblem') as mock_LoncapaProblem:
mock_LoncapaProblem.side_effect = LoncapaProblemError
report_data = list(descriptor.generate_report_data(
report_data = list(block.generate_report_data(
self._mock_user_state_generator(
user_count=1,
response_count=5,

View File

@@ -67,33 +67,33 @@ class ConditionalFactory:
if the source_is_error_block flag is set, create a real ErrorBlock for the source.
"""
# construct source descriptor and module:
# construct source block and module:
source_location = BlockUsageLocator(CourseLocator("edX", "conditional_test", "test_run", deprecated=True),
"problem", "SampleProblem", deprecated=True)
if source_is_error_block:
# Make an error descriptor and block
source_descriptor = ErrorBlock.from_xml(
# Make an error block
source_block = ErrorBlock.from_xml(
'some random xml data',
system,
id_generator=CourseLocationManager(source_location.course_key),
error_msg='random error message'
)
else:
source_descriptor = Mock(name='source_descriptor')
source_descriptor.location = source_location
source_block = Mock(name='source_block')
source_block.location = source_location
source_descriptor.visible_to_staff_only = source_visible_to_staff_only
source_descriptor.runtime = system
source_descriptor.render = lambda view, context=None: system.render(source_descriptor, view, context)
source_block.visible_to_staff_only = source_visible_to_staff_only
source_block.runtime = system
source_block.render = lambda view, context=None: system.render(source_block, view, context)
# construct other descriptors:
child_descriptor = Mock(name='child_descriptor')
child_descriptor.visible_to_staff_only = False
child_descriptor._xmodule.student_view.return_value = Fragment(content='<p>This is a secret</p>') # lint-amnesty, pylint: disable=protected-access
child_descriptor.student_view = child_descriptor._xmodule.student_view # lint-amnesty, pylint: disable=protected-access
child_descriptor.runtime = system
child_descriptor.render = lambda view, context=None: system.render(child_descriptor, view, context)
child_descriptor.location = source_location.replace(category='html', name='child')
# construct other blocks:
child_block = Mock(name='child_block')
child_block.visible_to_staff_only = False
child_block._xmodule.student_view.return_value = Fragment(content='<p>This is a secret</p>') # lint-amnesty, pylint: disable=protected-access
child_block.student_view = child_block._xmodule.student_view # lint-amnesty, pylint: disable=protected-access
child_block.runtime = system
child_block.render = lambda view, context=None: system.render(child_block, view, context)
child_block.location = source_location.replace(category='html', name='child')
def visible_to_nonstaff_users(desc):
"""
@@ -104,8 +104,8 @@ class ConditionalFactory:
def load_item(usage_id, for_parent=None): # pylint: disable=unused-argument
"""Test-only implementation of load_item that simply returns static xblocks."""
return {
child_descriptor.location: child_descriptor,
source_location: source_descriptor
child_block.location: child_block,
source_location: source_block
}.get(usage_id)
system.load_item = load_item
@@ -118,23 +118,23 @@ class ConditionalFactory:
'conditional_attr': 'attempted',
'conditional_value': 'true',
'xml_attributes': {'attempted': 'true'},
'children': [child_descriptor.location],
'children': [child_block.location],
})
cond_descriptor = ConditionalBlock(
cond_block = ConditionalBlock(
system,
field_data,
ScopeIds(None, None, cond_location, cond_location)
)
system.get_block_for_descriptor = lambda desc: desc if visible_to_nonstaff_users(desc) else None
cond_descriptor.get_required_blocks = [
system.get_block_for_descriptor(source_descriptor),
cond_block.get_required_blocks = [
system.get_block_for_descriptor(source_block),
]
# return dict:
return {'cond_block': cond_descriptor,
'source_block': source_descriptor,
'child_block': child_descriptor}
return {'cond_block': cond_block,
'source_block': source_block,
'child_block': child_block}
class ConditionalBlockBasicTest(unittest.TestCase):
@@ -228,10 +228,10 @@ class ConditionalBlockXmlTest(unittest.TestCase):
self.course = courses[0]
def get_block_for_location(self, location):
descriptor = self.modulestore.get_item(location, depth=None)
return self.test_system.get_block_for_descriptor(descriptor)
block = self.modulestore.get_item(location, depth=None)
return self.test_system.get_block_for_descriptor(block)
@patch('xmodule.x_module.descriptor_global_local_resource_url')
@patch('xmodule.x_module.block_global_local_resource_url')
@patch.dict(settings.FEATURES, {'ENABLE_EDXNOTES': False})
def test_conditional_block(self, _):
"""Make sure that conditional block works"""

View File

@@ -235,36 +235,36 @@ class IsNewCourseTestCase(unittest.TestCase):
assert d.start_date_is_still_default == s[3]
def test_display_organization(self):
descriptor = get_dummy_course(start='2012-12-02T12:00', is_new=True)
assert descriptor.location.org != descriptor.display_org_with_default
assert descriptor.display_org_with_default == f'{ORG}_display'
block = get_dummy_course(start='2012-12-02T12:00', is_new=True)
assert block.location.org != block.display_org_with_default
assert block.display_org_with_default == f'{ORG}_display'
def test_display_coursenumber(self):
descriptor = get_dummy_course(start='2012-12-02T12:00', is_new=True)
assert descriptor.location.course != descriptor.display_number_with_default
assert descriptor.display_number_with_default == f'{COURSE}_display'
block = get_dummy_course(start='2012-12-02T12:00', is_new=True)
assert block.location.course != block.display_number_with_default
assert block.display_number_with_default == f'{COURSE}_display'
def test_is_newish(self):
descriptor = get_dummy_course(start='2012-12-02T12:00', is_new=True)
assert descriptor.is_newish is True
block = get_dummy_course(start='2012-12-02T12:00', is_new=True)
assert block.is_newish is True
descriptor = get_dummy_course(start='2013-02-02T12:00', is_new=False)
assert descriptor.is_newish is False
block = get_dummy_course(start='2013-02-02T12:00', is_new=False)
assert block.is_newish is False
descriptor = get_dummy_course(start='2013-02-02T12:00', is_new=True)
assert descriptor.is_newish is True
block = get_dummy_course(start='2013-02-02T12:00', is_new=True)
assert block.is_newish is True
descriptor = get_dummy_course(start='2013-01-15T12:00')
assert descriptor.is_newish is True
block = get_dummy_course(start='2013-01-15T12:00')
assert block.is_newish is True
descriptor = get_dummy_course(start='2013-03-01T12:00')
assert descriptor.is_newish is True
block = get_dummy_course(start='2013-03-01T12:00')
assert block.is_newish is True
descriptor = get_dummy_course(start='2012-10-15T12:00')
assert descriptor.is_newish is False
block = get_dummy_course(start='2012-10-15T12:00')
assert block.is_newish is False
descriptor = get_dummy_course(start='2012-12-31T12:00')
assert descriptor.is_newish is True
block = get_dummy_course(start='2012-12-31T12:00')
assert block.is_newish is True
class DiscussionTopicsTestCase(unittest.TestCase):

View File

@@ -31,14 +31,14 @@ class TestErrorBlock(SetupTestErrorBlock):
"""
def test_error_block_xml_rendering(self):
descriptor = ErrorBlock.from_xml(
block = ErrorBlock.from_xml(
self.valid_xml,
self.system,
CourseLocationManager(self.course_id),
self.error_msg
)
assert isinstance(descriptor, ErrorBlock)
descriptor.runtime = self.system
context_repr = self.system.render(descriptor, STUDENT_VIEW).content
assert isinstance(block, ErrorBlock)
block.runtime = self.system
context_repr = self.system.render(block, STUDENT_VIEW).content
assert self.error_msg in context_repr
assert repr(self.valid_xml) in context_repr

View File

@@ -28,22 +28,22 @@ from xmodule.tests import DATA_DIR
from xmodule.x_module import XModuleMixin
def strip_filenames(descriptor):
def strip_filenames(block):
"""
Recursively strips 'filename' from all children's definitions.
"""
print(f"strip filename from {str(descriptor.location)}")
if descriptor._field_data.has(descriptor, 'filename'): # lint-amnesty, pylint: disable=protected-access
descriptor._field_data.delete(descriptor, 'filename') # lint-amnesty, pylint: disable=protected-access
print(f"strip filename from {str(block.location)}")
if block._field_data.has(block, 'filename'): # lint-amnesty, pylint: disable=protected-access
block._field_data.delete(block, 'filename') # lint-amnesty, pylint: disable=protected-access
if hasattr(descriptor, 'xml_attributes'):
if 'filename' in descriptor.xml_attributes:
del descriptor.xml_attributes['filename']
if hasattr(block, 'xml_attributes'):
if 'filename' in block.xml_attributes:
del block.xml_attributes['filename']
for child in descriptor.get_children():
for child in block.get_children():
strip_filenames(child)
descriptor.save()
block.save()
class PureXBlock(XBlock):

View File

@@ -16,9 +16,9 @@ from ..x_module import PUBLIC_VIEW, STUDENT_VIEW
from . import get_test_descriptor_system, get_test_system
def instantiate_descriptor(**field_data):
def instantiate_block(**field_data):
"""
Instantiate descriptor with most properties.
Instantiate block with most properties.
"""
system = get_test_descriptor_system()
course_key = CourseLocator('org', 'course', 'run')
@@ -152,8 +152,8 @@ class HtmlBlockIndexingTestCase(unittest.TestCase):
<p>Hello World!</p>
</html>
'''
descriptor = instantiate_descriptor(data=sample_xml)
assert descriptor.index_dictionary() ==\
block = instantiate_block(data=sample_xml)
assert block.index_dictionary() ==\
{'content': {'html_content': ' Hello World! ', 'display_name': 'Text'}, 'content_type': 'Text'}
def test_index_dictionary_cdata_html_block(self):
@@ -163,8 +163,8 @@ class HtmlBlockIndexingTestCase(unittest.TestCase):
<![CDATA[This is just a CDATA!]]>
</html>
'''
descriptor = instantiate_descriptor(data=sample_xml_cdata)
assert descriptor.index_dictionary() ==\
block = instantiate_block(data=sample_xml_cdata)
assert block.index_dictionary() ==\
{'content': {'html_content': ' This has CDATA in it. ', 'display_name': 'Text'}, 'content_type': 'Text'}
def test_index_dictionary_multiple_spaces_html_block(self):
@@ -173,8 +173,8 @@ class HtmlBlockIndexingTestCase(unittest.TestCase):
<p> Text has spaces :) </p>
</html>
'''
descriptor = instantiate_descriptor(data=sample_xml_tab_spaces)
assert descriptor.index_dictionary() ==\
block = instantiate_block(data=sample_xml_tab_spaces)
assert block.index_dictionary() ==\
{'content': {'html_content': ' Text has spaces :) ', 'display_name': 'Text'}, 'content_type': 'Text'}
def test_index_dictionary_html_block_with_comment(self):
@@ -184,8 +184,8 @@ class HtmlBlockIndexingTestCase(unittest.TestCase):
<!-- Html Comment -->
</html>
'''
descriptor = instantiate_descriptor(data=sample_xml_comment)
assert descriptor.index_dictionary() == {'content': {'html_content': ' This has HTML comment in it. ', 'display_name': 'Text'}, 'content_type': 'Text'} # pylint: disable=line-too-long
block = instantiate_block(data=sample_xml_comment)
assert block.index_dictionary() == {'content': {'html_content': ' This has HTML comment in it. ', 'display_name': 'Text'}, 'content_type': 'Text'} # pylint: disable=line-too-long
def test_index_dictionary_html_block_with_both_comments_and_cdata(self):
sample_xml_mix_comment_cdata = '''
@@ -197,8 +197,8 @@ class HtmlBlockIndexingTestCase(unittest.TestCase):
<p>HTML end.</p>
</html>
'''
descriptor = instantiate_descriptor(data=sample_xml_mix_comment_cdata)
assert descriptor.index_dictionary() ==\
block = instantiate_block(data=sample_xml_mix_comment_cdata)
assert block.index_dictionary() ==\
{'content': {'html_content': ' This has HTML comment in it. HTML end. ',
'display_name': 'Text'}, 'content_type': 'Text'}
@@ -216,8 +216,8 @@ class HtmlBlockIndexingTestCase(unittest.TestCase):
</script>
</html>
'''
descriptor = instantiate_descriptor(data=sample_xml_style_script_tags)
assert descriptor.index_dictionary() ==\
block = instantiate_block(data=sample_xml_style_script_tags)
assert block.index_dictionary() ==\
{'content': {'html_content': ' This has HTML comment in it. HTML end. ',
'display_name': 'Text'}, 'content_type': 'Text'}

View File

@@ -106,9 +106,9 @@ class PureXBlockImportTest(BaseCourseTestCase):
@patch('xmodule.x_module.XModuleMixin.location')
def test_parsing_pure_xblock(self, xml, mock_location):
system = self.get_system(load_error_blocks=False)
descriptor = system.process_xml(xml)
assert isinstance(descriptor, GenericXBlock)
self.assert_xblocks_are_good(descriptor)
block = system.process_xml(xml)
assert isinstance(block, GenericXBlock)
self.assert_xblocks_are_good(block)
assert not mock_location.called
@@ -122,9 +122,9 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
bad_xml = '''<sequential display_name="oops\N{SNOWMAN}"><video url="hi"></sequential>'''
system = self.get_system()
descriptor = system.process_xml(bad_xml)
block = system.process_xml(bad_xml)
assert descriptor.__class__.__name__ == 'ErrorBlockWithMixins'
assert block.__class__.__name__ == 'ErrorBlockWithMixins'
def test_unique_url_names(self):
'''Check that each error gets its very own url_name'''
@@ -132,19 +132,19 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
bad_xml2 = '''<sequential url_name="oops"><video url="hi"></sequential>'''
system = self.get_system()
descriptor1 = system.process_xml(bad_xml)
descriptor2 = system.process_xml(bad_xml2)
block1 = system.process_xml(bad_xml)
block2 = system.process_xml(bad_xml2)
assert descriptor1.location != descriptor2.location
assert block1.location != block2.location
# Check that each vertical gets its very own url_name
bad_xml = '''<vertical display_name="abc"><problem url_name="exam1:2013_Spring:abc"/></vertical>'''
bad_xml2 = '''<vertical display_name="abc"><problem url_name="exam2:2013_Spring:abc"/></vertical>'''
descriptor1 = system.process_xml(bad_xml)
descriptor2 = system.process_xml(bad_xml2)
block1 = system.process_xml(bad_xml)
block2 = system.process_xml(bad_xml2)
assert descriptor1.location != descriptor2.location
assert block1.location != block2.location
def test_reimport(self):
'''Make sure an already-exported error xml tag loads properly'''
@@ -152,16 +152,16 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
self.maxDiff = None
bad_xml = '''<sequential display_name="oops"><video url="hi"></sequential>'''
system = self.get_system()
descriptor = system.process_xml(bad_xml)
block = system.process_xml(bad_xml)
node = etree.Element('unknown')
descriptor.add_xml_to_node(node)
re_import_descriptor = system.process_xml(etree.tostring(node))
block.add_xml_to_node(node)
re_import_block = system.process_xml(etree.tostring(node))
assert re_import_descriptor.__class__.__name__ == 'ErrorBlockWithMixins'
assert re_import_block.__class__.__name__ == 'ErrorBlockWithMixins'
assert descriptor.contents == re_import_descriptor.contents
assert descriptor.error_msg == re_import_descriptor.error_msg
assert block.contents == re_import_block.contents
assert block.error_msg == re_import_block.error_msg
def test_fixed_xml_tag(self):
"""Make sure a tag that's been fixed exports as the original tag type"""
@@ -175,25 +175,25 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
# load it
system = self.get_system()
descriptor = system.process_xml(xml_str_in)
block = system.process_xml(xml_str_in)
# export it
node = etree.Element('unknown')
descriptor.add_xml_to_node(node)
block.add_xml_to_node(node)
# Now make sure the exported xml is a sequential
assert node.tag == 'sequential'
def course_descriptor_inheritance_check(self, descriptor, from_date_string, unicorn_color, course_run=RUN):
def course_block_inheritance_check(self, block, from_date_string, unicorn_color, course_run=RUN):
"""
Checks to make sure that metadata inheritance on a course descriptor is respected.
Checks to make sure that metadata inheritance on a course block is respected.
"""
# pylint: disable=protected-access
print((descriptor, descriptor._field_data))
assert descriptor.due == ImportTestCase.date.from_json(from_date_string)
print((block, block._field_data))
assert block.due == ImportTestCase.date.from_json(from_date_string)
# Check that the child inherits due correctly
child = descriptor.get_children()[0]
child = block.get_children()[0]
assert child.due == ImportTestCase.date.from_json(from_date_string)
# need to convert v to canonical json b4 comparing
assert ImportTestCase.date.to_json(ImportTestCase.date.from_json(from_date_string)) ==\
@@ -201,9 +201,9 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
# Now export and check things
file_system = OSFS(mkdtemp())
descriptor.runtime.export_fs = file_system.makedir('course', recreate=True)
block.runtime.export_fs = file_system.makedir('course', recreate=True)
node = etree.Element('unknown')
descriptor.add_xml_to_node(node)
block.add_xml_to_node(node)
# Check that the exported xml is just a pointer
print(("Exported xml:", etree.tostring(node)))
@@ -213,7 +213,7 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
assert node.attrib['org'] == ORG
# Does the course still have unicorns?
with descriptor.runtime.export_fs.open(f'course/{course_run}.xml') as f:
with block.runtime.export_fs.open(f'course/{course_run}.xml') as f:
course_xml = etree.fromstring(f.read())
assert course_xml.attrib['unicorn'] == unicorn_color
@@ -227,7 +227,7 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
# Does the chapter tag now have a due attribute?
# hardcoded path to child
with descriptor.runtime.export_fs.open('chapter/ch.xml') as f:
with block.runtime.export_fs.open('chapter/ch.xml') as f:
chapter_xml = etree.fromstring(f.read())
assert chapter_xml.tag == 'chapter'
assert 'due' not in chapter_xml.attrib
@@ -250,9 +250,9 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
</course>'''.format(
due=from_date_string, org=ORG, course=COURSE, url_name=url_name, unicorn_color=unicorn_color
)
descriptor = system.process_xml(start_xml)
compute_inherited_metadata(descriptor)
self.course_descriptor_inheritance_check(descriptor, from_date_string, unicorn_color)
block = system.process_xml(start_xml)
compute_inherited_metadata(block)
self.course_block_inheritance_check(block, from_date_string, unicorn_color)
def test_library_metadata_import_export(self):
"""Two checks:
@@ -274,18 +274,18 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
</library>'''.format(
due=from_date_string, org=ORG, course=COURSE, url_name=url_name, unicorn_color=unicorn_color
)
descriptor = system.process_xml(start_xml)
block = system.process_xml(start_xml)
# pylint: disable=protected-access
original_unwrapped = descriptor._unwrapped_field_data
LibraryXMLModuleStore.patch_descriptor_kvs(descriptor)
# '_unwrapped_field_data' is reset in `patch_descriptor_kvs`
original_unwrapped = block._unwrapped_field_data
LibraryXMLModuleStore.patch_block_kvs(block)
# '_unwrapped_field_data' is reset in `patch_block_kvs`
# pylint: disable=protected-access
assert original_unwrapped is not descriptor._unwrapped_field_data
compute_inherited_metadata(descriptor)
assert original_unwrapped is not block._unwrapped_field_data
compute_inherited_metadata(block)
# Check the course block, since it has inheritance
descriptor = descriptor.get_children()[0]
self.course_descriptor_inheritance_check(descriptor, from_date_string, unicorn_color)
block = block.get_children()[0]
self.course_block_inheritance_check(block, from_date_string, unicorn_color)
def test_metadata_no_inheritance(self):
"""
@@ -301,9 +301,9 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
<html url_name="h" display_name="H">Two houses, ...</html>
</chapter>
</course>'''.format(org=ORG, course=COURSE, url_name=url_name)
descriptor = system.process_xml(start_xml)
compute_inherited_metadata(descriptor)
self.course_descriptor_no_inheritance_check(descriptor)
block = system.process_xml(start_xml)
compute_inherited_metadata(block)
self.course_block_no_inheritance_check(block)
def test_library_metadata_no_inheritance(self):
"""
@@ -321,31 +321,31 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
</chapter>
</course>
</library>'''.format(org=ORG, course=COURSE, url_name=url_name)
descriptor = system.process_xml(start_xml)
LibraryXMLModuleStore.patch_descriptor_kvs(descriptor)
compute_inherited_metadata(descriptor)
block = system.process_xml(start_xml)
LibraryXMLModuleStore.patch_block_kvs(block)
compute_inherited_metadata(block)
# Run the checks on the course node instead.
descriptor = descriptor.get_children()[0]
self.course_descriptor_no_inheritance_check(descriptor)
block = block.get_children()[0]
self.course_block_no_inheritance_check(block)
def course_descriptor_no_inheritance_check(self, descriptor):
def course_block_no_inheritance_check(self, block):
"""
Verifies that a default value of None (for due) does not get marked as inherited.
"""
assert descriptor.due is None
assert block.due is None
# Check that the child does not inherit a value for due
child = descriptor.get_children()[0]
child = block.get_children()[0]
assert child.due is None
# Check that the child hasn't started yet
assert datetime.datetime.now(UTC) <= child.start
def override_metadata_check(self, descriptor, child, course_due, child_due):
def override_metadata_check(self, block, child, course_due, child_due):
"""
Verifies that due date can be overriden at child level.
"""
assert descriptor.due == ImportTestCase.date.from_json(course_due)
assert block.due == ImportTestCase.date.from_json(course_due)
assert child.due == ImportTestCase.date.from_json(child_due)
# Test inherited metadata. Due does not appear here (because explicitly set on child).
assert ImportTestCase.date.to_json(ImportTestCase.date.from_json(course_due)) == child.xblock_kvs.inherited_settings['due'] # pylint: disable=line-too-long
@@ -365,12 +365,12 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
<html url_name="h" display_name="H">Two houses, ...</html>
</chapter>
</course>'''.format(due=course_due, org=ORG, course=COURSE, url_name=url_name)
descriptor = system.process_xml(start_xml)
child = descriptor.get_children()[0]
block = system.process_xml(start_xml)
child = block.get_children()[0]
# pylint: disable=protected-access
child._field_data.set(child, 'due', child_due)
compute_inherited_metadata(descriptor)
self.override_metadata_check(descriptor, child, course_due, child_due)
compute_inherited_metadata(block)
self.override_metadata_check(block, child, course_due, child_due)
def test_library_metadata_override_default(self):
"""
@@ -389,15 +389,15 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
</chapter>
</course>
</library>'''.format(due=course_due, org=ORG, course=COURSE, url_name=url_name)
descriptor = system.process_xml(start_xml)
LibraryXMLModuleStore.patch_descriptor_kvs(descriptor)
block = system.process_xml(start_xml)
LibraryXMLModuleStore.patch_block_kvs(block)
# Chapter is two levels down here.
child = descriptor.get_children()[0].get_children()[0]
child = block.get_children()[0].get_children()[0]
# pylint: disable=protected-access
child._field_data.set(child, 'due', child_due)
compute_inherited_metadata(descriptor)
descriptor = descriptor.get_children()[0]
self.override_metadata_check(descriptor, child, course_due, child_due)
compute_inherited_metadata(block)
block = block.get_children()[0]
self.override_metadata_check(block, child, course_due, child_due)
def test_is_pointer_tag(self):
"""

View File

@@ -223,7 +223,7 @@ class LibraryContentBlockTestMixin:
assert len(self.lc_block.children) == len(self.lib_blocks)
# Check how many children each user will see:
assert len(self.lc_block.get_child_descriptors()) == 1
assert len(self.lc_block.get_child_blocks()) == 1
# Check that get_content_titles() doesn't return titles for hidden/unused children
assert len(self.lc_block.get_content_titles()) == 1
@@ -388,7 +388,7 @@ class LibraryContentBlockTestMixin:
children, and asserts that the number of selected children equals the count provided.
"""
self.lc_block.max_count = count
selected = self.lc_block.get_child_descriptors()
selected = self.lc_block.get_child_blocks()
assert len(selected) == count
return selected
@@ -532,7 +532,7 @@ class TestLibraryContentAnalytics(LibraryContentTest):
Test the "assigned" event emitted when a student is assigned specific blocks.
"""
# In the beginning was the lc_block and it assigned one child to the student:
child = self.lc_block.get_child_descriptors()[0]
child = self.lc_block.get_child_blocks()[0]
child_lib_location, child_lib_version = self.store.get_block_original_usage(child.location)
assert isinstance(child_lib_version, ObjectId)
event_data = self._assert_event_was_published("assigned")
@@ -551,7 +551,7 @@ class TestLibraryContentAnalytics(LibraryContentTest):
# Now increase max_count so that one more child will be added:
self.lc_block.max_count = 2
children = self.lc_block.get_child_descriptors()
children = self.lc_block.get_child_blocks()
assert len(children) == 2
child, new_child = children if children[0].location == child.location else reversed(children)
event_data = self._assert_event_was_published("assigned")
@@ -597,7 +597,7 @@ class TestLibraryContentAnalytics(LibraryContentTest):
course_usage_problem = inner_vertical_in_course.children[1]
# Trigger a publish event:
self.lc_block.get_child_descriptors()
self.lc_block.get_child_blocks()
event_data = self._assert_event_was_published("assigned")
for block_list in (event_data["added"], event_data["result"]):
@@ -628,12 +628,12 @@ class TestLibraryContentAnalytics(LibraryContentTest):
We go from one blocks assigned to none because max_count has been decreased.
"""
# Decrease max_count to 1, causing the block to be overlimit:
self.lc_block.get_child_descriptors() # This line is needed in the test environment or the change has no effect
self.lc_block.get_child_blocks() # This line is needed in the test environment or the change has no effect
self.publisher.reset_mock() # Clear the "assigned" event that was just published.
self.lc_block.max_count = 0
# Check that the event says that one block was removed, leaving no blocks left:
children = self.lc_block.get_child_descriptors()
children = self.lc_block.get_child_blocks()
assert len(children) == 0
event_data = self._assert_event_was_published("removed")
assert len(event_data['removed']) == 1
@@ -646,9 +646,9 @@ class TestLibraryContentAnalytics(LibraryContentTest):
We go from two blocks assigned, to one because the others have been deleted from the library.
"""
# Start by assigning two blocks to the student:
self.lc_block.get_child_descriptors() # This line is needed in the test environment or the change has no effect
self.lc_block.get_child_blocks() # This line is needed in the test environment or the change has no effect
self.lc_block.max_count = 2
initial_blocks_assigned = self.lc_block.get_child_descriptors()
initial_blocks_assigned = self.lc_block.get_child_blocks()
assert len(initial_blocks_assigned) == 2
self.publisher.reset_mock() # Clear the "assigned" event that was just published.
# Now make sure that one of the assigned blocks will have to be un-assigned.
@@ -663,7 +663,7 @@ class TestLibraryContentAnalytics(LibraryContentTest):
self.lc_block.refresh_children()
# Check that the event says that one block was removed, leaving one block left:
children = self.lc_block.get_child_descriptors()
children = self.lc_block.get_child_blocks()
assert len(children) == 1
event_data = self._assert_event_was_published("removed")
assert event_data['removed'] ==\

View File

@@ -104,8 +104,8 @@ class RandomizeBlockTest(MixedSplitTestCase):
assert len(randomize_block.children) == 3
# Check how many children each user will see:
assert len(randomize_block.get_child_descriptors()) == 1
assert randomize_block.get_child_descriptors()[0].display_name == 'Hello HTML 1'
assert len(randomize_block.get_child_blocks()) == 1
assert randomize_block.get_child_blocks()[0].display_name == 'Hello HTML 1'
# Check that get_content_titles() doesn't return titles for hidden/unused children
# get_content_titles() is not overridden in RandomizeBlock so titles of the 3 children are returned.
assert len(randomize_block.get_content_titles()) == 3
@@ -113,4 +113,4 @@ class RandomizeBlockTest(MixedSplitTestCase):
# Bind to another user and check a different child block is displayed to user.
randomize_block = self.store.get_item(self.randomize_block.location)
self._bind_module_system(randomize_block, 1)
assert randomize_block.get_child_descriptors()[0].display_name == 'Hello HTML 2'
assert randomize_block.get_child_blocks()[0].display_name == 'Hello HTML 2'

View File

@@ -142,7 +142,7 @@ class SplitTestBlockLMSTest(SplitTestBlockTest):
@ddt.unpack
def test_child(self, user_tag, child_url_name):
self.user_partition.scheme.current_group = self.user_partition.groups[user_tag]
assert self.split_test_block.child_descriptor.url_name == child_url_name
assert self.split_test_block.child_block.url_name == child_url_name
@ddt.data((0, 'HTML FOR GROUP 0'), (1, 'HTML FOR GROUP 1'))
@ddt.unpack
@@ -153,14 +153,14 @@ class SplitTestBlockLMSTest(SplitTestBlockTest):
@ddt.data(0, 1)
def test_child_missing_tag_value(self, _user_tag):
# If user_tag has a missing value, we should still get back a valid child url
assert self.split_test_block.child_descriptor.url_name in ['split_test_cond0', 'split_test_cond1']
assert self.split_test_block.child_block.url_name in ['split_test_cond0', 'split_test_cond1']
@ddt.data(100, 200, 300, 400, 500, 600, 700, 800, 900, 1000)
def test_child_persist_new_tag_value_when_tag_missing(self, _user_tag):
# If a user_tag has a missing value, a group should be saved/persisted for that user.
# So, we check that we get the same url_name when we call on the url_name twice.
# We run the test ten times so that, if our storage is failing, we'll be most likely to notice it.
assert self.split_test_block.child_descriptor.url_name == self.split_test_block.child_descriptor.url_name
assert self.split_test_block.child_block.url_name == self.split_test_block.child_block.url_name
# Patch the definition_to_xml for the html children.
@patch('xmodule.html_block.HtmlBlock.definition_to_xml')
@@ -170,7 +170,7 @@ class SplitTestBlockLMSTest(SplitTestBlockTest):
def_to_xml.return_value = lxml.etree.Element('html')
# Mock out the process_xml
# Expect it to return a child descriptor for the SplitTestDescriptor when called.
# Expect it to return a child block for the SplitTestDescriptor when called.
self.course.runtime.process_xml = Mock()
# Write out the xml.

View File

@@ -82,9 +82,9 @@ ALL_LANGUAGES = (
)
def instantiate_descriptor(**field_data):
def instantiate_block(**field_data):
"""
Instantiate descriptor with most properties.
Instantiate block with most properties.
"""
if field_data.get('data', None):
field_data = VideoBlock.parse_video_xml(field_data['data'])
@@ -172,7 +172,7 @@ class VideoBlockTestBase(unittest.TestCase):
def setUp(self):
super().setUp()
self.descriptor = instantiate_descriptor()
self.block = instantiate_block()
def assertXmlEqual(self, expected, xml):
"""
@@ -195,29 +195,29 @@ class VideoBlockTestBase(unittest.TestCase):
class TestCreateYoutubeString(VideoBlockTestBase):
"""
Checks that create_youtube_string correcty extracts information from Video descriptor.
Checks that create_youtube_string correcty extracts information from Video block.
"""
def test_create_youtube_string(self):
"""
Test that Youtube ID strings are correctly created when writing back out to XML.
"""
self.descriptor.youtube_id_0_75 = 'izygArpw-Qo'
self.descriptor.youtube_id_1_0 = 'p2Q6BrNhdh8'
self.descriptor.youtube_id_1_25 = '1EeWXzPdhSA'
self.descriptor.youtube_id_1_5 = 'rABDYkeK0x8'
self.block.youtube_id_0_75 = 'izygArpw-Qo'
self.block.youtube_id_1_0 = 'p2Q6BrNhdh8'
self.block.youtube_id_1_25 = '1EeWXzPdhSA'
self.block.youtube_id_1_5 = 'rABDYkeK0x8'
expected = "0.75:izygArpw-Qo,1.00:p2Q6BrNhdh8,1.25:1EeWXzPdhSA,1.50:rABDYkeK0x8"
assert create_youtube_string(self.descriptor) == expected
assert create_youtube_string(self.block) == expected
def test_create_youtube_string_missing(self):
"""
Test that Youtube IDs which aren't explicitly set aren't included in the output string.
"""
self.descriptor.youtube_id_0_75 = 'izygArpw-Qo'
self.descriptor.youtube_id_1_0 = 'p2Q6BrNhdh8'
self.descriptor.youtube_id_1_25 = '1EeWXzPdhSA'
self.block.youtube_id_0_75 = 'izygArpw-Qo'
self.block.youtube_id_1_0 = 'p2Q6BrNhdh8'
self.block.youtube_id_1_25 = '1EeWXzPdhSA'
expected = "0.75:izygArpw-Qo,1.00:p2Q6BrNhdh8,1.25:1EeWXzPdhSA"
assert create_youtube_string(self.descriptor) == expected
assert create_youtube_string(self.block) == expected
class TestCreateYouTubeUrl(VideoBlockTestBase):
@@ -230,7 +230,7 @@ class TestCreateYouTubeUrl(VideoBlockTestBase):
Test that passing unicode to `create_youtube_url` doesn't throw
an error.
"""
self.descriptor.create_youtube_url("üñîçø∂é")
self.block.create_youtube_url("üñîçø∂é")
@ddt.ddt
@@ -263,8 +263,8 @@ class VideoBlockImportTestCase(TestCase):
<transcript language="ge" src="german_translation.srt" />
</video>
'''
descriptor = instantiate_descriptor(data=sample_xml)
self.assert_attributes_equal(descriptor, {
block = instantiate_block(data=sample_xml)
self.assert_attributes_equal(block, {
'youtube_id_0_75': 'izygArpw-Qo',
'youtube_id_1_0': 'p2Q6BrNhdh8',
'youtube_id_1_25': '1EeWXzPdhSA',
@@ -698,22 +698,22 @@ class VideoExportTestCase(VideoBlockTestBase):
transcripts={}
)
)
self.descriptor.youtube_id_0_75 = 'izygArpw-Qo'
self.descriptor.youtube_id_1_0 = 'p2Q6BrNhdh8'
self.descriptor.youtube_id_1_25 = '1EeWXzPdhSA'
self.descriptor.youtube_id_1_5 = 'rABDYkeK0x8'
self.descriptor.show_captions = False
self.descriptor.start_time = datetime.timedelta(seconds=1.0)
self.descriptor.end_time = datetime.timedelta(seconds=60)
self.descriptor.track = 'http://www.example.com/track'
self.descriptor.handout = 'http://www.example.com/handout'
self.descriptor.download_track = True
self.descriptor.html5_sources = ['http://www.example.com/source.mp4', 'http://www.example.com/source1.ogg']
self.descriptor.download_video = True
self.descriptor.transcripts = {'ua': 'ukrainian_translation.srt', 'ge': 'german_translation.srt'}
self.descriptor.edx_video_id = edx_video_id
self.block.youtube_id_0_75 = 'izygArpw-Qo'
self.block.youtube_id_1_0 = 'p2Q6BrNhdh8'
self.block.youtube_id_1_25 = '1EeWXzPdhSA'
self.block.youtube_id_1_5 = 'rABDYkeK0x8'
self.block.show_captions = False
self.block.start_time = datetime.timedelta(seconds=1.0)
self.block.end_time = datetime.timedelta(seconds=60)
self.block.track = 'http://www.example.com/track'
self.block.handout = 'http://www.example.com/handout'
self.block.download_track = True
self.block.html5_sources = ['http://www.example.com/source.mp4', 'http://www.example.com/source1.ogg']
self.block.download_video = True
self.block.transcripts = {'ua': 'ukrainian_translation.srt', 'ge': 'german_translation.srt'}
self.block.edx_video_id = edx_video_id
xml = self.descriptor.definition_to_xml(self.file_system)
xml = self.block.definition_to_xml(self.file_system)
parser = etree.XMLParser(remove_blank_text=True)
xml_string = '''\
<video
@@ -741,7 +741,7 @@ class VideoExportTestCase(VideoBlockTestBase):
video_id=edx_video_id,
static_dir=EXPORT_IMPORT_STATIC_DIR,
resource_fs=self.file_system,
course_id=self.descriptor.scope_ids.usage_id.context_key,
course_id=self.block.scope_ids.usage_id.context_key,
)
@patch('xmodule.video_block.video_block.edxval_api')
@@ -749,9 +749,9 @@ class VideoExportTestCase(VideoBlockTestBase):
# Export should succeed without VAL data if video does not exist
mock_val_api.ValVideoNotFoundError = _MockValVideoNotFoundError
mock_val_api.export_to_xml = Mock(side_effect=mock_val_api.ValVideoNotFoundError)
self.descriptor.edx_video_id = 'test_edx_video_id'
self.block.edx_video_id = 'test_edx_video_id'
xml = self.descriptor.definition_to_xml(self.file_system)
xml = self.block.definition_to_xml(self.file_system)
parser = etree.XMLParser(remove_blank_text=True)
xml_string = '<video youtube="1.00:3_yD_cEKoCk" url_name="SampleProblem"/>'
expected = etree.XML(xml_string, parser=parser)
@@ -762,19 +762,19 @@ class VideoExportTestCase(VideoBlockTestBase):
"""
Test that we write the correct XML on export.
"""
self.descriptor.youtube_id_0_75 = 'izygArpw-Qo'
self.descriptor.youtube_id_1_0 = 'p2Q6BrNhdh8'
self.descriptor.youtube_id_1_25 = '1EeWXzPdhSA'
self.descriptor.youtube_id_1_5 = 'rABDYkeK0x8'
self.descriptor.show_captions = False
self.descriptor.start_time = datetime.timedelta(seconds=5.0)
self.descriptor.end_time = datetime.timedelta(seconds=0.0)
self.descriptor.track = 'http://www.example.com/track'
self.descriptor.download_track = True
self.descriptor.html5_sources = ['http://www.example.com/source.mp4', 'http://www.example.com/source.ogg']
self.descriptor.download_video = True
self.block.youtube_id_0_75 = 'izygArpw-Qo'
self.block.youtube_id_1_0 = 'p2Q6BrNhdh8'
self.block.youtube_id_1_25 = '1EeWXzPdhSA'
self.block.youtube_id_1_5 = 'rABDYkeK0x8'
self.block.show_captions = False
self.block.start_time = datetime.timedelta(seconds=5.0)
self.block.end_time = datetime.timedelta(seconds=0.0)
self.block.track = 'http://www.example.com/track'
self.block.download_track = True
self.block.html5_sources = ['http://www.example.com/source.mp4', 'http://www.example.com/source.ogg']
self.block.download_video = True
xml = self.descriptor.definition_to_xml(self.file_system)
xml = self.block.definition_to_xml(self.file_system)
parser = etree.XMLParser(remove_blank_text=True)
xml_string = '''\
<video url_name="SampleProblem" start_time="0:00:05" youtube="0.75:izygArpw-Qo,1.00:p2Q6BrNhdh8,1.25:1EeWXzPdhSA,1.50:rABDYkeK0x8" show_captions="false" download_video="true" download_track="true">
@@ -791,7 +791,7 @@ class VideoExportTestCase(VideoBlockTestBase):
"""
Test XML export with defaults.
"""
xml = self.descriptor.definition_to_xml(self.file_system)
xml = self.block.definition_to_xml(self.file_system)
# Check that download_video field is also set to default (False) in xml for backward compatibility
expected = '<video youtube="1.00:3_yD_cEKoCk" url_name="SampleProblem"/>\n'
assert expected == etree.tostring(xml, pretty_print=True).decode('utf-8')
@@ -801,8 +801,8 @@ class VideoExportTestCase(VideoBlockTestBase):
"""
Test XML export with transcripts being overridden to None.
"""
self.descriptor.transcripts = None
xml = self.descriptor.definition_to_xml(self.file_system)
self.block.transcripts = None
xml = self.block.definition_to_xml(self.file_system)
expected = b'<video youtube="1.00:3_yD_cEKoCk" url_name="SampleProblem"/>\n'
assert expected == etree.tostring(xml, pretty_print=True)
@@ -812,8 +812,8 @@ class VideoExportTestCase(VideoBlockTestBase):
Test XML export will *not* raise TypeError by lxml library if contains illegal characters.
The illegal characters in a String field are removed from the string instead.
"""
self.descriptor.display_name = 'Display\x1eName'
xml = self.descriptor.definition_to_xml(self.file_system)
self.block.display_name = 'Display\x1eName'
xml = self.block.definition_to_xml(self.file_system)
assert xml.get('display_name') == 'DisplayName'
@patch('xmodule.video_block.video_block.edxval_api', None)
@@ -821,8 +821,8 @@ class VideoExportTestCase(VideoBlockTestBase):
"""
Test XML export handles the unicode characters.
"""
self.descriptor.display_name = '这是文'
xml = self.descriptor.definition_to_xml(self.file_system)
self.block.display_name = '这是文'
xml = self.block.definition_to_xml(self.file_system)
assert xml.get('display_name') == '这是文'
@@ -869,8 +869,8 @@ class VideoBlockStudentViewDataTestCase(unittest.TestCase):
"""
Ensure that student_view_data returns the expected results for video blocks.
"""
descriptor = instantiate_descriptor(**field_data)
student_view_data = descriptor.student_view_data()
block = instantiate_block(**field_data)
student_view_data = block.student_view_data()
assert student_view_data == expected_student_view_data
@patch('xmodule.video_block.video_block.HLSPlaybackEnabledFlag.feature_enabled', Mock(return_value=True))
@@ -903,9 +903,9 @@ class VideoBlockStudentViewDataTestCase(unittest.TestCase):
'file_name': 'edx.sjson'
}
descriptor = instantiate_descriptor(edx_video_id='example_id', only_on_web=False)
descriptor.runtime.handler_url = MagicMock()
student_view_data = descriptor.student_view_data()
block = instantiate_block(edx_video_id='example_id', only_on_web=False)
block.runtime.handler_url = MagicMock()
student_view_data = block.student_view_data()
expected_video_data = {'hls': {'url': 'http://www.meowmix.com', 'file_size': 25556}}
self.assertDictEqual(student_view_data.get('encoded_videos'), expected_video_data)
@@ -973,8 +973,8 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
<handout src="http://www.example.com/handout"/>
</video>
'''
descriptor = instantiate_descriptor(data=xml_data)
assert descriptor.index_dictionary() == {'content': {'display_name': 'Test Video'}, 'content_type': 'Video'}
block = instantiate_block(data=xml_data)
assert block.index_dictionary() == {'content': {'display_name': 'Test Video'}, 'content_type': 'Video'}
def test_video_with_multiple_transcripts_index_dictionary(self):
"""
@@ -997,10 +997,10 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
</video>
'''
descriptor = instantiate_descriptor(data=xml_data_transcripts)
save_to_store(SRT_FILEDATA, "subs_grmtran1.srt", 'text/srt', descriptor.location)
save_to_store(CRO_SRT_FILEDATA, "subs_croatian1.srt", 'text/srt', descriptor.location)
assert descriptor.index_dictionary() ==\
block = instantiate_block(data=xml_data_transcripts)
save_to_store(SRT_FILEDATA, "subs_grmtran1.srt", 'text/srt', block.location)
save_to_store(CRO_SRT_FILEDATA, "subs_croatian1.srt", 'text/srt', block.location)
assert block.index_dictionary() ==\
{'content': {'display_name': 'Test Video',
'transcript_ge': 'sprechen sie deutsch? Ja, ich spreche Deutsch',
'transcript_hr': 'Dobar dan! Kako ste danas?'}, 'content_type': 'Video'}
@@ -1026,8 +1026,8 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
</video>
'''
descriptor = instantiate_descriptor(data=xml_data_transcripts)
translations = descriptor.available_translations(descriptor.get_transcripts_info())
block = instantiate_block(data=xml_data_transcripts)
translations = block.available_translations(block.get_transcripts_info())
assert sorted(translations) == sorted(['hr', 'ge'])
def test_video_with_no_transcripts_translation_retrieval(self):
@@ -1036,14 +1036,14 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
no transcripts uploaded by a user- ie, that retrieval
does not throw an exception.
"""
descriptor = instantiate_descriptor(data=None)
translations_with_fallback = descriptor.available_translations(descriptor.get_transcripts_info())
block = instantiate_block(data=None)
translations_with_fallback = block.available_translations(block.get_transcripts_info())
assert translations_with_fallback == ['en']
with patch.dict(settings.FEATURES, FALLBACK_TO_ENGLISH_TRANSCRIPTS=False):
# Some organizations don't have English transcripts for all videos
# This feature makes it configurable
translations_no_fallback = descriptor.available_translations(descriptor.get_transcripts_info())
translations_no_fallback = block.available_translations(block.get_transcripts_info())
assert translations_no_fallback == []
@override_settings(ALL_LANGUAGES=ALL_LANGUAGES)
@@ -1066,8 +1066,8 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
<transcript language="ur" src="" />
</video>
'''
descriptor = instantiate_descriptor(data=xml_data_transcripts)
translations = descriptor.available_translations(descriptor.get_transcripts_info(), verify_assets=False)
block = instantiate_block(data=xml_data_transcripts)
translations = block.available_translations(block.get_transcripts_info(), verify_assets=False)
assert translations != ['ur']
def assert_validation_message(self, validation, expected_msg):
@@ -1114,16 +1114,16 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
{xml_transcripts}
</video>
'''.format(xml_transcripts=xml_transcripts)
descriptor = instantiate_descriptor(data=xml_data_transcripts)
validation = descriptor.validate()
block = instantiate_block(data=xml_data_transcripts)
validation = block.validate()
self.assert_validation_message(validation, expected_validation_msg)
def test_video_transcript_none(self):
"""
Test video when transcripts is None.
"""
descriptor = instantiate_descriptor(data=None)
descriptor.transcripts = None
response = descriptor.get_transcripts_info()
block = instantiate_block(data=None)
block.transcripts = None
response = block.get_transcripts_info()
expected = {'transcripts': {}, 'sub': ''}
assert expected == response

View File

@@ -251,8 +251,8 @@ class EditableMetadataFieldsTest(unittest.TestCase):
)
def test_integer_field(self):
descriptor = self.get_descriptor(DictFieldData({'max_attempts': '7'}))
editable_fields = descriptor.editable_metadata_fields
block = self.get_block(DictFieldData({'max_attempts': '7'}))
editable_fields = block.editable_metadata_fields
assert 8 == len(editable_fields)
self.assert_field_values(
editable_fields, 'max_attempts', TestFields.max_attempts,
@@ -264,7 +264,7 @@ class EditableMetadataFieldsTest(unittest.TestCase):
explicitly_set=False, value='local default', default_value='local default'
)
editable_fields = self.get_descriptor(DictFieldData({})).editable_metadata_fields
editable_fields = self.get_block(DictFieldData({})).editable_metadata_fields
self.assert_field_values(
editable_fields, 'max_attempts', TestFields.max_attempts,
explicitly_set=False, value=1000, default_value=1000, type='Integer',
@@ -274,8 +274,8 @@ class EditableMetadataFieldsTest(unittest.TestCase):
def test_inherited_field(self):
kvs = InheritanceKeyValueStore(initial_values={}, inherited_settings={'showanswer': 'inherited'})
model_data = KvsFieldData(kvs)
descriptor = self.get_descriptor(model_data)
editable_fields = descriptor.editable_metadata_fields
block = self.get_block(model_data)
editable_fields = block.editable_metadata_fields
self.assert_field_values(
editable_fields, 'showanswer', InheritanceMixin.showanswer,
explicitly_set=False, value='inherited', default_value='inherited'
@@ -287,8 +287,8 @@ class EditableMetadataFieldsTest(unittest.TestCase):
inherited_settings={'showanswer': 'inheritable value'}
)
model_data = KvsFieldData(kvs)
descriptor = self.get_descriptor(model_data)
editable_fields = descriptor.editable_metadata_fields
block = self.get_block(model_data)
editable_fields = block.editable_metadata_fields
self.assert_field_values(
editable_fields, 'showanswer', InheritanceMixin.showanswer,
explicitly_set=True, value='explicit', default_value='inheritable value'
@@ -298,8 +298,8 @@ class EditableMetadataFieldsTest(unittest.TestCase):
# test_display_name_field verifies that a String field is of type "Generic".
# test_integer_field verifies that a Integer field is of type "Integer".
descriptor = self.get_descriptor(DictFieldData({}))
editable_fields = descriptor.editable_metadata_fields
block = self.get_block(DictFieldData({}))
editable_fields = block.editable_metadata_fields
# Tests for select
self.assert_field_values(
@@ -343,16 +343,16 @@ class EditableMetadataFieldsTest(unittest.TestCase):
field_data=field_data,
).editable_metadata_fields
def get_descriptor(self, field_data):
class TestModuleDescriptor(TestFields, self.TestableXmlXBlock): # lint-amnesty, pylint: disable=abstract-method
def get_block(self, field_data):
class TestModuleBlock(TestFields, self.TestableXmlXBlock): # lint-amnesty, pylint: disable=abstract-method
@property
def non_editable_metadata_fields(self):
non_editable_fields = super().non_editable_metadata_fields
non_editable_fields.append(TestModuleDescriptor.due)
non_editable_fields.append(TestModuleBlock.due)
return non_editable_fields
system = get_test_descriptor_system(render_template=Mock())
return system.construct_xblock_from_class(TestModuleDescriptor, field_data=field_data, scope_ids=Mock())
return system.construct_xblock_from_class(TestModuleBlock, field_data=field_data, scope_ids=Mock())
def assert_field_values(self, editable_fields, name, field, explicitly_set, value, default_value, # lint-amnesty, pylint: disable=dangerous-default-value
type='Generic', options=[]): # lint-amnesty, pylint: disable=redefined-builtin

View File

@@ -23,7 +23,7 @@ class InMemorySystem(XMLParsingSystem, MakoDescriptorSystem): # pylint: disable
def __init__(self, xml_import_data):
self.course_id = CourseKey.from_string(xml_import_data.course_id)
self.default_class = xml_import_data.default_class
self._descriptors = {}
self._blocks = {}
def get_policy(usage_id):
"""Return the policy data for the specified usage"""
@@ -42,19 +42,19 @@ class InMemorySystem(XMLParsingSystem, MakoDescriptorSystem): # pylint: disable
)
def process_xml(self, xml): # pylint: disable=method-hidden
"""Parse `xml` as an XBlock, and add it to `self._descriptors`"""
"""Parse `xml` as an XBlock, and add it to `self._blocks`"""
self.get_asides = Mock(return_value=[])
descriptor = self.xblock_from_node(
block = self.xblock_from_node(
etree.fromstring(xml),
None,
CourseLocationManager(self.course_id),
)
self._descriptors[str(descriptor.location)] = descriptor
return descriptor
self._blocks[str(block.location)] = block
return block
def load_item(self, location, for_parent=None): # pylint: disable=method-hidden, unused-argument
"""Return the descriptor loaded for `location`"""
return self._descriptors[str(location)]
"""Return the block loaded for `location`"""
return self._blocks[str(location)]
class XModuleXmlImportTest(TestCase):