UNPKG

gpii-universal

Version:

Cross platform, core components of the GPII personalization infrastructure.

170 lines (141 loc) 7.92 kB
"use strict"; 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();