diff --git a/common/test/data/embedded_python/course.xml b/common/test/data/embedded_python/course.xml new file mode 100644 index 0000000000..1662543b4d --- /dev/null +++ b/common/test/data/embedded_python/course.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/embedded_python/course/2013_Spring.xml b/common/test/data/embedded_python/course/2013_Spring.xml new file mode 100644 index 0000000000..35e0990d18 --- /dev/null +++ b/common/test/data/embedded_python/course/2013_Spring.xml @@ -0,0 +1,95 @@ + + + + + +
+# for a schematic response, submission[i] is the json representation +# of the diagram and analysis results for the i-th schematic tag + +def get_tran(json,signal): + for element in json: + if element[0] == 'transient': + return element[1].get(signal,[]) + return [] + +def get_value(at,output): + for (t,v) in output: + if at == t: return v + return None + +output = get_tran(submission[0],'Z') +okay = True + +# output should be 1, 1, 1, 1, 1, 0, 0, 0 +if get_value(0.0000004,output) < 2.7: okay = False; +if get_value(0.0000009,output) < 2.7: okay = False; +if get_value(0.0000014,output) < 2.7: okay = False; +if get_value(0.0000019,output) < 2.7: okay = False; +if get_value(0.0000024,output) < 2.7: okay = False; +if get_value(0.0000029,output) > 0.25: okay = False; +if get_value(0.0000034,output) > 0.25: okay = False; +if get_value(0.0000039,output) > 0.25: okay = False; + +correct = ['correct' if okay else 'incorrect'] + +
+ + + + +
+ +
+ + + +
+
diff --git a/common/test/data/embedded_python/roots/2013_Spring.xml b/common/test/data/embedded_python/roots/2013_Spring.xml new file mode 100644 index 0000000000..1662543b4d --- /dev/null +++ b/common/test/data/embedded_python/roots/2013_Spring.xml @@ -0,0 +1 @@ + diff --git a/lms/djangoapps/courseware/tests/tests.py b/lms/djangoapps/courseware/tests/tests.py index 5345630957..3a25b2b62d 100644 --- a/lms/djangoapps/courseware/tests/tests.py +++ b/lms/djangoapps/courseware/tests/tests.py @@ -372,6 +372,7 @@ class TestCoursesLoadTestCase_XmlModulestore(PageLoaderTestCase): '''Check that all pages in test courses load properly from XML''' def setUp(self): + super(TestCoursesLoadTestCase_XmlModulestore, self).setUp() self.setup_viewtest_user() xmodule.modulestore.django._MODULESTORES = {} @@ -390,6 +391,7 @@ class TestCoursesLoadTestCase_MongoModulestore(PageLoaderTestCase): '''Check that all pages in test courses load properly from Mongo''' def setUp(self): + super(TestCoursesLoadTestCase_MongoModulestore, self).setUp() self.setup_viewtest_user() xmodule.modulestore.django._MODULESTORES = {} modulestore().collection.drop() @@ -479,9 +481,6 @@ class TestDraftModuleStore(TestCase): class TestViewAuth(LoginEnrollmentTestCase): """Check that view authentication works properly""" - # NOTE: setUpClass() runs before override_settings takes effect, so - # can't do imports there without manually hacking settings. - def setUp(self): xmodule.modulestore.django._MODULESTORES = {} @@ -804,38 +803,61 @@ class TestViewAuth(LoginEnrollmentTestCase): @override_settings(MODULESTORE=TEST_DATA_XML_MODULESTORE) -class TestCourseGrader(LoginEnrollmentTestCase): +class TestSubmittingProblems(LoginEnrollmentTestCase): """Check that a course gets graded properly""" - # NOTE: setUpClass() runs before override_settings takes effect, so - # can't do imports there without manually hacking settings. + # Subclasses should specify the course slug + course_slug = "UNKNOWN" + course_when = "UNKNOWN" def setUp(self): xmodule.modulestore.django._MODULESTORES = {} - self.graded_course = modulestore().get_course("edX/graded/2012_Fall") + course_name = "edX/%s/%s" % (self.course_slug, self.course_when) + self.course = modulestore().get_course(course_name) + assert self.course, "Couldn't load course %r" % course_name # create a test student self.student = 'view@test.com' self.password = 'foo' self.create_account('u1', self.student, self.password) self.activate_user(self.student) - self.enroll(self.graded_course) + self.enroll(self.course) self.student_user = get_user(self.student) self.factory = RequestFactory() + def problem_location(self, problem_url_name): + return "i4x://edX/{}/problem/{}".format(self.course_slug, problem_url_name) + + def modx_url(self, problem_location, dispatch): + return reverse( + 'modx_dispatch', + kwargs={ + 'course_id': self.course.id, + 'location': problem_location, + 'dispatch': dispatch, + } + ) + + +class TestCourseGrader(TestSubmittingProblems): + """Check that a course gets graded properly""" + + course_slug = "graded" + course_when = "2012_Fall" + def get_grade_summary(self): '''calls grades.grade for current user and course''' model_data_cache = ModelDataCache.cache_for_descriptor_descendents( - self.graded_course.id, self.student_user, self.graded_course) + self.course.id, self.student_user, self.course) fake_request = self.factory.get(reverse('progress', - kwargs={'course_id': self.graded_course.id})) + kwargs={'course_id': self.course.id})) return grades.grade(self.student_user, fake_request, - self.graded_course, model_data_cache) + self.course, model_data_cache) def get_homework_scores(self): '''get scores for homeworks''' @@ -844,10 +866,10 @@ class TestCourseGrader(LoginEnrollmentTestCase): def get_progress_summary(self): '''return progress summary structure for current user and course''' model_data_cache = ModelDataCache.cache_for_descriptor_descendents( - self.graded_course.id, self.student_user, self.graded_course) + self.course.id, self.student_user, self.course) fake_request = self.factory.get(reverse('progress', - kwargs={'course_id': self.graded_course.id})) + kwargs={'course_id': self.course.id})) progress_summary = grades.progress_summary(self.student_user, fake_request, @@ -868,13 +890,8 @@ class TestCourseGrader(LoginEnrollmentTestCase): input_i4x-edX-graded-problem-H1P3_2_1 input_i4x-edX-graded-problem-H1P3_2_2 """ - problem_location = "i4x://edX/graded/problem/%s" % problem_url_name - - modx_url = reverse('modx_dispatch', - kwargs={'course_id': self.graded_course.id, - 'location': problem_location, - 'dispatch': 'problem_check', }) - + problem_location = self.problem_location(problem_url_name) + modx_url = self.modx_url(problem_location, 'problem_check') resp = self.client.post(modx_url, { 'input_i4x-edX-graded-problem-%s_2_1' % problem_url_name: responses[0], 'input_i4x-edX-graded-problem-%s_2_2' % problem_url_name: responses[1], @@ -884,19 +901,10 @@ class TestCourseGrader(LoginEnrollmentTestCase): return resp - def problem_location(self, problem_url_name): - '''Get location string for problem, assuming hardcoded course_id''' - return "i4x://edX/graded/problem/{0}".format(problem_url_name) - def reset_question_answer(self, problem_url_name): '''resets specified problem for current user''' problem_location = self.problem_location(problem_url_name) - - modx_url = reverse('modx_dispatch', - kwargs={'course_id': self.graded_course.id, - 'location': problem_location, - 'dispatch': 'problem_reset', }) - + modx_url = self.modx_url(problem_location, 'problem_reset') resp = self.client.post(modx_url) return resp @@ -962,3 +970,39 @@ class TestCourseGrader(LoginEnrollmentTestCase): # Now we answer the final question (worth half of the grade) self.submit_question_answer('FinalQuestion', ['Correct', 'Correct']) self.check_grade_percent(1.0) # Hooray! We got 100% + + +@override_settings(MODULESTORE=TEST_DATA_XML_MODULESTORE) +class TestSchematicResponse(TestSubmittingProblems): + """Check that a course gets graded properly""" + + course_slug = "embedded_python" + course_when = "2013_Spring" + + def submit_question_answer(self, problem_url_name, responses): + """Particular to the embedded_python/2013_Spring course.""" + problem_location = self.problem_location(problem_url_name) + modx_url = self.modx_url(problem_location, 'problem_check') + resp = self.client.post(modx_url, { + 'input_i4x-edX-embedded_python-problem-{0}_2_1'.format(problem_url_name): json.dumps(responses), + }) + print "modx_url", modx_url, "responses", responses + print "resp", resp + + return resp + + def test_get_graded(self): + resp = self.submit_question_answer('H1P1', + [['transient', {'Z': [ + [0.0000004, 2.8], + [0.0000009, 2.8], + [0.0000014, 2.8], + [0.0000019, 2.8], + [0.0000024, 2.8], + [0.0000029, 0.2], + [0.0000034, 0.2], + [0.0000039, 0.2] + ]}]] + ) + respdata = json.loads(resp.content) + self.assertEqual(respdata['success'], 'correct')