tor-browser

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

browser_sync_pairing.js (4516B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const { UIState } = ChromeUtils.importESModule(
      7  "resource://services-sync/UIState.sys.mjs"
      8 );
      9 const { FxAccountsPairingFlow } = ChromeUtils.importESModule(
     10  "resource://gre/modules/FxAccountsPairing.sys.mjs"
     11 );
     12 
     13 // Use sinon for mocking.
     14 const { sinon } = ChromeUtils.importESModule(
     15  "resource://testing-common/Sinon.sys.mjs"
     16 );
     17 
     18 let flowCounter = 0;
     19 
     20 add_setup(async function () {
     21  Services.prefs.setBoolPref("identity.fxaccounts.pairing.enabled", true);
     22  // Sync start-up might interfere with our tests, don't let UIState send UI updates.
     23  const origNotifyStateUpdated = UIState._internal.notifyStateUpdated;
     24  UIState._internal.notifyStateUpdated = () => {};
     25 
     26  const origGet = UIState.get;
     27  UIState.get = () => {
     28    return { status: UIState.STATUS_SIGNED_IN, email: "foo@bar.com" };
     29  };
     30 
     31  const origStart = FxAccountsPairingFlow.start;
     32  FxAccountsPairingFlow.start = () => {
     33    return `https://foo.bar/${flowCounter++}`;
     34  };
     35 
     36  registerCleanupFunction(() => {
     37    UIState._internal.notifyStateUpdated = origNotifyStateUpdated;
     38    UIState.get = origGet;
     39    FxAccountsPairingFlow.start = origStart;
     40  });
     41 });
     42 
     43 add_task(async function testShowsQRCode() {
     44  await runWithPairingDialog(async win => {
     45    let doc = win.document;
     46    let qrContainer = doc.getElementById("qrContainer");
     47    let qrWrapper = doc.getElementById("qrWrapper");
     48 
     49    await TestUtils.waitForCondition(
     50      () => qrWrapper.getAttribute("pairing-status") == "ready"
     51    );
     52 
     53    // Verify that a QRcode is being shown.
     54    Assert.ok(
     55      qrContainer.style.backgroundImage.startsWith(
     56        `url("data:image/gif;base64,R0lGODdhOgA6AIAAAAAAAP///ywAAAAAOgA6AAAC/4yPqcvtD6OctNqLs968+w+G4gKU5nkiJYO2JuW6KsDGKEw3a7AbPZ+r4Ry7nzFIQkKKN6Avlzowo78`
     57      )
     58    );
     59 
     60    // Close the dialog.
     61    let promiseUnloaded = BrowserTestUtils.waitForEvent(win, "unload");
     62    gBrowser.contentDocument.querySelector(".dialogClose").click();
     63 
     64    info("waiting for dialog to unload");
     65    await promiseUnloaded;
     66  });
     67 });
     68 
     69 add_task(async function testCantShowQrCode() {
     70  const origStart = FxAccountsPairingFlow.start;
     71  FxAccountsPairingFlow.start = async () => {
     72    throw new Error("boom");
     73  };
     74  await runWithPairingDialog(async win => {
     75    let doc = win.document;
     76    let qrWrapper = doc.getElementById("qrWrapper");
     77 
     78    await TestUtils.waitForCondition(
     79      () => qrWrapper.getAttribute("pairing-status") == "error"
     80    );
     81 
     82    // Close the dialog.
     83    let promiseUnloaded = BrowserTestUtils.waitForEvent(win, "unload");
     84    gBrowser.contentDocument.querySelector(".dialogClose").click();
     85 
     86    info("waiting for dialog to unload");
     87    await promiseUnloaded;
     88  });
     89  FxAccountsPairingFlow.start = origStart;
     90 });
     91 
     92 add_task(async function testSwitchToWebContent() {
     93  await runWithPairingDialog(async win => {
     94    let doc = win.document;
     95    let qrWrapper = doc.getElementById("qrWrapper");
     96 
     97    await TestUtils.waitForCondition(
     98      () => qrWrapper.getAttribute("pairing-status") == "ready"
     99    );
    100 
    101    const spySwitchURL = sinon.spy(win.gFxaPairDeviceDialog, "_switchToUrl");
    102    const emitter = win.gFxaPairDeviceDialog._emitter;
    103    emitter.emit("view:SwitchToWebContent", "about:robots");
    104 
    105    Assert.equal(spySwitchURL.callCount, 1);
    106  });
    107 });
    108 
    109 add_task(async function testError() {
    110  await runWithPairingDialog(async win => {
    111    let doc = win.document;
    112    let qrWrapper = doc.getElementById("qrWrapper");
    113 
    114    await TestUtils.waitForCondition(
    115      () => qrWrapper.getAttribute("pairing-status") == "ready"
    116    );
    117 
    118    const emitter = win.gFxaPairDeviceDialog._emitter;
    119    emitter.emit("view:Error");
    120 
    121    await TestUtils.waitForCondition(
    122      () => qrWrapper.getAttribute("pairing-status") == "error"
    123    );
    124 
    125    // Close the dialog.
    126    let promiseUnloaded = BrowserTestUtils.waitForEvent(win, "unload");
    127    gBrowser.contentDocument.querySelector(".dialogClose").click();
    128 
    129    info("waiting for dialog to unload");
    130    await promiseUnloaded;
    131  });
    132 });
    133 
    134 async function runWithPairingDialog(test) {
    135  await openPreferencesViaOpenPreferencesAPI("paneSync", { leaveOpen: true });
    136 
    137  let promiseSubDialogLoaded = promiseLoadSubDialog(
    138    "chrome://browser/content/preferences/fxaPairDevice.xhtml"
    139  );
    140  gBrowser.contentWindow.gSyncPane.pairAnotherDevice();
    141 
    142  let win = await promiseSubDialogLoaded;
    143 
    144  await test(win);
    145 
    146  sinon.restore();
    147 
    148  BrowserTestUtils.removeTab(gBrowser.selectedTab);
    149 }