tor-browser

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

test_bridged_engine.js (5441B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 const { BridgedEngine } = ChromeUtils.importESModule(
      5  "resource://services-sync/bridged_engine.sys.mjs"
      6 );
      7 const { Service } = ChromeUtils.importESModule(
      8  "resource://services-sync/service.sys.mjs"
      9 );
     10 
     11 add_task(async function test_interface() {
     12  class TestBridge {
     13    constructor() {
     14      this.storageVersion = 2;
     15      this.syncID = "syncID111111";
     16      this.clear();
     17    }
     18 
     19    clear() {
     20      this.lastSyncMillis = 0;
     21      this.wasSyncStarted = false;
     22      this.incomingEnvelopes = [];
     23      this.uploadedIDs = [];
     24      this.wasSyncFinished = false;
     25      this.wasReset = false;
     26      this.wasWiped = false;
     27    }
     28 
     29    // `mozIBridgedSyncEngine` methods.
     30 
     31    lastSync() {
     32      return this.lastSyncMillis;
     33    }
     34 
     35    setLastSync(millis) {
     36      this.lastSyncMillis = millis;
     37    }
     38 
     39    resetSyncId() {
     40      return this.syncID;
     41    }
     42 
     43    ensureCurrentSyncId(newSyncId) {
     44      equal(newSyncId, this.syncID, "Local and new sync IDs should match");
     45      return this.syncID;
     46    }
     47 
     48    syncStarted() {
     49      this.wasSyncStarted = true;
     50    }
     51 
     52    storeIncoming(envelopes) {
     53      this.incomingEnvelopes.push(...envelopes.map(r => JSON.parse(r)));
     54    }
     55 
     56    apply() {
     57      let outgoingEnvelopes = [
     58        {
     59          id: "hanson",
     60          data: {
     61            plants: ["seed", "flower 💐", "rose"],
     62            canYouTell: false,
     63          },
     64        },
     65        {
     66          id: "sheryl-crow",
     67          data: {
     68            today: "winding 🛣",
     69            tomorrow: "winding 🛣",
     70          },
     71        },
     72      ].map(cleartext =>
     73        JSON.stringify({
     74          id: cleartext.id,
     75          payload: JSON.stringify(cleartext),
     76        })
     77      );
     78      return outgoingEnvelopes;
     79    }
     80 
     81    setUploaded(millis, ids) {
     82      this.uploadedIDs.push(...ids);
     83    }
     84 
     85    syncFinished() {
     86      this.wasSyncFinished = true;
     87    }
     88 
     89    reset() {
     90      this.clear();
     91      this.wasReset = true;
     92    }
     93 
     94    wipe() {
     95      this.clear();
     96      this.wasWiped = true;
     97    }
     98  }
     99 
    100  let bridge = new TestBridge();
    101  let engine = new BridgedEngine("Nineties", Service);
    102  engine._bridge = bridge;
    103  engine.enabled = true;
    104 
    105  let server = await serverForFoo(engine);
    106  try {
    107    await SyncTestingInfrastructure(server);
    108 
    109    info("Add server records");
    110    let foo = server.user("foo");
    111    let collection = foo.collection("nineties");
    112    let now = new_timestamp();
    113    collection.insert(
    114      "backstreet",
    115      encryptPayload({
    116        id: "backstreet",
    117        data: {
    118          say: "I want it that way",
    119          when: "never",
    120        },
    121      }),
    122      now
    123    );
    124    collection.insert(
    125      "tlc",
    126      encryptPayload({
    127        id: "tlc",
    128        data: {
    129          forbidden: ["scrubs 🚫"],
    130          numberAvailable: false,
    131        },
    132      }),
    133      now + 5
    134    );
    135 
    136    info("Sync the engine");
    137    // Advance the last sync time to skip the Backstreet Boys...
    138    bridge.lastSyncMillis = 1000 * (now + 2);
    139    await sync_engine_and_validate_telem(engine, false);
    140 
    141    let metaGlobal = foo.collection("meta").wbo("global").get();
    142    deepEqual(
    143      JSON.parse(metaGlobal.payload).engines.nineties,
    144      {
    145        version: 2,
    146        syncID: "syncID111111",
    147      },
    148      "Should write storage version and sync ID to m/g"
    149    );
    150 
    151    greater(bridge.lastSyncMillis, 0, "Should update last sync time");
    152    ok(
    153      bridge.wasSyncStarted,
    154      "Should have started sync before storing incoming"
    155    );
    156    deepEqual(
    157      bridge.incomingEnvelopes
    158        .sort((a, b) => a.id.localeCompare(b.id))
    159        .map(({ payload, ...envelope }) => ({
    160          cleartextAsObject: JSON.parse(payload),
    161          ...envelope,
    162        })),
    163      [
    164        {
    165          id: "tlc",
    166          modified: now + 5,
    167          cleartextAsObject: {
    168            id: "tlc",
    169            data: {
    170              forbidden: ["scrubs 🚫"],
    171              numberAvailable: false,
    172            },
    173          },
    174        },
    175      ],
    176      "Should stage incoming records from server"
    177    );
    178    deepEqual(
    179      bridge.uploadedIDs.sort(),
    180      ["hanson", "sheryl-crow"],
    181      "Should mark new local records as uploaded"
    182    );
    183    ok(bridge.wasSyncFinished, "Should have finished sync after uploading");
    184 
    185    deepEqual(
    186      collection.keys().sort(),
    187      ["backstreet", "hanson", "sheryl-crow", "tlc"],
    188      "Should have all records on server"
    189    );
    190    let expectedRecords = [
    191      {
    192        id: "sheryl-crow",
    193        data: {
    194          today: "winding 🛣",
    195          tomorrow: "winding 🛣",
    196        },
    197      },
    198      {
    199        id: "hanson",
    200        data: {
    201          plants: ["seed", "flower 💐", "rose"],
    202          canYouTell: false,
    203        },
    204      },
    205    ];
    206    for (let expected of expectedRecords) {
    207      let actual = collection.cleartext(expected.id);
    208      deepEqual(
    209        actual,
    210        expected,
    211        `Should upload record ${expected.id} from bridged engine`
    212      );
    213    }
    214 
    215    await engine.resetClient();
    216    ok(bridge.wasReset, "Should reset local storage for bridge");
    217 
    218    await engine.wipeClient();
    219    ok(bridge.wasWiped, "Should wipe local storage for bridge");
    220 
    221    await engine.resetSyncID();
    222    ok(
    223      !foo.collection("nineties"),
    224      "Should delete server collection after resetting sync ID"
    225    );
    226  } finally {
    227    await promiseStopServer(server);
    228    await engine.finalize();
    229  }
    230 });