Skip to content

Commit a2b2405

Browse files
Merge pull request #38422 from openedx/iahmad/DEPR-36108-certificates
feat: Drop support for the legacy Certificates page.
2 parents f4a40dc + 7aaeef3 commit a2b2405

38 files changed

Lines changed: 17 additions & 3218 deletions

cms/djangoapps/contentstore/rest_api/v1/serializers/course_waffle_flags.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,7 @@ def get_use_new_certificates_page(self, obj):
177177
"""
178178
Method to get the use_new_certificates_page switch
179179
"""
180-
course_key = self.get_course_key()
181-
return toggles.use_new_certificates_page(course_key)
180+
return True
182181

183182
def get_use_new_textbooks_page(self, obj):
184183
"""

cms/djangoapps/contentstore/toggles.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -290,24 +290,6 @@ def use_new_course_team_page(course_key):
290290
return not LEGACY_STUDIO_COURSE_TEAM.is_enabled(course_key)
291291

292292

293-
# .. toggle_name: legacy_studio.certificates
294-
# .. toggle_implementation: WaffleFlag
295-
# .. toggle_default: False
296-
# .. toggle_description: Temporarily fall back to the old Studio Course Certificates page.
297-
# .. toggle_use_cases: temporary
298-
# .. toggle_creation_date: 2025-03-14
299-
# .. toggle_target_removal_date: 2025-09-14
300-
# .. toggle_tickets: https://github.com/openedx/edx-platform/issues/36275
301-
# .. toggle_warning: In Ulmo, this toggle will be removed. Only the new (React-based) experience will be available.
302-
LEGACY_STUDIO_CERTIFICATES = CourseWaffleFlag('legacy_studio.certificates', __name__)
303-
304-
305-
def use_new_certificates_page(course_key):
306-
"""
307-
Returns a boolean if new studio certificates mfe is enabled
308-
"""
309-
return not LEGACY_STUDIO_CERTIFICATES.is_enabled(course_key)
310-
311293

312294
# .. toggle_name: legacy_studio.configurations
313295
# .. toggle_implementation: WaffleFlag

cms/djangoapps/contentstore/utils.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
libraries_v2_enabled,
4343
split_library_view_on_dashboard,
4444
use_new_advanced_settings_page,
45-
use_new_certificates_page,
4645
use_new_course_team_page,
4746
use_new_export_page,
4847
use_new_group_configurations_page,
@@ -462,13 +461,10 @@ def get_certificates_url(course_locator) -> str:
462461
"""
463462
Gets course authoring microfrontend URL for certificates page view.
464463
"""
465-
certificates_url = None
466-
if use_new_certificates_page(course_locator):
467-
mfe_base_url = get_course_authoring_url(course_locator)
468-
course_mfe_url = f'{mfe_base_url}/course/{course_locator}/certificates'
469-
if mfe_base_url:
470-
certificates_url = course_mfe_url
471-
return certificates_url
464+
mfe_base_url = get_course_authoring_url(course_locator)
465+
if mfe_base_url:
466+
return f'{mfe_base_url}/course/{course_locator}/certificates'
467+
return None
472468

473469

474470
def get_textbooks_url(course_locator) -> str:

cms/djangoapps/contentstore/views/certificates.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,14 @@
4141

4242
from cms.djangoapps.contentstore.views.permissions import HasStudioWriteAccess
4343
from cms.djangoapps.contentstore.views.serializers import CertificateActivationSerializer, CertificateSerializer
44-
from common.djangoapps.edxmako.shortcuts import render_to_response
4544
from common.djangoapps.student.auth import has_studio_write_access
4645
from common.djangoapps.student.roles import GlobalStaff
4746
from common.djangoapps.util.json_request import JsonResponse
4847
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
4948
from xmodule.modulestore import EdxJSONEncoder # pylint: disable=wrong-import-order
5049
from xmodule.modulestore.django import modulestore # pylint: disable=wrong-import-order
5150

52-
from ..toggles import use_new_certificates_page
53-
from ..utils import get_certificates_context, get_certificates_url, reverse_course_url
51+
from ..utils import get_certificates_url, reverse_course_url
5452
from .certificate_manager import CertificateManager, CertificateValidationError
5553

5654
CERTIFICATE_MINIMUM_ID = 100
@@ -143,10 +141,7 @@ def certificates_list_handler(request, course_key_string):
143141
return JsonResponse({"error": msg}, status=403)
144142

145143
if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'):
146-
if use_new_certificates_page(course_key):
147-
return redirect(get_certificates_url(course_key))
148-
certificates_context = get_certificates_context(course, request.user)
149-
return render_to_response('certificates.html', certificates_context)
144+
return redirect(get_certificates_url(course_key))
150145
elif "application/json" in request.META.get('HTTP_ACCEPT'):
151146
# Retrieve the list of certificates for the specified course
152147
if request.method == 'GET':

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

Lines changed: 1 addition & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55

66
import itertools
77
import json
8-
from unittest import mock
98

109
import ddt
1110
from django.conf import settings
1211
from django.test.utils import override_settings
13-
from edx_toggles.toggles.testutils import override_waffle_flag
1412
from opaque_keys.edx.keys import AssetKey
1513

16-
from cms.djangoapps.contentstore import toggles
1714
from cms.djangoapps.contentstore.tests.utils import CourseTestCase
1815
from cms.djangoapps.contentstore.utils import get_lms_link_for_certificate_web_view, reverse_course_url
1916
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
@@ -277,11 +274,9 @@ def test_lms_link_for_certificate_web_view(self):
277274
)
278275
self.assertEqual(link, test_url) # noqa: PT009
279276

280-
@override_waffle_flag(toggles.LEGACY_STUDIO_CERTIFICATES, True)
281-
@mock.patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True})
282277
def test_certificate_info_in_response(self):
283278
"""
284-
Test that certificate has been created and rendered properly with non-audit course mode.
279+
Test that a created certificate is returned in the JSON GET response.
285280
"""
286281
CourseModeFactory.create(course_id=self.course.id, mode_slug='verified')
287282
response = self.client.ajax_post(
@@ -291,36 +286,13 @@ def test_certificate_info_in_response(self):
291286

292287
self.assertEqual(response.status_code, 201) # noqa: PT009
293288

294-
# in html response
295-
result = self.client.get_html(self._url())
296-
self.assertContains(result, 'Test certificate')
297-
self.assertContains(result, 'Test description')
298-
299-
# in JSON response
300289
response = self.client.get_json(self._url())
301290
data = json.loads(response.content.decode('utf-8'))
302291
self.assertEqual(len(data), 1) # noqa: PT009
303292
self.assertEqual(data[0]['name'], 'Test certificate') # noqa: PT009
304293
self.assertEqual(data[0]['description'], 'Test description') # noqa: PT009
305294
self.assertEqual(data[0]['version'], CERTIFICATE_SCHEMA_VERSION) # noqa: PT009
306295

307-
@mock.patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True})
308-
@override_waffle_flag(toggles.LEGACY_STUDIO_CERTIFICATES, True)
309-
def test_certificate_info_not_in_response(self):
310-
"""
311-
Test that certificate has not been rendered audit only course mode.
312-
"""
313-
response = self.client.ajax_post(
314-
self._url(),
315-
data=CERTIFICATE_JSON_WITH_SIGNATORIES
316-
)
317-
318-
self.assertEqual(response.status_code, 201) # noqa: PT009
319-
320-
# in html response
321-
result = self.client.get_html(self._url())
322-
self.assertNotContains(result, 'Test certificate')
323-
324296
def test_unsupported_http_accept_header(self):
325297
"""
326298
Test if not allowed header present in request.
@@ -350,55 +322,6 @@ def test_not_permitted(self):
350322
)
351323
self.assertContains(response, "error", status_code=403)
352324

