Merge pull request #17399 from edx/jmbowman/PLAT-1917

PLAT-1917 Stop using deprecated Location and AssetLocation
This commit is contained in:
Jeremy Bowman
2018-02-05 12:53:52 -05:00
committed by GitHub
21 changed files with 146 additions and 111 deletions

View File

@@ -3,7 +3,7 @@ Tests core caching facilities.
"""
from django.test import TestCase
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import AssetLocator, CourseLocator
from openedx.core.djangoapps.contentserver.caching import del_cached_content, get_cached_content, set_cached_content
@@ -24,9 +24,9 @@ class CachingTestCase(TestCase):
"""
Tests for https://edx.lighthouseapp.com/projects/102637/tickets/112-updating-asset-does-not-refresh-the-cached-copy
"""
unicodeLocation = Location(u'c4x', u'mitX', u'800', u'run', u'thumbnail', u'monsters.jpg')
unicodeLocation = AssetLocator(CourseLocator(u'c4x', u'mitX', u'800'), u'thumbnail', u'monsters.jpg')
# Note that some of the parts are strings instead of unicode strings
nonUnicodeLocation = Location('c4x', u'mitX', u'800', u'run', 'thumbnail', 'monsters.jpg')
nonUnicodeLocation = AssetLocator(CourseLocator('c4x', u'mitX', u'800'), 'thumbnail', 'monsters.jpg')
mockAsset = Content(unicodeLocation, 'my content')
def test_put_and_get(self):

View File

@@ -21,7 +21,7 @@ from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_GET, require_http_methods
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.waffle_utils import WaffleSwitchNamespace
from six import text_type
@@ -1371,7 +1371,7 @@ def assign_textbook_id(textbook, used_ids=()):
Return an ID that can be assigned to a textbook
and doesn't match the used_ids
"""
tid = Location.clean(textbook["tab_title"])
tid = BlockUsageLocator.clean(textbook["tab_title"])
if not tid[0].isdigit():
# stick a random digit in front
tid = random.choice(string.digits) + tid

View File

@@ -11,7 +11,7 @@ from django.test.client import RequestFactory
from mock import Mock, PropertyMock, patch
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey, UsageKey
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from pyquery import PyQuery
from pytz import UTC
from web_fragments.fragment import Fragment
@@ -2106,7 +2106,7 @@ class TestComponentHandler(TestCase):
self.descriptor = self.modulestore.return_value.get_item.return_value
self.usage_key_string = unicode(
Location('dummy_org', 'dummy_course', 'dummy_run', 'dummy_category', 'dummy_name')
BlockUsageLocator(CourseLocator('dummy_org', 'dummy_course', 'dummy_run'), 'dummy_category', 'dummy_name')
)
self.user = UserFactory()

View File

