Exemple #1
0
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError("course_id not specified")

        # Get the modulestore

        store = modulestore()

        # Get the course data

        try:
            course_key = CourseKey.from_string(args[0])
        except InvalidKeyError:
            raise CommandError("Invalid course_id")

        course = store.get_course(course_key)
        if course is None:
            raise CommandError("Invalid course_id")

        # Precompute inherited metadata at the course level, if needed:

        if options['inherited']:
            compute_inherited_metadata(course)

        # Convert course data to dictionary and dump it as JSON to stdout

        info = dump_module(course,
                           inherited=options['inherited'],
                           defaults=options['inherited_defaults'])

        return json.dumps(info, indent=2, sort_keys=True, default=unicode)
Exemple #2
0
    def test_metadata_override_default(self):
        """
        Checks that due date can be overriden at child level.
        """
        system = self.get_system()
        course_due = 'March 20 17:00'
        child_due = 'April 10 00:00'
        url_name = 'test1'
        start_xml = '''
        <course org="{org}" course="{course}"
                due="{due}" url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>'''.format(due=course_due, org=ORG, course=COURSE, url_name=url_name)
        descriptor = system.process_xml(start_xml)
        child = descriptor.get_children()[0]
        child._model_data['due'] = child_due
        compute_inherited_metadata(descriptor)

        self.assertEqual(descriptor.lms.due, Date().from_json(course_due))
        self.assertEqual(child.lms.due, Date().from_json(child_due))
        # Test inherited metadata. Due does not appear here (because explicitly set on child).
        self.assertEqual(1, len(child._inherited_metadata))
        self.assertEqual('1970-01-01T00:00:00Z', child._inherited_metadata['start'])
        # Test inheritable metadata. This has the course inheritable value for due.
        self.assertEqual(2, len(child._inheritable_metadata))
        self.assertEqual(course_due, child._inheritable_metadata['due'])
Exemple #3
0
    def test_metadata_no_inheritance(self):
        """
        Checks that default value of None (for due) does not get marked as inherited.
        """
        system = self.get_system()
        url_name = 'test1'
        start_xml = '''
        <course org="{org}" course="{course}"
                url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>'''.format(org=ORG, course=COURSE, url_name=url_name)
        descriptor = system.process_xml(start_xml)
        compute_inherited_metadata(descriptor)

        self.assertEqual(descriptor.lms.due, None)

        # Check that the child does not inherit a value for due
        child = descriptor.get_children()[0]
        self.assertEqual(child.lms.due, None)
        # pylint: disable=W0212
        self.assertEqual(child._inheritable_metadata,
                         child._inherited_metadata)
        self.assertEqual(1, len(child._inherited_metadata))
        # why do these tests look in the internal structure v just calling child.start?
        self.assertLessEqual(
            ImportTestCase.date.from_json(child._inherited_metadata['start']),
            datetime.datetime.now(UTC()))
    def test_metadata_override_default(self):
        """
        Checks that due date can be overriden at child level.
        """
        system = self.get_system()
        course_due = "March 20 17:00"
        child_due = "April 10 00:00"
        url_name = "test1"
        start_xml = """
        <course org="{org}" course="{course}"
                due="{due}" url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>""".format(
            due=course_due, org=ORG, course=COURSE, url_name=url_name
        )
        descriptor = system.process_xml(start_xml)
        child = descriptor.get_children()[0]
        # pylint: disable=W0212
        child._field_data.set(child, "due", child_due)
        compute_inherited_metadata(descriptor)

        self.assertEqual(descriptor.due, ImportTestCase.date.from_json(course_due))
        self.assertEqual(child.due, ImportTestCase.date.from_json(child_due))
        # Test inherited metadata. Due does not appear here (because explicitly set on child).
        self.assertEqual(
            ImportTestCase.date.to_json(ImportTestCase.date.from_json(course_due)),
            child.xblock_kvs.inherited_settings["due"],
        )
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError("course_id not specified")

        # Get the modulestore

        try:
            name = options['modulestore']
            store = modulestore(name)
        except KeyError:
            raise CommandError("Unknown modulestore {}".format(name))

        # Get the course data

        course_id = args[0]
        course = store.get_course(course_id)
        if course is None:
            raise CommandError("Invalid course_id")

        # precompute inherited metadata at the course level, if needed:
        if options['inherited']:
            compute_inherited_metadata(course)

        # Convert course data to dictionary and dump it as JSON to stdout

        info = dump_module(course, inherited=options['inherited'], defaults=options['inherited_defaults'])

        return json.dumps(info, indent=2, sort_keys=True)
    def test_metadata_override_default(self):
        """
        Checks that due date can be overriden at child level.
        """
        system = self.get_system()
        course_due = 'March 20 17:00'
        child_due = 'April 10 00:00'
        url_name = 'test1'
        start_xml = '''
        <course org="{org}" course="{course}"
                due="{due}" url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>'''.format(due=course_due,
                            org=ORG,
                            course=COURSE,
                            url_name=url_name)
        descriptor = system.process_xml(start_xml)
        child = descriptor.get_children()[0]
        # pylint: disable=W0212
        child._field_data.set(child, 'due', child_due)
        compute_inherited_metadata(descriptor)

        self.assertEqual(descriptor.due,
                         ImportTestCase.date.from_json(course_due))
        self.assertEqual(child.due, ImportTestCase.date.from_json(child_due))
        # Test inherited metadata. Due does not appear here (because explicitly set on child).
        self.assertEqual(
            ImportTestCase.date.to_json(
                ImportTestCase.date.from_json(course_due)),
            child.xblock_kvs.inherited_settings['due'])
