Merge pull request #3931 from edx/sarina/fixup-external-opaque-keys-impls
Use external OpaqueKey implementations
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
from lettuce import world, step
|
||||
from component_settings_editor_helpers import enter_xml_in_advanced_problem
|
||||
from nose.tools import assert_true, assert_equal
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from contentstore.utils import reverse_usage_url
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from lettuce import world, step
|
||||
from common import *
|
||||
from terrain.steps import reload_the_page
|
||||
from selenium.common.exceptions import InvalidElementStateException
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from contentstore.utils import reverse_course_url
|
||||
from nose.tools import assert_in, assert_not_in, assert_equal, assert_not_equal # pylint: disable=E0611
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.xml_importer import check_module_metadata_editability
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
||||
@@ -6,9 +6,9 @@ from xmodule.modulestore.store_utilities import clone_course
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.contentstore.django import contentstore
|
||||
from student.roles import CourseInstructorRole, CourseStaffRole
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
#
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from .prompt import query_yes_no
|
||||
from contentstore.utils import delete_course_and_groups
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
||||
@@ -14,8 +14,8 @@ from courseware.courses import get_course_by_id
|
||||
|
||||
from contentstore.views import tabs
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
|
||||
|
||||
def print_course(course):
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from xmodule.contentstore.utils import empty_asset_trashcan
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from .prompt import query_yes_no
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
||||
@@ -6,10 +6,10 @@ import os
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from xmodule.modulestore.xml_exporter import export_to_xml
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from xmodule.contentstore.django import contentstore
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
||||
@@ -20,10 +20,10 @@ from django.core.management.base import BaseCommand, CommandError
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
import contentstore.git_export_utils as git_export_utils
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys import InvalidKeyError
|
||||
from contentstore.git_export_utils import GitExportError
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@ from django.contrib.auth.models import User
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.split_migrator import SplitMigrator
|
||||
from xmodule.modulestore.django import loc_mapper
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
def user_from_str(identifier):
|
||||
|
||||
@@ -5,7 +5,7 @@ is to delete the course from the split mongo datastore.
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from xmodule.modulestore.django import modulestore, loc_mapper
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.locator import CourseLocator
|
||||
from opaque_keys.edx.locator import CourseLocator
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
||||
@@ -18,7 +18,7 @@ from django.test.utils import override_settings
|
||||
from contentstore.tests.utils import CourseTestCase
|
||||
import contentstore.git_export_utils as git_export_utils
|
||||
from contentstore.git_export_utils import GitExportError
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
FEATURES_WITH_EXPORT_GIT = settings.FEATURES.copy()
|
||||
FEATURES_WITH_EXPORT_GIT['ENABLE_EXPORT_GIT'] = True
|
||||
|
||||
@@ -14,7 +14,7 @@ from contentstore.tests.modulestore_config import TEST_MODULESTORE
|
||||
from django_comment_common.utils import are_permissions_roles_seeded
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_MODULESTORE)
|
||||
|
||||
@@ -11,7 +11,7 @@ from contentstore.tests.modulestore_config import TEST_MODULESTORE
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from xmodule.modulestore.django import modulestore, clear_existing_modulestores
|
||||
from xmodule.modulestore.locator import CourseLocator
|
||||
from opaque_keys.edx.locator import CourseLocator
|
||||
# pylint: disable=E1101
|
||||
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ from xmodule.modulestore import mongo
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.inheritance import own_metadata
|
||||
from xmodule.modulestore.keys import UsageKey
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey, AssetLocation
|
||||
from opaque_keys.edx.keys import UsageKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey, AssetLocation
|
||||
from xmodule.modulestore.store_utilities import clone_course, delete_course
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
|
||||
|
||||
@@ -16,7 +16,7 @@ from student.roles import CourseInstructorRole, CourseStaffRole
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
TOTAL_COURSES_COUNT = 500
|
||||
USER_COURSES_COUNT = 50
|
||||
|
||||
@@ -6,7 +6,7 @@ from xmodule.course_module import CourseDescriptor
|
||||
from xmodule.modulestore.django import modulestore, loc_mapper, clear_existing_modulestores
|
||||
from xmodule.seq_module import SequenceDescriptor
|
||||
from xmodule.capa_module import CapaDescriptor
|
||||
from xmodule.modulestore.locator import BlockUsageLocator, LocalId
|
||||
from opaque_keys.edx.locator import BlockUsageLocator, LocalId
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError
|
||||
from xmodule.html_module import HtmlDescriptor
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
|
||||
@@ -17,7 +17,7 @@ from contentstore.tests.modulestore_config import TEST_MODULESTORE
|
||||
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.contentstore.django import contentstore
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey, AssetLocation
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey, AssetLocation
|
||||
from xmodule.modulestore.xml_importer import import_from_xml
|
||||
from xmodule.contentstore.content import StaticContent
|
||||
from xmodule.contentstore.django import _CONTENTSTORE
|
||||
|
||||
@@ -9,7 +9,7 @@ from django.contrib.auth.models import User
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from contentstore.tests.modulestore_config import TEST_MODULESTORE
|
||||
from contentstore.tests.utils import AjaxEnabledTestClient
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from contentstore.utils import reverse_url, reverse_course_url
|
||||
from student.roles import CourseInstructorRole, CourseStaffRole
|
||||
from contentstore.views.access import has_course_access
|
||||
|
||||
@@ -7,7 +7,7 @@ from contentstore.utils import delete_course_and_groups, reverse_url
|
||||
from courseware.tests.factories import UserFactory
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
from student.models import CourseEnrollment
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from django.test.utils import override_settings
|
||||
|
||||
from contentstore import utils
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class LMSLinksTestCase(TestCase):
|
||||
|
||||
@@ -12,7 +12,7 @@ from xmodule.contentstore.content import StaticContent
|
||||
from xmodule.contentstore.django import contentstore
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey, Location
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey, Location
|
||||
from xmodule.modulestore.store_utilities import delete_course
|
||||
from student.roles import CourseInstructorRole, CourseStaffRole
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ from xmodule.modulestore.django import modulestore
|
||||
from xmodule.contentstore.content import StaticContent
|
||||
from xmodule.exceptions import NotFoundError
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from xmodule.modulestore.keys import CourseKey, AssetKey
|
||||
from opaque_keys.edx.keys import CourseKey, AssetKey
|
||||
|
||||
from util.date_utils import get_default_time_display
|
||||
from util.json_request import JsonResponse
|
||||
|
||||
@@ -9,7 +9,7 @@ from django_future.csrf import ensure_csrf_cookie
|
||||
from edxmako.shortcuts import render_to_response
|
||||
from django.http import HttpResponseNotFound
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from contentstore.utils import get_modulestore, reverse_course_url
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ from contentstore.utils import get_lms_link_for_item, compute_publish_state, Pub
|
||||
from contentstore.views.helpers import get_parent_xblock
|
||||
|
||||
from models.settings.course_grading import CourseGradingModel
|
||||
from xmodule.modulestore.keys import UsageKey
|
||||
from opaque_keys.edx.keys import UsageKey
|
||||
|
||||
from .access import has_course_access
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
@@ -23,7 +23,7 @@ from xmodule.tabs import PDFTextbookTabs
|
||||
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.locations import Location, SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import Location, SlashSeparatedCourseKey
|
||||
|
||||
from contentstore.course_info_model import get_course_updates, update_course_updates, delete_course_update
|
||||
from contentstore.utils import (
|
||||
@@ -53,7 +53,7 @@ from django_comment_common.utils import seed_permissions_roles
|
||||
from student.models import CourseEnrollment
|
||||
from student.roles import CourseRole, UserBasedRole
|
||||
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from course_creators.views import get_course_creator_status, add_user_with_status_unrequested
|
||||
from contentstore import utils
|
||||
from student.roles import CourseInstructorRole, CourseStaffRole, CourseCreatorRole, GlobalStaff
|
||||
|
||||
@@ -14,7 +14,7 @@ from .access import has_course_access
|
||||
import contentstore.git_export_utils as git_export_utils
|
||||
from edxmako.shortcuts import render_to_response
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ from edxmako.shortcuts import render_to_response
|
||||
from xmodule.contentstore.django import contentstore
|
||||
from xmodule.exceptions import SerializationError
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from xmodule.modulestore.xml_importer import import_from_xml
|
||||
from xmodule.modulestore.xml_exporter import export_to_xml
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ from contentstore.views.preview import get_preview_fragment
|
||||
from edxmako.shortcuts import render_to_string
|
||||
from models.settings.course_grading import CourseGradingModel
|
||||
from cms.lib.xblock.runtime import handler_url, local_resource_url
|
||||
from xmodule.modulestore.keys import UsageKey, CourseKey
|
||||
from opaque_keys.edx.keys import UsageKey, CourseKey
|
||||
|
||||
__all__ = ['orphan_handler', 'xblock_handler', 'xblock_view_handler']
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ from xmodule_modifiers import replace_static_urls, wrap_xblock, wrap_fragment
|
||||
from xmodule.error_module import ErrorDescriptor
|
||||
from xmodule.exceptions import NotFoundError, ProcessingError
|
||||
from xmodule.modulestore.django import modulestore, ModuleI18nService
|
||||
from xmodule.modulestore.keys import UsageKey
|
||||
from opaque_keys.edx.keys import UsageKey
|
||||
from xmodule.x_module import ModuleSystem
|
||||
from xblock.runtime import KvsFieldData
|
||||
from xblock.django.request import webob_to_django_response, django_to_webob_request
|
||||
|
||||
@@ -13,7 +13,7 @@ from django.views.decorators.http import require_http_methods
|
||||
from edxmako.shortcuts import render_to_response
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.tabs import CourseTabList, StaticTab, CourseTab, InvalidTabsException
|
||||
from xmodule.modulestore.keys import CourseKey, UsageKey
|
||||
from opaque_keys.edx.keys import CourseKey, UsageKey
|
||||
|
||||
from ..utils import get_lms_link_for_item
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from student.roles import CourseInstructorRole, CourseStaffRole
|
||||
from student.tests.factories import AdminFactory
|
||||
from student.auth import add_users
|
||||
from contentstore.views.access import get_user_role
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class RolesTest(TestCase):
|
||||
|
||||
@@ -18,7 +18,7 @@ from xmodule.contentstore.django import contentstore
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.xml_importer import import_from_xml
|
||||
from django.test.utils import override_settings
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey, AssetLocation
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey, AssetLocation
|
||||
|
||||
|
||||
class AssetsTestCase(CourseTestCase):
|
||||
|
||||
@@ -7,7 +7,7 @@ import lxml
|
||||
from contentstore.tests.utils import CourseTestCase
|
||||
from contentstore.utils import reverse_course_url
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
|
||||
from xmodule.modulestore.locator import Locator
|
||||
from opaque_keys.edx.locator import Locator
|
||||
|
||||
|
||||
class TestCourseIndex(CourseTestCase):
|
||||
|
||||
@@ -5,7 +5,7 @@ import json
|
||||
|
||||
from contentstore.tests.test_course_settings import CourseTestCase
|
||||
from contentstore.utils import reverse_course_url, reverse_usage_url
|
||||
from xmodule.modulestore.locations import Location, SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import Location, SlashSeparatedCourseKey
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ from student.tests.factories import UserFactory
|
||||
from xmodule.capa_module import CapaDescriptor
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.keys import UsageKey
|
||||
from xmodule.modulestore.locations import Location
|
||||
from opaque_keys.edx.keys import UsageKey
|
||||
from opaque_keys.edx.locations import Location
|
||||
|
||||
|
||||
class ItemTest(CourseTestCase):
|
||||
|
||||
@@ -18,7 +18,7 @@ from xmodule.modulestore.django import modulestore
|
||||
from xmodule.contentstore.django import contentstore, _CONTENTSTORE
|
||||
from xmodule.contentstore.content import StaticContent
|
||||
from xmodule.exceptions import NotFoundError
|
||||
from xmodule.modulestore.keys import UsageKey
|
||||
from opaque_keys.edx.keys import UsageKey
|
||||
from xmodule.video_module import transcripts_utils
|
||||
|
||||
from contentstore.tests.modulestore_config import TEST_MODULESTORE
|
||||
|
||||
@@ -22,7 +22,7 @@ from opaque_keys import InvalidKeyError
|
||||
from xmodule.contentstore.content import StaticContent
|
||||
from xmodule.exceptions import NotFoundError
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.keys import UsageKey
|
||||
from opaque_keys.edx.keys import UsageKey
|
||||
from xmodule.contentstore.django import contentstore
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from django_future.csrf import ensure_csrf_cookie
|
||||
from edxmako.shortcuts import render_to_response
|
||||
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from util.json_request import JsonResponse, expect_json
|
||||
from student.roles import CourseInstructorRole, CourseStaffRole
|
||||
from course_creators.views import user_requested_access
|
||||
|
||||
@@ -17,7 +17,7 @@ from student.models import CourseEnrollment
|
||||
from xmodule.contentstore.django import contentstore, _CONTENTSTORE
|
||||
from xmodule.contentstore.content import StaticContent
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from xmodule.modulestore.tests.django_utils import (studio_store_config,
|
||||
ModuleStoreTestCase)
|
||||
from xmodule.modulestore.xml_importer import import_from_xml
|
||||
|
||||
@@ -9,7 +9,7 @@ from course_groups.cohorts import (get_cohort, get_course_cohorts,
|
||||
is_commentable_cohorted, get_cohort_by_name)
|
||||
|
||||
from xmodule.modulestore.django import modulestore, clear_existing_modulestores
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
from xmodule.modulestore.tests.django_utils import mixed_store_config
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import json
|
||||
import logging
|
||||
import re
|
||||
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from courseware.courses import get_course_with_access
|
||||
from edxmako.shortcuts import render_to_response
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ from django import forms
|
||||
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class CourseModeForm(forms.ModelForm):
|
||||
|
||||
@@ -8,7 +8,7 @@ Replace this with more appropriate tests for your application.
|
||||
from datetime import datetime, timedelta
|
||||
import pytz
|
||||
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from django.test import TestCase
|
||||
from course_modes.models import CourseMode, Mode
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ from courseware.access import has_access
|
||||
from student.models import CourseEnrollment
|
||||
from student.views import course_from_id
|
||||
from verify_student.models import SoftwareSecurePhotoVerification
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class ChooseModeView(View):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from django_comment_common.models import Role
|
||||
from student.models import CourseEnrollment, User
|
||||
|
||||
@@ -37,7 +37,7 @@ class RoleAssignmentTest(TestCase):
|
||||
|
||||
# The following was written on the assumption that unenrolling from a course
|
||||
# should remove all forum Roles for that student for that course. This is
|
||||
# not necessarily the case -- please see comments at the top of
|
||||
# not necessarily the case -- please see comments at the top of
|
||||
# django_comment_client.models.assign_default_role(). Leaving it for the
|
||||
# forums team to sort out.
|
||||
#
|
||||
|
||||
@@ -11,8 +11,8 @@ import ipaddr
|
||||
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class EmbargoedCourseForm(forms.ModelForm): # pylint: disable=incomplete-protocol
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Test of models for embargo middleware app"""
|
||||
from django.test import TestCase
|
||||
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from embargo.models import EmbargoedCourse, EmbargoedState, IPFilter
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, mixed_store_config
|
||||
from xmodule.modulestore.inheritance import own_metadata
|
||||
from xmodule.modulestore.django import editable_modulestore
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
from external_auth.models import ExternalAuthMap
|
||||
from external_auth.views import shib_login, course_specific_login, course_specific_register, _flatten_to_ascii
|
||||
|
||||
@@ -207,7 +207,7 @@ class SSLClientTest(ModuleStoreTestCase):
|
||||
# Expect an InvalidKeyError from course page as we don't have anything else built
|
||||
with self.assertRaisesRegexp(
|
||||
InvalidKeyError,
|
||||
"<class 'xmodule.modulestore.keys.CourseKey'>: None"
|
||||
"<class 'opaque_keys.edx.keys.CourseKey'>: None"
|
||||
):
|
||||
self.client.get(
|
||||
reverse('signup'), follow=True,
|
||||
@@ -219,7 +219,7 @@ class SSLClientTest(ModuleStoreTestCase):
|
||||
# Now that we are logged in, make sure we don't see the registration page
|
||||
with self.assertRaisesRegexp(
|
||||
InvalidKeyError,
|
||||
"<class 'xmodule.modulestore.keys.CourseKey'>: None"
|
||||
"<class 'opaque_keys.edx.keys.CourseKey'>: None"
|
||||
):
|
||||
self.client.get(reverse('signup'), follow=True)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from reverification.models import MidcourseReverificationWindow
|
||||
from factory.django import DjangoModelFactory
|
||||
import pytz
|
||||
from datetime import timedelta, datetime
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
# Factories don't have __init__ methods, and are self documenting
|
||||
|
||||
@@ -5,7 +5,7 @@ from static_replace import (replace_static_urls, replace_course_urls,
|
||||
_url_replace_regex)
|
||||
from mock import patch, Mock
|
||||
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from xmodule.modulestore.mongo import MongoModuleStore
|
||||
from xmodule.modulestore.xml import XMLModuleStore
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ from django.contrib.auth.models import User
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from student.models import anonymous_id_for_user
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
||||
@@ -3,8 +3,8 @@ from opaque_keys import InvalidKeyError
|
||||
from optparse import make_option
|
||||
from student.models import CourseEnrollment, User
|
||||
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
||||
@@ -4,8 +4,8 @@ A script to create some dummy users
|
||||
from django.core.management.base import BaseCommand
|
||||
from student.models import CourseEnrollment
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from student.views import _do_create_account, get_random_post_override
|
||||
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ from django.core.management.base import BaseCommand
|
||||
from django.utils import translation
|
||||
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from student.models import CourseEnrollment, Registration, create_comments_service_user
|
||||
from student.views import _do_create_account, AccountValidationError
|
||||
from track.management.tracked_command import TrackedCommand
|
||||
|
||||
@@ -8,8 +8,8 @@ from django.test.client import RequestFactory
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
import os
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from django.contrib.auth.models import User
|
||||
from optparse import make_option
|
||||
import datetime
|
||||
|
||||
@@ -3,7 +3,7 @@ from django.core.management.base import BaseCommand
|
||||
from django.contrib.auth.models import User
|
||||
from student.models import CourseEnrollment
|
||||
from shoppingcart.models import CertificateItem
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
||||
@@ -4,7 +4,7 @@ from south.v2 import DataMigration
|
||||
from django.db import models
|
||||
from xmodule.modulestore.django import loc_mapper
|
||||
import re
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys import InvalidKeyError
|
||||
import bson.son
|
||||
import logging
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from south.v2 import DataMigration
|
||||
from xmodule.modulestore.django import loc_mapper, modulestore
|
||||
import re
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys import InvalidKeyError
|
||||
import logging
|
||||
from django.db.models.query_utils import Q
|
||||
|
||||
@@ -34,13 +34,13 @@ from track import contexts
|
||||
from eventtracking import tracker
|
||||
from importlib import import_module
|
||||
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
from course_modes.models import CourseMode
|
||||
import lms.lib.comment_client as cc
|
||||
from util.query import use_read_replica_if_available
|
||||
from xmodule_django.models import CourseKeyField, NoneToEmptyManager
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from functools import total_ordering
|
||||
|
||||
unenroll_done = Signal(providing_args=["course_enrollment"])
|
||||
|
||||
@@ -10,7 +10,7 @@ from django.core.exceptions import PermissionDenied
|
||||
from student.roles import CourseInstructorRole, CourseStaffRole, CourseCreatorRole
|
||||
from student.tests.factories import AdminFactory
|
||||
from student.auth import has_access, add_users, remove_users
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class CreatorGroupTest(TestCase):
|
||||
|
||||
@@ -6,7 +6,7 @@ from django_comment_common.models import (
|
||||
from django_comment_common.utils import seed_permissions_roles
|
||||
from student.models import CourseEnrollment, UserProfile
|
||||
from util.testing import UrlResetMixin
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from mock import patch
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ from student.tests.factories import UserFactory, CourseEnrollmentFactory
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
from bulk_email.models import CourseAuthorization
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ from xmodule.modulestore.inheritance import own_metadata
|
||||
from xmodule.modulestore.django import editable_modulestore
|
||||
|
||||
from external_auth.models import ExternalAuthMap
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
TEST_DATA_MIXED_MODULESTORE = mixed_store_config(settings.COMMON_TEST_DATA_ROOT, {})
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from student.tests.factories import AnonymousUserFactory
|
||||
|
||||
from student.roles import GlobalStaff, CourseRole, CourseStaffRole, OrgStaffRole, OrgInstructorRole, \
|
||||
CourseInstructorRole
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class RolesTestCase(TestCase):
|
||||
|
||||
@@ -21,7 +21,7 @@ from unittest.case import SkipTest
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from courseware.tests.tests import TEST_DATA_MIXED_MODULESTORE
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
from mock import Mock, patch
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ from dark_lang.models import DarkLangConfig
|
||||
from xmodule.course_module import CourseDescriptor
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from xmodule.modulestore import XML_MODULESTORE_TYPE, Location
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -21,7 +21,7 @@ from .course_helpers import *
|
||||
from .ui_helpers import *
|
||||
from nose.tools import assert_equals # pylint: disable=E0611
|
||||
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
from logging import getLogger
|
||||
logger = getLogger(__name__)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Generates common contexts"""
|
||||
import logging
|
||||
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys import InvalidKeyError
|
||||
from util.request import COURSE_REGEX
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ Adds user's tags to tracking event context.
|
||||
from track.contexts import COURSE_REGEX
|
||||
from eventtracking import tracker
|
||||
from user_api.models import UserCourseTag
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class UserTagsEventContextMiddleware(object):
|
||||
|
||||
@@ -3,7 +3,7 @@ from factory.django import DjangoModelFactory
|
||||
from factory import SubFactory
|
||||
from student.tests.factories import UserFactory
|
||||
from user_api.models import UserPreference, UserCourseTag
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
# Factories don't have __init__ methods, and are self documenting
|
||||
# pylint: disable=W0232, C0111
|
||||
|
||||
@@ -5,7 +5,7 @@ from django.test import TestCase
|
||||
|
||||
from student.tests.factories import UserFactory
|
||||
from user_api import user_service
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class TestUserService(TestCase):
|
||||
|
||||
@@ -9,7 +9,7 @@ from unittest import SkipTest
|
||||
from user_api.models import UserPreference
|
||||
from user_api.tests.factories import UserPreferenceFactory
|
||||
from django_comment_common import models
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
TEST_API_KEY = "test_api_key"
|
||||
|
||||
@@ -11,7 +11,7 @@ from rest_framework.response import Response
|
||||
from user_api.serializers import UserSerializer, UserPreferenceSerializer
|
||||
from user_api.models import UserPreference
|
||||
from django_comment_common.models import Role
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class ApiKeyHeaderPermission(permissions.BasePermission):
|
||||
|
||||
@@ -3,7 +3,7 @@ import re
|
||||
|
||||
from django.conf import settings
|
||||
from microsite_configuration import microsite
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
COURSE_REGEX = re.compile(r'^.*?/courses/(?P<course_id>[^/]+/[^/]+/[^/]+)')
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ Tests for sandboxing.py in util app
|
||||
from django.test import TestCase
|
||||
from util.sandboxing import can_execute_unsafe_code
|
||||
from django.test.utils import override_settings
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class SandboxingTest(TestCase):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from django.db import models
|
||||
from django.core.exceptions import ValidationError
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey, Location
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey, Location
|
||||
|
||||
from south.modelsinspector import add_introspection_rules
|
||||
add_introspection_rules([], ["^xmodule_django\.models\.CourseKeyField"])
|
||||
|
||||
@@ -55,6 +55,7 @@ setup(
|
||||
'capa',
|
||||
'path.py',
|
||||
'webob',
|
||||
'opaque-keys',
|
||||
],
|
||||
package_data={
|
||||
'xmodule': ['js/module/*'],
|
||||
@@ -68,19 +69,5 @@ setup(
|
||||
'console_scripts': [
|
||||
'xmodule_assets = xmodule.static_content:main',
|
||||
],
|
||||
'course_key': [
|
||||
'slashes = xmodule.modulestore.locations:SlashSeparatedCourseKey',
|
||||
'course-locator = xmodule.modulestore.locator:CourseLocator',
|
||||
],
|
||||
'usage_key': [
|
||||
'location = xmodule.modulestore.locations:Location',
|
||||
'edx = xmodule.modulestore.locator:BlockUsageLocator',
|
||||
],
|
||||
'asset_key': [
|
||||
'asset-location = xmodule.modulestore.locations:AssetLocation',
|
||||
],
|
||||
'definition_key': [
|
||||
'defx = xmodule.modulestore.locator:DefinitionLocator',
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
@@ -10,7 +10,7 @@ import StringIO
|
||||
from urlparse import urlparse, urlunparse, parse_qsl
|
||||
from urllib import urlencode
|
||||
|
||||
from xmodule.modulestore.locations import AssetLocation, SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import AssetLocation, SlashSeparatedCourseKey
|
||||
from .django import contentstore
|
||||
from PIL import Image
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ from fs.osfs import OSFS
|
||||
import os
|
||||
import json
|
||||
import bson.son
|
||||
from xmodule.modulestore.locations import AssetLocation
|
||||
from opaque_keys.edx.locations import AssetLocation
|
||||
|
||||
|
||||
class MongoContentStore(ContentStore):
|
||||
|
||||
@@ -17,7 +17,7 @@ import json
|
||||
|
||||
from xblock.fields import Scope, List, String, Dict, Boolean, Integer
|
||||
from .fields import Date
|
||||
from xmodule.modulestore.locator import CourseLocator
|
||||
from opaque_keys.edx.locator import CourseLocator
|
||||
from django.utils.timezone import UTC
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -14,10 +14,10 @@ from xblock.plugin import default_select
|
||||
|
||||
from .exceptions import InvalidLocationError, InsufficientSpecificationError
|
||||
from xmodule.errortracker import make_error_tracker
|
||||
from xmodule.modulestore.keys import CourseKey, UsageKey
|
||||
from xmodule.modulestore.locations import Location # For import backwards compatibility
|
||||
from opaque_keys.edx.keys import CourseKey, UsageKey
|
||||
from opaque_keys.edx.locations import Location # For import backwards compatibility
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from xblock.runtime import Mixologist
|
||||
from xblock.core import XBlock
|
||||
import datetime
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
"""
|
||||
OpaqueKey abstract classes for edx-platform object types (courses, definitions, usages, and assets).
|
||||
"""
|
||||
from abc import abstractmethod, abstractproperty
|
||||
|
||||
from opaque_keys import OpaqueKey
|
||||
from xblock.runtime import IdReader
|
||||
|
||||
|
||||
class CourseKey(OpaqueKey):
|
||||
"""
|
||||
An :class:`opaque_keys.OpaqueKey` identifying a particular Course object.
|
||||
"""
|
||||
KEY_TYPE = 'course_key'
|
||||
__slots__ = ()
|
||||
|
||||
@abstractproperty
|
||||
def org(self):
|
||||
"""
|
||||
The organization that this course belongs to.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@abstractproperty
|
||||
def offering(self):
|
||||
"""
|
||||
The offering identifier for this course.
|
||||
|
||||
This is complement of the org; in old-style IDs, "course/run"
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@abstractmethod
|
||||
def make_usage_key(self, block_type, block_id):
|
||||
"""
|
||||
Return a usage key, given the given the specified block_type and block_id.
|
||||
|
||||
This function should not actually create any new ids, but should simply
|
||||
return one that already exists.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@abstractmethod
|
||||
def make_asset_key(self, asset_type, path):
|
||||
"""
|
||||
Return an asset key, given the given the specified path.
|
||||
|
||||
This function should not actually create any new ids, but should simply
|
||||
return one that already exists.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class DefinitionKey(OpaqueKey):
|
||||
"""
|
||||
An :class:`opaque_keys.OpaqueKey` identifying an XBlock definition.
|
||||
"""
|
||||
KEY_TYPE = 'definition_key'
|
||||
__slots__ = ()
|
||||
|
||||
@abstractproperty
|
||||
def block_type(self):
|
||||
"""
|
||||
The XBlock type of this definition.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class CourseObjectMixin(object):
|
||||
"""
|
||||
An abstract :class:`opaque_keys.OpaqueKey` mixin
|
||||
for keys that belong to courses.
|
||||
"""
|
||||
__slots__ = ()
|
||||
|
||||
@abstractproperty
|
||||
def course_key(self):
|
||||
"""
|
||||
Return the :class:`CourseKey` for the course containing this usage.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@abstractmethod
|
||||
def map_into_course(self, course_key):
|
||||
"""
|
||||
Return a new :class:`UsageKey` or :class:`AssetKey` representing this usage inside the
|
||||
course identified by the supplied :class:`CourseKey`. It returns the same type as
|
||||
`self`
|
||||
|
||||
Args:
|
||||
course_key (:class:`CourseKey`): The course to map this object into.
|
||||
|
||||
Returns:
|
||||
A new :class:`CourseObjectMixin` instance.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class AssetKey(CourseObjectMixin, OpaqueKey):
|
||||
"""
|
||||
An :class:`opaque_keys.OpaqueKey` identifying a course asset.
|
||||
"""
|
||||
KEY_TYPE = 'asset_key'
|
||||
__slots__ = ()
|
||||
|
||||
@abstractproperty
|
||||
def path(self):
|
||||
"""
|
||||
Return the path for this asset.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class UsageKey(CourseObjectMixin, OpaqueKey):
|
||||
"""
|
||||
An :class:`opaque_keys.OpaqueKey` identifying an XBlock usage.
|
||||
"""
|
||||
KEY_TYPE = 'usage_key'
|
||||
__slots__ = ()
|
||||
|
||||
@abstractproperty
|
||||
def definition_key(self):
|
||||
"""
|
||||
Return the :class:`DefinitionKey` for the XBlock containing this usage.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def block_type(self):
|
||||
return self.category
|
||||
|
||||
|
||||
class OpaqueKeyReader(IdReader):
|
||||
"""
|
||||
IdReader for :class:`DefinitionKey` and :class:`UsageKey`s.
|
||||
"""
|
||||
def get_definition_id(self, usage_id):
|
||||
"""Retrieve the definition that a usage is derived from.
|
||||
|
||||
Args:
|
||||
usage_id: The id of the usage to query
|
||||
|
||||
Returns:
|
||||
The `definition_id` the usage is derived from
|
||||
"""
|
||||
return usage_id.definition_key
|
||||
|
||||
def get_block_type(self, def_id):
|
||||
"""Retrieve the block_type of a particular definition
|
||||
|
||||
Args:
|
||||
def_id: The id of the definition to query
|
||||
|
||||
Returns:
|
||||
The `block_type` of the definition
|
||||
"""
|
||||
return def_id.block_type
|
||||
@@ -8,8 +8,8 @@ import bson.son
|
||||
import urllib
|
||||
|
||||
from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError
|
||||
from xmodule.modulestore.locator import BlockUsageLocator, CourseLocator
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class LocMapperStore(object):
|
||||
|
||||
@@ -1,356 +0,0 @@
|
||||
"""OpaqueKey implementations used by XML and Mongo modulestores"""
|
||||
|
||||
import logging
|
||||
import re
|
||||
from bson.son import SON
|
||||
|
||||
from opaque_keys import InvalidKeyError, OpaqueKey
|
||||
|
||||
from xmodule.modulestore.keys import CourseKey, UsageKey, DefinitionKey, AssetKey
|
||||
import json
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
URL_RE = re.compile("""
|
||||
([^:/]+://?|/[^/]+)
|
||||
(?P<org>[^/]+)/
|
||||
(?P<course>[^/]+)/
|
||||
(?P<category>[^/]+)/
|
||||
(?P<name>[^@]+)
|
||||
(@(?P<revision>[^/]+))?
|
||||
""", re.VERBOSE)
|
||||
|
||||
# TODO (cpennington): We should decide whether we want to expand the
|
||||
# list of valid characters in a location
|
||||
INVALID_CHARS = re.compile(r"[^\w.%-]", re.UNICODE)
|
||||
# Names are allowed to have colons.
|
||||
INVALID_CHARS_NAME = re.compile(r"[^\w.:%-]", re.UNICODE)
|
||||
|
||||
# html ids can contain word chars and dashes
|
||||
INVALID_HTML_CHARS = re.compile(r"[^\w-]", re.UNICODE)
|
||||
|
||||
|
||||
class SlashSeparatedCourseKey(CourseKey):
|
||||
"""Course key for old style org/course/run course identifiers"""
|
||||
|
||||
CANONICAL_NAMESPACE = 'slashes'
|
||||
KEY_FIELDS = ('org', 'course', 'run')
|
||||
__slots__ = KEY_FIELDS
|
||||
|
||||
def __init__(self, org, course, run):
|
||||
"""
|
||||
checks that the values are syntactically valid before creating object
|
||||
"""
|
||||
for part in (org, course, run):
|
||||
LocationBase._check_location_part(part, INVALID_CHARS)
|
||||
super(SlashSeparatedCourseKey, self).__init__(org, course, run)
|
||||
|
||||
@classmethod
|
||||
def _from_string(cls, serialized):
|
||||
serialized = serialized.replace("+", "/")
|
||||
if serialized.count('/') != 2:
|
||||
raise InvalidKeyError(cls, serialized)
|
||||
|
||||
# Turns encoded slashes into actual slashes
|
||||
return cls(*serialized.split('/'))
|
||||
|
||||
def _to_string(self):
|
||||
# Turns slashes into pluses
|
||||
return u'+'.join([self.org, self.course, self.run])
|
||||
|
||||
@property
|
||||
def offering(self):
|
||||
return u'/'.join([self.course, self.run])
|
||||
|
||||
def make_asset_key(self, asset_type, path):
|
||||
return AssetLocation(self.org, self.course, self.run, asset_type, path, None)
|
||||
|
||||
def make_usage_key(self, block_type, name):
|
||||
return Location(self.org, self.course, self.run, block_type, name, None)
|
||||
|
||||
def to_deprecated_string(self):
|
||||
return u'/'.join([self.org, self.course, self.run])
|
||||
|
||||
@classmethod
|
||||
def from_deprecated_string(cls, serialized):
|
||||
return cls._from_string(serialized)
|
||||
|
||||
def make_usage_key_from_deprecated_string(self, location_url):
|
||||
"""
|
||||
Temporary mechanism for creating a UsageKey given a CourseKey and a serialized Location. NOTE:
|
||||
this prejudicially takes the tag, org, and course from the url not self.
|
||||
|
||||
Raises:
|
||||
InvalidKeyError: if the url does not parse
|
||||
"""
|
||||
match = URL_RE.match(location_url)
|
||||
if match is None:
|
||||
raise InvalidKeyError(Location, location_url)
|
||||
groups = match.groupdict()
|
||||
return Location(run=self.run, **groups)
|
||||
|
||||
|
||||
class LocationBase(object):
|
||||
"""
|
||||
Encodes a type of Location, which identifies a piece of
|
||||
content situated in a course.
|
||||
"""
|
||||
KEY_FIELDS = ('org', 'course', 'run', 'category', 'name', 'revision')
|
||||
|
||||
SERIALIZED_PATTERN = re.compile("""
|
||||
(?P<org>[^/]+)\+
|
||||
(?P<course>[^/]+)\+
|
||||
(?P<run>[^/]+)\+
|
||||
(?P<category>[^/]+)\+
|
||||
(?P<name>[^@/]+)
|
||||
(@(?P<revision>[^/]+))?
|
||||
""", re.VERBOSE)
|
||||
|
||||
@classmethod
|
||||
def _check_location_part(cls, val, regexp):
|
||||
"""
|
||||
Check that `regexp` doesn't match inside `val`. If it does, raise an exception
|
||||
|
||||
Args:
|
||||
val (string): The value to check
|
||||
regexp (re.RegexObject): The regular expression specifying invalid characters
|
||||
|
||||
Raises:
|
||||
InvalidKeyError: Raised if any invalid character is found in `val`
|
||||
"""
|
||||
if val is None:
|
||||
return
|
||||
|
||||
if not isinstance(val, basestring):
|
||||
raise InvalidKeyError(cls, "{!r} is not a string".format(val))
|
||||
|
||||
if regexp.search(val) is not None:
|
||||
raise InvalidKeyError(cls, "Invalid characters in {!r}.".format(val))
|
||||
|
||||
@classmethod
|
||||
def _clean(cls, value, invalid):
|
||||
"""
|
||||
invalid should be a compiled regexp of chars to replace with '_'
|
||||
"""
|
||||
return re.sub('_+', '_', invalid.sub('_', value))
|
||||
|
||||
@classmethod
|
||||
def clean(cls, value):
|
||||
"""
|
||||
Return value, made into a form legal for locations
|
||||
"""
|
||||
return cls._clean(value, INVALID_CHARS)
|
||||
|
||||
@classmethod
|
||||
def clean_keeping_underscores(cls, value):
|
||||
"""
|
||||
Return value, replacing INVALID_CHARS, but not collapsing multiple '_' chars.
|
||||
This for cleaning asset names, as the YouTube ID's may have underscores in them, and we need the
|
||||
transcript asset name to match. In the future we may want to change the behavior of _clean.
|
||||
"""
|
||||
return INVALID_CHARS.sub('_', value)
|
||||
|
||||
@classmethod
|
||||
def clean_for_url_name(cls, value):
|
||||
"""
|
||||
Convert value into a format valid for location names (allows colons).
|
||||
"""
|
||||
return cls._clean(value, INVALID_CHARS_NAME)
|
||||
|
||||
@classmethod
|
||||
def clean_for_html(cls, value):
|
||||
"""
|
||||
Convert a string into a form that's safe for use in html ids, classes, urls, etc.
|
||||
Replaces all INVALID_HTML_CHARS with '_', collapses multiple '_' chars
|
||||
"""
|
||||
return cls._clean(value, INVALID_HTML_CHARS)
|
||||
|
||||
def __init__(self, org, course, run, category, name, revision=None):
|
||||
"""
|
||||
Create a new Location that is a clone of the specifed one.
|
||||
|
||||
Components must be composed of alphanumeric characters, or the
|
||||
characters '_', '-', and '.'. The name component is additionally allowed to have ':',
|
||||
which is interpreted specially for xml storage.
|
||||
|
||||
Components may be set to None, which may be interpreted in some contexts
|
||||
to mean wildcard selection.
|
||||
"""
|
||||
# check that the values are syntactically valid before creating object
|
||||
for part in (org, course, run, category, revision):
|
||||
self._check_location_part(part, INVALID_CHARS)
|
||||
self._check_location_part(name, INVALID_CHARS_NAME)
|
||||
|
||||
# call the OpaqueKey constructor ensuring the args in the same order as KEY_FIELDS above
|
||||
super(LocationBase, self).__init__(org, course, run, category, name, revision)
|
||||
|
||||
@property
|
||||
def tag(self):
|
||||
return self.DEPRECATED_TAG
|
||||
|
||||
@property
|
||||
def definition_key(self):
|
||||
# Locations are both UsageKeys and DefinitionKeys
|
||||
return self
|
||||
|
||||
@property
|
||||
def block_type(self):
|
||||
return self.category
|
||||
|
||||
@classmethod
|
||||
def from_deprecated_string(cls, serialized):
|
||||
match = URL_RE.match(serialized)
|
||||
if match is None:
|
||||
raise InvalidKeyError(Location, serialized)
|
||||
groups = match.groupdict()
|
||||
return cls(run=None, **groups)
|
||||
|
||||
def to_deprecated_string(self):
|
||||
url = u"{0.DEPRECATED_TAG}://{0.org}/{0.course}/{0.category}/{0.name}".format(self)
|
||||
if self.revision:
|
||||
url += u"@{rev}".format(rev=self.revision) # pylint: disable=E1101
|
||||
return url
|
||||
|
||||
def _to_string(self):
|
||||
output = u"+".join(
|
||||
unicode(val)
|
||||
for val in (self.org, self.course, self.run, self.category, self.name)
|
||||
)
|
||||
if self.revision:
|
||||
output += u'@{}'.format(self.revision)
|
||||
return output
|
||||
|
||||
@classmethod
|
||||
def _from_string(cls, serialized):
|
||||
match = cls.SERIALIZED_PATTERN.match(serialized)
|
||||
if not match:
|
||||
raise InvalidKeyError(cls, serialized)
|
||||
|
||||
return cls(**match.groupdict())
|
||||
|
||||
def html_id(self):
|
||||
"""
|
||||
Return a string with a version of the location that is safe for use in
|
||||
html id attributes
|
||||
"""
|
||||
id_fields = [self.DEPRECATED_TAG, self.org, self.course, self.category, self.name, self.revision]
|
||||
id_string = u"-".join([v for v in id_fields if v is not None])
|
||||
return Location.clean_for_html(id_string)
|
||||
|
||||
@property
|
||||
def course_key(self):
|
||||
return SlashSeparatedCourseKey(self.org, self.course, self.run)
|
||||
|
||||
def to_deprecated_son(self, prefix='', tag='i4x'):
|
||||
"""
|
||||
Returns a SON object that represents this location
|
||||
"""
|
||||
# adding tag b/c deprecated form used it
|
||||
son = SON({prefix + 'tag': tag})
|
||||
for field_name in self.KEY_FIELDS:
|
||||
# Temporary filtering of run field because deprecated form left it out
|
||||
if field_name != 'run':
|
||||
son[prefix + field_name] = getattr(self, field_name)
|
||||
return son
|
||||
|
||||
@classmethod
|
||||
def _from_deprecated_son(cls, id_dict, run):
|
||||
"""
|
||||
Return the Location decoding this id_dict and run
|
||||
"""
|
||||
return cls(id_dict['org'], id_dict['course'], run, id_dict['category'], id_dict['name'], id_dict['revision'])
|
||||
|
||||
|
||||
class Location(LocationBase, UsageKey, DefinitionKey):
|
||||
"""
|
||||
UsageKey and DefinitionKey implementation class for use with
|
||||
XML and Mongo modulestores.
|
||||
"""
|
||||
|
||||
CANONICAL_NAMESPACE = 'location'
|
||||
DEPRECATED_TAG = 'i4x'
|
||||
__slots__ = LocationBase.KEY_FIELDS
|
||||
|
||||
def map_into_course(self, course_key):
|
||||
"""
|
||||
Return a new :class:`UsageKey` representing this usage inside the
|
||||
course identified by the supplied :class:`CourseKey`.
|
||||
|
||||
Args:
|
||||
course_key (CourseKey): The course to map this object into.
|
||||
|
||||
Returns:
|
||||
A new :class:`CourseObjectMixin` instance.
|
||||
"""
|
||||
return Location(course_key.org, course_key.course, course_key.run, self.category, self.name, self.revision)
|
||||
|
||||
|
||||
class AssetLocation(LocationBase, AssetKey):
|
||||
"""
|
||||
An AssetKey implementation class.
|
||||
"""
|
||||
CANONICAL_NAMESPACE = 'asset-location'
|
||||
DEPRECATED_TAG = 'c4x'
|
||||
__slots__ = LocationBase.KEY_FIELDS
|
||||
|
||||
def __init__(self, org, course, run, category, name, revision=None):
|
||||
super(AssetLocation, self).__init__(org, course, run, category, name, revision)
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return self.name
|
||||
|
||||
def to_deprecated_string(self):
|
||||
url = u"/{0.DEPRECATED_TAG}/{0.org}/{0.course}/{0.category}/{0.name}".format(self)
|
||||
return url
|
||||
|
||||
ASSET_URL_RE = re.compile(r"""
|
||||
/?c4x/
|
||||
(?P<org>[^/]+)/
|
||||
(?P<course>[^/]+)/
|
||||
(?P<category>[^/]+)/
|
||||
(?P<name>[^/]+)
|
||||
""", re.VERBOSE | re.IGNORECASE)
|
||||
|
||||
@classmethod
|
||||
def from_deprecated_string(cls, serialized):
|
||||
match = cls.ASSET_URL_RE.match(serialized)
|
||||
if match is None:
|
||||
raise InvalidKeyError(Location, serialized)
|
||||
groups = match.groupdict()
|
||||
return cls(run=None, **groups)
|
||||
|
||||
def map_into_course(self, course_key):
|
||||
"""
|
||||
Return a new :class:`UsageKey` representing this usage inside the
|
||||
course identified by the supplied :class:`CourseKey`.
|
||||
|
||||
Args:
|
||||
course_key (CourseKey): The course to map this object into.
|
||||
|
||||
Returns:
|
||||
A new :class:`CourseObjectMixin` instance.
|
||||
"""
|
||||
return AssetLocation(course_key.org, course_key.course, course_key.run, self.category, self.name, self.revision)
|
||||
|
||||
def to_deprecated_list_repr(self):
|
||||
"""
|
||||
Thumbnail locations are stored as lists [c4x, org, course, thumbnail, path, None] in contentstore.mongo
|
||||
That should be the only use of this method, but the method is general enough to provide the pre-opaque
|
||||
Location fields as an array in the old order with the tag.
|
||||
"""
|
||||
return ['c4x', self.org, self.course, self.block_type, self.name, None]
|
||||
|
||||
|
||||
class i4xEncoder(json.JSONEncoder):
|
||||
"""
|
||||
If provided as the cls to json.dumps, will serialize and Locations as i4x strings and other
|
||||
keys using the unicode strings.
|
||||
"""
|
||||
def default(self, key):
|
||||
if isinstance(key, OpaqueKey):
|
||||
if isinstance(key, (LocationBase, SlashSeparatedCourseKey)):
|
||||
return key.to_deprecated_string()
|
||||
else:
|
||||
return unicode(key)
|
||||
super(i4xEncoder, self).default(key)
|
||||
@@ -13,7 +13,7 @@ from bson.errors import InvalidId
|
||||
|
||||
from opaque_keys import OpaqueKey, InvalidKeyError
|
||||
|
||||
from xmodule.modulestore.keys import CourseKey, UsageKey, DefinitionKey
|
||||
from opaque_keys.edx.keys import CourseKey, UsageKey, DefinitionKey
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@ from opaque_keys import InvalidKeyError
|
||||
from . import ModuleStoreWriteBase
|
||||
from xmodule.modulestore.django import create_modulestore_instance, loc_mapper
|
||||
from xmodule.modulestore import Location, XML_MODULESTORE_TYPE
|
||||
from xmodule.modulestore.locator import CourseLocator, Locator, BlockUsageLocator
|
||||
from opaque_keys.edx.locator import CourseLocator, Locator, BlockUsageLocator
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.keys import CourseKey, UsageKey
|
||||
from opaque_keys.edx.keys import CourseKey, UsageKey
|
||||
from xmodule.modulestore.mongo.base import MongoModuleStore
|
||||
from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationErr
|
||||
from xmodule.modulestore.inheritance import own_metadata, InheritanceMixin, inherit_metadata, InheritanceKeyValueStore
|
||||
from xmodule.tabs import StaticTab, CourseTabList
|
||||
from xblock.core import XBlock
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ from pytz import UTC
|
||||
from xmodule.exceptions import InvalidVersionError
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateItemError
|
||||
from xmodule.modulestore.mongo.base import MongoModuleStore
|
||||
from xmodule.modulestore.locations import Location
|
||||
from opaque_keys.edx.locations import Location
|
||||
|
||||
DRAFT = 'draft'
|
||||
# Things w/ these categories should never be marked as version='draft'
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
Custom field types for mongoengine
|
||||
"""
|
||||
import mongoengine
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey, Location
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey, Location
|
||||
from types import NoneType
|
||||
from xmodule.modulestore.keys import CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
|
||||
|
||||
class CourseKeyField(mongoengine.StringField):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import sys
|
||||
import logging
|
||||
from xmodule.mako_module import MakoDescriptorSystem
|
||||
from xmodule.modulestore.locator import BlockUsageLocator, LocalId, CourseLocator
|
||||
from opaque_keys.edx.locator import BlockUsageLocator, LocalId, CourseLocator
|
||||
from xmodule.error_module import ErrorDescriptor
|
||||
from xmodule.errortracker import exc_info_to_str
|
||||
from xblock.runtime import KvsFieldData
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from xmodule.modulestore.locator import DefinitionLocator
|
||||
from opaque_keys.edx.locator import DefinitionLocator
|
||||
|
||||
|
||||
class DefinitionLazyLoader(object):
|
||||
|
||||
@@ -54,7 +54,7 @@ import copy
|
||||
from pytz import UTC
|
||||
|
||||
from xmodule.errortracker import null_error_tracker
|
||||
from xmodule.modulestore.locator import (
|
||||
from opaque_keys.edx.locator import (
|
||||
BlockUsageLocator, DefinitionLocator, CourseLocator, VersionTree,
|
||||
LocalId, Locator
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ from factory.containers import CyclicDefinitionError
|
||||
from uuid import uuid4
|
||||
|
||||
from xmodule.modulestore import prefer_xmodules
|
||||
from xmodule.modulestore.locations import Location
|
||||
from opaque_keys.edx.locations import Location
|
||||
from xblock.core import XBlock
|
||||
|
||||
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
"""
|
||||
Thorough tests of the Location class
|
||||
"""
|
||||
import ddt
|
||||
|
||||
from unittest import TestCase
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.locations import Location, AssetLocation, SlashSeparatedCourseKey
|
||||
|
||||
# Pairs for testing the clean* functions.
|
||||
# The first item in the tuple is the input string.
|
||||
# The second item in the tuple is what the result of
|
||||
# replacement should be.
|
||||
GENERAL_PAIRS = [
|
||||
('', ''),
|
||||
(' ', '_'),
|
||||
('abc,', 'abc_'),
|
||||
('ab fg!@//\\aj', 'ab_fg_aj'),
|
||||
(u"ab\xA9", "ab_"), # no unicode allowed for now
|
||||
]
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestLocations(TestCase):
|
||||
"""
|
||||
Tests of :class:`.Location`
|
||||
"""
|
||||
@ddt.data(
|
||||
"org+course+run+category+name",
|
||||
"org+course+run+category+name@revision"
|
||||
)
|
||||
def test_string_roundtrip(self, url):
|
||||
self.assertEquals(url, Location._from_string(url)._to_string()) # pylint: disable=protected-access
|
||||
|
||||
@ddt.data(
|
||||
"i4x://org/course/category/name",
|
||||
"i4x://org/course/category/name@revision"
|
||||
)
|
||||
def test_deprecated_roundtrip(self, url):
|
||||
course_id = SlashSeparatedCourseKey('org', 'course', 'run')
|
||||
self.assertEquals(
|
||||
url,
|
||||
course_id.make_usage_key_from_deprecated_string(url).to_deprecated_string()
|
||||
)
|
||||
|
||||
def test_invalid_chars_ssck(self):
|
||||
"""
|
||||
Test that the ssck constructor fails if given invalid chars
|
||||
"""
|
||||
valid_base = SlashSeparatedCourseKey(u'org.dept-1%2', u'course.sub-2%3', u'run.faster-4%5')
|
||||
for key in SlashSeparatedCourseKey.KEY_FIELDS:
|
||||
with self.assertRaises(InvalidKeyError):
|
||||
# this ends up calling the constructor where the legality check should occur
|
||||
valid_base.replace(**{key: u'funny thing'})
|
||||
|
||||
def test_invalid_chars_location(self):
|
||||
"""
|
||||
Test that the location constructor fails if given invalid chars
|
||||
"""
|
||||
course_key = SlashSeparatedCourseKey(u'org.dept-1%2', u'course.sub-2%3', u'run.faster-4%5')
|
||||
valid_base = course_key.make_usage_key('tomato-again%9', 'block-head:sub-4%9')
|
||||
for key in SlashSeparatedCourseKey.KEY_FIELDS:
|
||||
with self.assertRaises(InvalidKeyError):
|
||||
# this ends up calling the constructor where the legality check should occur
|
||||
valid_base.replace(**{key: u'funny thing'})
|
||||
|
||||
@ddt.data(
|
||||
((), {
|
||||
'org': 'org',
|
||||
'course': 'course',
|
||||
'run': 'run',
|
||||
'category': 'category',
|
||||
'name': 'name',
|
||||
}, 'org', 'course', 'run', 'category', 'name', None),
|
||||
((), {
|
||||
'org': 'org',
|
||||
'course': 'course',
|
||||
'run': 'run',
|
||||
'category': 'category',
|
||||
'name': 'name:more_name',
|
||||
}, 'org', 'course', 'run', 'category', 'name:more_name', None),
|
||||
(['org', 'course', 'run', 'category', 'name'], {}, 'org', 'course', 'run', 'category', 'name', None),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_valid_locations(self, args, kwargs, org, course, run, category, name, revision):
|
||||
location = Location(*args, **kwargs)
|
||||
self.assertEquals(org, location.org)
|
||||
self.assertEquals(course, location.course)
|
||||
self.assertEquals(run, location.run)
|
||||
self.assertEquals(category, location.category)
|
||||
self.assertEquals(name, location.name)
|
||||
self.assertEquals(revision, location.revision)
|
||||
|
||||
@ddt.data(
|
||||
(("foo",), {}),
|
||||
(["foo", "bar"], {}),
|
||||
(["foo", "bar", "baz", "blat/blat", "foo"], {}),
|
||||
(["foo", "bar", "baz", "blat", "foo/bar"], {}),
|
||||
(["foo", "bar", "baz", "blat:blat", "foo:bar"], {}), # ':' ok in name, not in category
|
||||
(('org', 'course', 'run', 'category', 'name with spaces', 'revision'), {}),
|
||||
(('org', 'course', 'run', 'category', 'name/with/slashes', 'revision'), {}),
|
||||
(('org', 'course', 'run', 'category', 'name', u'\xae'), {}),
|
||||
(('org', 'course', 'run', 'category', u'\xae', 'revision'), {}),
|
||||
((), {
|
||||
'tag': 'tag',
|
||||
'course': 'course',
|
||||
'category': 'category',
|
||||
'name': 'name@more_name',
|
||||
'org': 'org'
|
||||
}),
|
||||
((), {
|
||||
'tag': 'tag',
|
||||
'course': 'course',
|
||||
'category': 'category',
|
||||
'name': 'name ', # extra space
|
||||
'org': 'org'
|
||||
}),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_invalid_locations(self, *args, **kwargs):
|
||||
with self.assertRaises(TypeError):
|
||||
Location(*args, **kwargs)
|
||||
|
||||
def test_equality(self):
|
||||
self.assertEquals(
|
||||
Location('tag', 'org', 'course', 'run', 'category', 'name'),
|
||||
Location('tag', 'org', 'course', 'run', 'category', 'name')
|
||||
)
|
||||
|
||||
self.assertNotEquals(
|
||||
Location('tag', 'org', 'course', 'run', 'category', 'name1'),
|
||||
Location('tag', 'org', 'course', 'run', 'category', 'name')
|
||||
)
|
||||
|
||||
@ddt.data(
|
||||
('a:b', 'a_b'), # no colons in non-name components
|
||||
('a-b', 'a-b'), # dashes ok
|
||||
('a.b', 'a.b'), # dot ok
|
||||
*GENERAL_PAIRS
|
||||
)
|
||||
def test_clean(self, pair):
|
||||
self.assertEquals(Location.clean(pair[0]), pair[1])
|
||||
|
||||
@ddt.data(
|
||||
('a:b', 'a:b'), # colons ok in names
|
||||
('a-b', 'a-b'), # dashes ok in names
|
||||
('a.b', 'a.b'), # dot ok in names
|
||||
*GENERAL_PAIRS
|
||||
)
|
||||
def test_clean_for_url_name(self, pair):
|
||||
self.assertEquals(Location.clean_for_url_name(pair[0]), pair[1])
|
||||
|
||||
@ddt.data(
|
||||
("a:b", "a_b"), # no colons for html use
|
||||
("a-b", "a-b"), # dashes ok (though need to be replaced in various use locations. ugh.)
|
||||
('a.b', 'a_b'), # no dots.
|
||||
*GENERAL_PAIRS
|
||||
)
|
||||
def test_clean_for_html(self, pair):
|
||||
self.assertEquals(Location.clean_for_html(pair[0]), pair[1])
|
||||
|
||||
def test_html_id(self):
|
||||
loc = Location('org', 'course', 'run', 'cat', 'name:more_name', 'rev')
|
||||
self.assertEquals(loc.html_id(), "i4x-org-course-cat-name_more_name-rev")
|
||||
|
||||
def test_replacement(self):
|
||||
# pylint: disable=protected-access
|
||||
|
||||
self.assertEquals(
|
||||
Location('o', 'c', 'r', 'c', 'n', 'r').replace(name='new_name'),
|
||||
Location('o', 'c', 'r', 'c', 'new_name', 'r'),
|
||||
)
|
||||
|
||||
with self.assertRaises(InvalidKeyError):
|
||||
Location('o', 'c', 'r', 'c', 'n', 'r').replace(name=u'name\xae')
|
||||
|
||||
@ddt.data('org', 'course', 'category', 'name', 'revision')
|
||||
def test_immutable(self, attr):
|
||||
loc = Location('o', 'c', 'r', 'c', 'n', 'r')
|
||||
with self.assertRaises(AttributeError):
|
||||
setattr(loc, attr, attr)
|
||||
|
||||
def test_map_into_course_location(self):
|
||||
loc = Location('org', 'course', 'run', 'cat', 'name:more_name', 'rev')
|
||||
course_key = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")
|
||||
self.assertEquals(
|
||||
Location("edX", "toy", "2012_Fall", 'cat', 'name:more_name', 'rev'),
|
||||
loc.map_into_course(course_key)
|
||||
)
|
||||
|
||||
def test_map_into_course_asset_location(self):
|
||||
loc = AssetLocation('org', 'course', 'run', 'asset', 'foo.bar')
|
||||
course_key = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")
|
||||
self.assertEquals(
|
||||
AssetLocation("edX", "toy", "2012_Fall", 'asset', 'foo.bar'),
|
||||
loc.map_into_course(course_key)
|
||||
)
|
||||
@@ -4,11 +4,11 @@ Test the loc mapper store
|
||||
import unittest
|
||||
import uuid
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore.locator import BlockUsageLocator, CourseLocator
|
||||
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError
|
||||
from xmodule.modulestore.loc_mapper_store import LocMapperStore
|
||||
from mock import Mock
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
import bson.son
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
"""
|
||||
Tests for xmodule.modulestore.locator.
|
||||
Tests for opaque_keys.edx.locator.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
|
||||
import random
|
||||
from bson.objectid import ObjectId
|
||||
from opaque_keys import InvalidKeyError
|
||||
from xmodule.modulestore.locator import Locator, CourseLocator, BlockUsageLocator, DefinitionLocator
|
||||
from opaque_keys.edx.locator import Locator, CourseLocator, BlockUsageLocator, DefinitionLocator
|
||||
from ddt import ddt, data
|
||||
from xmodule.modulestore.keys import UsageKey, CourseKey, DefinitionKey
|
||||
from opaque_keys.edx.keys import UsageKey, CourseKey, DefinitionKey
|
||||
|
||||
|
||||
@ddt
|
||||
|
||||
@@ -9,12 +9,12 @@ from xmodule.modulestore import Location, MONGO_MODULESTORE_TYPE, SPLIT_MONGO_MO
|
||||
XML_MODULESTORE_TYPE
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
|
||||
from xmodule.modulestore.locator import BlockUsageLocator, CourseLocator
|
||||
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
|
||||
from xmodule.modulestore.tests.test_location_mapper import LocMapperSetupSansDjango, loc_mapper
|
||||
# Mixed modulestore depends on django, so we'll manually configure some django settings
|
||||
# before importing the module
|
||||
from django.conf import settings
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
import bson.son
|
||||
if not settings.configured:
|
||||
settings.configure()
|
||||
|
||||
@@ -2,7 +2,7 @@ from nose.tools import assert_equals, assert_raises, assert_true, assert_false
|
||||
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.search import path_to_location
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
def check_path_to_location(modulestore):
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user