169 lines
5.3 KiB
JavaScript
169 lines
5.3 KiB
JavaScript
/* 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/. */
|
|
|
|
"use strict";
|
|
|
|
const lazy = {};
|
|
|
|
ChromeUtils.defineESModuleGetters(lazy, {
|
|
NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
|
|
EnrollmentType: "resource://nimbus/ExperimentAPI.sys.mjs",
|
|
});
|
|
|
|
const { UrlbarProviderSemanticHistorySearch } = ChromeUtils.importESModule(
|
|
"resource:///modules/UrlbarProviderSemanticHistorySearch.sys.mjs"
|
|
);
|
|
const { PlacesSemanticHistoryManager } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/PlacesSemanticHistoryManager.sys.mjs"
|
|
);
|
|
|
|
let hasSufficientEntriesStub = sinon
|
|
.stub(
|
|
PlacesSemanticHistoryManager.prototype,
|
|
"hasSufficientEntriesForSearching"
|
|
)
|
|
.returns(true);
|
|
|
|
add_task(async function setup() {
|
|
registerCleanupFunction(() => {
|
|
sinon.restore();
|
|
});
|
|
|
|
// stub getEnrollmentMetadata once, then configure for both cases:
|
|
const getEnrollmentStub = sinon.stub(
|
|
lazy.NimbusFeatures.urlbar,
|
|
"getEnrollmentMetadata"
|
|
);
|
|
getEnrollmentStub
|
|
.withArgs(lazy.EnrollmentType.EXPERIMENT)
|
|
.returns({ slug: "test-slug", branch: "control" });
|
|
getEnrollmentStub.withArgs(lazy.EnrollmentType.ROLLOUT).returns(null);
|
|
sinon.stub(lazy.NimbusFeatures.urlbar, "recordExposureEvent");
|
|
});
|
|
|
|
add_task(async function test_startQuery_adds_results() {
|
|
const provider = UrlbarProviderSemanticHistorySearch;
|
|
|
|
// Set required prefs
|
|
Services.prefs.setBoolPref("browser.ml.enable", true);
|
|
Services.prefs.setBoolPref("places.semanticHistory.featureGate", true);
|
|
Services.prefs.setBoolPref("browser.urlbar.suggest.history", true);
|
|
Services.prefs
|
|
.getDefaultBranch("")
|
|
.setIntPref("browser.urlbar.suggest.semanticHistory.minLength", 5);
|
|
|
|
const queryContext = { searchString: "test page" };
|
|
|
|
// Trigger isActive() to initialize the semantic manager
|
|
Assert.ok(await provider.isActive(queryContext), "Provider should be active");
|
|
|
|
const semanticManager = provider.ensureSemanticManagerInitialized();
|
|
|
|
// Stub and simulate inference
|
|
sinon.stub(semanticManager.embedder, "ensureEngine").callsFake(() => {});
|
|
let url = "https://example.com";
|
|
sinon.stub(semanticManager, "infer").resolves({
|
|
results: [
|
|
{
|
|
id: 1,
|
|
title: "Test Page",
|
|
url,
|
|
},
|
|
],
|
|
});
|
|
await PlacesTestUtils.addVisits(url);
|
|
|
|
let added = [];
|
|
await provider.startQuery(queryContext, (_provider, result) => {
|
|
added.push(result);
|
|
});
|
|
|
|
Assert.equal(added.length, 1, "One result should be added");
|
|
Assert.equal(added[0].payload.url, url, "Correct URL should be used");
|
|
Assert.equal(
|
|
added[0].payload.icon,
|
|
UrlbarUtils.getIconForUrl(url),
|
|
"Correct icon should be used"
|
|
);
|
|
Assert.ok(added[0].payload.isBlockable, "Result should be blockable");
|
|
|
|
let controller = UrlbarTestUtils.newMockController();
|
|
let stub = sinon.stub(controller, "removeResult");
|
|
let promiseRemoved = PlacesTestUtils.waitForNotification("page-removed");
|
|
await provider.onEngagement(queryContext, controller, {
|
|
selType: "dismiss",
|
|
result: { payload: { url } },
|
|
});
|
|
Assert.ok(stub.calledOnce, "Result should be removed on dismissal");
|
|
await promiseRemoved;
|
|
let visited = await PlacesUtils.history.hasVisits(url);
|
|
Assert.ok(!visited, "URL should have been removed from history");
|
|
});
|
|
|
|
add_task(async function test_isActive_conditions() {
|
|
const provider = UrlbarProviderSemanticHistorySearch;
|
|
const semanticManager = provider.ensureSemanticManagerInitialized();
|
|
|
|
// Stub canUseSemanticSearch to control the return value
|
|
const canUseStub = sinon.stub(semanticManager, "canUseSemanticSearch");
|
|
|
|
// Default settings
|
|
Services.prefs.setBoolPref("browser.urlbar.suggest.history", true);
|
|
Services.prefs.setIntPref(
|
|
"browser.urlbar.suggest.semanticHistory.minLength",
|
|
5
|
|
);
|
|
|
|
const shortQuery = { searchString: "hi" };
|
|
const validQuery = { searchString: "hello world" };
|
|
|
|
// Pref is disabled
|
|
Services.prefs.setBoolPref("browser.urlbar.suggest.history", false);
|
|
Assert.ok(
|
|
!(await provider.isActive(validQuery)),
|
|
"Should be inactive when pref is disabled"
|
|
);
|
|
|
|
// Pref enabled, but string too short
|
|
Services.prefs.setBoolPref("browser.urlbar.suggest.history", true);
|
|
Assert.ok(
|
|
!(await provider.isActive(shortQuery)),
|
|
"Should be inactive for short search strings"
|
|
);
|
|
|
|
// All conditions met but semanticManager rejects
|
|
canUseStub.get(() => false);
|
|
hasSufficientEntriesStub.resetHistory();
|
|
Assert.ok(
|
|
!(await provider.isActive(validQuery)),
|
|
"Should be inactive if canUseSemanticSearch returns false"
|
|
);
|
|
Assert.ok(
|
|
hasSufficientEntriesStub.notCalled,
|
|
"hasSufficientEntriesForSearching should not have been called"
|
|
);
|
|
|
|
// All conditions met
|
|
canUseStub.get(() => true);
|
|
Assert.ok(
|
|
await provider.isActive(validQuery),
|
|
"Should be active when all conditions are met"
|
|
);
|
|
|
|
const engineSearchMode = createContext("hello world", {
|
|
searchMode: { engineName: "testEngine" },
|
|
});
|
|
Assert.ok(
|
|
!(await provider.isActive(engineSearchMode)),
|
|
"Should not be active when in search engine mode"
|
|
);
|
|
|
|
const historySearchMode = createContext("hello world", {
|
|
searchMode: { source: UrlbarUtils.RESULT_SOURCE.HISTORY },
|
|
});
|
|
Assert.ok(
|
|
await provider.isActive(historySearchMode),
|
|
"Should be active when in history search mode"
|
|
);
|
|
});
|