@@ -26,8 +26,7 @@ from contracts import contract, new_contract
from fs.osfs import OSFS
from mongodb_proxy import autoretry_read
from opaque_keys.edx.keys import UsageKey, CourseKey, AssetKey
from opaque_keys.edx.locations import Location, BlockUsageLocator
from opaque_keys.edx.locator import CourseLocator, LibraryLocator
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator, LibraryLocator
from path import Path as path
from pytz import UTC
from xblock.core import XBlock
@@ -716,7 +715,7 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
# now go through the results and order them by the location url
for result in resultset:
# manually pick it apart b/c the db has tag and we want as_published revision regardless
location = as_published(Location._from_deprecated_son(result['_id'], course_id.run))
location = as_published(BlockUsageLocator._from_deprecated_son(result['_id'], course_id.run))
location_url = unicode(location)
if location_url in results_by_url:
@@ -860,7 +859,7 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
children = []
for item in to_process:
self._clean_item_data(item)
item_location = Location._from_deprecated_son(item['location'], course_key.run)
item_location = BlockUsageLocator._from_deprecated_son(item['location'], course_key.run)
item_children = item.get('definition', {}).get('children', [])
children.extend(item_children)
for item_child in item_children:
@@ -908,7 +907,7 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
for_parent (:class:`XBlock`): The parent of the XBlock being loaded.
"""
course_key = self.fill_in_run(course_key)
location = Location._from_deprecated_son(item['location'], course_key.run)
location = BlockUsageLocator._from_deprecated_son(item['location'], course_key.run)
data_dir = getattr(item, 'data_dir', location.course)
root = self.fs_root / data_dir
resource_fs = _OSFS_INSTANCE.setdefault(root, OSFS(root, create=True))
@@ -1611,7 +1610,7 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
bulk_record = self._get_bulk_ops_record(location.course_key)
for parent in parents:
parent_loc = Location._from_deprecated_son(parent['_id'], location.course_key.run)
parent_loc = BlockUsageLocator._from_deprecated_son(parent['_id'], location.course_key.run)
# travel up the tree for orphan validation
ancestor_loc = parent_loc
@@ -1685,7 +1684,8 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
return cache_and_return(non_orphan_parents[0].replace(run=location.course_key.run))
else:
# return the single PUBLISHED parent
return cache_and_return(Location._from_deprecated_son(parents[0]['_id'], location.course_key.run))
return cache_and_return(BlockUsageLocator._from_deprecated_son(parents[0]['_id'],
location.course_key.run))
else:
# there could be 2 different parents if
# (1) the draft item was moved or
@@ -1705,7 +1705,7 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
found_id = all_parents[0]['_id']
# don't disclose revision outside modulestore
return cache_and_return(Location._from_deprecated_son(found_id, location.course_key.run))
return cache_and_return(BlockUsageLocator._from_deprecated_son(found_id, location.course_key.run))
def get_parent_location(self, location, revision=ModuleStoreEnum.RevisionOption.published_only, **kwargs):
'''
@@ -1750,7 +1750,7 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
if item['_id']['category'] != 'course':
# It would be nice to change this method to return UsageKeys instead of the deprecated string.
item_locs.add(
unicode(as_published(Location._from_deprecated_son(item['_id'], course_key.run)))
unicode(as_published(BlockUsageLocator._from_deprecated_son(item['_id'], course_key.run)))
)
all_reachable = all_reachable.union(item.get('definition', {}).get('children', []))
item_locs -= all_reachable
@@ -1768,7 +1768,7 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
)
# the course's run == its name. It's the only xblock for which that's necessarily true.
return [
Location._from_deprecated_son(course['_id'], course['_id']['name']).course_key
BlockUsageLocator._from_deprecated_son(course['_id'], course['_id']['name']).course_key
for course in courses
]

View File

@@ -10,7 +10,7 @@ import pymongo
import logging
from opaque_keys.edx.keys import UsageKey
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator
from six import text_type
from openedx.core.lib.cache_utils import memoize_in_request_cache
from xmodule.exceptions import InvalidVersionError
@@ -271,7 +271,7 @@ class DraftModuleStore(MongoModuleStore):
# return only the parent(s) that satisfy the request
return [
Location._from_deprecated_son(parent['_id'], location.course_key.run)
BlockUsageLocator._from_deprecated_son(parent['_id'], location.course_key.run)
for parent in parents
if (
# return all versions of the parent if revision is ModuleStoreEnum.RevisionOption.all
@@ -426,7 +426,7 @@ class DraftModuleStore(MongoModuleStore):
# collect the children's ids for future processing
next_tier = []
for child in item.get('definition', {}).get('children', []):
child_loc = Location.from_string(child)
child_loc = BlockUsageLocator.from_string(child)
next_tier.append(child_loc.to_deprecated_son())
# insert a new DRAFT version of the item
@@ -815,7 +815,7 @@ class DraftModuleStore(MongoModuleStore):
item = versions_found[0]
assert item.get('_id').get('revision') != MongoRevisionKey.draft
for child in item.get('definition', {}).get('children', []):
child_loc = Location.from_string(child)
child_loc = BlockUsageLocator.from_string(child)
delete_draft_only(child_loc)
delete_draft_only(location)
@@ -840,7 +840,7 @@ class DraftModuleStore(MongoModuleStore):
if source_item.parent and source_item.parent.block_id != original_parent_location.block_id:
if self.update_item_parent(item_location, original_parent_location, source_item.parent, user_id):
delete_draft_only(Location.from_string(child_location))
delete_draft_only(BlockUsageLocator.from_string(child_location))
def _query_children_for_cache_children(self, course_key, items):
# first get non-draft in a round-trip
@@ -848,7 +848,7 @@ class DraftModuleStore(MongoModuleStore):
to_process_dict = {}
for non_draft in to_process_non_drafts:
to_process_dict[Location._from_deprecated_son(non_draft["_id"], course_key.run)] = non_draft
to_process_dict[BlockUsageLocator._from_deprecated_son(non_draft["_id"], course_key.run)] = non_draft
if self.get_branch_setting() == ModuleStoreEnum.Branch.draft_preferred:
# now query all draft content in another round-trip
@@ -865,7 +865,7 @@ class DraftModuleStore(MongoModuleStore):
# with the draft. This is because the semantics of the DraftStore is to
# always return the draft - if available
for draft in to_process_drafts:
draft_loc = Location._from_deprecated_son(draft["_id"], course_key.run)
draft_loc = BlockUsageLocator._from_deprecated_son(draft["_id"], course_key.run)
draft_as_non_draft_loc = as_published(draft_loc)
# does non-draft exist in the collection

View File

@@ -18,7 +18,7 @@ from mock import patch
from nose.tools import assert_less_equal, assert_greater_equal
import dogstats_wrapper as dog_stats_api
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator
from opaque_keys.edx.keys import UsageKey
from xblock.core import XBlock
from xmodule.modulestore import prefer_xmodules, ModuleStoreEnum
@@ -116,7 +116,7 @@ class CourseFactory(XModuleFactory):
# because the factory provides a default 'number' arg, prefer the non-defaulted 'course' arg if any
number = kwargs.pop('course', kwargs.pop('number', None))
store = kwargs.pop('modulestore')
name = kwargs.get('name', kwargs.get('run', Location.clean(kwargs.get('display_name'))))
name = kwargs.get('name', kwargs.get('run', BlockUsageLocator.clean(kwargs.get('display_name'))))
run = kwargs.pop('run', name)
user_id = kwargs.pop('user_id', ModuleStoreEnum.UserID.test)
emit_signals = kwargs.pop('emit_signals', False)

View File

@@ -25,12 +25,10 @@ from xblock.exceptions import InvalidScopeError
from xmodule.tests import DATA_DIR
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locations import Location
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.mongo import MongoKeyValueStore
from xmodule.modulestore.draft import DraftModuleStore
from opaque_keys.edx.locations import AssetLocation
from opaque_keys.edx.locator import LibraryLocator, CourseLocator
from opaque_keys.edx.locator import AssetLocator, BlockUsageLocator, CourseLocator, LibraryLocator
from opaque_keys.edx.keys import UsageKey
from xmodule.modulestore.xml_exporter import export_course_to_xml
from xmodule.modulestore.xml_importer import import_course_from_xml, perform_xlint
@@ -320,15 +318,18 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
def test_loads(self):
assert_not_none(
self.draft_store.get_item(Location('edX', 'toy', '2012_Fall', 'course', '2012_Fall'))
self.draft_store.get_item(BlockUsageLocator(CourseLocator('edX', 'toy', '2012_Fall', deprecated=True),
'course', '2012_Fall', deprecated=True))
)
assert_not_none(
self.draft_store.get_item(Location('edX', 'simple', '2012_Fall', 'course', '2012_Fall')),
self.draft_store.get_item(BlockUsageLocator(CourseLocator('edX', 'simple', '2012_Fall', deprecated=True),
'course', '2012_Fall', deprecated=True)),
)
assert_not_none(
self.draft_store.get_item(Location('edX', 'toy', '2012_Fall', 'video', 'Welcome')),
self.draft_store.get_item(BlockUsageLocator(CourseLocator('edX', 'toy', '2012_Fall', deprecated=True),
'video', 'Welcome', deprecated=True)),
)
def test_unicode_loads(self):
@@ -336,30 +337,43 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
Test that getting items from the test_unicode course works
"""
assert_not_none(
self.draft_store.get_item(Location('edX', 'test_unicode', '2012_Fall', 'course', '2012_Fall')),
self.draft_store.get_item(
BlockUsageLocator(CourseLocator('edX', 'test_unicode', '2012_Fall', deprecated=True),
'course', '2012_Fall', deprecated=True)),
)
# All items with ascii-only filenames should load properly.
assert_not_none(
self.draft_store.get_item(Location('edX', 'test_unicode', '2012_Fall', 'video', 'Welcome')),
self.draft_store.get_item(
BlockUsageLocator(CourseLocator('edX', 'test_unicode', '2012_Fall', deprecated=True),
'video', 'Welcome', deprecated=True)),
)
assert_not_none(
self.draft_store.get_item(Location('edX', 'test_unicode', '2012_Fall', 'video', 'Welcome')),
self.draft_store.get_item(
BlockUsageLocator(CourseLocator('edX', 'test_unicode', '2012_Fall', deprecated=True),
'video', 'Welcome', deprecated=True)),
)
assert_not_none(
self.draft_store.get_item(Location('edX', 'test_unicode', '2012_Fall', 'chapter', 'Overview')),
self.draft_store.get_item(
BlockUsageLocator(CourseLocator('edX', 'test_unicode', '2012_Fall', deprecated=True),
'chapter', 'Overview', deprecated=True)),
)
def test_find_one(self):
assert_not_none(
self.draft_store._find_one(Location('edX', 'toy', '2012_Fall', 'course', '2012_Fall')),
self.draft_store._find_one(
BlockUsageLocator(CourseLocator('edX', 'toy', '2012_Fall', deprecated=True),
'course', '2012_Fall', deprecated=True)),
)
assert_not_none(
self.draft_store._find_one(Location('edX', 'simple', '2012_Fall', 'course', '2012_Fall')),
self.draft_store._find_one(
BlockUsageLocator(CourseLocator('edX', 'simple', '2012_Fall', deprecated=True),
'course', '2012_Fall', deprecated=True)),
)
assert_not_none(
self.draft_store._find_one(Location('edX', 'toy', '2012_Fall', 'video', 'Welcome')),
self.draft_store._find_one(BlockUsageLocator(CourseLocator('edX', 'toy', '2012_Fall', deprecated=True),
'video', 'Welcome', deprecated=True)),
)
def test_xlinter(self):
@@ -381,7 +395,8 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
"""
Test getting, setting, and defaulting the locked attr and arbitrary attrs.
"""
location = Location('edX', 'toy', '2012_Fall', 'course', '2012_Fall')
location = BlockUsageLocator(CourseLocator('edX', 'toy', '2012_Fall', deprecated=True),
'course', '2012_Fall', deprecated=True)
course_content, __ = self.content_store.get_all_content_for_course(location.course_key)
assert_true(len(course_content) > 0)
filter_params = _build_requested_filter('Images')
@@ -391,7 +406,7 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
# a bit overkill, could just do for content[0]
for content in course_content:
assert not content.get('locked', False)
asset_key = AssetLocation._from_deprecated_son(content.get('content_son', content['_id']), location.run)
asset_key = AssetLocator._from_deprecated_son(content.get('content_son', content['_id']), location.run)
assert not self.content_store.get_attr(asset_key, 'locked', False)
attrs = self.content_store.get_attrs(asset_key)
assert_in('uploadDate', attrs)
@@ -404,7 +419,7 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
self.content_store.set_attrs(asset_key, {'miscel': 99})
assert_equals(self.content_store.get_attr(asset_key, 'miscel'), 99)
asset_key = AssetLocation._from_deprecated_son(
asset_key = AssetLocator._from_deprecated_son(
course_content[0].get('content_son', course_content[0]['_id']),
location.run
)
@@ -418,26 +433,27 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
)
assert_raises(
NotFoundError, self.content_store.get_attr,
Location('bogus', 'bogus', 'bogus', 'asset', 'bogus'),
BlockUsageLocator(CourseLocator('bogus', 'bogus', 'bogus'), 'asset', 'bogus'),
'displayname'
)
assert_raises(
NotFoundError, self.content_store.set_attr,
Location('bogus', 'bogus', 'bogus', 'asset', 'bogus'),
BlockUsageLocator(CourseLocator('bogus', 'bogus', 'bogus'), 'asset', 'bogus'),
'displayname', 'hello'
)
assert_raises(
NotFoundError, self.content_store.get_attrs,
Location('bogus', 'bogus', 'bogus', 'asset', 'bogus')
BlockUsageLocator(CourseLocator('bogus', 'bogus', 'bogus'), 'asset', 'bogus')
)
assert_raises(
NotFoundError, self.content_store.set_attrs,
Location('bogus', 'bogus', 'bogus', 'asset', 'bogus'),
BlockUsageLocator(CourseLocator('bogus', 'bogus', 'bogus'), 'asset', 'bogus'),
{'displayname': 'hello'}
)
assert_raises(
NotFoundError, self.content_store.set_attrs,
Location('bogus', 'bogus', 'bogus', 'asset', None),
BlockUsageLocator(CourseLocator('bogus', 'bogus', 'bogus', deprecated=True),
'asset', None, deprecated=True),
{'displayname': 'hello'}
)
@@ -626,11 +642,16 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
self.draft_store.create_course(org, course, run, user_id)
locations = {
'grandparent': Location(org, course, run, 'chapter', 'grandparent'),
'parent_sibling': Location(org, course, run, 'sequential', 'parent_sibling'),
'parent': Location(org, course, run, 'sequential', 'parent'),
'child_sibling': Location(org, course, run, 'vertical', 'child_sibling'),
'child': Location(org, course, run, 'vertical', 'child'),
'grandparent': BlockUsageLocator(CourseLocator(org, course, run, deprecated=True),
'chapter', 'grandparent', deprecated=True),
'parent_sibling': BlockUsageLocator(CourseLocator(org, course, run, deprecated=True),
'sequential', 'parent_sibling', deprecated=True),
'parent': BlockUsageLocator(CourseLocator(org, course, run, deprecated=True),
'sequential', 'parent', deprecated=True),
'child_sibling': BlockUsageLocator(CourseLocator(org, course, run, deprecated=True),
'vertical', 'child_sibling', deprecated=True),
'child': BlockUsageLocator(CourseLocator(org, course, run, deprecated=True),
'vertical', 'child', deprecated=True),
}
for key in locations:
@@ -660,7 +681,8 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
"""
# Insert the test block directly into the module store
location = Location('edX', 'migration', '2012_Fall', 'html', 'test_html')
location = BlockUsageLocator(CourseLocator('edX', 'migration', '2012_Fall', deprecated=True),
'html', 'test_html', deprecated=True)
published_date = datetime(1970, 1, 1, tzinfo=UTC)
published_by = 123
self.draft_store._update_single_item(

View File

@@ -6,7 +6,6 @@ from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from xblock.fields import String, Scope, ScopeIds, List
from xblock.runtime import Runtime, KvsFieldData, DictKeyValueStore
from xmodule.x_module import XModuleMixin
from opaque_keys.edx.locations import Location
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.inheritance import InheritanceMixin
from xmodule.modulestore.xml_importer import (
@@ -141,7 +140,7 @@ class RemapNamespaceTest(ModuleStoreNoSettings):
def test_remap_namespace_native_xblock(self):
# Set the XBlock's location
self.xblock.location = Location("org", "import", "run", "category", "stubxblock")
self.xblock.location = BlockUsageLocator(CourseLocator("org", "import", "run"), "category", "stubxblock")
# Explicitly set the content and settings fields
self.xblock.test_content_field = "Explicitly set"
@@ -180,13 +179,13 @@ class RemapNamespaceTest(ModuleStoreNoSettings):
def test_remap_namespace_native_xblock_default_values(self):
# Set the XBlock's location
self.xblock.location = Location("org", "import", "run", "category", "stubxblock")
self.xblock.location = BlockUsageLocator(CourseLocator("org", "import", "run"), "category", "stubxblock")
# Do NOT set any values, so the fields should use the defaults
self.xblock.save()
# Remap the namespace
target_location_namespace = Location("org", "course", "run", "category", "stubxblock")
target_location_namespace = BlockUsageLocator(CourseLocator("org", "course", "run"), "category", "stubxblock")
new_version = _update_and_import_module(
self.xblock,
modulestore(),
@@ -214,11 +213,11 @@ class RemapNamespaceTest(ModuleStoreNoSettings):
def test_remap_namespace_native_xblock_inherited_values(self):
# Set the XBlock's location
self.xblock.location = Location("org", "import", "run", "category", "stubxblock")
self.xblock.location = BlockUsageLocator(CourseLocator("org", "import", "run"), "category", "stubxblock")
self.xblock.save()
# Remap the namespace
target_location_namespace = Location("org", "course", "run", "category", "stubxblock")
target_location_namespace = BlockUsageLocator(CourseLocator("org", "course", "run"), "category", "stubxblock")
new_version = _update_and_import_module(
self.xblock,
modulestore(),
@@ -242,7 +241,7 @@ class RemapNamespaceTest(ModuleStoreNoSettings):
# TypeError.
# Set the XBlock's location
self.xblock.location = Location("org", "import", "run", "category", "stubxblock")
self.xblock.location = BlockUsageLocator(CourseLocator("org", "import", "run"), "category", "stubxblock")
# Explicitly set the content field
self.xblock.test_content_field = ['Explicitly set']
self.xblock.save()
@@ -305,7 +304,7 @@ class UpdateLocationTest(ModuleStoreNoSettings):
def test_update_locations_native_xblock(self):
""" Update locations updates location and keeps values and "is_set_on" status """
# Set the XBlock's location
self.xblock.location = Location("org", "import", "run", "category", "stubxblock")
self.xblock.location = BlockUsageLocator(CourseLocator("org", "import", "run"), "category", "stubxblock")
# Explicitly set the content, settings and children fields
self.xblock.test_content_field = 'Explicitly set'

View File

@@ -27,7 +27,6 @@ from xmodule.modulestore.xml_exporter import DEFAULT_CONTENT_FIELDS
from xmodule.modulestore import ModuleStoreEnum, ModuleStoreReadBase, LIBRARY_ROOT, COURSE_ROOT
from xmodule.tabs import CourseTabList
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import CourseLocator, LibraryLocator, BlockUsageLocator
from xblock.field_data import DictFieldData
@@ -106,8 +105,8 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
# Things to try to get a name, in order (key, cleaning function, remove key after reading?)
lookups = [('url_name', id, False),
('slug', id, True),
('name', Location.clean, False),
('display_name', Location.clean, False)]
('name', BlockUsageLocator.clean, False),
('display_name', BlockUsageLocator.clean, False)]
url_name = None
for key, clean, remove in lookups:
@@ -533,7 +532,7 @@ class XMLModuleStore(ModuleStoreReadBase):
)
)
url_name = Location.clean(course_data.get('name'))
url_name = BlockUsageLocator.clean(course_data.get('name'))
tracker("'name' is deprecated for module xml. Please use "
"display_name and url_name.")
else:

View File

@@ -8,7 +8,7 @@ from mock import Mock
from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds
from xmodule.annotatable_module import AnnotatableModule
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from . import get_test_system
@@ -37,7 +37,7 @@ class AnnotatableModuleTestCase(unittest.TestCase):
Mock(),
get_test_system(),
DictFieldData({'data': self.sample_xml}),
ScopeIds(None, None, None, Location('org', 'course', 'run', 'category', 'name', None))
ScopeIds(None, None, None, BlockUsageLocator(CourseLocator('org', 'course', 'run'), 'category', 'name'))
)
def test_annotation_data_attr(self):

View File

@@ -28,7 +28,7 @@ from capa.responsetypes import (StudentInputError, LoncapaProblemError,
ResponseError)
from capa.xqueue_interface import XQueueInterface
from xmodule.capa_module import CapaModule, CapaDescriptor, ComplexEncoder
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds
from xblock.scorable import Score
@@ -101,13 +101,11 @@ class CapaFactory(object):
attempts: also added to instance state. Will be converted to an int.
"""
location = Location(
"edX",
"capa_test",
"2012_Fall",
location = BlockUsageLocator(
CourseLocator("edX", "capa_test", "2012_Fall", deprecated=True),
"problem",
"SampleProblem{0}".format(cls.next_num()),
None
deprecated=True,
)
if xml is None:
xml = cls.sample_problem_xml

View File

@@ -10,8 +10,7 @@ from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds
from xmodule.error_module import NonStaffErrorDescriptor
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from xmodule.modulestore.xml import ImportSystem, XMLModuleStore, CourseLocationManager
from xmodule.conditional_module import ConditionalDescriptor
from xmodule.tests import DATA_DIR, get_test_system, get_test_descriptor_system
@@ -65,7 +64,8 @@ class ConditionalFactory(object):
descriptor_system = get_test_descriptor_system()
# construct source descriptor and module:
source_location = Location("edX", "conditional_test", "test_run", "problem", "SampleProblem", None)
source_location = BlockUsageLocator(CourseLocator("edX", "conditional_test", "test_run", deprecated=True),
"problem", "SampleProblem", deprecated=True)
if source_is_error_module:
# Make an error descriptor and module
source_descriptor = NonStaffErrorDescriptor.from_xml(
@@ -111,7 +111,8 @@ class ConditionalFactory(object):
system.descriptor_runtime = descriptor_system
# construct conditional module:
cond_location = Location("edX", "conditional_test", "test_run", "conditional", "SampleConditional", None)
cond_location = BlockUsageLocator(CourseLocator("edX", "conditional_test", "test_run", deprecated=True),
"conditional", "SampleConditional", deprecated=True)
field_data = DictFieldData({
'data': '<conditional/>',
'conditional_attr': 'attempted',
@@ -245,7 +246,7 @@ class ConditionalModuleXmlTest(unittest.TestCase):
print "id: ", course.id
def inner_get_module(descriptor):
if isinstance(descriptor, Location):
if isinstance(descriptor, BlockUsageLocator):
location = descriptor
descriptor = self.modulestore.get_item(location, depth=None)
descriptor.xmodule_runtime = get_test_system()
@@ -255,7 +256,8 @@ class ConditionalModuleXmlTest(unittest.TestCase):
# edx - HarvardX
# cond_test - ER22x
location = Location("HarvardX", "ER22x", "2013_Spring", "conditional", "condone")
location = BlockUsageLocator(CourseLocator("HarvardX", "ER22x", "2013_Spring", deprecated=True),
"conditional", "condone", deprecated=True)
def replace_urls(text, staticfiles_prefix=None, replace_prefix='/static/', course_namespace=None):
return text
@@ -308,7 +310,8 @@ class ConditionalModuleXmlTest(unittest.TestCase):
via generating UsageKeys from the values in xml_attributes['sources']
"""
dummy_system = Mock()
dummy_location = Location("edX", "conditional_test", "test_run", "conditional", "SampleConditional", None)
dummy_location = BlockUsageLocator(CourseLocator("edX", "conditional_test", "test_run"),
"conditional", "SampleConditional")
dummy_scope_ids = ScopeIds(None, None, dummy_location, dummy_location)
dummy_field_data = DictFieldData({
'data': '<conditional/>',
@@ -329,7 +332,8 @@ class ConditionalModuleXmlTest(unittest.TestCase):
def test_conditional_module_parse_sources(self):
dummy_system = Mock()
dummy_location = Location("edX", "conditional_test", "test_run", "conditional", "SampleConditional", None)
dummy_location = BlockUsageLocator(CourseLocator("edX", "conditional_test", "test_run"),
"conditional", "SampleConditional")
dummy_scope_ids = ScopeIds(None, None, dummy_location, dummy_location)
dummy_field_data = DictFieldData({
'data': '<conditional/>',

View File

@@ -9,7 +9,7 @@ from path import Path as path
from xmodule.contentstore.content import StaticContent, StaticContentStream
from xmodule.contentstore.content import ContentStore
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locations import AssetLocation
from opaque_keys.edx.locator import AssetLocator, CourseLocator
from xmodule.static_content import _write_js, _list_descriptors
SAMPLE_STRING = """
@@ -118,11 +118,12 @@ class ContentTest(unittest.TestCase):
@ddt.unpack
def test_generate_thumbnail_image(self, original_filename, thumbnail_filename):
content_store = ContentStore()
content = Content(AssetLocation(u'mitX', u'800', u'ignore_run', u'asset', original_filename), None)
content = Content(AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'asset', original_filename),
None)
(thumbnail_content, thumbnail_file_location) = content_store.generate_thumbnail(content)
self.assertIsNone(thumbnail_content)
self.assertEqual(
AssetLocation(u'mitX', u'800', u'ignore_run', u'thumbnail', thumbnail_filename),
AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'thumbnail', thumbnail_filename),
thumbnail_file_location
)
@@ -134,7 +135,8 @@ class ContentTest(unittest.TestCase):
image_class_mock.open.return_value = mock_image
content_store = ContentStore()
content = Content(AssetLocation(u'mitX', u'800', u'ignore_run', u'asset', "monsters.jpg"), "image/jpeg")
content = Content(AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'asset', "monsters.jpg"),
"image/jpeg")
content.data = 'mock data'
content_store.generate_thumbnail(content)
self.assertTrue(image_class_mock.open.called, "Image.open not called")
@@ -146,12 +148,13 @@ class ContentTest(unittest.TestCase):
content_store = ContentStore()
content_store.save = Mock()
thumbnail_filename = u'test.svg'
content = Content(AssetLocation(u'mitX', u'800', u'ignore_run', u'asset', u'test.svg'), 'image/svg+xml')
content = Content(AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'asset', u'test.svg'),
'image/svg+xml')
content.data = 'mock svg file'
(thumbnail_content, thumbnail_file_location) = content_store.generate_thumbnail(content)
self.assertEqual(thumbnail_content.data.read(), b'mock svg file')
self.assertEqual(
AssetLocation(u'mitX', u'800', u'ignore_run', u'thumbnail', thumbnail_filename),
AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'thumbnail', thumbnail_filename),
thumbnail_file_location
)
@@ -162,14 +165,16 @@ class ContentTest(unittest.TestCase):
CourseKey.from_string('mitX/400/ignore'), 'subs__1eo_jXvZnE .srt.sjson'
)
self.assertEqual(
AssetLocation(u'mitX', u'400', u'ignore', u'asset', u'subs__1eo_jXvZnE_.srt.sjson', None),
AssetLocator(CourseLocator(u'mitX', u'400', u'ignore', deprecated=True),
u'asset', u'subs__1eo_jXvZnE_.srt.sjson'),
asset_location
)
def test_get_location_from_path(self):
asset_location = StaticContent.get_location_from_path(u'/c4x/a/b/asset/images_course_image.jpg')
self.assertEqual(
AssetLocation(u'a', u'b', None, u'asset', u'images_course_image.jpg', None),
AssetLocator(CourseLocator(u'a', u'b', None, deprecated=True),
u'asset', u'images_course_image.jpg', deprecated=True),
asset_location
)

