compute_publish_state -> has_published_version

LMS-11213
This commit is contained in:
Don Mitchell
2014-08-26 15:45:08 -04:00
parent 12e2d442e9
commit ee8fc41b62
10 changed files with 61 additions and 159 deletions

View File

@@ -9,17 +9,14 @@ from django.test.client import Client
from django.contrib.auth.models import User
from xmodule.contentstore.django import contentstore
from xmodule.modulestore import PublishState, ModuleStoreEnum
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.inheritance import own_metadata
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.modulestore.draft_and_published import DIRECT_ONLY_CATEGORIES
from xmodule.modulestore.xml_importer import import_from_xml
from student.models import Registration
from opaque_keys.edx.locations import SlashSeparatedCourseKey, AssetLocation
from contentstore.utils import reverse_url
from xmodule.modulestore.mongo.draft import DraftModuleStore
from xblock.fields import Scope
from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore
@@ -151,16 +148,16 @@ class CourseTestCase(ModuleStoreTestCase):
# create a Draft vertical
vertical = self.store.get_item(course_id.make_usage_key('vertical', self.TEST_VERTICAL), depth=1)
draft_vertical = self.store.convert_to_draft(vertical.location, self.user.id)
self.assertEqual(self.store.compute_publish_state(draft_vertical), PublishState.draft)
self.assertTrue(self.store.has_published_version(draft_vertical))
# create a Private (draft only) vertical
private_vertical = self.store.create_item(self.user.id, course_id, 'vertical', self.PRIVATE_VERTICAL)
self.assertEqual(self.store.compute_publish_state(private_vertical), PublishState.private)
self.assertFalse(self.store.has_published_version(private_vertical))
# create a Published (no draft) vertical
public_vertical = self.store.create_item(self.user.id, course_id, 'vertical', self.PUBLISHED_VERTICAL)
public_vertical = self.store.publish(public_vertical.location, self.user.id)
self.assertEqual(self.store.compute_publish_state(public_vertical), PublishState.public)
self.assertTrue(self.store.has_published_version(public_vertical))
# add the new private and new public as children of the sequential
sequential = self.store.get_item(course_id.make_usage_key('sequential', self.SEQUENTIAL))
@@ -197,11 +194,7 @@ class CourseTestCase(ModuleStoreTestCase):
def verify_item_publish_state(item, publish_state):
"""Verifies the publish state of the item is as expected."""
if publish_state in (PublishState.private, PublishState.draft):
self.assertTrue(getattr(item, 'is_draft', False))
else:
self.assertFalse(getattr(item, 'is_draft', False))
self.assertEqual(self.store.compute_publish_state(item), publish_state)
self.assertEqual(self.store.has_published_version(item), publish_state)
def get_and_verify_publish_state(item_type, item_name, publish_state):
"""Gets the given item from the store and verifies the publish state of the item is as expected."""
@@ -210,18 +203,18 @@ class CourseTestCase(ModuleStoreTestCase):
return item
# verify that the draft vertical is draft
vertical = get_and_verify_publish_state('vertical', self.TEST_VERTICAL, PublishState.draft)
vertical = get_and_verify_publish_state('vertical', self.TEST_VERTICAL, True)
for child in vertical.get_children():
verify_item_publish_state(child, PublishState.draft)
verify_item_publish_state(child, True)
# make sure that we don't have a sequential that is not in draft mode
sequential = get_and_verify_publish_state('sequential', self.SEQUENTIAL, PublishState.public)
sequential = get_and_verify_publish_state('sequential', self.SEQUENTIAL, True)
# verify that we have the private vertical
private_vertical = get_and_verify_publish_state('vertical', self.PRIVATE_VERTICAL, PublishState.private)
private_vertical = get_and_verify_publish_state('vertical', self.PRIVATE_VERTICAL, False)
# verify that we have the public vertical
public_vertical = get_and_verify_publish_state('vertical', self.PUBLISHED_VERTICAL, PublishState.public)
public_vertical = get_and_verify_publish_state('vertical', self.PUBLISHED_VERTICAL, True)
# verify verticals are children of sequential
for vert in [vertical, private_vertical, public_vertical]:
@@ -266,22 +259,11 @@ class CourseTestCase(ModuleStoreTestCase):
course2_item_loc = course2_item_loc.replace(name=new_name)
course2_item = self.store.get_item(course2_item_loc)
try:
# compare published state
self.assertEqual(
self.store.compute_publish_state(course1_item),
self.store.compute_publish_state(course2_item)
)
except AssertionError:
c1_state = self.compute_real_state(course1_item)
c2_state = self.compute_real_state(course2_item)
self.assertEqual(
c1_state,
c2_state,
"Publish states not equal: course item {} in state {} != course item {} in state {}".format(
course1_item_loc, c1_state, course2_item.location, c2_state
)
)
# compare published state
self.assertEqual(
self.store.has_published_version(course1_item),
self.store.has_published_version(course2_item)
)
# compare data
self.assertEqual(hasattr(course1_item, 'data'), hasattr(course2_item, 'data'))
@@ -332,37 +314,6 @@ class CourseTestCase(ModuleStoreTestCase):
else:
self.assertEqual(value, course2_asset_attrs[key])
def compute_real_state(self, item):
"""
In draft mongo, compute_published_state can return draft when the draft == published, but in split,
it'll return public in that case
"""
supposed_state = self.store.compute_publish_state(item)
if supposed_state == PublishState.draft and isinstance(item.runtime.modulestore, DraftModuleStore):
# see if the draft differs from the published
published = self.store.get_item(item.location, revision=ModuleStoreEnum.RevisionOption.published_only)
if item.get_explicitly_set_fields_by_scope() != published.get_explicitly_set_fields_by_scope():
# checking content: if published differs from item, return draft
return supposed_state
if item.get_explicitly_set_fields_by_scope(Scope.settings) != published.get_explicitly_set_fields_by_scope(Scope.settings):
# checking settings: if published differs from item, return draft
return supposed_state
if item.has_children and item.children != published.children:
# checking children: if published differs from item, return draft
return supposed_state
# published == item in all respects, so return public
return PublishState.public
elif supposed_state == PublishState.public and item.location.category in DIRECT_ONLY_CATEGORIES:
if not all([
self.store.has_item(child_loc, revision=ModuleStoreEnum.RevisionOption.draft_only)
for child_loc in item.children
]):
return PublishState.draft
else:
return supposed_state
else:
return supposed_state
def get_url(handler_name, key_value, key_name='usage_key_string', kwargs=None):
"""

View File

@@ -11,7 +11,6 @@ from django.conf import settings
from xmodule.modulestore.exceptions import ItemNotFoundError
from edxmako.shortcuts import render_to_response
from xmodule.modulestore import PublishState
from xmodule.modulestore.django import modulestore
from xblock.core import XBlock
@@ -96,11 +95,7 @@ def subsection_handler(request, usage_key_string):
can_view_live = False
subsection_units = item.get_children()
for unit in subsection_units:
has_published = modulestore().compute_publish_state(unit) != PublishState.private
if has_published:
can_view_live = True
break
can_view_live = any([modulestore().has_published_version(unit) for unit in subsection_units])
return render_to_response(
'edit_subsection.html',

View File

@@ -24,7 +24,7 @@ from xblock.fragment import Fragment
import xmodule
from xmodule.tabs import StaticTab, CourseTabList
from xmodule.modulestore import ModuleStoreEnum, PublishState, EdxJSONEncoder
from xmodule.modulestore import ModuleStoreEnum, EdxJSONEncoder
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError
from xmodule.modulestore.inheritance import own_metadata
@@ -387,8 +387,7 @@ def _save_xblock(user, xblock, data=None, children=None, metadata=None, nullout=
# then this item should be republished. This is used by staff locking to ensure that changing the draft
# value of the staff lock will also update the published version, but only at the unit level.
if publish == 'republish' and xblock.category not in DIRECT_ONLY_CATEGORIES:
published = modulestore().compute_publish_state(xblock) != PublishState.private
if published:
if modulestore().has_published_version(xblock):
publish = 'make_public'
# Make public after updating the xblock, in case the caller asked for both an update and a publish.
@@ -659,7 +658,7 @@ def create_xblock_info(xblock, data=None, metadata=None, include_ancestor_info=F
visibility_state = _compute_visibility_state(xblock, child_info, is_xblock_unit and has_changes)
else:
visibility_state = None
published = modulestore().compute_publish_state(xblock) != PublishState.private
published = modulestore().has_published_version(xblock)
xblock_info = {
"id": unicode(xblock.location),