test_openended_commands.py 8.02 KB
Newer Older
1 2 3 4
"""Test the openended_post management command."""

from datetime import datetime
import json
Ned Batchelder committed
5
from mock import patch
6 7 8 9 10
from pytz import UTC

from django.test.utils import override_settings

import capa.xqueue_interface as xqueue_interface
11
from opaque_keys.edx.locations import Location
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.open_ended_grading_classes.openendedchild import OpenEndedChild
from xmodule.tests.test_util_open_ended import (
    STATE_INITIAL, STATE_ACCESSING, STATE_POST_ASSESSMENT
)

from courseware.courses import get_course_with_access
from courseware.tests.factories import StudentModuleFactory, UserFactory
from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE
from student.models import anonymous_id_for_user

from instructor.management.commands.openended_post import post_submission_for_student
from instructor.management.commands.openended_stats import calculate_task_statistics
from instructor.utils import get_module_for_student

27
from opaque_keys.edx.locations import SlashSeparatedCourseKey
28

29 30 31 32 33 34

@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class OpenEndedPostTest(ModuleStoreTestCase):
    """Test the openended_post management command."""

    def setUp(self):
35 36
        self.course_id = SlashSeparatedCourseKey("edX", "open_ended", "2012_Fall")
        self.problem_location = Location("edX", "open_ended", "2012_Fall", "combinedopenended", "SampleQuestion")
37 38 39 40 41 42 43 44 45
        self.self_assessment_task_number = 0
        self.open_ended_task_number = 1

        self.student_on_initial = UserFactory()
        self.student_on_accessing = UserFactory()
        self.student_on_post_assessment = UserFactory()

        StudentModuleFactory.create(
            course_id=self.course_id,
46
            module_state_key=self.problem_location,
47 48 49 50 51 52 53 54
            student=self.student_on_initial,
            grade=0,
            max_grade=1,
            state=STATE_INITIAL
        )

        StudentModuleFactory.create(
            course_id=self.course_id,
55
            module_state_key=self.problem_location,
56 57 58 59 60 61 62 63
            student=self.student_on_accessing,
            grade=0,
            max_grade=1,
            state=STATE_ACCESSING
        )

        StudentModuleFactory.create(
            course_id=self.course_id,
64
            module_state_key=self.problem_location,
65 66 67 68 69 70 71
            student=self.student_on_post_assessment,
            grade=0,
            max_grade=1,
            state=STATE_POST_ASSESSMENT
        )

    def test_post_submission_for_student_on_initial(self):
72
        course = get_course_with_access(self.student_on_initial, 'load', self.course_id)
73 74 75 76 77 78 79 80

        dry_run_result = post_submission_for_student(self.student_on_initial, course, self.problem_location, self.open_ended_task_number, dry_run=True)
        self.assertFalse(dry_run_result)

        result = post_submission_for_student(self.student_on_initial, course, self.problem_location, self.open_ended_task_number, dry_run=False)
        self.assertFalse(result)

    def test_post_submission_for_student_on_accessing(self):
81
        course = get_course_with_access(self.student_on_accessing, 'load', self.course_id)
82 83 84 85 86 87 88

        dry_run_result = post_submission_for_student(self.student_on_accessing, course, self.problem_location, self.open_ended_task_number, dry_run=True)
        self.assertFalse(dry_run_result)

        with patch('capa.xqueue_interface.XQueueInterface.send_to_queue') as mock_send_to_queue:
            mock_send_to_queue.return_value = (0, "Successfully queued")

89
            module = get_module_for_student(self.student_on_accessing, self.problem_location)
90 91
            task = module.child_module.get_task_number(self.open_ended_task_number)

92
            student_response = "Here is an answer."
93
            student_anonymous_id = anonymous_id_for_user(self.student_on_accessing, None)
94
            submission_time = datetime.strftime(datetime.now(UTC), xqueue_interface.dateformat)
95 96

            result = post_submission_for_student(self.student_on_accessing, course, self.problem_location, self.open_ended_task_number, dry_run=False)
97

98
            self.assertTrue(result)
