diff --git a/resources/static/dialog/controllers/actions.js b/resources/static/dialog/controllers/actions.js index 7328e21fea8dcbebbbf803030bc3eb3f8b05e543..e01cb576cc4b51a08526164834a982a55081b62b 100644 --- a/resources/static/dialog/controllers/actions.js +++ b/resources/static/dialog/controllers/actions.js @@ -11,6 +11,7 @@ BrowserID.Modules.Actions = (function() { serviceManager = bid.module, user = bid.User, errors = bid.Errors, + mediator = bid.Mediator, dialogHelpers = bid.Helpers.Dialog, runningService, onsuccess, @@ -26,6 +27,7 @@ BrowserID.Modules.Actions = (function() { runningService = name; } + mediator.publish("service", { name: name }); bid.resize(); return module; diff --git a/resources/static/dialog/controllers/pick_email.js b/resources/static/dialog/controllers/pick_email.js index 61e65c469480a0f29a03415f979895d3506b5abf..4382645c75ce2777cfb4008e5e50d40cb2e5bebf 100644 --- a/resources/static/dialog/controllers/pick_email.js +++ b/resources/static/dialog/controllers/pick_email.js @@ -89,8 +89,12 @@ BrowserID.Modules.PickEmail = (function() { dom.addClass("body", "pickemail"); + var identities = getSortedIdentities(); + + self.publish("emails_displayed", { count: identities.length }); + self.renderDialog("pick_email", { - identities: getSortedIdentities(), + identities: identities, siteemail: storage.site.get(origin, "email"), privacy_url: options.privacyURL, tos_url: options.tosURL diff --git a/resources/static/lib/hub.js b/resources/static/lib/hub.js index 8da4476cb5ff89f30bac25e01a5b004868737aa9..f1be782aed42655546b7035ef3abc39aa24cc2af 100644 --- a/resources/static/lib/hub.js +++ b/resources/static/lib/hub.js @@ -34,6 +34,11 @@ Hub = (function() { } function fire(message) { + for(var j = 0, glistener; glistener = globalListeners[j]; ++j) { + // global listeners get the message name as the first argument + glistener.callback.apply(null, arguments); + } + var messageListeners = listeners[message]; if(messageListeners) { @@ -45,11 +50,6 @@ Hub = (function() { listener.callback.apply(null, arguments); } } - - for(var j = 0, glistener; glistener = globalListeners[j]; ++j) { - // global listeners get the message name as the first argument - glistener.callback.apply(null, arguments); - } } function off(id) { diff --git a/resources/static/shared/modules/interaction_data.js b/resources/static/shared/modules/interaction_data.js index 0ef57fd67381c5180d8e61a0734124032d6bf1bd..f9de4013f329732d62db7fe36bfe7c5423408999 100644 --- a/resources/static/shared/modules/interaction_data.js +++ b/resources/static/shared/modules/interaction_data.js @@ -30,6 +30,43 @@ BrowserID.Modules.InteractionData = (function() { dom = bid.DOM, sc; + /** + * This is a translation table from a message on the mediator to a KPI name. + * Names can be modified or added to the KPI storage directly. + * A name can be translated by using either a string or a function. + * + * value side contains - purpose + * null - no translation, use mediator name for KPI name. + * string - translate from mediator name to string. + * function - function takes two arguments, msg and data. These come + * directly from the mediator. Function returns a value. If no value is + * returned, field will not be saved to KPI data set. + */ + var MediatorToKPINameTable = { + service: function(msg, data) { return "screen." + data.name; }, + cancel_state: "screen.cancel", + primary_user_authenticating: "window.redirect_to_primary", + window_unload: "window.unload", + generate_assertion: null, + assertion_generated: null, + emails_displayed: function(msg, data) { return "user.email_count:" + data.count; }, + user_staged: "user.user_staged", + user_confirmed: "user.user_confirmed", + email_staged: "user.email_staged", + email_confirmed: "user.email_confrimed", + notme: "user.logout", + }; + + function getKPIName(msg, data) { + var self=this, + kpiInfo = self.mediatorToKPINameTable[msg]; + + var type = typeof kpiInfo; + if(kpiInfo === null) return msg; + if(type === "string") return kpiInfo; + if(type === "function") return kpiInfo(msg, data); + } + function onSessionContext(msg, result) { var self=this; @@ -101,10 +138,13 @@ BrowserID.Modules.InteractionData = (function() { } - function addEvent(eventName) { + function addEvent(msg, data) { var self=this; if (self.samplingEnabled === false) return; + var eventName = getKPIName.call(self, msg, data); + if (!eventName) return; + var eventData = [ eventName, new Date() - self.startTime ]; if (self.samplesBeingStored) { var d = model.getCurrent() || {}; @@ -142,6 +182,7 @@ BrowserID.Modules.InteractionData = (function() { options = options || {}; var self = this; + self.mediatorToKPINameTable = MediatorToKPINameTable; // options.samplingEnabled is used for testing purposes. // @@ -198,6 +239,13 @@ BrowserID.Modules.InteractionData = (function() { getCurrent: getCurrent, getCurrentEventStream: getCurrentEventStream, publishStored: publishStored + + // BEGIN TEST API + , + setNameTable: function(table) { + this.mediatorToKPINameTable = table; + } + // END TEST API }); sc = Module.sc; diff --git a/resources/static/test/cases/controllers/pick_email.js b/resources/static/test/cases/controllers/pick_email.js index 555d2f4631c63ae0c9949339feab0e389c180e2c..a4419af1df70e98e88503b7fd9d61b0529b4c87b 100644 --- a/resources/static/test/cases/controllers/pick_email.js +++ b/resources/static/test/cases/controllers/pick_email.js @@ -37,11 +37,16 @@ controller.start({}); } - test("multiple emails - print emails in alphabetical order", function() { + asyncTest("multiple emails - print emails in alphabetical order, emails_displayed triggered", function() { storage.addEmail("third@testuser.com", {}); storage.addEmail("second@testuser.com", {}); storage.addEmail("first@testuser.com", {}); + register("emails_displayed", function(msg, data) { + equal(data.count, 3, "emails_displayed triggered with correct email count"); + start(); + }); + createController(); var inputs = $(".inputs input[type=radio]"); diff --git a/resources/static/test/cases/shared/modules/interaction_data.js b/resources/static/test/cases/shared/modules/interaction_data.js index c3daf5632d88f963af41f9332389fb3a8f710986..f2b6b675d0ae32888178c1e63639f8f270c3e7dd 100644 --- a/resources/static/test/cases/shared/modules/interaction_data.js +++ b/resources/static/test/cases/shared/modules/interaction_data.js @@ -26,10 +26,29 @@ } }); - function createController(config) { + function createController(setKPINameTable, config) { + if (typeof setKPINameTable !== "boolean") { + config = setKPINameTable; + setKPINameTable = false; + } + config = _.extend({ samplingEnabled: true }, config); controller = BrowserID.Modules.InteractionData.create(); controller.start(config); + + controller.setNameTable({ + before_session_context: null, + after_session_context: null, + session1_before_session_context: null, + session1_after_session_context: null, + session2_before_session_context: null, + session2_after_session_context: null, + initial_string_name: "translated_name", + initial_function_name: function(msg, data) { + return "function_translation." + msg; + } + }); + } function indexOfEvent(eventStream, eventName) { @@ -68,12 +87,23 @@ testHelpers.testKeysInObject(data, ["event_stream", "sample_rate", "timestamp", "lang"]); controller.addEvent("after_session_context"); + controller.addEvent("after_session_context"); + + // The next two are translated from mediator names to names usable by the + // KPI backend. + + // translated to "translated_name" + controller.addEvent("initial_string_name"); + // translated to "function_translation.initial_function_name" + controller.addEvent("initial_function_name"); events = controller.getCurrentEventStream(); // Make sure both the before_session_context and after_session_context // are both on the event stream. ok(indexOfEvent(events, "before_session_context") > -1, "before_session_context correctly saved to current event stream"); ok(indexOfEvent(events, "after_session_context") > -1, "after_session_context correctly saved to current event stream"); + ok(indexOfEvent(events, "translated_name") > -1, "string translation - translated_name correctly saved to current event stream"); + ok(indexOfEvent(events, "function_translation.initial_function_name") > -1, "function translation - function_translation.initial_function_name correctly saved to current event stream"); // Ensure that the event name as well as relative time are saved for an