From 2bd0c3d9a1a4fec93f8e338225a2f4830c8c098a Mon Sep 17 00:00:00 2001 From: Jeremy Bowman Date: Fri, 2 Feb 2018 17:50:21 -0500 Subject: [PATCH] PLAT-1917 Stop using deprecated Location and AssetLocation --- .../contentstore/tests/test_core_caching.py | 6 +- cms/djangoapps/contentstore/views/course.py | 4 +- .../contentstore/views/tests/test_item.py | 4 +- .../xmodule/xmodule/modulestore/mongo/base.py | 20 ++--- .../xmodule/modulestore/mongo/draft.py | 14 ++-- .../xmodule/modulestore/tests/factories.py | 4 +- .../xmodule/modulestore/tests/test_mongo.py | 76 ++++++++++++------- .../modulestore/tests/test_xml_importer.py | 15 ++-- common/lib/xmodule/xmodule/modulestore/xml.py | 7 +- .../xmodule/tests/test_annotatable_module.py | 4 +- .../xmodule/xmodule/tests/test_capa_module.py | 10 +-- .../xmodule/xmodule/tests/test_conditional.py | 20 +++-- .../lib/xmodule/xmodule/tests/test_content.py | 21 +++-- .../tests/test_delay_between_attempts.py | 5 +- .../xmodule/tests/test_editing_module.py | 6 +- .../xmodule/tests/test_error_module.py | 6 +- .../lib/xmodule/xmodule/tests/test_export.py | 6 +- .../lib/xmodule/xmodule/tests/test_import.py | 14 ++-- .../xmodule/tests/test_xblock_wrappers.py | 4 +- .../class_dashboard/dashboard_data.py | 6 +- lms/djangoapps/courseware/tests/test_views.py | 5 +- 21 files changed, 146 insertions(+), 111 deletions(-) diff --git a/cms/djangoapps/contentstore/tests/test_core_caching.py b/cms/djangoapps/contentstore/tests/test_core_caching.py index f2d08dc001..6c606d596c 100644 --- a/cms/djangoapps/contentstore/tests/test_core_caching.py +++ b/cms/djangoapps/contentstore/tests/test_core_caching.py @@ -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): diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index b747a8bdc9..c960e7486a 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -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 diff --git a/cms/djangoapps/contentstore/views/tests/test_item.py b/cms/djangoapps/contentstore/views/tests/test_item.py index 0b00bceeec..da9f24aefd 100644 --- a/cms/djangoapps/contentstore/views/tests/test_item.py +++ b/cms/djangoapps/contentstore/views/tests/test_item.py @@ -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() diff --git a/common/lib/xmodule/xmodule/modulestore/mongo/base.py b/common/lib/xmodule/xmodule/modulestore/mongo/base.py index f39ff42dd3..48978c6d7f 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongo/base.py +++ b/common/lib/xmodule/xmodule/modulestore/mongo/base.py @@ -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 ] diff --git a/common/lib/xmodule/xmodule/modulestore/mongo/draft.py b/common/lib/xmodule/xmodule/modulestore/mongo/draft.py index d8146f3732..14a7b55f44 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongo/draft.py +++ b/common/lib/xmodule/xmodule/modulestore/mongo/draft.py @@ -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 diff --git a/common/lib/xmodule/xmodule/modulestore/tests/factories.py b/common/lib/xmodule/xmodule/modulestore/tests/factories.py index 22528573f6..0a6ec26ba3 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/factories.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/factories.py @@ -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) diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py index 8840633c13..54c17f41a6 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py @@ -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( diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_xml_importer.py b/common/lib/xmodule/xmodule/modulestore/tests/test_xml_importer.py index bdb6db4ebd..6f85d7211c 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_xml_importer.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_xml_importer.py @@ -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' diff --git a/common/lib/xmodule/xmodule/modulestore/xml.py b/common/lib/xmodule/xmodule/modulestore/xml.py index fbcfd25a93..6934b668cd 100644 --- a/common/lib/xmodule/xmodule/modulestore/xml.py +++ b/common/lib/xmodule/xmodule/modulestore/xml.py @@ -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: diff --git a/common/lib/xmodule/xmodule/tests/test_annotatable_module.py b/common/lib/xmodule/xmodule/tests/test_annotatable_module.py index 33b66d70ab..4e6768444b 100644 --- a/common/lib/xmodule/xmodule/tests/test_annotatable_module.py +++ b/common/lib/xmodule/xmodule/tests/test_annotatable_module.py @@ -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): diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py index 81c29787aa..d5019a57cc 100644 --- a/common/lib/xmodule/xmodule/tests/test_capa_module.py +++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py @@ -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 diff --git a/common/lib/xmodule/xmodule/tests/test_conditional.py b/common/lib/xmodule/xmodule/tests/test_conditional.py index 2029c81efa..a1b78cc888 100644 --- a/common/lib/xmodule/xmodule/tests/test_conditional.py +++ b/common/lib/xmodule/xmodule/tests/test_conditional.py @@ -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_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': '', @@ -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': '', diff --git a/common/lib/xmodule/xmodule/tests/test_content.py b/common/lib/xmodule/xmodule/tests/test_content.py index ef34f67285..657d6218b8 100644 --- a/common/lib/xmodule/xmodule/tests/test_content.py +++ b/common/lib/xmodule/xmodule/tests/test_content.py @@ -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 ) diff --git a/common/lib/xmodule/xmodule/tests/test_delay_between_attempts.py b/common/lib/xmodule/xmodule/tests/test_delay_between_attempts.py index 0bc983d6da..24bb1d6aff 100644 --- a/common/lib/xmodule/xmodule/tests/test_delay_between_attempts.py +++ b/common/lib/xmodule/xmodule/tests/test_delay_between_attempts.py @@ -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: diff --git a/common/lib/xmodule/xmodule/tests/test_editing_module.py b/common/lib/xmodule/xmodule/tests/test_editing_module.py index 14578ca197..c0439040cd 100644 --- a/common/lib/xmodule/xmodule/tests/test_editing_module.py +++ b/common/lib/xmodule/xmodule/tests/test_editing_module.py @@ -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({}), ) diff --git a/common/lib/xmodule/xmodule/tests/test_error_module.py b/common/lib/xmodule/xmodule/tests/test_error_module.py index 34c558e3cc..731f26b11f 100644 --- a/common/lib/xmodule/xmodule/tests/test_error_module.py +++ b/common/lib/xmodule/xmodule/tests/test_error_module.py @@ -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 diff --git a/common/lib/xmodule/xmodule/tests/test_export.py b/common/lib/xmodule/xmodule/tests/test_export.py index 46f5742881..0f3b6b3f0b 100644 --- a/common/lib/xmodule/xmodule/tests/test_export.py +++ b/common/lib/xmodule/xmodule/tests/test_export.py @@ -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): diff --git a/common/lib/xmodule/xmodule/tests/test_import.py b/common/lib/xmodule/xmodule/tests/test_import.py index 56d32d62b6..cc7b90de57 100644 --- a/common/lib/xmodule/xmodule/tests/test_import.py +++ b/common/lib/xmodule/xmodule/tests/test_import.py @@ -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") diff --git a/common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py b/common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py index f25438d2c0..dc5c9034ca 100644 --- a/common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py +++ b/common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py @@ -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): diff --git a/lms/djangoapps/class_dashboard/dashboard_data.py b/lms/djangoapps/class_dashboard/dashboard_data.py index 39191d6803..0a068791ce 100644 --- a/lms/djangoapps/class_dashboard/dashboard_data.py +++ b/lms/djangoapps/class_dashboard/dashboard_data.py @@ -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 diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index fdbbac2076..7be32848cc 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -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)