Bug 1881071: Stop suggest if the query length is less than length of when clicking 'Show less frequently' r=adw

Differential Revision: https://phabricator.services.mozilla.com/D202773
This commit is contained in:
Daisuke Akatsuka 2024-02-27 06:46:22 +00:00
Родитель b005b82248
Коммит 602e14aa85
5 изменённых файлов: 229 добавлений и 57 удалений

Просмотреть файл

@ -648,6 +648,10 @@ pref("browser.urlbar.suggest.mdn", true);
// Feature gate pref for Yelp suggestions in the urlbar. // Feature gate pref for Yelp suggestions in the urlbar.
pref("browser.urlbar.yelp.featureGate", false); pref("browser.urlbar.yelp.featureGate", false);
// The minimum prefix length of yelp query the user must type to trigger
// the suggestion.
pref("browser.urlbar.yelp.minKeywordLength", 5);
// If `browser.urlbar.yelp.featureGate` is true, this controls whether // If `browser.urlbar.yelp.featureGate` is true, this controls whether
// Yelp suggestions are turned on. // Yelp suggestions are turned on.
pref("browser.urlbar.suggest.yelp", true); pref("browser.urlbar.suggest.yelp", true);
@ -2501,7 +2505,7 @@ pref("identity.fxaccounts.toolbar.accessed", false);
pref("identity.fxaccounts.toolbar.defaultVisible", true); pref("identity.fxaccounts.toolbar.defaultVisible", true);
// Prefs to control Firefox Account panels that shows call to actions // Prefs to control Firefox Account panels that shows call to actions
// for other supported Mozilla products // for other supported Mozilla products
pref("identity.fxaccounts.toolbar.pxiToolbarEnabled", false); pref("identity.fxaccounts.toolbar.pxiToolbarEnabled", false);
pref("identity.fxaccounts.toolbar.pxiToolbarEnabled.monitorEnabled", true); pref("identity.fxaccounts.toolbar.pxiToolbarEnabled.monitorEnabled", true);
pref("identity.fxaccounts.toolbar.pxiToolbarEnabled.relayEnabled", true); pref("identity.fxaccounts.toolbar.pxiToolbarEnabled.relayEnabled", true);

Просмотреть файл

