def _create(cls, target_class, **kwargs): # All class attributes (from this class and base classes) are # passed in via **kwargs. However, some of those aren't actual field values, # so pop those off for use separately org = kwargs.pop('org', None) # because the factory provides a default 'number' arg, prefer the non-defaulted 'course' arg if any number = kwargs.pop('course', kwargs.pop('number', None)) store = kwargs.pop('modulestore') name = kwargs.get( 'name', kwargs.get('run', Location.clean(kwargs.get('display_name')))) run = kwargs.get('run', name) location = Location(org, number, run, 'course', name) # Write the data to the mongo datastore new_course = store.create_xmodule(location, metadata=kwargs.get( 'metadata', None)) # The rest of kwargs become attributes on the course: for k, v in kwargs.iteritems(): setattr(new_course, k, v) # Save the attributes we just set new_course.save() # Update the data in the mongo datastore store.update_item(new_course) return new_course
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 _query_children_for_cache_children(self, course_key, items): # first get non-draft in a round-trip to_process_non_drafts = super(DraftModuleStore, self)._query_children_for_cache_children(course_key, items) to_process_dict = {} for non_draft in to_process_non_drafts: to_process_dict[Location._from_deprecated_son(non_draft["_id"], course_key.run)] = non_draft # now query all draft content in another round-trip query = { "_id": { "$in": [ as_draft(course_key.make_usage_key_from_deprecated_string(item)).to_deprecated_son() for item in items ] } } to_process_drafts = list(self.collection.find(query)) # now we have to go through all drafts and replace the non-draft # with the draft. This is because the semantics of the DraftStore is to # always return the draft - if available for draft in to_process_drafts: draft_loc = Location._from_deprecated_son(draft["_id"], course_key.run) draft_as_non_draft_loc = draft_loc.replace(revision=None) # does non-draft exist in the collection # if so, replace it if draft_as_non_draft_loc in to_process_dict: to_process_dict[draft_as_non_draft_loc] = draft # convert the dict - which is used for look ups - back into a list queried_children = to_process_dict.values() return queried_children
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') )
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')
def _create(cls, target_class, **kwargs): # All class attributes (from this class and base classes) are # passed in via **kwargs. However, some of those aren't actual field values, # so pop those off for use separately org = kwargs.pop('org', None) # because the factory provides a default 'number' arg, prefer the non-defaulted 'course' arg if any number = kwargs.pop('course', kwargs.pop('number', None)) store = kwargs.pop('modulestore') name = kwargs.get('name', kwargs.get('run', Location.clean(kwargs.get('display_name')))) run = kwargs.get('run', name) location = Location(org, number, run, 'course', name) # Write the data to the mongo datastore new_course = store.create_xmodule(location, metadata=kwargs.get('metadata', None)) # The rest of kwargs become attributes on the course: for k, v in kwargs.iteritems(): setattr(new_course, k, v) # Save the attributes we just set new_course.save() # Update the data in the mongo datastore store.update_item(new_course) return new_course
def problem_location(problem_url_name): """ Create an internal location for a test problem. """ if "i4x:" in problem_url_name: return Location.from_deprecated_string(problem_url_name) else: return TEST_COURSE_KEY.make_usage_key('problem', problem_url_name)
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)
def setUp(self): field_data = Mock(spec=FieldData) self.descriptor = BrokenDescriptor( TestRuntime(Mock(spec=IdReader), field_data), field_data, ScopeIds(None, None, None, Location('org', 'course', 'run', 'broken', 'name', None))) self.descriptor.xmodule_runtime = TestRuntime(Mock(spec=IdReader), field_data) self.descriptor.xmodule_runtime.error_descriptor_class = ErrorDescriptor self.descriptor.xmodule_runtime.xmodule_instance = None
def test___find_corresponding_module_for_location_exceptions(self): """ Unit test for the exception cases of __find_corresponding_module_for_location Mainly for diff coverage @return: """ # pylint: disable=protected-access with self.assertRaises(ItemNotFoundError): self.peer_grading._find_corresponding_module_for_location( Location('org', 'course', 'run', 'category', 'name', 'revision'))
def to_python(self, location): """ Deserialize to a UsageKey instance: for now it's a location missing the run """ assert isinstance(location, (NoneType, basestring, Location)) if location == '': return None if isinstance(location, basestring): location = super(UsageKeyField, self).to_python(location) return Location.from_deprecated_string(location) else: return location
def _query_children_for_cache_children(self, course_key, items): # first get non-draft in a round-trip to_process_non_drafts = super(DraftModuleStore, self)._query_children_for_cache_children( course_key, items) to_process_dict = {} for non_draft in to_process_non_drafts: to_process_dict[Location._from_deprecated_son( non_draft["_id"], course_key.run)] = non_draft # now query all draft content in another round-trip query = { '_id': { '$in': [ as_draft( course_key.make_usage_key_from_deprecated_string( item)).to_deprecated_son() for item in items ] } } to_process_drafts = list(self.collection.find(query)) # now we have to go through all drafts and replace the non-draft # with the draft. This is because the semantics of the DraftStore is to # always return the draft - if available for draft in to_process_drafts: draft_loc = Location._from_deprecated_son(draft["_id"], course_key.run) draft_as_non_draft_loc = draft_loc.replace(revision=None) # does non-draft exist in the collection # if so, replace it if draft_as_non_draft_loc in to_process_dict: to_process_dict[draft_as_non_draft_loc] = draft # convert the dict - which is used for look ups - back into a list queried_children = to_process_dict.values() return queried_children
def assign_textbook_id(textbook, used_ids=()): """ Return an ID that can be assigned to a textbook and doesn't match the used_ids """ tid = Location.clean(textbook["tab_title"]) if not tid[0].isdigit(): # stick a random digit in front tid = random.choice(string.digits) + tid while tid in used_ids: # add a random ASCII character to the end tid = tid + random.choice(string.ascii_lowercase) return tid
def to_python(self, value): if value is self.Empty or value is None: return value assert isinstance(value, (basestring, Location)) if value == '': return None if isinstance(value, basestring): return Location.from_deprecated_string(value) else: return value
def parent_location(self): default_location = Location('MITx', '999', 'Robot_Super_Course', 'course', 'Robot_Super_Course', None) try: parent = self.parent # This error is raised if the caller hasn't provided either parent or parent_location # In this case, we'll just return the default parent_location except CyclicDefinitionError: return default_location if parent is None: return default_location return parent.location
def setUp(self): self.request_factory = RequestFactory() patcher = patch('contentstore.views.component.get_modulestore') self.get_modulestore = patcher.start() self.addCleanup(patcher.stop) self.descriptor = self.get_modulestore.return_value.get_item.return_value self.usage_key_string = unicode( Location('dummy_org', 'dummy_course', 'dummy_run', 'dummy_category', 'dummy_name')) self.user = UserFactory() self.request = self.request_factory.get('/dummy-url') self.request.user = self.user
def setUp(self): super(TabsEditingDescriptorTestCase, self).setUp() system = get_test_descriptor_system() system.render_template = Mock( return_value="<div>Test Template HTML</div>") self.tabs = [{ 'name': "Test_css", 'template': "tabs/codemirror-edit.html", 'current': True, 'css': { 'scss': [ resource_string( __name__, '../../test_files/test_tabseditingdescriptor.scss') ], 'css': [ resource_string( __name__, '../../test_files/test_tabseditingdescriptor.css') ] } }, { 'name': "Subtitles", 'template': "video/subtitles.html", }, { 'name': "Settings", 'template': "tabs/video-metadata-edit-tab.html" }] TabsEditingDescriptor.tabs = self.tabs self.descriptor = system.construct_xblock_from_class( TabsEditingDescriptor, scope_ids=ScopeIds( None, None, None, Location('org', 'course', 'run', 'category', 'name', 'revision')), field_data=DictFieldData({}), )
def test_clean_for_url_name(self, pair): self.assertEquals(Location.clean_for_url_name(pair[0]), pair[1])
def test_conditional_module(self): """Make sure that conditional module works""" print "Starting import" course = self.get_course('conditional_and_poll') print "Course: ", course print "id: ", course.id def inner_get_module(descriptor): if isinstance(descriptor, Location): location = descriptor descriptor = self.modulestore.get_item(location, depth=None) descriptor.xmodule_runtime = get_test_system() descriptor.xmodule_runtime.get_module = inner_get_module return descriptor # edx - HarvardX # cond_test - ER22x location = Location("HarvardX", "ER22x", "2013_Spring", "conditional", "condone") def replace_urls(text, staticfiles_prefix=None, replace_prefix='/static/', course_namespace=None): return text self.test_system.replace_urls = replace_urls self.test_system.get_module = inner_get_module module = inner_get_module(location) print "module: ", module print "module children: ", module.get_children() print "module display items (children): ", module.get_display_items() html = module.render('student_view').content print "html type: ", type(html) print "html: ", html html_expect = module.xmodule_runtime.render_template( 'conditional_ajax.html', { # Test ajax url is just usage-id / handler_name 'ajax_url': '{}/xmodule_handler'.format(location.to_deprecated_string()), 'element_id': u'i4x-HarvardX-ER22x-conditional-condone', 'depends': u'i4x-HarvardX-ER22x-problem-choiceprob' }) self.assertEqual(html, html_expect) gdi = module.get_display_items() print "gdi=", gdi ajax = json.loads(module.handle_ajax('', '')) module.save() print "ajax: ", ajax html = ajax['html'] self.assertFalse(any(['This is a secret' in item for item in html])) # Now change state of the capa problem to make it completed inner_module = inner_get_module( location.replace(category="problem", name='choiceprob')) inner_module.attempts = 1 # Save our modifications to the underlying KeyValueStore so they can be persisted inner_module.save() ajax = json.loads(module.handle_ajax('', '')) module.save() print "post-attempt ajax: ", ajax html = ajax['html'] self.assertTrue(any(['This is a secret' in item for item in html]))
def test_string_roundtrip(self, url): self.assertEquals(url, Location._from_string(url)._to_string()) # pylint: disable=protected-access
def create(system, source_is_error_module=False): """ return a dict of modules: the conditional with a single source and a single child. Keys are 'cond_module', 'source_module', and 'child_module'. if the source_is_error_module flag is set, create a real ErrorModule for the source. """ descriptor_system = get_test_descriptor_system() # construct source descriptor and module: source_location = Location("edX", "conditional_test", "test_run", "problem", "SampleProblem", None) if source_is_error_module: # Make an error descriptor and module source_descriptor = NonStaffErrorDescriptor.from_xml( 'some random xml data', system, id_generator=CourseLocationGenerator( SlashSeparatedCourseKey('edX', 'conditional_test', 'test_run')), error_msg='random error message') else: source_descriptor = Mock() source_descriptor.location = source_location source_descriptor.runtime = descriptor_system source_descriptor.render = lambda view, context=None: descriptor_system.render( source_descriptor, view, context) # construct other descriptors: child_descriptor = Mock() child_descriptor._xmodule.student_view.return_value.content = u'<p>This is a secret</p>' child_descriptor.student_view = child_descriptor._xmodule.student_view child_descriptor.displayable_items.return_value = [child_descriptor] child_descriptor.runtime = descriptor_system child_descriptor.xmodule_runtime = get_test_system() child_descriptor.render = lambda view, context=None: descriptor_system.render( child_descriptor, view, context) child_descriptor.location = source_location.replace(category='html', name='child') descriptor_system.load_item = { child_descriptor.location: child_descriptor, source_location: source_descriptor }.get # construct conditional module: cond_location = Location("edX", "conditional_test", "test_run", "conditional", "SampleConditional", None) field_data = DictFieldData({ 'data': '<conditional/>', 'xml_attributes': { 'attempted': 'true' }, 'children': [child_descriptor.location], }) cond_descriptor = ConditionalDescriptor( descriptor_system, field_data, ScopeIds(None, None, cond_location, cond_location)) cond_descriptor.xmodule_runtime = system system.get_module = lambda desc: desc cond_descriptor.get_required_module_descriptors = Mock( return_value=[source_descriptor]) # return dict: return { 'cond_module': cond_descriptor, 'source_module': source_descriptor, 'child_module': child_descriptor }
def test_immutable(self, attr): loc = Location('o', 'c', 'r', 'c', 'n', 'r') with self.assertRaises(AttributeError): setattr(loc, attr, attr)
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_clean_for_html(self, pair): self.assertEquals(Location.clean_for_html(pair[0]), pair[1])
def create(system, source_is_error_module=False): """ return a dict of modules: the conditional with a single source and a single child. Keys are 'cond_module', 'source_module', and 'child_module'. if the source_is_error_module flag is set, create a real ErrorModule for the source. """ descriptor_system = get_test_descriptor_system() # construct source descriptor and module: source_location = Location("edX", "conditional_test", "test_run", "problem", "SampleProblem", None) if source_is_error_module: # Make an error descriptor and module source_descriptor = NonStaffErrorDescriptor.from_xml( 'some random xml data', system, id_generator=CourseLocationGenerator(SlashSeparatedCourseKey('edX', 'conditional_test', 'test_run')), error_msg='random error message' ) else: source_descriptor = Mock() source_descriptor.location = source_location source_descriptor.runtime = descriptor_system source_descriptor.render = lambda view, context=None: descriptor_system.render(source_descriptor, view, context) # construct other descriptors: child_descriptor = Mock() child_descriptor._xmodule.student_view.return_value.content = u'<p>This is a secret</p>' child_descriptor.student_view = child_descriptor._xmodule.student_view child_descriptor.displayable_items.return_value = [child_descriptor] child_descriptor.runtime = descriptor_system child_descriptor.xmodule_runtime = get_test_system() child_descriptor.render = lambda view, context=None: descriptor_system.render(child_descriptor, view, context) child_descriptor.location = source_location.replace(category='html', name='child') descriptor_system.load_item = { child_descriptor.location: child_descriptor, source_location: source_descriptor }.get # construct conditional module: cond_location = Location("edX", "conditional_test", "test_run", "conditional", "SampleConditional", None) field_data = DictFieldData({ 'data': '<conditional/>', 'xml_attributes': {'attempted': 'true'}, 'children': [child_descriptor.location], }) cond_descriptor = ConditionalDescriptor( descriptor_system, field_data, ScopeIds(None, None, cond_location, cond_location) ) cond_descriptor.xmodule_runtime = system system.get_module = lambda desc: desc cond_descriptor.get_required_module_descriptors = Mock(return_value=[source_descriptor]) # return dict: return {'cond_module': cond_descriptor, 'source_module': source_descriptor, 'child_module': child_descriptor}
def test_invalid_locations(self, *args, **kwargs): with self.assertRaises(TypeError): Location(*args, **kwargs)
def test_conditional_module(self): """Make sure that conditional module works""" print "Starting import" course = self.get_course('conditional_and_poll') print "Course: ", course print "id: ", course.id def inner_get_module(descriptor): if isinstance(descriptor, Location): location = descriptor descriptor = self.modulestore.get_item(location, depth=None) descriptor.xmodule_runtime = get_test_system() descriptor.xmodule_runtime.get_module = inner_get_module return descriptor # edx - HarvardX # cond_test - ER22x location = Location("HarvardX", "ER22x", "2013_Spring", "conditional", "condone") def replace_urls(text, staticfiles_prefix=None, replace_prefix='/static/', course_namespace=None): return text self.test_system.replace_urls = replace_urls self.test_system.get_module = inner_get_module module = inner_get_module(location) print "module: ", module print "module children: ", module.get_children() print "module display items (children): ", module.get_display_items() html = module.render('student_view').content print "html type: ", type(html) print "html: ", html html_expect = module.xmodule_runtime.render_template( 'conditional_ajax.html', { # Test ajax url is just usage-id / handler_name 'ajax_url': '{}/xmodule_handler'.format(location.to_deprecated_string()), 'element_id': u'i4x-HarvardX-ER22x-conditional-condone', 'depends': u'i4x-HarvardX-ER22x-problem-choiceprob' } ) self.assertEqual(html, html_expect) gdi = module.get_display_items() print "gdi=", gdi ajax = json.loads(module.handle_ajax('', '')) module.save() print "ajax: ", ajax html = ajax['html'] self.assertFalse(any(['This is a secret' in item for item in html])) # Now change state of the capa problem to make it completed inner_module = inner_get_module(location.replace(category="problem", name='choiceprob')) inner_module.attempts = 1 # Save our modifications to the underlying KeyValueStore so they can be persisted inner_module.save() ajax = json.loads(module.handle_ajax('', '')) module.save() print "post-attempt ajax: ", ajax html = ajax['html'] self.assertTrue(any(['This is a secret' in item for item in html]))
def test_clean(self, pair): self.assertEquals(Location.clean(pair[0]), pair[1])