gpii-universal
Version:
Cross platform, core components of the GPII personalization infrastructure.
170 lines (141 loc) • 7.92 kB
JavaScript
;
var fluid = require("infusion");
var gpii = fluid.registerNamespace("gpii");
var jqUnit = require("node-jqunit");
require("json5/lib/register");
var fs = require("fs");
var path = require("path");
require("../src/js/sr-validation-middleware");
jqUnit.module("Sanity checks for test settings payloads.");
fluid.registerNamespace("gpii.tests.universal.solutionsRegistry.settingsPayloads");
gpii.tests.universal.solutionsRegistry.settingsPayloads.validateSettingsDir = function (that, validationMiddleware, globalValidator) {
jqUnit.asyncTest("Validating preferences test data.", function () {
var validationTimesByFile = {};
var promises = [];
fluid.each(that.options.settingsDataPaths, function (settingsDataPath) {
var resolvedPath = fluid.module.resolvePath(settingsDataPath);
var pathFiles = fs.readdirSync(resolvedPath);
var jsonFiles = pathFiles.filter(function (singlePath) { return singlePath.match(/.json5?$/i); });
fluid.each(jsonFiles, function (jsonFile) {
promises.push(function () {
// Clear the cache before each run to ensure that previous runs don't skew the "uncached" results.
globalValidator.clearCache();
fluid.set(validationTimesByFile, [jsonFile, "startUncached"], Date.now());
});
// Uncached pass
var settingsFilePath = path.resolve(resolvedPath, jsonFile);
var promiseFn = gpii.tests.universal.solutionsRegistry.settingsPayloads.validateSettingsFile(that, settingsFilePath, validationMiddleware);
promises.push(promiseFn);
promises.push(function () {
fluid.set(validationTimesByFile, [jsonFile, "endUncached"], Date.now());
});
// Cached pass
var cachedPromiseFn = gpii.tests.universal.solutionsRegistry.settingsPayloads.validateSettingsFile(that, settingsFilePath, validationMiddleware);
promises.push(cachedPromiseFn);
promises.push(function () {
fluid.set(validationTimesByFile, [jsonFile, "endCached"], Date.now());
});
// Check for settings not found in the "codex", i.e. that aren't in any solution registry or a common term.
var rogueSettingsPromiseFn = gpii.tests.universal.solutionsRegistry.settingsPayloads.findRogueSettings(that.options.codex, settingsFilePath);
promises.push(rogueSettingsPromiseFn);
});
});
fluid.promise.sequence(promises).then(
function () {
jqUnit.start();
jqUnit.assert("All test preference files are valid.");
// console.log("Filename, Uncached, Cached");
fluid.each(validationTimesByFile, function (validationTimes, filename) {
var uncachedTime = validationTimes.endUncached - validationTimes.startUncached;
jqUnit.assertTrue("The uncached validation time for file '" + filename + "' (" + uncachedTime + "ms) should be reasonable (< 2000ms).", uncachedTime < 2000);
var cachedTime = validationTimes.endCached - validationTimes.endUncached;
jqUnit.assertTrue("The cached validation time for file '" + filename + "' (" + cachedTime + "ms) should be reasonable (< 100ms).", cachedTime < 100);
// console.log([path.basename(filename, ".json5"), uncachedTime, cachedTime].join(", "));
});
},
function () {
jqUnit.start();
jqUnit.fail("All test preference files could not be validated.");
}
);
});
};
// Catch invalid test data that can't be detected by our "per solution" validation middleware.
gpii.tests.universal.solutionsRegistry.settingsPayloads.findRogueSettings = function (codex, settingsFilePath) {
var settingsData = require(settingsFilePath);
var rogueSettingsCount = 0;
// There are files that have purely test data mixed in with others, so we exclude them invidually.
var isTestData = false;
fluid.each(["testUser1.json5", "giant.json5"], function (toExclude) {
if (settingsFilePath.endsWith(toExclude)) {
isTestData = true;
}
});
if (isTestData) { return; }
var prefsToCheck = fluid.get(settingsData, ["flat", "contexts", "gpii-default", "preferences"]);
fluid.each(prefsToCheck, function (prefsPayload, prefKey) {
var keyToCheck = prefKey;
if (prefKey.startsWith("http://registry.gpii.net/applications/") && prefKey.endsWith("enabled")) {
keyToCheck = prefKey.replace(/\/enabled$/, "");
}
// We have to use the array notation for fluid.get to avoid interpreting the dots in the URI as path segments.
if (fluid.get(codex, [keyToCheck]) === undefined) {
fluid.log("Setting '" + prefKey + "' in file '" + settingsFilePath + " is not associated with a known solution or common term.");
rogueSettingsCount++;
}
});
jqUnit.assertEquals("There should be no 'rogue' settings in file '" + settingsFilePath + "'.", 0, rogueSettingsCount);
};
gpii.tests.universal.solutionsRegistry.settingsPayloads.validateSettingsFile = function (that, settingsFilePath, validationMiddleware) {
return function () {
var settingsData = {};
try {
settingsData = require(settingsFilePath);
}
catch (error) {
jqUnit.fail("There should not be any invalid settings files (failed checking '" + settingsFilePath + "'.");
fluid.log(error);
}
// Validate each file using the new "per solution" settings validation middleware.
var requestData = { body: settingsData };
var validationPromise = validationMiddleware.handle({ req: requestData});
validationPromise.then(
function () {
jqUnit.assert("Settings file '" + settingsFilePath + "' is valid.");
},
function (validationError) {
jqUnit.fail("Settings file '" + settingsFilePath + "' is invalid.");
fluid.log("The error returned was: " + validationError.message);
fluid.each(validationError.errors, function (singleError) {
fluid.log("Validation error in file '" + settingsFilePath + "':");
fluid.log(" - " + singleError.dataPath.join(".") + ": " + singleError.message);
var validatedMaterial = fluid.model.transformWithRules(requestData, validationMiddleware.options.rules.innerPayload);
var failingMaterial = fluid.get(validatedMaterial, singleError.dataPath);
fluid.log("The failing value was '" + failingMaterial + "'.");
});
}
);
return validationPromise;
};
};
fluid.defaults("gpii.tests.universal.solutionsRegistry.settingsPayloads", {
gradeNames: ["fluid.component"],
settingsDataPaths: [
"%gpii-universal/testData/preferences",
"%gpii-universal/tests/data/preferences"
],
codexPath: "%gpii-universal/build/schemas/solution-schema-codex.json",
codex: "@expand:fluid.require({that}.options.codexPath)",
components: {
settingsValidator: {
type: "gpii.universal.solutionsRegistry.validators.settings"
}
},
listeners: {
"onCreate.validateSettingsDir": {
funcName: "gpii.tests.universal.solutionsRegistry.settingsPayloads.validateSettingsDir",
args: ["{that}", "{gpii.universal.solutionsRegistry.validators.settings}", "{gpii.schema.validator}"]
}
}
});
gpii.tests.universal.solutionsRegistry.settingsPayloads();