Commit be4fbc56 by Don Mitchell

Refactor tests to no longer use templates

Add boilerplate option to ItemFactory
Minor start date fix to not use microsecs
parent 92391a22
...@@ -308,12 +308,14 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase): ...@@ -308,12 +308,14 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
CourseFactory.create(org='edX', course='999', display_name='Robot Super Course') CourseFactory.create(org='edX', course='999', display_name='Robot Super Course')
course_location = Location(['i4x', 'edX', '999', 'course', 'Robot_Super_Course', None]) course_location = Location(['i4x', 'edX', '999', 'course', 'Robot_Super_Course', None])
ItemFactory.create(parent_location=course_location, ItemFactory.create(
template="i4x://edx/templates/static_tab/Empty", parent_location=course_location,
display_name="Static_1") category="static_tab",
ItemFactory.create(parent_location=course_location, display_name="Static_1")
template="i4x://edx/templates/static_tab/Empty", ItemFactory.create(
display_name="Static_2") parent_location=course_location,
category="static_tab",
display_name="Static_2")
course = module_store.get_item(Location(['i4x', 'edX', '999', 'course', 'Robot_Super_Course', None])) course = module_store.get_item(Location(['i4x', 'edX', '999', 'course', 'Robot_Super_Course', None]))
...@@ -370,7 +372,7 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase): ...@@ -370,7 +372,7 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
course_location = Location(['i4x', 'edX', '999', 'course', 'Robot_Super_Course', None]) course_location = Location(['i4x', 'edX', '999', 'course', 'Robot_Super_Course', None])
chapterloc = ItemFactory.create(parent_location=course_location, display_name="Chapter").location chapterloc = ItemFactory.create(parent_location=course_location, display_name="Chapter").location
ItemFactory.create(parent_location=chapterloc, template='i4x://edx/templates/sequential/Empty', display_name="Sequential") ItemFactory.create(parent_location=chapterloc, category='sequential', display_name="Sequential")
sequential = direct_store.get_item(Location(['i4x', 'edX', '999', 'sequential', 'Sequential', None])) sequential = direct_store.get_item(Location(['i4x', 'edX', '999', 'sequential', 'Sequential', None]))
chapter = direct_store.get_item(Location(['i4x', 'edX', '999', 'chapter', 'Chapter', None])) chapter = direct_store.get_item(Location(['i4x', 'edX', '999', 'chapter', 'Chapter', None]))
...@@ -650,9 +652,9 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase): ...@@ -650,9 +652,9 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
vertical = module_store.get_item(Location(['i4x', 'edX', 'toy', vertical = module_store.get_item(Location(['i4x', 'edX', 'toy',
'vertical', 'vertical_test', None]), depth=1) 'vertical', 'vertical_test', None]), depth=1)
draft_store.clone_item(vertical.location, vertical.location) draft_store.convert_to_draft(vertical.location)
for child in vertical.get_children(): for child in vertical.get_children():
draft_store.clone_item(child.location, child.location) draft_store.convert_to_draft(child.location)
# delete the course # delete the course
delete_course(module_store, content_store, location, commit=True) delete_course(module_store, content_store, location, commit=True)
......
...@@ -49,7 +49,7 @@ class TestCreateItem(CourseTestCase): ...@@ -49,7 +49,7 @@ class TestCreateItem(CourseTestCase):
resp = self.client.post( resp = self.client.post(
reverse('create_item'), reverse('create_item'),
json.dumps({ json.dumps({
'parent_location': self.course_location.url(), 'parent_location': self.course.location.url(),
'display_name': display_name, 'display_name': display_name,
'category': 'chapter' 'category': 'chapter'
}), }),
...@@ -62,11 +62,11 @@ class TestCreateItem(CourseTestCase): ...@@ -62,11 +62,11 @@ class TestCreateItem(CourseTestCase):
new_obj = modulestore().get_item(chap_location) new_obj = modulestore().get_item(chap_location)
self.assertEqual(new_obj.category, 'chapter') self.assertEqual(new_obj.category, 'chapter')
self.assertEqual(new_obj.display_name, display_name) self.assertEqual(new_obj.display_name, display_name)
self.assertEqual(new_obj.location.org, self.course_location.org) self.assertEqual(new_obj.location.org, self.course.location.org)
self.assertEqual(new_obj.location.course, self.course_location.course) self.assertEqual(new_obj.location.course, self.course.location.course)
# get the course and ensure it now points to this one # get the course and ensure it now points to this one
course = modulestore().get_item(self.course_location) course = modulestore().get_item(self.course.location)
self.assertIn(chap_location, course.children) self.assertIn(chap_location, course.children)
# use default display name # use default display name
...@@ -112,7 +112,7 @@ class TestCreateItem(CourseTestCase): ...@@ -112,7 +112,7 @@ class TestCreateItem(CourseTestCase):
resp = self.client.post( resp = self.client.post(
reverse('create_item'), reverse('create_item'),
json.dumps( json.dumps(
{'parent_location': self.course_location.url(), {'parent_location': self.course.location.url(),
'category': 'problem', 'category': 'problem',
'boilerplate': 'nosuchboilerplate.yaml' 'boilerplate': 'nosuchboilerplate.yaml'
}), }),
...@@ -140,7 +140,7 @@ class TestEditItem(CourseTestCase): ...@@ -140,7 +140,7 @@ class TestEditItem(CourseTestCase):
resp = self.client.post( resp = self.client.post(
reverse('create_item'), reverse('create_item'),
json.dumps( json.dumps(
{'parent_location': self.course_location.url(), {'parent_location': self.course.location.url(),
'display_name': display_name, 'display_name': display_name,
'category': 'chapter' 'category': 'chapter'
}), }),
...@@ -209,4 +209,4 @@ class TestEditItem(CourseTestCase): ...@@ -209,4 +209,4 @@ class TestEditItem(CourseTestCase):
content_type="application/json" content_type="application/json"
) )
problem = modulestore('draft').get_item(self.problems[0]) problem = modulestore('draft').get_item(self.problems[0])
self.assertIsNo/ne(problem.markdown) self.assertIsNone(problem.markdown)
...@@ -8,6 +8,7 @@ from xmodule.modulestore import Location ...@@ -8,6 +8,7 @@ from xmodule.modulestore import Location
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.course_module import CourseDescriptor from xmodule.course_module import CourseDescriptor
from xblock.core import Scope from xblock.core import Scope
from xmodule.x_module import XModuleDescriptor
class XModuleCourseFactory(Factory): class XModuleCourseFactory(Factory):
""" """
...@@ -36,7 +37,7 @@ class XModuleCourseFactory(Factory): ...@@ -36,7 +37,7 @@ class XModuleCourseFactory(Factory):
if display_name is not None: if display_name is not None:
new_course.display_name = display_name new_course.display_name = display_name
new_course.lms.start = datetime.datetime.now(UTC) new_course.lms.start = datetime.datetime.now(UTC).replace(microsecond=0)
new_course.tabs = kwargs.pop( new_course.tabs = kwargs.pop(
'tabs', 'tabs',
[ [
...@@ -88,21 +89,23 @@ class XModuleItemFactory(Factory): ...@@ -88,21 +89,23 @@ class XModuleItemFactory(Factory):
@classmethod @classmethod
def _create(cls, target_class, **kwargs): def _create(cls, target_class, **kwargs):
""" """
Uses *kwargs*: Uses ``**kwargs``:
*parent_location* (required): the location of the parent module :parent_location: (required): the location of the parent module
(e.g. the parent course or section) (e.g. the parent course or section)
category: the category of the resulting item. :category: the category of the resulting item.
*data* (optional): the data for the item :data: (optional): the data for the item
(e.g. XML problem definition for a problem item) (e.g. XML problem definition for a problem item)
*display_name* (optional): the display name of the item :display_name: (optional): the display name of the item
*metadata* (optional): dictionary of metadata attributes :metadata: (optional): dictionary of metadata attributes
*target_class* is ignored :boilerplate: (optional) the boilerplate for overriding field values
:target_class: is ignored
""" """
DETACHED_CATEGORIES = ['about', 'static_tab', 'course_info'] DETACHED_CATEGORIES = ['about', 'static_tab', 'course_info']
...@@ -115,6 +118,14 @@ class XModuleItemFactory(Factory): ...@@ -115,6 +118,14 @@ class XModuleItemFactory(Factory):
metadata = kwargs.get('metadata', {}) metadata = kwargs.get('metadata', {})
location = kwargs.get('location', XModuleItemFactory.location(parent_location, category, display_name)) location = kwargs.get('location', XModuleItemFactory.location(parent_location, category, display_name))
assert location != parent_location assert location != parent_location
if kwargs.get('boilerplate') is not None:
template_id = kwargs.get('boilerplate')
clz = XModuleDescriptor.load_class(category)
template = clz.get_template(template_id)
assert template is not None
metadata.update(template.get('metadata', {}))
if not isinstance(data, basestring):
data.update(template.get('data'))
store = modulestore('direct') store = modulestore('direct')
......
...@@ -59,7 +59,7 @@ class TestSubmittingProblems(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -59,7 +59,7 @@ class TestSubmittingProblems(ModuleStoreTestCase, LoginEnrollmentTestCase):
Returns the url of the problem given the problem's name Returns the url of the problem given the problem's name
""" """
return "i4x://"+self.course.org+"/{}/problem/{}".format(self.COURSE_SLUG, problem_url_name) return "i4x://" + self.course.org + "/{}/problem/{}".format(self.COURSE_SLUG, problem_url_name)
def modx_url(self, problem_location, dispatch): def modx_url(self, problem_location, dispatch):
""" """
...@@ -119,7 +119,6 @@ class TestSubmittingProblems(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -119,7 +119,6 @@ class TestSubmittingProblems(ModuleStoreTestCase, LoginEnrollmentTestCase):
num_input: the number of input fields to create in the problem num_input: the number of input fields to create in the problem
""" """
problem_template = "i4x://edx/templates/problem/Blank_Common_Problem"
prob_xml = OptionResponseXMLFactory().build_xml( prob_xml = OptionResponseXMLFactory().build_xml(
question_text='The correct answer is Correct', question_text='The correct answer is Correct',
num_inputs=num_inputs, num_inputs=num_inputs,
...@@ -405,7 +404,7 @@ class TestCourseGrader(TestSubmittingProblems): ...@@ -405,7 +404,7 @@ class TestCourseGrader(TestSubmittingProblems):
# Get both parts correct # Get both parts correct
self.submit_question_answer('H1P1', {'2_1': 'Correct', '2_2': 'Correct'}) self.submit_question_answer('H1P1', {'2_1': 'Correct', '2_2': 'Correct'})
self.check_grade_percent(0.25) self.check_grade_percent(0.25)
self.assertEqual(self.earned_hw_scores(), [2.0]) # Order matters self.assertEqual(self.earned_hw_scores(), [2.0]) # Order matters
self.assertEqual(self.score_for_hw('homework'), [2.0]) self.assertEqual(self.score_for_hw('homework'), [2.0])
def test_weighted_exam(self): def test_weighted_exam(self):
...@@ -443,7 +442,7 @@ class TestCourseGrader(TestSubmittingProblems): ...@@ -443,7 +442,7 @@ class TestCourseGrader(TestSubmittingProblems):
self.assertEqual(self.score_for_hw('homework1'), [1.0, 0.0]) self.assertEqual(self.score_for_hw('homework1'), [1.0, 0.0])
self.assertEqual(self.score_for_hw('homework2'), [1.0, 1.0]) self.assertEqual(self.score_for_hw('homework2'), [1.0, 1.0])
self.assertEqual(self.earned_hw_scores(), [1.0, 2.0, 0]) # Order matters self.assertEqual(self.earned_hw_scores(), [1.0, 2.0, 0]) # Order matters
self.check_grade_percent(0.75) self.check_grade_percent(0.75)
def test_dropping_nochange(self): def test_dropping_nochange(self):
...@@ -457,7 +456,7 @@ class TestCourseGrader(TestSubmittingProblems): ...@@ -457,7 +456,7 @@ class TestCourseGrader(TestSubmittingProblems):
self.assertEqual(self.score_for_hw('homework1'), [1.0, 0.0]) self.assertEqual(self.score_for_hw('homework1'), [1.0, 0.0])
self.assertEqual(self.score_for_hw('homework2'), [1.0, 1.0]) self.assertEqual(self.score_for_hw('homework2'), [1.0, 1.0])
self.assertEqual(self.score_for_hw('homework3'), [1.0, 0.0]) self.assertEqual(self.score_for_hw('homework3'), [1.0, 0.0])
self.assertEqual(self.earned_hw_scores(), [1.0, 2.0, 1.0]) # Order matters self.assertEqual(self.earned_hw_scores(), [1.0, 2.0, 1.0]) # Order matters
self.check_grade_percent(0.75) self.check_grade_percent(0.75)
def test_dropping_all_correct(self): def test_dropping_all_correct(self):
...@@ -471,7 +470,7 @@ class TestCourseGrader(TestSubmittingProblems): ...@@ -471,7 +470,7 @@ class TestCourseGrader(TestSubmittingProblems):
self.submit_question_answer(name, {'2_1': 'Correct'}) self.submit_question_answer(name, {'2_1': 'Correct'})
self.check_grade_percent(1.0) self.check_grade_percent(1.0)
self.assertEqual(self.earned_hw_scores(), [1.0, 2.0, 2.0]) # Order matters self.assertEqual(self.earned_hw_scores(), [1.0, 2.0, 2.0]) # Order matters
self.assertEqual(self.score_for_hw('homework3'), [1.0, 1.0]) self.assertEqual(self.score_for_hw('homework3'), [1.0, 1.0])
...@@ -579,13 +578,13 @@ class TestPythonGradedResponse(TestSubmittingProblems): ...@@ -579,13 +578,13 @@ class TestPythonGradedResponse(TestSubmittingProblems):
set up an example Circuit_Schematic_Builder problem set up an example Circuit_Schematic_Builder problem
""" """
schematic_template = "i4x://edx/templates/problem/Circuit_Schematic_Builder"
script = self.SCHEMATIC_SCRIPT script = self.SCHEMATIC_SCRIPT
xmldata = SchematicResponseXMLFactory().build_xml(answer=script) xmldata = SchematicResponseXMLFactory().build_xml(answer=script)
ItemFactory.create( ItemFactory.create(
parent_location=self.section.location, parent_location=self.section.location,
template=schematic_template, category='problem',
boilerplate='circuitschematic.yaml',
display_name=name, display_name=name,
data=xmldata data=xmldata
) )
...@@ -602,14 +601,14 @@ class TestPythonGradedResponse(TestSubmittingProblems): ...@@ -602,14 +601,14 @@ class TestPythonGradedResponse(TestSubmittingProblems):
set up an example custom response problem using a check function set up an example custom response problem using a check function
""" """
custom_template = "i4x://edx/templates/problem/Custom_Python-Evaluated_Input"
test_csv = self.CUSTOM_RESPONSE_SCRIPT test_csv = self.CUSTOM_RESPONSE_SCRIPT
expect = self.CUSTOM_RESPONSE_CORRECT expect = self.CUSTOM_RESPONSE_CORRECT
cfn_problem_xml = CustomResponseXMLFactory().build_xml(script=test_csv, cfn='test_csv', expect=expect) cfn_problem_xml = CustomResponseXMLFactory().build_xml(script=test_csv, cfn='test_csv', expect=expect)
ItemFactory.create( ItemFactory.create(
parent_location=self.section.location, parent_location=self.section.location,
template=custom_template, category='problem',
boilerplate='customgrader.yaml',
data=cfn_problem_xml, data=cfn_problem_xml,
display_name=name display_name=name
) )
...@@ -628,13 +627,12 @@ class TestPythonGradedResponse(TestSubmittingProblems): ...@@ -628,13 +627,12 @@ class TestPythonGradedResponse(TestSubmittingProblems):
script = self.COMPUTED_ANSWER_SCRIPT script = self.COMPUTED_ANSWER_SCRIPT
custom_template = "i4x://edx/templates/problem/Custom_Python-Evaluated_Input"
computed_xml = CustomResponseXMLFactory().build_xml(answer=script) computed_xml = CustomResponseXMLFactory().build_xml(answer=script)
ItemFactory.create( ItemFactory.create(
parent_location=self.section.location, parent_location=self.section.location,
template=custom_template, category='problem',
boilerplate='customgrader.yaml',
data=computed_xml, data=computed_xml,
display_name=name display_name=name
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment