Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* Any copyright is dedicated to the Public Domain.
"use strict";
ChromeUtils.defineESModuleGetters(this, {
ShellService: "moz-src:///browser/components/shell/ShellService.sys.mjs",
TaskbarTabsPin: "resource:///modules/taskbartabs/TaskbarTabsPin.sys.mjs",
TaskbarTabsRegistry:
"resource:///modules/taskbartabs/TaskbarTabsRegistry.sys.mjs",
XPCOMUtils: "resource://gre/modules/XPCOMUtils.sys.mjs",
});
const gRegistry = new TaskbarTabsRegistry();
const patchedSpy = sinon.stub();
gRegistry.on(TaskbarTabsRegistry.events.patched, patchedSpy);
sinon.stub(ShellService, "writeShortcutIcon").resolves();
sinon.stub(ShellService, "shellService").value({
...ShellService.shellService,
// None of these should be called.
createShortcut: sinon.stub().throws(),
deleteShortcut: sinon.stub().throws(),
pinShortcutToTaskbar: sinon.stub().throws(),
unpinShortcutFromTaskbar: sinon.stub().throws(),
});
sinon.stub(ShellService, "requestCreateAndPinSecondaryTile").resolves();
sinon.stub(ShellService, "requestDeleteSecondaryTile").resolves();
sinon.stub(TaskbarTabsPin, "_getLocalization").returns({
formatValue(msg) {
// Slash must also be sanitized, so it should appear as '_' in paths.
return `[formatValue/${msg}]`;
},
});
registerCleanupFunction(() => {
sinon.restore();
});
// Favicons are written to the profile directory, ensure it exists.
do_get_profile();
function checkCreateSecondaryTileCall(aTaskbarTab) {
Assert.equal(
ShellService.requestCreateAndPinSecondaryTile.callCount,
1,
"requestCreateAndPinSecondaryTile was called once."
);
Assert.equal(
ShellService.requestCreateAndPinSecondaryTile.firstCall.args[0],
"taskbartab-" + aTaskbarTab.id,
"Correct secondary tile ID was specified."
);
Assert.equal(
ShellService.requestCreateAndPinSecondaryTile.firstCall.args[1],
aTaskbarTab.name,
"Correct name was specified."
);
Assert.ok(
ShellService.requestCreateAndPinSecondaryTile.firstCall.args[2].endsWith(
// This is Windows-only, so it'll be an ICO.
aTaskbarTab.id + ".ico"
),
"Reasonable icon path was specified."
);
Assert.ok(
ShellService.requestCreateAndPinSecondaryTile.firstCall.args[3].includes(
"-taskbar-tab"
),
"Reasonable arguments were specified."
);
Assert.equal(patchedSpy.callCount, 1, "A single patched event was emitted");
Assert.equal(
aTaskbarTab.shortcutRelativePath,
"taskbartab-" + aTaskbarTab.id,
"Correct relative path is saved to the taskbar tab"
);
}
add_task(async function test_pinCreatesDesktopEntry() {
const parsedURI = Services.io.newURI("https://www.example.com");
const taskbarTab = createTaskbarTab(gRegistry, parsedURI, 0);
sinon.resetHistory();
await TaskbarTabsPin.pinTaskbarTab(taskbarTab, gRegistry);
checkCreateSecondaryTileCall(taskbarTab);
gRegistry.removeTaskbarTab(taskbarTab.id);
});
// We should be able to put whatever we want into the name on MSIX systems.
add_task(async function test_pinUnusualName() {
const parsedURI = Services.io.newURI("https://another.test");
const invalidTaskbarTab = createTaskbarTab(gRegistry, parsedURI, 0, {
manifest: {
name: "** :\t\r\n \\\\ >> Not a valid. filename??! << // |||: **.",
},
});
sinon.resetHistory();
await TaskbarTabsPin.pinTaskbarTab(invalidTaskbarTab, gRegistry);
checkCreateSecondaryTileCall(invalidTaskbarTab);
gRegistry.removeTaskbarTab(invalidTaskbarTab.id);
});
add_task(async function test_unpin() {
const parsedURI = Services.io.newURI("https://example.com");
const tt = createTaskbarTab(gRegistry, parsedURI, 0);
gRegistry.patchTaskbarTab(tt, {
shortcutRelativePath: "321cba-batrabksat",
});
sinon.resetHistory();
await TaskbarTabsPin.unpinTaskbarTab(tt, gRegistry);
Assert.equal(
ShellService.requestDeleteSecondaryTile.callCount,
1,
"requestDeleteSecondaryTile was called once"
);
Assert.deepEqual(
ShellService.requestDeleteSecondaryTile.firstCall.args,
["321cba-batrabksat"],
"requestDeleteSecondaryTile was called with the value in shortcutRelativePath"
);
Assert.equal(
tt.shortcutRelativePath,
null,
"Shortcut relative path was removed from the taskbar tab"
);
Assert.equal(patchedSpy.callCount, 1, "A single patched event was emitted");
});