Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions cms/djangoapps/contentstore/tests/test_contentstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -1450,8 +1450,6 @@ def test_capa_block(self):
problem_loc = UsageKey.from_string(payload['locator'])
problem = self.store.get_item(problem_loc)
self.assertIsInstance(problem, ProblemBlock, "New problem is not a ProblemBlock")
context = problem.get_context()
self.assertIn('markdown', context, "markdown is missing from context")
self.assertNotIn('markdown', problem.editable_metadata_fields, "Markdown slipped into the editable metadata fields") # lint-amnesty, pylint: disable=line-too-long

def test_cms_imported_course_walkthrough(self):
Expand Down
14 changes: 0 additions & 14 deletions cms/djangoapps/contentstore/tests/test_crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,9 @@ def test_get_templates(self):
self.assertIsNotNone(found.get('course'))
self.assertIsNotNone(found.get('about'))
self.assertIsNotNone(found.get('html'))
self.assertIsNotNone(found.get('problem'))
self.assertEqual(len(found.get('course')), 0)
self.assertEqual(len(found.get('about')), 1)
self.assertGreaterEqual(len(found.get('html')), 2)
self.assertGreaterEqual(len(found.get('problem')), 10)
dropdown = None
for template in found['problem']:
self.assertIn('metadata', template)
self.assertIn('display_name', template['metadata'])
if template['metadata']['display_name'] == 'Dropdown':
dropdown = template
break
self.assertIsNotNone(dropdown)
self.assertIn('markdown', dropdown['metadata'])
self.assertIn('data', dropdown)
self.assertRegex(dropdown['metadata']['markdown'], r'.*dropdown problems.*')
self.assertRegex(dropdown['data'], r'<problem>\s*<optionresponse>\s*<p>.*dropdown problems.*')

def test_get_some_templates(self):
course = CourseFactory.create()
Expand Down
19 changes: 0 additions & 19 deletions cms/djangoapps/contentstore/toggles.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,25 +123,6 @@ def use_video_gallery_flow():
return ENABLE_VIDEO_GALLERY_FLOW_FLAG.is_enabled()


# .. toggle_name: legacy_studio.problem_editor
# .. toggle_implementation: WaffleFlag
# .. toggle_default: False
# .. toggle_description: Temporarily fall back to the old Problem component (a.k.a. CAPA/problem block) editor.
# .. toggle_use_cases: temporary
# .. toggle_creation_date: 2025-03-14
# .. toggle_target_removal_date: 2025-09-14
# .. toggle_tickets: https://github.com/openedx/edx-platform/issues/36275
# .. toggle_warning: In Ulmo, this toggle will be removed. Only the new (React-based) experience will be available.
LEGACY_STUDIO_PROBLEM_EDITOR = CourseWaffleFlag('legacy_studio.problem_editor', __name__)


def use_new_problem_editor(course_key):
"""
Returns a boolean if new problem editor is enabled
"""
return not LEGACY_STUDIO_PROBLEM_EDITOR.is_enabled(course_key)


# .. toggle_name: contentstore.individualize_anonymous_user_id
# .. toggle_implementation: CourseWaffleFlag
# .. toggle_default: False
Expand Down
7 changes: 3 additions & 4 deletions cms/djangoapps/contentstore/views/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
from cms.djangoapps.contentstore.toggles import (
libraries_v1_enabled,
libraries_v2_enabled,
use_new_problem_editor,
use_new_unit_page,
)
from cms.djangoapps.contentstore.xblock_storage_handlers.view_handlers import load_services_for_studio
Expand Down Expand Up @@ -368,16 +367,16 @@ def create_support_legend_dict():
)
)

#If using new problem editor, we select problem type inside the editor
# If using new problem editor, we select problem type inside the editor
# because of this, we only show one problem.
if category == 'problem' and use_new_problem_editor(courselike.context_key):
if category == 'problem':
templates_for_category = [
template for template in templates_for_category if template['boilerplate_name'] == 'blank_common.yaml'
]

