tor-browser

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

test_heuristic_cancel.js (7127B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /**
      6 * Tests that old results from UrlbarProviderAutofill do not overwrite results
      7 * from UrlbarProviderHeuristicFallback after the autofillable query is
      8 * cancelled. See bug 1653436.
      9 */
     10 
     11 const { setTimeout } = ChromeUtils.importESModule(
     12  "resource://gre/modules/Timer.sys.mjs"
     13 );
     14 
     15 /**
     16 * A test provider that waits before returning results to simulate a slow DB
     17 * lookup.
     18 */
     19 class SlowHeuristicProvider extends UrlbarTestUtils.TestProvider {
     20  constructor({ results }) {
     21    const delayResultsPromise = new Promise(resolve =>
     22      // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
     23      setTimeout(resolve, 300)
     24    );
     25    super({
     26      name: "MyProvider",
     27      type: UrlbarUtils.PROVIDER_TYPE.HEURISTIC,
     28      results,
     29      delayResultsPromise,
     30    });
     31  }
     32 }
     33 
     34 /**
     35 * A fast provider that alerts the test when it has added its results.
     36 */
     37 class FastHeuristicProvider extends UrlbarTestUtils.TestProvider {
     38  get type() {
     39    return UrlbarUtils.PROVIDER_TYPE.HEURISTIC;
     40  }
     41 
     42  async startQuery(context, add) {
     43    this._context = context;
     44    for (let result of this.results) {
     45      add(this, result);
     46    }
     47    Services.obs.notifyObservers(null, "results-added");
     48  }
     49 }
     50 
     51 add_setup(async function () {
     52  registerCleanupFunction(async () => {
     53    Services.prefs.clearUserPref("browser.urlbar.suggest.searches");
     54  });
     55 
     56  Services.prefs.setBoolPref("browser.urlbar.suggest.searches", false);
     57 });
     58 
     59 /**
     60 * Tests that UrlbarProvidersManager._heuristicProviderTimer is cancelled when
     61 * a query is cancelled.
     62 */
     63 add_task(async function timerIsCancelled() {
     64  let context = createContext("m", { isPrivate: false });
     65  await PlacesTestUtils.promiseAsyncUpdates();
     66  info("Manually set up query and then overwrite it.");
     67  // slowProvider is a stand-in for a slow UrlbarProviderPlaces returning a
     68  // non-heuristic result.
     69  let slowProvider = new SlowHeuristicProvider({
     70    results: [
     71      makeVisitResult(context, {
     72        uri: `http://mozilla.org/`,
     73        title: `mozilla.org/`,
     74      }),
     75    ],
     76  });
     77  UrlbarProvidersManager.registerProvider(slowProvider);
     78 
     79  // fastProvider is a stand-in for a fast Autofill returning a heuristic
     80  // result.
     81  let fastProvider = new FastHeuristicProvider({
     82    results: [
     83      makeVisitResult(context, {
     84        uri: `http://mozilla.com/`,
     85        title: `mozilla.com/`,
     86        heuristic: true,
     87      }),
     88    ],
     89  });
     90  UrlbarProvidersManager.registerProvider(fastProvider);
     91  let firstContext = createContext("m", {
     92    providers: [slowProvider.name, fastProvider.name],
     93  });
     94  let secondContext = createContext("ma", {
     95    providers: [slowProvider.name, fastProvider.name],
     96  });
     97 
     98  let controller = UrlbarTestUtils.newMockController();
     99  let queryRecieved, queryCancelled;
    100  const controllerListener = {
    101    onQueryResults(queryContext) {
    102      Assert.equal(
    103        queryContext,
    104        secondContext,
    105        "Only the second query should finish."
    106      );
    107      queryRecieved = true;
    108    },
    109    onQueryCancelled(queryContext) {
    110      Assert.equal(
    111        queryContext,
    112        firstContext,
    113        "The first query should be cancelled."
    114      );
    115      Assert.ok(!queryCancelled, "No more than one query should be cancelled.");
    116      queryCancelled = true;
    117    },
    118  };
    119  controller.addListener(controllerListener);
    120 
    121  // Wait until FastProvider sends its results to the providers manager.
    122  // Then they will be queued up in a _heuristicProvidersTimer, waiting for
    123  // the results from SlowProvider.
    124  let resultsAddedPromise = new Promise(resolve => {
    125    let observe = async () => {
    126      Services.obs.removeObserver(observe, "results-added");
    127      // Fire the second query to cancel the first.
    128      await controller.startQuery(secondContext);
    129      resolve();
    130    };
    131 
    132    Services.obs.addObserver(observe, "results-added");
    133  });
    134 
    135  controller.startQuery(firstContext);
    136  await resultsAddedPromise;
    137 
    138  Assert.ok(queryCancelled, "At least one query was cancelled.");
    139  Assert.ok(queryRecieved, "At least one query finished.");
    140  controller.removeListener(controllerListener);
    141 });
    142 
    143 /**
    144 * Tests that old autofill results aren't displayed after a query is cancelled.
    145 * See bug 1653436.
    146 */
    147 add_task(async function autofillIsCleared() {
    148  /**
    149   * Steps:
    150   *   1. Start query.
    151   *   2. Allow UrlbarProviderAutofill to start _getAutofillResult.
    152   *   3. Execute a new query with no autofill match, cancelling the first
    153   *      query.
    154   *   4. Test that the old result from UrlbarProviderAutofill isn't displayed.
    155   */
    156  await PlacesTestUtils.addVisits("http://example.com");
    157 
    158  let firstContext = createContext("e", {
    159    providers: ["UrlbarProviderAutofill", "UrlbarProviderHeuristicFallback"],
    160  });
    161  let secondContext = createContext("em", {
    162    providers: ["UrlbarProviderAutofill", "UrlbarProviderHeuristicFallback"],
    163  });
    164 
    165  info("Sanity check: The first query autofills and the second does not.");
    166  await check_results({
    167    firstContext,
    168    autofilled: "example.com",
    169    completed: "http://example.com/",
    170    matches: [
    171      makeVisitResult(firstContext, {
    172        uri: "http://example.com/",
    173        title: "example.com",
    174        heuristic: true,
    175      }),
    176    ],
    177  });
    178 
    179  await check_results({
    180    secondContext,
    181    matches: [
    182      makeSearchResult(secondContext, {
    183        engineName: (await Services.search.getDefault()).name,
    184        providerName: "UrlbarProviderHeuristicFallback",
    185        heuristic: true,
    186      }),
    187    ],
    188  });
    189 
    190  // Refresh our queries
    191  firstContext = createContext("e", {
    192    providers: ["UrlbarProviderAutofill", "UrlbarProviderHeuristicFallback"],
    193  });
    194  secondContext = createContext("em", {
    195    providers: ["UrlbarProviderAutofill", "UrlbarProviderHeuristicFallback"],
    196  });
    197 
    198  // Set up controller to observe queries.
    199  let controller = UrlbarTestUtils.newMockController();
    200  let queryRecieved, queryCancelled;
    201  const controllerListener = {
    202    onQueryResults(queryContext) {
    203      Assert.equal(
    204        queryContext,
    205        secondContext,
    206        "Only the second query should finish."
    207      );
    208      queryRecieved = true;
    209    },
    210    onQueryCancelled(queryContext) {
    211      Assert.equal(
    212        queryContext,
    213        firstContext,
    214        "The first query should be cancelled."
    215      );
    216      Assert.ok(
    217        !UrlbarProvidersManager.getProvider("UrlbarProviderAutofill")
    218          ._autofillData,
    219        "The first result should not have populated autofill data."
    220      );
    221      Assert.ok(!queryCancelled, "No more than one query should be cancelled.");
    222      queryCancelled = true;
    223    },
    224  };
    225  controller.addListener(controllerListener);
    226 
    227  // Intentionally do not await this first query.
    228  controller.startQuery(firstContext);
    229  await controller.startQuery(secondContext);
    230 
    231  Assert.ok(queryCancelled, "At least one query was cancelled.");
    232  Assert.ok(queryRecieved, "At least one query finished.");
    233  controller.removeListener(controllerListener);
    234  await cleanupPlaces();
    235 });