Exemple #7
0
    def test_metadata_no_inheritance(self):
        """
        Checks that default value of None (for due) does not get marked as inherited.
        """
        system = self.get_system()
        url_name = 'test1'
        start_xml = '''
        <course org="{org}" course="{course}"
                url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>'''.format(org=ORG, course=COURSE, url_name=url_name)
        descriptor = system.process_xml(start_xml)
        compute_inherited_metadata(descriptor)

        self.assertEqual(descriptor.lms.due, None)

        # Check that the child does not inherit a value for due
        child = descriptor.get_children()[0]
        self.assertEqual(child.lms.due, None)
        self.assertEqual(child._inheritable_metadata,
                         child._inherited_metadata)
        self.assertEqual(1, len(child._inherited_metadata))
        self.assertEqual('1970-01-01T00:00:00Z',
                         child._inherited_metadata['start'])
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError("course_id not specified")

        # Get the modulestore

        try:
            name = options['modulestore']
            store = modulestore(name)
        except KeyError:
            raise CommandError("Unknown modulestore {}".format(name))

        # Get the course data

        try:
            course_id = SlashSeparatedCourseKey.from_deprecated_string(args[0])
        except InvalidKeyError:
            raise CommandError("Invalid course_id")

        course = store.get_course(course_id)
        if course is None:
            raise CommandError("Invalid course_id")

        # precompute inherited metadata at the course level, if needed:
        if options['inherited']:
            compute_inherited_metadata(course)

        # Convert course data to dictionary and dump it as JSON to stdout

        info = dump_module(course,
                           inherited=options['inherited'],
                           defaults=options['inherited_defaults'])

        return json.dumps(info, indent=2, sort_keys=True)
Exemple #9
0
    def test_library_metadata_import_export(self):
        """Two checks:
            - unknown metadata is preserved across import-export
            - inherited metadata doesn't leak to children.
        """
        system = self.get_system(library=True)
        from_date_string = 'March 26 17:00'
        url_name = 'test2'
        unicorn_color = 'rainbow'
        start_xml = '''
        <library org="TestOrg" library="TestLib" display_name="stuff">
            <course org="{org}" course="{course}"
                due="{due}" url_name="{url_name}" unicorn="{unicorn_color}">
                <chapter url="hi" url_name="ch" display_name="CH">
                    <html url_name="h" display_name="H">Two houses, ...</html>
                </chapter>
            </course>
        </library>'''.format(due=from_date_string,
                             org=ORG,
                             course=COURSE,
                             url_name=url_name,
                             unicorn_color=unicorn_color)
        descriptor = system.process_xml(start_xml)

        # pylint: disable=protected-access
        original_unwrapped = descriptor._unwrapped_field_data
        LibraryXMLModuleStore.patch_descriptor_kvs(descriptor)
        # '_unwrapped_field_data' is reset in `patch_descriptor_kvs`
        # pylint: disable=protected-access
        self.assertIsNot(original_unwrapped, descriptor._unwrapped_field_data)
        compute_inherited_metadata(descriptor)
        # Check the course module, since it has inheritance
        descriptor = descriptor.get_children()[0]
        self.course_descriptor_inheritance_check(descriptor, from_date_string,
                                                 unicorn_color)
