コード例 #1
0
    def test_libraries_on_index(self):
        """
        Test that the library tab is present.
        """
        def _assert_library_tab_present(response):
            """
            Asserts there's a library tab.
            """
            parsed_html = lxml.html.fromstring(response.content)
            library_tab = parsed_html.find_class('react-library-listing')
            self.assertEqual(len(library_tab), 1)

        # Add a library:
        lib1 = LibraryFactory.create()

        index_url = '/home/'
        index_response = self.client.get(index_url, {}, HTTP_ACCEPT='text/html')
        _assert_library_tab_present(index_response)

        # Make sure libraries are visible to non-staff users too
        self.client.logout()
        non_staff_user, non_staff_userpassword = self.create_non_staff_user()
        lib2 = LibraryFactory.create(user_id=non_staff_user.id)
        LibraryUserRole(lib2.location.library_key).add_users(non_staff_user)
        self.client.login(username=non_staff_user.username, password=non_staff_userpassword)
        index_response = self.client.get(index_url, {}, HTTP_ACCEPT='text/html')
        _assert_library_tab_present(index_response)
コード例 #2
0
    def test_libraries_on_course_index(self):
        """
        Test getting the list of libraries from the course listing page
        """
        def _assert_library_link_present(response, library):
            """
            Asserts there's a valid library link on libraries tab.
            """
            parsed_html = lxml.html.fromstring(response.content)
            library_link_elements = parsed_html.find_class('library-link')
            self.assertEqual(len(library_link_elements), 1)
            link = library_link_elements[0]
            self.assertEqual(
                link.get("href"),
                reverse_library_url('library_handler', library.location.library_key),
            )
            # now test that url
            outline_response = self.client.get(link.get("href"), {}, HTTP_ACCEPT='text/html')
            self.assertEqual(outline_response.status_code, 200)

        # Add a library:
        lib1 = LibraryFactory.create()

        index_url = '/home/'
        index_response = self.client.get(index_url, {}, HTTP_ACCEPT='text/html')
        _assert_library_link_present(index_response, lib1)

        # Make sure libraries are visible to non-staff users too
        self.client.logout()
        non_staff_user, non_staff_userpassword = self.create_non_staff_user()
        lib2 = LibraryFactory.create(user_id=non_staff_user.id)
        LibraryUserRole(lib2.location.library_key).add_users(non_staff_user)
        self.client.login(username=non_staff_user.username, password=non_staff_userpassword)
        index_response = self.client.get(index_url, {}, HTTP_ACCEPT='text/html')
        _assert_library_link_present(index_response, lib2)
コード例 #3
0
ファイル: test_libraries.py プロジェクト: xego/edx-platform
 def test_duplicate_library(self):
     """
     Make sure we cannot create duplicate libraries
     """
     org, lib_code = ("DuplicateX", "DUP")
     LibraryFactory.create(org=org, library=lib_code, modulestore=self.store)
     with self.assertRaises(DuplicateCourseError):
         LibraryFactory.create(org=org, library=lib_code, modulestore=self.store)
コード例 #4
0
ファイル: test_libraries.py プロジェクト: xego/edx-platform
    def test_create_library(self):
        """
        Test that we can create a library, and see how many mongo calls it uses to do so.

        Expected mongo calls, in order:
        find_one({'org': '...', 'run': 'library', 'course': '...'})
        insert(definition: {'block_type': 'library', 'fields': {}})

        insert_structure(bulk)
        insert_course_index(bulk)
        get_course_index(bulk)
        """
        with check_mongo_calls(2, 3):
            LibraryFactory.create(modulestore=self.store)
コード例 #5
0
ファイル: test_library.py プロジェクト: shevious/edx-platform
    def test_manage_library_users(self):
        """
        Simple test that the Library "User Access" view works.
        Also tests that we can use the REST API to assign a user to a library.
        """
        library = LibraryFactory.create()
        extra_user, _ = self.create_non_staff_user()
        manage_users_url = reverse_library_url('manage_library_users', unicode(library.location.library_key))

        response = self.client.get(manage_users_url)
        self.assertEqual(response.status_code, 200)
        # extra_user has not been assigned to the library so should not show up in the list:
        self.assertNotIn(extra_user.username, response.content)

        # Now add extra_user to the library:
        user_details_url = reverse_course_url(
            'course_team_handler',
            library.location.library_key, kwargs={'email': extra_user.email}
        )
        edit_response = self.client.ajax_post(user_details_url, {"role": LibraryUserRole.ROLE})
        self.assertIn(edit_response.status_code, (200, 204))

        # Now extra_user should apear in the list:
        response = self.client.get(manage_users_url)
        self.assertEqual(response.status_code, 200)
        self.assertIn(extra_user.username, response.content)
コード例 #6
0
    def test_library_author_view_with_paging(self):
        """
        Test that LibraryRoot.author_view can apply paging
        We have to patch the runtime (module system) in order to be able to
        render blocks in our test environment.
        """
        library = LibraryFactory.create(modulestore=self.store)
        # Add five HTML blocks to the library:
        blocks = [
            ItemFactory.create(
                category="html",
                parent_location=library.location,
                user_id=self.user_id,
                publish_item=False,
                modulestore=self.store,
                data="HtmlBlock" + str(i)
            )
            for i in range(5)
        ]
        library = self.store.get_library(library.location.library_key)

        def render_and_check_contents(page, page_size):
            """ Renders block and asserts on returned content """
            context = {'reorderable_items': set(), 'paging': {'page_number': page, 'page_size': page_size}}
            expected_blocks = blocks[page_size * page:page_size * (page + 1)]
            result = library.render(AUTHOR_VIEW, context)

            for expected_block in expected_blocks:
                self.assertIn(expected_block.data, result.content)

        render_and_check_contents(0, 3)
        render_and_check_contents(1, 3)
        render_and_check_contents(0, 2)
        render_and_check_contents(1, 2)
コード例 #7
0
    def test_library_author_view(self):
        """
        Test that LibraryRoot.author_view can run and includes content from its
        children.
        We have to patch the runtime (module system) in order to be able to
        render blocks in our test environment.
        """
        message = u"Hello world"
        library = LibraryFactory.create(modulestore=self.store)
        # Add one HTML block to the library:
        ItemFactory.create(
            category="html",
            parent_location=library.location,
            user_id=self.user_id,
            publish_item=False,
            modulestore=self.store,
            data=message
        )
        library = self.store.get_library(library.location.library_key)

        context = {'reorderable_items': set(), }
        # Patch the HTML block to always render "Hello world"

        result = library.render(AUTHOR_VIEW, context)
        self.assertIn(message, result.content)
コード例 #8
0
    def test_library_import_branch_settings(self, branch_setting):
        """
        Try importing a known good library archive under either branch setting.
        The branch setting should have no effect on library import.
        """
        with self.store.branch_setting(branch_setting):
            library = LibraryFactory.create(modulestore=self.store)
            lib_key = library.location.library_key
            extract_dir = path(tempfile.mkdtemp(dir=settings.DATA_DIR))
            # the extract_dir needs to be passed as a relative dir to
            # import_library_from_xml
            extract_dir_relative = path.relpath(extract_dir, settings.DATA_DIR)

            try:
                with tarfile.open(path(TEST_DATA_DIR) / 'imports' / 'library.HhJfPD.tar.gz') as tar:
                    safetar_extractall(tar, extract_dir)
                import_library_from_xml(
                    self.store,
                    self.user.id,
                    settings.GITHUB_REPO_ROOT,
                    [extract_dir_relative / 'library'],
                    load_error_modules=False,
                    static_content_store=contentstore(),
                    target_id=lib_key
                )
            finally:
                shutil.rmtree(extract_dir)
コード例 #9
0
 def test_library_export(self):
     """
     Verify that useable library data can be exported.
     """
     youtube_id = "qS4NO9MNC6w"
     library = LibraryFactory.create(modulestore=self.store)
     video_block = ItemFactory.create(
         category="video",
         parent_location=library.location,
         user_id=self.user.id,
         publish_item=False,
         youtube_id_1_0=youtube_id
     )
     name = library.url_name
     lib_key = library.location.library_key
     root_dir = path(tempfile.mkdtemp())
     try:
         export_library_to_xml(self.store, contentstore(), lib_key, root_dir, name)
         lib_xml = lxml.etree.XML(open(root_dir / name / LIBRARY_ROOT).read())
         self.assertEqual(lib_xml.get('org'), lib_key.org)
         self.assertEqual(lib_xml.get('library'), lib_key.library)
         block = lib_xml.find('video')
         self.assertIsNotNone(block)
         self.assertEqual(block.get('url_name'), video_block.url_name)
         video_xml = lxml.etree.XML(open(root_dir / name / 'video' / video_block.url_name + '.xml').read())
         self.assertEqual(video_xml.tag, 'video')
         self.assertEqual(video_xml.get('youtube_id_1_0'), youtube_id)
     finally:
         shutil.rmtree(root_dir / name)
コード例 #10
0
    def test_copy_from_template_publish(self):
        """
        Test that copy_from_template's "defaults" data is not lost
        when blocks are published.
        """
        # Create a library with a problem:
        source_library = LibraryFactory.create(modulestore=self.store)
        display_name_expected = "CUSTOM Library Display Name"
        self.make_block("problem", source_library, display_name=display_name_expected)
        # Reload source_library since we need its branch and version to use copy_from_template:
        source_library = self.store.get_library(
            source_library.location.library_key, remove_version=False, remove_branch=False
        )
        # And a course with a vertical:
        course = CourseFactory.create(modulestore=self.store)
        self.make_block("vertical", course)

        problem_key_in_course = self.store.copy_from_template(
            source_library.children, dest_key=course.location, user_id=self.user_id
        )[0]

        # We do the following twice because different methods get used inside
        # split modulestore on first vs. subsequent publish
        for __ in range(2):
            # Publish:
            self.store.publish(problem_key_in_course, self.user_id)
            # Test that the defaults values are there.
            problem_published = self.store.get_item(
                problem_key_in_course.for_branch(ModuleStoreEnum.BranchName.published)
            )
            self.assertEqual(problem_published.display_name, display_name_expected)
コード例 #11
0
ファイル: test_libraries.py プロジェクト: xego/edx-platform
    def test_library_author_view(self):
        """
        Test that LibraryRoot.author_view can run and includes content from its
        children.
        We have to patch the runtime (module system) in order to be able to
        render blocks in our test environment.
        """
        library = LibraryFactory.create(modulestore=self.store)
        # Add one HTML block to the library:
        ItemFactory.create(
            category="html",
            parent_location=library.location,
            user_id=self.user_id,
            publish_item=False,
            modulestore=self.store,
        )
        library = self.store.get_library(library.location.library_key)

        context = {"reorderable_items": set()}
        # Patch the HTML block to always render "Hello world"
        message = u"Hello world"
        hello_render = lambda _, context: Fragment(message)
        with patch("xmodule.html_module.HtmlDescriptor.author_view", hello_render, create=True):
            with patch("xmodule.x_module.descriptor_global_get_asides", lambda block: []):
                result = library.render(AUTHOR_VIEW, context)
        self.assertIn(message, result.content)
コード例 #12
0
ファイル: test_library.py プロジェクト: shevious/edx-platform
    def test_no_access(self):
        user, password = self.create_non_staff_user()
        self.client.login(username=user, password=password)

        lib = LibraryFactory.create()
        response = self.client.get(make_url_for_lib(lib.location.library_key))
        self.assertEqual(response.status_code, 403)
コード例 #13
0
    def setUp(self):
        """ Setup method - create courses """
        super(TestReindexCourse, self).setUp()
        self.store = modulestore()
        self.first_lib = LibraryFactory.create(
            org="test", library="lib1", display_name="run1", default_store=ModuleStoreEnum.Type.split
        )
        self.second_lib = LibraryFactory.create(
            org="test", library="lib2", display_name="run2", default_store=ModuleStoreEnum.Type.split
        )

        self.first_course = CourseFactory.create(
            org="test", course="course1", display_name="run1"
        )
        self.second_course = CourseFactory.create(
            org="test", course="course2", display_name="run1"
        )
コード例 #14
0
ファイル: test_libraries.py プロジェクト: xego/edx-platform
 def test_str_repr(self, name):
     """
     Test __unicode__() and __str__() methods of libraries
     """
     library = LibraryFactory.create(metadata={"display_name": name}, modulestore=self.store)
     self.assertIn(name, unicode(library))
     if not isinstance(name, unicode):
         self.assertIn(name, str(library))
コード例 #15
0
ファイル: test_library.py プロジェクト: shevious/edx-platform
 def test_bad_http_verb_with_lib_key(self):
     """
     We should get an error if we do weird requests to /library/
     """
     lib = LibraryFactory.create()
     for verb in ("post", "delete", "put"):
         response = getattr(self.client, verb)(make_url_for_lib(lib.location.library_key))
         self.assertEqual(response.status_code, 405)
コード例 #16
0
 def test_list_available_libraries(self):
     """
     Test listing of libraries.
     """
     _ = LibraryFactory.create(modulestore=self.store)
     all_libraries = self.tools.list_available_libraries()
     self.assertTrue(all_libraries)
     self.assertEqual(len(all_libraries), 1)
