diff --git a/common/test/data/open_ended_nopath/README.md b/common/test/data/open_ended_nopath/README.md
new file mode 100644
index 0000000000..1e57b483bc
--- /dev/null
+++ b/common/test/data/open_ended_nopath/README.md
@@ -0,0 +1 @@
+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.
diff --git a/common/test/data/open_ended_nopath/course.xml b/common/test/data/open_ended_nopath/course.xml
new file mode 100644
index 0000000000..d60df1a471
--- /dev/null
+++ b/common/test/data/open_ended_nopath/course.xml
@@ -0,0 +1 @@
+
diff --git a/common/test/data/open_ended_nopath/course/2012_Fall.xml b/common/test/data/open_ended_nopath/course/2012_Fall.xml
new file mode 100644
index 0000000000..2535b4f462
--- /dev/null
+++ b/common/test/data/open_ended_nopath/course/2012_Fall.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/common/test/data/open_ended_nopath/peergrading/PeerGradingNoPath.xml b/common/test/data/open_ended_nopath/peergrading/PeerGradingNoPath.xml
new file mode 100644
index 0000000000..7e3afddf3a
--- /dev/null
+++ b/common/test/data/open_ended_nopath/peergrading/PeerGradingNoPath.xml
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/common/test/data/open_ended_nopath/policies/2012_Fall.json b/common/test/data/open_ended_nopath/policies/2012_Fall.json
new file mode 100644
index 0000000000..321cdf21df
--- /dev/null
+++ b/common/test/data/open_ended_nopath/policies/2012_Fall.json
@@ -0,0 +1,11 @@
+{
+ "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"
+ }
+}
diff --git a/lms/djangoapps/courseware/tests/modulestore_config.py b/lms/djangoapps/courseware/tests/modulestore_config.py
index 74fd3da57f..681f3fd4d1 100644
--- a/lms/djangoapps/courseware/tests/modulestore_config.py
+++ b/lms/djangoapps/courseware/tests/modulestore_config.py
@@ -22,5 +22,6 @@ MAPPINGS = {
'edX/test_about_blob_end_date/2012_Fall': 'xml',
'edX/graded/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)
diff --git a/lms/djangoapps/open_ended_grading/tests.py b/lms/djangoapps/open_ended_grading/tests.py
index 27e6fd6059..7ea81f4f3f 100644
--- a/lms/djangoapps/open_ended_grading/tests.py
+++ b/lms/djangoapps/open_ended_grading/tests.py
@@ -320,3 +320,22 @@ class TestPanel(ModuleStoreTestCase, LoginEnrollmentTestCase):
request = Mock(user=self.user)
response = views.student_problem_list(request, self.course.id)
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
diff --git a/lms/djangoapps/open_ended_grading/views.py b/lms/djangoapps/open_ended_grading/views.py
index e060f4c131..f5a2471226 100644
--- a/lms/djangoapps/open_ended_grading/views.py
+++ b/lms/djangoapps/open_ended_grading/views.py
@@ -97,28 +97,31 @@ def find_peer_grading_module(course):
@param course: A course object.
@return: boolean found_module, string problem_url
"""
- #Reverse the base course url
+
+ # Reverse the base course url.
base_course_url = reverse('courses')
found_module = False
problem_url = ""
- #Get the course id and split it
+ # Get the course id and split it.
course_id_parts = course.id.split("/")
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],
course_id=course.id)
#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)]
- #Get the first one
+ # Loop through all potential peer grading modules, and find the first one that has a path to it.
for item in items:
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)
except NoPathToItem:
- log.info("Invalid peer grading module location {0} in course {1}.".format(item_location, course.id))
+ # 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)
found_module = True