Skip to content

Commit 6124695

Browse files
kdmccormickfeanil
andcommitted
refactor: Remove broken Force-Publish UI from Studio
Co-Authored-By: Feanil Patel <[email protected]>
1 parent 569c2d9 commit 6124695

File tree

6 files changed

+1
-355
lines changed

6 files changed

+1
-355
lines changed

cms/djangoapps/maintenance/tests.py

Lines changed: 1 addition & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,15 @@
33
"""
44

55

6-
import json
7-
86
import ddt
97
from django.conf import settings
108
from django.urls import reverse
119

12-
from cms.djangoapps.contentstore.management.commands.utils import get_course_versions
1310
from common.djangoapps.student.tests.factories import AdminFactory, UserFactory
1411
from openedx.features.announcements.models import Announcement
15-
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
1612
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
17-
from xmodule.modulestore.tests.factories import CourseFactory, BlockFactory # lint-amnesty, pylint: disable=wrong-import-order
1813

19-
from .views import COURSE_KEY_ERROR_MESSAGES, MAINTENANCE_VIEWS
14+
from .views import MAINTENANCE_VIEWS
2015

2116
# This list contains URLs of all maintenance app views.
2217
MAINTENANCE_URLS = [reverse(view['url']) for view in MAINTENANCE_VIEWS.values()]
@@ -122,118 +117,6 @@ def test_non_global_staff_access(self, url):
122117
)
123118

124119

125-
@ddt.ddt
126-
class TestForcePublish(MaintenanceViewTestCase):
127-
"""
128-
Tests for the force publish view.
129-
"""
130-
131-
def setUp(self):
132-
super().setUp()
133-
self.view_url = reverse('maintenance:force_publish_course')
134-
135-
def setup_test_course(self):
136-
"""
137-
Creates the course and add some changes to it.
138-
139-
Returns:
140-
course: a course object
141-
"""
142-
course = CourseFactory.create()
143-
# Add some changes to course
144-
chapter = BlockFactory.create(category='chapter', parent_location=course.location)
145-
self.store.create_child(
146-
self.user.id,
147-
chapter.location,
148-
'html',
149-
block_id='html_component'
150-
)
151-
# verify that course has changes.
152-
self.assertTrue(self.store.has_changes(self.store.get_item(course.location)))
153-
return course
154-
155-
@ddt.data(
156-
('', COURSE_KEY_ERROR_MESSAGES['empty_course_key']),
157-
('edx', COURSE_KEY_ERROR_MESSAGES['invalid_course_key']),
158-
('course-v1:e+d+X', COURSE_KEY_ERROR_MESSAGES['course_key_not_found']),
159-
)
160-
@ddt.unpack
161-
def test_invalid_course_key_messages(self, course_key, error_message):
162-
"""
163-
Test all error messages for invalid course keys.
164-
"""
165-
# validate that course key contains error message
166-
self.verify_error_message(
167-
data={'course-id': course_key},
168-
error_message=error_message
169-
)
170-
171-
def test_already_published(self):
172-
"""
173-
Test that when a course is forcefully publish, we get a 'course is already published' message.
174-
"""
175-
course = self.setup_test_course()
176-
177-
# publish the course
178-
source_store = modulestore()._get_modulestore_for_courselike(course.id) # pylint: disable=protected-access
179-
source_store.force_publish_course(course.id, self.user.id, commit=True)
180-
181-
# now course is published, we should get `already published course` error.
182-
self.verify_error_message(
183-
data={'course-id': str(course.id)},
184-
error_message='Course is already in published state.'
185-
)
186-
187-
def verify_versions_are_different(self, course):
188-
"""
189-
Verify draft and published versions point to different locations.
190-
191-
Arguments:
192-
course (object): a course object.
193-
"""
194-
# get draft and publish branch versions
195-
versions = get_course_versions(str(course.id))
196-
197-
# verify that draft and publish point to different versions
198-
self.assertNotEqual(versions['draft-branch'], versions['published-branch'])
199-
200-
def get_force_publish_course_response(self, course):
201-
"""
202-
Get force publish the course response.
203-
204-
Arguments:
205-
course (object): a course object.
206-
207-
Returns:
208-
response : response from force publish post view.
209-
"""
210-
# Verify versions point to different locations initially
211-
self.verify_versions_are_different(course)
212-
213-
# force publish course view
214-
data = {
215-
'course-id': str(course.id)
216-
}
217-
response = self.client.post(self.view_url, data=data, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
218-
response_data = json.loads(response.content.decode('utf-8'))
219-
return response_data
220-
221-
def test_force_publish_dry_run(self):
222-
"""
223-
Test that dry run does not publishes the course but shows possible outcome if force published is executed.
224-
"""
225-
course = self.setup_test_course()
226-
response = self.get_force_publish_course_response(course)
227-
228-
self.assertIn('current_versions', response)
229-
230-
# verify that course still has changes as we just dry ran force publish course.
231-
self.assertTrue(self.store.has_changes(self.store.get_item(course.location)))
232-
233-
# verify that both branch versions are still different
234-
self.verify_versions_are_different(course)
235-
236-
237120
@ddt.ddt
238121
class TestAnnouncementsViews(MaintenanceViewTestCase):
239122
"""

cms/djangoapps/maintenance/urls.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@
99
AnnouncementDeleteView,
1010
AnnouncementEditView,
1111
AnnouncementIndexView,
12-
ForcePublishCourseView,
1312
MaintenanceIndexView
1413
)
1514

1615
app_name = 'cms.djangoapps.maintenance'
1716

