tor-browser

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

test_SyncedTabsListStore.js (7900B)


      1 "use strict";
      2 
      3 let { SyncedTabs } = ChromeUtils.importESModule(
      4  "resource://services-sync/SyncedTabs.sys.mjs"
      5 );
      6 let { SyncedTabsListStore } = ChromeUtils.importESModule(
      7  "resource:///modules/syncedtabs/SyncedTabsListStore.sys.mjs"
      8 );
      9 
     10 const FIXTURE = [
     11  {
     12    id: "2xU5h-4bkWqA",
     13    type: "client",
     14    lastModified: 1492201200,
     15    name: "laptop",
     16    isMobile: false,
     17    tabs: [
     18      {
     19        type: "tab",
     20        title:
     21          "Firefox for iOS — Mobile Web browser for your iPhone, iPad and iPod touch — Mozilla",
     22        url: "https://www.mozilla.org/en-US/firefox/ios/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=synced-tabs-sidebar",
     23        icon: "cached-favicon:https://www.mozilla.org/media/img/firefox/favicon.dc6635050bf5.ico",
     24        client: "2xU5h-4bkWqA",
     25        lastUsed: 1451519425,
     26      },
     27      {
     28        type: "tab",
     29        title: "Firefox Nightly First Run Page",
     30        url: "https://www.mozilla.org/en-US/firefox/nightly/firstrun/?oldversion=45.0a1",
     31        icon: "cached-favicon:https://www.mozilla.org/media/img/firefox/favicon-nightly.560395bbb2e1.png",
     32        client: "2xU5h-4bkWqA",
     33        lastUsed: 1451519420,
     34      },
     35    ],
     36  },
     37  {
     38    id: "OL3EJCsdb2JD",
     39    type: "client",
     40    lastModified: 1492201200,
     41    name: "desktop",
     42    isMobile: false,
     43    tabs: [],
     44  },
     45 ];
     46 
     47 add_task(async function testGetDataEmpty() {
     48  let store = new SyncedTabsListStore(SyncedTabs);
     49  let spy = sinon.spy();
     50 
     51  sinon.stub(SyncedTabs, "getTabClients").callsFake(() => {
     52    return Promise.resolve([]);
     53  });
     54  store.on("change", spy);
     55 
     56  await store.getData();
     57 
     58  Assert.ok(SyncedTabs.getTabClients.calledWith(""));
     59  Assert.ok(
     60    spy.calledWith({
     61      clients: [],
     62      canUpdateAll: false,
     63      canUpdateInput: false,
     64      filter: "",
     65      inputFocused: false,
     66    })
     67  );
     68 
     69  await store.getData("filter");
     70 
     71  Assert.ok(SyncedTabs.getTabClients.calledWith("filter"));
     72  Assert.ok(
     73    spy.calledWith({
     74      clients: [],
     75      canUpdateAll: false,
     76      canUpdateInput: true,
     77      filter: "filter",
     78      inputFocused: false,
     79    })
     80  );
     81 
     82  SyncedTabs.getTabClients.restore();
     83 });
     84 
     85 add_task(async function testRowSelectionWithoutFilter() {
     86  let store = new SyncedTabsListStore(SyncedTabs);
     87  let spy = sinon.spy();
     88 
     89  sinon.stub(SyncedTabs, "getTabClients").callsFake(() => {
     90    return Promise.resolve(FIXTURE);
     91  });
     92 
     93  await store.getData();
     94  SyncedTabs.getTabClients.restore();
     95 
     96  store.on("change", spy);
     97 
     98  store.selectRow(0, -1);
     99  Assert.ok(spy.args[0][0].canUpdateAll, "can update the whole view");
    100  Assert.ok(spy.args[0][0].clients[0].selected, "first client is selected");
    101 
    102  store.moveSelectionUp();
    103  Assert.ok(
    104    spy.calledOnce,
    105    "can't move up past first client, no change triggered"
    106  );
    107 
    108  store.selectRow(0, 0);
    109  Assert.ok(
    110    spy.args[1][0].clients[0].tabs[0].selected,
    111    "first tab of first client is selected"
    112  );
    113 
    114  store.selectRow(0, 0);
    115  Assert.ok(spy.calledTwice, "selecting same row doesn't trigger change");
    116 
    117  store.selectRow(0, 1);
    118  Assert.ok(
    119    spy.args[2][0].clients[0].tabs[1].selected,
    120    "second tab of first client is selected"
    121  );
    122 
    123  store.selectRow(1);
    124  Assert.ok(spy.args[3][0].clients[1].selected, "second client is selected");
    125 
    126  store.moveSelectionDown();
    127  Assert.equal(
    128    spy.callCount,
    129    4,
    130    "can't move selection down past last client, no change triggered"
    131  );
    132 
    133  store.moveSelectionUp();
    134  Assert.equal(spy.callCount, 5, "changed");
    135  Assert.ok(
    136    spy.args[4][0].clients[0].tabs[FIXTURE[0].tabs.length - 1].selected,
    137    "move selection up from client selects last tab of previous client"
    138  );
    139 
    140  store.moveSelectionUp();
    141  Assert.ok(
    142    spy.args[5][0].clients[0].tabs[FIXTURE[0].tabs.length - 2].selected,
    143    "move selection up from tab selects previous tab of client"
    144  );
    145 });
    146 
    147 add_task(async function testToggleBranches() {
    148  let store = new SyncedTabsListStore(SyncedTabs);
    149  let spy = sinon.spy();
    150 
    151  sinon.stub(SyncedTabs, "getTabClients").callsFake(() => {
    152    return Promise.resolve(FIXTURE);
    153  });
    154 
    155  await store.getData();
    156  SyncedTabs.getTabClients.restore();
    157 
    158  store.selectRow(0);
    159  store.on("change", spy);
    160 
    161  let clientId = FIXTURE[0].id;
    162  store.closeBranch(clientId);
    163  Assert.ok(spy.args[0][0].clients[0].closed, "first client is closed");
    164 
    165  store.openBranch(clientId);
    166  Assert.ok(!spy.args[1][0].clients[0].closed, "first client is open");
    167 
    168  store.toggleBranch(clientId);
    169  Assert.ok(spy.args[2][0].clients[0].closed, "first client is toggled closed");
    170 
    171  store.moveSelectionDown();
    172  Assert.ok(
    173    spy.args[3][0].clients[1].selected,
    174    "selection skips tabs if client is closed"
    175  );
    176 
    177  store.moveSelectionUp();
    178  Assert.ok(
    179    spy.args[4][0].clients[0].selected,
    180    "selection skips tabs if client is closed"
    181  );
    182 });
    183 
    184 add_task(async function testRowSelectionWithFilter() {
    185  let store = new SyncedTabsListStore(SyncedTabs);
    186  let spy = sinon.spy();
    187 
    188  sinon.stub(SyncedTabs, "getTabClients").callsFake(() => {
    189    return Promise.resolve(FIXTURE);
    190  });
    191 
    192  await store.getData("filter");
    193  SyncedTabs.getTabClients.restore();
    194 
    195  store.on("change", spy);
    196 
    197  store.selectRow(0);
    198  Assert.ok(
    199    spy.args[0][0].clients[0].tabs[0].selected,
    200    "first tab is selected"
    201  );
    202 
    203  store.moveSelectionUp();
    204  Assert.ok(
    205    spy.calledOnce,
    206    "can't move up past first tab, no change triggered"
    207  );
    208 
    209  store.moveSelectionDown();
    210  Assert.ok(
    211    spy.args[1][0].clients[0].tabs[1].selected,
    212    "selection skips tabs if client is closed"
    213  );
    214 
    215  store.moveSelectionDown();
    216  Assert.equal(
    217    spy.callCount,
    218    2,
    219    "can't move selection down past last tab, no change triggered"
    220  );
    221 
    222  store.selectRow(1);
    223  Assert.equal(spy.callCount, 2, "doesn't trigger change if same row selected");
    224 });
    225 
    226 add_task(async function testFilterAndClearFilter() {
    227  let store = new SyncedTabsListStore(SyncedTabs);
    228  let spy = sinon.spy();
    229 
    230  sinon.stub(SyncedTabs, "getTabClients").callsFake(() => {
    231    return Promise.resolve(FIXTURE);
    232  });
    233  store.on("change", spy);
    234 
    235  await store.getData("filter");
    236 
    237  Assert.ok(SyncedTabs.getTabClients.calledWith("filter"));
    238  Assert.ok(!spy.args[0][0].canUpdateAll, "can't update all");
    239  Assert.ok(spy.args[0][0].canUpdateInput, "can update just input");
    240 
    241  store.selectRow(0);
    242 
    243  Assert.equal(spy.args[1][0].filter, "filter");
    244  Assert.ok(spy.args[1][0].clients[0].tabs[0].selected, "tab is selected");
    245 
    246  await store.clearFilter();
    247 
    248  Assert.ok(SyncedTabs.getTabClients.calledWith(""));
    249  Assert.ok(!spy.args[2][0].canUpdateAll, "can't update all");
    250  Assert.ok(!spy.args[2][0].canUpdateInput, "can't just update input");
    251 
    252  Assert.equal(spy.args[2][0].filter, "");
    253  Assert.ok(
    254    !spy.args[2][0].clients[0].tabs[0].selected,
    255    "tab is no longer selected"
    256  );
    257 
    258  SyncedTabs.getTabClients.restore();
    259 });
    260 
    261 add_task(async function testFocusBlurInput() {
    262  let store = new SyncedTabsListStore(SyncedTabs);
    263  let spy = sinon.spy();
    264 
    265  sinon.stub(SyncedTabs, "getTabClients").callsFake(() => {
    266    return Promise.resolve(FIXTURE);
    267  });
    268  store.on("change", spy);
    269 
    270  await store.getData();
    271  SyncedTabs.getTabClients.restore();
    272 
    273  Assert.ok(!spy.args[0][0].canUpdateAll, "must rerender all");
    274 
    275  store.selectRow(0);
    276  Assert.ok(!spy.args[1][0].inputFocused, "input is not focused");
    277  Assert.ok(spy.args[1][0].clients[0].selected, "client is selected");
    278  Assert.ok(spy.args[1][0].clients[0].focused, "client is focused");
    279 
    280  store.focusInput();
    281  Assert.ok(spy.args[2][0].inputFocused, "input is focused");
    282  Assert.ok(spy.args[2][0].clients[0].selected, "client is still selected");
    283  Assert.ok(!spy.args[2][0].clients[0].focused, "client is no longer focused");
    284 
    285  store.blurInput();
    286  Assert.ok(!spy.args[3][0].inputFocused, "input is not focused");
    287  Assert.ok(spy.args[3][0].clients[0].selected, "client is selected");
    288  Assert.ok(spy.args[3][0].clients[0].focused, "client is focused");
    289 });