Exemple #10
0
    def handle(self, *args, **options):

        # Get the modulestore

        store = modulestore()

        # Get the course data

        try:
            course_key = CourseKey.from_string(options['course_id'])
        except InvalidKeyError:
            raise CommandError("Invalid course_id")  # lint-amnesty, pylint: disable=raise-missing-from

        course = store.get_course(course_key)
        if course is None:
            raise CommandError("Invalid course_id")

        # Precompute inherited metadata at the course level, if needed:

        if options['inherited']:
            compute_inherited_metadata(course)

        # Convert course data to dictionary and dump it as JSON to stdout

        info = dump_module(course, inherited=options['inherited'], defaults=options['inherited_defaults'])

        return json.dumps(info, indent=2, sort_keys=True, default=six.text_type)
Exemple #11
0
    def test_metadata_override_default(self):
        """
        Checks that due date can be overriden at child level.
        """
        system = self.get_system()
        course_due = 'March 20 17:00'
        child_due = 'April 10 00:00'
        url_name = 'test1'
        start_xml = '''
        <course org="{org}" course="{course}"
                due="{due}" url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>'''.format(due=course_due,
                            org=ORG,
                            course=COURSE,
                            url_name=url_name)
        descriptor = system.process_xml(start_xml)
        child = descriptor.get_children()[0]
        child._model_data['due'] = child_due
        compute_inherited_metadata(descriptor)

        self.assertEqual(descriptor.lms.due, Date().from_json(course_due))
        self.assertEqual(child.lms.due, Date().from_json(child_due))
        # Test inherited metadata. Due does not appear here (because explicitly
        # set on child).
        self.assertEqual(1, len(child._inherited_metadata))
        self.assertEqual('1970-01-01T00:00:00Z',
                         child._inherited_metadata['start'])
        # Test inheritable metadata. This has the course inheritable value for
        # due.
        self.assertEqual(2, len(child._inheritable_metadata))
        self.assertEqual(course_due, child._inheritable_metadata['due'])
    def test_metadata_no_inheritance(self):
        """
        Checks that default value of None (for due) does not get marked as inherited.
        """
        system = self.get_system()
        url_name = "test1"
        start_xml = """
        <course org="{org}" course="{course}"
                url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>""".format(
            org=ORG, course=COURSE, url_name=url_name
        )
        descriptor = system.process_xml(start_xml)
        compute_inherited_metadata(descriptor)

        self.assertEqual(descriptor.due, None)

        # Check that the child does not inherit a value for due
        child = descriptor.get_children()[0]
        self.assertEqual(child.due, None)

        # Check that the child hasn't started yet
        self.assertLessEqual(datetime.datetime.now(UTC()), child.start)
    def test_metadata_no_inheritance(self):
        """
        Checks that default value of None (for due) does not get marked as inherited.
        """
        system = self.get_system()
        url_name = 'test1'
        start_xml = '''
        <course org="{org}" course="{course}"
                url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>'''.format(org=ORG, course=COURSE, url_name=url_name)
        descriptor = system.process_xml(start_xml)
        compute_inherited_metadata(descriptor)

        self.assertEqual(descriptor.lms.due, None)

        # Check that the child does not inherit a value for due
        child = descriptor.get_children()[0]
        self.assertEqual(child.lms.due, None)
        # pylint: disable=W0212
        self.assertEqual(child._inheritable_metadata, child._inherited_metadata)
        self.assertEqual(1, len(child._inherited_metadata))
        # why do these tests look in the internal structure v just calling child.start?
        self.assertLessEqual(
            ImportTestCase.date.from_json(child._inherited_metadata['start']),
            datetime.datetime.now(UTC()))
Exemple #14
0
 def test_library_metadata_override_default(self):
     """
     Checks that due date can be overriden at child level when a library is the root.
     """
     system = self.get_system()
     course_due = 'March 20 17:00'
     child_due = 'April 10 00:00'
     url_name = 'test1'
     start_xml = '''
     <library org="TestOrg" library="TestLib" display_name="stuff">
         <course org="{org}" course="{course}"
                 due="{due}" url_name="{url_name}" unicorn="purple">
             <chapter url="hi" url_name="ch" display_name="CH">
                 <html url_name="h" display_name="H">Two houses, ...</html>
             </chapter>
         </course>
     </library>'''.format(due=course_due,
                          org=ORG,
                          course=COURSE,
                          url_name=url_name)
     descriptor = system.process_xml(start_xml)
     LibraryXMLModuleStore.patch_descriptor_kvs(descriptor)
     # Chapter is two levels down here.
     child = descriptor.get_children()[0].get_children()[0]
     # pylint: disable=protected-access
     child._field_data.set(child, 'due', child_due)
     compute_inherited_metadata(descriptor)
     descriptor = descriptor.get_children()[0]
     self.override_metadata_check(descriptor, child, course_due, child_due)
