gecko-dev/browser/components/urlbar/tests/unit/test_muxer.js
Harry Twyford b1c5a5b1f8 Bug 1715484 - Stop syncing browser.urlbar.resultBuckets and rename the pref. r=adw
I renamed the pref to resultGroups. This is similar enough that we don't have to change a lot of code. Functions and comments that refer to resultBuckets now clearly refer to resultGroups. As Marco pointed out in the bug, the renaming is necessary to avoid conflicts with old versions.

Differential Revision: https://phabricator.services.mozilla.com/D117354
2021-06-10 16:28:35 +00:00

592 lines
16 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function test_muxer() {
Assert.throws(
() => UrlbarProvidersManager.registerMuxer(),
/invalid muxer/,
"Should throw with no arguments"
);
Assert.throws(
() => UrlbarProvidersManager.registerMuxer({}),
/invalid muxer/,
"Should throw with empty object"
);
Assert.throws(
() =>
UrlbarProvidersManager.registerMuxer({
name: "",
}),
/invalid muxer/,
"Should throw with empty name"
);
Assert.throws(
() =>
UrlbarProvidersManager.registerMuxer({
name: "test",
sort: "no",
}),
/invalid muxer/,
"Should throw with invalid sort"
);
let matches = [
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.TAB_SWITCH,
UrlbarUtils.RESULT_SOURCE.TABS,
{ url: "http://mozilla.org/tab/" }
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.BOOKMARKS,
{ url: "http://mozilla.org/bookmark/" }
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/history/" }
),
];
let provider = registerBasicTestProvider(matches);
let context = createContext(undefined, { providers: [provider.name] });
let controller = UrlbarTestUtils.newMockController();
/**
* A test muxer.
*/
class TestMuxer extends UrlbarMuxer {
get name() {
return "TestMuxer";
}
sort(queryContext) {
queryContext.results.sort((a, b) => {
if (b.source == UrlbarUtils.RESULT_SOURCE.TABS) {
return -1;
}
if (b.source == UrlbarUtils.RESULT_SOURCE.BOOKMARKS) {
return 1;
}
return a.source == UrlbarUtils.RESULT_SOURCE.BOOKMARKS ? -1 : 1;
});
}
}
let muxer = new TestMuxer();
UrlbarProvidersManager.registerMuxer(muxer);
context.muxer = "TestMuxer";
info("Check results, the order should be: bookmark, history, tab");
await UrlbarProvidersManager.startQuery(context, controller);
Assert.deepEqual(context.results, [matches[1], matches[2], matches[0]]);
// Sanity check, should not throw.
UrlbarProvidersManager.unregisterMuxer(muxer);
UrlbarProvidersManager.unregisterMuxer("TestMuxer"); // no-op.
});
add_task(async function test_preselectedHeuristic_singleProvider() {
let matches = [
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/a" }
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/b" }
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/c" }
),
];
matches[1].heuristic = true;
let provider = registerBasicTestProvider(matches);
let context = createContext(undefined, {
providers: [provider.name],
});
let controller = UrlbarTestUtils.newMockController();
info("Check results, the order should be: b (heuristic), a, c");
await UrlbarProvidersManager.startQuery(context, controller);
Assert.deepEqual(context.results, [matches[1], matches[0], matches[2]]);
});
add_task(async function test_preselectedHeuristic_multiProviders() {
let matches1 = [
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/a" }
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/b" }
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/c" }
),
];
let matches2 = [
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/d" }
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/e" }
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/f" }
),
];
matches2[1].heuristic = true;
let provider1 = registerBasicTestProvider(matches1);
let provider2 = registerBasicTestProvider(matches2);
let context = createContext(undefined, {
providers: [provider1.name, provider2.name],
});
let controller = UrlbarTestUtils.newMockController();
info("Check results, the order should be: e (heuristic), a, b, c, d, f");
await UrlbarProvidersManager.startQuery(context, controller);
Assert.deepEqual(context.results, [
matches2[1],
...matches1,
matches2[0],
matches2[2],
]);
});
add_task(async function test_suggestions() {
Services.prefs.setIntPref("browser.urlbar.maxHistoricalSearchSuggestions", 1);
let matches = [
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/a" }
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/b" }
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.SEARCH,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{
engine: "mozSearch",
query: "moz",
suggestion: "mozzarella",
lowerCaseSuggestion: "mozzarella",
}
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.SEARCH,
UrlbarUtils.RESULT_SOURCE.SEARCH,
{
engine: "mozSearch",
query: "moz",
suggestion: "mozilla",
lowerCaseSuggestion: "mozilla",
}
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.SEARCH,
UrlbarUtils.RESULT_SOURCE.SEARCH,
{
engine: "mozSearch",
query: "moz",
providesSearchMode: true,
keyword: "@moz",
}
),
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/c" }
),
];
let provider = registerBasicTestProvider(matches);
let context = createContext(undefined, {
providers: [provider.name],
});
let controller = UrlbarTestUtils.newMockController();
info("Check results, the order should be: mozzarella, moz, a, b, @moz, c");
await UrlbarProvidersManager.startQuery(context, controller);
Assert.deepEqual(context.results, [
matches[2],
matches[3],
matches[0],
matches[1],
matches[4],
matches[5],
]);
Services.prefs.clearUserPref("browser.urlbar.maxHistoricalSearchSuggestions");
});
add_task(async function test_deduplicate_for_unitConversion() {
const searchSuggestion = new UrlbarResult(
UrlbarUtils.RESULT_TYPE.SEARCH,
UrlbarUtils.RESULT_SOURCE.SEARCH,
{
engine: "Google",
query: "10cm to m",
suggestion: "= 0.1 meters",
}
);
const searchProvider = registerBasicTestProvider(
[searchSuggestion],
null,
UrlbarUtils.PROVIDER_TYPE.PROFILE
);
const unitConversionSuggestion = new UrlbarResult(
UrlbarUtils.RESULT_TYPE.DYNAMIC,
UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
{
dynamicType: "unitConversion",
output: "0.1 m",
input: "10cm to m",
}
);
unitConversionSuggestion.suggestedIndex = 1;
const unitConversion = registerBasicTestProvider(
[unitConversionSuggestion],
null,
UrlbarUtils.PROVIDER_TYPE.PROFILE,
"UnitConversion"
);
const context = createContext(undefined, {
providers: [searchProvider.name, unitConversion.name],
});
const controller = UrlbarTestUtils.newMockController();
await UrlbarProvidersManager.startQuery(context, controller);
Assert.deepEqual(context.results, [unitConversionSuggestion]);
});
// These results are used in the badHeuristicBuckets tests below. The order of
// the results in the array isn't important because they all get added at the
// same time. It's the resultGroups in each test that is important.
const BAD_HEURISTIC_RESULTS = [
// heuristic
Object.assign(
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/heuristic-0" }
),
{ heuristic: true }
),
// heuristic
Object.assign(
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/heuristic-1" }
),
{ heuristic: true }
),
// non-heuristic
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/non-heuristic-0" }
),
// non-heuristic
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
{ url: "http://mozilla.org/non-heuristic-1" }
),
];
const BAD_HEURISTIC_RESULTS_FIRST_HEURISTIC = BAD_HEURISTIC_RESULTS[0];
const BAD_HEURISTIC_RESULTS_GENERAL = [
BAD_HEURISTIC_RESULTS[2],
BAD_HEURISTIC_RESULTS[3],
];
add_task(async function test_badHeuristicBuckets_multiple_0() {
await doBadHeuristicBucketsTest(
[
// 2 heuristics with child buckets
{
maxResultCount: 2,
children: [{ group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST }],
},
// infinite general
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
],
[BAD_HEURISTIC_RESULTS_FIRST_HEURISTIC, ...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
add_task(async function test_badHeuristicBuckets_multiple_1() {
await doBadHeuristicBucketsTest(
[
// infinite heuristics with child buckets
{
children: [{ group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST }],
},
// infinite general
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
],
[BAD_HEURISTIC_RESULTS_FIRST_HEURISTIC, ...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
add_task(async function test_badHeuristicBuckets_multiple_2() {
await doBadHeuristicBucketsTest(
[
// 2 heuristics
{
maxResultCount: 2,
group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
},
// infinite general
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
],
[BAD_HEURISTIC_RESULTS_FIRST_HEURISTIC, ...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
add_task(async function test_badHeuristicBuckets_multiple_3() {
await doBadHeuristicBucketsTest(
[
// infinite heuristics
{
group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
},
// infinite general
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
],
[BAD_HEURISTIC_RESULTS_FIRST_HEURISTIC, ...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
add_task(async function test_badHeuristicBuckets_multiple_4() {
await doBadHeuristicBucketsTest(
[
// 1 heuristic with child buckets
{
maxResultCount: 1,
children: [{ group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST }],
},
// infinite general
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
// 1 heuristic with child buckets
{
maxResultCount: 1,
children: [{ group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST }],
},
],
[BAD_HEURISTIC_RESULTS_FIRST_HEURISTIC, ...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
add_task(async function test_badHeuristicBuckets_multiple_5() {
await doBadHeuristicBucketsTest(
[
// infinite heuristics with child buckets
{
children: [{ group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST }],
},
// infinite general
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
// infinite heuristics with child buckets
{
children: [{ group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST }],
},
],
[BAD_HEURISTIC_RESULTS_FIRST_HEURISTIC, ...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
add_task(async function test_badHeuristicBuckets_multiple_6() {
await doBadHeuristicBucketsTest(
[
// 1 heuristic
{
maxResultCount: 1,
group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
},
// infinite general
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
// 1 heuristic
{
maxResultCount: 1,
group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
},
],
[BAD_HEURISTIC_RESULTS_FIRST_HEURISTIC, ...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
add_task(async function test_badHeuristicBuckets_multiple_7() {
await doBadHeuristicBucketsTest(
[
// infinite heuristics
{
group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
},
// infinite general
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
// infinite heuristics
{
group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
},
],
[BAD_HEURISTIC_RESULTS_FIRST_HEURISTIC, ...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
add_task(async function test_badHeuristicsBuckets_notFirst_0() {
await doBadHeuristicBucketsTest(
[
// infinite general first
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
// 1 heuristic with child buckets second
{
maxResultCount: 1,
children: [{ group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST }],
},
],
[...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
add_task(async function test_badHeuristicsBuckets_notFirst_1() {
await doBadHeuristicBucketsTest(
[
// infinite general first
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
// infinite heuristics with child buckets second
{
children: [{ group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST }],
},
],
[...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
add_task(async function test_badHeuristicsBuckets_notFirst_2() {
await doBadHeuristicBucketsTest(
[
// infinite general first
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
// 1 heuristic second
{
maxResultCount: 1,
group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
},
],
[...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
add_task(async function test_badHeuristicsBuckets_notFirst_3() {
await doBadHeuristicBucketsTest(
[
// infinite general first
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
// infinite heuristics second
{
group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
},
],
[...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
add_task(async function test_badHeuristicsBuckets_notFirst_4() {
await doBadHeuristicBucketsTest(
[
// 1 general first
{
maxResultCount: 1,
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
// infinite heuristics second
{
group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST,
},
// infinite general third
{
group: UrlbarUtils.RESULT_GROUP.GENERAL,
},
],
[...BAD_HEURISTIC_RESULTS_GENERAL]
);
});
/**
* Sets the resultGroups pref, performs a search, and then checks the results.
* Regardless of the buckets, the muxer should include at most one heuristic in
* its results and it should always be the first result.
*
* @param {array} resultBuckets
* The result buckets.
* @param {array} expectedResults
* The expected results.
*/
async function doBadHeuristicBucketsTest(resultBuckets, expectedResults) {
Services.prefs.setCharPref(
"browser.urlbar.resultGroups",
JSON.stringify({ children: resultBuckets })
);
let provider = registerBasicTestProvider(BAD_HEURISTIC_RESULTS);
let context = createContext("foo", { providers: [provider.name] });
let controller = UrlbarTestUtils.newMockController();
await UrlbarProvidersManager.startQuery(context, controller);
Assert.deepEqual(context.results, expectedResults);
Services.prefs.clearUserPref("browser.urlbar.resultGroups");
}