Skip to content

Commit 474dc71

Browse files
authored
chore: remove legacy problem studio view (#37795)
* fix: remove legacy problem studio view and resource templates
1 parent 0b62835 commit 474dc71

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+12
-4715
lines changed

cms/djangoapps/contentstore/tests/test_contentstore.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,8 +1450,6 @@ def test_capa_block(self):
14501450
problem_loc = UsageKey.from_string(payload['locator'])
14511451
problem = self.store.get_item(problem_loc)
14521452
self.assertIsInstance(problem, ProblemBlock, "New problem is not a ProblemBlock")
1453-
context = problem.get_context()
1454-
self.assertIn('markdown', context, "markdown is missing from context")
14551453
self.assertNotIn('markdown', problem.editable_metadata_fields, "Markdown slipped into the editable metadata fields") # lint-amnesty, pylint: disable=line-too-long
14561454

14571455
def test_cms_imported_course_walkthrough(self):

cms/djangoapps/contentstore/tests/test_crud.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,9 @@ def test_get_templates(self):
2020
self.assertIsNotNone(found.get('course'))
2121
self.assertIsNotNone(found.get('about'))
2222
self.assertIsNotNone(found.get('html'))
23-
self.assertIsNotNone(found.get('problem'))
2423
self.assertEqual(len(found.get('course')), 0)
2524
self.assertEqual(len(found.get('about')), 1)
2625
self.assertGreaterEqual(len(found.get('html')), 2)
27-
self.assertGreaterEqual(len(found.get('problem')), 10)
28-
dropdown = None
29-
for template in found['problem']:
30-
self.assertIn('metadata', template)
31-
self.assertIn('display_name', template['metadata'])
32-
if template['metadata']['display_name'] == 'Dropdown':
33-
dropdown = template
34-
break
35-
self.assertIsNotNone(dropdown)
36-
self.assertIn('markdown', dropdown['metadata'])
37-
self.assertIn('data', dropdown)
38-
self.assertRegex(dropdown['metadata']['markdown'], r'.*dropdown problems.*')
39-
self.assertRegex(dropdown['data'], r'<problem>\s*<optionresponse>\s*<p>.*dropdown problems.*')
4026

4127
def test_get_some_templates(self):
4228
course = CourseFactory.create()

cms/djangoapps/contentstore/toggles.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -123,25 +123,6 @@ def use_video_gallery_flow():
123123
return ENABLE_VIDEO_GALLERY_FLOW_FLAG.is_enabled()
124124

125125

126-
# .. toggle_name: legacy_studio.problem_editor
127-
# .. toggle_implementation: WaffleFlag
128-
# .. toggle_default: False
129-
# .. toggle_description: Temporarily fall back to the old Problem component (a.k.a. CAPA/problem block) editor.
130-
# .. toggle_use_cases: temporary
131-
# .. toggle_creation_date: 2025-03-14
132-
# .. toggle_target_removal_date: 2025-09-14
133-
# .. toggle_tickets: https://github.com/openedx/edx-platform/issues/36275
134-
# .. toggle_warning: In Ulmo, this toggle will be removed. Only the new (React-based) experience will be available.
135-
LEGACY_STUDIO_PROBLEM_EDITOR = CourseWaffleFlag('legacy_studio.problem_editor', __name__)
136-
137-
138-
def use_new_problem_editor(course_key):
139-
"""
140-
Returns a boolean if new problem editor is enabled
141-
"""
142-
return not LEGACY_STUDIO_PROBLEM_EDITOR.is_enabled(course_key)
143-
144-
145126
# .. toggle_name: contentstore.individualize_anonymous_user_id
146127
# .. toggle_implementation: CourseWaffleFlag
147128
# .. toggle_default: False

cms/djangoapps/contentstore/views/component.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
from cms.djangoapps.contentstore.toggles import (
3434
libraries_v1_enabled,
3535
libraries_v2_enabled,
36-
use_new_problem_editor,
3736
use_new_unit_page,
3837
)
3938
from cms.djangoapps.contentstore.xblock_storage_handlers.view_handlers import load_services_for_studio
@@ -368,16 +367,14 @@ def create_support_legend_dict():
368367
)
369368
)
370369

