tor-browser

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

browser_fxa_config.js (10564B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const { sinon } = ChromeUtils.importESModule(
      7  "resource://testing-common/Sinon.sys.mjs"
      8 );
      9 
     10 const { UIState } = ChromeUtils.importESModule(
     11  "resource://services-sync/UIState.sys.mjs"
     12 );
     13 
     14 var gTestTab;
     15 var gContentAPI;
     16 
     17 add_task(setup_UITourTest);
     18 
     19 add_UITour_task(async function test_no_user() {
     20  const sandbox = sinon.createSandbox();
     21  sandbox.stub(fxAccounts, "getSignedInUser").returns(null);
     22  let result = await getConfigurationPromise("fxa");
     23  Assert.deepEqual(result, { setup: false });
     24  sandbox.restore();
     25 });
     26 
     27 add_UITour_task(async function test_no_sync_no_devices() {
     28  const sandbox = sinon.createSandbox();
     29  sandbox
     30    .stub(fxAccounts, "getSignedInUser")
     31    .returns({ email: "foo@example.com" });
     32  sandbox.stub(fxAccounts.device, "recentDeviceList").get(() => {
     33    return [
     34      {
     35        id: 1,
     36        name: "This Device",
     37        isCurrentDevice: true,
     38        type: "desktop",
     39      },
     40    ];
     41  });
     42  sandbox.stub(fxAccounts, "listAttachedOAuthClients").resolves([]);
     43  sandbox.stub(fxAccounts, "hasLocalSession").resolves(true);
     44 
     45  let result = await getConfigurationPromise("fxaConnections");
     46  Assert.deepEqual(result, {
     47    setup: true,
     48    numOtherDevices: 0,
     49    numDevicesByType: {},
     50    accountServices: {},
     51  });
     52  sandbox.restore();
     53 });
     54 
     55 add_UITour_task(async function test_no_sync_many_devices() {
     56  const sandbox = sinon.createSandbox();
     57  sandbox
     58    .stub(fxAccounts, "getSignedInUser")
     59    .returns({ email: "foo@example.com" });
     60  sandbox.stub(fxAccounts.device, "recentDeviceList").get(() => {
     61    return [
     62      {
     63        id: 1,
     64        name: "This Device",
     65        isCurrentDevice: true,
     66        type: "desktop",
     67      },
     68      {
     69        id: 2,
     70        name: "Other Device",
     71        type: "mobile",
     72      },
     73      {
     74        id: 3,
     75        name: "My phone",
     76        type: "phone",
     77      },
     78      {
     79        id: 4,
     80        name: "Who knows?",
     81      },
     82      {
     83        id: 5,
     84        name: "Another desktop",
     85        type: "desktop",
     86      },
     87      {
     88        id: 6,
     89        name: "Yet Another desktop",
     90        type: "desktop",
     91      },
     92    ];
     93  });
     94  sandbox.stub(fxAccounts, "listAttachedOAuthClients").resolves([]);
     95  sandbox.stub(fxAccounts, "hasLocalSession").resolves(true);
     96 
     97  let result = await getConfigurationPromise("fxaConnections");
     98  Assert.deepEqual(result, {
     99    setup: true,
    100    accountServices: {},
    101    numOtherDevices: 5,
    102    numDevicesByType: {
    103      desktop: 2,
    104      mobile: 1,
    105      phone: 1,
    106      unknown: 1,
    107    },
    108  });
    109  sandbox.restore();
    110 });
    111 
    112 add_UITour_task(async function test_fxa_connections_no_cached_devices() {
    113  const sandbox = sinon.createSandbox();
    114  sandbox
    115    .stub(fxAccounts, "getSignedInUser")
    116    .returns({ email: "foo@example.com" });
    117  let devicesStub = sandbox.stub(fxAccounts.device, "recentDeviceList");
    118  devicesStub.get(() => {
    119    // Sinon doesn't seem to support second `getters` returning a different
    120    // value, so replace the getter here.
    121    devicesStub.get(() => {
    122      return [
    123        {
    124          id: 1,
    125          name: "This Device",
    126          isCurrentDevice: true,
    127          type: "desktop",
    128        },
    129        {
    130          id: 2,
    131          name: "Other Device",
    132          type: "mobile",
    133        },
    134      ];
    135    });
    136    // and here we want to say "nothing is yet cached"
    137    return null;
    138  });
    139 
    140  sandbox.stub(fxAccounts, "listAttachedOAuthClients").resolves([]);
    141  sandbox.stub(fxAccounts, "hasLocalSession").resolves(true);
    142  let rdlStub = sandbox.stub(fxAccounts.device, "refreshDeviceList").resolves();
    143 
    144  let result = await getConfigurationPromise("fxaConnections");
    145  Assert.deepEqual(result, {
    146    setup: true,
    147    accountServices: {},
    148    numOtherDevices: 1,
    149    numDevicesByType: {
    150      mobile: 1,
    151    },
    152  });
    153  Assert.ok(rdlStub.called);
    154  sandbox.restore();
    155 });
    156 
    157 add_UITour_task(async function test_account_connections() {
    158  const sandbox = sinon.createSandbox();
    159  sandbox
    160    .stub(fxAccounts, "getSignedInUser")
    161    .returns({ email: "foo@example.com" });
    162  sandbox.stub(fxAccounts.device, "recentDeviceList").get(() => []);
    163  sandbox.stub(fxAccounts, "listAttachedOAuthClients").resolves([
    164    {
    165      id: "802d56ef2a9af9fa",
    166      lastAccessedDaysAgo: 2,
    167    },
    168    {
    169      id: "1f30e32975ae5112",
    170      lastAccessedDaysAgo: 10,
    171    },
    172    {
    173      id: null,
    174      name: "Some browser",
    175      lastAccessedDaysAgo: 10,
    176    },
    177    {
    178      id: "null-last-accessed",
    179      lastAccessedDaysAgo: null,
    180    },
    181  ]);
    182  Assert.deepEqual(await getConfigurationPromise("fxaConnections"), {
    183    setup: true,
    184    numOtherDevices: 0,
    185    numDevicesByType: {},
    186    accountServices: {
    187      "802d56ef2a9af9fa": {
    188        id: "802d56ef2a9af9fa",
    189        lastAccessedWeeksAgo: 0,
    190      },
    191      "1f30e32975ae5112": {
    192        id: "1f30e32975ae5112",
    193        lastAccessedWeeksAgo: 1,
    194      },
    195      "null-last-accessed": {
    196        id: "null-last-accessed",
    197        lastAccessedWeeksAgo: null,
    198      },
    199    },
    200  });
    201  sandbox.restore();
    202 });
    203 
    204 add_UITour_task(async function test_sync() {
    205  const sandbox = sinon.createSandbox();
    206  sandbox
    207    .stub(fxAccounts, "getSignedInUser")
    208    .returns({ email: "foo@example.com" });
    209  sandbox.stub(fxAccounts.device, "recentDeviceList").get(() => []);
    210  sandbox.stub(fxAccounts, "listAttachedOAuthClients").resolves([]);
    211  sandbox.stub(fxAccounts, "hasLocalSession").resolves(true);
    212  Services.prefs.setCharPref("services.sync.username", "tests@mozilla.org");
    213  Services.prefs.setIntPref("services.sync.clients.devices.desktop", 4);
    214  Services.prefs.setIntPref("services.sync.clients.devices.mobile", 5);
    215  Services.prefs.setIntPref("services.sync.numClients", 9);
    216 
    217  Assert.deepEqual(await getConfigurationPromise("fxa"), {
    218    setup: true,
    219    accountStateOK: true,
    220    browserServices: {
    221      sync: {
    222        setup: true,
    223        mobileDevices: 5,
    224        desktopDevices: 4,
    225        totalDevices: 9,
    226      },
    227    },
    228  });
    229  Services.prefs.clearUserPref("services.sync.username");
    230  Services.prefs.clearUserPref("services.sync.clients.devices.desktop");
    231  Services.prefs.clearUserPref("services.sync.clients.devices.mobile");
    232  Services.prefs.clearUserPref("services.sync.numClients");
    233  sandbox.restore();
    234 });
    235 
    236 add_UITour_task(async function test_fxa_fails() {
    237  const sandbox = sinon.createSandbox();
    238  sandbox.stub(fxAccounts, "getSignedInUser").throws();
    239  let result = await getConfigurationPromise("fxa");
    240  Assert.deepEqual(result, {});
    241  sandbox.restore();
    242 });
    243 
    244 /**
    245 * Tests that a UITour page can get notifications on FxA sign-in state
    246 * changes.
    247 */
    248 add_UITour_task(async function test_fxa_signedin_state_change() {
    249  const sandbox = sinon.createSandbox();
    250  registerCleanupFunction(() => {
    251    sandbox.restore();
    252  });
    253 
    254  let fxaConfig = await getConfigurationPromise("fxa");
    255  Assert.ok(!fxaConfig.setup, "FxA should not yet be set up.");
    256 
    257  // A helper function that waits for the state change event to fire
    258  // in content, and returns a Promise that resolves to the status
    259  // parameter on the event detail.
    260  let waitForSignedInStateChange = () => {
    261    return SpecialPowers.spawn(gTestTab.linkedBrowser, [], async () => {
    262      let event = await ContentTaskUtils.waitForEvent(
    263        content.document,
    264        "mozUITourNotification",
    265        false,
    266        e => {
    267          return e.detail.event === "FxA:SignedInStateChange";
    268        },
    269        true
    270      );
    271      return event.detail.params.status;
    272    });
    273  };
    274 
    275  // We'll first test the STATUS_SIGNED_IN status.
    276 
    277  let stateChangePromise = waitForSignedInStateChange();
    278 
    279  // Per bug 1743857, we wait for a JSWindowActor message round trip to
    280  // ensure that the mozUITourNotification event listener has been setup
    281  // in the SpecialPowers.spawn task.
    282  await new Promise(resolve => {
    283    gContentAPI.ping(resolve);
    284  });
    285 
    286  let UIStateStub = sandbox.stub(UIState, "get").returns({
    287    status: UIState.STATUS_SIGNED_IN,
    288    syncEnabled: true,
    289    email: "email@example.com",
    290  });
    291 
    292  Services.obs.notifyObservers(null, UIState.ON_UPDATE);
    293 
    294  let status = await stateChangePromise;
    295  Assert.equal(
    296    status,
    297    UIState.STATUS_SIGNED_IN,
    298    "FxA:SignedInStateChange should have notified that we'd signed in."
    299  );
    300 
    301  // We'll next test the STATUS_NOT_CONFIGURED status.
    302 
    303  stateChangePromise = waitForSignedInStateChange();
    304 
    305  // Per bug 1743857, we wait for a JSWindowActor message round trip to
    306  // ensure that the mozUITourNotification event listener has been setup
    307  // in the SpecialPowers.spawn task.
    308  await new Promise(resolve => {
    309    gContentAPI.ping(resolve);
    310  });
    311 
    312  UIStateStub.restore();
    313  UIStateStub = sandbox.stub(UIState, "get").returns({
    314    status: UIState.STATUS_NOT_CONFIGURED,
    315  });
    316 
    317  Services.obs.notifyObservers(null, UIState.ON_UPDATE);
    318 
    319  status = await stateChangePromise;
    320  Assert.equal(
    321    status,
    322    UIState.STATUS_NOT_CONFIGURED,
    323    "FxA:SignedInStateChange should have notified that we're not configured."
    324  );
    325 
    326  // We'll next test the STATUS_LOGIN_FAILED status.
    327 
    328  stateChangePromise = waitForSignedInStateChange();
    329 
    330  // Per bug 1743857, we wait for a JSWindowActor message round trip to
    331  // ensure that the mozUITourNotification event listener has been setup
    332  // in the SpecialPowers.spawn task.
    333  await new Promise(resolve => {
    334    gContentAPI.ping(resolve);
    335  });
    336 
    337  UIStateStub.restore();
    338  UIStateStub = sandbox.stub(UIState, "get").returns({
    339    email: "foo@example.com",
    340    status: UIState.STATUS_LOGIN_FAILED,
    341  });
    342 
    343  Services.obs.notifyObservers(null, UIState.ON_UPDATE);
    344 
    345  status = await stateChangePromise;
    346  Assert.equal(
    347    status,
    348    UIState.STATUS_LOGIN_FAILED,
    349    "FxA:SignedInStateChange should have notified that login has failed."
    350  );
    351 
    352  // We'll next test the STATUS_NOT_VERIFIED status.
    353 
    354  stateChangePromise = waitForSignedInStateChange();
    355 
    356  // Per bug 1743857, we wait for a JSWindowActor message round trip to
    357  // ensure that the mozUITourNotification event listener has been setup
    358  // in the SpecialPowers.spawn task.
    359  await new Promise(resolve => {
    360    gContentAPI.ping(resolve);
    361  });
    362 
    363  UIStateStub.restore();
    364  UIStateStub = sandbox.stub(UIState, "get").returns({
    365    email: "foo@example.com",
    366    status: UIState.STATUS_NOT_VERIFIED,
    367  });
    368 
    369  Services.obs.notifyObservers(null, UIState.ON_UPDATE);
    370 
    371  status = await stateChangePromise;
    372  Assert.equal(
    373    status,
    374    UIState.STATUS_NOT_VERIFIED,
    375    "FxA:SignedInStateChange should have notified that the login hasn't yet been verified."
    376  );
    377 
    378  sandbox.restore();
    379 });