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
eb70f230
Commit
eb70f230
authored
Jul 02, 2015
by
Ali Mohammad
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8749 from edx/rc/2015-06-29
Merge back into master
parents
0bb519c2
9ada9d61
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
208 additions
and
45 deletions
+208
-45
cms/djangoapps/contentstore/tests/test_utils.py
+1
-1
cms/static/js/index.js
+2
-0
cms/templates/index.html
+3
-3
common/djangoapps/dark_lang/middleware.py
+18
-10
common/djangoapps/student/cookies.py
+12
-3
common/djangoapps/student/tests/test_login.py
+15
-0
common/lib/xmodule/xmodule/css/capa/display.scss
+22
-0
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
+10
-2
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
+69
-0
common/lib/xmodule/xmodule/modulestore/xml_importer.py
+3
-5
common/lib/xmodule/xmodule/tests/test_delay_between_attempts.py
+18
-18
common/lib/xmodule/xmodule/video_module/video_module.py
+2
-1
lms/djangoapps/courseware/tests/test_submitting_problems.py
+27
-1
lms/static/sass/views/_verification.scss
+5
-0
requirements/edx/github.txt
+1
-1
No files found.
cms/djangoapps/contentstore/tests/test_utils.py
View file @
eb70f230
...
...
@@ -154,7 +154,7 @@ class XBlockVisibilityTestCase(ModuleStoreTestCase):
super
(
XBlockVisibilityTestCase
,
self
)
.
setUp
()
self
.
dummy_user
=
ModuleStoreEnum
.
UserID
.
test
self
.
past
=
datetime
(
1970
,
1
,
1
)
self
.
past
=
datetime
(
1970
,
1
,
1
,
tzinfo
=
UTC
)
self
.
future
=
datetime
.
now
(
UTC
)
+
timedelta
(
days
=
1
)
self
.
course
=
CourseFactory
.
create
()
...
...
cms/static/js/index.js
View file @
eb70f230
...
...
@@ -141,6 +141,8 @@ define(["domReady", "jquery", "underscore", "js/utils/cancel_on_escape", "js/vie
e
.
preventDefault
();
$
(
'.courses-tab'
).
toggleClass
(
'active'
,
tab
===
'courses'
);
$
(
'.libraries-tab'
).
toggleClass
(
'active'
,
tab
===
'libraries'
);
// Also toggle this course-related notice shown below the course tab, if it is present:
$
(
'.wrapper-creationrights'
).
toggleClass
(
'is-hidden'
,
tab
===
'libraries'
);
};
};
...
...
cms/templates/index.html
View file @
eb70f230
...
...
@@ -103,7 +103,9 @@
</form>
</div>
%if libraries_enabled:
% endif
%if libraries_enabled and show_new_library_button:
<div
class=
"wrapper-create-element wrapper-create-library"
>
<form
class=
"form-create create-library library-info"
id=
"create-library-form"
name=
"create-library-form"
>
<div
class=
"wrap-error"
>
...
...
@@ -154,8 +156,6 @@
</div>
% endif
% endif
<!-- STATE: processing courses -->
%if allow_course_reruns and rerun_creator_status and len(in_process_course_actions) > 0:
<div
class=
"courses courses-processing"
>
...
...
common/djangoapps/dark_lang/middleware.py
View file @
eb70f230
...
...
@@ -17,7 +17,6 @@ from dark_lang.models import DarkLangConfig
from
openedx.core.djangoapps.user_api.preferences.api
import
(
delete_user_preference
,
get_user_preference
,
set_user_preference
)
from
openedx.core.djangoapps.user_api.errors
import
UserNotFound
from
lang_pref
import
LANGUAGE_KEY
# TODO re-import this once we're on Django 1.5 or greater. [PLAT-671]
...
...
@@ -133,27 +132,36 @@ class DarkLangMiddleware(object):
and that language doesn't appear in ``self.released_langs``,
then set the session LANGUAGE_SESSION_KEY to that language.
"""
auth_user
=
request
.
user
.
is_authenticated
()
if
'clear-lang'
in
request
.
GET
:
# Reset dark lang
# delete the session language key (if one is set)
if
LANGUAGE_SESSION_KEY
in
request
.
session
:
del
request
.
session
[
LANGUAGE_SESSION_KEY
]
if
auth_user
:
# Reset user's dark lang preference to null
delete_user_preference
(
request
.
user
,
DARK_LANGUAGE_KEY
)
# Reset user's language to their language preference, if they have on
e
# Get & set user's preferred languag
e
user_pref
=
get_user_preference
(
request
.
user
,
LANGUAGE_KEY
)
if
user_pref
:
request
.
session
[
LANGUAGE_SESSION_KEY
]
=
user_pref
elif
LANGUAGE_SESSION_KEY
in
request
.
session
:
del
request
.
session
[
LANGUAGE_SESSION_KEY
]
return
# Get the user's preview lang - this is either going to be set from a query
# param `?preview-lang=xx`, or we may have one already set as a dark lang preference.
preview_lang
=
request
.
GET
.
get
(
'preview-lang'
,
None
)
if
not
preview_lang
:
try
:
# Try to get the request user's preference (might not have a user, though)
if
not
preview_lang
and
auth_user
:
# Get the request user's dark lang preference
preview_lang
=
get_user_preference
(
request
.
user
,
DARK_LANGUAGE_KEY
)
except
UserNotFound
:
return
# User doesn't have a dark lang preference, so just return
if
not
preview_lang
:
return
# Set the session key to the requested preview lang
request
.
session
[
LANGUAGE_SESSION_KEY
]
=
preview_lang
# Make sure that we set the requested preview lang as the dark lang preference for the
# user, so that the lang_pref middleware doesn't clobber away the dark lang preview.
if
auth_user
:
set_user_preference
(
request
.
user
,
DARK_LANGUAGE_KEY
,
preview_lang
)
common/djangoapps/student/cookies.py
View file @
eb70f230
...
...
@@ -65,7 +65,12 @@ def set_logged_in_cookies(request, response, user):
# is logged in. This is just a boolean value, so it's not very useful.
# In the future, we should be able to replace this with the "user info"
# cookie set below.
response
.
set_cookie
(
settings
.
EDXMKTG_LOGGED_IN_COOKIE_NAME
,
'true'
,
secure
=
None
,
**
cookie_settings
)
response
.
set_cookie
(
settings
.
EDXMKTG_LOGGED_IN_COOKIE_NAME
.
encode
(
'utf-8'
),
'true'
,
secure
=
None
,
**
cookie_settings
)
# Set a cookie with user info. This can be used by external sites
# to customize content based on user information. Currently,
...
...
@@ -107,7 +112,7 @@ def set_logged_in_cookies(request, response, user):
user_info_cookie_is_secure
=
request
.
is_secure
()
response
.
set_cookie
(
settings
.
EDXMKTG_USER_INFO_COOKIE_NAME
,
settings
.
EDXMKTG_USER_INFO_COOKIE_NAME
.
encode
(
'utf-8'
)
,
json
.
dumps
(
user_info
),
secure
=
user_info_cookie_is_secure
,
**
cookie_settings
...
...
@@ -128,7 +133,11 @@ def delete_logged_in_cookies(response):
"""
for
cookie_name
in
[
settings
.
EDXMKTG_LOGGED_IN_COOKIE_NAME
,
settings
.
EDXMKTG_USER_INFO_COOKIE_NAME
]:
response
.
delete_cookie
(
cookie_name
,
path
=
'/'
,
domain
=
settings
.
SESSION_COOKIE_DOMAIN
)
response
.
delete_cookie
(
cookie_name
.
encode
(
'utf-8'
),
path
=
'/'
,
domain
=
settings
.
SESSION_COOKIE_DOMAIN
)
return
response
...
...
common/djangoapps/student/tests/test_login.py
View file @
eb70f230
...
...
@@ -6,6 +6,7 @@ import unittest
from
django.test
import
TestCase
from
django.test.client
import
Client
from
django.test.utils
import
override_settings
from
django.conf
import
settings
from
django.core.cache
import
cache
from
django.core.urlresolvers
import
reverse
,
NoReverseMatch
...
...
@@ -195,6 +196,20 @@ class LoginTest(TestCase):
cookie
=
self
.
client
.
cookies
[
cookie_name
]
self
.
assertIn
(
"01-Jan-1970"
,
cookie
.
get
(
'expires'
))
@override_settings
(
EDXMKTG_LOGGED_IN_COOKIE_NAME
=
u"unicode-logged-in"
,
EDXMKTG_USER_INFO_COOKIE_NAME
=
u"unicode-user-info"
,
)
def
test_unicode_mktg_cookie_names
(
self
):
# When logged in cookie names are loaded from JSON files, they may
# have type `unicode` instead of `str`, which can cause errors
# when calling Django cookie manipulation functions.
response
,
_
=
self
.
_login_response
(
'test@edx.org'
,
'test_password'
)
self
.
_assert_response
(
response
,
success
=
True
)
response
=
self
.
client
.
post
(
reverse
(
'logout'
))
self
.
assertRedirects
(
response
,
"/"
)
@patch.dict
(
"django.conf.settings.FEATURES"
,
{
'SQUELCH_PII_IN_LOGS'
:
True
})
def
test_logout_logging_no_pii
(
self
):
response
,
_
=
self
.
_login_response
(
'test@edx.org'
,
'test_password'
)
...
...
common/lib/xmodule/xmodule/css/capa/display.scss
View file @
eb70f230
...
...
@@ -16,6 +16,7 @@
// * +Problem - Rubric
// * +Problem - Annotation
// * +Problem - Choice Text Group
// * +Problem - Image Input Overrides
// +Variables - Capa
// ====================
...
...
@@ -1350,3 +1351,24 @@ div.problem {
}
}
}
// +Problem - Image Input Overrides
// ====================
// NOTE: temporary override until image inputs use same base html structure as other common capa input types.
div
.problem
.imageinput.capa_inputtype
{
.status
{
display
:
inline-block
;
position
:
relative
;
top
:
3px
;
width
:
25px
;
height
:
20px
;
}
.correct
{
background
:
url('../images/correct-icon.png')
center
center
no-repeat
;
}
.incorrect
{
background
:
url('../images/incorrect-icon.png')
center
center
no-repeat
;
}
}
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
View file @
eb70f230
...
...
@@ -1875,6 +1875,11 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
block_data
.
fields
=
settings
new_id
=
new_structure
[
'_id'
]
# source_version records which revision a block was copied from. In this method, we're updating
# the block, so it's no longer a direct copy, and we can remove the source_version reference.
block_data
.
edit_info
.
source_version
=
None
self
.
version_block
(
block_data
,
user_id
,
new_id
)
self
.
update_structure
(
course_key
,
new_structure
)
# update the index entry if appropriate
...
...
@@ -2969,8 +2974,11 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
if
getattr
(
destination_block
.
edit_info
,
key
)
is
None
:
setattr
(
destination_block
.
edit_info
,
key
,
val
)
# introduce new edit info field for tracing where copied/published blocks came
destination_block
.
edit_info
.
source_version
=
new_block
.
edit_info
.
update_version
# If the block we are copying from was itself a copy, then just
# reference the original source, rather than the copy.
destination_block
.
edit_info
.
source_version
=
(
new_block
.
edit_info
.
source_version
or
new_block
.
edit_info
.
update_version
)
if
blacklist
!=
EXCLUDE_ALL
:
for
child
in
destination_block
.
fields
.
get
(
'children'
,
[]):
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
View file @
eb70f230
...
...
@@ -523,6 +523,75 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
component
=
self
.
store
.
publish
(
component
.
location
,
self
.
user_id
)
self
.
assertFalse
(
self
.
store
.
has_changes
(
component
))
@ddt.data
(
'draft'
,
'split'
)
def
test_unit_stuck_in_draft_mode
(
self
,
default_ms
):
"""
After revert_to_published() the has_changes() should return false if draft has no changes
"""
self
.
initdb
(
default_ms
)
test_course
=
self
.
store
.
create_course
(
'testx'
,
'GreekHero'
,
'test_run'
,
self
.
user_id
)
# Create a dummy component to test against
xblock
=
self
.
store
.
create_item
(
self
.
user_id
,
test_course
.
id
,
'vertical'
,
block_id
=
'test_vertical'
)
# Not yet published, so changes are present
self
.
assertTrue
(
self
.
store
.
has_changes
(
xblock
))
# Publish and verify that there are no unpublished changes
component
=
self
.
store
.
publish
(
xblock
.
location
,
self
.
user_id
)
self
.
assertFalse
(
self
.
store
.
has_changes
(
component
))
self
.
store
.
revert_to_published
(
component
.
location
,
self
.
user_id
)
component
=
self
.
store
.
get_item
(
component
.
location
)
self
.
assertFalse
(
self
.
store
.
has_changes
(
component
))
# Publish and verify again
component
=
self
.
store
.
publish
(
component
.
location
,
self
.
user_id
)
self
.
assertFalse
(
self
.
store
.
has_changes
(
component
))
@ddt.data
(
'draft'
,
'split'
)
def
test_unit_stuck_in_published_mode
(
self
,
default_ms
):
"""
After revert_to_published() the has_changes() should return true if draft has changes
"""
self
.
initdb
(
default_ms
)
test_course
=
self
.
store
.
create_course
(
'testx'
,
'GreekHero'
,
'test_run'
,
self
.
user_id
)
# Create a dummy component to test against
xblock
=
self
.
store
.
create_item
(
self
.
user_id
,
test_course
.
id
,
'vertical'
,
block_id
=
'test_vertical'
)
# Not yet published, so changes are present
self
.
assertTrue
(
self
.
store
.
has_changes
(
xblock
))
# Publish and verify that there are no unpublished changes
component
=
self
.
store
.
publish
(
xblock
.
location
,
self
.
user_id
)
self
.
assertFalse
(
self
.
store
.
has_changes
(
component
))
# Discard changes and verify that there are no changes
self
.
store
.
revert_to_published
(
component
.
location
,
self
.
user_id
)
component
=
self
.
store
.
get_item
(
component
.
location
)
self
.
assertFalse
(
self
.
store
.
has_changes
(
component
))
# Change the component, then check that there now are changes
component
=
self
.
store
.
get_item
(
component
.
location
)
component
.
display_name
=
'Changed Display Name'
self
.
store
.
update_item
(
component
,
self
.
user_id
)
# Verify that changes are present
self
.
assertTrue
(
self
.
store
.
has_changes
(
component
))
def
setup_has_changes
(
self
,
default_ms
):
"""
Common set up for has_changes tests below.
...
...
common/lib/xmodule/xmodule/modulestore/xml_importer.py
View file @
eb70f230
...
...
@@ -1182,9 +1182,7 @@ def _update_module_location(module, new_location):
# in which one component of the key is the XBlock's location (equivalent to "scope_ids").
# Since we've changed the XBlock's location, we need to re-save
# all the XBlock's fields so they will be stored using the new location in the key.
# However, since XBlocks only save "dirty" fields, we need to
first
#
explicitly set each field to its current value before triggering the save.
# However, since XBlocks only save "dirty" fields, we need to
call
#
XBlock's `force_save_fields_method`
if
len
(
rekey_fields
)
>
0
:
for
rekey_field_name
in
rekey_fields
:
setattr
(
module
,
rekey_field_name
,
getattr
(
module
,
rekey_field_name
))
module
.
save
()
module
.
force_save_fields
(
rekey_fields
)
common/lib/xmodule/xmodule/tests/test_delay_between_attempts.py
View file @
eb70f230
...
...
@@ -188,9 +188,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts
=
1
(
module
,
result
)
=
self
.
create_and_check
(
num_attempts
=
num_attempts
,
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
),
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
,
tzinfo
=
UTC
),
submission_wait_seconds
=
180
,
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
18
,
36
)
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
18
,
36
,
tzinfo
=
UTC
)
)
# You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented
...
...
@@ -202,9 +202,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts
=
1
(
module
,
result
)
=
self
.
create_and_check
(
num_attempts
=
num_attempts
,
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
),
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
,
tzinfo
=
UTC
),
submission_wait_seconds
=
180
,
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
20
,
35
)
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
20
,
35
,
tzinfo
=
UTC
)
)
# You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented
...
...
@@ -216,9 +216,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts
=
1
(
module
,
result
)
=
self
.
create_and_check
(
num_attempts
=
num_attempts
,
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
),
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
,
tzinfo
=
UTC
),
submission_wait_seconds
=
180
,
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
20
,
36
)
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
20
,
36
,
tzinfo
=
UTC
)
)
# Successfully submitted and answered
# Also, the number of attempts should increment by 1
...
...
@@ -230,9 +230,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts
=
1
(
module
,
result
)
=
self
.
create_and_check
(
num_attempts
=
num_attempts
,
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
),
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
,
tzinfo
=
UTC
),
submission_wait_seconds
=
180
,
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
24
,
0
)
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
24
,
0
,
tzinfo
=
UTC
)
)
# Successfully submitted and answered
# Also, the number of attempts should increment by 1
...
...
@@ -246,17 +246,17 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
with
self
.
assertRaises
(
xmodule
.
exceptions
.
NotFoundError
):
(
module
,
unused_result
)
=
self
.
create_and_check
(
num_attempts
=
num_attempts
,
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
),
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
,
tzinfo
=
UTC
),
submission_wait_seconds
=
180
,
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
24
,
0
)
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
24
,
0
,
tzinfo
=
UTC
)
)
# Now try it without the check_problem
(
module
,
unused_result
)
=
self
.
create_and_check
(
num_attempts
=
num_attempts
,
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
),
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
,
tzinfo
=
UTC
),
submission_wait_seconds
=
180
,
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
24
,
0
),
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
24
,
0
,
tzinfo
=
UTC
),
skip_check_problem
=
True
)
# Expect that number of attempts NOT incremented
...
...
@@ -267,9 +267,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts
=
1
(
module
,
result
)
=
self
.
create_and_check
(
num_attempts
=
num_attempts
,
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
),
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
,
tzinfo
=
UTC
),
submission_wait_seconds
=
60
*
60
*
2
,
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
2
,
15
,
35
)
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
2
,
15
,
35
,
tzinfo
=
UTC
)
)
# You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented
...
...
@@ -281,9 +281,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts
=
1
(
module
,
result
)
=
self
.
create_and_check
(
num_attempts
=
num_attempts
,
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
),
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
,
tzinfo
=
UTC
),
submission_wait_seconds
=
60
*
60
*
2
+
63
,
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
1
,
15
,
40
)
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
1
,
15
,
40
,
tzinfo
=
UTC
)
)
# You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented
...
...
@@ -295,9 +295,9 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
num_attempts
=
1
(
module
,
result
)
=
self
.
create_and_check
(
num_attempts
=
num_attempts
,
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
),
last_submission_time
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
,
tzinfo
=
UTC
),
submission_wait_seconds
=
60
,
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
)
considered_now
=
datetime
.
datetime
(
2013
,
12
,
6
,
0
,
17
,
36
,
tzinfo
=
UTC
)
)
# You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented
...
...
common/lib/xmodule/xmodule/video_module/video_module.py
View file @
eb70f230
...
...
@@ -381,9 +381,10 @@ class VideoDescriptor(VideoFields, VideoTranscriptsMixin, VideoStudioViewHandler
if
not
self
.
fields
[
'download_video'
]
.
is_set_on
(
self
):
self
.
download_video
=
True
#
Set download_video field to default value if it
s not explicitly set for backward compatibility.
#
Force download_video field to default value if it'
s not explicitly set for backward compatibility.
if
not
self
.
fields
[
'download_video'
]
.
is_set_on
(
self
):
self
.
download_video
=
self
.
download_video
self
.
force_save_fields
([
'download_video'
])
# for backward compatibility.
# If course was existed and was not re-imported by the moment of adding `download_track` field,
...
...
lms/djangoapps/courseware/tests/test_submitting_problems.py
View file @
eb70f230
...
...
@@ -18,7 +18,7 @@ from capa.tests.response_xml_factory import (
CodeResponseXMLFactory
,
)
from
courseware
import
grades
from
courseware.models
import
StudentModule
from
courseware.models
import
StudentModule
,
StudentModuleHistory
from
courseware.tests.helpers
import
LoginEnrollmentTestCase
from
lms.djangoapps.lms_xblock.runtime
import
quote_slashes
from
student.tests.factories
import
UserFactory
...
...
@@ -431,6 +431,32 @@ class TestCourseGrader(TestSubmittingProblems):
)
self
.
assertEqual
(
json
.
loads
(
resp
.
content
)
.
get
(
"success"
),
err_msg
)
def
test_show_answer_doesnt_write_to_csm
(
self
):
self
.
basic_setup
()
self
.
submit_question_answer
(
'p1'
,
{
'2_1'
:
u'Correct'
})
# Now fetch the state entry for that problem.
student_module
=
StudentModule
.
objects
.
get
(
course_id
=
self
.
course
.
id
,
student
=
self
.
student_user
)
# count how many state history entries there are
baseline
=
StudentModuleHistory
.
objects
.
filter
(
student_module
=
student_module
)
baseline_count
=
baseline
.
count
()
self
.
assertEqual
(
baseline_count
,
3
)
# now click "show answer"
self
.
show_question_answer
(
'p1'
)
# check that we don't have more state history entries
csmh
=
StudentModuleHistory
.
objects
.
filter
(
student_module
=
student_module
)
current_count
=
csmh
.
count
()
self
.
assertEqual
(
current_count
,
3
)
def
test_none_grade
(
self
):
"""
Check grade is 0 to begin with.
...
...
lms/static/sass/views/_verification.scss
View file @
eb70f230
...
...
@@ -113,6 +113,11 @@
padding-bottom
:
(
$baseline
+
1
);
}
// HACK: fix global header height in verification flow ECOM-1808
header
.global
{
height
:
76px
;
}
// HACK: nasty override due to our bad input/button styling
button
,
input
[
type
=
"submit"
],
input
[
type
=
"button"
],
button
[
type
=
"submit"
]
{
@include
font-size
(
16
);
...
...
requirements/edx/github.txt
View file @
eb70f230
...
...
@@ -32,7 +32,7 @@ git+https://github.com/hmarr/django-debug-toolbar-mongo.git@b0686a76f1ce3532088c
-e git+https://github.com/jazkarta/ccx-keys.git@e6b03704b1bb97c1d2f31301ecb4e3a687c536ea#egg=ccx-keys
# Our libraries:
-e git+https://github.com/edx/XBlock.git@
74fdc5a361f48e5596acf3846ca3790a33a05253
#egg=XBlock
-e git+https://github.com/edx/XBlock.git@
017b46b80e712b1318379912257cf1cc1b68eb0e
#egg=XBlock
-e git+https://github.com/edx/codejail.git@6b17c33a89bef0ac510926b1d7fea2748b73aadd#egg=codejail
-e git+https://github.com/edx/js-test-tool.git@v0.1.6#egg=js_test_tool
-e git+https://github.com/edx/event-tracking.git@0.2.0#egg=event-tracking
...
...
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