tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_urlbar_persisted_search_terms_validation.js (2687B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 ChromeUtils.defineESModuleGetters(this, {
      7  RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
      8  JsonSchema: "resource://gre/modules/JsonSchema.sys.mjs",
      9 });
     10 
     11 const URLBAR_PERSISTENCE_SETTINGS_KEY = "urlbar-persisted-search-terms";
     12 
     13 /**
     14 * Checks to see if a value is an object or not.
     15 *
     16 * @param {*} value
     17 *   The value to check.
     18 * @returns {boolean}
     19 */
     20 function isObject(value) {
     21  return value != null && typeof value == "object" && !Array.isArray(value);
     22 }
     23 
     24 /**
     25 * This function modifies the schema to prevent allowing additional properties
     26 * on objects. This is used to enforce that the schema contains everything that
     27 * we deliver via the search configuration.
     28 *
     29 * These checks are not enabled in-product, as we want to allow older versions
     30 * to keep working if we add new properties for whatever reason.
     31 *
     32 * @param {object} section
     33 *   The section to check to see if an additionalProperties flag should be added.
     34 */
     35 function disallowAdditionalProperties(section) {
     36  // It is generally acceptable for new properties to be added to the
     37  // configuration as older builds will ignore them.
     38  //
     39  // As a result, we only check for new properties on nightly builds, and this
     40  // avoids us having to uplift schema changes. This also helps preserve the
     41  // schemas as documentation of "what was supported in this version".
     42  if (!AppConstants.NIGHTLY_BUILD) {
     43    info("Skipping additional properties validation.");
     44    return;
     45  }
     46 
     47  if (section.type == "object") {
     48    section.additionalProperties = false;
     49  }
     50  for (let value of Object.values(section)) {
     51    if (isObject(value)) {
     52      disallowAdditionalProperties(value);
     53    }
     54  }
     55 }
     56 
     57 add_task(async function test_search_telemetry_validates_to_schema() {
     58  let schema = await IOUtils.readJSON(
     59    PathUtils.join(
     60      do_get_cwd().path,
     61      "urlbar-persisted-search-terms-schema.json"
     62    )
     63  );
     64 
     65  disallowAdditionalProperties(schema);
     66 
     67  let data = await RemoteSettings(URLBAR_PERSISTENCE_SETTINGS_KEY).get();
     68 
     69  let validator = new JsonSchema.Validator(schema);
     70 
     71  for (let entry of data) {
     72    // Records in Remote Settings contain additional properties independent of
     73    // the schema. Hence, we don't want to validate their presence.
     74    delete entry.schema;
     75    delete entry.id;
     76    delete entry.last_modified;
     77 
     78    let result = validator.validate(entry);
     79    let message = `Should validate ${entry.providerId}`;
     80    if (!result.valid) {
     81      message += `:\n${JSON.stringify(result.errors, null, 2)}`;
     82    }
     83    Assert.ok(result.valid, message);
     84  }
     85 });