View File

@@ -15,7 +15,7 @@ from mock import Mock
import xmodule
from xmodule.capa_module import CapaModule
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds
from xblock.scorable import Score
@@ -85,7 +85,8 @@ class CapaFactoryWithDelay(object):
"""
Optional parameters here are cut down to what we actually use vs. the regular CapaFactory.
"""
location = Location("edX", "capa_test", "run", "problem", "SampleProblem{0}".format(cls.next_num()))
location = BlockUsageLocator(CourseLocator('edX', 'capa_test', 'run', deprecated=True),
'problem', 'SampleProblem{0}'.format(cls.next_num()), deprecated=True)
field_data = {'data': cls.sample_problem_xml}
if max_attempts is not None:

View File

@@ -5,7 +5,7 @@ import logging
from mock import Mock
from pkg_resources import resource_string
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from xmodule.editing_module import TabsEditingDescriptor
from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds
@@ -55,7 +55,9 @@ class TabsEditingDescriptorTestCase(unittest.TestCase):
TabsEditingDescriptor.tabs = self.tabs
self.descriptor = system.construct_xblock_from_class(
TabsEditingDescriptor,
scope_ids=ScopeIds(None, None, None, Location('org', 'course', 'run', 'category', 'name', 'revision')),
scope_ids=ScopeIds(None, None, None,
BlockUsageLocator(CourseLocator('org', 'course', 'run', branch='revision'),
'category', 'name')),
field_data=DictFieldData({}),
)