Exemple #15
0
    def test_library_metadata_import_export(self):
        """Two checks:
            - unknown metadata is preserved across import-export
            - inherited metadata doesn't leak to children.
        """
        system = self.get_system(library=True)
        from_date_string = 'March 26 17:00'
        url_name = 'test2'
        unicorn_color = 'rainbow'
        start_xml = '''
        <library org="TestOrg" library="TestLib" display_name="stuff">
            <course org="{org}" course="{course}"
                due="{due}" url_name="{url_name}" unicorn="{unicorn_color}">
                <chapter url="hi" url_name="ch" display_name="CH">
                    <html url_name="h" display_name="H">Two houses, ...</html>
                </chapter>
            </course>
        </library>'''.format(
            due=from_date_string, org=ORG, course=COURSE, url_name=url_name, unicorn_color=unicorn_color
        )
        descriptor = system.process_xml(start_xml)

        # pylint: disable=protected-access
        original_unwrapped = descriptor._unwrapped_field_data
        LibraryXMLModuleStore.patch_descriptor_kvs(descriptor)
        # '_unwrapped_field_data' is reset in `patch_descriptor_kvs`
        # pylint: disable=protected-access
        self.assertIsNot(original_unwrapped, descriptor._unwrapped_field_data)
        compute_inherited_metadata(descriptor)
        # Check the course module, since it has inheritance
        descriptor = descriptor.get_children()[0]
        self.course_descriptor_inheritance_check(descriptor, from_date_string, unicorn_color, url_name)
    def test_metadata_no_inheritance(self):
        """
        Checks that default value of None (for due) does not get marked as inherited.
        """
        system = self.get_system()
        url_name = 'test1'
        start_xml = '''
        <course org="{org}" course="{course}"
                url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>'''.format(org=ORG, course=COURSE, url_name=url_name)
        descriptor = system.process_xml(start_xml)
        compute_inherited_metadata(descriptor)

        self.assertEqual(descriptor.lms.due, None)

        # Check that the child does not inherit a value for due
        child = descriptor.get_children()[0]
        self.assertEqual(child.lms.due, None)
        self.assertEqual(
            child._inheritable_metadata, child._inherited_metadata)
        self.assertEqual(1, len(child._inherited_metadata))
        self.assertEqual(
            '1970-01-01T00:00:00Z', child._inherited_metadata['start'])
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError("course_id not specified")

        # Get the modulestore

        store = modulestore()

        # Get the course data

        try:
            course_key = CourseKey.from_string(args[0])
        except InvalidKeyError:
            raise CommandError("Invalid course_id")

        course = store.get_course(course_key)
        if course is None:
            raise CommandError("Invalid course_id")

        # Precompute inherited metadata at the course level, if needed:

        if options['inherited']:
            compute_inherited_metadata(course)

        # Convert course data to dictionary and dump it as JSON to stdout

        info = dump_module(course, inherited=options['inherited'], defaults=options['inherited_defaults'])

        return json.dumps(info, indent=2, sort_keys=True, default=unicode)
Exemple #18
0
 def test_library_metadata_override_default(self):
     """
     Checks that due date can be overriden at child level when a library is the root.
     """
     system = self.get_system()
     course_due = 'March 20 17:00'
     child_due = 'April 10 00:00'
     url_name = 'test1'
     start_xml = '''
     <library org="TestOrg" library="TestLib" display_name="stuff">
         <course org="{org}" course="{course}"
                 due="{due}" url_name="{url_name}" unicorn="purple">
             <chapter url="hi" url_name="ch" display_name="CH">
                 <html url_name="h" display_name="H">Two houses, ...</html>
             </chapter>
         </course>
     </library>'''.format(due=course_due, org=ORG, course=COURSE, url_name=url_name)
     descriptor = system.process_xml(start_xml)
     LibraryXMLModuleStore.patch_descriptor_kvs(descriptor)
     # Chapter is two levels down here.
     child = descriptor.get_children()[0].get_children()[0]
     # pylint: disable=protected-access
     child._field_data.set(child, 'due', child_due)
     compute_inherited_metadata(descriptor)
     descriptor = descriptor.get_children()[0]
     self.override_metadata_check(descriptor, child, course_due, child_due)
Exemple #19
0
    def test_metadata_import_export(self):
        """Two checks:
            - unknown metadata is preserved across import-export
            - inherited metadata doesn't leak to children.
        """
        system = self.get_system()
        v = 'March 20 17:00'
        url_name = 'test1'
        start_xml = '''
        <course org="{org}" course="{course}"
                due="{due}" url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>'''.format(due=v, org=ORG, course=COURSE, url_name=url_name)
        descriptor = system.process_xml(start_xml)
        compute_inherited_metadata(descriptor)

        print(descriptor, descriptor._model_data)
        self.assertEqual(descriptor.lms.due, Date().from_json(v))

        # Check that the child inherits due correctly
        child = descriptor.get_children()[0]
        self.assertEqual(child.lms.due, Date().from_json(v))
        self.assertEqual(child._inheritable_metadata, child._inherited_metadata)
        self.assertEqual(2, len(child._inherited_metadata))
        self.assertEqual('1970-01-01T00:00:00Z', child._inherited_metadata['start'])
        self.assertEqual(v, child._inherited_metadata['due'])

        # Now export and check things
        resource_fs = MemoryFS()
        exported_xml = descriptor.export_to_xml(resource_fs)

        # Check that the exported xml is just a pointer
        print("Exported xml:", exported_xml)
        pointer = etree.fromstring(exported_xml)
        self.assertTrue(is_pointer_tag(pointer))
        # but it's a special case course pointer
        self.assertEqual(pointer.attrib['course'], COURSE)
        self.assertEqual(pointer.attrib['org'], ORG)

        # Does the course still have unicorns?
        with resource_fs.open('course/{url_name}.xml'.format(url_name=url_name)) as f:
            course_xml = etree.fromstring(f.read())

        self.assertEqual(course_xml.attrib['unicorn'], 'purple')

        # the course and org tags should be _only_ in the pointer
        self.assertTrue('course' not in course_xml.attrib)
        self.assertTrue('org' not in course_xml.attrib)

        # did we successfully strip the url_name from the definition contents?
        self.assertTrue('url_name' not in course_xml.attrib)

        # Does the chapter tag now have a due attribute?
        # hardcoded path to child
        with resource_fs.open('chapter/ch.xml') as f:
            chapter_xml = etree.fromstring(f.read())
        self.assertEqual(chapter_xml.tag, 'chapter')
        self.assertFalse('due' in chapter_xml.attrib)
Exemple #20
0
 def test_metadata_no_inheritance(self):
     """
     Checks that default value of None (for due) does not get marked as inherited when a
     course is the root block.
     """
     system = self.get_system()
     url_name = 'test1'
     start_xml = '''
     <course org="{org}" course="{course}"
             url_name="{url_name}" unicorn="purple">
         <chapter url="hi" url_name="ch" display_name="CH">
             <html url_name="h" display_name="H">Two houses, ...</html>
         </chapter>
     </course>'''.format(org=ORG, course=COURSE, url_name=url_name)
     descriptor = system.process_xml(start_xml)
     compute_inherited_metadata(descriptor)
     self.course_descriptor_no_inheritance_check(descriptor)
Exemple #21
0
 def test_metadata_no_inheritance(self):
     """
     Checks that default value of None (for due) does not get marked as inherited when a
     course is the root block.
     """
     system = self.get_system()
     url_name = 'test1'
     start_xml = '''
     <course org="{org}" course="{course}"
             url_name="{url_name}" unicorn="purple">
         <chapter url="hi" url_name="ch" display_name="CH">
             <html url_name="h" display_name="H">Two houses, ...</html>
         </chapter>
     </course>'''.format(org=ORG, course=COURSE, url_name=url_name)
     descriptor = system.process_xml(start_xml)
     compute_inherited_metadata(descriptor)
     self.course_descriptor_no_inheritance_check(descriptor)
Exemple #22
0
 def test_metadata_import_export(self):
     """Two checks:
         - unknown metadata is preserved across import-export
         - inherited metadata doesn't leak to children.
     """
     system = self.get_system()
     from_date_string = 'March 20 17:00'
     url_name = 'test1'
     unicorn_color = 'purple'
     start_xml = '''
     <course org="{org}" course="{course}"
             due="{due}" url_name="{url_name}" unicorn="{unicorn_color}">
         <chapter url="hi" url_name="ch" display_name="CH">
             <html url_name="h" display_name="H">Two houses, ...</html>
         </chapter>
     </course>'''.format(
         due=from_date_string, org=ORG, course=COURSE, url_name=url_name, unicorn_color=unicorn_color
     )
     descriptor = system.process_xml(start_xml)
     compute_inherited_metadata(descriptor)
     self.course_descriptor_inheritance_check(descriptor, from_date_string, unicorn_color, url_name)
