tor-browser

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

test_tab_quickwrite.js (7171B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 ChromeUtils.importESModule("resource://services-sync/engines/tabs.sys.mjs");
      5 const { Service } = ChromeUtils.importESModule(
      6  "resource://services-sync/service.sys.mjs"
      7 );
      8 
      9 const { TabProvider } = ChromeUtils.importESModule(
     10  "resource://services-sync/engines/tabs.sys.mjs"
     11 );
     12 
     13 const FAR_FUTURE = 4102405200000; // 2100/01/01
     14 
     15 add_task(async function setup() {
     16  // Since these are xpcshell tests, we'll need to mock ui features
     17  TabProvider.shouldSkipWindow = mockShouldSkipWindow;
     18  TabProvider.getWindowEnumerator = mockGetWindowEnumerator.bind(this, [
     19    "http://foo.com",
     20  ]);
     21 });
     22 
     23 async function prepareServer() {
     24  _("Setting up Sync server");
     25  Service.serverConfiguration = {
     26    max_post_records: 100,
     27  };
     28 
     29  let server = new SyncServer();
     30  server.start();
     31  await SyncTestingInfrastructure(server, "username");
     32  server.registerUser("username");
     33 
     34  let collection = server.createCollection("username", "tabs");
     35  await generateNewKeys(Service.collectionKeys);
     36 
     37  let engine = Service.engineManager.get("tabs");
     38  await engine.initialize();
     39 
     40  return { server, collection, engine };
     41 }
     42 
     43 async function withPatchedValue(object, name, patchedVal, fn) {
     44  _(`patching ${name}=${patchedVal}`);
     45  let old = object[name];
     46  object[name] = patchedVal;
     47  try {
     48    await fn();
     49  } finally {
     50    object[name] = old;
     51  }
     52 }
     53 
     54 add_task(async function test_tab_quickwrite_works() {
     55  _("Ensure a simple quickWrite works.");
     56  let { server, collection, engine } = await prepareServer();
     57  Assert.equal(collection.count(), 0, "starting with 0 tab records");
     58  Assert.ok(await engine.quickWrite());
     59  // Validate we didn't bork lastSync
     60  let lastSync = await engine.getLastSync();
     61  Assert.less(lastSync, FAR_FUTURE);
     62  Assert.equal(collection.count(), 1, "tab record was written");
     63 
     64  await promiseStopServer(server);
     65 });
     66 
     67 add_task(async function test_tab_bad_status() {
     68  _("Ensure quickWrite silently aborts when we aren't setup correctly.");
     69  let { server, engine } = await prepareServer();
     70  // Store the original lock to reset it back after this test
     71  let lock = engine.lock;
     72  // Arrange for this test to fail if it tries to take the lock.
     73  engine.lock = function () {
     74    throw new Error("this test should abort syncing before locking");
     75  };
     76  let quickWrite = engine.quickWrite.bind(engine); // lol javascript.
     77 
     78  await withPatchedValue(engine, "enabled", false, quickWrite);
     79  await withPatchedValue(Service, "serverConfiguration", null, quickWrite);
     80 
     81  Services.prefs.clearUserPref("services.sync.username");
     82  await quickWrite();
     83  // Validate we didn't bork lastSync
     84  let lastSync = await engine.getLastSync();
     85  Assert.less(lastSync, FAR_FUTURE);
     86  Service.status.resetSync();
     87  engine.lock = lock;
     88  await promiseStopServer(server);
     89 });
     90 
     91 add_task(async function test_tab_quickwrite_lock() {
     92  _("Ensure we fail to quickWrite if the engine is locked.");
     93  let { server, collection, engine } = await prepareServer();
     94 
     95  Assert.equal(collection.count(), 0, "starting with 0 tab records");
     96  engine.lock();
     97  Assert.ok(!(await engine.quickWrite()));
     98  Assert.equal(collection.count(), 0, "didn't sync due to being locked");
     99  engine.unlock();
    100 
    101  await promiseStopServer(server);
    102 });
    103 
    104 add_task(async function test_tab_quickwrite_keeps_old_tabs() {
    105  _("Ensure we don't delete other tabs on quickWrite (bug 1801295).");
    106  let { server, engine } = await prepareServer();
    107 
    108  // The ID of another device.
    109  const id = "fake-guid-99";
    110 
    111  // The clients engine is always going to tell us there are no other clients,
    112  // but we need other clients, so we trick it.
    113  // (We can't just stick this on the server, because we treat it as stale because it
    114  // doesn't appear in the fxa list - but tricking it this way works)
    115  let observeClientsFinished = (_subject, _topic, data) => {
    116    if (data == "clients") {
    117      engine.service.clientsEngine.fxAccounts.device._deviceListCache = {
    118        devices: [],
    119      };
    120      // trick the clients engine into thinking it has a remote client with the same guid.
    121      engine.service.clientsEngine._store._remoteClients = {};
    122      engine.service.clientsEngine._store._remoteClients[id] = {
    123        id,
    124        fxaDeviceId: id,
    125      };
    126    }
    127  };
    128  Services.obs.addObserver(observeClientsFinished, "weave:engine:sync:finish");
    129 
    130  // need a first sync to ensure everything is setup correctly.
    131  await Service.sync({ engines: ["tabs"] });
    132 
    133  let remoteRecord = encryptPayload({
    134    id,
    135    clientName: "not local",
    136    tabs: [
    137      {
    138        title: "title2",
    139        urlHistory: ["http://bar.com/"],
    140        icon: "",
    141        lastUsed: 3000,
    142      },
    143    ],
    144  });
    145 
    146  let collection = server.getCollection("username", "tabs");
    147  collection.insert(id, remoteRecord);
    148 
    149  // This test can be flakey because sometimes we are so fast we think there is nothing to do.
    150  // Resetting the last sync time here ensures we always fetch records from the server.
    151  engine.setLastSync(0);
    152  await Service.sync({ engines: ["tabs"] });
    153 
    154  // collection should now have 2 records - ours and the pretend remote one we inserted.
    155  Assert.equal(collection.count(), 2, "starting with 2 tab records");
    156 
    157  let clients = await engine.getAllClients();
    158  Assert.equal(clients.length, 1);
    159 
    160  _("Doing a quick-write");
    161  Assert.ok(await engine.quickWrite());
    162 
    163  // Should still have our client after a quickWrite.
    164  _("Grabbing clients after the quick-write");
    165  clients = await engine.getAllClients();
    166  Assert.equal(clients.length, 1);
    167 
    168  engine.service.clientsEngine._store._remoteClients = {};
    169 
    170  Services.obs.removeObserver(
    171    observeClientsFinished,
    172    "weave:engine:sync:finish"
    173  );
    174 
    175  await promiseStopServer(server);
    176 });
    177 
    178 add_task(async function test_tab_lastSync() {
    179  _("Ensure we restore the lastSync timestamp after a quick-write.");
    180  let { server, collection, engine } = await prepareServer();
    181 
    182  await engine.initialize();
    183  await engine.service.clientsEngine.initialize();
    184 
    185  let origLastSync = engine.lastSync;
    186  Assert.ok(await engine.quickWrite());
    187  Assert.equal(engine.lastSync, origLastSync);
    188  Assert.equal(collection.count(), 1, "successful sync");
    189  engine.unlock();
    190 
    191  await promiseStopServer(server);
    192 });
    193 
    194 add_task(async function test_tab_quickWrite_telemetry() {
    195  _("Ensure we record the telemetry we expect.");
    196  // hook into telemetry
    197  let telem = get_sync_test_telemetry();
    198  telem.payloads = [];
    199  let oldSubmit = telem.submit;
    200  let submitPromise = new Promise(resolve => {
    201    telem.submit = function (ping) {
    202      telem.submit = oldSubmit;
    203      resolve(ping);
    204    };
    205  });
    206 
    207  let { server, collection, engine } = await prepareServer();
    208 
    209  Assert.equal(collection.count(), 0, "starting with 0 tab records");
    210  Assert.ok(await engine.quickWrite());
    211  Assert.equal(collection.count(), 1, "tab record was written");
    212 
    213  let ping = await submitPromise;
    214  let syncs = ping.syncs;
    215  Assert.equal(syncs.length, 1);
    216  let sync = syncs[0];
    217  Assert.equal(sync.why, "quick-write");
    218  Assert.equal(sync.engines.length, 1);
    219  Assert.equal(sync.engines[0].name, "tabs");
    220 
    221  await promiseStopServer(server);
    222 });