mirror of
https://github.com/zen-browser/desktop.git
synced 2026-08-01 04:38:55 +00:00
566 lines
17 KiB
JavaScript
566 lines
17 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
ChromeUtils.defineESModuleGetters(this, {
|
|
ExperimentAPI: "resource://nimbus/ExperimentAPI.sys.mjs",
|
|
NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
|
|
NimbusTestUtils: "resource://testing-common/NimbusTestUtils.sys.mjs",
|
|
sinon: "resource://testing-common/Sinon.sys.mjs",
|
|
});
|
|
|
|
const confusedFoxPath = ShellService.getBundledPdfFile("confused_fox.pdf").path;
|
|
const SET_HANDLER_WIN11 = Ci.nsIWindowsShellService.OPEN_WITH_SET_HANDLER;
|
|
|
|
const setDefaultBrowserUserChoiceStub = sinon.stub();
|
|
const setDefaultExtensionHandlersUserChoiceStub = sinon
|
|
.stub()
|
|
.callsFake(() => Promise.resolve());
|
|
|
|
const defaultAgentStub = sinon.stub(ShellService, "defaultAgent").value({
|
|
setDefaultBrowserUserChoiceAsync: setDefaultBrowserUserChoiceStub,
|
|
setDefaultExtensionHandlersUserChoice:
|
|
setDefaultExtensionHandlersUserChoiceStub,
|
|
});
|
|
|
|
XPCOMUtils.defineLazyServiceGetter(
|
|
this,
|
|
"XreDirProvider",
|
|
"@mozilla.org/xre/directory-provider;1",
|
|
Ci.nsIXREDirProvider
|
|
);
|
|
|
|
const _userChoiceImpossibleTelemetryResultStub = sinon
|
|
.stub(ShellService, "_userChoiceImpossibleTelemetryResult")
|
|
.callsFake(() => null);
|
|
|
|
// Ensure we don't fall back to a real implementation.
|
|
const setDefaultStub = sinon.stub();
|
|
// We'll dynamically update this as needed during the tests.
|
|
const queryCurrentDefaultHandlerForStub = sinon.stub();
|
|
const launchSetDefaultAppPickerStub = sinon.stub();
|
|
const launchModernSettingsDialogDefaultAppsStub = sinon.stub();
|
|
const shellStub = sinon.stub(ShellService, "shellService").value({
|
|
setDefaultBrowser: setDefaultStub,
|
|
queryCurrentDefaultHandlerFor: queryCurrentDefaultHandlerForStub,
|
|
launchSetDefaultAppPicker: launchSetDefaultAppPickerStub,
|
|
launchModernSettingsDialogDefaultApps:
|
|
launchModernSettingsDialogDefaultAppsStub,
|
|
QueryInterface: ChromeUtils.generateQI([]),
|
|
});
|
|
|
|
registerCleanupFunction(() => {
|
|
defaultAgentStub.restore();
|
|
_userChoiceImpossibleTelemetryResultStub.restore();
|
|
shellStub.restore();
|
|
});
|
|
|
|
add_task(async function ready() {
|
|
await ExperimentAPI.ready();
|
|
});
|
|
|
|
// Everything here is Windows.
|
|
Assert.equal(AppConstants.platform, "win", "Platform is Windows");
|
|
|
|
add_task(async function remoteEnableWithPDF() {
|
|
let doCleanup = await NimbusTestUtils.enrollWithFeatureConfig(
|
|
{
|
|
featureId: NimbusFeatures.shellService.featureId,
|
|
value: {
|
|
setDefaultBrowserUserChoice: true,
|
|
setDefaultPDFHandlerOnlyReplaceBrowsers: false,
|
|
setDefaultPDFHandler: true,
|
|
enabled: true,
|
|
},
|
|
},
|
|
{ isRollout: true }
|
|
);
|
|
|
|
Assert.equal(
|
|
NimbusFeatures.shellService.getVariable("setDefaultBrowserUserChoice"),
|
|
true
|
|
);
|
|
Assert.equal(
|
|
NimbusFeatures.shellService.getVariable("setDefaultPDFHandler"),
|
|
true
|
|
);
|
|
|
|
setDefaultBrowserUserChoiceStub.resetHistory();
|
|
await ShellService.setDefaultBrowser();
|
|
|
|
const aumi = XreDirProvider.getInstallHash();
|
|
Assert.ok(setDefaultBrowserUserChoiceStub.called);
|
|
Assert.deepEqual(setDefaultBrowserUserChoiceStub.firstCall.args, [
|
|
aumi,
|
|
[".pdf", "FirefoxPDF"],
|
|
]);
|
|
|
|
await doCleanup();
|
|
});
|
|
|
|
add_task(async function remoteEnableWithPDF_testOnlyReplaceBrowsers() {
|
|
let doCleanup = await NimbusTestUtils.enrollWithFeatureConfig(
|
|
{
|
|
featureId: NimbusFeatures.shellService.featureId,
|
|
value: {
|
|
setDefaultBrowserUserChoice: true,
|
|
setDefaultPDFHandlerOnlyReplaceBrowsers: true,
|
|
setDefaultPDFHandler: true,
|
|
enabled: true,
|
|
},
|
|
},
|
|
{ isRollout: true }
|
|
);
|
|
|
|
Assert.equal(
|
|
NimbusFeatures.shellService.getVariable("setDefaultBrowserUserChoice"),
|
|
true
|
|
);
|
|
Assert.equal(
|
|
NimbusFeatures.shellService.getVariable("setDefaultPDFHandler"),
|
|
true
|
|
);
|
|
Assert.equal(
|
|
NimbusFeatures.shellService.getVariable(
|
|
"setDefaultPDFHandlerOnlyReplaceBrowsers"
|
|
),
|
|
true
|
|
);
|
|
|
|
const aumi = XreDirProvider.getInstallHash();
|
|
|
|
// We'll take the default from a missing association or a known browser.
|
|
for (let progId of ["", "MSEdgePDF"]) {
|
|
queryCurrentDefaultHandlerForStub.callsFake(() => progId);
|
|
|
|
setDefaultBrowserUserChoiceStub.resetHistory();
|
|
await ShellService.setDefaultBrowser();
|
|
|
|
Assert.ok(setDefaultBrowserUserChoiceStub.called);
|
|
Assert.deepEqual(
|
|
setDefaultBrowserUserChoiceStub.firstCall.args,
|
|
[aumi, [".pdf", "FirefoxPDF"]],
|
|
`Will take default from missing association or known browser with ProgID '${progId}'`
|
|
);
|
|
}
|
|
|
|
// But not from a non-browser.
|
|
queryCurrentDefaultHandlerForStub.callsFake(() => "Acrobat.Document.DC");
|
|
|
|
setDefaultBrowserUserChoiceStub.resetHistory();
|
|
await ShellService.setDefaultBrowser();
|
|
|
|
Assert.ok(setDefaultBrowserUserChoiceStub.called);
|
|
Assert.deepEqual(
|
|
setDefaultBrowserUserChoiceStub.firstCall.args,
|
|
[aumi, []],
|
|
`Will not take default from non-browser`
|
|
);
|
|
|
|
await doCleanup();
|
|
});
|
|
|
|
add_task(async function remoteEnableWithoutPDF() {
|
|
let doCleanup = await NimbusTestUtils.enrollWithFeatureConfig(
|
|
{
|
|
featureId: NimbusFeatures.shellService.featureId,
|
|
value: {
|
|
setDefaultBrowserUserChoice: true,
|
|
setDefaultPDFHandler: false,
|
|
enabled: true,
|
|
},
|
|
},
|
|
{ isRollout: true }
|
|
);
|
|
|
|
Assert.equal(
|
|
NimbusFeatures.shellService.getVariable("setDefaultBrowserUserChoice"),
|
|
true
|
|
);
|
|
Assert.equal(
|
|
NimbusFeatures.shellService.getVariable("setDefaultPDFHandler"),
|
|
false
|
|
);
|
|
|
|
setDefaultBrowserUserChoiceStub.resetHistory();
|
|
await ShellService.setDefaultBrowser();
|
|
|
|
const aumi = XreDirProvider.getInstallHash();
|
|
Assert.ok(setDefaultBrowserUserChoiceStub.called);
|
|
Assert.deepEqual(setDefaultBrowserUserChoiceStub.firstCall.args, [aumi, []]);
|
|
|
|
await doCleanup();
|
|
});
|
|
|
|
add_task(async function remoteDisable() {
|
|
let doCleanup = await NimbusTestUtils.enrollWithFeatureConfig(
|
|
{
|
|
featureId: NimbusFeatures.shellService.featureId,
|
|
value: {
|
|
setDefaultBrowserUserChoice: false,
|
|
setDefaultPDFHandler: true,
|
|
enabled: false,
|
|
},
|
|
},
|
|
{ isRollout: true }
|
|
);
|
|
|
|
Assert.equal(
|
|
NimbusFeatures.shellService.getVariable("setDefaultBrowserUserChoice"),
|
|
false
|
|
);
|
|
Assert.equal(
|
|
NimbusFeatures.shellService.getVariable("setDefaultPDFHandler"),
|
|
true
|
|
);
|
|
|
|
setDefaultBrowserUserChoiceStub.resetHistory();
|
|
await ShellService.setDefaultBrowser();
|
|
|
|
Assert.ok(setDefaultBrowserUserChoiceStub.notCalled);
|
|
Assert.ok(setDefaultStub.called);
|
|
|
|
await doCleanup();
|
|
});
|
|
|
|
add_task(async function test_setAsDefaultPDFHandler_knownBrowser() {
|
|
const sandbox = sinon.createSandbox();
|
|
|
|
const aumi = XreDirProvider.getInstallHash();
|
|
const expectedArguments = [aumi, [".pdf", "FirefoxPDF"]];
|
|
const resetStubs = () => {
|
|
setDefaultExtensionHandlersUserChoiceStub.resetHistory();
|
|
launchSetDefaultAppPickerStub.resetHistory();
|
|
launchModernSettingsDialogDefaultAppsStub.resetHistory();
|
|
};
|
|
|
|
try {
|
|
const pdfHandlerResult = { registered: true, knownBrowser: true };
|
|
sandbox
|
|
.stub(ShellService, "getDefaultPDFHandler")
|
|
.returns(pdfHandlerResult);
|
|
|
|
info("Testing setAsDefaultPDFHandler(true) when knownBrowser = true");
|
|
await ShellService.setAsDefaultPDFHandler(true);
|
|
Assert.ok(
|
|
setDefaultExtensionHandlersUserChoiceStub.called,
|
|
"Used userChoice for .pdf"
|
|
);
|
|
Assert.deepEqual(
|
|
setDefaultExtensionHandlersUserChoiceStub.firstCall.args,
|
|
expectedArguments,
|
|
"Called default browser agent with expected arguments"
|
|
);
|
|
Assert.ok(
|
|
launchSetDefaultAppPickerStub.notCalled,
|
|
"Did not fall back to open-with picker"
|
|
);
|
|
Assert.ok(
|
|
launchModernSettingsDialogDefaultAppsStub.notCalled,
|
|
"Did not fall back to settings dialog"
|
|
);
|
|
resetStubs();
|
|
|
|
info("Testing setAsDefaultPDFHandler(false) when knownBrowser = true");
|
|
await ShellService.setAsDefaultPDFHandler(false);
|
|
Assert.ok(
|
|
setDefaultExtensionHandlersUserChoiceStub.called,
|
|
"Used userChoice for .pdf"
|
|
);
|
|
Assert.deepEqual(
|
|
setDefaultExtensionHandlersUserChoiceStub.firstCall.args,
|
|
expectedArguments,
|
|
"Called default browser agent with expected arguments"
|
|
);
|
|
Assert.ok(
|
|
launchSetDefaultAppPickerStub.notCalled,
|
|
"Did not fall back to open-with picker"
|
|
);
|
|
Assert.ok(
|
|
launchModernSettingsDialogDefaultAppsStub.notCalled,
|
|
"Did not fall back to settings dialog"
|
|
);
|
|
resetStubs();
|
|
|
|
pdfHandlerResult.knownBrowser = false;
|
|
|
|
info("Testing setAsDefaultPDFHandler(true) when knownBrowser = false");
|
|
await ShellService.setAsDefaultPDFHandler(true);
|
|
Assert.ok(
|
|
setDefaultExtensionHandlersUserChoiceStub.notCalled,
|
|
"Did not use userChoice"
|
|
);
|
|
Assert.ok(
|
|
launchSetDefaultAppPickerStub.notCalled,
|
|
"Did not fall back to open-with picker"
|
|
);
|
|
Assert.ok(
|
|
launchModernSettingsDialogDefaultAppsStub.notCalled,
|
|
"Did not fall back to settings dialog"
|
|
);
|
|
resetStubs();
|
|
|
|
info("Testing setAsDefaultPDFHandler(false) when knownBrowser = false");
|
|
await ShellService.setAsDefaultPDFHandler(false);
|
|
Assert.ok(
|
|
setDefaultExtensionHandlersUserChoiceStub.called,
|
|
"Used userChoice for .pdf"
|
|
);
|
|
Assert.deepEqual(
|
|
setDefaultExtensionHandlersUserChoiceStub.firstCall.args,
|
|
expectedArguments,
|
|
"Called default browser agent with expected arguments"
|
|
);
|
|
Assert.ok(
|
|
launchSetDefaultAppPickerStub.notCalled,
|
|
"Did not fall back to open-with picker"
|
|
);
|
|
Assert.ok(
|
|
launchModernSettingsDialogDefaultAppsStub.notCalled,
|
|
"Did not fall back to settings dialog"
|
|
);
|
|
resetStubs();
|
|
} finally {
|
|
sandbox.restore();
|
|
}
|
|
});
|
|
|
|
// Wait for the deferred set_default_pdf_handler_attempt event to be recorded,
|
|
// then return the single event that was emitted by the most recent call.
|
|
async function awaitAttemptEvent() {
|
|
await TestUtils.waitForCondition(() => {
|
|
const events = Glean.browser.setDefaultPdfHandlerAttempt.testGetValue();
|
|
return events && events.length;
|
|
}, "Recorded set_default_pdf_handler_attempt event");
|
|
const events = Glean.browser.setDefaultPdfHandlerAttempt.testGetValue();
|
|
Assert.equal(events.length, 1, "Recorded exactly one attempt event");
|
|
return events[0];
|
|
}
|
|
|
|
add_task(async function test_setAsDefaultPDFHandler_fallback() {
|
|
const sandbox = sinon.createSandbox();
|
|
// Enable the IOpenWithLauncher branch explicitly so the test does not
|
|
// depend on the build-channel default of
|
|
// browser.shell.setDefaultPDFHandler.useOpenWith, and use a 0ms wait so
|
|
// the deferred attempt event fires promptly.
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [
|
|
["browser.shell.setDefaultPDFHandler.useOpenWith", true],
|
|
["browser.shell.setDefaultPDFHandler.attemptWaitTimeMs", 0],
|
|
],
|
|
});
|
|
|
|
try {
|
|
const userChoiceStub = sandbox
|
|
.stub(ShellService, "setAsDefaultPDFHandlerUserChoice")
|
|
.rejects(new Error("mock userChoice failure"));
|
|
sandbox.stub(ShellService, "_isWindows11").returns(true);
|
|
const isDefaultHandlerForStub = sandbox
|
|
.stub(ShellService, "isDefaultHandlerFor")
|
|
.returns(true);
|
|
|
|
info(
|
|
"When userChoice fails and open-with picker succeeds, should not fall back to settings dialog"
|
|
);
|
|
Services.fog.testResetFOG();
|
|
await ShellService.setAsDefaultPDFHandler(false);
|
|
|
|
Assert.ok(userChoiceStub.called, "Attempted userChoice");
|
|
Assert.ok(
|
|
launchSetDefaultAppPickerStub.calledWith(
|
|
confusedFoxPath,
|
|
SET_HANDLER_WIN11
|
|
),
|
|
"Fell back to open-with picker with bundled PDF path and Win11 flag"
|
|
);
|
|
Assert.ok(
|
|
launchModernSettingsDialogDefaultAppsStub.notCalled,
|
|
"Did not fall back to settings dialog"
|
|
);
|
|
Assert.equal(
|
|
Glean.browser.setDefaultPdfHandlerUserChoiceResult.ErrOther.testGetValue(),
|
|
1,
|
|
"Recorded user-choice failure"
|
|
);
|
|
|
|
let event = await awaitAttemptEvent();
|
|
Assert.equal(event.extra.method, "open_with", "Event method is open_with");
|
|
Assert.equal(event.extra.success, "true", "Event success is true");
|
|
Assert.equal(
|
|
event.extra.result_is_default,
|
|
"true",
|
|
"Event result_is_default reflects isDefaultHandlerFor"
|
|
);
|
|
Assert.ok(
|
|
isDefaultHandlerForStub.calledWith(".pdf"),
|
|
"Sampled isDefaultHandlerFor after the delay"
|
|
);
|
|
userChoiceStub.resetHistory();
|
|
isDefaultHandlerForStub.resetHistory();
|
|
launchSetDefaultAppPickerStub.resetHistory();
|
|
launchModernSettingsDialogDefaultAppsStub.resetHistory();
|
|
|
|
info(
|
|
"When the picker succeeds but Firefox is not default after the delay, event records result_is_default=false"
|
|
);
|
|
Services.fog.testResetFOG();
|
|
isDefaultHandlerForStub.returns(false);
|
|
await ShellService.setAsDefaultPDFHandler(false);
|
|
|
|
event = await awaitAttemptEvent();
|
|
Assert.equal(event.extra.method, "open_with", "Event method is open_with");
|
|
Assert.equal(event.extra.success, "true", "Event success is true");
|
|
Assert.equal(
|
|
event.extra.result_is_default,
|
|
"false",
|
|
"Event result_is_default is false when Firefox did not become default"
|
|
);
|
|
isDefaultHandlerForStub.returns(true);
|
|
userChoiceStub.resetHistory();
|
|
isDefaultHandlerForStub.resetHistory();
|
|
launchSetDefaultAppPickerStub.resetHistory();
|
|
launchModernSettingsDialogDefaultAppsStub.resetHistory();
|
|
|
|
info(
|
|
"When userChoice fails and open-with picker fails, should fall back to settings dialog"
|
|
);
|
|
Services.fog.testResetFOG();
|
|
launchSetDefaultAppPickerStub.throws(
|
|
new Error("mock IOpenWithLauncher failure")
|
|
);
|
|
await ShellService.setAsDefaultPDFHandler(false);
|
|
|
|
Assert.ok(userChoiceStub.called, "Attempted userChoice");
|
|
Assert.ok(
|
|
launchSetDefaultAppPickerStub.calledWith(
|
|
confusedFoxPath,
|
|
SET_HANDLER_WIN11
|
|
),
|
|
"Attempted open-with picker with bundled PDF path and Win11 flag"
|
|
);
|
|
Assert.ok(
|
|
launchModernSettingsDialogDefaultAppsStub.called,
|
|
"Fell back to settings dialog"
|
|
);
|
|
Assert.equal(
|
|
Glean.browser.setDefaultPdfHandlerUserChoiceResult.ErrOther.testGetValue(),
|
|
1,
|
|
"Recorded user-choice failure"
|
|
);
|
|
Assert.equal(
|
|
Glean.browser.setDefaultPdfHandlerModernSettingsResult.Success.testGetValue(),
|
|
1,
|
|
"Recorded modern settings success"
|
|
);
|
|
|
|
event = await awaitAttemptEvent();
|
|
Assert.equal(
|
|
event.extra.method,
|
|
"settings",
|
|
"Event method is settings (last attempted)"
|
|
);
|
|
Assert.equal(
|
|
event.extra.success,
|
|
"true",
|
|
"Event success reflects modern settings launch"
|
|
);
|
|
Assert.equal(
|
|
event.extra.result_is_default,
|
|
"true",
|
|
"Event result_is_default reflects isDefaultHandlerFor"
|
|
);
|
|
userChoiceStub.resetHistory();
|
|
isDefaultHandlerForStub.resetHistory();
|
|
launchSetDefaultAppPickerStub.resetHistory();
|
|
launchModernSettingsDialogDefaultAppsStub.resetHistory();
|
|
|
|
info(
|
|
"When userChoice fails, open-with fails, and modern settings fails, event records success=false"
|
|
);
|
|
Services.fog.testResetFOG();
|
|
isDefaultHandlerForStub.returns(false);
|
|
launchModernSettingsDialogDefaultAppsStub.throws(
|
|
new Error("mock modern settings failure")
|
|
);
|
|
await ShellService.setAsDefaultPDFHandler(false);
|
|
|
|
Assert.equal(
|
|
Glean.browser.setDefaultPdfHandlerModernSettingsResult.Failure.testGetValue(),
|
|
1,
|
|
"Recorded modern settings failure"
|
|
);
|
|
|
|
event = await awaitAttemptEvent();
|
|
Assert.equal(
|
|
event.extra.method,
|
|
"settings",
|
|
"Event method is settings (last attempted)"
|
|
);
|
|
Assert.equal(
|
|
event.extra.success,
|
|
"false",
|
|
"Event success is false when every method failed"
|
|
);
|
|
Assert.equal(
|
|
event.extra.result_is_default,
|
|
"false",
|
|
"Event result_is_default is false when no method set the default"
|
|
);
|
|
} finally {
|
|
launchSetDefaultAppPickerStub.reset();
|
|
launchModernSettingsDialogDefaultAppsStub.reset();
|
|
sandbox.restore();
|
|
await SpecialPowers.popPrefEnv();
|
|
}
|
|
});
|
|
|
|
add_task(async function test_setAsDefaultPDFHandler_useOpenWithDisabled() {
|
|
const sandbox = sinon.createSandbox();
|
|
// With useOpenWith disabled, a userChoice failure should skip the
|
|
// IOpenWithLauncher branch entirely and fall straight through to the
|
|
// modern settings dialog.
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [
|
|
["browser.shell.setDefaultPDFHandler.useOpenWith", false],
|
|
["browser.shell.setDefaultPDFHandler.attemptWaitTimeMs", 0],
|
|
],
|
|
});
|
|
|
|
try {
|
|
sandbox
|
|
.stub(ShellService, "setAsDefaultPDFHandlerUserChoice")
|
|
.rejects(new Error("mock userChoice failure"));
|
|
sandbox.stub(ShellService, "_isWindows11").returns(true);
|
|
sandbox.stub(ShellService, "isDefaultHandlerFor").returns(true);
|
|
|
|
Services.fog.testResetFOG();
|
|
await ShellService.setAsDefaultPDFHandler(false);
|
|
|
|
Assert.ok(
|
|
launchSetDefaultAppPickerStub.notCalled,
|
|
"Did not invoke open-with picker when pref is disabled"
|
|
);
|
|
Assert.ok(
|
|
launchModernSettingsDialogDefaultAppsStub.called,
|
|
"Fell through to modern settings dialog"
|
|
);
|
|
|
|
const event = await awaitAttemptEvent();
|
|
Assert.equal(
|
|
event.extra.method,
|
|
"settings",
|
|
"Event method skipped open_with and recorded settings"
|
|
);
|
|
Assert.equal(event.extra.success, "true", "Event success is true");
|
|
Assert.equal(
|
|
event.extra.result_is_default,
|
|
"true",
|
|
"Event result_is_default reflects isDefaultHandlerFor"
|
|
);
|
|
} finally {
|
|
launchSetDefaultAppPickerStub.reset();
|
|
launchModernSettingsDialogDefaultAppsStub.reset();
|
|
sandbox.restore();
|
|
await SpecialPowers.popPrefEnv();
|
|
}
|
|
});
|