コード例 #17
0
    def setUpClass(cls):

        super(LibraryTestCase, cls).setUpClass()

        cls.library = LibraryFactory.create(modulestore=cls.store)
        creator = UserFactory()

        cls.library_blocks = [
            ItemFactory.create(
                category="html",
                parent=cls.library,
                parent_location=cls.library.location,
                publish_item=False,
                user_id=creator.id,
                modulestore=cls.store,
            ) for _ in range(3)
        ]
        cls.libtools = LibraryToolsService(cls.store)
        cls.store.update_item(cls.library, creator.id)

        with cls.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, None):
            cls.course = CourseFactory.create(modulestore=cls.store)
            cls.course_key = cls.course.id

            with cls.store.bulk_operations(cls.course_key, emit_signals=False):
                cls.chapter = ItemFactory.create(
                    parent=cls.course,
                    parent_location=cls.course.location,
                    category="chapter",
                    modulestore=cls.store,
                    publish_item=False,
                )
                cls.sequential = ItemFactory.create(
                    parent=cls.chapter,
                    parent_location=cls.chapter.location,
                    category='sequential',
                    modulestore=cls.store,
                    publish_item=False,
                )
                cls.vertical = ItemFactory.create(
                    parent=cls.sequential,
                    parent_location=cls.sequential.location,
                    category='vertical',
                    modulestore=cls.store,
                    publish_item=False,
                )

                cls.lc_block = ItemFactory.create(
                    category="library_content",
                    parent=cls.vertical,
                    parent_location=cls.vertical.location,
                    max_count=2,
                    source_library_id=unicode(cls.library.location.library_key),
                    modulestore=cls.store,
                )
                # copy children from library to content block (LibaryContentDescriptor.tools.update_children?)
                cls.store.update_item(cls.course, creator.id)
                cls.store.update_item(cls.lc_block, creator.id)
コード例 #18
0
    def test_content_library_export_import(self):
        library1 = LibraryFactory.create(modulestore=self.store)
        source_library1_key = library1.location.library_key
        library2 = LibraryFactory.create(modulestore=self.store)
        source_library2_key = library2.location.library_key

        import_library_from_xml(
            self.store,
            'test_user',
            TEST_DATA_DIR,
            ['library_empty_problem'],
            static_content_store=contentstore(),
            target_id=source_library1_key,
            load_error_modules=False,
            raise_on_failure=True,
            create_if_not_present=True,
        )

        export_library_to_xml(
            self.store,
            contentstore(),
            source_library1_key,
            self.export_dir,
            'exported_source_library',
        )

        source_library = self.store.get_library(source_library1_key)
        self.assertEqual(source_library.url_name, 'library')

        # Import the exported library into a different content library.
        import_library_from_xml(
            self.store,
            'test_user',
            self.export_dir,
            ['exported_source_library'],
            static_content_store=contentstore(),
            target_id=source_library2_key,
            load_error_modules=False,
            raise_on_failure=True,
            create_if_not_present=True,
        )

        # Compare the two content libraries for equality.
        self.assertCoursesEqual(source_library1_key, source_library2_key)
コード例 #19
0
ファイル: test_libraries.py プロジェクト: xego/edx-platform
    def test_get_libraries(self):
        """ Test get_libraries() """
        libraries = [LibraryFactory.create(modulestore=self.store) for _ in range(0, 3)]
        lib_dict = dict([(lib.location.library_key, lib) for lib in libraries])

        lib_list = self.store.get_libraries()

        self.assertEqual(len(lib_list), len(libraries))
        for lib in lib_list:
            self.assertIn(lib.location.library_key, lib_dict)
コード例 #20
0
 def test_xblock_in_lib_have_published_version_returns_false(self):
     library = LibraryFactory.create(modulestore=self.store)
     block = ItemFactory.create(
         category="html",
         parent_location=library.location,
         user_id=self.user_id,
         publish_item=False,
         modulestore=self.store,
     )
     self.assertFalse(self.store.has_published_version(block))
コード例 #21
0
ファイル: test_libraries.py プロジェクト: xego/edx-platform
 def test_display_with_default_methods(self):
     """
     Check that the display_x_with_default methods have been implemented, for
     compatibility with courses.
     """
     org = "TestOrgX"
     lib_code = "LC101"
     library = LibraryFactory.create(org=org, library=lib_code, modulestore=self.store)
     self.assertEqual(library.display_org_with_default, org)
     self.assertEqual(library.display_number_with_default, lib_code)
コード例 #22
0
ファイル: test_library.py プロジェクト: shevious/edx-platform
    def test_get_lib_edit_html(self):
        """
        Test that we can get the studio view for editing a library using /library/:key/
        """
        lib = LibraryFactory.create()

        response = self.client.get(make_url_for_lib(lib.location.library_key))
        self.assertEqual(response.status_code, 200)
        self.assertIn("<html", response.content)
        self.assertIn(lib.display_name, response.content)
コード例 #23
0
ファイル: test_libraries.py プロジェクト: xego/edx-platform
 def test_get_lib_version(self):
     """
     Test that we can get version data about a library from get_library()
     """
     # Create a library
     lib_key = LibraryFactory.create(modulestore=self.store).location.library_key
     # Re-load the library from the modulestore, explicitly including version information:
     lib = self.store.get_library(lib_key, remove_version=False, remove_branch=False)
     version = lib.location.library_key.version_guid
     self.assertIsInstance(version, ObjectId)
コード例 #24
0
ファイル: test_library.py プロジェクト: shevious/edx-platform
 def test_get_component_templates(self):
     """
     Verify that templates for adding discussion and advanced components to
     content libraries are not provided.
     """
     lib = LibraryFactory.create()
     lib.advanced_modules = ['lti']
     lib.save()
     templates = [template['type'] for template in get_component_templates(lib, library=True)]
     self.assertIn('problem', templates)
     self.assertNotIn('discussion', templates)
     self.assertNotIn('advanced', templates)
コード例 #25
0
ファイル: test_library.py プロジェクト: shevious/edx-platform
 def test_no_duplicate_libraries(self):
     """
     We should not be able to create multiple libraries with the same key
     """
     lib = LibraryFactory.create()
     lib_key = lib.location.library_key
     response = self.client.ajax_post(LIBRARY_REST_URL, {
         'org': lib_key.org,
         'library': lib_key.library,
         'display_name': "A Duplicate key, same as 'lib'",
     })
     self.assertIn('already a library defined', parse_json(response)['ErrMsg'])
     self.assertEqual(response.status_code, 400)
