Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
80f38b8f
Commit
80f38b8f
authored
Jun 03, 2013
by
Vasyl Nakvasiuk
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
python tests for videoalpha
parent
048be222
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
225 additions
and
58 deletions
+225
-58
common/lib/xmodule/xmodule/templates/videoalpha/default.yaml
+1
-1
common/lib/xmodule/xmodule/tests/test_logic.py
+12
-37
common/lib/xmodule/xmodule/videoalpha_module.py
+27
-18
lms/djangoapps/courseware/tests/__init__.py
+2
-2
lms/djangoapps/courseware/tests/test_videoalpha_mongo.py
+54
-0
lms/djangoapps/courseware/tests/test_videoalpha_xml.py
+129
-0
No files found.
common/lib/xmodule/xmodule/templates/videoalpha/default.yaml
View file @
80f38b8f
---
metadata
:
display_name
:
Video Alpha
1
display_name
:
Video Alpha
version
:
1
data
:
|
<videoalpha show_captions="true" sub="name_of_file" youtube="0.75:JMD_ifUUfsU,1.0:OEoXaMPEzfM,1.25:AKqURZnYqpk,1.50:DYpADpL7jAY" >
...
...
common/lib/xmodule/xmodule/tests/test_logic.py
View file @
80f38b8f
# -*- coding: utf-8 -*-
# pylint: disable=W0232
"""Test for Xmodule functional logic."""
import
json
import
unittest
from
lxml
import
etree
from
xmodule.poll_module
import
PollDescriptor
from
xmodule.conditional_module
import
ConditionalDescriptor
from
xmodule.word_cloud_module
import
WordCloudDescriptor
from
xmodule.
videoalpha_module
import
VideoAlphaDescriptor
from
xmodule.
tests
import
test_system
class
PostData
:
"""Class which emulate postdata."""
...
...
@@ -17,6 +16,7 @@ class PostData:
self
.
dict_data
=
dict_data
def
getlist
(
self
,
key
):
"""Get data by key from `self.dict_data`."""
return
self
.
dict_data
.
get
(
key
)
...
...
@@ -27,9 +27,10 @@ class LogicTest(unittest.TestCase):
def
setUp
(
self
):
class
EmptyClass
:
"""Empty object."""
pass
self
.
system
=
None
self
.
system
=
test_system
()
self
.
descriptor
=
EmptyClass
()
self
.
xmodule_class
=
self
.
descriptor_class
.
module_class
...
...
@@ -40,10 +41,12 @@ class LogicTest(unittest.TestCase):
)
def
ajax_request
(
self
,
dispatch
,
get
):
"""Call Xmodule.handle_ajax."""
return
json
.
loads
(
self
.
xmodule
.
handle_ajax
(
dispatch
,
get
))
class
PollModuleTest
(
LogicTest
):
"""Logic tests for Poll Xmodule."""
descriptor_class
=
PollDescriptor
raw_model_data
=
{
'poll_answers'
:
{
'Yes'
:
1
,
'Dont_know'
:
0
,
'No'
:
0
},
...
...
@@ -69,6 +72,7 @@ class PollModuleTest(LogicTest):
class
ConditionalModuleTest
(
LogicTest
):
"""Logic tests for Conditional Xmodule."""
descriptor_class
=
ConditionalDescriptor
def
test_ajax_request
(
self
):
...
...
@@ -83,6 +87,7 @@ class ConditionalModuleTest(LogicTest):
class
WordCloudModuleTest
(
LogicTest
):
"""Logic tests for Word Cloud Xmodule."""
descriptor_class
=
WordCloudDescriptor
raw_model_data
=
{
'all_words'
:
{
'cat'
:
10
,
'dog'
:
5
,
'mom'
:
1
,
'dad'
:
2
},
...
...
@@ -91,8 +96,6 @@ class WordCloudModuleTest(LogicTest):
}
def
test_bad_ajax_request
(
self
):
# TODO: move top global test. Formalize all our Xmodule errors.
response
=
self
.
ajax_request
(
'bad_dispatch'
,
{})
self
.
assertDictEqual
(
response
,
{
'status'
:
'fail'
,
...
...
@@ -118,34 +121,6 @@ class WordCloudModuleTest(LogicTest):
{
'text'
:
'cat'
,
'size'
:
12
,
'percent'
:
54.0
}]
)
self
.
assertEqual
(
100.0
,
sum
(
i
[
'percent'
]
for
i
in
response
[
'top_words'
])
)
class
VideoAlphaModuleTest
(
LogicTest
):
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
,
(
''
,
''
))
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
,
''
))
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
))
self
.
assertEqual
(
100.0
,
sum
(
i
[
'percent'
]
for
i
in
response
[
'top_words'
]))
common/lib/xmodule/xmodule/videoalpha_module.py
View file @
80f38b8f
# pylint: disable=W0223
"""VideoAlpha is ungraded Xmodule for support video content.
It's new improved video module, which support additional feature:
- Can play non-YouTube video sources via in-browser HTML5 video player.
- YouTube defaults to HTML5 mode from the start.
- Speed changes in both YouTube and non-YouTube videos happen via
in-browser HTML5 video method (when in HTML5 mode).
- Navigational subtitles can be disabled altogether via an attribute
in XML.
"""
import
json
import
logging
...
...
@@ -21,6 +33,7 @@ log = logging.getLogger(__name__)
class
VideoAlphaFields
(
object
):
"""Fields for `VideoAlphaModule` and `VideoAlphaDescriptor`."""
data
=
String
(
help
=
"XML data for the problem"
,
scope
=
Scope
.
content
)
position
=
Integer
(
help
=
"Current position in the video"
,
scope
=
Scope
.
user_state
,
default
=
0
)
display_name
=
String
(
help
=
"Display name for this module"
,
scope
=
Scope
.
settings
)
...
...
@@ -68,7 +81,7 @@ class VideoAlphaModule(VideoAlphaFields, XModule):
'ogv'
:
self
.
_get_source
(
xmltree
,
[
'ogv'
]),
}
self
.
track
=
self
.
_get_track
(
xmltree
)
self
.
start_time
,
self
.
end_time
=
self
.
_
get_timeframe
(
xmltree
)
self
.
start_time
,
self
.
end_time
=
self
.
get_timeframe
(
xmltree
)
def
_get_source
(
self
,
xmltree
,
exts
=
None
):
"""Find the first valid source, which ends with one of `exts`."""
...
...
@@ -77,7 +90,7 @@ class VideoAlphaModule(VideoAlphaFields, XModule):
return
self
.
_get_first_external
(
xmltree
,
'source'
,
condition
)
def
_get_track
(
self
,
xmltree
):
# find the first valid track
"""Find the first valid track."""
return
self
.
_get_first_external
(
xmltree
,
'track'
)
def
_get_first_external
(
self
,
xmltree
,
tag
,
condition
=
bool
):
...
...
@@ -93,39 +106,33 @@ class VideoAlphaModule(VideoAlphaFields, XModule):
break
return
result
def
_
get_timeframe
(
self
,
xmltree
):
def
get_timeframe
(
self
,
xmltree
):
""" Converts 'start_time' and 'end_time' parameters in video tag to seconds.
If there are no parameters, returns empty string. """
def
parse_time
(
s
):
def
parse_time
(
s
tr_time
):
"""Converts s in '12:34:45' format to seconds. If s is
None, returns empty string"""
if
s
is
None
:
if
s
tr_time
is
None
:
return
''
else
:
x
=
time
.
strptime
(
s
,
'
%
H:
%
M:
%
S'
)
obj_time
=
time
.
strptime
(
str_time
,
'
%
H:
%
M:
%
S'
)
return
datetime
.
timedelta
(
hours
=
x
.
tm_hour
,
minutes
=
x
.
tm_min
,
seconds
=
x
.
tm_sec
hours
=
obj_time
.
tm_hour
,
minutes
=
obj_time
.
tm_min
,
seconds
=
obj_time
.
tm_sec
)
.
total_seconds
()
return
parse_time
(
xmltree
.
get
(
'start_time'
)),
parse_time
(
xmltree
.
get
(
'end_time'
))
def
handle_ajax
(
self
,
dispatch
,
get
):
"""Handle ajax calls to this video.
TODO (vshnayder): This is not being called right now, so the
position is not being saved.
"""
"""This is not being called right now and we raise 404 error."""
log
.
debug
(
u"GET {0}"
.
format
(
get
))
log
.
debug
(
u"DISPATCH {0}"
.
format
(
dispatch
))
if
dispatch
==
'goto_position'
:
self
.
position
=
int
(
float
(
get
[
'position'
]))
log
.
info
(
u"NEW POSITION {0}"
.
format
(
self
.
position
))
return
json
.
dumps
({
'success'
:
True
})
raise
Http404
()
def
get_instance_state
(
self
):
"""Return information about state (position)."""
return
json
.
dumps
({
'position'
:
self
.
position
})
def
get_html
(
self
):
...
...
@@ -143,7 +150,8 @@ class VideoAlphaModule(VideoAlphaFields, XModule):
'sources'
:
self
.
sources
,
'track'
:
self
.
track
,
'display_name'
:
self
.
display_name_with_default
,
# TODO (cpennington): This won't work when we move to data that isn't on the filesystem
# This won't work when we move to data that
# isn't on the filesystem
'data_dir'
:
getattr
(
self
,
'data_dir'
,
None
),
'caption_asset_path'
:
caption_asset_path
,
'show_captions'
:
self
.
show_captions
,
...
...
@@ -154,5 +162,6 @@ class VideoAlphaModule(VideoAlphaFields, XModule):
class
VideoAlphaDescriptor
(
VideoAlphaFields
,
RawDescriptor
):
"""Descriptor for `VideoAlphaModule`."""
module_class
=
VideoAlphaModule
template_dir_name
=
"videoalpha"
lms/djangoapps/courseware/tests/__init__.py
View file @
80f38b8f
...
...
@@ -25,8 +25,8 @@ class BaseTestXmodule(ModuleStoreTestCase):
"""Base class for testing Xmodules with mongo store.
This class prepares course and users for tests:
1. create test course
2. create, enrol and login users for this course
1. create test course
;
2. create, enrol and login users for this course
;
Any xmodule should overwrite only next parameters for test:
1. TEMPLATE_NAME
...
...
lms/djangoapps/courseware/tests/test_videoalpha_mongo.py
0 → 100644
View file @
80f38b8f
# -*- coding: utf-8 -*-
"""Video xmodule tests in mongo."""
from
.
import
BaseTestXmodule
from
.test_videoalpha_xml
import
SOURCE_XML
from
django.conf
import
settings
class
TestVideo
(
BaseTestXmodule
):
"""Integration tests: web client + mongo."""
TEMPLATE_NAME
=
"i4x://edx/templates/videoalpha/Video_Alpha"
DATA
=
SOURCE_XML
MODEL_DATA
=
{
'data'
:
DATA
}
def
test_handle_ajax_dispatch
(
self
):
responses
=
{
user
.
username
:
self
.
clients
[
user
.
username
]
.
post
(
self
.
get_url
(
'whatever'
),
{},
HTTP_X_REQUESTED_WITH
=
'XMLHttpRequest'
)
for
user
in
self
.
users
}
self
.
assertEqual
(
set
([
response
.
status_code
for
_
,
response
in
responses
.
items
()
])
.
pop
(),
404
)
def
test_videoalpha_constructor
(
self
):
"""Make sure that all parameters extracted correclty from xml"""
# `get_html` return only context, cause we
# overwrite `system.render_template`
context
=
self
.
item_module
.
get_html
()
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
,
'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
,
'autoplay'
:
settings
.
MITX_FEATURES
.
get
(
'AUTOPLAY_VIDEOS'
,
True
)
}
self
.
assertDictEqual
(
context
,
expected_context
)
lms/djangoapps/courseware/tests/test_videoalpha_xml.py
0 → 100644
View file @
80f38b8f
# -*- coding: utf-8 -*-
"""Test for VideoAlpha Xmodule functional logic.
These tests data readed from xml, not from mongo.
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, flush the contentstore before and after, load the
templates, etc.
You can then use the CourseFactory and XModuleItemFactory as defined in
common/lib/xmodule/xmodule/modulestore/tests/factories.py to create the
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.modulestore
import
Location
from
xmodule.tests
import
test_system
from
xmodule.tests.test_logic
import
LogicTest
SOURCE_XML
=
"""
<videoalpha show_captions="true"
youtube="0.75:jNCf2gIqpeE,1.0:ZwkTiUPN0mg,1.25:rsq9auxASqI,1.50:kMyNdzVHHgg"
data_dir=""
caption_asset_path=""
autoplay="true"
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"/>
</videoalpha>
"""
class
VideoAlphaFactory
(
object
):
"""A helper class to create videoalpha modules with various parameters
for testing.
"""
# tag that uses youtube videos
sample_problem_xml_youtube
=
SOURCE_XML
@staticmethod
def
create
():
"""Method return VideoAlpha Xmodule instance."""
location
=
Location
([
"i4x"
,
"edX"
,
"videoalpha"
,
"default"
,
"SampleProblem1"
])
model_data
=
{
'data'
:
VideoAlphaFactory
.
sample_problem_xml_youtube
}
descriptor
=
Mock
(
weight
=
"1"
)
system
=
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
,
(
''
,
''
))
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
,
''
))
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
))
class
VideoAlphaModuleUnitTest
(
unittest
.
TestCase
):
"""Unit tests for VideoAlpha Xmodule."""
def
test_videoalpha_constructor
(
self
):
"""Make sure that all parameters extracted correclty from xml"""
module
=
VideoAlphaFactory
.
create
()
# `get_html` return only context, cause we
# overwrite `system.render_template`
context
=
module
.
get_html
()
expected_context
=
{
'caption_asset_path'
:
'/static/subs/'
,
'sub'
:
module
.
sub
,
'data_dir'
:
getattr
(
self
,
'data_dir'
,
None
),
'display_name'
:
module
.
display_name_with_default
,
'end'
:
module
.
end_time
,
'start'
:
module
.
start_time
,
'id'
:
module
.
location
.
html_id
(),
'show_captions'
:
module
.
show_captions
,
'sources'
:
module
.
sources
,
'youtube_streams'
:
module
.
youtube_streams
,
'track'
:
module
.
track
,
'autoplay'
:
settings
.
MITX_FEATURES
.
get
(
'AUTOPLAY_VIDEOS'
,
True
)
}
self
.
assertDictEqual
(
context
,
expected_context
)
self
.
assertDictEqual
(
json
.
loads
(
module
.
get_instance_state
()),
{
'position'
:
0
})
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment