コード例 #1
0
    def translate_location_to_course_locator(self, course_key, published=True):
        """
        Used when you only need the CourseLocator and not a full BlockUsageLocator. Probably only
        useful for get_items which wildcards name or category.

        :param course_key: a CourseKey
        :param published: a boolean representing whether or not we should return the published or draft version

        Returns a Courselocator
        """
        cached = self._get_course_locator_from_cache(course_key, published)
        if cached:
            return cached

        course_son = self._interpret_location_course_id(course_key)

        entry = self.location_map.find_one(course_son)
        if entry is None:
            raise ItemNotFoundError(course_key)

        published_course_locator = CourseLocator(org=entry['org'],
                                                 offering=entry['offering'],
                                                 branch=entry['prod_branch'])
        draft_course_locator = CourseLocator(org=entry['org'],
                                             offering=entry['offering'],
                                             branch=entry['draft_branch'])
        self._cache_course_locator(course_key, published_course_locator,
                                   draft_course_locator)
        if published:
            return published_course_locator
        else:
            return draft_course_locator
コード例 #2
0
    def translate_location_to_course_locator(self,
                                             old_style_course_id,
                                             location,
                                             published=True,
                                             lower_only=False):
        """
        Used when you only need the CourseLocator and not a full BlockUsageLocator. Probably only
        useful for get_items which wildcards name or category.

        :param course_id: old style course id
        """
        cached = self._get_course_locator_from_cache(old_style_course_id,
                                                     published)
        if cached:
            return cached

        location_id = self._interpret_location_course_id(
            old_style_course_id, location, lower_only)

        entry = self._get_map_entry_form_location(location_id)
        if entry is None:
            raise ItemNotFoundError(location)

        published_course_locator = CourseLocator(package_id=entry['course_id'],
                                                 branch=entry['prod_branch'])
        draft_course_locator = CourseLocator(package_id=entry['course_id'],
                                             branch=entry['draft_branch'])
        self._cache_course_locator(old_style_course_id,
                                   published_course_locator,
                                   draft_course_locator)
        if published:
            return published_course_locator
        else:
            return draft_course_locator
コード例 #3
0
ファイル: test_crud.py プロジェクト: danielnegri/edx-platform
    def test_delete_course(self):
        test_course = persistent_factories.PersistentCourseFactory.create(
            org='testx',
            prettyid='edu.harvard.history.doomed',
            display_name='doomed test course',
            user_id='testbot')
        persistent_factories.ItemFactory.create(
            display_name='chapter 1', parent_location=test_course.location)

        id_locator = CourseLocator(course_id=test_course.location.course_id,
                                   branch='draft')
        guid_locator = CourseLocator(
            version_guid=test_course.location.version_guid)
        # verify it can be retireved by id
        self.assertIsInstance(
            modulestore('split').get_course(id_locator), CourseDescriptor)
        # and by guid
        self.assertIsInstance(
            modulestore('split').get_course(guid_locator), CourseDescriptor)
        modulestore('split').delete_course(id_locator.course_id)
        # test can no longer retrieve by id
        self.assertRaises(ItemNotFoundError,
                          modulestore('split').get_course, id_locator)
        # but can by guid
        self.assertIsInstance(
            modulestore('split').get_course(guid_locator), CourseDescriptor)
コード例 #4
0
    def translate_location_to_course_locator(self, old_style_course_id, location, published=True, lower_only=False):
        """
        Used when you only need the CourseLocator and not a full BlockUsageLocator. Probably only
        useful for get_items which wildcards name or category.

        :param course_id: old style course id
        """
        cached = self._get_course_locator_from_cache(old_style_course_id, published)
        if cached:
            return cached

        location_id = self._interpret_location_course_id(old_style_course_id, location, lower_only)

        maps = self.location_map.find(location_id)
        maps = list(maps)
        if len(maps) == 0:
            raise ItemNotFoundError(location)
        elif len(maps) == 1:
            entry = maps[0]
        else:
            # find entry w/o name, if any; otherwise, pick arbitrary
            entry = maps[0]
            for item in maps:
                if 'name' not in item['_id']:
                    entry = item
                    break
        published_course_locator = CourseLocator(package_id=entry['course_id'], branch=entry['prod_branch'])
        draft_course_locator = CourseLocator(package_id=entry['course_id'], branch=entry['draft_branch'])
        self._cache_course_locator(old_style_course_id, published_course_locator, draft_course_locator)
        if published:
            return published_course_locator
        else:
            return draft_course_locator