Exemple #23
0
 def test_metadata_import_export(self):
     """Two checks:
         - unknown metadata is preserved across import-export
         - inherited metadata doesn't leak to children.
     """
     system = self.get_system()
     from_date_string = 'March 20 17:00'
     url_name = 'test1'
     unicorn_color = 'purple'
     start_xml = '''
     <course org="{org}" course="{course}"
             due="{due}" url_name="{url_name}" unicorn="{unicorn_color}">
         <chapter url="hi" url_name="ch" display_name="CH">
             <html url_name="h" display_name="H">Two houses, ...</html>
         </chapter>
     </course>'''.format(
         due=from_date_string, org=ORG, course=COURSE, url_name=url_name, unicorn_color=unicorn_color
     )
     descriptor = system.process_xml(start_xml)
     compute_inherited_metadata(descriptor)
     self.course_descriptor_inheritance_check(descriptor, from_date_string, unicorn_color, url_name)
Exemple #24
0
 def test_library_metadata_no_inheritance(self):
     """
     Checks that the default value of None (for due) does not get marked as inherited when a
     library is the root block.
     """
     system = self.get_system()
     url_name = 'test1'
     start_xml = '''
     <library org="TestOrg" library="TestLib" display_name="stuff">
         <course org="{org}" course="{course}"
                 url_name="{url_name}" unicorn="purple">
             <chapter url="hi" url_name="ch" display_name="CH">
                 <html url_name="h" display_name="H">Two houses, ...</html>
             </chapter>
         </course>
     </library>'''.format(org=ORG, course=COURSE, url_name=url_name)
     descriptor = system.process_xml(start_xml)
     LibraryXMLModuleStore.patch_descriptor_kvs(descriptor)
     compute_inherited_metadata(descriptor)
     # Run the checks on the course node instead.
     descriptor = descriptor.get_children()[0]
     self.course_descriptor_no_inheritance_check(descriptor)
Exemple #25
0
 def test_library_metadata_no_inheritance(self):
     """
     Checks that the default value of None (for due) does not get marked as inherited when a
     library is the root block.
     """
     system = self.get_system()
     url_name = 'test1'
     start_xml = '''
     <library org="TestOrg" library="TestLib" display_name="stuff">
         <course org="{org}" course="{course}"
                 url_name="{url_name}" unicorn="purple">
             <chapter url="hi" url_name="ch" display_name="CH">
                 <html url_name="h" display_name="H">Two houses, ...</html>
             </chapter>
         </course>
     </library>'''.format(org=ORG, course=COURSE, url_name=url_name)
     descriptor = system.process_xml(start_xml)
     LibraryXMLModuleStore.patch_descriptor_kvs(descriptor)
     compute_inherited_metadata(descriptor)
     # Run the checks on the course node instead.
     descriptor = descriptor.get_children()[0]
     self.course_descriptor_no_inheritance_check(descriptor)
Exemple #26
0
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError("course_id not specified")

        # Get the modulestore

        store = modulestore()

        # Get the course data

        try:
            course_key = CourseKey.from_string(args[0])
        except InvalidKeyError:
            raise CommandError("Invalid course_id")

        course = store.get_course(course_key)
        if course is None:
            raise CommandError("Invalid course_id")

        # Precompute inherited metadata at the course level, if needed:

        if options['inherited']:
            compute_inherited_metadata(course)

        # Convert course data to dictionary and dump it as JSON to stdout
        if options['flat']:
            info = dump_module_by_position(course_id, course)
        else:
            info = dump_module(course, inherited=options['inherited'], defaults=options['inherited_defaults'])

        if options['csv']:
            csvout = StringIO.StringIO()
            writer = csv.writer(csvout, dialect='excel')
            writer.writerows(info)
            return csvout.getvalue()

        return json.dumps(info, indent=2, sort_keys=True, default=unicode)
