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
1d748386
Commit
1d748386
authored
Jan 16, 2014
by
polesye
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
BLD-237: Persist speed preferences between videos.
parent
5bacfcc3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
212 additions
and
146 deletions
+212
-146
CHANGELOG.rst
+2
-0
common/lib/xmodule/xmodule/js/fixtures/video.html
+3
-1
common/lib/xmodule/xmodule/js/fixtures/video_all.html
+2
-0
common/lib/xmodule/xmodule/js/fixtures/video_html5.html
+2
-0
common/lib/xmodule/xmodule/js/fixtures/video_no_captions.html
+3
-1
common/lib/xmodule/xmodule/js/fixtures/video_yt_multiple.html
+3
-1
common/lib/xmodule/xmodule/js/spec/helper.js
+6
-0
common/lib/xmodule/xmodule/js/spec/video/cookie_storage_spec.js
+5
-5
common/lib/xmodule/xmodule/js/spec/video/general_spec.js
+39
-50
common/lib/xmodule/xmodule/js/spec/video/video_player_spec.js
+6
-6
common/lib/xmodule/xmodule/js/spec/video/video_speed_control_spec.js
+1
-1
common/lib/xmodule/xmodule/js/src/video/00_cookie_storage.js
+1
-3
common/lib/xmodule/xmodule/js/src/video/01_initialize.js
+0
-0
common/lib/xmodule/xmodule/js/src/video/03_video_player.js
+16
-8
common/lib/xmodule/xmodule/js/src/video/09_video_caption.js
+3
-3
common/lib/xmodule/xmodule/video_module.py
+34
-13
lms/djangoapps/courseware/features/video.feature
+21
-0
lms/djangoapps/courseware/features/video.py
+43
-4
lms/djangoapps/courseware/tests/test_video_mongo.py
+19
-9
lms/djangoapps/courseware/tests/test_video_xml.py
+1
-39
lms/templates/video.html
+2
-2
No files found.
CHANGELOG.rst
View file @
1d748386
...
@@ -5,6 +5,8 @@ These are notable changes in edx-platform. This is a rolling list of changes,
...
@@ -5,6 +5,8 @@ These are notable changes in edx-platform. This is a rolling list of changes,
in roughly chronological order, most recent first. Add your entries at or near
in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected.
the top. Include a label indicating the component affected.
Blades: Video player persist speed preferences between videos. BLD-237.
Blades: Change the download video field to a dropdown that will allow students
Blades: Change the download video field to a dropdown that will allow students
to download the first source listed in the alternate sources. BLD-364.
to download the first source listed in the alternate sources. BLD-364.
...
...
common/lib/xmodule/xmodule/js/fixtures/video.html
View file @
1d748386
...
@@ -4,8 +4,10 @@
...
@@ -4,8 +4,10 @@
<div
<div
id=
"video_id"
id=
"video_id"
class=
"video closed"
class=
"video closed"
data-streams=
"0.
75:7tqY6eQzVhE,1.0:cogebirgzzM
"
data-streams=
"0.
5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl
"
data-show-captions=
"true"
data-show-captions=
"true"
data-save-state-url=
"/save_user_state"
data-speed=
"1.5"
data-start=
""
data-start=
""
data-end=
""
data-end=
""
data-caption-asset-path=
"/static/subs/"
data-caption-asset-path=
"/static/subs/"
...
...
common/lib/xmodule/xmodule/js/fixtures/video_all.html
View file @
1d748386
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
id=
"video_id"
id=
"video_id"
class=
"video closed"
class=
"video closed"
data-show-captions=
"true"
data-show-captions=
"true"
data-save-state-url=
"/save_user_state"
data-speed=
"1.5"
data-start=
""
data-start=
""
data-end=
""
data-end=
""
data-caption-asset-path=
"/static/subs/"
data-caption-asset-path=
"/static/subs/"
...
...
common/lib/xmodule/xmodule/js/fixtures/video_html5.html
View file @
1d748386
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
id=
"video_id"
id=
"video_id"
class=
"video closed"
class=
"video closed"
data-show-captions=
"true"
data-show-captions=
"true"
data-save-state-url=
"/save_user_state"
data-speed=
"1.5"
data-start=
""
data-start=
""
data-end=
""
data-end=
""
data-caption-asset-path=
"/static/subs/"
data-caption-asset-path=
"/static/subs/"
...
...
common/lib/xmodule/xmodule/js/fixtures/video_no_captions.html
View file @
1d748386
...
@@ -4,8 +4,10 @@
...
@@ -4,8 +4,10 @@
<div
<div
id=
"video_id"
id=
"video_id"
class=
"video closed"
class=
"video closed"
data-streams=
"0.
75:7tqY6eQzVhE,1.0:cogebirgzzM
"
data-streams=
"0.
5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl
"
data-show-captions=
"false"
data-show-captions=
"false"
data-save-state-url=
"/save_user_state"
data-speed=
"1.5"
data-start=
""
data-start=
""
data-end=
""
data-end=
""
data-caption-asset-path=
"/static/subs/"
data-caption-asset-path=
"/static/subs/"
...
...
common/lib/xmodule/xmodule/js/fixtures/video_yt_multiple.html
View file @
1d748386
...
@@ -4,8 +4,10 @@
...
@@ -4,8 +4,10 @@
<div
<div
id=
"video_id1"
id=
"video_id1"
class=
"video closed"
class=
"video closed"
data-streams=
"0.
75:7tqY6eQzVhE,1.0:cogebirgzzM
"
data-streams=
"0.
5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl
"
data-show-captions=
"true"
data-show-captions=
"true"
data-save-state-url=
"/save_user_state"
data-speed=
"1.5"
data-start=
""
data-start=
""
data-end=
""
data-end=
""
data-caption-asset-path=
"/static/subs/"
data-caption-asset-path=
"/static/subs/"
...
...
common/lib/xmodule/xmodule/js/spec/helper.js
View file @
1d748386
...
@@ -113,6 +113,10 @@
...
@@ -113,6 +113,10 @@
id
:
'cogebirgzzM'
,
id
:
'cogebirgzzM'
,
duration
:
200
duration
:
200
},
},
'abcdefghijkl'
:
{
id
:
'abcdefghijkl'
,
duration
:
400
},
bogus
:
{
bogus
:
{
duration
:
100
duration
:
100
}
}
...
@@ -189,6 +193,8 @@
...
@@ -189,6 +193,8 @@
settings
.
url
.
match
(
/.+
\/
problem_
(
check|reset|show|save
)
$/
)
settings
.
url
.
match
(
/.+
\/
problem_
(
check|reset|show|save
)
$/
)
)
{
)
{
// Do nothing.
// Do nothing.
}
else
if
(
settings
.
url
==
'/save_user_state'
)
{
return
{
success
:
true
};
}
else
{
}
else
{
throw
'External request attempted for '
+
throw
'External request attempted for '
+
settings
.
url
+
settings
.
url
+
...
...
common/lib/xmodule/xmodule/js/spec/video/cookie_storage_spec.js
View file @
1d748386
...
@@ -32,7 +32,7 @@ function (CookieStorage) {
...
@@ -32,7 +32,7 @@ function (CookieStorage) {
it
(
'unload'
,
function
()
{
it
(
'unload'
,
function
()
{
var
expected
=
JSON
.
stringify
({
var
expected
=
JSON
.
stringify
({
storage
:
{
storage
:
{
'item_2'
:
{
item_2
:
{
value
:
'value_2'
,
value
:
'value_2'
,
session
:
false
session
:
false
}
}
...
@@ -51,7 +51,7 @@ function (CookieStorage) {
...
@@ -51,7 +51,7 @@ function (CookieStorage) {
describe
(
'methods: '
,
function
()
{
describe
(
'methods: '
,
function
()
{
var
data
=
{
var
data
=
{
storage
:
{
storage
:
{
'item_1'
:
{
item_1
:
{
value
:
'value_1'
,
value
:
'value_1'
,
session
:
false
session
:
false
}
}
...
@@ -69,15 +69,15 @@ function (CookieStorage) {
...
@@ -69,15 +69,15 @@ function (CookieStorage) {
it
(
'pass correct data'
,
function
()
{
it
(
'pass correct data'
,
function
()
{
var
expected
=
JSON
.
stringify
({
var
expected
=
JSON
.
stringify
({
storage
:
{
storage
:
{
'item_1'
:
{
item_1
:
{
value
:
'value_1'
,
value
:
'value_1'
,
session
:
false
session
:
false
},
},
'item_2'
:
{
item_2
:
{
value
:
'value_2'
,
value
:
'value_2'
,
session
:
false
session
:
false
},
},
'item_3'
:
{
item_3
:
{
value
:
'value_3'
,
value
:
'value_3'
,
session
:
true
session
:
true
},
},
...
...
common/lib/xmodule/xmodule/js/spec/video/general_spec.js
View file @
1d748386
...
@@ -4,9 +4,6 @@
...
@@ -4,9 +4,6 @@
beforeEach
(
function
()
{
beforeEach
(
function
()
{
jasmine
.
stubRequests
();
jasmine
.
stubRequests
();
this
.
videosDefinition
=
'0.75:7tqY6eQzVhE,1.0:cogebirgzzM'
;
this
[
'7tqY6eQzVhE'
]
=
'7tqY6eQzVhE'
;
this
[
'cogebirgzzM'
]
=
'cogebirgzzM'
;
});
});
afterEach
(
function
()
{
afterEach
(
function
()
{
...
@@ -17,7 +14,7 @@
...
@@ -17,7 +14,7 @@
describe
(
'YT'
,
function
()
{
describe
(
'YT'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
loadFixtures
(
'video.html'
);
loadFixtures
(
'video.html'
);
$
.
cookie
.
andReturn
(
'0.
75
'
);
$
.
cookie
.
andReturn
(
'0.
50
'
);
});
});
describe
(
'by default'
,
function
()
{
describe
(
'by default'
,
function
()
{
...
@@ -35,17 +32,18 @@
...
@@ -35,17 +32,18 @@
it
(
'parse the videos'
,
function
()
{
it
(
'parse the videos'
,
function
()
{
expect
(
this
.
state
.
videos
).
toEqual
({
expect
(
this
.
state
.
videos
).
toEqual
({
'0.75'
:
this
[
'7tqY6eQzVhE'
],
'0.50'
:
'7tqY6eQzVhE'
,
'1.0'
:
this
[
'cogebirgzzM'
]
'1.0'
:
'cogebirgzzM'
,
'1.50'
:
'abcdefghijkl'
});
});
});
});
it
(
'parse available video speeds'
,
function
()
{
it
(
'parse available video speeds'
,
function
()
{
expect
(
this
.
state
.
speeds
).
toEqual
([
'0.
75'
,
'1.
0'
]);
expect
(
this
.
state
.
speeds
).
toEqual
([
'0.
50'
,
'1.0'
,
'1.5
0'
]);
});
});
it
(
'set current video speed via cookie'
,
function
()
{
it
(
'set current video speed via cookie'
,
function
()
{
expect
(
this
.
state
.
speed
).
toEqual
(
'
0.75
'
);
expect
(
this
.
state
.
speed
).
toEqual
(
'
1.50
'
);
});
});
});
});
});
});
...
@@ -157,7 +155,7 @@
...
@@ -157,7 +155,7 @@
});
});
it
(
'set current video speed via cookie'
,
function
()
{
it
(
'set current video speed via cookie'
,
function
()
{
expect
(
state
.
speed
).
toEqual
(
'
0.75
'
);
expect
(
state
.
speed
).
toEqual
(
'
1.50
'
);
});
});
});
});
...
@@ -190,16 +188,18 @@
...
@@ -190,16 +188,18 @@
describe
(
'with speed'
,
function
()
{
describe
(
'with speed'
,
function
()
{
it
(
'return the video id for given speed'
,
function
()
{
it
(
'return the video id for given speed'
,
function
()
{
expect
(
state
.
youtubeId
(
'0.
75
'
))
expect
(
state
.
youtubeId
(
'0.
50
'
))
.
toEqual
(
this
[
'7tqY6eQzVhE'
]
);
.
toEqual
(
'7tqY6eQzVhE'
);
expect
(
state
.
youtubeId
(
'1.0'
))
expect
(
state
.
youtubeId
(
'1.0'
))
.
toEqual
(
this
[
'cogebirgzzM'
]);
.
toEqual
(
'cogebirgzzM'
);
expect
(
state
.
youtubeId
(
'1.50'
))
.
toEqual
(
'abcdefghijkl'
);
});
});
});
});
describe
(
'without speed'
,
function
()
{
describe
(
'without speed'
,
function
()
{
it
(
'return the video id for current speed'
,
function
()
{
it
(
'return the video id for current speed'
,
function
()
{
expect
(
state
.
youtubeId
()).
toEqual
(
this
.
cogebirgzzM
);
expect
(
state
.
youtubeId
()).
toEqual
(
'abcdefghijkl'
);
});
});
});
});
});
});
...
@@ -314,44 +314,25 @@
...
@@ -314,44 +314,25 @@
});
});
describe
(
'setSpeed'
,
function
()
{
describe
(
'setSpeed'
,
function
()
{
describe
(
'YT'
,
function
()
{
describe
(
'YT'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
loadFixtures
(
'video.html'
);
loadFixtures
(
'video.html'
);
state
=
new
Video
(
'#example'
);
state
=
new
Video
(
'#example'
);
});
});
describe
(
'when new speed is available'
,
function
()
{
it
(
'check mapping'
,
function
()
{
beforeEach
(
function
()
{
var
map
=
{
state
.
setSpeed
(
'0.75'
,
true
);
'0.75'
:
'0.50'
,
});
'1.25'
:
'1.50'
};
it
(
'set new speed'
,
function
()
{
expect
(
state
.
speed
).
toEqual
(
'0.75'
);
});
it
(
'save setting for new speed'
,
function
()
{
expect
(
$
.
cookie
).
toHaveBeenCalledWith
(
'video_speed'
,
'0.75'
,
{
expires
:
3650
,
path
:
'/'
}
);
});
});
describe
(
'when new speed is not available'
,
function
()
{
beforeEach
(
function
()
{
state
.
setSpeed
(
'1.75'
);
});
it
(
'set speed to 1.0x'
,
function
()
{
$
.
each
(
map
,
function
(
key
,
expected
)
{
expect
(
state
.
speed
).
toEqual
(
'1.0'
);
state
.
setSpeed
(
key
,
true
);
expect
(
state
.
speed
).
toBe
(
expected
);
});
});
});
});
});
});
describe
(
'HTML5'
,
function
()
{
describe
(
'HTML5'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
loadFixtures
(
'video_html5.html'
);
loadFixtures
(
'video_html5.html'
);
...
@@ -368,14 +349,9 @@
...
@@ -368,14 +349,9 @@
});
});
it
(
'save setting for new speed'
,
function
()
{
it
(
'save setting for new speed'
,
function
()
{
expect
(
$
.
cookie
).
toHaveBeenCalledWith
(
'video_speed'
,
expect
(
state
.
storage
.
getItem
(
'general_speed'
)).
toBe
(
'0.75'
);
'0.75'
,
expect
(
state
.
storage
.
getItem
(
'video_speed_'
+
state
.
id
)).
toBe
(
'0.75'
);
{
expires
:
3650
,
path
:
'/'
}
);
});
});
});
});
...
@@ -388,6 +364,19 @@
...
@@ -388,6 +364,19 @@
expect
(
state
.
speed
).
toEqual
(
'1.0'
);
expect
(
state
.
speed
).
toEqual
(
'1.0'
);
});
});
});
});
it
(
'check mapping'
,
function
()
{
var
map
=
{
'0.25'
:
'0.75'
,
'0.50'
:
'0.75'
,
'2.0'
:
'1.50'
};
$
.
each
(
map
,
function
(
key
,
expected
)
{
state
.
setSpeed
(
key
,
true
);
expect
(
state
.
speed
).
toBe
(
expected
);
});
});
});
});
});
});
...
@@ -398,7 +387,7 @@
...
@@ -398,7 +387,7 @@
});
});
it
(
'return duration for current video'
,
function
()
{
it
(
'return duration for current video'
,
function
()
{
expect
(
state
.
getDuration
()).
toEqual
(
2
00
);
expect
(
state
.
getDuration
()).
toEqual
(
4
00
);
});
});
});
});
...
...
common/lib/xmodule/xmodule/js/spec/video/video_player_spec.js
View file @
1d748386
...
@@ -36,9 +36,9 @@
...
@@ -36,9 +36,9 @@
it
(
'create video caption'
,
function
()
{
it
(
'create video caption'
,
function
()
{
expect
(
state
.
videoCaption
).
toBeDefined
();
expect
(
state
.
videoCaption
).
toBeDefined
();
expect
(
state
.
youtubeId
()).
toEqual
(
'Z5KLxerq05Y'
);
expect
(
state
.
youtubeId
(
'1.0'
)).
toEqual
(
'Z5KLxerq05Y'
);
expect
(
state
.
speed
).
toEqual
(
'1.0'
);
expect
(
state
.
speed
).
toEqual
(
'1.
5
0'
);
expect
(
state
.
config
.
caption
_asset_p
ath
)
expect
(
state
.
config
.
caption
AssetP
ath
)
.
toEqual
(
'/static/subs/'
);
.
toEqual
(
'/static/subs/'
);
});
});
...
@@ -47,7 +47,7 @@
...
@@ -47,7 +47,7 @@
expect
(
state
.
videoSpeedControl
.
el
).
toHaveClass
(
'speeds'
);
expect
(
state
.
videoSpeedControl
.
el
).
toHaveClass
(
'speeds'
);
expect
(
state
.
videoSpeedControl
.
speeds
)
expect
(
state
.
videoSpeedControl
.
speeds
)
.
toEqual
([
'0.75'
,
'1.0'
,
'1.25'
,
'1.50'
]);
.
toEqual
([
'0.75'
,
'1.0'
,
'1.25'
,
'1.50'
]);
expect
(
state
.
speed
).
toEqual
(
'1.0'
);
expect
(
state
.
speed
).
toEqual
(
'1.
5
0'
);
});
});
it
(
'create video progress slider'
,
function
()
{
it
(
'create video progress slider'
,
function
()
{
...
@@ -395,7 +395,7 @@
...
@@ -395,7 +395,7 @@
'speed_change_video'
,
'speed_change_video'
,
{
{
current_time
:
state
.
videoPlayer
.
currentTime
,
current_time
:
state
.
videoPlayer
.
currentTime
,
old_speed
:
'1.0'
,
old_speed
:
'1.
5
0'
,
new_speed
:
'0.75'
new_speed
:
'0.75'
}
}
);
);
...
@@ -406,7 +406,7 @@
...
@@ -406,7 +406,7 @@
});
});
it
(
'set video speed to the new speed'
,
function
()
{
it
(
'set video speed to the new speed'
,
function
()
{
expect
(
state
.
setSpeed
).
toHaveBeenCalledWith
(
'0.75'
,
fals
e
);
expect
(
state
.
setSpeed
).
toHaveBeenCalledWith
(
'0.75'
,
tru
e
);
});
});
});
});
...
...
common/lib/xmodule/xmodule/js/spec/video/video_speed_control_spec.js
View file @
1d748386
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
expect
(
secondaryControls
).
toContain
(
'.speeds'
);
expect
(
secondaryControls
).
toContain
(
'.speeds'
);
expect
(
secondaryControls
).
toContain
(
'.video_speeds'
);
expect
(
secondaryControls
).
toContain
(
'.video_speeds'
);
expect
(
secondaryControls
.
find
(
'p.active'
).
text
())
expect
(
secondaryControls
.
find
(
'p.active'
).
text
())
.
toBe
(
'1.0x'
);
.
toBe
(
'1.
5
0x'
);
expect
(
li
.
filter
(
'.active'
)).
toHaveData
(
expect
(
li
.
filter
(
'.active'
)).
toHaveData
(
'speed'
,
state
.
videoSpeedControl
.
currentSpeed
'speed'
,
state
.
videoSpeedControl
.
currentSpeed
);
);
...
...
common/lib/xmodule/xmodule/js/src/video/00_cookie_storage.js
View file @
1d748386
...
@@ -15,8 +15,6 @@ function() {
...
@@ -15,8 +15,6 @@ function() {
* @param {string} namespace Namespace that is used to store data.
* @param {string} namespace Namespace that is used to store data.
* @return {object} CookieStorage API.
* @return {object} CookieStorage API.
*/
*/
var
CookieStorage
=
function
(
namespace
)
{
var
CookieStorage
=
function
(
namespace
)
{
var
Storage
;
var
Storage
;
...
@@ -73,7 +71,7 @@ function() {
...
@@ -73,7 +71,7 @@ function() {
});
});
$
.
cookie
(
namespace
,
JSON
.
stringify
(
Storage
),
{
$
.
cookie
(
namespace
,
JSON
.
stringify
(
Storage
),
{
expires
:
-
1
,
expires
:
3650
,
path
:
'/'
path
:
'/'
});
});
};
};
...
...
common/lib/xmodule/xmodule/js/src/video/01_initialize.js
View file @
1d748386
This diff is collapsed.
Click to expand it.
common/lib/xmodule/xmodule/js/src/video/03_video_player.js
View file @
1d748386
...
@@ -324,7 +324,7 @@ function (HTML5Video, Resizer) {
...
@@ -324,7 +324,7 @@ function (HTML5Video, Resizer) {
}
}
}
}
function
onSpeedChange
(
newSpeed
,
updateCookie
)
{
function
onSpeedChange
(
newSpeed
)
{
var
time
=
this
.
videoPlayer
.
currentTime
,
var
time
=
this
.
videoPlayer
.
currentTime
,
methodName
,
youtubeId
;
methodName
,
youtubeId
;
...
@@ -347,7 +347,7 @@ function (HTML5Video, Resizer) {
...
@@ -347,7 +347,7 @@ function (HTML5Video, Resizer) {
}
}
);
);
this
.
setSpeed
(
newSpeed
,
updateCooki
e
);
this
.
setSpeed
(
newSpeed
,
tru
e
);
if
(
if
(
this
.
currentPlayerMode
===
'html5'
&&
this
.
currentPlayerMode
===
'html5'
&&
...
@@ -376,6 +376,15 @@ function (HTML5Video, Resizer) {
...
@@ -376,6 +376,15 @@ function (HTML5Video, Resizer) {
}
}
this
.
el
.
trigger
(
'speedchange'
,
arguments
);
this
.
el
.
trigger
(
'speedchange'
,
arguments
);
$
.
ajax
({
url
:
this
.
config
.
saveStateUrl
,
type
:
'POST'
,
dataType
:
'json'
,
data
:
{
speed
:
newSpeed
},
});
}
}
// Every 200 ms, if the video is playing, we call the function update, via
// Every 200 ms, if the video is playing, we call the function update, via
...
@@ -434,7 +443,7 @@ function (HTML5Video, Resizer) {
...
@@ -434,7 +443,7 @@ function (HTML5Video, Resizer) {
end
:
true
end
:
true
});
});
if
(
this
.
config
.
show
_c
aptions
)
{
if
(
this
.
config
.
show
C
aptions
)
{
this
.
trigger
(
'videoCaption.pause'
,
null
);
this
.
trigger
(
'videoCaption.pause'
,
null
);
}
}
...
@@ -466,7 +475,7 @@ function (HTML5Video, Resizer) {
...
@@ -466,7 +475,7 @@ function (HTML5Video, Resizer) {
this
.
trigger
(
'videoControl.pause'
,
null
);
this
.
trigger
(
'videoControl.pause'
,
null
);
if
(
this
.
config
.
show
_c
aptions
)
{
if
(
this
.
config
.
show
C
aptions
)
{
this
.
trigger
(
'videoCaption.pause'
,
null
);
this
.
trigger
(
'videoCaption.pause'
,
null
);
}
}
...
@@ -495,7 +504,7 @@ function (HTML5Video, Resizer) {
...
@@ -495,7 +504,7 @@ function (HTML5Video, Resizer) {
end
:
false
end
:
false
});
});
if
(
this
.
config
.
show
_c
aptions
)
{
if
(
this
.
config
.
show
C
aptions
)
{
this
.
trigger
(
'videoCaption.play'
,
null
);
this
.
trigger
(
'videoCaption.play'
,
null
);
}
}
...
@@ -579,7 +588,6 @@ function (HTML5Video, Resizer) {
...
@@ -579,7 +588,6 @@ function (HTML5Video, Resizer) {
var
key
=
value
.
toFixed
(
2
).
replace
(
/
\.
00$/
,
'.0'
);
var
key
=
value
.
toFixed
(
2
).
replace
(
/
\.
00$/
,
'.0'
);
_this
.
videos
[
key
]
=
baseSpeedSubs
;
_this
.
videos
[
key
]
=
baseSpeedSubs
;
_this
.
speeds
.
push
(
key
);
_this
.
speeds
.
push
(
key
);
});
});
...
@@ -590,8 +598,8 @@ function (HTML5Video, Resizer) {
...
@@ -590,8 +598,8 @@ function (HTML5Video, Resizer) {
currentSpeed
:
this
.
speed
currentSpeed
:
this
.
speed
}
}
);
);
this
.
setSpeed
(
this
.
speed
);
this
.
setSpeed
(
$
.
cookie
(
'video_speed'
)
);
this
.
trigger
(
'videoSpeedControl.setSpeed'
,
this
.
speed
);
}
}
}
}
...
...
common/lib/xmodule/xmodule/js/src/video/09_video_caption.js
View file @
1d748386
...
@@ -252,7 +252,7 @@ function () {
...
@@ -252,7 +252,7 @@ function () {
}
}
function
captionURL
()
{
function
captionURL
()
{
return
''
+
this
.
config
.
caption
_asset_p
ath
+
return
''
+
this
.
config
.
caption
AssetP
ath
+
this
.
youtubeId
(
'1.0'
)
+
'.srt.sjson'
;
this
.
youtubeId
(
'1.0'
)
+
'.srt.sjson'
;
}
}
...
@@ -356,7 +356,7 @@ function () {
...
@@ -356,7 +356,7 @@ function () {
_this
=
this
,
_this
=
this
,
autohideHtml5
=
this
.
config
.
autohideHtml5
;
autohideHtml5
=
this
.
config
.
autohideHtml5
;
this
.
elVideoWrapp
er
.
after
(
this
.
videoCaption
.
subtitlesEl
);
this
.
contain
er
.
after
(
this
.
videoCaption
.
subtitlesEl
);
this
.
el
.
find
(
'.video-controls .secondary-controls'
)
this
.
el
.
find
(
'.video-controls .secondary-controls'
)
.
append
(
this
.
videoCaption
.
hideSubtitlesEl
);
.
append
(
this
.
videoCaption
.
hideSubtitlesEl
);
...
@@ -745,7 +745,7 @@ function () {
...
@@ -745,7 +745,7 @@ function () {
0.5
*
this
.
videoControl
.
sliderEl
.
height
()
-
0.5
*
this
.
videoControl
.
sliderEl
.
height
()
-
2
*
paddingTop
;
2
*
paddingTop
;
}
else
{
}
else
{
return
this
.
elVideoWrapp
er
.
height
();
return
this
.
contain
er
.
height
();
}
}
}
}
...
...
common/lib/xmodule/xmodule/video_module.py
View file @
1d748386
...
@@ -20,7 +20,6 @@ import datetime
...
@@ -20,7 +20,6 @@ import datetime
import
copy
import
copy
from
webob
import
Response
from
webob
import
Response
from
django.http
import
Http404
from
django.conf
import
settings
from
django.conf
import
settings
from
xmodule.x_module
import
XModule
,
module_attr
from
xmodule.x_module
import
XModule
,
module_attr
...
@@ -31,7 +30,7 @@ from xmodule.contentstore.django import contentstore
...
@@ -31,7 +30,7 @@ from xmodule.contentstore.django import contentstore
from
xmodule.contentstore.content
import
StaticContent
from
xmodule.contentstore.content
import
StaticContent
from
xmodule.exceptions
import
NotFoundError
from
xmodule.exceptions
import
NotFoundError
from
xblock.core
import
XBlock
from
xblock.core
import
XBlock
from
xblock.fields
import
Scope
,
String
,
Boolean
,
List
,
Integer
,
ScopeIds
from
xblock.fields
import
Scope
,
String
,
Float
,
Boolean
,
List
,
Integer
,
ScopeIds
from
xmodule.fields
import
RelativeTime
from
xmodule.fields
import
RelativeTime
from
xmodule.modulestore.inheritance
import
InheritanceKeyValueStore
from
xmodule.modulestore.inheritance
import
InheritanceKeyValueStore
...
@@ -137,6 +136,15 @@ class VideoFields(object):
...
@@ -137,6 +136,15 @@ class VideoFields(object):
scope
=
Scope
.
settings
,
scope
=
Scope
.
settings
,
default
=
""
default
=
""
)
)
speed
=
Float
(
help
=
"The last speed that was explicitly set by user for the video."
,
scope
=
Scope
.
user_state
,
)
global_speed
=
Float
(
help
=
"Default speed in cases when speed wasn't explicitly for specific video"
,
scope
=
Scope
.
preferences
,
default
=
1.0
)
class
VideoModule
(
VideoFields
,
XModule
):
class
VideoModule
(
VideoFields
,
XModule
):
...
@@ -178,10 +186,21 @@ class VideoModule(VideoFields, XModule):
...
@@ -178,10 +186,21 @@ class VideoModule(VideoFields, XModule):
js_module_name
=
"Video"
js_module_name
=
"Video"
def
handle_ajax
(
self
,
dispatch
,
data
):
def
handle_ajax
(
self
,
dispatch
,
data
):
"""This is not being called right now and we raise 404 error."""
ACCEPTED_KEYS
=
[
'speed'
]
if
dispatch
==
'save_user_state'
:
for
key
in
data
:
if
hasattr
(
self
,
key
)
and
key
in
ACCEPTED_KEYS
:
setattr
(
self
,
key
,
json
.
loads
(
data
[
key
]))
if
key
==
'speed'
:
self
.
global_speed
=
self
.
speed
return
json
.
dumps
({
'success'
:
True
})
log
.
debug
(
u"GET {0}"
.
format
(
data
))
log
.
debug
(
u"GET {0}"
.
format
(
data
))
log
.
debug
(
u"DISPATCH {0}"
.
format
(
dispatch
))
log
.
debug
(
u"DISPATCH {0}"
.
format
(
dispatch
))
raise
Http404
()
raise
NotFoundError
(
'Unexpected dispatch type'
)
def
get_html
(
self
):
def
get_html
(
self
):
track_url
=
None
track_url
=
None
...
@@ -203,24 +222,26 @@ class VideoModule(VideoFields, XModule):
...
@@ -203,24 +222,26 @@ class VideoModule(VideoFields, XModule):
track_url
=
self
.
runtime
.
handler_url
(
self
,
'download_transcript'
)
track_url
=
self
.
runtime
.
handler_url
(
self
,
'download_transcript'
)
return
self
.
system
.
render_template
(
'video.html'
,
{
return
self
.
system
.
render_template
(
'video.html'
,
{
'youtube_streams'
:
_create_youtube_string
(
self
),
'ajax_url'
:
self
.
system
.
ajax_url
+
'/save_user_state'
,
'id'
:
self
.
location
.
html_id
(),
'autoplay'
:
settings
.
FEATURES
.
get
(
'AUTOPLAY_VIDEOS'
,
False
),
'sub'
:
self
.
sub
,
'sources'
:
sources
,
'track'
:
track_url
,
'display_name'
:
self
.
display_name_with_default
,
# This won't work when we move to data that
# This won't work when we move to data that
# isn't on the filesystem
# isn't on the filesystem
'data_dir'
:
getattr
(
self
,
'data_dir'
,
None
),
'data_dir'
:
getattr
(
self
,
'data_dir'
,
None
),
'display_name'
:
self
.
display_name_with_default
,
'caption_asset_path'
:
caption_asset_path
,
'caption_asset_path'
:
caption_asset_path
,
'end'
:
self
.
end_time
.
total_seconds
(),
'id'
:
self
.
location
.
html_id
(),
'show_captions'
:
json
.
dumps
(
self
.
show_captions
),
'show_captions'
:
json
.
dumps
(
self
.
show_captions
),
'sources'
:
sources
,
'speed'
:
self
.
speed
or
self
.
global_speed
,
'start'
:
self
.
start_time
.
total_seconds
(),
'start'
:
self
.
start_time
.
total_seconds
(),
'end'
:
self
.
end_time
.
total_seconds
(),
'sub'
:
self
.
sub
,
'autoplay'
:
settings
.
FEATURES
.
get
(
'AUTOPLAY_VIDEOS'
,
False
),
'track'
:
track_url
,
'youtube_streams'
:
_create_youtube_string
(
self
),
# TODO: Later on the value 1500 should be taken from some global
# TODO: Later on the value 1500 should be taken from some global
# configuration setting field.
# configuration setting field.
'yt_test_timeout'
:
1500
,
'yt_test_timeout'
:
1500
,
'yt_test_url'
:
settings
.
YOUTUBE_TEST_URL
'yt_test_url'
:
settings
.
YOUTUBE_TEST_URL
,
})
})
def
get_transcript
(
self
,
subs_id
):
def
get_transcript
(
self
,
subs_id
):
...
...
lms/djangoapps/courseware/features/video.feature
View file @
1d748386
...
@@ -45,3 +45,24 @@ Feature: LMS.Video component
...
@@ -45,3 +45,24 @@ Feature: LMS.Video component
Given
the course has a Video component in HTML5_Unsupported_Video mode
Given
the course has a Video component in HTML5_Unsupported_Video mode
Then
error message is shown
Then
error message is shown
And
error message has correct text
And
error message has correct text
# 8
Scenario
:
Video component stores speed correctly when each video is in separate sequence.
Given
I am registered for the course
"test_course"
And
it has a video
"A"
in
"Youtube"
mode in position
"1"
of sequential
And
a video
"B"
in
"Youtube"
mode in position
"2"
of sequential
And
a video
"C"
in
"Youtube"
mode in position
"3"
of sequential
And
I open the section with videos
And
I select the
"2.0"
speed on video
"A"
And
I select the
"0.50"
speed on video
"B"
When
I open video
"C"
Then
video
"C"
should start playing at speed
"0.50"
When
I open video
"A"
Then
video
"A"
should start playing at speed
"2.0"
And
I reload the page
When
I open video
"A"
Then
video
"A"
should start playing at speed
"2.0"
When
I open video
"B"
Then
video
"B"
should start playing at speed
"0.50"
When
I open video
"C"
Then
video
"C"
should start playing at speed
"0.50"
lms/djangoapps/courseware/features/video.py
View file @
1d748386
...
@@ -15,6 +15,9 @@ HTML5_SOURCES_INCORRECT = [
...
@@ -15,6 +15,9 @@ HTML5_SOURCES_INCORRECT = [
'https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.mp99'
'https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.mp99'
]
]
coursenum
=
'test_course'
sequence
=
{}
@step
(
'when I view the (.*) it does not have autoplay enabled$'
)
@step
(
'when I view the (.*) it does not have autoplay enabled$'
)
def
does_not_autoplay
(
_step
,
video_type
):
def
does_not_autoplay
(
_step
,
video_type
):
assert
(
world
.
css_find
(
'.
%
s'
%
video_type
)[
0
][
'data-autoplay'
]
==
'False'
)
assert
(
world
.
css_find
(
'.
%
s'
%
video_type
)[
0
][
'data-autoplay'
]
==
'False'
)
...
@@ -22,21 +25,48 @@ def does_not_autoplay(_step, video_type):
...
@@ -22,21 +25,48 @@ def does_not_autoplay(_step, video_type):
@step
(
'the course has a Video component in (.*) mode$'
)
@step
(
'the course has a Video component in (.*) mode$'
)
def
view_video
(
_step
,
player_mode
):
def
view_video
(
_step
,
player_mode
):
coursenum
=
'test_course'
i_am_registered_for_the_course
(
step
,
coursenum
)
i_am_registered_for_the_course
(
_
step
,
coursenum
)
# Make sure we have a video
# Make sure we have a video
add_video_to_course
(
coursenum
,
player_mode
.
lower
())
add_video_to_course
(
coursenum
,
player_mode
.
lower
())
visit_scenario_item
(
'SECTION'
)
visit_scenario_item
(
'SECTION'
)
def
add_video_to_course
(
course
,
player_mode
):
@step
(
'a video "([^"]*)" in "([^"]*)" mode in position "([^"]*)" of sequential$'
)
def
add_video
(
_step
,
player_id
,
player_mode
,
position
):
sequence
[
player_id
]
=
position
add_video_to_course
(
coursenum
,
player_mode
.
lower
(),
display_name
=
player_id
)
@step
(
'I open the section with videos$'
)
def
visit_video_section
(
_step
):
visit_scenario_item
(
'SECTION'
)
@step
(
'I select the "([^"]*)" speed on video "([^"]*)"$'
)
def
change_video_speed
(
_step
,
speed
,
player_id
):
_navigate_to_an_item_in_a_sequence
(
sequence
[
player_id
])
_change_video_speed
(
speed
)
@step
(
'I open video "([^"]*)"$'
)
def
open_video
(
_step
,
player_id
):
_navigate_to_an_item_in_a_sequence
(
sequence
[
player_id
])
@step
(
'video "([^"]*)" should start playing at speed "([^"]*)"$'
)
def
check_video_speed
(
_step
,
player_id
,
speed
):
speed_css
=
'.speeds p.active'
assert
world
.
css_has_text
(
speed_css
,
'{0}x'
.
format
(
speed
))
def
add_video_to_course
(
course
,
player_mode
,
display_name
=
'Video'
):
category
=
'video'
category
=
'video'
kwargs
=
{
kwargs
=
{
'parent_location'
:
section_location
(
course
),
'parent_location'
:
section_location
(
course
),
'category'
:
category
,
'category'
:
category
,
'display_name'
:
'Video'
'display_name'
:
display_name
}
}
if
player_mode
==
'html5'
:
if
player_mode
==
'html5'
:
...
@@ -112,3 +142,12 @@ def error_message_has_correct_text(_step):
...
@@ -112,3 +142,12 @@ def error_message_has_correct_text(_step):
assert
world
.
css_has_text
(
selector
,
text
)
assert
world
.
css_has_text
(
selector
,
text
)
def
_navigate_to_an_item_in_a_sequence
(
number
):
sequence_css
=
'a[data-element="{0}"]'
.
format
(
number
)
world
.
css_click
(
sequence_css
)
def
_change_video_speed
(
speed
):
world
.
browser
.
execute_script
(
"$('.speeds').addClass('open')"
)
speed_css
=
'li[data-speed="{0}"] a'
.
format
(
speed
)
world
.
css_click
(
speed_css
)
lms/djangoapps/courseware/tests/test_video_mongo.py
View file @
1d748386
...
@@ -19,6 +19,7 @@ from xmodule.exceptions import NotFoundError
...
@@ -19,6 +19,7 @@ from xmodule.exceptions import NotFoundError
class
TestVideo
(
BaseTestXmodule
):
class
TestVideo
(
BaseTestXmodule
):
"""Integration tests: web client + mongo."""
"""Integration tests: web client + mongo."""
CATEGORY
=
"video"
CATEGORY
=
"video"
DATA
=
SOURCE_XML
DATA
=
SOURCE_XML
METADATA
=
{}
METADATA
=
{}
...
@@ -57,6 +58,7 @@ class TestVideoYouTube(TestVideo):
...
@@ -57,6 +58,7 @@ class TestVideoYouTube(TestVideo):
}
}
expected_context
=
{
expected_context
=
{
'ajax_url'
:
self
.
item_descriptor
.
xmodule_runtime
.
ajax_url
+
'/save_user_state'
,
'data_dir'
:
getattr
(
self
,
'data_dir'
,
None
),
'data_dir'
:
getattr
(
self
,
'data_dir'
,
None
),
'caption_asset_path'
:
'/static/subs/'
,
'caption_asset_path'
:
'/static/subs/'
,
'show_captions'
:
'true'
,
'show_captions'
:
'true'
,
...
@@ -64,6 +66,7 @@ class TestVideoYouTube(TestVideo):
...
@@ -64,6 +66,7 @@ class TestVideoYouTube(TestVideo):
'end'
:
3610.0
,
'end'
:
3610.0
,
'id'
:
self
.
item_module
.
location
.
html_id
(),
'id'
:
self
.
item_module
.
location
.
html_id
(),
'sources'
:
sources
,
'sources'
:
sources
,
'speed'
:
1.0
,
'start'
:
3603.0
,
'start'
:
3603.0
,
'sub'
:
u'a_sub_file.srt.sjson'
,
'sub'
:
u'a_sub_file.srt.sjson'
,
'track'
:
None
,
'track'
:
None
,
...
@@ -75,7 +78,7 @@ class TestVideoYouTube(TestVideo):
...
@@ -75,7 +78,7 @@ class TestVideoYouTube(TestVideo):
self
.
assertEqual
(
self
.
assertEqual
(
context
,
context
,
self
.
item_module
.
xmodule_runtime
.
render_template
(
'video.html'
,
expected_context
)
self
.
item_module
.
xmodule_runtime
.
render_template
(
'video.html'
,
expected_context
)
,
)
)
...
@@ -93,9 +96,10 @@ class TestVideoNonYouTube(TestVideo):
...
@@ -93,9 +96,10 @@ class TestVideoNonYouTube(TestVideo):
</video>
</video>
"""
"""
MODEL_DATA
=
{
MODEL_DATA
=
{
'data'
:
DATA
'data'
:
DATA
,
}
}
METADATA
=
{}
METADATA
=
{}
def
test_video_constructor
(
self
):
def
test_video_constructor
(
self
):
"""Make sure that if the 'youtube' attribute is omitted in XML, then
"""Make sure that if the 'youtube' attribute is omitted in XML, then
the template generates an empty string for the YouTube streams.
the template generates an empty string for the YouTube streams.
...
@@ -107,8 +111,8 @@ class TestVideoNonYouTube(TestVideo):
...
@@ -107,8 +111,8 @@ class TestVideoNonYouTube(TestVideo):
}
}
context
=
self
.
item_module
.
render
(
'student_view'
)
.
content
context
=
self
.
item_module
.
render
(
'student_view'
)
.
content
expected_context
=
{
expected_context
=
{
'ajax_url'
:
self
.
item_descriptor
.
xmodule_runtime
.
ajax_url
+
'/save_user_state'
,
'data_dir'
:
getattr
(
self
,
'data_dir'
,
None
),
'data_dir'
:
getattr
(
self
,
'data_dir'
,
None
),
'caption_asset_path'
:
'/static/subs/'
,
'caption_asset_path'
:
'/static/subs/'
,
'show_captions'
:
'true'
,
'show_captions'
:
'true'
,
...
@@ -116,6 +120,7 @@ class TestVideoNonYouTube(TestVideo):
...
@@ -116,6 +120,7 @@ class TestVideoNonYouTube(TestVideo):
'end'
:
3610.0
,
'end'
:
3610.0
,
'id'
:
self
.
item_module
.
location
.
html_id
(),
'id'
:
self
.
item_module
.
location
.
html_id
(),
'sources'
:
sources
,
'sources'
:
sources
,
'speed'
:
1.0
,
'start'
:
3603.0
,
'start'
:
3603.0
,
'sub'
:
u'a_sub_file.srt.sjson'
,
'sub'
:
u'a_sub_file.srt.sjson'
,
'track'
:
None
,
'track'
:
None
,
...
@@ -127,7 +132,7 @@ class TestVideoNonYouTube(TestVideo):
...
@@ -127,7 +132,7 @@ class TestVideoNonYouTube(TestVideo):
self
.
assertEqual
(
self
.
assertEqual
(
context
,
context
,
self
.
item_module
.
xmodule_runtime
.
render_template
(
'video.html'
,
expected_context
)
self
.
item_module
.
xmodule_runtime
.
render_template
(
'video.html'
,
expected_context
)
,
)
)
...
@@ -137,6 +142,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
...
@@ -137,6 +142,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
'''
'''
CATEGORY
=
"video"
CATEGORY
=
"video"
DATA
=
SOURCE_XML
DATA
=
SOURCE_XML
maxDiff
=
None
METADATA
=
{}
METADATA
=
{}
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -195,7 +201,8 @@ class TestGetHtmlMethod(BaseTestXmodule):
...
@@ -195,7 +201,8 @@ class TestGetHtmlMethod(BaseTestXmodule):
},
},
'start'
:
3603.0
,
'start'
:
3603.0
,
'sub'
:
u'a_sub_file.srt.sjson'
,
'sub'
:
u'a_sub_file.srt.sjson'
,
'track'
:
''
,
'speed'
:
1.0
,
'track'
:
None
,
'youtube_streams'
:
'1.00:OEoXaMPEzfM'
,
'youtube_streams'
:
'1.00:OEoXaMPEzfM'
,
'autoplay'
:
settings
.
FEATURES
.
get
(
'AUTOPLAY_VIDEOS'
,
True
),
'autoplay'
:
settings
.
FEATURES
.
get
(
'AUTOPLAY_VIDEOS'
,
True
),
'yt_test_timeout'
:
1500
,
'yt_test_timeout'
:
1500
,
...
@@ -212,16 +219,18 @@ class TestGetHtmlMethod(BaseTestXmodule):
...
@@ -212,16 +219,18 @@ class TestGetHtmlMethod(BaseTestXmodule):
self
.
initialize_module
(
data
=
DATA
)
self
.
initialize_module
(
data
=
DATA
)
track_url
=
self
.
item_descriptor
.
xmodule_runtime
.
handler_url
(
self
.
item_module
,
'download_transcript'
)
track_url
=
self
.
item_descriptor
.
xmodule_runtime
.
handler_url
(
self
.
item_module
,
'download_transcript'
)
context
=
self
.
item_module
.
render
(
'student_view'
)
.
content
expected_context
.
update
({
expected_context
.
update
({
'ajax_url'
:
self
.
item_descriptor
.
xmodule_runtime
.
ajax_url
+
'/save_user_state'
,
'track'
:
track_url
if
data
[
'expected_track_url'
]
==
u'a_sub_file.srt.sjson'
else
data
[
'expected_track_url'
],
'track'
:
track_url
if
data
[
'expected_track_url'
]
==
u'a_sub_file.srt.sjson'
else
data
[
'expected_track_url'
],
'sub'
:
data
[
'sub'
],
'sub'
:
data
[
'sub'
],
'id'
:
self
.
item_module
.
location
.
html_id
(),
'id'
:
self
.
item_module
.
location
.
html_id
(),
})
})
context
=
self
.
item_module
.
render
(
'student_view'
)
.
content
self
.
assertEqual
(
self
.
assertEqual
(
context
,
context
,
self
.
item_module
.
xmodule_runtime
.
render_template
(
'video.html'
,
expected_context
)
self
.
item_module
.
xmodule_runtime
.
render_template
(
'video.html'
,
expected_context
)
,
)
)
def
test_get_html_source
(
self
):
def
test_get_html_source
(
self
):
...
@@ -293,6 +302,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
...
@@ -293,6 +302,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
'end'
:
3610.0
,
'end'
:
3610.0
,
'id'
:
None
,
'id'
:
None
,
'sources'
:
None
,
'sources'
:
None
,
'speed'
:
1.0
,
'start'
:
3603.0
,
'start'
:
3603.0
,
'sub'
:
u'a_sub_file.srt.sjson'
,
'sub'
:
u'a_sub_file.srt.sjson'
,
'track'
:
None
,
'track'
:
None
,
...
@@ -309,14 +319,14 @@ class TestGetHtmlMethod(BaseTestXmodule):
...
@@ -309,14 +319,14 @@ class TestGetHtmlMethod(BaseTestXmodule):
sources
=
data
[
'sources'
]
sources
=
data
[
'sources'
]
)
)
self
.
initialize_module
(
data
=
DATA
)
self
.
initialize_module
(
data
=
DATA
)
context
=
self
.
item_module
.
render
(
'student_view'
)
.
content
expected_context
.
update
({
expected_context
.
update
({
'ajax_url'
:
self
.
item_descriptor
.
xmodule_runtime
.
ajax_url
+
'/save_user_state'
,
'sources'
:
data
[
'result'
],
'sources'
:
data
[
'result'
],
'id'
:
self
.
item_module
.
location
.
html_id
(),
'id'
:
self
.
item_module
.
location
.
html_id
(),
})
})
context
=
self
.
item_module
.
render
(
'student_view'
)
.
content
self
.
assertEqual
(
self
.
assertEqual
(
context
,
context
,
self
.
item_module
.
xmodule_runtime
.
render_template
(
'video.html'
,
expected_context
)
self
.
item_module
.
xmodule_runtime
.
render_template
(
'video.html'
,
expected_context
)
...
...
lms/djangoapps/courseware/tests/test_video_xml.py
View file @
1d748386
...
@@ -15,11 +15,7 @@ common/lib/xmodule/xmodule/modulestore/tests/factories.py to create the
...
@@ -15,11 +15,7 @@ common/lib/xmodule/xmodule/modulestore/tests/factories.py to create the
course, section, subsection, unit, etc.
course, section, subsection, unit, etc.
"""
"""
import
unittest
from
xmodule.video_module
import
VideoDescriptor
from
django.conf
import
settings
from
xmodule.video_module
import
VideoDescriptor
,
_create_youtube_string
from
xmodule.modulestore
import
Location
from
xmodule.modulestore
import
Location
from
xmodule.tests
import
get_test_system
,
LogicTest
,
get_test_descriptor_system
from
xmodule.tests
import
get_test_system
,
LogicTest
,
get_test_descriptor_system
from
xblock.field_data
import
DictFieldData
from
xblock.field_data
import
DictFieldData
...
@@ -63,40 +59,6 @@ class VideoFactory(object):
...
@@ -63,40 +59,6 @@ class VideoFactory(object):
return
descriptor
return
descriptor
class
VideoModuleUnitTest
(
unittest
.
TestCase
):
"""Unit tests for Video Xmodule."""
def
test_video_get_html
(
self
):
"""Make sure that all parameters extracted correclty from xml"""
module
=
VideoFactory
.
create
()
sources
=
{
'main'
:
'example.mp4'
,
'mp4'
:
'example.mp4'
,
'webm'
:
'example.webm'
,
}
expected_context
=
{
'caption_asset_path'
:
'/static/subs/'
,
'sub'
:
'a_sub_file.srt.sjson'
,
'data_dir'
:
getattr
(
self
,
'data_dir'
,
None
),
'display_name'
:
'A Name'
,
'end'
:
3610.0
,
'start'
:
3603.0
,
'id'
:
module
.
location
.
html_id
(),
'show_captions'
:
'true'
,
'sources'
:
sources
,
'youtube_streams'
:
_create_youtube_string
(
module
),
'track'
:
None
,
'autoplay'
:
settings
.
FEATURES
.
get
(
'AUTOPLAY_VIDEOS'
,
False
),
'yt_test_timeout'
:
1500
,
'yt_test_url'
:
'https://gdata.youtube.com/feeds/api/videos/'
}
self
.
assertEqual
(
module
.
render
(
'student_view'
)
.
content
,
module
.
runtime
.
render_template
(
'video.html'
,
expected_context
)
)
class
VideoModuleLogicTest
(
LogicTest
):
class
VideoModuleLogicTest
(
LogicTest
):
"""Tests for logic of Video Xmodule."""
"""Tests for logic of Video Xmodule."""
...
...
lms/templates/video.html
View file @
1d748386
...
@@ -17,8 +17,10 @@
...
@@ -17,8 +17,10 @@
${'
data-webm-source=
"{}"
'.
format
(
sources
.
get
('
webm
'))
if
sources
.
get
('
webm
')
else
''}
${'
data-webm-source=
"{}"
'.
format
(
sources
.
get
('
webm
'))
if
sources
.
get
('
webm
')
else
''}
${'
data-ogg-source=
"{}"
'.
format
(
sources
.
get
('
ogv
'))
if
sources
.
get
('
ogv
')
else
''}
${'
data-ogg-source=
"{}"
'.
format
(
sources
.
get
('
ogv
'))
if
sources
.
get
('
ogv
')
else
''}
data-save-state-url=
"${ajax_url}"
data-caption-data-dir=
"${data_dir}"
data-caption-data-dir=
"${data_dir}"
data-show-captions=
"${show_captions}"
data-show-captions=
"${show_captions}"
data-speed=
"${speed}"
data-start=
"${start}"
data-start=
"${start}"
data-end=
"${end}"
data-end=
"${end}"
data-caption-asset-path=
"${caption_asset_path}"
data-caption-asset-path=
"${caption_asset_path}"
...
@@ -108,5 +110,3 @@
...
@@ -108,5 +110,3 @@
% endif
% endif
</ul>
</ul>
</div>
</div>
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