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
64e8f9c0
Commit
64e8f9c0
authored
Jan 10, 2013
by
Jay Zoldak
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add BDD lettuce tests for studio overview toggle section feature.
parent
c74605ab
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
296 additions
and
12 deletions
+296
-12
cms/djangoapps/contentstore/features/common.py
+10
-6
cms/djangoapps/contentstore/features/studio-overview-togglesection.feature
+60
-0
cms/djangoapps/contentstore/features/studio-overview-togglesection.py
+105
-0
lms/djangoapps/terrain/factories.py
+121
-6
No files found.
cms/djangoapps/contentstore/features/common.py
View file @
64e8f9c0
...
...
@@ -41,11 +41,14 @@ def i_press_the_category_delete_icon(step, category):
####### HELPER FUNCTIONS ##############
def
create_studio_user
(
uname
=
'robot'
,
em
=
'robot+studio@edx.org'
,
password
=
'test'
):
email
=
'robot+studio@edx.org'
,
password
=
'test'
,
is_staff
=
False
):
studio_user
=
UserFactory
.
build
(
username
=
uname
,
email
=
em
)
email
=
email
,
password
=
password
,
is_staff
=
is_staff
)
studio_user
.
set_password
(
password
)
studio_user
.
save
()
...
...
@@ -91,11 +94,12 @@ def fill_in_course_info(
def
log_into_studio
(
uname
=
'robot'
,
email
=
'robot+studio@edx.org'
,
password
=
'test'
):
create_studio_user
(
uname
,
email
)
password
=
'test'
,
is_staff
=
False
):
create_studio_user
(
uname
=
uname
,
email
=
email
,
is_staff
=
is_staff
)
world
.
browser
.
cookies
.
delete
()
world
.
browser
.
visit
(
django_url
(
'/'
))
world
.
browser
.
is_element_present_by_css
(
'body.no-header'
,
10
)
world
.
browser
.
is_element_present_by_css
(
'body.no-header'
,
10
)
login_form
=
world
.
browser
.
find_by_css
(
'form#login_form'
)
login_form
.
find_by_name
(
'email'
)
.
fill
(
email
)
...
...
cms/djangoapps/contentstore/features/studio-overview-togglesection.feature
0 → 100644
View file @
64e8f9c0
Feature
:
Overview Toggle Section
In order to quickly view the details of a course's section or to scan the inventory of sections
As a course author
I want to toggle the visibility of each section's subsection details in the overview listing
Scenario
:
The default layout for the overview page is to show sections in expanded view
Given
I have a course with multiple sections
When
I navigate to the course overview page
Then
I see the
"Collapse All Sections"
link
And
all sections are expanded
Scenario
:
Expand/collapse for a course with no sections
Given
I have a course with no sections
When
I navigate to the course overview page
Then
I do not see the
"Collapse All Sections"
link
Scenario
:
Collapse link appears after creating first section of a course
Given
I have a course with no sections
When
I navigate to the course overview page
And
I add a section
Then
I see the
"Collapse All Sections"
link
And
all sections are expanded
Scenario
:
Collapse link is removed after last section of a course is deleted
Given
I have a course with 1 section
And
I navigate to the course overview page
When
I press the
"section"
delete icon
And
I confirm the alert
Then
I do not see the
"Collapse All Sections"
link
Scenario
:
Collapsing all sections when all sections are expanded
Given
I navigate to the courseware page of a course with multiple sections
And
all sections are expanded
When
I click the
"Collapse All Sections"
link
Then
I see the
"Expand All Sections"
link
And
all sections are collapsed
Scenario
:
Collapsing all sections when 1 or more sections are already collapsed
Given
I navigate to the courseware page of a course with multiple sections
And
all sections are expanded
When
I collapse the first section
And
I click the
"Collapse All Sections"
link
Then
I see the
"Expand All Sections"
link
And
all sections are collapsed
Scenario
:
Expanding all sections when all sections are collapsed
Given
I navigate to the courseware page of a course with multiple sections
And
I click the
"Collapse All Sections"
link
When
I click the
"Expand All Sections"
link
Then
I see the
"Collapse All Sections"
link
And
all sections are expanded
Scenario
:
Expanding all sections when 1 or more sections are already expanded
Given
I navigate to the courseware page of a course with multiple sections
And
I click the
"Collapse All Sections"
link
When
I expand the first section
And
I click the
"Expand All Sections"
link
Then
I see the
"Collapse All Sections"
link
And
all sections are expanded
\ No newline at end of file
cms/djangoapps/contentstore/features/studio-overview-togglesection.py
0 → 100644
View file @
64e8f9c0
from
lettuce
import
world
,
step
from
terrain.factories
import
*
from
common
import
*
from
nose.tools
import
assert_true
,
assert_false
,
assert_equal
from
logging
import
getLogger
logger
=
getLogger
(
__name__
)
@step
(
u'I have a course with no sections$'
)
def
have_a_course
(
step
):
clear_courses
()
course
=
CourseFactory
.
create
()
@step
(
u'I have a course with 1 section$'
)
def
have_a_course_with_1_section
(
step
):
clear_courses
()
course
=
CourseFactory
.
create
()
section
=
ItemFactory
.
create
(
parent_location
=
course
.
location
)
subsection1
=
ItemFactory
.
create
(
parent_location
=
section
.
location
,
template
=
'i4x://edx/templates/sequential/Empty'
,
display_name
=
'Subsection One'
,)
@step
(
u'I have a course with multiple sections$'
)
def
have_a_course_with_two_sections
(
step
):
clear_courses
()
course
=
CourseFactory
.
create
()
section
=
ItemFactory
.
create
(
parent_location
=
course
.
location
)
subsection1
=
ItemFactory
.
create
(
parent_location
=
section
.
location
,
template
=
'i4x://edx/templates/sequential/Empty'
,
display_name
=
'Subsection One'
,)
section2
=
ItemFactory
.
create
(
parent_location
=
course
.
location
,
display_name
=
'Section Two'
,)
subsection2
=
ItemFactory
.
create
(
parent_location
=
section2
.
location
,
template
=
'i4x://edx/templates/sequential/Empty'
,
display_name
=
'Subsection Alpha'
,)
subsection3
=
ItemFactory
.
create
(
parent_location
=
section2
.
location
,
template
=
'i4x://edx/templates/sequential/Empty'
,
display_name
=
'Subsection Beta'
,)
@step
(
u'I navigate to the course overview page$'
)
def
navigate_to_the_course_overview_page
(
step
):
log_into_studio
(
is_staff
=
True
)
course_locator
=
'.class-name'
css_click
(
course_locator
)
@step
(
u'I navigate to the courseware page of a course with multiple sections'
)
def
nav_to_the_courseware_page_of_a_course_with_multiple_sections
(
step
):
step
.
given
(
'I have a course with multiple sections'
)
step
.
given
(
'I navigate to the course overview page'
)
@step
(
u'I add a section'
)
def
i_add_a_section
(
step
):
add_section
(
name
=
'My New Section That I Just Added'
)
@step
(
u'I click the "([^"]*)" link$'
)
def
i_click_the_text_span
(
step
,
text
):
span_locator
=
'.toggle-button-sections span'
assert_true
(
world
.
browser
.
is_element_present_by_css
(
span_locator
,
5
))
# first make sure that the expand/collapse text is the one you expected
assert_equal
(
world
.
browser
.
find_by_css
(
span_locator
)
.
value
,
text
)
css_click
(
span_locator
)
@step
(
u'I collapse the first section$'
)
def
i_collapse_a_section
(
step
):
collapse_locator
=
'section.courseware-section a.collapse'
css_click
(
collapse_locator
)
@step
(
u'I expand the first section$'
)
def
i_expand_a_section
(
step
):
expand_locator
=
'section.courseware-section a.expand'
css_click
(
expand_locator
)
@step
(
u'I see the "([^"]*)" link$'
)
def
i_see_the_span_with_text
(
step
,
text
):
span_locator
=
'.toggle-button-sections span'
assert_true
(
world
.
browser
.
is_element_present_by_css
(
span_locator
,
5
))
assert_equal
(
world
.
browser
.
find_by_css
(
span_locator
)
.
value
,
text
)
assert_true
(
world
.
browser
.
find_by_css
(
span_locator
)
.
visible
)
@step
(
u'I do not see the "([^"]*)" link$'
)
def
i_do_not_see_the_span_with_text
(
step
,
text
):
# Note that the span will exist on the page but not be visible
span_locator
=
'.toggle-button-sections span'
assert_true
(
world
.
browser
.
is_element_present_by_css
(
span_locator
))
assert_false
(
world
.
browser
.
find_by_css
(
span_locator
)
.
visible
)
@step
(
u'all sections are expanded$'
)
def
all_sections_are_expanded
(
step
):
subsection_locator
=
'div.subsection-list'
subsections
=
world
.
browser
.
find_by_css
(
subsection_locator
)
for
s
in
subsections
:
assert_true
(
s
.
visible
)
@step
(
u'all sections are collapsed$'
)
def
all_sections_are_expanded
(
step
):
subsection_locator
=
'div.subsection-list'
subsections
=
world
.
browser
.
find_by_css
(
subsection_locator
)
for
s
in
subsections
:
assert_false
(
s
.
visible
)
\ No newline at end of file
lms/djangoapps/terrain/factories.py
View file @
64e8f9c0
import
factory
from
student.models
import
User
,
UserProfile
,
Registration
from
datetime
import
datetime
import
uuid
from
factory
import
Factory
from
xmodule.modulestore
import
Location
from
xmodule.modulestore.django
import
modulestore
from
time
import
gmtime
from
uuid
import
uuid4
from
xmodule.timeparse
import
stringify_time
class
UserProfileFactory
(
factory
.
Factory
):
class
UserProfileFactory
(
Factory
):
FACTORY_FOR
=
UserProfile
user
=
None
...
...
@@ -13,13 +17,13 @@ class UserProfileFactory(factory.Factory):
mailing_address
=
None
goals
=
'World domination'
class
RegistrationFactory
(
factory
.
Factory
):
class
RegistrationFactory
(
Factory
):
FACTORY_FOR
=
Registration
user
=
None
activation_key
=
uuid
.
uuid
4
()
.
hex
activation_key
=
uuid4
()
.
hex
class
UserFactory
(
factory
.
Factory
):
class
UserFactory
(
Factory
):
FACTORY_FOR
=
User
username
=
'robot'
...
...
@@ -32,3 +36,113 @@ class UserFactory(factory.Factory):
is_superuser
=
False
last_login
=
datetime
(
2012
,
1
,
1
)
date_joined
=
datetime
(
2011
,
1
,
1
)
def
XMODULE_COURSE_CREATION
(
class_to_create
,
**
kwargs
):
return
XModuleCourseFactory
.
_create
(
class_to_create
,
**
kwargs
)
def
XMODULE_ITEM_CREATION
(
class_to_create
,
**
kwargs
):
return
XModuleItemFactory
.
_create
(
class_to_create
,
**
kwargs
)
class
XModuleCourseFactory
(
Factory
):
"""
Factory for XModule courses.
"""
ABSTRACT_FACTORY
=
True
_creation_function
=
(
XMODULE_COURSE_CREATION
,)
@classmethod
def
_create
(
cls
,
target_class
,
*
args
,
**
kwargs
):
template
=
Location
(
'i4x'
,
'edx'
,
'templates'
,
'course'
,
'Empty'
)
org
=
kwargs
.
get
(
'org'
)
number
=
kwargs
.
get
(
'number'
)
display_name
=
kwargs
.
get
(
'display_name'
)
location
=
Location
(
'i4x'
,
org
,
number
,
'course'
,
Location
.
clean
(
display_name
))
store
=
modulestore
(
'direct'
)
# Write the data to the mongo datastore
new_course
=
store
.
clone_item
(
template
,
location
)
# This metadata code was copied from cms/djangoapps/contentstore/views.py
if
display_name
is
not
None
:
new_course
.
metadata
[
'display_name'
]
=
display_name
new_course
.
metadata
[
'data_dir'
]
=
uuid4
()
.
hex
new_course
.
metadata
[
'start'
]
=
stringify_time
(
gmtime
())
new_course
.
tabs
=
[{
"type"
:
"courseware"
},
{
"type"
:
"course_info"
,
"name"
:
"Course Info"
},
{
"type"
:
"discussion"
,
"name"
:
"Discussion"
},
{
"type"
:
"wiki"
,
"name"
:
"Wiki"
},
{
"type"
:
"progress"
,
"name"
:
"Progress"
}]
# Update the data in the mongo datastore
store
.
update_metadata
(
new_course
.
location
.
url
(),
new_course
.
own_metadata
)
return
new_course
class
Course
:
pass
class
CourseFactory
(
XModuleCourseFactory
):
FACTORY_FOR
=
Course
template
=
'i4x://edx/templates/course/Empty'
org
=
'MITx'
number
=
'999'
display_name
=
'Robot Super Course'
class
XModuleItemFactory
(
Factory
):
"""
Factory for XModule items.
"""
ABSTRACT_FACTORY
=
True
_creation_function
=
(
XMODULE_ITEM_CREATION
,)
@classmethod
def
_create
(
cls
,
target_class
,
*
args
,
**
kwargs
):
"""
kwargs must include parent_location, template. Can contain display_name
target_class is ignored
"""
DETACHED_CATEGORIES
=
[
'about'
,
'static_tab'
,
'course_info'
]
parent_location
=
Location
(
kwargs
.
get
(
'parent_location'
))
template
=
Location
(
kwargs
.
get
(
'template'
))
display_name
=
kwargs
.
get
(
'display_name'
)
store
=
modulestore
(
'direct'
)
# This code was based off that in cms/djangoapps/contentstore/views.py
parent
=
store
.
get_item
(
parent_location
)
dest_location
=
parent_location
.
_replace
(
category
=
template
.
category
,
name
=
uuid4
()
.
hex
)
new_item
=
store
.
clone_item
(
template
,
dest_location
)
# TODO: This needs to be deleted when we have proper storage for static content
new_item
.
metadata
[
'data_dir'
]
=
parent
.
metadata
[
'data_dir'
]
# replace the display name with an optional parameter passed in from the caller
if
display_name
is
not
None
:
new_item
.
metadata
[
'display_name'
]
=
display_name
store
.
update_metadata
(
new_item
.
location
.
url
(),
new_item
.
own_metadata
)
if
new_item
.
location
.
category
not
in
DETACHED_CATEGORIES
:
store
.
update_children
(
parent_location
,
parent
.
definition
.
get
(
'children'
,
[])
+
[
new_item
.
location
.
url
()])
return
new_item
class
Item
:
pass
class
ItemFactory
(
XModuleItemFactory
):
FACTORY_FOR
=
Item
parent_location
=
'i4x://MITx/999/course/Robot_Super_Course'
template
=
'i4x://edx/templates/chapter/Empty'
display_name
=
'Section One'
\ 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