tor-browser

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

unit-entry.js (14956B)


      1 import {
      2  FakensIPrefService,
      3  GlobalOverrider,
      4  FakeConsoleAPI,
      5  FakeLogger,
      6 } from "asrouter/tests/unit/utils";
      7 import Adapter from "enzyme-adapter-react-16";
      8 import enzyme from "enzyme";
      9 
     10 enzyme.configure({ adapter: new Adapter() });
     11 
     12 // Cause React warnings to make tests that trigger them fail
     13 const origConsoleError = console.error;
     14 console.error = function (msg, ...args) {
     15  origConsoleError.apply(console, [msg, ...args]);
     16 
     17  if (
     18    /(Invalid prop|Failed prop type|Check the render method|React Intl)/.test(
     19      msg
     20    )
     21  ) {
     22    throw new Error(msg);
     23  }
     24 };
     25 
     26 const req = require.context(".", true, /\.test\.jsx?$/);
     27 const files = req.keys();
     28 
     29 // This exposes sinon assertions to chai.assert
     30 sinon.assert.expose(assert, { prefix: "" });
     31 
     32 const overrider = new GlobalOverrider();
     33 
     34 const RemoteSettings = name => ({
     35  get: () => {
     36    if (name === "attachment") {
     37      return Promise.resolve([{ attachment: {} }]);
     38    }
     39    return Promise.resolve([]);
     40  },
     41  on: () => {},
     42  off: () => {},
     43 });
     44 RemoteSettings.pollChanges = () => {};
     45 
     46 class JSWindowActorParent {
     47  sendAsyncMessage(name, data) {
     48    return { name, data };
     49  }
     50 }
     51 
     52 class JSWindowActorChild {
     53  sendAsyncMessage(name, data) {
     54    return { name, data };
     55  }
     56 
     57  sendQuery(name, data) {
     58    return Promise.resolve({ name, data });
     59  }
     60 
     61  get contentWindow() {
     62    return {
     63      Promise,
     64    };
     65  }
     66 }
     67 
     68 // Detect plain object passed to lazy getter APIs, and set its prototype to
     69 // global object, and return the global object for further modification.
     70 // Returns the object if it's not plain object.
     71 //
     72 // This is a workaround to make the existing testharness and testcase keep
     73 // working even after lazy getters are moved to plain `lazy` object.
     74 const cachedPlainObject = new Set();
     75 function updateGlobalOrObject(object) {
     76  // Given this function modifies the prototype, and the following
     77  // condition doesn't meet on the second call, cache the result.
     78  if (cachedPlainObject.has(object)) {
     79    return global;
     80  }
     81 
     82  if (Object.getPrototypeOf(object).constructor.name !== "Object") {
     83    return object;
     84  }
     85 
     86  cachedPlainObject.add(object);
     87  Object.setPrototypeOf(object, global);
     88  return global;
     89 }
     90 
     91 const TEST_GLOBAL = {
     92  JSWindowActorParent,
     93  JSWindowActorChild,
     94  AboutReaderParent: {
     95    addMessageListener: (_messageName, _listener) => {},
     96    removeMessageListener: (_messageName, _listener) => {},
     97  },
     98  AboutWelcomeTelemetry: class {
     99    submitGleanPingForPing() {}
    100  },
    101  AddonManager: {
    102    getActiveAddons() {
    103      return Promise.resolve({ addons: [], fullData: false });
    104    },
    105  },
    106  AppConstants: {
    107    MOZILLA_OFFICIAL: true,
    108    MOZ_APP_VERSION: "69.0a1",
    109    isPlatformAndVersionAtMost() {
    110      return false;
    111    },
    112    platform: "win",
    113  },
    114  ASRouterPreferences: {
    115    console: new FakeConsoleAPI({
    116      maxLogLevel: "off", // set this to "debug" or "all" to get more ASRouter logging in tests
    117      prefix: "ASRouter",
    118    }),
    119  },
    120  AWScreenUtils: {
    121    evaluateTargetingAndRemoveScreens() {
    122      return true;
    123    },
    124    async removeScreens() {
    125      return true;
    126    },
    127    evaluateScreenTargeting() {
    128      return true;
    129    },
    130  },
    131  BrowserUtils: {
    132    sendToDeviceEmailsSupported() {
    133      return true;
    134    },
    135    isChinaRepack() {
    136      return false;
    137    },
    138  },
    139  UpdateUtils: { getUpdateChannel() {} },
    140  BasePromiseWorker: class {
    141    constructor() {
    142      this.ExceptionHandlers = [];
    143    }
    144    post() {}
    145  },
    146  browserSearchRegion: "US",
    147  BrowserWindowTracker: { getTopWindow() {} },
    148  ChromeUtils: {
    149    defineLazyGetter(object, name, f) {
    150      updateGlobalOrObject(object)[name] = f();
    151    },
    152    defineESModuleGetters: updateGlobalOrObject,
    153    generateQI() {
    154      return {};
    155    },
    156    importESModule() {
    157      return global;
    158    },
    159  },
    160  ClientEnvironment: {
    161    get userId() {
    162      return "foo123";
    163    },
    164  },
    165  Components: {
    166    Constructor(classId) {
    167      switch (classId) {
    168        case "@mozilla.org/referrer-info;1":
    169          return function (referrerPolicy, sendReferrer, originalReferrer) {
    170            this.referrerPolicy = referrerPolicy;
    171            this.sendReferrer = sendReferrer;
    172            this.originalReferrer = originalReferrer;
    173          };
    174      }
    175      return function () {};
    176    },
    177    isSuccessCode: () => true,
    178  },
    179  // NB: These are functions/constructors
    180  // eslint-disable-next-line object-shorthand
    181  ContentSearchUIController: function () {},
    182  // eslint-disable-next-line object-shorthand
    183  ContentSearchHandoffUIController: function () {},
    184  Cc: {
    185    "@mozilla.org/browser/nav-bookmarks-service;1": {
    186      addObserver() {},
    187      getService() {
    188        return this;
    189      },
    190      removeObserver() {},
    191      SOURCES: {},
    192      TYPE_BOOKMARK: {},
    193    },
    194    "@mozilla.org/browser/nav-history-service;1": {
    195      addObserver() {},
    196      executeQuery() {},
    197      getNewQuery() {},
    198      getNewQueryOptions() {},
    199      getService() {
    200        return this;
    201      },
    202      insert() {},
    203      markPageAsTyped() {},
    204      removeObserver() {},
    205      pageFrecencyThreshold() {},
    206    },
    207    "@mozilla.org/io/string-input-stream;1": {
    208      createInstance() {
    209        return {};
    210      },
    211    },
    212    "@mozilla.org/updates/update-checker;1": { createInstance() {} },
    213    "@mozilla.org/widget/useridleservice;1": {
    214      getService() {
    215        return {
    216          idleTime: 0,
    217          addIdleObserver() {},
    218          removeIdleObserver() {},
    219        };
    220      },
    221    },
    222    "@mozilla.org/streamConverters;1": {
    223      getService() {
    224        return this;
    225      },
    226    },
    227    "@mozilla.org/network/stream-loader;1": {
    228      createInstance() {
    229        return {};
    230      },
    231    },
    232  },
    233  Ci: {
    234    nsICryptoHash: {},
    235    nsIReferrerInfo: { UNSAFE_URL: 5 },
    236    nsITimer: { TYPE_ONE_SHOT: 1 },
    237    nsIWebProgressListener: { LOCATION_CHANGE_SAME_DOCUMENT: 1 },
    238    nsIDOMWindow: Object,
    239    nsITrackingDBService: {
    240      TRACKERS_ID: 1,
    241      TRACKING_COOKIES_ID: 2,
    242      CRYPTOMINERS_ID: 3,
    243      FINGERPRINTERS_ID: 4,
    244      SOCIAL_ID: 5,
    245    },
    246    nsICookieBannerService: {
    247      MODE_DISABLED: 0,
    248      MODE_REJECT: 1,
    249      MODE_REJECT_OR_ACCEPT: 2,
    250      MODE_UNSET: 3,
    251    },
    252  },
    253  Cu: {
    254    importGlobalProperties() {},
    255    now: () => window.performance.now(),
    256    cloneInto: o => JSON.parse(JSON.stringify(o)),
    257  },
    258  console: {
    259    ...console,
    260    error() {},
    261  },
    262  dump() {},
    263  EveryWindow: {
    264    registerCallback: (_id, _init, _uninit) => {},
    265    unregisterCallback: _id => {},
    266  },
    267  setTimeout: window.setTimeout.bind(window),
    268  clearTimeout: window.clearTimeout.bind(window),
    269  fetch() {},
    270  // eslint-disable-next-line object-shorthand
    271  Image: function () {}, // NB: This is a function/constructor
    272  IOUtils: {
    273    writeJSON() {
    274      return Promise.resolve(0);
    275    },
    276    readJSON() {
    277      return Promise.resolve({});
    278    },
    279    read() {
    280      return Promise.resolve(new Uint8Array());
    281    },
    282    makeDirectory() {
    283      return Promise.resolve(0);
    284    },
    285    write() {
    286      return Promise.resolve(0);
    287    },
    288    exists() {
    289      return Promise.resolve(0);
    290    },
    291    remove() {
    292      return Promise.resolve(0);
    293    },
    294    stat() {
    295      return Promise.resolve(0);
    296    },
    297  },
    298  NewTabUtils: {
    299    activityStreamProvider: {
    300      getTopFrecentSites: () => [],
    301      executePlacesQuery: async (sql, options) => ({ sql, options }),
    302    },
    303  },
    304  OS: {
    305    File: {
    306      writeAtomic() {},
    307      makeDir() {},
    308      stat() {},
    309      Error: {},
    310      read() {},
    311      exists() {},
    312      remove() {},
    313      removeEmptyDir() {},
    314    },
    315    Path: {
    316      join() {
    317        return "/";
    318      },
    319    },
    320    Constants: {
    321      Path: {
    322        localProfileDir: "/",
    323      },
    324    },
    325  },
    326  PathUtils: {
    327    join(...parts) {
    328      return parts[parts.length - 1];
    329    },
    330    joinRelative(...parts) {
    331      return parts[parts.length - 1];
    332    },
    333    getProfileDir() {
    334      return Promise.resolve("/");
    335    },
    336    getLocalProfileDir() {
    337      return Promise.resolve("/");
    338    },
    339  },
    340  PlacesUtils: {
    341    get bookmarks() {
    342      return TEST_GLOBAL.Cc["@mozilla.org/browser/nav-bookmarks-service;1"];
    343    },
    344    get history() {
    345      return TEST_GLOBAL.Cc["@mozilla.org/browser/nav-history-service;1"];
    346    },
    347    observers: {
    348      addListener() {},
    349      removeListener() {},
    350    },
    351  },
    352  PrivateBrowsingUtils: {
    353    isBrowserPrivate: () => false,
    354    isWindowPrivate: () => false,
    355    permanentPrivateBrowsing: false,
    356  },
    357  DownloadsViewUI: {
    358    getDisplayName: () => "filename.ext",
    359    getSizeWithUnits: () => "1.5 MB",
    360  },
    361  FileUtils: {
    362    // eslint-disable-next-line object-shorthand
    363    File: function () {}, // NB: This is a function/constructor
    364  },
    365  Region: {
    366    home: "US",
    367    REGION_TOPIC: "browser-region-updated",
    368  },
    369  Services: {
    370    sysinfo: {
    371      getProperty() {
    372        return false;
    373      },
    374    },
    375    dirsvc: {
    376      get: () => ({ parent: { parent: { path: "appPath" } } }),
    377    },
    378    env: {
    379      set: () => undefined,
    380    },
    381    locale: {
    382      get appLocaleAsBCP47() {
    383        return "en-US";
    384      },
    385      negotiateLanguages() {},
    386    },
    387    urlFormatter: { formatURL: str => str, formatURLPref: str => str },
    388    mm: {
    389      addMessageListener: (_msg, _cb) => this.receiveMessage(),
    390      removeMessageListener() {},
    391    },
    392    obs: {
    393      addObserver() {},
    394      removeObserver() {},
    395      notifyObservers() {},
    396    },
    397    uuid: {
    398      generateUUID() {
    399        return "{foo-123-foo}";
    400      },
    401    },
    402    console: { logStringMessage: () => {} },
    403    prefs: new FakensIPrefService(),
    404    tm: {
    405      dispatchToMainThread: cb => cb(),
    406      idleDispatchToMainThread: cb => cb(),
    407    },
    408    eTLD: {
    409      getBaseDomain({ spec }) {
    410        return spec.match(/\/([^/]+)/)[1];
    411      },
    412      getBaseDomainFromHost(host) {
    413        return host.match(/.*?(\w+\.\w+)$/)[1];
    414      },
    415      getPublicSuffix() {},
    416    },
    417    io: {
    418      newURI: spec => ({
    419        mutate: () => ({
    420          setRef: ref => ({
    421            finalize: () => ({
    422              ref,
    423              spec,
    424            }),
    425          }),
    426        }),
    427        spec,
    428      }),
    429    },
    430    search: {
    431      init() {
    432        return Promise.resolve();
    433      },
    434      getVisibleEngines: () =>
    435        Promise.resolve([{ identifier: "google" }, { identifier: "bing" }]),
    436      defaultEngine: {
    437        identifier: "google",
    438        aliases: ["@google"],
    439      },
    440      defaultPrivateEngine: {
    441        identifier: "bing",
    442        aliases: ["@bing"],
    443      },
    444      getEngineByAlias: async () => null,
    445    },
    446    scriptSecurityManager: {
    447      createNullPrincipal() {},
    448      getSystemPrincipal() {},
    449    },
    450    wm: {
    451      getMostRecentWindow: () => window,
    452      getMostRecentBrowserWindow: () => window,
    453      getEnumerator: () => [],
    454    },
    455    ww: { registerNotification() {}, unregisterNotification() {} },
    456    appinfo: { appBuildID: "20180710100040", version: "69.0a1" },
    457    scriptloader: { loadSubScript: () => {} },
    458    startup: {
    459      getStartupInfo() {
    460        return {
    461          process: {
    462            getTime() {
    463              return 1588010448000;
    464            },
    465          },
    466        };
    467      },
    468    },
    469  },
    470  XPCOMUtils: {
    471    defineLazyGlobalGetters: updateGlobalOrObject,
    472    defineLazyServiceGetter: updateGlobalOrObject,
    473    defineLazyServiceGetters: updateGlobalOrObject,
    474    defineLazyPreferenceGetter(object, name) {
    475      updateGlobalOrObject(object)[name] = "";
    476    },
    477    generateQI() {
    478      return {};
    479    },
    480  },
    481  ShellService: {
    482    doesAppNeedPin: () => false,
    483    isDefaultBrowser: () => true,
    484  },
    485  FilterExpressions: {
    486    eval() {
    487      return Promise.resolve(false);
    488    },
    489  },
    490  RemoteSettings,
    491  Localization: class {
    492    async formatMessages(stringsIds) {
    493      return Promise.resolve(
    494        stringsIds.map(({ id, args }) => ({ value: { string_id: id, args } }))
    495      );
    496    }
    497    async formatValue(stringId) {
    498      return Promise.resolve(stringId);
    499    }
    500  },
    501  FxAccountsConfig: {
    502    promiseConnectAccountURI(id) {
    503      return Promise.resolve(id);
    504    },
    505  },
    506  FX_MONITOR_OAUTH_CLIENT_ID: "fake_client_id",
    507  ExperimentAPI: {},
    508  NimbusFeatures: {
    509    glean: {
    510      getVariable() {},
    511    },
    512    newtab: {
    513      getVariable() {},
    514      getAllVariables() {},
    515      onUpdate() {},
    516      offUpdate() {},
    517    },
    518    pocketNewtab: {
    519      getVariable() {},
    520      getAllVariables() {},
    521      onUpdate() {},
    522      offUpdate() {},
    523    },
    524    cookieBannerHandling: {
    525      getVariable() {},
    526    },
    527  },
    528  TelemetryEnvironment: {
    529    setExperimentActive() {},
    530    currentEnvironment: {
    531      profile: {
    532        creationDate: 16587,
    533      },
    534      settings: {},
    535    },
    536  },
    537  Sampling: {
    538    ratioSample(_seed, _ratios) {
    539      return Promise.resolve(0);
    540    },
    541  },
    542  BrowserHandler: {
    543    get kiosk() {
    544      return false;
    545    },
    546  },
    547  TelemetrySession: {
    548    getMetadata(reason) {
    549      return {
    550        reason,
    551        sessionId: "fake_session_id",
    552      };
    553    },
    554  },
    555  PageThumbs: {
    556    addExpirationFilter() {},
    557    removeExpirationFilter() {},
    558  },
    559  Logger: FakeLogger,
    560  getFxAccountsSingleton() {},
    561  AWEnsureAddonInstalled() {
    562    return Promise.resolve({ value: "complete" });
    563  },
    564  AboutNewTab: {},
    565  Glean: {
    566    newtab: {
    567      opened: {
    568        record() {},
    569      },
    570      closed: {
    571        record() {},
    572      },
    573      locale: {
    574        set() {},
    575      },
    576      newtabCategory: {
    577        set() {},
    578      },
    579      homepageCategory: {
    580        set() {},
    581      },
    582      blockedSponsors: {
    583        set() {},
    584      },
    585      sovAllocation: {
    586        set() {},
    587      },
    588    },
    589    newtabSearch: {
    590      enabled: {
    591        set() {},
    592      },
    593    },
    594    pocket: {
    595      enabled: {
    596        set() {},
    597      },
    598      impression: {
    599        record() {},
    600      },
    601      isSignedIn: {
    602        set() {},
    603      },
    604      sponsoredStoriesEnabled: {
    605        set() {},
    606      },
    607      click: {
    608        record() {},
    609      },
    610      save: {
    611        record() {},
    612      },
    613      topicClick: {
    614        record() {},
    615      },
    616    },
    617    topsites: {
    618      enabled: {
    619        set() {},
    620      },
    621      sponsoredEnabled: {
    622        set() {},
    623      },
    624      impression: {
    625        record() {},
    626      },
    627      click: {
    628        record() {},
    629      },
    630      rows: {
    631        set() {},
    632      },
    633      showPrivacyClick: {
    634        record() {},
    635      },
    636      dismiss: {
    637        record() {},
    638      },
    639      prefChanged: {
    640        record() {},
    641      },
    642    },
    643    topSites: {
    644      pingType: {
    645        set() {},
    646      },
    647      position: {
    648        set() {},
    649      },
    650      source: {
    651        set() {},
    652      },
    653      tileId: {
    654        set() {},
    655      },
    656      reportingUrl: {
    657        set() {},
    658      },
    659      advertiser: {
    660        set() {},
    661      },
    662      contextId: {
    663        set() {},
    664      },
    665    },
    666  },
    667  GleanPings: {
    668    newtab: {
    669      submit() {},
    670    },
    671    topSites: {
    672      submit() {},
    673    },
    674  },
    675  Utils: {
    676    SERVER_URL: "bogus://foo",
    677  },
    678 };
    679 overrider.set(TEST_GLOBAL);
    680 
    681 describe("activity-stream", () => {
    682  after(() => overrider.restore());
    683  files.forEach(file => req(file));
    684 });