# Add any advanced problem types. Note that these are different xblocks being stored as Advanced Problems,
# currently not supported in libraries .
if category == 'problem' and not library and not use_new_problem_editor(courselike.context_key):
if category == 'problem' and not library:
disabled_block_names = [block.name for block in disabled_xblocks()]
advanced_problem_types = [advanced_problem_type for advanced_problem_type in ADVANCED_PROBLEM_TYPES
if advanced_problem_type['component'] not in disabled_block_names]
Expand Down
107 changes: 1 addition & 106 deletions cms/djangoapps/contentstore/views/tests/test_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from django.test.client import RequestFactory
from django.urls import reverse
from django.test.utils import override_settings
from edx_toggles.toggles.testutils import override_waffle_flag
from openedx.core.djangoapps.video_config.toggles import PUBLIC_VIDEO_SHARE
from openedx_events.content_authoring.data import DuplicatedXBlockData
from openedx_events.content_authoring.signals import XBLOCK_DUPLICATED
Expand All @@ -23,7 +22,6 @@
from opaque_keys.edx.asides import AsideUsageKeyV2
from opaque_keys.edx.keys import CourseKey, UsageKey
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from pyquery import PyQuery
from pytz import UTC
from bs4 import BeautifulSoup
from web_fragments.fragment import Fragment
Expand Down Expand Up @@ -57,7 +55,6 @@
from xmodule.partitions.tests.test_partitions import MockPartitionService
from xmodule.x_module import STUDENT_VIEW, STUDIO_VIEW

from cms.djangoapps.contentstore import toggles
from cms.djangoapps.contentstore.tests.utils import CourseTestCase
from cms.djangoapps.contentstore.utils import (
reverse_course_url,
Expand Down Expand Up @@ -229,7 +226,6 @@ def test_get_container_fragment(self):
resp = self.create_xblock(
parent_usage_key=child_vertical_usage_key,
category="problem",
boilerplate="multiplechoice.yaml",
)
self.assertEqual(resp.status_code, 200)

Expand Down Expand Up @@ -258,7 +254,6 @@ def test_get_container_nested_container_fragment(self):
resp = self.create_xblock(
parent_usage_key=wrapper_usage_key,
category="problem",
boilerplate="multiplechoice.yaml",
)
self.assertEqual(resp.status_code, 200)

Expand Down Expand Up @@ -286,7 +281,6 @@ def test_tag_count_in_container_fragment(self, mock_get_object_tag_counts):
resp = self.create_xblock(
parent_usage_key=child_vertical_usage_key,
category="problem",
boilerplate="multiplechoice.yaml",
)
self.assertEqual(resp.status_code, 200)
usage_key = self.response_usage_key(resp)
Expand All @@ -311,18 +305,13 @@ def test_split_test(self):
resp = self.create_xblock(
parent_usage_key=split_test_usage_key,
category="html",
boilerplate="announcement.yaml",
)
self.assertEqual(resp.status_code, 200)
resp = self.create_xblock(
parent_usage_key=split_test_usage_key,
category="html",
boilerplate="latex_html.yaml",
)
self.assertEqual(resp.status_code, 200)
html, __ = self._get_container_preview(split_test_usage_key)
self.assertIn("Announcement", html)
self.assertIn("LaTeX", html)

def test_split_test_edited(self):
"""
Expand Down Expand Up @@ -608,33 +597,12 @@ def test_create_nicely(self):
course = self.get_item_from_modulestore(self.usage_key)
self.assertIn(chap_usage_key, course.children)

# use default display name
resp = self.create_xblock(parent_usage_key=chap_usage_key, category="vertical")
vert_usage_key = self.response_usage_key(resp)

# create problem w/ boilerplate
template_id = "multiplechoice.yaml"
resp = self.create_xblock(
parent_usage_key=vert_usage_key, category="problem", boilerplate=template_id
)
prob_usage_key = self.response_usage_key(resp)
problem = self.get_item_from_modulestore(prob_usage_key)
# check against the template
course = CourseFactory.create()
problem_block = BlockFactory.create(category="problem", parent_location=course.location)
template = problem_block.get_template(template_id)
self.assertEqual(problem.data, template["data"])
self.assertEqual(problem.display_name, template["metadata"]["display_name"])
self.assertEqual(problem.markdown, template["metadata"]["markdown"])

def test_create_block_negative(self):
"""
Negative tests for create_item
"""
# non-existent boilerplate: creates a default
resp = self.create_xblock(
category="problem", boilerplate="nosuchboilerplate.yaml"
)
resp = self.create_xblock(category="problem")
self.assertEqual(resp.status_code, 200)

def test_create_with_future_date(self):
Expand Down Expand Up @@ -836,7 +804,6 @@ def setUp(self):
resp = self.create_xblock(
parent_usage_key=self.vert_usage_key,
category="problem",
boilerplate="multiplechoice.yaml",
)
self.problem_usage_key = self.response_usage_key(resp)

Expand Down Expand Up @@ -936,19 +903,6 @@ def verify_name(
self.assertEqual(duplicated_item.display_name, expected_name)
return usage_key

# Display name comes from template.
dupe_usage_key = verify_name(
self.problem_usage_key,
self.vert_usage_key,
"Duplicate of 'Multiple Choice'",
)
# Test dupe of dupe.
verify_name(
dupe_usage_key,
self.vert_usage_key,
"Duplicate of 'Duplicate of 'Multiple Choice''",
)

# Uses default display_name of 'Text' from HTML component.
verify_name(self.html_usage_key, self.vert_usage_key, "Duplicate of 'Text'")

Expand Down Expand Up @@ -1847,7 +1801,6 @@ def setUp(self):
resp = self.create_xblock(
parent_usage_key=self.seq_usage_key,
category="problem",
boilerplate="multiplechoice.yaml",
)
self.problem_usage_key = self.response_usage_key(resp)

Expand Down Expand Up @@ -1930,11 +1883,9 @@ def setUp(self):
self.seq2_update_url = reverse_usage_url("xblock_handler", self.seq2_usage_key)

# create problem w/ boilerplate
template_id = "multiplechoice.yaml"
resp = self.create_xblock(
parent_usage_key=self.seq_usage_key,
category="problem",
boilerplate=template_id,
)
self.problem_usage_key = self.response_usage_key(resp)
self.problem_update_url = reverse_usage_url(
Expand Down Expand Up @@ -1965,19 +1916,6 @@ def test_delete_field(self):
problem = self.get_item_from_modulestore(self.problem_usage_key)
self.assertEqual(problem.rerandomize, 'never')

def test_null_field(self):
"""
Sending null in for a field 'deletes' it
"""
problem = self.get_item_from_modulestore(self.problem_usage_key)
self.assertIsNotNone(problem.markdown)
self.client.ajax_post(
self.problem_update_url,
data={'nullout': ['markdown']}
)
problem = self.get_item_from_modulestore(self.problem_usage_key)
self.assertIsNone(problem.markdown)

def test_date_fields(self):
"""
Test setting due & start dates on sequential
Expand Down Expand Up @@ -2427,28 +2365,6 @@ def test_field_value_errors(self):
) # See xmodule/fields.py


class TestEditItemSplitMongo(TestEditItemSetup):
"""
Tests for EditItem running on top of the SplitMongoModuleStore.
"""

def test_editing_view_wrappers(self):
"""
Verify that the editing view only generates a single wrapper, no matter how many times it's loaded

Exposes: PLAT-417
"""
view_url = reverse_usage_url(
"xblock_view_handler", self.problem_usage_key, {"view_name": STUDIO_VIEW}
)

