645 lines
16 KiB
JavaScript
645 lines
16 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
// Tests results with `suggestedIndex` and `isSuggestedIndexRelativeToGroup`.
|
|
|
|
"use strict";
|
|
|
|
const lazy = {};
|
|
|
|
ChromeUtils.defineESModuleGetters(lazy, {
|
|
sinon: "resource://testing-common/Sinon.sys.mjs",
|
|
});
|
|
|
|
const MAX_RESULTS = 10;
|
|
|
|
// Default result groups used in the tests below.
|
|
const RESULT_GROUPS = {
|
|
children: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
flexChildren: true,
|
|
children: [
|
|
{
|
|
flex: 1,
|
|
group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
|
|
},
|
|
{
|
|
flex: 1,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
},
|
|
{
|
|
flex: 1,
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
|
|
let sandbox;
|
|
add_setup(async () => {
|
|
sandbox = lazy.sinon.createSandbox();
|
|
registerCleanupFunction(() => {
|
|
sandbox.restore();
|
|
});
|
|
});
|
|
|
|
add_task(async function test() {
|
|
// Create the default non-suggestedIndex results we'll use for tests that
|
|
// don't specify `otherResults`.
|
|
let basicResults = [
|
|
...makeHistoryResults(),
|
|
...makeFormHistoryResults(),
|
|
...makeRemoteSuggestionResults(),
|
|
];
|
|
|
|
// Test cases follow. Each object in `tests` has the following properties:
|
|
//
|
|
// * {string} desc
|
|
// * {object} suggestedIndexResults
|
|
// Describes the suggestedIndex results the test provider should return.
|
|
// Properties:
|
|
// * {number} suggestedIndex
|
|
// * {UrlbarUtils.RESULT_GROUP} group
|
|
// This will force the result to have the given group.
|
|
// * {array} expected
|
|
// Describes the expected results the muxer should return, i.e., the search
|
|
// results. Each object in the array describes a slice of expected results.
|
|
// The size of the slice is defined by the `count` property.
|
|
// * {UrlbarUtils.RESULT_GROUP} group
|
|
// The expected group of the results in the slice.
|
|
// * {number} count
|
|
// The number of results in the slice.
|
|
// * {number} [offset]
|
|
// Can be used to offset the starting index of the slice in the results.
|
|
// * {array} [otherResults]
|
|
// An array of results besides the group-relative suggestedIndex results
|
|
// that the provider should return. If not specified `basicResults` is used.
|
|
// * {array} [resultGroups]
|
|
// The result groups to use. If not specified `RESULT_GROUPS` is used.
|
|
// * {number} [maxRichResults]
|
|
// The `maxRichResults` pref will be set to this value. If not specified
|
|
// `MAX_RESULTS` is used.
|
|
let tests = [
|
|
{
|
|
desc: "First result in GENERAL",
|
|
suggestedIndexResults: [
|
|
{
|
|
suggestedIndex: 0,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
},
|
|
],
|
|
expected: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
|
|
count: 4,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
suggestedIndex: 0,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
count: 2,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
// The muxer will remove the first 4 remote suggestions because they
|
|
// dupe the earlier form history.
|
|
offset: 4,
|
|
count: 3,
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
desc: "Last result in GENERAL",
|
|
suggestedIndexResults: [
|
|
{
|
|
suggestedIndex: -1,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
},
|
|
],
|
|
expected: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
|
|
count: 4,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
count: 2,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
suggestedIndex: -1,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
// The muxer will remove the first 4 remote suggestions because they
|
|
// dupe the earlier form history.
|
|
offset: 4,
|
|
count: 3,
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
desc: "First result in GENERAL_PARENT",
|
|
suggestedIndexResults: [
|
|
{
|
|
suggestedIndex: 0,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
},
|
|
],
|
|
expected: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
suggestedIndex: 0,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
|
|
count: 3,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
count: 3,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
// The muxer will remove the first 3 remote suggestions because they
|
|
// dupe the earlier form history.
|
|
offset: 3,
|
|
count: 3,
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
desc: "Last result in GENERAL_PARENT",
|
|
suggestedIndexResults: [
|
|
{
|
|
suggestedIndex: -1,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
},
|
|
],
|
|
expected: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
|
|
count: 3,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
count: 3,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
// The muxer will remove the first 3 remote suggestions because they
|
|
// dupe the earlier form history.
|
|
offset: 3,
|
|
count: 3,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
suggestedIndex: -1,
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
desc: "First and last results in GENERAL",
|
|
suggestedIndexResults: [
|
|
{
|
|
suggestedIndex: 0,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
},
|
|
{
|
|
suggestedIndex: -1,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
},
|
|
],
|
|
expected: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
|
|
count: 4,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
suggestedIndex: 0,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
count: 1,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
suggestedIndex: -1,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
// The muxer will remove the first 4 remote suggestions because they
|
|
// dupe the earlier form history.
|
|
offset: 4,
|
|
count: 3,
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
desc: "First and last results in GENERAL_PARENT",
|
|
suggestedIndexResults: [
|
|
{
|
|
suggestedIndex: 0,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
},
|
|
{
|
|
suggestedIndex: -1,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
},
|
|
],
|
|
expected: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
suggestedIndex: 0,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
|
|
count: 3,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
count: 3,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
// The muxer will remove the first 3 remote suggestions because they
|
|
// dupe the earlier form history.
|
|
offset: 3,
|
|
count: 2,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
suggestedIndex: -1,
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
desc: "First result in GENERAL_PARENT, first result in GENERAL",
|
|
suggestedIndexResults: [
|
|
{
|
|
suggestedIndex: 0,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
},
|
|
{
|
|
suggestedIndex: 0,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
},
|
|
],
|
|
expected: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
suggestedIndex: 0,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
|
|
count: 3,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
suggestedIndex: 0,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
count: 2,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
// The muxer will remove the first 3 remote suggestions because they
|
|
// dupe the earlier form history.
|
|
offset: 3,
|
|
count: 3,
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
desc: "Results in sibling group, no other results in same group",
|
|
otherResults: makeFormHistoryResults(),
|
|
suggestedIndexResults: [
|
|
{
|
|
suggestedIndex: -1,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
},
|
|
],
|
|
expected: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
|
|
count: 9,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
suggestedIndex: -1,
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
desc: "Results in sibling group, no other results in same group, has child group",
|
|
resultGroups: {
|
|
flexChildren: true,
|
|
children: [
|
|
{
|
|
flex: 2,
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
},
|
|
{
|
|
flex: 1,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
children: [{ group: UrlbarUtils.RESULT_GROUP.GENERAL }],
|
|
},
|
|
],
|
|
},
|
|
otherResults: makeRemoteSuggestionResults(),
|
|
suggestedIndexResults: [
|
|
{
|
|
suggestedIndex: -1,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
},
|
|
],
|
|
expected: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
count: 9,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
suggestedIndex: -1,
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
desc: "Complex group nesting with global suggestedIndex with resultSpan",
|
|
resultGroups: {
|
|
children: [
|
|
{
|
|
maxResultCount: 1,
|
|
children: [{ group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST }],
|
|
},
|
|
{
|
|
flexChildren: true,
|
|
children: [
|
|
{
|
|
flex: 2,
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
},
|
|
{
|
|
flex: 1,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
children: [{ group: UrlbarUtils.RESULT_GROUP.GENERAL }],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
otherResults: [
|
|
// heuristic
|
|
Object.assign(
|
|
new UrlbarResult(
|
|
UrlbarUtils.RESULT_TYPE.SEARCH,
|
|
UrlbarUtils.RESULT_SOURCE.SEARCH,
|
|
{
|
|
engine: "test",
|
|
suggestion: "foo",
|
|
lowerCaseSuggestion: "foo",
|
|
}
|
|
),
|
|
{
|
|
heuristic: true,
|
|
group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
|
|
}
|
|
),
|
|
// global suggestedIndex with resultSpan = 2
|
|
Object.assign(
|
|
new UrlbarResult(
|
|
UrlbarUtils.RESULT_TYPE.SEARCH,
|
|
UrlbarUtils.RESULT_SOURCE.SEARCH,
|
|
{
|
|
engine: "test",
|
|
}
|
|
),
|
|
{
|
|
suggestedIndex: 1,
|
|
resultSpan: 2,
|
|
}
|
|
),
|
|
// remote suggestions
|
|
...makeRemoteSuggestionResults(),
|
|
],
|
|
suggestedIndexResults: [
|
|
{
|
|
suggestedIndex: -1,
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
},
|
|
],
|
|
expected: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
|
|
count: 1,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.SUGGESTED_INDEX,
|
|
suggestedIndex: 1,
|
|
resultSpan: 2,
|
|
count: 1,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
count: 6,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
|
|
suggestedIndex: -1,
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
desc: "Last result in REMOTE_SUGGESTION, maxRichResults too small to add any REMOTE_SUGGESTION",
|
|
maxRichResults: 2,
|
|
suggestedIndexResults: [
|
|
{
|
|
suggestedIndex: -1,
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
},
|
|
],
|
|
expected: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
|
|
count: 1,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
count: 1,
|
|
},
|
|
// The suggestedIndex result should not be added.
|
|
],
|
|
},
|
|
|
|
{
|
|
desc: "Last result in REMOTE_SUGGESTION, maxRichResults just big enough to show one REMOTE_SUGGESTION",
|
|
maxRichResults: 3,
|
|
suggestedIndexResults: [
|
|
{
|
|
suggestedIndex: -1,
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
},
|
|
],
|
|
expected: [
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
|
|
count: 1,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.GENERAL,
|
|
count: 1,
|
|
},
|
|
{
|
|
group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
|
|
suggestedIndex: -1,
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
let controller = UrlbarTestUtils.newMockController();
|
|
|
|
for (let {
|
|
desc,
|
|
suggestedIndexResults,
|
|
expected,
|
|
resultGroups,
|
|
otherResults,
|
|
maxRichResults = MAX_RESULTS,
|
|
} of tests) {
|
|
info(`Running test: ${desc}`);
|
|
|
|
setResultGroups(resultGroups || RESULT_GROUPS);
|
|
|
|
UrlbarPrefs.set("maxRichResults", maxRichResults);
|
|
|
|
// Make the array of all results and do a search.
|
|
let results = (otherResults || basicResults).concat(
|
|
makeSuggestedIndexResults(suggestedIndexResults)
|
|
);
|
|
let provider = registerBasicTestProvider(results);
|
|
let context = createContext(undefined, { providers: [provider.name] });
|
|
await UrlbarProvidersManager.startQuery(context, controller);
|
|
|
|
// Make the list of expected results.
|
|
let expectedResults = [];
|
|
for (let { group, offset, count, suggestedIndex } of expected) {
|
|
// Find the index in `results` of the expected result.
|
|
let index = results.findIndex(
|
|
r =>
|
|
UrlbarUtils.getResultGroup(r) == group &&
|
|
r.suggestedIndex === suggestedIndex
|
|
);
|
|
Assert.notEqual(
|
|
index,
|
|
-1,
|
|
"Sanity check: Expected result is in `results`"
|
|
);
|
|
if (offset) {
|
|
index += offset;
|
|
}
|
|
|
|
// Extract the expected number of results from `results` and append them
|
|
// to the expected results array.
|
|
count = count || 1;
|
|
expectedResults.push(...results.slice(index, index + count));
|
|
}
|
|
|
|
Assert.deepEqual(context.results, expectedResults);
|
|
|
|
UrlbarProvidersManager.unregisterProvider(provider);
|
|
}
|
|
});
|
|
|
|
function makeHistoryResults(count = MAX_RESULTS) {
|
|
let results = [];
|
|
for (let i = 0; i < count; i++) {
|
|
results.push(
|
|
new UrlbarResult(
|
|
UrlbarUtils.RESULT_TYPE.URL,
|
|
UrlbarUtils.RESULT_SOURCE.HISTORY,
|
|
{ url: "http://example.com/" + i }
|
|
)
|
|
);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
function makeRemoteSuggestionResults(count = MAX_RESULTS) {
|
|
let results = [];
|
|
for (let i = 0; i < count; i++) {
|
|
results.push(
|
|
new UrlbarResult(
|
|
UrlbarUtils.RESULT_TYPE.SEARCH,
|
|
UrlbarUtils.RESULT_SOURCE.SEARCH,
|
|
{
|
|
engine: "test",
|
|
query: "test",
|
|
suggestion: "test " + i,
|
|
lowerCaseSuggestion: "test " + i,
|
|
}
|
|
)
|
|
);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
function makeFormHistoryResults(count = MAX_RESULTS) {
|
|
let results = [];
|
|
for (let i = 0; i < count; i++) {
|
|
results.push(
|
|
new UrlbarResult(
|
|
UrlbarUtils.RESULT_TYPE.SEARCH,
|
|
UrlbarUtils.RESULT_SOURCE.HISTORY,
|
|
{
|
|
engine: "test",
|
|
suggestion: "test " + i,
|
|
lowerCaseSuggestion: "test " + i,
|
|
}
|
|
)
|
|
);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
function makeSuggestedIndexResults(objects) {
|
|
return objects.map(({ suggestedIndex, group }) =>
|
|
Object.assign(
|
|
new UrlbarResult(
|
|
UrlbarUtils.RESULT_TYPE.URL,
|
|
UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
|
|
{
|
|
url: "http://example.com/si " + suggestedIndex,
|
|
}
|
|
),
|
|
{
|
|
group,
|
|
suggestedIndex,
|
|
isSuggestedIndexRelativeToGroup: true,
|
|
}
|
|
)
|
|
);
|
|
}
|
|
|
|
function setResultGroups(resultGroups) {
|
|
sandbox.restore();
|
|
if (resultGroups) {
|
|
sandbox.stub(UrlbarPrefs, "resultGroups").get(() => resultGroups);
|
|
}
|
|
}
|