/* 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 keywords and zero-prefix behavior of quick suggest weather. "use strict"; ChromeUtils.defineESModuleGetters(this, { UrlbarProviderWeather: "resource:///modules/UrlbarProviderWeather.sys.mjs", }); const { WEATHER_RS_DATA, WEATHER_SUGGESTION } = MerinoTestUtils; add_task(async function init() { await QuickSuggestTestUtils.ensureQuickSuggestInit({ remoteSettingsResults: [ { type: "weather", weather: WEATHER_RS_DATA, }, ], }); UrlbarPrefs.set("quicksuggest.enabled", true); await MerinoTestUtils.initWeather(); }); // * Settings data: none // * Nimbus values: none // * Min keyword length pref: none // * Expected: no suggestion add_task(async function () { await doKeywordsTest({ desc: "No data", tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: false, f: false, fo: false, for: false, fore: false, forec: false, foreca: false, forecas: false, forecast: false, }, }); }); // * Settings data: empty // * Nimbus values: none // * Min keyword length pref: none // * Expected: no suggestion add_task(async function () { await doKeywordsTest({ desc: "Empty settings", settingsData: {}, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: false, f: false, fo: false, for: false, fore: false, forec: false, foreca: false, forecas: false, forecast: false, }, }); }); // * Settings data: keywords only // * Nimbus values: none // * Min keyword length pref: none // * Expected: full keywords only add_task(async function () { await doKeywordsTest({ desc: "Settings only, keywords only", settingsData: { keywords: ["weather", "forecast"], }, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: true, f: false, fo: false, for: false, fore: false, forec: false, foreca: false, forecas: false, forecast: true, }, }); }); // * Settings data: keywords and min keyword length = 0 // * Nimbus values: none // * Min keyword length pref: none // * Expected: full keywords only add_task(async function () { await doKeywordsTest({ desc: "Settings only, min keyword length = 0", settingsData: { keywords: ["weather", "forecast"], min_keyword_length: 0, }, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: true, f: false, fo: false, for: false, fore: false, forec: false, foreca: false, forecas: false, forecast: true, }, }); }); // * Settings data: keywords and min keyword length > 0 // * Nimbus values: none // * Min keyword length pref: none // * Expected: use settings data add_task(async function () { await doKeywordsTest({ desc: "Settings only, min keyword length > 0", settingsData: { keywords: ["weather", "forecast"], min_keyword_length: 3, }, tests: { "": false, w: false, we: false, wea: true, weat: true, weath: true, weathe: true, weather: true, f: false, fo: false, for: true, fore: true, forec: true, foreca: true, forecas: true, forecast: true, }, }); }); // * Settings data: keywords and min keyword length = 0 // * Nimbus values: none // * Min keyword length pref: 6 // * Expected: use settings keywords and min keyword length pref add_task(async function () { await doKeywordsTest({ desc: "Settings only, min keyword length = 0, pref exists", settingsData: { keywords: ["weather", "forecast"], min_keyword_length: 0, }, minKeywordLength: 6, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: true, weather: true, f: false, fo: false, for: false, fore: false, forec: false, foreca: true, forecas: true, forecast: true, }, }); }); // * Settings data: keywords and min keyword length > 0 // * Nimbus values: none // * Min keyword length pref: 6 // * Expected: use settings keywords and min keyword length pref add_task(async function () { await doKeywordsTest({ desc: "Settings only, min keyword length > 0, pref exists", settingsData: { keywords: ["weather", "forecast"], min_keyword_length: 3, }, minKeywordLength: 6, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: true, weather: true, f: false, fo: false, for: false, fore: false, forec: false, foreca: true, forecas: true, forecast: true, }, }); }); // * Settings data: empty // * Nimbus values: empty // * Min keyword length pref: none // * Expected: no suggestion add_task(async function () { await doKeywordsTest({ desc: "Settings: empty; Nimbus: empty", settingsData: {}, nimbusValues: {}, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: false, f: false, fo: false, for: false, fore: false, forec: false, foreca: false, forecas: false, forecast: false, }, }); }); // * Settings data: keywords only // * Nimbus values: keywords only // * Min keyword length pref: none // * Expected: full keywords in Nimbus add_task(async function () { await doKeywordsTest({ desc: "Settings: keywords; Nimbus: keywords", settingsData: { keywords: ["weather"], }, nimbusValues: { weatherKeywords: ["forecast"], }, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: false, f: false, fo: false, for: false, fore: false, forec: false, foreca: false, forecas: false, forecast: true, }, }); }); // * Settings data: keywords and min keyword length = 0 // * Nimbus values: keywords only // * Min keyword length pref: none // * Expected: full keywords in Nimbus add_task(async function () { await doKeywordsTest({ desc: "Settings: keywords, min keyword length = 0; Nimbus: keywords", settingsData: { keywords: ["weather"], min_keyword_length: 0, }, nimbusValues: { weatherKeywords: ["forecast"], }, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: false, f: false, fo: false, for: false, fore: false, forec: false, foreca: false, forecas: false, forecast: true, }, }); }); // * Settings data: keywords and min keyword length > 0 // * Nimbus values: keywords only // * Min keyword length pref: none // * Expected: Nimbus keywords with settings min keyword length add_task(async function () { await doKeywordsTest({ desc: "Settings: keywords, min keyword length > 0; Nimbus: keywords", settingsData: { keywords: ["weather"], min_keyword_length: 3, }, nimbusValues: { weatherKeywords: ["forecast"], }, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: false, f: false, fo: false, for: true, fore: true, forec: true, foreca: true, forecas: true, forecast: true, }, }); }); // * Settings data: keywords and min keyword length > 0 // * Nimbus values: keywords and min keyword length = 0 // * Min keyword length pref: none // * Expected: Nimbus keywords with settings min keyword length add_task(async function () { await doKeywordsTest({ desc: "Settings: keywords, min keyword length > 0; Nimbus: keywords, min keyword length = 0", settingsData: { keywords: ["weather"], min_keyword_length: 3, }, nimbusValues: { weatherKeywords: ["forecast"], weatherKeywordsMinimumLength: 0, }, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: false, f: false, fo: false, for: true, fore: true, forec: true, foreca: true, forecas: true, forecast: true, }, }); }); // * Settings data: keywords and min keyword length > 0 // * Nimbus values: keywords and min keyword length > 0 // * Min keyword length pref: none // * Expected: use Nimbus values add_task(async function () { await doKeywordsTest({ desc: "Settings: keywords, min keyword length > 0; Nimbus: keywords, min keyword length > 0", settingsData: { keywords: ["weather"], min_keyword_length: 3, }, nimbusValues: { weatherKeywords: ["forecast"], weatherKeywordsMinimumLength: 4, }, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: false, f: false, fo: false, for: false, fore: true, forec: true, foreca: true, forecas: true, forecast: true, }, }); }); // * Settings data: keywords and min keyword length > 0 // * Nimbus values: keywords and min keyword length = 0 // * Min keyword length pref: exists // * Expected: Nimbus keywords with min keyword length pref add_task(async function () { await doKeywordsTest({ desc: "Settings: keywords, min keyword length > 0; Nimbus: keywords, min keyword length = 0; pref exists", settingsData: { keywords: ["weather"], min_keyword_length: 3, }, nimbusValues: { weatherKeywords: ["forecast"], weatherKeywordsMinimumLength: 0, }, minKeywordLength: 6, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: false, f: false, fo: false, for: false, fore: false, forec: false, foreca: true, forecas: true, forecast: true, }, }); }); // * Settings data: keywords and min keyword length > 0 // * Nimbus values: keywords and min keyword length > 0 // * Min keyword length pref: exists // * Expected: Nimbus keywords with min keyword length pref add_task(async function () { await doKeywordsTest({ desc: "Settings: keywords, min keyword length > 0; Nimbus: keywords, min keyword length > 0; pref exists", settingsData: { keywords: ["weather", "forecast"], min_keyword_length: 3, }, nimbusValues: { weatherKeywords: ["forecast"], weatherKeywordsMinimumLength: 4, }, minKeywordLength: 6, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: false, f: false, fo: false, for: false, fore: false, forec: false, foreca: true, forecas: true, forecast: true, }, }); }); // * Settings data: none // * Nimbus values: keywords only // * Min keyword length pref: none // * Expected: full keywords add_task(async function () { await doKeywordsTest({ desc: "Settings: none; Nimbus: keywords", nimbusValues: { weatherKeywords: ["weather", "forecast"], }, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: true, f: false, fo: false, for: false, fore: false, forec: false, foreca: false, forecas: false, forecast: true, }, }); }); // * Settings data: none // * Nimbus values: keywords and min keyword length = 0 // * Min keyword length pref: none // * Expected: full keywords add_task(async function () { await doKeywordsTest({ desc: "Settings: none; Nimbus: keywords, min keyword length = 0", nimbusValues: { weatherKeywords: ["weather", "forecast"], weatherKeywordsMinimumLength: 0, }, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: true, f: false, fo: false, for: false, fore: false, forec: false, foreca: false, forecas: false, forecast: true, }, }); }); // * Settings data: none // * Nimbus values: keywords and min keyword length > 0 // * Min keyword length pref: none // * Expected: use Nimbus values add_task(async function () { await doKeywordsTest({ desc: "Settings: none; Nimbus: keywords, min keyword length > 0", nimbusValues: { weatherKeywords: ["weather", "forecast"], weatherKeywordsMinimumLength: 3, }, tests: { "": false, w: false, we: false, wea: true, weat: true, weath: true, weathe: true, weather: true, f: false, fo: false, for: true, fore: true, forec: true, foreca: true, forecas: true, forecast: true, }, }); }); // * Settings data: none // * Nimbus values: keywords and min keyword length > 0 // * Min keyword length pref: exists // * Expected: use Nimbus keywords and min keyword length pref add_task(async function () { await doKeywordsTest({ desc: "Settings: none; Nimbus: keywords, min keyword length > 0; pref exists", nimbusValues: { weatherKeywords: ["weather", "forecast"], weatherKeywordsMinimumLength: 3, }, minKeywordLength: 6, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: true, weather: true, f: false, fo: false, for: false, fore: false, forec: false, foreca: true, forecas: true, forecast: true, }, }); }); // When `weatherKeywords` is non-null and `weatherKeywordsMinimumLength` is // larger than the length of all keywords, the suggestion should not be // triggered. add_task(async function minLength_large() { await doKeywordsTest({ desc: "Large min length", nimbusValues: { weatherKeywords: ["weather", "forecast"], weatherKeywordsMinimumLength: 999, }, tests: { "": false, w: false, we: false, wea: false, weat: false, weath: false, weathe: false, weather: false, f: false, fo: false, for: false, fore: false, forec: false, foreca: false, forecas: false, forecast: false, }, }); }); // Leading and trailing spaces should be ignored. add_task(async function leadingAndTrailingSpaces() { await doKeywordsTest({ nimbusValues: { weatherKeywords: ["weather"], weatherKeywordsMinimumLength: 3, }, tests: { " wea": true, " wea": true, "wea ": true, "wea ": true, " wea ": true, " weat": true, " weat": true, "weat ": true, "weat ": true, " weat ": true, }, }); }); add_task(async function caseInsensitive() { await doKeywordsTest({ desc: "Case insensitive", settingsData: { keywords: ["weather"], min_keyword_length: 3, }, tests: { wea: true, WEA: true, Wea: true, WeA: true, WEATHER: true, Weather: true, WeAtHeR: true, }, }); }); async function doKeywordsTest({ desc, tests, nimbusValues = null, settingsData = null, minKeywordLength = undefined, }) { info("Doing keywords test: " + desc); info(JSON.stringify({ nimbusValues, settingsData, minKeywordLength })); // If a suggestion hasn't already been fetched and the data contains keywords, // a fetch will start. Wait for it to finish below. let fetchPromise; if ( !QuickSuggest.weather.suggestion && (nimbusValues?.weatherKeywords || settingsData?.keywords) ) { fetchPromise = QuickSuggest.weather.waitForFetches(); } let nimbusCleanup; if (nimbusValues) { nimbusCleanup = await UrlbarTestUtils.initNimbusFeature(nimbusValues); } await QuickSuggestTestUtils.setRemoteSettingsResults([ { type: "weather", weather: settingsData, }, ]); if (minKeywordLength) { UrlbarPrefs.set("weather.minKeywordLength", minKeywordLength); } if (fetchPromise) { info("Waiting for fetch"); assertFetchingStarted({ pendingFetchCount: 1 }); await fetchPromise; info("Got fetch"); } for (let [searchString, expected] of Object.entries(tests)) { info( "Doing search: " + JSON.stringify({ searchString, expected, }) ); let suggestedIndex = searchString ? 1 : 0; await check_results({ context: createContext(searchString, { providers: [UrlbarProviderWeather.name], isPrivate: false, }), matches: expected ? [makeExpectedResult({ suggestedIndex })] : [], }); } await nimbusCleanup?.(); fetchPromise = null; if (!QuickSuggest.weather.suggestion) { fetchPromise = QuickSuggest.weather.waitForFetches(); } await QuickSuggestTestUtils.setRemoteSettingsResults([ { type: "weather", weather: MerinoTestUtils.WEATHER_RS_DATA, }, ]); UrlbarPrefs.clear("weather.minKeywordLength"); await fetchPromise; } // When a sponsored quick suggest result matches the same keyword as the weather // result, the weather result should be shown and the quick suggest result // should not be shown. add_task(async function matchingQuickSuggest_sponsored() { await doMatchingQuickSuggestTest("suggest.quicksuggest.sponsored", true); }); // When a non-sponsored quick suggest result matches the same keyword as the // weather result, the weather result should be shown and the quick suggest // result should not be shown. add_task(async function matchingQuickSuggest_nonsponsored() { await doMatchingQuickSuggestTest("suggest.quicksuggest.nonsponsored", false); }); async function doMatchingQuickSuggestTest(pref, isSponsored) { let keyword = "test"; let iab_category = isSponsored ? "22 - Shopping" : "5 - Education"; // Add a remote settings result to quick suggest. UrlbarPrefs.set(pref, true); await QuickSuggestTestUtils.setRemoteSettingsResults([ { type: "data", attachment: [ { id: 1, url: "http://example.com/", title: "Suggestion", keywords: [keyword], click_url: "http://example.com/click", impression_url: "http://example.com/impression", advertiser: "TestAdvertiser", iab_category, }, ], }, { type: "weather", weather: MerinoTestUtils.WEATHER_RS_DATA, }, ]); // First do a search to verify the quick suggest result matches the keyword. info("Doing first search for quick suggest result"); await check_results({ context: createContext(keyword, { providers: [UrlbarProviderQuickSuggest.name, UrlbarProviderWeather.name], isPrivate: false, }), matches: [ { type: UrlbarUtils.RESULT_TYPE.URL, source: UrlbarUtils.RESULT_SOURCE.SEARCH, heuristic: false, payload: { telemetryType: isSponsored ? "adm_sponsored" : "adm_nonsponsored", qsSuggestion: keyword, title: "Suggestion", url: "http://example.com/", displayUrl: "http://example.com", originalUrl: "http://example.com/", icon: null, sponsoredImpressionUrl: "http://example.com/impression", sponsoredClickUrl: "http://example.com/click", sponsoredBlockId: 1, sponsoredAdvertiser: "TestAdvertiser", sponsoredIabCategory: iab_category, isSponsored, helpUrl: QuickSuggest.HELP_URL, helpL10n: { id: UrlbarPrefs.get("resultMenu") ? "urlbar-result-menu-learn-more-about-firefox-suggest" : "firefox-suggest-urlbar-learn-more", }, isBlockable: UrlbarPrefs.get("quickSuggestBlockingEnabled"), blockL10n: { id: UrlbarPrefs.get("resultMenu") ? "urlbar-result-menu-dismiss-firefox-suggest" : "firefox-suggest-urlbar-block", }, source: "remote-settings", }, }, ], }); // Set up the keyword for the weather suggestion and do a second search to // verify only the weather result matches. info("Doing second search for weather suggestion"); let cleanup = await UrlbarTestUtils.initNimbusFeature({ weatherKeywords: [keyword], weatherKeywordsMinimumLength: 1, }); await check_results({ context: createContext(keyword, { providers: [UrlbarProviderQuickSuggest.name, UrlbarProviderWeather.name], isPrivate: false, }), matches: [makeExpectedResult({ suggestedIndex: 1 })], }); await cleanup(); UrlbarPrefs.clear(pref); } add_task(async function () { await doIncrementTest({ desc: "Settings only", setup: { settingsData: { keywords: ["forecast", "wind"], min_keyword_length: 3, }, }, tests: [ { minKeywordLength: 3, canIncrement: true, searches: { fo: false, for: true, fore: true, forec: true, wi: false, win: true, wind: true, }, }, { minKeywordLength: 4, canIncrement: true, searches: { fo: false, for: false, fore: true, forec: true, wi: false, win: false, wind: true, }, }, { minKeywordLength: 5, canIncrement: true, searches: { fo: false, for: false, fore: false, forec: true, wi: false, win: false, wind: false, }, }, ], }); }); add_task(async function () { await doIncrementTest({ desc: "Settings only with cap", setup: { settingsData: { keywords: ["forecast", "wind"], min_keyword_length: 3, min_keyword_length_cap: 6, }, }, tests: [ { minKeywordLength: 3, canIncrement: true, searches: { fo: false, for: true, fore: true, forec: true, foreca: true, forecas: true, wi: false, win: true, wind: true, }, }, { minKeywordLength: 4, canIncrement: true, searches: { fo: false, for: false, fore: true, forec: true, foreca: true, forecas: true, wi: false, win: false, wind: true, }, }, { minKeywordLength: 5, canIncrement: true, searches: { fo: false, for: false, fore: false, forec: true, foreca: true, forecas: true, wi: false, win: false, wind: false, windy: false, }, }, { minKeywordLength: 6, canIncrement: false, searches: { fo: false, for: false, fore: false, forec: false, foreca: true, forecas: true, wi: false, win: false, wind: false, windy: false, }, }, { minKeywordLength: 6, canIncrement: false, searches: { fo: false, for: false, fore: false, forec: false, foreca: true, forecas: true, wi: false, win: false, wind: false, windy: false, }, }, ], }); }); add_task(async function () { await doIncrementTest({ desc: "Settings and Nimbus", setup: { settingsData: { keywords: ["weather"], min_keyword_length: 5, }, nimbusValues: { weatherKeywords: ["forecast", "wind"], weatherKeywordsMinimumLength: 3, }, }, tests: [ { minKeywordLength: 3, canIncrement: true, searches: { we: false, wea: false, weat: false, weath: false, fo: false, for: true, fore: true, forec: true, wi: false, win: true, wind: true, }, }, { minKeywordLength: 4, canIncrement: true, searches: { we: false, wea: false, weat: false, weath: false, fo: false, for: false, fore: true, forec: true, wi: false, win: false, wind: true, }, }, { minKeywordLength: 5, canIncrement: true, searches: { we: false, wea: false, weat: false, weath: false, fo: false, for: false, fore: false, forec: true, wi: false, win: false, wind: false, windy: false, }, }, ], }); }); add_task(async function () { await doIncrementTest({ desc: "Settings and Nimbus with cap in Nimbus", setup: { settingsData: { keywords: ["weather"], min_keyword_length: 5, }, nimbusValues: { weatherKeywords: ["forecast", "wind"], weatherKeywordsMinimumLength: 3, weatherKeywordsMinimumLengthCap: 6, }, }, tests: [ { minKeywordLength: 3, canIncrement: true, searches: { we: false, wea: false, weat: false, weath: false, fo: false, for: true, fore: true, forec: true, foreca: true, forecas: true, wi: false, win: true, wind: true, }, }, { minKeywordLength: 4, canIncrement: true, searches: { we: false, wea: false, weat: false, weath: false, fo: false, for: false, fore: true, forec: true, foreca: true, forecas: true, wi: false, win: false, wind: true, }, }, { minKeywordLength: 5, canIncrement: true, searches: { we: false, wea: false, weat: false, weath: false, fo: false, for: false, fore: false, forec: true, foreca: true, forecas: true, wi: false, win: false, wind: false, windy: false, }, }, { minKeywordLength: 6, canIncrement: false, searches: { we: false, wea: false, weat: false, weath: false, fo: false, for: false, fore: false, forec: false, foreca: true, forecas: true, wi: false, win: false, wind: false, windy: false, }, }, { minKeywordLength: 6, canIncrement: false, searches: { we: false, wea: false, weat: false, weath: false, fo: false, for: false, fore: false, forec: false, foreca: true, forecas: true, wi: false, win: false, wind: false, windy: false, }, }, ], }); }); async function doIncrementTest({ desc, setup, tests }) { info("Doing increment test: " + desc); info(JSON.stringify({ setup })); let { nimbusValues, settingsData } = setup; let fetchPromise; if ( !QuickSuggest.weather.suggestion && (nimbusValues?.weatherKeywords || settingsData?.keywords) ) { fetchPromise = QuickSuggest.weather.waitForFetches(); } let nimbusCleanup; if (nimbusValues) { nimbusCleanup = await UrlbarTestUtils.initNimbusFeature(nimbusValues); } await QuickSuggestTestUtils.setRemoteSettingsResults([ { type: "weather", weather: settingsData, }, ]); if (fetchPromise) { info("Waiting for fetch"); assertFetchingStarted({ pendingFetchCount: 1 }); await fetchPromise; info("Got fetch"); } for (let { minKeywordLength, canIncrement, searches } of tests) { info( "Doing increment test case: " + JSON.stringify({ minKeywordLength, canIncrement, }) ); Assert.equal( QuickSuggest.weather.minKeywordLength, minKeywordLength, "minKeywordLength should be correct" ); Assert.equal( QuickSuggest.weather.canIncrementMinKeywordLength, canIncrement, "canIncrement should be correct" ); for (let [searchString, expected] of Object.entries(searches)) { Assert.equal( QuickSuggest.weather.keywords.has(searchString), expected, "Keyword should be present/absent as expected: " + searchString ); await check_results({ context: createContext(searchString, { providers: [UrlbarProviderWeather.name], isPrivate: false, }), matches: expected ? [makeExpectedResult({ suggestedIndex: 1 })] : [], }); } QuickSuggest.weather.incrementMinKeywordLength(); info( "Incremented min keyword length, new value is: " + QuickSuggest.weather.minKeywordLength ); } await nimbusCleanup?.(); fetchPromise = null; if (!QuickSuggest.weather.suggestion) { fetchPromise = QuickSuggest.weather.waitForFetches(); } await QuickSuggestTestUtils.setRemoteSettingsResults([ { type: "weather", weather: MerinoTestUtils.WEATHER_RS_DATA, }, ]); UrlbarPrefs.clear("weather.minKeywordLength"); await fetchPromise; } function makeExpectedResult({ suggestedIndex = 0, temperatureUnit = undefined, } = {}) { if (!temperatureUnit) { temperatureUnit = Services.locale.regionalPrefsLocales[0] == "en-US" ? "f" : "c"; } return { suggestedIndex, type: UrlbarUtils.RESULT_TYPE.DYNAMIC, source: UrlbarUtils.RESULT_SOURCE.SEARCH, heuristic: false, payload: { temperatureUnit, url: WEATHER_SUGGESTION.url, iconId: "6", helpUrl: QuickSuggest.HELP_URL, helpL10n: { id: UrlbarPrefs.get("resultMenu") ? "urlbar-result-menu-learn-more-about-firefox-suggest" : "firefox-suggest-urlbar-learn-more", }, isBlockable: true, blockL10n: { id: UrlbarPrefs.get("resultMenu") ? "urlbar-result-menu-dismiss-firefox-suggest" : "firefox-suggest-urlbar-block", }, requestId: MerinoTestUtils.server.response.body.request_id, source: "merino", merinoProvider: "accuweather", dynamicType: "weather", city: WEATHER_SUGGESTION.city_name, temperature: WEATHER_SUGGESTION.current_conditions.temperature[temperatureUnit], currentConditions: WEATHER_SUGGESTION.current_conditions.summary, forecast: WEATHER_SUGGESTION.forecast.summary, high: WEATHER_SUGGESTION.forecast.high[temperatureUnit], low: WEATHER_SUGGESTION.forecast.low[temperatureUnit], shouldNavigate: true, }, }; } function assertFetchingStarted() { info("Asserting fetching has started"); Assert.notEqual( QuickSuggest.weather._test_fetchTimer, 0, "Fetch timer is non-zero" ); Assert.ok(QuickSuggest.weather._test_merino, "Merino client is non-null"); Assert.equal( QuickSuggest.weather._test_pendingFetchCount, 1, "Expected pending fetch count" ); }