Skip to content
Snippets Groups Projects
Commit 8b16aad3 authored by Shimul Chowdhury's avatar Shimul Chowdhury Committed by Ned Batchelder
Browse files

Add support for html content type

Add test for image

Fix broken tests

Add `html` content type serializer
parent 594ee5fd
No related branches found
No related tags found
No related merge requests found
......@@ -55,9 +55,9 @@ LTI_1P3_ACCESS_TOKEN_SCOPES = [
LTI_DEEP_LINKING_ACCEPTED_TYPES = [
'ltiResourceLink',
'link',
'html',
# TODO: implement "image" support,
# TODO: implement "file" support,
# TODO: implement "html" support,
]
......
......@@ -4,10 +4,12 @@ LTI 1.3/Advantage DRF Related Constants
from .serializers import (
LtiDlLtiResourceLinkSerializer,
LtiDlLinkSerializer,
LtiDlHtmlSerializer,
)
LTI_DL_CONTENT_TYPE_SERIALIZER_MAP = {
"ltiResourceLink": LtiDlLtiResourceLinkSerializer,
"link": LtiDlLinkSerializer,
"html": LtiDlHtmlSerializer,
}
......@@ -330,3 +330,18 @@ class LtiDlLinkSerializer(serializers.Serializer):
embed = LtiDlEmbedPropertySerializer(required=False)
window = LtiDlWindowPropertySerializer(required=False)
iframe = LtiDlIframePropertySerializer(required=False)
# pylint: disable=abstract-method
class LtiDlHtmlSerializer(serializers.Serializer):
"""
LTI Deep Linking - html Serializer.
This serializer implements validation for the HTML Fragment content type.
Reference:
http://www.imsglobal.org/spec/lti-dl/v2p0#html-fragment
"""
html = serializers.CharField()
title = serializers.CharField(max_length=255, required=False)
text = serializers.CharField(required=False)
......@@ -8,6 +8,8 @@
{% for item in content_items %}
{% if item.content_type == 'link' %}
{% include "html/lti-dl/render_link.html" with item=item attrs=item.attributes %}
{% elif item.content_type == 'html' %}
{% include "html/lti-dl/render_html.html" with item=item attrs=item.attributes %}
{% endif %}
{% endfor %}
</body>
......
{% load lti_sanitize %}
{% if attrs.title %}<h2>{{ attrs.title }}</h2>{% endif %}
{% if attrs.text %}<p>{{ attrs.text }}</p>{% endif %}
{{ attrs.html|lti_sanitize }}
"""
Template tags and helper functions for sanitizing html.
"""
import bleach
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
@register.filter()
def lti_sanitize(html):
"""
Sanitize a html fragment with bleach.
"""
allowed_tags = bleach.sanitizer.ALLOWED_TAGS + ['img']
allowed_attributes = dict(bleach.sanitizer.ALLOWED_ATTRIBUTES, **{'img': ['src', 'alt']})
sanitized_html = bleach.clean(html, tags=allowed_tags, attributes=allowed_attributes)
return mark_safe(sanitized_html)
......@@ -328,6 +328,28 @@ class LtiDeepLinkingResponseEndpointTestCase(LtiDeepLinkingTestCase):
content_item, is_valid = test_data
self._content_type_validation_test_helper(content_item, is_valid)
@ddt.data(
({"type": "html"}, False),
({"type": "html", "html": "<p>Hello</p>"}, True),
({
"type": "html",
"html": "<p>Hello</p>",
"text": "This is a link",
"title": "This is a link"
}, True),
)
def test_html_content_type(self, test_data):
"""
Tests validation for `html` content type.
Args:
self
test_data (tuple): 1st element is the datastructure to test,
and the second one indicates wether it's valid or not.
"""
content_item, is_valid = test_data
self._content_type_validation_test_helper(content_item, is_valid)
@ddt.ddt
class LtiDeepLinkingContentEndpointTestCase(LtiDeepLinkingTestCase):
......@@ -455,3 +477,34 @@ class LtiDeepLinkingContentEndpointTestCase(LtiDeepLinkingTestCase):
else:
# otherwise, the link should be on the href of the anchor tag.
self.assertContains(resp, 'href="{}"'.format(test_data['url']))
@ddt.data(
{'url': 'https://example.com', 'html': '<i>Hello World!</i>'},
{'url': 'https://example.com', 'html': '<i>Hello World!</i>', 'title': 'With Title'},
{'url': 'https://example.com', 'html': '<i>Hello World!</i>', 'title': 'With Title', 'text': 'With Text'},
{'url': 'https://example.com', 'html': '<img alt="alt text" src="location_to_image">', 'title': 'With Title'},
)
@patch('lti_consumer.plugin.views.has_block_access', return_value=True)
def test_dl_content_type_html(self, test_data, has_block_access_patcher): # pylint: disable=unused-argument
"""
Test if html content type successfully rendered.
"""
attributes = {'type': LtiDlContentItem.HTML_FRAGMENT}
attributes.update(test_data)
LtiDlContentItem.objects.create(
lti_configuration=self.lti_config,
content_type=LtiDlContentItem.HTML_FRAGMENT,
attributes=attributes
)
resp = self.client.get(self.url)
self.assertEqual(resp.status_code, 200)
if test_data.get('title'):
self.assertContains(resp, '<h2>{}</h2>'.format(test_data['title']))
if test_data.get('text'):
self.assertContains(resp, '<p>{}</p>'.format(test_data['text']))
self.assertContains(resp, test_data['html'])
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment