tests.py 9.33 KB
Newer Older
1
"""
2
Tests for open ended grading interfaces
3

4
django-admin.py test --settings=lms.envs.test --pythonpath=. lms/djangoapps/open_ended_grading
5 6 7
"""

from django.test import TestCase
8
from open_ended_grading import staff_grading_service
9 10
from xmodule.open_ended_grading_classes import peer_grading_service
from xmodule import  peer_grading_module
11 12
from django.core.urlresolvers import reverse
from django.contrib.auth.models import Group
13

14 15 16 17
from courseware.access import _course_staff_group_name
import courseware.tests.tests as ct
from xmodule.modulestore.django import modulestore
import xmodule.modulestore.django
18
from nose import SkipTest
19
from mock import patch, Mock, MagicMock
20
import json
21 22
from xmodule.x_module import ModuleSystem
from mitxmako.shortcuts import render_to_string
23

24 25
import logging
log = logging.getLogger(__name__)
26
from django.test.utils import override_settings
27
from django.http import QueryDict
28

Vik Paruchuri committed
29 30
from xmodule.tests import test_util_open_ended

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

@override_settings(MODULESTORE=ct.TEST_DATA_XML_MODULESTORE)
class TestStaffGradingService(ct.PageLoader):
    '''
    Check that staff grading service proxy works.  Basically just checking the
    access control and error handling logic -- all the actual work is on the
    backend.
    '''
    def setUp(self):
        xmodule.modulestore.django._MODULESTORES = {}

        self.student = 'view@test.com'
        self.instructor = 'view2@test.com'
        self.password = 'foo'
        self.location = 'TestLocation'
        self.create_account('u1', self.student, self.password)
        self.create_account('u2', self.instructor, self.password)
        self.activate_user(self.student)
        self.activate_user(self.instructor)
Calen Pennington committed
50

51 52 53 54 55 56 57 58 59
        self.course_id = "edX/toy/2012_Fall"
        self.toy = modulestore().get_course(self.course_id)
        def make_instructor(course):
            group_name = _course_staff_group_name(course.location)
            g = Group.objects.create(name=group_name)
            g.user_set.add(ct.user(self.instructor))

        make_instructor(self.toy)

60
        self.mock_service = staff_grading_service.staff_grading_service()
61 62 63 64

        self.logout()

    def test_access(self):
65
        """
66
        Make sure only staff have access.
67
        """
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
        self.login(self.student, self.password)

        # both get and post should return 404
        for view_name in ('staff_grading_get_next', 'staff_grading_save_grade'):
            url = reverse(view_name, kwargs={'course_id': self.course_id})
            self.check_for_get_code(404, url)
            self.check_for_post_code(404, url)


    def test_get_next(self):
        self.login(self.instructor, self.password)

        url = reverse('staff_grading_get_next', kwargs={'course_id': self.course_id})
        data = {'location': self.location}

        r = self.check_for_post_code(200, url, data)
        d = json.loads(r.content)
        self.assertTrue(d['success'])
        self.assertEquals(d['submission_id'], self.mock_service.cnt)
        self.assertIsNotNone(d['submission'])
        self.assertIsNotNone(d['num_graded'])
        self.assertIsNotNone(d['min_for_ml'])
        self.assertIsNotNone(d['num_pending'])
        self.assertIsNotNone(d['prompt'])
        self.assertIsNotNone(d['ml_error_info'])
        self.assertIsNotNone(d['max_score'])
        self.assertIsNotNone(d['rubric'])


    def test_save_grade(self):
        self.login(self.instructor, self.password)

        url = reverse('staff_grading_save_grade', kwargs={'course_id': self.course_id})

        data = {'score': '12',
                'feedback': 'great!',
                'submission_id': '123',
105
                'location': self.location,
106
                'submission_flagged': "true",
107
                'rubric_scores[]': ['1', '2']}
108

109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
        r = self.check_for_post_code(200, url, data)
        d = json.loads(r.content)
        self.assertTrue(d['success'], str(d))
        self.assertEquals(d['submission_id'], self.mock_service.cnt)

    def test_get_problem_list(self):
        self.login(self.instructor, self.password)

        url = reverse('staff_grading_get_problem_list', kwargs={'course_id': self.course_id})
        data = {}

        r = self.check_for_post_code(200, url, data)
        d = json.loads(r.content)
        self.assertTrue(d['success'], str(d))
        self.assertIsNotNone(d['problem_list'])
124

Calen Pennington committed
125

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
@override_settings(MODULESTORE=ct.TEST_DATA_XML_MODULESTORE)
class TestPeerGradingService(ct.PageLoader):
    '''
    Check that staff grading service proxy works.  Basically just checking the
    access control and error handling logic -- all the actual work is on the
    backend.
    '''
    def setUp(self):
        xmodule.modulestore.django._MODULESTORES = {}

        self.student = 'view@test.com'
        self.instructor = 'view2@test.com'
        self.password = 'foo'
        self.location = 'TestLocation'
        self.create_account('u1', self.student, self.password)
        self.create_account('u2', self.instructor, self.password)
        self.activate_user(self.student)
        self.activate_user(self.instructor)