コード例 #5
0
    def test_course_keyword_setters(self):
        raise SkipTest()
        # arg list inits
        testobj = CourseLocator(version_guid='versionid')
        self.check_course_locn_fields(testobj, 'versionid arg', 'versionid')

        testobj = CourseLocator(course_id='courseid')
        self.check_course_locn_fields(testobj,
                                      'courseid arg',
                                      course_id='courseid')

        testobj = CourseLocator(course_id='courseid', revision='rev')
        self.check_course_locn_fields(testobj,
                                      'rev arg',
                                      course_id='courseid',
                                      revision='rev')
        # ignores garbage
        testobj = CourseLocator(course_id='courseid',
                                revision='rev',
                                potato='spud')
        self.check_course_locn_fields(testobj,
                                      'extra keyword arg',
                                      course_id='courseid',
                                      revision='rev')

        # url w/ keyword override
        testurn = 'crx/courseid@revision/blockid'
        testobj = CourseLocator(testurn, revision='rev')
        self.check_course_locn_fields(testobj,
                                      'rev override',
                                      course_id='courseid',
                                      revision='rev')
コード例 #6
0
 def test_get_course_negative(self):
     # Now negative testing
     self.assertRaises(InsufficientSpecificationError,
                       modulestore().get_course, CourseLocator(course_id='edu.meh.blah'))
     self.assertRaises(ItemNotFoundError,
                       modulestore().get_course, CourseLocator(course_id='nosuchthing', branch='draft'))
     self.assertRaises(ItemNotFoundError,
                       modulestore().get_course,
                       CourseLocator(course_id='GreekHero', branch='published'))
コード例 #7
0
    def test_cloned_course(self):
        """
        Test making a course which points to an existing draft and published but not making any changes to either.
        """
        pre_time = datetime.datetime.now(UTC)
        original_locator = CourseLocator(course_id="wonderful", branch='draft')
        original_index = modulestore().get_course_index_info(original_locator)
        new_draft = modulestore().create_course(
            'leech', 'best_course', 'leech_master', id_root='best',
            versions_dict=original_index['versions'])
        new_draft_locator = new_draft.location
        self.assertRegexpMatches(new_draft_locator.course_id, r'best.*')
        # the edited_by and other meta fields on the new course will be the original author not this one
        self.assertEqual(new_draft.edited_by, '*****@*****.**')
        self.assertLess(new_draft.edited_on, pre_time)
        self.assertEqual(new_draft.location.version_guid, original_index['versions']['draft'])
        # however the edited_by and other meta fields on course_index will be this one
        new_index = modulestore().get_course_index_info(new_draft_locator)
        self.assertGreaterEqual(new_index["edited_on"], pre_time)
        self.assertLessEqual(new_index["edited_on"], datetime.datetime.now(UTC))
        self.assertEqual(new_index['edited_by'], 'leech_master')

        new_published_locator = CourseLocator(course_id=new_draft_locator.course_id, branch='published')
        new_published = modulestore().get_course(new_published_locator)
        self.assertEqual(new_published.edited_by, '*****@*****.**')
        self.assertLess(new_published.edited_on, pre_time)
        self.assertEqual(new_published.location.version_guid, original_index['versions']['published'])

        # changing this course will not change the original course
        # using new_draft.location will insert the chapter under the course root
        new_item = modulestore().create_item(
            new_draft.location, 'chapter', 'leech_master',
            fields={'display_name': 'new chapter'}
        )
        new_draft_locator.version_guid = None
        new_index = modulestore().get_course_index_info(new_draft_locator)
        self.assertNotEqual(new_index['versions']['draft'], original_index['versions']['draft'])
        new_draft = modulestore().get_course(new_draft_locator)
        self.assertEqual(new_item.edited_by, 'leech_master')
        self.assertGreaterEqual(new_item.edited_on, pre_time)
        self.assertNotEqual(new_item.location.version_guid, original_index['versions']['draft'])
        self.assertNotEqual(new_draft.location.version_guid, original_index['versions']['draft'])
        structure_info = modulestore().get_course_history_info(new_draft_locator)
        self.assertGreaterEqual(structure_info["edited_on"], pre_time)
        self.assertLessEqual(structure_info["edited_on"], datetime.datetime.now(UTC))
        self.assertEqual(structure_info['edited_by'], 'leech_master')

        original_course = modulestore().get_course(original_locator)
        self.assertEqual(original_course.location.version_guid, original_index['versions']['draft'])
        self.assertFalse(
            modulestore().has_item(new_draft_locator.course_id, BlockUsageLocator(
                original_locator,
                usage_id=new_item.location.usage_id
            ))
        )
