Exemple #1
0
 def test_submit_nonrescorable_modules(self):
     # confirm that a rescore of an existent but unscorable module returns an exception
     # (Note that it is easier to test a scoreable but non-rescorable module in test_tasks,
     # where we are creating real modules.)
     problem_url = self.problem_section.location
     request = None
     with pytest.raises(NotImplementedError):
         submit_rescore_problem_for_student(request, problem_url, self.student)
     with pytest.raises(NotImplementedError):
         submit_rescore_problem_for_all_students(request, problem_url)
Exemple #2
0
 def test_submit_nonrescorable_modules(self):
     # confirm that a rescore of an existent but unscorable module returns an exception
     # (Note that it is easier to test a scoreable but non-rescorable module in test_tasks,
     # where we are creating real modules.)
     problem_url = self.problem_section.location
     request = None
     with self.assertRaises(NotImplementedError):
         submit_rescore_problem_for_student(request, problem_url, self.student)
     with self.assertRaises(NotImplementedError):
         submit_rescore_problem_for_all_students(request, problem_url)
Exemple #3
0
 def test_submit_nonexistent_modules(self):
     # confirm that a rescore of a non-existent module returns an exception
     problem_url = InstructorTaskModuleTestCase.problem_location("NonexistentProblem")
     request = None
     with self.assertRaises(ItemNotFoundError):
         submit_rescore_problem_for_student(request, problem_url, self.student)
     with self.assertRaises(ItemNotFoundError):
         submit_rescore_problem_for_all_students(request, problem_url)
     with self.assertRaises(ItemNotFoundError):
         submit_reset_problem_attempts_for_all_students(request, problem_url)
     with self.assertRaises(ItemNotFoundError):
         submit_delete_problem_state_for_all_students(request, problem_url)
Exemple #4
0
 def test_submit_nonexistent_modules(self):
     # confirm that a rescore of a non-existent module returns an exception
     problem_url = InstructorTaskModuleTestCase.problem_location("NonexistentProblem")
     request = None
     with pytest.raises(ItemNotFoundError):
         submit_rescore_problem_for_student(request, problem_url, self.student)
     with pytest.raises(ItemNotFoundError):
         submit_rescore_problem_for_all_students(request, problem_url)
     with pytest.raises(ItemNotFoundError):
         submit_reset_problem_attempts_for_all_students(request, problem_url)
     with pytest.raises(ItemNotFoundError):
         submit_delete_problem_state_for_all_students(request, problem_url)
Exemple #5
0
 def submit_rescore_one_student_answer(self, instructor, problem_url_name,
                                       student):
     """Submits the particular problem for rescoring for a particular student"""
     return submit_rescore_problem_for_student(
         self.create_task_request(instructor),
         InstructorTaskModuleTestCase.problem_location(problem_url_name),
         student)
Exemple #6
0
 def submit_rescore_one_student_answer(self, instructor, problem_url_name, student, only_if_higher=False):
     """Submits the particular problem for rescoring for a particular student"""
     return submit_rescore_problem_for_student(
         self.create_task_request(instructor),
         InstructorTaskModuleTestCase.problem_location(problem_url_name),
         student,
         only_if_higher,
     )
    def test_rescoring_events(self, models_tracker, handlers_tracker, instructor_task_tracker):
        # submit answer
        self.submit_question_answer('p1', {'2_1': 'choice_choice_3'})
        models_tracker.reset_mock()
        handlers_tracker.reset_mock()

        new_problem_xml = MultipleChoiceResponseXMLFactory().build_xml(
            question_text='The correct answer is Choice 3',
            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):
            self.problem.data = new_problem_xml
            module_store.update_item(self.problem, self.instructor.id)
            module_store.publish(self.problem.location, self.instructor.id)

        submit_rescore_problem_for_student(
            request=get_mock_request(self.instructor),
            usage_key=self.problem.location,
            student=self.student,
            only_if_higher=False
        )
        # check logging to make sure id's are tracked correctly across
        # events
        event_transaction_id = instructor_task_tracker.emit.mock_calls[0][1][1]['event_transaction_id']
        self.assertEqual(
            instructor_task_tracker.get_tracker().context.call_args[0],
            ('edx.grades.problem.rescored', {'course_id': unicode(self.course.id), 'org_id': unicode(self.course.org)})
        )
        # make sure the id is propagated throughout the event flow
        for call in models_tracker.emit.mock_calls:
            self.assertEqual(event_transaction_id, call[1][1]['event_transaction_id'])
            self.assertEqual(unicode(RESCORE_TYPE), call[1][1]['event_transaction_type'])

        # make sure the models calls have re-added the course id to the context
        for args in models_tracker.get_tracker().context.call_args_list:
            self.assertEqual(
                args[0][1],
                {'course_id': unicode(self.course.id), 'org_id': unicode(self.course.org)}
            )

        handlers_tracker.assert_not_called()

        instructor_task_tracker.emit.assert_called_with(
            unicode(RESCORE_TYPE),
            {
                'course_id': unicode(self.course.id),
                'user_id': unicode(self.student.id),
                'problem_id': unicode(self.problem.location),
                'new_weighted_earned': 2,
                'new_weighted_possible': 2,
                'only_if_higher': False,
                'instructor_id': unicode(self.instructor.id),
                'event_transaction_id': event_transaction_id,
                'event_transaction_type': unicode(RESCORE_TYPE),
            }
        )
        course = modulestore().get_course(self.course.id, depth=0)
        models_tracker.emit.assert_called_with(
            u'edx.grades.course.grade_calculated',
            {
                'course_version': unicode(course.course_version),
                'percent_grade': 0.02,
                'grading_policy_hash': u'ChVp0lHGQGCevD0t4njna/C44zQ=',
                'user_id': unicode(self.student.id),
                'letter_grade': u'',
                'event_transaction_id': event_transaction_id,
                'event_transaction_type': unicode(RESCORE_TYPE),
                'course_id': unicode(self.course.id),
                'course_edited_timestamp': unicode(course.subtree_edited_on),
            }
        )
        instructor_task_tracker.reset_mock()
        models_tracker.reset_mock()
        handlers_tracker.reset_mock()
