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
011ceb8e
Commit
011ceb8e
authored
Jul 19, 2013
by
Renzo Lucioni
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #418 from edx/renzo/in-context-progress
Renzo/in context progress
parents
73e6e6f4
9af87e41
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
151 additions
and
15 deletions
+151
-15
common/lib/xmodule/xmodule/capa_module.py
+14
-5
common/lib/xmodule/xmodule/css/capa/display.scss
+8
-0
common/lib/xmodule/xmodule/js/fixtures/problem.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/problem_content.html
+3
-0
common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee
+19
-0
common/lib/xmodule/xmodule/js/src/capa/display.coffee
+23
-4
common/lib/xmodule/xmodule/js/src/sequence/display.coffee
+1
-1
common/lib/xmodule/xmodule/tests/test_capa_module.py
+31
-0
lms/djangoapps/courseware/features/problems.feature
+42
-0
lms/djangoapps/courseware/features/problems.py
+5
-0
lms/templates/problem.html
+3
-3
lms/templates/problem_ajax.html
+1
-1
No files found.
common/lib/xmodule/xmodule/capa_module.py
View file @
011ceb8e
...
...
@@ -309,7 +309,13 @@ class CapaModule(CapaFields, XModule):
d
=
self
.
get_score
()
score
=
d
[
'score'
]
total
=
d
[
'total'
]
if
total
>
0
:
if
self
.
weight
is
not
None
:
# scale score and total by weight/total:
score
=
score
*
self
.
weight
/
total
total
=
self
.
weight
try
:
return
Progress
(
score
,
total
)
except
(
TypeError
,
ValueError
):
...
...
@@ -321,11 +327,13 @@ class CapaModule(CapaFields, XModule):
"""
Return some html with data about the module
"""
progress
=
self
.
get_progress
()
return
self
.
system
.
render_template
(
'problem_ajax.html'
,
{
'element_id'
:
self
.
location
.
html_id
(),
'id'
:
self
.
id
,
'ajax_url'
:
self
.
system
.
ajax_url
,
'progress'
:
Progress
.
to_js_status_str
(
self
.
get_progress
())
'progress_status'
:
Progress
.
to_js_status_str
(
progress
),
'progress_detail'
:
Progress
.
to_js_detail_str
(
progress
),
})
def
check_button_name
(
self
):
...
...
@@ -485,8 +493,7 @@ class CapaModule(CapaFields, XModule):
"""
Return html for the problem.
Adds check, reset, save buttons as necessary based on the problem config
and state.
Adds check, reset, save buttons as necessary based on the problem config and state.
"""
try
:
...
...
@@ -516,13 +523,12 @@ class CapaModule(CapaFields, XModule):
'reset_button'
:
self
.
should_show_reset_button
(),
'save_button'
:
self
.
should_show_save_button
(),
'answer_available'
:
self
.
answer_available
(),
'ajax_url'
:
self
.
system
.
ajax_url
,
'attempts_used'
:
self
.
attempts
,
'attempts_allowed'
:
self
.
max_attempts
,
'progress'
:
self
.
get_progress
(),
}
html
=
self
.
system
.
render_template
(
'problem.html'
,
context
)
if
encapsulate
:
html
=
u'<div id="problem_{id}" class="problem" data-url="{ajax_url}">'
.
format
(
id
=
self
.
location
.
html_id
(),
ajax_url
=
self
.
system
.
ajax_url
...
...
@@ -584,6 +590,7 @@ class CapaModule(CapaFields, XModule):
result
.
update
({
'progress_changed'
:
after
!=
before
,
'progress_status'
:
Progress
.
to_js_status_str
(
after
),
'progress_detail'
:
Progress
.
to_js_detail_str
(
after
),
})
return
json
.
dumps
(
result
,
cls
=
ComplexEncoder
)
...
...
@@ -614,6 +621,7 @@ class CapaModule(CapaFields, XModule):
Problem can be completely wrong.
Pressing RESET button makes this function to return False.
"""
# used by conditional module
return
self
.
lcp
.
done
def
is_attempted
(
self
):
...
...
@@ -757,6 +765,7 @@ class CapaModule(CapaFields, XModule):
"""
return
{
'html'
:
self
.
get_problem_html
(
encapsulate
=
False
)}
@staticmethod
def
make_dict_of_responses
(
data
):
"""
...
...
common/lib/xmodule/xmodule/css/capa/display.scss
View file @
011ceb8e
...
...
@@ -3,6 +3,7 @@ h2 {
margin-bottom
:
15px
;
&
.problem-header
{
display
:
inline-block
;
section
.staff
{
margin-top
:
30px
;
font-size
:
80%
;
...
...
@@ -28,6 +29,13 @@ iframe[seamless]{
color
:
darken
(
$error-red
,
11%
);
}
section
.problem-progress
{
display
:
inline-block
;
color
:
#999
;
font-size
:
em
(
16
);
font-weight
:
100
;
padding-left
:
5px
;
}
section
.problem
{
@media
print
{
...
...
common/lib/xmodule/xmodule/js/fixtures/problem.html
View file @
011ceb8e
<section
class=
'xmodule_display xmodule_CapaModule'
data-type=
'Problem'
>
<section
id=
'problem_1'
class=
'problems-wrapper'
class=
'problems-wrapper'
data-problem-id=
'i4x://edX/101/problem/Problem1'
data-url=
'/problem/Problem1'
>
</section>
...
...
common/lib/xmodule/xmodule/js/fixtures/problem_content.html
View file @
011ceb8e
<h2
class=
"problem-header"
>
Problem Header
</h2>
<section
class=
'problem-progress'
>
</section>
<section
class=
"problem"
>
<p>
Problem Content
</p>
...
...
common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee
View file @
011ceb8e
...
...
@@ -77,6 +77,25 @@ describe 'Problem', ->
[
@
problem
.
updateMathML
,
@
stubbedJax
,
$
(
'#input_example_1'
).
get
(
0
)]
]
describe
'renderProgressState'
,
->
beforeEach
->
@
problem
=
new
Problem
(
$
(
'.xmodule_display'
))
#@renderProgressState = @problem.renderProgressState
describe
'with a status of "none"'
,
->
it
'reports the number of points possible'
,
->
@
problem
.
el
.
data
(
'progress_status'
,
'none'
)
@
problem
.
el
.
data
(
'progress_detail'
,
'0/1'
)
@
problem
.
renderProgressState
()
expect
(
@
problem
.
$
(
'.problem-progress'
).
html
()).
toEqual
"(1 point possible)"
describe
'with any other valid status'
,
->
it
'reports the current score'
,
->
@
problem
.
el
.
data
(
'progress_status'
,
'foo'
)
@
problem
.
el
.
data
(
'progress_detail'
,
'1/1'
)
@
problem
.
renderProgressState
()
expect
(
@
problem
.
$
(
'.problem-progress'
).
html
()).
toEqual
"(1/1 points)"
describe
'render'
,
->
beforeEach
->
@
problem
=
new
Problem
(
$
(
'.xmodule_display'
))
...
...
common/lib/xmodule/xmodule/js/src/capa/display.coffee
View file @
011ceb8e
...
...
@@ -35,15 +35,34 @@ class @Problem
@
$
(
'input.math'
).
each
(
index
,
element
)
=>
MathJax
.
Hub
.
Queue
[
@
refreshMath
,
null
,
element
]
renderProgressState
:
=>
detail
=
@
el
.
data
(
'progress_detail'
)
status
=
@
el
.
data
(
'progress_status'
)
# i18n
progress
=
"(
#{
detail
}
points)"
if
status
==
'none'
and
detail
?
and
detail
.
indexOf
(
'/'
)
>
0
a
=
detail
.
split
(
'/'
)
possible
=
parseInt
(
a
[
1
])
if
possible
==
1
# i18n
progress
=
"(
#{
possible
}
point possible)"
else
# i18n
progress
=
"(
#{
possible
}
points possible)"
@
$
(
'.problem-progress'
).
html
(
progress
)
updateProgress
:
(
response
)
=>
if
response
.
progress_changed
@
el
.
attr
progress
:
response
.
progress_status
@
el
.
data
(
'progress_status'
,
response
.
progress_status
)
@
el
.
data
(
'progress_detail'
,
response
.
progress_detail
)
@
el
.
trigger
(
'progressChanged'
)
@
renderProgressState
()
forceUpdate
:
(
response
)
=>
@
el
.
attr
progress
:
response
.
progress_status
@
el
.
data
(
'progress_status'
,
response
.
progress_status
)
@
el
.
data
(
'progress_detail'
,
response
.
progress_detail
)
@
el
.
trigger
(
'progressChanged'
)
@
renderProgressState
()
queueing
:
=>
@
queued_items
=
@
$
(
".xqueue"
)
...
...
@@ -113,7 +132,7 @@ class @Problem
@
setupInputTypes
()
@
bind
()
@
queueing
()
@
forceUpdate
response
# TODO add hooks for problem types here by inspecting response.html and doing
# stuff if a div w a class is found
...
...
common/lib/xmodule/xmodule/js/src/sequence/display.coffee
View file @
011ceb8e
...
...
@@ -45,7 +45,7 @@ class @Sequence
new_progress
=
"NA"
_this
=
this
$
(
'.problems-wrapper'
).
each
(
index
)
->
progress
=
$
(
this
).
attr
'progres
s'
progress
=
$
(
this
).
data
'progress_statu
s'
new_progress
=
_this
.
mergeProgress
progress
,
new_progress
@
progressTable
[
@
position
]
=
new_progress
...
...
common/lib/xmodule/xmodule/tests/test_capa_module.py
View file @
011ceb8e
...
...
@@ -1233,6 +1233,37 @@ class CapaModuleTest(unittest.TestCase):
mock_log
.
exception
.
assert_called_once_with
(
'Got bad progress'
)
mock_log
.
reset_mock
()
@patch
(
'xmodule.capa_module.Progress'
)
def
test_get_progress_calculate_progress_fraction
(
self
,
mock_progress
):
"""
Check that score and total are calculated correctly for the progress fraction.
"""
module
=
CapaFactory
.
create
()
module
.
weight
=
1
module
.
get_progress
()
mock_progress
.
assert_called_with
(
0
,
1
)
other_module
=
CapaFactory
.
create
(
correct
=
True
)
other_module
.
weight
=
1
other_module
.
get_progress
()
mock_progress
.
assert_called_with
(
1
,
1
)
def
test_get_html
(
self
):
"""
Check that get_html() calls get_progress() with no arguments.
"""
module
=
CapaFactory
.
create
()
module
.
get_progress
=
Mock
(
wraps
=
module
.
get_progress
)
module
.
get_html
()
module
.
get_progress
.
assert_called_once_with
()
def
test_get_problem
(
self
):
"""
Check that get_problem() returns the expected dictionary.
"""
module
=
CapaFactory
.
create
()
self
.
assertEquals
(
module
.
get_problem
(
"data"
),
{
'html'
:
module
.
get_problem_html
(
encapsulate
=
False
)})
class
ComplexEncoderTest
(
unittest
.
TestCase
):
def
test_default
(
self
):
...
...
lms/djangoapps/courseware/features/problems.feature
View file @
011ceb8e
...
...
@@ -129,3 +129,45 @@ Feature: Answer problems
When
I press the button with the label
"Hide Answer(s)"
Then
the button with the label
"Show Answer(s)"
does appear
And
I should not see
"4.14159"
anywhere on the page
Scenario
:
I
can see my score on a problem when I answer it and after I reset it
Given
I am viewing a
"<ProblemType>"
problem
When
I answer a
"<ProblemType>"
problem
"<Correctness>ly"
Then
I should see a score of
"<Score>"
When
I reset the problem
Then
I should see a score of
"<Points Possible>"
Examples
:
|
ProblemType
|
Correctness
|
Score
|
Points
Possible
|
|
drop
down
|
correct
|
1/1
points
|
1
point
possible
|
|
drop
down
|
incorrect
|
1
point
possible
|
1
point
possible
|
|
multiple
choice
|
correct
|
1/1
points
|
1
point
possible
|
|
multiple
choice
|
incorrect
|
1
point
possible
|
1
point
possible
|
|
checkbox
|
correct
|
1/1
points
|
1
point
possible
|
|
checkbox
|
incorrect
|
1
point
possible
|
1
point
possible
|
|
radio
|
correct
|
1/1
points
|
1
point
possible
|
|
radio
|
incorrect
|
1
point
possible
|
1
point
possible
|
|
string
|
correct
|
1/1
points
|
1
point
possible
|
|
string
|
incorrect
|
1
point
possible
|
1
point
possible
|
|
numerical
|
correct
|
1/1
points
|
1
point
possible
|
|
numerical
|
incorrect
|
1
point
possible
|
1
point
possible
|
|
formula
|
correct
|
1/1
points
|
1
point
possible
|
|
formula
|
incorrect
|
1
point
possible
|
1
point
possible
|
|
script
|
correct
|
2/2
points
|
2
points
possible
|
|
script
|
incorrect
|
2
points
possible
|
2
points
possible
|
Scenario
:
I
can see my score on a problem to which I submit a blank answer
Given
I am viewing a
"<ProblemType>"
problem
When
I check a problem
Then
I should see a score of
"<Points Possible>"
Examples
:
|
ProblemType
|
Points
Possible
|
|
drop
down
|
1
point
possible
|
|
multiple
choice
|
1
point
possible
|
|
checkbox
|
1
point
possible
|
|
radio
|
1
point
possible
|
|
string
|
1
point
possible
|
|
numerical
|
1
point
possible
|
|
formula
|
1
point
possible
|
|
script
|
2
points
possible
|
lms/djangoapps/courseware/features/problems.py
View file @
011ceb8e
...
...
@@ -142,6 +142,11 @@ def button_with_label_present(_step, buttonname, doesnt_appear):
assert
world
.
browser
.
is_text_present
(
buttonname
,
wait_time
=
5
)
@step
(
u'I should see a score of "([^"]*)"$'
)
def
see_score
(
_step
,
score
):
assert
world
.
browser
.
is_text_present
(
score
)
@step
(
u'My "([^"]*)" answer is marked "([^"]*)"'
)
def
assert_answer_mark
(
step
,
problem_type
,
correctness
):
"""
...
...
lms/templates/problem.html
View file @
011ceb8e
<
%
namespace
name=
'static'
file=
'static_content.html'
/>
<h2
class=
"problem-header"
>
${ problem['name'] }
% if problem['weight'] != 1 and problem['weight'] is not None:
: ${ problem['weight'] } points
% endif
</h2>
<section
class=
"problem-progress"
>
</section>
<section
class=
"problem"
>
${ problem['html'] }
...
...
lms/templates/problem_ajax.html
View file @
011ceb8e
<section
id=
"problem_${element_id}"
class=
"problems-wrapper"
data-problem-id=
"${id}"
data-url=
"${ajax_url}"
progress=
"${progress
}"
></section>
<section
id=
"problem_${element_id}"
class=
"problems-wrapper"
data-problem-id=
"${id}"
data-url=
"${ajax_url}"
data-progress_status=
"${progress_status}"
data-progress_detail=
"${progress_detail
}"
></section>
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