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
9b54e44b
Commit
9b54e44b
authored
Feb 21, 2014
by
Calen Pennington
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2602 from cpennington/xblock-acid-child-tests
Add tests of the frontend children api using the AcidXBlock
parents
29857036
dbc99ef8
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
279 additions
and
109 deletions
+279
-109
cms/djangoapps/contentstore/views/item.py
+10
-1
cms/djangoapps/contentstore/views/preview.py
+2
-1
cms/static/coffee/src/xblock/cms.runtime.v1.coffee
+2
-2
common/lib/xmodule/xmodule/tests/__init__.py
+1
-0
common/lib/xmodule/xmodule/x_module.py
+5
-2
common/static/coffee/spec/xblock/core_spec.coffee
+2
-2
common/static/coffee/spec/xblock/runtime.v1_spec.coffee
+5
-4
common/static/coffee/src/xblock/core.coffee
+2
-1
common/static/coffee/src/xblock/runtime.v1.coffee
+5
-4
common/test/acceptance/fixtures/course.py
+40
-31
common/test/acceptance/pages/studio/unit.py
+25
-13
common/test/acceptance/pages/xblock/acid.py
+10
-0
common/test/acceptance/tests/test_lms.py
+69
-19
common/test/acceptance/tests/test_studio.py
+84
-22
lms/djangoapps/courseware/module_render.py
+3
-3
lms/djangoapps/courseware/tests/test_module_render.py
+4
-0
lms/djangoapps/open_ended_grading/open_ended_notifications.py
+2
-0
lms/djangoapps/open_ended_grading/staff_grading_service.py
+1
-0
lms/djangoapps/open_ended_grading/tests.py
+1
-0
lms/djangoapps/open_ended_grading/utils.py
+1
-0
lms/lib/xblock/test/test_runtime.py
+1
-0
lms/static/coffee/src/xblock/lms.runtime.v1.coffee
+2
-2
requirements/edx/github.txt
+2
-2
No files found.
cms/djangoapps/contentstore/views/item.py
View file @
9b54e44b
...
@@ -316,9 +316,18 @@ def _save_item(request, usage_loc, item_location, data=None, children=None, meta
...
@@ -316,9 +316,18 @@ def _save_item(request, usage_loc, item_location, data=None, children=None, meta
# Make public after updating the xblock, in case the caller asked
# Make public after updating the xblock, in case the caller asked
# for both an update and a publish.
# for both an update and a publish.
if
publish
and
publish
==
'make_public'
:
if
publish
and
publish
==
'make_public'
:
def
_publish
(
block
):
# This is super gross, but prevents us from publishing something that
# we shouldn't. Ideally, all modulestores would have a consistant
# interface for publishing. However, as of now, only the DraftMongoModulestore
# does, so we have to check for the attribute explicitly.
store
=
get_modulestore
(
block
.
location
)
if
hasattr
(
store
,
'publish'
):
store
.
publish
(
block
.
location
,
request
.
user
.
id
)
_xmodule_recurse
(
_xmodule_recurse
(
existing_item
,
existing_item
,
lambda
i
:
modulestore
()
.
publish
(
i
.
location
,
request
.
user
.
id
)
_publish
)
)
# Note that children aren't being returned until we have a use case.
# Note that children aren't being returned until we have a use case.
...
...
cms/djangoapps/contentstore/views/preview.py
View file @
9b54e44b
...
@@ -131,6 +131,7 @@ def _preview_module_system(request, descriptor):
...
@@ -131,6 +131,7 @@ def _preview_module_system(request, descriptor):
# get_user_role accepts a location or a CourseLocator.
# get_user_role accepts a location or a CourseLocator.
# If descriptor.location is a CourseLocator, course_id is unused.
# If descriptor.location is a CourseLocator, course_id is unused.
get_user_role
=
lambda
:
get_user_role
(
request
.
user
,
descriptor
.
location
,
course_id
),
get_user_role
=
lambda
:
get_user_role
(
request
.
user
,
descriptor
.
location
,
course_id
),
descriptor_runtime
=
descriptor
.
runtime
,
)
)
...
@@ -158,6 +159,6 @@ def get_preview_fragment(request, descriptor):
...
@@ -158,6 +159,6 @@ def get_preview_fragment(request, descriptor):
try
:
try
:
fragment
=
module
.
render
(
"student_view"
)
fragment
=
module
.
render
(
"student_view"
)
except
Exception
as
exc
:
# pylint: disable=W0703
except
Exception
as
exc
:
# pylint: disable=W0703
log
.
debu
g
(
"Unable to render student_view for
%
r"
,
module
,
exc_info
=
True
)
log
.
warnin
g
(
"Unable to render student_view for
%
r"
,
module
,
exc_info
=
True
)
fragment
=
Fragment
(
render_to_string
(
'html_error.html'
,
{
'message'
:
str
(
exc
)}))
fragment
=
Fragment
(
render_to_string
(
'html_error.html'
,
{
'message'
:
str
(
exc
)}))
return
fragment
return
fragment
cms/static/coffee/src/xblock/cms.runtime.v1.coffee
View file @
9b54e44b
...
@@ -3,7 +3,7 @@ define ["jquery", "xblock/runtime.v1", "URI"], ($, XBlock, URI) ->
...
@@ -3,7 +3,7 @@ define ["jquery", "xblock/runtime.v1", "URI"], ($, XBlock, URI) ->
class
PreviewRuntime
.
v1
extends
XBlock
.
Runtime
.
v1
class
PreviewRuntime
.
v1
extends
XBlock
.
Runtime
.
v1
handlerUrl
:
(
element
,
handlerName
,
suffix
,
query
,
thirdparty
)
->
handlerUrl
:
(
element
,
handlerName
,
suffix
,
query
,
thirdparty
)
->
uri
=
URI
(
"/preview/xblock"
).
segment
(
$
(
@
element
).
data
(
'usage-id'
))
uri
=
URI
(
"/preview/xblock"
).
segment
(
$
(
element
).
data
(
'usage-id'
))
.
segment
(
'handler'
)
.
segment
(
'handler'
)
.
segment
(
handlerName
)
.
segment
(
handlerName
)
if
suffix
?
then
uri
.
segment
(
suffix
)
if
suffix
?
then
uri
.
segment
(
suffix
)
...
@@ -14,7 +14,7 @@ define ["jquery", "xblock/runtime.v1", "URI"], ($, XBlock, URI) ->
...
@@ -14,7 +14,7 @@ define ["jquery", "xblock/runtime.v1", "URI"], ($, XBlock, URI) ->
class
StudioRuntime
.
v1
extends
XBlock
.
Runtime
.
v1
class
StudioRuntime
.
v1
extends
XBlock
.
Runtime
.
v1
handlerUrl
:
(
element
,
handlerName
,
suffix
,
query
,
thirdparty
)
->
handlerUrl
:
(
element
,
handlerName
,
suffix
,
query
,
thirdparty
)
->
uri
=
URI
(
"/xblock"
).
segment
(
$
(
@
element
).
data
(
'usage-id'
))
uri
=
URI
(
"/xblock"
).
segment
(
$
(
element
).
data
(
'usage-id'
))
.
segment
(
'handler'
)
.
segment
(
'handler'
)
.
segment
(
handlerName
)
.
segment
(
handlerName
)
if
suffix
?
then
uri
.
segment
(
suffix
)
if
suffix
?
then
uri
.
segment
(
suffix
)
...
...
common/lib/xmodule/xmodule/tests/__init__.py
View file @
9b54e44b
...
@@ -78,6 +78,7 @@ def get_test_system(course_id=''):
...
@@ -78,6 +78,7 @@ def get_test_system(course_id=''):
course_id
=
course_id
,
course_id
=
course_id
,
error_descriptor_class
=
ErrorDescriptor
,
error_descriptor_class
=
ErrorDescriptor
,
get_user_role
=
Mock
(
is_staff
=
False
),
get_user_role
=
Mock
(
is_staff
=
False
),
descriptor_runtime
=
get_test_descriptor_system
(),
)
)
...
...
common/lib/xmodule/xmodule/x_module.py
View file @
9b54e44b
...
@@ -1048,7 +1048,7 @@ class ModuleSystem(ConfigurableFragmentWrapper, Runtime): # pylint: disable=abs
...
@@ -1048,7 +1048,7 @@ class ModuleSystem(ConfigurableFragmentWrapper, Runtime): # pylint: disable=abs
"""
"""
def
__init__
(
def
__init__
(
self
,
static_url
,
track_function
,
get_module
,
render_template
,
self
,
static_url
,
track_function
,
get_module
,
render_template
,
replace_urls
,
user
=
None
,
filestore
=
None
,
replace_urls
,
descriptor_runtime
,
user
=
None
,
filestore
=
None
,
debug
=
False
,
hostname
=
""
,
xqueue
=
None
,
publish
=
None
,
node_path
=
""
,
debug
=
False
,
hostname
=
""
,
xqueue
=
None
,
publish
=
None
,
node_path
=
""
,
anonymous_student_id
=
''
,
course_id
=
None
,
anonymous_student_id
=
''
,
course_id
=
None
,
open_ended_grading_interface
=
None
,
s3_interface
=
None
,
open_ended_grading_interface
=
None
,
s3_interface
=
None
,
...
@@ -1089,6 +1089,8 @@ class ModuleSystem(ConfigurableFragmentWrapper, Runtime): # pylint: disable=abs
...
@@ -1089,6 +1089,8 @@ class ModuleSystem(ConfigurableFragmentWrapper, Runtime): # pylint: disable=abs
that capa_module can use to fix up the static urls in
that capa_module can use to fix up the static urls in
ajax results.
ajax results.
descriptor_runtime - A `DescriptorSystem` to use for loading xblocks by id
anonymous_student_id - Used for tracking modules with student id
anonymous_student_id - Used for tracking modules with student id
course_id - the course_id containing this module
course_id - the course_id containing this module
...
@@ -1148,6 +1150,7 @@ class ModuleSystem(ConfigurableFragmentWrapper, Runtime): # pylint: disable=abs
...
@@ -1148,6 +1150,7 @@ class ModuleSystem(ConfigurableFragmentWrapper, Runtime): # pylint: disable=abs
self
.
get_real_user
=
get_real_user
self
.
get_real_user
=
get_real_user
self
.
get_user_role
=
get_user_role
self
.
get_user_role
=
get_user_role
self
.
descriptor_runtime
=
descriptor_runtime
def
get
(
self
,
attr
):
def
get
(
self
,
attr
):
""" provide uniform access to attributes (like etree)."""
""" provide uniform access to attributes (like etree)."""
...
@@ -1172,7 +1175,7 @@ class ModuleSystem(ConfigurableFragmentWrapper, Runtime): # pylint: disable=abs
...
@@ -1172,7 +1175,7 @@ class ModuleSystem(ConfigurableFragmentWrapper, Runtime): # pylint: disable=abs
return
self
.
handler_url
(
self
.
xmodule_instance
,
'xmodule_handler'
,
''
,
''
)
.
rstrip
(
'/?'
)
return
self
.
handler_url
(
self
.
xmodule_instance
,
'xmodule_handler'
,
''
,
''
)
.
rstrip
(
'/?'
)
def
get_block
(
self
,
block_id
):
def
get_block
(
self
,
block_id
):
r
aise
NotImplementedError
(
"XModules must use get_module to load other modules"
)
r
eturn
self
.
get_module
(
self
.
descriptor_runtime
.
get_block
(
block_id
)
)
def
resource_url
(
self
,
resource
):
def
resource_url
(
self
,
resource
):
raise
NotImplementedError
(
"edX Platform doesn't currently implement XBlock resource urls"
)
raise
NotImplementedError
(
"edX Platform doesn't currently implement XBlock resource urls"
)
...
...
common/static/coffee/spec/xblock/core_spec.coffee
View file @
9b54e44b
...
@@ -31,8 +31,8 @@ describe "XBlock", ->
...
@@ -31,8 +31,8 @@ describe "XBlock", ->
@
missingInitBlock
=
XBlock
.
initializeBlock
(
$
(
'#missing-init'
)[
0
])
@
missingInitBlock
=
XBlock
.
initializeBlock
(
$
(
'#missing-init'
)[
0
])
it
"loads the right runtime version"
,
->
it
"loads the right runtime version"
,
->
expect
(
TestRuntime
.
vA
).
toHaveBeenCalledWith
(
$
(
'#vA'
)[
0
],
@
fakeChildren
)
expect
(
TestRuntime
.
vA
).
toHaveBeenCalledWith
()
expect
(
TestRuntime
.
vZ
).
toHaveBeenCalledWith
(
$
(
'#vZ'
)[
0
],
@
fakeChildren
)
expect
(
TestRuntime
.
vZ
).
toHaveBeenCalledWith
()
it
"loads the right init function"
,
->
it
"loads the right init function"
,
->
expect
(
window
.
initFnA
).
toHaveBeenCalledWith
(
@
runtimeA
,
$
(
'#vA'
)[
0
])
expect
(
window
.
initFnA
).
toHaveBeenCalledWith
(
@
runtimeA
,
$
(
'#vA'
)[
0
])
...
...
common/static/coffee/spec/xblock/runtime.v1_spec.coffee
View file @
9b54e44b
...
@@ -9,12 +9,13 @@ describe "XBlock.Runtime.v1", ->
...
@@ -9,12 +9,13 @@ describe "XBlock.Runtime.v1", ->
]
]
@
element
=
$
(
'.xblock'
)[
0
]
@
element
=
$
(
'.xblock'
)[
0
]
$
(
@
element
).
prop
(
'xblock_children'
,
@
children
)
@
runtime
=
new
XBlock
.
Runtime
.
v1
(
@
element
,
@
children
)
@
runtime
=
new
XBlock
.
Runtime
.
v1
(
@
element
)
it
"provides a list of children"
,
->
it
"provides a list of children"
,
->
expect
(
@
runtime
.
children
).
toBe
(
@
children
)
expect
(
@
runtime
.
children
(
@
element
)
).
toBe
(
@
children
)
it
"maps children by name"
,
->
it
"maps children by name"
,
->
expect
(
@
runtime
.
childMap
.
childA
).
toBe
(
@
children
[
0
])
expect
(
@
runtime
.
childMap
(
@
element
,
'childA'
)
).
toBe
(
@
children
[
0
])
expect
(
@
runtime
.
childMap
.
childB
).
toBe
(
@
children
[
1
])
expect
(
@
runtime
.
childMap
(
@
element
,
'childB'
)
).
toBe
(
@
children
[
1
])
common/static/coffee/src/xblock/core.coffee
View file @
9b54e44b
...
@@ -7,8 +7,9 @@
...
@@ -7,8 +7,9 @@
runtime
=
$element
.
data
(
"runtime-class"
)
runtime
=
$element
.
data
(
"runtime-class"
)
version
=
$element
.
data
(
"runtime-version"
)
version
=
$element
.
data
(
"runtime-version"
)
initFnName
=
$element
.
data
(
"init"
)
initFnName
=
$element
.
data
(
"init"
)
$element
.
prop
(
'xblock_children'
,
children
)
if
runtime
?
and
version
?
and
initFnName
?
if
runtime
?
and
version
?
and
initFnName
?
runtime
=
new
window
[
runtime
][
"v
#{
version
}
"
]
(
element
,
children
)
runtime
=
new
window
[
runtime
][
"v
#{
version
}
"
]
initFn
=
window
[
initFnName
]
initFn
=
window
[
initFnName
]
block
=
initFn
(
runtime
,
element
)
?
{}
block
=
initFn
(
runtime
,
element
)
?
{}
else
else
...
...
common/static/coffee/src/xblock/runtime.v1.coffee
View file @
9b54e44b
class
XBlock
.
Runtime
.
v1
class
XBlock
.
Runtime
.
v1
c
onstructor
:
(
@
element
,
@
children
)
->
c
hildren
:
(
block
)
=>
$
(
block
).
prop
(
'xblock_children'
)
@
childMap
=
{}
childMap
:
(
block
,
childName
)
=>
$
.
each
@
children
,
(
idx
,
child
)
=>
for
child
in
@
children
(
block
)
@
childMap
[
child
.
name
]
=
child
return
child
if
child
.
name
==
childName
\ No newline at end of file
common/test/acceptance/fixtures/course.py
View file @
9b54e44b
...
@@ -95,31 +95,20 @@ class XBlockFixtureDesc(object):
...
@@ -95,31 +95,20 @@ class XBlockFixtureDesc(object):
self
.
children
.
extend
(
args
)
self
.
children
.
extend
(
args
)
return
self
return
self
def
serialize
(
self
,
parent_loc
=
None
):
def
serialize
(
self
):
"""
"""
Return a JSON representation of the XBlock, suitable
Return a JSON representation of the XBlock, suitable
for sending as POST data to /xblock
for sending as POST data to /xblock
XBlocks are always set to public visibility.
XBlocks are always set to public visibility.
"""
"""
payload
=
{
return
json
.
dumps
({
'category'
:
self
.
category
,
'display_name'
:
self
.
display_name
,
'display_name'
:
self
.
display_name
,
'data'
:
self
.
data
,
'data'
:
self
.
data
,
'metadata'
:
self
.
metadata
,
'metadata'
:
self
.
metadata
,
'grader
_t
ype'
:
self
.
grader_type
,
'grader
T
ype'
:
self
.
grader_type
,
'publish'
:
self
.
publish
'publish'
:
self
.
publish
}
})
# Need to handle detached categories differently, since they are not published
# This may change in the future.
if
self
.
category
in
[
'static_tab'
]:
del
payload
[
'publish'
]
if
parent_loc
is
not
None
:
payload
[
'parent_locator'
]
=
parent_loc
return
json
.
dumps
(
payload
)
def
__str__
(
self
):
def
__str__
(
self
):
"""
"""
...
@@ -395,15 +384,25 @@ class CourseFixture(StudioApiFixture):
...
@@ -395,15 +384,25 @@ class CourseFixture(StudioApiFixture):
loc
=
self
.
_create_xblock
(
parent_loc
,
desc
)
loc
=
self
.
_create_xblock
(
parent_loc
,
desc
)
self
.
_create_xblock_children
(
loc
,
desc
.
children
)
self
.
_create_xblock_children
(
loc
,
desc
.
children
)
self
.
_publish_xblock
(
parent_loc
)
def
_create_xblock
(
self
,
parent_loc
,
xblock_desc
):
def
_create_xblock
(
self
,
parent_loc
,
xblock_desc
):
"""
"""
Create an XBlock with `parent_loc` (the location of the parent block)
Create an XBlock with `parent_loc` (the location of the parent block)
and `xblock_desc` (an `XBlockFixtureDesc` instance).
and `xblock_desc` (an `XBlockFixtureDesc` instance).
"""
"""
create_payload
=
{
'category'
:
xblock_desc
.
category
,
'display_name'
:
xblock_desc
.
display_name
,
}
if
parent_loc
is
not
None
:
create_payload
[
'parent_locator'
]
=
parent_loc
# Create the new XBlock
# Create the new XBlock
response
=
self
.
session
.
post
(
response
=
self
.
session
.
post
(
STUDIO_BASE_URL
+
'/xblock'
,
STUDIO_BASE_URL
+
'/xblock'
,
data
=
xblock_desc
.
serialize
(
parent_loc
=
parent_loc
),
data
=
json
.
dumps
(
create_payload
),
headers
=
self
.
headers
,
headers
=
self
.
headers
,
)
)
...
@@ -417,24 +416,34 @@ class CourseFixture(StudioApiFixture):
...
@@ -417,24 +416,34 @@ class CourseFixture(StudioApiFixture):
except
ValueError
:
except
ValueError
:
raise
CourseFixtureError
(
"Could not decode JSON from '{0}'"
.
format
(
response
.
content
))
raise
CourseFixtureError
(
"Could not decode JSON from '{0}'"
.
format
(
response
.
content
))
if
loc
is
not
None
:
# Configure the XBlock
response
=
self
.
session
.
post
(
STUDIO_BASE_URL
+
'/xblock/'
+
loc
,
data
=
xblock_desc
.
serialize
(),
headers
=
self
.
headers
,
)
# Configure the XBlock
if
response
.
ok
:
re
sponse
=
self
.
session
.
post
(
re
turn
loc
STUDIO_BASE_URL
+
'/xblock/'
+
loc
,
else
:
data
=
xblock_desc
.
serialize
(),
raise
CourseFixtureError
(
headers
=
self
.
headers
,
"Could not update {0}. Status code: {1}"
.
format
(
)
xblock_desc
,
response
.
status_code
)
)
if
response
.
ok
:
def
_publish_xblock
(
self
,
locator
):
return
loc
"""
else
:
Publish the xblock at `locator`.
raise
CourseFixtureError
(
"""
"Could not update {0}. Status code: {1}"
.
format
(
# Create the new XBlock
xblock_desc
,
response
.
status_code
))
response
=
self
.
session
.
put
(
"{}/xblock/{}"
.
format
(
STUDIO_BASE_URL
,
locator
),
data
=
json
.
dumps
({
'publish'
:
'make_public'
}),
headers
=
self
.
headers
,
)
else
:
if
not
response
.
ok
:
raise
CourseFixtureError
(
"Could not retrieve location of {0}"
.
format
(
xblock_desc
))
msg
=
"Could not publish {}. Status was {}"
.
format
(
locator
,
response
.
status_code
)
raise
CourseFixtureError
(
msg
)
def
_encode_post_dict
(
self
,
post_dict
):
def
_encode_post_dict
(
self
,
post_dict
):
"""
"""
...
...
common/test/acceptance/pages/studio/unit.py
View file @
9b54e44b
...
@@ -4,7 +4,7 @@ Unit page in Studio
...
@@ -4,7 +4,7 @@ Unit page in Studio
from
bok_choy.page_object
import
PageObject
from
bok_choy.page_object
import
PageObject
from
bok_choy.query
import
SubQuery
from
bok_choy.query
import
SubQuery
from
bok_choy.promise
import
Promise
,
EmptyPromise
,
fulfill
from
bok_choy.promise
import
EmptyPromise
,
fulfill
from
.
import
BASE_URL
from
.
import
BASE_URL
...
@@ -24,20 +24,32 @@ class UnitPage(PageObject):
...
@@ -24,20 +24,32 @@ class UnitPage(PageObject):
return
"{}/unit/{}"
.
format
(
BASE_URL
,
self
.
unit_locator
)
return
"{}/unit/{}"
.
format
(
BASE_URL
,
self
.
unit_locator
)
def
is_browser_on_page
(
self
):
def
is_browser_on_page
(
self
):
return
self
.
is_css_present
(
'body.view-unit'
)
# Wait until all components have been loaded
return
(
def
component
(
self
,
title
):
self
.
is_css_present
(
'body.view-unit'
)
and
return
Component
(
self
.
browser
,
self
.
_locator
(
title
))
len
(
self
.
q
(
css
=
Component
.
BODY_SELECTOR
))
==
len
(
self
.
q
(
css
=
'{} .xblock-student_view'
.
format
(
Component
.
BODY_SELECTOR
)))
)
def
_locator
(
self
,
title
):
def
_check_func
():
locators
=
self
.
q
(
css
=
Component
.
BODY_SELECTOR
)
.
filter
(
SubQuery
(
css
=
Component
.
NAME_SELECTOR
)
.
filter
(
text
=
title
)
)
.
map
(
lambda
el
:
el
[
'data-locator'
])
.
results
return
(
len
(
locators
)
>
0
,
locators
[
0
])
@property
def
components
(
self
):
"""
Return a list of components loaded on the unit page.
"""
return
self
.
q
(
css
=
Component
.
BODY_SELECTOR
)
.
map
(
lambda
el
:
Component
(
self
.
browser
,
el
[
'data-locator'
]))
.
results
return
fulfill
(
Promise
(
_check_func
,
"Found data locator for component"
))
def
edit_draft
(
self
):
"""
Started editing a draft of this unit.
"""
fulfill
(
EmptyPromise
(
lambda
:
self
.
q
(
css
=
'.create-draft'
)
.
present
,
'Wait for edit draft link to be present'
))
self
.
q
(
css
=
'.create-draft'
)
.
click
()
fulfill
(
EmptyPromise
(
lambda
:
self
.
q
(
css
=
'.editing-draft-alert'
)
.
present
,
'Wait for draft mode to be activated'
))
class
Component
(
PageObject
):
class
Component
(
PageObject
):
...
...
common/test/acceptance/pages/xblock/acid.py
View file @
9b54e44b
...
@@ -51,6 +51,16 @@ class AcidView(PageObject):
...
@@ -51,6 +51,16 @@ class AcidView(PageObject):
"""
"""
return
self
.
test_passed
(
'.document-ready-run'
)
return
self
.
test_passed
(
'.document-ready-run'
)
@property
def
child_tests_passed
(
self
):
"""
Whether the tests of children passed
"""
return
all
([
self
.
test_passed
(
'.child-counts-match'
),
self
.
test_passed
(
'.child-values-match'
)
])
def
scope_passed
(
self
,
scope
):
def
scope_passed
(
self
,
scope
):
return
all
(
return
all
(
self
.
test_passed
(
'.scope-storage-test.scope-{} {}'
.
format
(
scope
,
test
))
self
.
test_passed
(
'.scope-storage-test.scope-{} {}'
.
format
(
scope
,
test
))
...
...
common/test/acceptance/tests/test_lms.py
View file @
9b54e44b
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
E2E tests for the LMS.
E2E tests for the LMS.
"""
"""
from
unittest
import
skip
from
unittest
import
skip
,
expectedFailure
from
bok_choy.web_app_test
import
WebAppTest
from
bok_choy.web_app_test
import
WebAppTest
from
bok_choy.promise
import
EmptyPromise
,
fulfill_before
,
fulfill
,
Promise
from
bok_choy.promise
import
EmptyPromise
,
fulfill_before
,
fulfill
,
Promise
...
@@ -292,8 +292,9 @@ class VideoTest(UniqueCourseTest):
...
@@ -292,8 +292,9 @@ class VideoTest(UniqueCourseTest):
course_fix
.
add_children
(
course_fix
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
'video'
,
'Video'
)
XBlockFixtureDesc
(
'vertical'
,
'Test Unit'
)
.
add_children
(
)))
.
install
()
XBlockFixtureDesc
(
'video'
,
'Video'
)
))))
.
install
()
# Auto-auth register for the course
# Auto-auth register for the course
...
@@ -338,18 +339,48 @@ class VideoTest(UniqueCourseTest):
...
@@ -338,18 +339,48 @@ class VideoTest(UniqueCourseTest):
self
.
assertGreaterEqual
(
self
.
video
.
duration
,
self
.
video
.
elapsed_time
)
self
.
assertGreaterEqual
(
self
.
video
.
duration
,
self
.
video
.
elapsed_time
)
class
XBlockAcid
Test
(
UniqueCourseTest
):
class
XBlockAcid
Base
(
UniqueCourseTest
):
"""
"""
T
ests that verify that XBlock integration is working correctly
Base class for t
ests that verify that XBlock integration is working correctly
"""
"""
__test__
=
False
def
setUp
(
self
):
def
setUp
(
self
):
"""
"""
Create a unique identifier for the course used in this test.
Create a unique identifier for the course used in this test.
"""
"""
# Ensure that the superclass sets up
# Ensure that the superclass sets up
super
(
XBlockAcid
Test
,
self
)
.
setUp
()
super
(
XBlockAcid
Base
,
self
)
.
setUp
()
self
.
setup_fixtures
()
AutoAuthPage
(
self
.
browser
,
course_id
=
self
.
course_id
)
.
visit
()
self
.
course_info_page
=
CourseInfoPage
(
self
.
browser
,
self
.
course_id
)
self
.
tab_nav
=
TabNavPage
(
self
.
browser
)
def
test_acid_block
(
self
):
"""
Verify that all expected acid block tests pass in the lms.
"""
self
.
course_info_page
.
visit
()
self
.
tab_nav
.
go_to_tab
(
'Courseware'
)
acid_block
=
AcidView
(
self
.
browser
,
'.xblock-student_view[data-block-type=acid]'
)
self
.
assertTrue
(
acid_block
.
init_fn_passed
)
self
.
assertTrue
(
acid_block
.
doc_ready_passed
)
self
.
assertTrue
(
acid_block
.
child_tests_passed
)
self
.
assertTrue
(
acid_block
.
scope_passed
(
'user_state'
))
class
XBlockAcidNoChildTest
(
XBlockAcidBase
):
"""
Tests of an AcidBlock with no children
"""
__test__
=
True
def
setup_fixtures
(
self
):
course_fix
=
CourseFixture
(
course_fix
=
CourseFixture
(
self
.
course_info
[
'org'
],
self
.
course_info
[
'org'
],
self
.
course_info
[
'number'
],
self
.
course_info
[
'number'
],
...
@@ -360,24 +391,43 @@ class XBlockAcidTest(UniqueCourseTest):
...
@@ -360,24 +391,43 @@ class XBlockAcidTest(UniqueCourseTest):
course_fix
.
add_children
(
course_fix
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
'acid'
,
'Acid Block'
)
XBlockFixtureDesc
(
'vertical'
,
'Test Unit'
)
.
add_children
(
XBlockFixtureDesc
(
'acid'
,
'Acid Block'
)
)
)
)
)
)
)
.
install
()
)
.
install
()
AutoAuthPage
(
self
.
browser
,
course_id
=
self
.
course_id
)
.
visit
()
self
.
course_info_page
=
CourseInfoPage
(
self
.
browser
,
self
.
course_id
)
class
XBlockAcidChildTest
(
XBlockAcidBase
):
self
.
tab_nav
=
TabNavPage
(
self
.
browser
)
"""
Tests of an AcidBlock with children
"""
__test__
=
True
self
.
course_info_page
.
visit
()
def
setup_fixtures
(
self
):
self
.
tab_nav
.
go_to_tab
(
'Courseware'
)
course_fix
=
CourseFixture
(
self
.
course_info
[
'org'
],
self
.
course_info
[
'number'
],
self
.
course_info
[
'run'
],
self
.
course_info
[
'display_name'
]
)
course_fix
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
'vertical'
,
'Test Unit'
)
.
add_children
(
XBlockFixtureDesc
(
'acid'
,
'Acid Block'
)
.
add_children
(
XBlockFixtureDesc
(
'acid'
,
'First Acid Child'
,
metadata
=
{
'name'
:
'first'
}),
XBlockFixtureDesc
(
'acid'
,
'Second Acid Child'
,
metadata
=
{
'name'
:
'second'
}),
XBlockFixtureDesc
(
'html'
,
'Html Child'
,
data
=
"<html>Contents</html>"
),
)
)
)
)
)
.
install
()
# This will fail until we fix support of children in pure XBlocks
@expectedFailure
def
test_acid_block
(
self
):
def
test_acid_block
(
self
):
"""
super
(
XBlockAcidChildTest
,
self
)
.
test_acid_block
()
Verify that all expected acid block tests pass in the lms.
"""
acid_block
=
AcidView
(
self
.
browser
,
'.xblock-student_view[data-block-type=acid]'
)
self
.
assertTrue
(
acid_block
.
init_fn_passed
)
self
.
assertTrue
(
acid_block
.
doc_ready_passed
)
self
.
assertTrue
(
acid_block
.
scope_passed
(
'user_state'
))
common/test/acceptance/tests/test_studio.py
View file @
9b54e44b
"""
"""
Acceptance tests for Studio.
Acceptance tests for Studio.
"""
"""
from
unittest
import
expectedFailure
from
bok_choy.web_app_test
import
WebAppTest
from
bok_choy.web_app_test
import
WebAppTest
from
..pages.studio.asset_index
import
AssetIndexPage
from
..pages.studio.asset_index
import
AssetIndexPage
...
@@ -110,17 +112,18 @@ class CoursePagesTest(UniqueCourseTest):
...
@@ -110,17 +112,18 @@ class CoursePagesTest(UniqueCourseTest):
page
.
visit
()
page
.
visit
()
class
XBlockAcid
Test
(
WebAppTest
):
class
XBlockAcid
Base
(
WebAppTest
):
"""
"""
T
ests that verify that XBlock integration is working correctly
Base class for t
ests that verify that XBlock integration is working correctly
"""
"""
__test__
=
False
def
setUp
(
self
):
def
setUp
(
self
):
"""
"""
Create a unique identifier for the course used in this test.
Create a unique identifier for the course used in this test.
"""
"""
# Ensure that the superclass sets up
# Ensure that the superclass sets up
super
(
XBlockAcid
Test
,
self
)
.
setUp
()
super
(
XBlockAcid
Base
,
self
)
.
setUp
()
# Define a unique course identifier
# Define a unique course identifier
self
.
course_info
=
{
self
.
course_info
=
{
...
@@ -140,6 +143,50 @@ class XBlockAcidTest(WebAppTest):
...
@@ -140,6 +143,50 @@ class XBlockAcidTest(WebAppTest):
self
.
course_id
=
'{org}.{number}.{run}'
.
format
(
**
self
.
course_info
)
self
.
course_id
=
'{org}.{number}.{run}'
.
format
(
**
self
.
course_info
)
self
.
setup_fixtures
()
self
.
auth_page
.
visit
()
def
test_acid_block_preview
(
self
):
"""
Verify that all expected acid block tests pass in studio preview
"""
self
.
outline
.
visit
()
unit
=
self
.
outline
.
section
(
'Test Section'
)
.
subsection
(
'Test Subsection'
)
.
toggle_expand
()
.
unit
(
'Test Unit'
)
.
go_to
()
acid_block
=
AcidView
(
self
.
browser
,
unit
.
components
[
0
]
.
preview_selector
)
self
.
assertTrue
(
acid_block
.
init_fn_passed
)
self
.
assertTrue
(
acid_block
.
doc_ready_passed
)
self
.
assertTrue
(
acid_block
.
child_tests_passed
)
self
.
assertTrue
(
acid_block
.
scope_passed
(
'user_state'
))
def
test_acid_block_editor
(
self
):
"""
Verify that all expected acid block tests pass in studio preview
"""
self
.
outline
.
visit
()
unit
=
self
.
outline
.
section
(
'Test Section'
)
.
subsection
(
'Test Subsection'
)
.
toggle_expand
()
.
unit
(
'Test Unit'
)
.
go_to
()
unit
.
edit_draft
()
acid_block
=
AcidView
(
self
.
browser
,
unit
.
components
[
0
]
.
edit
()
.
editor_selector
)
self
.
assertTrue
(
acid_block
.
init_fn_passed
)
self
.
assertTrue
(
acid_block
.
doc_ready_passed
)
self
.
assertTrue
(
acid_block
.
child_tests_passed
)
self
.
assertTrue
(
acid_block
.
scope_passed
(
'content'
))
self
.
assertTrue
(
acid_block
.
scope_passed
(
'settings'
))
class
XBlockAcidNoChildTest
(
XBlockAcidBase
):
"""
Tests of an AcidBlock with no children
"""
__test__
=
True
def
setup_fixtures
(
self
):
course_fix
=
CourseFixture
(
course_fix
=
CourseFixture
(
self
.
course_info
[
'org'
],
self
.
course_info
[
'org'
],
self
.
course_info
[
'number'
],
self
.
course_info
[
'number'
],
...
@@ -157,27 +204,42 @@ class XBlockAcidTest(WebAppTest):
...
@@ -157,27 +204,42 @@ class XBlockAcidTest(WebAppTest):
)
)
)
.
install
()
)
.
install
()
self
.
auth_page
.
visit
()
self
.
outline
.
visit
()
class
XBlockAcidChildTest
(
XBlockAcidBase
):
unit
=
self
.
outline
.
section
(
'Test Section'
)
.
subsection
(
'Test Subsection'
)
.
toggle_expand
()
.
unit
(
'Test Unit'
)
.
go_to
()
"""
self
.
acid_component
=
unit
.
component
(
'Acid Block'
)
Tests of an AcidBlock with children
"""
__test__
=
True
def
setup_fixtures
(
self
):
course_fix
=
CourseFixture
(
self
.
course_info
[
'org'
],
self
.
course_info
[
'number'
],
self
.
course_info
[
'run'
],
self
.
course_info
[
'display_name'
]
)
course_fix
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
'vertical'
,
'Test Unit'
)
.
add_children
(
XBlockFixtureDesc
(
'acid'
,
'Acid Block'
)
.
add_children
(
XBlockFixtureDesc
(
'acid'
,
'First Acid Child'
,
metadata
=
{
'name'
:
'first'
}),
XBlockFixtureDesc
(
'acid'
,
'Second Acid Child'
,
metadata
=
{
'name'
:
'second'
}),
XBlockFixtureDesc
(
'html'
,
'Html Child'
,
data
=
"<html>Contents</html>"
),
)
)
)
)
)
.
install
()
# This will fail until we fix support of children in pure XBlocks
@expectedFailure
def
test_acid_block_preview
(
self
):
def
test_acid_block_preview
(
self
):
"""
super
(
XBlockAcidChildTest
,
self
)
.
test_acid_block_preview
()
Verify that all expected acid block tests pass in studio preview
"""
acid_block
=
AcidView
(
self
.
browser
,
self
.
acid_component
.
preview_selector
)
self
.
assertTrue
(
acid_block
.
init_fn_passed
)
self
.
assertTrue
(
acid_block
.
doc_ready_passed
)
self
.
assertTrue
(
acid_block
.
scope_passed
(
'user_state'
))
# This will fail until we fix support of children in pure XBlocks
@expectedFailure
def
test_acid_block_editor
(
self
):
def
test_acid_block_editor
(
self
):
"""
super
(
XBlockAcidChildTest
,
self
)
.
test_acid_block_editor
()
Verify that all expected acid block tests pass in studio preview
"""
acid_block
=
AcidView
(
self
.
browser
,
self
.
acid_component
.
edit
()
.
editor_selector
)
self
.
assertTrue
(
acid_block
.
init_fn_passed
)
self
.
assertTrue
(
acid_block
.
doc_ready_passed
)
self
.
assertTrue
(
acid_block
.
scope_passed
(
'content'
))
self
.
assertTrue
(
acid_block
.
scope_passed
(
'settings'
))
lms/djangoapps/courseware/module_render.py
View file @
9b54e44b
...
@@ -227,7 +227,6 @@ def get_module_for_descriptor_internal(user, descriptor, field_data_cache, cours
...
@@ -227,7 +227,6 @@ def get_module_for_descriptor_internal(user, descriptor, field_data_cache, cours
return
None
return
None
student_data
=
KvsFieldData
(
DjangoKeyValueStore
(
field_data_cache
))
student_data
=
KvsFieldData
(
DjangoKeyValueStore
(
field_data_cache
))
descriptor
.
_field_data
=
LmsFieldData
(
descriptor
.
_field_data
,
student_data
)
def
make_xqueue_callback
(
dispatch
=
'score_update'
):
def
make_xqueue_callback
(
dispatch
=
'score_update'
):
...
@@ -433,6 +432,7 @@ def get_module_for_descriptor_internal(user, descriptor, field_data_cache, cours
...
@@ -433,6 +432,7 @@ def get_module_for_descriptor_internal(user, descriptor, field_data_cache, cours
'i18n'
:
ModuleI18nService
(),
'i18n'
:
ModuleI18nService
(),
},
},
get_user_role
=
lambda
:
get_user_role
(
user
,
course_id
),
get_user_role
=
lambda
:
get_user_role
(
user
,
course_id
),
descriptor_runtime
=
descriptor
.
runtime
,
)
)
# pass position specified in URL to module through ModuleSystem
# pass position specified in URL to module through ModuleSystem
...
@@ -451,8 +451,8 @@ def get_module_for_descriptor_internal(user, descriptor, field_data_cache, cours
...
@@ -451,8 +451,8 @@ def get_module_for_descriptor_internal(user, descriptor, field_data_cache, cours
else
:
else
:
system
.
error_descriptor_class
=
NonStaffErrorDescriptor
system
.
error_descriptor_class
=
NonStaffErrorDescriptor
descriptor
.
xmodule_runtime
=
system
descriptor
.
bind_for_student
(
system
,
LmsFieldData
(
descriptor
.
_field_data
,
student_data
))
# pylint: disable=protected-access
descriptor
.
scope_ids
=
descriptor
.
scope_ids
.
_replace
(
user_id
=
user
.
id
)
descriptor
.
scope_ids
=
descriptor
.
scope_ids
.
_replace
(
user_id
=
user
.
id
)
# pylint: disable=protected-access
return
descriptor
return
descriptor
...
...
lms/djangoapps/courseware/tests/test_module_render.py
View file @
9b54e44b
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
Test for lms courseware app, module render unit
Test for lms courseware app, module render unit
"""
"""
from
ddt
import
ddt
,
data
from
ddt
import
ddt
,
data
from
functools
import
partial
from
mock
import
MagicMock
,
patch
,
Mock
from
mock
import
MagicMock
,
patch
,
Mock
import
json
import
json
...
@@ -657,6 +658,9 @@ class TestAnonymousStudentId(ModuleStoreTestCase, LoginEnrollmentTestCase):
...
@@ -657,6 +658,9 @@ class TestAnonymousStudentId(ModuleStoreTestCase, LoginEnrollmentTestCase):
),
),
scope_ids
=
Mock
(
spec
=
ScopeIds
),
scope_ids
=
Mock
(
spec
=
ScopeIds
),
)
)
# Use the xblock_class's bind_for_student method
descriptor
.
bind_for_student
=
partial
(
xblock_class
.
bind_for_student
,
descriptor
)
if
hasattr
(
xblock_class
,
'module_class'
):
if
hasattr
(
xblock_class
,
'module_class'
):
descriptor
.
module_class
=
xblock_class
.
module_class
descriptor
.
module_class
=
xblock_class
.
module_class
...
...
lms/djangoapps/open_ended_grading/open_ended_notifications.py
View file @
9b54e44b
...
@@ -69,6 +69,7 @@ def peer_grading_notifications(course, user):
...
@@ -69,6 +69,7 @@ def peer_grading_notifications(course, user):
get_module
=
None
,
get_module
=
None
,
render_template
=
render_to_string
,
render_template
=
render_to_string
,
replace_urls
=
None
,
replace_urls
=
None
,
descriptor_runtime
=
None
,
)
)
peer_gs
=
peer_grading_service
.
PeerGradingService
(
settings
.
OPEN_ENDED_GRADING_INTERFACE
,
system
)
peer_gs
=
peer_grading_service
.
PeerGradingService
(
settings
.
OPEN_ENDED_GRADING_INTERFACE
,
system
)
pending_grading
=
False
pending_grading
=
False
...
@@ -129,6 +130,7 @@ def combined_notifications(course, user):
...
@@ -129,6 +130,7 @@ def combined_notifications(course, user):
get_module
=
None
,
get_module
=
None
,
render_template
=
render_to_string
,
render_template
=
render_to_string
,
replace_urls
=
None
,
replace_urls
=
None
,
descriptor_runtime
=
None
,
)
)
#Initialize controller query service using our mock system
#Initialize controller query service using our mock system
controller_qs
=
ControllerQueryService
(
settings
.
OPEN_ENDED_GRADING_INTERFACE
,
system
)
controller_qs
=
ControllerQueryService
(
settings
.
OPEN_ENDED_GRADING_INTERFACE
,
system
)
...
...
lms/djangoapps/open_ended_grading/staff_grading_service.py
View file @
9b54e44b
...
@@ -83,6 +83,7 @@ class StaffGradingService(GradingService):
...
@@ -83,6 +83,7 @@ class StaffGradingService(GradingService):
get_module
=
None
,
get_module
=
None
,
render_template
=
render_to_string
,
render_template
=
render_to_string
,
replace_urls
=
None
,
replace_urls
=
None
,
descriptor_runtime
=
None
,
)
)
super
(
StaffGradingService
,
self
)
.
__init__
(
config
)
super
(
StaffGradingService
,
self
)
.
__init__
(
config
)
self
.
url
=
config
[
'url'
]
+
config
[
'staff_grading'
]
self
.
url
=
config
[
'url'
]
+
config
[
'staff_grading'
]
...
...
lms/djangoapps/open_ended_grading/tests.py
View file @
9b54e44b
...
@@ -285,6 +285,7 @@ class TestPeerGradingService(ModuleStoreTestCase, LoginEnrollmentTestCase):
...
@@ -285,6 +285,7 @@ class TestPeerGradingService(ModuleStoreTestCase, LoginEnrollmentTestCase):
open_ended_grading_interface
=
test_util_open_ended
.
OPEN_ENDED_GRADING_INTERFACE
,
open_ended_grading_interface
=
test_util_open_ended
.
OPEN_ENDED_GRADING_INTERFACE
,
mixins
=
settings
.
XBLOCK_MIXINS
,
mixins
=
settings
.
XBLOCK_MIXINS
,
error_descriptor_class
=
ErrorDescriptor
,
error_descriptor_class
=
ErrorDescriptor
,
descriptor_runtime
=
None
,
)
)
self
.
descriptor
=
peer_grading_module
.
PeerGradingDescriptor
(
self
.
system
,
field_data
,
ScopeIds
(
None
,
None
,
None
,
None
))
self
.
descriptor
=
peer_grading_module
.
PeerGradingDescriptor
(
self
.
system
,
field_data
,
ScopeIds
(
None
,
None
,
None
,
None
))
self
.
descriptor
.
xmodule_runtime
=
self
.
system
self
.
descriptor
.
xmodule_runtime
=
self
.
system
...
...
lms/djangoapps/open_ended_grading/utils.py
View file @
9b54e44b
...
@@ -33,6 +33,7 @@ SYSTEM = LmsModuleSystem(
...
@@ -33,6 +33,7 @@ SYSTEM = LmsModuleSystem(
get_module
=
None
,
get_module
=
None
,
render_template
=
render_to_string
,
render_template
=
render_to_string
,
replace_urls
=
None
,
replace_urls
=
None
,
descriptor_runtime
=
None
,
)
)
...
...
lms/lib/xblock/test/test_runtime.py
View file @
9b54e44b
...
@@ -48,6 +48,7 @@ class TestHandlerUrl(TestCase):
...
@@ -48,6 +48,7 @@ class TestHandlerUrl(TestCase):
render_template
=
Mock
(),
render_template
=
Mock
(),
replace_urls
=
str
,
replace_urls
=
str
,
course_id
=
self
.
course_id
,
course_id
=
self
.
course_id
,
descriptor_runtime
=
Mock
(),
)
)
def
test_trailing_characters
(
self
):
def
test_trailing_characters
(
self
):
...
...
lms/static/coffee/src/xblock/lms.runtime.v1.coffee
View file @
9b54e44b
...
@@ -2,8 +2,8 @@
...
@@ -2,8 +2,8 @@
class
LmsRuntime
.
v1
extends
XBlock
.
Runtime
.
v1
class
LmsRuntime
.
v1
extends
XBlock
.
Runtime
.
v1
handlerUrl
:
(
element
,
handlerName
,
suffix
,
query
,
thirdparty
)
->
handlerUrl
:
(
element
,
handlerName
,
suffix
,
query
,
thirdparty
)
->
courseId
=
$
(
@
element
).
data
(
"course-id"
)
courseId
=
$
(
element
).
data
(
"course-id"
)
usageId
=
$
(
@
element
).
data
(
"usage-id"
)
usageId
=
$
(
element
).
data
(
"usage-id"
)
handlerAuth
=
if
thirdparty
then
"handler_noauth"
else
"handler"
handlerAuth
=
if
thirdparty
then
"handler_noauth"
else
"handler"
uri
=
URI
(
'/courses'
).
segment
(
courseId
)
uri
=
URI
(
'/courses'
).
segment
(
courseId
)
...
...
requirements/edx/github.txt
View file @
9b54e44b
...
@@ -21,6 +21,6 @@
...
@@ -21,6 +21,6 @@
-e git+https://github.com/edx/js-test-tool.git@v0.1.5#egg=js_test_tool
-e git+https://github.com/edx/js-test-tool.git@v0.1.5#egg=js_test_tool
-e git+https://github.com/edx/django-waffle.git@823a102e48#egg=django-waffle
-e git+https://github.com/edx/django-waffle.git@823a102e48#egg=django-waffle
-e git+https://github.com/edx/event-tracking.git@f0211d702d#egg=event-tracking
-e git+https://github.com/edx/event-tracking.git@f0211d702d#egg=event-tracking
-e git+https://github.com/edx/bok-choy.git@
v0.2.
1#egg=bok_choy
-e git+https://github.com/edx/bok-choy.git@
62de7b576a08f36cde5b030c52bccb1a2f3f8df
1#egg=bok_choy
-e git+https://github.com/edx-solutions/django-splash.git@15bf143b15714e22fc451ff1b0f8a7a2a9483172#egg=django-splash
-e git+https://github.com/edx-solutions/django-splash.git@15bf143b15714e22fc451ff1b0f8a7a2a9483172#egg=django-splash
-e git+https://github.com/edx/acid-block.git@
aa95a3
c#egg=acid-xblock
-e git+https://github.com/edx/acid-block.git@
9c832513f0c01f79227bea894fba11c66fe4c08
c#egg=acid-xblock
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