99 100 101 102 103 104
            mock_send_to_queue_body_arg = json.loads(mock_send_to_queue.call_args[1]['body'])
            self.assertEqual(mock_send_to_queue_body_arg['max_score'], 2)
            self.assertEqual(mock_send_to_queue_body_arg['student_response'], student_response)
            body_arg_student_info = json.loads(mock_send_to_queue_body_arg['student_info'])
            self.assertEqual(body_arg_student_info['anonymous_student_id'], student_anonymous_id)
            self.assertGreaterEqual(body_arg_student_info['submission_time'], submission_time)
105 106

    def test_post_submission_for_student_on_post_assessment(self):
107
        course = get_course_with_access(self.student_on_post_assessment, 'load', self.course_id)
108 109 110 111 112 113 114 115

        dry_run_result = post_submission_for_student(self.student_on_post_assessment, course, self.problem_location, self.open_ended_task_number, dry_run=True)
        self.assertFalse(dry_run_result)

        result = post_submission_for_student(self.student_on_post_assessment, course, self.problem_location, self.open_ended_task_number, dry_run=False)
        self.assertFalse(result)

    def test_post_submission_for_student_invalid_task(self):
116
        course = get_course_with_access(self.student_on_accessing, 'load', self.course_id)
117 118 119 120 121 122 123 124 125 126 127 128 129 130

        result = post_submission_for_student(self.student_on_accessing, course, self.problem_location, self.self_assessment_task_number, dry_run=False)
        self.assertFalse(result)

        out_of_bounds_task_number = 3
        result = post_submission_for_student(self.student_on_accessing, course, self.problem_location, out_of_bounds_task_number, dry_run=False)
        self.assertFalse(result)


@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class OpenEndedStatsTest(ModuleStoreTestCase):
    """Test the openended_stats management command."""

    def setUp(self):
131 132
        self.course_id = SlashSeparatedCourseKey("edX", "open_ended", "2012_Fall")
        self.problem_location = Location("edX", "open_ended", "2012_Fall", "combinedopenended", "SampleQuestion")
133 134 135 136 137 138 139 140 141
        self.task_number = 1
        self.invalid_task_number = 3

        self.student_on_initial = UserFactory()
        self.student_on_accessing = UserFactory()
        self.student_on_post_assessment = UserFactory()

        StudentModuleFactory.create(
            course_id=self.course_id,
142
            module_state_key=self.problem_location,
143 144 145 146 147 148 149 150
            student=self.student_on_initial,
            grade=0,
            max_grade=1,
            state=STATE_INITIAL
        )

        StudentModuleFactory.create(
            course_id=self.course_id,
151
            module_state_key=self.problem_location,
152 153 154 155 156 157 158 159
            student=self.student_on_accessing,
            grade=0,
            max_grade=1,
            state=STATE_ACCESSING
        )

        StudentModuleFactory.create(
            course_id=self.course_id,
160
            module_state_key=self.problem_location,
161 162 163 164 165 166 167 168 169
            student=self.student_on_post_assessment,
            grade=0,
            max_grade=1,
            state=STATE_POST_ASSESSMENT
        )

        self.students = [self.student_on_initial, self.student_on_accessing, self.student_on_post_assessment]

    def test_calculate_task_statistics(self):
170
        course = get_course_with_access(self.student_on_accessing, 'load', self.course_id)
171 172 173 174 175 176 177 178 179 180 181
        stats = calculate_task_statistics(self.students, course, self.problem_location, self.task_number, write_to_file=False)
        self.assertEqual(stats[OpenEndedChild.INITIAL], 1)
        self.assertEqual(stats[OpenEndedChild.ASSESSING], 1)
        self.assertEqual(stats[OpenEndedChild.POST_ASSESSMENT], 1)
        self.assertEqual(stats[OpenEndedChild.DONE], 0)

        stats = calculate_task_statistics(self.students, course, self.problem_location, self.invalid_task_number, write_to_file=False)
        self.assertEqual(stats[OpenEndedChild.INITIAL], 0)
        self.assertEqual(stats[OpenEndedChild.ASSESSING], 0)
        self.assertEqual(stats[OpenEndedChild.POST_ASSESSMENT], 0)
        self.assertEqual(stats[OpenEndedChild.DONE], 0)