Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

"use strict";
let { SyncedTabs } = ChromeUtils.importESModule(
);
let { SyncedTabsDeckComponent } = ChromeUtils.importESModule(
"resource:///modules/syncedtabs/SyncedTabsDeckComponent.sys.mjs"
);
let { SyncedTabsListStore } = ChromeUtils.importESModule(
"resource:///modules/syncedtabs/SyncedTabsListStore.sys.mjs"
);
let { SyncedTabsDeckStore } = ChromeUtils.importESModule(
"resource:///modules/syncedtabs/SyncedTabsDeckStore.sys.mjs"
);
const { UIState } = ChromeUtils.importESModule(
);
add_task(async function testInitUninit() {
let deckStore = new SyncedTabsDeckStore();
let listComponent = {};
let mockWindow = {};
let ViewMock = sinon.stub();
let view = { render: sinon.spy(), destroy: sinon.spy(), container: {} };
ViewMock.returns(view);
sinon.stub(SyncedTabs, "syncTabs").callsFake(() => Promise.resolve());
sinon.spy(deckStore, "on");
sinon.stub(deckStore, "setPanels");
let component = new SyncedTabsDeckComponent({
window: mockWindow,
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], mockWindow);
Assert.equal(ViewMock.args[0][1], listComponent);
Assert.ok(
ViewMock.args[0][2].onConnectDeviceClick,
"view is passed onConnectDeviceClick 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");
});
add_task(async function testObserver() {
let deckStore = new SyncedTabsDeckStore();
let listStore = new SyncedTabsListStore(SyncedTabs);
let listComponent = {};
let mockWindow = {};
let ViewMock = sinon.stub();
let view = { render: sinon.spy(), destroy: sinon.spy(), container: {} };
ViewMock.returns(view);
sinon.stub(SyncedTabs, "syncTabs").callsFake(() => Promise.resolve());
sinon.spy(deckStore, "on");
sinon.stub(deckStore, "setPanels");
sinon.stub(listStore, "getData");
let component = new SyncedTabsDeckComponent({
window: mockWindow,
deckStore,
listStore,
listComponent,
SyncedTabs,
DeckView: ViewMock,
});
sinon.spy(component, "observe");
sinon.stub(component, "updatePanel");
sinon.stub(component, "updateDir");
component.init();
SyncedTabs.syncTabs.restore();
Assert.ok(component.updatePanel.called, "triggers panel update during init");
Assert.ok(
component.updateDir.called,
"triggers UI direction 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, UIState.ON_UPDATE);
Assert.ok(
component.observe.calledWith(null, UIState.ON_UPDATE),
"component is notified of FxA/Sync UI Update"
);
Assert.equal(
component.updatePanel.callCount,
3,
"triggers panel update again"
);
Services.locale.availableLocales = ["ab-CD"];
Services.locale.requestedLocales = ["ab-CD"];
Assert.ok(
component.updateDir.calledTwice,
"locale change triggers UI direction update"
);
Services.prefs.setStringPref("intl.l10n.pseudo", "bidi");
Assert.equal(
component.updateDir.callCount,
3,
"pref change triggers UI direction update"
);
});
add_task(async function testPanelStatus() {
let deckStore = new SyncedTabsDeckStore();
let listStore = new SyncedTabsListStore();
let listComponent = {};
let SyncedTabsMock = {
getTabClients() {},
};
sinon.stub(listStore, "getData");
let component = new SyncedTabsDeckComponent({
deckStore,
listComponent,
SyncedTabs: SyncedTabsMock,
});
sinon.stub(UIState, "get").returns({ status: UIState.STATUS_NOT_CONFIGURED });
let result = await component.getPanelStatus();
Assert.equal(result, component.PANELS.NOT_AUTHED_INFO);
UIState.get.restore();
sinon.stub(UIState, "get").returns({ status: UIState.STATUS_NOT_VERIFIED });
result = await component.getPanelStatus();
Assert.equal(result, component.PANELS.UNVERIFIED);
UIState.get.restore();
sinon.stub(UIState, "get").returns({ status: UIState.STATUS_LOGIN_FAILED });
result = await component.getPanelStatus();
Assert.equal(result, component.PANELS.LOGIN_FAILED);
UIState.get.restore();
sinon
.stub(UIState, "get")
.returns({ status: UIState.STATUS_SIGNED_IN, syncEnabled: false });
SyncedTabsMock.isConfiguredToSyncTabs = true;
result = await component.getPanelStatus();
Assert.equal(result, component.PANELS.SYNC_DISABLED);
UIState.get.restore();
sinon
.stub(UIState, "get")
.returns({ status: UIState.STATUS_SIGNED_IN, syncEnabled: true });
SyncedTabsMock.isConfiguredToSyncTabs = false;
result = await component.getPanelStatus();
Assert.equal(result, component.PANELS.TABS_DISABLED);
SyncedTabsMock.isConfiguredToSyncTabs = true;
SyncedTabsMock.hasSyncedThisSession = false;
result = await component.getPanelStatus();
Assert.equal(result, component.PANELS.TABS_FETCHING);
SyncedTabsMock.hasSyncedThisSession = true;
let clients = [];
sinon
.stub(SyncedTabsMock, "getTabClients")
.callsFake(() => Promise.resolve(clients));
result = await component.getPanelStatus();
Assert.equal(result, component.PANELS.SINGLE_DEVICE_INFO);
clients = ["mock-client"];
result = await component.getPanelStatus();
Assert.equal(result, component.PANELS.TABS_CONTAINER);
sinon
.stub(component, "getPanelStatus")
.callsFake(() => Promise.resolve("mock-panelId"));
sinon.spy(deckStore, "selectPanel");
await component.updatePanel();
Assert.ok(deckStore.selectPanel.calledWith("mock-panelId"));
});
add_task(async function testActions() {
let windowMock = {};
let chromeWindowMock = {
gSync: {
openPrefs() {},
openConnectAnotherDevice() {},
},
};
sinon.spy(chromeWindowMock.gSync, "openPrefs");
sinon.spy(chromeWindowMock.gSync, "openConnectAnotherDevice");
let getChromeWindowMock = sinon.stub();
getChromeWindowMock.returns(chromeWindowMock);
let component = new SyncedTabsDeckComponent({
window: windowMock,
getChromeWindowMock,
});
component.openConnectDevice();
Assert.ok(chromeWindowMock.gSync.openConnectAnotherDevice.called);
component.openSyncPrefs();
Assert.ok(getChromeWindowMock.calledWith(windowMock));
Assert.ok(chromeWindowMock.gSync.openPrefs.called);
});