コード例 #26
0
ファイル: test_libraries.py プロジェクト: xego/edx-platform
 def test_strip(self):
     """
     Test that library keys coming out of MixedModuleStore are stripped of
     branch and version info by default.
     """
     # Create a library
     lib_key = LibraryFactory.create(modulestore=self.store).location.library_key
     # Re-load the library from the modulestore, explicitly including version information:
     lib = self.store.get_library(lib_key)
     self.assertEqual(lib.location.version_guid, None)
     self.assertEqual(lib.location.branch, None)
     self.assertEqual(lib.location.library_key.version_guid, None)
     self.assertEqual(lib.location.library_key.branch, None)
コード例 #27
0
ファイル: test_libraries.py プロジェクト: swardi/edx-platform
 def test_strip(self):
     """
     Test that library keys coming out of MixedModuleStore are stripped of
     branch and version info by default.
     """
     # Create a library
     lib_key = LibraryFactory.create(
         modulestore=self.store).location.library_key
     # Re-load the library from the modulestore, explicitly including version information:
     lib = self.store.get_library(lib_key)
     self.assertEqual(lib.location.version_guid, None)
     self.assertEqual(lib.location.branch, None)
     self.assertEqual(lib.location.library_key.version_guid, None)
     self.assertEqual(lib.location.library_key.branch, None)
コード例 #28
0
    def setUp(self):
        super(TestTaskExecution, self).setUp()
        SignalHandler.course_published.disconnect(listen_for_course_publish)
        SignalHandler.library_updated.disconnect(listen_for_library_update)
        self.course = CourseFactory.create(start=datetime(2015, 3, 1, tzinfo=UTC))

        self.chapter = ItemFactory.create(
            parent_location=self.course.location,
            category='chapter',
            display_name="Week 1",
            publish_item=True,
            start=datetime(2015, 3, 1, tzinfo=UTC),
        )
        self.sequential = ItemFactory.create(
            parent_location=self.chapter.location,
            category='sequential',
            display_name="Lesson 1",
            publish_item=True,
            start=datetime(2015, 3, 1, tzinfo=UTC),
        )
        self.vertical = ItemFactory.create(
            parent_location=self.sequential.location,
            category='vertical',
            display_name='Subsection 1',
            publish_item=True,
            start=datetime(2015, 4, 1, tzinfo=UTC),
        )
        # unspecified start - should inherit from container
        self.html_unit = ItemFactory.create(
            parent_location=self.vertical.location,
            category="html",
            display_name="Html Content",
            publish_item=False,
        )

        self.library = LibraryFactory.create()

        self.library_block1 = ItemFactory.create(
            parent_location=self.library.location,
            category="html",
            display_name="Html Content",
            publish_item=False,
        )

        self.library_block2 = ItemFactory.create(
            parent_location=self.library.location,
            category="html",
            display_name="Html Content 2",
            publish_item=False,
        )
コード例 #29
0
    def setUp(self):
        super(TestTaskExecution, self).setUp()
        SignalHandler.course_published.disconnect(listen_for_course_publish)
        SignalHandler.library_updated.disconnect(listen_for_library_update)
        self.course = CourseFactory.create(start=datetime(2015, 3, 1, tzinfo=UTC))

        self.chapter = ItemFactory.create(
            parent_location=self.course.location,
            category='chapter',
            display_name="Week 1",
            publish_item=True,
            start=datetime(2015, 3, 1, tzinfo=UTC),
        )
        self.sequential = ItemFactory.create(
            parent_location=self.chapter.location,
            category='sequential',
            display_name="Lesson 1",
            publish_item=True,
            start=datetime(2015, 3, 1, tzinfo=UTC),
        )
        self.vertical = ItemFactory.create(
            parent_location=self.sequential.location,
            category='vertical',
            display_name='Subsection 1',
            publish_item=True,
            start=datetime(2015, 4, 1, tzinfo=UTC),
        )
        # unspecified start - should inherit from container
        self.html_unit = ItemFactory.create(
            parent_location=self.vertical.location,
            category="html",
            display_name="Html Content",
            publish_item=False,
        )

        self.library = LibraryFactory.create()

        self.library_block1 = ItemFactory.create(
            parent_location=self.library.location,
            category="html",
            display_name="Html Content",
            publish_item=False,
        )

        self.library_block2 = ItemFactory.create(
            parent_location=self.library.location,
            category="html",
            display_name="Html Content 2",
            publish_item=False,
        )
コード例 #30
0
ファイル: test_services.py プロジェクト: xzhuwu/edx-platform
    def test_vertical_completion_with_library_content(self):
        library = LibraryFactory.create(modulestore=self.store)
        ItemFactory.create(parent=library, category='problem', publish_item=False, user_id=self.user.id)
        ItemFactory.create(parent=library, category='problem', publish_item=False, user_id=self.user.id)
        ItemFactory.create(parent=library, category='problem', publish_item=False, user_id=self.user.id)
        lib_vertical = ItemFactory.create(parent=self.sequence, category='vertical', publish_item=False)
        library_content_block = ItemFactory.create(
            parent=lib_vertical,
            category='library_content',
            max_count=1,
            source_library_id=str(library.location.library_key),
            user_id=self.user.id,
        )
        library_content_block.refresh_children()
        lib_vertical = self.store.get_item(lib_vertical.location)
        self._bind_course_module(lib_vertical)
        # We need to refetch the library_content_block to retrieve the
        # fresh version from the call to get_item for lib_vertical
        library_content_block = [child for child in lib_vertical.get_children()
                                 if child.scope_ids.block_type == 'library_content'][0]

        ## Ensure the library_content_block is properly set up
        # This is needed so we can call get_child_descriptors
        self._bind_course_module(library_content_block)
        # Make sure the runtime knows that the block's children vary per-user:
        self.assertTrue(library_content_block.has_dynamic_children())
        self.assertEqual(len(library_content_block.children), 3)
        # Check how many children each user will see:
        self.assertEqual(len(library_content_block.get_child_descriptors()), 1)

        # No problems are complete yet
        self.assertFalse(self.completion_service.vertical_is_complete(lib_vertical))

        for block_key in self.block_keys:
            BlockCompletion.objects.submit_completion(
                user=self.user,
                block_key=block_key,
                completion=1.0
            )
        # Library content problems aren't complete yet
        self.assertFalse(self.completion_service.vertical_is_complete(lib_vertical))

        for child in library_content_block.get_child_descriptors():
            BlockCompletion.objects.submit_completion(
                user=self.user,
                block_key=child.scope_ids.usage_id,
                completion=1.0
            )
        self.assertTrue(self.completion_service.vertical_is_complete(lib_vertical))
コード例 #31
0
    def setUp(self):
        super(LibraryContentTest, self).setUp()

        self.tools = LibraryToolsService(self.store)
        self.library = LibraryFactory.create(modulestore=self.store)
        self.lib_blocks = [
            self.make_block("html", self.library, data="Hello world from block {}".format(i)) for i in range(1, 5)
        ]
        self.course = CourseFactory.create(modulestore=self.store)
        self.chapter = self.make_block("chapter", self.course)
        self.sequential = self.make_block("sequential", self.chapter)
        self.vertical = self.make_block("vertical", self.sequential)
        self.lc_block = self.make_block(
            "library_content", self.vertical, max_count=1, source_library_id=unicode(self.library.location.library_key)
        )
コード例 #32
0
 def test_no_duplicate_libraries(self):
     """
     We should not be able to create multiple libraries with the same key
     """
     lib = LibraryFactory.create()
     lib_key = lib.location.library_key
     response = self.client.ajax_post(
         LIBRARY_REST_URL, {
             'org': lib_key.org,
             'library': lib_key.library,
             'display_name': "A Duplicate key, same as 'lib'",
         })
     self.assertIn('already a library defined',
                   parse_json(response)['ErrMsg'])
     self.assertEqual(response.status_code, 400)
コード例 #33
0
 def test_get_component_templates(self):
     """
     Verify that templates for adding discussion and advanced components to
     content libraries are not provided.
     """
     lib = LibraryFactory.create()
     lib.advanced_modules = ['lti']
     lib.save()
     templates = [
         template['type']
         for template in get_component_templates(lib, library=True)
     ]
     self.assertIn('problem', templates)
     self.assertNotIn('discussion', templates)
     self.assertNotIn('advanced', templates)
コード例 #34
0
    def test_xblock_studio_url(self):

        # Verify course URL
        course_url = u'/course/{}'.format(unicode(self.course.id))
        self.assertEqual(xblock_studio_url(self.course), course_url)

        # Verify chapter URL
        chapter = ItemFactory.create(parent_location=self.course.location,
                                     category='chapter',
                                     display_name="Week 1")
        self.assertEqual(
            xblock_studio_url(chapter),
            u'{}?show={}'.format(course_url, http.urlquote(chapter.location)))

        # Verify sequential URL
        sequential = ItemFactory.create(parent_location=chapter.location,
                                        category='sequential',
                                        display_name="Lesson 1")
        self.assertEqual(
            xblock_studio_url(sequential),
            u'{}?show={}'.format(course_url,
                                 http.urlquote(sequential.location)))

        # Verify unit URL
        vertical = ItemFactory.create(parent_location=sequential.location,
                                      category='vertical',
                                      display_name='Unit')
        self.assertEqual(xblock_studio_url(vertical),
                         u'/container/{}'.format(vertical.location))

        # Verify child vertical URL
        child_vertical = ItemFactory.create(parent_location=vertical.location,
                                            category='vertical',
                                            display_name='Child Vertical')
        self.assertEqual(xblock_studio_url(child_vertical),
                         u'/container/{}'.format(child_vertical.location))

        # Verify video URL
        video = ItemFactory.create(parent_location=child_vertical.location,
                                   category="video",
                                   display_name="My Video")
        self.assertIsNone(xblock_studio_url(video))

        # Verify library URL
        library = LibraryFactory.create()
        expected_url = u'/library/{}'.format(
            unicode(library.location.library_key))
        self.assertEqual(xblock_studio_url(library), expected_url)
コード例 #35
0
    def test_libraries_on_course_index(self):
        """
        Test getting the list of libraries from the course listing page
        """
        # Add a library:
        lib1 = LibraryFactory.create()

        index_url = "/home/"
        index_response = self.client.get(index_url, {}, HTTP_ACCEPT="text/html")
        parsed_html = lxml.html.fromstring(index_response.content)
        library_link_elements = parsed_html.find_class("library-link")
        self.assertEqual(len(library_link_elements), 1)
        link = library_link_elements[0]
        self.assertEqual(link.get("href"), reverse_library_url("library_handler", lib1.location.library_key))
        # now test that url
        outline_response = self.client.get(link.get("href"), {}, HTTP_ACCEPT="text/html")
        self.assertEqual(outline_response.status_code, 200)
コード例 #36
0
    def test_advanced_problem_types(self):
        """
        Verify that advanced problem types are not provided in problem component for libraries.
        """
        lib = LibraryFactory.create()
        lib.save()

        problem_type_templates = next(
            (component['templates'] for component in get_component_templates(lib, library=True) if component['type'] == 'problem'),
            []
        )
        # Each problem template has a category which shows whether problem is a 'problem'
        # or which of the advanced problem type (e.g drag-and-drop-v2).
        problem_type_categories = [problem_template['category'] for problem_template in problem_type_templates]

        for advance_problem_type in settings.ADVANCED_PROBLEM_TYPES:
            self.assertNotIn(advance_problem_type['component'], problem_type_categories)
コード例 #37
0
    def test_component_limits(self):
        """
        Test that component limits in libraries are respected.
        """
        with self.settings(MAX_BLOCKS_PER_CONTENT_LIBRARY=1):
            library = LibraryFactory.create()
            data = {
                'parent_locator': str(library.location),
                'category': 'html'
            }
            response = self.client.ajax_post(reverse('xblock_handler'), data)
            self.assertEqual(response.status_code, 200)

            # Adding another component should cause failure:
            response = self.client.ajax_post(reverse('xblock_handler'), data)
            self.assertEqual(response.status_code, 400)
            self.assertIn('cannot have more than 1 component', parse_json(response)['error'])
コード例 #38
0
    def test_advanced_problem_types(self):
        """
        Verify that advanced problem types are not provided in problem component for libraries.
        """
        lib = LibraryFactory.create()
        lib.save()

        problem_type_templates = next(
            (component['templates'] for component in get_component_templates(lib, library=True) if component['type'] == 'problem'),
            []
        )
        # Each problem template has a category which shows whether problem is a 'problem'
        # or which of the advanced problem type (e.g drag-and-drop-v2).
        problem_type_categories = [problem_template['category'] for problem_template in problem_type_templates]

        for advance_problem_type in settings.ADVANCED_PROBLEM_TYPES:
            self.assertNotIn(advance_problem_type['component'], problem_type_categories)
コード例 #39
0
 def test_delete_item(self):
     """
     Test to make sure delete_item() works on blocks in a library
     """
     library = LibraryFactory.create(modulestore=self.store)
     lib_key = library.location.library_key
     block = ItemFactory.create(
         category="html",
         parent_location=library.location,
         user_id=self.user_id,
         publish_item=False,
         modulestore=self.store,
     )
     library = self.store.get_library(lib_key)
     assert len(library.children) == 1
     self.store.delete_item(block.location, self.user_id)
     library = self.store.get_library(lib_key)
     assert len(library.children) == 0