for __ in range(3):
resp = self.client.get(view_url, HTTP_ACCEPT="application/json")
self.assertEqual(resp.status_code, 200)
content = json.loads(resp.content.decode("utf-8"))
self.assertEqual(len(PyQuery(content["html"])(f".xblock-{STUDIO_VIEW}")), 1)


class TestEditSplitModule(ItemTest):
"""
Tests around editing instances of the split_test block.
Expand Down Expand Up @@ -2864,7 +2780,6 @@ def get_usage_key():
assert mocked_get_aside_from_xblock.called is is_get_aside_called


@override_waffle_flag(toggles.LEGACY_STUDIO_PROBLEM_EDITOR, True)
class TestComponentTemplates(CourseTestCase):
"""
Unit tests for the generation of the component templates for a course.
Expand Down Expand Up @@ -3012,12 +2927,6 @@ def test_basic_components_support_levels(self):
self.course.allow_unsupported_xblocks = True
self.templates = get_component_templates(self.course)
self._verify_basic_component("video", "Video", "us")
problem_templates = self.get_templates_of_type("problem")
problem_no_boilerplate = self.get_template(
problem_templates, "Blank Problem"
)
self.assertIsNotNone(problem_no_boilerplate)
self.assertEqual("us", problem_no_boilerplate["support_level"])

# Now fully disable video through XBlockConfiguration
XBlockConfiguration.objects.create(name="video", enabled=False)
Expand Down Expand Up @@ -3061,20 +2970,6 @@ def test_advanced_components(self):
self.templates = get_component_templates(self.course)
self.assertTrue((not any(item.get("category") == "done" for item in self.get_templates_of_type("advanced"))))

def test_advanced_problems(self):
"""
Test the handling of advanced problem templates.
"""
problem_templates = self.get_templates_of_type("problem")
circuit_template = self.get_template(
problem_templates, "Circuit Schematic Builder"
)
self.assertIsNotNone(circuit_template)
self.assertEqual(circuit_template.get("category"), "problem")
self.assertEqual(
circuit_template.get("boilerplate_name"), "circuitschematic.yaml"
)

def test_deprecated_no_advance_component_button(self):
"""
Test that there will be no `Advanced` button on unit page if xblocks have disabled
Expand Down
34 changes: 1 addition & 33 deletions cms/static/js/spec/models/component_template_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,9 @@ define(['js/models/component_template'],
var mockTemplateJSON = {
templates: [
{
category: 'problem',
boilerplate_name: 'formularesponse.yaml',
display_name: 'Math Expression Input'
}, {
category: 'problem',
boilerplate_name: null,
display_name: 'Blank Advanced Problem'
}, {
category: 'problem',
boilerplate_name: 'checkboxes.yaml',
display_name: 'Checkboxes'
}, {
category: 'problem',
boilerplate_name: 'multiple_choice.yaml',
display_name: 'Multiple Choice'
}, {
category: 'problem',
boilerplate_name: 'drag_and_drop.yaml',
display_name: 'Drag and Drop'
}, {
category: 'problem',
boilerplate_name: 'problem_with_hint.yaml',
display_name: 'Problem with Adaptive Hint'
}, {
category: 'problem',
boilerplate_name: 'imageresponse.yaml',
display_name: 'Image Mapped Input'
}, {
category: 'openassessment',
boilerplate_name: null,
display_name: 'Peer Assessment'
}, {
category: 'problem',
boilerplate_name: 'an_easy_problem.yaml',
display_name: 'An Easy Problem'
}, {
category: 'word_cloud',
boilerplate_name: null,
Expand Down Expand Up @@ -69,7 +37,7 @@ define(['js/models/component_template'],
} else {
// If the first template is blank, make sure that it has the correct category
if (!template.boilerplate_name) {
expect(template.category).toBe('problem');
expect(template.category).toBe('openassessment');
}
lastTemplate = template;
}
Expand Down
Loading
Loading