Exemple #8
0
    def test_rescoring_events(self, models_tracker, handlers_tracker,
                              instructor_task_tracker):
        # submit answer
        self.submit_question_answer('p1', {'2_1': 'choice_choice_3'})
        models_tracker.reset_mock()
        handlers_tracker.reset_mock()

        new_problem_xml = MultipleChoiceResponseXMLFactory().build_xml(
            question_text='The correct answer is Choice 3',
            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):
            self.problem.data = new_problem_xml
            module_store.update_item(self.problem, self.instructor.id)
            module_store.publish(self.problem.location, self.instructor.id)

        submit_rescore_problem_for_student(request=get_mock_request(
            self.instructor),
                                           usage_key=self.problem.location,
                                           student=self.student,
                                           only_if_higher=False)
        # check logging to make sure id's are tracked correctly across
        # events
        event_transaction_id = instructor_task_tracker.emit.mock_calls[0][1][
            1]['event_transaction_id']
        self.assertEqual(
            instructor_task_tracker.get_tracker().context.call_args[0],
            ('edx.grades.problem.rescored', {
                'course_id': unicode(self.course.id),
                'org_id': unicode(self.course.org)
            }))
        # make sure the id is propagated throughout the event flow
        for call in models_tracker.emit.mock_calls:
            self.assertEqual(event_transaction_id,
                             call[1][1]['event_transaction_id'])
            self.assertEqual(unicode(RESCORE_TYPE),
                             call[1][1]['event_transaction_type'])

        # make sure the models calls have re-added the course id to the context
        for args in models_tracker.get_tracker().context.call_args_list:
            self.assertEqual(
                args[0][1], {
                    'course_id': unicode(self.course.id),
                    'org_id': unicode(self.course.org)
                })

        handlers_tracker.assert_not_called()

        instructor_task_tracker.emit.assert_called_with(
            unicode(RESCORE_TYPE), {
                'course_id': unicode(self.course.id),
                'user_id': unicode(self.student.id),
                'problem_id': unicode(self.problem.location),
                'new_weighted_earned': 2,
                'new_weighted_possible': 2,
                'only_if_higher': False,
                'instructor_id': unicode(self.instructor.id),
                'event_transaction_id': event_transaction_id,
                'event_transaction_type': unicode(RESCORE_TYPE),
            })
        course = modulestore().get_course(self.course.id, depth=0)
        models_tracker.emit.assert_called_with(
            u'edx.grades.course.grade_calculated', {
                'course_version': unicode(course.course_version),
                'percent_grade': 0.02,
                'grading_policy_hash': u'ChVp0lHGQGCevD0t4njna/C44zQ=',
                'user_id': unicode(self.student.id),
                'letter_grade': u'',
                'event_transaction_id': event_transaction_id,
                'event_transaction_type': unicode(RESCORE_TYPE),
                'course_id': unicode(self.course.id),
                'course_edited_timestamp': unicode(course.subtree_edited_on),
            })
        instructor_task_tracker.reset_mock()
        models_tracker.reset_mock()
        handlers_tracker.reset_mock()
