refactor: xmodule/capa_module.py -> xmodule/capa_block.py

This commit is contained in:
0x29a
2022-10-26 21:01:20 +02:00
committed by Piotr Surowiec
parent 7f2e68c2fd
commit 4c005e86e8
25 changed files with 110 additions and 110 deletions

View File

@@ -24,7 +24,7 @@ from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import AssetKey, CourseKey, UsageKey
from opaque_keys.edx.locations import CourseLocator
from path import Path as path
from xmodule.capa_module import ProblemBlock
from xmodule.capa_block import ProblemBlock
from xmodule.contentstore.content import StaticContent
from xmodule.contentstore.django import contentstore
from xmodule.contentstore.utils import empty_asset_trashcan, restore_asset_from_trashcan
@@ -1518,7 +1518,7 @@ class ContentStoreTest(ContentStoreTestCase):
retarget = str(course.id.make_usage_key('chapter', 'REPLACE')).replace('REPLACE', r'([0-9]|[a-f]){3,}')
self.assertRegex(data['locator'], retarget)
def test_capa_module(self):
def test_capa_block(self):
"""Test that a problem treats markdown specially."""
course = CourseFactory.create()

View File

@@ -2,7 +2,7 @@
from xmodule import templates
from xmodule.capa_module import ProblemBlock
from xmodule.capa_block import ProblemBlock
from xmodule.course_module import CourseBlock
from xmodule.html_module import HtmlBlock
from xmodule.modulestore import ModuleStoreEnum

View File

@@ -27,7 +27,7 @@ from xblock.fields import Scope, ScopeIds, String
from xblock.runtime import DictKeyValueStore, KvsFieldData
from xblock.test.tools import TestRuntime
from xblock.validation import ValidationMessage
from xmodule.capa_module import ProblemBlock
from xmodule.capa_block import ProblemBlock
from xmodule.course_module import DEFAULT_START_DATE
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore

View File

@@ -8,7 +8,7 @@ from xblock.core import XBlock, XBlockAside
from xblock.fields import Dict, Scope
from common.djangoapps.edxmako.shortcuts import render_to_string
from xmodule.capa_module import ProblemBlock # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.capa_block import ProblemBlock # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.x_module import AUTHOR_VIEW # lint-amnesty, pylint: disable=wrong-import-order
_ = lambda text: text

View File

@@ -1 +1 @@
These files really should be in the capa module, but we don't have a way to load js from there at the moment. (TODO)
These files really should be in the capa block, but we don't have a way to load js from there at the moment. (TODO)

View File

@@ -131,7 +131,7 @@ capa
* PR: https://github.com/openedx/edx-platform/pull/30403
* Notes: Like xmodule, extracting capa from edx-platform would have been difficult. However, updating its import path was feasible; so, to create avoid creating a sixth top-level package, it was decided to move the code within ./xmodule as a sub-packages. ./xmodule was chosen as the parent package because it contains related code, notably ./xmodule/capa_module.py, which defines the ``ProblemBlock`` (formerly the ``CapaModule``).
* Notes: Like xmodule, extracting capa from edx-platform would have been difficult. However, updating its import path was feasible; so, to create avoid creating a sixth top-level package, it was decided to move the code within ./xmodule as a sub-packages. ./xmodule was chosen as the parent package because it contains related code, notably ./xmodule/capa_block.py, which defines the ``ProblemBlock`` (formerly the ``CapaModule``).
xblock_discussion
-----------------

View File

@@ -42,7 +42,7 @@ from xblock.test.tools import TestRuntime # lint-amnesty, pylint: disable=wrong
from xmodule.capa.tests.response_xml_factory import OptionResponseXMLFactory # lint-amnesty, pylint: disable=reimported
from xmodule.capa.xqueue_interface import XQueueInterface
from xmodule.capa_module import ProblemBlock
from xmodule.capa_block import ProblemBlock
from xmodule.contentstore.django import contentstore
from xmodule.html_module import AboutBlock, CourseInfoBlock, HtmlBlock, StaticTabBlock
from xmodule.lti_module import LTIBlock

View File