コード例 #40
0
    def test_list_libraries(self):
        """
        Test that we can GET /library/ to list all libraries visible to the current user.
        """
        # Create some more libraries
        libraries = [LibraryFactory.create() for _ in range(3)]
        lib_dict = dict([(lib.location.library_key, lib) for lib in libraries])

        response = self.client.get_json(LIBRARY_REST_URL)
        self.assertEqual(response.status_code, 200)
        lib_list = parse_json(response)
        self.assertEqual(len(lib_list), len(libraries))
        for entry in lib_list:
            self.assertIn("library_key", entry)
            self.assertIn("display_name", entry)
            key = CourseKey.from_string(entry["library_key"])
            self.assertIn(key, lib_dict)
            self.assertEqual(entry["display_name"], lib_dict[key].display_name)
            del lib_dict[key]  # To ensure no duplicates are matched
コード例 #41
0
    def setUp(self):
        super().setUp()

        self.tools = LibraryToolsService(self.store, self.user_id)
        self.library = LibraryFactory.create(modulestore=self.store)
        self.lib_blocks = [
            self.make_block("html", self.library, data=f"Hello world from block {i}")
            for i in range(1, 5)
        ]
        self.course = CourseFactory.create(modulestore=self.store)
        self.chapter = self.make_block("chapter", self.course)
        self.sequential = self.make_block("sequential", self.chapter)
        self.vertical = self.make_block("vertical", self.sequential)
        self.lc_block = self.make_block(
            "library_content",
            self.vertical,
            max_count=1,
            source_library_id=str(self.library.location.library_key)
        )
コード例 #42
0
    def setUp(self):
        super(LibraryContentTest, self).setUp()

        self.tools = LibraryToolsService(self.store)
        self.library = LibraryFactory.create(modulestore=self.store)
        self.lib_blocks = [
            self.make_block("html", self.library, data="Hello world from block {}".format(i))
            for i in range(1, 5)
        ]
        self.course = CourseFactory.create(modulestore=self.store)
        self.chapter = self.make_block("chapter", self.course)
        self.sequential = self.make_block("sequential", self.chapter)
        self.vertical = self.make_block("vertical", self.sequential)
        self.lc_block = self.make_block(
            "library_content",
            self.vertical,
            max_count=1,
            source_libraries=[LibraryVersionReference(self.library.location.library_key)]
        )
コード例 #43
0
    def test_get_lib_info(self):
        """
        Test that we can get data about a library (in JSON format) using /library/:key/
        """
        # Create a library
        lib_key = LibraryFactory.create().location.library_key
        # Re-load the library from the modulestore, explicitly including version information:
        lib = self.store.get_library(lib_key, remove_version=False, remove_branch=False)
        version = lib.location.library_key.version_guid
        self.assertNotEqual(version, None)

        response = self.client.get_json(make_url_for_lib(lib_key))
        self.assertEqual(response.status_code, 200)
        info = parse_json(response)
        self.assertEqual(info['display_name'], lib.display_name)
        self.assertEqual(info['library_id'], unicode(lib_key))
        self.assertEqual(info['previous_version'], None)
        self.assertNotEqual(info['version'], None)
        self.assertNotEqual(info['version'], '')
        self.assertEqual(info['version'], unicode(version))
