diff --git a/lms/djangoapps/grades/api/tests/test_views.py b/lms/djangoapps/grades/api/tests/test_views.py index 53c2bb6f29..5d17441f2f 100644 --- a/lms/djangoapps/grades/api/tests/test_views.py +++ b/lms/djangoapps/grades/api/tests/test_views.py @@ -16,7 +16,7 @@ from lms.djangoapps.courseware.tests.factories import GlobalStaffFactory, StaffF from lms.djangoapps.grades.tests.utils import mock_get_score from student.tests.factories import CourseEnrollmentFactory, UserFactory from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory +from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase, TEST_DATA_SPLIT_MODULESTORE @@ -68,34 +68,35 @@ class CurrentGradeViewTest(SharedModuleStoreTestCase, APITestCase): super(CurrentGradeViewTest, cls).setUpClass() cls.course = CourseFactory.create(display_name='test course', run="Testing_course") + with cls.store.bulk_operations(cls.course.id): - chapter = ItemFactory.create( - category='chapter', - parent_location=cls.course.location, - display_name="Chapter 1", - ) - # create a problem for each type and minimum count needed by the grading policy - # A section is not considered if the student answers less than "min_count" problems - for grading_type, min_count in (("Homework", 12), ("Lab", 12), ("Midterm Exam", 1), ("Final Exam", 1)): - for num in xrange(min_count): - section = ItemFactory.create( - category='sequential', - parent_location=chapter.location, - due=datetime(2013, 9, 18, 11, 30, 00), - display_name='Sequential {} {}'.format(grading_type, num), - format=grading_type, - graded=True, - ) - vertical = ItemFactory.create( - category='vertical', - parent_location=section.location, - display_name='Vertical {} {}'.format(grading_type, num), - ) - ItemFactory.create( - category='problem', - parent_location=vertical.location, - display_name='Problem {} {}'.format(grading_type, num), - ) + chapter = ItemFactory.create( + category='chapter', + parent_location=cls.course.location, + display_name="Chapter 1", + ) + # create a problem for each type and minimum count needed by the grading policy + # A section is not considered if the student answers less than "min_count" problems + for grading_type, min_count in (("Homework", 12), ("Lab", 12), ("Midterm Exam", 1), ("Final Exam", 1)): + for num in xrange(min_count): + section = ItemFactory.create( + category='sequential', + parent_location=chapter.location, + due=datetime(2013, 9, 18, 11, 30, 00, tzinfo=UTC), + display_name='Sequential {} {}'.format(grading_type, num), + format=grading_type, + graded=True, + ) + vertical = ItemFactory.create( + category='vertical', + parent_location=section.location, + display_name='Vertical {} {}'.format(grading_type, num), + ) + ItemFactory.create( + category='problem', + parent_location=vertical.location, + display_name='Problem {} {}'.format(grading_type, num), + ) cls.course_key = cls.course.id @@ -141,8 +142,14 @@ class CurrentGradeViewTest(SharedModuleStoreTestCase, APITestCase): """ Test that a user can successfully request her own grade. """ - resp = self.client.get(self.get_url(self.student.username)) - self.assertEqual(resp.status_code, status.HTTP_200_OK) + with check_mongo_calls(6): + resp = self.client.get(self.get_url(self.student.username)) + self.assertEqual(resp.status_code, status.HTTP_200_OK) + + # redo with block structure now in the cache + with check_mongo_calls(3): + resp = self.client.get(self.get_url(self.student.username)) + self.assertEqual(resp.status_code, status.HTTP_200_OK) def test_nonexistent_user(self): """ @@ -383,8 +390,8 @@ class GradingPolicyTestMixin(object): The view should be addressable by course-keys from both module stores. """ course = CourseFactory.create( - start=datetime(2014, 6, 16, 14, 30), - end=datetime(2015, 1, 16), + start=datetime(2014, 6, 16, 14, 30, tzinfo=UTC), + end=datetime(2015, 1, 16, tzinfo=UTC), org="MTD", default_store=modulestore_type, ) diff --git a/lms/djangoapps/grades/new/course_grade.py b/lms/djangoapps/grades/new/course_grade.py index 10a4240456..319a3b8156 100644 --- a/lms/djangoapps/grades/new/course_grade.py +++ b/lms/djangoapps/grades/new/course_grade.py @@ -31,11 +31,15 @@ class CourseGrade(object): def __init__(self, student, course, course_structure): self.student = student self.course = course - self.course_version = getattr(course, 'course_version', None) - self.course_edited_timestamp = getattr(course, 'subtree_edited_on', None) - self.course_structure = course_structure self._percent = None self._letter_grade = None + + self.course_structure = course_structure + if self.course_structure: + course_block = course_structure[course.location] + self.course_version = getattr(course_block, 'course_version', None) + self.course_edited_timestamp = getattr(course_block, 'subtree_edited_on', None) + self._subsection_grade_factory = SubsectionGradeFactory(self.student, self.course, self.course_structure) @lazy diff --git a/lms/djangoapps/grades/tasks.py b/lms/djangoapps/grades/tasks.py index c838471825..c72aad70c6 100644 --- a/lms/djangoapps/grades/tasks.py +++ b/lms/djangoapps/grades/tasks.py @@ -16,7 +16,6 @@ from openedx.core.djangoapps.celery_utils.persist_on_failure import PersistOnFai from opaque_keys.edx.keys import UsageKey from opaque_keys.edx.locator import CourseLocator from submissions import api as sub_api -from student.models import anonymous_id_for_user from track.event_transaction_utils import ( set_event_transaction_type, set_event_transaction_id, diff --git a/lms/djangoapps/grades/tests/integration/test_events.py b/lms/djangoapps/grades/tests/integration/test_events.py index 855ef1a1ae..c177e9a124 100644 --- a/lms/djangoapps/grades/tests/integration/test_events.py +++ b/lms/djangoapps/grades/tests/integration/test_events.py @@ -30,7 +30,6 @@ class GradesEventIntegrationTest(ProblemSubmissionTestMixin, SharedModuleStoreTe @classmethod def setUpClass(cls): super(GradesEventIntegrationTest, cls).setUpClass() - cls.store = modulestore() with cls.store.default_store(ModuleStoreEnum.Type.split): cls.course = CourseFactory.create() cls.chapter = ItemFactory.create( @@ -141,7 +140,7 @@ class GradesEventIntegrationTest(ProblemSubmissionTestMixin, SharedModuleStoreTe } ) - course = modulestore().get_course(self.course.id, depth=0) + course = self.store.get_course(self.course.id, depth=0) models_tracker.emit.assert_called_with( u'edx.grades.course.grade_calculated', { @@ -156,9 +155,6 @@ class GradesEventIntegrationTest(ProblemSubmissionTestMixin, SharedModuleStoreTe 'course_version': unicode(course.course_version), } ) - enrollment_tracker.reset_mock() - models_tracker.reset_mock() - handlers_tracker.reset_mock() @patch('lms.djangoapps.instructor_task.tasks_helper.tracker') @patch('lms.djangoapps.grades.signals.handlers.tracker') @@ -174,11 +170,10 @@ class GradesEventIntegrationTest(ProblemSubmissionTestMixin, SharedModuleStoreTe choices=[False, False, False, True], choice_names=['choice_0', 'choice_1', 'choice_2', 'choice_3'] ) - module_store = modulestore() - with module_store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, self.course.id): + with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, self.course.id): self.problem.data = new_problem_xml - module_store.update_item(self.problem, self.instructor.id) - module_store.publish(self.problem.location, self.instructor.id) + self.store.update_item(self.problem, self.instructor.id) + self.store.publish(self.problem.location, self.instructor.id) submit_rescore_problem_for_student( request=get_mock_request(self.instructor), @@ -221,7 +216,7 @@ class GradesEventIntegrationTest(ProblemSubmissionTestMixin, SharedModuleStoreTe 'event_transaction_type': unicode(RESCORE_TYPE), } ) - course = modulestore().get_course(self.course.id, depth=0) + course = self.store.get_course(self.course.id, depth=0) models_tracker.emit.assert_called_with( u'edx.grades.course.grade_calculated', { @@ -236,6 +231,3 @@ class GradesEventIntegrationTest(ProblemSubmissionTestMixin, SharedModuleStoreTe 'course_edited_timestamp': unicode(course.subtree_edited_on), } ) - instructor_task_tracker.reset_mock() - models_tracker.reset_mock() - handlers_tracker.reset_mock()