def _get_anonymous_id(self, course_id, xblock_class):
        location = course_id.make_usage_key('dummy_category', 'dummy_name')
        descriptor = Mock(
            spec=xblock_class,
            _field_data=Mock(spec=FieldData),
            location=location,
            static_asset_path=None,
            runtime=Mock(spec=Runtime,
                         resources_fs=None,
                         mixologist=Mock(_mixins=())),
            scope_ids=Mock(spec=ScopeIds),
        )
        # Use the xblock_class's bind_for_student method
        descriptor.bind_for_student = partial(xblock_class.bind_for_student,
                                              descriptor)

        if hasattr(xblock_class, 'module_class'):
            descriptor.module_class = xblock_class.module_class

        return render.get_module_for_descriptor_internal(
            self.user,
            descriptor,
            Mock(spec=FieldDataCache),
            course_id,
            Mock(),  # Track Function
            Mock(),  # XQueue Callback Url Prefix
        ).xmodule_runtime.anonymous_student_id
Exemplo n.º 2
0
    def _get_anonymous_id(self, course_id, xblock_class):
        location = course_id.make_usage_key("dummy_category", "dummy_name")
        descriptor = Mock(
            spec=xblock_class,
            _field_data=Mock(spec=FieldData),
            location=location,
            static_asset_path=None,
            runtime=Mock(spec=Runtime, resources_fs=None, mixologist=Mock(_mixins=())),
            scope_ids=Mock(spec=ScopeIds),
        )
        # Use the xblock_class's bind_for_student method
        descriptor.bind_for_student = partial(xblock_class.bind_for_student, descriptor)

        if hasattr(xblock_class, "module_class"):
            descriptor.module_class = xblock_class.module_class

        return render.get_module_for_descriptor_internal(
            user=self.user,
            descriptor=descriptor,
            field_data_cache=Mock(spec=FieldDataCache),
            course_id=course_id,
            track_function=Mock(),  # Track Function
            xqueue_callback_url_prefix=Mock(),  # XQueue Callback Url Prefix
            request_token="request_token",
        ).xmodule_runtime.anonymous_student_id
Exemplo n.º 3
0
    def _get_anonymous_id(self, course_id, xblock_class):
        location = Location('dummy_org', 'dummy_course', 'dummy_category', 'dummy_name')
        descriptor = Mock(
            spec=xblock_class,
            _field_data=Mock(spec=FieldData),
            location=location,
            static_asset_path=None,
            runtime=Mock(
                spec=Runtime,
                resources_fs=None,
                mixologist=Mock(_mixins=())
            ),
            scope_ids=Mock(spec=ScopeIds),
        )
        # Use the xblock_class's bind_for_student method
        descriptor.bind_for_student = partial(xblock_class.bind_for_student, descriptor)

        if hasattr(xblock_class, 'module_class'):
            descriptor.module_class = xblock_class.module_class

        return render.get_module_for_descriptor_internal(
            self.user,
            descriptor,
            Mock(spec=FieldDataCache),
            course_id,
            Mock(),  # Track Function
            Mock(),  # XQueue Callback Url Prefix
        ).xmodule_runtime.anonymous_student_id
    def _get_anonymous_id(self, course_id, xblock_class):
        location = course_id.make_usage_key('dummy_category', 'dummy_name')
        descriptor = Mock(
            spec=xblock_class,
            _field_data=Mock(spec=FieldData),
            location=location,
            static_asset_path=None,
            _runtime=Mock(
                spec=Runtime,
                resources_fs=None,
                mixologist=Mock(_mixins=(), name='mixologist'),
                name='runtime',
            ),
            scope_ids=Mock(spec=ScopeIds),
            name='descriptor'
        )
        descriptor.runtime = CombinedSystem(descriptor._runtime, None)  # pylint: disable=protected-access
        # Use the xblock_class's bind_for_student method
        descriptor.bind_for_student = partial(xblock_class.bind_for_student, descriptor)

        if hasattr(xblock_class, 'module_class'):
            descriptor.module_class = xblock_class.module_class

        return render.get_module_for_descriptor_internal(
            user=self.user,
            descriptor=descriptor,
            field_data_cache=Mock(spec=FieldDataCache, name='field_data_cache'),
            course_id=course_id,
            track_function=Mock(name='track_function'),  # Track Function
            xqueue_callback_url_prefix=Mock(name='xqueue_callback_url_prefix'),  # XQueue Callback Url Prefix
            request_token='request_token',
        ).xmodule_runtime.anonymous_student_id