Exemple #27
0
    def test_metadata_import_export(self):
        """Two checks:
            - unknown metadata is preserved across import-export
            - inherited metadata doesn't leak to children.
        """
        system = self.get_system()
        v = 'March 20 17:00'
        url_name = 'test1'
        start_xml = '''
        <course org="{org}" course="{course}"
                due="{due}" url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>'''.format(due=v, org=ORG, course=COURSE, url_name=url_name)
        descriptor = system.process_xml(start_xml)
        compute_inherited_metadata(descriptor)

        print(descriptor, descriptor._model_data)
        self.assertEqual(descriptor.lms.due, Date().from_json(v))

        # Check that the child inherits due correctly
        child = descriptor.get_children()[0]
        self.assertEqual(child.lms.due, Date().from_json(v))
        self.assertEqual(child._inheritable_metadata,
                         child._inherited_metadata)
        self.assertEqual(2, len(child._inherited_metadata))
        self.assertEqual('1970-01-01T00:00:00Z',
                         child._inherited_metadata['start'])
        self.assertEqual(v, child._inherited_metadata['due'])

        # Now export and check things
        resource_fs = MemoryFS()
        exported_xml = descriptor.export_to_xml(resource_fs)

        # Check that the exported xml is just a pointer
        print("Exported xml:", exported_xml)
        pointer = etree.fromstring(exported_xml)
        self.assertTrue(is_pointer_tag(pointer))
        # but it's a special case course pointer
        self.assertEqual(pointer.attrib['course'], COURSE)
        self.assertEqual(pointer.attrib['org'], ORG)

        # Does the course still have unicorns?
        with resource_fs.open(
                'course/{url_name}.xml'.format(url_name=url_name)) as f:
            course_xml = etree.fromstring(f.read())

        self.assertEqual(course_xml.attrib['unicorn'], 'purple')

        # the course and org tags should be _only_ in the pointer
        self.assertTrue('course' not in course_xml.attrib)
        self.assertTrue('org' not in course_xml.attrib)

        # did we successfully strip the url_name from the definition contents?
        self.assertTrue('url_name' not in course_xml.attrib)

        # Does the chapter tag now have a due attribute?
        # hardcoded path to child
        with resource_fs.open('chapter/ch.xml') as f:
            chapter_xml = etree.fromstring(f.read())
        self.assertEqual(chapter_xml.tag, 'chapter')
        self.assertFalse('due' in chapter_xml.attrib)
    def test_metadata_import_export(self):
        """Two checks:
            - unknown metadata is preserved across import-export
            - inherited metadata doesn't leak to children.
        """
        system = self.get_system()
        v = 'March 20 17:00'
        url_name = 'test1'
        start_xml = '''
        <course org="{org}" course="{course}"
                due="{due}" url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>'''.format(due=v, org=ORG, course=COURSE, url_name=url_name)
        descriptor = system.process_xml(start_xml)
        compute_inherited_metadata(descriptor)

        # pylint: disable=W0212
        print(descriptor, descriptor._field_data)
        self.assertEqual(descriptor.due, ImportTestCase.date.from_json(v))

        # Check that the child inherits due correctly
        child = descriptor.get_children()[0]
        self.assertEqual(child.due, ImportTestCase.date.from_json(v))
        # need to convert v to canonical json b4 comparing
        self.assertEqual(
            ImportTestCase.date.to_json(ImportTestCase.date.from_json(v)),
            child.xblock_kvs.inherited_settings['due'])

        # Now export and check things
        descriptor.runtime.export_fs = MemoryFS()
        node = etree.Element('unknown')
        descriptor.add_xml_to_node(node)

        # Check that the exported xml is just a pointer
        print("Exported xml:", etree.tostring(node))
        self.assertTrue(is_pointer_tag(node))
        # but it's a special case course pointer
        self.assertEqual(node.attrib['course'], COURSE)
        self.assertEqual(node.attrib['org'], ORG)

        # Does the course still have unicorns?
        with descriptor.runtime.export_fs.open(
                'course/{url_name}.xml'.format(url_name=url_name)) as f:
            course_xml = etree.fromstring(f.read())

        self.assertEqual(course_xml.attrib['unicorn'], 'purple')

        # the course and org tags should be _only_ in the pointer
        self.assertTrue('course' not in course_xml.attrib)
        self.assertTrue('org' not in course_xml.attrib)

        # did we successfully strip the url_name from the definition contents?
        self.assertTrue('url_name' not in course_xml.attrib)

        # Does the chapter tag now have a due attribute?
        # hardcoded path to child
        with descriptor.runtime.export_fs.open('chapter/ch.xml') as f:
            chapter_xml = etree.fromstring(f.read())
        self.assertEqual(chapter_xml.tag, 'chapter')
        self.assertFalse('due' in chapter_xml.attrib)
    def test_metadata_import_export(self):
        """Two checks:
            - unknown metadata is preserved across import-export
            - inherited metadata doesn't leak to children.
        """
        system = self.get_system()
        v = 'March 20 17:00'
        url_name = 'test1'
        start_xml = '''
        <course org="{org}" course="{course}"
                due="{due}" url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>'''.format(due=v, org=ORG, course=COURSE, url_name=url_name)
        descriptor = system.process_xml(start_xml)
        compute_inherited_metadata(descriptor)

        # pylint: disable=protected-access
        print(descriptor, descriptor._field_data)
        self.assertEqual(descriptor.due, ImportTestCase.date.from_json(v))

        # Check that the child inherits due correctly
        child = descriptor.get_children()[0]
        self.assertEqual(child.due, ImportTestCase.date.from_json(v))
        # need to convert v to canonical json b4 comparing
        self.assertEqual(
            ImportTestCase.date.to_json(ImportTestCase.date.from_json(v)),
            child.xblock_kvs.inherited_settings['due']
        )

        # Now export and check things
        descriptor.runtime.export_fs = MemoryFS()
        node = etree.Element('unknown')
        descriptor.add_xml_to_node(node)

        # Check that the exported xml is just a pointer
        print("Exported xml:", etree.tostring(node))
        self.assertTrue(is_pointer_tag(node))
        # but it's a special case course pointer
        self.assertEqual(node.attrib['course'], COURSE)
        self.assertEqual(node.attrib['org'], ORG)

        # Does the course still have unicorns?
        with descriptor.runtime.export_fs.open('course/{url_name}.xml'.format(url_name=url_name)) as f:
            course_xml = etree.fromstring(f.read())

        self.assertEqual(course_xml.attrib['unicorn'], 'purple')

        # the course and org tags should be _only_ in the pointer
        self.assertTrue('course' not in course_xml.attrib)
        self.assertTrue('org' not in course_xml.attrib)

        # did we successfully strip the url_name from the definition contents?
        self.assertTrue('url_name' not in course_xml.attrib)

        # Does the chapter tag now have a due attribute?
        # hardcoded path to child
        with descriptor.runtime.export_fs.open('chapter/ch.xml') as f:
            chapter_xml = etree.fromstring(f.read())
        self.assertEqual(chapter_xml.tag, 'chapter')
        self.assertFalse('due' in chapter_xml.attrib)
    def test_metadata_import_export(self):
        """Two checks:
            - unknown metadata is preserved across import-export
            - inherited metadata doesn't leak to children.
        """
        system = self.get_system()
        v = "March 20 17:00"
        url_name = "test1"
        start_xml = """
        <course org="{org}" course="{course}"
                due="{due}" url_name="{url_name}" unicorn="purple">
            <chapter url="hi" url_name="ch" display_name="CH">
                <html url_name="h" display_name="H">Two houses, ...</html>
            </chapter>
        </course>""".format(
            due=v, org=ORG, course=COURSE, url_name=url_name
        )
        descriptor = system.process_xml(start_xml)
        compute_inherited_metadata(descriptor)

        # pylint: disable=W0212
        print(descriptor, descriptor._field_data)
        self.assertEqual(descriptor.due, ImportTestCase.date.from_json(v))

        # Check that the child inherits due correctly
        child = descriptor.get_children()[0]
        self.assertEqual(child.due, ImportTestCase.date.from_json(v))
        # need to convert v to canonical json b4 comparing
        self.assertEqual(
            ImportTestCase.date.to_json(ImportTestCase.date.from_json(v)), child.xblock_kvs.inherited_settings["due"]
        )

        # Now export and check things
        resource_fs = MemoryFS()
        exported_xml = descriptor.export_to_xml(resource_fs)

        # Check that the exported xml is just a pointer
        print("Exported xml:", exported_xml)
        pointer = etree.fromstring(exported_xml)
        self.assertTrue(is_pointer_tag(pointer))
        # but it's a special case course pointer
        self.assertEqual(pointer.attrib["course"], COURSE)
        self.assertEqual(pointer.attrib["org"], ORG)

        # Does the course still have unicorns?
        with resource_fs.open("course/{url_name}.xml".format(url_name=url_name)) as f:
            course_xml = etree.fromstring(f.read())

        self.assertEqual(course_xml.attrib["unicorn"], "purple")

        # the course and org tags should be _only_ in the pointer
        self.assertTrue("course" not in course_xml.attrib)
        self.assertTrue("org" not in course_xml.attrib)

        # did we successfully strip the url_name from the definition contents?
        self.assertTrue("url_name" not in course_xml.attrib)

        # Does the chapter tag now have a due attribute?
        # hardcoded path to child
        with resource_fs.open("chapter/ch.xml") as f:
            chapter_xml = etree.fromstring(f.read())
        self.assertEqual(chapter_xml.tag, "chapter")
        self.assertFalse("due" in chapter_xml.attrib)