gpii-universal
Version:
Cross platform, core components of the GPII personalization infrastructure.
119 lines (104 loc) • 6.35 kB
JavaScript
/*!
GPII Exploding Settings Handler
Copyright 2018 Raising the Floor - International
Licensed under the New BSD license. You may not use this file except in
compliance with this License.
You may obtain a copy of the License at
https://github.com/gpii/universal/LICENSE.txt
*/
;
var fluid = require("infusion"),
gpii = fluid.registerNamespace("gpii");
fluid.registerNamespace("gpii.settingsHandlers.exploding");
/** The exploding settings handler is used in both automated and manual tests in order to verify that errors which occur
* when reading or writing system settings are appropriately signalled to the user. To aid in doing this, it accepts
* various material in its settings payload encoding the method to be used when failing, and special preference sets
* have been drawn up to be used in manual testing which make use of these payloads
*/
/**
* The payload type sent to some exploding settings handler methods.
* @typedef {Object} {ExplodingPayload}
* @property {String} operation - Either "get" or "set" depending on which settings handler method was requested
* @property {String} explodeOn - Either "get" or "set" depending on which settings handler method was required to explode
* @property {Object} errorPayload - [optional] An error payload (with member `isError: true`) which should be sent to either the
* "reject" or "throw" operations if either of these was requested in `explodeMethod`
* @property {String} explodeMethod - Either:
* "reject", if the explosion should be signalled via returning a rejected promise
* "fail", if the explosion should be signalled via calling `fluid.fail`
* "throw", if the explosion should be signalled by throwing a bare execption
*/
/** The implementation for the exploding settings handler.
* @param {String} operation - Either "get" or "set"
* @param {ExplodingPayload} explodeSettings - Settings payload describing whether the settings handler should explode
* @return {Promise|None} A rejected promise if the operation should explode and the payload requested that it should do so by returning a rejected promise
*/
gpii.settingsHandlers.exploding.explode = function (operation, explodeSettings) {
var errorMessage = "Exploding settings handler has failed on " + operation + " method";
var errorPayload = explodeSettings.errorPayload || {
isError: true,
message: errorMessage
};
if (explodeSettings.explodeMethod === "reject") {
return fluid.promise().reject(errorPayload);
} else if (explodeSettings.explodeMethod === "fail") {
fluid.fail(errorMessage);
} else if (explodeSettings.explodeMethod === "throw") {
throw new Error(errorMessage);
}
};
/** Global store for mock solution running state **/
gpii.settingsHandlers.exploding.runningState = {
running: false
};
/** Return an explosion or settings, depending on whether the operation in progress matches the one designated to explode
* @param {String} operation - Either "get", "set", "launch" or "stop"
* @param {ExplodingPayload} explodeSettings - Settings payload describing whether the settings handler should explode
* @param {Object} settings - Settings handler options which may include a member
* {Boolean} options.launchHandler Set to `true` if this settings handler is being invoked as a launch handler
* {Object} options.preferences The user's entire preference set (for tunnelling launch settings)
* @return {Promise|Value} A rejected promise if an error should have been signalled, and should have been signalled by that method, or otherwise the
* appropriate get/set settingsHandler payload.
*/
gpii.settingsHandlers.exploding.determineExplode = function (operation, explodeSettings, settings) {
if (explodeSettings.explodeOn === operation) {
return gpii.settingsHandlers.exploding.explode(operation, explodeSettings);
} else {
if (operation === "get") {
return "running" in settings ? gpii.settingsHandlers.exploding.runningState : settings;
} else {
return "running" in settings ? {running: {newValue: settings.running, oldValue: !settings.running}} :
fluid.transform(settings, function (value) {
return {newValue: value};
});
}
}
};
/** Core implementation of the exploding settings handler.
* @param {String} operation - Either "get" or "set"
* @param {ExplodingPayload|Object} settings - Settings payload describing whether the settings handler should explode, or standard settings payload
* @param {Object} options - Settings handler options which may include a member
* {Boolean} options.launchHandler Set to `true` if this settings handler is being invoked as a launch handler
* {Object} options.preferences The user's entire preference set (for tunnelling launch settings)
* @return {Promise|Value} A rejected promise if an error should have been signalled, and should have been signalled by that method, or the
* original input payload if no error should be signalled.
*/
// In the case of "launch"/"stop" interception we use hard-coded knowledge of the exact structure of the preference set as
// being explodeLaunchHandlerXxxxx.json
gpii.settingsHandlers.exploding.impl = function (operation, settings, options) {
if (options && options.launchHandler && operation === "set") {
gpii.settingsHandlers.exploding.runningState.running = settings.running;
var launchOperation = settings.running ? "launch" : "stop";
var launchSettings = fluid.get(options, ["preferences", "contexts", "gpii-default", "preferences", "http://registry.gpii.net/applications/net.gpii.explode"]);
return gpii.settingsHandlers.exploding.determineExplode(launchOperation, launchSettings, settings);
} else {
return gpii.settingsHandlers.exploding.determineExplode(operation, settings, settings);
}
};
// Top-level driver methods for SettingsHandler
["get", "set"].forEach(function (operation) {
gpii.settingsHandlers.exploding[operation] = function (payload) {
return gpii.settingsHandlers.invokeSettingsHandler(function (payload) {
return gpii.settingsHandlers.exploding.impl(operation, payload.settings, payload.options);
}, payload);
};
});