Commit 08998719 by John Eskew

Merge pull request #11042 from edx/jeskew/xml_removal

Remove XML modulestore code from most tests.
parents edb356a4 8354e6d7
......@@ -29,10 +29,6 @@ class TestArgParsing(unittest.TestCase):
with self.assertRaises(CommandError):
self.command.handle("foo", "user@foo.org", "org", "course", "run")
def test_xml_store(self):
with self.assertRaises(CommandError):
self.command.handle(ModuleStoreEnum.Type.xml, "user@foo.org", "org", "course", "run")
def test_nonexistent_user_id(self):
errstring = "No user 99 found"
with self.assertRaisesRegexp(CommandError, errstring):
......
......@@ -124,15 +124,6 @@ class MixedWithOptionsTestCase(MixedSplitTestCase):
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
'OPTIONS': modulestore_options
},
{
'NAME': 'xml',
'ENGINE': 'xmodule.modulestore.xml.XMLModuleStore',
'OPTIONS': {
'data_dir': DATA_DIR,
'default_class': 'xmodule.hidden_module.HiddenDescriptor',
'xblock_mixins': modulestore_options['xblock_mixins'],
}
},
],
'xblock_mixins': modulestore_options['xblock_mixins'],
}
......
......@@ -34,9 +34,7 @@ from embargo.exceptions import InvalidAccessPoint
from mock import patch
# Since we don't need any XML course fixtures, use a modulestore configuration
# that disables the XML modulestore.
MODULESTORE_CONFIG = mixed_store_config(settings.COMMON_TEST_DATA_ROOT, {}, include_xml=False)
MODULESTORE_CONFIG = mixed_store_config(settings.COMMON_TEST_DATA_ROOT, {})
@ddt.ddt
......
......@@ -163,9 +163,7 @@ def replace_static_urls(text, data_directory=None, course_id=None, static_asset_
if settings.DEBUG and finders.find(rest, True):
return original
# if we're running with a MongoBacked store course_namespace is not None, then use studio style urls
elif (not static_asset_path) \
and course_id \
and modulestore().get_modulestore_type(course_id) != ModuleStoreEnum.Type.xml:
elif (not static_asset_path) and course_id:
# first look in the static file pipeline and see if we are trying to reference
# a piece of static content which is in the edx-platform repo (e.g. JS associated with an xmodule)
......
......@@ -13,7 +13,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
from student.tests.factories import UserFactory, CourseEnrollmentFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_TOY_MODULESTORE
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_MODULESTORE
from xmodule.modulestore.tests.factories import CourseFactory
# This import is for an lms djangoapp.
......@@ -90,7 +90,7 @@ class TestStudentDashboardEmailViewXMLBacked(SharedModuleStoreTestCase):
"""
Check for email view on student dashboard, with XML backed course.
"""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
def setUp(self):
super(TestStudentDashboardEmailViewXMLBacked, self).setUp()
......
......@@ -649,7 +649,6 @@ def dashboard(request):
show_email_settings_for = frozenset(
enrollment.course_id for enrollment in course_enrollments if (
settings.FEATURES['ENABLE_INSTRUCTOR_EMAIL'] and
modulestore().get_modulestore_type(enrollment.course_id) != ModuleStoreEnum.Type.xml and
CourseAuthorization.instructor_email_enabled(enrollment.course_id)
)
)
......
......@@ -175,7 +175,7 @@ class CourseFields(object):
scope=Scope.settings
)
textbooks = TextbookList(
help=_("List of pairs of (title, url) for textbooks used in this course"),
help=_("List of Textbook objects with (title, url) for textbooks used in this course"),
default=[],
scope=Scope.content
)
......
......@@ -55,7 +55,6 @@ class ModuleStoreEnum(object):
"""
split = 'split'
mongo = 'mongo'
xml = 'xml'
class RevisionOption(object):
"""
......
"""
MixedModuleStore allows for aggregation between multiple modulestores.
In this way, courses can be served up both - say - XMLModuleStore or MongoModuleStore
In this way, courses can be served up via either SplitMongoModuleStore or MongoModuleStore.
"""
......@@ -169,15 +169,6 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
for store_settings in stores:
key = store_settings['NAME']
is_xml = 'XMLModuleStore' in store_settings['ENGINE']
if is_xml:
# restrict xml to only load courses in mapping
store_settings['OPTIONS']['course_ids'] = [
course_key.to_deprecated_string()
for course_key, store_key in self.mappings.iteritems()
if store_key == key
]
store = create_modulestore_instance(
store_settings['ENGINE'],
self.contentstore,
......
......@@ -29,13 +29,13 @@ from openedx.core.djangoapps.bookmarks.signals import trigger_update_xblocks_cac
class StoreConstructors(object):
"""Enumeration of store constructor types."""
draft, split, xml = range(3)
draft, split = range(2)
def mixed_store_config(data_dir, mappings, include_xml=False, xml_source_dirs=None, store_order=None):
def mixed_store_config(data_dir, mappings, store_order=None):
"""
Return a `MixedModuleStore` configuration, which provides
access to both Mongo- and XML-backed courses.
access to both Mongo-backed courses.
Args:
data_dir (string): the directory from which to load XML-backed courses.
......@@ -51,26 +51,15 @@ def mixed_store_config(data_dir, mappings, include_xml=False, xml_source_dirs=No
Keyword Args:
include_xml (boolean): If True, include an XML modulestore in the configuration.
xml_source_dirs (list): The directories containing XML courses to load from disk.
note: For the courses to be loaded into the XML modulestore and accessible do the following:
* include_xml should be True
* xml_source_dirs should be the list of directories (relative to data_dir)
containing the courses you want to load
* mappings should be configured, pointing the xml courses to the xml modulestore
store_order (list): List of StoreConstructors providing order of modulestores
to use in creating courses.
"""
if store_order is None:
store_order = [StoreConstructors.draft, StoreConstructors.split]
if include_xml and StoreConstructors.xml not in store_order:
store_order.append(StoreConstructors.xml)
store_constructors = {
StoreConstructors.split: split_mongo_store_config(data_dir)['default'],
StoreConstructors.draft: draft_mongo_store_config(data_dir)['default'],
StoreConstructors.xml: xml_store_config(data_dir, source_dirs=xml_source_dirs)['default'],
}
store = {
......@@ -140,28 +129,6 @@ def split_mongo_store_config(data_dir):
return store
def xml_store_config(data_dir, source_dirs=None):
"""
Defines default module store using XMLModuleStore.
Note: you should pass in a list of source_dirs that you care about,
otherwise all courses in the data_dir will be processed.
"""
store = {
'default': {
'NAME': 'xml',
'ENGINE': 'xmodule.modulestore.xml.XMLModuleStore',
'OPTIONS': {
'data_dir': data_dir,
'default_class': 'xmodule.hidden_module.HiddenDescriptor',
'source_dirs': source_dirs,
}
}
}
return store
@patch('xmodule.modulestore.django.create_modulestore_instance', autospec=True)
def drop_mongo_collections(mock_create):
"""
......@@ -180,39 +147,25 @@ def drop_mongo_collections(mock_create):
TEST_DATA_DIR = settings.COMMON_TEST_DATA_ROOT
# This is an XML only modulestore with only the toy course loaded
TEST_DATA_XML_MODULESTORE = xml_store_config(TEST_DATA_DIR, source_dirs=['toy'])
# This modulestore will provide both a mixed mongo editable modulestore, and
# an XML store with just the toy course loaded.
TEST_DATA_MIXED_TOY_MODULESTORE = mixed_store_config(
TEST_DATA_DIR, {'edX/toy/2012_Fall': 'xml', }, include_xml=True, xml_source_dirs=['toy']
)
# This modulestore will provide both a mixed mongo editable modulestore, and
# an XML store with common/test/data/2014 loaded, which is a course that is closed.
TEST_DATA_MIXED_CLOSED_MODULESTORE = mixed_store_config(
TEST_DATA_DIR, {'edX/detached_pages/2014': 'xml', }, include_xml=True, xml_source_dirs=['2014']
)
# This modulestore will provide both a mixed mongo editable modulestore, and
# an XML store with common/test/data/graded loaded, which is a course that is graded.
TEST_DATA_MIXED_GRADED_MODULESTORE = mixed_store_config(
TEST_DATA_DIR, {'edX/graded/2012_Fall': 'xml', }, include_xml=True, xml_source_dirs=['graded']
# This modulestore will provide a mixed mongo editable modulestore.
# If your test uses the 'toy' course, use the the ToyCourseFactory to construct it.
# If your test needs a closed course to test against, import the common/test/data/2014
# test course into this modulestore.
# If your test needs a graded course to test against, import the common/test/data/graded
# test course into this modulestore.
TEST_DATA_MIXED_MODULESTORE = mixed_store_config(
TEST_DATA_DIR, {}
)
# All store requests now go through mixed
# Use this modulestore if you specifically want to test mongo and not a mocked modulestore.
# This modulestore definition below will not load any xml courses.
TEST_DATA_MONGO_MODULESTORE = mixed_store_config(mkdtemp_clean(), {}, include_xml=False)
TEST_DATA_MONGO_MODULESTORE = mixed_store_config(mkdtemp_clean(), {})
# All store requests now go through mixed
# Use this modulestore if you specifically want to test split-mongo and not a mocked modulestore.
# This modulestore definition below will not load any xml courses.
TEST_DATA_SPLIT_MODULESTORE = mixed_store_config(
mkdtemp_clean(),
{},
include_xml=False,
store_order=[StoreConstructors.split, StoreConstructors.draft]
)
......@@ -265,7 +218,7 @@ class SharedModuleStoreTestCase(TestCase):
In Django 1.8, we will be able to use setUpTestData() to do class level init
for Django ORM models that will get cleaned up properly.
"""
MODULESTORE = mixed_store_config(mkdtemp_clean(), {}, include_xml=False)
MODULESTORE = mixed_store_config(mkdtemp_clean(), {})
# Tell Django to clean out all databases, not just default
multi_db = True
......@@ -429,7 +382,7 @@ class ModuleStoreTestCase(TestCase):
your `setUp()` method.
"""
MODULESTORE = mixed_store_config(mkdtemp_clean(), {}, include_xml=False)
MODULESTORE = mixed_store_config(mkdtemp_clean(), {})
# Tell Django to clean out all databases, not just default
multi_db = True
......
......@@ -25,6 +25,7 @@ from xmodule.modulestore import prefer_xmodules, ModuleStoreEnum
from xmodule.modulestore.tests.sample_courses import default_block_info_tree, TOY_BLOCK_INFO_TREE
from xmodule.tabs import CourseTab
from xmodule.x_module import DEPRECATION_VSCOMPAT_EVENT
from xmodule.course_module import Textbook
class Dummy(object):
......@@ -190,7 +191,7 @@ class ToyCourseFactory(SampleCourseFactory):
fields = {
'block_info_tree': TOY_BLOCK_INFO_TREE,
'textbooks': [["Textbook", "path/to/a/text_book"]],
'textbooks': [Textbook("Textbook", "path/to/a/text_book")],
'wiki_slug': "toy",
'graded': True,
'discussion_topics': {"General": {"id": "i4x-edX-toy-course-2012_Fall"}},
......
......@@ -31,10 +31,6 @@ class TestXMLModuleStore(unittest.TestCase):
"""
Test around the XML modulestore
"""
def test_xml_modulestore_type(self):
store = XMLModuleStore(DATA_DIR, source_dirs=[])
self.assertEqual(store.get_modulestore_type(), ModuleStoreEnum.Type.xml)
@patch('xmodule.tabs.CourseTabList.initialize_default', Mock())
def test_unicode_chars_in_xml_content(self):
# edX/full/6.002_Spring_2012 has non-ASCII chars, and during
......
......@@ -875,7 +875,8 @@ class XMLModuleStore(ModuleStoreReadBase):
Args:
course_key: just for signature compatibility
"""
return ModuleStoreEnum.Type.xml
# return ModuleStoreEnum.Type.xml
return None
def get_courses_for_wiki(self, wiki_slug, **kwargs):
"""
......@@ -893,7 +894,7 @@ class XMLModuleStore(ModuleStoreReadBase):
Returns the course count
"""
return {ModuleStoreEnum.Type.xml: True}
return {'xml': True}
@contextmanager
def branch_setting(self, branch_setting, course_id=None): # pylint: disable=unused-argument
......
......@@ -279,9 +279,7 @@ class CourseExportManager(ExportManager):
policy = {'course/' + courselike.location.name: own_metadata(courselike)}
course_policy.write(dumps(policy, cls=EdxJSONEncoder, sort_keys=True, indent=4))
# xml backed courses don't support drafts!
if courselike.runtime.modulestore.get_modulestore_type() != ModuleStoreEnum.Type.xml:
_export_drafts(self.modulestore, self.courselike_key, export_fs, xml_centric_courselike_key)
_export_drafts(self.modulestore, self.courselike_key, export_fs, xml_centric_courselike_key)
class LibraryExportManager(ExportManager):
......
......@@ -100,11 +100,4 @@ class CourseAuthorizationAdminForm(forms.ModelForm):
msg += 'Please recheck that you have supplied a valid course id.'
raise forms.ValidationError(msg)
# Now, try and discern if it is a Studio course - HTML editor doesn't work with XML courses
is_studio_course = modulestore().get_modulestore_type(course_key) != ModuleStoreEnum.Type.xml
if not is_studio_course:
msg = "Course Email feature is only available for courses authored in Studio. "
msg += '"{0}" appears to be an XML backed course.'.format(course_key.to_deprecated_string())
raise forms.ValidationError(msg)
return course_key
......@@ -8,7 +8,6 @@ from nose.plugins.attrib import attr
from bulk_email.models import CourseAuthorization, CourseEmailTemplate
from bulk_email.forms import CourseAuthorizationAdminForm, CourseEmailTemplateForm
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_TOY_MODULESTORE
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
......@@ -127,32 +126,6 @@ class CourseAuthorizationFormTest(ModuleStoreTestCase):
form.save()
class CourseAuthorizationXMLFormTest(ModuleStoreTestCase):
"""Check that XML courses cannot be authorized for email."""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
@patch.dict(settings.FEATURES, {'ENABLE_INSTRUCTOR_EMAIL': True, 'REQUIRE_COURSE_EMAIL_AUTH': True})
def test_xml_course_authorization(self):
course_id = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
# Assert this is an XML course
self.assertEqual(modulestore().get_modulestore_type(course_id), ModuleStoreEnum.Type.xml)
form_data = {'course_id': course_id.to_deprecated_string(), 'email_enabled': True}
form = CourseAuthorizationAdminForm(data=form_data)
# Validation shouldn't work
self.assertFalse(form.is_valid())
msg = u"Course Email feature is only available for courses authored in Studio. "
msg += u'"{0}" appears to be an XML backed course.'.format(course_id.to_deprecated_string())
self.assertEquals(msg, form._errors['course_id'][0]) # pylint: disable=protected-access
with self.assertRaisesRegexp(
ValueError,
"The CourseAuthorization could not be created because the data didn't validate."
):
form.save()
class CourseEmailTemplateFormTest(ModuleStoreTestCase):
"""Test the CourseEmailTemplateForm that is used in the Django admin subsystem."""
......
......@@ -453,10 +453,8 @@ def get_studio_url(course, page):
Args:
course (CourseDescriptor)
"""
is_studio_course = course.course_edit_method == "Studio"
is_mongo_course = modulestore().get_modulestore_type(course.id) != ModuleStoreEnum.Type.xml
studio_link = None
if is_studio_course and is_mongo_course:
if course.course_edit_method == "Studio":
studio_link = get_cms_course_link(course, page)
return studio_link
......
......@@ -14,7 +14,9 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
from course_modes.models import CourseMode
from track.tests import EventTrackingTestCase
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_CLOSED_MODULESTORE
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_MODULESTORE
from xmodule.modulestore.tests.utils import TEST_DATA_DIR
from xmodule.modulestore.xml_importer import import_course_from_xml
from student.models import CourseEnrollment
from student.tests.factories import AdminFactory, CourseEnrollmentAllowedFactory, UserFactory
......@@ -199,16 +201,32 @@ class AboutTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase):
"""
Tests for the course about page
"""
MODULESTORE = TEST_DATA_MIXED_CLOSED_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
# The following XML test course (which lives at common/test/data/2014)
# is closed; we're testing that an about page still appears when
# the course is already closed
xml_course_id = SlashSeparatedCourseKey('edX', 'detached_pages', '2014')
def setUp(self):
"""
Set up the tests
"""
super(AboutTestCaseXML, self).setUp()
# The following test course (which lives at common/test/data/2014)
# is closed; we're testing that an about page still appears when
# the course is already closed
self.xml_course_id = self.store.make_course_key('edX', 'detached_pages', '2014')
import_course_from_xml(
self.store,
'test_user',
TEST_DATA_DIR,
source_dirs=['2014'],
static_content_store=None,
target_id=self.xml_course_id,
raise_on_failure=True,
create_if_not_present=True,
)
# this text appears in that course's about page
# common/test/data/2014/about/overview.html
xml_data = "about page 463139"
# this text appears in that course's about page
# common/test/data/2014/about/overview.html
self.xml_data = "about page 463139"
@patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
def test_logged_in_xml(self):
......
......@@ -17,9 +17,11 @@ from util.date_utils import strftime_localized
from xmodule.modulestore.tests.django_utils import (
ModuleStoreTestCase,
SharedModuleStoreTestCase,
TEST_DATA_SPLIT_MODULESTORE
TEST_DATA_SPLIT_MODULESTORE,
TEST_DATA_MIXED_MODULESTORE
)
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_CLOSED_MODULESTORE
from xmodule.modulestore.tests.utils import TEST_DATA_DIR
from xmodule.modulestore.xml_importer import import_course_from_xml
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls
from student.models import CourseEnrollment
from student.tests.factories import AdminFactory
......@@ -212,16 +214,32 @@ class CourseInfoTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase):
"""
Tests for the Course Info page for an XML course
"""
MODULESTORE = TEST_DATA_MIXED_CLOSED_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
# The following XML test course (which lives at common/test/data/2014)
# is closed; we're testing that a course info page still appears when
# the course is already closed
xml_course_key = SlashSeparatedCourseKey('edX', 'detached_pages', '2014')
def setUp(self):
"""
Set up the tests
"""
super(CourseInfoTestCaseXML, self).setUp()
# The following test course (which lives at common/test/data/2014)
# is closed; we're testing that a course info page still appears when
# the course is already closed
self.xml_course_key = self.store.make_course_key('edX', 'detached_pages', '2014')
import_course_from_xml(
self.store,
'test_user',
TEST_DATA_DIR,
source_dirs=['2014'],
static_content_store=None,
target_id=self.xml_course_key,
raise_on_failure=True,
create_if_not_present=True,
)
# this text appears in that course's course info page
# common/test/data/2014/info/updates.html
xml_data = "course info 463139"
# this text appears in that course's course info page
# common/test/data/2014/info/updates.html
self.xml_data = "course info 463139"
@mock.patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
def test_logged_in_xml(self):
......
......@@ -33,8 +33,9 @@ from xmodule.modulestore.django import _get_modulestore_branch_setting, modulest
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.xml_importer import import_course_from_xml
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_TOY_MODULESTORE
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls
from xmodule.modulestore.tests.factories import (
CourseFactory, ItemFactory, check_mongo_calls
)
from xmodule.tests.xml import factories as xml
from xmodule.tests.xml import XModuleXmlImportTest
......@@ -304,30 +305,6 @@ class CoursesRenderTest(ModuleStoreTestCase):
@attr('shard_1')
class XmlCoursesRenderTest(ModuleStoreTestCase):
"""Test methods related to rendering courses content for an XML course."""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
toy_course_key = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
def test_get_course_info_section_render(self):
course = get_course_by_id(self.toy_course_key)
request = get_request_for_user(UserFactory.create())
# Test render works okay. Note the href is different in XML courses.
course_info = get_course_info_section(request, request.user, course, 'handouts')
self.assertEqual(course_info, "<a href='/static/toy/handouts/sample_handout.txt'>Sample</a>")
# Test when render raises an exception
with mock.patch('courseware.courses.get_module') as mock_module_render:
mock_module_render.return_value = mock.MagicMock(
render=mock.Mock(side_effect=Exception('Render failed!'))
)
course_info = get_course_info_section(request, request.user, course, 'handouts')
self.assertIn("this module is temporarily unavailable", course_info)
@attr('shard_1')
@ddt.ddt
class CourseInstantiationTests(ModuleStoreTestCase):
"""
......
......@@ -43,13 +43,13 @@ from openedx.core.lib.courses import course_image_url
from openedx.core.lib.gating import api as gating_api
from student.models import anonymous_id_for_user
from xmodule.modulestore.tests.django_utils import (
TEST_DATA_MIXED_TOY_MODULESTORE,
TEST_DATA_XML_MODULESTORE,
SharedModuleStoreTestCase)
ModuleStoreTestCase,
SharedModuleStoreTestCase,
TEST_DATA_MIXED_MODULESTORE
)
from xmodule.lti_module import LTIDescriptor
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory, ToyCourseFactory, check_mongo_calls
from xmodule.x_module import XModuleDescriptor, XModule, STUDENT_VIEW, CombinedSystem
......@@ -1369,17 +1369,6 @@ class ViewInStudioTest(ModuleStoreTestCase):
# pylint: disable=attribute-defined-outside-init
self.child_module = self._get_module(course.id, child_descriptor, child_descriptor.location)
def setup_xml_course(self):
"""
Define the XML backed course to use.
Toy courses are already loaded in XML and mixed modulestores.
"""
course_key = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
location = course_key.make_usage_key('chapter', 'Overview')
descriptor = modulestore().get_item(location)
self.module = self._get_module(course_key, descriptor, location)
@attr('shard_1')
class MongoViewInStudioTest(ViewInStudioTest):
......@@ -1414,7 +1403,7 @@ class MongoViewInStudioTest(ViewInStudioTest):
class MixedViewInStudioTest(ViewInStudioTest):
"""Test the 'View in Studio' link visibility in a mixed mongo backed course."""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
def test_view_in_studio_link_mongo_backed(self):
"""Mixed mongo courses that are mongo backed should see 'View in Studio' links."""
......@@ -1428,24 +1417,6 @@ class MixedViewInStudioTest(ViewInStudioTest):
result_fragment = self.module.render(STUDENT_VIEW, context=self.default_context)
self.assertNotIn('View Unit in Studio', result_fragment.content)
def test_view_in_studio_link_xml_backed(self):
"""Course in XML only modulestore should not see 'View in Studio' links."""
self.setup_xml_course()
result_fragment = self.module.render(STUDENT_VIEW, context=self.default_context)
self.assertNotIn('View Unit in Studio', result_fragment.content)
@attr('shard_1')
class XmlViewInStudioTest(ViewInStudioTest):
"""Test the 'View in Studio' link visibility in an xml backed course."""
MODULESTORE = TEST_DATA_XML_MODULESTORE
def test_view_in_studio_link_xml_backed(self):
"""Course in XML only modulestore should not see 'View in Studio' links."""
self.setup_xml_course()
result_fragment = self.module.render(STUDENT_VIEW)
self.assertNotIn('View Unit in Studio', result_fragment.content)
@XBlock.tag("detached")
class DetachedXBlock(XBlock):
......
......@@ -27,10 +27,13 @@ from util.milestones_helpers import (
from milestones.tests.utils import MilestonesTestCaseMixin
from xmodule import tabs as xmodule_tabs
from xmodule.modulestore.tests.django_utils import (
TEST_DATA_MIXED_TOY_MODULESTORE, TEST_DATA_MIXED_CLOSED_MODULESTORE,
SharedModuleStoreTestCase)
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
ModuleStoreTestCase,
SharedModuleStoreTestCase,
TEST_DATA_MIXED_MODULESTORE
)
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.modulestore.tests.utils import TEST_DATA_DIR
from xmodule.modulestore.xml_importer import import_course_from_xml
class TabTestCase(SharedModuleStoreTestCase):
......@@ -225,7 +228,7 @@ class TextbooksTestCase(TabTestCase):
class StaticTabDateTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase):
"""Test cases for Static Tab Dates."""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
@classmethod
def setUpClass(cls):
......@@ -237,10 +240,6 @@ class StaticTabDateTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase):
)
cls.course.tabs.append(xmodule_tabs.CourseTab.load('static_tab', name='New Tab', url_slug='new_tab'))
cls.course.save()
cls.toy_course_key = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
def setUp(self):
super(StaticTabDateTestCase, self).setUp()
def test_logged_in(self):
self.setup_user()
......@@ -263,13 +262,13 @@ class StaticTabDateTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase):
def test_get_static_tab_contents(self):
self.setup_user()
course = get_course_by_id(self.toy_course_key)
course = get_course_by_id(self.course.id)
request = get_request_for_user(self.user)
tab = xmodule_tabs.CourseTabList.get_tab_by_slug(course.tabs, 'resources')
tab = xmodule_tabs.CourseTabList.get_tab_by_slug(course.tabs, 'new_tab')
# Test render works okay
tab_content = get_static_tab_contents(request, course, tab)
self.assertIn(self.toy_course_key.to_deprecated_string(), tab_content)
self.assertIn(self.course.id.to_deprecated_string(), tab_content)
self.assertIn('static_tab', tab_content)
# Test when render raises an exception
......@@ -287,17 +286,33 @@ class StaticTabDateTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase):
Tests for the static tab dates of an XML course
"""
MODULESTORE = TEST_DATA_MIXED_CLOSED_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
# The following XML test course (which lives at common/test/data/2014)
# is closed; we're testing that tabs still appear when
# the course is already closed
xml_course_key = SlashSeparatedCourseKey('edX', 'detached_pages', '2014')
def setUp(self):
"""
Set up the tests
"""
super(StaticTabDateTestCaseXML, self).setUp()
# The following XML test course (which lives at common/test/data/2014)
# is closed; we're testing that tabs still appear when
# the course is already closed
self.xml_course_key = self.store.make_course_key('edX', 'detached_pages', '2014')
import_course_from_xml(
self.store,
'test_user',
TEST_DATA_DIR,
source_dirs=['2014'],
static_content_store=None,
target_id=self.xml_course_key,
raise_on_failure=True,
create_if_not_present=True,
)
# this text appears in the test course's tab
# common/test/data/2014/tabs/8e4cce2b4aaf4ba28b1220804619e41f.html
xml_data = "static 463139"
xml_url = "8e4cce2b4aaf4ba28b1220804619e41f"
# this text appears in the test course's tab
# common/test/data/2014/tabs/8e4cce2b4aaf4ba28b1220804619e41f.html
self.xml_data = "static 463139"
self.xml_url = "8e4cce2b4aaf4ba28b1220804619e41f"
@patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
def test_logged_in_xml(self):
......@@ -321,7 +336,7 @@ class EntranceExamsTabsTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, Mi
"""
Validate tab behavior when dealing with Entrance Exams
"""
MODULESTORE = TEST_DATA_MIXED_CLOSED_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
@patch.dict('django.conf.settings.FEATURES', {'ENTRANCE_EXAMS': True, 'MILESTONES_APP': True})
def setUp(self):
......@@ -428,7 +443,7 @@ class TextBookCourseViewsTestCase(LoginEnrollmentTestCase, SharedModuleStoreTest
"""
Validate tab behavior when dealing with textbooks.
"""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
@classmethod
def setUpClass(cls):
......
......@@ -51,7 +51,7 @@ from util.url import reload_django_url_config
from util.views import ensure_valid_course_key
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_TOY_MODULESTORE
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_MODULESTORE
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls
from openedx.core.djangoapps.credit.api import set_credit_requirements
......@@ -63,7 +63,7 @@ class TestJumpTo(ModuleStoreTestCase):
"""
Check the jumpto link for a course.
"""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
def setUp(self):
super(TestJumpTo, self).setUp()
......
......@@ -10,12 +10,13 @@ from nose.plugins.attrib import attr
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from courseware.tests.helpers import LoginEnrollmentTestCase
from xmodule.modulestore.tests.django_utils import TEST_DATA_XML_MODULESTORE as XML_MODULESTORE
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_TOY_MODULESTORE as TOY_MODULESTORE
from lms.djangoapps.lms_xblock.field_data import LmsFieldData
from xmodule.error_module import ErrorDescriptor
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.django_utils import (
ModuleStoreTestCase, TEST_DATA_MIXED_MODULESTORE
)
from xmodule.modulestore.tests.factories import ToyCourseFactory
@attr('shard_1')
......@@ -123,33 +124,16 @@ class PageLoaderTestCase(LoginEnrollmentTestCase):
@attr('shard_1')
class TestXmlCoursesLoad(ModuleStoreTestCase, PageLoaderTestCase):
"""
Check that all pages in test courses load properly from XML.
"""
MODULESTORE = XML_MODULESTORE
def setUp(self):
super(TestXmlCoursesLoad, self).setUp()
self.setup_user()
def test_toy_course_loads(self):
# Load one of the XML based courses
# Our test mapping rules allow the MixedModuleStore
# to load this course from XML, not Mongo.
self.check_all_pages_load(SlashSeparatedCourseKey('edX', 'toy', '2012_Fall'))
@attr('shard_1')
class TestMongoCoursesLoad(ModuleStoreTestCase, PageLoaderTestCase):
"""
Check that all pages in test courses load properly from Mongo.
"""
MODULESTORE = TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
def setUp(self):
super(TestMongoCoursesLoad, self).setUp()
self.setup_user()
self.toy_course_key = ToyCourseFactory.create().id
@mock.patch('xmodule.course_module.requests.get')
def test_toy_textbooks_loads(self, mock_get):
......@@ -158,8 +142,7 @@ class TestMongoCoursesLoad(ModuleStoreTestCase, PageLoaderTestCase):
<entry page="5" page_label="ii" name="Table of Contents"/>
</table_of_contents>
""").strip()
location = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall').make_usage_key('course', '2012_Fall')
location = self.toy_course_key.make_usage_key('course', '2012_Fall')
course = self.store.get_item(location)
self.assertGreater(len(course.textbooks), 0)
......
......@@ -491,23 +491,7 @@ class Courses(SysadminDashboardView):
escape(str(err))
)
is_xml_course = (modulestore().get_modulestore_type(course_key) == ModuleStoreEnum.Type.xml)
if course_found and is_xml_course:
cdir = course.data_dir
self.def_ms.courses.pop(cdir)
# now move the directory (don't actually delete it)
new_dir = "{course_dir}_deleted_{timestamp}".format(
course_dir=cdir,
timestamp=int(time.time())
)
os.rename(settings.DATA_DIR / cdir, settings.DATA_DIR / new_dir)
self.msg += (u"<font color='red'>Deleted "
u"{0} = {1} ({2})</font>".format(
cdir, course.id, course.display_name))
elif course_found and not is_xml_course:
if course_found:
# delete course that is stored with mongodb backend
self.def_ms.delete_course(course.id, request.user.id)
# don't delete user permission groups, though
......
......@@ -5,9 +5,11 @@ from django.test.testcases import TestCase
from nose.plugins.attrib import attr
from opaque_keys.edx.keys import CourseKey
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_TOY_MODULESTORE
import django_comment_common.models as models
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.django_utils import (
TEST_DATA_MIXED_MODULESTORE, ModuleStoreTestCase
)
from xmodule.modulestore.tests.factories import ToyCourseFactory
@attr('shard_1')
......@@ -15,7 +17,7 @@ class RoleClassTestCase(ModuleStoreTestCase):
"""
Tests for roles of the comment client service integration
"""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
def setUp(self):
super(RoleClassTestCase, self).setUp()
......@@ -23,7 +25,7 @@ class RoleClassTestCase(ModuleStoreTestCase):
# For course ID, syntax edx/classname/classdate is important
# because xmodel.course_module.id_to_location looks for a string to split
self.course_id = CourseKey.from_string("edX/toy/2012_Fall")
self.course_id = ToyCourseFactory.create().id
self.student_role = models.Role.objects.get_or_create(name="Student",
course_id=self.course_id)[0]
self.student_role.add_permission("delete_thread")
......
......@@ -25,8 +25,8 @@ from openedx.core.djangoapps.content.course_structures.models import CourseStruc
from openedx.core.djangoapps.util.testing import ContentGroupTestCase
from student.roles import CourseStaffRole
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_MIXED_TOY_MODULESTORE
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, ToyCourseFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_MIXED_MODULESTORE
from xmodule.modulestore.django import modulestore
from opaque_keys.edx.locator import CourseLocator
from lms.djangoapps.teams.tests.factories import CourseTeamFactory
......@@ -1248,14 +1248,14 @@ class IsCommentableCohortedTestCase(ModuleStoreTestCase):
Test the is_commentable_cohorted function.
"""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
def setUp(self):
"""
Make sure that course is reloaded every time--clear out the modulestore.
"""
super(IsCommentableCohortedTestCase, self).setUp()
self.toy_course_key = CourseLocator("edX", "toy", "2012_Fall", deprecated=True)
self.toy_course_key = ToyCourseFactory.create().id
def test_is_commentable_cohorted(self):
course = modulestore().get_course(self.toy_course_key)
......
......@@ -12,7 +12,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
from bulk_email.models import CourseAuthorization
from xmodule.modulestore.tests.django_utils import (
TEST_DATA_MIXED_TOY_MODULESTORE, SharedModuleStoreTestCase
TEST_DATA_MIXED_MODULESTORE, SharedModuleStoreTestCase
)
from student.tests.factories import AdminFactory
from xmodule.modulestore.tests.factories import CourseFactory
......@@ -112,7 +112,7 @@ class TestNewInstructorDashboardEmailViewXMLBacked(SharedModuleStoreTestCase):
Check for email view on the new instructor dashboard
"""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
@classmethod
def setUpClass(cls):
......
......@@ -66,10 +66,9 @@ def bulk_email_is_enabled_for_course(course_id):
"""
bulk_email_enabled_globally = (settings.FEATURES['ENABLE_INSTRUCTOR_EMAIL'] is True)
is_studio_course = (modulestore().get_modulestore_type(course_id) != ModuleStoreEnum.Type.xml)
bulk_email_enabled_for_course = CourseAuthorization.instructor_email_enabled(course_id)
if bulk_email_enabled_globally and is_studio_course and bulk_email_enabled_for_course:
if bulk_email_enabled_globally and bulk_email_enabled_for_course:
return True
return False
......
......@@ -745,14 +745,6 @@ MODULESTORE = {
'fs_root': DATA_DIR,
'render_template': 'edxmako.shortcuts.render_to_string',
}
},
{
'NAME': 'xml',
'ENGINE': 'xmodule.modulestore.xml.XMLModuleStore',
'OPTIONS': {
'data_dir': DATA_DIR,
'default_class': 'xmodule.hidden_module.HiddenDescriptor',
}
}
]
}
......
......@@ -6,7 +6,7 @@ import ddt
from xblock.validation import ValidationMessage
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.factories import CourseFactory, ToyCourseFactory, ItemFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_MIXED_TOY_MODULESTORE
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_MIXED_MODULESTORE
from xmodule.partitions.partitions import Group, UserPartition
......@@ -157,21 +157,17 @@ class XBlockGetParentTest(LmsXBlockMixinTestCase):
Test that XBlock.get_parent returns correct results with each modulestore
backend.
"""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split, ModuleStoreEnum.Type.xml)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_parents(self, modulestore_type):
with self.store.default_store(modulestore_type):
# setting up our own local course tree here, since it needs to be
# created with the correct modulestore type.
if modulestore_type == 'xml':
course_key = self.store.make_course_key('edX', 'toy', '2012_Fall')
else:
course_key = ToyCourseFactory.create(run='2012_Fall_copy').id
course_key = ToyCourseFactory.create().id
course = self.store.get_course(course_key)
self.assertIsNone(course.get_parent())
def recurse(parent):
......
......@@ -16,7 +16,8 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
from student.models import CourseEnrollment
from student.tests.factories import UserFactory
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_TOY_MODULESTORE, ModuleStoreTestCase
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_MODULESTORE, ModuleStoreTestCase
from xmodule.modulestore.tests.factories import ToyCourseFactory
from ..models import CourseUserGroup, CourseCohort, CourseUserGroupPartitionGroup
from .. import cohorts
......@@ -138,14 +139,14 @@ class TestCohorts(ModuleStoreTestCase):
"""
Test the cohorts feature
"""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
def setUp(self):
"""
Make sure that course is reloaded every time--clear out the modulestore.
"""
super(TestCohorts, self).setUp()
self.toy_course_key = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")
self.toy_course_key = ToyCourseFactory.create().id
def _create_cohort(self, course_id, cohort_name, assignment_type):
"""
......@@ -732,7 +733,7 @@ class TestCohortsAndPartitionGroups(ModuleStoreTestCase):
"""
Test Cohorts and Partitions Groups.
"""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
def setUp(self):
"""
......@@ -740,7 +741,7 @@ class TestCohortsAndPartitionGroups(ModuleStoreTestCase):
"""
super(TestCohortsAndPartitionGroups, self).setUp()
self.test_course_key = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")
self.test_course_key = ToyCourseFactory.create().id
self.course = modulestore().get_course(self.test_course_key)
self.first_cohort = CohortFactory(course_id=self.course.id, name="FirstCohort")
......
......@@ -15,7 +15,8 @@ from courseware.tests.test_masquerade import StaffMasqueradeTestCase
from student.tests.factories import UserFactory
from xmodule.partitions.partitions import Group, UserPartition, UserPartitionError
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_MIXED_TOY_MODULESTORE
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_MIXED_MODULESTORE
from xmodule.modulestore.tests.factories import ToyCourseFactory
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme
......@@ -31,7 +32,7 @@ class TestCohortPartitionScheme(ModuleStoreTestCase):
"""
Test the logic for linking a user to a partition group based on their cohort.
"""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
def setUp(self):
"""
......@@ -40,7 +41,7 @@ class TestCohortPartitionScheme(ModuleStoreTestCase):
"""
super(TestCohortPartitionScheme, self).setUp()
self.course_key = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")
self.course_key = ToyCourseFactory.create().id
self.course = modulestore().get_course(self.course_key)
config_course_cohorts(self.course, is_cohorted=True)
......@@ -278,7 +279,7 @@ class TestGetCohortedUserPartition(ModuleStoreTestCase):
"""
Test that `get_cohorted_user_partition` returns the first user_partition with scheme `CohortPartitionScheme`.
"""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
def setUp(self):
"""
......@@ -286,7 +287,7 @@ class TestGetCohortedUserPartition(ModuleStoreTestCase):
and a student for each test.
"""
super(TestGetCohortedUserPartition, self).setUp()
self.course_key = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")
self.course_key = ToyCourseFactory.create().id
self.course = modulestore().get_course(self.course_key)
self.student = UserFactory.create()
......
......@@ -13,7 +13,7 @@ from xmodule.modulestore import ModuleStoreEnum
def course_image_url(course):
"""Try to look up the image url for the course. If it's not found,
log an error and return the dead link"""
if course.static_asset_path or modulestore().get_modulestore_type(course.id) == ModuleStoreEnum.Type.xml:
if course.static_asset_path:
# If we are a static course with the course_image attribute
# set different than the default, return that path so that
# courses can use custom course image paths, otherwise just
......
......@@ -300,10 +300,9 @@ def add_staff_markup(user, has_instructor_access, disable_staff_debug_info, bloc
# TODO: make this more general, eg use an XModule attribute instead
if isinstance(block, VerticalBlock) and (not context or not context.get('child_of_vertical', False)):
# check that the course is a mongo backed Studio course before doing work
is_mongo_course = modulestore().get_modulestore_type(block.location.course_key) != ModuleStoreEnum.Type.xml
is_studio_course = block.course_edit_method == "Studio"
if is_studio_course and is_mongo_course:
if is_studio_course:
# build edit link to unit in CMS. Can't use reverse here as lms doesn't load cms's urls.py
edit_link = "//" + settings.CMS_BASE + '/container/' + unicode(block.location)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment