add ability to delete published orphans from courses (PLAT-832)
fix quality violations create child parent mapping to avoid potential performance hit when deleting items
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
import ddt
|
||||
from django.core.management import call_command
|
||||
from contentstore.tests.test_orphan import TestOrphanBase
|
||||
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
|
||||
|
||||
@@ -42,3 +44,68 @@ class TestDeleteOrphan(TestOrphanBase):
|
||||
self.assertFalse(self.store.has_item(course.id.make_usage_key('vertical', 'OrphanVert')))
|
||||
self.assertFalse(self.store.has_item(course.id.make_usage_key('chapter', 'OrphanChapter')))
|
||||
self.assertFalse(self.store.has_item(course.id.make_usage_key('html', 'OrphanHtml')))
|
||||
|
||||
def test_delete_orphans_published_branch_split(self):
|
||||
"""
|
||||
Tests that if there are orphans only on the published branch,
|
||||
running delete orphans with a course key that specifies
|
||||
the published branch will delete the published orphan
|
||||
"""
|
||||
course, orphan = self.create_split_course_with_published_orphan()
|
||||
published_branch = course.id.for_branch(ModuleStoreEnum.BranchName.published)
|
||||
|
||||
items_in_published = self.store.get_items(published_branch)
|
||||
items_in_draft_preferred = self.store.get_items(course.id)
|
||||
|
||||
# call delete orphans, specifying the published branch
|
||||
# of the course
|
||||
call_command('delete_orphans', unicode(published_branch), 'commit')
|
||||
|
||||
# now all orphans should be deleted
|
||||
self.assertOrphanCount(course.id, 0)
|
||||
self.assertOrphanCount(published_branch, 0)
|
||||
self.assertNotIn(orphan, self.store.get_items(published_branch))
|
||||
# we should have one fewer item in the published branch of the course
|
||||
self.assertEqual(
|
||||
len(items_in_published) - 1,
|
||||
len(self.store.get_items(published_branch)),
|
||||
)
|
||||
# and the same amount of items in the draft branch of the course
|
||||
self.assertEqual(
|
||||
len(items_in_draft_preferred),
|
||||
len(self.store.get_items(course.id)),
|
||||
)
|
||||
|
||||
def create_split_course_with_published_orphan(self):
|
||||
"""
|
||||
Helper to create a split course with a published orphan
|
||||
"""
|
||||
course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split)
|
||||
# create an orphan
|
||||
orphan = self.store.create_item(
|
||||
self.user.id, course.id, 'html', "PublishedOnlyOrphan"
|
||||
)
|
||||
self.store.publish(orphan.location, self.user.id)
|
||||
|
||||
# grab the published branch of the course
|
||||
published_branch = course.id.for_branch(
|
||||
ModuleStoreEnum.BranchName.published
|
||||
)
|
||||
|
||||
# assert that this orphan is present in both branches
|
||||
self.assertOrphanCount(course.id, 1)
|
||||
self.assertOrphanCount(published_branch, 1)
|
||||
|
||||
# delete this orphan from the draft branch without
|
||||
# auto-publishing this change to the published branch
|
||||
self.store.delete_item(
|
||||
orphan.location, self.user.id, skip_auto_publish=True
|
||||
)
|
||||
|
||||
# now there should be no orphans in the draft branch, but
|
||||
# there should be one in published
|
||||
self.assertOrphanCount(course.id, 0)
|
||||
self.assertOrphanCount(published_branch, 1)
|
||||
self.assertIn(orphan, self.store.get_items(published_branch))
|
||||
|
||||
return course, orphan
|
||||
|
||||
@@ -16,7 +16,7 @@ class TestFixNotFound(ModuleStoreTestCase):
|
||||
"""
|
||||
The management command doesn't work on non split courses
|
||||
"""
|
||||
course = CourseFactory(default_store=ModuleStoreEnum.Type.mongo)
|
||||
course = CourseFactory.create(default_store=ModuleStoreEnum.Type.mongo)
|
||||
with self.assertRaises(SystemExit):
|
||||
call_command("fix_not_found", unicode(course.id))
|
||||
|
||||
|
||||
@@ -60,6 +60,13 @@ class TestOrphanBase(CourseTestCase):
|
||||
|
||||
return course
|
||||
|
||||
def assertOrphanCount(self, course_key, number):
|
||||
"""
|
||||
Asserts that we have the expected count of orphans
|
||||
for a given course_key
|
||||
"""
|
||||
self.assertEqual(len(self.store.get_orphans(course_key)), number)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestOrphan(TestOrphanBase):
|
||||
|
||||
@@ -702,10 +702,14 @@ def _delete_orphans(course_usage_key, user_id, commit=False):
|
||||
"""
|
||||
store = modulestore()
|
||||
items = store.get_orphans(course_usage_key)
|
||||
branch = course_usage_key.branch
|
||||
if commit:
|
||||
for itemloc in items:
|
||||
# need to delete all versions
|
||||
store.delete_item(itemloc, user_id, revision=ModuleStoreEnum.RevisionOption.all)
|
||||
revision = ModuleStoreEnum.RevisionOption.all
|
||||
# specify branches when deleting orphans
|
||||
if branch == ModuleStoreEnum.BranchName.published:
|
||||
revision = ModuleStoreEnum.RevisionOption.published_only
|
||||
store.delete_item(itemloc, user_id, revision=revision)
|
||||
return [unicode(item) for item in items]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user