371-
#If using new problem editor, we select problem type inside the editor
372-
# because of this, we only show one problem.
373-
if category == 'problem' and use_new_problem_editor(courselike.context_key):
370+
if category == 'problem':
374371
templates_for_category = [
375372
template for template in templates_for_category if template['boilerplate_name'] == 'blank_common.yaml'
376373
]
377374

378375
# Add any advanced problem types. Note that these are different xblocks being stored as Advanced Problems,
379376
# currently not supported in libraries .
380-
if category == 'problem' and not library and not use_new_problem_editor(courselike.context_key):
377+
if category == 'problem' and not library:
381378
disabled_block_names = [block.name for block in disabled_xblocks()]
382379
advanced_problem_types = [advanced_problem_type for advanced_problem_type in ADVANCED_PROBLEM_TYPES
383380
if advanced_problem_type['component'] not in disabled_block_names]

cms/djangoapps/contentstore/views/tests/test_block.py

Lines changed: 1 addition & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from django.test.client import RequestFactory
1414
from django.urls import reverse
1515
from django.test.utils import override_settings
16-
from edx_toggles.toggles.testutils import override_waffle_flag
1716
from openedx.core.djangoapps.video_config.toggles import PUBLIC_VIDEO_SHARE
1817
from openedx_events.content_authoring.data import DuplicatedXBlockData
1918
from openedx_events.content_authoring.signals import XBLOCK_DUPLICATED
@@ -23,7 +22,6 @@
2322
from opaque_keys.edx.asides import AsideUsageKeyV2
2423
from opaque_keys.edx.keys import CourseKey, UsageKey
2524
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
26-
from pyquery import PyQuery
2725
from pytz import UTC
2826
from bs4 import BeautifulSoup
2927
from web_fragments.fragment import Fragment
@@ -57,7 +55,6 @@
5755
from xmodule.partitions.tests.test_partitions import MockPartitionService
5856
from xmodule.x_module import STUDENT_VIEW, STUDIO_VIEW
5957

