def test_dag_course(self, mock_logging): """ Test a course whose structure is not a tree. """ store = XMLModuleStore( DATA_DIR, source_dirs=['xml_dag'], xblock_mixins=(XModuleMixin,), ) course_key = store.get_courses()[0].id mock_logging.warning.assert_called_with( "%s has more than one definition", course_key.make_usage_key('discussion', 'duplicate_def') ) shared_item_loc = course_key.make_usage_key('html', 'toyhtml') shared_item = store.get_item(shared_item_loc) parent = shared_item.get_parent() self.assertIsNotNone(parent, "get_parent failed to return a value") parent_loc = course_key.make_usage_key('vertical', 'vertical_test') self.assertEqual(parent.location, parent_loc) self.assertIn(shared_item, parent.get_children()) # ensure it's still a child of the other parent even tho it doesn't claim the other parent as its parent other_parent_loc = course_key.make_usage_key('vertical', 'zeta') other_parent = store.get_item(other_parent_loc) # children rather than get_children b/c the instance returned by get_children != shared_item self.assertIn(shared_item_loc, other_parent.children)
def test_dag_course(self, mock_logging): """ Test a course whose structure is not a tree. """ store = XMLModuleStore( DATA_DIR, source_dirs=['xml_dag'], xblock_mixins=(XModuleMixin, ), ) course_key = store.get_courses()[0].id mock_logging.warning.assert_called_with( "%s has more than one definition", course_key.make_usage_key('discussion', 'duplicate_def')) shared_item_loc = course_key.make_usage_key('html', 'toyhtml') shared_item = store.get_item(shared_item_loc) parent = shared_item.get_parent() self.assertIsNotNone(parent, "get_parent failed to return a value") parent_loc = course_key.make_usage_key('vertical', 'vertical_test') self.assertEqual(parent.location, parent_loc) self.assertIn(shared_item.location, [x.location for x in parent.get_children()]) # ensure it's still a child of the other parent even tho it doesn't claim the other parent as its parent other_parent_loc = course_key.make_usage_key('vertical', 'zeta') other_parent = store.get_item(other_parent_loc) # children rather than get_children b/c the instance returned by get_children != shared_item self.assertIn(shared_item_loc, other_parent.children)
def test_poll_and_conditional_import(self): modulestore = XMLModuleStore(DATA_DIR, course_dirs=['conditional_and_poll']) course = modulestore.get_courses()[0] chapters = course.get_children() ch1 = chapters[0] sections = ch1.get_children() self.assertEqual(len(sections), 1) conditional_location = course.id.make_usage_key('conditional', 'condone') module = modulestore.get_item(conditional_location) self.assertEqual(len(module.children), 1) poll_location = course.id.make_usage_key('poll_question', 'first_poll') module = modulestore.get_item(poll_location) self.assertEqual(len(module.get_children()), 0) self.assertEqual(module.voted, False) self.assertEqual(module.poll_answer, '') self.assertEqual(module.poll_answers, {}) self.assertEqual( module.answers, [ {'text': u'Yes', 'id': 'Yes'}, {'text': u'No', 'id': 'No'}, {'text': u"Don't know", 'id': 'Dont_know'} ] )
def test_colon_in_url_name(self): """Ensure that colons in url_names convert to file paths properly""" print("Starting import") # Not using get_courses because we need the modulestore object too afterward modulestore = XMLModuleStore(DATA_DIR, source_dirs=['toy']) courses = modulestore.get_courses() self.assertEquals(len(courses), 1) course = courses[0] print("course errors:") for (msg, err) in modulestore.get_course_errors(course.id): print(msg) print(err) chapters = course.get_children() self.assertEquals(len(chapters), 5) ch2 = chapters[1] self.assertEquals(ch2.url_name, "secret:magic") print("Ch2 location: ", ch2.location) also_ch2 = modulestore.get_item(ch2.location) self.assertEquals(ch2, also_ch2) print("making sure html loaded") loc = course.id.make_usage_key('html', 'secret:toylab') html = modulestore.get_item(loc) self.assertEquals(html.display_name, "Toy lab")
def test_definition_loading(self): """When two courses share the same org and course name and both have a module with the same url_name, the definitions shouldn't clash. TODO (vshnayder): once we have a CMS, this shouldn't happen--locations should uniquely name definitions. But in our imperfect XML world, it can (and likely will) happen.""" modulestore = XMLModuleStore(DATA_DIR, source_dirs=['toy', 'two_toys']) location = BlockUsageLocator(CourseLocator("edX", "toy", "2012_Fall", deprecated=True), "video", "Welcome", deprecated=True) toy_video = modulestore.get_item(location) location_two = BlockUsageLocator(CourseLocator("edX", "toy", "TT_2012_Fall", deprecated=True), "video", "Welcome", deprecated=True) two_toy_video = modulestore.get_item(location_two) self.assertEqual(toy_video.youtube_id_1_0, "p2Q6BrNhdh8") self.assertEqual(two_toy_video.youtube_id_1_0, "p2Q6BrNhdh9")
def test_poll_and_conditional_import(self): modulestore = XMLModuleStore(DATA_DIR, source_dirs=['conditional_and_poll']) course = modulestore.get_courses()[0] chapters = course.get_children() ch1 = chapters[0] sections = ch1.get_children() self.assertEqual(len(sections), 1) conditional_location = course.id.make_usage_key( 'conditional', 'condone') module = modulestore.get_item(conditional_location) self.assertEqual(len(module.children), 1) poll_location = course.id.make_usage_key('poll_question', 'first_poll') module = modulestore.get_item(poll_location) self.assertEqual(len(module.get_children()), 0) self.assertEqual(module.voted, False) self.assertEqual(module.poll_answer, '') self.assertEqual(module.poll_answers, {}) self.assertEqual(module.answers, [{ 'text': u'Yes', 'id': 'Yes' }, { 'text': u'No', 'id': 'No' }, { 'text': u"Don't know", 'id': 'Dont_know' }])
def test_colon_in_url_name(self): """Ensure that colons in url_names convert to file paths properly""" print("Starting import") # Not using get_courses because we need the modulestore object too afterward modulestore = XMLModuleStore(DATA_DIR, course_dirs=['toy']) courses = modulestore.get_courses() self.assertEquals(len(courses), 1) course = courses[0] print("course errors:") for (msg, err) in modulestore.get_course_errors(course.id): print(msg) print(err) chapters = course.get_children() self.assertEquals(len(chapters), 5) ch2 = chapters[1] self.assertEquals(ch2.url_name, "secret:magic") print("Ch2 location: ", ch2.location) also_ch2 = modulestore.get_item(ch2.location) self.assertEquals(ch2, also_ch2) print("making sure html loaded") loc = course.id.make_usage_key('html', 'secret:toylab') html = modulestore.get_item(loc) self.assertEquals(html.display_name, "Toy lab")
def test_static_tabs_import(self): """Make sure that the static tabs are imported correctly""" modulestore = XMLModuleStore(DATA_DIR, source_dirs=['toy']) location_tab_syllabus = Location("edX", "toy", "2012_Fall", "static_tab", "syllabus", None) toy_tab_syllabus = modulestore.get_item(location_tab_syllabus) self.assertEqual(toy_tab_syllabus.display_name, 'Syllabus') self.assertEqual(toy_tab_syllabus.course_staff_only, False) location_tab_resources = Location("edX", "toy", "2012_Fall", "static_tab", "resources", None) toy_tab_resources = modulestore.get_item(location_tab_resources) self.assertEqual(toy_tab_resources.display_name, 'Resources') self.assertEqual(toy_tab_resources.course_staff_only, True)
def test_static_tabs_import(self): """Make sure that the static tabs are imported correctly""" modulestore = XMLModuleStore(DATA_DIR, source_dirs=['toy']) location_tab_syllabus = Location("edX", "toy", "2012_Fall", "static_tab", "syllabus", None) toy_tab_syllabus = modulestore.get_item(location_tab_syllabus) self.assertEqual(toy_tab_syllabus.display_name, 'Syllabus') self.assertEqual(toy_tab_syllabus.course_staff_only, False) location_tab_resources = Location("edX", "toy", "2012_Fall", "static_tab", "resources", None) toy_tab_resources = modulestore.get_item(location_tab_resources) self.assertEqual(toy_tab_resources.display_name, 'Resources') self.assertEqual(toy_tab_resources.course_staff_only, True)
def test_branch_setting(self): """ Test the branch setting context manager """ store = XMLModuleStore(DATA_DIR, source_dirs=['toy']) course = store.get_courses()[0] # XML store allows published_only branch setting with store.branch_setting(ModuleStoreEnum.Branch.published_only, course.id): store.get_item(course.location) # XML store does NOT allow draft_preferred branch setting with self.assertRaises(ValueError): with store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, course.id): # verify that the above context manager raises a ValueError pass # pragma: no cover
def test_static_tabs_import(self): """Make sure that the static tabs are imported correctly""" modulestore = XMLModuleStore(DATA_DIR, source_dirs=['toy']) location_tab_syllabus = BlockUsageLocator(CourseLocator("edX", "toy", "2012_Fall", deprecated=True), "static_tab", "syllabus", deprecated=True) toy_tab_syllabus = modulestore.get_item(location_tab_syllabus) assert toy_tab_syllabus.display_name == 'Syllabus' assert toy_tab_syllabus.course_staff_only is False location_tab_resources = BlockUsageLocator(CourseLocator("edX", "toy", "2012_Fall", deprecated=True), "static_tab", "resources", deprecated=True) toy_tab_resources = modulestore.get_item(location_tab_resources) assert toy_tab_resources.display_name == 'Resources' assert toy_tab_resources.course_staff_only is True
def test_definition_loading(self): """When two courses share the same org and course name and both have a module with the same url_name, the definitions shouldn't clash. TODO (vshnayder): once we have a CMS, this shouldn't happen--locations should uniquely name definitions. But in our imperfect XML world, it can (and likely will) happen.""" modulestore = XMLModuleStore(DATA_DIR, course_dirs=['toy', 'two_toys']) location = Location("edX", "toy", "2012_Fall", "video", "Welcome", None) toy_video = modulestore.get_item(location) location_two = Location("edX", "toy", "TT_2012_Fall", "video", "Welcome", None) two_toy_video = modulestore.get_item(location_two) self.assertEqual(toy_video.youtube_id_1_0, "p2Q6BrNhdh8") self.assertEqual(two_toy_video.youtube_id_1_0, "p2Q6BrNhdh9")
def test_tilde_files_ignored(self, _fake_glob): modulestore = XMLModuleStore(DATA_DIR, course_dirs=['tilde'], load_error_modules=False) about_location = SlashSeparatedCourseKey('edX', 'tilde', '2012_Fall').make_usage_key( 'about', 'index', ) about_module = modulestore.get_item(about_location) self.assertIn("GREEN", about_module.data) self.assertNotIn("RED", about_module.data)
def test_tilde_files_ignored(self, _fake_glob): modulestore = XMLModuleStore(DATA_DIR, course_dirs=['tilde'], load_error_modules=False) about_location = SlashSeparatedCourseKey('edX', 'tilde', '2012_Fall').make_usage_key( 'about', 'index', ) about_module = modulestore.get_item(about_location) self.assertIn("GREEN", about_module.data) self.assertNotIn("RED", about_module.data)
def test_tilde_files_ignored(self, _fake_glob): modulestore = XMLModuleStore(DATA_DIR, source_dirs=['course_ignore'], load_error_modules=False) about_location = CourseKey.from_string('edX/course_ignore/2014_Fall').make_usage_key( 'about', 'index', ) about_module = modulestore.get_item(about_location) self.assertIn("GREEN", about_module.data) self.assertNotIn("RED", about_module.data)
def test_poll_and_conditional_import(self): modulestore = XMLModuleStore(DATA_DIR, source_dirs=['conditional_and_poll']) course = modulestore.get_courses()[0] chapters = course.get_children() ch1 = chapters[0] sections = ch1.get_children() assert len(sections) == 1 conditional_location = course.id.make_usage_key('conditional', 'condone') module = modulestore.get_item(conditional_location) assert len(module.children) == 1 poll_location = course.id.make_usage_key('poll_question', 'first_poll') module = modulestore.get_item(poll_location) assert len(module.get_children()) == 0 assert module.voted is False assert module.poll_answer == '' assert module.poll_answers == {} assert module.answers ==\ [{'text': u'Yes', 'id': 'Yes'}, {'text': u'No', 'id': 'No'}, {'text': u"Don't know", 'id': 'Dont_know'}]
def test_word_cloud_import(self): modulestore = XMLModuleStore(DATA_DIR, source_dirs=['word_cloud']) course = modulestore.get_courses()[0] chapters = course.get_children() ch1 = chapters[0] sections = ch1.get_children() self.assertEqual(len(sections), 1) location = course.id.make_usage_key('word_cloud', 'cloud1') module = modulestore.get_item(location) self.assertEqual(len(module.get_children()), 0) self.assertEqual(module.num_inputs, 5) self.assertEqual(module.num_top_words, 250)
def test_graphicslidertool_import(self): ''' Check to see if definition_from_xml in gst_module.py works properly. Pulls data from the graphic_slider_tool directory in the test data directory. ''' modulestore = XMLModuleStore(DATA_DIR, course_dirs=['graphic_slider_tool']) sa_id = SlashSeparatedCourseKey("edX", "gst_test", "2012_Fall") location = sa_id.make_usage_key("graphical_slider_tool", "sample_gst") gst_sample = modulestore.get_item(location) render_string_from_sample_gst_xml = """ <slider var="a" style="width:400px;float:left;"/>\ <plot style="margin-top:15px;margin-bottom:15px;"/>""".strip() self.assertIn(render_string_from_sample_gst_xml, gst_sample.data)
def test_word_cloud_import(self): modulestore = XMLModuleStore(DATA_DIR, source_dirs=['word_cloud']) course = modulestore.get_courses()[0] chapters = course.get_children() ch1 = chapters[0] sections = ch1.get_children() assert len(sections) == 1 location = course.id.make_usage_key('word_cloud', 'cloud1') module = modulestore.get_item(location) assert len(module.get_children()) == 0 assert module.num_inputs == 5 assert module.num_top_words == 250
def test_word_cloud_import(self): modulestore = XMLModuleStore(DATA_DIR, course_dirs=['word_cloud']) course = modulestore.get_courses()[0] chapters = course.get_children() ch1 = chapters[0] sections = ch1.get_children() self.assertEqual(len(sections), 1) location = course.id.make_usage_key('word_cloud', 'cloud1') module = modulestore.get_item(location) self.assertEqual(len(module.get_children()), 0) self.assertEqual(module.num_inputs, 5) self.assertEqual(module.num_top_words, 250)
def test_graphicslidertool_import(self): ''' Check to see if definition_from_xml in gst_module.py works properly. Pulls data from the graphic_slider_tool directory in the test data directory. ''' modulestore = XMLModuleStore(DATA_DIR, course_dirs=['graphic_slider_tool']) sa_id = SlashSeparatedCourseKey("edX", "gst_test", "2012_Fall") location = sa_id.make_usage_key("graphical_slider_tool", "sample_gst") gst_sample = modulestore.get_item(location) render_string_from_sample_gst_xml = """ <slider var="a" style="width:400px;float:left;"/>\ <plot style="margin-top:15px;margin-bottom:15px;"/>""".strip() self.assertIn(render_string_from_sample_gst_xml, gst_sample.data)
class ConditionalBlockXmlTest(unittest.TestCase): """ Make sure ConditionalBlock works, by loading data in from an XML-defined course. """ def setUp(self): super().setUp() self.test_system = get_test_system() self.modulestore = XMLModuleStore(DATA_DIR, source_dirs=['conditional_and_poll']) courses = self.modulestore.get_courses() assert len(courses) == 1 self.course = courses[0] def get_module_for_location(self, location): descriptor = self.modulestore.get_item(location, depth=None) return self.test_system.get_module(descriptor) @patch('xmodule.x_module.descriptor_global_local_resource_url') @patch.dict(settings.FEATURES, {'ENABLE_EDXNOTES': False}) def test_conditional_module(self, _): """Make sure that conditional module works""" # edx - HarvardX # cond_test - ER22x location = BlockUsageLocator(CourseLocator("HarvardX", "ER22x", "2013_Spring", deprecated=True), "conditional", "condone", deprecated=True) module = self.get_module_for_location(location) html = module.render(STUDENT_VIEW).content mako_service = module.xmodule_runtime.service(module, 'mako') html_expect = mako_service.render_template( 'conditional_ajax.html', { # Test ajax url is just usage-id / handler_name 'ajax_url': f'{str(location)}/xmodule_handler', 'element_id': 'i4x-HarvardX-ER22x-conditional-condone', 'depends': 'i4x-HarvardX-ER22x-problem-choiceprob' }) assert html == html_expect ajax = json.loads(module.handle_ajax('', '')) fragments = ajax['fragments'] assert not any( ('This is a secret' in item['content']) for item in fragments) # Now change state of the capa problem to make it completed inner_module = self.get_module_for_location( 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('', '')) fragments = ajax['fragments'] assert any( ('This is a secret' in item['content']) for item in fragments) def test_conditional_module_with_empty_sources_list(self): """ If a ConditionalBlock is initialized with an empty sources_list, we assert that the sources_list is set via generating UsageKeys from the values in xml_attributes['sources'] """ dummy_system = Mock() dummy_location = BlockUsageLocator( CourseLocator("edX", "conditional_test", "test_run"), "conditional", "SampleConditional") dummy_scope_ids = ScopeIds(None, None, dummy_location, dummy_location) dummy_field_data = DictFieldData({ 'data': '<conditional/>', 'xml_attributes': { 'sources': 'i4x://HarvardX/ER22x/poll_question/T15_poll' }, 'children': None, }) conditional = ConditionalBlock( dummy_system, dummy_field_data, dummy_scope_ids, ) new_run = conditional.location.course_key.run # lint-amnesty, pylint: disable=unused-variable assert conditional.sources_list[0] == BlockUsageLocator.from_string(conditional.xml_attributes['sources'])\ .replace(run=dummy_location.course_key.run) def test_conditional_module_parse_sources(self): dummy_system = Mock() dummy_location = BlockUsageLocator( CourseLocator("edX", "conditional_test", "test_run"), "conditional", "SampleConditional") dummy_scope_ids = ScopeIds(None, None, dummy_location, dummy_location) dummy_field_data = DictFieldData({ 'data': '<conditional/>', 'xml_attributes': { 'sources': 'i4x://HarvardX/ER22x/poll_question/T15_poll;i4x://HarvardX/ER22x/poll_question/T16_poll' }, # lint-amnesty, pylint: disable=line-too-long 'children': None, }) conditional = ConditionalBlock( dummy_system, dummy_field_data, dummy_scope_ids, ) assert conditional.parse_sources(conditional.xml_attributes) == [ 'i4x://HarvardX/ER22x/poll_question/T15_poll', 'i4x://HarvardX/ER22x/poll_question/T16_poll' ] def test_conditional_module_parse_attr_values(self): root = '<conditional attempted="false"></conditional>' xml_object = etree.XML(root) definition = ConditionalBlock.definition_from_xml(xml_object, Mock())[0] expected_definition = { 'show_tag_list': [], 'conditional_attr': 'attempted', 'conditional_value': 'false', 'conditional_message': '' } assert definition == expected_definition def test_presence_attributes_in_xml_attributes(self): modules = ConditionalFactory.create(self.test_system) modules['cond_module'].save() modules['cond_module'].definition_to_xml(Mock()) expected_xml_attributes = { 'attempted': 'true', 'message': 'You must complete {link} before you can access this unit.', 'sources': '' } self.assertDictEqual(modules['cond_module'].xml_attributes, expected_xml_attributes)