コード例 #8
0
    def test_course_constructor_bad_package_id(self, bad_id):
        """
        Test all sorts of badly-formed package_ids (and urls with those package_ids)
        """
        with self.assertRaises(InvalidKeyError):
            CourseLocator(org=bad_id, offering='test')

        with self.assertRaises(InvalidKeyError):
            CourseLocator(org='test', offering=bad_id)

        with self.assertRaises(InvalidKeyError):
            CourseKey.from_string('course-locator:test+{}'.format(bad_id))
コード例 #9
0
    def _load_item(self, block_id, course_entry_override=None):
        if isinstance(block_id, BlockUsageLocator):
            if isinstance(block_id.block_id, LocalId):
                try:
                    return self.local_modules[block_id]
                except KeyError:
                    raise ItemNotFoundError
            else:
                block_id = block_id.block_id

        json_data = self.module_data.get(block_id)
        if json_data is None:
            # deeper than initial descendant fetch or doesn't exist
            course_info = course_entry_override or self.course_entry
            course_key = CourseLocator(course_info.get('org'),
                                       course_info.get('offering'),
                                       course_info.get('branch'),
                                       course_info['structure']['_id'])
            self.modulestore.cache_items(self, [block_id],
                                         course_key,
                                         lazy=self.lazy)
            json_data = self.module_data.get(block_id)
            if json_data is None:
                raise ItemNotFoundError(block_id)

        class_ = self.load_block_type(json_data.get('category'))
        return self.xblock_from_json(class_, block_id, json_data,
                                     course_entry_override)
コード例 #10
0
ファイル: test_access.py プロジェクト: ybergner/edx-platform
 def setUp(self):
     """ Test case setup """
     self.global_admin = AdminFactory()
     self.instructor = User.objects.create_user('testinstructor', '*****@*****.**', 'foo')
     self.staff = User.objects.create_user('teststaff', '*****@*****.**', 'foo')
     self.location = Location('i4x', 'mitX', '101', 'course', 'test')
     self.locator = CourseLocator(url='edx://mitX.101.test')
コード例 #11
0
    def handle(self, *args, **options):
        if len(args) < 2:
            raise CommandError(
                "rollback_split_course requires 2 arguments (org offering)"
            )

        try:
            locator = CourseLocator(org=args[0], offering=args[1])
        except ValueError:
            raise CommandError("Invalid org or offering string {}, {}".format(*args))

        location = loc_mapper().translate_locator_to_location(locator, get_course=True)
        if not location:
            raise CommandError(
                "This course does not exist in the old Mongo store. "
                "This command is designed to rollback a course, not delete "
                "it entirely."
            )
        old_mongo_course = modulestore('direct').get_item(location)
        if not old_mongo_course:
            raise CommandError(
                "This course does not exist in the old Mongo store. "
                "This command is designed to rollback a course, not delete "
                "it entirely."
            )

        try:
            modulestore('split').delete_course(locator)
        except ItemNotFoundError:
            raise CommandError("No course found with locator {}".format(locator))

        print(
            'Course rolled back successfully. To delete this course entirely, '
            'call the "delete_course" management command.'
        )