60-
from cms.djangoapps.contentstore import toggles
6158
from cms.djangoapps.contentstore.tests.utils import CourseTestCase
6259
from cms.djangoapps.contentstore.utils import (
6360
reverse_course_url,
@@ -229,7 +226,6 @@ def test_get_container_fragment(self):
229226
resp = self.create_xblock(
230227
parent_usage_key=child_vertical_usage_key,
231228
category="problem",
232-
boilerplate="multiplechoice.yaml",
233229
)
234230
self.assertEqual(resp.status_code, 200)
235231

@@ -258,7 +254,6 @@ def test_get_container_nested_container_fragment(self):
258254
resp = self.create_xblock(
259255
parent_usage_key=wrapper_usage_key,
260256
category="problem",
261-
boilerplate="multiplechoice.yaml",
262257
)
263258
self.assertEqual(resp.status_code, 200)
264259

@@ -286,7 +281,6 @@ def test_tag_count_in_container_fragment(self, mock_get_object_tag_counts):
286281
resp = self.create_xblock(
287282
parent_usage_key=child_vertical_usage_key,
288283
category="problem",
289-
boilerplate="multiplechoice.yaml",
290284
)
291285
self.assertEqual(resp.status_code, 200)
292286
usage_key = self.response_usage_key(resp)
@@ -311,18 +305,13 @@ def test_split_test(self):
311305
resp = self.create_xblock(
312306
parent_usage_key=split_test_usage_key,
313307
category="html",
314-
boilerplate="announcement.yaml",
315308
)
316309
self.assertEqual(resp.status_code, 200)
317310
resp = self.create_xblock(
318311
parent_usage_key=split_test_usage_key,
319312
category="html",
320-
boilerplate="latex_html.yaml",
321313
)
322314
self.assertEqual(resp.status_code, 200)
323-
html, __ = self._get_container_preview(split_test_usage_key)
324-
self.assertIn("Announcement", html)
325-
self.assertIn("LaTeX", html)
326315

327316
def test_split_test_edited(self):
328317
"""
@@ -608,33 +597,12 @@ def test_create_nicely(self):
608597
course = self.get_item_from_modulestore(self.usage_key)
609598
self.assertIn(chap_usage_key, course.children)
610599

611-
# use default display name
612-
resp = self.create_xblock(parent_usage_key=chap_usage_key, category="vertical")
613-
vert_usage_key = self.response_usage_key(resp)
614-
615-
# create problem w/ boilerplate
616-
template_id = "multiplechoice.yaml"
617-
resp = self.create_xblock(
618-
parent_usage_key=vert_usage_key, category="problem", boilerplate=template_id
619-
)
620-
prob_usage_key = self.response_usage_key(resp)
621-
problem = self.get_item_from_modulestore(prob_usage_key)
622-
# check against the template
623-
course = CourseFactory.create()
624-
problem_block = BlockFactory.create(category="problem", parent_location=course.location)
625-
template = problem_block.get_template(template_id)
626-
self.assertEqual(problem.data, template["data"])
627-
self.assertEqual(problem.display_name, template["metadata"]["display_name"])
628-
self.assertEqual(problem.markdown, template["metadata"]["markdown"])
629-
630600
def test_create_block_negative(self):
631601
"""
632602
Negative tests for create_item
633603
"""
634604
# non-existent boilerplate: creates a default
635-
resp = self.create_xblock(
636-
category="problem", boilerplate="nosuchboilerplate.yaml"
637-
)
605+
resp = self.create_xblock(category="problem")
638606
self.assertEqual(resp.status_code, 200)
639607

640608
def test_create_with_future_date(self):
@@ -836,7 +804,6 @@ def setUp(self):
836804
resp = self.create_xblock(
837805
parent_usage_key=self.vert_usage_key,
838806
category="problem",
839-
boilerplate="multiplechoice.yaml",
840807
)
841808
self.problem_usage_key = self.response_usage_key(resp)
842809

@@ -936,19 +903,6 @@ def verify_name(
936903
self.assertEqual(duplicated_item.display_name, expected_name)
937904
return usage_key
938905

939-
# Display name comes from template.
940-
dupe_usage_key = verify_name(
941-
self.problem_usage_key,
942-
self.vert_usage_key,
943-
"Duplicate of 'Multiple Choice'",
944-
)
945-
# Test dupe of dupe.
946-
verify_name(
947-
dupe_usage_key,
948-
self.vert_usage_key,
949-
"Duplicate of 'Duplicate of 'Multiple Choice''",
950-
)
951-
952906
# Uses default display_name of 'Text' from HTML component.
953907
verify_name(self.html_usage_key, self.vert_usage_key, "Duplicate of 'Text'")
954908

@@ -1847,7 +1801,6 @@ def setUp(self):
18471801
resp = self.create_xblock(
18481802
parent_usage_key=self.seq_usage_key,
18491803
category="problem",
1850-
boilerplate="multiplechoice.yaml",
18511804
)
18521805
self.problem_usage_key = self.response_usage_key(resp)
18531806

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

19321885
# create problem w/ boilerplate
1933-
template_id = "multiplechoice.yaml"
19341886
resp = self.create_xblock(
19351887
parent_usage_key=self.seq_usage_key,
19361888
category="problem",
1937-
boilerplate=template_id,
19381889
)
19391890
self.problem_usage_key = self.response_usage_key(resp)
19401891
self.problem_update_url = reverse_usage_url(
@@ -1965,19 +1916,6 @@ def test_delete_field(self):
19651916
problem = self.get_item_from_modulestore(self.problem_usage_key)
19661917
self.assertEqual(problem.rerandomize, 'never')
19671918

1968-
def test_null_field(self):
1969-
"""
1970-
Sending null in for a field 'deletes' it
1971-
"""
1972-
problem = self.get_item_from_modulestore(self.problem_usage_key)
1973-
self.assertIsNotNone(problem.markdown)
1974-
self.client.ajax_post(
1975-
self.problem_update_url,
1976-
data={'nullout': ['markdown']}
1977-
)
1978-
problem = self.get_item_from_modulestore(self.problem_usage_key)
1979-
self.assertIsNone(problem.markdown)
1980-
19811919
def test_date_fields(self):
19821920
"""
19831921
Test setting due & start dates on sequential
@@ -2427,28 +2365,6 @@ def test_field_value_errors(self):
24272365
) # See xmodule/fields.py
24282366

24292367

