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
0fb11365
Commit
0fb11365
authored
Jun 05, 2013
by
dcadams
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of github.com:edx/edx-platform into feature-dcadams-usermanagement
parents
a8ec1ca9
468dfe34
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
267 additions
and
103 deletions
+267
-103
AUTHORS
+1
-0
cms/djangoapps/contentstore/features/advanced-settings.feature
+0
-8
cms/djangoapps/contentstore/features/advanced-settings.py
+8
-5
cms/djangoapps/contentstore/features/common.py
+8
-0
cms/djangoapps/contentstore/features/component_settings_editor_helpers.py
+13
-6
cms/djangoapps/contentstore/features/discussion-editor.feature
+4
-0
cms/djangoapps/contentstore/features/discussion-editor.py
+7
-0
cms/djangoapps/contentstore/features/video.feature
+4
-0
cms/djangoapps/contentstore/features/video.py
+7
-0
cms/djangoapps/contentstore/tests/test_contentstore.py
+25
-7
cms/envs/aws.py
+6
-0
cms/static/coffee/src/views/unit.coffee
+2
-1
cms/templates/unit.html
+51
-43
common/djangoapps/mitxmako/makoloader.py
+5
-1
common/djangoapps/mitxmako/management/commands/preprocess_assets.py
+8
-0
common/djangoapps/terrain/browser.py
+2
-2
common/lib/xmodule/xmodule/error_module.py
+1
-1
common/lib/xmodule/xmodule/html_module.py
+2
-0
common/lib/xmodule/xmodule/tests/test_error_module.py
+40
-12
common/lib/xmodule/xmodule/tests/test_html_module.py
+40
-0
lms/djangoapps/courseware/module_render.py
+2
-3
lms/envs/aws.py
+6
-0
lms/static/sass/course/layout/_courseware_header.scss
+13
-9
lms/templates/navigation.html
+1
-1
rakefiles/assets.rake
+8
-4
requirements/edx-sandbox/base.txt
+3
-0
No files found.
AUTHORS
View file @
0fb11365
...
@@ -74,3 +74,4 @@ Jason Bau <jbau@stanford.edu>
...
@@ -74,3 +74,4 @@ Jason Bau <jbau@stanford.edu>
Frances Botsford <frances@edx.org>
Frances Botsford <frances@edx.org>
Jonah Stanley <Jonah_Stanley@brown.edu>
Jonah Stanley <Jonah_Stanley@brown.edu>
Slater Victoroff <slater.r.victoroff@gmail.com>
Slater Victoroff <slater.r.victoroff@gmail.com>
Peter Fogg <peter.p.fogg@gmail.com>
cms/djangoapps/contentstore/features/advanced-settings.feature
View file @
0fb11365
...
@@ -11,8 +11,6 @@ Feature: Advanced (manual) course policy
...
@@ -11,8 +11,6 @@ Feature: Advanced (manual) course policy
Given
I am on the Advanced Course Settings page in Studio
Given
I am on the Advanced Course Settings page in Studio
Then
the settings are alphabetized
Then
the settings are alphabetized
# Skipped because Ubuntu ChromeDriver cannot click notification "Cancel"
@skip
Scenario
:
Test cancel editing key value
Scenario
:
Test cancel editing key value
Given
I am on the Advanced Course Settings page in Studio
Given
I am on the Advanced Course Settings page in Studio
When
I edit the value of a policy key
When
I edit the value of a policy key
...
@@ -21,8 +19,6 @@ Feature: Advanced (manual) course policy
...
@@ -21,8 +19,6 @@ Feature: Advanced (manual) course policy
And
I reload the page
And
I reload the page
Then
the policy key value is unchanged
Then
the policy key value is unchanged
# Skipped because Ubuntu ChromeDriver cannot click notification "Save"
@skip
Scenario
:
Test editing key value
Scenario
:
Test editing key value
Given
I am on the Advanced Course Settings page in Studio
Given
I am on the Advanced Course Settings page in Studio
When
I edit the value of a policy key and save
When
I edit the value of a policy key and save
...
@@ -30,8 +26,6 @@ Feature: Advanced (manual) course policy
...
@@ -30,8 +26,6 @@ Feature: Advanced (manual) course policy
And
I reload the page
And
I reload the page
Then
the policy key value is changed
Then
the policy key value is changed
# Skipped because Ubuntu ChromeDriver cannot edit CodeMirror input
@skip
Scenario
:
Test how multi-line input appears
Scenario
:
Test how multi-line input appears
Given
I am on the Advanced Course Settings page in Studio
Given
I am on the Advanced Course Settings page in Studio
When
I create a JSON object as a value
When
I create a JSON object as a value
...
@@ -39,8 +33,6 @@ Feature: Advanced (manual) course policy
...
@@ -39,8 +33,6 @@ Feature: Advanced (manual) course policy
And
I reload the page
And
I reload the page
Then
it is displayed as formatted
Then
it is displayed as formatted
# Skipped because Ubuntu ChromeDriver cannot edit CodeMirror input
@skip
Scenario
:
Test automatic quoting of non-JSON values
Scenario
:
Test automatic quoting of non-JSON values
Given
I am on the Advanced Course Settings page in Studio
Given
I am on the Advanced Course Settings page in Studio
When
I create a non-JSON value not in quotes
When
I create a non-JSON value not in quotes
...
...
cms/djangoapps/contentstore/features/advanced-settings.py
View file @
0fb11365
...
@@ -42,8 +42,9 @@ def edit_the_value_of_a_policy_key(step):
...
@@ -42,8 +42,9 @@ def edit_the_value_of_a_policy_key(step):
It is hard to figure out how to get into the CodeMirror
It is hard to figure out how to get into the CodeMirror
area, so cheat and do it from the policy key field :)
area, so cheat and do it from the policy key field :)
"""
"""
e
=
world
.
css_find
(
KEY_CSS
)[
get_index_of
(
DISPLAY_NAME_KEY
)]
world
.
css_find
(
".CodeMirror"
)[
get_index_of
(
DISPLAY_NAME_KEY
)]
.
click
()
e
.
_element
.
send_keys
(
Keys
.
TAB
,
Keys
.
END
,
Keys
.
ARROW_LEFT
,
' '
,
'X'
)
g
=
world
.
css_find
(
"div.CodeMirror.CodeMirror-focused > div > textarea"
)
g
.
_element
.
send_keys
(
Keys
.
ARROW_LEFT
,
' '
,
'X'
)
@step
(
u'I edit the value of a policy key and save$'
)
@step
(
u'I edit the value of a policy key and save$'
)
...
@@ -123,10 +124,12 @@ def get_display_name_value():
...
@@ -123,10 +124,12 @@ def get_display_name_value():
def
change_display_name_value
(
step
,
new_value
):
def
change_display_name_value
(
step
,
new_value
):
e
=
world
.
css_find
(
KEY_CSS
)[
get_index_of
(
DISPLAY_NAME_KEY
)]
world
.
css_find
(
".CodeMirror"
)[
get_index_of
(
DISPLAY_NAME_KEY
)]
.
click
()
g
=
world
.
css_find
(
"div.CodeMirror.CodeMirror-focused > div > textarea"
)
display_name
=
get_display_name_value
()
display_name
=
get_display_name_value
()
for
count
in
range
(
len
(
display_name
)):
for
count
in
range
(
len
(
display_name
)):
e
.
_element
.
send_keys
(
Keys
.
TAB
,
Keys
.
END
,
Keys
.
BACK_SPACE
)
g
.
_element
.
send_keys
(
Keys
.
END
,
Keys
.
BACK_SPACE
)
# Must delete "" before typing the JSON value
# Must delete "" before typing the JSON value
e
.
_element
.
send_keys
(
Keys
.
TAB
,
Keys
.
END
,
Keys
.
BACK_SPACE
,
Keys
.
BACK_SPACE
,
new_value
)
g
.
_element
.
send_keys
(
Keys
.
END
,
Keys
.
BACK_SPACE
,
Keys
.
BACK_SPACE
,
new_value
)
press_the_notification_button
(
step
,
"Save"
)
press_the_notification_button
(
step
,
"Save"
)
cms/djangoapps/contentstore/features/common.py
View file @
0fb11365
...
@@ -161,3 +161,11 @@ def i_created_a_video_component(step):
...
@@ -161,3 +161,11 @@ def i_created_a_video_component(step):
'i4x://edx/templates/video/default'
,
'i4x://edx/templates/video/default'
,
'.xmodule_VideoModule'
'.xmodule_VideoModule'
)
)
@step
(
'I have clicked the new unit button'
)
def
open_new_unit
(
step
):
step
.
given
(
'I have opened a new course section in Studio'
)
step
.
given
(
'I have added a new subsection'
)
step
.
given
(
'I expand the first section'
)
world
.
css_click
(
'a.new-unit-item'
)
cms/djangoapps/contentstore/features/component_settings_editor_helpers.py
View file @
0fb11365
...
@@ -14,20 +14,27 @@ def create_component_instance(step, component_button_css, instance_id, expected_
...
@@ -14,20 +14,27 @@ def create_component_instance(step, component_button_css, instance_id, expected_
@world.absorb
@world.absorb
def
click_new_component_button
(
step
,
component_button_css
):
def
click_new_component_button
(
step
,
component_button_css
):
step
.
given
(
'I have opened a new course section in Studio'
)
step
.
given
(
'I have clicked the new unit button'
)
step
.
given
(
'I have added a new subsection'
)
step
.
given
(
'I expand the first section'
)
world
.
css_click
(
'a.new-unit-item'
)
world
.
css_click
(
component_button_css
)
world
.
css_click
(
component_button_css
)
@world.absorb
@world.absorb
def
click_component_from_menu
(
instance_id
,
expected_css
):
def
click_component_from_menu
(
instance_id
,
expected_css
):
"""
Creates a component from `instance_id`. For components with more
than one template, clicks on `elem_css` to create the new
component. Components with only one template are created as soon
as the user clicks the appropriate button, so we assert that the
expected component is present.
"""
elem_css
=
"a[data-location='
%
s']"
%
instance_id
elem_css
=
"a[data-location='
%
s']"
%
instance_id
assert_equal
(
1
,
len
(
world
.
css_find
(
elem_css
)))
elements
=
world
.
css_find
(
elem_css
)
world
.
css_click
(
elem_css
)
assert
(
len
(
elements
)
==
1
)
if
elements
[
0
][
'id'
]
==
instance_id
:
# If this is a component with multiple templates
world
.
css_click
(
elem_css
)
assert_equal
(
1
,
len
(
world
.
css_find
(
expected_css
)))
assert_equal
(
1
,
len
(
world
.
css_find
(
expected_css
)))
@world.absorb
@world.absorb
def
edit_component_and_select_settings
():
def
edit_component_and_select_settings
():
world
.
css_click
(
'a.edit-button'
)
world
.
css_click
(
'a.edit-button'
)
...
...
cms/djangoapps/contentstore/features/discussion-editor.feature
View file @
0fb11365
...
@@ -11,3 +11,7 @@ Feature: Discussion Component Editor
...
@@ -11,3 +11,7 @@ Feature: Discussion Component Editor
And
I edit and select Settings
And
I edit and select Settings
Then
I can modify the display name
Then
I can modify the display name
And
my display name change is persisted on save
And
my display name change is persisted on save
Scenario
:
Creating a discussion takes a single click
Given
I have clicked the new unit button
Then
creating a discussion takes a single click
cms/djangoapps/contentstore/features/discussion-editor.py
View file @
0fb11365
...
@@ -21,3 +21,10 @@ def i_see_only_the_settings_and_values(step):
...
@@ -21,3 +21,10 @@ def i_see_only_the_settings_and_values(step):
[
'Display Name'
,
"Discussion Tag"
,
True
],
[
'Display Name'
,
"Discussion Tag"
,
True
],
[
'Subcategory'
,
"Topic-Level Student-Visible Label"
,
True
]
[
'Subcategory'
,
"Topic-Level Student-Visible Label"
,
True
]
])
])
@step
(
'creating a discussion takes a single click'
)
def
discussion_takes_a_single_click
(
step
):
assert
(
not
world
.
is_css_present
(
'.xmodule_DiscussionModule'
))
world
.
css_click
(
"a[data-location='i4x://edx/templates/discussion/Discussion_Tag']"
)
assert
(
world
.
is_css_present
(
'.xmodule_DiscussionModule'
))
cms/djangoapps/contentstore/features/video.feature
View file @
0fb11365
...
@@ -4,3 +4,7 @@ Feature: Video Component
...
@@ -4,3 +4,7 @@ Feature: Video Component
Scenario
:
Autoplay is disabled in Studio
Scenario
:
Autoplay is disabled in Studio
Given
I have created a Video component
Given
I have created a Video component
Then
when I view the video it does not have autoplay enabled
Then
when I view the video it does not have autoplay enabled
Scenario
:
Creating a video takes a single click
Given
I have clicked the new unit button
Then
creating a video takes a single click
cms/djangoapps/contentstore/features/video.py
View file @
0fb11365
...
@@ -9,3 +9,10 @@ from lettuce import world, step
...
@@ -9,3 +9,10 @@ from lettuce import world, step
def
does_not_autoplay
(
step
):
def
does_not_autoplay
(
step
):
assert
world
.
css_find
(
'.video'
)[
0
][
'data-autoplay'
]
==
'False'
assert
world
.
css_find
(
'.video'
)[
0
][
'data-autoplay'
]
==
'False'
assert
world
.
css_find
(
'.video_control'
)[
0
]
.
has_class
(
'play'
)
assert
world
.
css_find
(
'.video_control'
)[
0
]
.
has_class
(
'play'
)
@step
(
'creating a video takes a single click'
)
def
video_takes_a_single_click
(
step
):
assert
(
not
world
.
is_css_present
(
'.xmodule_VideoModule'
))
world
.
css_click
(
"a[data-location='i4x://edx/templates/video/default']"
)
assert
(
world
.
is_css_present
(
'.xmodule_VideoModule'
))
cms/djangoapps/contentstore/tests/test_contentstore.py
View file @
0fb11365
...
@@ -77,14 +77,25 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
...
@@ -77,14 +77,25 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
self
.
client
=
Client
()
self
.
client
=
Client
()
self
.
client
.
login
(
username
=
uname
,
password
=
password
)
self
.
client
.
login
(
username
=
uname
,
password
=
password
)
def
test_advanced_components_in_edit_unit
(
self
):
def
check_components_on_page
(
self
,
component_types
,
expected_types
):
"""
Ensure that the right types end up on the page.
component_types is the list of advanced components.
expected_types is the list of elements that should appear on the page.
expected_types and component_types should be similar, but not
exactly the same -- for example, 'videoalpha' in
component_types should cause 'Video Alpha' to be present.
"""
store
=
modulestore
(
'direct'
)
store
=
modulestore
(
'direct'
)
import_from_xml
(
store
,
'common/test/data/'
,
[
'simple'
])
import_from_xml
(
store
,
'common/test/data/'
,
[
'simple'
])
course
=
store
.
get_item
(
Location
([
'i4x'
,
'edX'
,
'simple'
,
course
=
store
.
get_item
(
Location
([
'i4x'
,
'edX'
,
'simple'
,
'course'
,
'2012_Fall'
,
None
]),
depth
=
None
)
'course'
,
'2012_Fall'
,
None
]),
depth
=
None
)
course
.
advanced_modules
=
ADVANCED_COMPONENT_TYPES
course
.
advanced_modules
=
component_types
store
.
update_metadata
(
course
.
location
,
own_metadata
(
course
))
store
.
update_metadata
(
course
.
location
,
own_metadata
(
course
))
...
@@ -94,13 +105,20 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
...
@@ -94,13 +105,20 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
resp
=
self
.
client
.
get
(
reverse
(
'edit_unit'
,
kwargs
=
{
'location'
:
descriptor
.
location
.
url
()}))
resp
=
self
.
client
.
get
(
reverse
(
'edit_unit'
,
kwargs
=
{
'location'
:
descriptor
.
location
.
url
()}))
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
for
expected
in
expected_types
:
self
.
assertIn
(
expected
,
resp
.
content
)
def
test_advanced_components_in_edit_unit
(
self
):
# This could be made better, but for now let's just assert that we see the advanced modules mentioned in the page
# This could be made better, but for now let's just assert that we see the advanced modules mentioned in the page
# response HTML
# response HTML
self
.
assertIn
(
'Video Alpha'
,
resp
.
content
)
self
.
check_components_on_page
(
ADVANCED_COMPONENT_TYPES
,
[
'Video Alpha'
,
self
.
assertIn
(
'Word cloud'
,
resp
.
content
)
'Word cloud'
,
self
.
assertIn
(
'Annotation'
,
resp
.
content
)
'Annotation'
,
self
.
assertIn
(
'Open Ended Response'
,
resp
.
content
)
'Open Ended Response'
,
self
.
assertIn
(
'Peer Grading Interface'
,
resp
.
content
)
'Peer Grading Interface'
])
def
test_advanced_components_require_two_clicks
(
self
):
self
.
check_components_on_page
([
'videoalpha'
],
[
'Video Alpha'
])
def
check_edit_unit
(
self
,
test_course_name
):
def
check_edit_unit
(
self
,
test_course_name
):
import_from_xml
(
modulestore
(
'direct'
),
'common/test/data/'
,
[
test_course_name
])
import_from_xml
(
modulestore
(
'direct'
),
'common/test/data/'
,
[
test_course_name
])
...
...
cms/envs/aws.py
View file @
0fb11365
...
@@ -91,6 +91,12 @@ CACHES = ENV_TOKENS['CACHES']
...
@@ -91,6 +91,12 @@ CACHES = ENV_TOKENS['CACHES']
SESSION_COOKIE_DOMAIN
=
ENV_TOKENS
.
get
(
'SESSION_COOKIE_DOMAIN'
)
SESSION_COOKIE_DOMAIN
=
ENV_TOKENS
.
get
(
'SESSION_COOKIE_DOMAIN'
)
# allow for environments to specify what cookie name our login subsystem should use
# this is to fix a bug regarding simultaneous logins between edx.org and edge.edx.org which can
# happen with some browsers (e.g. Firefox)
if
ENV_TOKENS
.
get
(
'SESSION_COOKIE_NAME'
,
None
):
SESSION_COOKIE_NAME
=
ENV_TOKENS
.
get
(
'SESSION_COOKIE_NAME'
)
#Email overrides
#Email overrides
DEFAULT_FROM_EMAIL
=
ENV_TOKENS
.
get
(
'DEFAULT_FROM_EMAIL'
,
DEFAULT_FROM_EMAIL
)
DEFAULT_FROM_EMAIL
=
ENV_TOKENS
.
get
(
'DEFAULT_FROM_EMAIL'
,
DEFAULT_FROM_EMAIL
)
DEFAULT_FEEDBACK_EMAIL
=
ENV_TOKENS
.
get
(
'DEFAULT_FEEDBACK_EMAIL'
,
DEFAULT_FEEDBACK_EMAIL
)
DEFAULT_FEEDBACK_EMAIL
=
ENV_TOKENS
.
get
(
'DEFAULT_FEEDBACK_EMAIL'
,
DEFAULT_FEEDBACK_EMAIL
)
...
...
cms/static/coffee/src/views/unit.coffee
View file @
0fb11365
class
CMS
.
Views
.
UnitEdit
extends
Backbone
.
View
class
CMS
.
Views
.
UnitEdit
extends
Backbone
.
View
events
:
events
:
'click .new-component .new-component-type a'
:
'showComponentTemplates'
'click .new-component .new-component-type a.multiple-templates'
:
'showComponentTemplates'
'click .new-component .new-component-type a.single-template'
:
'saveNewComponent'
'click .new-component .cancel-button'
:
'closeNewComponent'
'click .new-component .cancel-button'
:
'closeNewComponent'
'click .new-component-templates .new-component-template a'
:
'saveNewComponent'
'click .new-component-templates .new-component-template a'
:
'saveNewComponent'
'click .new-component-templates .cancel-button'
:
'closeNewComponent'
'click .new-component-templates .cancel-button'
:
'closeNewComponent'
...
...
cms/templates/unit.html
View file @
0fb11365
...
@@ -53,9 +53,15 @@
...
@@ -53,9 +53,15 @@
<div
class=
"new-component"
>
<div
class=
"new-component"
>
<h5>
Add New Component
</h5>
<h5>
Add New Component
</h5>
<ul
class=
"new-component-type"
>
<ul
class=
"new-component-type"
>
% for type
in sorted(component_templates.key
s()):
% for type
, templates in sorted(component_templates.item
s()):
<li>
<li>
<a
href=
"#"
data-type=
"${type}"
>
% if type == 'advanced' or len(templates) > 1:
<a
href=
"#"
class=
"multiple-templates"
data-type=
"${type}"
>
% else:
% for _, location, _ in templates:
<a
href=
"#"
class=
"single-template"
data-type=
"${type}"
data-location=
"${location}"
>
% endfor
% endif
<span
class=
"large-template-icon large-${type}-icon"
></span>
<span
class=
"large-template-icon large-${type}-icon"
></span>
<span
class=
"name"
>
${type}
</span>
<span
class=
"name"
>
${type}
</span>
</a>
</a>
...
@@ -64,50 +70,52 @@
...
@@ -64,50 +70,52 @@
</ul>
</ul>
</div>
</div>
% for type, templates in sorted(component_templates.items()):
% for type, templates in sorted(component_templates.items()):
% if len(templates) > 1 or type == 'advanced':
<div
class=
"new-component-templates new-component-${type}"
>
<div
class=
"new-component-templates new-component-${type}"
>
% if type == "problem":
% if type == "problem":
<div
class=
"tab-group tabs"
>
<div
class=
"tab-group tabs"
>
<ul
class=
"problem-type-tabs nav-tabs"
>
<ul
class=
"problem-type-tabs nav-tabs"
>
<li
class=
"current"
>
<li
class=
"current"
>
<a
class=
"link-tab"
href=
"#tab1"
>
Common Problem Types
</a>
<a
class=
"link-tab"
href=
"#tab1"
>
Common Problem Types
</a>
</li>
</li>
<li>
<li>
<a
class=
"link-tab"
href=
"#tab2"
>
Advanced
</a>
<a
class=
"link-tab"
href=
"#tab2"
>
Advanced
</a>
</li>
</li>
</ul>
% endif
<div
class=
"tab current"
id=
"tab1"
>
<ul
class=
"new-component-template"
>
% for name, location, has_markdown in templates:
% if has_markdown or type != "problem":
<li
class=
"editor-md"
>
<a
href=
"#"
id=
"${location}"
data-location=
"${location}"
>
<span
class=
"name"
>
${name}
</span>
</a>
</li>
% endif
%endfor
</ul>
</div>
% if type == "problem":
<div
class=
"tab"
id=
"tab2"
>
<ul
class=
"new-component-template"
>
% for name, location, has_markdown in templates:
% if not has_markdown:
<li
class=
"editor-manual"
>
<a
href=
"#"
id=
"${location}"
data-location=
"${location}"
>
<span
class=
"name"
>
${name}
</span>
</a>
</li>
% endif
% endfor
</ul>
</ul>
</div>
% endif
</div>
<div
class=
"tab current"
id=
"tab1"
>
% endif
<ul
class=
"new-component-template"
>
<a
href=
"#"
class=
"cancel-button"
>
Cancel
</a>
% for name, location, has_markdown in templates:
</div>
% if has_markdown or type != "problem":
<li
class=
"editor-md"
>
<a
href=
"#"
id=
"${location}"
data-location=
"${location}"
>
<span
class=
"name"
>
${name}
</span>
</a>
</li>
% endif
%endfor
</ul>
</div>
% if type == "problem":
<div
class=
"tab"
id=
"tab2"
>
<ul
class=
"new-component-template"
>
% for name, location, has_markdown in templates:
% if not has_markdown:
<li
class=
"editor-manual"
>
<a
href=
"#"
id=
"${location}"
data-location=
"${location}"
>
<span
class=
"name"
>
${name}
</span>
</a>
</li>
% endif
% endfor
</ul>
</div>
</div>
% endif
<a
href=
"#"
class=
"cancel-button"
>
Cancel
</a>
</div>
% endif
% endfor
% endfor
</li>
</li>
</ol>
</ol>
...
...
common/djangoapps/mitxmako/makoloader.py
View file @
0fb11365
...
@@ -44,7 +44,11 @@ class MakoLoader(object):
...
@@ -44,7 +44,11 @@ class MakoLoader(object):
if
source
.
startswith
(
"## mako
\n
"
):
if
source
.
startswith
(
"## mako
\n
"
):
# This is a mako template
# This is a mako template
template
=
Template
(
filename
=
file_path
,
module_directory
=
self
.
module_directory
,
uri
=
template_name
)
template
=
Template
(
filename
=
file_path
,
module_directory
=
self
.
module_directory
,
input_encoding
=
'utf-8'
,
output_encoding
=
'utf-8'
,
uri
=
template_name
)
return
template
,
None
return
template
,
None
else
:
else
:
# This is a regular template
# This is a regular template
...
...
common/djangoapps/mitxmako/management/commands/preprocess_assets.py
View file @
0fb11365
...
@@ -14,6 +14,7 @@ from django.core.management.base import NoArgsCommand
...
@@ -14,6 +14,7 @@ from django.core.management.base import NoArgsCommand
from
django.conf
import
settings
from
django.conf
import
settings
from
mako.template
import
Template
from
mako.template
import
Template
import
textwrap
class
Command
(
NoArgsCommand
):
class
Command
(
NoArgsCommand
):
"""
"""
...
@@ -61,5 +62,12 @@ class Command(NoArgsCommand):
...
@@ -61,5 +62,12 @@ class Command(NoArgsCommand):
result in `outfile`.
result in `outfile`.
"""
"""
with
open
(
outfile
,
"w"
)
as
_outfile
:
with
open
(
outfile
,
"w"
)
as
_outfile
:
_outfile
.
write
(
textwrap
.
dedent
(
"""
\
/*
* This file is dynamically generated and ignored by Git.
* DO NOT MAKE CHANGES HERE. Instead, go edit its template:
*
%
s
*/
"""
%
infile
))
_outfile
.
write
(
Template
(
filename
=
str
(
infile
))
.
render
(
env
=
self
.
__context
()))
_outfile
.
write
(
Template
(
filename
=
str
(
infile
))
.
render
(
env
=
self
.
__context
()))
common/djangoapps/terrain/browser.py
View file @
0fb11365
...
@@ -87,8 +87,8 @@ def reset_data(scenario):
...
@@ -87,8 +87,8 @@ def reset_data(scenario):
LOGGER
.
debug
(
"Flushing the test database..."
)
LOGGER
.
debug
(
"Flushing the test database..."
)
call_command
(
'flush'
,
interactive
=
False
)
call_command
(
'flush'
,
interactive
=
False
)
# Uncomment below to trigger a screenshot on error
@after.each_scenario
#
@after.each_scenario
def
screenshot_on_error
(
scenario
):
def
screenshot_on_error
(
scenario
):
"""
"""
Save a screenshot to help with debugging.
Save a screenshot to help with debugging.
...
...
common/lib/xmodule/xmodule/error_module.py
View file @
0fb11365
...
@@ -121,7 +121,7 @@ class ErrorDescriptor(ErrorFields, JSONEditingDescriptor):
...
@@ -121,7 +121,7 @@ class ErrorDescriptor(ErrorFields, JSONEditingDescriptor):
def
from_descriptor
(
cls
,
descriptor
,
error_msg
=
'Error not available'
):
def
from_descriptor
(
cls
,
descriptor
,
error_msg
=
'Error not available'
):
return
cls
.
_construct
(
return
cls
.
_construct
(
descriptor
.
system
,
descriptor
.
system
,
descriptor
.
_model_data
,
str
(
descriptor
)
,
error_msg
,
error_msg
,
location
=
descriptor
.
location
,
location
=
descriptor
.
location
,
)
)
...
...
common/lib/xmodule/xmodule/html_module.py
View file @
0fb11365
...
@@ -32,6 +32,8 @@ class HtmlModule(HtmlFields, XModule):
...
@@ -32,6 +32,8 @@ class HtmlModule(HtmlFields, XModule):
css
=
{
'scss'
:
[
resource_string
(
__name__
,
'css/html/display.scss'
)]}
css
=
{
'scss'
:
[
resource_string
(
__name__
,
'css/html/display.scss'
)]}
def
get_html
(
self
):
def
get_html
(
self
):
if
self
.
system
.
anonymous_student_id
:
return
self
.
data
.
replace
(
"
%%
USER_ID
%%
"
,
self
.
system
.
anonymous_student_id
)
return
self
.
data
return
self
.
data
...
...
common/lib/xmodule/xmodule/tests/test_error_module.py
View file @
0fb11365
...
@@ -4,6 +4,9 @@ Tests for ErrorModule and NonStaffErrorModule
...
@@ -4,6 +4,9 @@ Tests for ErrorModule and NonStaffErrorModule
import
unittest
import
unittest
from
xmodule.tests
import
test_system
from
xmodule.tests
import
test_system
import
xmodule.error_module
as
error_module
import
xmodule.error_module
as
error_module
from
xmodule.modulestore
import
Location
from
xmodule.x_module
import
XModuleDescriptor
from
mock
import
MagicMock
class
TestErrorModule
(
unittest
.
TestCase
):
class
TestErrorModule
(
unittest
.
TestCase
):
...
@@ -14,22 +17,33 @@ class TestErrorModule(unittest.TestCase):
...
@@ -14,22 +17,33 @@ class TestErrorModule(unittest.TestCase):
self
.
system
=
test_system
()
self
.
system
=
test_system
()
self
.
org
=
"org"
self
.
org
=
"org"
self
.
course
=
"course"
self
.
course
=
"course"
self
.
fake_xml
=
"<problem />"
self
.
location
=
Location
([
'i4x'
,
self
.
org
,
self
.
course
,
None
,
None
])
self
.
valid_xml
=
"<problem />"
self
.
broken_xml
=
"<problem>"
self
.
broken_xml
=
"<problem>"
self
.
error_msg
=
"Error"
self
.
error_msg
=
"Error"
def
test_error_module_
create
(
self
):
def
test_error_module_
xml_rendering
(
self
):
descriptor
=
error_module
.
ErrorDescriptor
.
from_xml
(
descriptor
=
error_module
.
ErrorDescriptor
.
from_xml
(
self
.
fake_xml
,
self
.
system
,
self
.
org
,
self
.
course
)
self
.
valid_xml
,
self
.
system
,
self
.
org
,
self
.
course
,
self
.
error_msg
)
self
.
assertTrue
(
isinstance
(
descriptor
,
error_module
.
ErrorDescriptor
))
self
.
assertTrue
(
isinstance
(
descriptor
,
error_module
.
ErrorDescriptor
))
def
test_error_module_rendering
(
self
):
descriptor
=
error_module
.
ErrorDescriptor
.
from_xml
(
self
.
fake_xml
,
self
.
system
,
self
.
org
,
self
.
course
,
self
.
error_msg
)
module
=
descriptor
.
xmodule
(
self
.
system
)
module
=
descriptor
.
xmodule
(
self
.
system
)
rendered_html
=
module
.
get_html
()
rendered_html
=
module
.
get_html
()
self
.
assertIn
(
self
.
error_msg
,
rendered_html
)
self
.
assertIn
(
self
.
error_msg
,
rendered_html
)
self
.
assertIn
(
self
.
fake_xml
,
rendered_html
)
self
.
assertIn
(
self
.
valid_xml
,
rendered_html
)
def
test_error_module_from_descriptor
(
self
):
descriptor
=
MagicMock
([
XModuleDescriptor
],
system
=
self
.
system
,
location
=
self
.
location
,
_model_data
=
self
.
valid_xml
)
error_descriptor
=
error_module
.
ErrorDescriptor
.
from_descriptor
(
descriptor
,
self
.
error_msg
)
self
.
assertTrue
(
isinstance
(
error_descriptor
,
error_module
.
ErrorDescriptor
))
module
=
error_descriptor
.
xmodule
(
self
.
system
)
rendered_html
=
module
.
get_html
()
self
.
assertIn
(
self
.
error_msg
,
rendered_html
)
self
.
assertIn
(
str
(
descriptor
),
rendered_html
)
class
TestNonStaffErrorModule
(
TestErrorModule
):
class
TestNonStaffErrorModule
(
TestErrorModule
):
...
@@ -39,13 +53,27 @@ class TestNonStaffErrorModule(TestErrorModule):
...
@@ -39,13 +53,27 @@ class TestNonStaffErrorModule(TestErrorModule):
def
test_non_staff_error_module_create
(
self
):
def
test_non_staff_error_module_create
(
self
):
descriptor
=
error_module
.
NonStaffErrorDescriptor
.
from_xml
(
descriptor
=
error_module
.
NonStaffErrorDescriptor
.
from_xml
(
self
.
fake
_xml
,
self
.
system
,
self
.
org
,
self
.
course
)
self
.
valid
_xml
,
self
.
system
,
self
.
org
,
self
.
course
)
self
.
assertTrue
(
isinstance
(
descriptor
,
error_module
.
NonStaffErrorDescriptor
))
self
.
assertTrue
(
isinstance
(
descriptor
,
error_module
.
NonStaffErrorDescriptor
))
def
test_
non_staff_error_module_rendering
(
self
):
def
test_
from_xml_render
(
self
):
descriptor
=
error_module
.
NonStaffErrorDescriptor
.
from_xml
(
descriptor
=
error_module
.
NonStaffErrorDescriptor
.
from_xml
(
self
.
fake
_xml
,
self
.
system
,
self
.
org
,
self
.
course
)
self
.
valid
_xml
,
self
.
system
,
self
.
org
,
self
.
course
)
module
=
descriptor
.
xmodule
(
self
.
system
)
module
=
descriptor
.
xmodule
(
self
.
system
)
rendered_html
=
module
.
get_html
()
rendered_html
=
module
.
get_html
()
self
.
assertNotIn
(
self
.
error_msg
,
rendered_html
)
self
.
assertNotIn
(
self
.
error_msg
,
rendered_html
)
self
.
assertNotIn
(
self
.
fake_xml
,
rendered_html
)
self
.
assertNotIn
(
self
.
valid_xml
,
rendered_html
)
def
test_error_module_from_descriptor
(
self
):
descriptor
=
MagicMock
([
XModuleDescriptor
],
system
=
self
.
system
,
location
=
self
.
location
,
_model_data
=
self
.
valid_xml
)
error_descriptor
=
error_module
.
NonStaffErrorDescriptor
.
from_descriptor
(
descriptor
,
self
.
error_msg
)
self
.
assertTrue
(
isinstance
(
error_descriptor
,
error_module
.
ErrorDescriptor
))
module
=
error_descriptor
.
xmodule
(
self
.
system
)
rendered_html
=
module
.
get_html
()
self
.
assertNotIn
(
self
.
error_msg
,
rendered_html
)
self
.
assertNotIn
(
str
(
descriptor
),
rendered_html
)
common/lib/xmodule/xmodule/tests/test_html_module.py
0 → 100644
View file @
0fb11365
import
unittest
from
mock
import
Mock
from
xmodule.html_module
import
HtmlModule
from
xmodule.modulestore
import
Location
from
.
import
test_system
class
HtmlModuleSubstitutionTestCase
(
unittest
.
TestCase
):
location
=
Location
([
"i4x"
,
"edX"
,
"toy"
,
"html"
,
"simple_html"
])
descriptor
=
Mock
()
def
test_substitution_works
(
self
):
sample_xml
=
'''
%%
USER_ID
%%
'''
module_data
=
{
'data'
:
sample_xml
}
module_system
=
test_system
()
module
=
HtmlModule
(
module_system
,
self
.
location
,
self
.
descriptor
,
module_data
)
self
.
assertEqual
(
module
.
get_html
(),
str
(
module_system
.
anonymous_student_id
))
def
test_substitution_without_magic_string
(
self
):
sample_xml
=
'''
<html>
<p>Hi USER_ID!11!</p>
</html>
'''
module_data
=
{
'data'
:
sample_xml
}
module
=
HtmlModule
(
test_system
(),
self
.
location
,
self
.
descriptor
,
module_data
)
self
.
assertEqual
(
module
.
get_html
(),
sample_xml
)
def
test_substitution_without_anonymous_student_id
(
self
):
sample_xml
=
'''
%%
USER_ID
%%
'''
module_data
=
{
'data'
:
sample_xml
}
module_system
=
test_system
()
module_system
.
anonymous_student_id
=
None
module
=
HtmlModule
(
module_system
,
self
.
location
,
self
.
descriptor
,
module_data
)
self
.
assertEqual
(
module
.
get_html
(),
sample_xml
)
lms/djangoapps/courseware/module_render.py
View file @
0fb11365
...
@@ -335,9 +335,8 @@ def get_module_for_descriptor(user, request, descriptor, model_data_cache, cours
...
@@ -335,9 +335,8 @@ def get_module_for_descriptor(user, request, descriptor, model_data_cache, cours
else
:
else
:
err_descriptor_class
=
NonStaffErrorDescriptor
err_descriptor_class
=
NonStaffErrorDescriptor
err_descriptor
=
err_descriptor_class
.
from_xml
(
err_descriptor
=
err_descriptor_class
.
from_descriptor
(
str
(
descriptor
),
descriptor
.
system
,
descriptor
,
org
=
descriptor
.
location
.
org
,
course
=
descriptor
.
location
.
course
,
error_msg
=
exc_info_to_str
(
sys
.
exc_info
())
error_msg
=
exc_info_to_str
(
sys
.
exc_info
())
)
)
...
...
lms/envs/aws.py
View file @
0fb11365
...
@@ -102,6 +102,12 @@ with open(ENV_ROOT / CONFIG_PREFIX + "env.json") as env_file:
...
@@ -102,6 +102,12 @@ with open(ENV_ROOT / CONFIG_PREFIX + "env.json") as env_file:
SITE_NAME
=
ENV_TOKENS
[
'SITE_NAME'
]
SITE_NAME
=
ENV_TOKENS
[
'SITE_NAME'
]
SESSION_COOKIE_DOMAIN
=
ENV_TOKENS
.
get
(
'SESSION_COOKIE_DOMAIN'
)
SESSION_COOKIE_DOMAIN
=
ENV_TOKENS
.
get
(
'SESSION_COOKIE_DOMAIN'
)
# allow for environments to specify what cookie name our login subsystem should use
# this is to fix a bug regarding simultaneous logins between edx.org and edge.edx.org which can
# happen with some browsers (e.g. Firefox)
if
ENV_TOKENS
.
get
(
'SESSION_COOKIE_NAME'
,
None
):
SESSION_COOKIE_NAME
=
ENV_TOKENS
.
get
(
'SESSION_COOKIE_NAME'
)
BOOK_URL
=
ENV_TOKENS
[
'BOOK_URL'
]
BOOK_URL
=
ENV_TOKENS
[
'BOOK_URL'
]
MEDIA_URL
=
ENV_TOKENS
[
'MEDIA_URL'
]
MEDIA_URL
=
ENV_TOKENS
[
'MEDIA_URL'
]
LOG_DIR
=
ENV_TOKENS
[
'LOG_DIR'
]
LOG_DIR
=
ENV_TOKENS
[
'LOG_DIR'
]
...
...
lms/static/sass/course/layout/_courseware_header.scss
View file @
0fb11365
...
@@ -62,7 +62,8 @@ nav.course-material {
...
@@ -62,7 +62,8 @@ nav.course-material {
header
.global.slim
{
header
.global.slim
{
@include
box-shadow
(
0
1px
2px
rgba
(
0
,
0
,
0
,
.1
));
@include
box-shadow
(
0
1px
2px
rgba
(
0
,
0
,
0
,
.1
));
height
:
50px
;
height
:
auto
;
padding
:
5px
0
10px
0
;
border-bottom
:
1px
solid
$outer-border-color
;
border-bottom
:
1px
solid
$outer-border-color
;
background
:
$white
;
background
:
$white
;
...
@@ -106,16 +107,15 @@ header.global.slim {
...
@@ -106,16 +107,15 @@ header.global.slim {
padding-top
:
5px
;
padding-top
:
5px
;
}
}
h1
.logo
{
h1
.logo
{
margin-left
:
13px
;
margin
:
0
10px
0
13px
;
margin-right
:
20px
;
padding-right
:
20px
;
padding-right
:
20px
;
&
:before
{
&
:before
{
@extend
.faded-vertical-divider
;
@extend
.faded-vertical-divider
;
content
:
""
;
content
:
""
;
display
:
block
;
display
:
block
;
height
:
40
px
;
height
:
35
px
;
position
:
absolute
;
position
:
absolute
;
right
:
3px
;
right
:
3px
;
top
:
0
;
top
:
0
;
...
@@ -126,12 +126,16 @@ header.global.slim {
...
@@ -126,12 +126,16 @@ header.global.slim {
@extend
.faded-vertical-divider-light
;
@extend
.faded-vertical-divider-light
;
content
:
""
;
content
:
""
;
display
:
block
;
display
:
block
;
height
:
40
px
;
height
:
35
px
;
position
:
absolute
;
position
:
absolute
;
right
:
0
px
;
right
:
0
;
top
:
0
;
top
:
0
;
width
:
1px
;
width
:
1px
;
}
}
img
{
height
:
30px
;
}
}
}
.nav-global
{
.nav-global
{
...
@@ -147,6 +151,7 @@ header.global.slim {
...
@@ -147,6 +151,7 @@ header.global.slim {
color
:
#777
;
color
:
#777
;
letter-spacing
:
0
;
letter-spacing
:
0
;
margin-top
:
9px
;
margin-top
:
9px
;
margin-bottom
:
0
;
text-transform
:
none
;
text-transform
:
none
;
text-shadow
:
0
1px
0
#fff
;
text-shadow
:
0
1px
0
#fff
;
white-space
:
nowrap
;
white-space
:
nowrap
;
...
@@ -168,4 +173,4 @@ header.global.slim {
...
@@ -168,4 +173,4 @@ header.global.slim {
font-weight
:
bold
;
font-weight
:
bold
;
letter-spacing
:
0
;
letter-spacing
:
0
;
}
}
}
}
\ No newline at end of file
lms/templates/navigation.html
View file @
0fb11365
...
@@ -39,7 +39,7 @@ site_status_msg = get_site_status_msg(course_id)
...
@@ -39,7 +39,7 @@ site_status_msg = get_site_status_msg(course_id)
<h1
class=
"logo"
>
<h1
class=
"logo"
>
<a
href=
"${marketing_link('ROOT')}"
>
<a
href=
"${marketing_link('ROOT')}"
>
<img
src=
"${static.url(branding.get_logo_url(request.META.get('HTTP_HOST')))}"
/>
<img
src=
"${static.url(branding.get_logo_url(request.META.get('HTTP_HOST')))}"
alt=
"edX home"
/>
</a></h1>
</a></h1>
% if course:
% if course:
...
...
rakefiles/assets.rake
View file @
0fb11365
...
@@ -27,10 +27,11 @@ def coffee_cmd(watch=false, debug=false)
...
@@ -27,10 +27,11 @@ def coffee_cmd(watch=false, debug=false)
#
#
# Ref: https://github.com/joyent/node/issues/2479
# Ref: https://github.com/joyent/node/issues/2479
#
#
# Instead, watch 50 files per process in parallel
# Rather than watching all of the directories in one command
# watch each static files subdirectory separately
cmds
=
[]
cmds
=
[]
Dir
[
'*/static/**/*.coffee'
].
each_slice
(
50
)
do
|
coffee_files
|
[
'lms/static/coffee'
,
'cms/static/coffee'
,
'common/static/coffee'
,
'common/static/xmodule'
].
each
do
|
coffee_folder
|
cmds
<<
"node_modules/.bin/coffee --watch --compile
#{
coffee_f
iles
.
join
(
' '
)
}
"
cmds
<<
"node_modules/.bin/coffee --watch --compile
#{
coffee_f
older
}
"
end
end
cmds
cmds
else
else
...
@@ -119,12 +120,15 @@ namespace :assets do
...
@@ -119,12 +120,15 @@ namespace :assets do
namespace
:sass
do
namespace
:sass
do
# In watch mode, sass doesn't immediately compile out of date files,
# In watch mode, sass doesn't immediately compile out of date files,
# so force a recompile first
# so force a recompile first
task
:_watch
=>
'assets:sass:debug'
# Also force xmodule files to be generated before we start watching anything
task
:_watch
=>
[
'assets:sass:debug'
,
'assets:xmodule'
]
multitask
:debug
=>
'assets:xmodule:debug'
multitask
:debug
=>
'assets:xmodule:debug'
end
end
multitask
:coffee
=>
'assets:xmodule'
multitask
:coffee
=>
'assets:xmodule'
namespace
:coffee
do
namespace
:coffee
do
# Force xmodule files to be generated before we start watching anything
task
:_watch
=>
'assets:xmodule'
multitask
:debug
=>
'assets:xmodule:debug'
multitask
:debug
=>
'assets:xmodule:debug'
end
end
end
end
...
...
requirements/edx-sandbox/base.txt
View file @
0fb11365
numpy==1.6.2
numpy==1.6.2
networkx==1.7
sympy==0.7.1
\ 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