View File

@@ -5,8 +5,7 @@ import unittest
from xmodule.tests import get_test_system
from xmodule.error_module import ErrorDescriptor, ErrorModule, NonStaffErrorDescriptor
from xmodule.modulestore.xml import CourseLocationManager
from opaque_keys.edx.locator import CourseLocator
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from xmodule.x_module import XModuleDescriptor, XModule, STUDENT_VIEW
from mock import MagicMock, Mock, patch
from xblock.runtime import Runtime, IdReader
@@ -129,7 +128,8 @@ class TestErrorModuleConstruction(unittest.TestCase):
self.descriptor = BrokenDescriptor(
TestRuntime(Mock(spec=IdReader), field_data),
field_data,
ScopeIds(None, None, None, Location('org', 'course', 'run', 'broken', 'name', None))
ScopeIds(None, None, None,
BlockUsageLocator(CourseLocator('org', 'course', 'run'), 'broken', 'name'))
)
self.descriptor.xmodule_runtime = TestRuntime(Mock(spec=IdReader), field_data)
self.descriptor.xmodule_runtime.error_descriptor_class = ErrorDescriptor

View File

@@ -20,7 +20,7 @@ from xblock.core import XBlock
from xblock.fields import String, Scope, Integer
from xblock.test.tools import blocks_are_equivalent
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from xmodule.modulestore import EdxJSONEncoder
from xmodule.modulestore.xml import XMLModuleStore
from xmodule.tests import DATA_DIR
@@ -171,10 +171,10 @@ class TestEdxJsonEncoder(unittest.TestCase):
self.null_utc_tz = NullTZ()
def test_encode_location(self):
loc = Location('org', 'course', 'run', 'category', 'name', None)
loc = BlockUsageLocator(CourseLocator('org', 'course', 'run'), 'category', 'name')
self.assertEqual(text_type(loc), self.encoder.default(loc))
loc = Location('org', 'course', 'run', 'category', 'name', 'version')
loc = BlockUsageLocator(CourseLocator('org', 'course', 'run', branch='version'), 'category', 'name')
self.assertEqual(text_type(loc), self.encoder.default(loc))
def test_encode_naive_datetime(self):

View File

@@ -12,7 +12,7 @@ from pytz import UTC
from six import text_type
from xmodule.xml_module import is_pointer_tag
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from xmodule.modulestore import only_xmodules
from xmodule.modulestore.xml import ImportSystem, XMLModuleStore, LibraryXMLModuleStore
from xmodule.modulestore.inheritance import compute_inherited_metadata
@@ -482,12 +482,14 @@ class ImportTestCase(BaseCourseTestCase):
modulestore = XMLModuleStore(DATA_DIR, source_dirs=['toy'])
location_tab_syllabus = Location("edX", "toy", "2012_Fall", "static_tab", "syllabus", None)
location_tab_syllabus = BlockUsageLocator(CourseLocator("edX", "toy", "2012_Fall", deprecated=True),
"static_tab", "syllabus", deprecated=True)
toy_tab_syllabus = modulestore.get_item(location_tab_syllabus)
self.assertEqual(toy_tab_syllabus.display_name, 'Syllabus')
self.assertEqual(toy_tab_syllabus.course_staff_only, False)
location_tab_resources = Location("edX", "toy", "2012_Fall", "static_tab", "resources", None)
location_tab_resources = BlockUsageLocator(CourseLocator("edX", "toy", "2012_Fall", deprecated=True),
"static_tab", "resources", deprecated=True)
toy_tab_resources = modulestore.get_item(location_tab_resources)
self.assertEqual(toy_tab_resources.display_name, 'Resources')
self.assertEqual(toy_tab_resources.course_staff_only, True)
@@ -502,9 +504,11 @@ class ImportTestCase(BaseCourseTestCase):
modulestore = XMLModuleStore(DATA_DIR, source_dirs=['toy', 'two_toys'])
location = Location("edX", "toy", "2012_Fall", "video", "Welcome", None)
location = BlockUsageLocator(CourseLocator("edX", "toy", "2012_Fall", deprecated=True),
"video", "Welcome", deprecated=True)
toy_video = modulestore.get_item(location)
location_two = Location("edX", "toy", "TT_2012_Fall", "video", "Welcome", None)
location_two = BlockUsageLocator(CourseLocator("edX", "toy", "TT_2012_Fall", deprecated=True),
"video", "Welcome", deprecated=True)
two_toy_video = modulestore.get_item(location_two)
self.assertEqual(toy_video.youtube_id_1_0, "p2Q6BrNhdh8")
self.assertEqual(two_toy_video.youtube_id_1_0, "p2Q6BrNhdh9")

