diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index 1be328d765..c7c4cd6921 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -1450,8 +1450,6 @@ class ContentStoreTest(ContentStoreTestCase): 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): diff --git a/cms/djangoapps/contentstore/tests/test_crud.py b/cms/djangoapps/contentstore/tests/test_crud.py index 1c1f051524..792d0386ac 100644 --- a/cms/djangoapps/contentstore/tests/test_crud.py +++ b/cms/djangoapps/contentstore/tests/test_crud.py @@ -20,23 +20,9 @@ class TemplateTests(ModuleStoreTestCase): 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'\s*\s*

.*dropdown problems.*') def test_get_some_templates(self): course = CourseFactory.create() diff --git a/cms/djangoapps/contentstore/toggles.py b/cms/djangoapps/contentstore/toggles.py index 1f5924163b..9601d118fc 100644 --- a/cms/djangoapps/contentstore/toggles.py +++ b/cms/djangoapps/contentstore/toggles.py @@ -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 diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py index 34c1f465c5..fbd29a89d1 100644 --- a/cms/djangoapps/contentstore/views/component.py +++ b/cms/djangoapps/contentstore/views/component.py @@ -33,7 +33,6 @@ from cms.djangoapps.contentstore.helpers import ( 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 @@ -368,16 +367,14 @@ def get_component_templates(courselike, library=False): # lint-amnesty, pylint: ) ) - #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] diff --git a/cms/djangoapps/contentstore/views/tests/test_block.py b/cms/djangoapps/contentstore/views/tests/test_block.py index 46c1f83198..846c62d243 100644 --- a/cms/djangoapps/contentstore/views/tests/test_block.py +++ b/cms/djangoapps/contentstore/views/tests/test_block.py @@ -13,7 +13,6 @@ from django.test import TestCase 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 @@ -23,7 +22,6 @@ from opaque_keys import InvalidKeyError 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 @@ -57,7 +55,6 @@ from xmodule.partitions.partitions import ( 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, @@ -229,7 +226,6 @@ class GetItemTest(ItemTest): resp = self.create_xblock( parent_usage_key=child_vertical_usage_key, category="problem", - boilerplate="multiplechoice.yaml", ) self.assertEqual(resp.status_code, 200) @@ -258,7 +254,6 @@ class GetItemTest(ItemTest): resp = self.create_xblock( parent_usage_key=wrapper_usage_key, category="problem", - boilerplate="multiplechoice.yaml", ) self.assertEqual(resp.status_code, 200) @@ -286,7 +281,6 @@ class GetItemTest(ItemTest): 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) @@ -311,18 +305,13 @@ class GetItemTest(ItemTest): 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): """ @@ -608,33 +597,12 @@ class TestCreateItem(ItemTest): 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): @@ -836,7 +804,6 @@ class TestDuplicateItem(ItemTest, DuplicateHelper, OpenEdxEventsTestMixin): 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) @@ -936,19 +903,6 @@ class TestDuplicateItem(ItemTest, DuplicateHelper, OpenEdxEventsTestMixin): 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'") @@ -1847,7 +1801,6 @@ class TestDuplicateItemWithAsides(ItemTest, DuplicateHelper): 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) @@ -1930,11 +1883,9 @@ class TestEditItemSetup(ItemTest): 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( @@ -1965,19 +1916,6 @@ class TestEditItem(TestEditItemSetup): 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 @@ -2427,28 +2365,6 @@ class TestEditItem(TestEditItemSetup): ) # 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. @@ -2864,7 +2780,6 @@ class TestComponentHandler(TestCase): 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. @@ -3012,12 +2927,6 @@ class TestComponentTemplates(CourseTestCase): 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) @@ -3061,20 +2970,6 @@ class TestComponentTemplates(CourseTestCase): 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 diff --git a/cms/static/js/spec/models/component_template_spec.js b/cms/static/js/spec/models/component_template_spec.js index 3bc2226655..d683b5d0f8 100644 --- a/cms/static/js/spec/models/component_template_spec.js +++ b/cms/static/js/spec/models/component_template_spec.js @@ -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, @@ -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; } diff --git a/cms/static/js/views/pages/container.js b/cms/static/js/views/pages/container.js index 1920a61eda..5de1d38e5c 100644 --- a/cms/static/js/views/pages/container.js +++ b/cms/static/js/views/pages/container.js @@ -507,12 +507,11 @@ function($, _, Backbone, gettext, BasePage, const primaryHeader = $(event.target).closest('.xblock-header-primary, .nav-actions'); var useNewVideoEditor = primaryHeader.attr('use-new-editor-video'), - useNewProblemEditor = primaryHeader.attr('use-new-editor-problem'), blockType = primaryHeader.attr('data-block-type'); if((blockType === 'html') || (useNewVideoEditor === 'True' && blockType === 'video') - || (useNewProblemEditor === 'True' && blockType === 'problem') + || (blockType === 'problem') ) { var destinationUrl = primaryHeader.attr('authoring_MFE_base_url') + '/' + blockType @@ -1172,8 +1171,7 @@ function($, _, Backbone, gettext, BasePage, onNewXBlock: function(xblockElement, scrollOffset, is_duplicate, data) { var useNewVideoEditor = this.$('.xblock-header-primary').attr('use-new-editor-video'), - useVideoGalleryFlow = this.$('.xblock-header-primary').attr("use-video-gallery-flow"), - useNewProblemEditor = this.$('.xblock-header-primary').attr('use-new-editor-problem'); + useVideoGalleryFlow = this.$('.xblock-header-primary').attr("use-video-gallery-flow"); // find the block type in the locator if availible if(data.hasOwnProperty('locator')) { @@ -1183,7 +1181,7 @@ function($, _, Backbone, gettext, BasePage, // open mfe editors for new blocks only and not for content imported from libraries if(!data.hasOwnProperty('upstreamRef') && (blockType.includes('html') || (useNewVideoEditor === 'True' && blockType.includes('video')) - || (useNewProblemEditor === 'True' && blockType.includes('problem'))) + || (blockType.includes('problem'))) ){ if (this.options.isIframeEmbed && (this.isSplitTestContentPage || this.isVerticalContentPage)) { return this.postMessageToParent({ diff --git a/cms/templates/container.html b/cms/templates/container.html index 61e52f617a..047578be75 100644 --- a/cms/templates/container.html +++ b/cms/templates/container.html @@ -13,7 +13,7 @@ from django.urls import reverse from django.utils.translation import gettext as _ from cms.djangoapps.contentstore.helpers import xblock_studio_url, xblock_type_display_name -from cms.djangoapps.contentstore.toggles import use_new_problem_editor, use_new_video_editor, use_video_gallery_flow +from cms.djangoapps.contentstore.toggles import use_new_video_editor, use_video_gallery_flow from cms.djangoapps.contentstore.utils import get_editor_page_base_url from openedx.core.djangolib.js_utils import ( dump_js_escaped_json, js_escaped_string @@ -112,7 +112,6 @@ from openedx.core.djangolib.markup import HTML, Text <% use_new_editor_video = use_new_video_editor(xblock_locator.course_key) -use_new_editor_problem = use_new_problem_editor(xblock_locator.course_key) use_new_video_gallery_flow = use_video_gallery_flow() %> @@ -168,7 +167,6 @@ use_new_video_gallery_flow = use_video_gallery_flow()