summaryrefslogtreecommitdiffstats
path: root/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_merinoSessions.js
blob: 935577c36c9eeca5e01434df2d0e753c5210d0e3 (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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* 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 Merino session integration with UrlbarProviderQuickSuggest.

"use strict";

// `UrlbarProviderQuickSuggest.#merino` is lazily created on the first Merino
// fetch, so it's easiest to create `gClient` lazily too.
XPCOMUtils.defineLazyGetter(
  this,
  "gClient",
  () => UrlbarProviderQuickSuggest._test_merino
);

add_task(async function init() {
  UrlbarPrefs.set("quicksuggest.enabled", true);
  UrlbarPrefs.set("suggest.quicksuggest.sponsored", true);
  UrlbarPrefs.set("merino.enabled", true);
  UrlbarPrefs.set("quicksuggest.remoteSettings.enabled", false);
  UrlbarPrefs.set("quicksuggest.dataCollection.enabled", true);

  await MerinoTestUtils.server.start();
  await QuickSuggestTestUtils.ensureQuickSuggestInit();
});

// In a single engagement, all requests should use the same session ID and the
// sequence number should be incremented.
add_task(async function singleEngagement() {
  let controller = UrlbarTestUtils.newMockController();

  for (let i = 0; i < 3; i++) {
    let searchString = "search" + i;
    await controller.startQuery(
      createContext(searchString, {
        providers: [UrlbarProviderQuickSuggest.name],
        isPrivate: false,
      })
    );

    MerinoTestUtils.server.checkAndClearRequests([
      {
        params: {
          [MerinoTestUtils.SEARCH_PARAMS.QUERY]: searchString,
          [MerinoTestUtils.SEARCH_PARAMS.SEQUENCE_NUMBER]: i,
        },
      },
    ]);
  }

  // End the engagement to reset the session for the next test.
  endEngagement();
});

// New engagements should not use the same session ID as previous engagements
// and the sequence number should be reset. This task completes each engagement
// successfully.
add_task(async function manyEngagements_engagement() {
  await doManyEngagementsTest("engagement");
});

// New engagements should not use the same session ID as previous engagements
// and the sequence number should be reset. This task abandons each engagement.
add_task(async function manyEngagements_abandonment() {
  await doManyEngagementsTest("abandonment");
});

async function doManyEngagementsTest(state) {
  let controller = UrlbarTestUtils.newMockController();

  for (let i = 0; i < 3; i++) {
    let searchString = "search" + i;
    let context = createContext(searchString, {
      providers: [UrlbarProviderQuickSuggest.name],
      isPrivate: false,
    });
    await controller.startQuery(context);

    MerinoTestUtils.server.checkAndClearRequests([
      {
        params: {
          [MerinoTestUtils.SEARCH_PARAMS.QUERY]: searchString,
          [MerinoTestUtils.SEARCH_PARAMS.SEQUENCE_NUMBER]: 0,
        },
      },
    ]);

    endEngagement(context, state);
  }
}

// When a search is canceled after the request is sent and before the Merino
// response is received, the sequence number should still be incremented.
add_task(async function canceledQueries() {
  let controller = UrlbarTestUtils.newMockController();

  for (let i = 0; i < 3; i++) {
    // Send the first response after a delay to make sure the client will not
    // receive it before we start the second fetch.
    MerinoTestUtils.server.response.delay = UrlbarPrefs.get("merino.timeoutMs");

    // Start the first search.
    let requestPromise = MerinoTestUtils.server.waitForNextRequest();
    let searchString1 = "search" + i;
    controller.startQuery(
      createContext(searchString1, {
        providers: [UrlbarProviderQuickSuggest.name],
        isPrivate: false,
      })
    );

    // Wait until the first request is received before starting the second
    // search. If we started the second search immediately, the first would be
    // canceled before the provider is even called due to the urlbar's 50ms
    // delay (see `browser.urlbar.delay`) so the sequence number would not be
    // incremented for it. Here we want to test the case where the first search
    // is canceled after the request is sent and the number is incremented.
    await requestPromise;
    delete MerinoTestUtils.server.response.delay;

    // Now do a second search that cancels the first.
    let searchString2 = searchString1 + "again";
    await controller.startQuery(
      createContext(searchString2, {
        providers: [UrlbarProviderQuickSuggest.name],
        isPrivate: false,
      })
    );

    // The sequence number should have been incremented for each search.
    MerinoTestUtils.server.checkAndClearRequests([
      {
        params: {
          [MerinoTestUtils.SEARCH_PARAMS.QUERY]: searchString1,
          [MerinoTestUtils.SEARCH_PARAMS.SEQUENCE_NUMBER]: 2 * i,
        },
      },
      {
        params: {
          [MerinoTestUtils.SEARCH_PARAMS.QUERY]: searchString2,
          [MerinoTestUtils.SEARCH_PARAMS.SEQUENCE_NUMBER]: 2 * i + 1,
        },
      },
    ]);
  }

  // End the engagement to reset the session for the next test.
  endEngagement();
});

function endEngagement(context = null, state = "engagement") {
  UrlbarProviderQuickSuggest.onEngagement(
    false,
    state,
    context ||
      createContext("endEngagement", {
        providers: [UrlbarProviderQuickSuggest.name],
        isPrivate: false,
      }),
    { selIndex: -1 }
  );

  Assert.strictEqual(
    gClient.sessionID,
    null,
    "sessionID is null after engagement"
  );
  Assert.strictEqual(
    gClient._test_sessionTimer,
    null,
    "sessionTimer is null after engagement"
  );
}