diff options
Diffstat (limited to 'browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckComponent.js')
-rw-r--r-- | browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckComponent.js | 218 |
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); +}); |