コード例 #1
0
 def test_replace_jump_to_id_urls_not_called(self):
     """
     Test replace_jump_to_id_urls method called jump_to_id_base_url is not provided.
     """
     replace_url_service = ReplaceURLService(course_id=COURSE_KEY)
     return_text = replace_url_service.replace_urls("text")
     assert not self.mock_replace_jump_to_id_urls.called
コード例 #2
0
 def test_replace_course_urls_called(self):
     """
     Test replace_course_urls method called static_replace_only is passed as False.
     """
     replace_url_service = ReplaceURLService(course_id=COURSE_KEY)
     return_text = replace_url_service.replace_urls("text")
     assert self.mock_replace_course_urls.called
コード例 #3
0
 def test_replace_static_url_only(self):
     """
     Test only replace_static_urls method called when static_replace_only is passed as True.
     """
     replace_url_service = ReplaceURLService(course_id=COURSE_KEY)
     return_text = replace_url_service.replace_urls(
         "text", static_replace_only=True)
     assert self.mock_replace_static_urls.called
     assert not self.mock_replace_course_urls.called
     assert not self.mock_replace_jump_to_id_urls.called
コード例 #4
0
ファイル: shims.py プロジェクト: edx/edx-platform
 def replace_urls(self, html_str):
     """
     Deprecated in favor of the replace_urls service.
     """
     warnings.warn(
         'replace_urls is deprecated. Please use ReplaceURLService instead.',
         DeprecationWarning,
         stacklevel=3,
     )
     return ReplaceURLService(
         xblock=self._active_block,
         lookup_asset_url=self._lookup_asset_url).replace_urls(html_str)
コード例 #5
0
    def service(self, block, service_name):
        """
        Return a service, or None.
        Services are objects implementing arbitrary other interfaces.
        """
        # TODO: Do these declarations actually help with anything? Maybe this check should
        # be removed from here and from XBlock.runtime
        declaration = block.service_declaration(service_name)
        if declaration is None:
            raise NoSuchServiceError(f"Service {service_name!r} was not requested.")
        # Most common service is field-data so check that first:
        if service_name == "field-data":
            if block.scope_ids not in self.block_field_datas:
                try:
                    self.block_field_datas[block.scope_ids] = self._init_field_data_for_block(block)
                except:
                    # Don't try again pointlessly every time another field is accessed
                    self.block_field_datas[block.scope_ids] = None
                    raise
            return self.block_field_datas[block.scope_ids]
        elif service_name == "completion":
            context_key = block.scope_ids.usage_id.context_key
            return CompletionService(user=self.user, context_key=context_key)
        elif service_name == "user":
            return DjangoXBlockUserService(
                self.user,
                # The value should be updated to whether the user is staff in the context when Blockstore runtime adds
                # support for courses.
                user_is_staff=self.user.is_staff,
                anonymous_user_id=self.anonymous_student_id,
            )
        elif service_name == "mako":
            if self.system.student_data_mode == XBlockRuntimeSystem.STUDENT_DATA_EPHEMERAL:
                return MakoService(namespace_prefix='lms.')
            return MakoService()
        elif service_name == "i18n":
            return ModuleI18nService(block=block)
        elif service_name == 'sandbox':
            context_key = block.scope_ids.usage_id.context_key
            return SandboxService(contentstore=contentstore, course_id=context_key)
        elif service_name == 'cache':
            return CacheService(cache)
        elif service_name == 'replace_urls':
            return ReplaceURLService(xblock=block, lookup_asset_url=self._lookup_asset_url)

        # Check if the XBlockRuntimeSystem wants to handle this:
        service = self.system.get_service(block, service_name)
        # Otherwise, fall back to the base implementation which loads services
        # defined in the constructor:
        if service is None:
            service = super().service(block, service_name)
        return service
コード例 #6
0
 def test_replace_course_urls(self, course_id, anchor_tag):
     """
     Verify that the course URL has been replaced.
     """
     course = getattr(self, course_id)
     replace_url_service = ReplaceURLService(course_id=course.id)
     test_replace = replace_urls_wrapper(
         block=course,
         view='baseview',
         frag=Fragment('<a href="/course/id">'),
         context=None,
         replace_url_service=replace_url_service)
     assert isinstance(test_replace, Fragment)
     assert test_replace.content == anchor_tag
コード例 #7
0
 def test_replace_jump_to_id_urls(self, course_id):
     """
     Verify that the jump-to URL has been replaced.
     """
     course = getattr(self, course_id)
     replace_url_service = ReplaceURLService(
         course_id=course.id, jump_to_id_base_url='/base_url/')
     test_replace = replace_urls_wrapper(
         block=course,
         view='baseview',
         frag=Fragment('<a href="/jump_to_id/id">'),
         context=None,
         replace_url_service=replace_url_service)
     assert isinstance(test_replace, Fragment)
     assert test_replace.content == '<a href="/base_url/id">'
コード例 #8
0
ファイル: runtime.py プロジェクト: edx/edx-platform
    def render(self, block, view_name, context=None):
        """
        Render a specific view of an XBlock.
        """
        # Users who aren't logged in are not allowed to view any views other
        # than public_view. They may call any handlers though.
        if (self.user is None or self.user.is_anonymous) and view_name != 'public_view':
            raise PermissionDenied

        # We also need to override this method because some XBlocks in the
        # edx-platform codebase use methods like add_webpack_to_fragment()
        # which create relative URLs (/static/studio/bundles/webpack-foo.js).
        # We want all resource URLs to be absolute, such as is done when
        # local_resource_url() is used.
        fragment = super().render(block, view_name, context)
        needs_fix = False
        for resource in fragment.resources:
            if resource.kind == 'url' and resource.data.startswith('/'):
                needs_fix = True
                break
        if needs_fix:
            log.warning("XBlock %s returned relative resource URLs, which are deprecated", block.scope_ids.usage_id)
            # The Fragment API is mostly immutable, so changing a resource requires this:
            frag_data = fragment.to_dict()
            for resource in frag_data['resources']:
                if resource['kind'] == 'url' and resource['data'].startswith('/'):
                    log.debug("-> Relative resource URL: %s", resource['data'])
                    resource['data'] = get_xblock_app_config().get_site_root_url() + resource['data']
            fragment = Fragment.from_dict(frag_data)

        # Apply any required transforms to the fragment.
        # We could move to doing this in wrap_xblock() and/or use an array of
        # wrapper methods like the ConfigurableFragmentWrapper mixin does.
        fragment = wrap_fragment(
            fragment,
            ReplaceURLService(xblock=block, lookup_asset_url=self._lookup_asset_url).replace_urls(fragment.content)
        )

        return fragment
コード例 #9
0
ファイル: preview.py プロジェクト: angelapper/edx-platform
def _preview_module_system(request, descriptor, field_data):
    """
    Returns a ModuleSystem for the specified descriptor that is specialized for
    rendering module previews.

    request: The active django request
    descriptor: An XModuleDescriptor
    """

    course_id = descriptor.location.course_key
    display_name_only = (descriptor.category == 'static_tab')

    replace_url_service = ReplaceURLService(course_id=course_id)

    wrappers = [
        # This wrapper wraps the module in the template specified above
        partial(wrap_xblock,
                'PreviewRuntime',
                display_name_only=display_name_only,
                usage_id_serializer=str,
                request_token=request_token(request)),

        # This wrapper replaces urls in the output that start with /static
        # with the correct course-specific url for the static content
        partial(replace_urls_wrapper,
                replace_url_service=replace_url_service,
                static_replace_only=True),
        _studio_wrap_xblock,
    ]

    wrappers_asides = [
        partial(wrap_xblock_aside,
                'PreviewRuntime',
                usage_id_serializer=str,
                request_token=request_token(request))
    ]

    mako_service = MakoService(namespace_prefix='lms.')
    if settings.FEATURES.get("LICENSING", False):
        # stick the license wrapper in front
        wrappers.insert(0, partial(wrap_with_license,
                                   mako_service=mako_service))

    return PreviewModuleSystem(
        static_url=settings.STATIC_URL,
        # TODO (cpennington): Do we want to track how instructors are using the preview problems?
        track_function=lambda event_type, event: None,
        get_module=partial(_load_preview_module, request),
        debug=True,
        mixins=settings.XBLOCK_MIXINS,
        course_id=course_id,

        # Set up functions to modify the fragment produced by student_view
        wrappers=wrappers,
        wrappers_asides=wrappers_asides,
        error_descriptor_class=ErrorBlock,
        # Get the raw DescriptorSystem, not the CombinedSystem
        descriptor_runtime=descriptor._runtime,  # pylint: disable=protected-access
        services={
            "field-data":
            field_data,
            "i18n":
            ModuleI18nService,
            'mako':
            mako_service,
            "settings":
            SettingsService(),
            "user":
            DjangoXBlockUserService(
                request.user,
                anonymous_user_id='student',
                user_role=get_user_role(request.user, course_id),
            ),
            "partitions":
            StudioPartitionService(course_id=course_id),
            "teams_configuration":
            TeamsConfigurationService(),
            "sandbox":
            SandboxService(contentstore=contentstore, course_id=course_id),
            "cache":
            CacheService(cache),
            'replace_urls':
            replace_url_service
        },
    )