UNPKG

gpii-universal

Version:

Cross platform, core components of the GPII personalization infrastructure.

201 lines (171 loc) 10.9 kB
"use strict"; var fluid = require("infusion"); var gpii = fluid.registerNamespace("gpii"); var jqUnit = require("node-jqunit"); require("json5/lib/register"); require("gpii-json-schema"); require("./lib/validation"); require("./lib/utils"); require("../../transformer/src/js/Transformer"); jqUnit.module("Sanity checks for Generic Preference Terms data."); fluid.registerNamespace("gpii.tests.universal.solutionsRegistry.genericTerms"); // Validate the generic preference settings to confirm that they're at least valid GSS schemas. gpii.tests.universal.solutionsRegistry.genericTerms.validateCommonTerms = function (that, globalValidator) { var resolvedGenericTermsPath = fluid.module.resolvePath(that.options.genericPreferenceTermsPath); var genericTerms = require(resolvedGenericTermsPath); jqUnit.test("Validating generic preference term schemas.", function () { fluid.each(genericTerms, function (termDef, termKey) { if (termDef.schema) { var schemaAsGss = fluid.merge({}, { "$schema": "gss-v7-full#" }, termDef.schema); // Separate check here as we are only validating the schema itself. In theory, this is already hit for // any settings in our test data set, but we do it explicitly for all schemas here. var validationResults = gpii.schema.validator.validateSchema(schemaAsGss); // We perform these checks a bit flipped so that only a particular value trips it, and not a missing value. jqUnit.assertFalse("There should be no validation errors in generic preference term '" + termKey + "'.", validationResults.isValid === false); jqUnit.assertFalse("There should be no low-level errors in generic preference term '" + termKey + "'.", validationResults.isError === true); if (!validationResults.isError && !validationResults.isValid) { var localisedErrors = gpii.schema.validator.localiseErrors(validationResults.errors, schemaAsGss); fluid.each(localisedErrors, function (singleError) { fluid.log("Validation error is as folows:"); fluid.log(" - " + singleError.dataPath.join(".") + ": " + singleError.message); }); } } else { jqUnit.fail("Generic Preference Term '" + termKey + "' has no schema."); } }); }); jqUnit.test("Validating raw default values for all generic preference terms.", function () { // We do this so we can report all validation errors rather than failing on the first. var rawDefaultErrorCount = 0; fluid.each(genericTerms, function (termDef, termKey) { var schema = fluid.get(termDef, "schema"); var defaultValue = fluid.get(termDef, "schema.default"); if (defaultValue !== undefined) { // Check the raw value against the schema var isValid = gpii.tests.universal.solutionsRegistry.validateSinglePayload( globalValidator, defaultValue, schema, "Default raw value for generic preference term '" + termKey + "'" ); if (!isValid) { rawDefaultErrorCount++; } } }); jqUnit.assertEquals("There should be no validation errors for the raw defaults.", 0, rawDefaultErrorCount); }); jqUnit.test("Ensure that generic preference term defaults can be transformed to valid application-specific settings.", function () { var combinedDefaults = {}; var combinedMaximums = {}; var combinedMinimums = {}; fluid.each(genericTerms, function (termDef, termKey) { var defaultValue = fluid.get(termDef, "schema.default"); if (defaultValue !== undefined) { combinedDefaults[termKey] = defaultValue; // If there is no min/max, we add the default so there's at least some value. Otherwise any // transform that refers to a generic preference term will end up with a value of `undefined` // and likely fail. combinedMaximums[termKey] = defaultValue; combinedMinimums[termKey] = defaultValue; } var maxValue = fluid.get(termDef, "schema.maximum"); if (maxValue !== undefined) { combinedMaximums[termKey] = maxValue; } var minValue = fluid.get(termDef, "schema.minimum"); if (minValue !== undefined) { combinedMinimums[termKey] = minValue; } }); // Build a crude rollup of all possible transformations for all solutions. var solutionsDefs = fluid.require(that.options.srPath); var combinedCapabilitiesTransform = {}; fluid.each(solutionsDefs, function (solutionDef, solutionKey) { var escapedSolutionKey = "http://registry\\.gpii\\.net/applications/" + solutionKey.replace(/\./g, "\\."); fluid.each(solutionDef.settingsHandlers, function (settingsHandlerDef) { if (settingsHandlerDef.capabilitiesTransformations) { // Allow for at least a shallow mix of intra-application and common terms transforms. var filteredTransforms = {}; fluid.each(settingsHandlerDef.capabilitiesTransformations, function (singleTransform, transformKey) { var hasIntraApplicationTransform = gpii.tests.universal.solutionsRegistry.hasIntraApplicationTransform(singleTransform); if (!hasIntraApplicationTransform) { filteredTransforms[transformKey] = singleTransform; } }); if (Object.keys(filteredTransforms).length) { combinedCapabilitiesTransform[escapedSolutionKey] = fluid.extend({}, combinedCapabilitiesTransform[escapedSolutionKey], filteredTransforms); } } }); }); // Transform the defaults into application-specific terms. var transformedDefaults = fluid.model.transformWithRules(combinedDefaults, combinedCapabilitiesTransform); var transformedMaximums = fluid.model.transformWithRules(combinedMaximums, combinedCapabilitiesTransform); var transformedMinimums = fluid.model.transformWithRules(combinedMinimums, combinedCapabilitiesTransform); // Now validate against each solution individually. var validationErrorCount = 0; var codex = fluid.require(that.options.codexPath); fluid.each(codex, function (solutionSchema, solutionKey) { var defaultToValidate = transformedDefaults[solutionKey]; if (defaultToValidate) { var defaultValidationResults = globalValidator.validate(solutionSchema, defaultToValidate); if (defaultValidationResults.isError || !defaultValidationResults.isValid) { validationErrorCount += defaultValidationResults.errors.length; var localisedDefaultErrors = gpii.schema.validator.localiseErrors(defaultValidationResults.errors, defaultToValidate); // Log the failure details. fluid.log("Error validating generic preference term default(s) for " + solutionKey + ":"); gpii.tests.universal.solutionsRegistry.genericTerms.logValidationErrors(localisedDefaultErrors, defaultToValidate); } } var maximumToValidate = transformedMaximums[solutionKey]; if (maximumToValidate) { var maxValidationResults = globalValidator.validate(solutionSchema, maximumToValidate); if (maxValidationResults.isError || !maxValidationResults.isValid) { validationErrorCount += maxValidationResults.errors.length; var localisedMaxErrors = gpii.schema.validator.localiseErrors(maxValidationResults.errors, maximumToValidate); // Log the failure details. fluid.log("Error validating generic preference term maximum value(s) for " + solutionKey + ":"); gpii.tests.universal.solutionsRegistry.genericTerms.logValidationErrors(localisedMaxErrors, maximumToValidate); } } var minimumToValidate = transformedMinimums[solutionKey]; if (minimumToValidate) { var minValidationResults = globalValidator.validate(solutionSchema, minimumToValidate); if (minValidationResults.isError || !minValidationResults.isValid) { validationErrorCount += minValidationResults.errors.length; var localisedMinErrors = gpii.schema.validator.localiseErrors(minValidationResults.errors, minimumToValidate); // Log the failure details. fluid.log("Error validating generic preference term minimum value(s) for " + solutionKey + ":"); gpii.tests.universal.solutionsRegistry.genericTerms.logValidationErrors(localisedMinErrors, minimumToValidate); } } }); // Ensure that the tests also fail if there are errors. jqUnit.assertEquals("There should be no validation errors that result from transforming generic preference terms defaults.", 0, validationErrorCount); }); }; gpii.tests.universal.solutionsRegistry.genericTerms.logValidationErrors = function (localisedErrors, toValidate) { fluid.each(localisedErrors, function (singleError) { // TODO: Track down bogus data paths like `.properties['BounceKeysInterval']` var dataPath = Array.isArray(singleError.dataPath) ? singleError.dataPath : []; var problematicValue = fluid.get(toValidate, dataPath); fluid.log(" - " + dataPath.join(".") + " -> " + JSON.stringify(problematicValue) + " : " + singleError.message); }); }; fluid.defaults("gpii.tests.universal.solutionsRegistry.genericTerms", { gradeNames: ["fluid.component"], genericPreferenceTermsPath: "%gpii-universal/testData/ontologies/flat.json5", codexPath: "%gpii-universal/build/schemas/solution-schema-codex.json", // TODO: Replace this with all solutions as part of the LSR refactor. srPath: "%gpii-universal/testData/solutions/win32.json5", listeners: { "onCreate.validateCommonTerms": { funcName: "gpii.tests.universal.solutionsRegistry.genericTerms.validateCommonTerms", args: ["{that}", "{gpii.schema.validator}"] } } }); gpii.tests.universal.solutionsRegistry.genericTerms();