Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xblock-drag-and-drop-v2
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
OpenEdx
xblock-drag-and-drop-v2
Commits
5f21dbc8
Commit
5f21dbc8
authored
Jan 06, 2016
by
Tim Krones
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5 from open-craft/better-defaults
Improve default settings for DnDv2 blocks
parents
672aa8c0
8469ed60
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
134 additions
and
85 deletions
+134
-85
README.md
+31
-20
drag_and_drop_v2/default_data.py
+59
-16
drag_and_drop_v2/public/css/drag_and_drop_edit.css
+2
-1
drag_and_drop_v2/templates/html/drag_and_drop_edit.html
+6
-3
drag_and_drop_v2/templates/html/js_templates.html
+12
-4
tests/integration/test_interaction.py
+3
-2
tests/integration/test_render.py
+2
-1
tests/unit/test_basics.py
+19
-35
tests/utils.py
+0
-3
No files found.
README.md
View file @
5f21dbc8
...
@@ -8,29 +8,30 @@ The editor is fully guided. Features include:
...
@@ -8,29 +8,30 @@ The editor is fully guided. Features include:
*
custom target image
*
custom target image
*
free target zone positioning and sizing
*
free target zone positioning and sizing
*
custom size items
*
custom zone labels
*
custom text and background colors for items
*
image items
*
image items
*
decoy items that don't have a zone
*
decoy items that don't have a zone
*
feedback popups for both correct and incorrect attempts
*
feedback popups for both correct and incorrect attempts
*
introductory and final feedback
*
introductory and final feedback
It
supports progressive grading and keeps progress across
The XBlock
supports progressive grading and keeps progress across
refreshes. All checking and record keeping is done on the server side.
refreshes. All checking and record keeping is done on the server side.
The
screenshot shows the Drag and Drop XBlock rendered inside the edX
The
following screenshot shows the Drag and Drop XBlock rendered
LMS before starting
before the user starts solving the problem:
inside the edX LMS
before the user starts solving the problem:


This screenshot shows the XBlock after the student successfully
This screenshot shows the XBlock after the student successfully
completed the
drag and d
rop problem:
completed the
Drag and D
rop problem:


Installation
Installation
------------
------------
Install the requirements into the
p
ython virtual environment of your
Install the requirements into the
P
ython virtual environment of your
`edx-platform`
installation by running the following command from the
`edx-platform`
installation by running the following command from the
root folder:
root folder:
...
@@ -41,12 +42,12 @@ $ pip install -e .
...
@@ -41,12 +42,12 @@ $ pip install -e .
Enabling in Studio
Enabling in Studio
------------------
------------------
You can enable the Drag and Drop XBlock in
studio through the a
dvanced
You can enable the Drag and Drop XBlock in
Studio through the A
dvanced
s
ettings.
S
ettings.
1.
From the main page of a specific course, navigate to
`Settings ->
1.
From the main page of a specific course, navigate to
`Settings ->
Advanced Settings`
from the top menu.
Advanced Settings`
from the top menu.
2.
Check for the
`
advanced_modules
`
policy key, and add
2.
Check for the
`
Advanced Module List
`
policy key, and add
`"drag-and-drop-v2"`
to the policy value list.
`"drag-and-drop-v2"`
to the policy value list.
3.
Click the "Save changes" button.
3.
Click the "Save changes" button.
...
@@ -54,13 +55,13 @@ Usage
...
@@ -54,13 +55,13 @@ Usage
-----
-----
The Drag and Drop XBlock features an interactive editor. Add the Drag
The Drag and Drop XBlock features an interactive editor. Add the Drag
and Drop component to a lesson, then click the
'Edit'
button.
and Drop component to a lesson, then click the
`EDIT`
button.


