summaryrefslogtreecommitdiffstats
path: root/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_addResults.js
blob: 024f5526a60a42e86916f8059bf646a0fdd1fb57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Tests the chunking feature of `RemoteSettingsClient.#addResults()`.

"use strict";

XPCOMUtils.defineLazyModuleGetters(this, {
  ObjectUtils: "resource://gre/modules/ObjectUtils.jsm",
});

// This overrides `QuickSuggest.remoteSettings._addResultsChunkSize`. Testing
// the actual value can make the test run too long. This is OK because the
// correctness of the chunking behavior doesn't depend on the chunk size.
const TEST_ADD_RESULTS_CHUNK_SIZE = 100;

add_task(async function init() {
  UrlbarPrefs.set("quicksuggest.enabled", true);
  await QuickSuggestTestUtils.ensureQuickSuggestInit();

  // Sanity check the actual `_addResultsChunkSize` value.
  Assert.equal(
    typeof QuickSuggest.remoteSettings._addResultsChunkSize,
    "number",
    "Sanity check: _addResultsChunkSize is a number"
  );
  Assert.greater(
    QuickSuggest.remoteSettings._addResultsChunkSize,
    0,
    "Sanity check: _addResultsChunkSize > 0"
  );

  // Set our test value.
  QuickSuggest.remoteSettings._addResultsChunkSize = TEST_ADD_RESULTS_CHUNK_SIZE;
});

// Tests many results with one keyword each.
add_task(async function chunking_singleKeyword() {
  let resultCounts = [
    1 * QuickSuggest.remoteSettings._addResultsChunkSize - 1,
    1 * QuickSuggest.remoteSettings._addResultsChunkSize,
    1 * QuickSuggest.remoteSettings._addResultsChunkSize + 1,
    2 * QuickSuggest.remoteSettings._addResultsChunkSize - 1,
    2 * QuickSuggest.remoteSettings._addResultsChunkSize,
    2 * QuickSuggest.remoteSettings._addResultsChunkSize + 1,
    3 * QuickSuggest.remoteSettings._addResultsChunkSize - 1,
    3 * QuickSuggest.remoteSettings._addResultsChunkSize,
    3 * QuickSuggest.remoteSettings._addResultsChunkSize + 1,
  ];
  for (let count of resultCounts) {
    await doChunkingTest(count, 1);
  }
});

// Tests a small number of results with many keywords each.
add_task(async function chunking_manyKeywords() {
  let keywordCounts = [
    1 * QuickSuggest.remoteSettings._addResultsChunkSize - 1,
    1 * QuickSuggest.remoteSettings._addResultsChunkSize,
    1 * QuickSuggest.remoteSettings._addResultsChunkSize + 1,
    2 * QuickSuggest.remoteSettings._addResultsChunkSize - 1,
    2 * QuickSuggest.remoteSettings._addResultsChunkSize,
    2 * QuickSuggest.remoteSettings._addResultsChunkSize + 1,
    3 * QuickSuggest.remoteSettings._addResultsChunkSize - 1,
    3 * QuickSuggest.remoteSettings._addResultsChunkSize,
    3 * QuickSuggest.remoteSettings._addResultsChunkSize + 1,
  ];
  for (let resultCount = 1; resultCount <= 3; resultCount++) {
    for (let keywordCount of keywordCounts) {
      await doChunkingTest(resultCount, keywordCount);
    }
  }
});

async function doChunkingTest(resultCount, keywordCountPerResult) {
  info(
    "Running chunking test: " +
      JSON.stringify({ resultCount, keywordCountPerResult })
  );

  // Create `resultCount` results, each with `keywordCountPerResult` keywords.
  let results = [];
  for (let i = 0; i < resultCount; i++) {
    let keywords = [];
    for (let k = 0; k < keywordCountPerResult; k++) {
      keywords.push(`keyword-${i}-${k}`);
    }
    results.push({
      keywords,
      id: i,
      url: "http://example.com/" + i,
      title: "Suggestion " + i,
      click_url: "http://example.com/click",
      impression_url: "http://example.com/impression",
      advertiser: "TestAdvertiser",
      iab_category: "22 - Shopping",
    });
  }

  // Add the results.
  QuickSuggest.remoteSettings._test_resultsByKeyword.clear();
  await QuickSuggest.remoteSettings._test_addResults(results);

  // Make sure all keyword-result pairs have been added.
  for (let i = 0; i < resultCount; i++) {
    for (let k = 0; k < keywordCountPerResult; k++) {
      let keyword = `keyword-${i}-${k}`;

      // Check the resultsByKeyword map. Logging all assertions takes a ton of
      // time and makes the test run much longer than it otherwise would,
      // especially if `_addResultsChunkSize` is large, so only log failing
      // assertions.
      let actualResult = QuickSuggest.remoteSettings._test_resultsByKeyword.get(
        keyword
      );
      if (!ObjectUtils.deepEqual(actualResult, results[i])) {
        Assert.deepEqual(
          actualResult,
          results[i],
          `Result ${i} is in _test_resultsByKeyword for keyword ${keyword}`
        );
      }

      // Call `query()` and make sure a suggestion is returned for the result.
      // Computing the expected value of `full_keyword` is kind of a pain and
      // it's not important to check it, so first delete it from the returned
      // suggestion.
      let actualSuggestions = await QuickSuggest.remoteSettings.fetch(keyword);
      for (let s of actualSuggestions) {
        delete s.full_keyword;
      }
      let expectedSuggestions = [
        {
          block_id: i,
          url: "http://example.com/" + i,
          title: "Suggestion " + i,
          click_url: "http://example.com/click",
          impression_url: "http://example.com/impression",
          advertiser: "TestAdvertiser",
          iab_category: "22 - Shopping",
          is_sponsored: true,
          score: RemoteSettingsClient.DEFAULT_SUGGESTION_SCORE,
          source: "remote-settings",
          icon: null,
          position: undefined,
        },
      ];
      if (!ObjectUtils.deepEqual(actualSuggestions, expectedSuggestions)) {
        Assert.deepEqual(
          actualSuggestions,
          expectedSuggestions,
          `query() returns a suggestion for result ${i} with keyword ${keyword}`
        );
      }
    }
  }
}