Commit 08c5f955 by Peter Fogg

Unstyled prototype for new list editor design.

parent f317244a
......@@ -22,3 +22,17 @@ def set_show_captions(step, setting):
world.wait_for(lambda _driver: world.css_visible('a.save-button'))
world.browser.select('Show Captions', setting)
world.css_click('a.save-button')
@step('I see the correct videoalpha settings and default values$')
def correct_videoalpha_settings(_step):
world.verify_all_setting_entries([['Display Name', 'Video Alpha', False],
['Download Track', '', False],
['Download Video', '', False],
['HTML5 Subtitles', '', False],
['Show Captions', 'True', False],
['Video Sources', '', False],
['Youtube ID', 'OEoXaMPEzfM', False],
['Youtube ID for .75x speed', '', False],
['Youtube ID for 1.25x speed', '', False],
['Youtube ID for 1.5x speed', '', False]])
......@@ -22,3 +22,30 @@ Feature: Video Component
Given I have created a Video component
And I have toggled captions
Then when I view the video it does show the captions
Scenario: Autoplay is disabled in Studio for Video Alpha
Given I have created a Video Alpha component
Then when I view the videoalpha it does not have autoplay enabled
Scenario: User can view Video Alpha 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 Video Alpha 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: Video Alpha captions are hidden when "show captions" is false
Given I have created a Video Alpha component
And I have set "show captions" to False
Then when I view the video it does not show the captions
@skip
Scenario: Video Alpha captions are shown when "show captions" is true
Given I have created a Video Alpha component
And I have set "show captions" to True
Then when I view the video it does show the captions
......@@ -5,9 +5,9 @@ from lettuce import world, step
############### ACTIONS ####################
@step('when I view the video it does not have autoplay enabled')
def does_not_autoplay(_step):
assert world.css_find('.video')[0]['data-autoplay'] == 'False'
@step('when I view the (.*) it does not have autoplay enabled')
def does_not_autoplay(_step, video_type):
assert world.css_find('.%s' % video_type)[0]['data-autoplay'] == 'False'
assert world.css_has_class('.video_control', 'play')
......
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')
......@@ -334,3 +334,13 @@ describe "Test Metadata Editor", ->
it "has an update model method", ->
assertUpdateModel(@listView, null, ['a new value'])
it "can add an entry", ->
expect(@listView.model.get('value').length).toEqual(2)
@listView.$el.find('.setting-add').click()
expect(@listView.$el.find('input.input').length).toEqual(3)
it "can remove an entry", ->
expect(@listView.model.get('value').length).toEqual(2)
@listView.$el.find('.setting-remove').first().click()
expect(@listView.model.get('value').length).toEqual(1)
......@@ -319,17 +319,46 @@ CMS.Views.Metadata.List = CMS.Views.Metadata.AbstractEditor.extend({
events : {
"click .setting-clear" : "clear",
"keypress .setting-input" : "showClearButton",
"change input" : "updateModel"
"change input" : "updateModel",
"click .setting-add" : "addEntry",
"click .setting-remove" : "removeEntry"
},
templateName: "metadata-list-entry",
getValueFromEditor: function () {
return _.map(this.$el.find('#' + this.uniqueId).val().split(/,/),
function (url) { return url.trim(); });
return _.map(
this.$el.find('li input'),
function (ele) { return ele.value.trim(); }
).filter(_.identity);
},
setValueInEditor: function (value) {
this.$el.find('.input').val(value.join(', '));
var list = this.$el.find('ol');
list.empty();
_.each(value, function(ele, index) {
var template = _.template(
'<li>' +
'<input class="input" value="<%= ele %>">' +
'<a href="#" class="setting-remove" data-index="<%= index %>">remove</a>' +
'</li>'
);
list.append($(template({'ele': ele, 'index': index})));
});
},
addEntry: function(event) {
event.preventDefault();
// We don't call updateModel here since it's bound to the
// change event
var list = this.model.get('value') || [];
this.setValueInEditor(list.concat(['']))
},
removeEntry: function(event) {
event.preventDefault();
var entry = $(event.currentTarget).siblings().val();
this.setValueInEditor(_.without(this.model.get('value'), entry));
this.updateModel();
}
});
<div class="wrapper-comp-setting">
<label class="label setting-label" for="<%= uniqueId %>"><%= model.get('display_name')%></label>
<input class="input setting-input" type="text" id="<%= uniqueId %>" value='<%= model.get("value") %>'/>
<div id="<%= uniqueId %>" class="setting-list-wrapper">
<ol class="setting-input" type="text"></ol>
</div>
<a href="#" class="setting-add">add</a>
<button class="action setting-clear inactive" type="button" name="setting-clear" value="<%= gettext("Clear") %>" data-tooltip="<%= gettext("Clear") %>">
<i class="icon-undo"></i><span class="sr">"<%= gettext("Clear Value") %>"</span>
</button>
......
# -*- coding: utf-8 -*-
#pylint: disable=W0212
"""Test for Video Alpha Xmodule functional logic.
These tests data readed from xml or from mongo.
These test data read from xml, not from mongo.
we have a ModuleStoreTestCase class defined in
We have a ModuleStoreTestCase class defined in
common/lib/xmodule/xmodule/modulestore/tests/django_utils.py. You can
search for usages of this in the cms and lms tests for examples. You use
this so that it will do things like point the modulestore setting to mongo,
......@@ -238,7 +238,7 @@ class VideoAlphaDescriptorImportTestCase(unittest.TestCase):
xml_data = '<videoalpha></videoalpha>'
output = VideoAlphaDescriptor.from_xml(xml_data, module_system)
self.assertEquals(output.youtube_id_0_75, '')
self.assertEquals(output.youtube_id_1_0, '')
self.assertEquals(output.youtube_id_1_0, 'OEoXaMPEzfM')
self.assertEquals(output.youtube_id_1_25, '')
self.assertEquals(output.youtube_id_1_5, '')
self.assertEquals(output.show_captions, True)
......@@ -344,6 +344,6 @@ class VideoAlphaExportTestCase(unittest.TestCase):
desc = VideoAlphaDescriptor(module_system, {'location': location})
xml = desc.export_to_xml(None)
expected = '<videoalpha display_name="Video Alpha" show_captions="true"/>\n'
expected = '<videoalpha display_name="Video Alpha" youtube="1.00:OEoXaMPEzfM" show_captions="true"/>\n'
self.assertEquals(expected, xml)
......@@ -36,7 +36,7 @@ log = logging.getLogger(__name__)
class VideoAlphaFields(object):
"""Fields for `VideoAlphaModule` and `VideoAlphaDescriptor`."""
display_name = String(
display_name="Display Name", help="Display name for this module",
display_name="Display Name", help="Display name for this module.",
default="Video Alpha",
scope=Scope.settings
)
......@@ -51,28 +51,27 @@ class VideoAlphaFields(object):
scope=Scope.settings,
default=True
)
# TODO (pfogg): Do we want to show these to the user if HTML5 sources are preferred?
youtube_id_1_0 = String(
help="This is the Youtube ID reference for the normal speed video.",
display_name="Default Speed",
display_name="Youtube ID",
scope=Scope.settings,
default=""
default="OEoXaMPEzfM"
)
youtube_id_0_75 = String(
help="The Youtube ID for the .75x speed video.",
display_name="Speed: .75x",
display_name="Youtube ID for .75x speed",
scope=Scope.settings,
default=""
)
youtube_id_1_25 = String(
help="The Youtube ID for the 1.25x speed video.",
display_name="Speed: 1.25x",
display_name="Youtube ID for 1.25x speed",
scope=Scope.settings,
default=""
)
youtube_id_1_5 = String(
help="The Youtube ID for the 1.5x speed video.",
display_name="Speed: 1.5x",
display_name="Youtube ID for 1.5x speed",
scope=Scope.settings,
default=""
)
......@@ -95,7 +94,7 @@ class VideoAlphaFields(object):
default=""
)
html5_sources = List(
help="A comma-separated list of filenames to be used with HTML5 video.",
help="A list of filenames to be used with HTML5 video.",
display_name="Video Sources",
scope=Scope.settings,
default=[]
......@@ -205,6 +204,8 @@ class VideoAlphaDescriptor(VideoAlphaFields, TabsEditingDescriptor, RawDescripto
def __init__(self, *args, **kwargs):
super(VideoAlphaDescriptor, self).__init__(*args, **kwargs)
# For backwards compatibility -- if we've got XML data, parse
# it out and set the metadata fields
if self.data:
model_data = VideoAlphaDescriptor._parse_video_xml(self.data)
self._model_data.update(model_data)
......@@ -213,9 +214,7 @@ class VideoAlphaDescriptor(VideoAlphaFields, TabsEditingDescriptor, RawDescripto
@property
def non_editable_metadata_fields(self):
non_editable_fields = super(TabsEditingDescriptor, self).non_editable_metadata_fields
non_editable_fields.extend([VideoAlphaFields.start_time,
VideoAlphaFields.end_time])
return non_editable_fields
return non_editable_fields + [VideoAlphaFields.start_time, VideoAlphaFields.end_time]
@classmethod
def from_xml(cls, xml_data, system, org=None, course=None):
......
......@@ -46,10 +46,10 @@ class TestVideo(BaseTestXmodule):
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'
'main': 'example.mp4',
'mp4': 'example.mp4',
'webm': 'example.webm',
'ogv': 'example.ogv'
}
expected_context = {
......@@ -79,9 +79,9 @@ class TestVideoNonYouTube(TestVideo):
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"/>
<source src=".../mit-3091x/M-3091X-FA12-L21-3_100.webm"/>
<source src=".../mit-3091x/M-3091X-FA12-L21-3_100.ogv"/>
<source src="example.mp4"/>
<source src="example.webm"/>
<source src="example.ogv"/>
</videoalpha>
"""
MODEL_DATA = {
......@@ -93,10 +93,10 @@ class TestVideoNonYouTube(TestVideo):
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'
u'main': u'example.mp4',
u'mp4': u'example.mp4',
u'webm': u'example.webm',
u'ogv': u'example.ogv'
}
context = self.item_module.get_html()
......@@ -112,7 +112,7 @@ class TestVideoNonYouTube(TestVideo):
'start': 3603.0,
'sub': 'a_sub_file.srt.sjson',
'track': '',
'youtube_streams': '',
'youtube_streams': '1.00:OEoXaMPEzfM',
'autoplay': settings.MITX_FEATURES.get('AUTOPLAY_VIDEOS', True)
}
......
# -*- coding: utf-8 -*-
"""Test for VideoAlpha Xmodule functional logic.
These tests data readed from xml, not from mongo.
These test data read from xml, not from mongo.
We have a ModuleStoreTestCase class defined in
common/lib/xmodule/xmodule/modulestore/tests/django_utils.py.
......@@ -30,9 +30,9 @@ SOURCE_XML = """
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"/>
<source src=".../mit-3091x/M-3091X-FA12-L21-3_100.webm"/>
<source src=".../mit-3091x/M-3091X-FA12-L21-3_100.ogv"/>
<source src="example.mp4"/>
<source src="example.webm"/>
<source src="example.ogv"/>
</videoalpha>
"""
......@@ -72,10 +72,10 @@ class VideoAlphaModuleUnitTest(unittest.TestCase):
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',
'main': 'example.mp4',
'mp4': 'example.mp4',
'webm': 'example.webm',
'ogv': 'example.ogv'
}
expected_context = {
......
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