Exemplo n.º 5
0
def _get_module_instance_for_task(course_id, student, module_descriptor, xmodule_instance_args=None,
                                  grade_bucket_type=None):
    """
    Fetches a StudentModule instance for a given `course_id`, `student` object, and `module_descriptor`.

    `xmodule_instance_args` is used to provide information for creating a track function and an XQueue callback.
    These are passed, along with `grade_bucket_type`, to get_module_for_descriptor_internal, which sidesteps
    the need for a Request object when instantiating an xmodule instance.
    """
    # reconstitute the problem's corresponding XModule:
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course_id, student, module_descriptor)

    # get request-related tracking information from args passthrough, and supplement with task-specific
    # information:
    request_info = xmodule_instance_args.get('request_info', {}) if xmodule_instance_args is not None else {}
    task_info = {"student": student.username, "task_id": _get_task_id_from_xmodule_args(xmodule_instance_args)}

    def make_track_function():
        '''
        Make a tracking function that logs what happened.

        For insertion into ModuleSystem, and used by CapaModule, which will
        provide the event_type (as string) and event (as dict) as arguments.
        The request_info and task_info (and page) are provided here.
        '''
        return lambda event_type, event: task_track(request_info, task_info, event_type, event, page='x_module_task')

    xqueue_callback_url_prefix = xmodule_instance_args.get('xqueue_callback_url_prefix', '') \
        if xmodule_instance_args is not None else ''

    return get_module_for_descriptor_internal(student, module_descriptor, field_data_cache, course_id,
                                              make_track_function(), xqueue_callback_url_prefix,
                                              grade_bucket_type=grade_bucket_type)
Exemplo n.º 6
0
def _get_module_instance_for_task(course_id, student, module_descriptor, xmodule_instance_args=None,
                                  grade_bucket_type=None):
    """
    Fetches a StudentModule instance for a given `course_id`, `student` object, and `module_descriptor`.

    `xmodule_instance_args` is used to provide information for creating a track function and an XQueue callback.
    These are passed, along with `grade_bucket_type`, to get_module_for_descriptor_internal, which sidesteps
    the need for a Request object when instantiating an xmodule instance.
    """
    # reconstitute the problem's corresponding XModule:
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course_id, student, module_descriptor)

    # get request-related tracking information from args passthrough, and supplement with task-specific
    # information:
    request_info = xmodule_instance_args.get('request_info', {}) if xmodule_instance_args is not None else {}
    task_info = {"student": student.username, "task_id": _get_task_id_from_xmodule_args(xmodule_instance_args)}

    def make_track_function():
        '''
        Make a tracking function that logs what happened.

        For insertion into ModuleSystem, and used by CapaModule, which will
        provide the event_type (as string) and event (as dict) as arguments.
        The request_info and task_info (and page) are provided here.
        '''
        return lambda event_type, event: task_track(request_info, task_info, event_type, event, page='x_module_task')

    xqueue_callback_url_prefix = xmodule_instance_args.get('xqueue_callback_url_prefix', '') \
        if xmodule_instance_args is not None else ''

    return get_module_for_descriptor_internal(student, module_descriptor, field_data_cache, course_id,
                                              make_track_function(), xqueue_callback_url_prefix,
                                              grade_bucket_type=grade_bucket_type)
Exemplo n.º 7
0
    def test_discussion_render_successfully_with_orphan_parent(
            self, default_store):
        """
        Test that discussion xblock render successfully
        if discussion xblock is child of an orphan.
        """
        with self.store.default_store(default_store):
            orphan_sequential = self.store.create_item(self.user.id,
                                                       self.course.id,
                                                       'sequential')

            vertical = self.store.create_child(
                self.user.id,
                orphan_sequential.location,
                'vertical',
                block_id=self.course.location.block_id)

            discussion = self.store.create_child(
                self.user.id,
                vertical.location,
                'discussion',
                block_id=self.course.location.block_id)

            discussion = self.store.get_item(discussion.location)

            root = self.get_root(discussion)
            # Assert that orphan sequential is root of the discussion xblock.
            self.assertEqual(orphan_sequential.location.block_type,
                             root.location.block_type)
            self.assertEqual(orphan_sequential.location.block_id,
                             root.location.block_id)

            # Get xblock bound to a user and a descriptor.
            discussion_xblock = get_module_for_descriptor_internal(
                user=self.user,
                descriptor=discussion,
                student_data=mock.Mock(name='student_data'),
                course_id=self.course.id,
                track_function=mock.Mock(name='track_function'),
                xqueue_callback_url_prefix=mock.Mock(
                    name='xqueue_callback_url_prefix'),
                request_token='request_token',
            )

            fragment = discussion_xblock.render('student_view')
            html = fragment.content

            self.assertIsInstance(discussion_xblock, DiscussionXBlock)
            self.assertIn('data-user-create-comment="false"', html)
            self.assertIn('data-user-create-subcomment="false"', html)
    def test_discussion_render_successfully_with_orphan_parent(
            self, default_store):
        """
        Test that discussion module render successfully
        if discussion module is child of an orphan.
        """
        user = UserFactory.create()
        store = modulestore()
        with store.default_store(default_store):
            course = store.create_course('testX', 'orphan', '123X', user.id)
            orphan_sequential = store.create_item(self.user.id, course.id,
                                                  'sequential')

            vertical = store.create_child(user.id,
                                          orphan_sequential.location,
                                          'vertical',
                                          block_id=course.location.block_id)

            discussion = store.create_child(user.id,
                                            vertical.location,
                                            'discussion',
                                            block_id=course.location.block_id)

            discussion = store.get_item(discussion.location)

            root = self.get_root(discussion)
            # Assert that orphan sequential is root of the discussion module.
            self.assertEqual(orphan_sequential.location.block_type,
                             root.location.block_type)
            self.assertEqual(orphan_sequential.location.block_id,
                             root.location.block_id)

            # Get module system bound to a user and a descriptor.
            discussion_module = get_module_for_descriptor_internal(
                user=user,
                descriptor=discussion,
                student_data=Mock(name='student_data'),
                course_id=course.id,
                track_function=Mock(name='track_function'),
                xqueue_callback_url_prefix=Mock(
                    name='xqueue_callback_url_prefix'),
                request_token='request_token',
            )

            fragment = discussion_module.render('student_view')
            html = fragment.content

            self.assertIsInstance(discussion_module._xmodule, DiscussionModule)  # pylint: disable=protected-access
            self.assertIn('data-user-create-comment="false"', html)
            self.assertIn('data-user-create-subcomment="false"', html)
Exemplo n.º 9
0
            def create_module(descriptor):
                '''creates an XModule instance given a descriptor'''
                with manual_transaction():
                    field_data_cache = FieldDataCache([descriptor], course.id,
                                                      student)

                # don't need tracking/xqueue but we have to pass something
                return get_module_for_descriptor_internal(
                    student, descriptor,
                    field_data_cache,
                    course.id,
                    track_function=noop_track_function,  # dummy
                    xqueue_callback_url_prefix='',  # dummy
                    request_token='')  # dummy
