summaryrefslogtreecommitdiffstats
path: root/browser/components/syncedtabs/test/xpcshell/test_TabListComponent.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/syncedtabs/test/xpcshell/test_TabListComponent.js')
-rw-r--r--browser/components/syncedtabs/test/xpcshell/test_TabListComponent.js190
1 files changed, 190 insertions, 0 deletions
diff --git a/browser/components/syncedtabs/test/xpcshell/test_TabListComponent.js b/browser/components/syncedtabs/test/xpcshell/test_TabListComponent.js
new file mode 100644
index 0000000000..734baac254
--- /dev/null
+++ b/browser/components/syncedtabs/test/xpcshell/test_TabListComponent.js
@@ -0,0 +1,190 @@
+"use strict";
+
+let { SyncedTabs } = ChromeUtils.importESModule(
+ "resource://services-sync/SyncedTabs.sys.mjs"
+);
+let { TabListComponent } = ChromeUtils.importESModule(
+ "resource:///modules/syncedtabs/TabListComponent.sys.mjs"
+);
+let { SyncedTabsListStore } = ChromeUtils.importESModule(
+ "resource:///modules/syncedtabs/SyncedTabsListStore.sys.mjs"
+);
+
+const ACTION_METHODS = [
+ "onSelectRow",
+ "onOpenTab",
+ "onOpenTabs",
+ "onMoveSelectionDown",
+ "onMoveSelectionUp",
+ "onToggleBranch",
+ "onBookmarkTab",
+ "onSyncRefresh",
+ "onFilter",
+ "onClearFilter",
+ "onFilterFocus",
+ "onFilterBlur",
+];
+
+add_task(async function testInitUninit() {
+ let store = new SyncedTabsListStore();
+ let ViewMock = sinon.stub();
+ let view = { render() {}, destroy() {} };
+ let mockWindow = {};
+
+ ViewMock.returns(view);
+
+ sinon.spy(view, "render");
+ sinon.spy(view, "destroy");
+
+ sinon.spy(store, "on");
+ sinon.stub(store, "getData");
+ sinon.stub(store, "focusInput");
+
+ let component = new TabListComponent({
+ window: mockWindow,
+ store,
+ View: ViewMock,
+ SyncedTabs,
+ });
+
+ for (let action of ACTION_METHODS) {
+ sinon.stub(component, action);
+ }
+
+ component.init();
+
+ Assert.ok(ViewMock.calledWithNew(), "view is instantiated");
+ Assert.ok(store.on.calledOnce, "listener is added to store");
+ Assert.equal(store.on.args[0][0], "change");
+ Assert.ok(
+ view.render.calledWith({ clients: [] }),
+ "render is called on view instance"
+ );
+ Assert.ok(store.getData.calledOnce, "store gets initial data");
+ Assert.ok(store.focusInput.calledOnce, "input field is focused");
+
+ for (let method of ACTION_METHODS) {
+ let action = ViewMock.args[0][1][method];
+ Assert.ok(action, method + " action is passed to View");
+ action("foo", "bar");
+ Assert.ok(
+ component[method].calledWith("foo", "bar"),
+ method + " action passed to View triggers the component method with args"
+ );
+ }
+
+ store.emit("change", "mock state");
+ Assert.ok(
+ view.render.secondCall.calledWith("mock state"),
+ "view.render is called on state change"
+ );
+
+ component.uninit();
+ Assert.ok(view.destroy.calledOnce, "view is destroyed on uninit");
+});
+
+add_task(async function testActions() {
+ let store = new SyncedTabsListStore();
+ let chromeWindowMock = {
+ gBrowser: {
+ loadTabs() {},
+ },
+ };
+ let getChromeWindowMock = sinon.stub();
+ getChromeWindowMock.returns(chromeWindowMock);
+ let clipboardHelperMock = {
+ copyString() {},
+ };
+ let windowMock = {
+ top: {
+ PlacesCommandHook: {
+ bookmarkLink() {
+ return Promise.resolve();
+ },
+ },
+ },
+ openDialog() {},
+ openTrustedLinkIn() {},
+ };
+ let component = new TabListComponent({
+ window: windowMock,
+ store,
+ View: null,
+ SyncedTabs,
+ clipboardHelper: clipboardHelperMock,
+ getChromeWindow: getChromeWindowMock,
+ });
+
+ sinon.stub(store, "getData");
+ component.onFilter("query");
+ Assert.ok(store.getData.calledWith("query"));
+
+ sinon.stub(store, "clearFilter");
+ component.onClearFilter();
+ Assert.ok(store.clearFilter.called);
+
+ sinon.stub(store, "focusInput");
+ component.onFilterFocus();
+ Assert.ok(store.focusInput.called);
+
+ sinon.stub(store, "blurInput");
+ component.onFilterBlur();
+ Assert.ok(store.blurInput.called);
+
+ sinon.stub(store, "selectRow");
+ component.onSelectRow([-1, -1]);
+ Assert.ok(store.selectRow.calledWith(-1, -1));
+
+ sinon.stub(store, "moveSelectionDown");
+ component.onMoveSelectionDown();
+ Assert.ok(store.moveSelectionDown.called);
+
+ sinon.stub(store, "moveSelectionUp");
+ component.onMoveSelectionUp();
+ Assert.ok(store.moveSelectionUp.called);
+
+ sinon.stub(store, "toggleBranch");
+ component.onToggleBranch("foo-id");
+ Assert.ok(store.toggleBranch.calledWith("foo-id"));
+
+ sinon.spy(windowMock.top.PlacesCommandHook, "bookmarkLink");
+ component.onBookmarkTab("uri", "title");
+ Assert.equal(windowMock.top.PlacesCommandHook.bookmarkLink.args[0][0], "uri");
+ Assert.equal(
+ windowMock.top.PlacesCommandHook.bookmarkLink.args[0][1],
+ "title"
+ );
+
+ sinon.spy(windowMock, "openTrustedLinkIn");
+ component.onOpenTab("uri", "where", "params");
+ Assert.ok(windowMock.openTrustedLinkIn.calledWith("uri", "where", "params"));
+
+ sinon.spy(chromeWindowMock.gBrowser, "loadTabs");
+ let tabsToOpen = ["uri1", "uri2"];
+ component.onOpenTabs(tabsToOpen, "where");
+ Assert.ok(getChromeWindowMock.calledWith(windowMock));
+ Assert.ok(
+ chromeWindowMock.gBrowser.loadTabs.calledWith(tabsToOpen, {
+ inBackground: false,
+ replace: false,
+ triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+ })
+ );
+ component.onOpenTabs(tabsToOpen, "tabshifted");
+ Assert.ok(
+ chromeWindowMock.gBrowser.loadTabs.calledWith(tabsToOpen, {
+ inBackground: true,
+ replace: false,
+ triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+ })
+ );
+
+ sinon.spy(clipboardHelperMock, "copyString");
+ component.onCopyTabLocation("uri");
+ Assert.ok(clipboardHelperMock.copyString.calledWith("uri"));
+
+ sinon.stub(SyncedTabs, "syncTabs");
+ component.onSyncRefresh();
+ Assert.ok(SyncedTabs.syncTabs.calledWith(true));
+ SyncedTabs.syncTabs.restore();
+});