コード例 #12
0
    def test_get_items(self):
        '''
        get_items(locator, qualifiers, [branch])
        '''
        locator = CourseLocator(version_guid=self.GUID_D0)
        # get all modules
        matches = modulestore().get_items(locator)
        self.assertEqual(len(matches), 6)
        matches = modulestore().get_items(locator, qualifiers={})
        self.assertEqual(len(matches), 6)
        matches = modulestore().get_items(locator, qualifiers={'category': 'chapter'})
        self.assertEqual(len(matches), 3)
        matches = modulestore().get_items(locator, qualifiers={'category': 'garbage'})
        self.assertEqual(len(matches), 0)
        matches = modulestore().get_items(
            locator,
            qualifiers=
            {
                'category': 'chapter',
                'fields': {'display_name': {'$regex': 'Hera'}}
            }
        )
        self.assertEqual(len(matches), 2)

        matches = modulestore().get_items(locator, qualifiers={'fields': {'children': 'chapter2'}})
        self.assertEqual(len(matches), 1)
        self.assertEqual(matches[0].location.usage_id, 'head12345')
コード例 #13
0
 def test_course_constructor_url_course_id_branch_and_version_guid(self):
     test_id_loc = '519665f6223ebd6980884f2b'
     testobj = CourseLocator(url='edx://mit.eecs.6002x' + BRANCH_PREFIX + 'draft' + VERSION_PREFIX + test_id_loc)
     self.check_course_locn_fields(testobj, 'error parsing url with both course ID branch, and version GUID',
                                   course_id='mit.eecs.6002x',
                                   branch='draft',
                                   version_guid=ObjectId(test_id_loc))
コード例 #14
0
 def test_course_constructor_course_id_no_branch(self):
     testurn = 'mit.eecs.6002x'
     testobj = CourseLocator(course_id=testurn)
     self.check_course_locn_fields(testobj, 'course_id', course_id=testurn)
     self.assertEqual(testobj.course_id, testurn)
     self.assertEqual(str(testobj), testurn)
     self.assertEqual(testobj.url(), 'edx://' + testurn)
コード例 #15
0
    def test_course_constructor_version_guid(self):
        # generate a random location
        test_id_1 = ObjectId()
        test_id_1_loc = str(test_id_1)
        testobj_1 = CourseLocator(version_guid=test_id_1)
        self.check_course_locn_fields(testobj_1, version_guid=test_id_1)
        self.assertEqual(str(testobj_1.version_guid), test_id_1_loc)
        self.assertEqual(testobj_1._to_string(), u'+'.join((testobj_1.VERSION_PREFIX, test_id_1_loc)))

        # Test using a given string
        test_id_2_loc = '519665f6223ebd6980884f2b'
        test_id_2 = ObjectId(test_id_2_loc)
        testobj_2 = CourseLocator(version_guid=test_id_2)
        self.check_course_locn_fields(testobj_2, version_guid=test_id_2)
        self.assertEqual(str(testobj_2.version_guid), test_id_2_loc)
        self.assertEqual(testobj_2._to_string(), u'+'.join((testobj_2.VERSION_PREFIX, test_id_2_loc)))
コード例 #16
0
 def test_course_constructor_package_id_no_branch(self):
     org = 'mit.eecs'
     offering = '6002x'
     testurn = '{}+{}'.format(org, offering)
     testobj = CourseLocator(org=org, offering=offering)
     self.check_course_locn_fields(testobj, org=org, offering=offering)
     self.assertEqual(testobj._to_string(), testurn)
コード例 #17
0
 def _create_item(self, category, name, data, metadata, parent_category, parent_name, runtime):
     """
     Create the item of the given category and block id in split and old mongo, add it to the optional
     parent. The parent category is only needed because old mongo requires it for the id.
     """
     location = Location('i4x', 'test_org', 'test_course', category, name)
     self.old_mongo.create_and_save_xmodule(location, data, metadata, runtime)
     if isinstance(data, basestring):
         fields = {'data': data}
     else:
         fields = data.copy()
     fields.update(metadata)
     if parent_name:
         # add child to parent in mongo
         parent_location = Location('i4x', 'test_org', 'test_course', parent_category, parent_name)
         parent = self.old_mongo.get_item(parent_location)
         parent.children.append(location.url())
         self.old_mongo.update_children(parent_location, parent.children)
         # create pointer for split
         course_or_parent_locator = BlockUsageLocator(
             course_id=self.split_course_id,
             branch='draft',
             usage_id=parent_name
         )
     else:
         course_or_parent_locator = CourseLocator(
             course_id='test_org.test_course.runid',
             branch='draft',
         )
     self.split_mongo.create_item(course_or_parent_locator, category, self.userid, usage_id=name, fields=fields)