In the first step, you can set some basic properties of the component,
In the first step, you can set some basic properties of the component,
such as the title,
question text that rendered
above the background
such as the title,
the question text to render
above the background
image, the introduct
ion
feedback (shown initially) and the final
image, the introduct
ory
feedback (shown initially) and the final
feedback (shown after the student successfully completes the drag and
feedback (shown after the student successfully completes the drag and
drop problem).
drop problem).
...
@@ -69,21 +70,31 @@ drop problem).
...
@@ -69,21 +70,31 @@ drop problem).
In the next step, you set the background image URL and define the
In the next step, you set the background image URL and define the
properties of the drop zones. The properties include the title/text
properties of the drop zones. The properties include the title/text
rendered in the drop zone, the zone's dimensions and position
rendered in the drop zone, the zone's dimensions and position
coordinates. You can define an arbitrary number of drop zones as long
coordinates. In this step you can also specify whether you would like
as their titles are unique.
zone labels to be shown to students or not. It is possible to define
an arbitrary number of drop zones as long as their titles are unique.


In the final step, you define the drag items. A drag item can contain
In the final step, you define the drag items. A drag item can contain
either text or an image. You can define the success and error feedback
either text or an image. You can define custom success and error feedback
texts. The feedback text is displayed in a popup after the student
for each item. The feedback text is displayed in a popup after the student
drops the item into a zone - the success feedback is shown if the item
drops the item on a zone - the success feedback is shown if the item
is dropped into the correct zone, while the error feedback is shown
is dropped on the correct zone, while the error feedback is shown
when dropping the item into a wrong drop zone.
when dropping the item on an incorrect drop zone.
Additionally, items can have a numerical value (and an optional error
margin) associated with them. When a student drops an item that has a
numerical value on the correct zone, an input field for entering a
value is shown next to the item. The value that the student submits is
checked against the expected value for the item. If you also specify a
margin, the value entered by the student will be considered correct if
it does not differ from the expected value by more than that margin
(and incorrect otherwise).


