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
81a5a7b9
Commit
81a5a7b9
authored
Jul 02, 2014
by
Muhammad Ammar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
CMS Video Handout Tests
parent
6fa96cf0
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
504 additions
and
75 deletions
+504
-75
cms/djangoapps/contentstore/features/video_handout.feature
+0
-71
common/test/acceptance/fixtures/course.py
+4
-3
common/test/acceptance/pages/studio/unit.py
+39
-0
common/test/acceptance/pages/studio/video/__init__.py
+0
-0
common/test/acceptance/pages/studio/video/video.py
+142
-0
common/test/acceptance/tests/video/test_studio_video_module.py
+117
-0
common/test/acceptance/tests/video/test_video_handout.py
+191
-0
common/test/data/uploads/.gitignore
+0
-1
common/test/data/uploads/asset.html
+11
-0
No files found.
cms/djangoapps/contentstore/features/video_handout.feature
deleted
100644 → 0
View file @
6fa96cf0
@shard_3
@requires_stub_youtube
Feature
:
CMS Video Component Handout
As a course author, I want to be able to create video handout
# 1
Scenario
:
Handout uploading works correctly
Given
I have created a Video component with handout file
"textbook.pdf"
And
I save changes
Then
I can see video button
"handout"
And
I can download handout file with mime type
"application/pdf"
# 2
Scenario
:
Handout downloading works correctly w/ preliminary saving
Given
I have created a Video component with handout file
"textbook.pdf"
And
I save changes
And
I edit the component
And
I open tab
"Advanced"
And
I can download handout file in editor with mime type
"application/pdf"
# 3
Scenario
:
Handout downloading works correctly w/o preliminary saving
Given
I have created a Video component with handout file
"textbook.pdf"
And
I can download handout file in editor with mime type
"application/pdf"
# 4
Scenario
:
Handout clearing works correctly w/ preliminary saving
Given
I have created a Video component with handout file
"textbook.pdf"
And
I save changes
And
I can download handout file with mime type
"application/pdf"
And
I edit the component
And
I open tab
"Advanced"
And
I clear handout
And
I save changes
Then
I do not see video button
"handout"
# 5
Scenario
:
Handout clearing works correctly w/o preliminary saving
Given
I have created a Video component with handout file
"asset.html"
And
I clear handout
And
I save changes
Then
I do not see video button
"handout"
# 6
Scenario
:
User can easy replace the handout by another one w/ preliminary saving
Given
I have created a Video component with handout file
"asset.html"
And
I save changes
Then
I can see video button
"handout"
And
I can download handout file with mime type
"text/html"
And
I edit the component
And
I open tab
"Advanced"
And
I replace handout file by
"textbook.pdf"
And
I save changes
Then
I can see video button
"handout"
And
I can download handout file with mime type
"application/pdf"
# 7
Scenario
:
User can easy replace the handout by another one w/o preliminary saving
Given
I have created a Video component with handout file
"asset.html"
And
I replace handout file by
"textbook.pdf"
And
I save changes
Then
I can see video button
"handout"
And
I can download handout file with mime type
"application/pdf"
# 8
Scenario
:
Upload file "A" -> Remove it -> Upload file "B"
Given
I have created a Video component with handout file
"asset.html"
And
I clear handout
And
I upload handout file
"textbook.pdf"
And
I save changes
Then
I can see video button
"handout"
And
I can download handout file with mime type
"application/pdf"
common/test/acceptance/fixtures/course.py
View file @
81a5a7b9
...
...
@@ -2,6 +2,7 @@
Fixture to create a course and course components (XBlocks).
"""
import
mimetypes
import
json
import
re
import
datetime
...
...
@@ -407,10 +408,10 @@ class CourseFixture(StudioApiFixture):
test_dir
=
path
(
__file__
)
.
abspath
()
.
dirname
()
.
dirname
()
.
dirname
()
for
asset_name
in
self
.
_assets
:
srt
_path
=
test_dir
+
'/data/uploads/'
+
asset_name
asset_file
_path
=
test_dir
+
'/data/uploads/'
+
asset_name
asset_file
=
open
(
srt
_path
)
files
=
{
'file'
:
(
asset_name
,
asset_file
)}
asset_file
=
open
(
asset_file
_path
)
files
=
{
'file'
:
(
asset_name
,
asset_file
,
mimetypes
.
guess_type
(
asset_file_path
)[
0
]
)}
headers
=
{
'Accept'
:
'application/json'
,
...
...
common/test/acceptance/pages/studio/unit.py
View file @
81a5a7b9
...
...
@@ -62,6 +62,22 @@ class UnitPage(PageObject):
'Wait for draft mode to be activated'
)
.
fulfill
()
def
set_unit_visibility
(
self
,
visibility
):
"""
Set unit visibility state
Arguments:
visibility (str): private or public
"""
self
.
q
(
css
=
'select[name="visibility-select"] option[value="{}"]'
.
format
(
visibility
))
.
first
.
click
()
self
.
wait_for_ajax
()
COMPONENT_BUTTONS
=
{
'advanced_tab'
:
'.editor-tabs li.inner_tab_wrap:nth-child(2) > a'
,
'save_settings'
:
'.action-save'
,
}
class
Component
(
PageObject
):
"""
...
...
@@ -125,3 +141,26 @@ class Component(PageObject):
an initialized :class:`.ContainerPage` for that xblock.
"""
return
ContainerPage
(
self
.
browser
,
self
.
locator
)
.
visit
()
def
_click_button
(
self
,
button_name
):
"""
Click on a button as specified by `button_name`
Arguments:
button_name (str): button name
"""
self
.
q
(
css
=
COMPONENT_BUTTONS
[
button_name
])
.
first
.
click
()
self
.
wait_for_ajax
()
def
open_advanced_tab
(
self
):
"""
Click on Advanced Tab.
"""
self
.
_click_button
(
'advanced_tab'
)
def
save_settings
(
self
):
"""
Click on settings Save button.
"""
self
.
_click_button
(
'save_settings'
)
common/test/acceptance/pages/studio/video/__init__.py
0 → 100644
View file @
81a5a7b9
common/test/acceptance/pages/studio/video/video.py
0 → 100644
View file @
81a5a7b9
"""
CMS Video
"""
import
os
import
requests
from
bok_choy.page_object
import
PageObject
from
bok_choy.promise
import
EmptyPromise
,
Promise
from
bok_choy.javascript
import
wait_for_js
,
js_defined
CLASS_SELECTORS
=
{
'video_init'
:
'.is-initialized'
,
'video_xmodule'
:
'.xmodule_VideoModule'
,
'video_spinner'
:
'.video-wrapper .spinner'
,
'video_controls'
:
'section.video-controls'
,
'attach_handout'
:
'.upload-dialog > input[type="file"]'
,
'upload_dialog'
:
'.wrapper-modal-window-assetupload'
,
}
BUTTON_SELECTORS
=
{
'handout_download'
:
'.video-handout.video-download-button a'
,
'handout_download_editor'
:
'.wrapper-comp-setting.file-uploader .download-action'
,
'upload_handout'
:
'.upload-action'
,
'handout_submit'
:
'.action-upload'
,
'handout_clear'
:
'.wrapper-comp-setting.file-uploader .setting-clear'
,
}
@js_defined
(
'window.Video'
,
'window.RequireJS.require'
,
'window.jQuery'
,
'window.XModule'
,
'window.XBlock'
,
'window.MathJax.isReady'
)
class
VidoComponentPage
(
PageObject
):
"""
CMS Video Component Page
"""
url
=
None
@wait_for_js
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
'div{0}'
.
format
(
CLASS_SELECTORS
[
'video_xmodule'
]))
.
present
def
_wait_for
(
self
,
check_func
,
desc
,
result
=
False
,
timeout
=
200
):
"""
Calls the method provided as an argument until the Promise satisfied or BrokenPromise
Arguments:
check_func (callable): Promise function to be fulfilled.
desc (str): Description of the Promise, used in log messages.
result (bool): Indicates whether we need result from Promise or not
timeout (float): Maximum number of seconds to wait for the Promise to be satisfied before timing out.
"""
if
result
:
return
Promise
(
check_func
,
desc
,
timeout
=
timeout
)
.
fulfill
()
else
:
return
EmptyPromise
(
check_func
,
desc
,
timeout
=
timeout
)
.
fulfill
()
def
wait_for_video_component_render
(
self
):
"""
Wait until video component rendered completely
"""
self
.
_wait_for
(
lambda
:
self
.
q
(
css
=
CLASS_SELECTORS
[
'video_init'
])
.
present
,
'Video Player Initialized'
)
self
.
_wait_for
(
lambda
:
not
self
.
q
(
css
=
CLASS_SELECTORS
[
'video_spinner'
])
.
visible
,
'Video Buffering Completed'
)
self
.
_wait_for
(
lambda
:
self
.
q
(
css
=
CLASS_SELECTORS
[
'video_controls'
])
.
visible
,
'Player Controls are Visible'
)
def
click_button
(
self
,
button_name
):
"""
Click on a button as specified by `button_name`
Arguments:
button_name (str): button name
"""
self
.
q
(
css
=
BUTTON_SELECTORS
[
button_name
])
.
first
.
click
()
self
.
wait_for_ajax
()
def
upload_handout
(
self
,
handout_filename
):
"""
Upload a handout file to assets
Arguments:
handout_filename (str): handout file name
"""
handout_path
=
os
.
sep
.
join
(
__file__
.
split
(
os
.
sep
)[:
-
5
])
+
'/data/uploads/'
+
handout_filename
self
.
click_button
(
'upload_handout'
)
self
.
q
(
css
=
CLASS_SELECTORS
[
'attach_handout'
])
.
results
[
0
]
.
send_keys
(
handout_path
)
self
.
click_button
(
'handout_submit'
)
# confirm upload completion
self
.
_wait_for
(
lambda
:
not
self
.
q
(
css
=
CLASS_SELECTORS
[
'upload_dialog'
])
.
present
,
'Upload Handout Completed'
)
def
clear_handout
(
self
):
"""
Clear handout from settings
"""
self
.
click_button
(
'handout_clear'
)
def
_get_handout
(
self
,
url
):
"""
Download handout at `url`
"""
kwargs
=
dict
()
session_id
=
[{
i
[
'name'
]:
i
[
'value'
]}
for
i
in
self
.
browser
.
get_cookies
()
if
i
[
'name'
]
==
u'sessionid'
]
if
session_id
:
kwargs
.
update
({
'cookies'
:
session_id
[
0
]
})
response
=
requests
.
get
(
url
,
**
kwargs
)
return
response
.
status_code
<
400
,
response
.
headers
def
download_handout
(
self
,
mime_type
,
is_editor
=
False
):
"""
Download handout with mime type specified by `mime_type`
Arguments:
mime_type (str): mime type of handout file
Returns:
tuple: Handout download result.
"""
selector
=
BUTTON_SELECTORS
[
'handout_download_editor'
]
if
is_editor
else
BUTTON_SELECTORS
[
'handout_download'
]
handout_url
=
self
.
q
(
css
=
selector
)
.
attrs
(
'href'
)[
0
]
result
,
headers
=
self
.
_get_handout
(
handout_url
)
return
result
,
headers
[
'content-type'
]
==
mime_type
@property
def
is_handout_button_visible
(
self
):
"""
Check if handout download button is visible
"""
# TODO! Remove .present below after bok-choy is updated to latest commit, Only .visible is enough
return
self
.
q
(
css
=
BUTTON_SELECTORS
[
'handout_download'
])
.
present
and
self
.
q
(
css
=
BUTTON_SELECTORS
[
'handout_download'
])
.
visible
common/test/acceptance/tests/video/test_studio_video_module.py
0 → 100644
View file @
81a5a7b9
# -*- coding: utf-8 -*-
"""
Acceptance tests for CMS Video Module.
"""
from
unittest
import
skipIf
from
...pages.studio.auto_auth
import
AutoAuthPage
from
...pages.studio.overview
import
CourseOutlinePage
from
...pages.studio.video.video
import
VidoComponentPage
from
...fixtures.course
import
CourseFixture
,
XBlockFixtureDesc
from
..helpers
import
UniqueCourseTest
,
is_youtube_available
@skipIf
(
is_youtube_available
()
is
False
,
'YouTube is not available!'
)
class
CMSVideoBaseTest
(
UniqueCourseTest
):
"""
CMS Video Module Base Test Class
"""
def
setUp
(
self
):
"""
Initialization of pages and course fixture for tests
"""
super
(
CMSVideoBaseTest
,
self
)
.
setUp
()
self
.
video
=
VidoComponentPage
(
self
.
browser
)
# This will be initialized later
self
.
unit_page
=
None
self
.
outline
=
CourseOutlinePage
(
self
.
browser
,
self
.
course_info
[
'org'
],
self
.
course_info
[
'number'
],
self
.
course_info
[
'run'
]
)
self
.
course_fixture
=
CourseFixture
(
self
.
course_info
[
'org'
],
self
.
course_info
[
'number'
],
self
.
course_info
[
'run'
],
self
.
course_info
[
'display_name'
]
)
def
_install_course_fixture
(
self
):
"""
Prepare for tests by creating a course with a section, subsection, and unit.
Performs the following:
Create a course with a section, subsection, and unit
Create a user and make that user a course author
Log the user into studio
"""
# Create course with Video component
self
.
course_fixture
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
"vertical"
,
"Test Unit"
)
.
add_children
(
XBlockFixtureDesc
(
'video'
,
'Video'
),
)
)
)
)
.
install
()
# Auto login and register the course
AutoAuthPage
(
self
.
browser
,
staff
=
False
,
username
=
self
.
course_fixture
.
user
.
get
(
'username'
),
email
=
self
.
course_fixture
.
user
.
get
(
'email'
),
password
=
self
.
course_fixture
.
user
.
get
(
'password'
)
)
.
visit
()
def
_navigate_to_course_unit_page
(
self
):
"""
Open the course from the dashboard and expand the section and subsection and click on the Unit link
The end result is the page where the user is editing the newly created unit
"""
# Visit Course Outline page
self
.
outline
.
visit
()
# Visit Unit page
self
.
unit_page
=
self
.
outline
.
section
(
'Test Section'
)
.
subsection
(
'Test Subsection'
)
.
toggle_expand
()
.
unit
(
'Test Unit'
)
.
go_to
()
self
.
video
.
wait_for_video_component_render
()
def
navigate_to_course_unit
(
self
):
"""
Install the course with required components and navigate to course unit page
"""
self
.
_install_course_fixture
()
self
.
_navigate_to_course_unit_page
()
def
edit_component
(
self
):
"""
Make component editable and open components Edit Dialog.
Arguments:
handout_filename (str): handout file name to be uploaded
save_settings (bool): save settings or not
"""
self
.
unit_page
.
set_unit_visibility
(
'private'
)
self
.
unit_page
.
components
[
0
]
.
edit
()
def
open_advanced_tab
(
self
):
"""
Open components advanced tab.
"""
self
.
unit_page
.
components
[
0
]
.
open_advanced_tab
()
def
save_unit_settings
(
self
):
"""
Save component settings.
"""
self
.
unit_page
.
components
[
0
]
.
save_settings
()
common/test/acceptance/tests/video/test_video_handout.py
0 → 100644
View file @
81a5a7b9
# -*- coding: utf-8 -*-
"""
Acceptance tests for CMS Video Handout.
"""
from
.test_studio_video_module
import
CMSVideoBaseTest
class
VideoHandoutTest
(
CMSVideoBaseTest
):
"""
CMS Video Handout Test Class
"""
def
setUp
(
self
):
super
(
VideoHandoutTest
,
self
)
.
setUp
()
def
_create_course_unit_with_handout
(
self
,
handout_filename
,
save_settings
=
True
):
"""
Create a course with unit and also upload handout
Arguments:
handout_filename (str): handout file name to be uploaded
save_settings (bool): save settings or not
"""
self
.
navigate_to_course_unit
()
self
.
edit_component
()
self
.
open_advanced_tab
()
self
.
video
.
upload_handout
(
handout_filename
)
if
save_settings
:
self
.
save_unit_settings
()
def
test_handout_uploads_correctly
(
self
):
"""
Scenario: Handout uploading works correctly
Given I have created a Video component with handout file "textbook.pdf"
Then I can see video button "handout"
And I can download handout file with mime type "application/pdf"
"""
self
.
_create_course_unit_with_handout
(
'textbook.pdf'
)
self
.
assertTrue
(
self
.
video
.
is_handout_button_visible
)
self
.
assertEqual
(
self
.
video
.
download_handout
(
'application/pdf'
),
(
True
,
True
))
def
test_handout_download_works_with_save
(
self
):
"""
Scenario: Handout downloading works correctly w/ preliminary saving
Given I have created a Video component with handout file "textbook.pdf"
And I save changes
And I edit the component
And I open tab "Advanced"
And I can download handout file in editor with mime type "application/pdf"
"""
self
.
_create_course_unit_with_handout
(
'textbook.pdf'
)
self
.
edit_component
()
self
.
open_advanced_tab
()
self
.
assertEqual
(
self
.
video
.
download_handout
(
'application/pdf'
,
is_editor
=
True
),
(
True
,
True
))
def
test_handout_download_works_wo_save
(
self
):
"""
Scenario: Handout downloading works correctly w/o preliminary saving
Given I have created a Video component with handout file "textbook.pdf"
And I can download handout file in editor with mime type "application/pdf"
"""
self
.
_create_course_unit_with_handout
(
'textbook.pdf'
,
save_settings
=
False
)
self
.
assertEqual
(
self
.
video
.
download_handout
(
'application/pdf'
,
is_editor
=
True
),
(
True
,
True
))
def
test_handout_clearing_works_w_save
(
self
):
"""
Scenario: Handout clearing works correctly w/ preliminary saving
Given I have created a Video component with handout file "textbook.pdf"
And I save changes
And I can download handout file with mime type "application/pdf"
And I edit the component
And I open tab "Advanced"
And I clear handout
And I save changes
Then I do not see video button "handout"
"""
self
.
_create_course_unit_with_handout
(
'textbook.pdf'
)
self
.
assertEqual
(
self
.
video
.
download_handout
(
'application/pdf'
),
(
True
,
True
))
self
.
edit_component
()
self
.
open_advanced_tab
()
self
.
video
.
clear_handout
()
self
.
save_unit_settings
()
self
.
assertFalse
(
self
.
video
.
is_handout_button_visible
)
def
test_handout_clearing_works_wo_save
(
self
):
"""
Scenario: Handout clearing works correctly w/o preliminary saving
Given I have created a Video component with handout file "asset.html"
And I clear handout
And I save changes
Then I do not see video button "handout"
"""
self
.
_create_course_unit_with_handout
(
'asset.html'
,
save_settings
=
False
)
self
.
video
.
clear_handout
()
self
.
save_unit_settings
()
self
.
assertFalse
(
self
.
video
.
is_handout_button_visible
)
def
test_handout_replace_w_save
(
self
):
"""
Scenario: User can easy replace the handout by another one w/ preliminary saving
Given I have created a Video component with handout file "asset.html"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "text/html"
And I edit the component
And I open tab "Advanced"
And I replace handout file by "textbook.pdf"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "application/pdf"
"""
self
.
_create_course_unit_with_handout
(
'asset.html'
)
self
.
assertTrue
(
self
.
video
.
is_handout_button_visible
)
self
.
assertEqual
(
self
.
video
.
download_handout
(
'text/html'
),
(
True
,
True
))
self
.
edit_component
()
self
.
open_advanced_tab
()
self
.
video
.
upload_handout
(
'textbook.pdf'
)
self
.
save_unit_settings
()
self
.
assertTrue
(
self
.
video
.
is_handout_button_visible
)
self
.
assertEqual
(
self
.
video
.
download_handout
(
'application/pdf'
),
(
True
,
True
))
def
test_handout_replace_wo_save
(
self
):
"""
Scenario: User can easy replace the handout by another one w/o preliminary saving
Given I have created a Video component with handout file "asset.html"
And I replace handout file by "textbook.pdf"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "application/pdf"
"""
self
.
_create_course_unit_with_handout
(
'asset.html'
,
save_settings
=
False
)
self
.
video
.
upload_handout
(
'textbook.pdf'
)
self
.
save_unit_settings
()
self
.
assertTrue
(
self
.
video
.
is_handout_button_visible
)
self
.
assertEqual
(
self
.
video
.
download_handout
(
'application/pdf'
),
(
True
,
True
))
def
test_handout_upload_and_clear_works
(
self
):
"""
Scenario: Upload file "A" -> Remove it -> Upload file "B"
Given I have created a Video component with handout file "asset.html"
And I clear handout
And I upload handout file "textbook.pdf"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "application/pdf"
"""
self
.
_create_course_unit_with_handout
(
'asset.html'
,
save_settings
=
False
)
self
.
video
.
clear_handout
()
self
.
video
.
upload_handout
(
'textbook.pdf'
)
self
.
save_unit_settings
()
self
.
assertTrue
(
self
.
video
.
is_handout_button_visible
)
self
.
assertEqual
(
self
.
video
.
download_handout
(
'application/pdf'
),
(
True
,
True
))
common/test/data/uploads/.gitignore
View file @
81a5a7b9
test
test2
asset.html
common/test/data/uploads/asset.html
0 → 100644
View file @
81a5a7b9
<!DOCTYPE html>
<html>
<head>
<title>
ASSET
</title>
</head>
<body>
<div>
i am a dummy asset file
</div>
</body>
</html>
\ No newline at end of file
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