tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_SyncedTabsDeckComponent.js (7506B)


      1 "use strict";
      2 
      3 let { SyncedTabs } = ChromeUtils.importESModule(
      4  "resource://services-sync/SyncedTabs.sys.mjs"
      5 );
      6 let { SyncedTabsDeckComponent } = ChromeUtils.importESModule(
      7  "resource:///modules/syncedtabs/SyncedTabsDeckComponent.sys.mjs"
      8 );
      9 let { SyncedTabsListStore } = ChromeUtils.importESModule(
     10  "resource:///modules/syncedtabs/SyncedTabsListStore.sys.mjs"
     11 );
     12 let { SyncedTabsDeckStore } = ChromeUtils.importESModule(
     13  "resource:///modules/syncedtabs/SyncedTabsDeckStore.sys.mjs"
     14 );
     15 const { UIState } = ChromeUtils.importESModule(
     16  "resource://services-sync/UIState.sys.mjs"
     17 );
     18 
     19 add_task(async function testInitUninit() {
     20  let deckStore = new SyncedTabsDeckStore();
     21  let listComponent = {};
     22  let mockWindow = {};
     23 
     24  let ViewMock = sinon.stub();
     25  let view = { render: sinon.spy(), destroy: sinon.spy(), container: {} };
     26  ViewMock.returns(view);
     27 
     28  sinon.stub(SyncedTabs, "syncTabs").callsFake(() => Promise.resolve());
     29 
     30  sinon.spy(deckStore, "on");
     31  sinon.stub(deckStore, "setPanels");
     32 
     33  let component = new SyncedTabsDeckComponent({
     34    window: mockWindow,
     35    deckStore,
     36    listComponent,
     37    SyncedTabs,
     38    DeckView: ViewMock,
     39  });
     40 
     41  sinon.stub(component, "updatePanel");
     42 
     43  component.init();
     44 
     45  Assert.ok(SyncedTabs.syncTabs.called);
     46  SyncedTabs.syncTabs.restore();
     47 
     48  Assert.ok(ViewMock.calledWithNew(), "view is instantiated");
     49  Assert.equal(ViewMock.args[0][0], mockWindow);
     50  Assert.equal(ViewMock.args[0][1], listComponent);
     51  Assert.ok(
     52    ViewMock.args[0][2].onConnectDeviceClick,
     53    "view is passed onConnectDeviceClick prop"
     54  );
     55  Assert.ok(
     56    ViewMock.args[0][2].onSyncPrefClick,
     57    "view is passed onSyncPrefClick prop"
     58  );
     59 
     60  Assert.equal(
     61    component.container,
     62    view.container,
     63    "component returns view's container"
     64  );
     65 
     66  Assert.ok(deckStore.on.calledOnce, "listener is added to store");
     67  Assert.equal(deckStore.on.args[0][0], "change");
     68  // Object.values only in nightly
     69  let values = Object.keys(component.PANELS).map(k => component.PANELS[k]);
     70  Assert.ok(
     71    deckStore.setPanels.calledWith(values),
     72    "panels are set on deck store"
     73  );
     74 
     75  Assert.ok(component.updatePanel.called);
     76 
     77  deckStore.emit("change", "mock state");
     78  Assert.ok(
     79    view.render.calledWith("mock state"),
     80    "view.render is called on state change"
     81  );
     82 
     83  component.uninit();
     84 
     85  Assert.ok(view.destroy.calledOnce, "view is destroyed on uninit");
     86 });
     87 
     88 add_task(async function testObserver() {
     89  let deckStore = new SyncedTabsDeckStore();
     90  let listStore = new SyncedTabsListStore(SyncedTabs);
     91  let listComponent = {};
     92  let mockWindow = {};
     93 
     94  let ViewMock = sinon.stub();
     95  let view = { render: sinon.spy(), destroy: sinon.spy(), container: {} };
     96  ViewMock.returns(view);
     97 
     98  sinon.stub(SyncedTabs, "syncTabs").callsFake(() => Promise.resolve());
     99 
    100  sinon.spy(deckStore, "on");
    101  sinon.stub(deckStore, "setPanels");
    102 
    103  sinon.stub(listStore, "getData");
    104 
    105  let component = new SyncedTabsDeckComponent({
    106    window: mockWindow,
    107    deckStore,
    108    listStore,
    109    listComponent,
    110    SyncedTabs,
    111    DeckView: ViewMock,
    112  });
    113 
    114  sinon.spy(component, "observe");
    115  sinon.stub(component, "updatePanel");
    116  sinon.stub(component, "updateDir");
    117 
    118  component.init();
    119  SyncedTabs.syncTabs.restore();
    120  Assert.ok(component.updatePanel.called, "triggers panel update during init");
    121  Assert.ok(
    122    component.updateDir.called,
    123    "triggers UI direction update during init"
    124  );
    125 
    126  Services.obs.notifyObservers(null, SyncedTabs.TOPIC_TABS_CHANGED);
    127 
    128  Assert.ok(
    129    component.observe.calledWith(null, SyncedTabs.TOPIC_TABS_CHANGED),
    130    "component is notified"
    131  );
    132 
    133  Assert.ok(listStore.getData.called, "gets list data");
    134  Assert.ok(component.updatePanel.calledTwice, "triggers panel update");
    135 
    136  Services.obs.notifyObservers(null, UIState.ON_UPDATE);
    137 
    138  Assert.ok(
    139    component.observe.calledWith(null, UIState.ON_UPDATE),
    140    "component is notified of FxA/Sync UI Update"
    141  );
    142  Assert.equal(
    143    component.updatePanel.callCount,
    144    3,
    145    "triggers panel update again"
    146  );
    147 
    148  Services.locale.availableLocales = ["ab-CD"];
    149  Services.locale.requestedLocales = ["ab-CD"];
    150 
    151  Assert.ok(
    152    component.updateDir.calledTwice,
    153    "locale change triggers UI direction update"
    154  );
    155 
    156  Services.prefs.setStringPref("intl.l10n.pseudo", "bidi");
    157 
    158  Assert.equal(
    159    component.updateDir.callCount,
    160    3,
    161    "pref change triggers UI direction update"
    162  );
    163 });
    164 
    165 add_task(async function testPanelStatus() {
    166  let deckStore = new SyncedTabsDeckStore();
    167  let listStore = new SyncedTabsListStore();
    168  let listComponent = {};
    169  let SyncedTabsMock = {
    170    getTabClients() {},
    171  };
    172 
    173  sinon.stub(listStore, "getData");
    174 
    175  let component = new SyncedTabsDeckComponent({
    176    deckStore,
    177    listComponent,
    178    SyncedTabs: SyncedTabsMock,
    179  });
    180 
    181  sinon.stub(UIState, "get").returns({ status: UIState.STATUS_NOT_CONFIGURED });
    182  let result = await component.getPanelStatus();
    183  Assert.equal(result, component.PANELS.NOT_AUTHED_INFO);
    184  UIState.get.restore();
    185 
    186  sinon.stub(UIState, "get").returns({ status: UIState.STATUS_NOT_VERIFIED });
    187  result = await component.getPanelStatus();
    188  Assert.equal(result, component.PANELS.UNVERIFIED);
    189  UIState.get.restore();
    190 
    191  sinon.stub(UIState, "get").returns({ status: UIState.STATUS_LOGIN_FAILED });
    192  result = await component.getPanelStatus();
    193  Assert.equal(result, component.PANELS.LOGIN_FAILED);
    194  UIState.get.restore();
    195 
    196  sinon
    197    .stub(UIState, "get")
    198    .returns({ status: UIState.STATUS_SIGNED_IN, syncEnabled: false });
    199  SyncedTabsMock.isConfiguredToSyncTabs = true;
    200  result = await component.getPanelStatus();
    201  Assert.equal(result, component.PANELS.SYNC_DISABLED);
    202  UIState.get.restore();
    203 
    204  sinon
    205    .stub(UIState, "get")
    206    .returns({ status: UIState.STATUS_SIGNED_IN, syncEnabled: true });
    207  SyncedTabsMock.isConfiguredToSyncTabs = false;
    208  result = await component.getPanelStatus();
    209  Assert.equal(result, component.PANELS.TABS_DISABLED);
    210 
    211  SyncedTabsMock.isConfiguredToSyncTabs = true;
    212 
    213  SyncedTabsMock.hasSyncedThisSession = false;
    214  result = await component.getPanelStatus();
    215  Assert.equal(result, component.PANELS.TABS_FETCHING);
    216 
    217  SyncedTabsMock.hasSyncedThisSession = true;
    218 
    219  let clients = [];
    220  sinon
    221    .stub(SyncedTabsMock, "getTabClients")
    222    .callsFake(() => Promise.resolve(clients));
    223  result = await component.getPanelStatus();
    224  Assert.equal(result, component.PANELS.SINGLE_DEVICE_INFO);
    225 
    226  clients = ["mock-client"];
    227  result = await component.getPanelStatus();
    228  Assert.equal(result, component.PANELS.TABS_CONTAINER);
    229 
    230  sinon
    231    .stub(component, "getPanelStatus")
    232    .callsFake(() => Promise.resolve("mock-panelId"));
    233  sinon.spy(deckStore, "selectPanel");
    234  await component.updatePanel();
    235  Assert.ok(deckStore.selectPanel.calledWith("mock-panelId"));
    236 });
    237 
    238 add_task(async function testActions() {
    239  let windowMock = {};
    240  let chromeWindowMock = {
    241    gSync: {
    242      openPrefs() {},
    243      openConnectAnotherDevice() {},
    244    },
    245  };
    246  sinon.spy(chromeWindowMock.gSync, "openPrefs");
    247  sinon.spy(chromeWindowMock.gSync, "openConnectAnotherDevice");
    248 
    249  let getChromeWindowMock = sinon.stub();
    250  getChromeWindowMock.returns(chromeWindowMock);
    251 
    252  let component = new SyncedTabsDeckComponent({
    253    window: windowMock,
    254    getChromeWindowMock,
    255  });
    256 
    257  component.openConnectDevice();
    258  Assert.ok(chromeWindowMock.gSync.openConnectAnotherDevice.called);
    259 
    260  component.openSyncPrefs();
    261  Assert.ok(getChromeWindowMock.calledWith(windowMock));
    262  Assert.ok(chromeWindowMock.gSync.openPrefs.called);
    263 });