tor-browser

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

test_device.js (5048B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const { getFxAccountsSingleton } = ChromeUtils.importESModule(
      7  "resource://gre/modules/FxAccounts.sys.mjs"
      8 );
      9 const fxAccounts = getFxAccountsSingleton();
     10 
     11 const { CLIENT_IS_THUNDERBIRD, ON_NEW_DEVICE_ID, PREF_ACCOUNT_ROOT } =
     12  ChromeUtils.importESModule("resource://gre/modules/FxAccountsCommon.sys.mjs");
     13 const { TestUtils } = ChromeUtils.importESModule(
     14  "resource://testing-common/TestUtils.sys.mjs"
     15 );
     16 
     17 _("Misc tests for FxAccounts.device");
     18 
     19 fxAccounts.device._checkRemoteCommandsUpdateNeeded = async () => false;
     20 
     21 add_test(function test_default_device_name() {
     22  // Note that head_helpers overrides getDefaultLocalName - this test is
     23  // really just to ensure the actual implementation is sane - we can't
     24  // really check the value it uses is correct.
     25  // We are just hoping to avoid a repeat of bug 1369285.
     26  let def = fxAccounts.device.getDefaultLocalName(); // make sure it doesn't throw.
     27  _("default value is " + def);
     28  ok(!!def.length);
     29 
     30  // This is obviously tied to the implementation, but we want early warning
     31  // if any of these things fail.
     32  // We really want one of these 2 to provide a value.
     33  let hostname = Services.sysinfo.get("device") || Services.dns.myHostName;
     34  _("hostname is " + hostname);
     35  ok(!!hostname.length);
     36  // the hostname should be in the default.
     37  ok(def.includes(hostname));
     38  // We expect the following to work as a fallback to the above.
     39  let fallback = Cc["@mozilla.org/network/protocol;1?name=http"].getService(
     40    Ci.nsIHttpProtocolHandler
     41  ).oscpu;
     42  _("UA fallback is " + fallback);
     43  ok(!!fallback.length);
     44  // the fallback should not be in the default
     45  ok(!def.includes(fallback));
     46 
     47  run_next_test();
     48 });
     49 
     50 add_test(function test_migration() {
     51  Services.prefs.clearUserPref("identity.fxaccounts.account.device.name");
     52  Services.prefs.setStringPref("services.sync.client.name", "my client name");
     53  // calling getLocalName() should move the name to the new pref and reset the old.
     54  equal(fxAccounts.device.getLocalName(), "my client name");
     55  equal(
     56    Services.prefs.getStringPref("identity.fxaccounts.account.device.name"),
     57    "my client name"
     58  );
     59  ok(!Services.prefs.prefHasUserValue("services.sync.client.name"));
     60  run_next_test();
     61 });
     62 
     63 add_test(function test_migration_set_before_get() {
     64  Services.prefs.setStringPref("services.sync.client.name", "old client name");
     65  fxAccounts.device.setLocalName("new client name");
     66  equal(fxAccounts.device.getLocalName(), "new client name");
     67  run_next_test();
     68 });
     69 
     70 add_task(async function test_reset() {
     71  // We don't test the client name specifically here because the client name
     72  // is set as part of signing the user in via the attempt to register the
     73  // device.
     74  const testPref = PREF_ACCOUNT_ROOT + "test-pref";
     75  Services.prefs.setStringPref(testPref, "whatever");
     76  let credentials = {
     77    email: "foo@example.com",
     78    uid: "1234@lcip.org",
     79    sessionToken: "dead",
     80    verified: true,
     81    ...MOCK_ACCOUNT_KEYS,
     82  };
     83  // FxA will try to register its device record in the background after signin.
     84  const registerDevice = sinon
     85    .stub(fxAccounts._internal.fxAccountsClient, "registerDevice")
     86    .callsFake(async () => {
     87      return { id: "foo" };
     88    });
     89  const notifyPromise = TestUtils.topicObserved(ON_NEW_DEVICE_ID);
     90  await fxAccounts._internal.setSignedInUser(credentials);
     91  await notifyPromise;
     92  if (!CLIENT_IS_THUNDERBIRD) {
     93    // Firefox fires the notification twice - once during `setSignedInUser` and
     94    // once after it returns. It's the second notification we need to wait for.
     95    // Thunderbird, OTOH, fires only once during `setSignedInUser` and that's
     96    // what we need to wait for.
     97    await TestUtils.topicObserved(ON_NEW_DEVICE_ID);
     98  }
     99  ok(!Services.prefs.prefHasUserValue(testPref));
    100  // signing the user out should reset the name pref.
    101  const namePref = PREF_ACCOUNT_ROOT + "device.name";
    102  ok(Services.prefs.prefHasUserValue(namePref));
    103  await fxAccounts.signOut(/* localOnly = */ true);
    104  ok(!Services.prefs.prefHasUserValue(namePref));
    105  registerDevice.restore();
    106 });
    107 
    108 add_task(async function test_name_sanitization() {
    109  fxAccounts.device.setLocalName("emoji is valid \u2665");
    110  Assert.equal(fxAccounts.device.getLocalName(), "emoji is valid \u2665");
    111 
    112  let invalid = "x\uFFFD\n\r\t" + "x".repeat(255);
    113  let sanitized = "x\uFFFD\uFFFD\uFFFD\uFFFD" + "x".repeat(250); // 255 total.
    114 
    115  // If the pref already has the invalid value we still get the valid one back.
    116  Services.prefs.setStringPref(
    117    "identity.fxaccounts.account.device.name",
    118    invalid
    119  );
    120  Assert.equal(fxAccounts.device.getLocalName(), sanitized);
    121 
    122  // But if we explicitly set it to an invalid name, the sanitized value ends
    123  // up in the pref.
    124  fxAccounts.device.setLocalName(invalid);
    125  Assert.equal(fxAccounts.device.getLocalName(), sanitized);
    126  Assert.equal(
    127    Services.prefs.getStringPref("identity.fxaccounts.account.device.name"),
    128    sanitized
    129  );
    130 });