summaryrefslogtreecommitdiffstats
path: root/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckComponent.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckComponent.js')
-rw-r--r--browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckComponent.js218
1 files changed, 218 insertions, 0 deletions
diff --git a/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckComponent.js b/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckComponent.js
new file mode 100644
index 000000000..3d748b33c
--- /dev/null
+++ b/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckComponent.js
@@ -0,0 +1,218 @@
+"use strict";
+
+let { SyncedTabs } = Cu.import("resource://services-sync/SyncedTabs.jsm", {});
+let { SyncedTabsDeckComponent } = Cu.import("resource:///modules/syncedtabs/SyncedTabsDeckComponent.js", {});
+let { TabListComponent } = Cu.import("resource:///modules/syncedtabs/TabListComponent.js", {});
+let { SyncedTabsListStore } = Cu.import("resource:///modules/syncedtabs/SyncedTabsListStore.js", {});
+let { SyncedTabsDeckStore } = Cu.import("resource:///modules/syncedtabs/SyncedTabsDeckStore.js", {});
+let { TabListView } = Cu.import("resource:///modules/syncedtabs/TabListView.js", {});
+let { DeckView } = Cu.import("resource:///modules/syncedtabs/SyncedTabsDeckView.js", {});
+
+
+add_task(function* testInitUninit() {
+ let deckStore = new SyncedTabsDeckStore();
+ let listComponent = {};
+
+ let ViewMock = sinon.stub();
+ let view = {render: sinon.spy(), destroy: sinon.spy(), container: {}};
+ ViewMock.returns(view);
+
+ sinon.stub(SyncedTabs, "syncTabs", () => Promise.resolve());
+
+ sinon.spy(deckStore, "on");
+ sinon.stub(deckStore, "setPanels");
+
+ let component = new SyncedTabsDeckComponent({
+ window,
+ deckStore,
+ listComponent,
+ SyncedTabs,
+ DeckView: ViewMock,
+ });
+
+ sinon.stub(component, "updatePanel");
+
+ component.init();
+
+ Assert.ok(SyncedTabs.syncTabs.called);
+ SyncedTabs.syncTabs.restore();
+
+ Assert.ok(ViewMock.calledWithNew(), "view is instantiated");
+ Assert.equal(ViewMock.args[0][0], window);
+ Assert.equal(ViewMock.args[0][1], listComponent);
+ Assert.ok(ViewMock.args[0][2].onAndroidClick,
+ "view is passed onAndroidClick prop");
+ Assert.ok(ViewMock.args[0][2].oniOSClick,
+ "view is passed oniOSClick prop");
+ Assert.ok(ViewMock.args[0][2].onSyncPrefClick,
+ "view is passed onSyncPrefClick prop");
+
+ Assert.equal(component.container, view.container,
+ "component returns view's container");
+
+ Assert.ok(deckStore.on.calledOnce, "listener is added to store");
+ Assert.equal(deckStore.on.args[0][0], "change");
+ // Object.values only in nightly
+ let values = Object.keys(component.PANELS).map(k => component.PANELS[k]);
+ Assert.ok(deckStore.setPanels.calledWith(values),
+ "panels are set on deck store");
+
+ Assert.ok(component.updatePanel.called);
+
+ deckStore.emit("change", "mock state");
+ Assert.ok(view.render.calledWith("mock state"),
+ "view.render is called on state change");
+
+ component.uninit();
+
+ Assert.ok(view.destroy.calledOnce, "view is destroyed on uninit");
+});
+
+
+function waitForObserver() {
+ return new Promise((resolve, reject) => {
+ Services.obs.addObserver((subject, topic) => {
+ resolve();
+ }, SyncedTabs.TOPIC_TABS_CHANGED, false);
+ });
+}
+
+add_task(function* testObserver() {
+ let deckStore = new SyncedTabsDeckStore();
+ let listStore = new SyncedTabsListStore(SyncedTabs);
+ let listComponent = {};
+
+ let ViewMock = sinon.stub();
+ let view = {render: sinon.spy(), destroy: sinon.spy(), container: {}};
+ ViewMock.returns(view);
+
+ sinon.stub(SyncedTabs, "syncTabs", () => Promise.resolve());
+
+ sinon.spy(deckStore, "on");
+ sinon.stub(deckStore, "setPanels");
+
+ sinon.stub(listStore, "getData");
+
+ let component = new SyncedTabsDeckComponent({
+ window,
+ deckStore,
+ listStore,
+ listComponent,
+ SyncedTabs,
+ DeckView: ViewMock,
+ });
+
+ sinon.spy(component, "observe");
+ sinon.stub(component, "updatePanel");
+
+ component.init();
+ SyncedTabs.syncTabs.restore();
+ Assert.ok(component.updatePanel.called, "triggers panel update during init");
+
+ Services.obs.notifyObservers(null, SyncedTabs.TOPIC_TABS_CHANGED, "");
+
+ Assert.ok(component.observe.calledWith(null, SyncedTabs.TOPIC_TABS_CHANGED, ""),
+ "component is notified");
+
+ Assert.ok(listStore.getData.called, "gets list data");
+ Assert.ok(component.updatePanel.calledTwice, "triggers panel update");
+
+ Services.obs.notifyObservers(null, FxAccountsCommon.ONLOGIN_NOTIFICATION, "");
+
+ Assert.ok(component.observe.calledWith(null, FxAccountsCommon.ONLOGIN_NOTIFICATION, ""),
+ "component is notified of login");
+ Assert.equal(component.updatePanel.callCount, 3, "triggers panel update again");
+});
+
+add_task(function* testPanelStatus() {
+ let deckStore = new SyncedTabsDeckStore();
+ let listStore = new SyncedTabsListStore();
+ let listComponent = {};
+ let fxAccounts = {
+ accountStatus() {}
+ };
+ let SyncedTabsMock = {
+ getTabClients() {}
+ };
+
+ sinon.stub(listStore, "getData");
+
+
+ let component = new SyncedTabsDeckComponent({
+ fxAccounts,
+ deckStore,
+ listComponent,
+ SyncedTabs: SyncedTabsMock,
+ });
+
+ let isAuthed = false;
+ sinon.stub(fxAccounts, "accountStatus", () => Promise.resolve(isAuthed));
+ let result = yield component.getPanelStatus();
+ Assert.equal(result, component.PANELS.NOT_AUTHED_INFO);
+
+ isAuthed = true;
+
+ SyncedTabsMock.isConfiguredToSyncTabs = false;
+ result = yield component.getPanelStatus();
+ Assert.equal(result, component.PANELS.TABS_DISABLED);
+
+ SyncedTabsMock.isConfiguredToSyncTabs = true;
+
+ SyncedTabsMock.hasSyncedThisSession = false;
+ result = yield component.getPanelStatus();
+ Assert.equal(result, component.PANELS.TABS_FETCHING);
+
+ SyncedTabsMock.hasSyncedThisSession = true;
+
+ let clients = [];
+ sinon.stub(SyncedTabsMock, "getTabClients", () => Promise.resolve(clients));
+ result = yield component.getPanelStatus();
+ Assert.equal(result, component.PANELS.SINGLE_DEVICE_INFO);
+
+ clients = ["mock-client"];
+ result = yield component.getPanelStatus();
+ Assert.equal(result, component.PANELS.TABS_CONTAINER);
+
+ fxAccounts.accountStatus.restore();
+ sinon.stub(fxAccounts, "accountStatus", () => Promise.reject("err"));
+ result = yield component.getPanelStatus();
+ Assert.equal(result, component.PANELS.NOT_AUTHED_INFO);
+
+ sinon.stub(component, "getPanelStatus", () => Promise.resolve("mock-panelId"));
+ sinon.spy(deckStore, "selectPanel");
+ yield component.updatePanel();
+ Assert.ok(deckStore.selectPanel.calledWith("mock-panelId"));
+});
+
+add_task(function* testActions() {
+ let windowMock = {
+ openUILink() {},
+ };
+ let chromeWindowMock = {
+ gSyncUI: {
+ openSetup() {}
+ }
+ };
+ sinon.spy(windowMock, "openUILink");
+ sinon.spy(chromeWindowMock.gSyncUI, "openSetup");
+
+ let getChromeWindowMock = sinon.stub();
+ getChromeWindowMock.returns(chromeWindowMock);
+
+ let component = new SyncedTabsDeckComponent({
+ window: windowMock,
+ getChromeWindowMock
+ });
+
+ let href = Services.prefs.getCharPref("identity.mobilepromo.android") + "synced-tabs-sidebar";
+ component.openAndroidLink("mock-event");
+ Assert.ok(windowMock.openUILink.calledWith(href, "mock-event"));
+
+ href = Services.prefs.getCharPref("identity.mobilepromo.ios") + "synced-tabs-sidebar";
+ component.openiOSLink("mock-event");
+ Assert.ok(windowMock.openUILink.calledWith(href, "mock-event"));
+
+ component.openSyncPrefs();
+ Assert.ok(getChromeWindowMock.calledWith(windowMock));
+ Assert.ok(chromeWindowMock.gSyncUI.openSetup.called);
+});