Skip to content

Commit

Permalink
GPII-4218: Modifed to send confirmation receipt to the source request
Browse files Browse the repository at this point in the history
When a browser channel client sends a request to change settings, instead
of silence, they receive a "changeSettingsReceived" message type as a response.
All other clients are sent the "onSettingsChanged" message type, as before.
  • Loading branch information
klown committed Jun 15, 2020
1 parent d598a9f commit 54a04cf
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 34 deletions.
16 changes: 6 additions & 10 deletions gpii/node_modules/flowManager/src/BrowserChannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ gpii.flowManager.browserChannel.sendError = function (request, message) {
* gpii.flowManager.browserChannel.receiveChangeSettingsMsg() listener to
* handle "changeSettings" message types after the connection is established.
* - any subsequent "connect" message types are silently ignored,
* - all other message types cause an error response and the closing of the
* connection. The one exception is the "changeSettings" message type (see
* first point).
* - all other message types cause an error response and close the connection
* The one exception is the "changeSettings" message type (see first point).
* @param {Component} that - An instance of gpii.flowManager.browserChannel.handler.
* @param {Object} message - Object containing the message type and its payload.
* @param {Component} solutionsRegistryDataSource - Used to match the solution
Expand All @@ -59,7 +58,6 @@ gpii.flowManager.browserChannel.sendError = function (request, message) {
* is running on.
*/
gpii.flowManager.browserChannel.receiveMessage = function (that, message, solutionsRegistryDataSource, platformReporter) {
console.log("BC receiveMsg: " + JSON.stringify(message));
if (message.type !== "connect") {
return;
}
Expand All @@ -82,15 +80,13 @@ gpii.flowManager.browserChannel.receiveMessage = function (that, message, soluti
};

/**
* Listener for the "changeSettings" message type. If the message type is not
* "changeSettings", or if the socket connection has not been established,
* the message is ignored and this is a no-op.
* Listener for the "changeSettings" message type. This is added as a listener
* after the connection has been established. That is, this will not function
* without a previous "connect" message type.
* @param {Component} that - An instance of gpii.flowManager.browserChannel.handler.
* @param {Object} message - The "changeSettings" message and a payload of settings
* to modify.
* @param {Object} message - Object containing the message type and its payload.
*/
gpii.flowManager.browserChannel.receiveChangeSettingsMsg = function (that, message) {
console.log("BC receiveChangeSettingsMsg: " + JSON.stringify(message));
if (message.type === "changeSettings" && that.established) {
var wsPayload = {};
wsPayload[that.solutionId] = [{
Expand Down
34 changes: 19 additions & 15 deletions gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,13 @@ gpii.tests.flowManager.browserChannel.checkPersistentSettings = function (client
expectedSettings, gpii.settingsHandlers.webSockets.instance.getSettingsForId(clientId));
};

gpii.tests.flowManager.browserChannel.checkSettingsAfterSet = function (data, clientId, expectedSettings) {
jqUnit.assertDeepEq(
"The persistent settings for " + clientId + " are, after setting them,",
expectedSettings, data
);
gpii.tests.flowManager.browserChannel.checkSettingsAfterSet = function (responses, expectedSettings) {
fluid.each(responses, function (settingsArray, response) {
jqUnit.assertDeepEq(
"The persistent settings for " + response + " are, after setting them,",
expectedSettings, settingsArray[0]
);
});
};

gpii.tests.flowManager.browserChannel.loginAndSettingsChanged = function (multiArg, spec) {
Expand Down Expand Up @@ -163,6 +165,7 @@ fluid.defaults("gpii.tests.flowManager.browserChannel.clientHolder", {
settings: {},
events: {
onSettingsChanged: null,
changeSettingsReceived: null,
connectionSucceeded: null
},
listeners: {
Expand Down Expand Up @@ -323,7 +326,7 @@ gpii.tests.flowManager.browserChannel.testDefs = [{
}]
}, {
name: "Flow Manager BrowserChannel tests",
expect: 31,
expect: 32,
config: {
configName: "gpii.flowManager.tests.browserChannel.config",
configPath: "%flowManager/test/configs"
Expand All @@ -339,6 +342,13 @@ gpii.tests.flowManager.browserChannel.testDefs = [{
gpiiKey: "{loginChromeAndFirefox}.options.gpiiKey",
clientIds: ["org.nvda-project", "org.gnome.orca"]
}]
},
clientOneChangeSettings: {
events: {
"clientOneChangeReceipt": "{clientOne}.events.changeSettingsReceived",
"clientTwoSettingsChanged": "{clientTwo}.events.onSettingsChanged"
},
args: ["{arguments}", "{clientOne}.options.settings"]
}
},
components: {
Expand Down Expand Up @@ -455,19 +465,13 @@ gpii.tests.flowManager.browserChannel.testDefs = [{
}
},
// All three clients now connected - clientOne sends a "changeSettings"
// request. As the source, it won't be notified of the change, but
// clientTwo, having the same ID, will.
// request and gets back a receipt, whereas clientTwo receives the changes.
{
func: "{clientOne}.sendChangeSettings"
},
{
event: "{clientTwo}.events.onSettingsChanged",
listener: "gpii.tests.flowManager.browserChannel.checkSettingsAfterSet",
args: [
"{arguments}.0",
"{clientTwo}.options.solutionId",
gpii.tests.flowManager.browserChannel.nvdaSetSettings
]
event: "{testCaseHolder}.events.clientOneChangeSettings",
listener: "gpii.tests.flowManager.browserChannel.checkSettingsAfterSet"
},
// Disconnect client 1 and try a spurious logout
{
Expand Down
104 changes: 95 additions & 9 deletions gpii/node_modules/settingsHandlers/src/WebSocketsSettingsHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,18 @@ fluid.defaults("gpii.settingsHandlers.webSockets.component", {

///////////////// Clients /////////////////////

/**
* Add a client, a web sockets message handler, to the set of clients that this
* settings handler services. This also:
* - adds a listener to the client so thatit relays "changeSettings" message
* payloads to this settings handler.
* - sends a reply back to the client containing the current settings value for
* that client's solution.
* @param {Component} that - An instance of gpii.settingsHandlers.webSockets.component.
* @param {String} solutionId - The solution that the client handles.
* @param {Component} client - The client request handler to add.
*/
gpii.settingsHandlers.webSockets.addClient = function (that, solutionId, client) {
console.log("CLIENT: " + client.typeName);
client.events.onReceiveMessage.addListener(gpii.flowManager.browserChannel.receiveChangeSettingsMsg);
var initialSettings = fluid.get(that.model.settings, [solutionId]);
var currentValue = fluid.get(that.clients, [solutionId, client.id]);
Expand All @@ -80,6 +90,12 @@ gpii.settingsHandlers.webSockets.addClient = function (that, solutionId, client)
}
};

/**
* Remoove a client, a web sockets message handler, from the set of clients that
* this settings handler services.
* @param {Component} that - An instance of gpii.settingsHandlers.webSockets.component.
* @param {Component} client - The client request handler to remove.
*/
gpii.settingsHandlers.webSockets.removeClient = function (that, client) {
for (var solutionId in that.clients) {
client.events.onReceiveMessage.removeListener(gpii.flowManager.browserChannel.receiveChangeSettingsMsg);
Expand All @@ -92,17 +108,39 @@ gpii.settingsHandlers.webSockets.removeClient = function (that, client) {

///////////////// Settings /////////////////////

/**
* For debugging: log changes to settings.
* @param {Object} change - The modified setting.
*/
gpii.settingsHandlers.webSockets.settingsChanged = function (/*change*/) {
// Function retained for debugging purposes
// Warning: the 'change' argument can be a circular JSON structure;
// Using util.inspect() instead of JSON.stringify()
// console.log("A change in settings has been registered: " + util.inspect(change));
};

/**
* Get the current settings associated with the given solution persisted by this
* settings handler.
* @param {Component} that - An instance of gpii.settingsHandlers.webSockets.component.
* @param {String} solutionId - The solution whose setting are sought.
* @return {Object} - The current values of the settings for the solution.
*/
gpii.settingsHandlers.webSockets.getSettingsForId = function (that, solutionId) {
return fluid.get(that.model.settings, [solutionId]);
};

/**
* Get the current value of specified settings associated with the given
* solution.
* @param {Object} payload - The solution and its setting whose current values
* are to be retrieved.
* @param {String} payload.options.path - The relevant solution.
* @param {Object} payload.settings - The settings whose current values are
* sought.
* @param {Component} that - An instance of gpii.settingsHandlers.webSockets.component.
* @return {Object} - the current values of the settings passed in.
*/
gpii.settingsHandlers.webSockets.getImpl = function (payload, that) {
var path = payload.options.path;
var results = fluid.transform(payload.settings, function (value, key) {
Expand All @@ -112,6 +150,21 @@ gpii.settingsHandlers.webSockets.getImpl = function (payload, that) {
return results;
};

/**
* Modify the persistent settings based on the values passed in, and notify
* relevant clients of the changes.
* @param {Object} payload - Information about which settings to modify.
* @param {Object} payload.settings - The new values of the settings.
* @param {String} payload.options.path - Solution id whose setting are to change.
* @param {String} payload.options.source - The client requesting the changes.
* This client will not be notified of
* any changes. Other clients, who
* support the same solution, will.
* @param {Component} that - An instance of gpii.settingsHandlers.webSockets.component.
* @param {String} solutionId - The solution whose setting are sought.
* @return {Object} - a set of old value, new value pairs showing the changes
* for each setting.
*/
gpii.settingsHandlers.webSockets.setImpl = function (payload, that) {
var path = payload.options.path;
var results = fluid.transform(payload.settings, function (value, key) {
Expand Down Expand Up @@ -141,29 +194,62 @@ gpii.settingsHandlers.webSockets.setImpl = function (payload, that) {
}

gpii.settingsHandlers.webSockets.notifySettings(payload.options, that);

return results;
};

/**
* Notify relevant clients about changes to their solution's settings with
* either a "onSettingsChanged" or "changeSettingsReceived" message type. The
* client that requested the changes is sent the "changeSettingsReceived"
* response. All others are notified of the changes ("onSettingsChanged").
* @param {Object} clientOptions - Information about which solutions and clients
* to notify.
* @param {String} clientOptions.path - The relevant solution id.
* @param {Component} clientOptions.source - The client who requested the
* changes.
* @param {Component} that - An instance of gpii.settingsHandlers.webSockets.component.
* managing clients and their solution's settings.
*/
gpii.settingsHandlers.webSockets.notifySettings = function (clientOptions, that) {
var id = clientOptions.path;
if (id in that.clients) {
var newSettings = gpii.settingsHandlers.webSockets.getSettingsForId(that, id);
for (var client in that.clients[id]) {
if (client !== clientOptions.source) {
that.clients[id][client].sendTypedMessage("onSettingsChanged", newSettings);
var solutionId = clientOptions.path;
if (solutionId in that.clients) {
var newSettings = gpii.settingsHandlers.webSockets.getSettingsForId(that, solutionId);
for (var clientId in that.clients[solutionId]) {
var client = that.clients[solutionId][clientId];
if (client === clientOptions.source) {
client.sendTypedMessage("changeSettingsReceived", newSettings);
} else {
client.sendTypedMessage("onSettingsChanged", newSettings);
}
}
}
};

// Top-level driver methods for SettingsHandler
/////////// Top-level driver methods for SettingsHandler ///////////////

/**
* Retrieve a solution's settings based on the given information.
* @param {Object} payload - The solution's settings to retreive.
* @param {String} payload.options.path - Solution identifier.
* @param {Object} payload.settings - The settings whose current values are
* sought.
* @return {Promise} - A promise whose value, when resolved, is the settings.
*/
gpii.settingsHandlers.webSockets.get = function (payload) {
var instance = gpii.settingsHandlers.webSockets.instance; // this is placed there by FlowManager's mountInstance
return gpii.settingsHandlers.invokeSettingsHandler(instance.getImpl, payload);
};

/**
* Modify a solution's settings based on the given information.
* @param {Object} payload - Array of solutions, their clients and settings to
* modify.
* @param {Component} payload.solutionId[i] - The client requesting the change.
* @param {Object} payload.solutionId[i].settings - The new values for the settings.
* @param {String} payload.solutionId[i].options.path - Solution identifier.
* @param {Component} payload.solutionId[i].options.source - The client requesting the change.
* @return {Promise} - A promise whose value, when resolved, is the modified settings.
*/
gpii.settingsHandlers.webSockets.set = function (payload) {
var instance = gpii.settingsHandlers.webSockets.instance; // this is placed there by FlowManager's mountInstance
return gpii.settingsHandlers.invokeSettingsHandler(instance.setImpl, payload);
Expand Down

0 comments on commit 54a04cf

Please sign in to comment.