Exemple #9
0
    def test_rescoring_events(self):
        self.submit_question_answer('p1', {'2_1': 'choice_choice_3'})
        new_problem_xml = MultipleChoiceResponseXMLFactory().build_xml(
            question_text='The correct answer is Choice 3',
            choices=[False, False, False, True],
            choice_names=['choice_0', 'choice_1', 'choice_2', 'choice_3']
        )
        with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, self.course.id):
            self.problem.data = new_problem_xml
            self.store.update_item(self.problem, self.instructor.id)
        self.store.publish(self.problem.location, self.instructor.id)

        with patch('lms.djangoapps.grades.events.tracker') as events_tracker:
            submit_rescore_problem_for_student(
                request=get_mock_request(self.instructor),
                usage_key=self.problem.location,
                student=self.student,
                only_if_higher=False
            )
        course = self.store.get_course(self.course.id, depth=0)

        # make sure the tracker's context is updated with course info
        for args in events_tracker.get_tracker().context.call_args_list:
            self.assertEqual(
                args[0][1],
                {'course_id': unicode(self.course.id), 'org_id': unicode(self.course.org)}
            )

        event_transaction_id = events_tracker.emit.mock_calls[0][1][1]['event_transaction_id']
        events_tracker.emit.assert_has_calls(
            [
                mock_call(
                    events.GRADES_RESCORE_EVENT_TYPE,
                    {
                        'course_id': unicode(self.course.id),
                        'user_id': unicode(self.student.id),
                        'problem_id': unicode(self.problem.location),
                        'new_weighted_earned': 2,
                        'new_weighted_possible': 2,
                        'only_if_higher': False,
                        'instructor_id': unicode(self.instructor.id),
                        'event_transaction_id': event_transaction_id,
                        'event_transaction_type': events.GRADES_RESCORE_EVENT_TYPE,
                    },
                ),
                mock_call(
                    events.COURSE_GRADE_CALCULATED,
                    {
                        'course_version': unicode(course.course_version),
                        'percent_grade': 0.02,
                        'grading_policy_hash': u'ChVp0lHGQGCevD0t4njna/C44zQ=',
                        'user_id': unicode(self.student.id),
                        'letter_grade': u'',
                        'event_transaction_id': event_transaction_id,
                        'event_transaction_type': events.GRADES_RESCORE_EVENT_TYPE,
                        'course_id': unicode(self.course.id),
                        'course_edited_timestamp': unicode(course.subtree_edited_on),
                    },
                ),
            ],
            any_order=True,
        )
Exemple #10
0
    def test_rescoring_events(self):
        self.submit_question_answer('p1', {'2_1': 'choice_choice_3'})
        new_problem_xml = MultipleChoiceResponseXMLFactory().build_xml(
            question_text='The correct answer is Choice 3',
            choices=[False, False, False, True],
            choice_names=['choice_0', 'choice_1', 'choice_2', 'choice_3'])
        with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred,
                                       self.course.id):
            self.problem.data = new_problem_xml
            self.store.update_item(self.problem, self.instructor.id)
        self.store.publish(self.problem.location, self.instructor.id)

        with patch('lms.djangoapps.grades.events.tracker') as events_tracker:
            submit_rescore_problem_for_student(request=get_mock_request(
                self.instructor),
                                               usage_key=self.problem.location,
                                               student=self.student,
                                               only_if_higher=False)
        course = self.store.get_course(self.course.id, depth=0)

        # make sure the tracker's context is updated with course info
        for args in events_tracker.get_tracker().context.call_args_list:
            self.assertEqual(
                args[0][1], {
                    'course_id': six.text_type(self.course.id),
                    'org_id': six.text_type(self.course.org)
                })

        event_transaction_id = events_tracker.emit.mock_calls[0][1][1][
            'event_transaction_id']
        events_tracker.emit.assert_has_calls(
            [
                mock_call(
                    events.GRADES_RESCORE_EVENT_TYPE,
                    {
                        'course_id': six.text_type(self.course.id),
                        'user_id': six.text_type(self.student.id),
                        'problem_id': six.text_type(self.problem.location),
                        'new_weighted_earned': 2,
                        'new_weighted_possible': 2,
                        'only_if_higher': False,
                        'instructor_id': six.text_type(self.instructor.id),
                        'event_transaction_id': event_transaction_id,
                        'event_transaction_type':
                        events.GRADES_RESCORE_EVENT_TYPE,
                    },
                ),
                mock_call(
                    events.COURSE_GRADE_CALCULATED,
                    {
                        'course_version':
                        six.text_type(course.course_version),
                        'percent_grade':
                        0.02,
                        'grading_policy_hash':
                        u'ChVp0lHGQGCevD0t4njna/C44zQ=',
                        'user_id':
                        six.text_type(self.student.id),
                        'letter_grade':
                        u'',
                        'event_transaction_id':
                        event_transaction_id,
                        'event_transaction_type':
                        events.GRADES_RESCORE_EVENT_TYPE,
                        'course_id':
                        six.text_type(self.course.id),
                        'course_edited_timestamp':
                        six.text_type(course.subtree_edited_on),
                    },
                ),
            ],
            any_order=True,
        )