コード例 #18
0
    def create_map_entry(self,
                         course_key,
                         org=None,
                         offering=None,
                         draft_branch='draft',
                         prod_branch='published',
                         block_map=None):
        """
        Add a new entry to map this SlashSeparatedCourseKey to the new style CourseLocator.org & offering. If
        org and offering are not provided, it defaults them based on course_key.

        WARNING: Exactly 1 CourseLocator key should index a given SlashSeparatedCourseKey.
        We provide no mechanism to enforce this assertion.

        NOTE: if there's already an entry w the given course_key, this may either overwrite that entry or
        throw an error depending on how mongo is configured.

        :param course_key (SlashSeparatedCourseKey): a SlashSeparatedCourseKey
        :param org (string): the CourseLocator style org
        :param offering (string): the CourseLocator offering
        :param draft_branch: the branch name to assign for drafts. This is hardcoded because old mongo had
        a fixed notion that there was 2 and only 2 versions for modules: draft and production. The old mongo
        did not, however, require that a draft version exist. The new one, however, does require a draft to
        exist.
        :param prod_branch: the branch name to assign for the production (live) copy. In old mongo, every course
        had to have a production version (whereas new split mongo does not require that until the author's ready
        to publish).
        :param block_map: an optional map to specify preferred names for blocks where the keys are the
        Location block names and the values are the BlockUsageLocator.block_id.

        Returns:
            :class:`CourseLocator` representing the new id for the course

        Raises:
            ValueError if one and only one of org and offering is provided. Provide either both or neither.
        """
        if org is None and offering is None:
            assert (isinstance(course_key, SlashSeparatedCourseKey))
            org = course_key.org
            offering = u"{0.course}.{0.run}".format(course_key)
        elif org is None or offering is None:
            raise ValueError(
                u"Either supply both org and offering or neither. Not just one: {}, {}"
                .format(org, offering))

        # very like _interpret_location_id but using mongo subdoc lookup (more performant)
        course_son = self._construct_course_son(course_key)

        self.location_map.insert({
            '_id': course_son,
            'org': org,
            'offering': offering,
            'draft_branch': draft_branch,
            'prod_branch': prod_branch,
            'block_map': block_map or {},
            'schema': self.SCHEMA_VERSION,
        })

        return CourseLocator(org, offering)
コード例 #19
0
 def test_course_constructor_redundant_002(self):
     testurn = 'mit.eecs.6002x' + BRANCH_PREFIX + 'published'
     expected_urn = 'mit.eecs.6002x'
     expected_rev = 'published'
     testobj = CourseLocator(course_id=testurn, url='edx://' + testurn)
     self.check_course_locn_fields(testobj, 'course_id',
                                   course_id=expected_urn,
                                   branch=expected_rev)