@@ -477,7 +477,7 @@ class TestProblemResponsesReport(TestReportMixin, InstructorTaskModuleTestCase):
Temporarily removes the generate_report_data method so we can test
report generation when it's absent.
"""
from xmodule.capa_module import ProblemBlock
from xmodule.capa_block import ProblemBlock
generate_report_data = ProblemBlock.generate_report_data
del ProblemBlock.generate_report_data
try:
@@ -532,7 +532,7 @@ class TestProblemResponsesReport(TestReportMixin, InstructorTaskModuleTestCase):
assert student_data_keys_list == ['username', 'title', 'location', 'block_key', 'state']
mock_list_problem_responses.assert_called_with(self.course.id, ANY, ANY)
@patch('xmodule.capa_module.ProblemBlock.generate_report_data', create=True)
@patch('xmodule.capa_block.ProblemBlock.generate_report_data', create=True)
def test_build_student_data_for_block_with_mock_generate_report_data(self, mock_generate_report_data):
"""
Ensure that building student data for a block that supports the
@@ -571,7 +571,7 @@ class TestProblemResponsesReport(TestReportMixin, InstructorTaskModuleTestCase):
assert student_data[0]['state'] == student_data[1]['state']
assert student_data_keys_list == ['username', 'title', 'location', 'more', 'some', 'block_key', 'state']
@patch('xmodule.capa_module.ProblemBlock.generate_report_data', create=True)
@patch('xmodule.capa_block.ProblemBlock.generate_report_data', create=True)
def test_build_student_data_for_block_with_ordered_generate_report_data(self, mock_generate_report_data):
"""
Ensure that building student data for a block that returns OrderedDicts from the
@@ -698,7 +698,7 @@ class TestProblemResponsesReport(TestReportMixin, InstructorTaskModuleTestCase):
assert len(student_data) == filtered_count
@patch('lms.djangoapps.instructor_task.tasks_helper.grades.list_problem_responses')
@patch('xmodule.capa_module.ProblemBlock.generate_report_data', create=True)
@patch('xmodule.capa_block.ProblemBlock.generate_report_data', create=True)
def test_build_student_data_for_block_with_generate_report_data_not_implemented(
self,
mock_generate_report_data,

View File

@@ -5,7 +5,7 @@ new Show Answer values that remove the Past Due check (keeping the rest intact)
from lms.djangoapps.courseware.field_overrides import FieldOverrideProvider
from openedx.features.course_experience import RELATIVE_DATES_FLAG
from xmodule.capa_module import SHOWANSWER # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.capa_block import SHOWANSWER # lint-amnesty, pylint: disable=wrong-import-order
class ShowAnswerFieldOverride(FieldOverrideProvider):

View File

@@ -10,7 +10,7 @@ from lms.djangoapps.ccx.tests.test_overrides import inject_field_overrides
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module
from openedx.features.course_experience import RELATIVE_DATES_FLAG
from xmodule.capa_module import SHOWANSWER # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.capa_block import SHOWANSWER # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order

View File

@@ -25,7 +25,7 @@ XBLOCKS = [
"library_sourced = xmodule.library_sourced_block:LibrarySourcedBlock",
"lti = xmodule.lti_module:LTIBlock",
"poll_question = xmodule.poll_module:PollBlock",
"problem = xmodule.capa_module:ProblemBlock",
"problem = xmodule.capa_block:ProblemBlock",
"randomize = xmodule.randomize_module:RandomizeBlock",
"sequential = xmodule.seq_module:SequenceBlock",
"slides = xmodule.template_module:TranslateCustomTagBlock",

View File

@@ -10,7 +10,7 @@
"""
Main module which shows problems (of "capa" type).
This is used by capa_module.
This is used by capa_block.
"""
@@ -34,7 +34,7 @@ import xmodule.capa.responsetypes as responsetypes
import xmodule.capa.xqueue_interface as xqueue_interface
from xmodule.capa.correctmap import CorrectMap
from xmodule.capa.safe_exec import safe_exec
from xmodule.capa.util import contextualize_text, convert_files_to_filenames, get_course_id_from_capa_module
from xmodule.capa.util import contextualize_text, convert_files_to_filenames, get_course_id_from_capa_block
from openedx.core.djangolib.markup import HTML, Text
from openedx.core.lib.edx_six import get_gettext
from xmodule.stringify import stringify_children
@@ -130,7 +130,7 @@ class LoncapaProblem(object):
"""
Main class for capa Problems.
"""
def __init__(self, problem_text, id, capa_system, capa_module, # pylint: disable=redefined-builtin
def __init__(self, problem_text, id, capa_system, capa_block, # pylint: disable=redefined-builtin
state=None, seed=None, minimal_init=False, extract_tree=True):
"""
Initializes capa Problem.
@@ -141,7 +141,7 @@ class LoncapaProblem(object):
id (string): identifier for this problem, often a filename (no spaces).
capa_system (LoncapaSystem): LoncapaSystem instance which provides OS,
rendering, user context, and other resources.
capa_module: instance needed to access runtime/logging
capa_block: instance needed to access runtime/logging
state (dict): containing the following keys:
- `seed` (int) random number generator seed
- `student_answers` (dict) maps input id to the stored answer for that input
@@ -159,7 +159,7 @@ class LoncapaProblem(object):
self.do_reset()
self.problem_id = id
self.capa_system = capa_system
self.capa_module = capa_module
self.capa_block = capa_block
state = state or {}
@@ -190,12 +190,12 @@ class LoncapaProblem(object):
try:
self.make_xml_compatible(self.tree)
except Exception:
capa_module = self.capa_module
capa_block = self.capa_block
log.exception(
"CAPAProblemError: %s, id:%s, data: %s",
capa_module.display_name,
capa_block.display_name,
self.problem_id,
capa_module.data
capa_block.data
)
raise
@@ -421,7 +421,7 @@ class LoncapaProblem(object):
def grade_answers(self, answers):
"""
Grade student responses. Called by capa_module.submit_problem.
Grade student responses. Called by capa_block.submit_problem.
`answers` is a dict of all the entries from request.POST, but with the first part
of each key removed (the string before the first "_").
@@ -501,7 +501,7 @@ class LoncapaProblem(object):
Returns a dict of answer_ids to answer values. If we cannot generate
an answer (this sometimes happens in customresponses), that answer_id is
not included. Called by "show answers" button JSON request
(see capa_module)
(see capa_block)
"""
# dict of (id, correct_answer)
answer_map = {}
@@ -935,8 +935,8 @@ class LoncapaProblem(object):
python_path=python_path,
extra_files=extra_files,
cache=self.capa_system.cache,
limit_overrides_context=get_course_id_from_capa_module(
self.capa_module
limit_overrides_context=get_course_id_from_capa_block(
self.capa_block
),
slug=self.problem_id,
unsafely=self.capa_system.can_execute_unsafe_code(),
@@ -994,7 +994,7 @@ class LoncapaProblem(object):
# If we're withholding correctness, don't show adaptive hints either.
# Note that regular, "demand" hints will be shown, if the course author has added them to the problem.
if not self.capa_module.correctness_available():
if not self.capa_block.correctness_available():
status = 'submitted'
else:
# If the the problem has not been saved since the last submit set the status to the
@@ -1107,7 +1107,7 @@ class LoncapaProblem(object):
# instantiate capa Response
responsetype_cls = responsetypes.registry.get_class_for_tag(response.tag)
responder = responsetype_cls(
response, inputfields, self.context, self.capa_system, self.capa_module, minimal_init
response, inputfields, self.context, self.capa_system, self.capa_block, minimal_init
)
# save in list in self
self.responders[response] = responder

View File

@@ -57,7 +57,7 @@ from .util import (
convert_files_to_filenames,
default_tolerance,
find_with_default,
get_course_id_from_capa_module,
get_course_id_from_capa_block,
get_inner_html_from_xpath,
is_list_of_files
)
@@ -162,7 +162,7 @@ class LoncapaResponse(six.with_metaclass(abc.ABCMeta, object)):
# By default, we set this to False, allowing subclasses to override as appropriate.
multi_device_support = False
def __init__(self, xml, inputfields, context, system, capa_module, minimal_init):
def __init__(self, xml, inputfields, context, system, capa_block, minimal_init):
"""
Init is passed the following arguments:
@@ -170,13 +170,13 @@ class LoncapaResponse(six.with_metaclass(abc.ABCMeta, object)):
- inputfields : ordered list of ElementTrees for each input entry field in this Response
- context : script processor context
- system : LoncapaSystem instance which provides OS, rendering, and user context
- capa_module : Capa module, to access runtime
- capa_block : Capa block, to access runtime
"""
self.xml = xml
self.inputfields = inputfields
self.context = context
self.capa_system = system
self.capa_module = capa_module # njp, note None
self.capa_block = capa_block # njp, note None
self.id = xml.get('id')
@@ -373,7 +373,7 @@ class LoncapaResponse(six.with_metaclass(abc.ABCMeta, object)):
# This is the "feedback hint" event
event_info = {}
event_info['module_id'] = text_type(self.capa_module.location)
event_info['module_id'] = text_type(self.capa_block.location)
event_info['problem_part_id'] = self.id
event_info['trigger_type'] = 'single' # maybe be overwritten by log_extra
event_info['hint_label'] = label
@@ -383,7 +383,7 @@ class LoncapaResponse(six.with_metaclass(abc.ABCMeta, object)):
event_info['question_type'] = question_tag
if log_extra:
event_info.update(log_extra)
self.capa_module.runtime.publish(self.capa_module, 'edx.problem.hint.feedback_displayed', event_info)
self.capa_block.runtime.publish(self.capa_block, 'edx.problem.hint.feedback_displayed', event_info)
# Form the div-wrapped hint texts
hints_wrap = HTML('').join(
@@ -486,8 +486,8 @@ class LoncapaResponse(six.with_metaclass(abc.ABCMeta, object)):
globals_dict,
python_path=self.context['python_path'],
extra_files=self.context['extra_files'],
limit_overrides_context=get_course_id_from_capa_module(
self.capa_module
limit_overrides_context=get_course_id_from_capa_block(
self.capa_block
),
slug=self.id,
random_seed=self.context['seed'],
@@ -985,7 +985,7 @@ class MultipleChoiceResponse(LoncapaResponse):
whole software stack works with just the one system of naming.
The .has_mask() test on a response checks for masking, implemented by a
._has_mask attribute on the response object.
The logging functionality in capa_module calls the unmask functions here
The logging functionality in capa_block calls the unmask functions here
to translate back to choice_0 name style for recording in the logs, so
the logging is in terms of the regular names.
"""

View File

@@ -83,9 +83,9 @@ def test_capa_system(render_template=None):
return the_system
def mock_capa_module():
def mock_capa_block():
"""
capa response types needs just two things from the capa_module: location and publish.
capa response types needs just two things from the capa_block: location and publish.
"""
def mock_location_text(self): # lint-amnesty, pylint: disable=unused-argument
"""
@@ -93,21 +93,21 @@ def mock_capa_module():
"""
return 'i4x://Foo/bar/mock/abc'
capa_module = Mock()
capa_block = Mock()
if six.PY2:
capa_module.location.__unicode__ = mock_location_text
capa_block.location.__unicode__ = mock_location_text
else:
capa_module.location.__str__ = mock_location_text
capa_block.location.__str__ = mock_location_text
# The following comes into existence by virtue of being called
# capa_module.runtime.publish
return capa_module
# capa_block.runtime.publish
return capa_block
def new_loncapa_problem(xml, problem_id='1', capa_system=None, seed=723, use_capa_render_template=False):
"""Construct a `LoncapaProblem` suitable for unit tests."""
render_template = capa_render_template if use_capa_render_template else None
return LoncapaProblem(xml, id=problem_id, seed=seed, capa_system=capa_system or test_capa_system(render_template),
capa_module=mock_capa_module())
capa_block=mock_capa_block())
def load_fixture(relpath):

View File

@@ -359,7 +359,7 @@ class SchematicResponseXMLFactory(ResponseXMLFactory):
Although <schematic> can have several attributes,
(*height*, *width*, *parts*, *analyses*, *submit_analysis*, and *initial_value*),
none of them are used in the capa module.
none of them are used in the capa block.
For testing, we create a bare-bones version of <schematic>."""
return etree.Element("schematic")

View File

@@ -48,10 +48,10 @@ class TextInputHintsTest(HintTest):
def test_tracking_log(self):
"""Test that the tracking log comes out right."""
self.problem.capa_module.reset_mock()
self.problem.capa_block.reset_mock()
self.get_hint('1_3_1', 'Blue')
self.problem.capa_module.runtime.publish.assert_called_with(
self.problem.capa_module,
self.problem.capa_block.runtime.publish.assert_called_with(
self.problem.capa_block,
'edx.problem.hint.feedback_displayed',
{'module_id': 'i4x://Foo/bar/mock/abc',
'problem_part_id': '1_2',
@@ -224,8 +224,8 @@ class NumericInputHintsTest(HintTest):
def test_tracking_log(self):
self.get_hint('1_2_1', '1.141')
self.problem.capa_module.runtime.publish.assert_called_with(
self.problem.capa_module,
self.problem.capa_block.runtime.publish.assert_called_with(
self.problem.capa_block,
'edx.problem.hint.feedback_displayed',
{'module_id': 'i4x://Foo/bar/mock/abc', 'problem_part_id': '1_1', 'trigger_type': 'single',
'hint_label': 'Nice',
@@ -363,8 +363,8 @@ class CheckboxHintsTestTracking(HintTest):
"""Test checkbox tracking log - by far the most complicated case"""
# A -> 1 hint
self.get_hint('1_2_1', ['choice_0'])
self.problem.capa_module.runtime.publish.assert_called_with(
self.problem.capa_module,
self.problem.capa_block.runtime.publish.assert_called_with(
self.problem.capa_block,
'edx.problem.hint.feedback_displayed',
{'hint_label': 'Incorrect:',
'module_id': 'i4x://Foo/bar/mock/abc',
@@ -378,10 +378,10 @@ class CheckboxHintsTestTracking(HintTest):
)
# B C -> 2 hints
self.problem.capa_module.runtime.publish.reset_mock()
self.problem.capa_block.runtime.publish.reset_mock()
self.get_hint('1_2_1', ['choice_1', 'choice_2'])
self.problem.capa_module.runtime.publish.assert_called_with(
self.problem.capa_module,
self.problem.capa_block.runtime.publish.assert_called_with(
self.problem.capa_block,
'edx.problem.hint.feedback_displayed',
{'hint_label': 'Incorrect:',
'module_id': 'i4x://Foo/bar/mock/abc',
@@ -398,10 +398,10 @@ class CheckboxHintsTestTracking(HintTest):
)
# A C -> 1 Compound hint
self.problem.capa_module.runtime.publish.reset_mock()
self.problem.capa_block.runtime.publish.reset_mock()
self.get_hint('1_2_1', ['choice_0', 'choice_2'])
self.problem.capa_module.runtime.publish.assert_called_with(
self.problem.capa_module,
self.problem.capa_block.runtime.publish.assert_called_with(
self.problem.capa_block,
'edx.problem.hint.feedback_displayed',
{'hint_label': 'Correct:',
'module_id': 'i4x://Foo/bar/mock/abc',
@@ -428,10 +428,10 @@ class MultpleChoiceHintsTest(HintTest):
def test_tracking_log(self):
"""Test that the tracking log comes out right."""
self.problem.capa_module.reset_mock()
self.problem.capa_block.reset_mock()
self.get_hint('1_3_1', 'choice_2')
self.problem.capa_module.runtime.publish.assert_called_with(
self.problem.capa_module,
self.problem.capa_block.runtime.publish.assert_called_with(
self.problem.capa_block,
'edx.problem.hint.feedback_displayed',
{'module_id': 'i4x://Foo/bar/mock/abc', 'problem_part_id': '1_2', 'trigger_type': 'single',
'student_answer': ['choice_2'], 'correctness': False, 'question_type': 'multiplechoiceresponse',
@@ -469,10 +469,10 @@ class MultpleChoiceHintsWithHtmlTest(HintTest):
def test_tracking_log(self):
"""Test that the tracking log comes out right."""
self.problem.capa_module.reset_mock()
self.problem.capa_block.reset_mock()
self.get_hint('1_2_1', 'choice_0')
self.problem.capa_module.runtime.publish.assert_called_with(
self.problem.capa_module,
self.problem.capa_block.runtime.publish.assert_called_with(
self.problem.capa_block,
'edx.problem.hint.feedback_displayed',
{'module_id': 'i4x://Foo/bar/mock/abc', 'problem_part_id': '1_1', 'trigger_type': 'single',
'student_answer': ['choice_0'], 'correctness': False, 'question_type': 'multiplechoiceresponse',
@@ -503,10 +503,10 @@ class DropdownHintsTest(HintTest):
def test_tracking_log(self):
"""Test that the tracking log comes out right."""
self.problem.capa_module.reset_mock()
self.problem.capa_block.reset_mock()
self.get_hint('1_3_1', 'FACES')
self.problem.capa_module.runtime.publish.assert_called_with(
self.problem.capa_module,
self.problem.capa_block.runtime.publish.assert_called_with(
self.problem.capa_block,
'edx.problem.hint.feedback_displayed',
{'module_id': 'i4x://Foo/bar/mock/abc', 'problem_part_id': '1_2', 'trigger_type': 'single',
'student_answer': ['FACES'], 'correctness': True, 'question_type': 'optionresponse',

View File

@@ -224,28 +224,28 @@ def remove_markup(html):
return HTML(bleach.clean(html, tags=[], strip=True))
def get_course_id_from_capa_module(capa_module):
def get_course_id_from_capa_block(capa_block):
"""
Extract a stringified course run key from a CAPA module (aka ProblemBlock).
Extract a stringified course run key from a CAPA block (aka ProblemBlock).
This is a bit of a hack. Its intended use is to allow us to pass the course id
(if available) to `safe_exec`, enabling course-run-specific resource limits
in the safe execution environment (codejail).
Arguments:
capa_module (ProblemBlock|None)
capa_block (ProblemBlock|None)
Returns: str|None
The stringified course run key of the module.
If not available, fall back to None.
"""
if not capa_module:
if not capa_block:
return None
try:
return str(capa_module.scope_ids.usage_id.course_key)
return str(capa_block.scope_ids.usage_id.course_key)
except (AttributeError, TypeError):
# AttributeError:
# If the capa module lacks scope ids or has unexpected scope ids, we
# If the capa block lacks scope ids or has unexpected scope ids, we
# would rather fall back to `None` than let an AttributeError be raised
# here.
# TypeError:

View File

@@ -547,7 +547,7 @@ class ProblemBlock(
try:
tree = etree.XML(self.data)
except etree.XMLSyntaxError:
log.error(f'Error parsing problem types from xml for capa module {self.display_name}')
log.error(f'Error parsing problem types from xml for capa block {self.display_name}')
return None # short-term fix to prevent errors (TNL-5057). Will be more properly addressed in TNL-4525.
registered_tags = responsetypes.registry.registered_tags()
return {node.tag for node in tree.iter() if node.tag in registered_tags}
@@ -638,7 +638,7 @@ class ProblemBlock(
problem_text=self.data,
id=self.location.html_id(),
capa_system=capa_system,
capa_module=self,
capa_block=self,
state={},
seed=1,
minimal_init=True,
@@ -708,7 +708,7 @@ class ProblemBlock(
id=self.location.html_id(),
capa_system=capa_system,
# We choose to run without a fully initialized CapaModule
capa_module=None,
capa_block=None,
state={
'done': user_state.state.get('done'),
'correct_map': user_state.state.get('correct_map'),
@@ -849,7 +849,7 @@ class ProblemBlock(
state=state,
seed=self.get_seed(),
capa_system=capa_system,
capa_module=self, # njp
capa_block=self, # njp
)
def get_state_for_lcp(self):
@@ -1070,7 +1070,7 @@ class ProblemBlock(
if self.debug:
msg = HTML(
'[courseware.capa.capa_module] '
'[courseware.capa.capa_block] '
'Failed to generate HTML for problem {url}'
).format(
url=str(self.location)
@@ -1786,7 +1786,7 @@ class ProblemBlock(
except (StudentInputError, ResponseError, LoncapaProblemError) as inst:
if self.debug:
log.warning(
"StudentInputError in capa_module:problem_check",
"StudentInputError in capa_block:problem_check",
exc_info=True
)
@@ -2174,7 +2174,7 @@ class ProblemBlock(
self.update_correctness()
calculated_score = self.calculate_score()
except (StudentInputError, ResponseError, LoncapaProblemError) as inst: # lint-amnesty, pylint: disable=unused-variable
log.warning("Input error in capa_module:problem_rescore", exc_info=True)
log.warning("Input error in capa_block:problem_rescore", exc_info=True)
event_info['failure'] = 'input_error'
self.publish_unmasked('problem_rescore_fail', event_info)
raise

View File

@@ -14,7 +14,7 @@ from openedx.core.djangoapps.content_libraries import api as library_api
from openedx.core.djangoapps.xblock.api import load_block
from openedx.core.lib import blockstore_api
from common.djangoapps.student.auth import has_studio_write_access
from xmodule.capa_module import ProblemBlock
from xmodule.capa_block import ProblemBlock
from xmodule.library_content_module import ANY_CAPA_TYPE_VALUE
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.exceptions import ItemNotFoundError

View File

@@ -2455,12 +2455,12 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
new_block_info.defaults = new_block_info.fields
# <workaround>
# CAPA modules store their 'markdown' value (an alternate representation of their content)
# CAPA blocks store their 'markdown' value (an alternate representation of their content)
# in Scope.settings rather than Scope.content :-/
# markdown is a field that really should not be overridable - it fundamentally changes the content.
# capa modules also use a custom editor that always saves their markdown field to the metadata,
# capa blocks also use a custom editor that always saves their markdown field to the metadata,
# even if it hasn't changed, which breaks our override system.
# So until capa modules are fixed, we special-case them and remove their markdown fields,
# So until capa blocks are fixed, we special-case them and remove their markdown fields,
# forcing the inherited version to use XML only.
if usage_key.block_type == 'problem' and 'markdown' in new_block_info.defaults:
del new_block_info.defaults['markdown']

View File

@@ -59,7 +59,7 @@ class TestSplitCopyTemplate(MixedSplitTestCase):
problem_block_course = self.store.get_item(vertical_block_course.children[0])
assert problem_block_course.display_name == problem_library_display_name
# Check that when capa modules are copied, their "markdown" fields (Scope.settings) are removed.
# Check that when capa blocks are copied, their "markdown" fields (Scope.settings) are removed.
# (See note in split.py:copy_from_template())
assert problem_block.markdown is not None
assert problem_block_course.markdown is None

View File

@@ -20,7 +20,7 @@ from docopt import docopt
from path import Path as path
from xmodule.annotatable_block import AnnotatableBlock
from xmodule.capa_module import ProblemBlock
from xmodule.capa_block import ProblemBlock
from xmodule.conditional_module import ConditionalBlock
from xmodule.html_module import AboutBlock, CourseInfoBlock, HtmlBlock, StaticTabBlock
from xmodule.library_content_module import LibraryContentBlock

View File

@@ -33,10 +33,10 @@ from xmodule.capa import responsetypes
from xmodule.capa.correctmap import CorrectMap
from xmodule.capa.responsetypes import LoncapaProblemError, ResponseError, StudentInputError
from xmodule.capa.xqueue_interface import XQueueInterface
from xmodule.capa_module import ComplexEncoder, ProblemBlock
from xmodule.capa_block import ComplexEncoder, ProblemBlock
from xmodule.tests import DATA_DIR
from ..capa_module import RANDOMIZATION, SHOWANSWER
from ..capa_block import RANDOMIZATION, SHOWANSWER
from . import get_test_system
@@ -218,7 +218,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
def test_get_score(self):
"""
Tests the internals of get_score. In keeping with the ScorableXBlock spec,
Capa modules store their score independently of the LCP internals, so it must
Capa blocks store their score independently of the LCP internals, so it must
be explicitly updated.
"""
student_answers = {'1_2_1': 'abcd'}
@@ -705,7 +705,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# what the input is, by patching CorrectMap.is_correct()
# Also simulate rendering the HTML
with patch('xmodule.capa.correctmap.CorrectMap.is_correct') as mock_is_correct:
with patch('xmodule.capa_module.ProblemBlock.get_problem_html') as mock_html:
with patch('xmodule.capa_block.ProblemBlock.get_problem_html') as mock_html:
mock_is_correct.return_value = True
mock_html.return_value = "Test HTML"
@@ -749,7 +749,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Problem closed -- cannot submit
# Simulate that ProblemBlock.closed() always returns True
with patch('xmodule.capa_module.ProblemBlock.closed') as mock_closed:
with patch('xmodule.capa_block.ProblemBlock.closed') as mock_closed:
mock_closed.return_value = True
with pytest.raises(xmodule.exceptions.NotFoundError):
get_request_dict = {CapaFactory.input_key(): '3.14'}
@@ -902,7 +902,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
def test_submit_problem_error(self):
# Try each exception that capa_module should handle
# Try each exception that capa_block should handle
exception_classes = [StudentInputError,
LoncapaProblemError,
ResponseError]
@@ -929,7 +929,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
def test_submit_problem_error_with_codejail_exception(self):
# Try each exception that capa_module should handle
# Try each exception that capa_block should handle
exception_classes = [StudentInputError,
LoncapaProblemError,
ResponseError]
@@ -999,7 +999,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
def test_submit_problem_error_nonascii(self):
# Try each exception that capa_module should handle
# Try each exception that capa_block should handle
exception_classes = [StudentInputError,
LoncapaProblemError,
ResponseError]
@@ -1026,7 +1026,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
def test_submit_problem_error_with_staff_user(self):
# Try each exception that capa module should handle
# Try each exception that capa block should handle
for exception_class in [StudentInputError,
LoncapaProblemError,
ResponseError]:
@@ -1088,7 +1088,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module.choose_new_seed = Mock(wraps=module.choose_new_seed)
# Stub out HTML rendering
with patch('xmodule.capa_module.ProblemBlock.get_problem_html') as mock_html:
with patch('xmodule.capa_block.ProblemBlock.get_problem_html') as mock_html:
mock_html.return_value = "<div>Test HTML</div>"
# Reset the problem
@@ -1110,7 +1110,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS)
# Simulate that the problem is closed
with patch('xmodule.capa_module.ProblemBlock.closed') as mock_closed:
with patch('xmodule.capa_block.ProblemBlock.closed') as mock_closed:
mock_closed.return_value = True
# Try to reset the problem
@@ -1302,7 +1302,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module = CapaFactory.create(done=False)
# Simulate that the problem is closed
with patch('xmodule.capa_module.ProblemBlock.closed') as mock_closed:
with patch('xmodule.capa_block.ProblemBlock.closed') as mock_closed:
mock_closed.return_value = True
# Try to save the problem
@@ -1931,8 +1931,8 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
assert 0 <= module.seed < 1000
i -= 1
@patch('xmodule.capa_module.log')
@patch('xmodule.capa_module.Progress')
@patch('xmodule.capa_block.log')
@patch('xmodule.capa_block.Progress')
def test_get_progress_error(self, mock_progress, mock_log):
"""
Check that an exception given in `Progress` produces a `log.exception` call.
@@ -1945,7 +1945,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
mock_log.exception.assert_called_once_with('Got bad progress')
mock_log.reset_mock()
@patch('xmodule.capa_module.Progress')
@patch('xmodule.capa_block.Progress')
def test_get_progress_no_error_if_weight_zero(self, mock_progress):
"""
Check that if the weight is 0 get_progress does not try to create a Progress object.
@@ -1957,7 +1957,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
assert progress is None
assert not mock_progress.called
@patch('xmodule.capa_module.Progress')
@patch('xmodule.capa_block.Progress')
def test_get_progress_calculate_progress_fraction(self, mock_progress):
"""
Check that score and total are calculated correctly for the progress fraction.
@@ -3266,7 +3266,7 @@ class ProblemBlockReportGenerationTest(unittest.TestCase):
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()
with patch('xmodule.capa_module.LoncapaProblem') as mock_LoncapaProblem:
with patch('xmodule.capa_block.LoncapaProblem') as mock_LoncapaProblem:
mock_LoncapaProblem.side_effect = LoncapaProblemError
report_data = list(descriptor.generate_report_data(
self._mock_user_state_generator(

View File

@@ -1,9 +1,9 @@
"""
Tests the logic of problems with a delay between attempt submissions.
Note that this test file is based off of test_capa_module.py and as
Note that this test file is based off of test_capa_block.py and as
such, uses the same CapaFactory problem setup to test the functionality
of the submit_problem method of a capa module when the "delay between quiz
of the submit_problem method of a capa block when the "delay between quiz
submissions" setting is set to different values
"""
@@ -21,7 +21,7 @@ from xblock.fields import ScopeIds
from xblock.scorable import Score
import xmodule
from xmodule.capa_module import ProblemBlock
from xmodule.capa_block import ProblemBlock
from . import get_test_system
@@ -30,7 +30,7 @@ class CapaFactoryWithDelay:
"""
Create problem modules class, specialized for delay_between_attempts
test cases. This factory seems different enough from the one in
test_capa_module that unifying them is unattractive.
test_capa_block that unifying them is unattractive.
Removed the unused optional arguments.
"""

View File

@@ -22,7 +22,7 @@ from xmodule.modulestore.tests.utils import MixedSplitTestCase
from xmodule.tests import get_test_system
from xmodule.validation import StudioValidationMessage
from xmodule.x_module import AUTHOR_VIEW
from xmodule.capa_module import ProblemBlock
from xmodule.capa_block import ProblemBlock
from .test_course_module import DummySystem as TestImportSystem