tor-browser

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

test_suggestedIndexRelativeToGroup.js (16849B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 // Tests results with `suggestedIndex` and `isSuggestedIndexRelativeToGroup`.
      5 
      6 "use strict";
      7 
      8 const lazy = {};
      9 
     10 ChromeUtils.defineESModuleGetters(lazy, {
     11  sinon: "resource://testing-common/Sinon.sys.mjs",
     12 });
     13 
     14 const MAX_RESULTS = 10;
     15 
     16 // Default result groups used in the tests below.
     17 const RESULT_GROUPS = {
     18  children: [
     19    {
     20      group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
     21      flexChildren: true,
     22      children: [
     23        {
     24          flex: 1,
     25          group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
     26        },
     27        {
     28          flex: 1,
     29          group: UrlbarUtils.RESULT_GROUP.GENERAL,
     30        },
     31        {
     32          flex: 1,
     33          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
     34        },
     35      ],
     36    },
     37  ],
     38 };
     39 
     40 let sandbox;
     41 add_setup(async () => {
     42  sandbox = lazy.sinon.createSandbox();
     43  registerCleanupFunction(() => {
     44    sandbox.restore();
     45  });
     46 });
     47 
     48 add_task(async function test() {
     49  // Create the default non-suggestedIndex results we'll use for tests that
     50  // don't specify `otherResults`.
     51  let basicResults = [
     52    ...makeHistoryResults(),
     53    ...makeFormHistoryResults(),
     54    ...makeRemoteSuggestionResults(),
     55  ];
     56 
     57  // Test cases follow. Each object in `tests` has the following properties:
     58  //
     59  // * {string} desc
     60  // * {object} suggestedIndexResults
     61  //   Describes the suggestedIndex results the test provider should return.
     62  //   Properties:
     63  //     * {number} suggestedIndex
     64  //     * {UrlbarUtils.RESULT_GROUP} group
     65  //       This will force the result to have the given group.
     66  // * {array} expected
     67  //   Describes the expected results the muxer should return, i.e., the search
     68  //   results. Each object in the array describes a slice of expected results.
     69  //   The size of the slice is defined by the `count` property.
     70  //     * {UrlbarUtils.RESULT_GROUP} group
     71  //       The expected group of the results in the slice.
     72  //     * {number} count
     73  //       The number of results in the slice.
     74  //     * {number} [offset]
     75  //       Can be used to offset the starting index of the slice in the results.
     76  // * {array} [otherResults]
     77  //   An array of results besides the group-relative suggestedIndex results
     78  //   that the provider should return. If not specified `basicResults` is used.
     79  // * {array} [resultGroups]
     80  //   The result groups to use. If not specified `RESULT_GROUPS` is used.
     81  // * {number} [maxRichResults]
     82  //   The `maxRichResults` pref will be set to this value. If not specified
     83  //   `MAX_RESULTS` is used.
     84  let tests = [
     85    {
     86      desc: "First result in GENERAL",
     87      suggestedIndexResults: [
     88        {
     89          suggestedIndex: 0,
     90          group: UrlbarUtils.RESULT_GROUP.GENERAL,
     91        },
     92      ],
     93      expected: [
     94        {
     95          group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
     96          count: 4,
     97        },
     98        {
     99          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    100          suggestedIndex: 0,
    101        },
    102        {
    103          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    104          count: 2,
    105        },
    106        {
    107          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    108          // The muxer will remove the first 4 remote suggestions because they
    109          // dupe the earlier form history.
    110          offset: 4,
    111          count: 3,
    112        },
    113      ],
    114    },
    115 
    116    {
    117      desc: "Last result in GENERAL",
    118      suggestedIndexResults: [
    119        {
    120          suggestedIndex: -1,
    121          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    122        },
    123      ],
    124      expected: [
    125        {
    126          group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
    127          count: 4,
    128        },
    129        {
    130          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    131          count: 2,
    132        },
    133        {
    134          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    135          suggestedIndex: -1,
    136        },
    137        {
    138          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    139          // The muxer will remove the first 4 remote suggestions because they
    140          // dupe the earlier form history.
    141          offset: 4,
    142          count: 3,
    143        },
    144      ],
    145    },
    146 
    147    {
    148      desc: "First result in GENERAL_PARENT",
    149      suggestedIndexResults: [
    150        {
    151          suggestedIndex: 0,
    152          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    153        },
    154      ],
    155      expected: [
    156        {
    157          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    158          suggestedIndex: 0,
    159        },
    160        {
    161          group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
    162          count: 3,
    163        },
    164        {
    165          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    166          count: 3,
    167        },
    168        {
    169          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    170          // The muxer will remove the first 3 remote suggestions because they
    171          // dupe the earlier form history.
    172          offset: 3,
    173          count: 3,
    174        },
    175      ],
    176    },
    177 
    178    {
    179      desc: "Last result in GENERAL_PARENT",
    180      suggestedIndexResults: [
    181        {
    182          suggestedIndex: -1,
    183          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    184        },
    185      ],
    186      expected: [
    187        {
    188          group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
    189          count: 3,
    190        },
    191        {
    192          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    193          count: 3,
    194        },
    195        {
    196          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    197          // The muxer will remove the first 3 remote suggestions because they
    198          // dupe the earlier form history.
    199          offset: 3,
    200          count: 3,
    201        },
    202        {
    203          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    204          suggestedIndex: -1,
    205        },
    206      ],
    207    },
    208 
    209    {
    210      desc: "First and last results in GENERAL",
    211      suggestedIndexResults: [
    212        {
    213          suggestedIndex: 0,
    214          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    215        },
    216        {
    217          suggestedIndex: -1,
    218          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    219        },
    220      ],
    221      expected: [
    222        {
    223          group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
    224          count: 4,
    225        },
    226        {
    227          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    228          suggestedIndex: 0,
    229        },
    230        {
    231          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    232          count: 1,
    233        },
    234        {
    235          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    236          suggestedIndex: -1,
    237        },
    238        {
    239          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    240          // The muxer will remove the first 4 remote suggestions because they
    241          // dupe the earlier form history.
    242          offset: 4,
    243          count: 3,
    244        },
    245      ],
    246    },
    247 
    248    {
    249      desc: "First and last results in GENERAL_PARENT",
    250      suggestedIndexResults: [
    251        {
    252          suggestedIndex: 0,
    253          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    254        },
    255        {
    256          suggestedIndex: -1,
    257          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    258        },
    259      ],
    260      expected: [
    261        {
    262          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    263          suggestedIndex: 0,
    264        },
    265        {
    266          group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
    267          count: 3,
    268        },
    269        {
    270          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    271          count: 3,
    272        },
    273        {
    274          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    275          // The muxer will remove the first 3 remote suggestions because they
    276          // dupe the earlier form history.
    277          offset: 3,
    278          count: 2,
    279        },
    280        {
    281          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    282          suggestedIndex: -1,
    283        },
    284      ],
    285    },
    286 
    287    {
    288      desc: "First result in GENERAL_PARENT, first result in GENERAL",
    289      suggestedIndexResults: [
    290        {
    291          suggestedIndex: 0,
    292          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    293        },
    294        {
    295          suggestedIndex: 0,
    296          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    297        },
    298      ],
    299      expected: [
    300        {
    301          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    302          suggestedIndex: 0,
    303        },
    304        {
    305          group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
    306          count: 3,
    307        },
    308        {
    309          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    310          suggestedIndex: 0,
    311        },
    312        {
    313          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    314          count: 2,
    315        },
    316        {
    317          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    318          // The muxer will remove the first 3 remote suggestions because they
    319          // dupe the earlier form history.
    320          offset: 3,
    321          count: 3,
    322        },
    323      ],
    324    },
    325 
    326    {
    327      desc: "Results in sibling group, no other results in same group",
    328      otherResults: makeFormHistoryResults(),
    329      suggestedIndexResults: [
    330        {
    331          suggestedIndex: -1,
    332          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    333        },
    334      ],
    335      expected: [
    336        {
    337          group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
    338          count: 9,
    339        },
    340        {
    341          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    342          suggestedIndex: -1,
    343        },
    344      ],
    345    },
    346 
    347    {
    348      desc: "Results in sibling group, no other results in same group, has child group",
    349      resultGroups: {
    350        flexChildren: true,
    351        children: [
    352          {
    353            flex: 2,
    354            group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    355          },
    356          {
    357            flex: 1,
    358            group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    359            children: [{ group: UrlbarUtils.RESULT_GROUP.GENERAL }],
    360          },
    361        ],
    362      },
    363      otherResults: makeRemoteSuggestionResults(),
    364      suggestedIndexResults: [
    365        {
    366          suggestedIndex: -1,
    367          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    368        },
    369      ],
    370      expected: [
    371        {
    372          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    373          count: 9,
    374        },
    375        {
    376          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    377          suggestedIndex: -1,
    378        },
    379      ],
    380    },
    381 
    382    {
    383      desc: "Complex group nesting with global suggestedIndex with resultSpan",
    384      resultGroups: {
    385        children: [
    386          {
    387            maxResultCount: 1,
    388            children: [{ group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST }],
    389          },
    390          {
    391            flexChildren: true,
    392            children: [
    393              {
    394                flex: 2,
    395                group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    396              },
    397              {
    398                flex: 1,
    399                group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    400                children: [{ group: UrlbarUtils.RESULT_GROUP.GENERAL }],
    401              },
    402            ],
    403          },
    404        ],
    405      },
    406      otherResults: [
    407        // heuristic
    408        new UrlbarResult({
    409          type: UrlbarUtils.RESULT_TYPE.SEARCH,
    410          source: UrlbarUtils.RESULT_SOURCE.SEARCH,
    411          heuristic: true,
    412          group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
    413          payload: {
    414            engine: "test",
    415            suggestion: "foo",
    416            lowerCaseSuggestion: "foo",
    417          },
    418        }),
    419        // global suggestedIndex with resultSpan = 2
    420        new UrlbarResult({
    421          type: UrlbarUtils.RESULT_TYPE.SEARCH,
    422          source: UrlbarUtils.RESULT_SOURCE.SEARCH,
    423          suggestedIndex: 1,
    424          resultSpan: 2,
    425          payload: {
    426            engine: "test",
    427          },
    428        }),
    429        // remote suggestions
    430        ...makeRemoteSuggestionResults(),
    431      ],
    432      suggestedIndexResults: [
    433        {
    434          suggestedIndex: -1,
    435          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    436        },
    437      ],
    438      expected: [
    439        {
    440          group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
    441          count: 1,
    442        },
    443        {
    444          group: UrlbarUtils.RESULT_GROUP.SUGGESTED_INDEX,
    445          suggestedIndex: 1,
    446          resultSpan: 2,
    447          count: 1,
    448        },
    449        {
    450          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    451          count: 6,
    452        },
    453        {
    454          group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
    455          suggestedIndex: -1,
    456        },
    457      ],
    458    },
    459 
    460    {
    461      desc: "Last result in REMOTE_SUGGESTION, maxRichResults too small to add any REMOTE_SUGGESTION",
    462      maxRichResults: 2,
    463      suggestedIndexResults: [
    464        {
    465          suggestedIndex: -1,
    466          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    467        },
    468      ],
    469      expected: [
    470        {
    471          group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
    472          count: 1,
    473        },
    474        {
    475          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    476          count: 1,
    477        },
    478        // The suggestedIndex result should not be added.
    479      ],
    480    },
    481 
    482    {
    483      desc: "Last result in REMOTE_SUGGESTION, maxRichResults just big enough to show one REMOTE_SUGGESTION",
    484      maxRichResults: 3,
    485      suggestedIndexResults: [
    486        {
    487          suggestedIndex: -1,
    488          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    489        },
    490      ],
    491      expected: [
    492        {
    493          group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
    494          count: 1,
    495        },
    496        {
    497          group: UrlbarUtils.RESULT_GROUP.GENERAL,
    498          count: 1,
    499        },
    500        {
    501          group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
    502          suggestedIndex: -1,
    503        },
    504      ],
    505    },
    506  ];
    507 
    508  let controller = UrlbarTestUtils.newMockController();
    509 
    510  for (let {
    511    desc,
    512    suggestedIndexResults,
    513    expected,
    514    resultGroups,
    515    otherResults,
    516    maxRichResults = MAX_RESULTS,
    517  } of tests) {
    518    info(`Running test: ${desc}`);
    519 
    520    setResultGroups(resultGroups || RESULT_GROUPS);
    521 
    522    UrlbarPrefs.set("maxRichResults", maxRichResults);
    523 
    524    // Make the array of all results and do a search.
    525    let results = (otherResults || basicResults).concat(
    526      makeSuggestedIndexResults(suggestedIndexResults)
    527    );
    528    let provider = registerBasicTestProvider(results);
    529    let context = createContext(undefined, { providers: [provider.name] });
    530    await UrlbarProvidersManager.startQuery(context, controller);
    531 
    532    // Make the list of expected results.
    533    let expectedResults = [];
    534    for (let { group, offset, count, suggestedIndex } of expected) {
    535      // Find the index in `results` of the expected result.
    536      let index = results.findIndex(
    537        r =>
    538          UrlbarUtils.getResultGroup(r) == group &&
    539          r.suggestedIndex === suggestedIndex
    540      );
    541      Assert.notEqual(
    542        index,
    543        -1,
    544        "Sanity check: Expected result is in `results`"
    545      );
    546      if (offset) {
    547        index += offset;
    548      }
    549 
    550      // Extract the expected number of results from `results` and append them
    551      // to the expected results array.
    552      count = count || 1;
    553      expectedResults.push(...results.slice(index, index + count));
    554    }
    555 
    556    Assert.deepEqual(context.results, expectedResults);
    557 
    558    UrlbarProvidersManager.unregisterProvider(provider);
    559  }
    560 });
    561 
    562 function makeHistoryResults(count = MAX_RESULTS) {
    563  let results = [];
    564  for (let i = 0; i < count; i++) {
    565    results.push(
    566      new UrlbarResult({
    567        type: UrlbarUtils.RESULT_TYPE.URL,
    568        source: UrlbarUtils.RESULT_SOURCE.HISTORY,
    569        payload: { url: "http://example.com/" + i },
    570      })
    571    );
    572  }
    573  return results;
    574 }
    575 
    576 function makeRemoteSuggestionResults(count = MAX_RESULTS) {
    577  let results = [];
    578  for (let i = 0; i < count; i++) {
    579    results.push(
    580      new UrlbarResult({
    581        type: UrlbarUtils.RESULT_TYPE.SEARCH,
    582        source: UrlbarUtils.RESULT_SOURCE.SEARCH,
    583        payload: {
    584          engine: "test",
    585          query: "test",
    586          suggestion: "test " + i,
    587          lowerCaseSuggestion: "test " + i,
    588        },
    589      })
    590    );
    591  }
    592  return results;
    593 }
    594 
    595 function makeFormHistoryResults(count = MAX_RESULTS) {
    596  let results = [];
    597  for (let i = 0; i < count; i++) {
    598    results.push(
    599      new UrlbarResult({
    600        type: UrlbarUtils.RESULT_TYPE.SEARCH,
    601        source: UrlbarUtils.RESULT_SOURCE.HISTORY,
    602        payload: {
    603          engine: "test",
    604          suggestion: "test " + i,
    605          lowerCaseSuggestion: "test " + i,
    606        },
    607      })
    608    );
    609  }
    610  return results;
    611 }
    612 
    613 function makeSuggestedIndexResults(objects) {
    614  return objects.map(({ suggestedIndex, group }) =>
    615    Object.assign(
    616      new UrlbarResult({
    617        type: UrlbarUtils.RESULT_TYPE.URL,
    618        source: UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
    619        group,
    620        suggestedIndex,
    621        isSuggestedIndexRelativeToGroup: true,
    622        payload: {
    623          url: "http://example.com/si " + suggestedIndex,
    624        },
    625      })
    626    )
    627  );
    628 }
    629 
    630 function setResultGroups(resultGroups) {
    631  sandbox.restore();
    632  if (resultGroups) {
    633    sandbox.stub(UrlbarPrefs, "getResultGroups").returns(resultGroups);
    634  }
    635 }