tor-browser

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

test_search_suggestions_aliases.js (11210B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 /**
      5 * Tests that an engine with suggestions works with our alias autocomplete
      6 * behavior.
      7 */
      8 
      9 const DEFAULT_ENGINE_NAME = "TestDefaultEngine";
     10 const SUGGEST_PREF = "browser.urlbar.suggest.searches";
     11 const SUGGEST_ENABLED_PREF = "browser.search.suggest.enabled";
     12 const HISTORY_TITLE = "fire";
     13 
     14 // We make sure that aliases and search terms are correctly recognized when they
     15 // are separated by each of these different types of spaces and combinations of
     16 // spaces.  U+3000 is the ideographic space in CJK and is commonly used by CJK
     17 // speakers.
     18 const TEST_SPACES = [" ", "\u3000", " \u3000", "\u3000 "];
     19 
     20 let engine;
     21 let port;
     22 
     23 add_setup(async function () {
     24  engine = await addTestSuggestionsEngine();
     25  port = engine.getSubmission("abc").uri.port;
     26 
     27  Services.prefs.setBoolPref("browser.urlbar.suggest.quickactions", false);
     28 
     29  // Set a mock engine as the default so we don't hit the network below when we
     30  // do searches that return the default engine heuristic result.
     31  await SearchTestUtils.installSearchExtension(
     32    {
     33      name: DEFAULT_ENGINE_NAME,
     34      search_url: "https://my.search.com/",
     35    },
     36    { setAsDefault: true }
     37  );
     38 
     39  // History matches should not appear with @aliases, so this visit should not
     40  // appear when searching with @aliases below.
     41  await PlacesTestUtils.addVisits({
     42    uri: engine.getSubmission("abc").uri,
     43    title: HISTORY_TITLE,
     44  });
     45 });
     46 
     47 // A non-token alias without a trailing space shouldn't be recognized as a
     48 // keyword.  It should be treated as part of the search string.
     49 add_task(async function nonTokenAlias_noTrailingSpace() {
     50  Services.prefs.setBoolPref(
     51    "browser.search.separatePrivateDefault.ui.enabled",
     52    false
     53  );
     54 
     55  let alias = "moz";
     56  engine.alias = alias;
     57  Assert.equal(engine.alias, alias);
     58  let context = createContext(alias, { isPrivate: false });
     59  await check_results({
     60    context,
     61    matches: [
     62      makeSearchResult(context, {
     63        engineName: DEFAULT_ENGINE_NAME,
     64        query: alias,
     65        heuristic: true,
     66      }),
     67    ],
     68  });
     69  Services.prefs.clearUserPref(
     70    "browser.search.separatePrivateDefault.ui.enabled"
     71  );
     72 });
     73 
     74 // A non-token alias with a trailing space should be recognized as a keyword,
     75 // and the history result should be included.
     76 add_task(async function nonTokenAlias_trailingSpace() {
     77  let alias = "moz";
     78  engine.alias = alias;
     79  Assert.equal(engine.alias, alias);
     80 
     81  for (let isPrivate of [false, true]) {
     82    for (let spaces of TEST_SPACES) {
     83      info(
     84        "Testing: " + JSON.stringify({ isPrivate, spaces: codePoints(spaces) })
     85      );
     86      let context = createContext(alias + spaces, { isPrivate });
     87      await check_results({
     88        context,
     89        matches: [
     90          makeSearchResult(context, {
     91            engineName: SUGGESTIONS_ENGINE_NAME,
     92            alias,
     93            query: "",
     94            heuristic: true,
     95          }),
     96          makeVisitResult(context, {
     97            uri: `http://localhost:${port}/search?q=abc`,
     98            title: HISTORY_TITLE,
     99          }),
    100        ],
    101      });
    102    }
    103  }
    104 });
    105 
    106 // Search for "alias HISTORY_TITLE" with a non-token alias in a non-private
    107 // context.  The remote suggestions and history result should be shown.
    108 add_task(async function nonTokenAlias_history_nonPrivate() {
    109  let alias = "moz";
    110  engine.alias = alias;
    111  Assert.equal(engine.alias, alias);
    112  for (let spaces of TEST_SPACES) {
    113    info("Testing: " + JSON.stringify({ spaces: codePoints(spaces) }));
    114    let context = createContext(alias + spaces + HISTORY_TITLE, {
    115      isPrivate: false,
    116    });
    117    await check_results({
    118      context,
    119      matches: [
    120        makeSearchResult(context, {
    121          engineName: SUGGESTIONS_ENGINE_NAME,
    122          alias,
    123          query: HISTORY_TITLE,
    124          heuristic: true,
    125        }),
    126        makeSearchResult(context, {
    127          engineName: SUGGESTIONS_ENGINE_NAME,
    128          alias,
    129          query: HISTORY_TITLE,
    130          suggestion: `${HISTORY_TITLE} foo`,
    131        }),
    132        makeSearchResult(context, {
    133          engineName: SUGGESTIONS_ENGINE_NAME,
    134          alias,
    135          query: HISTORY_TITLE,
    136          suggestion: `${HISTORY_TITLE} bar`,
    137        }),
    138        makeVisitResult(context, {
    139          uri: `http://localhost:${port}/search?q=abc`,
    140          title: HISTORY_TITLE,
    141        }),
    142      ],
    143    });
    144  }
    145 });
    146 
    147 // Search for "alias HISTORY_TITLE" with a non-token alias in a private context.
    148 // The history result should be shown, but not the remote suggestions.
    149 add_task(async function nonTokenAlias_history_private() {
    150  let alias = "moz";
    151  engine.alias = alias;
    152  Assert.equal(engine.alias, alias);
    153  for (let spaces of TEST_SPACES) {
    154    info("Testing: " + JSON.stringify({ spaces: codePoints(spaces) }));
    155    let context = createContext(alias + spaces + HISTORY_TITLE, {
    156      isPrivate: true,
    157    });
    158    await check_results({
    159      context,
    160      matches: [
    161        makeSearchResult(context, {
    162          engineName: SUGGESTIONS_ENGINE_NAME,
    163          alias,
    164          query: HISTORY_TITLE,
    165          heuristic: true,
    166        }),
    167        makeVisitResult(context, {
    168          uri: `http://localhost:${port}/search?q=abc`,
    169          title: HISTORY_TITLE,
    170        }),
    171      ],
    172    });
    173  }
    174 });
    175 
    176 // A token alias without a trailing space should be autofilled with a trailing
    177 // space and recognized as a keyword with a keyword offer.
    178 add_task(async function tokenAlias_noTrailingSpace() {
    179  let alias = "@moz";
    180  engine.alias = alias;
    181  Assert.equal(engine.alias, alias);
    182  for (let isPrivate of [false, true]) {
    183    let context = createContext(alias, { isPrivate });
    184    await check_results({
    185      context,
    186      autofilled: alias + " ",
    187      matches: [
    188        makeSearchResult(context, {
    189          engineName: SUGGESTIONS_ENGINE_NAME,
    190          alias,
    191          providesSearchMode: true,
    192          query: "",
    193          heuristic: false,
    194          providerName: "UrlbarProviderTokenAliasEngines",
    195        }),
    196      ],
    197    });
    198  }
    199 });
    200 
    201 // A token alias with a trailing space should be recognized as a keyword without
    202 // a keyword offer.
    203 add_task(async function tokenAlias_trailingSpace() {
    204  let alias = "@moz";
    205  engine.alias = alias;
    206  Assert.equal(engine.alias, alias);
    207  for (let isPrivate of [false, true]) {
    208    for (let spaces of TEST_SPACES) {
    209      info(
    210        "Testing: " + JSON.stringify({ isPrivate, spaces: codePoints(spaces) })
    211      );
    212      let context = createContext(alias + spaces, { isPrivate });
    213      await check_results({
    214        context,
    215        matches: [
    216          makeSearchResult(context, {
    217            engineName: SUGGESTIONS_ENGINE_NAME,
    218            alias,
    219            query: "",
    220            heuristic: true,
    221          }),
    222        ],
    223      });
    224    }
    225  }
    226 });
    227 
    228 // Search for "alias HISTORY_TITLE" with a token alias in a non-private context.
    229 // The remote suggestions should be shown, but not the history result.
    230 add_task(async function tokenAlias_history_nonPrivate() {
    231  let alias = "@moz";
    232  engine.alias = alias;
    233  Assert.equal(engine.alias, alias);
    234  for (let spaces of TEST_SPACES) {
    235    info("Testing: " + JSON.stringify({ spaces: codePoints(spaces) }));
    236    let context = createContext(alias + spaces + HISTORY_TITLE, {
    237      isPrivate: false,
    238    });
    239    await check_results({
    240      context,
    241      matches: [
    242        makeSearchResult(context, {
    243          engineName: SUGGESTIONS_ENGINE_NAME,
    244          alias,
    245          query: HISTORY_TITLE,
    246          heuristic: true,
    247        }),
    248        makeSearchResult(context, {
    249          engineName: SUGGESTIONS_ENGINE_NAME,
    250          alias,
    251          query: HISTORY_TITLE,
    252          suggestion: `${HISTORY_TITLE} foo`,
    253        }),
    254        makeSearchResult(context, {
    255          engineName: SUGGESTIONS_ENGINE_NAME,
    256          alias,
    257          query: HISTORY_TITLE,
    258          suggestion: `${HISTORY_TITLE} bar`,
    259        }),
    260      ],
    261    });
    262  }
    263 });
    264 
    265 // Search for "alias HISTORY_TITLE" with a token alias in a private context.
    266 // Neither the history result nor the remote suggestions should be shown.
    267 add_task(async function tokenAlias_history_private() {
    268  let alias = "@moz";
    269  engine.alias = alias;
    270  Assert.equal(engine.alias, alias);
    271  for (let spaces of TEST_SPACES) {
    272    info("Testing: " + JSON.stringify({ spaces: codePoints(spaces) }));
    273    let context = createContext(alias + spaces + HISTORY_TITLE, {
    274      isPrivate: true,
    275    });
    276    await check_results({
    277      context,
    278      matches: [
    279        makeSearchResult(context, {
    280          engineName: SUGGESTIONS_ENGINE_NAME,
    281          alias,
    282          query: HISTORY_TITLE,
    283          heuristic: true,
    284        }),
    285      ],
    286    });
    287  }
    288 });
    289 
    290 // Even when they're disabled, suggestions should still be returned when using a
    291 // token alias in a non-private context.
    292 add_task(async function suggestionsDisabled_nonPrivate() {
    293  Services.prefs.setBoolPref(SUGGEST_PREF, false);
    294  Services.prefs.setBoolPref(SUGGEST_ENABLED_PREF, true);
    295  let alias = "@moz";
    296  engine.alias = alias;
    297  Assert.equal(engine.alias, alias);
    298  for (let spaces of TEST_SPACES) {
    299    info("Testing: " + JSON.stringify({ spaces: codePoints(spaces) }));
    300    let context = createContext(alias + spaces + "term", { isPrivate: false });
    301    await check_results({
    302      context,
    303      matches: [
    304        makeSearchResult(context, {
    305          engineName: SUGGESTIONS_ENGINE_NAME,
    306          alias,
    307          query: "term",
    308          heuristic: true,
    309        }),
    310        makeSearchResult(context, {
    311          engineName: SUGGESTIONS_ENGINE_NAME,
    312          alias,
    313          query: "term",
    314          suggestion: "term foo",
    315        }),
    316        makeSearchResult(context, {
    317          engineName: SUGGESTIONS_ENGINE_NAME,
    318          alias,
    319          query: "term",
    320          suggestion: "term bar",
    321        }),
    322      ],
    323    });
    324  }
    325  Services.prefs.clearUserPref(SUGGEST_PREF);
    326  Services.prefs.clearUserPref(SUGGEST_ENABLED_PREF);
    327 });
    328 
    329 // Suggestions should not be returned when using a token alias in a private
    330 // context.
    331 add_task(async function suggestionsDisabled_private() {
    332  Services.prefs.setBoolPref(SUGGEST_PREF, false);
    333  Services.prefs.setBoolPref(SUGGEST_ENABLED_PREF, true);
    334  let alias = "@moz";
    335  engine.alias = alias;
    336  Assert.equal(engine.alias, alias);
    337  for (let spaces of TEST_SPACES) {
    338    info("Testing: " + JSON.stringify({ spaces: codePoints(spaces) }));
    339    let context = createContext(alias + spaces + "term", { isPrivate: true });
    340    await check_results({
    341      context,
    342      matches: [
    343        makeSearchResult(context, {
    344          engineName: SUGGESTIONS_ENGINE_NAME,
    345          alias,
    346          query: "term",
    347          heuristic: true,
    348        }),
    349      ],
    350    });
    351    Services.prefs.clearUserPref(SUGGEST_PREF);
    352    Services.prefs.clearUserPref(SUGGEST_ENABLED_PREF);
    353  }
    354 });
    355 
    356 /**
    357 * Returns an array of code points in the given string.  Each code point is
    358 * returned as a hexidecimal string.
    359 *
    360 * @param {string} str
    361 *   The code points of this string will be returned.
    362 * @returns {Array}
    363 *   Array of code points in the string, where each is a hexidecimal string.
    364 */
    365 function codePoints(str) {
    366  return str.split("").map(s => s.charCodeAt(0).toString(16));
    367 }