Commit f317244a by Peter Fogg

Convert Video Alpha to metadata-only.

parent 74b81527
......@@ -42,6 +42,9 @@ Common: Add a manage.py that knows about edx-platform specific settings and proj
Common: Added *experimental* support for jsinput type.
Studio: Remove XML from HTML5 video component editor. All settings are
moved to be edited as metadata.
Common: Added setting to specify Celery Broker vhost
Common: Utilize new XBlock bulk save API in LMS and CMS.
......
......@@ -228,6 +228,26 @@ def i_created_a_video_component(step):
)
@step('I have created a Video Alpha component$')
def i_created_video_alpha(step):
step.given('I have enabled the videoalpha advanced module')
world.css_click('a.course-link')
step.given('I have added a new subsection')
step.given('I expand the first section')
world.css_click('a.new-unit-item')
world.css_click('.large-advanced-icon')
world.click_component_from_menu('videoalpha', None, '.xmodule_VideoAlphaModule')
@step('I have enabled the (.*) advanced module$')
def i_enabled_the_advanced_module(step, module):
step.given('I have opened a new course section in Studio')
world.css_click('.nav-course-settings')
world.css_click('.nav-course-settings-advanced')
type_in_codemirror(0, '["%s"]' % module)
press_the_notification_button(step, 'Save')
@step('I have clicked the new unit button')
def open_new_unit(step):
step.given('I have opened a new course section in Studio')
......
Feature: Video Alpha Component Editor
As a course author, I want to be able to create videoalpha components.
Scenario: User can view metadata
Given I have created a Video Alpha component
And I edit and select Settings
Then I see the correct videoalpha settings and default values
Scenario: User can modify display name
Given I have created a Video Alpha component
And I edit and select Settings
Then I can modify the display name
And my display name change is persisted on save
@skip
Scenario: Captions are hidden when "show captions" is false
Given I have created a Video component
And I have set "show captions" to False
Then when I view the video it does not show the captions
@skip
Scenario: Captions are shown when "show captions" is true
Given I have created a Video component
And I have set "show captions" to True
Then when I view the video it does show the captions
# disable missing docstring
# pylint: disable=C0111
from lettuce import world, step
@step('I see the correct videoalpha settings and default values$')
def correct_videoalpha_settings(_step):
world.verify_all_setting_entries([['Default Speed', '', False],
['Display Name', 'Video Alpha', False],
['Download Track', '', False],
['Download Video', '', False],
['HTML5 Subtitles', '', False],
['Show Captions', 'True', False],
['Speed: .75x', '', False],
['Speed: 1.25x', '', False],
['Speed: 1.5x', '', False],
['Video Sources', '', False]])
Feature: Video Alpha Component
As a course author, I want to be able to view my created videos in Studio.
Scenario: Autoplay is disabled in Studio
Given I have created a Video Alpha component
Then when I view the video alpha it does not have autoplay enabled
# disable missing docstring
# pylint: disable=C0111
from lettuce import world, step
@step('when I view the video alpha it does not have autoplay enabled')
def does_not_autoplay(_step):
assert world.css_find('.videoalpha')[0]['data-autoplay'] == 'False'
assert world.css_has_class('.video_control', 'play')
......@@ -9,7 +9,7 @@
% endfor
</ul>
</div>
<div class="${'tabs-wrapper' if (len(tabs) != 1) else 'editor-single-tab' }">
<div class="tabs-wrapper">
% for tab in tabs:
<div class="component-tab ${'is-inactive' if not tab.get('current', False) else ''}" id="tab-${html_id}-${loop.index}" >
<%include file="${tab['template']}" args="tabName=tab['name']"/>
......
......@@ -20,5 +20,9 @@
<%static:include path="js/metadata-option-entry.underscore" />
</script>
<script id="metadata-list-entry" type="text/template">
<%static:include path="js/metadata-list-entry.underscore" />
</script>
<div class="wrapper-comp-settings metadata_edit" id="settings-tab" data-metadata='${json.dumps(editable_metadata_fields) | h}'/>
......@@ -81,12 +81,16 @@ class BaseTestXmodule(ModuleStoreTestCase):
# Allow us to assert that the template was called in the same way from
# different code paths while maintaining the type returned by render_template
self.runtime.render_template = lambda template, context: u'{!r}, {!r}'.format(template, sorted(context.items()))
model_data = {'location': self.item_descriptor.location}
model_data.update(self.MODEL_DATA)
self.item_module = self.item_descriptor.module_class(
self.runtime, self.item_descriptor, model_data
self.runtime,
self.item_descriptor,
model_data
)
self.item_url = Location(self.item_module.location).url()
# login all users for acces to Xmodule
......
......@@ -4,6 +4,7 @@
from . import BaseTestXmodule
from .test_videoalpha_xml import SOURCE_XML
from django.conf import settings
from xmodule.videoalpha_module import _create_youtube_string
class TestVideo(BaseTestXmodule):
......@@ -15,6 +16,14 @@ class TestVideo(BaseTestXmodule):
'data': DATA
}
def setUp(self):
# Since the VideoAlphaDescriptor changes `self._model_data`,
# we need to instantiate `self.item_module` through
# `self.item_descriptor` rather than directly constructing it
super(TestVideo, self).setUp()
self.item_module = self.item_descriptor.xmodule(self.runtime)
self.item_module.runtime.render_template = lambda template, context: context
def test_handle_ajax_dispatch(self):
responses = {
user.username: self.clients[user.username].post(
......@@ -34,22 +43,31 @@ class TestVideo(BaseTestXmodule):
def test_videoalpha_constructor(self):
"""Make sure that all parameters extracted correclty from xml"""
fragment = self.runtime.render(self.item_module, None, 'student_view')
context = self.item_module.get_html()
sources = {
'main': '.../mit-3091x/M-3091X-FA12-L21-3_100.mp4',
'mp4': '.../mit-3091x/M-3091X-FA12-L21-3_100.mp4',
'webm': '.../mit-3091x/M-3091X-FA12-L21-3_100.webm',
'ogv': '.../mit-3091x/M-3091X-FA12-L21-3_100.ogv'
}
expected_context = {
'data_dir': getattr(self, 'data_dir', None),
'caption_asset_path': '/c4x/MITx/999/asset/subs_',
'show_captions': self.item_module.show_captions,
'display_name': self.item_module.display_name_with_default,
'end': self.item_module.end_time,
'show_captions': True,
'display_name': 'A Name',
'end': 3610.0,
'id': self.item_module.location.html_id(),
'sources': self.item_module.sources,
'start': self.item_module.start_time,
'sub': self.item_module.sub,
'track': self.item_module.track,
'youtube_streams': self.item_module.youtube_streams,
'sources': sources,
'start': 3603.0,
'sub': 'a_sub_file.srt.sjson',
'track': '',
'youtube_streams': _create_youtube_string(self.item_module),
'autoplay': settings.MITX_FEATURES.get('AUTOPLAY_VIDEOS', True)
}
self.assertEqual(fragment.content, self.runtime.render_template('videoalpha.html', expected_context))
self.assertEqual(context, expected_context)
class TestVideoNonYouTube(TestVideo):
......@@ -57,9 +75,8 @@ class TestVideoNonYouTube(TestVideo):
DATA = """
<videoalpha show_captions="true"
data_dir=""
caption_asset_path=""
autoplay="true"
display_name="A Name"
sub="a_sub_file.srt.sjson"
start_time="01:00:03" end_time="01:00:10"
>
<source src=".../mit-3091x/M-3091X-FA12-L21-3_100.mp4"/>
......@@ -75,20 +92,28 @@ class TestVideoNonYouTube(TestVideo):
"""Make sure that if the 'youtube' attribute is omitted in XML, then
the template generates an empty string for the YouTube streams.
"""
sources = {
u'main': u'.../mit-3091x/M-3091X-FA12-L21-3_100.mp4',
u'mp4': u'.../mit-3091x/M-3091X-FA12-L21-3_100.mp4',
u'webm': u'.../mit-3091x/M-3091X-FA12-L21-3_100.webm',
u'ogv': u'.../mit-3091x/M-3091X-FA12-L21-3_100.ogv'
}
context = self.item_module.get_html()
fragment = self.runtime.render(self.item_module, None, 'student_view')
expected_context = {
'data_dir': getattr(self, 'data_dir', None),
'caption_asset_path': '/c4x/MITx/999/asset/subs_',
'show_captions': self.item_module.show_captions,
'display_name': self.item_module.display_name_with_default,
'end': self.item_module.end_time,
'show_captions': True,
'display_name': 'A Name',
'end': 3610.0,
'id': self.item_module.location.html_id(),
'sources': self.item_module.sources,
'start': self.item_module.start_time,
'sub': self.item_module.sub,
'track': self.item_module.track,
'sources': sources,
'start': 3603.0,
'sub': 'a_sub_file.srt.sjson',
'track': '',
'youtube_streams': '',
'autoplay': settings.MITX_FEATURES.get('AUTOPLAY_VIDEOS', True)
}
self.assertEqual(fragment.content, self.runtime.render_template('videoalpha.html', expected_context))
self.assertEqual(context, expected_context)
......@@ -15,23 +15,19 @@ course, section, subsection, unit, etc.
import json
import unittest
from mock import Mock
from lxml import etree
from django.conf import settings
from xmodule.videoalpha_module import VideoAlphaDescriptor, VideoAlphaModule
from xmodule.videoalpha_module import VideoAlphaDescriptor, _create_youtube_string
from xmodule.modulestore import Location
from xmodule.tests import get_test_system
from xmodule.tests import LogicTest
SOURCE_XML = """
<videoalpha show_captions="true"
display_name="A Name"
youtube="0.75:jNCf2gIqpeE,1.0:ZwkTiUPN0mg,1.25:rsq9auxASqI,1.50:kMyNdzVHHgg"
data_dir=""
caption_asset_path=""
autoplay="true"
sub="a_sub_file.srt.sjson"
start_time="01:00:03" end_time="01:00:10"
>
<source src=".../mit-3091x/M-3091X-FA12-L21-3_100.mp4"/>
......@@ -54,74 +50,53 @@ class VideoAlphaFactory(object):
"""Method return VideoAlpha Xmodule instance."""
location = Location(["i4x", "edX", "videoalpha", "default",
"SampleProblem1"])
model_data = {'data': VideoAlphaFactory.sample_problem_xml_youtube}
descriptor = Mock(weight="1")
model_data = {'data': VideoAlphaFactory.sample_problem_xml_youtube,
'location': location}
system = get_test_system()
system.render_template = lambda template, context: context
VideoAlphaModule.location = location
module = VideoAlphaModule(system, descriptor, model_data)
return module
class VideoAlphaModuleTest(LogicTest):
"""Tests for logic of VideoAlpha Xmodule."""
descriptor_class = VideoAlphaDescriptor
raw_model_data = {
'data': '<videoalpha />'
}
def test_get_timeframe_no_parameters(self):
xmltree = etree.fromstring('<videoalpha>test</videoalpha>')
output = self.xmodule.get_timeframe(xmltree)
self.assertEqual(output, ('', ''))
descriptor = VideoAlphaDescriptor(system, model_data)
def test_get_timeframe_with_one_parameter(self):
xmltree = etree.fromstring(
'<videoalpha start_time="00:04:07">test</videoalpha>'
)
output = self.xmodule.get_timeframe(xmltree)
self.assertEqual(output, (247, ''))
module = descriptor.xmodule(system)
def test_get_timeframe_with_two_parameters(self):
xmltree = etree.fromstring(
'''<videoalpha
start_time="00:04:07"
end_time="13:04:39"
>test</videoalpha>'''
)
output = self.xmodule.get_timeframe(xmltree)
self.assertEqual(output, (247, 47079))
return module
class VideoAlphaModuleUnitTest(unittest.TestCase):
"""Unit tests for VideoAlpha Xmodule."""
def test_videoalpha_constructor(self):
def test_videoalpha_get_html(self):
"""Make sure that all parameters extracted correclty from xml"""
module = VideoAlphaFactory.create()
module.runtime.render_template = lambda template, context: u'{!r}, {!r}'.format(template, sorted(context.items()))
module.runtime.render_template = lambda template, context: context
sources = {
'main': '.../mit-3091x/M-3091X-FA12-L21-3_100.mp4',
'mp4': '.../mit-3091x/M-3091X-FA12-L21-3_100.mp4',
'ogv': '.../mit-3091x/M-3091X-FA12-L21-3_100.ogv',
'webm': '.../mit-3091x/M-3091X-FA12-L21-3_100.webm',
}
fragment = module.runtime.render(module, None, 'student_view')
expected_context = {
'caption_asset_path': '/static/subs/',
'sub': module.sub,
'sub': 'a_sub_file.srt.sjson',
'data_dir': getattr(self, 'data_dir', None),
'display_name': module.display_name_with_default,
'end': module.end_time,
'start': module.start_time,
'display_name': 'A Name',
'end': 3610.0,
'start': 3603.0,
'id': module.location.html_id(),
'show_captions': module.show_captions,
'sources': module.sources,
'youtube_streams': module.youtube_streams,
'track': module.track,
'show_captions': True,
'sources': sources,
'youtube_streams': _create_youtube_string(module),
'track': '',
'autoplay': settings.MITX_FEATURES.get('AUTOPLAY_VIDEOS', True)
}
self.assertEqual(fragment.content, module.runtime.render_template('videoalpha.html', expected_context))
self.assertEqual(module.get_html(), expected_context)
def test_videoalpha_instance_state(self):
module = VideoAlphaFactory.create()
self.assertDictEqual(
json.loads(module.get_instance_state()),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment