tor-browser

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

test_quicksuggest_topPicks.js (5542B)


      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
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 // Tests top pick quick suggest results. "Top picks" refers to two different
      6 // concepts:
      7 //
      8 // (1) Any type of suggestion from Merino can have a boolean property called
      9 //     `is_top_pick`. When true, Firefox should show the suggestion using the
     10 //     "best match" UI treatment (labeled "top pick" in the UI) that makes a
     11 //     result's row larger than usual and sets `suggestedIndex` to 1.
     12 // (2) There is a Merino provider called "top_picks" that returns a specific
     13 //     type of suggestion called "navigational suggestions". These suggestions
     14 //     also have `is_top_pick` set to true.
     15 //
     16 // This file tests aspects of both concepts.
     17 
     18 "use strict";
     19 
     20 const SUGGESTION_SEARCH_STRING = "example";
     21 const SUGGESTION_URL = "http://example.com/";
     22 const SUGGESTION_URL_WWW = "http://www.example.com/";
     23 
     24 const MERINO_SUGGESTIONS = [
     25  {
     26    is_top_pick: true,
     27    provider: "top_picks",
     28    url: SUGGESTION_URL,
     29    title: "title",
     30    icon: "icon",
     31    is_sponsored: false,
     32    score: 1,
     33  },
     34 ];
     35 
     36 add_setup(async function init() {
     37  // Disable search suggestions so we don't hit the network.
     38  Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
     39 
     40  await QuickSuggestTestUtils.ensureQuickSuggestInit({
     41    merinoSuggestions: MERINO_SUGGESTIONS,
     42    prefs: [["suggest.quicksuggest.all", true]],
     43  });
     44 });
     45 
     46 // When `all` is disabled, navigational suggestions should be disabled.
     47 add_task(async function allDisabled() {
     48  // Disable sponsored suggestions. Navigational suggestions are non-sponsored,
     49  // so doing this should not prevent them from being enabled.
     50  UrlbarPrefs.set("suggest.quicksuggest.sponsored", false);
     51 
     52  // First make sure the suggestion is added when non-sponsored suggestions are
     53  // enabled.
     54  await check_results({
     55    context: createContext(SUGGESTION_SEARCH_STRING, {
     56      providers: [UrlbarProviderQuickSuggest.name],
     57      isPrivate: false,
     58    }),
     59    matches: [
     60      makeExpectedResult({
     61        isBestMatch: true,
     62        suggestedIndex: 1,
     63      }),
     64    ],
     65  });
     66 
     67  // Now disable them.
     68  UrlbarPrefs.set("suggest.quicksuggest.all", false);
     69  await check_results({
     70    context: createContext(SUGGESTION_SEARCH_STRING, {
     71      providers: [UrlbarProviderQuickSuggest.name],
     72      isPrivate: false,
     73    }),
     74    matches: [],
     75  });
     76 
     77  UrlbarPrefs.set("suggest.quicksuggest.all", true);
     78  UrlbarPrefs.clear("suggest.quicksuggest.sponsored");
     79 });
     80 
     81 // Test that bestMatch navigational suggestion results are not shown when there
     82 // is a heuristic result for the same domain.
     83 add_task(async function heuristicDeduplication() {
     84  let expectedNavSuggestResult = makeExpectedResult({
     85    isBestMatch: true,
     86    suggestedIndex: 1,
     87    dupedHeuristic: false,
     88  });
     89 
     90  let scenarios = [
     91    [SUGGESTION_URL, false],
     92    [SUGGESTION_URL_WWW, false],
     93    ["http://exampledomain.com/", true],
     94  ];
     95  let quickSuggestProviderInstance = UrlbarProvidersManager.getProvider(
     96    UrlbarProviderQuickSuggest.name
     97  );
     98 
     99  // Stub `UrlbarProviderQuickSuggest.startQuery()` so we can collect the
    100  // results it adds for each query.
    101  let addedResults = [];
    102  let sandbox = sinon.createSandbox();
    103  let startQueryStub = sandbox.stub(quickSuggestProviderInstance, "startQuery");
    104  startQueryStub.callsFake((queryContext, add) => {
    105    let fakeAdd = (provider, result) => {
    106      addedResults.push(result);
    107      add(provider, result);
    108    };
    109    return startQueryStub.wrappedMethod.call(
    110      quickSuggestProviderInstance,
    111      queryContext,
    112      fakeAdd
    113    );
    114  });
    115 
    116  for (let [url, expectBestMatch] of scenarios) {
    117    await PlacesTestUtils.addVisits(url);
    118 
    119    // Do a search and check the results.
    120    let context = createContext(SUGGESTION_SEARCH_STRING, {
    121      providers: [UrlbarProviderQuickSuggest.name, UrlbarProviderAutofill.name],
    122      isPrivate: false,
    123    });
    124    const EXPECTED_AUTOFILL_RESULT = makeVisitResult(context, {
    125      uri: url,
    126      title: `test visit for ${url}`,
    127      heuristic: true,
    128    });
    129    await check_results({
    130      context,
    131      matches: expectBestMatch
    132        ? [EXPECTED_AUTOFILL_RESULT, expectedNavSuggestResult]
    133        : [EXPECTED_AUTOFILL_RESULT],
    134    });
    135 
    136    // Regardless of whether it was shown, one result should have been added and
    137    // its `payload.dupedHeuristic` should be set properly.
    138    Assert.equal(
    139      addedResults.length,
    140      1,
    141      "The provider should have added one result"
    142    );
    143    Assert.equal(
    144      !addedResults[0].payload.dupedHeuristic,
    145      expectBestMatch,
    146      "dupedHeuristic should be the opposite of expectBestMatch"
    147    );
    148    addedResults = [];
    149 
    150    await PlacesUtils.history.clear();
    151  }
    152 
    153  sandbox.restore();
    154 });
    155 
    156 function makeExpectedResult({
    157  isBestMatch,
    158  suggestedIndex,
    159  dupedHeuristic,
    160  telemetryType = "top_picks",
    161 }) {
    162  let result = {
    163    isBestMatch,
    164    suggestedIndex,
    165    type: UrlbarUtils.RESULT_TYPE.URL,
    166    source: UrlbarUtils.RESULT_SOURCE.SEARCH,
    167    heuristic: false,
    168    payload: {
    169      dupedHeuristic,
    170      telemetryType,
    171      title: "title",
    172      url: SUGGESTION_URL,
    173      icon: "icon",
    174      isSponsored: false,
    175      shouldShowUrl: true,
    176      source: "merino",
    177      provider: telemetryType,
    178      isBlockable: true,
    179      isManageable: true,
    180    },
    181  };
    182  if (typeof dupedHeuristic == "boolean") {
    183    result.payload.dupedHeuristic = dupedHeuristic;
    184  }
    185  return result;
    186 }