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
8613594c
Commit
8613594c
authored
Sep 13, 2013
by
Vik Paruchuri
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #971 from edx/fix/vik/pg-hotfix
Fix/vik/pg hotfix
parents
dcbb9bcd
c6e5e674
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
174 additions
and
24 deletions
+174
-24
common/lib/xmodule/xmodule/open_ended_grading_classes/peer_grading_service.py
+6
-6
common/lib/xmodule/xmodule/peer_grading_module.py
+30
-10
common/lib/xmodule/xmodule/tests/test_peer_grading.py
+80
-0
common/test/data/open_ended/course/2012_Fall.xml
+1
-0
common/test/data/open_ended/peergrading/PeerGradingLinked.xml
+2
-0
common/test/data/open_ended_nopath/README.md
+1
-0
common/test/data/open_ended_nopath/course.xml
+1
-0
common/test/data/open_ended_nopath/course/2012_Fall.xml
+4
-0
common/test/data/open_ended_nopath/peergrading/PeerGradingNoPath.xml
+2
-0
common/test/data/open_ended_nopath/policies/2012_Fall.json
+11
-0
lms/djangoapps/courseware/tests/modulestore_config.py
+1
-0
lms/djangoapps/open_ended_grading/tests.py
+20
-0
lms/djangoapps/open_ended_grading/views.py
+15
-8
No files found.
common/lib/xmodule/xmodule/open_ended_grading_classes/peer_grading_service.py
View file @
8613594c
...
@@ -94,9 +94,9 @@ class MockPeerGradingService(object):
...
@@ -94,9 +94,9 @@ class MockPeerGradingService(object):
'success'
:
True
,
'success'
:
True
,
'submission_id'
:
1
,
'submission_id'
:
1
,
'submission_key'
:
""
,
'submission_key'
:
""
,
'student_response'
:
'
fake student response
'
,
'student_response'
:
'
Sample student response.
'
,
'prompt'
:
'
fake submission prompt
'
,
'prompt'
:
'
Sample submission prompt.
'
,
'rubric'
:
'
fake rubric
'
,
'rubric'
:
'
Placeholder text for the full rubric.
'
,
'max_score'
:
4
'max_score'
:
4
}
}
...
@@ -110,9 +110,9 @@ class MockPeerGradingService(object):
...
@@ -110,9 +110,9 @@ class MockPeerGradingService(object):
return
{
'success'
:
True
,
return
{
'success'
:
True
,
'submission_id'
:
1
,
'submission_id'
:
1
,
'submission_key'
:
''
,
'submission_key'
:
''
,
'student_response'
:
'
fake student response
'
,
'student_response'
:
'
Sample student response.
'
,
'prompt'
:
'
fake submission prompt
'
,
'prompt'
:
'
Sample submission prompt.
'
,
'rubric'
:
'
fake rubric
'
,
'rubric'
:
'
Placeholder text for the full rubric.
'
,
'max_score'
:
4
}
'max_score'
:
4
}
def
save_calibration_essay
(
self
,
**
kwargs
):
def
save_calibration_essay
(
self
,
**
kwargs
):
...
...
common/lib/xmodule/xmodule/peer_grading_module.py
View file @
8613594c
...
@@ -8,7 +8,7 @@ from pkg_resources import resource_string
...
@@ -8,7 +8,7 @@ from pkg_resources import resource_string
from
.capa_module
import
ComplexEncoder
from
.capa_module
import
ComplexEncoder
from
.x_module
import
XModule
from
.x_module
import
XModule
from
xmodule.raw_module
import
RawDescriptor
from
xmodule.raw_module
import
RawDescriptor
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
,
NoPathToItem
from
.timeinfo
import
TimeInfo
from
.timeinfo
import
TimeInfo
from
xblock.fields
import
Dict
,
String
,
Scope
,
Boolean
,
Float
from
xblock.fields
import
Dict
,
String
,
Scope
,
Boolean
,
Float
from
xmodule.fields
import
Date
,
Timedelta
from
xmodule.fields
import
Date
,
Timedelta
...
@@ -72,6 +72,12 @@ class PeerGradingFields(object):
...
@@ -72,6 +72,12 @@ class PeerGradingFields(object):
scope
=
Scope
.
content
scope
=
Scope
.
content
)
)
class
InvalidLinkLocation
(
Exception
):
"""
Exception for the case in which a peer grading module tries to link to an invalid location.
"""
pass
class
PeerGradingModule
(
PeerGradingFields
,
XModule
):
class
PeerGradingModule
(
PeerGradingFields
,
XModule
):
"""
"""
...
@@ -103,11 +109,21 @@ class PeerGradingModule(PeerGradingFields, XModule):
...
@@ -103,11 +109,21 @@ class PeerGradingModule(PeerGradingFields, XModule):
if
self
.
use_for_single_location
:
if
self
.
use_for_single_location
:
try
:
try
:
self
.
linked_problem
=
self
.
system
.
get_module
(
self
.
link_to_location
)
linked_descriptors
=
self
.
descriptor
.
get_required_module_descriptors
()
if
len
(
linked_descriptors
)
==
0
:
error_msg
=
"Peer grading module {0} is trying to use single problem mode without "
"a location specified."
.
format
(
self
.
location
)
log
.
error
(
error_msg
)
raise
InvalidLinkLocation
(
error_msg
)
self
.
linked_problem
=
self
.
system
.
get_module
(
linked_descriptors
[
0
])
except
ItemNotFoundError
:
except
ItemNotFoundError
:
log
.
error
(
"Linked location {0} for peer grading module {1} does not exist"
.
format
(
log
.
error
(
"Linked location {0} for peer grading module {1} does not exist"
.
format
(
self
.
link_to_location
,
self
.
location
))
self
.
link_to_location
,
self
.
location
))
raise
raise
except
NoPathToItem
:
log
.
error
(
"Linked location {0} for peer grading module {1} cannot be linked to."
.
format
(
self
.
link_to_location
,
self
.
location
))
raise
due_date
=
self
.
linked_problem
.
due
due_date
=
self
.
linked_problem
.
due
if
due_date
:
if
due_date
:
self
.
due
=
due_date
self
.
due
=
due_date
...
@@ -514,14 +530,18 @@ class PeerGradingModule(PeerGradingFields, XModule):
...
@@ -514,14 +530,18 @@ class PeerGradingModule(PeerGradingFields, XModule):
def
_find_corresponding_module_for_location
(
location
):
def
_find_corresponding_module_for_location
(
location
):
'''
"""
find the peer grading module that links to the given location
Find the peer grading module that exists at the given location.
'''
"""
try
:
try
:
return
modulestore
()
.
get_instance
(
self
.
system
.
course_id
,
location
)
return
self
.
descriptor
.
system
.
load_item
(
location
)
except
Exception
:
except
ItemNotFoundError
:
# the linked problem doesn't exist
# The linked problem doesn't exist.
log
.
error
(
"Problem {0} does not exist in this course"
.
format
(
location
))
log
.
error
(
"Problem {0} does not exist in this course."
.
format
(
location
))
raise
except
NoPathToItem
:
# The linked problem does not have a path to it (ie is in a draft or other strange state).
log
.
error
(
"Cannot find a path to problem {0} in this course."
.
format
(
location
))
raise
raise
good_problem_list
=
[]
good_problem_list
=
[]
...
@@ -529,7 +549,7 @@ class PeerGradingModule(PeerGradingFields, XModule):
...
@@ -529,7 +549,7 @@ class PeerGradingModule(PeerGradingFields, XModule):
problem_location
=
problem
[
'location'
]
problem_location
=
problem
[
'location'
]
try
:
try
:
descriptor
=
_find_corresponding_module_for_location
(
problem_location
)
descriptor
=
_find_corresponding_module_for_location
(
problem_location
)
except
Exception
:
except
(
NoPathToItem
,
ItemNotFoundError
)
:
continue
continue
if
descriptor
:
if
descriptor
:
problem
[
'due'
]
=
descriptor
.
due
problem
[
'due'
]
=
descriptor
.
due
...
...
common/lib/xmodule/xmodule/tests/test_peer_grading.py
View file @
8613594c
...
@@ -2,6 +2,12 @@ import unittest
...
@@ -2,6 +2,12 @@ import unittest
from
xmodule.modulestore
import
Location
from
xmodule.modulestore
import
Location
from
.
import
get_test_system
from
.
import
get_test_system
from
test_util_open_ended
import
MockQueryDict
,
DummyModulestore
from
test_util_open_ended
import
MockQueryDict
,
DummyModulestore
from
xmodule.open_ended_grading_classes.peer_grading_service
import
MockPeerGradingService
import
json
from
mock
import
Mock
from
xmodule.peer_grading_module
import
PeerGradingModule
from
xblock.field_data
import
DictFieldData
from
xblock.fields
import
ScopeIds
import
logging
import
logging
...
@@ -136,6 +142,13 @@ class PeerGradingModuleTest(unittest.TestCase, DummyModulestore):
...
@@ -136,6 +142,13 @@ class PeerGradingModuleTest(unittest.TestCase, DummyModulestore):
"""
"""
self
.
peer_grading
.
get_instance_state
()
self
.
peer_grading
.
get_instance_state
()
class
MockPeerGradingServiceProblemList
(
MockPeerGradingService
):
def
get_problem_list
(
self
,
course_id
,
grader_id
):
return
{
'success'
:
True
,
'problem_list'
:
[
{
"num_graded"
:
3
,
"num_pending"
:
681
,
"num_required"
:
3
,
"location"
:
"i4x://edX/open_ended/combinedopenended/SampleQuestion"
,
"problem_name"
:
"Peer-Graded Essay"
},
]}
class
PeerGradingModuleScoredTest
(
unittest
.
TestCase
,
DummyModulestore
):
class
PeerGradingModuleScoredTest
(
unittest
.
TestCase
,
DummyModulestore
):
"""
"""
Test peer grading xmodule at the unit level. More detailed tests are difficult, as the module relies on an
Test peer grading xmodule at the unit level. More detailed tests are difficult, as the module relies on an
...
@@ -155,3 +168,70 @@ class PeerGradingModuleScoredTest(unittest.TestCase, DummyModulestore):
...
@@ -155,3 +168,70 @@ class PeerGradingModuleScoredTest(unittest.TestCase, DummyModulestore):
def
test_metadata_load
(
self
):
def
test_metadata_load
(
self
):
peer_grading
=
self
.
get_module_from_location
(
self
.
problem_location
,
COURSE
)
peer_grading
=
self
.
get_module_from_location
(
self
.
problem_location
,
COURSE
)
self
.
assertEqual
(
peer_grading
.
closed
(),
False
)
self
.
assertEqual
(
peer_grading
.
closed
(),
False
)
def
test_problem_list
(
self
):
"""
Test to see if a peer grading problem list can be correctly initialized.
"""
# Initialize peer grading module.
peer_grading
=
self
.
get_module_from_location
(
self
.
problem_location
,
COURSE
)
# Ensure that it cannot find any peer grading.
html
=
peer_grading
.
peer_grading
()
self
.
assertNotIn
(
"Peer-Graded"
,
html
)
# Swap for our mock class, which will find peer grading.
peer_grading
.
peer_gs
=
MockPeerGradingServiceProblemList
()
html
=
peer_grading
.
peer_grading
()
self
.
assertIn
(
"Peer-Graded"
,
html
)
class
PeerGradingModuleLinkedTest
(
unittest
.
TestCase
,
DummyModulestore
):
"""
Test peer grading that is linked to an open ended module.
"""
problem_location
=
Location
([
"i4x"
,
"edX"
,
"open_ended"
,
"peergrading"
,
"PeerGradingLinked"
])
coe_location
=
Location
([
"i4x"
,
"edX"
,
"open_ended"
,
"combinedopenended"
,
"SampleQuestion"
])
def
setUp
(
self
):
"""
Create a peer grading module from a test system.
"""
self
.
test_system
=
get_test_system
()
self
.
test_system
.
open_ended_grading_interface
=
None
self
.
setup_modulestore
(
COURSE
)
def
test_linked_problem
(
self
):
"""
Check to see if a peer grading module with a linked problem loads properly.
"""
# Mock the linked problem descriptor.
linked_descriptor
=
Mock
()
linked_descriptor
.
location
=
self
.
coe_location
# Mock the peer grading descriptor.
pg_descriptor
=
Mock
()
pg_descriptor
.
location
=
self
.
problem_location
pg_descriptor
.
get_required_module_descriptors
=
lambda
:
[
linked_descriptor
,
]
# Setup the proper field data for the peer grading module.
field_data
=
DictFieldData
({
'data'
:
'<peergrading/>'
,
'location'
:
self
.
problem_location
,
'use_for_single_location'
:
True
,
'link_to_location'
:
self
.
coe_location
,
})
# Initialize the peer grading module.
peer_grading
=
PeerGradingModule
(
pg_descriptor
,
self
.
test_system
,
field_data
,
ScopeIds
(
None
,
None
,
self
.
problem_location
,
self
.
problem_location
)
)
# Ensure that it is properly setup.
self
.
assertTrue
(
peer_grading
.
use_for_single_location
)
common/test/data/open_ended/course/2012_Fall.xml
View file @
8613594c
...
@@ -4,5 +4,6 @@
...
@@ -4,5 +4,6 @@
<combinedopenended
url_name=
"SampleQuestion1Attempt"
/>
<combinedopenended
url_name=
"SampleQuestion1Attempt"
/>
<peergrading
url_name=
"PeerGradingSample"
/>
<peergrading
url_name=
"PeerGradingSample"
/>
<peergrading
url_name=
"PeerGradingScored"
/>
<peergrading
url_name=
"PeerGradingScored"
/>
<peergrading
url_name=
"PeerGradingLinked"
/>
</chapter>
</chapter>
</course>
</course>
common/test/data/open_ended/peergrading/PeerGradingLinked.xml
0 → 100644
View file @
8613594c
<peergrading
is_graded=
"True"
max_grade=
"1"
use_for_single_location=
"True"
link_to_location=
"i4x://edX/open_ended/combinedopenended/SampleQuestion"
/>
\ No newline at end of file
common/test/data/open_ended_nopath/README.md
0 → 100644
View file @
8613594c
This is a very very simple course, useful for debugging open ended grading code. This is specifically for testing if a peer grading module with no path to it in the course will be handled properly.
common/test/data/open_ended_nopath/course.xml
0 → 100644
View file @
8613594c
<course
org=
"edX"
course=
"open_ended_nopath"
url_name=
"2012_Fall"
/>
common/test/data/open_ended_nopath/course/2012_Fall.xml
0 → 100644
View file @
8613594c
<course>
<chapter
url_name=
"Overview"
>
</chapter>
</course>
common/test/data/open_ended_nopath/peergrading/PeerGradingNoPath.xml
0 → 100644
View file @
8613594c
<peergrading/>
\ No newline at end of file
common/test/data/open_ended_nopath/policies/2012_Fall.json
0 → 100644
View file @
8613594c
{
"course/2012_Fall"
:
{
"graceperiod"
:
"2 days 5 hours 59 minutes 59 seconds"
,
"start"
:
"2015-07-17T12:00"
,
"display_name"
:
"Self Assessment Test"
,
"graded"
:
"true"
},
"chapter/Overview"
:
{
"display_name"
:
"Overview"
}
}
lms/djangoapps/courseware/tests/modulestore_config.py
View file @
8613594c
...
@@ -22,5 +22,6 @@ MAPPINGS = {
...
@@ -22,5 +22,6 @@ MAPPINGS = {
'edX/test_about_blob_end_date/2012_Fall'
:
'xml'
,
'edX/test_about_blob_end_date/2012_Fall'
:
'xml'
,
'edX/graded/2012_Fall'
:
'xml'
,
'edX/graded/2012_Fall'
:
'xml'
,
'edX/open_ended/2012_Fall'
:
'xml'
,
'edX/open_ended/2012_Fall'
:
'xml'
,
'edX/open_ended_nopath/2012_Fall'
:
'xml'
,
}
}
TEST_DATA_MIXED_MODULESTORE
=
mixed_store_config
(
TEST_DATA_DIR
,
MAPPINGS
)
TEST_DATA_MIXED_MODULESTORE
=
mixed_store_config
(
TEST_DATA_DIR
,
MAPPINGS
)
lms/djangoapps/open_ended_grading/tests.py
View file @
8613594c
...
@@ -320,3 +320,22 @@ class TestPanel(ModuleStoreTestCase, LoginEnrollmentTestCase):
...
@@ -320,3 +320,22 @@ class TestPanel(ModuleStoreTestCase, LoginEnrollmentTestCase):
request
=
Mock
(
user
=
self
.
user
)
request
=
Mock
(
user
=
self
.
user
)
response
=
views
.
student_problem_list
(
request
,
self
.
course
.
id
)
response
=
views
.
student_problem_list
(
request
,
self
.
course
.
id
)
self
.
assertRegexpMatches
(
response
.
content
,
"Here are a list of open ended problems for this course."
)
self
.
assertRegexpMatches
(
response
.
content
,
"Here are a list of open ended problems for this course."
)
@override_settings
(
MODULESTORE
=
TEST_DATA_MIXED_MODULESTORE
)
class
TestPeerGradingFound
(
ModuleStoreTestCase
):
"""
Test to see if peer grading modules can be found properly.
"""
def
setUp
(
self
):
self
.
course_name
=
'edX/open_ended_nopath/2012_Fall'
self
.
course
=
modulestore
()
.
get_course
(
self
.
course_name
)
def
test_peer_grading_nopath
(
self
):
"""
The open_ended_nopath course contains a peer grading module with no path to it.
Ensure that the exception is caught.
"""
found
,
url
=
views
.
find_peer_grading_module
(
self
.
course
)
self
.
assertEqual
(
found
,
False
)
\ No newline at end of file
lms/djangoapps/open_ended_grading/views.py
View file @
8613594c
...
@@ -20,7 +20,7 @@ import open_ended_notifications
...
@@ -20,7 +20,7 @@ import open_ended_notifications
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore
import
search
from
xmodule.modulestore
import
search
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
,
NoPathToItem
from
django.http
import
HttpResponse
,
Http404
,
HttpResponseRedirect
from
django.http
import
HttpResponse
,
Http404
,
HttpResponseRedirect
from
mitxmako.shortcuts
import
render_to_string
from
mitxmako.shortcuts
import
render_to_string
...
@@ -97,25 +97,32 @@ def find_peer_grading_module(course):
...
@@ -97,25 +97,32 @@ def find_peer_grading_module(course):
@param course: A course object.
@param course: A course object.
@return: boolean found_module, string problem_url
@return: boolean found_module, string problem_url
"""
"""
#Reverse the base course url
# Reverse the base course url.
base_course_url
=
reverse
(
'courses'
)
base_course_url
=
reverse
(
'courses'
)
found_module
=
False
found_module
=
False
problem_url
=
""
problem_url
=
""
#
Get the course id and split it
#
Get the course id and split it.
course_id_parts
=
course
.
id
.
split
(
"/"
)
course_id_parts
=
course
.
id
.
split
(
"/"
)
log
.
info
(
"COURSE ID PARTS"
)
log
.
info
(
"COURSE ID PARTS"
)
log
.
info
(
course_id_parts
)
log
.
info
(
course_id_parts
)
#Get the peer grading modules currently in the course. Explicitly specify the course id to avoid issues with different runs.
#
Get the peer grading modules currently in the course. Explicitly specify the course id to avoid issues with different runs.
items
=
modulestore
()
.
get_items
([
'i4x'
,
course_id_parts
[
0
],
course_id_parts
[
1
],
'peergrading'
,
None
],
items
=
modulestore
()
.
get_items
([
'i4x'
,
course_id_parts
[
0
],
course_id_parts
[
1
],
'peergrading'
,
None
],
course_id
=
course
.
id
)
course_id
=
course
.
id
)
#See if any of the modules are centralized modules (ie display info from multiple problems)
#See if any of the modules are centralized modules (ie display info from multiple problems)
items
=
[
i
for
i
in
items
if
not
getattr
(
i
,
"use_for_single_location"
,
True
)]
items
=
[
i
for
i
in
items
if
not
getattr
(
i
,
"use_for_single_location"
,
True
)]
#Get the first one
# Loop through all potential peer grading modules, and find the first one that has a path to it.
if
len
(
items
)
>
0
:
for
item
in
items
:
item_location
=
items
[
0
]
.
location
item_location
=
item
.
location
#Generate a url for the first module and redirect the user to it
# Generate a url for the first module and redirect the user to it.
try
:
problem_url_parts
=
search
.
path_to_location
(
modulestore
(),
course
.
id
,
item_location
)
problem_url_parts
=
search
.
path_to_location
(
modulestore
(),
course
.
id
,
item_location
)
except
NoPathToItem
:
# In the case of nopathtoitem, the peer grading module that was found is in an invalid state, and
# can no longer be accessed. Log an informational message, but this will not impact normal behavior.
log
.
info
(
"Invalid peer grading module location {0} in course {1}. This module may need to be removed."
.
format
(
item_location
,
course
.
id
))
continue
problem_url
=
generate_problem_url
(
problem_url_parts
,
base_course_url
)
problem_url
=
generate_problem_url
(
problem_url_parts
,
base_course_url
)
found_module
=
True
found_module
=
True
...
...
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