Exemplo n.º 10
0
    def test_discussion_render_successfully_with_orphan_parent(self, default_store):
        """
        Test that discussion module render successfully
        if discussion module is child of an orphan.
        """
        user = UserFactory.create()
        store = modulestore()
        with store.default_store(default_store):
            course = store.create_course('testX', 'orphan', '123X', user.id)
            orphan_sequential = store.create_item(self.user.id, course.id, 'sequential')

            vertical = store.create_child(
                user.id,
                orphan_sequential.location,
                'vertical',
                block_id=course.location.block_id
            )

            discussion = store.create_child(
                user.id,
                vertical.location,
                'discussion',
                block_id=course.location.block_id
            )

            discussion = store.get_item(discussion.location)

            root = self.get_root(discussion)
            # Assert that orphan sequential is root of the discussion module.
            self.assertEqual(orphan_sequential.location.block_type, root.location.block_type)
            self.assertEqual(orphan_sequential.location.block_id, root.location.block_id)

            # Get module system bound to a user and a descriptor.
            discussion_module = get_module_for_descriptor_internal(
                user=user,
                descriptor=discussion,
                student_data=Mock(name='student_data'),
                course_id=course.id,
                track_function=Mock(name='track_function'),
                xqueue_callback_url_prefix=Mock(name='xqueue_callback_url_prefix'),
                request_token='request_token',
            )

            fragment = discussion_module.render('student_view')
            html = fragment.content

            self.assertIsInstance(discussion_module._xmodule, DiscussionModule)     # pylint: disable=protected-access
            self.assertIn('data-user-create-comment="false"', html)
            self.assertIn('data-user-create-subcomment="false"', html)
