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 });