Skip to content

Commit

Permalink
Fix: Allow delete course content in Studio only for admin users (#440)
Browse files Browse the repository at this point in the history
* Fix PREVENT_STAFF_STRUCTURE_DELETION flag for ajax requests

* Add testcase for CourseCreatorRole
  • Loading branch information
joidegn committed Nov 17, 2021
1 parent 46e1a9c commit 3649123
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 9 deletions.
7 changes: 3 additions & 4 deletions cms/djangoapps/contentstore/views/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -1342,10 +1342,9 @@ def create_xblock_info(xblock, data=None, metadata=None, include_ancestor_info=F
else:
xblock_info['staff_only_message'] = False

if user is not None:
xblock_info['show_delete_button'] = user.has_perm(DELETE_COURSE_CONTENT, xblock)
else:
xblock_info['show_delete_button'] = False
xblock_info['show_delete_button'] = True
if PREVENT_STAFF_STRUCTURE_DELETION.is_enabled():
xblock_info['show_delete_button'] = user.has_perm(DELETE_COURSE_CONTENT, xblock) if user is not None else False

xblock_info['has_partition_group_components'] = has_children_visible_to_specific_partition_groups(
xblock
Expand Down
124 changes: 119 additions & 5 deletions cms/djangoapps/contentstore/views/tests/test_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from django.test.client import RequestFactory
from django.urls import reverse
from edx_proctoring.exceptions import ProctoredExamNotFoundException
from edx_toggles.toggles.testutils import override_waffle_switch, override_waffle_flag
from mock import Mock, PropertyMock, patch
from opaque_keys import InvalidKeyError
from opaque_keys.edx.asides import AsideUsageKeyV2
from opaque_keys.edx.keys import CourseKey, UsageKey
Expand All @@ -28,10 +30,12 @@
from xblock.test.tools import TestRuntime
from xblock.validation import ValidationMessage

from cms.djangoapps.contentstore.config.waffle import PREVENT_STAFF_STRUCTURE_DELETION
from cms.djangoapps.contentstore.tests.utils import CourseTestCase
from cms.djangoapps.contentstore.utils import reverse_course_url, reverse_usage_url
from cms.djangoapps.contentstore.views import item as item_module
from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole
from lms.djangoapps.lms_xblock.mixin import NONSENSICAL_ACCESS_RESTRICTION
from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole, CourseCreatorRole
from common.djangoapps.student.tests.factories import UserFactory
from common.djangoapps.xblock_django.models import (
XBlockConfiguration,
Expand Down Expand Up @@ -3427,11 +3431,11 @@ def test_self_paced_item_visibility_state(self, store_type):
xblock_info = self._get_xblock_info(chapter.location)
self._verify_visibility_state(xblock_info, VisibilityState.live)

def test_staff_show_delte_button(self):
def test_staff_show_delete_button(self):
"""
Test delete button is *not visible* to user with CourseStaffRole
"""
# add user as course staff
# Add user as course staff
CourseStaffRole(self.course_key).add_users(self.user)

# Get xblock outline
Expand All @@ -3442,15 +3446,105 @@ def test_staff_show_delte_button(self):
include_children_predicate=lambda xblock: not xblock.category == 'vertical',
user=self.user
)
self.assertTrue(xblock_info['show_delete_button'])

def test_staff_show_delete_button_with_waffle(self):
"""
Test delete button is *not visible* to user with CourseStaffRole and
PREVENT_STAFF_STRUCTURE_DELETION waffle set
"""
# Add user as course staff
CourseStaffRole(self.course_key).add_users(self.user)

with override_waffle_flag(PREVENT_STAFF_STRUCTURE_DELETION, active=True):
# Get xblock outline
xblock_info = create_xblock_info(
self.course,
include_child_info=True,
course_outline=True,
include_children_predicate=lambda xblock: not xblock.category == 'vertical',
user=self.user
)

self.assertFalse(xblock_info['show_delete_button'])

def test_no_user_show_delete_button(self):
"""
Test delete button is *visible* when user attribute is not set on
xblock. This happens with ajax requests.
"""
# Get xblock outline
xblock_info = create_xblock_info(
self.course,
include_child_info=True,
course_outline=True,
include_children_predicate=lambda xblock: not xblock.category == 'vertical',
user=None
)
self.assertTrue(xblock_info['show_delete_button'])

def test_no_user_show_delete_button_with_waffle(self):
"""
Test delete button is *visible* when user attribute is not set on
xblock (this happens with ajax requests) and PREVENT_STAFF_STRUCTURE_DELETION waffle set.
"""

with override_waffle_flag(PREVENT_STAFF_STRUCTURE_DELETION, active=True):
# Get xblock outline
xblock_info = create_xblock_info(
self.course,
include_child_info=True,
course_outline=True,
include_children_predicate=lambda xblock: not xblock.category == 'vertical',
user=None
)

self.assertFalse(xblock_info['show_delete_button'])

def test_instructor_show_delete_button(self):
"""
Test delete button is *visible* to user with CourseCreatorRole only
Test delete button is *visible* to user with CourseInstructorRole only
"""
# Add user as course instructor
CourseInstructorRole(self.course_key).add_users(self.user)

# Get xblock outline
xblock_info = create_xblock_info(
self.course,
include_child_info=True,
course_outline=True,
include_children_predicate=lambda xblock: not xblock.category == 'vertical',
user=self.user
)
self.assertTrue(xblock_info['show_delete_button'])

def test_instructor_show_delete_button_with_waffle(self):
"""
Test delete button is *visible* to user with CourseInstructorRole only
and PREVENT_STAFF_STRUCTURE_DELETION waffle set
"""
# add user as course instructor
# Add user as course instructor
CourseInstructorRole(self.course_key).add_users(self.user)

with override_waffle_flag(PREVENT_STAFF_STRUCTURE_DELETION, active=True):
# Get xblock outline
xblock_info = create_xblock_info(
self.course,
include_child_info=True,
course_outline=True,
include_children_predicate=lambda xblock: not xblock.category == 'vertical',
user=self.user
)

self.assertTrue(xblock_info['show_delete_button'])

def test_creator_show_delete_button(self):
"""
Test delete button is *visible* to user with CourseInstructorRole only
"""
# Add user as course creator
CourseCreatorRole(self.course_key).add_users(self.user)

# Get xblock outline
xblock_info = create_xblock_info(
self.course,
Expand All @@ -3460,3 +3554,23 @@ def test_instructor_show_delete_button(self):
user=self.user
)
self.assertTrue(xblock_info['show_delete_button'])

def test_creator_show_delete_button_with_waffle(self):
"""
Test delete button is *visible* to user with CourseInstructorRole only
and PREVENT_STAFF_STRUCTURE_DELETION waffle set
"""
# Add user as course creator
CourseCreatorRole(self.course_key).add_users(self.user)

with override_waffle_flag(PREVENT_STAFF_STRUCTURE_DELETION, active=True):
# Get xblock outline
xblock_info = create_xblock_info(
self.course,
include_child_info=True,
course_outline=True,
include_children_predicate=lambda xblock: not xblock.category == 'vertical',
user=self.user
)

self.assertFalse(xblock_info['show_delete_button'])

0 comments on commit 3649123

Please sign in to comment.