Commit c98c5be0 authored by Marco Bonardo's avatar Marco Bonardo
Browse files

Bug 1834546 - Add a Nimbus feature and variables for alternative frecency. r=daisuke a=pascalc

parent 831713ee
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -43,13 +43,18 @@ const ORIGIN_FRECENCY_FIELD = ORIGIN_USE_ALT_FRECENCY
// the mean of all moz_origins.frecency values + stddevMultiplier * one standard
// deviation.  This is inlined directly in the SQL (as opposed to being a custom
// Sqlite function for example) in order to be as efficient as possible.
// For alternative frecency, a NULL frecency will be normalized to 0.0, and when
// it will graduate, it will likely become 1 (official frecency is NOT NULL).
// Thus we set a minimum threshold of 2.0, otherwise if all the visits are older
// than the cutoff, we end up checking 0.0 (frecency) >= 0.0 (threshold) and
// autofill everything instead of nothing.
const SQL_AUTOFILL_WITH = ORIGIN_USE_ALT_FRECENCY
  ? `
    WITH
    autofill_frecency_threshold(value) AS (
      SELECT IFNULL(
        (SELECT value FROM moz_meta WHERE key = 'origin_alt_frecency_threshold'),
        0.0
        2.0
      )
    )
    `
+18 −6
Original line number Diff line number Diff line
@@ -1148,26 +1148,38 @@ export var UrlbarTestUtils = {
  },

  /**
   * Enrolls in a mock Nimbus rollout.
   * Enrolls in a mock Nimbus feature.
   *
   * If you call UrlbarPrefs.updateFirefoxSuggestScenario() from an xpcshell
   * test, you must call this first to intialize the Nimbus urlbar feature.
   *
   * @param {object} value
   *   Define any desired Nimbus variables in this object.
   * @param {string} [feature]
   *   The feature to init.
   * @param {string} [enrollmentType]
   *   The enrollment type, either "rollout" (default) or "config".
   * @returns {Function}
   *   A cleanup function that will remove the mock rollout.
   *   A cleanup function that will unenroll the feature, returns a promise.
   */
  async initNimbusFeature(value = {}) {
  async initNimbusFeature(
    value = {},
    feature = "urlbar",
    enrollmentType = "rollout"
  ) {
    this.info?.("initNimbusFeature awaiting ExperimentManager.onStartup");
    await lazy.ExperimentManager.onStartup();

    this.info?.("initNimbusFeature awaiting ExperimentAPI.ready");
    await lazy.ExperimentAPI.ready();

    this.info?.("initNimbusFeature awaiting ExperimentFakes.enrollWithRollout");
    let doCleanup = await lazy.ExperimentFakes.enrollWithRollout({
      featureId: lazy.NimbusFeatures.urlbar.featureId,
    let method =
      enrollmentType == "rollout"
        ? "enrollWithRollout"
        : "enrollWithFeatureConfig";
    this.info?.(`initNimbusFeature awaiting ExperimentFakes.${method}`);
    let doCleanup = await lazy.ExperimentFakes[method]({
      featureId: lazy.NimbusFeatures[feature].featureId,
      value: { enabled: true, ...value },
    });

+49 −0
Original line number Diff line number Diff line
@@ -192,3 +192,52 @@ add_task(
    await PlacesUtils.history.clear();
  }
);

add_task(
  {
    pref_set: [["browser.urlbar.suggest.quickactions", false]],
  },
  async function test_autofill_cutoff() {
    async function getOriginAltFrecency(origin) {
      let db = await PlacesUtils.promiseDBConnection();
      let rows = await db.execute(
        "SELECT alt_frecency FROM moz_origins WHERE host = :origin",
        { origin }
      );
      return rows?.[0].getResultByName("alt_frecency");
    }

    // Add many visits older than the default 90 days cutoff.
    const visitDate = new Date(Date.now() - 120 * 86400000);
    await PlacesTestUtils.addVisits(
      new Array(10)
        .fill("https://example.com/")
        .map(url => ({ url, visitDate }))
    );
    await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies();

    Assert.strictEqual(
      await getOriginAltFrecency("example.com"),
      null,
      "Check example.com has a NULL frecency"
    );

    let engine = Services.search.defaultEngine;
    let context = createContext("ex", { isPrivate: false });
    await check_results({
      context,
      matches: [
        makeSearchResult(context, {
          heuristic: true,
          query: "ex",
          engineName: engine.name,
        }),
        makeVisitResult(context, {
          uri: "https://example.com/",
          title: "test visit for https://example.com/",
        }),
      ],
    });
    await PlacesUtils.history.clear();
  }
);
+50 −0
Original line number Diff line number Diff line
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

const ORIGINS_FEATUREGATE = "places.frecency.origins.alternative.featureGate";
const ORIGINS_DAYSCUTOFF = "places.frecency.origins.alternative.daysCutOff";

add_task(async function () {
  let reset = await UrlbarTestUtils.initNimbusFeature(
    {
      // Empty for sanity check.
    },
    "frecency",
    "config"
  );
  Assert.equal(Services.prefs.getBoolPref(ORIGINS_FEATUREGATE), false);
  Assert.throws(
    () => Services.prefs.getIntPref(ORIGINS_DAYSCUTOFF),
    /NS_ERROR_UNEXPECTED/
  );
  await reset();

  reset = await UrlbarTestUtils.initNimbusFeature(
    {
      originsAlternativeEnable: true,
    },
    "frecency",
    "config"
  );
  Assert.equal(Services.prefs.getBoolPref(ORIGINS_FEATUREGATE), true);
  Assert.ok(Services.prefs.prefHasUserValue(ORIGINS_FEATUREGATE));
  Assert.throws(
    () => Services.prefs.getIntPref(ORIGINS_DAYSCUTOFF),
    /NS_ERROR_UNEXPECTED/
  );
  await reset();

  reset = await UrlbarTestUtils.initNimbusFeature(
    {
      originsAlternativeEnable: true,
      originsDaysCutOff: 60,
    },
    "frecency",
    "config"
  );
  Assert.equal(Services.prefs.getBoolPref(ORIGINS_FEATUREGATE), true);
  Assert.ok(Services.prefs.prefHasUserValue(ORIGINS_FEATUREGATE));
  Assert.equal(Services.prefs.getIntPref(ORIGINS_DAYSCUTOFF, 90), 60);
  Assert.ok(Services.prefs.prefHasUserValue(ORIGINS_DAYSCUTOFF));
  await reset();
});
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ prefs = places.frecency.origins.alternative.featureGate=true
[test_escaping_escapeSelf.js]
[test_exposure.js]
[test_frecency.js]
[test_frecency_alternative_nimbus.js]
[test_heuristic_cancel.js]
[test_hideSponsoredHistory.js]
[test_keywords.js]
Loading