Files
edx-platform/lms/djangoapps/grades/tests/test_signals.py
Eric Fischer 6a47311479 Update Persisted Course Grade on Subsection Grade update
Makes use of the new SUBSECTION_SCORE_CHANGED signal to trigger a task that
updates persisted course grade values. We've also renamed SCORE_CHANGED to
PROBLEM_SCORE_CHANGED to head off any issues with unclear signal names.

TNL-5740
2016-10-25 14:47:31 -04:00

120 lines
4.0 KiB
Python

"""
Tests for the score change signals defined in the courseware models module.
"""
import ddt
from django.test import TestCase
from mock import patch, MagicMock
from ..signals.handlers import (
submissions_score_set_handler,
submissions_score_reset_handler,
)
SUBMISSION_SET_KWARGS = {
'points_possible': 10,
'points_earned': 5,
'anonymous_user_id': 'anonymous_id',
'course_id': 'CourseID',
'item_id': 'i4x://org/course/usage/123456'
}
SUBMISSION_RESET_KWARGS = {
'anonymous_user_id': 'anonymous_id',
'course_id': 'CourseID',
'item_id': 'i4x://org/course/usage/123456'
}
@ddt.ddt
class SubmissionSignalRelayTest(TestCase):
"""
Tests to ensure that the courseware module correctly catches score_set and
score_reset signals from the Submissions API and recasts them as LMS
signals. This ensures that listeners in the LMS only have to handle one type
of signal for all scoring events.
"""
def setUp(self):
"""
Configure mocks for all the dependencies of the render method
"""
super(SubmissionSignalRelayTest, self).setUp()
self.signal_mock = self.setup_patch('lms.djangoapps.grades.signals.signals.PROBLEM_SCORE_CHANGED.send', None)
self.user_mock = MagicMock()
self.user_mock.id = 42
self.get_user_mock = self.setup_patch(
'lms.djangoapps.grades.signals.handlers.user_by_anonymous_id',
self.user_mock
)
def setup_patch(self, function_name, return_value):
"""
Patch a function with a given return value, and return the mock
"""
mock = MagicMock(return_value=return_value)
new_patch = patch(function_name, new=mock)
new_patch.start()
self.addCleanup(new_patch.stop)
return mock
@ddt.data(
[submissions_score_set_handler, SUBMISSION_SET_KWARGS, 5, 10],
[submissions_score_reset_handler, SUBMISSION_RESET_KWARGS, 0, 0],
)
@ddt.unpack
def test_score_set_signal_handler(self, handler, kwargs, earned, possible):
"""
Ensure that on receipt of a score_(re)set signal from the Submissions API,
the signal handler correctly converts it to a PROBLEM_SCORE_CHANGED signal.
Also ensures that the handler calls user_by_anonymous_id correctly.
"""
handler(None, **kwargs)
expected_set_kwargs = {
'sender': None,
'points_possible': possible,
'points_earned': earned,
'user_id': self.user_mock.id,
'course_id': 'CourseID',
'usage_id': 'i4x://org/course/usage/123456'
}
self.signal_mock.assert_called_once_with(**expected_set_kwargs)
self.get_user_mock.assert_called_once_with(kwargs['anonymous_user_id'])
@ddt.data(
[submissions_score_set_handler, SUBMISSION_SET_KWARGS],
[submissions_score_reset_handler, SUBMISSION_RESET_KWARGS]
)
@ddt.unpack
def test_score_set_missing_kwarg(self, handler, kwargs):
"""
Ensure that, on receipt of a score_(re)set signal from the Submissions API
that does not have the correct kwargs, the courseware model does not
generate a signal.
"""
for missing in kwargs:
local_kwargs = kwargs.copy()
del local_kwargs[missing]
with self.assertRaises(KeyError):
handler(None, **local_kwargs)
self.signal_mock.assert_not_called()
@ddt.data(
[submissions_score_set_handler, SUBMISSION_SET_KWARGS],
[submissions_score_reset_handler, SUBMISSION_RESET_KWARGS]
)
@ddt.unpack
def test_score_set_bad_user(self, handler, kwargs):
"""
Ensure that, on receipt of a score_(re)set signal from the Submissions API
that has an invalid user ID, the courseware model does not generate a
signal.
"""
self.get_user_mock = self.setup_patch('lms.djangoapps.grades.signals.handlers.user_by_anonymous_id', None)
handler(None, **kwargs)
self.signal_mock.assert_not_called()