The zone that
the item belongs
is selected from a dropdown that
The zone that
an item belongs to
is selected from a dropdown that
includes all drop zones defined in the previous step and a
`none`
includes all drop zones defined in the previous step and a
`none`
option that can be used for "decoy" items - items that don't belong to
option that can be used for "decoy" items - items that don't belong to
any zone.
any zone.
...
...
drag_and_drop_v2/default_data.py
View file @
5f21dbc8
from
.utils
import
_
from
.utils
import
_
TARGET_IMG_DESCRIPTION
=
_
(
"An isosceles triangle with three layers of similar height. "
"It is shown upright, so the widest layer is located at the bottom, "
"and the narrowest layer is located at the top."
)
TOP_ZONE_TITLE
=
_
(
"The Top Zone"
)
MIDDLE_ZONE_TITLE
=
_
(
"The Middle Zone"
)
BOTTOM_ZONE_TITLE
=
_
(
"The Bottom Zone"
)
TOP_ZONE_DESCRIPTION
=
_
(
"Use this zone to associate an item with the top layer of the triangle."
)
MIDDLE_ZONE_DESCRIPTION
=
_
(
"Use this zone to associate an item with the middle layer of the triangle."
)
BOTTOM_ZONE_DESCRIPTION
=
_
(
"Use this zone to associate an item with the bottom layer of the triangle."
)
ITEM_INCORRECT_FEEDBACK
=
_
(
"No, this item does not belong here. Try again."
)
ITEM_CORRECT_FEEDBACK
=
_
(
"Correct! This one belongs to {zone}."
)
START_FEEDBACK
=
_
(
"Drag the items onto the image above."
)
FINISH_FEEDBACK
=
_
(
"Good work! You have completed this drag and drop exercise."
)
DEFAULT_DATA
=
{
DEFAULT_DATA
=
{
"targetImgDescription"
:
TARGET_IMG_DESCRIPTION
,
"zones"
:
[
"zones"
:
[
{
{
"index"
:
1
,
"index"
:
1
,
"id"
:
"zone-1"
,
"id"
:
"zone-1"
,
"title"
:
_
(
"Zone 1"
),
"title"
:
TOP_ZONE_TITLE
,
"description"
:
TOP_ZONE_DESCRIPTION
,
"x"
:
160
,
"x"
:
160
,
"y"
:
30
,
"y"
:
30
,
"width"
:
196
,
"width"
:
196
,
...
@@ -14,47 +36,68 @@ DEFAULT_DATA = {
...
@@ -14,47 +36,68 @@ DEFAULT_DATA = {
{
{
"index"
:
2
,
"index"
:
2
,
"id"
:
"zone-2"
,
"id"
:
"zone-2"
,
"title"
:
_
(
"Zone 2"
),
"title"
:
MIDDLE_ZONE_TITLE
,
"description"
:
MIDDLE_ZONE_DESCRIPTION
,
"x"
:
86
,
"x"
:
86
,
"y"
:
210
,
"y"
:
210
,
"width"
:
340
,
"width"
:
340
,
"height"
:
140
,
"height"
:
138
,
},
{
"index"
:
3
,
"id"
:
"zone-3"
,
"title"
:
BOTTOM_ZONE_TITLE
,
"description"
:
BOTTOM_ZONE_DESCRIPTION
,
"x"
:
15
,
"y"
:
350
,
"width"
:
485
,
"height"
:
135
,
}
}
],
],
"items"
:
[
"items"
:
[
{
{
"displayName"
:
"1"
,
"displayName"
:
_
(
"Goes to the top"
)
,
"feedback"
:
{
"feedback"
:
{
"incorrect"
:
_
(
"No, 1 does not belong here"
)
,
"incorrect"
:
ITEM_INCORRECT_FEEDBACK
,
"correct"
:
_
(
"Yes, it's a 1"
)
"correct"
:
ITEM_CORRECT_FEEDBACK
.
format
(
zone
=
TOP_ZONE_TITLE
)
},
},
"zone"
:
"Zone 1"
,
"zone"
:
TOP_ZONE_TITLE
,
"imageURL"
:
""
,
"imageURL"
:
""
,
"id"
:
0
,
"id"
:
0
,
},
},
{
{
"displayName"
:
"2"
,
"displayName"
:
_
(
"Goes to the middle"
)
,
"feedback"
:
{
"feedback"
:
{
"incorrect"
:
_
(
"No, 2 does not belong here"
)
,
"incorrect"
:
ITEM_INCORRECT_FEEDBACK
,
"correct"
:
_
(
"Yes, it's a 2"
)
"correct"
:
ITEM_CORRECT_FEEDBACK
.
format
(
zone
=
MIDDLE_ZONE_TITLE
)
},
},
"zone"
:
"Zone 2"
,
"zone"
:
MIDDLE_ZONE_TITLE
,
"imageURL"
:
""
,
"imageURL"
:
""
,
"id"
:
1
,
"id"
:
1
,
},
},
{
{
"displayName"
:
"X"
,
"displayName"
:
_
(
"Goes to the bottom"
)
,
"feedback"
:
{
"feedback"
:
{
"incorrect"
:
_
(
"You silly, there are no zones for X"
),
"incorrect"
:
ITEM_INCORRECT_FEEDBACK
,
"correct"
:
ITEM_CORRECT_FEEDBACK
.
format
(
zone
=
BOTTOM_ZONE_TITLE
)
},
"zone"
:
BOTTOM_ZONE_TITLE
,
"imageURL"
:
""
,
"id"
:
2
,
},
{
"displayName"
:
_
(
"I don't belong anywhere"
),
"feedback"
:
{
"incorrect"
:
_
(
"You silly, there are no zones for this one."
),
"correct"
:
""
"correct"
:
""
},
},
"zone"
:
"none"
,
"zone"
:
"none"
,
"imageURL"
:
""
,
"imageURL"
:
""
,
"id"
:
2
,
"id"
:
3
,
},
},
],
],
"feedback"
:
{
"feedback"
:
{
"start"
:
_
(
"Drag the items onto the image above."
)
,
"start"
:
START_FEEDBACK
,
"finish"
:
_
(
"Good work! You have completed this drag and drop exercise."
)
"finish"
:
FINISH_FEEDBACK
,
},
},
}
}
drag_and_drop_v2/public/css/drag_and_drop_edit.css
View file @
5f21dbc8
...
@@ -203,7 +203,8 @@
...
@@ -203,7 +203,8 @@
.xblock--drag-and-drop--editor
.items-form
.item-numerical-value
,
.xblock--drag-and-drop--editor
.items-form
.item-numerical-value
,
.xblock--drag-and-drop--editor
.items-form
.item-numerical-margin
{
.xblock--drag-and-drop--editor
.items-form
.item-numerical-margin
{
width
:
60px
;
margin
:
0
1%
;
width
:
50%
;
}
}
.xblock--drag-and-drop--editor
.items-form
textarea
{
.xblock--drag-and-drop--editor
.items-form
textarea
{
...
...
drag_and_drop_v2/templates/html/drag_and_drop_edit.html
View file @
5f21dbc8
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
</label>
</label>
<h3>
{% trans "Maximum score" %}
</h3>
<h3>
{% trans "Maximum score" %}
</h3>
<input
class=
"weight"
value=
"1"
value=
"{{ self.weight }}"
/>
<input
type=
"number"
step=
"0.1"
class=
"weight"
value=
"1"
value=
"{{ self.weight }}"
/>
<h3>
{% trans "Question text" %}
</h3>
<h3>
{% trans "Question text" %}
</h3>
<textarea
class=
"question-text"
>
{{ self.question_text }}
</textarea>
<textarea
class=
"question-text"
>
{{ self.question_text }}
</textarea>
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
{% trans "Show \"Question\" heading" %}
{% trans "Show \"Question\" heading" %}
</label>
</label>
<h3>
{% trans "Introduct
ion
Feedback" %}
</h3>
<h3>
{% trans "Introduct
ory
Feedback" %}
</h3>
<textarea
class=
"intro-feedback"
>
{{ self.data.feedback.start }}
</textarea>
<textarea
class=
"intro-feedback"
>
{{ self.data.feedback.start }}
</textarea>
<h3>
{% trans "Final Feedback" %}
</h3>
<h3>
{% trans "Final Feedback" %}
</h3>
...
@@ -48,7 +48,10 @@
...
@@ -48,7 +48,10 @@
<h3
id=
"background-url-label"
>
<h3
id=
"background-url-label"
>
{% trans "Background URL" %}
{% trans "Background URL" %}
</h3>
</h3>
<input
type=
"text"
class=
"url-input"
aria-labelledby=
"background-url-label"
>
<input
type=
"text"
class=
"url-input"
aria-labelledby=
"background-url-label"
placeholder=
"{% trans 'e.g. http://example.com/background.png or /static/background.png' %}"
>
<h3
id=
"background-description-label"
>
<h3
id=
"background-description-label"
>
{% trans "Background description" %}
{% trans "Background description" %}
</h3>
</h3>
...
...
drag_and_drop_v2/templates/html/js_templates.html
View file @
5f21dbc8
...
@@ -113,12 +113,20 @@
...
@@ -113,12 +113,20 @@
value
=
"{{ height }}"
/>
value
=
"{{ height }}"
/>
<
/div
>
<
/div
>
<
div
class
=
"row"
>
<
div
class
=
"row"
>
<
label
for
=
"item-{{id}}-numerical-value"
>
{{
i18n
"Optional numerical value"
}}
<
/label
>
<
label
for
=
"item-{{id}}-numerical-value"
>
<
input
type
=
"text"
{{
i18n
"Optional numerical value (if you set this, students will be prompted for this value after dropping this item)"
}}
<
/label
>
<
input
type
=
"number"
step
=
"0.1"
id
=
"item-{{id}}-numerical-value"
id
=
"item-{{id}}-numerical-value"
class
=
"item-numerical-value"
value
=
"{{ numericalValue }}"
/>
class
=
"item-numerical-value"
value
=
"{{ numericalValue }}"
/>
<
label
for
=
"item-{{id}}-numerical-margin"
>
{{
i18n
"Margin ±"
}}
<
/label
>
<
/div
>
<
input
type
=
"text"
<
div
class
=
"row"
>
<
label
for
=
"item-{{id}}-numerical-margin"
>
{{
i18n
"Margin ± (when a numerical value is required, values entered by students must not differ from the expected value by more than this margin; default is zero)"
}}
<
/label
>
<
input
type
=
"number"
step
=
"0.1"
id
=
"item-{{id}}-numerical-margin"
id
=
"item-{{id}}-numerical-margin"
class
=
"item-numerical-margin"
value
=
"{{ numericalMargin }}"
/>
class
=
"item-numerical-margin"
value
=
"{{ numericalMargin }}"
/>
<
/div
>
<
/div
>
...
...
tests/integration/test_interaction.py
View file @
5f21dbc8
from
selenium.webdriver
import
ActionChains
from
selenium.webdriver
import
ActionChains
from
drag_and_drop_v2.default_data
import
START_FEEDBACK
,
FINISH_FEEDBACK
from
.test_base
import
BaseIntegrationTest
from
.test_base
import
BaseIntegrationTest
from
..utils
import
load_resource
from
..utils
import
load_resource
...
@@ -161,8 +162,8 @@ class BasicInteractionTest(InteractionTestBase):
...
@@ -161,8 +162,8 @@ class BasicInteractionTest(InteractionTestBase):
all_zones
=
[
'Zone 1'
,
'Zone 2'
]
all_zones
=
[
'Zone 1'
,
'Zone 2'
]
feedback
=
{
feedback
=
{
"intro"
:
"Drag the items onto the image above."
,
"intro"
:
START_FEEDBACK
,
"final"
:
"Good work! You have completed this drag and drop exercise."
"final"
:
FINISH_FEEDBACK
,
}
}
def
_get_scenario_xml
(
self
):
# pylint: disable=no-self-use
def
_get_scenario_xml
(
self
):
# pylint: disable=no-self-use
...
...
tests/integration/test_render.py
View file @
5f21dbc8
from
ddt
import
ddt
,
unpack
,
data
from
ddt
import
ddt
,
unpack
,
data
from
selenium.common.exceptions
import
NoSuchElementException
from
selenium.common.exceptions
import
NoSuchElementException
from
drag_and_drop_v2.default_data
import
START_FEEDBACK
from
..utils
import
load_resource
from
..utils
import
load_resource
from
.test_base
import
BaseIntegrationTest
from
.test_base
import
BaseIntegrationTest
...
@@ -184,7 +185,7 @@ class TestDragAndDropRender(BaseIntegrationTest):
...
@@ -184,7 +185,7 @@ class TestDragAndDropRender(BaseIntegrationTest):
feedback
=
self
.
_get_feedback
()
feedback
=
self
.
_get_feedback
()
feedback_message
=
self
.
_get_feedback_message
()
feedback_message
=
self
.
_get_feedback_message
()
self
.
assertEqual
(
feedback
.
get_attribute
(
'aria-live'
),
'polite'
)
self
.
assertEqual
(
feedback
.
get_attribute
(
'aria-live'
),
'polite'
)
self
.
assertEqual
(
feedback_message
.
text
,
"Drag the items onto the image above."
)
self
.
assertEqual
(
feedback_message
.
text
,
START_FEEDBACK
)
def
test_background_image
(
self
):
def
test_background_image
(
self
):
self
.
load_scenario
()
self
.
load_scenario
()
...
...
tests/unit/test_basics.py
View file @
5f21dbc8
import
unittest
import
unittest
from
..utils
import
(
from
drag_and_drop_v2.default_data
import
(
DEFAULT_START_FEEDBACK
,
TARGET_IMG_DESCRIPTION
,
START_FEEDBACK
,
FINISH_FEEDBACK
,
DEFAULT_DATA
DEFAULT_FINISH_FEEDBACK
,
make_block
,
TestCaseMixin
,
)
)
from
..utils
import
make_block
,
TestCaseMixin
class
BasicTests
(
TestCaseMixin
,
unittest
.
TestCase
):
class
BasicTests
(
TestCaseMixin
,
unittest
.
TestCase
):
...
@@ -36,36 +34,18 @@ class BasicTests(TestCaseMixin, unittest.TestCase):
...
@@ -36,36 +34,18 @@ class BasicTests(TestCaseMixin, unittest.TestCase):
"question_text"
:
""
,
"question_text"
:
""
,
"show_question_header"
:
True
,
"show_question_header"
:
True
,
"target_img_expanded_url"
:
'/expanded/url/to/drag_and_drop_v2/public/img/triangle.png'
,
"target_img_expanded_url"
:
'/expanded/url/to/drag_and_drop_v2/public/img/triangle.png'
,
"target_img_description"
:
""
,
"target_img_description"
:
TARGET_IMG_DESCRIPTION
,
"item_background_color"
:
None
,
"item_background_color"
:
None
,
"item_text_color"
:
None
,
"item_text_color"
:
None
,
"initial_feedback"
:
DEFAULT_
START_FEEDBACK
,
"initial_feedback"
:
START_FEEDBACK
,
})
})
self
.
assertEqual
(
zones
,
[
self
.
assertEqual
(
zones
,
DEFAULT_DATA
[
"zones"
])
{
"index"
:
1
,
"title"
:
"Zone 1"
,
"id"
:
"zone-1"
,
"x"
:
160
,
"y"
:
30
,
"width"
:
196
,
"height"
:
178
,
},
{
"index"
:
2
,
"title"
:
"Zone 2"
,
"id"
:
"zone-2"
,
"x"
:
86
,
"y"
:
210
,
"width"
:
340
,
"height"
:
140
,
}
])
# Items should contain no answer data:
# Items should contain no answer data:
self
.
assertEqual
(
items
,
[
self
.
assertEqual
(
items
,
[
{
"id"
:
0
,
"displayName"
:
"1"
,
"imageURL"
:
""
,
"inputOptions"
:
False
},
{
"id"
:
0
,
"displayName"
:
"Goes to the top"
,
"imageURL"
:
""
,
"inputOptions"
:
False
},
{
"id"
:
1
,
"displayName"
:
"2"
,
"imageURL"
:
""
,
"inputOptions"
:
False
},
{
"id"
:
1
,
"displayName"
:
"Goes to the middle"
,
"imageURL"
:
""
,
"inputOptions"
:
False
},
{
"id"
:
2
,
"displayName"
:
"X"
,
"imageURL"
:
""
,
"inputOptions"
:
False
},
{
"id"
:
2
,
"displayName"
:
"Goes to the bottom"
,
"imageURL"
:
""
,
"inputOptions"
:
False
},
{
"id"
:
3
,
"displayName"
:
"I don't belong anywhere"
,
"imageURL"
:
""
,
"inputOptions"
:
False
},
])
])
def
test_ajax_solve_and_reset
(
self
):
def
test_ajax_solve_and_reset
(
self
):
...
@@ -77,14 +57,16 @@ class BasicTests(TestCaseMixin, unittest.TestCase):
...
@@ -77,14 +57,16 @@ class BasicTests(TestCaseMixin, unittest.TestCase):
self
.
assertEqual
(
self
.
call_handler
(
"get_user_state"
),
{
self
.
assertEqual
(
self
.
call_handler
(
"get_user_state"
),
{
'items'
:
{},
'items'
:
{},
'finished'
:
False
,
'finished'
:
False
,
'overall_feedback'
:
DEFAULT_
START_FEEDBACK
,
'overall_feedback'
:
START_FEEDBACK
,
})
})
assert_user_state_empty
()
assert_user_state_empty
()
# Drag both items into the correct spot:
# Drag three items into the correct spot:
data
=
{
"val"
:
0
,
"zone"
:
"Zone 1"
,
"x_percent"
:
"33
%
"
,
"y_percent"
:
"11
%
"
}
data
=
{
"val"
:
0
,
"zone"
:
"The Top Zone"
,
"x_percent"
:
"33
%
"
,
"y_percent"
:
"11
%
"
}
self
.
call_handler
(
'do_attempt'
,
data
)
data
=
{
"val"
:
1
,
"zone"
:
"The Middle Zone"
,
"x_percent"
:
"67
%
"
,
"y_percent"
:
"80
%
"
}
self
.
call_handler
(
'do_attempt'
,
data
)
self
.
call_handler
(
'do_attempt'
,
data
)
data
=
{
"val"
:
1
,
"zone"
:
"Zone 2"
,
"x_percent"
:
"67
%
"
,
"y_percent"
:
"80
%
"
}
data
=
{
"val"
:
2
,
"zone"
:
"The Bottom Zone"
,
"x_percent"
:
"99
%
"
,
"y_percent"
:
"95
%
"
}
self
.
call_handler
(
'do_attempt'
,
data
)
self
.
call_handler
(
'do_attempt'
,
data
)
# Check the result:
# Check the result:
...
@@ -92,14 +74,16 @@ class BasicTests(TestCaseMixin, unittest.TestCase):
...
@@ -92,14 +74,16 @@ class BasicTests(TestCaseMixin, unittest.TestCase):
self
.
assertEqual
(
self
.
block
.
item_state
,
{
self
.
assertEqual
(
self
.
block
.
item_state
,
{
'0'
:
{
'x_percent'
:
'33
%
'
,
'y_percent'
:
'11
%
'
},
'0'
:
{
'x_percent'
:
'33
%
'
,
'y_percent'
:
'11
%
'
},
'1'
:
{
'x_percent'
:
'67
%
'
,
'y_percent'
:
'80
%
'
},
'1'
:
{
'x_percent'
:
'67
%
'
,
'y_percent'
:
'80
%
'
},
'2'
:
{
'x_percent'
:
'99
%
'
,
'y_percent'
:
'95
%
'
},
})
})
self
.
assertEqual
(
self
.
call_handler
(
'get_user_state'
),
{
self
.
assertEqual
(
self
.
call_handler
(
'get_user_state'
),
{
'items'
:
{
'items'
:
{
'0'
:
{
'x_percent'
:
'33
%
'
,
'y_percent'
:
'11
%
'
,
'correct_input'
:
True
},
'0'
:
{
'x_percent'
:
'33
%
'
,
'y_percent'
:
'11
%
'
,
'correct_input'
:
True
},
'1'
:
{
'x_percent'
:
'67
%
'
,
'y_percent'
:
'80
%
'
,
'correct_input'
:
True
},
'1'
:
{
'x_percent'
:
'67
%
'
,
'y_percent'
:
'80
%
'
,
'correct_input'
:
True
},
'2'
:
{
'x_percent'
:
'99
%
'
,
'y_percent'
:
'95
%
'
,
'correct_input'
:
True
},
},
},
'finished'
:
True
,
'finished'
:
True
,
'overall_feedback'
:
DEFAULT_
FINISH_FEEDBACK
,
'overall_feedback'
:
FINISH_FEEDBACK
,
})
})
# Reset to initial conditions
# Reset to initial conditions
...
...
tests/utils.py
View file @
5f21dbc8
...
@@ -10,9 +10,6 @@ from xblock.runtime import KvsFieldData, DictKeyValueStore
...
@@ -10,9 +10,6 @@ from xblock.runtime import KvsFieldData, DictKeyValueStore
import
drag_and_drop_v2
import
drag_and_drop_v2
DEFAULT_START_FEEDBACK
=
"Drag the items onto the image above."
DEFAULT_FINISH_FEEDBACK
=
"Good work! You have completed this drag and drop exercise."
def
make_request
(
data
,
method
=
'POST'
):
def
make_request
(
data
,
method
=
'POST'
):
""" Make a webob JSON Request """
""" Make a webob JSON Request """
...
...
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