Calen Pennington committed
144

145 146
        self.course_id = "edX/toy/2012_Fall"
        self.toy = modulestore().get_course(self.course_id)
147
        location = "i4x://edX/toy/peergrading/init"
148

149
        self.mock_service = peer_grading_service.MockPeerGradingService()
Vik Paruchuri committed
150 151 152 153
        self.system = ModuleSystem(location, None, None, render_to_string, None,
            s3_interface = test_util_open_ended.S3_INTERFACE,
            open_ended_grading_interface=test_util_open_ended.OPEN_ENDED_GRADING_INTERFACE
        )
154
        self.descriptor = peer_grading_module.PeerGradingDescriptor(self.system)
Calen Pennington committed
155
        self.peer_module = peer_grading_module.PeerGradingModule(self.system, location, "<peergrading/>", self.descriptor)
156
        self.peer_module.peer_gs = self.mock_service
157 158 159 160 161
        self.logout()

    def test_get_next_submission_success(self):
        data = {'location': self.location}

162
        r = self.peer_module.get_next_submission(data)
Vik Paruchuri committed
163
        d = json.loads(r)
164 165 166 167 168 169 170 171
        self.assertTrue(d['success'])
        self.assertIsNotNone(d['submission_id'])
        self.assertIsNotNone(d['prompt'])
        self.assertIsNotNone(d['submission_key'])
        self.assertIsNotNone(d['max_score'])

    def test_get_next_submission_missing_location(self):
        data = {}
172
        d = self.peer_module.get_next_submission(data)
173 174 175 176
        self.assertFalse(d['success'])
        self.assertEqual(d['error'], "Missing required keys: location")

    def test_save_grade_success(self):
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
        data = {
                'rubric_scores[]': [0, 0],
                'location': self.location,
                'submission_id': 1,
                'submission_key': 'fake key',
                'score': 2,
                'feedback': 'feedback',
                'submission_flagged': 'false'
                }

        qdict = MagicMock()
        def fake_get_item(key):
            return data[key]
        qdict.__getitem__.side_effect = fake_get_item
        qdict.getlist = fake_get_item
        qdict.keys = data.keys

194
        r = self.peer_module.save_grade(qdict)
195
        d = json.loads(r)
196 197 198 199
        self.assertTrue(d['success'])

    def test_save_grade_missing_keys(self):
        data = {}
200
        d = self.peer_module.save_grade(data)
201 202 203
        self.assertFalse(d['success'])
        self.assertTrue(d['error'].find('Missing required keys:') > -1)

204
    def test_is_calibrated_success(self):
205
        data = {'location': self.location}
206
        r = self.peer_module.is_student_calibrated(data)
Vik Paruchuri committed
207
        d = json.loads(r)
208 209 210
        self.assertTrue(d['success'])
        self.assertTrue('calibrated' in d)

211 212
    def test_is_calibrated_failure(self):
        data = {}
213
        d = self.peer_module.is_student_calibrated(data)
214 215 216 217 218 219
        self.assertFalse(d['success'])
        self.assertFalse('calibrated' in d)

    def test_show_calibration_essay_success(self):
        data = {'location': self.location}

220
        r = self.peer_module.show_calibration_essay(data)
Vik Paruchuri committed
221
        d = json.loads(r)
222 223
        log.debug(d)
        log.debug(type(d))
224 225 226 227 228 229 230 231 232
        self.assertTrue(d['success'])
        self.assertIsNotNone(d['submission_id'])
        self.assertIsNotNone(d['prompt'])
        self.assertIsNotNone(d['submission_key'])
        self.assertIsNotNone(d['max_score'])

    def test_show_calibration_essay_missing_key(self):
        data = {}

233
        d = self.peer_module.show_calibration_essay(data)
234 235 236 237 238

        self.assertFalse(d['success'])
        self.assertEqual(d['error'], "Missing required keys: location")

    def test_save_calibration_essay_success(self):
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
        data = {
                'rubric_scores[]': [0, 0],
                'location': self.location,
                'submission_id': 1,
                'submission_key': 'fake key',
                'score': 2,
                'feedback': 'feedback',
                'submission_flagged': 'false'
                }

        qdict = MagicMock()
        def fake_get_item(key):
            return data[key]
        qdict.__getitem__.side_effect = fake_get_item
        qdict.getlist = fake_get_item
        qdict.keys = data.keys

        d = self.peer_module.save_calibration_essay(qdict)
257 258 259 260 261
        self.assertTrue(d['success'])
        self.assertTrue('actual_score' in d)

    def test_save_calibration_essay_missing_keys(self):
        data = {}
262
        d = self.peer_module.save_calibration_essay(data)
263 264 265
        self.assertFalse(d['success'])
        self.assertTrue(d['error'].find('Missing required keys:') > -1)
        self.assertFalse('actual_score' in d)