@ -255,7 +255,12 @@ class ProviderQuickSuggest extends UrlbarProvider {
if (details.result?.providerName == this.name) { if (details.result?.providerName == this.name) {
let feature = this.#getFeatureByResult(details.result); let feature = this.#getFeatureByResult(details.result);
if (feature?.handleCommand) { if (feature?.handleCommand) {
feature.handleCommand(controller.view, details.result, details.selType); feature.handleCommand(
controller.view,
details.result,
details.selType,
this._trimmedSearchString
);
} else if (details.selType == "dismiss") { } else if (details.selType == "dismiss") {
// Handle dismissals. // Handle dismissals.
this.#dismissResult(controller, details.result); this.#dismissResult(controller, details.result);

Просмотреть файл

@ -71,8 +71,7 @@ export class YelpSuggestions extends BaseFeature {
// return null if the entire search string is too short. // return null if the entire search string is too short.
if ( if (
(this.showLessFrequentlyCount || !suggestion.subjectExactMatch) && (this.showLessFrequentlyCount || !suggestion.subjectExactMatch) &&
searchString.length < searchString.length < this.#minKeywordLength
this.showLessFrequentlyCount + this.#minKeywordLength
) { ) {
return null; return null;
} }
@ -165,7 +164,7 @@ export class YelpSuggestions extends BaseFeature {
return commands; return commands;
} }
handleCommand(view, result, selType) { handleCommand(view, result, selType, searchString) {
switch (selType) { switch (selType) {
case RESULT_MENU_COMMAND.HELP: case RESULT_MENU_COMMAND.HELP:
// "help" is handled by UrlbarInput, no need to do anything here. // "help" is handled by UrlbarInput, no need to do anything here.
@ -199,6 +198,7 @@ export class YelpSuggestions extends BaseFeature {
if (!this.canShowLessFrequently) { if (!this.canShowLessFrequently) {
view.invalidateResultMenuCommands(); view.invalidateResultMenuCommands();
} }
lazy.UrlbarPrefs.set("yelp.minKeywordLength", searchString.length + 1);
break; break;
} }
} }
@ -213,8 +213,19 @@ export class YelpSuggestions extends BaseFeature {
} }
get #minKeywordLength() { get #minKeywordLength() {
const len = lazy.UrlbarPrefs.get("yelpMinKeywordLength") || 0; // It's unusual to get both a Nimbus variable and its fallback pref at the
return Math.max(len, 0); // same time, but we have a good reason. To recap, if a variable doesn't
// have a value, then the value of its fallback will be returned; otherwise
// the variable value will be returned. That's usually what we want, but for
// Yelp, we set the pref each time the user clicks "show less frequently",
// and we want the variable to act only as an initial min length. In other
// words, if the pref has a user value (because we set it), use it;
// otherwise use the initial value defined by the variable.
return Math.max(
lazy.UrlbarPrefs.get("yelpMinKeywordLength") || 0,
lazy.UrlbarPrefs.get("yelp.minKeywordLength") || 0,
0
);
} }
async #fetchCity() { async #fetchCity() {

Просмотреть файл

@ -81,63 +81,87 @@ add_task(async function basic() {
// Tests the "Show less frequently" result menu command. // Tests the "Show less frequently" result menu command.
add_task(async function resultMenu_show_less_frequently() { add_task(async function resultMenu_show_less_frequently() {
info("Test for no yelpMinKeywordLength and no yelpShowLessFrequentlyCap");
await doShowLessFrequently({ await doShowLessFrequently({
minKeywordLength: 0, minKeywordLength: 0,
frequentlyCap: 0, frequentlyCap: 0,
initialFrequentlyCount: 2,
testData: [ testData: [
{ {
input: "ramen", input: "best ra",
expected: { expected: {
hasSuggestion: true, hasSuggestion: true,
hasShowLessItem: true, hasShowLessItem: true,
}, },
}, },
{ {
input: "ramen", input: "best ra",
expected: {
hasSuggestion: false,
},
},
{
input: "best ram",
expected: { expected: {
hasSuggestion: true, hasSuggestion: true,
hasShowLessItem: true, hasShowLessItem: true,
}, },
}, },
{ {
input: "ramen", input: "best ram",
expected: {
hasSuggestion: false,
},
},
{
input: "best rame",
expected: { expected: {
hasSuggestion: true, hasSuggestion: true,
hasShowLessItem: true, hasShowLessItem: true,
}, },
}, },
{ {
input: "ramen", input: "best rame",
expected: { expected: {
hasSuggestion: true, hasSuggestion: false,
hasShowLessItem: true,
}, },
}, },
], ],
}); });
info("Test whether yelpShowLessFrequentlyCap can work");
await doShowLessFrequently({ await doShowLessFrequently({
minKeywordLength: 0, minKeywordLength: 0,
frequentlyCap: 4, frequentlyCap: 2,
initialFrequentlyCount: 2,
testData: [ testData: [
{ {
input: "ramen", input: "best ra",
expected: { expected: {
hasSuggestion: true, hasSuggestion: true,
hasShowLessItem: true, hasShowLessItem: true,
}, },
}, },
{ {
input: "ramen", input: "best ram",
expected: { expected: {
hasSuggestion: true, hasSuggestion: true,
hasShowLessItem: true, hasShowLessItem: true,
}, },
}, },
{ {
input: "ramen", input: "best ram",
expected: {
hasSuggestion: false,
},
},
{
input: "best rame",
expected: {
hasSuggestion: true,
hasShowLessItem: false,
},
},
{
input: "best ramen",
expected: { expected: {
hasSuggestion: true, hasSuggestion: true,
hasShowLessItem: false, hasShowLessItem: false,
@ -146,30 +170,37 @@ add_task(async function resultMenu_show_less_frequently() {
], ],
}); });
info(
"Test whether local yelp.minKeywordLength pref can override nimbus variable yelpMinKeywordLength"
);
await doShowLessFrequently({ await doShowLessFrequently({
minKeywordLength: 1, minKeywordLength: 8,
frequentlyCap: 4, frequentlyCap: 0,
initialFrequentlyCount: 2,
testData: [ testData: [
{ {
input: "ramen", input: "best ra",
expected: {
hasSuggestion: false,
},
},
{
input: "best ram",
expected: { expected: {
hasSuggestion: true, hasSuggestion: true,
hasShowLessItem: true, hasShowLessItem: true,
}, },
}, },
{ {
input: "ramen", input: "best rame",
expected: { expected: {
hasSuggestion: true, hasSuggestion: true,
hasShowLessItem: true, hasShowLessItem: true,
}, },
}, },
{ {
input: "ramen", input: "best rame",
expected: { expected: {
hasSuggestion: true, hasSuggestion: false,
hasShowLessItem: false,
}, },
}, },
], ],
@ -179,14 +210,15 @@ add_task(async function resultMenu_show_less_frequently() {
async function doShowLessFrequently({ async function doShowLessFrequently({
minKeywordLength, minKeywordLength,
frequentlyCap, frequentlyCap,
initialFrequentlyCount,
testData, testData,
}) { }) {
UrlbarPrefs.clear("yelp.showLessFrequentlyCount");
UrlbarPrefs.clear("yelp.minKeywordLength");
let cleanUpNimbus = await UrlbarTestUtils.initNimbusFeature({ let cleanUpNimbus = await UrlbarTestUtils.initNimbusFeature({
yelpMinKeywordLength: minKeywordLength, yelpMinKeywordLength: minKeywordLength,
yelpShowLessFrequentlyCap: frequentlyCap, yelpShowLessFrequentlyCap: frequentlyCap,
}); });
UrlbarPrefs.set("yelp.showLessFrequentlyCount", initialFrequentlyCount);
for (let { input, expected } of testData) { for (let { input, expected } of testData) {
await UrlbarTestUtils.promiseAutocompleteResultPopup({ await UrlbarTestUtils.promiseAutocompleteResultPopup({
@ -217,6 +249,10 @@ async function doShowLessFrequently({
UrlbarPrefs.get("yelp.showLessFrequentlyCount"), UrlbarPrefs.get("yelp.showLessFrequentlyCount"),
previousShowLessFrequentlyCount + 1 previousShowLessFrequentlyCount + 1
); );
Assert.equal(
UrlbarPrefs.get("yelp.minKeywordLength"),
input.length + 1
);
} else { } else {
let menuitem = await UrlbarTestUtils.openResultMenuAndGetItem({ let menuitem = await UrlbarTestUtils.openResultMenuAndGetItem({
window, window,
@ -238,7 +274,8 @@ async function doShowLessFrequently({
} }
await cleanUpNimbus(); await cleanUpNimbus();
UrlbarPrefs.set("yelp.showLessFrequentlyCount", 0); UrlbarPrefs.clear("yelp.showLessFrequentlyCount");
UrlbarPrefs.clear("yelp.minKeywordLength");
} }
// Tests the "Not relevant" result menu dismissal command. // Tests the "Not relevant" result menu dismissal command.

Просмотреть файл

@ -57,17 +57,6 @@ add_task(async function basic() {
title: "BeSt RaMeN dElIvErY iN tOkYo", title: "BeSt RaMeN dElIvErY iN tOkYo",
}, },
}, },
{
description: "No specific location",
query: "ramen",
expected: {
url: "https://www.yelp.com/search?find_desc=ramen&find_loc=Yokohama%2C+Kanagawa",
originalUrl: "https://www.yelp.com/search?find_desc=ramen",
displayUrl:
"yelp.com/search?find_desc=ramen&find_loc=Yokohama,+Kanagawa",
title: "ramen in Yokohama, Kanagawa",
},
},
{ {
description: "Query too short, no subject exact match: ra", description: "Query too short, no subject exact match: ra",
query: "ra", query: "ra",
@ -143,7 +132,13 @@ add_task(async function basic() {
"Subject exact match with length == minKeywordLength, showLessFrequentlyCount non-zero", "Subject exact match with length == minKeywordLength, showLessFrequentlyCount non-zero",
query: "ramen", query: "ramen",
showLessFrequentlyCount: 1, showLessFrequentlyCount: 1,
expected: null, expected: {
url: "https://www.yelp.com/search?find_desc=ramen&find_loc=Yokohama%2C+Kanagawa",
originalUrl: "https://www.yelp.com/search?find_desc=ramen",
displayUrl:
"yelp.com/search?find_desc=ramen&find_loc=Yokohama,+Kanagawa",
title: "ramen in Yokohama, Kanagawa",
},
}, },
{ {
description: "Query too short: alon", description: "Query too short: alon",
@ -166,7 +161,13 @@ add_task(async function basic() {
"Query length == minKeywordLength, subject not exact match, showLessFrequentlyCount non-zero", "Query length == minKeywordLength, subject not exact match, showLessFrequentlyCount non-zero",
query: "along", query: "along",
showLessFrequentlyCount: 1, showLessFrequentlyCount: 1,
expected: null, expected: {
url: "https://www.yelp.com/search?find_desc=alongerkeyword&find_loc=Yokohama%2C+Kanagawa",
originalUrl: "https://www.yelp.com/search?find_desc=alongerkeyword",
displayUrl:
"yelp.com/search?find_desc=alongerkeyword&find_loc=Yokohama,+Kanagawa",
title: "alongerkeyword in Yokohama, Kanagawa",
},
}, },
{ {
description: description:
@ -186,7 +187,13 @@ add_task(async function basic() {
"Query length < minKeywordLength + showLessFrequentlyCount, subject not exact match", "Query length < minKeywordLength + showLessFrequentlyCount, subject not exact match",
query: "alonge", query: "alonge",
showLessFrequentlyCount: 2, showLessFrequentlyCount: 2,
expected: null, expected: {
url: "https://www.yelp.com/search?find_desc=alongerkeyword&find_loc=Yokohama%2C+Kanagawa",
originalUrl: "https://www.yelp.com/search?find_desc=alongerkeyword",
displayUrl:
"yelp.com/search?find_desc=alongerkeyword&find_loc=Yokohama,+Kanagawa",
title: "alongerkeyword in Yokohama, Kanagawa",
},
}, },
{ {
description: description:
@ -556,27 +563,135 @@ add_task(async function notInterested() {
// Tests the "show less frequently" behavior. // Tests the "show less frequently" behavior.
add_task(async function showLessFrequently() { add_task(async function showLessFrequently() {
UrlbarPrefs.set("yelp.showLessFrequentlyCount", 0);
UrlbarPrefs.set("yelp.minKeywordLength", 0);
let cleanUpNimbus = await UrlbarTestUtils.initNimbusFeature({
yelpMinKeywordLength: 0,
yelpShowLessFrequentlyCap: 3,
});
let location = `${GEOLOCATION.city}, ${GEOLOCATION.region}`; let location = `${GEOLOCATION.city}, ${GEOLOCATION.region}`;
let originalUrl = new URL("https://www.yelp.com/search"); let originalUrl = new URL("https://www.yelp.com/search");
originalUrl.searchParams.set("find_desc", "alongerkeyword"); originalUrl.searchParams.set("find_desc", "best ramen");
let url = new URL(originalUrl); let url = new URL(originalUrl);
url.searchParams.set("find_loc", location); url.searchParams.set("find_loc", location);
await doShowLessFrequentlyTests({ let result = makeExpectedResult({
feature: QuickSuggest.getFeature("YelpSuggestions"), url: url.toString(),
showLessFrequentlyCountPref: "yelp.showLessFrequentlyCount", originalUrl: originalUrl.toString(),
nimbusCapVariable: "yelpShowLessFrequentlyCap", title: `best ramen in ${location}`,
expectedResult: () =>
makeExpectedResult({
url: url.toString(),
originalUrl: originalUrl.toString(),
title: `alongerkeyword in ${location}`,
}),
keyword: "alongerkeyword",
keywordBaseIndex: 5,
}); });
const testData = [
{
input: "best ra",
before: {
canShowLessFrequently: true,
showLessFrequentlyCount: 0,
minKeywordLength: 0,
},
after: {
canShowLessFrequently: true,
showLessFrequentlyCount: 1,
minKeywordLength: 8,
},
},
{
input: "best ram",
before: {
canShowLessFrequently: true,
showLessFrequentlyCount: 1,
minKeywordLength: 8,
},
after: {
canShowLessFrequently: true,
showLessFrequentlyCount: 2,
minKeywordLength: 9,
},
},
{
input: "best rame",
before: {
canShowLessFrequently: true,
showLessFrequentlyCount: 2,
minKeywordLength: 9,
},
after: {
canShowLessFrequently: false,
showLessFrequentlyCount: 3,
minKeywordLength: 10,
},
},
{
input: "best ramen",
before: {
canShowLessFrequently: false,
showLessFrequentlyCount: 3,
minKeywordLength: 10,
},
after: {
canShowLessFrequently: false,
showLessFrequentlyCount: 3,
minKeywordLength: 11,
},
},
];
for (let { input, before, after } of testData) {
let feature = QuickSuggest.getFeature("YelpSuggestions");
await check_results({
context: createContext(input, {
providers: [UrlbarProviderQuickSuggest.name],
isPrivate: false,
}),
matches: [result],
});
Assert.equal(
UrlbarPrefs.get("yelp.minKeywordLength"),
before.minKeywordLength
);
Assert.equal(feature.canShowLessFrequently, before.canShowLessFrequently);
Assert.equal(
feature.showLessFrequentlyCount,
before.showLessFrequentlyCount
);
feature.handleCommand(
{
acknowledgeFeedback: () => {},
invalidateResultMenuCommands: () => {},
},
result,
"show_less_frequently",
input
);
Assert.equal(
UrlbarPrefs.get("yelp.minKeywordLength"),
after.minKeywordLength
);
Assert.equal(feature.canShowLessFrequently, after.canShowLessFrequently);
Assert.equal(
feature.showLessFrequentlyCount,
after.showLessFrequentlyCount
);
await check_results({
context: createContext(input, {
providers: [UrlbarProviderQuickSuggest.name],
isPrivate: false,
}),
matches: [],
});
}
await cleanUpNimbus();
UrlbarPrefs.clear("yelp.showLessFrequentlyCount");
UrlbarPrefs.clear("yelp.minKeywordLength");
}); });
// The `Yelp` Rust provider should be passed to the Rust component when // The `Yelp` Rust provider should be passed to the Rust component when