コード例 #44
0
    def setUp(self):
        super(LibraryContentTest, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments

        self.tools = LibraryToolsService(self.store, self.user_id)
        self.library = LibraryFactory.create(modulestore=self.store)
        self.lib_blocks = [
            self.make_block("html",
                            self.library,
                            data="Hello world from block {}".format(i))
            for i in range(1, 5)
        ]
        self.course = CourseFactory.create(modulestore=self.store)
        self.chapter = self.make_block("chapter", self.course)
        self.sequential = self.make_block("sequential", self.chapter)
        self.vertical = self.make_block("vertical", self.sequential)
        self.lc_block = self.make_block("library_content",
                                        self.vertical,
                                        max_count=1,
                                        source_library_id=six.text_type(
                                            self.library.location.library_key))
コード例 #45
0
    def setup_course_base(self, store):
        """
        Set up the for the course outline tests.
        """
        self.library = LibraryFactory.create(modulestore=store)

        self.html_unit1 = ItemFactory.create(
            parent_location=self.library.location,
            category="html",
            display_name="Html Content",
            modulestore=store,
            publish_item=False,
        )

        self.html_unit2 = ItemFactory.create(
            parent_location=self.library.location,
            category="html",
            display_name="Html Content 2",
            modulestore=store,
            publish_item=False,
        )
コード例 #46
0
    def test_libraries_on_course_index(self):
        """
        Test getting the list of libraries from the course listing page
        """
        # Add a library:
        lib1 = LibraryFactory.create()

        index_url = '/home/'
        index_response = self.client.get(index_url, {},
                                         HTTP_ACCEPT='text/html')
        parsed_html = lxml.html.fromstring(index_response.content)
        library_link_elements = parsed_html.find_class('library-link')
        self.assertEqual(len(library_link_elements), 1)
        link = library_link_elements[0]
        self.assertEqual(
            link.get("href"),
            reverse_library_url('library_handler', lib1.location.library_key),
        )
        # now test that url
        outline_response = self.client.get(link.get("href"), {},
                                           HTTP_ACCEPT='text/html')
        self.assertEqual(outline_response.status_code, 200)
コード例 #47
0
    def test_block_with_children(self):
        """
        Test that blocks used from a library can have children.
        """
        library = LibraryFactory.create(modulestore=self.store)

        # In the library, create a vertical block with a child:
        vert_block = ItemFactory.create(
            category="vertical",
            parent_location=library.location,
            user_id=self.user_id,
            publish_item=False,
            modulestore=self.store,
        )
        child_block = ItemFactory.create(
            category="html",
            parent_location=vert_block.location,
            user_id=self.user_id,
            publish_item=False,
            metadata={"data": "Hello world", },
            modulestore=self.store,
        )
        assert child_block.parent.replace(version_guid=None, branch=None) == vert_block.location
コード例 #48
0
    def test_library_author_view_with_paging(self):
        """
        Test that LibraryRoot.author_view can apply paging
        We have to patch the runtime (module system) in order to be able to
        render blocks in our test environment.
        """
        library = LibraryFactory.create(modulestore=self.store)
        # Add five HTML blocks to the library:
        blocks = [
            ItemFactory.create(category="html",
                               parent_location=library.location,
                               user_id=self.user_id,
                               publish_item=False,
                               modulestore=self.store,
                               data="HtmlBlock" + str(i)) for i in range(5)
        ]
        library = self.store.get_library(library.location.library_key)

        def render_and_check_contents(page, page_size):
            """ Renders block and asserts on returned content """
            context = {
                'reorderable_items': set(),
                'paging': {
                    'page_number': page,
                    'page_size': page_size
                }
            }
            expected_blocks = blocks[page_size * page:page_size * (page + 1)]
            result = library.render(AUTHOR_VIEW, context)

            for expected_block in expected_blocks:
                self.assertIn(expected_block.data, result.content)

        render_and_check_contents(0, 3)
        render_and_check_contents(1, 3)
        render_and_check_contents(0, 2)
        render_and_check_contents(1, 2)
コード例 #49
0
    def test_copy_from_template_publish(self):
        """
        Test that copy_from_template's "defaults" data is not lost
        when blocks are published.
        """
        # Create a library with a problem:
        source_library = LibraryFactory.create(modulestore=self.store)
        display_name_expected = "CUSTOM Library Display Name"
        self.make_block("problem",
                        source_library,
                        display_name=display_name_expected)
        # Reload source_library since we need its branch and version to use copy_from_template:
        source_library = self.store.get_library(
            source_library.location.library_key,
            remove_version=False,
            remove_branch=False)
        # And a course with a vertical:
        course = CourseFactory.create(modulestore=self.store)
        self.make_block("vertical", course)

        problem_key_in_course = self.store.copy_from_template(
            source_library.children,
            dest_key=course.location,
            user_id=self.user_id)[0]

        # We do the following twice because different methods get used inside
        # split modulestore on first vs. subsequent publish
        for __ in range(2):
            # Publish:
            self.store.publish(problem_key_in_course, self.user_id)
            # Test that the defaults values are there.
            problem_published = self.store.get_item(
                problem_key_in_course.for_branch(
                    ModuleStoreEnum.BranchName.published))
            self.assertEqual(problem_published.display_name,
                             display_name_expected)
コード例 #50
0
    def test_update_item(self):
        """
        Test that update_item works for a block in a library
        """
        library = LibraryFactory.create(modulestore=self.store)

        block = ItemFactory.create(
            category="html",
            parent_location=library.location,
            user_id=self.user_id,
            publish_item=False,
            metadata={"data": "Hello world", },
            modulestore=self.store,
        )
        block_key = block.location
        block.data = "NEW"
        old_version = self.store.get_item(block_key, remove_version=False, remove_branch=False).location.version_guid
        self.store.update_item(block, self.user_id)
        # Reload block from the modulestore
        block = self.store.get_item(block_key)
        assert block.data == 'NEW'
        assert block.location == block_key
        new_version = self.store.get_item(block_key, remove_version=False, remove_branch=False).location.version_guid
        assert old_version != new_version
コード例 #51
0
    def test_library_import(self):
        """
        Try importing a known good library archive, and verify that the
        contents of the library have completely replaced the old contents.
        """
        # Create some blocks to overwrite
        library = LibraryFactory.create(modulestore=self.store)
        lib_key = library.location.library_key
        test_block = ItemFactory.create(
            category="vertical",
            parent_location=library.location,
            user_id=self.user.id,
            publish_item=False,
        )
        test_block2 = ItemFactory.create(category="vertical",
                                         parent_location=library.location,
                                         user_id=self.user.id,
                                         publish_item=False)
        # Create a library and blocks that should remain unmolested.
        unchanged_lib = LibraryFactory.create()
        unchanged_key = unchanged_lib.location.library_key
        test_block3 = ItemFactory.create(
            category="vertical",
            parent_location=unchanged_lib.location,
            user_id=self.user.id,
            publish_item=False)
        test_block4 = ItemFactory.create(
            category="vertical",
            parent_location=unchanged_lib.location,
            user_id=self.user.id,
            publish_item=False)
        # Refresh library.
        library = self.store.get_library(lib_key)
        children = [
            self.store.get_item(child).url_name for child in library.children
        ]
        self.assertEqual(len(children), 2)
        self.assertIn(test_block.url_name, children)
        self.assertIn(test_block2.url_name, children)

        unchanged_lib = self.store.get_library(unchanged_key)
        children = [
            self.store.get_item(child).url_name
            for child in unchanged_lib.children
        ]
        self.assertEqual(len(children), 2)
        self.assertIn(test_block3.url_name, children)
        self.assertIn(test_block4.url_name, children)

        extract_dir = path(tempfile.mkdtemp(dir=settings.DATA_DIR))
        # the extract_dir needs to be passed as a relative dir to
        # import_library_from_xml
        extract_dir_relative = path.relpath(extract_dir, settings.DATA_DIR)

        try:
            with tarfile.open(
                    path(TEST_DATA_DIR) / 'imports' /
                    'library.HhJfPD.tar.gz') as tar:
                safetar_extractall(tar, extract_dir)
            library_items = import_library_from_xml(
                self.store,
                self.user.id,
                settings.GITHUB_REPO_ROOT, [extract_dir_relative / 'library'],
                load_error_modules=False,
                static_content_store=contentstore(),
                target_id=lib_key)
        finally:
            shutil.rmtree(extract_dir)

        self.assertEqual(lib_key, library_items[0].location.library_key)
        library = self.store.get_library(lib_key)
        children = [
            self.store.get_item(child).url_name for child in library.children
        ]
        self.assertEqual(len(children), 3)
        self.assertNotIn(test_block.url_name, children)
        self.assertNotIn(test_block2.url_name, children)

        unchanged_lib = self.store.get_library(unchanged_key)
        children = [
            self.store.get_item(child).url_name
            for child in unchanged_lib.children
        ]
        self.assertEqual(len(children), 2)
        self.assertIn(test_block3.url_name, children)
        self.assertIn(test_block4.url_name, children)
コード例 #52
0
    def test_end_to_end(self):
        """
        Test the happy path of the backfill command without any mocking.
        """
        # org_A: already existing, with courses and a library.
        org_a = add_organization({"short_name": "org_A", "name": "Org A"})
        course_a1_key = CourseOverviewFactory(org="org_A", run="1").id
        CourseOverviewFactory(org="org_A", run="2")
        LibraryFactory(org="org_A")

        # Write linkage for org_a->course_a1.
        # (Linkage for org_a->course_a2 is purposefully left out here;
        # it should be created by the backfill).
        add_organization_course(org_a, course_a1_key)

        # org_B: already existing, but has no content.
        add_organization({"short_name": "org_B", "name": "Org B"})

        # org_C: has a couple courses; should be created.
        CourseOverviewFactory(org="org_C", run="1")
        CourseOverviewFactory(org="org_C", run="2")

        # org_D: has both a course and a library; should be created.
        CourseOverviewFactory(org="org_D", run="1")
        LibraryFactory(org="org_D")

        # org_E: just has a library; should be created.
        LibraryFactory(org="org_E")

        # Confirm starting condition:
        # Only orgs are org_A and org_B, and only linkage is org_a->course_a1.
        assert set(org["short_name"]
                   for org in get_organizations()) == {"org_A", "org_B"}
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_A'))) == 1
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_B'))) == 0

        # Run the backfill.
        call_command("backfill_orgs_and_org_courses", "--apply")

        # Confirm ending condition:
        # All five orgs present. Each org a has expected number of org-course linkages.
        assert set(org["short_name"] for org in get_organizations()) == {
            "org_A", "org_B", "org_C", "org_D", "org_E"
        }
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_A'))) == 2
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_B'))) == 0
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_C'))) == 2
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_D'))) == 1
        assert len(
            get_organization_courses(
                get_organization_by_short_name('org_E'))) == 0
コード例 #53
0
    def test_end_to_end(self, run_type):
        """
        Test the happy path of the backfill command without any mocking.
        """
        # org_A: already existing, with courses and a library.
        org_a = add_organization({"short_name": "org_A", "name": "Org A"})
        course_a1_key = CourseOverviewFactory(org="org_A", run="1").id
        CourseOverviewFactory(org="org_A", run="2")
        LibraryFactory(org="org_A")

        # Write linkage for org_a->course_a1.
        # (Linkage for org_a->course_a2 is purposefully left out here;
        # it should be created by the backfill).
        add_organization_course(org_a, course_a1_key)

        # org_B: already existing, but has no content.
        add_organization({"short_name": "org_B", "name": "Org B"})

        # org_C: has a few courses; should be created.
        CourseOverviewFactory(org="org_C", run="1")
        CourseOverviewFactory(org="org_C", run="2")
        # Include an Old Mongo Modulestore -style deprecated course key.
        # This can be safely removed when Old Mongo Modulestore support is
        # removed.
        CourseOverviewFactory(
            id=CourseLocator.from_string("org_C/toy/3"),
            org="org_C",
            run="3",
        )

        # org_D: has both a course and a library; should be created.
        CourseOverviewFactory(org="org_D", run="1")
        LibraryFactory(org="org_D")

        # org_E: just has a library; should be created.
        LibraryFactory(org="org_E")

        # Confirm starting condition:
        # Only orgs are org_A and org_B, and only linkage is org_a->course_a1.
        assert set(
            org["short_name"] for org in get_organizations()
        ) == {
            "org_A", "org_B"
        }
        assert len(get_organization_courses(get_organization_by_short_name('org_A'))) == 1
        assert len(get_organization_courses(get_organization_by_short_name('org_B'))) == 0

        # Run the backfill.
        call_command("backfill_orgs_and_org_courses", run_type)

        if run_type == "--dry":
            # Confirm ending conditions are the same as the starting conditions.
            assert set(
                org["short_name"] for org in get_organizations()
            ) == {
                "org_A", "org_B"
            }
            assert len(get_organization_courses(get_organization_by_short_name('org_A'))) == 1
            assert len(get_organization_courses(get_organization_by_short_name('org_B'))) == 0
        else:
            # Confirm ending condition:
            # All five orgs present. Each org a has expected number of org-course linkages.
            assert set(
                org["short_name"] for org in get_organizations()
            ) == {
                "org_A", "org_B", "org_C", "org_D", "org_E"
            }
            assert len(get_organization_courses(get_organization_by_short_name('org_A'))) == 2
            assert len(get_organization_courses(get_organization_by_short_name('org_B'))) == 0
            assert len(get_organization_courses(get_organization_by_short_name('org_C'))) == 3
            assert len(get_organization_courses(get_organization_by_short_name('org_D'))) == 1
            assert len(get_organization_courses(get_organization_by_short_name('org_E'))) == 0
コード例 #54
0
 def test_get_library_keys(self):
     """ Test get_library_keys() """
     libraries = [LibraryFactory.create(modulestore=self.store) for _ in range(3)]
     lib_keys_expected = {lib.location.library_key for lib in libraries}
     lib_keys_actual = set(self.store.get_library_keys())
     assert lib_keys_expected == lib_keys_actual
コード例 #55
0
ファイル: test_services.py プロジェクト: yrchen/edx-platform
    def test_vertical_completion_with_library_content(self):
        library = LibraryFactory.create(modulestore=self.store)
        ItemFactory.create(parent=library,
                           category='problem',
                           publish_item=False,
                           user_id=self.user.id)
        ItemFactory.create(parent=library,
                           category='problem',
                           publish_item=False,
                           user_id=self.user.id)
        ItemFactory.create(parent=library,
                           category='problem',
                           publish_item=False,
                           user_id=self.user.id)
        # Create a new vertical to hold the library content block
        # It is very important that we use parent_location=self.sequence.location (and not parent=self.sequence), since
        # sequence is a class attribute and passing it by value will update its .children=[] which will then leak into
        # other tests and cause errors if the children no longer exist.
        lib_vertical = ItemFactory.create(
            parent_location=self.sequence.location,
            category='vertical',
            publish_item=False,
        )
        library_content_block = ItemFactory.create(
            parent=lib_vertical,
            category='library_content',
            max_count=1,
            source_library_id=str(library.location.library_key),
            user_id=self.user.id,
        )
        library_content_block.refresh_children()
        lib_vertical = self.store.get_item(lib_vertical.location)
        self._bind_course_module(lib_vertical)
        # We need to refetch the library_content_block to retrieve the
        # fresh version from the call to get_item for lib_vertical
        library_content_block = [
            child for child in lib_vertical.get_children()
            if child.scope_ids.block_type == 'library_content'
        ][0]

        ## Ensure the library_content_block is properly set up
        # This is needed so we can call get_child_descriptors
        self._bind_course_module(library_content_block)
        # Make sure the runtime knows that the block's children vary per-user:
        assert library_content_block.has_dynamic_children()
        assert len(library_content_block.children) == 3
        # Check how many children each user will see:
        assert len(library_content_block.get_child_descriptors()) == 1

        # No problems are complete yet
        assert not self.completion_service.vertical_is_complete(lib_vertical)

        for block_key in self.block_keys:
            BlockCompletion.objects.submit_completion(user=self.user,
                                                      block_key=block_key,
                                                      completion=1.0)
        # Library content problems aren't complete yet
        assert not self.completion_service.vertical_is_complete(lib_vertical)

        for child in library_content_block.get_child_descriptors():
            BlockCompletion.objects.submit_completion(
                user=self.user,
                block_key=child.scope_ids.usage_id,
                completion=1.0)
        assert self.completion_service.vertical_is_complete(lib_vertical)