Commit 633fb7dd by Diana Huang Committed by Andy Armstrong

Add new eventing helpers.

parent dc92457d
......@@ -922,6 +922,26 @@ class OpenAssessmentBlock(
event_data
)
@XBlock.json_handler
def publish_event(self, data, suffix=''):
"""
Publish the given data to an event.
Expects key 'event_name' to be present in the data dictionary.
"""
try:
event_name = data['event_name']
except KeyError:
logger.exception("Could not find the name of the event to be triggered.")
return {'success': False}
# Remove the name so we don't publish as part of the data.
del data['event_name']
self.runtime.publish(self, event_name, data)
return {'success': True}
def _serialize_opaque_key(self, key):
"""
Gracefully handle opaque keys, both before and after the transition.
......@@ -955,4 +975,3 @@ class OpenAssessmentBlock(
return effective
return start
......@@ -312,6 +312,18 @@ describe("OpenAssessment.Server", function() {
});
});
it("verifies that publishing an event submits the correct data to the backend", function() {
stubAjax(true, {success: true});
server.publishEvent('test_event_name', {'key': 'test_data'});
expect($.ajax).toHaveBeenCalledWith({
url: '/publish_event',
type: 'POST',
data: JSON.stringify({'key': 'test_data', 'event_name': 'test_event_name'}),
contentType: jsonContentType
});
});
it("informs the caller of an Ajax error when rendering as HTML", function() {
stubAjax(false, null);
......
......@@ -549,6 +549,21 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
defer.rejectWith(this, [gettext('The submission could not be removed from the grading pool.')]);
});
}).promise();
},
/**
* Submit an event to the runtime for publishing.
*
* @param {object} eventName - the name of the event
* @param {object} eventData - additional context data for the event
*/
publishEvent: function(eventName, eventData) {
eventData.event_name = eventName;
var url = this.url('publish_event');
var payload = JSON.stringify(eventData);
$.ajax({
type: "POST", url: url, data: payload, contentType: jsonContentType
});
}
};
}
......@@ -129,6 +129,8 @@ class XBlockHandlerTestCaseMixin(object):
"""
super(XBlockHandlerTestCaseMixin, self).setUp()
self.runtime = WorkbenchRuntime()
mock_publish = mock.MagicMock(side_effect=self.runtime.publish)
self.runtime.publish=mock_publish
def set_user(self, user_id):
"""
......@@ -198,6 +200,61 @@ class XBlockHandlerTestCaseMixin(object):
else:
raise NotImplementedError("Response format '{format}' not supported".format(response_format))
def assert_assessment_event_published(self, xblock, event_name, assessment, **kwargs):
parts_list = []
for part in assessment["parts"]:
# Some assessment parts do not include point values,
# only written feedback. In this case, the assessment
# part won't have an associated option.
option_dict = None
if part["option"] is not None:
option_dict = {
"name": part["option"]["name"],
"points": part["option"]["points"],
}
# All assessment parts are associated with criteria
criterion_dict = {
"name": part["criterion"]["name"],
"points_possible": part["criterion"]["points_possible"]
}
parts_list.append({
"option": option_dict,
"criterion": criterion_dict,
"feedback": part["feedback"]
})
event_data = {
"feedback": assessment["feedback"],
"rubric": {
"content_hash": assessment["rubric"]["content_hash"],
},
"scorer_id": assessment["scorer_id"],
"score_type": assessment["score_type"],
"scored_at": assessment["scored_at"],
"submission_uuid": assessment["submission_uuid"],
"parts": parts_list
}
for key in kwargs:
event_data[key] = kwargs[key]
self.assert_event_published(
xblock, event_name, event_data
)
def assert_event_published(self, xblock, event_name, event_data):
"""
Assert that an event was emitted with the given parameters.
Args:
event_name(str): The name of the event emitted
event_data(dict): A dictionary containing the data we expect to have publish
"""
self.runtime.publish.assert_any_call(
xblock, event_name, event_data
)
@staticmethod
def load_fixture_str(path):
"""
......
......@@ -160,6 +160,8 @@ class TestStaffAssessment(StaffAssessmentTestBase):
self.assertEqual(assessment['points_earned'], score['points_earned'])
self.assertEqual(assessment['points_possible'], score['points_possible'])
self.assert_assessment_event_published(xblock, 'openassessmentblock.staff_assess', assessment, type='full-grade')
@scenario('data/self_assessment_scenario.xml', user_id='Bob')
def test_permission_error(self, xblock):
# Create a submission for the student
......
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