Exemplo n.º 11
0
    def test_html_with_user(self):
        discussion = get_module_for_descriptor_internal(
            user=self.users[0],
            descriptor=self.item_descriptor,
            student_data=Mock(name='student_data'),
            course_id=self.course.id,
            track_function=Mock(name='track_function'),
            xqueue_callback_url_prefix=Mock(name='xqueue_callback_url_prefix'),
            request_token='request_token',
        )

        fragment = discussion.render('student_view')
        html = fragment.content
        self.assertIn('data-user-create-comment="false"', html)
        self.assertIn('data-user-create-subcomment="false"', html)
    def test_html_with_user(self):
        discussion = get_module_for_descriptor_internal(
            user=self.users[0],
            descriptor=self.item_descriptor,
            student_data=Mock(name='student_data'),
            course_id=self.course.id,
            track_function=Mock(name='track_function'),
            xqueue_callback_url_prefix=Mock(name='xqueue_callback_url_prefix'),
            request_token='request_token',
        )

        fragment = discussion.render('student_view')
        html = fragment.content
        self.assertIn('data-user-create-comment="false"', html)
        self.assertIn('data-user-create-subcomment="false"', html)
    def test_permissions_query_load(self):
        """
        Tests that the permissions queries are cached when rendering numerous discussion XBlocks.
        """
        user = UserFactory()
        course = ToyCourseFactory()
        course_key = course.id
        course_usage_key = self.store.make_course_usage_key(course_key)
        discussions = []

        for counter in range(5):
            discussion_id = 'test_discussion_{}'.format(counter)
            discussions.append(
                ItemFactory.create(
                    parent_location=course_usage_key,
                    category='discussion',
                    discussion_id=discussion_id,
                    discussion_category='Category discussion',
                    discussion_target='Target Discussion',
                ))

        # 2 queries are required to do first discussion xblock render:
        # * django_comment_client_role
        # * lms_xblock_xblockasidesconfig
        # If the query for roles returned a non-empty result set, there would be
        # an additional query against django_comment_client_permission, but there
        # are no roles associated with this test.
        num_queries = 2
        for discussion in discussions:
            discussion_xblock = get_module_for_descriptor_internal(
                user=user,
                descriptor=discussion,
                student_data=mock.Mock(name='student_data'),
                course_id=course.id,
                track_function=mock.Mock(name='track_function'),
                xqueue_callback_url_prefix=mock.Mock(
                    name='xqueue_callback_url_prefix'),
                request_token='request_token',
            )
            with self.assertNumQueries(num_queries):
                fragment = discussion_xblock.render('student_view')

            # Permissions are cached, so no queries required for subsequent renders
            num_queries = 0

            html = fragment.content
            self.assertIn('data-user-create-comment="false"', html)
            self.assertIn('data-user-create-subcomment="false"', html)
    def test_discussion_render_successfully_with_orphan_parent(self, default_store):
        """
        Test that discussion xblock render successfully
        if discussion xblock is child of an orphan.
        """
        with self.store.default_store(default_store):
            orphan_sequential = self.store.create_item(self.user.id, self.course.id, 'sequential')

            vertical = self.store.create_child(
                self.user.id,
                orphan_sequential.location,
                'vertical',
                block_id=self.course.location.block_id
            )

            discussion = self.store.create_child(
                self.user.id,
                vertical.location,
                'discussion',
                block_id=self.course.location.block_id
            )

            discussion = self.store.get_item(discussion.location)

            root = self.get_root(discussion)
            # Assert that orphan sequential is root of the discussion xblock.
            self.assertEqual(orphan_sequential.location.block_type, root.location.block_type)
            self.assertEqual(orphan_sequential.location.block_id, root.location.block_id)

            # Get xblock bound to a user and a descriptor.
            discussion_xblock = get_module_for_descriptor_internal(
                user=self.user,
                descriptor=discussion,
                student_data=mock.Mock(name='student_data'),
                course_id=self.course.id,
                track_function=mock.Mock(name='track_function'),
                xqueue_callback_url_prefix=mock.Mock(name='xqueue_callback_url_prefix'),
                request_token='request_token',
            )

            fragment = discussion_xblock.render('student_view')
            html = fragment.content

            self.assertIsInstance(discussion_xblock, DiscussionXBlock)
            self.assertIn('data-user-create-comment="false"', html)
            self.assertIn('data-user-create-subcomment="false"', html)
    def test_permissions_query_load(self):
        """
        Tests that the permissions queries are cached when rendering numerous discussion XBlocks.
        """
        user = UserFactory.create()
        course = ToyCourseFactory.create()
        course_key = course.id
        course_usage_key = self.store.make_course_usage_key(course_key)
        discussions = []

        for counter in range(5):
            discussion_id = "test_discussion_{}".format(counter)
            discussions.append(
                ItemFactory.create(
                    parent_location=course_usage_key,
                    category="discussion",
                    discussion_id=discussion_id,
                    discussion_category="Category discussion",
                    discussion_target="Target Discussion",
                )
            )

        # 3 queries are required to do first discussion xblock render:
        # * django_comment_client_role
        # * django_comment_client_permission
        # * lms_xblock_xblockasidesconfig
        num_queries = 3
        for discussion in discussions:
            discussion_xblock = get_module_for_descriptor_internal(
                user=user,
                descriptor=discussion,
                student_data=mock.Mock(name="student_data"),
                course_id=course.id,
                track_function=mock.Mock(name="track_function"),
                xqueue_callback_url_prefix=mock.Mock(name="xqueue_callback_url_prefix"),
                request_token="request_token",
            )
            with self.assertNumQueries(num_queries):
                fragment = discussion_xblock.render("student_view")

            # Permissions are cached, so no queries required for subsequent renders
            num_queries = 0

            html = fragment.content
            self.assertIn('data-user-create-comment="false"', html)
            self.assertIn('data-user-create-subcomment="false"', html)
Exemplo n.º 16
0
    def test_html_with_user(self):
        """
        Test rendered DiscussionXBlock permissions.
        """
        discussion_xblock = get_module_for_descriptor_internal(
            user=self.user,
            descriptor=self.discussion,
            student_data=mock.Mock(name='student_data'),
            course_id=self.course.id,
            track_function=mock.Mock(name='track_function'),
            xqueue_callback_url_prefix=mock.Mock(name='xqueue_callback_url_prefix'),
            request_token='request_token',
        )

        fragment = discussion_xblock.render('student_view')
        html = fragment.content
        self.assertIn('data-user-create-comment="false"', html)
        self.assertIn('data-user-create-subcomment="false"', html)