View File

@@ -25,7 +25,7 @@ from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds
from xblock.core import XBlock
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from xmodule.x_module import ModuleSystem, XModule, XModuleDescriptor, DescriptorSystem, STUDENT_VIEW, STUDIO_VIEW
from xmodule.annotatable_module import AnnotatableDescriptor
@@ -188,7 +188,7 @@ class LeafDescriptorFactory(Factory):
@lazy_attribute
def location(self):
return Location('org', 'course', 'run', 'category', self.url_name, None)
return BlockUsageLocator(CourseLocator('org', 'course', 'run'), 'category', self.url_name)
@lazy_attribute
def block_type(self):

View File

@@ -6,7 +6,7 @@ import json
from django.db.models import Count
from django.utils.translation import ugettext as _
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator
from six import text_type
from courseware import models
@@ -435,7 +435,7 @@ def get_students_opened_subsection(request, csv=False):
If 'csv' is True, returns a header array, and an array of arrays in the format:
student names, usernames for CSV download.
"""
module_state_key = Location.from_string(request.GET.get('module_id'))
module_state_key = BlockUsageLocator.from_string(request.GET.get('module_id'))
csv = request.GET.get('csv')
# Query for "opened a subsection" students
@@ -487,7 +487,7 @@ def get_students_problem_grades(request, csv=False):
If 'csv' is True, returns a header array, and an array of arrays in the format:
student names, usernames, grades, percents for CSV download.
"""
module_state_key = Location.from_string(request.GET.get('module_id'))
module_state_key = BlockUsageLocator.from_string(request.GET.get('module_id'))
csv = request.GET.get('csv')
# Query for "problem grades" students

View File

@@ -23,7 +23,7 @@ from milestones.tests.utils import MilestonesTestCaseMixin
from mock import MagicMock, PropertyMock, create_autospec, patch
from nose.plugins.attrib import attr
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locations import Location
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from pytz import UTC
from six import text_type
from web_fragments.fragment import Fragment
@@ -187,7 +187,8 @@ class TestJumpTo(ModuleStoreTestCase):
self.assertRedirects(response, expected_redirect_url(expected), status_code=302, target_status_code=302)
def test_jumpto_id_invalid_location(self):
location = Location('edX', 'toy', 'NoSuchPlace', None, None, None)
location = BlockUsageLocator(CourseLocator('edX', 'toy', 'NoSuchPlace', deprecated=True),
None, None, deprecated=True)
jumpto_url = '{0}/{1}/jump_to_id/{2}'.format('/courses', unicode(self.course_key), unicode(location))
response = self.client.get(jumpto_url)
self.assertEqual(response.status_code, 404)