2430-
class TestEditItemSplitMongo(TestEditItemSetup):
2431-
"""
2432-
Tests for EditItem running on top of the SplitMongoModuleStore.
2433-
"""
2434-
2435-
def test_editing_view_wrappers(self):
2436-
"""
2437-
Verify that the editing view only generates a single wrapper, no matter how many times it's loaded
2438-
2439-
Exposes: PLAT-417
2440-
"""
2441-
view_url = reverse_usage_url(
2442-
"xblock_view_handler", self.problem_usage_key, {"view_name": STUDIO_VIEW}
2443-
)
2444-
2445-
for __ in range(3):
2446-
resp = self.client.get(view_url, HTTP_ACCEPT="application/json")
2447-
self.assertEqual(resp.status_code, 200)
2448-
content = json.loads(resp.content.decode("utf-8"))
2449-
self.assertEqual(len(PyQuery(content["html"])(f".xblock-{STUDIO_VIEW}")), 1)
2450-
2451-
24522368
class TestEditSplitModule(ItemTest):
24532369
"""
24542370
Tests around editing instances of the split_test block.
@@ -2864,7 +2780,6 @@ def get_usage_key():
28642780
assert mocked_get_aside_from_xblock.called is is_get_aside_called
28652781

28662782

2867-
@override_waffle_flag(toggles.LEGACY_STUDIO_PROBLEM_EDITOR, True)
28682783
class TestComponentTemplates(CourseTestCase):
28692784
"""
28702785
Unit tests for the generation of the component templates for a course.
@@ -3012,12 +2927,6 @@ def test_basic_components_support_levels(self):
30122927
self.course.allow_unsupported_xblocks = True
30132928
self.templates = get_component_templates(self.course)
30142929
self._verify_basic_component("video", "Video", "us")
3015-
problem_templates = self.get_templates_of_type("problem")
3016-
problem_no_boilerplate = self.get_template(
3017-
problem_templates, "Blank Problem"
3018-
)
3019-
self.assertIsNotNone(problem_no_boilerplate)
3020-
self.assertEqual("us", problem_no_boilerplate["support_level"])
30212930

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

3064-
def test_advanced_problems(self):
3065-
"""
3066-
Test the handling of advanced problem templates.
3067-
"""
3068-
problem_templates = self.get_templates_of_type("problem")
3069-
circuit_template = self.get_template(
3070-
problem_templates, "Circuit Schematic Builder"
3071-
)
3072-
self.assertIsNotNone(circuit_template)
3073-
self.assertEqual(circuit_template.get("category"), "problem")
3074-
self.assertEqual(
3075-
circuit_template.get("boilerplate_name"), "circuitschematic.yaml"
3076-
)
3077-
30782973
def test_deprecated_no_advance_component_button(self):
30792974
"""
30802975
Test that there will be no `Advanced` button on unit page if xblocks have disabled

cms/static/js/spec/models/component_template_spec.js

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,9 @@ define(['js/models/component_template'],
44
var mockTemplateJSON = {
55
templates: [
66
{
7-
category: 'problem',
8-
boilerplate_name: 'formularesponse.yaml',
9-
display_name: 'Math Expression Input'
10-
}, {
11-
category: 'problem',
12-
boilerplate_name: null,
13-
display_name: 'Blank Advanced Problem'
14-
}, {
15-
category: 'problem',
16-
boilerplate_name: 'checkboxes.yaml',
17-
display_name: 'Checkboxes'
18-
}, {
19-
category: 'problem',
20-
boilerplate_name: 'multiple_choice.yaml',
21-
display_name: 'Multiple Choice'
22-
}, {
23-
category: 'problem',
24-
boilerplate_name: 'drag_and_drop.yaml',
25-
display_name: 'Drag and Drop'
26-
}, {
27-
category: 'problem',
28-
boilerplate_name: 'problem_with_hint.yaml',
29-
display_name: 'Problem with Adaptive Hint'
30-
}, {
31-
category: 'problem',
32-
boilerplate_name: 'imageresponse.yaml',
33-
display_name: 'Image Mapped Input'
34-
}, {
357
category: 'openassessment',
368
boilerplate_name: null,
379
display_name: 'Peer Assessment'
38-
}, {
39-
category: 'problem',
40-
boilerplate_name: 'an_easy_problem.yaml',
41-
display_name: 'An Easy Problem'
4210
}, {
4311
category: 'word_cloud',
4412
boilerplate_name: null,
@@ -69,7 +37,7 @@ define(['js/models/component_template'],
6937
} else {
7038
// If the first template is blank, make sure that it has the correct category
7139
if (!template.boilerplate_name) {
72-
expect(template.category).toBe('problem');
40+
expect(template.category).toBe('openassessment');
7341
}
7442
lastTemplate = template;
7543
}

0 commit comments

Comments
 (0)