コード例 #20
0
ファイル: course.py プロジェクト: raeeschachar/edx-platform
def course_info_update_handler(request,
                               tag=None,
                               package_id=None,
                               branch=None,
                               version_guid=None,
                               block=None,
                               provided_id=None):
    """
    restful CRUD operations on course_info updates.
    provided_id should be none if it's new (create) and index otherwise.
    GET
        json: return the course info update models
    POST
        json: create an update
    PUT or DELETE
        json: change an existing update
    """
    if 'application/json' not in request.META.get('HTTP_ACCEPT',
                                                  'application/json'):
        return HttpResponseBadRequest("Only supports json requests")

    course_location = loc_mapper().translate_locator_to_location(
        CourseLocator(package_id=package_id), get_course=True)
    updates_location = course_location.replace(category='course_info',
                                               name=block)
    if provided_id == '':
        provided_id = None

    # check that logged in user has permissions to this item (GET shouldn't require this level?)
    if not has_course_access(request.user, updates_location):
        raise PermissionDenied()

    if request.method == 'GET':
        course_updates = get_course_updates(updates_location, provided_id)
        if isinstance(course_updates, dict) and course_updates.get('error'):
            return JsonResponse(
                get_course_updates(updates_location, provided_id),
                course_updates.get('status', 400))
        else:
            return JsonResponse(
                get_course_updates(updates_location, provided_id))
    elif request.method == 'DELETE':
        try:
            return JsonResponse(
                delete_course_update(updates_location, request.json,
                                     provided_id, request.user))
        except:
            return HttpResponseBadRequest("Failed to delete",
                                          content_type="text/plain")
    # can be either and sometimes django is rewriting one to the other:
    elif request.method in ('POST', 'PUT'):
        try:
            return JsonResponse(
                update_course_updates(updates_location, request.json,
                                      provided_id, request.user))
        except:
            return HttpResponseBadRequest("Failed to save",
                                          content_type="text/plain")
コード例 #21
0
 def test_course_constructor_url_package_id_and_version_guid(self):
     test_id_loc = '519665f6223ebd6980884f2b'
     testobj = CourseLocator(url='edx://mit.eecs-honors.6002x/' +
                             VERSION_PREFIX + test_id_loc)
     self.check_course_locn_fields(
         testobj,
         'error parsing url with both course ID and version GUID',
         package_id='mit.eecs-honors.6002x',
         version_guid=ObjectId(test_id_loc))
コード例 #22
0
 def test_course_constructor_url(self):
     # Test parsing a url when it starts with a version ID and there is also a block ID.
     # This hits the parsers parse_guid method.
     test_id_loc = '519665f6223ebd6980884f2b'
     testobj = CourseLocator(url="edx://" + URL_VERSION_PREFIX +
                             test_id_loc + BLOCK_PREFIX + "hw3")
     self.check_course_locn_fields(testobj,
                                   'test_block constructor',
                                   version_guid=ObjectId(test_id_loc))
コード例 #23
0
    def test_course_constructor_version_guid(self):
        # generate a random location
        test_id_1 = ObjectId()
        test_id_1_loc = str(test_id_1)
        testobj_1 = CourseLocator(version_guid=test_id_1)
        self.check_course_locn_fields(testobj_1, 'version_guid', version_guid=test_id_1)
        self.assertEqual(str(testobj_1.version_guid), test_id_1_loc)
        self.assertEqual(str(testobj_1), URL_VERSION_PREFIX + test_id_1_loc)
        self.assertEqual(testobj_1.url(), 'edx://' + URL_VERSION_PREFIX + test_id_1_loc)

        # Test using a given string
        test_id_2_loc = '519665f6223ebd6980884f2b'
        test_id_2 = ObjectId(test_id_2_loc)
        testobj_2 = CourseLocator(version_guid=test_id_2)
        self.check_course_locn_fields(testobj_2, 'version_guid', version_guid=test_id_2)
        self.assertEqual(str(testobj_2.version_guid), test_id_2_loc)
        self.assertEqual(str(testobj_2), URL_VERSION_PREFIX + test_id_2_loc)
        self.assertEqual(testobj_2.url(), 'edx://' + URL_VERSION_PREFIX + test_id_2_loc)
コード例 #24
0
 def test_course_constructor_redundant_002(self):
     testurn = 'edu.mit.eecs.6002x;published'
     expected_urn = 'edu.mit.eecs.6002x'
     expected_rev = 'published'
     testobj = CourseLocator(course_id=testurn, url='edx://' + testurn)
     self.check_course_locn_fields(testobj,
                                   'course_id',
                                   course_id=expected_urn,
                                   revision=expected_rev)
コード例 #25
0
ファイル: mixed.py プロジェクト: skim-ks/edx-platform
    def get_course(self, course_id):
        """
        returns the course module associated with the course_id. If no such course exists,
        it returns None

        :param course_id: must be either a string course_id or a CourseLocator
        """
        store = self._get_modulestore_for_courseid(
            course_id.package_id if hasattr(course_id, 'package_id'
                                            ) else course_id)
        try:
            # translate won't work w/ missing fields so work around it
            if store.reference_type == Location:
                # takes the course_id: figure out if this is old or new style
                if not self.use_locations:
                    if isinstance(course_id, basestring):
                        course_id = CourseLocator(package_id=course_id,
                                                  branch='published')
                    course_location = loc_mapper(
                    ).translate_locator_to_location(course_id, get_course=True)
                    course_id = course_location.course_id
                xblock = store.get_course(course_id)
            else:
                # takes a courseLocator
                if isinstance(course_id, CourseLocator):
                    location = course_id
                    course_id = None  # not an old style course_id; so, don't use it further
                elif '/' in course_id:
                    location = loc_mapper(
                    ).translate_location_to_course_locator(
                        course_id, None, True)
                else:
                    location = CourseLocator(package_id=course_id,
                                             branch='published')
                    course_id = None  # not an old style course_id; so, don't use it further
                xblock = store.get_course(location)
        except ItemNotFoundError:
            return None
        if xblock is not None:
            return self._outgoing_xblock_adaptor(store, course_id, xblock)
        else:
            return None
コード例 #26
0
    def test_update_course_index(self):
        """
        Test changing the org, pretty id, etc of a course. Test that it doesn't allow changing the id, etc.
        """
        locator = CourseLocator(course_id="GreekHero", branch='draft')
        modulestore().update_course_index(locator, {'org': 'funkyU'})
        course_info = modulestore().get_course_index_info(locator)
        self.assertEqual(course_info['org'], 'funkyU')

        modulestore().update_course_index(locator, {'org': 'moreFunky', 'prettyid': 'Ancient Greek Demagods'})
        course_info = modulestore().get_course_index_info(locator)
        self.assertEqual(course_info['org'], 'moreFunky')
        self.assertEqual(course_info['prettyid'], 'Ancient Greek Demagods')

        self.assertRaises(ValueError, modulestore().update_course_index, locator, {'_id': 'funkygreeks'})

        with self.assertRaises(ValueError):
            modulestore().update_course_index(
                locator,
                {'edited_on': datetime.datetime.now(UTC)}
            )
        with self.assertRaises(ValueError):
            modulestore().update_course_index(
                locator,
                {'edited_by': 'sneak'}
            )

        self.assertRaises(ValueError, modulestore().update_course_index, locator,
                          {'versions': {'draft': self.GUID_D1}})

        # an allowed but not necessarily recommended way to revert the draft version
        versions = course_info['versions']
        versions['draft'] = self.GUID_D1
        modulestore().update_course_index(locator, {'versions': versions}, update_versions=True)
        course = modulestore().get_course(locator)
        self.assertEqual(str(course.location.version_guid), self.GUID_D1)

        # an allowed but not recommended way to publish a course
        versions['published'] = self.GUID_D1
        modulestore().update_course_index(locator, {'versions': versions}, update_versions=True)
        course = modulestore().get_course(CourseLocator(course_id=locator.course_id, branch="published"))
        self.assertEqual(str(course.location.version_guid), self.GUID_D1)
コード例 #27
0
    def test_course_urls(self):
        '''
        Test constructor and property accessors.
        '''
        raise SkipTest()
        self.assertRaises(TypeError, CourseLocator, 'empty constructor')

        # url inits
        testurn = 'edx://org/course/category/name'
        self.assertRaises(InvalidLocationError, CourseLocator, url=testurn)
        testurn = 'unknown/versionid/blockid'
        self.assertRaises(InvalidLocationError, CourseLocator, url=testurn)

        testurn = 'cvx/versionid'
        testobj = CourseLocator(testurn)
        self.check_course_locn_fields(testobj, testurn, 'versionid')
        self.assertEqual(testobj, CourseLocator(testobj),
                         'initialization from another instance')

        testurn = 'cvx/versionid/'
        testobj = CourseLocator(testurn)
        self.check_course_locn_fields(testobj, testurn, 'versionid')

        testurn = 'cvx/versionid/blockid'
        testobj = CourseLocator(testurn)
        self.check_course_locn_fields(testobj, testurn, 'versionid')

        testurn = 'cvx/versionid/blockid/extraneousstuff?including=args'
        testobj = CourseLocator(testurn)
        self.check_course_locn_fields(testobj, testurn, 'versionid')

        testurn = 'cvx://versionid/blockid'
        testobj = CourseLocator(testurn)
        self.check_course_locn_fields(testobj, testurn, 'versionid')

        testurn = 'crx/courseid/blockid'
        testobj = CourseLocator(testurn)
        self.check_course_locn_fields(testobj, testurn, course_id='courseid')

        testurn = 'crx/courseid@revision/blockid'
        testobj = CourseLocator(testurn)
        self.check_course_locn_fields(testobj,
                                      testurn,
                                      course_id='courseid',
                                      revision='revision')
        self.assertEqual(testobj, CourseLocator(testobj),
                         'run initialization from another instance')