353-
@override_waffle_flag(toggles.LEGACY_STUDIO_CERTIFICATES, True)
354-
def test_audit_course_mode_is_skipped(self):
355-
"""
356-
Tests audit course mode is skipped when rendering certificates page.
357-
"""
358-
CourseModeFactory.create(course_id=self.course.id)
359-
CourseModeFactory.create(course_id=self.course.id, mode_slug='verified')
360-
response = self.client.get_html(
361-
self._url(),
362-
)
363-
self.assertEqual(response.status_code, 200) # noqa: PT009
364-
self.assertContains(response, 'verified')
365-
self.assertNotContains(response, 'audit')
366-
367-
@override_waffle_flag(toggles.LEGACY_STUDIO_CERTIFICATES, True)
368-
def test_audit_only_disables_cert(self):
369-
"""
370-
Tests audit course mode is skipped when rendering certificates page.
371-
"""
372-
CourseModeFactory.create(course_id=self.course.id, mode_slug='audit')
373-
response = self.client.get_html(
374-
self._url(),
375-
)
376-
self.assertEqual(response.status_code, 200) # noqa: PT009
377-
self.assertContains(response, 'This course does not use a mode that offers certificates.')
378-
self.assertNotContains(response, 'This module is not enabled.')
379-
self.assertNotContains(response, 'Loading')
380-
381-
@ddt.data(
382-
['audit', 'verified'],
383-
['verified'],
384-
['audit', 'verified', 'credit'],
385-
['verified', 'credit'],
386-
['professional']
387-
)
388-
@override_waffle_flag(toggles.LEGACY_STUDIO_CERTIFICATES, True)
389-
def test_non_audit_enables_cert(self, slugs):
390-
"""
391-
Tests audit course mode is skipped when rendering certificates page.
392-
"""
393-
for slug in slugs:
394-
CourseModeFactory.create(course_id=self.course.id, mode_slug=slug)
395-
response = self.client.get_html(
396-
self._url(),
397-
)
398-
self.assertEqual(response.status_code, 200) # noqa: PT009
399-
self.assertNotContains(response, 'This course does not use a mode that offers certificates.')
400-
self.assertNotContains(response, 'This module is not enabled.')
401-
self.assertContains(response, 'Loading')
402325

403326
def test_assign_unique_identifier_to_certificates(self):
404327
"""

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
"ENABLE_PROCTORED_EXAMS": True,
2525
},
2626
)
27-
@override_waffle_flag(toggles.LEGACY_STUDIO_CERTIFICATES, True)
2827
@override_waffle_flag(toggles.LEGACY_STUDIO_CONFIGURATIONS, True)
2928
@override_waffle_flag(toggles.LEGACY_STUDIO_ADVANCED_SETTINGS, True)
3029
@override_settings(COURSE_AUTHORING_MICROFRONTEND_URL='https://mfe.example')
@@ -50,7 +49,6 @@ def _get_exam_settings_alert_text(raw_html_content):
5049

5150
@override_waffle_flag(toggles.LEGACY_STUDIO_EXAM_SETTINGS, True)
5251
@ddt.data(
53-
"certificates_list_handler",
5452
"group_configurations_list_handler",
5553
"advanced_settings_handler"
5654
)
@@ -65,7 +63,6 @@ def test_view_without_exam_settings_enabled(self, handler):
6563
self.assertNotContains(resp, 'Proctored Exam Settings')
6664

6765
@ddt.data(
68-
"certificates_list_handler",
6966
"group_configurations_list_handler",
7067
"advanced_settings_handler"
7168
)
@@ -91,6 +88,12 @@ def test_settings_handler_redirects_to_mfe(self):
9188
resp = self.client.get(url, HTTP_ACCEPT='text/html')
9289
self.assertEqual(resp.status_code, 302) # noqa: PT009
9390

91+
def test_certificates_list_handler_redirects_to_mfe(self):
92+
"""certificates_list_handler redirects to the authoring MFE."""
93+
url = reverse_course_url('certificates_list_handler', self.course.id)
94+
resp = self.client.get(url, HTTP_ACCEPT='text/html')
95+
self.assertEqual(resp.status_code, 302) # noqa: PT009
96+
9497

9598
@override_settings(
9699
PROCTORING_BACKENDS={

cms/static/cms/js/build.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
'js/factories/course_create_rerun',
2323
'js/factories/export',
2424
'js/factories/group_configurations',
25-
'js/certificates/factories/certificates_page_factory',
2625
'js/factories/index',
2726
'js/factories/manage_users',
2827
'js/factories/outline',

cms/static/cms/js/spec/main.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,11 +265,6 @@
265265
'js/spec/views/modals/move_xblock_modal_spec',
266266
'js/spec/views/modals/validation_error_modal_spec',
267267
'js/spec/views/settings/main_spec',
268-
'js/certificates/spec/models/certificate_spec',
269-
'js/certificates/spec/views/certificate_details_spec',
270-
'js/certificates/spec/views/certificate_editor_spec',
271-
'js/certificates/spec/views/certificates_list_spec',
272-
'js/certificates/spec/views/certificate_preview_spec'
273268
];
274269

275270
i = 0;

cms/static/js/certificates/collections/certificates.js

Lines changed: 0 additions & 73 deletions
This file was deleted.

cms/static/js/certificates/collections/signatories.js

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)