Commit bfd87488 by Jason Bau

Send student email to xqueue with coderesponse (lms setting controls)

Conflicts:
	lms/envs/common.py
parent c79d621d
......@@ -1473,6 +1473,9 @@ class CodeResponse(LoncapaResponse):
'anonymous_student_id': anonymous_student_id,
'submission_time': qtime,
}
if getattr(self.system, 'send_users_emailaddr_with_coderesponse', False):
student_info.update({'student_email': self.system.deanonymized_user_email})
contents.update({'student_info': json.dumps(student_info)})
# Submit request. When successful, 'msg' is the prior length of the
......
......@@ -11,6 +11,7 @@ import unittest
import textwrap
import requests
import mock
import itertools
from . import new_loncapa_problem, test_system
import calc
......@@ -722,6 +723,30 @@ class CodeResponseTest(ResponseTest):
self.assertEquals(answers_converted['1_3_1'], ['answer1', 'answer2', 'answer3'])
self.assertEquals(answers_converted['1_4_1'], [fp.name, fp.name])
def test_send_email_address(self):
'''
Tests that when appropriate settings are passed in via LMS courseware, the coderesonse request
sends the student's deanonymized email address.
@return:
'''
TEST_EMAIL = 'student@edx.org' # pylint: disable=C0103
TEST_STUDENT_RESP = 'Lorem Ipsum' # pylint: disable=C0103
answer_ids = self.problem.get_question_answers().keys()
student_ans = {}
for ans_id in answer_ids:
student_ans[ans_id] = TEST_STUDENT_RESP
self.problem.system.send_users_emailaddr_with_coderesponse = True
self.problem.system.deanonymized_user_email = TEST_EMAIL
mock_qinterface = mock.Mock()
# side_effect needed b/c get_score destructures the return value of send_to_queue
mock_send_to_queue = mock.Mock(side_effect=itertools.repeat((False, "OK")))
mock_qinterface.send_to_queue = mock_send_to_queue
self.problem.system.xqueue['interface'] = mock_qinterface
self.problem.grade_answers(student_ans)
# From docstring of send_to_queue: "The operation of xqueue is agnostic to the contents of (argument) 'body'"
(_, kwargs) = mock_send_to_queue.call_args
self.assertIn(TEST_EMAIL, kwargs['body'])
self.assertIn(TEST_STUDENT_RESP, kwargs['body'])
class ChoiceResponseTest(ResponseTest):
from capa.tests.response_xml_factory import ChoiceResponseXMLFactory
......
......@@ -377,6 +377,9 @@ def get_module_for_descriptor_internal(user, descriptor, field_data_cache, cours
# TODO: When we merge the descriptor and module systems, we can stop reaching into the mixologist (cpennington)
mixins=descriptor.system.mixologist._mixins,
)
if settings.MITX_FEATURES.get('SEND_USERS_EMAILADDR_WITH_CODERESPONSE', False):
system.set('send_users_emailaddr_with_coderesponse', True)
system.set('deanonymized_user_email', user.email)
# pass position specified in URL to module through ModuleSystem
system.set('position', position)
......
......@@ -80,6 +80,54 @@ class ModuleRenderTestCase(ModuleStoreTestCase, LoginEnrollmentTestCase):
# note if the URL mapping changes then this assertion will break
self.assertIn('/courses/' + self.course_id + '/jump_to_id/vertical_test', html)
FEATURES_WITH_EMAIL = settings.MITX_FEATURES.copy()
FEATURES_WITH_EMAIL['SEND_USERS_EMAILADDR_WITH_CODERESPONSE'] = True
@override_settings(MITX_FEATURES=FEATURES_WITH_EMAIL)
def test_module_populated_with_user_email(self):
"""
This tests that the module's system knows about the user's email when the appropriate flag is
set in LMS settings
"""
mock_request = MagicMock()
mock_request.user = self.mock_user
course = get_course_with_access(self.mock_user, self.course_id, 'load')
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
self.course_id, self.mock_user, course, depth=2)
module = render.get_module(
self.mock_user,
mock_request,
['i4x', 'edX', 'toy', 'html', 'toyjumpto'],
field_data_cache,
self.course_id
)
self.assertTrue(module.system.send_users_emailaddr_with_coderesponse)
self.assertEqual(module.system.deanonymized_user_email, self.mock_user.email)
def test_module_not_populated_with_user_email(self):
"""
This tests that the module's system DOES NOT know about the user's email when the appropriate flag is NOT
set in LMS settings, which is the default
"""
mock_request = MagicMock()
mock_request.user = self.mock_user
course = get_course_with_access(self.mock_user, self.course_id, 'load')
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
self.course_id, self.mock_user, course, depth=2)
module = render.get_module(
self.mock_user,
mock_request,
['i4x', 'edX', 'toy', 'html', 'toyjumpto'],
field_data_cache,
self.course_id
)
self.assertFalse(hasattr(module.system, 'send_users_emailaddr_with_coderesponse'))
self.assertFalse(hasattr(module.system, 'deanonymized_user_email'))
def test_modx_dispatch(self):
self.assertRaises(Http404, render.modx_dispatch, 'dummy', 'dummy',
'invalid Location', 'dummy')
......
......@@ -174,7 +174,11 @@ MITX_FEATURES = {
'STORE_BILLING_INFO': False,
#Toggle using CME registration instead of normal
'USE_CME_REGISTRATION': False
'USE_CME_REGISTRATION': False,
# Sends the user's deanonymized email address to xqueue with code responses
# DO NOT SET if you don't want the anonymous user id to be linked with user.email in xqueue (Stanford does)
'SEND_USERS_EMAILADDR_WITH_CODERESPONSE': False,
}
# Used for A/B testing
......
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