コード例 #28
0
 def test_locator_string(self):
     call_command(
         "migrate_to_split",
         str(self.course.location),
         str(self.user.id),
         "org.dept.name.run",
     )
     locator = CourseLocator(package_id="org.dept.name.run",
                             branch="published")
     course_from_split = modulestore('split').get_course(locator)
     self.assertIsNotNone(course_from_split)
コード例 #29
0
    def test_get_course(self):
        '''
        Test the various calling forms for get_course
        '''
        locator = CourseLocator(version_guid=self.GUID_D1)
        course = modulestore().get_course(locator)
        self.assertIsNone(course.location.course_id)
        self.assertEqual(str(course.location.version_guid), self.GUID_D1)
        self.assertEqual(course.category, 'course')
        self.assertEqual(len(course.tabs), 6)
        self.assertEqual(course.display_name, "The Ancient Greek Hero")
        self.assertEqual(course.graceperiod, datetime.timedelta(hours=2))
        self.assertIsNone(course.advertised_start)
        self.assertEqual(len(course.children), 0)
        self.assertEqual(course.definition_locator.definition_id, "head12345_11")
        # check dates and graders--forces loading of descriptor
        self.assertEqual(course.edited_by, "*****@*****.**")
        self.assertDictEqual(course.grade_cutoffs, {"Pass": 0.55})

        locator = CourseLocator(course_id='GreekHero', branch='draft')
        course = modulestore().get_course(locator)
        self.assertEqual(course.location.course_id, "GreekHero")
        self.assertEqual(str(course.location.version_guid), self.GUID_D0)
        self.assertEqual(course.category, 'course')
        self.assertEqual(len(course.tabs), 6)
        self.assertEqual(course.display_name, "The Ancient Greek Hero")
        self.assertEqual(course.advertised_start, "Fall 2013")
        self.assertEqual(len(course.children), 3)
        # check dates and graders--forces loading of descriptor
        self.assertEqual(course.edited_by, "*****@*****.**")
        self.assertDictEqual(course.grade_cutoffs, {"Pass": 0.45})

        locator = CourseLocator(course_id='wonderful', branch='published')
        course = modulestore().get_course(locator)
        self.assertEqual(course.location.course_id, "wonderful")
        self.assertEqual(str(course.location.version_guid), self.GUID_P)

        locator = CourseLocator(course_id='wonderful', branch='draft')
        course = modulestore().get_course(locator)
        self.assertEqual(str(course.location.version_guid), self.GUID_D2)
コード例 #30
0
 def test_course_constructor_course_id_separate_branch(self):
     test_id = 'mit.eecs.6002x'
     test_branch = 'published'
     expected_urn = 'mit.eecs.6002x' + BRANCH_PREFIX + 'published'
     testobj = CourseLocator(course_id=test_id, branch=test_branch)
     self.check_course_locn_fields(testobj, 'course_id with separate branch',
                                   course_id=test_id,
                                   branch=test_branch,
                                   )
     self.assertEqual(testobj.course_id, test_id)
     self.assertEqual(testobj.branch, test_branch)
     self.assertEqual(str(testobj), expected_urn)
     self.assertEqual(testobj.url(), 'edx://' + expected_urn)