1817
urlpatterns = [
1918
path('', MaintenanceIndexView.as_view(), name='maintenance_index'),
20-
re_path(r'^force_publish_course/?$', ForcePublishCourseView.as_view(), name='force_publish_course'),
2119
re_path(r'^announcements/(?P<page>\d+)?$', AnnouncementIndexView.as_view(), name='announcement_index'),
2220
path('announcements/create', AnnouncementCreateView.as_view(), name='announcement_create'),
2321
re_path(r'^announcements/edit/(?P<pk>\d+)?$', AnnouncementEditView.as_view(), name='announcement_edit'),

cms/djangoapps/maintenance/views.py

Lines changed: 0 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,14 @@
66
import logging
77

88
from django.core.validators import ValidationError
9-
from django.db import transaction
109
from django.urls import reverse, reverse_lazy
1110
from django.utils.decorators import method_decorator
1211
from django.utils.translation import gettext as _
1312
from django.views.generic import View
1413
from django.views.generic.edit import CreateView, DeleteView, UpdateView
1514
from django.views.generic.list import ListView
16-
from opaque_keys import InvalidKeyError
1715
from opaque_keys.edx.keys import CourseKey
1816

19-
from cms.djangoapps.contentstore.management.commands.utils import get_course_versions
2017
from common.djangoapps.edxmako.shortcuts import render_to_response
2118
from common.djangoapps.util.json_request import JsonResponse
2219
from common.djangoapps.util.views import require_global_staff
@@ -30,16 +27,6 @@
3027

3128
# This dict maintains all the views that will be used Maintenance app.
3229
MAINTENANCE_VIEWS = {
33-
'force_publish_course': {
34-
'url': 'maintenance:force_publish_course',
35-
'name': _('Force Publish Course'),
36-
'slug': 'force_publish_course',
37-
'description': _(
38-
'Sometimes the draft and published branches of a course can get out of sync. Force publish course command '
39-
'resets the published branch of a course to point to the draft branch, effectively force publishing the '
40-
'course. This view dry runs the force publish command'
41-
),
42-
},
4330
'announcement_index': {
4431
'url': 'maintenance:announcement_index',
4532
'name': _('Edit Announcements'),
@@ -131,104 +118,6 @@ def validate_course_key(self, course_key, branch=ModuleStoreEnum.BranchName.draf
131118
return course_usage_key
132119

133120

134-
class ForcePublishCourseView(MaintenanceBaseView):
135-
"""
136-
View for force publishing state of the course, used by the global staff.
137-
138-
This view uses `force_publish_course` method of modulestore which publishes the draft state of the course. After
139-
the course has been forced published, both draft and publish draft point to same location.
140-
"""
141-
142-
def __init__(self):
143-
super().__init__(MAINTENANCE_VIEWS['force_publish_course'])
144-
self.context.update({
145-
'current_versions': [],
146-
'updated_versions': [],
147-
'form_data': {
148-
'course_id': '',
149-
'is_dry_run': True
150-
}
151-
})
152-
153-
def get_course_branch_versions(self, versions):
154-
"""
155-
Returns a dict containing unicoded values of draft and published draft versions.
156-
"""
157-
return {
158-
'draft-branch': str(versions['draft-branch']),
159-
'published-branch': str(versions['published-branch'])
160-
}
161-
162-
@transaction.atomic
163-
@method_decorator(require_global_staff)
164-
def post(self, request):
165-
"""
166-
This method force publishes a course if dry-run argument is not selected. If dry-run is selected, this view
167-
shows possible outcome if the `force_publish_course` modulestore method is executed.
168-
169-
Arguments:
170-
course_id (string): a request parameter containing course id
171-
is_dry_run (string): a request parameter containing dry run value.
172-
It is obtained from checkbox so it has either values 'on' or ''.
173-
"""
174-
course_id = request.POST.get('course-id')
175-
176-
self.context.update({
177-
'form_data': {
178-
'course_id': course_id
179-
}
180-
})
181-
182-
try:
183-
course_usage_key = self.validate_course_key(course_id)
184-
except InvalidKeyError:
185-
self.context['error'] = True
186-
self.context['msg'] = COURSE_KEY_ERROR_MESSAGES['invalid_course_key']
187-
except ItemNotFoundError as exc:
188-
self.context['error'] = True
189-
self.context['msg'] = str(exc)
190-
except ValidationError as exc:
191-
self.context['error'] = True
192-
self.context['msg'] = str(exc)
193-
194-
if self.context['error']:
195-
return self.render_response()
196-
197-
source_store = modulestore()._get_modulestore_for_courselike(course_usage_key) # pylint: disable=protected-access
198-
if not hasattr(source_store, 'force_publish_course'):
199-
self.context['msg'] = _('Force publishing course is not supported with old mongo courses.')
200-
log.warning(
201-
'Force publishing course is not supported with old mongo courses. \
202-
%s attempted to force publish the course %s.',
203-
request.user,
204-
course_id,
205-
exc_info=True
206-
)
207-
return self.render_response()
208-
209-
current_versions = self.get_course_branch_versions(get_course_versions(course_id))
210-
211-
# if publish and draft are NOT different
212-
if current_versions['published-branch'] == current_versions['draft-branch']:
213-
self.context['msg'] = _('Course is already in published state.')
214-
log.warning(
215-
'Course is already in published state. %s attempted to force publish the course %s.',
216-
request.user,
217-
course_id,
218-
exc_info=True
219-
)
220-
return self.render_response()
221-
222-
self.context['current_versions'] = current_versions
223-
log.info(
224-
'%s dry ran force publish the course %s.',
225-
request.user,
226-
course_id,
227-
exc_info=True
228-
)
229-
return self.render_response()
230-
231-
232121
class AnnouncementBaseView(View):
233122
"""
234123
Base view for Announcements pages

cms/static/js/maintenance/force_publish_course.js

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

0 commit comments

Comments
 (0)