Skip to content

Commit

Permalink
Merge pull request #48 from LanghaniKuldeep/Kuldeep/MCKIN-7824-change…
Browse files Browse the repository at this point in the history
…-static-url-description-hotspots

Kuldeep/MCKIN-7824 change static url description hotspots
  • Loading branch information
xitij2000 authored Aug 9, 2018
2 parents c0efef7 + 1293af7 commit 660595b
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 18 deletions.
34 changes: 23 additions & 11 deletions image_explorer/image_explorer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import textwrap
from lxml import etree, html
from urlparse import urljoin
from parsel import Selector

from django.conf import settings

from xblock.core import XBlock
Expand Down Expand Up @@ -155,11 +157,10 @@ def student_view_data(self, context=None):
"""
xmltree = etree.fromstring(self.data)

description = self._get_description(xmltree)
description = self._get_description(xmltree, absolute_urls=True)
background = self._get_background(xmltree)
background['src'] = self._replace_static_from_url(background['src'])
hotspots = self._get_hotspots(xmltree)

hotspots = self._get_hotspots(xmltree, absolute_urls=True)
return {
'description': description,
'background': background,
Expand Down Expand Up @@ -279,24 +280,36 @@ def _make_url_absolute(self, url):
lms_base = '{}://{}'.format(scheme, lms_base)
return urljoin(lms_base, url)

def _inner_content(self, tag):
def _inner_content(self, tag, absolute_urls=False):
"""
Helper met
"""
if tag is not None:
return u''.join(html.tostring(e) for e in tag)
tag_content = u''.join(html.tostring(e) for e in tag)
if absolute_urls:
return self._change_relative_url_to_absolute(tag_content)
else:
return tag_content
return None

def _get_description(self, xmltree):
def _get_description(self, xmltree, absolute_urls=False):
"""
Parse the XML to get the description information
"""
description = xmltree.find('description')
if description is not None:
return self._inner_content(description)
description = self._inner_content(description, absolute_urls)
return description
return None

def _get_hotspots(self, xmltree):
def _change_relative_url_to_absolute(self, text):
if text:
relative_urls = Selector(text=text).css('::attr(href),::attr(src)').extract()
for url in relative_urls:
text = text.replace(url, self._replace_static_from_url(url))
return text

def _get_hotspots(self, xmltree, absolute_urls=False):
"""
Parse the XML to get the hotspot information
"""
Expand All @@ -310,15 +323,14 @@ def _get_hotspots(self, xmltree):
feedback.width = feedback_element.get('width')
feedback.height = feedback_element.get('height')
feedback.max_height = feedback_element.get('max-height')
feedback.header = self._inner_content(feedback_element.find('header'))

feedback.header = self._inner_content(feedback_element.find('header'), absolute_urls)
feedback.side = hotspot_element.get('side', 'auto')

feedback.body = None
body_element = feedback_element.find('body')
if body_element is not None:
feedback.type = 'text'
feedback.body = self._inner_content(body_element)
feedback.body = self._inner_content(body_element, absolute_urls)

feedback.youtube = None
youtube_element = feedback_element.find('youtube')
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-e .
-e git+https://github.com/edx/[email protected]#egg=xblock-utils==1.1.0
lxml==3.0.1
parsel==1.2.0
41 changes: 34 additions & 7 deletions tests/unit/test_image_explorer.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import unittest
from lxml import etree

from parsel import Selector

from django.test import override_settings
from xblock.field_data import DictFieldData

from image_explorer.image_explorer import ImageExplorerBlock
from ..utils import MockRuntime
from ..utils import MockRuntime, patch_static_replace_module


class TestImageExplorerBlock(unittest.TestCase):
"""
Expand All @@ -16,8 +20,11 @@ def setUp(self):
"""
super(TestImageExplorerBlock, self).setUp()
self.runtime = MockRuntime()
self.image_url = 'http://example.com/test.jpg'
self.image_explorer_description = '<p>Test Descrption</p>'
patch_static_replace_module()

self.processed_absolute_url = 'https://lms/a/dynamic/url'
self.image_url = '/static/test.jpg'
self.image_explorer_description = '<p>Test Descrption</p><img src="/static/test.jpg" />'
self.image_explorer_xml = """
<image_explorer schema_version='1'>
<background src='{0}' />
Expand All @@ -26,7 +33,10 @@ def setUp(self):
<hotspot x='370' y='20' item-id='hotspotA'>
<feedback width='300' height='240'>
<header><p>Test Header</p></header>
<body><p>Test Body</p></body>
<body>
<p>Test Body</p>
<img src="/static/test.jpg" />
</body>
</feedback>
</hotspot>
</hotspots>
Expand Down Expand Up @@ -54,17 +64,19 @@ def setUp(self):
DictFieldData(self.image_explorer_data),
None
)
self.image_explorer_block.course_id = 'abc/xyz/123'

@override_settings(ENV_TOKENS={'LMS_BASE': 'lms'}, HTTPS='on')
def test_student_view_data(self):
"""
Test the student_view_data results.
"""
xmltree = etree.fromstring(self.image_explorer_xml)
hotspots = self.image_explorer_block._get_hotspots(xmltree)
hotspots = self.image_explorer_block._get_hotspots(xmltree, absolute_urls=True)
expected_image_explorer_data = {
'description': self.image_explorer_description,
'description': self.image_explorer_block._get_description(xmltree, absolute_urls=True),
'background': {
'src': self.image_url,
'src': self.processed_absolute_url,
'height': None,
'width': None
},
Expand All @@ -74,6 +86,21 @@ def test_student_view_data(self):
student_view_data = self.image_explorer_block.student_view_data()
self.assertEqual(student_view_data, expected_image_explorer_data)

@override_settings(ENV_TOKENS={'LMS_BASE': 'lms'}, HTTPS='on')
def test_static_urls_conversion(self):
"""
Test static urls are processed to absolute if
`absolute_urls` is set
"""
xmltree = etree.fromstring(self.image_explorer_xml)
description = self.image_explorer_block._inner_content(
xmltree.find('description'), absolute_urls=True
)

relative_urls = Selector(text=description).css('::attr(href),::attr(src)').extract()
for url in relative_urls:
self.assertEqual(url, self.processed_absolute_url)

def test_student_view_multi_device_support(self):
"""
Test student_view multi device support is set
Expand Down
20 changes: 20 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Test mocks and helpers
from mock import patch, MagicMock

from xblock.runtime import DictKeyValueStore, KvsFieldData
from xblock.test.tools import TestRuntime

Expand All @@ -10,3 +12,21 @@ class MockRuntime(TestRuntime):
def __init__(self, **kwargs):
field_data = kwargs.get('field_data', KvsFieldData(DictKeyValueStore()))
super(MockRuntime, self).__init__(field_data=field_data)


def patch_static_replace_module():
"""
patchs platform's `static_replace` module as it's
unavailable in test environment
"""
mocked_static_replace = MagicMock()
mocked_static_replace.replace_static_urls = _mocked_replace_static_urls

patch.dict('sys.modules', static_replace=mocked_static_replace).start()


def _mocked_replace_static_urls(*args, **kwargs):
"""
fake `replace_static_urls` method
"""
return '/a/dynamic/url'

0 comments on commit 660595b

Please sign in to comment.