Bug 1541888 - Enable ESLinting in dom/push/ r=glasserc,lina
authorMathieu Leplatre <mathieu@mozilla.com>
Tue, 09 Apr 2019 10:05:51 +0000
changeset 468586 829c937f690939edeb83cc5143214e8445fbbf36
parent 468585 354e9abf1a431424b554e2ce00e232dcc6955ff8
child 468587 6db3e21f8901c808ad1da3706fbc166328c4af22
push id112738
push usernbeleuzu@mozilla.com
push dateTue, 09 Apr 2019 22:28:41 +0000
treeherdermozilla-inbound@d6bbb316b768 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglasserc, lina
bugs1541888
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1541888 - Enable ESLinting in dom/push/ r=glasserc,lina Enable ESLinting in dom/push/ Differential Revision: https://phabricator.services.mozilla.com/D26321
.eslintignore
dom/push/Push.jsm
dom/push/PushBroadcastService.jsm
dom/push/PushComponents.jsm
dom/push/PushCrypto.jsm
dom/push/PushDB.jsm
dom/push/PushRecord.jsm
dom/push/PushService.jsm
dom/push/PushServiceAndroidGCM.jsm
dom/push/PushServiceHttp2.jsm
dom/push/PushServiceWebSocket.jsm
dom/push/test/lifetime_worker.js
dom/push/test/mockpushserviceparent.js
dom/push/test/test_data.html
dom/push/test/test_error_reporting.html
dom/push/test/test_has_permissions.html
dom/push/test/test_multiple_register.html
dom/push/test/test_multiple_register_different_scope.html
dom/push/test/test_multiple_register_during_service_activation.html
dom/push/test/test_permissions.html
dom/push/test/test_register.html
dom/push/test/test_register_key.html
dom/push/test/test_serviceworker_lifetime.html
dom/push/test/test_subscription_change.html
dom/push/test/test_try_registering_offline_disabled.html
dom/push/test/test_unregister.html
dom/push/test/test_utils.js
dom/push/test/webpush.js
dom/push/test/worker.js
dom/push/test/xpcshell/PushServiceHandler.js
dom/push/test/xpcshell/broadcast_handler.jsm
dom/push/test/xpcshell/head.js
dom/push/test/xpcshell/test_broadcast_success.js
dom/push/test/xpcshell/test_clearAll_successful.js
dom/push/test/xpcshell/test_clear_forgetAboutSite.js
dom/push/test/xpcshell/test_clear_origin_data.js
dom/push/test/xpcshell/test_crypto.js
dom/push/test/xpcshell/test_crypto_encrypt.js
dom/push/test/xpcshell/test_drop_expired.js
dom/push/test/xpcshell/test_notification_ack.js
dom/push/test/xpcshell/test_notification_data.js
dom/push/test/xpcshell/test_notification_duplicate.js
dom/push/test/xpcshell/test_notification_error.js
dom/push/test/xpcshell/test_notification_http2.js
dom/push/test/xpcshell/test_notification_incomplete.js
dom/push/test/xpcshell/test_notification_version_string.js
dom/push/test/xpcshell/test_observer_data.js
dom/push/test/xpcshell/test_observer_remoting.js
dom/push/test/xpcshell/test_permissions.js
dom/push/test/xpcshell/test_quota_exceeded.js
dom/push/test/xpcshell/test_quota_observer.js
dom/push/test/xpcshell/test_quota_with_notification.js
dom/push/test/xpcshell/test_reconnect_retry.js
dom/push/test/xpcshell/test_record.js
dom/push/test/xpcshell/test_register_5xxCode_http2.js
dom/push/test/xpcshell/test_register_case.js
dom/push/test/xpcshell/test_register_error_http2.js
dom/push/test/xpcshell/test_register_flush.js
dom/push/test/xpcshell/test_register_invalid_channel.js
dom/push/test/xpcshell/test_register_invalid_endpoint.js
dom/push/test/xpcshell/test_register_invalid_json.js
dom/push/test/xpcshell/test_register_no_id.js
dom/push/test/xpcshell/test_register_request_queue.js
dom/push/test/xpcshell/test_register_rollback.js
dom/push/test/xpcshell/test_register_success.js
dom/push/test/xpcshell/test_register_success_http2.js
dom/push/test/xpcshell/test_register_timeout.js
dom/push/test/xpcshell/test_register_wrong_id.js
dom/push/test/xpcshell/test_register_wrong_type.js
dom/push/test/xpcshell/test_registration_error.js
dom/push/test/xpcshell/test_registration_error_http2.js
dom/push/test/xpcshell/test_registration_missing_scope.js
dom/push/test/xpcshell/test_registration_none.js
dom/push/test/xpcshell/test_registration_success.js
dom/push/test/xpcshell/test_registration_success_http2.js
dom/push/test/xpcshell/test_resubscribe_4xxCode_http2.js
dom/push/test/xpcshell/test_resubscribe_5xxCode_http2.js
dom/push/test/xpcshell/test_resubscribe_listening_for_msg_error_http2.js
dom/push/test/xpcshell/test_retry_ws.js
dom/push/test/xpcshell/test_service_child.js
dom/push/test/xpcshell/test_service_parent.js
dom/push/test/xpcshell/test_unregister_empty_scope.js
dom/push/test/xpcshell/test_unregister_error.js
dom/push/test/xpcshell/test_unregister_invalid_json.js
dom/push/test/xpcshell/test_unregister_not_found.js
dom/push/test/xpcshell/test_unregister_success.js
dom/push/test/xpcshell/test_unregister_success_http2.js
dom/push/test/xpcshell/test_updateRecordNoEncryptionKeys_http2.js
dom/push/test/xpcshell/test_updateRecordNoEncryptionKeys_ws.js
--- a/.eslintignore
+++ b/.eslintignore
@@ -178,17 +178,16 @@ dom/media/webaudio/**
 dom/media/webspeech/**
 dom/messagechannel/**
 dom/midi/**
 dom/network/**
 dom/payments/**
 dom/performance/**
 dom/permission/**
 dom/promise/**
-dom/push/**
 dom/quota/**
 dom/security/test/cors/**
 dom/security/test/csp/**
 dom/security/test/general/**
 dom/security/test/mixedcontentblocker/**
 dom/security/test/sri/**
 dom/serviceworkers/**
 dom/smil/**
--- a/dom/push/Push.jsm
+++ b/dom/push/Push.jsm
@@ -30,39 +30,39 @@ function Push() {
   console.debug("Push()");
 }
 
 Push.prototype = {
   __proto__: DOMRequestIpcHelper.prototype,
 
   contractID: "@mozilla.org/push/PushManager;1",
 
-  classID : PUSH_CID,
+  classID: PUSH_CID,
 
-  QueryInterface : ChromeUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer,
-                                           Ci.nsISupportsWeakReference,
-                                           Ci.nsIObserver]),
+  QueryInterface: ChromeUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer,
+                                          Ci.nsISupportsWeakReference,
+                                          Ci.nsIObserver]),
 
-  init: function(win) {
+  init(win) {
     console.debug("init()");
 
     this._window = win;
 
     this.initDOMRequestHelper(win);
 
     this._principal = win.document.nodePrincipal;
 
     this._topLevelPrincipal = win.top.document.nodePrincipal;
   },
 
-  __init: function(scope) {
+  __init(scope) {
     this._scope = scope;
   },
 
-  askPermission: function () {
+  askPermission() {
     console.debug("askPermission()");
 
     let isHandlingUserInput = this._window.windowUtils.isHandlingUserInput;
 
     return this.createPromise((resolve, reject) => {
       let permissionDenied = () => {
         reject(new this._window.DOMException(
           "User denied permission to use the Push API.",
@@ -73,17 +73,17 @@ Push.prototype = {
       if (Services.prefs.getBoolPref("dom.push.testing.ignorePermission", false)) {
         resolve();
       }
 
       this._requestPermission(isHandlingUserInput, resolve, permissionDenied);
     });
   },
 
-  subscribe: function(options) {
+  subscribe(options) {
     console.debug("subscribe()", this._scope);
 
     return this.askPermission().then(() =>
       this.createPromise((resolve, reject) => {
         let callback = new PushSubscriptionCallback(this, resolve, reject);
 
         if (!options || options.applicationServerKey === null) {
           PushService.subscribe(this._scope, this._principal, callback);
@@ -97,17 +97,17 @@ Push.prototype = {
         }
         PushService.subscribeWithKey(this._scope, this._principal,
                                      keyView.byteLength, keyView,
                                      callback);
       })
     );
   },
 
-  _normalizeAppServerKey: function(appServerKey) {
+  _normalizeAppServerKey(appServerKey) {
     let key;
     if (typeof appServerKey == "string") {
       try {
         key = Cu.cloneInto(ChromeUtils.base64URLDecode(appServerKey, {
           padding: "reject",
         }), this._window);
       } catch (e) {
         throw new this._window.DOMException(
@@ -119,63 +119,63 @@ Push.prototype = {
       key = appServerKey.buffer;
     } else {
       // `appServerKey` is an array buffer.
       key = appServerKey;
     }
     return new this._window.Uint8Array(key);
   },
 
-  getSubscription: function() {
+  getSubscription() {
     console.debug("getSubscription()", this._scope);
 
     return this.createPromise((resolve, reject) => {
       let callback = new PushSubscriptionCallback(this, resolve, reject);
       PushService.getSubscription(this._scope, this._principal, callback);
     });
   },
 
-  permissionState: function() {
+  permissionState() {
     console.debug("permissionState()", this._scope);
 
     return this.createPromise((resolve, reject) => {
       let permission = Ci.nsIPermissionManager.UNKNOWN_ACTION;
 
       try {
         permission = this._testPermission();
-      } catch(e) {
+      } catch (e) {
         reject();
         return;
       }
 
       let pushPermissionStatus = "prompt";
       if (permission == Ci.nsIPermissionManager.ALLOW_ACTION) {
         pushPermissionStatus = "granted";
       } else if (permission == Ci.nsIPermissionManager.DENY_ACTION) {
         pushPermissionStatus = "denied";
       }
       resolve(pushPermissionStatus);
     });
   },
 
-  _testPermission: function() {
+  _testPermission() {
     let permission = Services.perms.testExactPermissionFromPrincipal(
       this._principal, "desktop-notification");
     if (permission == Ci.nsIPermissionManager.ALLOW_ACTION) {
       return permission;
     }
     try {
       if (Services.prefs.getBoolPref("dom.push.testing.ignorePermission")) {
         permission = Ci.nsIPermissionManager.ALLOW_ACTION;
       }
     } catch (e) {}
     return permission;
   },
 
-  _requestPermission: function(isHandlingUserInput, allowCallback, cancelCallback) {
+  _requestPermission(isHandlingUserInput, allowCallback, cancelCallback) {
     // Create an array with a single nsIContentPermissionType element.
     let type = {
       type: "desktop-notification",
       options: [],
       QueryInterface: ChromeUtils.generateQI([Ci.nsIContentPermissionType]),
     };
     let typeArray = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
     typeArray.appendElement(type);
@@ -203,60 +203,60 @@ function PushSubscriptionCallback(pushMa
   this.pushManager = pushManager;
   this.resolve = resolve;
   this.reject = reject;
 }
 
 PushSubscriptionCallback.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIPushSubscriptionCallback]),
 
-  onPushSubscription: function(ok, subscription) {
+  onPushSubscription(ok, subscription) {
     let {pushManager} = this;
     if (!Components.isSuccessCode(ok)) {
       this._rejectWithError(ok);
       return;
     }
 
     if (!subscription) {
       this.resolve(null);
       return;
     }
 
     let p256dhKey = this._getKey(subscription, "p256dh");
     let authSecret = this._getKey(subscription, "auth");
     let options = {
       endpoint: subscription.endpoint,
       scope: pushManager._scope,
-      p256dhKey: p256dhKey,
-      authSecret: authSecret,
+      p256dhKey,
+      authSecret,
     };
     let appServerKey = this._getKey(subscription, "appServer");
     if (appServerKey) {
       // Avoid passing null keys to work around bug 1256449.
       options.appServerKey = appServerKey;
     }
     let sub = new pushManager._window.PushSubscription(options);
     this.resolve(sub);
   },
 
-  _getKey: function(subscription, name) {
+  _getKey(subscription, name) {
     let outKeyLen = {};
     let rawKey = Cu.cloneInto(subscription.getKey(name, outKeyLen),
                               this.pushManager._window);
     if (!outKeyLen.value) {
       return null;
     }
 
     let key = new this.pushManager._window.ArrayBuffer(outKeyLen.value);
     let keyView = new this.pushManager._window.Uint8Array(key);
     keyView.set(rawKey);
     return key;
   },
 
-  _rejectWithError: function(result) {
+  _rejectWithError(result) {
     let error;
     switch (result) {
       case Cr.NS_ERROR_DOM_PUSH_INVALID_KEY_ERR:
         error = new this.pushManager._window.DOMException(
           "Invalid raw ECDSA P-256 public key.",
           "InvalidAccessError"
         );
         break;
@@ -273,9 +273,9 @@ PushSubscriptionCallback.prototype = {
           "Error retrieving push subscription.",
           "AbortError"
         );
     }
     this.reject(error);
   },
 };
 
-var EXPORTED_SYMBOLS = ["Push"];
+const EXPORTED_SYMBOLS = ["Push"];
--- a/dom/push/PushBroadcastService.jsm
+++ b/dom/push/PushBroadcastService.jsm
@@ -4,34 +4,34 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
 const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "JSONFile", "resource://gre/modules/JSONFile.jsm");
 
-var EXPORTED_SYMBOLS = ["pushBroadcastService"];
+const EXPORTED_SYMBOLS = ["pushBroadcastService"];
 
 // We are supposed to ignore any updates with this version.
 const DUMMY_VERSION_STRING = "____NOP____";
 
 XPCOMUtils.defineLazyGetter(this, "console", () => {
   let {ConsoleAPI} = ChromeUtils.import("resource://gre/modules/Console.jsm");
   return new ConsoleAPI({
     maxLogLevelPref: "dom.push.loglevel",
     prefix: "BroadcastService",
   });
 });
 ChromeUtils.defineModuleGetter(this, "PushService", "resource://gre/modules/PushService.jsm");
 
 class InvalidSourceInfo extends Error {
   constructor(message) {
     super(message);
-    this.name = 'InvalidSourceInfo';
+    this.name = "InvalidSourceInfo";
   }
 }
 
 const BROADCAST_SERVICE_VERSION = 1;
 
 var BroadcastService = class {
   constructor(pushService, path) {
     this.pushService = pushService;
@@ -172,17 +172,17 @@ var BroadcastService = class {
         console.error("receivedBroadcastMessage: couldn't invoke", broadcastId,
                       "because import of module", moduleURI,
                       "failed", e);
         continue;
       }
 
       if (!module[symbolName]) {
         console.error("receivedBroadcastMessage: couldn't invoke", broadcastId,
-                      "because module", moduleName, "missing attribute", symbolName);
+                      "because module", moduleURI, "missing attribute", symbolName);
         continue;
       }
 
       const handler = module[symbolName];
 
       if (!handler.receivedBroadcastMessage) {
         console.error("receivedBroadcastMessage: couldn't invoke", broadcastId,
                       "because handler returned by", `${moduleURI}.${symbolName}`,
@@ -209,21 +209,21 @@ var BroadcastService = class {
       }
     }
   }
 
   // For test only.
   _saveImmediately() {
     return this.jsonFile._save();
   }
-}
+};
 
 function initializeBroadcastService() {
   // Fallback path for xpcshell tests.
   let path = "broadcast-listeners.json";
   if (OS.Constants.Path.profileDir) {
     // Real path for use in a real profile.
     path = OS.Path.join(OS.Constants.Path.profileDir, path);
   }
   return new BroadcastService(PushService, path);
-};
+}
 
 var pushBroadcastService = initializeBroadcastService();
--- a/dom/push/PushComponents.jsm
+++ b/dom/push/PushComponents.jsm
@@ -84,17 +84,16 @@ PushServiceBase.prototype = {
     if (topic === "sessionstore-windows-restored") {
       Services.obs.removeObserver(this, "sessionstore-windows-restored");
       this._handleReady();
       return;
     }
     if (topic === "android-push-service") {
       // Load PushService immediately.
       this._handleReady();
-      return;
     }
   },
 
   _deliverSubscription(request, props) {
     if (!props) {
       request.onPushSubscription(Cr.NS_OK, null);
       return;
     }
@@ -142,48 +141,48 @@ Object.assign(PushServiceParent.prototyp
   // nsIPushService methods
 
   subscribe(scope, principal, callback) {
     this.subscribeWithKey(scope, principal, 0, null, callback);
   },
 
   subscribeWithKey(scope, principal, keyLen, key, callback) {
     this._handleRequest("Push:Register", principal, {
-      scope: scope,
+      scope,
       appServerKey: key,
     }).then(result => {
       this._deliverSubscription(callback, result);
     }, error => {
       this._deliverSubscriptionError(callback, error);
     }).catch(Cu.reportError);
   },
 
   unsubscribe(scope, principal, callback) {
     this._handleRequest("Push:Unregister", principal, {
-      scope: scope,
+      scope,
     }).then(result => {
       callback.onUnsubscribe(Cr.NS_OK, result);
     }, error => {
       callback.onUnsubscribe(Cr.NS_ERROR_FAILURE, false);
     }).catch(Cu.reportError);
   },
 
   getSubscription(scope, principal, callback) {
     return this._handleRequest("Push:Registration", principal, {
-      scope: scope,
+      scope,
     }).then(result => {
       this._deliverSubscription(callback, result);
     }, error => {
       this._deliverSubscriptionError(callback, error);
     }).catch(Cu.reportError);
   },
 
   clearForDomain(domain, callback) {
     return this._handleRequest("Push:Clear", null, {
-      domain: domain,
+      domain,
     }).then(result => {
       callback.onClear(Cr.NS_OK);
     }, error => {
       callback.onClear(Cr.NS_ERROR_FAILURE);
     }).catch(Cu.reportError);
   },
 
   // nsIPushQuotaManager methods
@@ -214,20 +213,20 @@ Object.assign(PushServiceParent.prototyp
     if (name === "Push:NotificationForOriginClosed") {
       this.notificationForOriginClosed(data);
       return;
     }
     if (name === "Push:ReportError") {
       this.reportDeliveryError(data.messageId, data.reason);
       return;
     }
-    return this._handleRequest(name, principal, data).then(result => {
+    this._handleRequest(name, principal, data).then(result => {
       target.sendAsyncMessage(this._getResponseName(name, "OK"), {
         requestID: data.requestID,
-        result: result
+        result,
       });
     }, error => {
       target.sendAsyncMessage(this._getResponseName(name, "KO"), {
         requestID: data.requestID,
         result: error.result,
       });
     }).catch(Cu.reportError);
   },
@@ -348,45 +347,45 @@ Object.assign(PushServiceContent.prototy
 
   // nsIPushService methods
 
   subscribe(scope, principal, callback) {
     this.subscribeWithKey(scope, principal, 0, null, callback);
   },
 
   subscribeWithKey(scope, principal, keyLen, key, callback) {
-    let requestId = this._addRequest(callback);
+    let requestID = this._addRequest(callback);
     this._mm.sendAsyncMessage("Push:Register", {
-      scope: scope,
+      scope,
       appServerKey: key,
-      requestID: requestId,
+      requestID,
     }, null, principal);
   },
 
   unsubscribe(scope, principal, callback) {
-    let requestId = this._addRequest(callback);
+    let requestID = this._addRequest(callback);
     this._mm.sendAsyncMessage("Push:Unregister", {
-      scope: scope,
-      requestID: requestId,
+      scope,
+      requestID,
     }, null, principal);
   },
 
   getSubscription(scope, principal, callback) {
-    let requestId = this._addRequest(callback);
+    let requestID = this._addRequest(callback);
     this._mm.sendAsyncMessage("Push:Registration", {
-      scope: scope,
-      requestID: requestId,
+      scope,
+      requestID,
     }, null, principal);
   },
 
   clearForDomain(domain, callback) {
-    let requestId = this._addRequest(callback);
+    let requestID = this._addRequest(callback);
     this._mm.sendAsyncMessage("Push:Clear", {
-      domain: domain,
-      requestID: requestId,
+      domain,
+      requestID,
     });
   },
 
   // nsIPushQuotaManager methods
 
   notificationForOriginShown(origin) {
     this._mm.sendAsyncMessage("Push:NotificationForOriginShown", origin);
   },
@@ -394,18 +393,18 @@ Object.assign(PushServiceContent.prototy
   notificationForOriginClosed(origin) {
     this._mm.sendAsyncMessage("Push:NotificationForOriginClosed", origin);
   },
 
   // nsIPushErrorReporter methods
 
   reportDeliveryError(messageId, reason) {
     this._mm.sendAsyncMessage("Push:ReportError", {
-      messageId: messageId,
-      reason: reason,
+      messageId,
+      reason,
     });
   },
 
   _addRequest(data) {
     let id = ++this._requestId;
     this._requests.set(id, data);
     return id;
   },
@@ -555,9 +554,9 @@ PushSubscription.prototype = {
     return rawKey;
   },
 };
 
 // Export the correct implementation depending on whether we're running in
 // the parent or content process.
 let Service = isParent ? PushServiceParent : PushServiceContent;
 
-var EXPORTED_SYMBOLS = ["Service"];
+const EXPORTED_SYMBOLS = ["Service"];
--- a/dom/push/PushCrypto.jsm
+++ b/dom/push/PushCrypto.jsm
@@ -1,52 +1,53 @@
-/* jshint moz: true, esnext: true */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-'use strict';
+"use strict";
 
-const {Services} = ChromeUtils.import('resource://gre/modules/Services.jsm');
-const {XPCOMUtils} = ChromeUtils.import('resource://gre/modules/XPCOMUtils.jsm');
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
-XPCOMUtils.defineLazyGetter(this, 'gDOMBundle', () =>
-  Services.strings.createBundle('chrome://global/locale/dom/dom.properties'));
+XPCOMUtils.defineLazyGetter(this, "gDOMBundle", () =>
+  Services.strings.createBundle("chrome://global/locale/dom/dom.properties"));
 
-XPCOMUtils.defineLazyGlobalGetters(this, ['crypto']);
+XPCOMUtils.defineLazyGlobalGetters(this, ["crypto"]);
 
-var EXPORTED_SYMBOLS = ['PushCrypto', 'concatArray'];
+const EXPORTED_SYMBOLS = ["PushCrypto", "concatArray"];
 
-var UTF8 = new TextEncoder('utf-8');
+const UTF8 = new TextEncoder("utf-8");
 
-var ECDH_KEY = { name: 'ECDH', namedCurve: 'P-256' };
-var ECDSA_KEY =  { name: 'ECDSA', namedCurve: 'P-256' };
+const ECDH_KEY = { name: "ECDH", namedCurve: "P-256" };
+const ECDSA_KEY = { name: "ECDSA", namedCurve: "P-256" };
+const HMAC_SHA256 = { name: "HMAC", hash: "SHA-256" };
+const NONCE_INFO = UTF8.encode("Content-Encoding: nonce");
 
 // A default keyid with a name that won't conflict with a real keyid.
-var DEFAULT_KEYID = '';
+const DEFAULT_KEYID = "";
 
 /** Localized error property names. */
 
 // `Encryption` header missing or malformed.
-const BAD_ENCRYPTION_HEADER = 'PushMessageBadEncryptionHeader';
+const BAD_ENCRYPTION_HEADER = "PushMessageBadEncryptionHeader";
 // `Crypto-Key` or legacy `Encryption-Key` header missing.
-const BAD_CRYPTO_KEY_HEADER = 'PushMessageBadCryptoKeyHeader';
-const BAD_ENCRYPTION_KEY_HEADER = 'PushMessageBadEncryptionKeyHeader';
+const BAD_CRYPTO_KEY_HEADER = "PushMessageBadCryptoKeyHeader";
+const BAD_ENCRYPTION_KEY_HEADER = "PushMessageBadEncryptionKeyHeader";
 // `Content-Encoding` header missing or contains unsupported encoding.
-const BAD_ENCODING_HEADER = 'PushMessageBadEncodingHeader';
+const BAD_ENCODING_HEADER = "PushMessageBadEncodingHeader";
 // `dh` parameter of `Crypto-Key` header missing or not base64url-encoded.
-const BAD_DH_PARAM = 'PushMessageBadSenderKey';
+const BAD_DH_PARAM = "PushMessageBadSenderKey";
 // `salt` parameter of `Encryption` header missing or not base64url-encoded.
-const BAD_SALT_PARAM = 'PushMessageBadSalt';
+const BAD_SALT_PARAM = "PushMessageBadSalt";
 // `rs` parameter of `Encryption` header not a number or less than pad size.
-const BAD_RS_PARAM = 'PushMessageBadRecordSize';
+const BAD_RS_PARAM = "PushMessageBadRecordSize";
 // Invalid or insufficient padding for encrypted chunk.
-const BAD_PADDING = 'PushMessageBadPaddingError';
+const BAD_PADDING = "PushMessageBadPaddingError";
 // Generic crypto error.
-const BAD_CRYPTO = 'PushMessageBadCryptoError';
+const BAD_CRYPTO = "PushMessageBadCryptoError";
 
 class CryptoError extends Error {
   /**
    * Creates an error object indicating an incoming push message could not be
    * decrypted.
    *
    * @param {String} message A human-readable error message. This is only for
    * internal module logging, and doesn't need to be localized.
@@ -75,59 +76,59 @@ class CryptoError extends Error {
                                            params.length);
   }
 }
 
 function getEncryptionKeyParams(encryptKeyField) {
   if (!encryptKeyField) {
     return null;
   }
-  var params = encryptKeyField.split(',');
+  var params = encryptKeyField.split(",");
   return params.reduce((m, p) => {
-    var pmap = p.split(';').reduce(parseHeaderFieldParams, {});
+    var pmap = p.split(";").reduce(parseHeaderFieldParams, {});
     if (pmap.keyid && pmap.dh) {
       m[pmap.keyid] = pmap.dh;
     }
     if (!m[DEFAULT_KEYID] && pmap.dh) {
       m[DEFAULT_KEYID] = pmap.dh;
     }
     return m;
   }, {});
 }
 
 function getEncryptionParams(encryptField) {
   if (!encryptField) {
-    throw new CryptoError('Missing encryption header',
+    throw new CryptoError("Missing encryption header",
                           BAD_ENCRYPTION_HEADER);
   }
-  var p = encryptField.split(',', 1)[0];
+  var p = encryptField.split(",", 1)[0];
   if (!p) {
-    throw new CryptoError('Encryption header missing params',
+    throw new CryptoError("Encryption header missing params",
                           BAD_ENCRYPTION_HEADER);
   }
-  return p.split(';').reduce(parseHeaderFieldParams, {});
+  return p.split(";").reduce(parseHeaderFieldParams, {});
 }
 
 // Extracts the sender public key, salt, and record size from the payload for the
 // aes128gcm scheme.
 function getCryptoParamsFromPayload(payload) {
   if (payload.byteLength < 21) {
-    throw new CryptoError('Truncated header', BAD_CRYPTO);
+    throw new CryptoError("Truncated header", BAD_CRYPTO);
   }
   let rs = (payload[16] << 24) | (payload[17] << 16) | (payload[18] << 8) | payload[19];
   let keyIdLen = payload[20];
   if (keyIdLen != 65) {
-    throw new CryptoError('Invalid sender public key', BAD_DH_PARAM);
+    throw new CryptoError("Invalid sender public key", BAD_DH_PARAM);
   }
   if (payload.byteLength <= 21 + keyIdLen) {
-    throw new CryptoError('Truncated payload', BAD_CRYPTO);
+    throw new CryptoError("Truncated payload", BAD_CRYPTO);
   }
   return {
     salt: payload.slice(0, 16),
-    rs: rs,
+    rs,
     senderKey: payload.slice(21, 21 + keyIdLen),
     ciphertext: payload.slice(21 + keyIdLen),
   };
 }
 
 // Extracts the sender public key, salt, and record size from the `Crypto-Key`,
 // `Encryption-Key`, and `Encryption` headers for the aesgcm and aesgcm128
 // schemes.
@@ -138,148 +139,144 @@ function getCryptoParamsFromHeaders(head
 
   var keymap;
   if (headers.encoding == AESGCM_ENCODING) {
     // aesgcm uses the Crypto-Key header, 2 bytes for the pad length, and an
     // authentication secret.
     // https://tools.ietf.org/html/draft-ietf-httpbis-encryption-encoding-01
     keymap = getEncryptionKeyParams(headers.crypto_key);
     if (!keymap) {
-      throw new CryptoError('Missing Crypto-Key header',
+      throw new CryptoError("Missing Crypto-Key header",
                             BAD_CRYPTO_KEY_HEADER);
     }
   } else if (headers.encoding == AESGCM128_ENCODING) {
     // aesgcm128 uses Encryption-Key, 1 byte for the pad length, and no secret.
     // https://tools.ietf.org/html/draft-thomson-http-encryption-02
     keymap = getEncryptionKeyParams(headers.encryption_key);
     if (!keymap) {
-      throw new CryptoError('Missing Encryption-Key header',
+      throw new CryptoError("Missing Encryption-Key header",
                             BAD_ENCRYPTION_KEY_HEADER);
     }
   }
 
   var enc = getEncryptionParams(headers.encryption);
   var dh = keymap[enc.keyid || DEFAULT_KEYID];
   var senderKey = base64URLDecode(dh);
   if (!senderKey) {
-    throw new CryptoError('Invalid dh parameter', BAD_DH_PARAM);
+    throw new CryptoError("Invalid dh parameter", BAD_DH_PARAM);
   }
 
   var salt = base64URLDecode(enc.salt);
   if (!salt) {
-    throw new CryptoError('Invalid salt parameter', BAD_SALT_PARAM);
+    throw new CryptoError("Invalid salt parameter", BAD_SALT_PARAM);
   }
   var rs = enc.rs ? parseInt(enc.rs, 10) : 4096;
   if (isNaN(rs)) {
-    throw new CryptoError('rs parameter must be a number', BAD_RS_PARAM);
+    throw new CryptoError("rs parameter must be a number", BAD_RS_PARAM);
   }
   return {
-    salt: salt,
-    rs: rs,
-    senderKey: senderKey,
+    salt,
+    rs,
+    senderKey,
   };
 }
 
 // Decodes an unpadded, base64url-encoded string.
 function base64URLDecode(string) {
   if (!string) {
     return null;
   }
   try {
     return ChromeUtils.base64URLDecode(string, {
       // draft-ietf-httpbis-encryption-encoding-01 prohibits padding.
-      padding: 'reject',
+      padding: "reject",
     });
   } catch (ex) {}
   return null;
 }
 
 var parseHeaderFieldParams = (m, v) => {
-  var i = v.indexOf('=');
+  var i = v.indexOf("=");
   if (i >= 0) {
     // A quoted string with internal quotes is invalid for all the possible
     // values of this header field.
     m[v.substring(0, i).trim()] = v.substring(i + 1).trim()
-                                   .replace(/^"(.*)"$/, '$1');
+                                   .replace(/^"(.*)"$/, "$1");
   }
   return m;
 };
 
 function chunkArray(array, size) {
   var start = array.byteOffset || 0;
   array = array.buffer || array;
   var index = 0;
   var result = [];
-  while(index + size <= array.byteLength) {
+  while (index + size <= array.byteLength) {
     result.push(new Uint8Array(array, start + index, size));
     index += size;
   }
   if (index < array.byteLength) {
     result.push(new Uint8Array(array, start + index));
   }
   return result;
 }
 
-var concatArray = function(arrays) {
+function concatArray(arrays) {
   var size = arrays.reduce((total, a) => total + a.byteLength, 0);
   var index = 0;
   return arrays.reduce((result, a) => {
     result.set(new Uint8Array(a), index);
     index += a.byteLength;
     return result;
   }, new Uint8Array(size));
-};
-
-var HMAC_SHA256 = { name: 'HMAC', hash: 'SHA-256' };
+}
 
 function hmac(key) {
-  this.keyPromise = crypto.subtle.importKey('raw', key, HMAC_SHA256,
-                                            false, ['sign']);
+  this.keyPromise = crypto.subtle.importKey("raw", key, HMAC_SHA256,
+                                            false, ["sign"]);
 }
 
 hmac.prototype.hash = function(input) {
-  return this.keyPromise.then(k => crypto.subtle.sign('HMAC', k, input));
+  return this.keyPromise.then(k => crypto.subtle.sign("HMAC", k, input));
 };
 
 function hkdf(salt, ikm) {
   this.prkhPromise = new hmac(salt).hash(ikm)
     .then(prk => new hmac(prk));
 }
 
 hkdf.prototype.extract = function(info, len) {
   var input = concatArray([info, new Uint8Array([1])]);
   return this.prkhPromise
     .then(prkh => prkh.hash(input))
     .then(h => {
       if (h.byteLength < len) {
-        throw new CryptoError('HKDF length is too long', BAD_CRYPTO);
+        throw new CryptoError("HKDF length is too long", BAD_CRYPTO);
       }
       return h.slice(0, len);
     });
 };
 
 /* generate a 96-bit nonce for use in GCM, 48-bits of which are populated */
 function generateNonce(base, index) {
   if (index >= Math.pow(2, 48)) {
-    throw new CryptoError('Nonce index is too large', BAD_CRYPTO);
+    throw new CryptoError("Nonce index is too large", BAD_CRYPTO);
   }
   var nonce = base.slice(0, 12);
   nonce = new Uint8Array(nonce);
   for (var i = 0; i < 6; ++i) {
     nonce[nonce.byteLength - 1 - i] ^= (index / Math.pow(256, i)) & 0xff;
   }
   return nonce;
 }
 
 function encodeLength(buffer) {
   return new Uint8Array([0, buffer.byteLength]);
 }
 
-var NONCE_INFO = UTF8.encode('Content-Encoding: nonce');
-
 class Decoder {
   /**
    * Creates a decoder for decrypting an incoming push message.
    *
    * @param {JsonWebKey} privateKey The static subscription private key.
    * @param {BufferSource} publicKey The static subscription public key.
    * @param {BufferSource} authenticationSecret The subscription authentication
    *  secret, or `null` if not used by the scheme.
@@ -307,202 +304,202 @@ class Decoder {
   async decode() {
     if (this.ciphertext.byteLength === 0) {
       // Zero length messages will be passed as null.
       return null;
     }
     try {
       let ikm = await this.computeSharedSecret();
       let [gcmBits, nonce] = await this.deriveKeyAndNonce(ikm);
-      let key = await crypto.subtle.importKey('raw', gcmBits, 'AES-GCM', false,
-                                              ['decrypt']);
+      let key = await crypto.subtle.importKey("raw", gcmBits, "AES-GCM", false,
+                                              ["decrypt"]);
 
       let r = await Promise.all(chunkArray(this.ciphertext, this.chunkSize)
         .map((slice, index, chunks) => this.decodeChunk(slice, index, nonce,
           key, index >= chunks.length - 1)));
 
       return concatArray(r);
     } catch (error) {
       if (error.isCryptoError) {
         throw error;
       }
       // Web Crypto returns an unhelpful "operation failed for an
       // operation-specific reason" error if decryption fails. We don't have
       // context about what went wrong, so we throw a generic error instead.
-      throw new CryptoError('Bad encryption', BAD_CRYPTO);
+      throw new CryptoError("Bad encryption", BAD_CRYPTO);
     }
   }
 
   /**
    * Computes the ECDH shared secret, used as the input key material for HKDF.
    *
    * @throws if the static or ephemeral ECDH keys are invalid.
    * @returns {ArrayBuffer} The shared secret.
    */
   async computeSharedSecret() {
     let [appServerKey, subscriptionPrivateKey] = await Promise.all([
-      crypto.subtle.importKey('raw', this.senderKey, ECDH_KEY,
-                              false, ['deriveBits']),
-      crypto.subtle.importKey('jwk', this.privateKey, ECDH_KEY,
-                              false, ['deriveBits'])
+      crypto.subtle.importKey("raw", this.senderKey, ECDH_KEY,
+                              false, ["deriveBits"]),
+      crypto.subtle.importKey("jwk", this.privateKey, ECDH_KEY,
+                              false, ["deriveBits"]),
     ]);
-    return crypto.subtle.deriveBits({ name: 'ECDH', public: appServerKey },
+    return crypto.subtle.deriveBits({ name: "ECDH", public: appServerKey },
                                     subscriptionPrivateKey, 256);
   }
 
   /**
    * Derives the content encryption key and nonce.
    *
    * @param {BufferSource} ikm The ECDH shared secret.
    * @returns {Array} A `[gcmBits, nonce]` tuple.
    */
   async deriveKeyAndNonce(ikm) {
-    throw new Error('Missing `deriveKeyAndNonce` implementation');
+    throw new Error("Missing `deriveKeyAndNonce` implementation");
   }
 
   /**
    * Decrypts and removes padding from an encrypted record.
    *
    * @throws {CryptoError} if decryption fails or padding is incorrect.
    * @param {Uint8Array} slice The encrypted record.
    * @param {Number} index The record sequence number.
    * @param {Uint8Array} nonce The nonce base, used to generate the IV.
    * @param {Uint8Array} key The content encryption key.
    * @param {Boolean} last Indicates if this is the final record.
    * @returns {Uint8Array} The decrypted block with padding removed.
    */
   async decodeChunk(slice, index, nonce, key, last) {
     let params = {
-      name: 'AES-GCM',
-      iv: generateNonce(nonce, index)
+      name: "AES-GCM",
+      iv: generateNonce(nonce, index),
     };
     let decoded = await crypto.subtle.decrypt(params, key, slice);
     return this.unpadChunk(new Uint8Array(decoded), last);
   }
 
   /**
    * Removes padding from a decrypted block.
    *
    * @throws {CryptoError} if padding is missing or invalid.
    * @param {Uint8Array} chunk The decrypted block with padding.
    * @returns {Uint8Array} The block with padding removed.
    */
   unpadChunk(chunk, last) {
-    throw new Error('Missing `unpadChunk` implementation');
+    throw new Error("Missing `unpadChunk` implementation");
   }
 
   /** The record chunking size. */
   get chunkSize() {
-    throw new Error('Missing `chunkSize` implementation');
+    throw new Error("Missing `chunkSize` implementation");
   }
 }
 
 class OldSchemeDecoder extends Decoder {
   async decode() {
     // For aesgcm and aesgcm128, the ciphertext length can't fall on a record
     // boundary.
     if (this.ciphertext.byteLength > 0 &&
         this.ciphertext.byteLength % this.chunkSize === 0) {
-      throw new CryptoError('Encrypted data truncated', BAD_CRYPTO);
+      throw new CryptoError("Encrypted data truncated", BAD_CRYPTO);
     }
     return super.decode();
   }
 
   /**
    * For aesgcm, the padding length is a 16-bit unsigned big endian integer.
    * For aesgcm128, the padding is an 8-bit integer.
    */
   unpadChunk(decoded) {
     if (decoded.length < this.padSize) {
-      throw new CryptoError('Decoded array is too short!', BAD_PADDING);
+      throw new CryptoError("Decoded array is too short!", BAD_PADDING);
     }
-    var pad = decoded[0]
+    var pad = decoded[0];
     if (this.padSize == 2) {
       pad = (pad << 8) | decoded[1];
     }
     if (pad > decoded.length - this.padSize) {
-      throw new CryptoError('Padding is wrong!', BAD_PADDING);
+      throw new CryptoError("Padding is wrong!", BAD_PADDING);
     }
     // All padded bytes must be zero except the first one.
     for (var i = this.padSize; i < this.padSize + pad; i++) {
       if (decoded[i] !== 0) {
-        throw new CryptoError('Padding is wrong!', BAD_PADDING);
+        throw new CryptoError("Padding is wrong!", BAD_PADDING);
       }
     }
     return decoded.slice(pad + this.padSize);
   }
 
   /**
    * aesgcm and aesgcm128 don't account for the authentication tag as part of
    * the record size.
    */
   get chunkSize() {
     return this.rs + 16;
   }
 
   get padSize() {
-    throw new Error('Missing `padSize` implementation');
+    throw new Error("Missing `padSize` implementation");
   }
 }
 
 /** New encryption scheme (draft-ietf-httpbis-encryption-encoding-06). */
 
-var AES128GCM_ENCODING = 'aes128gcm';
-var AES128GCM_KEY_INFO = UTF8.encode('Content-Encoding: aes128gcm\0');
-var AES128GCM_AUTH_INFO = UTF8.encode('WebPush: info\0');
-var AES128GCM_NONCE_INFO = UTF8.encode('Content-Encoding: nonce\0');
+const AES128GCM_ENCODING = "aes128gcm";
+const AES128GCM_KEY_INFO = UTF8.encode("Content-Encoding: aes128gcm\0");
+const AES128GCM_AUTH_INFO = UTF8.encode("WebPush: info\0");
+const AES128GCM_NONCE_INFO = UTF8.encode("Content-Encoding: nonce\0");
 
 class aes128gcmDecoder extends Decoder {
   /**
    * Derives the aes128gcm decryption key and nonce. The PRK info string for
    * HKDF is "WebPush: info\0", followed by the unprefixed receiver and sender
    * public keys.
    */
   async deriveKeyAndNonce(ikm) {
     let authKdf = new hkdf(this.authenticationSecret, ikm);
     let authInfo = concatArray([
       AES128GCM_AUTH_INFO,
       this.publicKey,
-      this.senderKey
+      this.senderKey,
     ]);
     let prk = await authKdf.extract(authInfo, 32);
     let prkKdf = new hkdf(this.salt, prk);
     return Promise.all([
       prkKdf.extract(AES128GCM_KEY_INFO, 16),
-      prkKdf.extract(AES128GCM_NONCE_INFO, 12)
+      prkKdf.extract(AES128GCM_NONCE_INFO, 12),
     ]);
   }
 
   unpadChunk(decoded, last) {
     let length = decoded.length;
     while (length--) {
       if (decoded[length] === 0) {
         continue;
       }
       let recordPad = last ? 2 : 1;
       if (decoded[length] != recordPad) {
-        throw new CryptoError('Padding is wrong!', BAD_PADDING);
+        throw new CryptoError("Padding is wrong!", BAD_PADDING);
       }
       return decoded.slice(0, length);
     }
-    throw new CryptoError('Zero plaintext', BAD_PADDING);
+    throw new CryptoError("Zero plaintext", BAD_PADDING);
   }
 
   /** aes128gcm accounts for the authentication tag in the record size. */
   get chunkSize() {
     return this.rs;
   }
 }
 
 /** Older encryption scheme (draft-ietf-httpbis-encryption-encoding-01). */
 
-var AESGCM_ENCODING = 'aesgcm';
-var AESGCM_KEY_INFO = UTF8.encode('Content-Encoding: aesgcm\0');
-var AESGCM_AUTH_INFO = UTF8.encode('Content-Encoding: auth\0'); // note nul-terminus
-var AESGCM_P256DH_INFO = UTF8.encode('P-256\0');
+const AESGCM_ENCODING = "aesgcm";
+const AESGCM_KEY_INFO = UTF8.encode("Content-Encoding: aesgcm\0");
+const AESGCM_AUTH_INFO = UTF8.encode("Content-Encoding: auth\0"); // note nul-terminus
+const AESGCM_P256DH_INFO = UTF8.encode("P-256\0");
 
 class aesgcmDecoder extends OldSchemeDecoder {
   /**
    * Derives the aesgcm decryption key and nonce. We mix the authentication
    * secret with the ikm using HKDF. The context string for the PRK is
    * "Content-Encoding: auth\0". The context string for the key and nonce is
    * "Content-Encoding: <blah>\0P-256\0" then the length and value of both the
    * receiver key and sender key.
@@ -511,80 +508,80 @@ class aesgcmDecoder extends OldSchemeDec
     // Since we are using an authentication secret, we need to run an extra
     // round of HKDF with the authentication secret as salt.
     let authKdf = new hkdf(this.authenticationSecret, ikm);
     let prk = await authKdf.extract(AESGCM_AUTH_INFO, 32);
     let prkKdf = new hkdf(this.salt, prk);
     let keyInfo = concatArray([
       AESGCM_KEY_INFO, AESGCM_P256DH_INFO,
       encodeLength(this.publicKey), this.publicKey,
-      encodeLength(this.senderKey), this.senderKey
+      encodeLength(this.senderKey), this.senderKey,
     ]);
     let nonceInfo = concatArray([
       NONCE_INFO, new Uint8Array([0]), AESGCM_P256DH_INFO,
       encodeLength(this.publicKey), this.publicKey,
-      encodeLength(this.senderKey), this.senderKey
+      encodeLength(this.senderKey), this.senderKey,
     ]);
     return Promise.all([
       prkKdf.extract(keyInfo, 16),
-      prkKdf.extract(nonceInfo, 12)
+      prkKdf.extract(nonceInfo, 12),
     ]);
   }
 
   get padSize() {
     return 2;
   }
 }
 
 /** Oldest encryption scheme (draft-thomson-http-encryption-02). */
 
-var AESGCM128_ENCODING = 'aesgcm128';
-var AESGCM128_KEY_INFO = UTF8.encode('Content-Encoding: aesgcm128');
+const AESGCM128_ENCODING = "aesgcm128";
+const AESGCM128_KEY_INFO = UTF8.encode("Content-Encoding: aesgcm128");
 
 class aesgcm128Decoder extends OldSchemeDecoder {
   constructor(privateKey, publicKey, cryptoParams, ciphertext) {
     super(privateKey, publicKey, null, cryptoParams, ciphertext);
   }
 
   /**
    * The aesgcm128 scheme ignores the authentication secret, and uses
    * "Content-Encoding: <blah>" for the context string. It should eventually
    * be removed: bug 1230038.
    */
   deriveKeyAndNonce(ikm) {
     let prkKdf = new hkdf(this.salt, ikm);
     return Promise.all([
       prkKdf.extract(AESGCM128_KEY_INFO, 16),
-      prkKdf.extract(NONCE_INFO, 12)
+      prkKdf.extract(NONCE_INFO, 12),
     ]);
   }
 
   get padSize() {
     return 1;
   }
 }
 
 var PushCrypto = {
 
   generateAuthenticationSecret() {
     return crypto.getRandomValues(new Uint8Array(16));
   },
 
   validateAppServerKey(key) {
-    return crypto.subtle.importKey('raw', key, ECDSA_KEY,
-                                   true, ['verify'])
+    return crypto.subtle.importKey("raw", key, ECDSA_KEY,
+                                   true, ["verify"])
       .then(_ => key);
   },
 
   generateKeys() {
-    return crypto.subtle.generateKey(ECDH_KEY, true, ['deriveBits'])
+    return crypto.subtle.generateKey(ECDH_KEY, true, ["deriveBits"])
       .then(cryptoKey =>
          Promise.all([
-           crypto.subtle.exportKey('raw', cryptoKey.publicKey),
-           crypto.subtle.exportKey('jwk', cryptoKey.privateKey)
+           crypto.subtle.exportKey("raw", cryptoKey.publicKey),
+           crypto.subtle.exportKey("jwk", cryptoKey.privateKey),
          ]));
   },
 
   /**
    * Decrypts a push message.
    *
    * @throws {CryptoError} if decryption fails.
    * @param {JsonWebKey} privateKey The ECDH private key of the subscription
@@ -599,17 +596,17 @@ var PushCrypto = {
    */
   async decrypt(privateKey, publicKey, authenticationSecret, headers, payload) {
     if (!headers) {
       return null;
     }
 
     let encoding = headers.encoding;
     if (!headers.encoding) {
-      throw new CryptoError('Missing Content-Encoding header',
+      throw new CryptoError("Missing Content-Encoding header",
                             BAD_ENCODING_HEADER);
     }
 
     let decoder;
     if (encoding == AES128GCM_ENCODING) {
       // aes128gcm includes the salt, record size, and sender public key in a
       // binary header preceding the ciphertext.
       let cryptoParams = getCryptoParamsFromPayload(new Uint8Array(payload));
@@ -625,17 +622,17 @@ var PushCrypto = {
                                     cryptoParams, payload);
       } else {
         decoder = new aesgcm128Decoder(privateKey, publicKey, cryptoParams,
                                        payload);
       }
     }
 
     if (!decoder) {
-      throw new CryptoError('Unsupported Content-Encoding: ' + encoding,
+      throw new CryptoError("Unsupported Content-Encoding: " + encoding,
                             BAD_ENCODING_HEADER);
     }
 
     return decoder.decode();
   },
 
   /**
    * Encrypts a payload suitable for using in a push message. The encryption
@@ -645,17 +642,17 @@ var PushCrypto = {
    * @param {plaintext} Uint8Array The plaintext to encrypt.
    * @param {receiverPublicKey} Uint8Array The public key of the recipient
    *  of the message as a buffer.
    * @param {receiverAuthSecret} Uint8Array The auth secret of the of the
    *  message recipient as a buffer.
    * @param {options} Object Encryption options, used for tests.
    * @returns {ciphertext, encoding} The encrypted payload and encoding.
    */
-  async encrypt(plaintext, receiverPublicKey, receiverAuthSecret, options={}) {
+  async encrypt(plaintext, receiverPublicKey, receiverAuthSecret, options = {}) {
     const encoding = options.encoding || AES128GCM_ENCODING;
     // We only support one encoding type.
     if (encoding != AES128GCM_ENCODING) {
       throw new CryptoError(`Only ${AES128GCM_ENCODING} is supported`,
                             BAD_ENCODING_HEADER);
     }
     // We typically use an ephemeral key for this message, but for testing
     // purposes we allow it to be specified.
@@ -669,32 +666,32 @@ var PushCrypto = {
                                          receiverAuthSecret, senderKeyPair,
                                          salt, rs);
     return encoder.encode();
   },
 };
 
 // A class for aes128gcm encryption - the only kind we support.
 class aes128gcmEncoder {
-  constructor(plaintext ,receiverPublicKey, receiverAuthSecret, senderKeyPair, salt, rs) {
+  constructor(plaintext, receiverPublicKey, receiverAuthSecret, senderKeyPair, salt, rs) {
     this.receiverPublicKey = receiverPublicKey;
     this.receiverAuthSecret = receiverAuthSecret;
     this.senderKeyPair = senderKeyPair;
     this.salt = salt;
     this.rs = rs;
     this.plaintext = plaintext;
   }
 
   async encode() {
     const sharedSecret = await this.computeSharedSecret(this.receiverPublicKey,
                                                         this.senderKeyPair.privateKey);
 
     const rawSenderPublicKey = await crypto.subtle.exportKey("raw", this.senderKeyPair.publicKey);
     const [gcmBits, nonce] = await this.deriveKeyAndNonce(sharedSecret,
-                                                          rawSenderPublicKey)
+                                                          rawSenderPublicKey);
 
     const contentEncryptionKey = await crypto.subtle.importKey("raw", gcmBits,
                                                                "AES-GCM", false,
                                                                ["encrypt"]);
     const payloadHeader = this.createHeader(rawSenderPublicKey);
 
     const ciphertextChunks = await this.encrypt(contentEncryptionKey, nonce);
     return {ciphertext: concatArray([payloadHeader, ...ciphertextChunks]),
@@ -707,27 +704,27 @@ class aes128gcmEncoder {
       throw new CryptoError("recordsize is too small", BAD_RS_PARAM);
     }
 
     let chunks;
     if (this.plaintext.byteLength === 0) {
       // Send an authentication tag for empty messages.
       chunks = [await crypto.subtle.encrypt({
         name: "AES-GCM",
-        iv: generateNonce(nonce, 0)
+        iv: generateNonce(nonce, 0),
       }, key, new Uint8Array([2]))];
     } else {
       // Use specified recordsize, though we burn 1 for padding and 16 byte
       // overhead.
       let inChunks = chunkArray(this.plaintext, this.rs - 1 - 16);
-      chunks = await Promise.all(inChunks.map(async function (slice, index) {
+      chunks = await Promise.all(inChunks.map(async function(slice, index) {
         let isLast = index == inChunks.length - 1;
         let padding = new Uint8Array([isLast ? 2 : 1]);
         let input = concatArray([slice, padding]);
-        return await crypto.subtle.encrypt({
+        return crypto.subtle.encrypt({
           name: "AES-GCM",
           iv: generateNonce(nonce, index),
         }, key, input);
       }));
     }
     return chunks;
   }
 
--- a/dom/push/PushDB.jsm
+++ b/dom/push/PushDB.jsm
@@ -1,20 +1,18 @@
-/* jshint moz: true, esnext: true */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {IndexedDBHelper} = ChromeUtils.import("resource://gre/modules/IndexedDBHelper.jsm");
 const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyGlobalGetters(this, ["indexedDB"]);
 
-var EXPORTED_SYMBOLS = ["PushDB"];
+const EXPORTED_SYMBOLS = ["PushDB"];
 
 XPCOMUtils.defineLazyGetter(this, "console", () => {
   let {ConsoleAPI} = ChromeUtils.import("resource://gre/modules/Console.jsm");
   return new ConsoleAPI({
     maxLogLevelPref: "dom.push.loglevel",
     prefix: "PushDB",
   });
 });
@@ -28,34 +26,34 @@ function PushDB(dbName, dbVersion, dbSto
   // set the indexeddb database
   this.initDBHelper(dbName, dbVersion,
                     [dbStoreName]);
 }
 
 this.PushDB.prototype = {
   __proto__: IndexedDBHelper.prototype,
 
-  toPushRecord: function(record) {
+  toPushRecord(record) {
     if (!record) {
-      return;
+      return null;
     }
     return new this._model(record);
   },
 
-  isValidRecord: function(record) {
+  isValidRecord(record) {
     return record && typeof record.scope == "string" &&
            typeof record.originAttributes == "string" &&
            record.quota >= 0 &&
            typeof record[this._keyPath] == "string";
   },
 
-  upgradeSchema: function(aTransaction, aDb, aOldVersion, aNewVersion) {
+  upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) {
     if (aOldVersion <= 3) {
-      //XXXnsm We haven't shipped Push during this upgrade, so I'm just going to throw old
-      //registrations away without even informing the app.
+      // XXXnsm We haven't shipped Push during this upgrade, so I'm just going to throw old
+      // registrations away without even informing the app.
       if (aDb.objectStoreNames.contains(this._dbStoreName)) {
         aDb.deleteObjectStore(this._dbStoreName);
       }
 
       let objectStore = aDb.createObjectStore(this._dbStoreName,
                                               { keyPath: this._keyPath });
 
       // index to fetch records based on endpoints. used by unregister
@@ -78,17 +76,17 @@ this.PushDB.prototype = {
     }
   },
 
   /*
    * @param aRecord
    *        The record to be added.
    */
 
-  put: function(aRecord) {
+  put(aRecord) {
     console.debug("put()", aRecord);
     if (!this.isValidRecord(aRecord)) {
       return Promise.reject(new TypeError(
         "Scope, originAttributes, and quota are required! " +
           JSON.stringify(aRecord)
         )
       );
     }
@@ -111,17 +109,17 @@ this.PushDB.prototype = {
       )
     );
   },
 
   /*
    * @param aKeyID
    *        The ID of record to be deleted.
    */
-  delete: function(aKeyID) {
+  delete(aKeyID) {
     console.debug("delete()");
 
     return new Promise((resolve, reject) =>
       this.newTxn(
         "readwrite",
         this._dbStoreName,
         (aTxn, aStore) => {
           console.debug("delete: Removing record", aKeyID);
@@ -133,17 +131,17 @@ this.PushDB.prototype = {
         resolve,
         reject
       )
     );
   },
 
   // testFn(record) is called with a database record and should return true if
   // that record should be deleted.
-  clearIf: function(testFn) {
+  clearIf(testFn) {
     console.debug("clearIf()");
     return new Promise((resolve, reject) =>
       this.newTxn(
         "readwrite",
         this._dbStoreName,
         (aTxn, aStore) => {
           aTxn.result = undefined;
 
@@ -151,29 +149,29 @@ this.PushDB.prototype = {
             let cursor = event.target.result;
             if (cursor) {
               let record = this.toPushRecord(cursor.value);
               if (testFn(record)) {
                 let deleteRequest = cursor.delete();
                 deleteRequest.onerror = e => {
                   console.error("clearIf: Error removing record",
                     record.keyID, e);
-                }
+                };
               }
               cursor.continue();
             }
-          }
+          };
         },
         resolve,
         reject
       )
     );
   },
 
-  getByPushEndpoint: function(aPushEndpoint) {
+  getByPushEndpoint(aPushEndpoint) {
     console.debug("getByPushEndpoint()");
 
     return new Promise((resolve, reject) =>
       this.newTxn(
         "readonly",
         this._dbStoreName,
         (aTxn, aStore) => {
           aTxn.result = undefined;
@@ -186,17 +184,17 @@ this.PushDB.prototype = {
           };
         },
         resolve,
         reject
       )
     );
   },
 
-  getByKeyID: function(aKeyID) {
+  getByKeyID(aKeyID) {
     console.debug("getByKeyID()");
 
     return new Promise((resolve, reject) =>
       this.newTxn(
         "readonly",
         this._dbStoreName,
         (aTxn, aStore) => {
           aTxn.result = undefined;
@@ -219,17 +217,17 @@ this.PushDB.prototype = {
    * @param {String} origin The origin, matched as a prefix against the scope.
    * @param {String} originAttributes Additional origin attributes. Requires
    *  an exact match.
    * @param {Function} callback A function with the signature `(record,
    *  cursor)`, called for each record. `record` is the registration, and
    *  `cursor` is an `IDBCursor`.
    * @returns {Promise} Resolves once all records have been processed.
    */
-  forEachOrigin: function(origin, originAttributes, callback) {
+  forEachOrigin(origin, originAttributes, callback) {
     console.debug("forEachOrigin()");
 
     return new Promise((resolve, reject) =>
       this.newTxn(
         "readwrite",
         this._dbStoreName,
         (aTxn, aStore) => {
           aTxn.result = undefined;
@@ -250,17 +248,17 @@ this.PushDB.prototype = {
         },
         resolve,
         reject
       )
     );
   },
 
   // Perform a unique match against { scope, originAttributes }
-  getByIdentifiers: function(aPageRecord) {
+  getByIdentifiers(aPageRecord) {
     console.debug("getByIdentifiers()", aPageRecord);
     if (!aPageRecord.scope || aPageRecord.originAttributes == undefined) {
       console.error("getByIdentifiers: Scope and originAttributes are required",
         aPageRecord);
       return Promise.reject(new TypeError("Invalid page record"));
     }
 
     return new Promise((resolve, reject) =>
@@ -277,17 +275,17 @@ this.PushDB.prototype = {
           };
         },
         resolve,
         reject
       )
     );
   },
 
-  _getAllByKey: function(aKeyName, aKeyValue) {
+  _getAllByKey(aKeyName, aKeyValue) {
     return new Promise((resolve, reject) =>
       this.newTxn(
         "readonly",
         this._dbStoreName,
         (aTxn, aStore) => {
           aTxn.result = undefined;
 
           let index = aStore.index(aKeyName);
@@ -302,24 +300,24 @@ this.PushDB.prototype = {
         },
         resolve,
         reject
       )
     );
   },
 
   // aOriginAttributes must be a string!
-  getAllByOriginAttributes: function(aOriginAttributes) {
+  getAllByOriginAttributes(aOriginAttributes) {
     if (typeof aOriginAttributes !== "string") {
       return Promise.reject("Expected string!");
     }
     return this._getAllByKey("originAttributes", aOriginAttributes);
   },
 
-  getAllKeyIDs: function() {
+  getAllKeyIDs() {
     console.debug("getAllKeyIDs()");
 
     return new Promise((resolve, reject) =>
       this.newTxn(
         "readonly",
         this._dbStoreName,
         (aTxn, aStore) => {
           aTxn.result = undefined;
@@ -329,17 +327,17 @@ this.PushDB.prototype = {
           };
         },
         resolve,
         reject
       )
     );
   },
 
-  _getAllByPushQuota: function(range) {
+  _getAllByPushQuota(range) {
     console.debug("getAllByPushQuota()");
 
     return new Promise((resolve, reject) =>
       this.newTxn(
         "readonly",
         this._dbStoreName,
         (aTxn, aStore) => {
           aTxn.result = [];
@@ -354,37 +352,37 @@ this.PushDB.prototype = {
           };
         },
         resolve,
         reject
       )
     );
   },
 
-  getAllUnexpired: function() {
+  getAllUnexpired() {
     console.debug("getAllUnexpired()");
     return this._getAllByPushQuota(IDBKeyRange.lowerBound(1));
   },
 
-  getAllExpired: function() {
+  getAllExpired() {
     console.debug("getAllExpired()");
     return this._getAllByPushQuota(IDBKeyRange.only(0));
   },
 
   /**
    * Updates an existing push registration.
    *
    * @param {String} aKeyID The registration ID.
    * @param {Function} aUpdateFunc A function that receives the existing
    *  registration record as its argument, and returns a new record.
    * @returns {Promise} A promise resolved with either the updated record.
    *  Rejects if the record does not exist, or the function returns an invalid
    *  record.
    */
-  update: function(aKeyID, aUpdateFunc) {
+  update(aKeyID, aUpdateFunc) {
     return new Promise((resolve, reject) =>
       this.newTxn(
         "readwrite",
         this._dbStoreName,
         (aTxn, aStore) => {
           aStore.get(aKeyID).onsuccess = aEvent => {
             aTxn.result = undefined;
 
@@ -415,17 +413,17 @@ this.PushDB.prototype = {
           };
         },
         resolve,
         reject
       )
     );
   },
 
-  drop: function() {
+  drop() {
     console.debug("drop()");
 
     return new Promise((resolve, reject) =>
       this.newTxn(
         "readwrite",
         this._dbStoreName,
         function txnCb(aTxn, aStore) {
           aStore.clear();
--- a/dom/push/PushRecord.jsm
+++ b/dom/push/PushRecord.jsm
@@ -11,17 +11,17 @@ ChromeUtils.defineModuleGetter(this, "Ev
                                "resource://gre/modules/Messaging.jsm");
 
 ChromeUtils.defineModuleGetter(this, "PlacesUtils",
                                "resource://gre/modules/PlacesUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
                                "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 
-var EXPORTED_SYMBOLS = ["PushRecord"];
+const EXPORTED_SYMBOLS = ["PushRecord"];
 
 const prefs = Services.prefs.getBranch("dom.push.");
 
 /**
  * The push subscription record, stored in IndexedDB.
  */
 function PushRecord(props) {
   this.pushEndpoint = props.pushEndpoint;
@@ -142,17 +142,17 @@ PushRecord.prototype = {
     // `pushsubscriptionchange` event when the user visits a site with expired push
     // registrations. Visits only count if the user sees the origin in the address
     // bar. This excludes embedded resources, downloads, and framed links.
     const QUOTA_REFRESH_TRANSITIONS_SQL = [
       Ci.nsINavHistoryService.TRANSITION_LINK,
       Ci.nsINavHistoryService.TRANSITION_TYPED,
       Ci.nsINavHistoryService.TRANSITION_BOOKMARK,
       Ci.nsINavHistoryService.TRANSITION_REDIRECT_PERMANENT,
-      Ci.nsINavHistoryService.TRANSITION_REDIRECT_TEMPORARY
+      Ci.nsINavHistoryService.TRANSITION_REDIRECT_TEMPORARY,
     ].join(",");
 
     let db =  await PlacesUtils.promiseDBConnection();
     // We're using a custom query instead of `nsINavHistoryQueryOptions`
     // because the latter doesn't expose a way to filter by transition type:
     // `setTransitions` performs a logical "and," but we want an "or." We
     // also avoid an unneeded left join with favicons, and an `ORDER BY`
     // clause that emits a suboptimal index warning.
@@ -277,17 +277,16 @@ Object.defineProperties(PushRecord.proto
       if (this.systemRecord) {
         return Services.scriptSecurityManager.getSystemPrincipal();
       }
       let principal = principals.get(this);
       if (!principal) {
         let uri = Services.io.newURI(this.scope);
         // Allow tests to omit origin attributes.
         let originSuffix = this.originAttributes || "";
-        let originAttributes =
         principal = Services.scriptSecurityManager.createCodebasePrincipal(uri,
           ChromeUtils.createOriginAttributesFromOrigin(originSuffix));
         principals.set(this, principal);
       }
       return principal;
     },
     configurable: true,
   },
--- a/dom/push/PushService.jsm
+++ b/dom/push/PushService.jsm
@@ -1,63 +1,56 @@
-/* jshint moz: true, esnext: true */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 const {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm");
 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const {clearTimeout, setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm");
 const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
-var {
-  PushCrypto,
-  CryptoError,
-} = ChromeUtils.import("resource://gre/modules/PushCrypto.jsm", null);
-const {PushDB} = ChromeUtils.import("resource://gre/modules/PushDB.jsm");
-
 var PushServiceWebSocket, PushServiceHttp2;
 
 const CONNECTION_PROTOCOLS = (function() {
-  if ('android' != AppConstants.MOZ_WIDGET_TOOLKIT) {
+  if ("android" != AppConstants.MOZ_WIDGET_TOOLKIT) {
     ({PushServiceWebSocket} = ChromeUtils.import("resource://gre/modules/PushServiceWebSocket.jsm"));
     ({PushServiceHttp2} = ChromeUtils.import("resource://gre/modules/PushServiceHttp2.jsm"));
     return [PushServiceWebSocket, PushServiceHttp2];
-  } else {
-    const {PushServiceAndroidGCM} = ChromeUtils.import("resource://gre/modules/PushServiceAndroidGCM.jsm");
-    return [PushServiceAndroidGCM];
   }
+  const {PushServiceAndroidGCM} = ChromeUtils.import("resource://gre/modules/PushServiceAndroidGCM.jsm");
+  return [PushServiceAndroidGCM];
 })();
 
 XPCOMUtils.defineLazyServiceGetter(this, "gPushNotifier",
                                    "@mozilla.org/push/Notifier;1",
                                    "nsIPushNotifier");
 XPCOMUtils.defineLazyServiceGetter(this, "eTLDService",
                                    "@mozilla.org/network/effective-tld-service;1",
                                    "nsIEffectiveTLDService");
 ChromeUtils.defineModuleGetter(this, "pushBroadcastService", "resource://gre/modules/PushBroadcastService.jsm");
+ChromeUtils.defineModuleGetter(this, "PushCrypto", "resource://gre/modules/PushCrypto.jsm");
 
-var EXPORTED_SYMBOLS = ["PushService"];
+const EXPORTED_SYMBOLS = ["PushService"];
 
 XPCOMUtils.defineLazyGetter(this, "console", () => {
   let {ConsoleAPI} = ChromeUtils.import("resource://gre/modules/Console.jsm");
   return new ConsoleAPI({
     maxLogLevelPref: "dom.push.loglevel",
     prefix: "PushService",
   });
 });
 
 const prefs = new Preferences("dom.push.");
 
 const PUSH_SERVICE_UNINIT = 0;
 const PUSH_SERVICE_INIT = 1; // No serverURI
-const PUSH_SERVICE_ACTIVATING = 2;//activating db
+const PUSH_SERVICE_ACTIVATING = 2; // activating db
 const PUSH_SERVICE_CONNECTION_DISABLE = 3;
 const PUSH_SERVICE_ACTIVE_OFFLINE = 4;
 const PUSH_SERVICE_RUNNING = 5;
 
 /**
  * State is change only in couple of functions:
  *   init - change state to PUSH_SERVICE_INIT if state was PUSH_SERVICE_UNINIT
  *   changeServerURL - change state to PUSH_SERVICE_ACTIVATING if serverURL
@@ -107,17 +100,17 @@ var PushService = {
   _updateQuotaTestCallback: null,
 
   // Set of timeout ID of tasks to reduce quota.
   _updateQuotaTimeouts: new Set(),
 
   // When serverURI changes (this is used for testing), db is cleaned up and a
   // a new db is started. This events must be sequential.
   _stateChangeProcessQueue: null,
-  _stateChangeProcessEnqueue: function(op) {
+  _stateChangeProcessEnqueue(op) {
     if (!this._stateChangeProcessQueue) {
       this._stateChangeProcessQueue = Promise.resolve();
     }
 
     this._stateChangeProcessQueue = this._stateChangeProcessQueue
       .then(op)
       .catch(error => {
         console.error(
@@ -132,50 +125,52 @@ var PushService = {
   },
 
   // Pending request. If a worker try to register for the same scope again, do
   // not send a new registration request. Therefore we need queue of pending
   // register requests. This is the list of scopes which pending registration.
   _pendingRegisterRequest: {},
   _notifyActivated: null,
   _activated: null,
-  _checkActivated: function() {
+  _checkActivated() {
     if (this._state < PUSH_SERVICE_ACTIVATING) {
       return Promise.reject(new Error("Push service not active"));
-    } else if (this._state > PUSH_SERVICE_ACTIVATING) {
+    }
+    if (this._state > PUSH_SERVICE_ACTIVATING) {
       return Promise.resolve();
-    } else {
-      return (this._activated) ? this._activated :
-                                 this._activated = new Promise((res, rej) =>
-                                   this._notifyActivated = {resolve: res,
-                                                            reject: rej});
     }
+    if (!this._activated) {
+      this._activated = new Promise((resolve, reject) => {
+        this._notifyActivated = {resolve, reject};
+      });
+    }
+    return this._activated;
   },
 
-  _makePendingKey: function(aPageRecord) {
+  _makePendingKey(aPageRecord) {
     return aPageRecord.scope + "|" + aPageRecord.originAttributes;
   },
 
-  _lookupOrPutPendingRequest: function(aPageRecord) {
+  _lookupOrPutPendingRequest(aPageRecord) {
     let key = this._makePendingKey(aPageRecord);
     if (this._pendingRegisterRequest[key]) {
       return this._pendingRegisterRequest[key];
     }
 
     return this._pendingRegisterRequest[key] = this._registerWithServer(aPageRecord);
   },
 
-  _deletePendingRequest: function(aPageRecord) {
+  _deletePendingRequest(aPageRecord) {
     let key = this._makePendingKey(aPageRecord);
     if (this._pendingRegisterRequest[key]) {
       delete this._pendingRegisterRequest[key];
     }
   },
 
-  _setState: function(aNewState) {
+  _setState(aNewState) {
     console.debug("setState()", "new state", aNewState, "old state", this._state);
 
     if (this._state == aNewState) {
       return;
     }
 
     if (this._state == PUSH_SERVICE_ACTIVATING) {
       // It is not important what is the new state as soon as we leave
@@ -227,17 +222,17 @@ var PushService = {
     // listeners. If PushBroadcastService gets woken first, it will
     // update the value that is eventually returned from
     // getListeners.
     this._setState(PUSH_SERVICE_RUNNING);
 
     this._service.connect(broadcastListeners);
   },
 
-  _changeStateConnectionEnabledEvent: function(enabled) {
+  _changeStateConnectionEnabledEvent(enabled) {
     console.debug("changeStateConnectionEnabledEvent()", enabled);
 
     if (this._state < PUSH_SERVICE_CONNECTION_DISABLE &&
         this._state != PUSH_SERVICE_ACTIVATING) {
       return Promise.resolve();
     }
 
     if (enabled) {
@@ -284,17 +279,16 @@ var PushService = {
       case "nsPref:changed":
         if (aData == "dom.push.serverURL") {
           console.debug("observe: dom.push.serverURL changed for websocket",
                 prefs.get("serverURL"));
           this._stateChangeProcessEnqueue(_ =>
             this._changeServerURL(prefs.get("serverURL"),
                                   CHANGING_SERVICE_EVENT)
           );
-
         } else if (aData == "dom.push.connection.enabled") {
           this._stateChangeProcessEnqueue(_ =>
             this._changeStateConnectionEnabledEvent(prefs.get("connection.enabled"))
           );
         }
         break;
 
       case "idle-daily":
@@ -302,28 +296,28 @@ var PushService = {
           console.error("Failed to drop expired registrations on idle", error);
         });
         break;
 
       case "perm-changed":
         this._onPermissionChange(aSubject, aData).catch(error => {
           console.error("onPermissionChange: Error updating registrations:",
             error);
-        })
+        });
         break;
 
       case "clear-origin-attributes-data":
         this._clearOriginData(aData).catch(error => {
           console.error("clearOriginData: Error clearing origin data:", error);
         });
         break;
     }
   },
 
-  _clearOriginData: function(data) {
+  _clearOriginData(data) {
     console.log("clearOriginData()");
 
     if (!data) {
       return Promise.resolve();
     }
 
     let pattern = JSON.parse(data);
     return this._dropRegistrationsIf(record =>
@@ -348,17 +342,17 @@ var PushService = {
     console.debug("backgroundUnregister: Notifying server", record);
     this._sendUnregister(record, reason).then(() => {
       gPushNotifier.notifySubscriptionModified(record.scope, record.principal);
     }).catch(e => {
       console.error("backgroundUnregister: Error notifying server", e);
     });
   },
 
-  _findService: function(serverURL) {
+  _findService(serverURL) {
     console.debug("findService()");
 
     let uri;
     let service;
 
     if (!serverURL) {
       console.warn("findService: No dom.push.serverURL found");
       return [];
@@ -376,20 +370,20 @@ var PushService = {
       if (connProtocol.validServerURI(uri)) {
         service = connProtocol;
         break;
       }
     }
     return [service, uri];
   },
 
-  _changeServerURL: function(serverURI, event, options = {}) {
+  _changeServerURL(serverURI, event, options = {}) {
     console.debug("changeServerURL()");
 
-    switch(event) {
+    switch (event) {
       case UNINIT_EVENT:
         return this._stopService(event);
 
       case STARTING_SERVICE_EVENT:
       {
         let [service, uri] = this._findService(serverURI);
         if (!service) {
           this._setState(PUSH_SERVICE_INIT);
@@ -403,40 +397,32 @@ var PushService = {
         let [service, uri] = this._findService(serverURI);
         if (service) {
           if (this._state == PUSH_SERVICE_INIT) {
             this._setState(PUSH_SERVICE_ACTIVATING);
             // The service has not been running - start it.
             return this._startService(service, uri, options)
               .then(_ => this._changeStateConnectionEnabledEvent(prefs.get("connection.enabled"))
               );
+          }
+          this._setState(PUSH_SERVICE_ACTIVATING);
+          // If we already had running service - stop service, start the new
+          // one and check connection.enabled and offline state(offline state
+          // check is called in changeStateConnectionEnabledEvent function)
+          return this._stopService(CHANGING_SERVICE_EVENT)
+            .then(_ => this._startService(service, uri, options))
+            .then(_ => this._changeStateConnectionEnabledEvent(prefs.get("connection.enabled")));
+        }
+        if (this._state == PUSH_SERVICE_INIT) {
+          return Promise.resolve();
+        }
+        // The new serverUri is empty or misconfigured - stop service.
+        this._setState(PUSH_SERVICE_INIT);
+        return this._stopService(STOPPING_SERVICE_EVENT);
 
-          } else {
-            this._setState(PUSH_SERVICE_ACTIVATING);
-            // If we already had running service - stop service, start the new
-            // one and check connection.enabled and offline state(offline state
-            // check is called in changeStateConnectionEnabledEvent function)
-            return this._stopService(CHANGING_SERVICE_EVENT)
-              .then(_ =>
-                 this._startService(service, uri, options)
-              )
-              .then(_ => this._changeStateConnectionEnabledEvent(prefs.get("connection.enabled"))
-              );
-
-          }
-        } else {
-          if (this._state == PUSH_SERVICE_INIT) {
-            return Promise.resolve();
-
-          } else {
-            // The new serverUri is empty or misconfigured - stop service.
-            this._setState(PUSH_SERVICE_INIT);
-            return this._stopService(STOPPING_SERVICE_EVENT);
-          }
-        }
       default:
         console.error("Unexpected event in _changeServerURL", event);
         return Promise.reject(new Error(`Unexpected event ${event}`));
     }
   },
 
   /**
    * PushService initialization is divided into 4 parts:
@@ -465,26 +451,25 @@ var PushService = {
     prefs.observe("serverURL", this);
     Services.obs.addObserver(this, "quit-application");
 
     if (options.serverURI) {
       // this is use for xpcshell test.
 
       await this._stateChangeProcessEnqueue(_ =>
         this._changeServerURL(options.serverURI, STARTING_SERVICE_EVENT, options));
-
     } else {
       // This is only used for testing. Different tests require connecting to
       // slightly different URLs.
       await this._stateChangeProcessEnqueue(_ =>
         this._changeServerURL(prefs.get("serverURL"), STARTING_SERVICE_EVENT));
     }
   },
 
-  _startObservers: function() {
+  _startObservers() {
     console.debug("startObservers()");
 
     if (this._state != PUSH_SERVICE_ACTIVATING) {
       return;
     }
 
     Services.obs.addObserver(this, "clear-origin-attributes-data");
 
@@ -529,17 +514,17 @@ var PushService = {
    * PushService uninitialization is divided into 3 parts:
    * stopObservers() - stot observers started in startObservers.
    * stopService() - It stops listening for broadcasted messages, stops db and
    *                 PushService connection (WebSocket).
    *                 state is changed to PUSH_SERVICE_INIT.
    * uninit() - stop listening for quit-application and serverURL changes.
    *            state is change to PUSH_SERVICE_UNINIT
    */
-  _stopService: function(event) {
+  _stopService(event) {
     console.debug("stopService()");
 
     if (this._state < PUSH_SERVICE_ACTIVATING) {
       return Promise.resolve();
     }
 
     this._stopObservers();
 
@@ -565,17 +550,17 @@ var PushService = {
          this._db.close();
          this._db = null;
        }, err => {
          this._db.close();
          this._db = null;
        });
   },
 
-  _stopObservers: function() {
+  _stopObservers() {
     console.debug("stopObservers()");
 
     if (this._state < PUSH_SERVICE_ACTIVATING) {
       return;
     }
 
     prefs.ignore("connection.enabled", this);
 
@@ -611,73 +596,73 @@ var PushService = {
    * or when the server invalidates all existing registrations.
    *
    * We ignore expired registrations because they're already handled in other
    * code paths. Registrations that expired after exceeding their quotas are
    * evicted at startup, or on the next `idle-daily` event. Registrations that
    * expired because the user revoked the notification permission are evicted
    * once the permission is reinstated.
    */
-  dropUnexpiredRegistrations: function() {
+  dropUnexpiredRegistrations() {
     return this._db.clearIf(record => {
       if (record.isExpired()) {
         return false;
       }
       this._notifySubscriptionChangeObservers(record);
       return true;
     });
   },
 
-  _notifySubscriptionChangeObservers: function(record) {
+  _notifySubscriptionChangeObservers(record) {
     if (!record) {
       return;
     }
     gPushNotifier.notifySubscriptionChange(record.scope, record.principal);
   },
 
   /**
    * Drops a registration and notifies the associated service worker. If the
    * registration does not exist, this function is a no-op.
    *
    * @param {String} keyID The registration ID to remove.
    * @returns {Promise} Resolves once the worker has been notified.
    */
-  dropRegistrationAndNotifyApp: function(aKeyID) {
+  dropRegistrationAndNotifyApp(aKeyID) {
     return this._db.delete(aKeyID)
       .then(record => this._notifySubscriptionChangeObservers(record));
   },
 
   /**
    * Replaces an existing registration and notifies the associated service
    * worker.
    *
    * @param {String} aOldKey The registration ID to replace.
    * @param {PushRecord} aNewRecord The new record.
    * @returns {Promise} Resolves once the worker has been notified.
    */
-  updateRegistrationAndNotifyApp: function(aOldKey, aNewRecord) {
+  updateRegistrationAndNotifyApp(aOldKey, aNewRecord) {
     return this.updateRecordAndNotifyApp(aOldKey, _ => aNewRecord);
   },
   /**
    * Updates a registration and notifies the associated service worker.
    *
    * @param {String} keyID The registration ID to update.
    * @param {Function} updateFunc Returns the updated record.
    * @returns {Promise} Resolves with the updated record once the worker
    *  has been notified.
    */
-  updateRecordAndNotifyApp: function(aKeyID, aUpdateFunc) {
+  updateRecordAndNotifyApp(aKeyID, aUpdateFunc) {
     return this._db.update(aKeyID, aUpdateFunc)
       .then(record => {
         this._notifySubscriptionChangeObservers(record);
         return record;
       });
   },
 
-  ensureCrypto: function(record) {
+  ensureCrypto(record) {
     if (record.hasAuthenticationSecret() &&
         record.p256dhPublicKey &&
         record.p256dhPrivateKey) {
       return Promise.resolve(record);
     }
 
     let keygen = Promise.resolve([]);
     if (!record.p256dhPublicKey || !record.p256dhPrivateKey) {
@@ -725,18 +710,17 @@ var PushService = {
    */
   receivedPushMessage(keyID, messageID, headers, data, updateFunc) {
     console.debug("receivedPushMessage()");
 
     return this._updateRecordAfterPush(keyID, updateFunc).then(record => {
       if (record.quotaApplies()) {
         // Update quota after the delay, at which point
         // we check for visible notifications.
-        let timeoutID = setTimeout(_ =>
-          {
+        let timeoutID = setTimeout(_ => {
             this._updateQuota(keyID);
             if (!this._updateQuotaTimeouts.delete(timeoutID)) {
               console.debug("receivedPushMessage: quota update timeout missing?");
             }
           }, prefs.get("quotaUpdateDelay"));
         this._updateQuotaTimeouts.add(timeoutID);
       }
       return this._decryptAndNotifyApp(record, messageID, headers, data);
@@ -748,17 +732,17 @@ var PushService = {
 
   /**
    * Dispatches a broadcast notification to the BroadcastService.
    */
   receivedBroadcastMessage(message) {
     pushBroadcastService.receivedBroadcastMessage(message.broadcasts)
       .catch(e => {
         console.error(e);
-      });;
+      });
   },
 
   /**
    * Updates a registration record after receiving a push message.
    *
    * @param {String} keyID The push registration ID.
    * @param {Function} updateFunc The function passed to `receivedPushMessage`.
    * @returns {Promise} Resolves with the updated record, or rejects if the
@@ -822,17 +806,17 @@ var PushService = {
 
           let message = error.format(record.scope);
           gPushNotifier.notifyError(record.scope, record.principal, message,
                                     Ci.nsIScriptError.errorFlag);
           return Ci.nsIPushErrorReporter.ACK_DECRYPTION_ERROR;
         });
   },
 
-  _updateQuota: function(keyID) {
+  _updateQuota(keyID) {
     console.debug("updateQuota()");
 
     this._db.update(keyID, record => {
       // Record may have expired from an earlier quota update.
       if (record.isExpired()) {
         console.debug(
           "updateQuota: Trying to update quota for expired record", record);
         return null;
@@ -889,17 +873,16 @@ var PushService = {
       this._visibleNotifications.delete(origin);
     }
   },
 
   reportDeliveryError(messageID, reason) {
     console.debug("reportDeliveryError()", messageID, reason);
     if (this._state == PUSH_SERVICE_RUNNING &&
         this._service.isConnected()) {
-
       // Only report errors if we're initialized and connected.
       this._service.reportDeliveryError(messageID, reason);
     }
   },
 
   _notifyApp(aPushRecord, messageID, message) {
     if (!aPushRecord || !aPushRecord.scope ||
         aPushRecord.originAttributes === undefined) {
@@ -930,21 +913,21 @@ var PushService = {
     } else {
       gPushNotifier.notifyPush(aPushRecord.scope, aPushRecord.principal,
                                messageID);
     }
 
     return Ci.nsIPushErrorReporter.ACK_DELIVERED;
   },
 
-  getByKeyID: function(aKeyID) {
+  getByKeyID(aKeyID) {
     return this._db.getByKeyID(aKeyID);
   },
 
-  getAllUnexpired: function() {
+  getAllUnexpired() {
     return this._db.getAllUnexpired();
   },
 
   _sendRequest(action, ...params) {
     if (this._state == PUSH_SERVICE_CONNECTION_DISABLE) {
       return Promise.reject(new Error("Push service disabled"));
     }
     if (this._state == PUSH_SERVICE_ACTIVE_OFFLINE) {
@@ -963,17 +946,17 @@ var PushService = {
       return Promise.reject(new Error("Unknown request type: " + action));
     });
   },
 
   /**
    * Called on message from the child process. aPageRecord is an object sent by
    * the push manager, identifying the sending page and other fields.
    */
-  _registerWithServer: function(aPageRecord) {
+  _registerWithServer(aPageRecord) {
     console.debug("registerWithServer()", aPageRecord);
 
     return this._sendRequest("register", aPageRecord)
       .then(record => this._onRegisterSuccess(record),
             err => this._onRegisterError(err))
       .then(record => {
         this._deletePendingRequest(aPageRecord);
         gPushNotifier.notifySubscriptionModified(record.scope,
@@ -988,33 +971,33 @@ var PushService = {
   _sendUnregister(aRecord, aReason) {
     return this._sendRequest("unregister", aRecord, aReason);
   },
 
   /**
    * Exceptions thrown in _onRegisterSuccess are caught by the promise obtained
    * from _service.request, causing the promise to be rejected instead.
    */
-  _onRegisterSuccess: function(aRecord) {
+  _onRegisterSuccess(aRecord) {
     console.debug("_onRegisterSuccess()");
 
     return this._db.put(aRecord)
       .catch(error => {
         // Unable to save. Destroy the subscription in the background.
         this._backgroundUnregister(aRecord,
                                    Ci.nsIPushErrorReporter.UNSUBSCRIBE_MANUAL);
         throw error;
       });
   },
 
   /**
    * Exceptions thrown in _onRegisterError are caught by the promise obtained
    * from _service.request, causing the promise to be rejected instead.
    */
-  _onRegisterError: function(reply) {
+  _onRegisterError(reply) {
     console.debug("_onRegisterError()");
 
     if (!reply.error) {
       console.warn("onRegisterError: Called without valid error message!",
         reply);
       throw new Error("Registration error");
     }
     throw reply.error;
@@ -1025,17 +1008,17 @@ var PushService = {
   },
 
   _getByPageRecord(pageRecord) {
     return this._checkActivated().then(_ =>
       this._db.getByIdentifiers(pageRecord)
     );
   },
 
-  register: function(aPageRecord) {
+  register(aPageRecord) {
     console.debug("register()", aPageRecord);
 
     let keyPromise;
     if (aPageRecord.appServerKey) {
       let keyView = new Uint8Array(aPageRecord.appServerKey);
       keyPromise = PushCrypto.validateAppServerKey(keyView)
         .catch(error => {
           // Normalize Web Crypto exceptions. `nsIPushService` will forward the
@@ -1109,54 +1092,54 @@ var PushService = {
    * failure, the application is never informed. In addition the application may
    * retry the unregister when it fails due to timeout (websocket) or any other
    * reason at which point the server will say it does not know of this
    * unregistration.  We'll have to make the registration/unregistration phases
    * have retries and attempts to resend messages from the server, and have the
    * client acknowledge. On a server, data is cheap, reliable notification is
    * not.
    */
-  unregister: function(aPageRecord) {
+  unregister(aPageRecord) {
     console.debug("unregister()", aPageRecord);
 
     return this._getByPageRecord(aPageRecord)
       .then(record => {
-        if (record === undefined) {
+        if (record === null) {
           return false;
         }
 
         let reason = Ci.nsIPushErrorReporter.UNSUBSCRIBE_MANUAL;
         return Promise.all([
           this._sendUnregister(record, reason),
-          this._db.delete(record.keyID).then(record => {
-            if (record) {
-              gPushNotifier.notifySubscriptionModified(record.scope,
-                                                       record.principal);
+          this._db.delete(record.keyID).then(rec => {
+            if (rec) {
+              gPushNotifier.notifySubscriptionModified(rec.scope,
+                                                       rec.principal);
             }
           }),
         ]).then(([success]) => success);
       });
   },
 
-  clear: function(info) {
+  clear(info) {
     return this._checkActivated()
       .then(_ => {
         return this._dropRegistrationsIf(record =>
           info.domain == "*" ||
           (record.uri && eTLDService.hasRootDomain(record.uri.prePath, info.domain))
         );
       })
       .catch(e => {
         console.warn("clear: Error dropping subscriptions for domain",
           info.domain, e);
         return Promise.resolve();
       });
   },
 
-  registration: function(aPageRecord) {
+  registration(aPageRecord) {
     console.debug("registration()");
 
     return this._getByPageRecord(aPageRecord)
       .then(record => {
         if (!record) {
           return null;
         }
         if (record.isExpired()) {
@@ -1166,36 +1149,36 @@ var PushService = {
             }
             return null;
           });
         }
         return record.toSubscription();
       });
   },
 
-  _dropExpiredRegistrations: function() {
+  _dropExpiredRegistrations() {
     console.debug("dropExpiredRegistrations()");
 
     return this._db.getAllExpired().then(records => {
       return Promise.all(records.map(record =>
         record.quotaChanged().then(isChanged => {
           if (isChanged) {
             // If the user revisited the site, drop the expired push
             // registration and notify the associated service worker.
-            return this.dropRegistrationAndNotifyApp(record.keyID);
+            this.dropRegistrationAndNotifyApp(record.keyID);
           }
         }).catch(error => {
           console.error("dropExpiredRegistrations: Error dropping registration",
             record.keyID, error);
         })
       ));
     });
   },
 
-  _onPermissionChange: function(subject, data) {
+  _onPermissionChange(subject, data) {
     console.debug("onPermissionChange()");
 
     if (data == "cleared") {
       return this._clearPermissions();
     }
 
     let permission = subject.QueryInterface(Ci.nsIPermission);
     if (permission.type != "desktop-notification") {
@@ -1214,17 +1197,17 @@ var PushService = {
         return false;
       }
       this._backgroundUnregister(record,
         Ci.nsIPushErrorReporter.UNSUBSCRIBE_PERMISSION_REVOKED);
       return true;
     });
   },
 
-  _updatePermission: function(permission, type) {
+  _updatePermission(permission, type) {
     console.debug("updatePermission()");
 
     let isAllow = permission.capability ==
                   Ci.nsIPermissionManager.ALLOW_ACTION;
     let isChange = type == "added" || type == "changed";
 
     if (isAllow && isChange) {
       // Permission set to "allow". Drop all expired registrations for this
@@ -1241,17 +1224,17 @@ var PushService = {
         permission.principal,
         (record, cursor) => this._permissionDenied(record, cursor)
       );
     }
 
     return Promise.resolve();
   },
 
-  _forEachPrincipal: function(principal, callback) {
+  _forEachPrincipal(principal, callback) {
     return this._db.forEachOrigin(
       principal.URI.prePath,
       ChromeUtils.originAttributesToSuffix(principal.originAttributes),
       callback
     );
   },
 
   /**
@@ -1259,17 +1242,17 @@ var PushService = {
    * permission is revoked. We only expire the record so we can notify the
    * service worker as soon as the permission is reinstated. If we just
    * deleted the record, the worker wouldn't be notified until the next visit
    * to the site.
    *
    * @param {PushRecord} record The record to expire.
    * @param {IDBCursor} cursor The IndexedDB cursor.
    */
-  _permissionDenied: function(record, cursor) {
+  _permissionDenied(record, cursor) {
     console.debug("permissionDenied()");
 
     if (!record.quotaApplies() || record.isExpired()) {
       // Ignore already-expired records.
       return;
     }
     // Drop the registration in the background.
     this._backgroundUnregister(record,
--- a/dom/push/PushServiceAndroidGCM.jsm
+++ b/dom/push/PushServiceAndroidGCM.jsm
@@ -1,26 +1,29 @@
-/* jshint moz: true, esnext: true */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const {PushDB} = ChromeUtils.import("resource://gre/modules/PushDB.jsm");
-const {PushRecord} = ChromeUtils.import("resource://gre/modules/PushRecord.jsm");
-const {PushCrypto} = ChromeUtils.import("resource://gre/modules/PushCrypto.jsm");
-const {EventDispatcher} = ChromeUtils.import("resource://gre/modules/Messaging.jsm"); /*global: EventDispatcher */
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); /*global: Services */
-const {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm"); /*global: Preferences */
-const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); /*global: XPCOMUtils */
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
-const Log = ChromeUtils.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.bind("Push");
+ChromeUtils.defineModuleGetter(this, "PushDB", "resource://gre/modules/PushDB.jsm");
+ChromeUtils.defineModuleGetter(this, "PushRecord", "resource://gre/modules/PushRecord.jsm");
+ChromeUtils.defineModuleGetter(this, "PushCrypto", "resource://gre/modules/PushCrypto.jsm");
+ChromeUtils.defineModuleGetter(this, "EventDispatcher", "resource://gre/modules/Messaging.jsm");
+ChromeUtils.defineModuleGetter(this, "Preferences", "resource://gre/modules/Preferences.jsm");
 
-var EXPORTED_SYMBOLS = ["PushServiceAndroidGCM"];
+XPCOMUtils.defineLazyGetter(this, "Log", () => {
+  return ChromeUtils.import("resource://gre/modules/AndroidLog.jsm", {})
+    .AndroidLog.bind("Push");
+});
+
+const EXPORTED_SYMBOLS = ["PushServiceAndroidGCM"];
 
 XPCOMUtils.defineLazyGetter(this, "console", () => {
   let {ConsoleAPI} = ChromeUtils.import("resource://gre/modules/Console.jsm");
   return new ConsoleAPI({
     dump: Log.i,
     maxLogLevelPref: "dom.push.loglevel",
     prefix: "PushServiceAndroidGCM",
   });
@@ -37,41 +40,41 @@ const prefs = new Preferences("dom.push.
 /**
  * The implementation of WebPush push backed by Android's GCM
  * delivery.
  */
 var PushServiceAndroidGCM = {
   _mainPushService: null,
   _serverURI: null,
 
-  newPushDB: function() {
+  newPushDB() {
     return new PushDB(kPUSHANDROIDGCMDB_DB_NAME,
                       kPUSHANDROIDGCMDB_DB_VERSION,
                       kPUSHANDROIDGCMDB_STORE_NAME,
                       "channelID",
                       PushRecordAndroidGCM);
   },
 
-  validServerURI: function(serverURI) {
+  validServerURI(serverURI) {
     if (!serverURI) {
       return false;
     }
 
     if (serverURI.scheme == "https") {
       return true;
     }
     if (serverURI.scheme == "http") {
       // Allow insecure server URLs for development and testing.
       return !!prefs.get("testing.allowInsecureServerURL");
     }
     console.info("Unsupported Android GCM dom.push.serverURL scheme", serverURI.scheme);
     return false;
   },
 
-  observe: function(subject, topic, data) {
+  observe(subject, topic, data) {
     switch (topic) {
       case "nsPref:changed":
         if (data == "dom.push.debug") {
           // Reconfigure.
           let debug = !!prefs.get("debug");
           console.info("Debug parameter changed; updating configuration with new debug", debug);
           this._configure(this._serverURI, debug);
         }
@@ -116,70 +119,70 @@ var PushServiceAndroidGCM = {
     if (data.message) {
       if (data.enc && (data.enckey || data.cryptokey)) {
         headers = {
           encryption_key: data.enckey,
           crypto_key: data.cryptokey,
           encryption: data.enc,
           encoding: data.con,
         };
-      } else if (data.con == 'aes128gcm') {
+      } else if (data.con == "aes128gcm") {
         headers = {
           encoding: data.con,
         };
       }
       // Ciphertext is (urlsafe) Base 64 encoded.
       message = ChromeUtils.base64URLDecode(data.message, {
         // The Push server may append padding.
         padding: "ignore",
       });
     }
 
     return { headers, message };
   },
 
-  _configure: function(serverURL, debug) {
+  _configure(serverURL, debug) {
     return EventDispatcher.instance.sendRequestForResult({
       type: "PushServiceAndroidGCM:Configure",
       endpoint: serverURL.spec,
-      debug: debug,
+      debug,
     });
   },
 
-  init: function(options, mainPushService, serverURL) {
+  init(options, mainPushService, serverURL) {
     console.debug("init()");
     this._mainPushService = mainPushService;
     this._serverURI = serverURL;
 
     prefs.observe("debug", this);
     Services.obs.addObserver(this, "PushServiceAndroidGCM:ReceivedPushMessage");
 
     return this._configure(serverURL, !!prefs.get("debug")).then(() => {
       EventDispatcher.instance.sendRequestForResult({
-        type: "PushServiceAndroidGCM:Initialized"
+        type: "PushServiceAndroidGCM:Initialized",
       });
     });
   },
 
-  uninit: function() {
+  uninit() {
     console.debug("uninit()");
     EventDispatcher.instance.sendRequestForResult({
-      type: "PushServiceAndroidGCM:Uninitialized"
+      type: "PushServiceAndroidGCM:Uninitialized",
     });
 
     this._mainPushService = null;
     Services.obs.removeObserver(this, "PushServiceAndroidGCM:ReceivedPushMessage");
     prefs.ignore("debug", this);
   },
 
-  onAlarmFired: function() {
+  onAlarmFired() {
     // No action required.
   },
 
-  connect: function(records, broadcastListeners) {
+  connect(records, broadcastListeners) {
     console.debug("connect:", records);
     // It's possible for the registration or subscriptions backing the
     // PushService to not be registered with the underlying AndroidPushService.
     // Expire those that are unrecognized.
     return EventDispatcher.instance.sendRequestForResult({
       type: "PushServiceAndroidGCM:DumpSubscriptions",
     })
     .then(subscriptions => {
@@ -196,40 +199,40 @@ var PushServiceAndroidGCM = {
         return this._mainPushService.dropRegistrationAndNotifyApp(record.keyID)
           .catch(error => {
             console.error("connect: Error dropping registration", record.keyID, error);
           });
       }));
     });
   },
 
-  sendSubscribeBroadcast: async function(serviceId, version) {
+  async sendSubscribeBroadcast(serviceId, version) {
     // Not implemented yet
   },
 
-  isConnected: function() {
+  isConnected() {
     return this._mainPushService != null;
   },
 
-  disconnect: function() {
+  disconnect() {
     console.debug("disconnect");
   },
 
-  register: function(record) {
+  register(record) {
     console.debug("register:", record);
     let ctime = Date.now();
     let appServerKey = record.appServerKey ?
       ChromeUtils.base64URLEncode(record.appServerKey, {
         // The Push server requires padding.
         pad: true,
       }) : null;
     let message = {
       type: "PushServiceAndroidGCM:SubscribeChannel",
-      appServerKey: appServerKey,
-    }
+      appServerKey,
+    };
     if (record.scope == FXA_PUSH_SCOPE) {
       message.service = "fxa";
     }
     // Caller handles errors.
     return EventDispatcher.instance.sendRequestForResult(message)
     .then(data => {
       data = JSON.parse(data);
       console.debug("Got data:", data);
@@ -237,37 +240,37 @@ var PushServiceAndroidGCM = {
         .then(exportedKeys =>
           new PushRecordAndroidGCM({
             // Straight from autopush.
             channelID: data.channelID,
             pushEndpoint: data.endpoint,
             // Common to all PushRecord implementations.
             scope: record.scope,
             originAttributes: record.originAttributes,
-            ctime: ctime,
+            ctime,
             systemRecord: record.systemRecord,
             // Cryptography!
             p256dhPublicKey: exportedKeys[0],
             p256dhPrivateKey: exportedKeys[1],
             authenticationSecret: PushCrypto.generateAuthenticationSecret(),
             appServerKey: record.appServerKey,
           })
       );
     });
   },
 
-  unregister: function(record) {
+  unregister(record) {
     console.debug("unregister: ", record);
     return EventDispatcher.instance.sendRequestForResult({
       type: "PushServiceAndroidGCM:UnsubscribeChannel",
       channelID: record.keyID,
     });
   },
 
-  reportDeliveryError: function(messageID, reason) {
+  reportDeliveryError(messageID, reason) {
     console.warn("reportDeliveryError: Ignoring message delivery error",
       messageID, reason);
   },
 };
 
 function PushRecordAndroidGCM(record) {
   PushRecord.call(this, record);
   this.channelID = record.channelID;
--- a/dom/push/PushServiceHttp2.jsm
+++ b/dom/push/PushServiceHttp2.jsm
@@ -47,96 +47,96 @@ var PushSubscriptionListener = function(
   this.uri = uri;
 };
 
 PushSubscriptionListener.prototype = {
 
   QueryInterface: ChromeUtils.generateQI(["nsIHttpPushListener",
                                          "nsIStreamListener"]),
 
-  getInterface: function(aIID) {
+  getInterface(aIID) {
     return this.QueryInterface(aIID);
   },
 
-  onStartRequest: function(aRequest) {
+  onStartRequest(aRequest) {
     console.debug("PushSubscriptionListener: onStartRequest()");
     // We do not do anything here.
   },
 
-  onDataAvailable: function(aRequest, aStream, aOffset, aCount) {
+  onDataAvailable(aRequest, aStream, aOffset, aCount) {
     console.debug("PushSubscriptionListener: onDataAvailable()");
     // Nobody should send data, but just to be sure, otherwise necko will
     // complain.
     if (aCount === 0) {
       return;
     }
 
     let inputStream = Cc["@mozilla.org/scriptableinputstream;1"]
                         .createInstance(Ci.nsIScriptableInputStream);
 
     inputStream.init(aStream);
-    var data = inputStream.read(aCount);
+    inputStream.read(aCount);
   },
 
-  onStopRequest: function(aRequest, aStatusCode) {
+  onStopRequest(aRequest, aStatusCode) {
     console.debug("PushSubscriptionListener: onStopRequest()");
     if (!this._pushService) {
         return;
     }
 
     this._pushService.connOnStop(aRequest,
                                  Components.isSuccessCode(aStatusCode),
                                  this.uri);
   },
 
-  onPush: function(associatedChannel, pushChannel) {
+  onPush(associatedChannel, pushChannel) {
     console.debug("PushSubscriptionListener: onPush()");
     var pushChannelListener = new PushChannelListener(this);
     pushChannel.asyncOpen(pushChannelListener);
   },
 
-  disconnect: function() {
+  disconnect() {
     this._pushService = null;
-  }
+  },
 };
 
 /**
  * The listener for pushed messages. The message data is collected in
  * OnDataAvailable and send to the app in OnStopRequest.
  */
 var PushChannelListener = function(pushSubscriptionListener) {
   console.debug("PushChannelListener()");
   this._mainListener = pushSubscriptionListener;
   this._message = [];
   this._ackUri = null;
 };
 
 PushChannelListener.prototype = {
 
-  onStartRequest: function(aRequest) {
+  onStartRequest(aRequest) {
     this._ackUri = aRequest.URI.spec;
   },
 
-  onDataAvailable: function(aRequest, aStream, aOffset, aCount) {
+  onDataAvailable(aRequest, aStream, aOffset, aCount) {
     console.debug("PushChannelListener: onDataAvailable()");
 
     if (aCount === 0) {
       return;
     }
 
     let inputStream = Cc["@mozilla.org/binaryinputstream;1"]
                         .createInstance(Ci.nsIBinaryInputStream);
 
     inputStream.setInputStream(aStream);
     let chunk = new ArrayBuffer(aCount);
     inputStream.readArrayBuffer(aCount, chunk);
     this._message.push(chunk);
   },
 
-  onStopRequest: function(aRequest, aStatusCode) {
+  onStopRequest(aRequest, aStatusCode) {
     console.debug("PushChannelListener: onStopRequest()", "status code",
       aStatusCode);
     if (Components.isSuccessCode(aStatusCode) &&
         this._mainListener &&
         this._mainListener._pushService) {
       let headers = {
         encryption_key: getHeaderField(aRequest, "Encryption-Key"),
         crypto_key: getHeaderField(aRequest, "Crypto-Key"),
@@ -145,95 +145,79 @@ PushChannelListener.prototype = {
       };
       let msg = concatArray(this._message);
 
       this._mainListener._pushService._pushChannelOnStop(this._mainListener.uri,
                                                          this._ackUri,
                                                          headers,
                                                          msg);
     }
-  }
+  },
 };
 
 function getHeaderField(aRequest, name) {
   try {
     return aRequest.getRequestHeader(name);
-  } catch(e) {
+  } catch (e) {
     // getRequestHeader can throw.
     return null;
   }
 }
 
 var PushServiceDelete = function(resolve, reject) {
   this._resolve = resolve;
   this._reject = reject;
 };
 
 PushServiceDelete.prototype = {
 
-  onStartRequest: function(aRequest) {},
+  onStartRequest(aRequest) {},
 
-  onDataAvailable: function(aRequest, aStream, aOffset, aCount) {
+  onDataAvailable(aRequest, aStream, aOffset, aCount) {
     // Nobody should send data, but just to be sure, otherwise necko will
     // complain.
     if (aCount === 0) {
       return;
     }
 
     let inputStream = Cc["@mozilla.org/scriptableinputstream;1"]
                         .createInstance(Ci.nsIScriptableInputStream);
 
     inputStream.init(aStream);
-    var data = inputStream.read(aCount);
+    inputStream.read(aCount);
   },
 
-  onStopRequest: function(aRequest, aStatusCode) {
-
+  onStopRequest(aRequest, aStatusCode) {
     if (Components.isSuccessCode(aStatusCode)) {
        this._resolve();
     } else {
        this._reject(new Error("Error removing subscription: " + aStatusCode));
     }
-  }
+  },
 };
 
 var SubscriptionListener = function(aSubInfo, aResolve, aReject,
                                     aServerURI, aPushServiceHttp2) {
   console.debug("SubscriptionListener()");
   this._subInfo = aSubInfo;
   this._resolve = aResolve;
   this._reject = aReject;
-  this._data = '';
   this._serverURI = aServerURI;
   this._service = aPushServiceHttp2;
   this._ctime = Date.now();
   this._retryTimeoutID = null;
 };
 
 SubscriptionListener.prototype = {
 
-  onStartRequest: function(aRequest) {},
-
-  onDataAvailable: function(aRequest, aStream, aOffset, aCount) {
-    console.debug("SubscriptionListener: onDataAvailable()");
+  onStartRequest(aRequest) {},
 
-    // We do not expect any data, but necko will complain if we do not consume
-    // it.
-    if (aCount === 0) {
-      return;
-    }
+  onDataAvailable(aRequest, aStream, aOffset, aCount) {},
 
-    let inputStream = Cc["@mozilla.org/scriptableinputstream;1"]
-                        .createInstance(Ci.nsIScriptableInputStream);
-
-    inputStream.init(aStream);
-    this._data.concat(inputStream.read(aCount));
-  },
-
-  onStopRequest: function(aRequest, aStatus) {
+  onStopRequest(aRequest, aStatus) {
     console.debug("SubscriptionListener: onStopRequest()");
 
     // Check if pushService is still active.
     if (!this._service.hasmainPushService()) {
       this._reject(new Error("Push service unavailable"));
       return;
     }
 
@@ -243,22 +227,21 @@ SubscriptionListener.prototype = {
     }
 
     var statusCode = aRequest.QueryInterface(Ci.nsIHttpChannel).responseStatus;
 
     if (Math.floor(statusCode / 100) == 5) {
       if (this._subInfo.retries < prefs.getIntPref("http2.maxRetries")) {
         this._subInfo.retries++;
         var retryAfter = retryAfterParser(aRequest);
-        this._retryTimeoutID = setTimeout(_ =>
-          {
+        this._retryTimeoutID = setTimeout(_ => {
             this._reject(
               {
                 retry: true,
-                subInfo: this._subInfo
+                subInfo: this._subInfo,
               });
             this._service.removeListenerPendingRetry(this);
             this._retryTimeoutID = null;
           }, retryAfter);
         this._service.addListenerPendingRetry(this);
       } else {
         this._reject(new Error("Unexpected server response: " + statusCode));
       }
@@ -294,98 +277,96 @@ SubscriptionListener.prototype = {
       return;
     }
 
     if (!subscriptionUri) {
       this._reject(new Error("Invalid Location header"));
       return;
     }
     try {
-      let uriTry = Services.io.newURI(subscriptionUri);
+      Services.io.newURI(subscriptionUri);
     } catch (e) {
       console.error("onStopRequest: Invalid subscription URI",
         subscriptionUri);
       this._reject(new Error("Invalid subscription endpoint: " +
         subscriptionUri));
       return;
     }
 
     let reply = new PushRecordHttp2({
-      subscriptionUri: subscriptionUri,
+      subscriptionUri,
       pushEndpoint: linkParserResult.pushEndpoint,
       pushReceiptEndpoint: linkParserResult.pushReceiptEndpoint,
       scope: this._subInfo.record.scope,
       originAttributes: this._subInfo.record.originAttributes,
       systemRecord: this._subInfo.record.systemRecord,
       appServerKey: this._subInfo.record.appServerKey,
       ctime: Date.now(),
     });
 
     this._resolve(reply);
   },
 
-  abortRetry: function() {
+  abortRetry() {
     if (this._retryTimeoutID != null) {
       clearTimeout(this._retryTimeoutID);
       this._retryTimeoutID = null;
     } else {
       console.debug("SubscriptionListener.abortRetry: aborting non-existent retry?");
     }
   },
 };
 
 function retryAfterParser(aRequest) {
-  var retryAfter = 0;
+  let retryAfter = 0;
   try {
-    var retryField = aRequest.getResponseHeader("retry-after");
+    let retryField = aRequest.getResponseHeader("retry-after");
     if (isNaN(retryField)) {
       retryAfter = Date.parse(retryField) - (new Date().getTime());
     } else {
       retryAfter = parseInt(retryField, 10) * 1000;
     }
     retryAfter = (retryAfter > 0) ? retryAfter : 0;
-  } catch(e) {}
+  } catch (e) {}
 
   return retryAfter;
 }
 
 function linkParser(linkHeader, serverURI) {
-
-  var linkList = linkHeader.split(',');
+  let linkList = linkHeader.split(",");
   if ((linkList.length < 1)) {
     throw new Error("Invalid Link header");
   }
 
-  var pushEndpoint;
-  var pushReceiptEndpoint;
+  let pushEndpoint;
+  let pushReceiptEndpoint;
 
   linkList.forEach(link => {
-    var linkElems = link.split(';');
+    let linkElems = link.split(";");
 
     if (linkElems.length == 2) {
       if (linkElems[1].trim() === 'rel="urn:ietf:params:push"') {
-        pushEndpoint = linkElems[0].substring(linkElems[0].indexOf('<') + 1,
-                                              linkElems[0].indexOf('>'));
-
+        pushEndpoint = linkElems[0].substring(linkElems[0].indexOf("<") + 1,
+                                              linkElems[0].indexOf(">"));
       } else if (linkElems[1].trim() === 'rel="urn:ietf:params:push:receipt"') {
-        pushReceiptEndpoint = linkElems[0].substring(linkElems[0].indexOf('<') + 1,
-                                                     linkElems[0].indexOf('>'));
+        pushReceiptEndpoint = linkElems[0].substring(linkElems[0].indexOf("<") + 1,
+                                                     linkElems[0].indexOf(">"));
       }
     }
   });
 
   console.debug("linkParser: pushEndpoint", pushEndpoint);
   console.debug("linkParser: pushReceiptEndpoint", pushReceiptEndpoint);
   // Missing pushReceiptEndpoint is allowed.
   if (!pushEndpoint) {
     throw new Error("Missing push endpoint");
   }
 
-  var pushURI = Services.io.newURI(pushEndpoint, null, serverURI);
-  var pushReceiptURI;
+  const pushURI = Services.io.newURI(pushEndpoint, null, serverURI);
+  let pushReceiptURI;
   if (pushReceiptEndpoint) {
     pushReceiptURI = Services.io.newURI(pushReceiptEndpoint, null,
                                         serverURI);
   }
 
   return {
     pushEndpoint: pushURI.spec,
     pushReceiptEndpoint: (pushReceiptURI) ? pushReceiptURI.spec : "",
@@ -401,137 +382,135 @@ var PushServiceHttp2 = {
 
   // Keep information about all connections, e.g. the channel, listener...
   _conns: {},
   _started: false,
 
   // Set of SubscriptionListeners that are pending a subscription retry attempt.
   _listenersPendingRetry: new Set(),
 
-  newPushDB: function() {
+  newPushDB() {
     return new PushDB(kPUSHHTTP2DB_DB_NAME,
                       kPUSHHTTP2DB_DB_VERSION,
                       kPUSHHTTP2DB_STORE_NAME,
                       "subscriptionUri",
                       PushRecordHttp2);
   },
 
-  hasmainPushService: function() {
+  hasmainPushService() {
     return this._mainPushService !== null;
   },
 
-  validServerURI: function(serverURI) {
+  validServerURI(serverURI) {
     if (serverURI.scheme == "http") {
       return !!prefs.getBoolPref("testing.allowInsecureServerURL", false);
     }
     return serverURI.scheme == "https";
   },
 
   async connect(broadcastListeners) {
     let subscriptions = await this._mainPushService.getAllUnexpired();
     this.startConnections(subscriptions);
   },
 
-  sendSubscribeBroadcast: async function(serviceId, version) {
+  async sendSubscribeBroadcast(serviceId, version) {
     // Not implemented yet
   },
 
-  isConnected: function() {
+  isConnected() {
     return this._mainPushService != null;
   },
 
-  disconnect: function() {
+  disconnect() {
     this._shutdownConnections(false);
   },
 
-  _makeChannel: function(aUri) {
+  _makeChannel(aUri) {
     var chan = NetUtil.newChannel({uri: aUri, loadUsingSystemPrincipal: true})
                       .QueryInterface(Ci.nsIHttpChannel);
 
     var loadGroup = Cc["@mozilla.org/network/load-group;1"]
                       .createInstance(Ci.nsILoadGroup);
     chan.loadGroup = loadGroup;
     return chan;
   },
 
   /**
    * Subscribe new resource.
    */
-  register: function(aRecord) {
+  register(aRecord) {
     console.debug("subscribeResource()");
 
     return this._subscribeResourceInternal({
       record: aRecord,
-      retries: 0
+      retries: 0,
     })
     .then(result =>
       PushCrypto.generateKeys()
         .then(([publicKey, privateKey]) => {
-        result.p256dhPublicKey = publicKey;
-        result.p256dhPrivateKey = privateKey;
-        result.authenticationSecret = PushCrypto.generateAuthenticationSecret();
-        this._conns[result.subscriptionUri] = {
-          channel: null,
-          listener: null,
-          countUnableToConnect: 0,
-          lastStartListening: 0,
-          retryTimerID: 0,
-        };
-        this._listenForMsgs(result.subscriptionUri);
-        return result;
-      })
+          result.p256dhPublicKey = publicKey;
+          result.p256dhPrivateKey = privateKey;
+          result.authenticationSecret = PushCrypto.generateAuthenticationSecret();
+          this._conns[result.subscriptionUri] = {
+            channel: null,
+            listener: null,
+            countUnableToConnect: 0,
+            lastStartListening: 0,
+            retryTimerID: 0,
+          };
+          this._listenForMsgs(result.subscriptionUri);
+          return result;
+        })
     );
   },
 
-  _subscribeResourceInternal: function(aSubInfo) {
+  _subscribeResourceInternal(aSubInfo) {
     console.debug("subscribeResourceInternal()");
 
     return new Promise((resolve, reject) => {
       var listener = new SubscriptionListener(aSubInfo,
                                               resolve,
                                               reject,
                                               this._serverURI,
                                               this);
 
       var chan = this._makeChannel(this._serverURI.spec);
       chan.requestMethod = "POST";
       chan.asyncOpen(listener);
     })
     .catch(err => {
       if ("retry" in err) {
         return this._subscribeResourceInternal(err.subInfo);
-      } else {
-        throw err;
       }
-    })
+      throw err;
+    });
   },
 
-  _deleteResource: function(aUri) {
-
-    return new Promise((resolve,reject) => {
+  _deleteResource(aUri) {
+    return new Promise((resolve, reject) => {
       var chan = this._makeChannel(aUri);
       chan.requestMethod = "DELETE";
       chan.asyncOpen(new PushServiceDelete(resolve, reject));
     });
   },
 
   /**
    * Unsubscribe the resource with a subscription uri aSubscriptionUri.
    * We can't do anything about it if it fails, so we don't listen for response.
    */
-  _unsubscribeResource: function(aSubscriptionUri) {
+  _unsubscribeResource(aSubscriptionUri) {
     console.debug("unsubscribeResource()");
 
     return this._deleteResource(aSubscriptionUri);
   },
 
   /**
    * Start listening for messages.
    */
-  _listenForMsgs: function(aSubscriptionUri) {
+  _listenForMsgs(aSubscriptionUri) {
     console.debug("listenForMsgs()", aSubscriptionUri);
     if (!this._conns[aSubscriptionUri]) {
       console.warn("listenForMsgs: We do not have this subscription",
         aSubscriptionUri);
       return;
     }
 
     var chan = this._makeChannel(aSubscriptionUri);
@@ -551,33 +530,32 @@ var PushServiceHttp2 = {
       chan.cancel(Cr.NS_ERROR_ABORT);
       this._retryAfterBackoff(aSubscriptionUri, -1);
       return;
     }
 
     this._conns[aSubscriptionUri].lastStartListening = Date.now();
     this._conns[aSubscriptionUri].channel = conn.channel;
     this._conns[aSubscriptionUri].listener = conn.listener;
-
   },
 
-  _ackMsgRecv: function(aAckUri) {
+  _ackMsgRecv(aAckUri) {
     console.debug("ackMsgRecv()", aAckUri);
     return this._deleteResource(aAckUri);
   },
 
-  init: function(aOptions, aMainPushService, aServerURL) {
+  init(aOptions, aMainPushService, aServerURL) {
     console.debug("init()");
     this._mainPushService = aMainPushService;
     this._serverURI = aServerURL;
 
     return Promise.resolve();
   },
 
-  _retryAfterBackoff: function(aSubscriptionUri, retryAfter) {
+  _retryAfterBackoff(aSubscriptionUri, retryAfter) {
     console.debug("retryAfterBackoff()");
 
     var resetRetryCount = prefs.getIntPref("http2.reset_retry_count_after_ms");
     // If it was running for some time, reset retry counter.
     if ((Date.now() - this._conns[aSubscriptionUri].lastStartListening) >
         resetRetryCount) {
       this._conns[aSubscriptionUri].countUnableToConnect = 0;
     }
@@ -605,17 +583,17 @@ var PushServiceHttp2 = {
     this._conns[aSubscriptionUri].countUnableToConnect++;
     this._conns[aSubscriptionUri].retryTimerID =
       setTimeout(_ => this._listenForMsgs(aSubscriptionUri), retryAfter);
 
     console.debug("retryAfterBackoff: Retry in", retryAfter);
   },
 
   // Close connections.
-  _shutdownConnections: function(deleteInfo) {
+  _shutdownConnections(deleteInfo) {
     console.debug("shutdownConnections()");
 
     for (let subscriptionUri in this._conns) {
       if (this._conns[subscriptionUri]) {
         if (this._conns[subscriptionUri].listener) {
           this._conns[subscriptionUri].listener._pushService = null;
         }
 
@@ -634,90 +612,90 @@ var PushServiceHttp2 = {
         if (deleteInfo) {
           delete this._conns[subscriptionUri];
         }
       }
     }
   },
 
   // Start listening if subscriptions present.
-  startConnections: function(aSubscriptions) {
+  startConnections(aSubscriptions) {
     console.debug("startConnections()", aSubscriptions.length);
 
     for (let i = 0; i < aSubscriptions.length; i++) {
       let record = aSubscriptions[i];
       this._mainPushService.ensureCrypto(record).then(record => {
         this._startSingleConnection(record);
       }, error => {
         console.error("startConnections: Error updating record",
           record.keyID, error);
       });
     }
   },
 
-  _startSingleConnection: function(record) {
+  _startSingleConnection(record) {
     console.debug("_startSingleConnection()");
     if (typeof this._conns[record.subscriptionUri] != "object") {
       this._conns[record.subscriptionUri] = {channel: null,
                                              listener: null,
                                              countUnableToConnect: 0,
                                              retryTimerID: 0};
     }
     if (!this._conns[record.subscriptionUri].conn) {
       this._listenForMsgs(record.subscriptionUri);
     }
   },
 
   // Close connection and notify apps that subscription are gone.
-  _shutdownSubscription: function(aSubscriptionUri) {
+  _shutdownSubscription(aSubscriptionUri) {
     console.debug("shutdownSubscriptions()");
 
     if (typeof this._conns[aSubscriptionUri] == "object") {
       if (this._conns[aSubscriptionUri].listener) {
         this._conns[aSubscriptionUri].listener._pushService = null;
       }
 
       if (this._conns[aSubscriptionUri].channel) {
         try {
           this._conns[aSubscriptionUri].channel.cancel(Cr.NS_ERROR_ABORT);
         } catch (e) {}
       }
       delete this._conns[aSubscriptionUri];
     }
   },
 
-  uninit: function() {
+  uninit() {
     console.debug("uninit()");
     this._abortPendingSubscriptionRetries();
     this._shutdownConnections(true);
     this._mainPushService = null;
   },
 
-  _abortPendingSubscriptionRetries: function() {
+  _abortPendingSubscriptionRetries() {
     this._listenersPendingRetry.forEach((listener) => listener.abortRetry());
     this._listenersPendingRetry.clear();
   },
 
-  unregister: function(aRecord) {
+  unregister(aRecord) {
     this._shutdownSubscription(aRecord.subscriptionUri);
     return this._unsubscribeResource(aRecord.subscriptionUri);
   },
 
-  reportDeliveryError: function(messageID, reason) {
+  reportDeliveryError(messageID, reason) {
     console.warn("reportDeliveryError: Ignoring message delivery error",
       messageID, reason);
   },
 
   /** Push server has deleted subscription.
    *  Re-subscribe - if it succeeds send update db record and send
    *                 pushsubscriptionchange,
    *               - on error delete record and send pushsubscriptionchange
    *  TODO: maybe pushsubscriptionerror will be included.
    */
-  _resubscribe: function(aSubscriptionUri) {
+  _resubscribe(aSubscriptionUri) {
     this._mainPushService.getByKeyID(aSubscriptionUri)
       .then(record => this.register(record)
         .then(recordNew => {
           if (this._mainPushService) {
             this._mainPushService
                 .updateRegistrationAndNotifyApp(aSubscriptionUri, recordNew)
                 .catch(Cu.reportError);
           }
@@ -726,59 +704,56 @@ var PushServiceHttp2 = {
             this._mainPushService
                 .dropRegistrationAndNotifyApp(aSubscriptionUri)
                 .catch(Cu.reportError);
           }
         })
       );
   },
 
-  connOnStop: function(aRequest, aSuccess,
-                       aSubscriptionUri) {
+  connOnStop(aRequest, aSuccess, aSubscriptionUri) {
     console.debug("connOnStop() succeeded", aSuccess);
 
     var conn = this._conns[aSubscriptionUri];
     if (!conn) {
       // there is no connection description that means that we closed
       // connection, so do nothing. But we should have already deleted
       // the listener.
       return;
     }
 
     conn.channel = null;
     conn.listener = null;
 
     if (!aSuccess) {
       this._retryAfterBackoff(aSubscriptionUri, -1);
-
     } else if (Math.floor(aRequest.responseStatus / 100) == 5) {
       var retryAfter = retryAfterParser(aRequest);
       this._retryAfterBackoff(aSubscriptionUri, retryAfter);
-
     } else if (Math.floor(aRequest.responseStatus / 100) == 4) {
       this._shutdownSubscription(aSubscriptionUri);
       this._resubscribe(aSubscriptionUri);
     } else if (Math.floor(aRequest.responseStatus / 100) == 2) { // This should be 204
       setTimeout(_ => this._listenForMsgs(aSubscriptionUri), 0);
     } else {
       this._retryAfterBackoff(aSubscriptionUri, -1);
     }
   },
 
-  addListenerPendingRetry: function(aListener) {
+  addListenerPendingRetry(aListener) {
     this._listenersPendingRetry.add(aListener);
   },
 
-  removeListenerPendingRetry: function(aListener) {
+  removeListenerPendingRetry(aListener) {
     if (!this._listenersPendingRetry.remove(aListener)) {
       console.debug("removeListenerPendingRetry: listener not in list?");
     }
   },
 
-  _pushChannelOnStop: function(aUri, aAckUri, aHeaders, aMessage) {
+  _pushChannelOnStop(aUri, aAckUri, aHeaders, aMessage) {
     console.debug("pushChannelOnStop()");
 
     this._mainPushService.receivedPushMessage(
       aUri, "", aHeaders, aMessage, record => {
         // Always update the stored record.
         return record;
       }
     )
--- a/dom/push/PushServiceWebSocket.jsm
+++ b/dom/push/PushServiceWebSocket.jsm
@@ -38,17 +38,17 @@ const kUNREGISTER_REASON_TO_CODE = {
 const kDELIVERY_REASON_TO_CODE = {
   [Ci.nsIPushErrorReporter.DELIVERY_UNCAUGHT_EXCEPTION]: 301,
   [Ci.nsIPushErrorReporter.DELIVERY_UNHANDLED_REJECTION]: 302,
   [Ci.nsIPushErrorReporter.DELIVERY_INTERNAL_ERROR]: 303,
 };
 
 const prefs = new Preferences("dom.push.");
 
-var EXPORTED_SYMBOLS = ["PushServiceWebSocket"];
+const EXPORTED_SYMBOLS = ["PushServiceWebSocket"];
 
 XPCOMUtils.defineLazyGetter(this, "console", () => {
   let {ConsoleAPI} = ChromeUtils.import("resource://gre/modules/Console.jsm");
   return new ConsoleAPI({
     maxLogLevelPref: "dom.push.loglevel",
     prefix: "PushServiceWebSocket",
   });
 });
@@ -61,51 +61,51 @@ XPCOMUtils.defineLazyGetter(this, "conso
  * closed but the PushService may not be interested in these. It's easier to
  * stop listening than to have checks at specific points.
  */
 var PushWebSocketListener = function(pushService) {
   this._pushService = pushService;
 };
 
 PushWebSocketListener.prototype = {
-  onStart: function(context) {
+  onStart(context) {
     if (!this._pushService) {
         return;
     }
     this._pushService._wsOnStart(context);
   },
 
-  onStop: function(context, statusCode) {
+  onStop(context, statusCode) {
     if (!this._pushService) {
         return;
     }
     this._pushService._wsOnStop(context, statusCode);
   },
 
-  onAcknowledge: function(context, size) {
+  onAcknowledge(context, size) {
     // EMPTY
   },
 
-  onBinaryMessageAvailable: function(context, message) {
+  onBinaryMessageAvailable(context, message) {
     // EMPTY
   },
 
-  onMessageAvailable: function(context, message) {
+  onMessageAvailable(context, message) {
     if (!this._pushService) {
         return;
     }
     this._pushService._wsOnMessageAvailable(context, message);
   },
 
-  onServerClose: function(context, aStatusCode, aReason) {
+  onServerClose(context, aStatusCode, aReason) {
     if (!this._pushService) {
         return;
     }
     this._pushService._wsOnServerClose(context, aStatusCode, aReason);
-  }
+  },
 };
 
 // websocket states
 // websocket is off
 const STATE_SHUT_DOWN = 0;
 // Websocket has been opened on client side, waiting for successful open.
 // (_wsOnStart)
 const STATE_WAITING_FOR_WS_START = 1;
@@ -113,29 +113,29 @@ const STATE_WAITING_FOR_WS_START = 1;
 const STATE_WAITING_FOR_HELLO = 2;
 // Websocket operational, handshake completed, begin protocol messaging.
 const STATE_READY = 3;
 
 var PushServiceWebSocket = {
   _mainPushService: null,
   _serverURI: null,
 
-  newPushDB: function() {
+  newPushDB() {
     return new PushDB(kPUSHWSDB_DB_NAME,
                       kPUSHWSDB_DB_VERSION,
                       kPUSHWSDB_STORE_NAME,
                       "channelID",
                       PushRecordWebSocket);
   },
 
-  disconnect: function() {
+  disconnect() {
     this._shutdownWS();
   },
 
-  observe: function(aSubject, aTopic, aData) {
+  observe(aSubject, aTopic, aData) {
     if (aTopic == "nsPref:changed" && aData == "dom.push.userAgentID") {
       this._onUAIDChanged();
     } else if (aTopic == "timer-callback") {
       this._onTimerFired(aSubject);
     }
   },
 
   /**
@@ -162,17 +162,16 @@ var PushServiceWebSocket = {
     if (timer == this._backoffTimer) {
       console.debug("onTimerFired: Reconnecting after backoff");
       this._beginWSSetup();
       return;
     }
 
     if (timer == this._requestTimeoutTimer) {
       this._timeOutRequests();
-      return;
     }
   },
 
   /**
    * Sends a ping to the server. Bypasses the request queue, but starts the
    * request timeout timer. If the socket is already closed, or the server
    * does not respond within the timeout, the client will reconnect.
    */
@@ -203,20 +202,18 @@ var PushServiceWebSocket = {
     let now = Date.now();
 
     // Set to true if at least one request timed out, or we're still waiting
     // for a pong after the request timeout.
     let requestTimedOut = false;
 
     if (this._lastPingTime > 0 &&
         now - this._lastPingTime > this._requestTimeout) {
-
       console.debug("timeOutRequests: Did not receive pong in time");
       requestTimedOut = true;
-
     } else {
       for (let [key, request] of this._pendingRequests) {
         let duration = now - request.ctime;
         // If any of the registration requests time out, all the ones after it
         // also made to fail, since we are going to be disconnecting the
         // socket.
         requestTimedOut |= duration > this._requestTimeout;
         if (requestTimedOut) {
@@ -228,17 +225,17 @@ var PushServiceWebSocket = {
 
     // The most likely reason for a pong or registration request timing out is
     // that the socket has disconnected. Best to reconnect.
     if (requestTimedOut) {
       this._reconnect();
     }
   },
 
-  validServerURI: function(serverURI) {
+  validServerURI(serverURI) {
     if (serverURI.scheme == "ws") {
       return !!prefs.get("testing.allowInsecureServerURL");
     }
     return serverURI.scheme == "wss";
   },
 
   get _UAID() {
     return prefs.get("userAgentID");
@@ -291,28 +288,28 @@ var PushServiceWebSocket = {
 
   /** A one-shot timer fired after the reconnect backoff period. */
   _backoffTimer: null,
 
   /**
    * Sends a message to the Push Server through an open websocket.
    * typeof(msg) shall be an object
    */
-  _wsSendMessage: function(msg) {
+  _wsSendMessage(msg) {
     if (!this._ws) {
       console.warn("wsSendMessage: No WebSocket initialized.",
         "Cannot send a message");
       return;
     }
     msg = JSON.stringify(msg);
     console.debug("wsSendMessage: Sending message", msg);
     this._ws.sendMsg(msg);
   },
 
-  init: function(options, mainPushService, serverURI) {
+  init(options, mainPushService, serverURI) {
     console.debug("init()");
 
     this._mainPushService = mainPushService;
     this._serverURI = serverURI;
     // Filled in at connect() time
     this._broadcastListeners = null;
 
     // Override the default WebSocket factory function. The returned object
@@ -322,23 +319,23 @@ var PushServiceWebSocket = {
       this._makeWebSocket = options.makeWebSocket;
     }
 
     this._requestTimeout = prefs.get("requestTimeout");
 
     return Promise.resolve();
   },
 
-  _reconnect: function () {
+  _reconnect() {
     console.debug("reconnect()");
     this._shutdownWS(false);
     this._startBackoffTimer();
   },
 
-  _shutdownWS: function(shouldCancelPending = true) {
+  _shutdownWS(shouldCancelPending = true) {
     console.debug("shutdownWS()");
 
     if (this._currentState == STATE_READY) {
       prefs.ignore("userAgentID", this);
     }
 
     this._currentState = STATE_SHUT_DOWN;
     this._skipReconnect = false;
@@ -362,17 +359,17 @@ var PushServiceWebSocket = {
     }
 
     if (this._notifyRequestQueue) {
       this._notifyRequestQueue();
       this._notifyRequestQueue = null;
     }
   },
 
-  uninit: function() {
+  uninit() {
     // All pending requests (ideally none) are dropped at this point. We
     // shouldn't have any applications performing registration/unregistration
     // or receiving notifications.
     this._shutdownWS();
 
     if (this._backoffTimer) {
       this._backoffTimer.cancel();
     }
@@ -444,17 +441,17 @@ var PushServiceWebSocket = {
     if (!this._pingTimer) {
       this._pingTimer = Cc["@mozilla.org/timer;1"]
                           .createInstance(Ci.nsITimer);
     }
     this._pingTimer.init(this, prefs.get("pingInterval"),
                          Ci.nsITimer.TYPE_ONE_SHOT);
   },
 
-  _makeWebSocket: function(uri) {
+  _makeWebSocket(uri) {
     if (!prefs.get("connection.enabled")) {
       console.warn("makeWebSocket: connection.enabled is not set to true.",
         "Aborting.");
       return null;
     }
     if (Services.io.offline) {
       console.warn("makeWebSocket: Network is offline.");
       return null;
@@ -468,17 +465,17 @@ var PushServiceWebSocket = {
                         Services.scriptSecurityManager.getSystemPrincipal(),
                         null, // aTriggeringPrincipal
                         Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
                         Ci.nsIContentPolicy.TYPE_WEBSOCKET);
 
     return socket;
   },
 
-  _beginWSSetup: function() {
+  _beginWSSetup() {
     console.debug("beginWSSetup()");
     if (this._currentState != STATE_SHUT_DOWN) {
       console.error("_beginWSSetup: Not in shutdown state! Current state",
         this._currentState);
       return;
     }
 
     // Stop any pending reconnects scheduled for the near future.
@@ -500,37 +497,37 @@ var PushServiceWebSocket = {
     this._wsListener = new PushWebSocketListener(this);
     this._ws.protocol = "push-notification";
 
     try {
       // Grab a wakelock before we open the socket to ensure we don't go to
       // sleep before connection the is opened.
       this._ws.asyncOpen(uri, uri.spec, 0, this._wsListener, null);
       this._currentState = STATE_WAITING_FOR_WS_START;
-    } catch(e) {
+    } catch (e) {
       console.error("beginWSSetup: Error opening websocket.",
         "asyncOpen failed", e);
       this._reconnect();
     }
   },
 
-  connect: function(broadcastListeners) {
+  connect(broadcastListeners) {
     console.debug("connect()", broadcastListeners);
     this._broadcastListeners = broadcastListeners;
     this._beginWSSetup();
   },
 
-  isConnected: function() {
+  isConnected() {
     return !!this._ws;
   },
 
   /**
    * Protocol handler invoked by server message.
    */
-  _handleHelloReply: function(reply) {
+  _handleHelloReply(reply) {
     console.debug("handleHelloReply()");
     if (this._currentState != STATE_WAITING_FOR_HELLO) {
       console.error("handleHelloReply: Unexpected state", this._currentState,
         "(expected STATE_WAITING_FOR_HELLO)");
       this._shutdownWS();
       return;
     }
 
@@ -606,29 +603,28 @@ var PushServiceWebSocket = {
 
     // otherwise we are good to go
     finishHandshake.bind(this)();
   },
 
   /**
    * Protocol handler invoked by server message.
    */
-  _handleRegisterReply: function(reply) {
+  _handleRegisterReply(reply) {
     console.debug("handleRegisterReply()");
 
     let tmp = this._takeRequestForReply(reply);
     if (!tmp) {
       return;
     }
 
     if (reply.status == 200) {
       try {
         Services.io.newURI(reply.pushEndpoint);
-      }
-      catch (e) {
+      } catch (e) {
         tmp.reject(new Error("Invalid push endpoint: " + reply.pushEndpoint));
         return;
       }
 
       let record = new PushRecordWebSocket({
         channelID: reply.channelID,
         pushEndpoint: reply.pushEndpoint,
         scope: tmp.record.scope,
@@ -653,17 +649,17 @@ var PushServiceWebSocket = {
     if (!request) {
       return;
     }
 
     let success = reply.status === 200;
     request.resolve(success);
   },
 
-  _handleDataUpdate: function(update) {
+  _handleDataUpdate(update) {
     let promise;
     if (typeof update.channelID != "string") {
       console.warn("handleDataUpdate: Discarding update without channel ID",
         update);
       return;
     }
     function updateRecord(record) {
       // Ignore messages that we've already processed. This can happen if the
@@ -709,24 +705,24 @@ var PushServiceWebSocket = {
       console.error("handleDataUpdate: Error acknowledging message", update,
         err);
     });
   },
 
   /**
    * Protocol handler invoked by server message.
    */
-  _handleNotificationReply: function(reply) {
+  _handleNotificationReply(reply) {
     console.debug("handleNotificationReply()");
     if (this._dataEnabled) {
       this._handleDataUpdate(reply);
       return;
     }
 
-    if (typeof reply.updates !== 'object') {
+    if (typeof reply.updates !== "object") {
       console.warn("handleNotificationReply: Missing updates", reply.updates);
       return;
     }
 
     console.debug("handleNotificationReply: Got updates", reply.updates);
     for (let i = 0; i < reply.updates.length; i++) {
       let update = reply.updates[i];
       console.debug("handleNotificationReply: Handling update", update);
@@ -750,46 +746,46 @@ var PushServiceWebSocket = {
       if (typeof version === "number" && version >= 0) {
         // FIXME(nsm): this relies on app update notification being infallible!
         // eventually fix this
         this._receivedUpdate(update.channelID, version);
       }
     }
   },
 
-  _handleBroadcastReply: function(reply) {
+  _handleBroadcastReply(reply) {
     this._mainPushService.receivedBroadcastMessage(reply);
   },
 
   reportDeliveryError(messageID, reason) {
     console.debug("reportDeliveryError()");
     let code = kDELIVERY_REASON_TO_CODE[reason];
     if (!code) {
-      throw new Error('Invalid delivery error reason');
+      throw new Error("Invalid delivery error reason");
     }
-    let data = {messageType: 'nack',
+    let data = {messageType: "nack",
                 version: messageID,
-                code: code};
+                code};
     this._queueRequest(data);
   },
 
   _sendAck(channelID, version, status) {
     console.debug("sendAck()");
     let code = kACK_STATUS_TO_CODE[status];
     if (!code) {
-      throw new Error('Invalid ack status');
+      throw new Error("Invalid ack status");
     }
-    let data = {messageType: 'ack',
-                updates: [{channelID: channelID,
-                           version: version,
-                           code: code}]};
+    let data = {messageType: "ack",
+                updates: [{channelID,
+                           version,
+                           code}]};
     this._queueRequest(data);
   },
 
-  _generateID: function() {
+  _generateID() {
     let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"]
                           .getService(Ci.nsIUUIDGenerator);
     // generateUUID() gives a UUID surrounded by {...}, slice them off.
     return uuidGenerator.generateUUID().toString().slice(1, -1);
   },
 
   register(record) {
     console.debug("register() ", record);
@@ -819,30 +815,30 @@ var PushServiceWebSocket = {
   },
 
   unregister(record, reason) {
     console.debug("unregister() ", record, reason);
 
     return Promise.resolve().then(_ => {
       let code = kUNREGISTER_REASON_TO_CODE[reason];
       if (!code) {
-        throw new Error('Invalid unregister reason');
+        throw new Error("Invalid unregister reason");
       }
       let data = {channelID: record.channelID,
                   messageType: "unregister",
-                  code: code};
+                  code};
 
       return this._sendRequestForReply(record, data);
     });
   },
 
   _queueStart: Promise.resolve(),
   _notifyRequestQueue: null,
   _queue: null,
-  _enqueue: function(op) {
+  _enqueue(op) {
     console.debug("enqueue()");
     if (!this._queue) {
       this._queue = this._queueStart;
     }
     this._queue = this._queue
                     .then(op)
                     .catch(_ => {});
   },
@@ -918,17 +914,17 @@ var PushServiceWebSocket = {
       // not be call.
       if (!this._ws && this._notifyRequestQueue) {
         this._notifyRequestQueue();
         this._notifyRequestQueue = null;
       }
     }
   },
 
-  _receivedUpdate: function(aChannelID, aLatestVersion) {
+  _receivedUpdate(aChannelID, aLatestVersion) {
     console.debug("receivedUpdate: Updating", aChannelID, "->", aLatestVersion);
 
     this._mainPushService.receivedPushMessage(aChannelID, "", null, null, record => {
       if (record.version === null ||
           record.version < aLatestVersion) {
         console.debug("receivedUpdate: Version changed for", aChannelID,
           aLatestVersion);
         record.version = aLatestVersion;
@@ -941,17 +937,17 @@ var PushServiceWebSocket = {
       this._sendAck(aChannelID, aLatestVersion, status);
     }).catch(err => {
       console.error("receivedUpdate: Error acknowledging message", aChannelID,
         aLatestVersion, err);
     });
   },
 
   // begin Push protocol handshake
-  _wsOnStart: function(context) {
+  _wsOnStart(context) {
     console.debug("wsOnStart()");
 
     if (this._currentState != STATE_WAITING_FOR_WS_START) {
       console.error("wsOnStart: NOT in STATE_WAITING_FOR_WS_START. Current",
         "state", this._currentState, "Skipping");
       return;
     }
 
@@ -971,48 +967,48 @@ var PushServiceWebSocket = {
 
   /**
    * This statusCode is not the websocket protocol status code, but the TCP
    * connection close status code.
    *
    * If we do not explicitly call ws.close() then statusCode is always
    * NS_BASE_STREAM_CLOSED, even on a successful close.
    */
-  _wsOnStop: function(context, statusCode) {
+  _wsOnStop(context, statusCode) {
     console.debug("wsOnStop()");
 
     if (statusCode != Cr.NS_OK && !this._skipReconnect) {
       console.debug("wsOnStop: Reconnecting after socket error", statusCode);
       this._reconnect();
       return;
     }
 
     this._shutdownWS();
   },
 
-  _wsOnMessageAvailable: function(context, message) {
+  _wsOnMessageAvailable(context, message) {
     console.debug("wsOnMessageAvailable()", message);
 
     // Clearing the last ping time indicates we're no longer waiting for a pong.
     this._lastPingTime = 0;
 
     let reply;
     try {
       reply = JSON.parse(message);
-    } catch(e) {
+    } catch (e) {
       console.warn("wsOnMessageAvailable: Invalid JSON", message, e);
       return;
     }
 
     // If we receive a message, we know the connection succeeded. Reset the
     // connection attempt and ping interval counters.
     this._retryFailCount = 0;
 
     let doNotHandle = false;
-    if ((message === '{}') ||
+    if ((message === "{}") ||
         (reply.messageType === undefined) ||
         (reply.messageType === "ping") ||
         (typeof reply.messageType != "string")) {
       console.debug("wsOnMessageAvailable: Pong received");
       doNotHandle = true;
     }
 
     // Reset the ping timer.  Note: This path is executed at every step of the
@@ -1055,17 +1051,17 @@ var PushServiceWebSocket = {
    * _wsOnStop() receives error code NS_BASE_STREAM_CLOSED (see comment in that
    * function), which calls reconnect and re-establishes the WebSocket
    * connection.
    *
    * If the server requested that we back off, we won't reconnect until the
    * next network state change event, or until we need to send a new register
    * request.
    */
-  _wsOnServerClose: function(context, aStatusCode, aReason) {
+  _wsOnServerClose(context, aStatusCode, aReason) {
     console.debug("wsOnServerClose()", aStatusCode, aReason);
 
     if (aStatusCode == kBACKOFF_WS_STATUS_CODE) {
       console.debug("wsOnServerClose: Skipping automatic reconnect");
       this._skipReconnect = true;
     }
   },
 
@@ -1088,18 +1084,18 @@ var PushServiceWebSocket = {
   _sendRequestForReply(record, data) {
     return Promise.resolve().then(_ => {
       // start the timer since we now have at least one request
       this._startRequestTimeoutTimer();
 
       let key = this._makePendingRequestKey(data);
       if (!this._pendingRequests.has(key)) {
         let request = {
-          data: data,
-          record: record,
+          data,
+          record,
           ctime: Date.now(),
         };
         request.promise = new Promise((resolve, reject) => {
           request.resolve = resolve;
           request.reject = reject;
         });
         this._pendingRequests.set(key, request);
         this._queueRequest(data);
@@ -1125,17 +1121,17 @@ var PushServiceWebSocket = {
     }
     return request;
   },
 
   sendSubscribeBroadcast(serviceId, version) {
     let data = {
       messageType: "broadcast_subscribe",
       broadcasts: {
-        [serviceId]: version
+        [serviceId]: version,
       },
     };
 
     this._queueRequest(data);
   },
 };
 
 function PushRecordWebSocket(record) {
--- a/dom/push/test/lifetime_worker.js
+++ b/dom/push/test/lifetime_worker.js
@@ -1,25 +1,25 @@
 var state = "from_scope";
 var resolvePromiseCallback;
 
-onfetch = function(event) {
+self.onfetch = function(event) {
   if (event.request.url.includes("lifetime_frame.html")) {
     event.respondWith(new Response("iframe_lifetime"));
     return;
   }
 
   var currentState = state;
   event.waitUntil(
-    clients.matchAll()
-           .then(clients => {
-             clients.forEach(client => {
-               client.postMessage({type: "fetch", state: currentState});
-             });
-           })
+    self.clients.matchAll()
+      .then(clients => {
+        clients.forEach(client => {
+          client.postMessage({type: "fetch", state: currentState});
+        });
+      })
   );
 
   if (event.request.url.includes("update")) {
     state = "update";
   } else if (event.request.url.includes("wait")) {
     event.respondWith(new Promise(function(res, rej) {
       if (resolvePromiseCallback) {
         dump("ERROR: service worker was already waiting on a promise.\n");
@@ -28,58 +28,58 @@ onfetch = function(event) {
         res(new Response("resolve_respondWithPromise"));
       };
     }));
     state = "wait";
   } else if (event.request.url.includes("release")) {
     state = "release";
     resolvePromise();
   }
-}
+};
 
 function resolvePromise() {
   if (resolvePromiseCallback === undefined || resolvePromiseCallback == null) {
     dump("ERROR: wait promise was not set.\n");
     return;
   }
   resolvePromiseCallback();
   resolvePromiseCallback = null;
 }
 
-onmessage = function(event) {
+self.onmessage = function(event) {
   var lastState = state;
   state = event.data;
-  if (state === 'wait') {
+  if (state === "wait") {
     event.waitUntil(new Promise(function(res, rej) {
       if (resolvePromiseCallback) {
         dump("ERROR: service worker was already waiting on a promise.\n");
       }
       resolvePromiseCallback = res;
     }));
-  } else if (state === 'release') {
+  } else if (state === "release") {
     resolvePromise();
   }
   event.source.postMessage({type: "message", state: lastState});
-}
+};
 
-onpush = function(event) {
+self.onpush = function(event) {
   var pushResolve;
   event.waitUntil(new Promise(function(resolve) {
     pushResolve = resolve;
   }));
 
   // FIXME(catalinb): push message carry no data. So we assume the only
   // push message we get is "wait"
-  clients.matchAll().then(function(client) {
+  self.clients.matchAll().then(function(client) {
     if (client.length == 0) {
       dump("ERROR: no clients to send the response to.\n");
     }
 
-    client[0].postMessage({type: "push", state: state});
+    client[0].postMessage({type: "push", state});
 
     state = "wait";
     if (resolvePromiseCallback) {
       dump("ERROR: service worker was already waiting on a promise.\n");
     } else {
       resolvePromiseCallback = pushResolve;
     }
   });
-}
+};
--- a/dom/push/test/mockpushserviceparent.js
+++ b/dom/push/test/mockpushserviceparent.js
@@ -1,8 +1,10 @@
+/* eslint-env mozilla/frame-script */
+
 "use strict";
 
 /**
  * Defers one or more callbacks until the next turn of the event loop. Multiple
  * callbacks are executed in order.
  *
  * @param {Function[]} callbacks The callbacks to execute. One callback will be
  *  executed per tick.
@@ -56,63 +58,63 @@ MockWebSocketParent.prototype = {
 
 var pushService = Cc["@mozilla.org/push/Service;1"].
                   getService(Ci.nsIPushService).
                   wrappedJSObject;
 
 var mockSocket;
 var serverMsgs = [];
 
-addMessageListener("socket-setup", function () {
+addMessageListener("socket-setup", function() {
   pushService.replaceServiceBackend({
     serverURI: "wss://push.example.org/",
     makeWebSocket(uri) {
       mockSocket = new MockWebSocketParent(uri);
       while (serverMsgs.length > 0) {
         let msg = serverMsgs.shift();
         mockSocket.serverSendMsg(msg);
       }
       return mockSocket;
-    }
+    },
   });
 });
 
-addMessageListener("socket-teardown", function (msg) {
+addMessageListener("socket-teardown", function(msg) {
   pushService.restoreServiceBackend().then(_ => {
     serverMsgs.length = 0;
     if (mockSocket) {
       mockSocket.close();
       mockSocket = null;
     }
     sendAsyncMessage("socket-server-teardown");
   }).catch(error => {
     Cu.reportError(`Error restoring service backend: ${error}`);
-  })
+  });
 });
 
-addMessageListener("socket-server-msg", function (msg) {
+addMessageListener("socket-server-msg", function(msg) {
   if (mockSocket) {
     mockSocket.serverSendMsg(msg);
   } else {
     serverMsgs.push(msg);
   }
 });
 
 var MockService = {
   requestID: 1,
   resolvers: new Map(),
 
   sendRequest(name, params) {
     return new Promise((resolve, reject) => {
       let id = this.requestID++;
       this.resolvers.set(id, { resolve, reject });
       sendAsyncMessage("service-request", {
-        name: name,
-        id: id,
-        params: params,
+        name,
+        id,
+        params,
       });
     });
   },
 
   handleResponse(response) {
     if (!this.resolvers.has(response.id)) {
       Cu.reportError(`Unexpected response for request ${response.id}`);
       return;
@@ -137,18 +139,18 @@ var MockService = {
   },
 
   unregister(pageRecord) {
     return this.sendRequest("unregister", pageRecord);
   },
 
   reportDeliveryError(messageId, reason) {
     sendAsyncMessage("service-delivery-error", {
-      messageId: messageId,
-      reason: reason,
+      messageId,
+      reason,
     });
   },
 
   uninit() {
     return Promise.resolve();
   },
 };
 
@@ -169,11 +171,11 @@ addMessageListener("service-replace", fu
 addMessageListener("service-restore", function() {
   replaceService(null).then(_ => {
     sendAsyncMessage("service-restored");
   }).catch(error => {
     Cu.reportError(`Error restoring service: ${error}`);
   });
 });
 
-addMessageListener("service-response", function (response) {
+addMessageListener("service-response", function(response) {
   MockService.handleResponse(response);
 });
--- a/dom/push/test/test_data.html
+++ b/dom/push/test/test_data.html
@@ -20,37 +20,41 @@ http://creativecommons.org/licenses/publ
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* import-globals-from ./test_utils.js */
+
+  /* globals webPushEncrypt */
+
   var userAgentID = "ac44402c-85fc-41e4-a0d0-483316d15351";
   var channelID = null;
 
   var mockSocket = new MockWebSocket();
   mockSocket.onRegister = function(request) {
     channelID = request.channelID;
     this.serverSendMsg(JSON.stringify({
       messageType: "register",
       uaid: userAgentID,
       channelID,
       status: 200,
-      pushEndpoint: "https://example.com/endpoint/1"
+      pushEndpoint: "https://example.com/endpoint/1",
     }));
   };
 
   var registration;
   add_task(async function start() {
     await setupPrefsAndMockSocket(mockSocket);
     await setPushPermission(true);
 
-    var url = "worker.js" + "?" + (Math.random());
+    var url = "worker.js?" + (Math.random());
     registration = await navigator.serviceWorker.register(url, {scope: "."});
     await waitForActive(registration);
   });
 
   var controlledFrame;
   add_task(async function createControlledIFrame() {
     controlledFrame = await injectControlledFrame();
   });
@@ -87,38 +91,38 @@ http://creativecommons.org/licenses/publ
     isDeeply(
       authSecret,
       new Uint8Array(data.auth),
       "Mismatched auth secret"
     );
   });
 
   var version = 0;
-  function sendEncryptedMsg(pushSubscription, message) {
-    return webPushEncrypt(pushSubscription, message)
+  function sendEncryptedMsg(pushSub, message) {
+    return webPushEncrypt(pushSub, message)
       .then((encryptedData) => {
         mockSocket.serverSendMsg(JSON.stringify({
-          messageType: 'notification',
+          messageType: "notification",
           version: version++,
-          channelID: channelID,
+          channelID,
           data: encryptedData.data,
           headers: {
             encryption: encryptedData.encryption,
             encryption_key: encryptedData.encryption_key,
-            encoding: encryptedData.encoding
-          }
+            encoding: encryptedData.encoding,
+          },
         }));
       });
   }
 
-  function waitForMessage(pushSubscription, message) {
+  function waitForMessage(pushSub, message) {
     return Promise.all([
       controlledFrame.waitOnWorkerMessage("finished"),
-      sendEncryptedMsg(pushSubscription, message),
-    ]).then(([message]) => message);
+      sendEncryptedMsg(pushSub, message),
+    ]).then(([msg]) => msg);
   }
 
   add_task(async function sendPushMessageFromPage() {
     var typedArray = new Uint8Array([226, 130, 40, 240, 40, 140, 188]);
     var json = { hello: "world" };
 
     var message = await waitForMessage(pushSubscription, "Text message from page");
     is(message.data.text, "Text message from page", "Wrong text message data");
@@ -164,21 +168,21 @@ http://creativecommons.org/licenses/publ
     });
     is(text, "Hi! \ud83d\udc40", "Wrong blob data for message with emoji");
 
     var finishedPromise = controlledFrame.waitOnWorkerMessage("finished");
     // Send a blank message.
     mockSocket.serverSendMsg(JSON.stringify({
       messageType: "notification",
       version: "vDummy",
-      channelID: channelID
+      channelID,
     }));
 
-    var message = await finishedPromise;
-    ok(!message.data, "Should exclude data for blank messages");
+    var msg = await finishedPromise;
+    ok(!msg.data, "Should exclude data for blank messages");
   });
 
   add_task(async function unsubscribe() {
     controlledFrame.remove();
     await pushSubscription.unsubscribe();
   });
 
   add_task(async function unregister() {
--- a/dom/push/test/test_error_reporting.html
+++ b/dom/push/test/test_error_reporting.html
@@ -19,36 +19,37 @@ http://creativecommons.org/licenses/publ
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* import-globals-from ./test_utils.js */
 
   var pushNotifier = SpecialPowers.Cc["@mozilla.org/push/Notifier;1"]
                                   .getService(SpecialPowers.Ci.nsIPushNotifier);
 
   var reporters = new Map();
 
   var registration;
   add_task(async function start() {
     await setupPrefsAndReplaceService({
       reportDeliveryError(messageId, reason) {
         ok(reporters.has(messageId),
-          'Unexpected error reported for message ' + messageId);
+          "Unexpected error reported for message " + messageId);
         var resolve = reporters.get(messageId);
         reporters.delete(messageId);
         resolve(reason);
       },
     });
     await setPushPermission(true);
 
-    var url = "error_worker.js" + "?" + (Math.random());
+    var url = "error_worker.js?" + (Math.random());
     registration = await navigator.serviceWorker.register(url, {scope: "."});
     await waitForActive(registration);
   });
 
   var controlledFrame;
   add_task(async function createControlledIFrame() {
     controlledFrame = await injectControlledFrame();
   });
@@ -73,25 +74,25 @@ http://creativecommons.org/licenses/publ
 
     reason = await waitForDeliveryError({ type: "rejection" });
     is(reason, SpecialPowers.Ci.nsIPushErrorReporter.DELIVERY_UNHANDLED_REJECTION,
       "Should report unhandled rejections");
   });
 
   add_task(async function reportDecryptionError() {
     var message = await new Promise(resolve => {
-      SpecialPowers.registerConsoleListener(message => {
-        if (!message.isScriptError && !message.isConsoleEvent) {
+      SpecialPowers.registerConsoleListener(msg => {
+        if (!msg.isScriptError && !msg.isConsoleEvent) {
           return;
         }
         const scope = "http://mochi.test:8888/tests/dom/push/test/";
-        if (message.innerWindowID === "ServiceWorker" &&
-            message.windowID === scope) {
+        if (msg.innerWindowID === "ServiceWorker" &&
+            msg.windowID === scope) {
           SpecialPowers.postConsoleSentinel();
-          resolve(message);
+          resolve(msg);
         }
       });
 
       var principal = SpecialPowers.wrap(document).nodePrincipal;
       pushNotifier.notifyError(registration.scope, principal, "Push error",
         SpecialPowers.Ci.nsIScriptError.errorFlag);
     });
 
--- a/dom/push/test/test_has_permissions.html
+++ b/dom/push/test/test_has_permissions.html
@@ -19,25 +19,28 @@ http://creativecommons.org/licenses/publ
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* import-globals-from ./test_utils.js */
 
   function debug(str) {
   // console.log(str + "\n");
   }
 
+  var registration;
+
   add_task(async function start() {
     await setupPrefsAndMockSocket(new MockWebSocket());
 
-    var url = "worker.js" + "?" + Math.random();
+    var url = "worker.js?" + Math.random();
     registration = await navigator.serviceWorker.register(url, {scope: "."});
     await waitForActive(registration);
   });
 
   add_task(async function hasPermission() {
     var state = await registration.pushManager.permissionState();
     debug("state: " + state);
     ok(["granted", "denied", "prompt"].includes(state), "permissionState() returned a valid state.");
--- a/dom/push/test/test_multiple_register.html
+++ b/dom/push/test/test_multiple_register.html
@@ -18,25 +18,28 @@ http://creativecommons.org/licenses/publ
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* import-globals-from ./test_utils.js */
 
   function debug(str) {
   //  console.log(str + "\n");
   }
 
+  var registration;
+
   function start() {
-    return navigator.serviceWorker.register("worker.js" + "?" + (Math.random()), {scope: "."})
+    return navigator.serviceWorker.register("worker.js?" + (Math.random()), {scope: "."})
     .then((swr) => {
-      registration = swr
+      registration = swr;
       return waitForActive(registration);
     });
   }
 
   function unregister() {
     return registration.unregister().then(function(result) {
       ok(result, "Unregister should return true.");
     }, function(e) {
@@ -44,17 +47,17 @@ http://creativecommons.org/licenses/publ
     });
   }
 
   function setupPushNotification(swr) {
     var p = new Promise(function(res, rej) {
       swr.pushManager.subscribe().then(
         function(pushSubscription) {
           ok(true, "successful registered for push notification");
-          res({swr: swr, pushSubscription: pushSubscription});
+          res({swr, pushSubscription});
         }, function(error) {
           ok(false, "could not register for push notification");
           res(null);
         }
         );
     });
     return p;
   }
--- a/dom/push/test/test_multiple_register_different_scope.html
+++ b/dom/push/test/test_multiple_register_different_scope.html
@@ -18,35 +18,36 @@ http://creativecommons.org/licenses/publ
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* import-globals-from ./test_utils.js */
 
   var scopeA = "./a/";
   var scopeB = "./b/";
 
   function debug(str) {
   //  console.log(str + "\n");
   }
 
   function registerServiceWorker(scope) {
-    return navigator.serviceWorker.register("worker.js" + "?" + (Math.random()), {scope: scope})
+    return navigator.serviceWorker.register("worker.js?" + (Math.random()), {scope})
       .then(swr => waitForActive(swr));
   }
 
   function unregister(swr) {
     return swr.unregister()
       .then(result => {
         ok(result, "Unregister should return true.");
       }, err => {
-        ok(false,"Unregistering the SW failed with " + err + "\n");
+        ok(false, "Unregistering the SW failed with " + err + "\n");
         throw err;
       });
   }
 
   function subscribe(swr) {
     return swr.pushManager.subscribe()
       .then(sub => {
         ok(true, "successful registered for push notification");
@@ -56,17 +57,17 @@ http://creativecommons.org/licenses/publ
         throw err;
       });
   }
 
 
   function setupMultipleSubscriptions(swr1, swr2) {
     return Promise.all([
       subscribe(swr1),
-      subscribe(swr2)
+      subscribe(swr2),
     ]).then(a => {
       ok(a[0].endpoint != a[1].endpoint, "setupMultipleSubscriptions - Got different endpoints.");
       return a;
     });
   }
 
   function getEndpointExpectNull(swr) {
     return swr.pushManager.getSubscription()
--- a/dom/push/test/test_multiple_register_during_service_activation.html
+++ b/dom/push/test/test_multiple_register_during_service_activation.html
@@ -20,23 +20,26 @@ http://creativecommons.org/licenses/publ
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* import-globals-from ./test_utils.js */
+
+  /* globals setupMockPushSocket,teardownMockPushSocket */
 
   function debug(str) {
   //  console.log(str + "\n");
   }
 
   function registerServiceWorker() {
-    return navigator.serviceWorker.register("worker.js" + "?" + (Math.random()), {scope: "."});
+    return navigator.serviceWorker.register("worker.js?" + (Math.random()), {scope: "."});
   }
 
   function unregister(swr) {
     return swr.unregister()
       .then(result => {
         ok(result, "Unregister should return true.");
       }, err => {
         dump("Unregistering the SW failed with " + err + "\n");
@@ -58,17 +61,17 @@ http://creativecommons.org/licenses/publ
   function setupMultipleSubscriptions(swr) {
     // We need to do this to restart service so that a queue will be formed.
     let promiseTeardown = teardownMockPushSocket();
     setupMockPushSocket(new MockWebSocket());
 
     var pushSubscription;
     return Promise.all([
       subscribe(swr),
-      subscribe(swr)
+      subscribe(swr),
     ]).then(a => {
       ok(a[0].endpoint == a[1].endpoint, "setupMultipleSubscriptions - Got the same endpoint back.");
       pushSubscription = a[0];
       return promiseTeardown;
     }).then(_ => {
       return pushSubscription;
     }, err => {
       ok(false, "could not register for push notification");
--- a/dom/push/test/test_permissions.html
+++ b/dom/push/test/test_permissions.html
@@ -19,27 +19,28 @@ http://creativecommons.org/licenses/publ
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* import-globals-from ./test_utils.js */
 
   function debug(str) {
   //  console.log(str + "\n");
   }
 
   var registration;
   add_task(async function start() {
     await setupPrefsAndMockSocket(new MockWebSocket());
     await setPushPermission(false);
 
-    var url = "worker.js" + "?" + Math.random();
+    var url = "worker.js?" + Math.random();
     registration = await navigator.serviceWorker.register(url, {scope: "."});
     await waitForActive(registration);
   });
 
   add_task(async function denySubscribe() {
     try {
       await registration.pushManager.subscribe();
       ok(false, "subscribe() should fail because no permission for push");
--- a/dom/push/test/test_register.html
+++ b/dom/push/test/test_register.html
@@ -19,42 +19,43 @@ http://creativecommons.org/licenses/publ
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* import-globals-from ./test_utils.js */
 
   function debug(str) {
   //  console.log(str + "\n");
   }
 
   var mockSocket = new MockWebSocket();
 
   var channelID = null;
 
   mockSocket.onRegister = function(request) {
     channelID = request.channelID;
     this.serverSendMsg(JSON.stringify({
       messageType: "register",
       uaid: "c69e2014-9e15-438d-b253-d79cc2df60a8",
       channelID,
       status: 200,
-      pushEndpoint: "https://example.com/endpoint/1"
+      pushEndpoint: "https://example.com/endpoint/1",
     }));
   };
 
   var registration;
   add_task(async function start() {
     await setupPrefsAndMockSocket(mockSocket);
     await setPushPermission(true);
 
-    var url = "worker.js" + "?" + (Math.random());
+    var url = "worker.js?" + (Math.random());
     registration = await navigator.serviceWorker.register(url, {scope: "."});
     await waitForActive(registration);
   });
 
   var controlledFrame;
   add_task(async function createControlledIFrame() {
     controlledFrame = await injectControlledFrame();
   });
@@ -83,17 +84,17 @@ http://creativecommons.org/licenses/publ
 
   add_task(async function waitForPushNotification() {
     var finishedPromise = controlledFrame.waitOnWorkerMessage("finished");
 
     // Send a blank message.
     mockSocket.serverSendMsg(JSON.stringify({
       messageType: "notification",
       version: "vDummy",
-      channelID: channelID
+      channelID,
     }));
 
     await finishedPromise;
   });
 
   add_task(async function unsubscribe() {
     controlledFrame.remove();
     await pushSubscription.unsubscribe();
--- a/dom/push/test/test_register_key.html
+++ b/dom/push/test/test_register_key.html
@@ -19,16 +19,17 @@ http://creativecommons.org/licenses/publ
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* import-globals-from ./test_utils.js */
 
   var isTestingMismatchedKey = false;
   var subscriptions = 0;
   var testKey; // Generated in `start`.
 
   function generateKey() {
     return crypto.subtle.generateKey({
       name: "ECDSA",
@@ -40,20 +41,22 @@ http://creativecommons.org/licenses/publ
 
   var registration;
   add_task(async function start() {
     await setupPrefsAndReplaceService({
       register(pageRecord) {
         ok(pageRecord.appServerKey.length > 0,
           "App server key should not be empty");
         if (pageRecord.appServerKey.length != 65) {
+          // eslint-disable-next-line no-throw-literal
           throw { result:
-                  SpecialPowers.Cr.NS_ERROR_DOM_PUSH_INVALID_KEY_ERR };
-        }
-        if (isTestingMismatchedKey) {
+            SpecialPowers.Cr.NS_ERROR_DOM_PUSH_INVALID_KEY_ERR };
+          }
+          if (isTestingMismatchedKey) {
+          // eslint-disable-next-line no-throw-literal
           throw { result:
                   SpecialPowers.Cr.NS_ERROR_DOM_PUSH_MISMATCHED_KEY_ERR };
         }
         return {
           endpoint: "https://example.com/push/" + (++subscriptions),
           appServerKey: pageRecord.appServerKey,
         };
       },
@@ -63,17 +66,17 @@ http://creativecommons.org/licenses/publ
           endpoint: "https://example.com/push/subWithKey",
           appServerKey: testKey,
         };
       },
     });
     await setPushPermission(true);
     testKey = await generateKey();
 
-    var url = "worker.js" + "?" + (Math.random());
+    var url = "worker.js?" + (Math.random());
     registration = await navigator.serviceWorker.register(url, {scope: "."});
     await waitForActive(registration);
   });
 
   var controlledFrame;
   add_task(async function createControlledIFrame() {
     controlledFrame = await injectControlledFrame();
   });
@@ -166,17 +169,17 @@ http://creativecommons.org/licenses/publ
     is(errorInfo.name, "InvalidAccessError",
       "Wrong exception name in worker for invalid key");
   });
 
   add_task(async function validKeyInWorker() {
     var key = await generateKey();
     var data = await sendRequestToWorker({
       type: "subscribeWithKey",
-      key: key,
+      key,
     });
     is(data.endpoint, "https://example.com/push/2",
       "Wrong endpoint for subscription with key created in worker");
     isDeeply(new Uint8Array(data.key), key,
       "Wrong app server key for subscription created in worker");
   });
 
   add_task(async function mismatchedKeyInWorker() {
--- a/dom/push/test/test_serviceworker_lifetime.html
+++ b/dom/push/test/test_serviceworker_lifetime.html
@@ -31,16 +31,17 @@
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* import-globals-from ./test_utils.js */
 
   function start() {
     return navigator.serviceWorker.register("lifetime_worker.js", {scope: "./"})
     .then((swr) => ({registration: swr}));
   }
 
   function waitForActiveServiceWorker(ctx) {
     return waitForActive(ctx.registration).then(function(result) {
@@ -77,67 +78,67 @@
   var channelID = null;
   mockSocket.onRegister = function(request) {
     channelID = request.channelID;
     this.serverSendMsg(JSON.stringify({
       messageType: "register",
       uaid: "fa8f2e4b-5ddc-4408-b1e3-5f25a02abff0",
       channelID,
       status: 200,
-      pushEndpoint: endpoint
+      pushEndpoint: endpoint,
     }));
   };
 
   function sendPushToPushServer(pushEndpoint) {
     is(pushEndpoint, endpoint, "Got unexpected endpoint");
     mockSocket.serverSendMsg(JSON.stringify({
       messageType: "notification",
       version: "vDummy",
-      channelID
+      channelID,
     }));
   }
 
   function unregisterPushNotification(ctx) {
     return ctx.subscription.unsubscribe().then(function(result) {
       ok(result, "unsubscribe should succeed.");
       ctx.subscription = null;
       return ctx;
     });
   }
 
   function createIframe(ctx) {
     var p = new Promise(function(res, rej) {
-      var iframe = document.createElement('iframe');
+      var iframe = document.createElement("iframe");
       // This file doesn't exist, the service worker will give us an empty
       // document.
       iframe.src = "http://mochi.test:8888/tests/dom/push/test/lifetime_frame.html";
 
       iframe.onload = function() {
         ctx.iframe = iframe;
         res(ctx);
-      }
+      };
       document.body.appendChild(iframe);
     });
     return p;
   }
 
   function closeIframe(ctx) {
     ctx.iframe.remove();
     return new Promise(function(res, rej) {
       // XXXcatalinb: give the worker more time to "notice" it stopped
       // controlling documents
       ctx.iframe = null;
       setTimeout(res, 0);
     }).then(() => ctx);
   }
 
   function waitAndCheckMessage(contentWindow, expected) {
-    function checkMessage(expected, resolve, event) {
-      ok(event.data.type == expected.type, "Received correct message type: " + expected.type);
-      ok(event.data.state == expected.state, "Service worker is in the correct state: " + expected.state);
+    function checkMessage({ type, state }, resolve, event) {
+      ok(event.data.type == type, "Received correct message type: " + type);
+      ok(event.data.state == state, "Service worker is in the correct state: " + state);
       this.navigator.serviceWorker.onmessage = null;
       resolve();
     }
     return new Promise(function(res, rej) {
       contentWindow.navigator.serviceWorker.onmessage =
         checkMessage.bind(contentWindow, expected, res);
     });
   }
@@ -169,47 +170,47 @@
     ctx.registration.active.postMessage(new_state);
     return p;
   }
 
   function checkStateAndUpdate(eventFunction, expected_state, new_state) {
     return function(ctx) {
       return eventFunction(ctx, expected_state, new_state)
         .then(() => ctx);
-    }
+    };
   }
 
   let shutdownTopic =
     SpecialPowers.getBoolPref("dom.serviceWorkers.parent_intercept", false) ?
       "specialpowers-service-worker-shutdown" :
       "service-worker-shutdown";
   SpecialPowers.registerObservers("service-worker-shutdown");
 
   function setShutdownObserver(expectingEvent) {
     info("Setting shutdown observer: expectingEvent=" + expectingEvent);
     return function(ctx) {
       cancelShutdownObserver(ctx);
 
       ctx.observer_promise = new Promise(function(res, rej) {
         ctx.observer = {
-          observe: function(subject, topic, data) {
+          observe(subject, topic, data) {
             ok((topic == shutdownTopic) && expectingEvent, "Service worker was terminated.");
             this.remove(ctx);
           },
-          remove: function(ctx) {
+          remove(context) {
             SpecialPowers.removeObserver(this, shutdownTopic);
-            ctx.observer = null;
-            res(ctx);
-          }
-        }
+            context.observer = null;
+            res(context);
+          },
+        };
         SpecialPowers.addObserver(ctx.observer, shutdownTopic);
       });
 
       return ctx;
-    }
+    };
   }
 
   function waitOnShutdownObserver(ctx) {
     info("Waiting on worker to shutdown.");
     return ctx.observer_promise;
   }
 
   function cancelShutdownObserver(ctx) {
@@ -220,32 +221,32 @@
   }
 
   function subTest(test) {
     return function(ctx) {
       return new Promise(function(res, rej) {
         function run() {
           test.steps(ctx).catch(function(e) {
             ok(false, "Some test failed with error: " + e);
-          }).then((ctx) => res(ctx));
+          }).then(res);
         }
 
-        SpecialPowers.pushPrefEnv({"set" : test.prefs}, run);
+        SpecialPowers.pushPrefEnv({"set": test.prefs}, run);
       });
-    }
+    };
   }
 
   var test1 = {
     prefs: [
       ["dom.serviceWorkers.idle_timeout", 0],
-      ["dom.serviceWorkers.idle_extended_timeout", 2999999]
+      ["dom.serviceWorkers.idle_extended_timeout", 2999999],
     ],
     // Test that service workers are terminated after the grace period expires
     // when there are no pending waitUntil or respondWith promises.
-    steps: function(ctx) {
+    steps(ctx) {
       // Test with fetch events and respondWith promises
       return createIframe(ctx)
         .then(setShutdownObserver(true))
         .then(checkStateAndUpdate(fetchEvent, "from_scope", "update"))
         .then(waitOnShutdownObserver)
         .then(setShutdownObserver(false))
         .then(checkStateAndUpdate(fetchEvent, "from_scope", "wait"))
         .then(checkStateAndUpdate(fetchEvent, "wait", "update"))
@@ -266,26 +267,26 @@
         .then(waitOnShutdownObserver)
         .then(setShutdownObserver(false))
         .then(checkStateAndUpdate(pushEvent, "from_scope", "wait"))
         .then(checkStateAndUpdate(messageEventIframe, "wait", "update"))
         .then(checkStateAndUpdate(messageEventIframe, "update", "update"))
         .then(setShutdownObserver(true))
         .then(checkStateAndUpdate(messageEventIframe, "update", "release"))
         .then(waitOnShutdownObserver)
-        .then(closeIframe)
-    }
-  }
+        .then(closeIframe);
+    },
+  };
 
   var test2 = {
     prefs: [
       ["dom.serviceWorkers.idle_timeout", 0],
-      ["dom.serviceWorkers.idle_extended_timeout", 2999999]
+      ["dom.serviceWorkers.idle_extended_timeout", 2999999],
     ],
-    steps: function(ctx) {
+    steps(ctx) {
       // Older versions used to terminate workers when the last controlled
       // window was closed.  This should no longer happen, though.  Verify
       // the new behavior.
       setShutdownObserver(true)(ctx);
       return createIframe(ctx)
         // Make sure we are shutdown before entering our "no shutdown" sequence
         // to avoid races.
         .then(waitOnShutdownObserver)
@@ -303,66 +304,66 @@
         // Make sure we are shutdown before entering our "no shutdown" sequence
         // to avoid races.
         .then(waitOnShutdownObserver)
         .then(setShutdownObserver(false))
         .then(checkStateAndUpdate(pushEvent, "from_scope", "wait"))
         .then(closeIframe)
         .then(setShutdownObserver(true))
         .then(checkStateAndUpdate(messageEvent, "wait", "release"))
-        .then(waitOnShutdownObserver)
-    }
+        .then(waitOnShutdownObserver);
+    },
   };
 
   var test3 = {
     prefs: [
       ["dom.serviceWorkers.idle_timeout", 2999999],
-      ["dom.serviceWorkers.idle_extended_timeout", 0]
+      ["dom.serviceWorkers.idle_extended_timeout", 0],
     ],
-    steps: function(ctx) {
+    steps(ctx) {
       // set the grace period to 0 and dispatch a message which will reset
       // the internal sw timer to the new value.
       var test3_1 = {
         prefs: [
           ["dom.serviceWorkers.idle_timeout", 0],
-          ["dom.serviceWorkers.idle_extended_timeout", 0]
+          ["dom.serviceWorkers.idle_extended_timeout", 0],
         ],
-        steps: function(ctx) {
-          return new Promise(function(res, rej) {
-            ctx.iframe.contentWindow.fetch("update");
-            res(ctx);
-          });
-        }
-      }
+        steps(context) {
+        return new Promise(function(res, rej) {
+          context.iframe.contentWindow.fetch("update");
+          res(context);
+        });
+      },
+      };
 
       // Test that service worker is closed when the extended timeout expired
       return createIframe(ctx)
         .then(setShutdownObserver(false))
         .then(checkStateAndUpdate(messageEvent, "from_scope", "update"))
         .then(checkStateAndUpdate(messageEventIframe, "update", "update"))
         .then(checkStateAndUpdate(fetchEvent, "update", "wait"))
         .then(setShutdownObserver(true))
         .then(subTest(test3_1)) // This should cause the internal timer to expire.
         .then(waitOnShutdownObserver)
-        .then(closeIframe)
-    }
-  }
+        .then(closeIframe);
+    },
+  };
 
   function runTest() {
     start()
       .then(waitForActiveServiceWorker)
       .then(registerPushNotification)
       .then(subTest(test1))
       .then(subTest(test2))
       .then(subTest(test3))
       .then(unregisterPushNotification)
       .then(unregister)
       .catch(function(e) {
-        ok(false, "Some test failed with error " + e)
+        ok(false, "Some test failed with error " + e);
       }).then(SimpleTest.finish);
   }
 
   setupPrefsAndMockSocket(mockSocket).then(_ => runTest());
-  SpecialPowers.addPermission('desktop-notification', true, document);
+  SpecialPowers.addPermission("desktop-notification", true, document);
   SimpleTest.waitForExplicitFinish();
 </script>
 </body>
 </html>
--- a/dom/push/test/test_subscription_change.html
+++ b/dom/push/test/test_subscription_change.html
@@ -19,23 +19,24 @@ http://creativecommons.org/licenses/publ
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* import-globals-from ./test_utils.js */
 
   var registration;
   add_task(async function start() {
     await setupPrefsAndMockSocket(new MockWebSocket());
     await setPushPermission(true);
 
-    var url = "worker.js" + "?" + (Math.random());
+    var url = "worker.js?" + (Math.random());
     registration = await navigator.serviceWorker.register(url, {scope: "."});
     await waitForActive(registration);
   });
 
   var controlledFrame;
   add_task(async function createControlledIFrame() {
     controlledFrame = await injectControlledFrame();
   });
@@ -43,17 +44,17 @@ http://creativecommons.org/licenses/publ
   add_task(async function togglePermission() {
     var subscription = await registration.pushManager.subscribe();
     ok(subscription, "Should create a push subscription");
 
     await setPushPermission(false);
     var permissionState = await registration.pushManager.permissionState();
     is(permissionState, "denied", "Should deny push permission");
 
-    var subscription = await registration.pushManager.getSubscription();
+    subscription = await registration.pushManager.getSubscription();
     is(subscription, null, "Should not return subscription when permission is revoked");
 
     var changePromise = controlledFrame.waitOnWorkerMessage("changed");
     await setPushPermission(true);
     await changePromise;
 
     subscription = await registration.pushManager.getSubscription();
     is(subscription, null, "Should drop subscription after reinstating permission");
--- a/dom/push/test/test_try_registering_offline_disabled.html
+++ b/dom/push/test/test_try_registering_offline_disabled.html
@@ -18,23 +18,25 @@ http://creativecommons.org/licenses/publ
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* eslint-env mozilla/frame-script */
+  /* import-globals-from ./test_utils.js */
 
   function debug(str) {
   //  console.log(str + "\n");
   }
 
   function registerServiceWorker() {
-    return navigator.serviceWorker.register("worker.js" + "?" + (Math.random()), {scope: "."})
+    return navigator.serviceWorker.register("worker.js?" + (Math.random()), {scope: "."})
       .then(swr => waitForActive(swr));
   }
 
   function unregister(swr) {
     return swr.unregister()
       .then(result => {
         ok(result, "Unregister should return true.");
       }, err => {
@@ -54,17 +56,17 @@ http://creativecommons.org/licenses/publ
       });
   }
 
   function subscribeFail(swr) {
     return new Promise((res, rej) => {
       swr.pushManager.subscribe()
         .then(sub => {
           ok(false, "successful registered for push notification");
-          throw "Should fail";
+          throw new Error("Should fail");
         }, err => {
           ok(true, "could not register for push notification");
           res(swr);
         });
     });
   }
 
   function getEndpointExpectNull(swr) {
@@ -85,101 +87,104 @@ http://creativecommons.org/licenses/publ
       }, err => {
           ok(false, "could not register for push notification");
           throw err;
       });
   }
 
   // Load chrome script to change offline status in the
   // parent process.
-  var chromeScript = SpecialPowers.loadChromeScript(_ => {
-    var ioService = Cc["@mozilla.org/network/io-service;1"]
-                      .getService(Ci.nsIIOService);
+  var offlineChromeScript = SpecialPowers.loadChromeScript(_ => {
     addMessageListener("change-status", function(offline) {
+      // eslint-disable-next-line mozilla/use-services
+      const ioService = Cc["@mozilla.org/network/io-service;1"]
+        .getService(Ci.nsIIOService);
       ioService.offline = offline;
     });
   });
 
   function offlineObserver(res) {
     this._res = res;
   }
   offlineObserver.prototype = {
     _res: null,
 
-    observe: function(subject, topic, data) {
-      debug("observe: " + subject + " " + topic + " " + data);
-      if (topic === "network:offline-status-changed") {
-        var obsService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
-                           .getService(SpecialPowers.Ci.nsIObserverService);
-        obsService.removeObserver(this, topic);
-        this._res(null);
-      }
+    observe(subject, topic, data) {
+    debug("observe: " + subject + " " + topic + " " + data);
+    if (topic === "network:offline-status-changed") {
+      // eslint-disable-next-line mozilla/use-services
+      const obsService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
+        .getService(SpecialPowers.Ci.nsIObserverService);
+      obsService.removeObserver(this, topic);
+      this._res(null);
     }
-  }
+  },
+  };
 
   function changeOfflineState(offline) {
     return new Promise(function(res, rej) {
-      var obsService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
-                         .getService(SpecialPowers.Ci.nsIObserverService);
+      // eslint-disable-next-line mozilla/use-services
+      const obsService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
+        .getService(SpecialPowers.Ci.nsIObserverService);
       obsService.addObserver(SpecialPowers.wrapCallbackObject(new offlineObserver(res)),
-                             "network:offline-status-changed");
-      chromeScript.sendAsyncMessage("change-status", offline);
+                               "network:offline-status-changed");
+      offlineChromeScript.sendAsyncMessage("change-status", offline);
     });
   }
 
   function changePushServerConnectionEnabled(enable) {
     debug("changePushServerConnectionEnabled");
     SpecialPowers.setBoolPref("dom.push.connection.enabled", enable);
   }
 
   function unsubscribe(sub) {
     return sub.unsubscribe()
-      .then(_ => {ok(true, "Unsubscribed!");});
+      .then(_ => { ok(true, "Unsubscribed!"); });
   }
 
   // go offline then go online
   function runTest1() {
     return registerServiceWorker()
     .then(swr =>
       getEndpointExpectNull(swr)
         .then(_ => changeOfflineState(true))
         .then(_ => subscribeFail(swr))
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => changeOfflineState(false))
         .then(_ => subscribe(swr))
         .then(sub => getEndpoint(swr, sub)
-          .then(sub => unsubscribe(sub))
+          .then(s => unsubscribe(s))
         )
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => unregister(swr))
     )
     .catch(err => {
       ok(false, "Some test failed with error " + err);
-    })
+    });
   }
 
   // disable - enable push connection.
   function runTest2() {
     return registerServiceWorker()
     .then(swr =>
       getEndpointExpectNull(swr)
         .then(_ => changePushServerConnectionEnabled(false))
         .then(_ => subscribeFail(swr))
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => changePushServerConnectionEnabled(true))
         .then(_ => subscribe(swr))
         .then(sub => getEndpoint(swr, sub)
-          .then(sub => unsubscribe(sub))
+          .then(s => unsubscribe(s))
         )
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => unregister(swr))
     )
     .catch(err => {
       ok(false, "Some test failed with error " + err);
-    })
+    });
   }
 
   // go offline - disable - enable - go online
   function runTest3() {
     return registerServiceWorker()
     .then(swr =>
       getEndpointExpectNull(swr)
         .then(_ => changeOfflineState(true))
@@ -189,24 +194,24 @@ http://creativecommons.org/licenses/publ
         .then(_ => subscribeFail(swr))
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => changePushServerConnectionEnabled(true))
         .then(_ => subscribeFail(swr))
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => changeOfflineState(false))
         .then(_ => subscribe(swr))
         .then(sub => getEndpoint(swr, sub)
-          .then(sub => unsubscribe(sub))
+          .then(s => unsubscribe(s))
         )
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => unregister(swr))
     )
     .catch(err => {
       ok(false, "Some test failed with error " + err);
-    })
+    });
   }
 
   // disable - offline - online - enable.
   function runTest4() {
     return registerServiceWorker()
     .then(swr =>
       getEndpointExpectNull(swr)
         .then(_ => changePushServerConnectionEnabled(false))
@@ -216,24 +221,24 @@ http://creativecommons.org/licenses/publ
         .then(_ => subscribeFail(swr))
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => changeOfflineState(false))
         .then(_ => subscribeFail(swr))
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => changePushServerConnectionEnabled(true))
         .then(_ => subscribe(swr))
         .then(sub => getEndpoint(swr, sub)
-          .then(sub => unsubscribe(sub))
+          .then(s => unsubscribe(s))
         )
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => unregister(swr))
     )
     .catch(err => {
       ok(false, "Some test failed with error " + err);
-    })
+    });
   }
 
   // go offline - disable - go online - enable
   function runTest5() {
     return registerServiceWorker()
     .then(swr =>
       getEndpointExpectNull(swr)
         .then(_ => changeOfflineState(true))
@@ -243,24 +248,24 @@ http://creativecommons.org/licenses/publ
         .then(_ => subscribeFail(swr))
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => changeOfflineState(false))
         .then(_ => subscribeFail(swr))
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => changePushServerConnectionEnabled(true))
         .then(_ => subscribe(swr))
         .then(sub => getEndpoint(swr, sub)
-          .then(sub => unsubscribe(sub))
+          .then(s => unsubscribe(s))
         )
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => unregister(swr))
     )
     .catch(err => {
       ok(false, "Some test failed with error " + err);
-    })
+    });
   }
 
   // disable - go offline - enable - go online.
   function runTest6() {
     return registerServiceWorker()
     .then(swr =>
       getEndpointExpectNull(swr)
         .then(_ => changePushServerConnectionEnabled(false))
@@ -270,24 +275,24 @@ http://creativecommons.org/licenses/publ
         .then(_ => subscribeFail(swr))
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => changePushServerConnectionEnabled(true))
         .then(_ => subscribeFail(swr))
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => changeOfflineState(false))
         .then(_ => subscribe(swr))
         .then(sub => getEndpoint(swr, sub)
-          .then(sub => unsubscribe(sub))
+          .then(s => unsubscribe(s))
         )
         .then(_ => getEndpointExpectNull(swr))
         .then(_ => unregister(swr))
     )
     .catch(err => {
       ok(false, "Some test failed with error " + err);
-    })
+    });
   }
 
   function runTest() {
     runTest1()
     .then(_ => runTest2())
     .then(_ => runTest3())
     .then(_ => runTest4())
     .then(_ => runTest5())
--- a/dom/push/test/test_unregister.html
+++ b/dom/push/test/test_unregister.html
@@ -19,19 +19,20 @@ http://creativecommons.org/licenses/publ
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="text/javascript">
+  /* import-globals-from ./test_utils.js */
 
   function generateURL() {
-    return "worker.js" + "?" + (Math.random());
+    return "worker.js?" + (Math.random());
   }
 
   var registration;
   add_task(async function start() {
     await setupPrefsAndMockSocket(new MockWebSocket());
     await setPushPermission(true);
 
     registration = await navigator.serviceWorker.register(
@@ -60,17 +61,17 @@ http://creativecommons.org/licenses/publ
     ok(pushSubscription, "Should create a new push subscription");
 
     var result = await registration.unregister();
     ok(result, "Should unregister the service worker");
 
     registration = await navigator.serviceWorker.register(
       generateURL(), {scope: "."});
     await waitForActive(registration);
-    var pushSubscription = await registration.pushManager.getSubscription();
+    pushSubscription = await registration.pushManager.getSubscription();
     ok(!pushSubscription,
       "Unregistering a service worker should drop its subscription");
   });
 
   add_task(async function unregister() {
     var result = await registration.unregister();
     ok(result, "Unregister should return true.");
   });
--- a/dom/push/test/test_utils.js
+++ b/dom/push/test/test_utils.js
@@ -1,173 +1,163 @@
-(function (g) {
-  "use strict";
+"use strict";
 
-  let url = SimpleTest.getTestFileURL("mockpushserviceparent.js");
-  let chromeScript = SpecialPowers.loadChromeScript(url);
+const url = SimpleTest.getTestFileURL("mockpushserviceparent.js");
+const chromeScript = SpecialPowers.loadChromeScript(url);
 
-  /**
-   * Replaces `PushService.jsm` with a mock implementation that handles requests
-   * from the DOM API. This allows tests to simulate local errors and error
-   * reporting, bypassing the `PushService.jsm` machinery.
-   */
-  async function replacePushService(mockService) {
-    chromeScript.addMessageListener("service-delivery-error", function(msg) {
-      mockService.reportDeliveryError(msg.messageId, msg.reason);
-    });
-    chromeScript.addMessageListener("service-request", function(msg) {
-      let promise;
-      try {
-        let handler = mockService[msg.name];
-        promise = Promise.resolve(handler(msg.params));
-      } catch (error) {
-        promise = Promise.reject(error);
-      }
-      promise.then(result => {
-        chromeScript.sendAsyncMessage("service-response", {
-          id: msg.id,
-          result: result,
-        });
-      }, error => {
-        chromeScript.sendAsyncMessage("service-response", {
-          id: msg.id,
-          error: error,
-        });
+/**
+ * Replaces `PushService.jsm` with a mock implementation that handles requests
+ * from the DOM API. This allows tests to simulate local errors and error
+ * reporting, bypassing the `PushService.jsm` machinery.
+ */
+async function replacePushService(mockService) {
+  chromeScript.addMessageListener("service-delivery-error", function(msg) {
+    mockService.reportDeliveryError(msg.messageId, msg.reason);
+  });
+  chromeScript.addMessageListener("service-request", function(msg) {
+    let promise;
+    try {
+      let handler = mockService[msg.name];
+      promise = Promise.resolve(handler(msg.params));
+    } catch (error) {
+      promise = Promise.reject(error);
+    }
+    promise.then(result => {
+      chromeScript.sendAsyncMessage("service-response", {
+        id: msg.id,
+        result,
+      });
+    }, error => {
+      chromeScript.sendAsyncMessage("service-response", {
+        id: msg.id,
+        error,
       });
     });
-    await new Promise(resolve => {
-      chromeScript.addMessageListener("service-replaced", function onReplaced() {
-        chromeScript.removeMessageListener("service-replaced", onReplaced);
-        resolve();
-      });
-      chromeScript.sendAsyncMessage("service-replace");
+  });
+  await new Promise(resolve => {
+    chromeScript.addMessageListener("service-replaced", function onReplaced() {
+      chromeScript.removeMessageListener("service-replaced", onReplaced);
+      resolve();
+    });
+    chromeScript.sendAsyncMessage("service-replace");
+  });
+}
+
+async function restorePushService() {
+  await new Promise(resolve => {
+    chromeScript.addMessageListener("service-restored", function onRestored() {
+      chromeScript.removeMessageListener("service-restored", onRestored);
+      resolve();
     });
-  }
+    chromeScript.sendAsyncMessage("service-restore");
+  });
+}
+
+let currentMockSocket = null;
 
-  async function restorePushService() {
-    await new Promise(resolve => {
-      chromeScript.addMessageListener("service-restored", function onRestored() {
-        chromeScript.removeMessageListener("service-restored", onRestored);
-        resolve();
-      });
-      chromeScript.sendAsyncMessage("service-restore");
+/**
+ * Sets up a mock connection for the WebSocket backend. This only replaces
+ * the transport layer; `PushService.jsm` still handles DOM API requests,
+ * observes permission changes, writes to IndexedDB, and notifies service
+ * workers of incoming push messages.
+ */
+function setupMockPushSocket(mockWebSocket) {
+  currentMockSocket = mockWebSocket;
+  currentMockSocket._isActive = true;
+  chromeScript.sendSyncMessage("socket-setup");
+  chromeScript.addMessageListener("socket-client-msg", function(msg) {
+    mockWebSocket.handleMessage(msg);
+  });
+}
+
+function teardownMockPushSocket() {
+  if (currentMockSocket) {
+    return new Promise(resolve => {
+      currentMockSocket._isActive = false;
+      chromeScript.addMessageListener("socket-server-teardown", resolve);
+      chromeScript.sendSyncMessage("socket-teardown");
     });
   }
-
-  let userAgentID = "8e1c93a9-139b-419c-b200-e715bb1e8ce8";
-
-  let currentMockSocket = null;
+  return Promise.resolve();
+}
 
-  /**
-   * Sets up a mock connection for the WebSocket backend. This only replaces
-   * the transport layer; `PushService.jsm` still handles DOM API requests,
-   * observes permission changes, writes to IndexedDB, and notifies service
-   * workers of incoming push messages.
-   */
-  function setupMockPushSocket(mockWebSocket) {
-    currentMockSocket = mockWebSocket;
-    currentMockSocket._isActive = true;
-    chromeScript.sendSyncMessage("socket-setup");
-    chromeScript.addMessageListener("socket-client-msg", function(msg) {
-      mockWebSocket.handleMessage(msg);
-    });
+/**
+ * Minimal implementation of web sockets for use in testing. Forwards
+ * messages to a mock web socket in the parent process that is used
+ * by the push service.
+ */
+class MockWebSocket {
+  // Default implementation to make the push server work minimally.
+  // Override methods to implement custom functionality.
+  constructor() {
+    this.userAgentID = "8e1c93a9-139b-419c-b200-e715bb1e8ce8";
+    this.registerCount = 0;
+    // We only allow one active mock web socket to talk to the parent.
+    // This flag is used to keep track of which mock web socket is active.
+    this._isActive = false;
   }
 
-  function teardownMockPushSocket() {
-    if (currentMockSocket) {
-      return new Promise(resolve => {
-        currentMockSocket._isActive = false;
-        chromeScript.addMessageListener("socket-server-teardown", resolve);
-        chromeScript.sendSyncMessage("socket-teardown");
-      });
-    }
-    return Promise.resolve();
+  onHello(request) {
+    this.serverSendMsg(JSON.stringify({
+      messageType: "hello",
+      uaid: this.userAgentID,
+      status: 200,
+      use_webpush: true,
+    }));
+  }
+
+  onRegister(request) {
+    this.serverSendMsg(JSON.stringify({
+      messageType: "register",
+      uaid: this.userAgentID,
+      channelID: request.channelID,
+      status: 200,
+      pushEndpoint: "https://example.com/endpoint/" + this.registerCount++,
+    }));
+  }
+
+  onUnregister(request) {
+    this.serverSendMsg(JSON.stringify({
+      messageType: "unregister",
+      channelID: request.channelID,
+      status: 200,
+    }));
   }
 
-  /**
-   * Minimal implementation of web sockets for use in testing. Forwards
-   * messages to a mock web socket in the parent process that is used
-   * by the push service.
-   */
-  function MockWebSocket() {}
-
-  let registerCount = 0;
-
-  // Default implementation to make the push server work minimally.
-  // Override methods to implement custom functionality.
-  MockWebSocket.prototype = {
-    // We only allow one active mock web socket to talk to the parent.
-    // This flag is used to keep track of which mock web socket is active.
-    _isActive: false,
-
-    onHello(request) {
-      this.serverSendMsg(JSON.stringify({
-        messageType: "hello",
-        uaid: userAgentID,
-        status: 200,
-        use_webpush: true,
-      }));
-    },
-
-    onRegister(request) {
-      this.serverSendMsg(JSON.stringify({
-        messageType: "register",
-        uaid: userAgentID,
-        channelID: request.channelID,
-        status: 200,
-        pushEndpoint: "https://example.com/endpoint/" + registerCount++
-      }));
-    },
+  onAck(request) {
+    // Do nothing.
+  }
 
-    onUnregister(request) {
-      this.serverSendMsg(JSON.stringify({
-        messageType: "unregister",
-        channelID: request.channelID,
-        status: 200,
-      }));
-    },
-
-    onAck(request) {
-      // Do nothing.
-    },
+  handleMessage(msg) {
+    let request = JSON.parse(msg);
+    let messageType = request.messageType;
+    switch (messageType) {
+    case "hello":
+      this.onHello(request);
+      break;
+    case "register":
+      this.onRegister(request);
+      break;
+    case "unregister":
+      this.onUnregister(request);
+      break;
+    case "ack":
+      this.onAck(request);
+      break;
+    default:
+      throw new Error("Unexpected message: " + messageType);
+    }
+  }
 
-    handleMessage(msg) {
-      let request = JSON.parse(msg);
-      let messageType = request.messageType;
-      switch (messageType) {
-      case "hello":
-        this.onHello(request);
-        break;
-      case "register":
-        this.onRegister(request);
-        break;
-      case "unregister":
-        this.onUnregister(request);
-        break;
-      case "ack":
-        this.onAck(request);
-        break;
-      default:
-        throw new Error("Unexpected message: " + messageType);
-      }
-    },
-
-    serverSendMsg(msg) {
-      if (this._isActive) {
-        chromeScript.sendAsyncMessage("socket-server-msg", msg);
-      }
-    },
-  };
-
-  g.MockWebSocket = MockWebSocket;
-  g.setupMockPushSocket = setupMockPushSocket;
-  g.teardownMockPushSocket = teardownMockPushSocket;
-  g.replacePushService = replacePushService;
-  g.restorePushService = restorePushService;
-}(this));
+  serverSendMsg(msg) {
+    if (this._isActive) {
+      chromeScript.sendAsyncMessage("socket-server-msg", msg);
+    }
+  }
+}
 
 // Remove permissions and prefs when the test finishes.
 SimpleTest.registerCleanupFunction(async function() {
   await new Promise(resolve => SpecialPowers.flushPermissions(resolve));
   await SpecialPowers.flushPrefEnv();
   await restorePushService();
   await teardownMockPushSocket();
 });
@@ -182,17 +172,17 @@ function setPushPermission(allow) {
 
 function setupPrefs() {
   return SpecialPowers.pushPrefEnv({"set": [
     ["dom.push.enabled", true],
     ["dom.push.connection.enabled", true],
     ["dom.push.maxRecentMessageIDsPerSubscription", 0],
     ["dom.serviceWorkers.exemptFromPerDomainMax", true],
     ["dom.serviceWorkers.enabled", true],
-    ["dom.serviceWorkers.testing.enabled", true]
+    ["dom.serviceWorkers.testing.enabled", true],
     ]});
 }
 
 async function setupPrefsAndReplaceService(mockService) {
   await replacePushService(mockService);
   await setupPrefs();
 }
 
@@ -236,45 +226,45 @@ function sendRequestToWorker(request) {
       registration.active.postMessage(request, [channel.port2]);
     });
   });
 }
 
 function waitForActive(swr) {
   let sw = swr.installing || swr.waiting || swr.active;
   return new Promise(resolve => {
-    if (sw.state === 'activated') {
+    if (sw.state === "activated") {
       resolve(swr);
       return;
     }
-    sw.addEventListener('statechange', function onStateChange(evt) {
-      if (sw.state === 'activated') {
-        sw.removeEventListener('statechange', onStateChange);
+    sw.addEventListener("statechange", function onStateChange(evt) {
+      if (sw.state === "activated") {
+        sw.removeEventListener("statechange", onStateChange);
         resolve(swr);
       }
     });
   });
 }
 
 function base64UrlDecode(s) {
-  s = s.replace(/-/g, '+').replace(/_/g, '/');
+  s = s.replace(/-/g, "+").replace(/_/g, "/");
 
   // Replace padding if it was stripped by the sender.
   // See http://tools.ietf.org/html/rfc4648#section-4
   switch (s.length % 4) {
     case 0:
       break; // No pad chars in this case
     case 2:
-      s += '==';
+      s += "==";
       break; // Two pad chars
     case 3:
-      s += '=';
+      s += "=";
       break; // One pad char
     default:
-      throw new Error('Illegal base64url string!');
+      throw new Error("Illegal base64url string!");
   }
 
   // With correct padding restored, apply the standard base64 decoder
   var decoded = atob(s);
 
   var array = new Uint8Array(new ArrayBuffer(decoded.length));
   for (var i = 0; i < decoded.length; i++) {
     array[i] = decoded.charCodeAt(i);
--- a/dom/push/test/webpush.js
+++ b/dom/push/test/webpush.js
@@ -7,184 +7,184 @@
  * Uses the WebCrypto API.
  *
  * Note that this test file uses the old, deprecated aesgcm128 encryption
  * scheme. PushCrypto.encrypt() exists and uses the later aes128gcm, but
  * there's no good reason to upgrade this at this time (and having mochitests
  * use PushCrypto directly is easier said than done.)
  */
 
-(function (g) {
-  'use strict';
+(function(g) {
+  "use strict";
 
   var P256DH = {
-    name: 'ECDH',
-    namedCurve: 'P-256'
+    name: "ECDH",
+    namedCurve: "P-256",
   };
   var webCrypto = g.crypto.subtle;
-  var ENCRYPT_INFO = new TextEncoder('utf-8').encode("Content-Encoding: aesgcm128");
-  var NONCE_INFO = new TextEncoder('utf-8').encode("Content-Encoding: nonce");
+  var ENCRYPT_INFO = new TextEncoder("utf-8").encode("Content-Encoding: aesgcm128");
+  var NONCE_INFO = new TextEncoder("utf-8").encode("Content-Encoding: nonce");
 
   function chunkArray(array, size) {
     var start = array.byteOffset || 0;
     array = array.buffer || array;
     var index = 0;
     var result = [];
-    while(index + size <= array.byteLength) {
+    while (index + size <= array.byteLength) {
       result.push(new Uint8Array(array, start + index, size));
       index += size;
     }
     if (index < array.byteLength) {
       result.push(new Uint8Array(array, start + index));
     }
     return result;
   }
 
   /* I can't believe that this is needed here, in this day and age ...
    * Note: these are not efficient, merely expedient.
    */
   var base64url = {
-    _strmap: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
-    encode: function(data) {
+    _strmap: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
+    encode(data) {
       data = new Uint8Array(data);
       var len = Math.ceil(data.length * 4 / 3);
       return chunkArray(data, 3).map(chunk => [
         chunk[0] >>> 2,
         ((chunk[0] & 0x3) << 4) | (chunk[1] >>> 4),
         ((chunk[1] & 0xf) << 2) | (chunk[2] >>> 6),
-        chunk[2] & 0x3f
-      ].map(v => base64url._strmap[v]).join('')).join('').slice(0, len);
+        chunk[2] & 0x3f,
+      ].map(v => base64url._strmap[v]).join("")).join("").slice(0, len);
     },
-    _lookup: function(s, i) {
+    _lookup(s, i) {
       return base64url._strmap.indexOf(s.charAt(i));
     },
-    decode: function(str) {
+    decode(str) {
       var v = new Uint8Array(Math.floor(str.length * 3 / 4));
       var vi = 0;
       for (var si = 0; si < str.length;) {
         var w = base64url._lookup(str, si++);
         var x = base64url._lookup(str, si++);
         var y = base64url._lookup(str, si++);
         var z = base64url._lookup(str, si++);
         v[vi++] = w << 2 | x >>> 4;
         v[vi++] = x << 4 | y >>> 2;
         v[vi++] = y << 6 | z;
       }
       return v;
-    }
+    },
   };
 
   g.base64url = base64url;
 
   /* Coerces data into a Uint8Array */
   function ensureView(data) {
-    if (typeof data === 'string') {
-      return new TextEncoder('utf-8').encode(data);
+    if (typeof data === "string") {
+      return new TextEncoder("utf-8").encode(data);
     }
     if (data instanceof ArrayBuffer) {
       return new Uint8Array(data);
     }
     if (ArrayBuffer.isView(data)) {
       return new Uint8Array(data.buffer);
     }
-    throw new Error('webpush() needs a string or BufferSource');
+    throw new Error("webpush() needs a string or BufferSource");
   }
 
   function bsConcat(arrays) {
     var size = arrays.reduce((total, a) => total + a.byteLength, 0);
     var index = 0;
     return arrays.reduce((result, a) => {
       result.set(new Uint8Array(a), index);
       index += a.byteLength;
       return result;
     }, new Uint8Array(size));
   }
 
   function hmac(key) {
-    this.keyPromise = webCrypto.importKey('raw', key, { name: 'HMAC', hash: 'SHA-256' },
-                                          false, ['sign']);
+    this.keyPromise = webCrypto.importKey("raw", key, { name: "HMAC", hash: "SHA-256" },
+                                          false, ["sign"]);
   }
   hmac.prototype.hash = function(input) {
-    return this.keyPromise.then(k => webCrypto.sign('HMAC', k, input));
+    return this.keyPromise.then(k => webCrypto.sign("HMAC", k, input));
   };
 
   function hkdf(salt, ikm) {
     this.prkhPromise = new hmac(salt).hash(ikm)
       .then(prk => new hmac(prk));
   }
 
   hkdf.prototype.generate = function(info, len) {
     var input = bsConcat([info, new Uint8Array([1])]);
     return this.prkhPromise
       .then(prkh => prkh.hash(input))
       .then(h => {
         if (h.byteLength < len) {
-          throw new Error('Length is too long');
+          throw new Error("Length is too long");
         }
         return h.slice(0, len);
       });
   };
 
   /* generate a 96-bit IV for use in GCM, 48-bits of which are populated */
   function generateNonce(base, index) {
     var nonce = base.slice(0, 12);
     for (var i = 0; i < 6; ++i) {
       nonce[nonce.length - 1 - i] ^= (index / Math.pow(256, i)) & 0xff;
     }
     return nonce;
   }
 
   function encrypt(localKey, remoteShare, salt, data) {
-    return webCrypto.importKey('raw', remoteShare, P256DH, false, ['deriveBits'])
+    return webCrypto.importKey("raw", remoteShare, P256DH, false, ["deriveBits"])
       .then(remoteKey =>
             webCrypto.deriveBits({ name: P256DH.name, public: remoteKey },
                                  localKey, 256))
       .then(rawKey => {
         var kdf = new hkdf(salt, rawKey);
         return Promise.all([
           kdf.generate(ENCRYPT_INFO, 16)
             .then(gcmBits =>
-                  webCrypto.importKey('raw', gcmBits, 'AES-GCM', false, ['encrypt'])),
-          kdf.generate(NONCE_INFO, 12)
+                  webCrypto.importKey("raw", gcmBits, "AES-GCM", false, ["encrypt"])),
+          kdf.generate(NONCE_INFO, 12),
         ]);
       })
       .then(([key, nonce]) => {
         if (data.byteLength === 0) {
           // Send an authentication tag for empty messages.
           return webCrypto.encrypt({
-            name: 'AES-GCM',
-            iv: generateNonce(nonce, 0)
+            name: "AES-GCM",
+            iv: generateNonce(nonce, 0),
           }, key, new Uint8Array([0])).then(value => [value]);
         }
         // 4096 is the default size, though we burn 1 for padding
         return Promise.all(chunkArray(data, 4095).map((slice, index) => {
           var padded = bsConcat([new Uint8Array([0]), slice]);
           return webCrypto.encrypt({
-            name: 'AES-GCM',
-            iv: generateNonce(nonce, index)
+            name: "AES-GCM",
+            iv: generateNonce(nonce, index),
           }, key, padded);
         }));
       }).then(bsConcat);
   }
 
   function webPushEncrypt(subscription, data) {
     data = ensureView(data);
 
     var salt = g.crypto.getRandomValues(new Uint8Array(16));
-    return webCrypto.generateKey(P256DH, false, ['deriveBits'])
+    return webCrypto.generateKey(P256DH, false, ["deriveBits"])
       .then(localKey => {
         return Promise.all([
           encrypt(localKey.privateKey, subscription.getKey("p256dh"), salt, data),
           // 1337 p-256 specific haxx to get the raw value out of the spki value
-          webCrypto.exportKey('raw', localKey.publicKey),
+          webCrypto.exportKey("raw", localKey.publicKey),
         ]);
       }).then(([payload, pubkey]) => {
         return {
           data: base64url.encode(payload),
-          encryption: 'keyid=p256dh;salt=' + base64url.encode(salt),
-          encryption_key: 'keyid=p256dh;dh=' + base64url.encode(pubkey),
-          encoding: 'aesgcm128'
+          encryption: "keyid=p256dh;salt=" + base64url.encode(salt),
+          encryption_key: "keyid=p256dh;dh=" + base64url.encode(pubkey),
+          encoding: "aesgcm128",
         };
       });
   }
 
   g.webPushEncrypt = webPushEncrypt;
 }(this));
--- a/dom/push/test/worker.js
+++ b/dom/push/test/worker.js
@@ -3,16 +3,18 @@
 
 // This worker is used for two types of tests. `handlePush` sends messages to
 // `frame.html`, which verifies that the worker can receive push messages.
 
 // `handleMessage` receives messages from `test_push_manager_worker.html`
 // and `test_data.html`, and verifies that `PushManager` can be used from
 // the worker.
 
+/* globals PushEvent */
+
 this.onpush = handlePush;
 this.onmessage = handleMessage;
 this.onpushsubscriptionchange = handlePushSubscriptionChange;
 
 function getJSON(data) {
   var result = {
     ok: false,
   };
@@ -46,17 +48,17 @@ function reply(event, promise) {
     event.ports[0].postMessage({
       error: String(error),
     });
   }));
 }
 
 function handlePush(event) {
   if (event instanceof PushEvent) {
-    if (!('data' in event)) {
+    if (!("data" in event)) {
       broadcast(event, {type: "finished", okay: "yes"});
       return;
     }
     var message = {
       type: "finished",
       okay: "yes",
     };
     if (event.data) {
--- a/dom/push/test/xpcshell/PushServiceHandler.js
+++ b/dom/push/test/xpcshell/PushServiceHandler.js
@@ -19,11 +19,11 @@ function PushServiceHandler() {
 
 PushServiceHandler.prototype = {
   classID: Components.ID("{bb7c5199-c0f7-4976-9f6d-1306e32c5591}"),
   QueryInterface: ChromeUtils.generateQI([]),
 
   observe(subject, topic, data) {
     this.observed.push({ subject, topic, data });
   },
-}
+};
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PushServiceHandler]);
--- a/dom/push/test/xpcshell/broadcast_handler.jsm
+++ b/dom/push/test/xpcshell/broadcast_handler.jsm
@@ -7,10 +7,10 @@ var broadcastHandler = {
     this.notifications = [];
 
     this.wasNotified = new Promise((resolve, reject) => {
       this.receivedBroadcastMessage = function() {
         resolve();
         this.notifications.push(Array.from(arguments));
       };
     });
-  }
+  },
 };
--- a/dom/push/test/xpcshell/head.js
+++ b/dom/push/test/xpcshell/head.js
@@ -1,37 +1,35 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-'use strict';
+"use strict";
 
-var {XPCOMUtils} = ChromeUtils.import('resource://gre/modules/XPCOMUtils.jsm');
-var {Services} = ChromeUtils.import('resource://gre/modules/Services.jsm');
-var {clearInterval, clearTimeout, setInterval, setIntervalWithTarget, setTimeout, setTimeoutWithTarget} = ChromeUtils.import('resource://gre/modules/Timer.jsm');
-var {Preferences} = ChromeUtils.import('resource://gre/modules/Preferences.jsm');
-var {PlacesUtils} = ChromeUtils.import('resource://gre/modules/PlacesUtils.jsm');
-var {ObjectUtils} = ChromeUtils.import('resource://gre/modules/ObjectUtils.jsm');
+var {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+var {clearInterval, clearTimeout, setInterval, setIntervalWithTarget, setTimeout, setTimeoutWithTarget} = ChromeUtils.import("resource://gre/modules/Timer.jsm");
+var {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm");
+var {PlacesUtils} = ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
+var {ObjectUtils} = ChromeUtils.import("resource://gre/modules/ObjectUtils.jsm");
 
-ChromeUtils.defineModuleGetter(this, 'PlacesTestUtils',
-                               'resource://testing-common/PlacesTestUtils.jsm');
-ChromeUtils.defineModuleGetter(this, 'pushBroadcastService',
-                               'resource://gre/modules/PushBroadcastService.jsm', {});
-XPCOMUtils.defineLazyServiceGetter(this, 'PushServiceComponent',
-                                   '@mozilla.org/push/Service;1', 'nsIPushService');
+ChromeUtils.defineModuleGetter(this, "PlacesTestUtils",
+                               "resource://testing-common/PlacesTestUtils.jsm");
+ChromeUtils.defineModuleGetter(this, "pushBroadcastService",
+                               "resource://gre/modules/PushBroadcastService.jsm", {});
+XPCOMUtils.defineLazyServiceGetter(this, "PushServiceComponent",
+                                   "@mozilla.org/push/Service;1", "nsIPushService");
 
 const serviceExports = ChromeUtils.import("resource://gre/modules/PushService.jsm", null);
-const servicePrefs = new Preferences('dom.push.');
+const servicePrefs = new Preferences("dom.push.");
 
 const WEBSOCKET_CLOSE_GOING_AWAY = 1001;
 
 const MS_IN_ONE_DAY = 24 * 60 * 60 * 1000;
 
-var isParent = Cc['@mozilla.org/xre/runtime;1']
-                 .getService(Ci.nsIXULRuntime).processType ==
-                 Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+var isParent = Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
 
 // Stop and clean up after the PushService.
 Services.obs.addObserver(function observe(subject, topic, data) {
   Services.obs.removeObserver(observe, topic);
   serviceExports.PushService.uninit();
   // Occasionally, `profile-change-teardown` and `xpcom-shutdown` will fire
   // before the PushService and AlarmService finish writing to IndexedDB. This
   // causes spurious errors and crashes, so we spin the event loop to let the
@@ -41,30 +39,30 @@ Services.obs.addObserver(function observ
   let thread = Services.tm.mainThread;
   while (!done) {
     try {
       thread.processNextEvent(true);
     } catch (e) {
       Cu.reportError(e);
     }
   }
-}, 'profile-change-net-teardown');
+}, "profile-change-net-teardown");
 
 /**
  * Gates a function so that it is called only after the wrapper is called a
  * given number of times.
  *
  * @param {Number} times The number of wrapper calls before |func| is called.
  * @param {Function} func The function to gate.
  * @returns {Function} The gated function wrapper.
  */
 function after(times, func) {
   return function afterFunc() {
     if (--times <= 0) {
-      return func.apply(this, arguments);
+      func.apply(this, arguments);
     }
   };
 }
 
 /**
  * Defers one or more callbacks until the next turn of the event loop. Multiple
  * callbacks are executed in order.
  *
@@ -80,22 +78,22 @@ function waterfall(...callbacks) {
 /**
  * Waits for an observer notification to fire.
  *
  * @param {String} topic The notification topic.
  * @returns {Promise} A promise that fulfills when the notification is fired.
  */
 function promiseObserverNotification(topic, matchFunc) {
   return new Promise((resolve, reject) => {
-    Services.obs.addObserver(function observe(subject, topic, data) {
-      let matches = typeof matchFunc != 'function' || matchFunc(subject, data);
+    Services.obs.addObserver(function observe(subject, aTopic, data) {
+      let matches = typeof matchFunc != "function" || matchFunc(subject, data);
       if (!matches) {
         return;
       }
-      Services.obs.removeObserver(observe, topic);
+      Services.obs.removeObserver(observe, aTopic);
       resolve({subject, data});
     }, topic);
   });
 }
 
 /**
  * Wraps an object in a proxy that traps property gets and returns stubs. If
  * the stub is a function, the original value will be passed as the first
@@ -103,67 +101,70 @@ function promiseObserverNotification(top
  * that calls the stub; otherwise, the stub is called as a getter.
  *
  * @param {Object} target The object to wrap.
  * @param {Object} stubs An object containing stubbed values and functions.
  * @returns {Proxy} A proxy that returns stubs for property gets.
  */
 function makeStub(target, stubs) {
   return new Proxy(target, {
-    get(target, property) {
-      if (!stubs || typeof stubs != 'object' || !(property in stubs)) {
-        return target[property];
+    get(aTarget, property) {
+      if (!stubs || typeof stubs != "object" || !(property in stubs)) {
+        return aTarget[property];
       }
       let stub = stubs[property];
-      if (typeof stub != 'function') {
+      if (typeof stub != "function") {
         return stub;
       }
-      let original = target[property];
-      if (typeof original != 'function') {
+      let original = aTarget[property];
+      if (typeof original != "function") {
         return stub.call(this, original);
       }
       return function callStub(...params) {
         return stub.call(this, original, ...params);
       };
-    }
+    },
   });
 }
 
 /**
  * Sets default PushService preferences. All pref names are prefixed with
  * `dom.push.`; any additional preferences will override the defaults.
  *
  * @param {Object} [prefs] Additional preferences to set.
  */
 function setPrefs(prefs = {}) {
   let defaultPrefs = Object.assign({
-    loglevel: 'all',
-    serverURL: 'wss://push.example.org',
-    'connection.enabled': true,
-    userAgentID: '',
+    loglevel: "all",
+    serverURL: "wss://push.example.org",
+    "connection.enabled": true,
+    userAgentID: "",
     enabled: true,
     // Defaults taken from /modules/libpref/init/all.js.
     requestTimeout: 10000,
     retryBaseInterval: 5000,
     pingInterval: 30 * 60 * 1000,
     // Misc. defaults.
-    'http2.maxRetries': 2,
-    'http2.retryInterval': 500,
-    'http2.reset_retry_count_after_ms': 60000,
+    "http2.maxRetries": 2,
+    "http2.retryInterval": 500,
+    "http2.reset_retry_count_after_ms": 60000,
     maxQuotaPerSubscription: 16,
     quotaUpdateDelay: 3000,
-    'testing.notifyWorkers': false,
+    "testing.notifyWorkers": false,
   }, prefs);
   for (let pref in defaultPrefs) {
     servicePrefs.set(pref, defaultPrefs[pref]);
   }
 }
 
 function compareAscending(a, b) {
-  return a > b ? 1 : a < b ? -1 : 0;
+  if (a > b) {
+    return 1;
+  }
+  return a < b ? -1 : 0;
 }
 
 /**
  * Creates a mock WebSocket object that implements a subset of the
  * nsIWebSocketChannel interface used by the PushService.
  *
  * The given protocol handlers are invoked for each Simple Push command sent
  * by the PushService. The ping handler is optional; all others will throw if
@@ -210,70 +211,70 @@ MockWebSocket.prototype = {
   asyncOpen(uri, origin, windowId, listener, context) {
     this._listener = listener;
     this._context = context;
     waterfall(() => this._listener.onStart(this._context));
   },
 
   _handleMessage(msg) {
     let messageType, request;
-    if (msg == '{}') {
+    if (msg == "{}") {
       request = {};
-      messageType = 'ping';
+      messageType = "ping";
     } else {
       request = JSON.parse(msg);
       messageType = request.messageType;
     }
     switch (messageType) {
-    case 'hello':
-      if (typeof this._onHello != 'function') {
-        throw new Error('Unexpected handshake request');
+    case "hello":
+      if (typeof this._onHello != "function") {
+        throw new Error("Unexpected handshake request");
       }
       this._onHello(request);
       break;
 
-    case 'register':
-      if (typeof this._onRegister != 'function') {
-        throw new Error('Unexpected register request');
+    case "register":
+      if (typeof this._onRegister != "function") {
+        throw new Error("Unexpected register request");
       }
       this._onRegister(request);
       break;
 
-    case 'unregister':
-      if (typeof this._onUnregister != 'function') {
-        throw new Error('Unexpected unregister request');
+    case "unregister":
+      if (typeof this._onUnregister != "function") {
+        throw new Error("Unexpected unregister request");
       }
       this._onUnregister(request);
       break;
 
-    case 'ack':
-      if (typeof this._onACK != 'function') {
-        throw new Error('Unexpected acknowledgement');
+    case "ack":
+      if (typeof this._onACK != "function") {
+        throw new Error("Unexpected acknowledgement");
       }
       this._onACK(request);
       break;
 
-    case 'ping':
-      if (typeof this._onPing == 'function') {
+    case "ping":
+      if (typeof this._onPing == "function") {
         this._onPing(request);
       } else {
         // Echo ping packets.
-        this.serverSendMsg('{}');
+        this.serverSendMsg("{}");
       }
       break;
 
-    case 'broadcast_subscribe':
-      if (typeof this._onBroadcastSubscribe != 'function') {
-        throw new Error('Unexpected broadcast_subscribe');
+    case "broadcast_subscribe":
+      if (typeof this._onBroadcastSubscribe != "function") {
+        throw new Error("Unexpected broadcast_subscribe");
       }
       this._onBroadcastSubscribe(request);
       break;
 
     default:
-      throw new Error('Unexpected message: ' + messageType);
+      throw new Error("Unexpected message: " + messageType);
     }
   },
 
   sendMsg(msg) {
     this._handleMessage(msg);
   },
 
   close(code, reason) {
@@ -283,33 +284,33 @@ MockWebSocket.prototype = {
   /**
    * Responds with the given message, calling onMessageAvailable() and
    * onAcknowledge() synchronously. Throws if the message is not a string.
    * Used by the tests to respond to client commands.
    *
    * @param {String} msg The message to send to the client.
    */
   serverSendMsg(msg) {
-    if (typeof msg != 'string') {
-      throw new Error('Invalid response message');
+    if (typeof msg != "string") {
+      throw new Error("Invalid response message");
     }
     waterfall(
       () => this._listener.onMessageAvailable(this._context, msg),
       () => this._listener.onAcknowledge(this._context, 0)
     );
   },
 
   /**
    * Closes the server end of the connection, calling onServerClose()
    * followed by onStop(). Used to test abrupt connection termination.
    *
    * @param {Number} [statusCode] The WebSocket connection close code.
    * @param {String} [reason] The connection close reason.
    */
-  serverClose(statusCode, reason = '') {
+  serverClose(statusCode, reason = "") {
     if (!isFinite(statusCode)) {
       statusCode = WEBSOCKET_CLOSE_GOING_AWAY;
     }
     waterfall(
       () => this._listener.onServerClose(this._context, statusCode, reason),
       () => this._listener.onStop(this._context, Cr.NS_BASE_STREAM_CLOSED)
     );
   },
@@ -319,139 +320,139 @@ MockWebSocket.prototype = {
   },
 };
 
 var setUpServiceInParent = async function(service, db) {
   if (!isParent) {
     return;
   }
 
-  let userAgentID = 'ce704e41-cb77-4206-b07b-5bf47114791b';
+  let userAgentID = "ce704e41-cb77-4206-b07b-5bf47114791b";
   setPrefs({
-    userAgentID: userAgentID,
+    userAgentID,
   });
 
   await db.put({
-    channelID: '6e2814e1-5f84-489e-b542-855cc1311f09',
-    pushEndpoint: 'https://example.org/push/get',
-    scope: 'https://example.com/get/ok',
-    originAttributes: '',
+    channelID: "6e2814e1-5f84-489e-b542-855cc1311f09",
+    pushEndpoint: "https://example.org/push/get",
+    scope: "https://example.com/get/ok",
+    originAttributes: "",
     version: 1,
     pushCount: 10,
     lastPush: 1438360548322,
     quota: 16,
   });
   await db.put({
-    channelID: '3a414737-2fd0-44c0-af05-7efc172475fc',
-    pushEndpoint: 'https://example.org/push/unsub',
-    scope: 'https://example.com/unsub/ok',
-    originAttributes: '',
+    channelID: "3a414737-2fd0-44c0-af05-7efc172475fc",
+    pushEndpoint: "https://example.org/push/unsub",
+    scope: "https://example.com/unsub/ok",
+    originAttributes: "",
     version: 2,
     pushCount: 10,
     lastPush: 1438360848322,
     quota: 4,
   });
   await db.put({
-    channelID: 'ca3054e8-b59b-4ea0-9c23-4a3c518f3161',
-    pushEndpoint: 'https://example.org/push/stale',
-    scope: 'https://example.com/unsub/fail',
-    originAttributes: '',
+    channelID: "ca3054e8-b59b-4ea0-9c23-4a3c518f3161",
+    pushEndpoint: "https://example.org/push/stale",
+    scope: "https://example.com/unsub/fail",
+    originAttributes: "",
     version: 3,
     pushCount: 10,
     lastPush: 1438362348322,
     quota: 1,
   });
 
   service.init({
-    serverURI: 'wss://push.example.org/',
+    serverURI: "wss://push.example.org/",
     db: makeStub(db, {
       put(prev, record) {
-        if (record.scope == 'https://example.com/sub/fail') {
-          return Promise.reject('synergies not aligned');
+        if (record.scope == "https://example.com/sub/fail") {
+          return Promise.reject("synergies not aligned");
         }
         return prev.call(this, record);
       },
-      delete: function(prev, channelID) {
-        if (channelID == 'ca3054e8-b59b-4ea0-9c23-4a3c518f3161') {
-          return Promise.reject('splines not reticulated');
+      delete(prev, channelID) {
+        if (channelID == "ca3054e8-b59b-4ea0-9c23-4a3c518f3161") {
+          return Promise.reject("splines not reticulated");
         }
         return prev.call(this, channelID);
       },
       getByIdentifiers(prev, identifiers) {
-        if (identifiers.scope == 'https://example.com/get/fail') {
-          return Promise.reject('qualia unsynchronized');
+        if (identifiers.scope == "https://example.com/get/fail") {
+          return Promise.reject("qualia unsynchronized");
         }
         return prev.call(this, identifiers);
       },
     }),
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(request) {
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             uaid: userAgentID,
             status: 200,
           }));
         },
         onRegister(request) {
           if (request.key) {
             let appServerKey = new Uint8Array(
               ChromeUtils.base64URLDecode(request.key, {
                 padding: "require",
               })
             );
-            equal(appServerKey.length, 65, 'Wrong app server key length');
-            equal(appServerKey[0], 4, 'Wrong app server key format');
+            equal(appServerKey.length, 65, "Wrong app server key length");
+            equal(appServerKey[0], 4, "Wrong app server key format");
           }
           this.serverSendMsg(JSON.stringify({
-            messageType: 'register',
+            messageType: "register",
             uaid: userAgentID,
             channelID: request.channelID,
             status: 200,
-            pushEndpoint: 'https://example.org/push/' + request.channelID,
+            pushEndpoint: "https://example.org/push/" + request.channelID,
           }));
         },
         onUnregister(request) {
           this.serverSendMsg(JSON.stringify({
-            messageType: 'unregister',
+            messageType: "unregister",
             channelID: request.channelID,
             status: 200,
           }));
         },
       });
     },
   });
 };
 
 var tearDownServiceInParent = async function(db) {
   if (!isParent) {
     return;
   }
 
   let record = await db.getByIdentifiers({
-    scope: 'https://example.com/sub/ok',
-    originAttributes: '',
+    scope: "https://example.com/sub/ok",
+    originAttributes: "",
   });
-  ok(record.pushEndpoint.startsWith('https://example.org/push'),
-    'Wrong push endpoint in subscription record');
+  ok(record.pushEndpoint.startsWith("https://example.org/push"),
+    "Wrong push endpoint in subscription record");
 
-  record = await db.getByKeyID('3a414737-2fd0-44c0-af05-7efc172475fc');
-  ok(!record, 'Unsubscribed record should not exist');
+  record = await db.getByKeyID("3a414737-2fd0-44c0-af05-7efc172475fc");
+  ok(!record, "Unsubscribed record should not exist");
 };
 
 function putTestRecord(db, keyID, scope, quota) {
   return db.put({
     channelID: keyID,
-    pushEndpoint: 'https://example.org/push/' + keyID,
-    scope: scope,
+    pushEndpoint: "https://example.org/push/" + keyID,
+    scope,
     pushCount: 0,
     lastPush: 0,
     version: null,
-    originAttributes: '',
-    quota: quota,
+    originAttributes: "",
+    quota,
     systemRecord: quota == Infinity,
   });
 }
 
 function getAllKeyIDs(db) {
   return db.getAllKeyIDs().then(records =>
     records.map(record => record.keyID).sort(compareAscending)
   );
--- a/dom/push/test/xpcshell/test_broadcast_success.js
+++ b/dom/push/test/xpcshell/test_broadcast_success.js
@@ -1,52 +1,52 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-'use strict';
+"use strict";
 
 const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
 const {BroadcastService} = ChromeUtils.import("resource://gre/modules/PushBroadcastService.jsm", null);
 const {JSONFile} = ChromeUtils.import("resource://gre/modules/JSONFile.jsm");
 
 const {FileTestUtils} = ChromeUtils.import("resource://testing-common/FileTestUtils.jsm");
 const {broadcastHandler} = ChromeUtils.import("resource://test/broadcast_handler.jsm");
 
 const broadcastService = pushBroadcastService;
 const assert = Assert;
-const userAgentID = 'bd744428-f125-436a-b6d0-dd0c9845837f';
-const channelID = '0ef2ad4a-6c49-41ad-af6e-95d2425276bf';
+const userAgentID = "bd744428-f125-436a-b6d0-dd0c9845837f";
+const channelID = "0ef2ad4a-6c49-41ad-af6e-95d2425276bf";
 
 function run_test() {
   do_get_profile();
   setPrefs({
     userAgentID,
     alwaysConnect: true,
     requestTimeout: 1000,
-    retryBaseInterval: 150
+    retryBaseInterval: 150,
   });
   run_next_test();
 }
 
 function getPushServiceMock() {
   return {
     subscribed: [],
-    subscribeBroadcast: function(broadcastId, version) {
+    subscribeBroadcast(broadcastId, version) {
       this.subscribed.push([broadcastId, version]);
     },
   };
 }
 
 add_task(async function test_register_success() {
   await broadcastService._resetListeners();
   let db = PushServiceWebSocket.newPushDB();
   broadcastHandler.reset();
   let notifications = broadcastHandler.notifications;
   let socket;
-  registerCleanupFunction(() => {return db.drop().then(_ => db.close());});
+  registerCleanupFunction(() => { return db.drop().then(_ => db.close()); });
 
   await broadcastService.addListener("broadcast-test", "2018-02-01", {
     moduleURI: "resource://test/broadcast_handler.jsm",
     symbolName: "broadcastHandler",
   });
 
   PushServiceWebSocket._generateID = () => channelID;
 
@@ -55,226 +55,224 @@ add_task(async function test_register_su
   await PushService.init({
     serverURI: "wss://push.example.org/",
     db,
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(data) {
           socket = this;
           deepEqual(data.broadcasts, {"broadcast-test": "2018-02-01"}, "Handshake: doesn't consult listeners");
-          equal(data.messageType, 'hello', 'Handshake: wrong message type');
-          equal(data.uaid, userAgentID, 'Handshake: wrong device ID');
+          equal(data.messageType, "hello", "Handshake: wrong message type");
+          equal(data.uaid, userAgentID, "Handshake: wrong device ID");
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             status: 200,
-            uaid: userAgentID
+            uaid: userAgentID,
           }));
         },
 
         onBroadcastSubscribe(data) {
           broadcastSubscriptions.push(data);
         },
       });
-    }
-  })
+    },
+  });
 
   socket.serverSendMsg(JSON.stringify({
     messageType: "broadcast",
     broadcasts: {
-      "broadcast-test": "2018-03-02"
-    }
+      "broadcast-test": "2018-03-02",
+    },
   }));
 
   await broadcastHandler.wasNotified;
 
   deepEqual(notifications, [["2018-03-02", "broadcast-test"]], "Broadcast notification didn't get delivered");
 
   deepEqual(await broadcastService.getListeners(), {
-    "broadcast-test": "2018-03-02"
+    "broadcast-test": "2018-03-02",
   }, "Broadcast version wasn't updated");
 
   await broadcastService.addListener("example-listener", "2018-03-01", {
     moduleURI: "resource://gre/modules/not-real-example.jsm",
-    symbolName: "doesntExist"
+    symbolName: "doesntExist",
   });
 
   deepEqual(broadcastSubscriptions, [{
     messageType: "broadcast_subscribe",
-    broadcasts: {"example-listener": "2018-03-01"}
+    broadcasts: {"example-listener": "2018-03-01"},
   }]);
 });
 
 add_task(async function test_handle_hello_broadcasts() {
   PushService.uninit();
   await broadcastService._resetListeners();
   let db = PushServiceWebSocket.newPushDB();
   broadcastHandler.reset();
   let notifications = broadcastHandler.notifications;
-  registerCleanupFunction(() => {return db.drop().then(_ => db.close());});
+  registerCleanupFunction(() => { return db.drop().then(_ => db.close()); });
 
   await broadcastService.addListener("broadcast-test", "2018-02-01", {
     moduleURI: "resource://test/broadcast_handler.jsm",
     symbolName: "broadcastHandler",
   });
 
   PushServiceWebSocket._generateID = () => channelID;
 
   await PushService.init({
     serverURI: "wss://push.example.org/",
     db,
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(data) {
           deepEqual(data.broadcasts, {"broadcast-test": "2018-02-01"}, "Handshake: doesn't consult listeners");
-          equal(data.messageType, 'hello', 'Handshake: wrong message type');
-          equal(data.uaid, userAgentID, 'Handshake: wrong device ID');
+          equal(data.messageType, "hello", "Handshake: wrong message type");
+          equal(data.uaid, userAgentID, "Handshake: wrong device ID");
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             status: 200,
             uaid: userAgentID,
             broadcasts: {
-              "broadcast-test": "2018-02-02"
-            }
+              "broadcast-test": "2018-02-02",
+            },
           }));
         },
 
-        onBroadcastSubscribe(data) {
-          broadcastSubscriptions.push(data);
-        },
+        onBroadcastSubscribe(data) {},
       });
-    }
-  })
+    },
+  });
 
   await broadcastHandler.wasNotified;
 
   deepEqual(notifications, [["2018-02-02", "broadcast-test"]], "Broadcast notification on hello was delivered");
 
   deepEqual(await broadcastService.getListeners(), {
-    "broadcast-test": "2018-02-02"
+    "broadcast-test": "2018-02-02",
   }, "Broadcast version wasn't updated");
 });
 
 add_task(async function test_broadcast_unit() {
   const fakeListenersData = {
     "abc": {
       version: "2018-03-04",
       sourceInfo: {
         moduleURI: "resource://gre/modules/abc.jsm",
-        symbolName: "getAbc"
-      }
+        symbolName: "getAbc",
+      },
     },
     "def": {
       version: "2018-04-05",
       sourceInfo: {
         moduleURI: "resource://gre/modules/def.jsm",
-        symbolName: "getDef"
-      }
-    }
+        symbolName: "getDef",
+      },
+    },
   };
   const path = FileTestUtils.getTempFile("broadcast-listeners.json").path;
 
   const jsonFile = new JSONFile({path});
   jsonFile.data = {
     listeners: fakeListenersData,
   };
   await jsonFile._save();
 
   const pushServiceMock = getPushServiceMock();
 
-  const broadcastService = new BroadcastService(pushServiceMock, path);
-  const listeners = await broadcastService.getListeners();
+  const mockBroadcastService = new BroadcastService(pushServiceMock, path);
+  const listeners = await mockBroadcastService.getListeners();
   deepEqual(listeners, {
     "abc": "2018-03-04",
-    "def": "2018-04-05"
+    "def": "2018-04-05",
   });
 
-  await broadcastService.addListener("ghi", "2018-05-06", {
+  await mockBroadcastService.addListener("ghi", "2018-05-06", {
     moduleURI: "resource://gre/modules/ghi.jsm",
-    symbolName: "getGhi"
+    symbolName: "getGhi",
   });
 
   deepEqual(pushServiceMock.subscribed, [
-    ["ghi", "2018-05-06"]
+    ["ghi", "2018-05-06"],
   ]);
 
-  await broadcastService._saveImmediately();
+  await mockBroadcastService._saveImmediately();
 
   const newJSONFile = new JSONFile({path});
   await newJSONFile.load();
 
   deepEqual(newJSONFile.data, {
     listeners: {
       ...fakeListenersData,
       ghi: {
         version: "2018-05-06",
         sourceInfo: {
           moduleURI: "resource://gre/modules/ghi.jsm",
-          symbolName: "getGhi"
-        }
-      }
+          symbolName: "getGhi",
+        },
+      },
     },
     version: 1,
   });
 
-  deepEqual(await broadcastService.getListeners(), {
+  deepEqual(await mockBroadcastService.getListeners(), {
     "abc": "2018-03-04",
     "def": "2018-04-05",
-    "ghi": "2018-05-06"
+    "ghi": "2018-05-06",
   });
 });
 
 add_task(async function test_broadcast_initialize_sane() {
   const path = FileTestUtils.getTempFile("broadcast-listeners.json").path;
-  const broadcastService = new BroadcastService(getPushServiceMock(), path);
-  deepEqual(await broadcastService.getListeners(), {}, "listeners should start out sane");
-  await broadcastService._saveImmediately();
+  const mockBroadcastService = new BroadcastService(getPushServiceMock(), path);
+  deepEqual(await mockBroadcastService.getListeners(), {}, "listeners should start out sane");
+  await mockBroadcastService._saveImmediately();
   let onDiskJSONFile = new JSONFile({path});
   await onDiskJSONFile.load();
   deepEqual(onDiskJSONFile.data, {listeners: {}, version: 1},
             "written JSON file has listeners and version fields");
 
-  await broadcastService.addListener("ghi", "2018-05-06", {
+  await mockBroadcastService.addListener("ghi", "2018-05-06", {
     moduleURI: "resource://gre/modules/ghi.jsm",
-    symbolName: "getGhi"
+    symbolName: "getGhi",
   });
 
-  await broadcastService._saveImmediately();
+  await mockBroadcastService._saveImmediately();
 
   onDiskJSONFile = new JSONFile({path});
   await onDiskJSONFile.load();
 
   deepEqual(onDiskJSONFile.data, {
     listeners: {
       ghi: {
         version: "2018-05-06",
         sourceInfo: {
           moduleURI: "resource://gre/modules/ghi.jsm",
-          symbolName: "getGhi"
-        }
-      }
+          symbolName: "getGhi",
+        },
+      },
     },
     version: 1,
   }, "adding listeners to initial state is written OK");
 });
 
 add_task(async function test_broadcast_reject_invalid_sourceinfo() {
   const path = FileTestUtils.getTempFile("broadcast-listeners.json").path;
-  const broadcastService = new BroadcastService(getPushServiceMock(), path);
+  const mockBroadcastService = new BroadcastService(getPushServiceMock(), path);
 
-  await assert.rejects(broadcastService.addListener("ghi", "2018-05-06", {
+  await assert.rejects(mockBroadcastService.addListener("ghi", "2018-05-06", {
       moduleName: "resource://gre/modules/ghi.jsm",
-      symbolName: "getGhi"
+      symbolName: "getGhi",
   }), /moduleURI must be a string/, "rejects sourceInfo that doesn't have moduleURI");
 });
 
 add_task(async function test_broadcast_reject_version_not_string() {
   await assert.rejects(broadcastService.addListener("ghi", {}, {
       moduleURI: "resource://gre/modules/ghi.jsm",
-      symbolName: "getGhi"
+      symbolName: "getGhi",
   }), /version should be a string/, "rejects version that isn't a string");
 });
 
 add_task(async function test_broadcast_reject_version_empty_string() {
   await assert.rejects(broadcastService.addListener("ghi", "", {
       moduleURI: "resource://gre/modules/ghi.jsm",
-      symbolName: "getGhi"
+      symbolName: "getGhi",
   }), /version should not be an empty string/, "rejects version that is an empty string");
 });
--- a/dom/push/test/xpcshell/test_clearAll_successful.js
+++ b/dom/push/test/xpcshell/test_clearAll_successful.js
@@ -1,71 +1,71 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-'use strict';
+"use strict";
 
 const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
 
 var db;
 var unregisterDefers = {};
-var userAgentID = '4ce480ef-55b2-4f83-924c-dcd35ab978b4';
+var userAgentID = "4ce480ef-55b2-4f83-924c-dcd35ab978b4";
 
 function promiseUnregister(keyID, code) {
   return new Promise(r => unregisterDefers[keyID] = r);
 }
 
 function run_test() {
   do_get_profile();
   setPrefs({
-    userAgentID: userAgentID,
+    userAgentID,
   });
   run_next_test();
 }
 
 add_task(async function setup() {
   db = PushServiceWebSocket.newPushDB();
-  registerCleanupFunction(_ => db.drop().then(_ => db.close()));
+  registerCleanupFunction(() => db.drop().then(() => db.close()));
 
   // Active subscriptions; should be expired then dropped.
-  await putTestRecord(db, 'active-1', 'https://example.info/some-page', 8);
-  await putTestRecord(db, 'active-2', 'https://example.com/another-page', 16);
+  await putTestRecord(db, "active-1", "https://example.info/some-page", 8);
+  await putTestRecord(db, "active-2", "https://example.com/another-page", 16);
 
   // Expired subscription; should be dropped.
-  await putTestRecord(db, 'expired', 'https://example.net/yet-another-page', 0);
+  await putTestRecord(db, "expired", "https://example.net/yet-another-page", 0);
 
   // A privileged subscription that should not be affected by sanitizing data
   // because its quota is set to `Infinity`.
-  await putTestRecord(db, 'privileged', 'app://chrome/only', Infinity);
+  await putTestRecord(db, "privileged", "app://chrome/only", Infinity);
 
   let handshakeDone;
   let handshakePromise = new Promise(r => handshakeDone = r);
   PushService.init({
-    serverURI: 'wss://push.example.org/',
-    db: db,
+    serverURI: "wss://push.example.org/",
+    db,
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(request) {
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             uaid: userAgentID,
             status: 200,
             use_webpush: true,
           }));
           handshakeDone();
         },
         onUnregister(request) {
           let resolve = unregisterDefers[request.channelID];
-          equal(typeof resolve, 'function',
-            'Dropped unexpected channel ID ' + request.channelID);
+          equal(typeof resolve, "function",
+            "Dropped unexpected channel ID " + request.channelID);
           delete unregisterDefers[request.channelID];
           equal(request.code, 200,
-            'Expected manual unregister reason');
+            "Expected manual unregister reason");
           this.serverSendMsg(JSON.stringify({
-            messageType: 'unregister',
+            messageType: "unregister",
             channelID: request.channelID,
             status: 200,
           }));
           resolve();
         },
       });
     },
   });
@@ -73,43 +73,43 @@ add_task(async function setup() {
 });
 
 add_task(async function test_sanitize() {
   let modifiedScopes = [];
   let changeScopes = [];
 
   let promiseCleared = Promise.all([
     // Active subscriptions should be unregistered.
-    promiseUnregister('active-1'),
-    promiseUnregister('active-2'),
+    promiseUnregister("active-1"),
+    promiseUnregister("active-2"),
     promiseObserverNotification(
       PushServiceComponent.subscriptionModifiedTopic, (subject, data) => {
         modifiedScopes.push(data);
         return modifiedScopes.length == 3;
     }),
 
     // Privileged should be recreated.
-    promiseUnregister('privileged'),
+    promiseUnregister("privileged"),
     promiseObserverNotification(
       PushServiceComponent.subscriptionChangeTopic, (subject, data) => {
         changeScopes.push(data);
         return changeScopes.length == 1;
     }),
   ]);
 
   await PushService.clear({
-    domain: '*',
+    domain: "*",
   });
 
   await promiseCleared;
 
   deepEqual(modifiedScopes.sort(compareAscending), [
-    'app://chrome/only',
-    'https://example.com/another-page',
-    'https://example.info/some-page',
-  ], 'Should modify active subscription scopes');
+    "app://chrome/only",
+    "https://example.com/another-page",
+    "https://example.info/some-page",
+  ], "Should modify active subscription scopes");
 
-  deepEqual(changeScopes, ['app://chrome/only'],
-    'Should fire change notification for privileged scope');
+  deepEqual(changeScopes, ["app://chrome/only"],
+    "Should fire change notification for privileged scope");
 
   let remainingIDs = await getAllKeyIDs(db);
-  deepEqual(remainingIDs, [], 'Should drop all subscriptions');
+  deepEqual(remainingIDs, [], "Should drop all subscriptions");
 });
--- a/dom/push/test/xpcshell/test_clear_forgetAboutSite.js
+++ b/dom/push/test/xpcshell/test_clear_forgetAboutSite.js
@@ -1,127 +1,127 @@
-'use strict';
+"use strict";
 
 const {PushService, PushServiceWebSocket} = serviceExports;
 const {ForgetAboutSite} = ChromeUtils.import("resource://gre/modules/ForgetAboutSite.jsm");
 
 var db;
 var unregisterDefers = {};
-var userAgentID = '4fe01c2d-72ac-4c13-93d2-bb072caf461d';
+var userAgentID = "4fe01c2d-72ac-4c13-93d2-bb072caf461d";
 
 function promiseUnregister(keyID) {
   return new Promise(r => unregisterDefers[keyID] = r);
 }
 
 function run_test() {
   do_get_profile();
   setPrefs({
-    userAgentID: userAgentID,
+    userAgentID,
   });
   run_next_test();
 }
 
 add_task(async function setup() {
   db = PushServiceWebSocket.newPushDB();
-  registerCleanupFunction(_ => db.drop().then(_ => db.close()));
+  registerCleanupFunction(() => db.drop().then(() => db.close()));
 
   // Active and expired subscriptions for a subdomain. The active subscription
   // should be expired, then removed; the expired subscription should be
   // removed immediately.
-  await putTestRecord(db, 'active-sub', 'https://sub.example.com/sub-page', 4);
-  await putTestRecord(db, 'expired-sub', 'https://sub.example.com/yet-another-page', 0);
+  await putTestRecord(db, "active-sub", "https://sub.example.com/sub-page", 4);
+  await putTestRecord(db, "expired-sub", "https://sub.example.com/yet-another-page", 0);
 
   // Active subscriptions for another subdomain. Should be unsubscribed and
   // dropped.
-  await putTestRecord(db, 'active-1', 'https://sub2.example.com/some-page', 8);
-  await putTestRecord(db, 'active-2', 'https://sub3.example.com/another-page', 16);
+  await putTestRecord(db, "active-1", "https://sub2.example.com/some-page", 8);
+  await putTestRecord(db, "active-2", "https://sub3.example.com/another-page", 16);
 
   // A privileged subscription with a real URL that should not be affected
   // because its quota is set to `Infinity`.
-  await putTestRecord(db, 'privileged', 'https://sub.example.com/real-url', Infinity);
+  await putTestRecord(db, "privileged", "https://sub.example.com/real-url", Infinity);
 
   let handshakeDone;
   let handshakePromise = new Promise(r => handshakeDone = r);
   PushService.init({
-    serverURI: 'wss://push.example.org/',
-    db: db,
+    serverURI: "wss://push.example.org/",
+    db,
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(request) {
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             uaid: userAgentID,
             status: 200,
             use_webpush: true,
           }));
           handshakeDone();
         },
         onUnregister(request) {
           let resolve = unregisterDefers[request.channelID];
-          equal(typeof resolve, 'function',
-            'Dropped unexpected channel ID ' + request.channelID);
+          equal(typeof resolve, "function",
+            "Dropped unexpected channel ID " + request.channelID);
           delete unregisterDefers[request.channelID];
           equal(request.code, 200,
-            'Expected manual unregister reason');
+            "Expected manual unregister reason");
           resolve();
           this.serverSendMsg(JSON.stringify({
-            messageType: 'unregister',
+            messageType: "unregister",
             status: 200,
             channelID: request.channelID,
           }));
         },
       });
     },
   });
   // For cleared subscriptions, we only send unregister requests in the
   // background and if we're connected.
   await handshakePromise;
 });
 
 add_task(async function test_forgetAboutSubdomain() {
   let modifiedScopes = [];
   let promiseForgetSubs = Promise.all([
     // Active subscriptions should be dropped.
-    promiseUnregister('active-sub'),
+    promiseUnregister("active-sub"),
     promiseObserverNotification(
       PushServiceComponent.subscriptionModifiedTopic, (subject, data) => {
         modifiedScopes.push(data);
         return modifiedScopes.length == 1;
       }
     ),
   ]);
-  await ForgetAboutSite.removeDataFromDomain('sub.example.com');
+  await ForgetAboutSite.removeDataFromDomain("sub.example.com");
   await promiseForgetSubs;
 
   deepEqual(modifiedScopes.sort(compareAscending), [
-    'https://sub.example.com/sub-page',
-  ], 'Should fire modified notifications for active subscriptions');
+    "https://sub.example.com/sub-page",
+  ], "Should fire modified notifications for active subscriptions");
 
   let remainingIDs = await getAllKeyIDs(db);
-  deepEqual(remainingIDs, ['active-1', 'active-2', 'privileged'],
-    'Should only forget subscriptions for subdomain');
+  deepEqual(remainingIDs, ["active-1", "active-2", "privileged"],
+    "Should only forget subscriptions for subdomain");
 });
 
 add_task(async function test_forgetAboutRootDomain() {
   let modifiedScopes = [];
   let promiseForgetSubs = Promise.all([
-    promiseUnregister('active-1'),
-    promiseUnregister('active-2'),
+    promiseUnregister("active-1"),
+    promiseUnregister("active-2"),
     promiseObserverNotification(
       PushServiceComponent.subscriptionModifiedTopic, (subject, data) => {
         modifiedScopes.push(data);
         return modifiedScopes.length == 2;
       }
     ),
   ]);
 
-  await ForgetAboutSite.removeDataFromDomain('example.com');
+  await ForgetAboutSite.removeDataFromDomain("example.com");
   await promiseForgetSubs;
 
   deepEqual(modifiedScopes.sort(compareAscending), [
-    'https://sub2.example.com/some-page',
-    'https://sub3.example.com/another-page',
-  ], 'Should fire modified notifications for entire domain');
+    "https://sub2.example.com/some-page",
+    "https://sub3.example.com/another-page",
+  ], "Should fire modified notifications for entire domain");
 
   let remainingIDs = await getAllKeyIDs(db);
-  deepEqual(remainingIDs, ['privileged'],
-    'Should ignore privileged records with a real URL');
+  deepEqual(remainingIDs, ["privileged"],
+    "Should ignore privileged records with a real URL");
 });
--- a/dom/push/test/xpcshell/test_clear_origin_data.js
+++ b/dom/push/test/xpcshell/test_clear_origin_data.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-'use strict';
+"use strict";
 
 const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
 
-const userAgentID = 'bd744428-f125-436a-b6d0-dd0c9845837f';
+const userAgentID = "bd744428-f125-436a-b6d0-dd0c9845837f";
 
 let clearForPattern = async function(testRecords, pattern) {
   let patternString = JSON.stringify(pattern);
   await PushService._clearOriginData(patternString);
 
   for (let length = testRecords.length; length--;) {
     let test = testRecords[length];
     let originSuffix = ChromeUtils.originAttributesToSuffix(
@@ -19,104 +19,104 @@ let clearForPattern = async function(tes
     let registration = await PushService.registration({
       scope: test.scope,
       originAttributes: originSuffix,
     });
 
     let url = test.scope + originSuffix;
 
     if (ObjectUtils.deepEqual(test.clearIf, pattern)) {
-      ok(!registration, 'Should clear registration ' + url +
-        ' for pattern ' + patternString);
+      ok(!registration, "Should clear registration " + url +
+        " for pattern " + patternString);
       testRecords.splice(length, 1);
     } else {
-      ok(registration, 'Should not clear registration ' + url +
-        ' for pattern ' + patternString);
+      ok(registration, "Should not clear registration " + url +
+        " for pattern " + patternString);
     }
   }
 };
 
 function run_test() {
   do_get_profile();
   setPrefs({
     userAgentID,
     requestTimeout: 1000,
-    retryBaseInterval: 150
+    retryBaseInterval: 150,
   });
   run_next_test();
 }
 
 add_task(async function test_webapps_cleardata() {
   let db = PushServiceWebSocket.newPushDB();
-  registerCleanupFunction(() => {return db.drop().then(_ => db.close());});
+  registerCleanupFunction(() => { return db.drop().then(_ => db.close()); });
 
   let testRecords = [{
-    scope: 'https://example.org/1',
+    scope: "https://example.org/1",
     originAttributes: { appId: 1 },
     clearIf: { appId: 1, inIsolatedMozBrowser: false },
   }, {
-    scope: 'https://example.org/1',
+    scope: "https://example.org/1",
     originAttributes: { appId: 1, inIsolatedMozBrowser: true },
     clearIf: { appId: 1 },
   }, {
-    scope: 'https://example.org/1',
+    scope: "https://example.org/1",
     originAttributes: { appId: 2, inIsolatedMozBrowser: true },
     clearIf: { appId: 2, inIsolatedMozBrowser: true },
   }, {
-    scope: 'https://example.org/2',
+    scope: "https://example.org/2",
     originAttributes: { appId: 1 },
     clearIf: { appId: 1, inIsolatedMozBrowser: false },
   }, {
-    scope: 'https://example.org/2',
+    scope: "https://example.org/2",
     originAttributes: { appId: 2, inIsolatedMozBrowser: true },
     clearIf: { appId: 2, inIsolatedMozBrowser: true },
   }, {
-    scope: 'https://example.org/3',
+    scope: "https://example.org/3",
     originAttributes: { appId: 3, inIsolatedMozBrowser: true },
     clearIf: { inIsolatedMozBrowser: true },
   }, {
-    scope: 'https://example.org/3',
+    scope: "https://example.org/3",
     originAttributes: { appId: 4, inIsolatedMozBrowser: true },
     clearIf: { inIsolatedMozBrowser: true },
   }];
 
   let unregisterDone;
   let unregisterPromise = new Promise(resolve =>
     unregisterDone = after(testRecords.length, resolve));
 
   PushService.init({
     serverURI: "wss://push.example.org",
     db,
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(data) {
-          equal(data.messageType, 'hello', 'Handshake: wrong message type');
-          equal(data.uaid, userAgentID, 'Handshake: wrong device ID');
+          equal(data.messageType, "hello", "Handshake: wrong message type");
+          equal(data.uaid, userAgentID, "Handshake: wrong device ID");
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             status: 200,
-            uaid: userAgentID
+            uaid: userAgentID,
           }));
         },
         onRegister(data) {
-          equal(data.messageType, 'register', 'Register: wrong message type');
+          equal(data.messageType, "register", "Register: wrong message type");
           this.serverSendMsg(JSON.stringify({
-            messageType: 'register',
+            messageType: "register",
             status: 200,
             channelID: data.channelID,
             uaid: userAgentID,
-            pushEndpoint: 'https://example.com/update/' + Math.random(),
+            pushEndpoint: "https://example.com/update/" + Math.random(),
           }));
         },
         onUnregister(data) {
-          equal(data.code, 200, 'Expected manual unregister reason');
+          equal(data.code, 200, "Expected manual unregister reason");
           unregisterDone();
         },
       });
-    }
+    },
   });
 
   await Promise.all(testRecords.map(test =>
     PushService.register({
       scope: test.scope,
       originAttributes: ChromeUtils.originAttributesToSuffix(
         test.originAttributes),
     })
@@ -131,11 +131,11 @@ add_task(async function test_webapps_cle
 
   // Removes all records for all scopes with the same app ID, where
   // `inIsolatedMozBrowser` is true.
   await clearForPattern(testRecords, { appId: 2, inIsolatedMozBrowser: true });
 
   // Removes all records where `inIsolatedMozBrowser` is true.
   await clearForPattern(testRecords, { inIsolatedMozBrowser: true });
 
-  equal(testRecords.length, 0, 'Should remove all test records');
+  equal(testRecords.length, 0, "Should remove all test records");
   await unregisterPromise;
 });
--- a/dom/push/test/xpcshell/test_crypto.js
+++ b/dom/push/test/xpcshell/test_crypto.js
@@ -1,565 +1,565 @@
-'use strict';
+"use strict";
 
 const {
   getCryptoParamsFromHeaders,
   PushCrypto,
 } = ChromeUtils.import("resource://gre/modules/PushCrypto.jsm", null);
 
-const REJECT_PADDING = { padding: 'reject' };
+const REJECT_PADDING = { padding: "reject" };
 
 // A common key to decrypt some aesgcm and aesgcm128 messages. Other decryption
 // tests have their own keys.
 const LEGACY_PRIVATE_KEY = {
-  kty: 'EC',
-  crv: 'P-256',
-  d: '4h23G_KkXC9TvBSK2v0Q7ImpS2YAuRd8hQyN0rFAwBg',
-  x: 'sd85ZCbEG6dEkGMCmDyGBIt454Qy-Yo-1xhbaT2Jlk4',
-  y: 'vr3cKpQ-Sp1kpZ9HipNjUCwSA55yy0uM8N9byE8dmLs',
+  kty: "EC",
+  crv: "P-256",
+  d: "4h23G_KkXC9TvBSK2v0Q7ImpS2YAuRd8hQyN0rFAwBg",
+  x: "sd85ZCbEG6dEkGMCmDyGBIt454Qy-Yo-1xhbaT2Jlk4",
+  y: "vr3cKpQ-Sp1kpZ9HipNjUCwSA55yy0uM8N9byE8dmLs",
   ext: true,
 };
 
-const LEGACY_PUBLIC_KEY = 'BLHfOWQmxBunRJBjApg8hgSLeOeEMvmKPtcYW2k9iZZOvr3cKpQ-Sp1kpZ9HipNjUCwSA55yy0uM8N9byE8dmLs';
+const LEGACY_PUBLIC_KEY = "BLHfOWQmxBunRJBjApg8hgSLeOeEMvmKPtcYW2k9iZZOvr3cKpQ-Sp1kpZ9HipNjUCwSA55yy0uM8N9byE8dmLs";
 
 async function assertDecrypts(test, headers) {
   let privateKey = test.privateKey;
   let publicKey = ChromeUtils.base64URLDecode(test.publicKey, REJECT_PADDING);
   let authSecret = null;
   if (test.authSecret) {
     authSecret = ChromeUtils.base64URLDecode(test.authSecret, REJECT_PADDING);
   }
   let payload = ChromeUtils.base64URLDecode(test.data, REJECT_PADDING);
   let result = await PushCrypto.decrypt(privateKey, publicKey, authSecret,
                                         headers, payload);
-  let decoder = new TextDecoder('utf-8');
+  let decoder = new TextDecoder("utf-8");
   equal(decoder.decode(new Uint8Array(result)), test.result, test.desc);
 }
 
 async function assertNotDecrypts(test, headers) {
   let authSecret = null;
   if (test.authSecret) {
     authSecret = ChromeUtils.base64URLDecode(test.authSecret, REJECT_PADDING);
   }
   let data = ChromeUtils.base64URLDecode(test.data, REJECT_PADDING);
   let publicKey = ChromeUtils.base64URLDecode(test.publicKey, REJECT_PADDING);
   let promise = PushCrypto.decrypt(test.privateKey, publicKey, authSecret,
                                    headers, data);
-  await rejects(promise, test.expected, test.desc);
+  await Assert.rejects(promise, test.expected, test.desc);
 }
 
 add_task(async function test_crypto_getCryptoParamsFromHeaders() {
   // These headers should parse correctly.
   let shouldParse = [{
-    desc: 'aesgcm with multiple keys',
+    desc: "aesgcm with multiple keys",
     headers: {
-      encoding: 'aesgcm',
-      crypto_key: 'keyid=p256dh;dh=Iy1Je2Kv11A,p256ecdsa=o2M8QfiEKuI',
-      encryption: 'keyid=p256dh;salt=upk1yFkp1xI',
+      encoding: "aesgcm",
+      crypto_key: "keyid=p256dh;dh=Iy1Je2Kv11A,p256ecdsa=o2M8QfiEKuI",
+      encryption: "keyid=p256dh;salt=upk1yFkp1xI",
     },
     params: {
-      senderKey: 'Iy1Je2Kv11A',
-      salt: 'upk1yFkp1xI',
+      senderKey: "Iy1Je2Kv11A",
+      salt: "upk1yFkp1xI",
       rs: 4096,
     },
   }, {
-    desc: 'aesgcm with quoted key param',
+    desc: "aesgcm with quoted key param",
     headers: {
-      encoding: 'aesgcm',
+      encoding: "aesgcm",
       crypto_key: 'dh="byfHbUffc-k"',
-      encryption: 'salt=C11AvAsp6Gc',
+      encryption: "salt=C11AvAsp6Gc",
     },
     params: {
-      senderKey: 'byfHbUffc-k',
-      salt: 'C11AvAsp6Gc',
+      senderKey: "byfHbUffc-k",
+      salt: "C11AvAsp6Gc",
       rs: 4096,
     },
   }, {
-    desc: 'aesgcm with Crypto-Key and rs = 24',
+    desc: "aesgcm with Crypto-Key and rs = 24",
     headers: {
-      encoding: 'aesgcm',
+      encoding: "aesgcm",
       crypto_key: 'dh="ybuT4VDz-Bg"',
-      encryption: 'salt=H7U7wcIoIKs; rs=24',
+      encryption: "salt=H7U7wcIoIKs; rs=24",
     },
     params: {
-      senderKey: 'ybuT4VDz-Bg',
-      salt: 'H7U7wcIoIKs',
+      senderKey: "ybuT4VDz-Bg",
+      salt: "H7U7wcIoIKs",
       rs: 24,
     },
   }, {
-    desc: 'aesgcm128 with Encryption-Key and rs = 2',
+    desc: "aesgcm128 with Encryption-Key and rs = 2",
     headers: {
-      encoding: 'aesgcm128',
-      encryption_key: 'keyid=legacy; dh=LqrDQuVl9lY',
-      encryption: 'keyid=legacy; salt=YngI8B7YapM; rs=2',
+      encoding: "aesgcm128",
+      encryption_key: "keyid=legacy; dh=LqrDQuVl9lY",
+      encryption: "keyid=legacy; salt=YngI8B7YapM; rs=2",
     },
     params: {
-      senderKey: 'LqrDQuVl9lY',
-      salt: 'YngI8B7YapM',
+      senderKey: "LqrDQuVl9lY",
+      salt: "YngI8B7YapM",
       rs: 2,
     },
   }, {
-    desc: 'aesgcm128 with Encryption-Key',
+    desc: "aesgcm128 with Encryption-Key",
     headers: {
-      encoding: 'aesgcm128',
-      encryption_key: 'keyid=v2; dh=VA6wmY1IpiE',
-      encryption: 'keyid=v2; salt=khtpyXhpDKM',
+      encoding: "aesgcm128",
+      encryption_key: "keyid=v2; dh=VA6wmY1IpiE",
+      encryption: "keyid=v2; salt=khtpyXhpDKM",
     },
     params: {
-      senderKey: 'VA6wmY1IpiE',
-      salt: 'khtpyXhpDKM',
+      senderKey: "VA6wmY1IpiE",
+      salt: "khtpyXhpDKM",
       rs: 4096,
-    }
+    },
   }];
   for (let test of shouldParse) {
     let params = getCryptoParamsFromHeaders(test.headers);
     let senderKey = ChromeUtils.base64URLDecode(test.params.senderKey,
                                                 REJECT_PADDING);
     let salt = ChromeUtils.base64URLDecode(test.params.salt, REJECT_PADDING);
     deepEqual(new Uint8Array(params.senderKey), new Uint8Array(senderKey),
       "Sender key should match for " + test.desc);
     deepEqual(new Uint8Array(params.salt), new Uint8Array(salt),
       "Salt should match for " + test.desc);
     equal(params.rs, test.params.rs,
       "Record size should match for " + test.desc);
   }
 
   // These headers should be rejected.
   let shouldThrow = [{
-    desc: 'aesgcm128 with Crypto-Key',
+    desc: "aesgcm128 with Crypto-Key",
     headers: {
-      encoding: 'aesgcm128',
-      crypto_key: 'keyid=v2; dh=VA6wmY1IpiE',
-      encryption: 'keyid=v2; salt=F0Im7RtGgNY',
+      encoding: "aesgcm128",
+      crypto_key: "keyid=v2; dh=VA6wmY1IpiE",
+      encryption: "keyid=v2; salt=F0Im7RtGgNY",
     },
     exception: /Missing Encryption-Key header/,
   }, {
-    desc: 'Invalid encoding',
+    desc: "Invalid encoding",
     headers: {
-      encoding: 'nonexistent',
+      encoding: "nonexistent",
     },
     exception: /Missing encryption header/,
   }, {
-    desc: 'Invalid record size',
+    desc: "Invalid record size",
     headers: {
-      encoding: 'aesgcm',
-      crypto_key: 'dh=pbmv1QkcEDY',
-      encryption: 'dh=Esao8aTBfIk;rs=bad',
+      encoding: "aesgcm",
+      crypto_key: "dh=pbmv1QkcEDY",
+      encryption: "dh=Esao8aTBfIk;rs=bad",
     },
     exception: /Invalid salt parameter/,
   }, {
-    desc: 'aesgcm with Encryption-Key',
+    desc: "aesgcm with Encryption-Key",
     headers: {
-      encoding: 'aesgcm',
-      encryption_key: 'dh=FplK5KkvUF0',
-      encryption: 'salt=p6YHhFF3BQY',
+      encoding: "aesgcm",
+      encryption_key: "dh=FplK5KkvUF0",
+      encryption: "salt=p6YHhFF3BQY",
     },
     exception: /Missing Crypto-Key header/,
   }];
   for (let test of shouldThrow) {
     throws(() => getCryptoParamsFromHeaders(test.headers), test.exception, test.desc);
   }
 });
 
 add_task(async function test_aes128gcm_ok() {
   let expectedSuccesses = [{
-    desc: 'Example from draft-ietf-webpush-encryption-latest',
-    result: 'When I grow up, I want to be a watermelon',
-    data: 'DGv6ra1nlYgDCS1FRnbzlwAAEABBBP4z9KsN6nGRTbVYI_c7VJSPQTBtkgcy27mlmlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A_yl95bQpu6cVPTpK4Mqgkf1CXztLVBSt2Ks3oZwbuwXPXLWyouBWLVWGNWQexSgSxsj_Qulcy4a-fN',
-    authSecret: 'BTBZMqHH6r4Tts7J_aSIgg',
+    desc: "Example from draft-ietf-webpush-encryption-latest",
+    result: "When I grow up, I want to be a watermelon",
+    data: "DGv6ra1nlYgDCS1FRnbzlwAAEABBBP4z9KsN6nGRTbVYI_c7VJSPQTBtkgcy27mlmlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A_yl95bQpu6cVPTpK4Mqgkf1CXztLVBSt2Ks3oZwbuwXPXLWyouBWLVWGNWQexSgSxsj_Qulcy4a-fN",
+    authSecret: "BTBZMqHH6r4Tts7J_aSIgg",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: 'q1dXpw3UpT5VOmu_cf_v6ih07Aems3njxI-JWgLcM94',
-      x: 'JXGyvs3942BVGq8e0PTNNmwRzr5VX4m8t7GGpTM5FzE',
-      y: 'aOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4',
+      kty: "EC",
+      crv: "P-256",
+      d: "q1dXpw3UpT5VOmu_cf_v6ih07Aems3njxI-JWgLcM94",
+      x: "JXGyvs3942BVGq8e0PTNNmwRzr5VX4m8t7GGpTM5FzE",
+      y: "aOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4",
       ext: true,
     },
-    publicKey: 'BCVxsr7N_eNgVRqvHtD0zTZsEc6-VV-JvLexhqUzORcxaOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4',
+    publicKey: "BCVxsr7N_eNgVRqvHtD0zTZsEc6-VV-JvLexhqUzORcxaOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4",
   }, {
-    desc: 'rs = 24, pad = 0',
+    desc: "rs = 24, pad = 0",
     result: "I am the very model of a modern Major-General; I've information vegetable, animal, and mineral",
-    data: 'goagSH7PP0ZGwUsgShmdkwAAABhBBDJVyIuUJbOSVMeWHP8VNPnxY-dZSw86doqOkEzZZZY1ALBWVXTVf0rUDH3oi68I9Hrp-01zA-mr8XKWl5kcH8cX0KiV2PtCwdkEyaQ73YF5fsDxgoWDiaTA3wPqMvuLDqGsZWHnE9Psnfoy7UMEqKlh2a1nE7ZOXiXcOBHLNj260jYzSJnEPV2eXixSXfyWpaSJHAwfj4wVdAAocmViIg6ywk8wFB1hgJpnX2UVEU_qIOcaP6AOIOr1UUQPfosQqC2MEHe5u9gHXF5pi-E267LAlkoYefq01KV_xK_vjbxpw8GAYfSjQEm0L8FG-CN37c8pnQ2Yf61MkihaXac9OctfNeWq_22cN6hn4qsOq0F7QoWIiZqWhB1vS9cJ3KUlyPQvKI9cvevDxw0fJHWeTFzhuwT9BjdILjjb2Vkqc0-qTDOawqD4c8WXsvdGDQCec5Y1x3UhdQXdjR_mhXypxFM37OZTvKJBr1vPCpRXl-bI6iOd7KScgtMM1x5luKhGzZyz25HyuFyj1ec82A',
-    authSecret: '_tK2LDGoIt6be6agJ_nvGA',
+    data: "goagSH7PP0ZGwUsgShmdkwAAABhBBDJVyIuUJbOSVMeWHP8VNPnxY-dZSw86doqOkEzZZZY1ALBWVXTVf0rUDH3oi68I9Hrp-01zA-mr8XKWl5kcH8cX0KiV2PtCwdkEyaQ73YF5fsDxgoWDiaTA3wPqMvuLDqGsZWHnE9Psnfoy7UMEqKlh2a1nE7ZOXiXcOBHLNj260jYzSJnEPV2eXixSXfyWpaSJHAwfj4wVdAAocmViIg6ywk8wFB1hgJpnX2UVEU_qIOcaP6AOIOr1UUQPfosQqC2MEHe5u9gHXF5pi-E267LAlkoYefq01KV_xK_vjbxpw8GAYfSjQEm0L8FG-CN37c8pnQ2Yf61MkihaXac9OctfNeWq_22cN6hn4qsOq0F7QoWIiZqWhB1vS9cJ3KUlyPQvKI9cvevDxw0fJHWeTFzhuwT9BjdILjjb2Vkqc0-qTDOawqD4c8WXsvdGDQCec5Y1x3UhdQXdjR_mhXypxFM37OZTvKJBr1vPCpRXl-bI6iOd7KScgtMM1x5luKhGzZyz25HyuFyj1ec82A",
+    authSecret: "_tK2LDGoIt6be6agJ_nvGA",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: 'bGViEe3PvjjFJg8lcnLsqu71b2yqWGnZN9J2MTed-9s',
-      x: 'auB0GHF0AZ2LAocFnvOXDS7EeCMopnzbg-tS21FMHrU',
-      y: 'GpbhrW-_xKj3XhhXA-kDZSicKZ0kn0BuVhqzhLOB-Cc',
+      kty: "EC",
+      crv: "P-256",
+      d: "bGViEe3PvjjFJg8lcnLsqu71b2yqWGnZN9J2MTed-9s",
+      x: "auB0GHF0AZ2LAocFnvOXDS7EeCMopnzbg-tS21FMHrU",
+      y: "GpbhrW-_xKj3XhhXA-kDZSicKZ0kn0BuVhqzhLOB-Cc",
       ext: true,
     },
-    publicKey: 'BGrgdBhxdAGdiwKHBZ7zlw0uxHgjKKZ824PrUttRTB61GpbhrW-_xKj3XhhXA-kDZSicKZ0kn0BuVhqzhLOB-Cc',
+    publicKey: "BGrgdBhxdAGdiwKHBZ7zlw0uxHgjKKZ824PrUttRTB61GpbhrW-_xKj3XhhXA-kDZSicKZ0kn0BuVhqzhLOB-Cc",
   }, {
-    desc: 'rs = 49, pad = 84; ciphertext length falls on record boundary',
-    result: 'Hello, world',
-    data: '-yiDzsHE_K3W0TcfbqSR4AAAADFBBC1EHuf5_2oDKaZJJ9BST9vnsixvtl4Qq0_cA4-UQgoMo_oo2tNshOyRoWLq4Hj6rSwc7XjegRPhlgKyDolPSXa5c-L89oL6DIzNmvPVv_Ht4W-tWjHOGdOLXh_h94pPrYQrvBAlTCxs3ZaitVKE2XLFPK2MO6yxD19X6w1KQzO2BBAroRfK4pEI-9n2Kai6aWDdAZRbOe03unBsQ0oQ_SvSCU_5JJvNrUUTX1_kX804Bx-LLTlBr9pDmBDXeqyvfOULVDJb9YyVAzN9BzeFoyPfo0M',
-    authSecret: 'lfF1cOUI72orKtG09creMw',
+    desc: "rs = 49, pad = 84; ciphertext length falls on record boundary",
+    result: "Hello, world",
+    data: "-yiDzsHE_K3W0TcfbqSR4AAAADFBBC1EHuf5_2oDKaZJJ9BST9vnsixvtl4Qq0_cA4-UQgoMo_oo2tNshOyRoWLq4Hj6rSwc7XjegRPhlgKyDolPSXa5c-L89oL6DIzNmvPVv_Ht4W-tWjHOGdOLXh_h94pPrYQrvBAlTCxs3ZaitVKE2XLFPK2MO6yxD19X6w1KQzO2BBAroRfK4pEI-9n2Kai6aWDdAZRbOe03unBsQ0oQ_SvSCU_5JJvNrUUTX1_kX804Bx-LLTlBr9pDmBDXeqyvfOULVDJb9YyVAzN9BzeFoyPfo0M",
+    authSecret: "lfF1cOUI72orKtG09creMw",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: 'ZwBKTqgg3u2OSdtelIDmPT6jzOGujhpgYJcT1SfQAe8',
-      x: 'AU6PFLktoHzgg7k_ljZ-h7IXpH9-8u6TqdNDqgY-V1o',
-      y: 'nzDVnGkMajmz_IFbFQyn3RSWAXQTN7U1B6UfQbFzpyE',
+      kty: "EC",
+      crv: "P-256",
+      d: "ZwBKTqgg3u2OSdtelIDmPT6jzOGujhpgYJcT1SfQAe8",
+      x: "AU6PFLktoHzgg7k_ljZ-h7IXpH9-8u6TqdNDqgY-V1o",
+      y: "nzDVnGkMajmz_IFbFQyn3RSWAXQTN7U1B6UfQbFzpyE",
       ext: true,
     },
-    publicKey: 'BAFOjxS5LaB84IO5P5Y2foeyF6R_fvLuk6nTQ6oGPldanzDVnGkMajmz_IFbFQyn3RSWAXQTN7U1B6UfQbFzpyE',
+    publicKey: "BAFOjxS5LaB84IO5P5Y2foeyF6R_fvLuk6nTQ6oGPldanzDVnGkMajmz_IFbFQyn3RSWAXQTN7U1B6UfQbFzpyE",
   }, {
-    desc: 'rs = 18, pad = 0',
-    result: '1',
-    data: 'fK69vCCTjuNAqUbxvU9o8QAAABJBBDfP21Ij2fleqgL27ZQP8i6vBbNiLpSdw86fM15u-bJq6qzKD3QICos2RZLyzMbV7d1DAEtwuRiH0UTZ-pPxbDvH6mj0_VR6lOyoSxbhOKYIAXc',
-    authSecret: '1loE35Xy215gSDn3F9zeeQ',
+    desc: "rs = 18, pad = 0",
+    result: "1",
+    data: "fK69vCCTjuNAqUbxvU9o8QAAABJBBDfP21Ij2fleqgL27ZQP8i6vBbNiLpSdw86fM15u-bJq6qzKD3QICos2RZLyzMbV7d1DAEtwuRiH0UTZ-pPxbDvH6mj0_VR6lOyoSxbhOKYIAXc",
+    authSecret: "1loE35Xy215gSDn3F9zeeQ",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: 'J0M_q4lws8tShLYRg--0YoZWLNKnMw2MrpYJEaVXHQw',
-      x: 'UV1DJjVWUjmdoksr6SQeYztc8U-vDPOm_WAxe5VMCi8',
-      y: 'SEhUgASyewz3SAvIEMa-wDqPt5yOoA_IsF4A-INFY-8',
+      kty: "EC",
+      crv: "P-256",
+      d: "J0M_q4lws8tShLYRg--0YoZWLNKnMw2MrpYJEaVXHQw",
+      x: "UV1DJjVWUjmdoksr6SQeYztc8U-vDPOm_WAxe5VMCi8",
+      y: "SEhUgASyewz3SAvIEMa-wDqPt5yOoA_IsF4A-INFY-8",
       ext: true,
     },
-    publicKey: 'BFFdQyY1VlI5naJLK-kkHmM7XPFPrwzzpv1gMXuVTAovSEhUgASyewz3SAvIEMa-wDqPt5yOoA_IsF4A-INFY-8',
+    publicKey: "BFFdQyY1VlI5naJLK-kkHmM7XPFPrwzzpv1gMXuVTAovSEhUgASyewz3SAvIEMa-wDqPt5yOoA_IsF4A-INFY-8",
   }];
   for (let test of expectedSuccesses) {
     let privateKey = test.privateKey;
     let publicKey = ChromeUtils.base64URLDecode(test.publicKey, {
-      padding: 'reject',
+      padding: "reject",
     });
     let authSecret = ChromeUtils.base64URLDecode(test.authSecret, {
-      padding: 'reject',
+      padding: "reject",
     });
     let payload = ChromeUtils.base64URLDecode(test.data, {
-      padding: 'reject',
+      padding: "reject",
     });
     let result = await PushCrypto.decrypt(privateKey, publicKey, authSecret, {
-      encoding: 'aes128gcm',
+      encoding: "aes128gcm",
     }, payload);
-    let decoder = new TextDecoder('utf-8');
+    let decoder = new TextDecoder("utf-8");
     equal(decoder.decode(new Uint8Array(result)), test.result, test.desc);
   }
 });
 
 add_task(async function test_aes128gcm_err() {
   let expectedFailures = [{
     // Just the payload; no header at all.
-    desc: 'Missing header block',
-    data: 'RbdNK2m-mwdN47NaqH58FWEd',
+    desc: "Missing header block",
+    data: "RbdNK2m-mwdN47NaqH58FWEd",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: 'G-g_ODMu8JaB-vPzB7H_LhDKt4zHzatoOsDukqw_buE',
-      x: '26mRyiFTQ_Nr3T6FfK_ePRi_V_GDWygzutQU8IhBYgU',
-      y: 'GslqCyRJADfQfPUo5OGOEAoaZOt0R0hUS_HiINq6zyw',
+      kty: "EC",
+      crv: "P-256",
+      d: "G-g_ODMu8JaB-vPzB7H_LhDKt4zHzatoOsDukqw_buE",
+      x: "26mRyiFTQ_Nr3T6FfK_ePRi_V_GDWygzutQU8IhBYgU",
+      y: "GslqCyRJADfQfPUo5OGOEAoaZOt0R0hUS_HiINq6zyw",
       ext: true,
     },
-    publicKey: 'BNupkcohU0Pza90-hXyv3j0Yv1fxg1soM7rUFPCIQWIFGslqCyRJADfQfPUo5OGOEAoaZOt0R0hUS_HiINq6zyw',
-    authSecret: 'NHG7mEgeAlM785VCvPPbpA',
+    publicKey: "BNupkcohU0Pza90-hXyv3j0Yv1fxg1soM7rUFPCIQWIFGslqCyRJADfQfPUo5OGOEAoaZOt0R0hUS_HiINq6zyw",
+    authSecret: "NHG7mEgeAlM785VCvPPbpA",
     expected: /Truncated header/,
   }, {
     // The sender key should be 65 bytes; this header contains an invalid key
     // that's only 1 byte.
-    desc: 'Truncated sender key',
-    data: '3ltpa4fxoVy2revdedb5ngAAABIBALa8GCbDfJ9z3WtIWcK1BRgZUg',
+    desc: "Truncated sender key",
+    data: "3ltpa4fxoVy2revdedb5ngAAABIBALa8GCbDfJ9z3WtIWcK1BRgZUg",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: 'zojo4LMFekdS60yPqTHrYhwwLaWtA7ga9FnPZzVWDK4',
-      x: 'oyXZkITEDeDOcioELESNlKMmkXIcp54890XnjGmIYZQ',
-      y: 'sCzqGSJBdnlanU27sgc68szW-m8KTHxJaFVr5QKjuoE',
+      kty: "EC",
+      crv: "P-256",
+      d: "zojo4LMFekdS60yPqTHrYhwwLaWtA7ga9FnPZzVWDK4",
+      x: "oyXZkITEDeDOcioELESNlKMmkXIcp54890XnjGmIYZQ",
+      y: "sCzqGSJBdnlanU27sgc68szW-m8KTHxJaFVr5QKjuoE",
       ext: true,
     },
-    publicKey: 'BKMl2ZCExA3gznIqBCxEjZSjJpFyHKeePPdF54xpiGGUsCzqGSJBdnlanU27sgc68szW-m8KTHxJaFVr5QKjuoE',
-    authSecret: 'XDHg2W2aE5iZrAlp01n3QA',
+    publicKey: "BKMl2ZCExA3gznIqBCxEjZSjJpFyHKeePPdF54xpiGGUsCzqGSJBdnlanU27sgc68szW-m8KTHxJaFVr5QKjuoE",
+    authSecret: "XDHg2W2aE5iZrAlp01n3QA",
     expected: /Invalid sender public key/,
   }, {
     // The message is encrypted with only the first 12 bytes of the 16-byte
     // auth secret, so the derived decryption key and nonce won't match.
-    desc: 'Encrypted with mismatched auth secret',
-    data: 'gRX0mIuMOSp7rLQ8jxrFZQAAABJBBBmUSDxUHpvDmmrwP_cTqndFwoThOKQqJDW3l7IMS2mM9RGLT4VVMXwZDqvr-rdJwWTT9r3r4NRBcZExo1fYiQoTxNvUsW_z3VqD98ka1uBArEJzCn8LPNMkXp-Nb_McdR1BDP0',
+    desc: "Encrypted with mismatched auth secret",
+    data: "gRX0mIuMOSp7rLQ8jxrFZQAAABJBBBmUSDxUHpvDmmrwP_cTqndFwoThOKQqJDW3l7IMS2mM9RGLT4VVMXwZDqvr-rdJwWTT9r3r4NRBcZExo1fYiQoTxNvUsW_z3VqD98ka1uBArEJzCn8LPNMkXp-Nb_McdR1BDP0",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: 'YMdjalF95wOaCsLQ4wZEAHlMeOfgSTmBKaInzuD5qAE',
-      x: '_dBBKKhcBYltf4H-EYvcuIe588H_QYOtxMgk0ShgcwA',
-      y: '6Yay37WmEOWvQ-QIoAcwWE-T49_d_ERzfV8I-y1viRY',
+      kty: "EC",
+      crv: "P-256",
+      d: "YMdjalF95wOaCsLQ4wZEAHlMeOfgSTmBKaInzuD5qAE",
+      x: "_dBBKKhcBYltf4H-EYvcuIe588H_QYOtxMgk0ShgcwA",
+      y: "6Yay37WmEOWvQ-QIoAcwWE-T49_d_ERzfV8I-y1viRY",
       ext: true,
     },
-    publicKey: 'BP3QQSioXAWJbX-B_hGL3LiHufPB_0GDrcTIJNEoYHMA6Yay37WmEOWvQ-QIoAcwWE-T49_d_ERzfV8I-y1viRY',
-    authSecret: 'NVo4zW2b7xWZDi0zCNvWAA',
+    publicKey: "BP3QQSioXAWJbX-B_hGL3LiHufPB_0GDrcTIJNEoYHMA6Yay37WmEOWvQ-QIoAcwWE-T49_d_ERzfV8I-y1viRY",
+    authSecret: "NVo4zW2b7xWZDi0zCNvWAA",
     expected: /Bad encryption/,
   }, {
     // Multiple records; the first has padding delimiter = 2, but should be 1.
-    desc: 'Early final record',
-    data: '2-IVUH0a09Lq6r6ubodNjwAAABJBBHvEND80qDSM3E5GL_x8QKpqjGGnOcTEHUUSVQX3Dp_F-e-oaFLdSI3Pjo6iyvt14Hq9XufJ1cA4uv7weVcbC9opRBHOmMdt0DHA5YBXekmAo3XkXtMEKb4OLunafm34aW0BuOw',
+    desc: "Early final record",
+    data: "2-IVUH0a09Lq6r6ubodNjwAAABJBBHvEND80qDSM3E5GL_x8QKpqjGGnOcTEHUUSVQX3Dp_F-e-oaFLdSI3Pjo6iyvt14Hq9XufJ1cA4uv7weVcbC9opRBHOmMdt0DHA5YBXekmAo3XkXtMEKb4OLunafm34aW0BuOw",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: 'XdodkYvEB7o82hLLgBTUmqfgJpACggMERmvIADTKkkA',
-      x: 'yVxlINrRHo9qG_gDGkDCpO4QRcGQO-BqHfp_gpzOst4',
-      y: 'Akga5r0EdhIbEsVTLQsjF4gHfvoGg6W_4NYjObJRyzU',
+      kty: "EC",
+      crv: "P-256",
+      d: "XdodkYvEB7o82hLLgBTUmqfgJpACggMERmvIADTKkkA",
+      x: "yVxlINrRHo9qG_gDGkDCpO4QRcGQO-BqHfp_gpzOst4",
+      y: "Akga5r0EdhIbEsVTLQsjF4gHfvoGg6W_4NYjObJRyzU",
       ext: true,
     },
-    publicKey: 'BMlcZSDa0R6Pahv4AxpAwqTuEEXBkDvgah36f4KczrLeAkga5r0EdhIbEsVTLQsjF4gHfvoGg6W_4NYjObJRyzU',
-    authSecret: 'QMJB_eQmnuHm1yVZLZgnGA',
+    publicKey: "BMlcZSDa0R6Pahv4AxpAwqTuEEXBkDvgah36f4KczrLeAkga5r0EdhIbEsVTLQsjF4gHfvoGg6W_4NYjObJRyzU",
+    authSecret: "QMJB_eQmnuHm1yVZLZgnGA",
     expected: /Padding is wrong!/,
   }];
   for (let test of expectedFailures) {
-    await assertNotDecrypts(test, { encoding: 'aes128gcm' });
+    await assertNotDecrypts(test, { encoding: "aes128gcm" });
   }
 });
 
 add_task(async function test_aesgcm_ok() {
   let expectedSuccesses = [{
-    desc: 'padSize = 2, rs = 24, pad = 0',
-    result: 'Some message',
-    data: 'Oo34w2F9VVnTMFfKtdx48AZWQ9Li9M6DauWJVgXU',
-    authSecret: 'aTDc6JebzR6eScy2oLo4RQ',
+    desc: "padSize = 2, rs = 24, pad = 0",
+    result: "Some message",
+    data: "Oo34w2F9VVnTMFfKtdx48AZWQ9Li9M6DauWJVgXU",
+    authSecret: "aTDc6JebzR6eScy2oLo4RQ",
     privateKey: LEGACY_PRIVATE_KEY,
     publicKey: LEGACY_PUBLIC_KEY,
     headers: {
-      crypto_key: 'dh=BCHFVrflyxibGLlgztLwKelsRZp4gqX3tNfAKFaxAcBhpvYeN1yIUMrxaDKiLh4LNKPtj0BOXGdr-IQ-QP82Wjo',
-      encryption: 'salt=zCU18Rw3A5aB_Xi-vfixmA; rs=24',
-      encoding: 'aesgcm',
+      crypto_key: "dh=BCHFVrflyxibGLlgztLwKelsRZp4gqX3tNfAKFaxAcBhpvYeN1yIUMrxaDKiLh4LNKPtj0BOXGdr-IQ-QP82Wjo",
+      encryption: "salt=zCU18Rw3A5aB_Xi-vfixmA; rs=24",
+      encoding: "aesgcm",
     },
   }, {
-    desc: 'padSize = 2, rs = 8, pad = 16',
-    result: 'Yet another message',
-    data: 'uEC5B_tR-fuQ3delQcrzrDCp40W6ipMZjGZ78USDJ5sMj-6bAOVG3AK6JqFl9E6AoWiBYYvMZfwThVxmDnw6RHtVeLKFM5DWgl1EwkOohwH2EhiDD0gM3io-d79WKzOPZE9rDWUSv64JstImSfX_ADQfABrvbZkeaWxh53EG59QMOElFJqHue4dMURpsMXg',
-    authSecret: '6plwZnSpVUbF7APDXus3UQ',
+    desc: "padSize = 2, rs = 8, pad = 16",
+    result: "Yet another message",
+    data: "uEC5B_tR-fuQ3delQcrzrDCp40W6ipMZjGZ78USDJ5sMj-6bAOVG3AK6JqFl9E6AoWiBYYvMZfwThVxmDnw6RHtVeLKFM5DWgl1EwkOohwH2EhiDD0gM3io-d79WKzOPZE9rDWUSv64JstImSfX_ADQfABrvbZkeaWxh53EG59QMOElFJqHue4dMURpsMXg",
+    authSecret: "6plwZnSpVUbF7APDXus3UQ",
     privateKey: LEGACY_PRIVATE_KEY,
     publicKey: LEGACY_PUBLIC_KEY,
     headers: {
-      crypto_key: 'dh=BEaA4gzA3i0JDuirGhiLgymS4hfFX7TNTdEhSk_HBlLpkjgCpjPL5c-GL9uBGIfa_fhGNKKFhXz1k9Kyens2ZpQ',
-      encryption: 'salt=ZFhzj0S-n29g9P2p4-I7tA; rs=8',
-      encoding: 'aesgcm',
+      crypto_key: "dh=BEaA4gzA3i0JDuirGhiLgymS4hfFX7TNTdEhSk_HBlLpkjgCpjPL5c-GL9uBGIfa_fhGNKKFhXz1k9Kyens2ZpQ",
+      encryption: "salt=ZFhzj0S-n29g9P2p4-I7tA; rs=8",
+      encoding: "aesgcm",
     },
   }, {
-    desc: 'padSize = 2, rs = 3, pad = 0',
-    result: 'Small record size',
-    data: 'oY4e5eDatDVt2fpQylxbPJM-3vrfhDasfPc8Q1PWt4tPfMVbz_sDNL_cvr0DXXkdFzS1lxsJsj550USx4MMl01ihjImXCjrw9R5xFgFrCAqJD3GwXA1vzS4T5yvGVbUp3SndMDdT1OCcEofTn7VC6xZ-zP8rzSQfDCBBxmPU7OISzr8Z4HyzFCGJeBfqiZ7yUfNlKF1x5UaZ4X6iU_TXx5KlQy_toV1dXZ2eEAMHJUcSdArvB6zRpFdEIxdcHcJyo1BIYgAYTDdAIy__IJVCPY_b2CE5W_6ohlYKB7xDyH8giNuWWXAgBozUfScLUVjPC38yJTpAUi6w6pXgXUWffende5FreQpnMFL1L4G-38wsI_-ISIOzdO8QIrXHxmtc1S5xzYu8bMqSgCinvCEwdeGFCmighRjj8t1zRWo0D14rHbQLPR_b1P5SvEeJTtS9Nm3iibM',
-    authSecret: 'g2rWVHUCpUxgcL9Tz7vyeQ',
+    desc: "padSize = 2, rs = 3, pad = 0",
+    result: "Small record size",
+    data: "oY4e5eDatDVt2fpQylxbPJM-3vrfhDasfPc8Q1PWt4tPfMVbz_sDNL_cvr0DXXkdFzS1lxsJsj550USx4MMl01ihjImXCjrw9R5xFgFrCAqJD3GwXA1vzS4T5yvGVbUp3SndMDdT1OCcEofTn7VC6xZ-zP8rzSQfDCBBxmPU7OISzr8Z4HyzFCGJeBfqiZ7yUfNlKF1x5UaZ4X6iU_TXx5KlQy_toV1dXZ2eEAMHJUcSdArvB6zRpFdEIxdcHcJyo1BIYgAYTDdAIy__IJVCPY_b2CE5W_6ohlYKB7xDyH8giNuWWXAgBozUfScLUVjPC38yJTpAUi6w6pXgXUWffende5FreQpnMFL1L4G-38wsI_-ISIOzdO8QIrXHxmtc1S5xzYu8bMqSgCinvCEwdeGFCmighRjj8t1zRWo0D14rHbQLPR_b1P5SvEeJTtS9Nm3iibM",
+    authSecret: "g2rWVHUCpUxgcL9Tz7vyeQ",
     privateKey: LEGACY_PRIVATE_KEY,
     publicKey: LEGACY_PUBLIC_KEY,
     headers: {
-      crypto_key: 'dh=BCg6ZIGuE2ZNm2ti6Arf4CDVD_8--aLXAGLYhpghwjl1xxVjTLLpb7zihuEOGGbyt8Qj0_fYHBP4ObxwJNl56bk',
-      encryption: 'salt=5LIDBXbvkBvvb7ZdD-T4PQ; rs=3',
-      encoding: 'aesgcm',
+      crypto_key: "dh=BCg6ZIGuE2ZNm2ti6Arf4CDVD_8--aLXAGLYhpghwjl1xxVjTLLpb7zihuEOGGbyt8Qj0_fYHBP4ObxwJNl56bk",
+      encryption: "salt=5LIDBXbvkBvvb7ZdD-T4PQ; rs=3",
+      encoding: "aesgcm",
     },
   }, {
-    desc: 'Example from draft-ietf-httpbis-encryption-encoding-02',
-    result: 'I am the walrus',
-    data: '6nqAQUME8hNqw5J3kl8cpVVJylXKYqZOeseZG8UueKpA',
-    authSecret: 'R29vIGdvbyBnJyBqb29iIQ',
+    desc: "Example from draft-ietf-httpbis-encryption-encoding-02",
+    result: "I am the walrus",
+    data: "6nqAQUME8hNqw5J3kl8cpVVJylXKYqZOeseZG8UueKpA",
+    authSecret: "R29vIGdvbyBnJyBqb29iIQ",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: '9FWl15_QUQAWDaD3k3l50ZBZQJ4au27F1V4F0uLSD_M',
-      x: 'ISQGPMvxncL6iLZDugTm3Y2n6nuiyMYuD3epQ_TC-pE',
-      y: 'T21EEWyf0cQDQcakQMqz4hQKYOQ3il2nNZct4HgAUQU',
+      kty: "EC",
+      crv: "P-256",
+      d: "9FWl15_QUQAWDaD3k3l50ZBZQJ4au27F1V4F0uLSD_M",
+      x: "ISQGPMvxncL6iLZDugTm3Y2n6nuiyMYuD3epQ_TC-pE",
+      y: "T21EEWyf0cQDQcakQMqz4hQKYOQ3il2nNZct4HgAUQU",
       ext: true,
     },
-    publicKey: 'BCEkBjzL8Z3C-oi2Q7oE5t2Np-p7osjGLg93qUP0wvqRT21EEWyf0cQDQcakQMqz4hQKYOQ3il2nNZct4HgAUQU',
+    publicKey: "BCEkBjzL8Z3C-oi2Q7oE5t2Np-p7osjGLg93qUP0wvqRT21EEWyf0cQDQcakQMqz4hQKYOQ3il2nNZct4HgAUQU",
     headers: {
       crypto_key: 'keyid="dhkey"; dh="BNoRDbb84JGm8g5Z5CFxurSqsXWJ11ItfXEWYVLE85Y7CYkDjXsIEc4aqxYaQ1G8BqkXCJ6DPpDrWtdWj_mugHU"',
       encryption: 'keyid="dhkey"; salt="lngarbyKfMoi9Z75xYXmkg"',
-      encoding: 'aesgcm',
+      encoding: "aesgcm",
     },
   }];
   for (let test of expectedSuccesses) {
     await assertDecrypts(test, test.headers);
   }
 });
 
 add_task(async function test_aesgcm_err() {
   let expectedFailures = [{
-    desc: 'aesgcm128 message decrypted as aesgcm',
-    data: 'fwkuwTTChcLnrzsbDI78Y2EoQzfnbMI8Ax9Z27_rwX8',
-    authSecret: 'BhbpNTWyO5wVJmVKTV6XaA',
+    desc: "aesgcm128 message decrypted as aesgcm",
+    data: "fwkuwTTChcLnrzsbDI78Y2EoQzfnbMI8Ax9Z27_rwX8",
+    authSecret: "BhbpNTWyO5wVJmVKTV6XaA",
     privateKey: LEGACY_PRIVATE_KEY,
     publicKey: LEGACY_PUBLIC_KEY,
     headers: {
-      crypto_key: 'dh=BCHn-I-J3dfPRLJBlNZ3xFoAqaBLZ6qdhpaz9W7Q00JW1oD-hTxyEECn6KYJNK8AxKUyIDwn6Icx_PYWJiEYjQ0',
-      encryption: 'salt=c6JQl9eJ0VvwrUVCQDxY7Q',
-      encoding: 'aesgcm',
+      crypto_key: "dh=BCHn-I-J3dfPRLJBlNZ3xFoAqaBLZ6qdhpaz9W7Q00JW1oD-hTxyEECn6KYJNK8AxKUyIDwn6Icx_PYWJiEYjQ0",
+      encryption: "salt=c6JQl9eJ0VvwrUVCQDxY7Q",
+      encoding: "aesgcm",
     },
     expected: /Bad encryption/,
   }, {
     // The plaintext is "O hai". The ciphertext is exactly `rs + 16` bytes,
     // but we didn't include the empty trailing block that aesgcm requires for
     // exact multiples.
-    desc: 'rs = 7, no trailing block',
-    data: 'YG4F-b06y590hRlnSsw_vuOw62V9Iz8',
-    authSecret: 'QoDi0u6vcslIVJKiouXMXw',
+    desc: "rs = 7, no trailing block",
+    data: "YG4F-b06y590hRlnSsw_vuOw62V9Iz8",
+    authSecret: "QoDi0u6vcslIVJKiouXMXw",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: '2bu4paOAZbL2ef1u-wTzONuTIcDPc00o0zUJgg46XTc',
-      x: 'uEvLZUMVn1my0cwnLdcFT0mj1gSU5uzI3HeGwXC7jX8',
-      y: 'SfNVLGL-FurydsuzciDfw8K1cUHyoDWnJJ_16UG6Dbo',
+      kty: "EC",
+      crv: "P-256",
+      d: "2bu4paOAZbL2ef1u-wTzONuTIcDPc00o0zUJgg46XTc",
+      x: "uEvLZUMVn1my0cwnLdcFT0mj1gSU5uzI3HeGwXC7jX8",
+      y: "SfNVLGL-FurydsuzciDfw8K1cUHyoDWnJJ_16UG6Dbo",
       ext: true,
     },
-    publicKey: 'BLhLy2VDFZ9ZstHMJy3XBU9Jo9YElObsyNx3hsFwu41_SfNVLGL-FurydsuzciDfw8K1cUHyoDWnJJ_16UG6Dbo',
+    publicKey: "BLhLy2VDFZ9ZstHMJy3XBU9Jo9YElObsyNx3hsFwu41_SfNVLGL-FurydsuzciDfw8K1cUHyoDWnJJ_16UG6Dbo",
     headers: {
-      crypto_key: 'dh=BD_bsTUpxBMvSv8eksith3vijMLj44D4jhJjO51y7wK1ytbUlsyYBBYYyB5AAe5bnREA_WipTgemDVz00LiWcfM',
-      encryption: 'salt=xKWvs_jWWeg4KOsot_uBhA; rs=7',
-      encoding: 'aesgcm',
+      crypto_key: "dh=BD_bsTUpxBMvSv8eksith3vijMLj44D4jhJjO51y7wK1ytbUlsyYBBYYyB5AAe5bnREA_WipTgemDVz00LiWcfM",
+      encryption: "salt=xKWvs_jWWeg4KOsot_uBhA; rs=7",
+      encoding: "aesgcm",
     },
     expected: /Encrypted data truncated/,
   }, {
     // The last block is only 1 byte, but valid blocks must be at least 2 bytes.
-    desc: 'Pad size > last block length',
-    data: 'JvX9HsJ4lL5gzP8_uCKc6s15iRIaNhD4pFCgq5-dfwbUqEcNUkqv',
-    authSecret: 'QtGZeY8MQfCaq-XwKOVGBQ',
+    desc: "Pad size > last block length",
+    data: "JvX9HsJ4lL5gzP8_uCKc6s15iRIaNhD4pFCgq5-dfwbUqEcNUkqv",
+    authSecret: "QtGZeY8MQfCaq-XwKOVGBQ",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: 'CosERAVXgvTvoh7UkrRC2V-iXoNs0bXle9I68qzkles',
-      x: '_D0YqEwirvTJQJdjG6xXrjstMVpeAzf221cUqZz6hgY',
-      y: '9MnFbM7U14uiYMDI5e2I4jN29tYmsM9F66QodhKmA-c',
+      kty: "EC",
+      crv: "P-256",
+      d: "CosERAVXgvTvoh7UkrRC2V-iXoNs0bXle9I68qzkles",
+      x: "_D0YqEwirvTJQJdjG6xXrjstMVpeAzf221cUqZz6hgY",
+      y: "9MnFbM7U14uiYMDI5e2I4jN29tYmsM9F66QodhKmA-c",
       ext: true,
     },
-    publicKey: 'BPw9GKhMIq70yUCXYxusV647LTFaXgM39ttXFKmc-oYG9MnFbM7U14uiYMDI5e2I4jN29tYmsM9F66QodhKmA-c',
+    publicKey: "BPw9GKhMIq70yUCXYxusV647LTFaXgM39ttXFKmc-oYG9MnFbM7U14uiYMDI5e2I4jN29tYmsM9F66QodhKmA-c",
     headers: {
-      crypto_key: 'dh=BBNZNEi5Ew_ID5S4Y9jWBi1NeVDje6Mjs7SDLViUn6A8VAZj-6X3QAuYQ3j20BblqjwTgYst7PRnY6UGrKyLbmU',
-      encryption: 'salt=ot8hzbwOo6CYe6ZhdlwKtg; rs=6',
-      encoding: 'aesgcm',
+      crypto_key: "dh=BBNZNEi5Ew_ID5S4Y9jWBi1NeVDje6Mjs7SDLViUn6A8VAZj-6X3QAuYQ3j20BblqjwTgYst7PRnY6UGrKyLbmU",
+      encryption: "salt=ot8hzbwOo6CYe6ZhdlwKtg; rs=6",
+      encoding: "aesgcm",
     },
     expected: /Decoded array is too short/,
   }, {
     // The last block is 3 bytes (2 bytes for the pad length; 1 byte of data),
     // but claims its pad length is 2.
-    desc: 'Padding length > last block length',
-    data: 'oWSOFA-UO5oWq-kI79RHaFfwAejLiQJ4C7eTmrSTBl4gArLXfx7lZ-Y',
-    authSecret: 'gKG_P6-de5pyzS8hyH_NyQ',
+    desc: "Padding length > last block length",
+    data: "oWSOFA-UO5oWq-kI79RHaFfwAejLiQJ4C7eTmrSTBl4gArLXfx7lZ-Y",
+    authSecret: "gKG_P6-de5pyzS8hyH_NyQ",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: '9l-ahcBM-I0ykwbWiDS9KRrPdhyvTZ0SxKiPpj2aeaI',
-      x: 'qx0tU4EDaQv6ayFA3xvLLBdMmn4mLxjn7SK6mIeIxeg',
-      y: 'ymbMcmUOEyh_-rLrBsi26NG4UFCis2MTDs5FG2VdDPI',
+      kty: "EC",
+      crv: "P-256",
+      d: "9l-ahcBM-I0ykwbWiDS9KRrPdhyvTZ0SxKiPpj2aeaI",
+      x: "qx0tU4EDaQv6ayFA3xvLLBdMmn4mLxjn7SK6mIeIxeg",
+      y: "ymbMcmUOEyh_-rLrBsi26NG4UFCis2MTDs5FG2VdDPI",
       ext: true,
     },
-    publicKey: 'BKsdLVOBA2kL-mshQN8byywXTJp-Ji8Y5-0iupiHiMXoymbMcmUOEyh_-rLrBsi26NG4UFCis2MTDs5FG2VdDPI',
+    publicKey: "BKsdLVOBA2kL-mshQN8byywXTJp-Ji8Y5-0iupiHiMXoymbMcmUOEyh_-rLrBsi26NG4UFCis2MTDs5FG2VdDPI",
     headers: {
-      crypto_key: 'dh=BKe2IBO_cwmEzQyTVscSbQcj0Y3uBSzGZ_mHlANMciS8uGpb7U8_Bw7TNdlYfpwWDLd0cxM8YYWNDbNJ_p2Rp4o',
-      encryption: 'salt=z7QJ6UR89SiFRkd4RsC4Vg; rs=6',
-      encoding: 'aesgcm',
+      crypto_key: "dh=BKe2IBO_cwmEzQyTVscSbQcj0Y3uBSzGZ_mHlANMciS8uGpb7U8_Bw7TNdlYfpwWDLd0cxM8YYWNDbNJ_p2Rp4o",
+      encryption: "salt=z7QJ6UR89SiFRkd4RsC4Vg; rs=6",
+      encoding: "aesgcm",
     },
     expected: /Padding is wrong/,
   }, {
     // The first block has no padding, but claims its pad length is 1.
-    desc: 'Non-zero padding',
-    data: 'Qdvjh0LkZXKu_1Hvv56D0rOSF6Mww3y0F8xkxUNlwVu2U1iakOUUGRs',
-    authSecret: 'cMpWQW58BrpDbJ8KqbS9ig',
+    desc: "Non-zero padding",
+    data: "Qdvjh0LkZXKu_1Hvv56D0rOSF6Mww3y0F8xkxUNlwVu2U1iakOUUGRs",
+    authSecret: "cMpWQW58BrpDbJ8KqbS9ig",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: 'IzuaxLqFJmjSu8GjLCo2oEaDZjDButW4m4T0qx02XsM',
-      x: 'Xy7vt_TJTynxwWsQyY069BcKmrhkRjhKPFuTi-AphoY',
-      y: '0M10IVM1ourR7Q5AUX2b2fgdmGyTWcYsdHcdFK_b4Hk',
+      kty: "EC",
+      crv: "P-256",
+      d: "IzuaxLqFJmjSu8GjLCo2oEaDZjDButW4m4T0qx02XsM",
+      x: "Xy7vt_TJTynxwWsQyY069BcKmrhkRjhKPFuTi-AphoY",
+      y: "0M10IVM1ourR7Q5AUX2b2fgdmGyTWcYsdHcdFK_b4Hk",
       ext: true,
     },
-    publicKey: 'BF8u77f0yU8p8cFrEMmNOvQXCpq4ZEY4Sjxbk4vgKYaG0M10IVM1ourR7Q5AUX2b2fgdmGyTWcYsdHcdFK_b4Hk',
+    publicKey: "BF8u77f0yU8p8cFrEMmNOvQXCpq4ZEY4Sjxbk4vgKYaG0M10IVM1ourR7Q5AUX2b2fgdmGyTWcYsdHcdFK_b4Hk",
     headers: {
-      crypto_key: 'dh=BBicj01QI0ryiFzAaty9VpW_crgq9XbU1bOCtEZI9UNE6tuOgp4lyN_UN0N905ECnLWK5v_sCPUIxnQgOuCseSo',
-      encryption: 'salt=SbkGHONbQBBsBcj9dLyIUw; rs=6',
-      encoding: 'aesgcm',
+      crypto_key: "dh=BBicj01QI0ryiFzAaty9VpW_crgq9XbU1bOCtEZI9UNE6tuOgp4lyN_UN0N905ECnLWK5v_sCPUIxnQgOuCseSo",
+      encryption: "salt=SbkGHONbQBBsBcj9dLyIUw; rs=6",
+      encoding: "aesgcm",
     },
     expected: /Padding is wrong/,
   }, {
     // The first record is 22 bytes: 2 bytes for the pad length, 4 bytes of
     // data, and a 16-byte auth tag. The second "record" is missing the pad
     // and data, and contains just the auth tag.
-    desc: 'rs = 6, second record truncated to only auth tag',
-    data: 'C7u3j5AL4Yzh2yYB_umN6tzrVHxrt7D5baTEW9DE1Bk3up9fY4w',
-    authSecret: '3rWhsRCU_KdaqfKPbd3zBQ',
+    desc: "rs = 6, second record truncated to only auth tag",
+    data: "C7u3j5AL4Yzh2yYB_umN6tzrVHxrt7D5baTEW9DE1Bk3up9fY4w",
+    authSecret: "3rWhsRCU_KdaqfKPbd3zBQ",
     privateKey: {
-      kty: 'EC',
-      crv: 'P-256',
-      d: 'nhOT9171xuoQBJGkiZ3aqT5qw_ILJ94_PPiVNu1LFSY',
-      x: 'lCj7ctQTmRfwzTMcODlNfHjFMAHmgdI44OhTQXX_xpE',
-      y: 'WBdgz4GWGtGAisC63O9DtP5l--hnCzPZiV-YZ-a6Lcw',
+      kty: "EC",
+      crv: "P-256",
+      d: "nhOT9171xuoQBJGkiZ3aqT5qw_ILJ94_PPiVNu1LFSY",
+      x: "lCj7ctQTmRfwzTMcODlNfHjFMAHmgdI44OhTQXX_xpE",
+      y: "WBdgz4GWGtGAisC63O9DtP5l--hnCzPZiV-YZ-a6Lcw",
       ext: true,
     },
-    publicKey: 'BJQo-3LUE5kX8M0zHDg5TXx4xTAB5oHSOODoU0F1_8aRWBdgz4GWGtGAisC63O9DtP5l--hnCzPZiV-YZ-a6Lcw',
+    publicKey: "BJQo-3LUE5kX8M0zHDg5TXx4xTAB5oHSOODoU0F1_8aRWBdgz4GWGtGAisC63O9DtP5l--hnCzPZiV-YZ-a6Lcw",
     headers: {
-      crypto_key: 'dh=BI38Qs_OhDmQIxbszc6Nako-MrX3FzAE_8HzxM1wgoEIG4ocxyF-YAAVhfkpJUvDpRyKW2LDHIaoylaZuxQfRhE',
-      encryption: 'salt=QClh48OlvGpSjZ0Mg0e8rg; rs=6',
-      encoding: 'aesgcm',
+      crypto_key: "dh=BI38Qs_OhDmQIxbszc6Nako-MrX3FzAE_8HzxM1wgoEIG4ocxyF-YAAVhfkpJUvDpRyKW2LDHIaoylaZuxQfRhE",
+      encryption: "salt=QClh48OlvGpSjZ0Mg0e8rg; rs=6",
+      encoding: "aesgcm",
     },
     expected: /Decoded array is too short/,
   }];
   for (let test of expectedFailures) {
     await assertNotDecrypts(test, test.headers);
   }
 });
 
 add_task(async function test_aesgcm128_ok() {
   let expectedSuccesses = [{
-    desc: 'padSize = 1, rs = 4096, pad = 2',
-    result: 'aesgcm128 encrypted message',
-    data: 'ljBJ44NPzJFH9EuyT5xWMU4vpZ90MdAqaq1TC1kOLRoPNHtNFXeJ0GtuSaE',
+    desc: "padSize = 1, rs = 4096, pad = 2",
+    result: "aesgcm128 encrypted message",
+    data: "ljBJ44NPzJFH9EuyT5xWMU4vpZ90MdAqaq1TC1kOLRoPNHtNFXeJ0GtuSaE",
     privateKey: LEGACY_PRIVATE_KEY,
     publicKey: LEGACY_PUBLIC_KEY,
     headers: {
-      encryption_key: 'dh=BOmnfg02vNd6RZ7kXWWrCGFF92bI-rQ-bV0Pku3-KmlHwbGv4ejWqgasEdLGle5Rhmp6SKJunZw2l2HxKvrIjfI',
-      encryption: 'salt=btxxUtclbmgcc30b9rT3Bg; rs=4096',
-      encoding: 'aesgcm128',
+      encryption_key: "dh=BOmnfg02vNd6RZ7kXWWrCGFF92bI-rQ-bV0Pku3-KmlHwbGv4ejWqgasEdLGle5Rhmp6SKJunZw2l2HxKvrIjfI",
+      encryption: "salt=btxxUtclbmgcc30b9rT3Bg; rs=4096",
+      encoding: "aesgcm128",
     },
   }];
   for (let test of expectedSuccesses) {
     await assertDecrypts(test, test.headers);
   }
 });
 
 add_task(async function test_aesgcm128_err() {
   let expectedFailures = [{
     // aesgcm128 doesn't use an auth secret, but we've mixed one in during
     // encryption, so the decryption key and nonce won't match.
-    desc: 'padSize = 1, rs = 4096, auth secret, pad = 8',
-    data: 'h0FmyldY8aT5EQ6CJrbfRn_IdDvytoLeHb9_q5CjtdFRfgDRknxLmOzavLaVG4oOiS0r',
-    authSecret: 'Sxb6u0gJIhGEogyLawjmCw',
+    desc: "padSize = 1, rs = 4096, auth secret, pad = 8",
+    data: "h0FmyldY8aT5EQ6CJrbfRn_IdDvytoLeHb9_q5CjtdFRfgDRknxLmOzavLaVG4oOiS0r",
+    authSecret: "Sxb6u0gJIhGEogyLawjmCw",
     privateKey: LEGACY_PRIVATE_KEY,
     publicKey: LEGACY_PUBLIC_KEY,
     headers: {
-      crypto_key: 'dh=BCXHk7O8CE-9AOp6xx7g7c-NCaNpns1PyyHpdcmDaijLbT6IdGq0ezGatBwtFc34BBfscFxdk4Tjksa2Mx5rRCM',
-      encryption: 'salt=aGBpoKklLtrLcAUCcCr7JQ',
-      encoding: 'aesgcm128',
+      crypto_key: "dh=BCXHk7O8CE-9AOp6xx7g7c-NCaNpns1PyyHpdcmDaijLbT6IdGq0ezGatBwtFc34BBfscFxdk4Tjksa2Mx5rRCM",
+      encryption: "salt=aGBpoKklLtrLcAUCcCr7JQ",
+      encoding: "aesgcm128",
     },
     expected: /Missing Encryption-Key header/,
   }, {
     // The first byte of each record must be the pad length.
-    desc: 'Missing padding',
-    data: 'anvsHj7oBQTPMhv7XSJEsvyMS4-8EtbC7HgFZsKaTg',
+    desc: "Missing padding",
+    data: "anvsHj7oBQTPMhv7XSJEsvyMS4-8EtbC7HgFZsKaTg",
     privateKey: LEGACY_PRIVATE_KEY,
     publicKey: LEGACY_PUBLIC_KEY,
     headers: {
-      crypto_key: 'dh=BMSqfc3ohqw2DDgu3nsMESagYGWubswQPGxrW1bAbYKD18dIHQBUmD3ul_lu7MyQiT5gNdzn5JTXQvCcpf-oZE4',
-      encryption: 'salt=Czx2i18rar8XWOXAVDnUuw',
-      encoding: 'aesgcm128',
+      crypto_key: "dh=BMSqfc3ohqw2DDgu3nsMESagYGWubswQPGxrW1bAbYKD18dIHQBUmD3ul_lu7MyQiT5gNdzn5JTXQvCcpf-oZE4",
+      encryption: "salt=Czx2i18rar8XWOXAVDnUuw",
+      encoding: "aesgcm128",
     },
     expected: /Missing Encryption-Key header/,
   }, {
-    desc: 'Truncated input',
-    data: 'AlDjj6NvT5HGyrHbT8M5D6XBFSra6xrWS9B2ROaCIjwSu3RyZ1iyuv0',
+    desc: "Truncated input",
+    data: "AlDjj6NvT5HGyrHbT8M5D6XBFSra6xrWS9B2ROaCIjwSu3RyZ1iyuv0",
     privateKey: LEGACY_PRIVATE_KEY,
     publicKey: LEGACY_PUBLIC_KEY,
     headers: {
-      crypto_key: 'dh=BCHn-I-J3dfPRLJBlNZ3xFoAqaBLZ6qdhpaz9W7Q00JW1oD-hTxyEECn6KYJNK8AxKUyIDwn6Icx_PYWJiEYjQ0',
-      encryption: 'salt=c6JQl9eJ0VvwrUVCQDxY7Q; rs=25',
-      encoding: 'aesgcm128',
+      crypto_key: "dh=BCHn-I-J3dfPRLJBlNZ3xFoAqaBLZ6qdhpaz9W7Q00JW1oD-hTxyEECn6KYJNK8AxKUyIDwn6Icx_PYWJiEYjQ0",
+      encryption: "salt=c6JQl9eJ0VvwrUVCQDxY7Q; rs=25",
+      encoding: "aesgcm128",
     },
     expected: /Missing Encryption-Key header/,
   }, {
-    desc: 'Padding length > rs',
-    data: 'Ct_h1g7O55e6GvuhmpjLsGnv8Rmwvxgw8iDESNKGxk_8E99iHKDzdV8wJPyHA-6b2E6kzuVa5UWiQ7s4Zms1xzJ4FKgoxvBObXkc_r_d4mnb-j245z3AcvRmcYGk5_HZ0ci26SfhAN3lCgxGzTHS4nuHBRkGwOb4Tj4SFyBRlLoTh2jyVK2jYugNjH9tTrGOBg7lP5lajLTQlxOi91-RYZSfFhsLX3LrAkXuRoN7G1CdiI7Y3_eTgbPIPabDcLCnGzmFBTvoJSaQF17huMl_UnWoCj2WovA4BwK_TvWSbdgElNnQ4CbArJ1h9OqhDOphVu5GUGr94iitXRQR-fqKPMad0ULLjKQWZOnjuIdV1RYEZ873r62Yyd31HoveJcSDb1T8l_QK2zVF8V4k0xmK9hGuC0rF5YJPYPHgl5__usknzxMBnRrfV5_MOL5uPZwUEFsu',
+    desc: "Padding length > rs",
+    data: "Ct_h1g7O55e6GvuhmpjLsGnv8Rmwvxgw8iDESNKGxk_8E99iHKDzdV8wJPyHA-6b2E6kzuVa5UWiQ7s4Zms1xzJ4FKgoxvBObXkc_r_d4mnb-j245z3AcvRmcYGk5_HZ0ci26SfhAN3lCgxGzTHS4nuHBRkGwOb4Tj4SFyBRlLoTh2jyVK2jYugNjH9tTrGOBg7lP5lajLTQlxOi91-RYZSfFhsLX3LrAkXuRoN7G1CdiI7Y3_eTgbPIPabDcLCnGzmFBTvoJSaQF17huMl_UnWoCj2WovA4BwK_TvWSbdgElNnQ4CbArJ1h9OqhDOphVu5GUGr94iitXRQR-fqKPMad0ULLjKQWZOnjuIdV1RYEZ873r62Yyd31HoveJcSDb1T8l_QK2zVF8V4k0xmK9hGuC0rF5YJPYPHgl5__usknzxMBnRrfV5_MOL5uPZwUEFsu",
     privateKey: LEGACY_PRIVATE_KEY,
     publicKey: LEGACY_PUBLIC_KEY,
     headers: {
-      crypto_key: 'dh=BAcMdWLJRGx-kPpeFtwqR3GE1LWzd1TYh2rg6CEFu53O-y3DNLkNe_BtGtKRR4f7ZqpBMVS6NgfE2NwNPm3Ndls',
-      encryption: 'salt=NQVTKhB0rpL7ZzKkotTGlA; rs=1',
-      encoding: 'aesgcm128',
+      crypto_key: "dh=BAcMdWLJRGx-kPpeFtwqR3GE1LWzd1TYh2rg6CEFu53O-y3DNLkNe_BtGtKRR4f7ZqpBMVS6NgfE2NwNPm3Ndls",
+      encryption: "salt=NQVTKhB0rpL7ZzKkotTGlA; rs=1",
+      encoding: "aesgcm128",
     },
     expected: /Missing Encryption-Key header/,
   }];
   for (let test of expectedFailures) {
     await assertNotDecrypts(test, test.headers);
   }
 });
--- a/dom/push/test/xpcshell/test_crypto_encrypt.js
+++ b/dom/push/test/xpcshell/test_crypto_encrypt.js
@@ -2,40 +2,40 @@
 "use strict";
 
 Cu.importGlobalProperties(["crypto"]);
 
 const {PushCrypto} = ChromeUtils.import("resource://gre/modules/PushCrypto.jsm");
 
 let from64 = v => {
   // allow whitespace in the strings.
-  let stripped = v.replace(/ |\t|\r|\n/g, '');
+  let stripped = v.replace(/ |\t|\r|\n/g, "");
   return new Uint8Array(ChromeUtils.base64URLDecode(stripped, {padding: "reject"}));
-}
+};
 
 let to64 = v => ChromeUtils.base64URLEncode(v, {pad: false});
 
 // A helper function to take a public key (as a buffer containing a 65-byte
 // buffer of uncompressed EC points) and a private key (32byte buffer) and
 // return 2 crypto keys.
 async function importKeyPair(publicKeyBuffer, privateKeyBuffer) {
   let jwk = {
     kty: "EC",
     crv: "P-256",
     x: to64(publicKeyBuffer.slice(1, 33)),
     y: to64(publicKeyBuffer.slice(33, 65)),
     ext: true,
   };
-  let publicKey = await crypto.subtle.importKey('jwk', jwk,
-                                                { name: 'ECDH', namedCurve: 'P-256' },
+  let publicKey = await crypto.subtle.importKey("jwk", jwk,
+                                                { name: "ECDH", namedCurve: "P-256" },
                                                 true, []);
   jwk.d = to64(privateKeyBuffer);
-  let privateKey = await crypto.subtle.importKey('jwk', jwk,
-                                                 { name: 'ECDH', namedCurve: 'P-256' },
-                                                 true, ['deriveBits']);
+  let privateKey = await crypto.subtle.importKey("jwk", jwk,
+                                                 { name: "ECDH", namedCurve: "P-256" },
+                                                 true, ["deriveBits"]);
   return {publicKey, privateKey};
 }
 
 // The example from draft-ietf-webpush-encryption-09.
 add_task(async function static_aes128gcm() {
   let fixture = {
     ciphertext: from64(`DGv6ra1nlYgDCS1FRnbzlwAAEABBBP4z9KsN6nGRTbVYI_c7VJSPQTBtkgcy27ml
                         mlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A_yl95bQpu6cVPT
@@ -50,24 +50,20 @@ add_task(async function static_aes128gcm
     sender: {
       private: from64("yfWPiYE-n46HLnH0KqZOF1fJJU3MYrct3AELtAQ-oRw"),
       public: from64(`BP4z9KsN6nGRTbVYI_c7VJSPQTBtkgcy27mlmlMoZIIg
                       Dll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A8`),
     },
     salt: from64("DGv6ra1nlYgDCS1FRnbzlw"),
   };
 
-
-  let publicKeyBuffer = from64(`BP4z9KsN6nGRTbVYI_c7VJSPQTBtkgcy27mlmlMoZ
-                                IIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A8`);
-  let privateKeyBuffer = from64("yfWPiYE-n46HLnH0KqZOF1fJJU3MYrct3AELtAQ-oRw");
   let options = {
     senderKeyPair: await importKeyPair(fixture.sender.public, fixture.sender.private),
     salt: fixture.salt,
-  }
+  };
 
   let {ciphertext, encoding} = await PushCrypto.encrypt(fixture.plaintext,
                                                         fixture.receiver.public,
                                                         fixture.authSecret,
                                                         options);
 
   Assert.deepEqual(ciphertext, fixture.ciphertext);
   Assert.equal(encoding, "aes128gcm");
@@ -125,17 +121,17 @@ add_task(async function aes128gcm_rs() {
     deepEqual(message, plaintext);
   }
 });
 
 // And try and hit some edge-cases.
 add_task(async function aes128gcm_edgecases() {
   let [recvPublicKey, recvPrivateKey] = await PushCrypto.generateKeys();
 
-  for (let size of [0, 4096-16, 4096-16-1, 4096-16+1,
+  for (let size of [0, 4096 - 16, 4096 - 16 - 1, 4096 - 16 + 1,
                     4095, 4096, 4097, 10240]) {
     info(`testing encryption of ${size} byte payload`);
     let message = new TextEncoder("utf-8").encode("x".repeat(size));
     let authSecret = crypto.getRandomValues(new Uint8Array(16));
     let {ciphertext, encoding} = await PushCrypto.encrypt(message, recvPublicKey, authSecret);
     Assert.equal(encoding, "aes128gcm");
     // and decrypt it.
     let plaintext = await PushCrypto.decrypt(recvPrivateKey, recvPublicKey,
--- a/dom/push/test/xpcshell/test_drop_expired.js
+++ b/dom/push/test/xpcshell/test_drop_expired.js
@@ -1,154 +1,154 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-'use strict';
+"use strict";
 
 const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
 
-const userAgentID = '2c43af06-ab6e-476a-adc4-16cbda54fb89';
+const userAgentID = "2c43af06-ab6e-476a-adc4-16cbda54fb89";
 
 var db;
 var quotaURI;
 var permURI;
 
 function visitURI(uri, timestamp) {
   return PlacesTestUtils.addVisits({
-    uri: uri,
+    uri,
     title: uri.spec,
     visitDate: timestamp * 1000,
-    transition: Ci.nsINavHistoryService.TRANSITION_LINK
+    transition: Ci.nsINavHistoryService.TRANSITION_LINK,
   });
 }
 
 var putRecord = async function({scope, perm, quota, lastPush, lastVisit}) {
   let uri = Services.io.newURI(scope);
 
-  Services.perms.add(uri, 'desktop-notification',
+  Services.perms.add(uri, "desktop-notification",
     Ci.nsIPermissionManager[perm]);
   registerCleanupFunction(() => {
-    Services.perms.remove(uri, 'desktop-notification');
+    Services.perms.remove(uri, "desktop-notification");
   });
 
   await visitURI(uri, lastVisit);
 
   await db.put({
     channelID: uri.pathQueryRef,
-    pushEndpoint: 'https://example.org/push' + uri.pathQueryRef,
+    pushEndpoint: "https://example.org/push" + uri.pathQueryRef,
     scope: uri.spec,
     pushCount: 0,
-    lastPush: lastPush,
+    lastPush,
     version: null,
-    originAttributes: '',
-    quota: quota,
+    originAttributes: "",
+    quota,
   });
 
   return uri;
 };
 
 function run_test() {
   do_get_profile();
   setPrefs({
-    userAgentID: userAgentID,
+    userAgentID,
   });
 
   db = PushServiceWebSocket.newPushDB();
-  registerCleanupFunction(() => {return db.drop().then(_ => db.close());});
+  registerCleanupFunction(() => { return db.drop().then(_ => db.close()); });
 
   run_next_test();
 }
 
 add_task(async function setUp() {
   // An expired registration that should be evicted on startup. Permission is
   // granted for this origin, and the last visit is more recent than the last
   // push message.
   await putRecord({
-    scope: 'https://example.com/expired-quota-restored',
-    perm: 'ALLOW_ACTION',
+    scope: "https://example.com/expired-quota-restored",
+    perm: "ALLOW_ACTION",
     quota: 0,
     lastPush: Date.now() - 10,
     lastVisit: Date.now(),
   });
 
   // An expired registration that we should evict when the origin is visited
   // again.
   quotaURI = await putRecord({
-    scope: 'https://example.xyz/expired-quota-exceeded',
-    perm: 'ALLOW_ACTION',
+    scope: "https://example.xyz/expired-quota-exceeded",
+    perm: "ALLOW_ACTION",
     quota: 0,
     lastPush: Date.now() - 10,
     lastVisit: Date.now() - 20,
   });
 
   // An expired registration that we should evict when permission is granted
   // again.
   permURI = await putRecord({
-    scope: 'https://example.info/expired-perm-revoked',
-    perm: 'DENY_ACTION',
+    scope: "https://example.info/expired-perm-revoked",
+    perm: "DENY_ACTION",
     quota: 0,
     lastPush: Date.now() - 10,
     lastVisit: Date.now(),
   });
 
   // An active registration that we should leave alone.
   await putRecord({
-    scope: 'https://example.ninja/active',
-    perm: 'ALLOW_ACTION',
+    scope: "https://example.ninja/active",
+    perm: "ALLOW_ACTION",
     quota: 16,
     lastPush: Date.now() - 10,
     lastVisit: Date.now() - 20,
   });
 
   let subChangePromise = promiseObserverNotification(
     PushServiceComponent.subscriptionChangeTopic,
-    (subject, data) => data == 'https://example.com/expired-quota-restored'
+    (subject, data) => data == "https://example.com/expired-quota-restored"
   );
 
   PushService.init({
-    serverURI: 'wss://push.example.org/',
+    serverURI: "wss://push.example.org/",
     db,
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(request) {
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             status: 200,
             uaid: userAgentID,
           }));
         },
         onUnregister(request) {
           this.serverSendMsg(JSON.stringify({
-            messageType: 'unregister',
+            messageType: "unregister",
             channelID: request.channelID,
             status: 200,
           }));
         },
       });
     },
   });
 
   await subChangePromise;
 });
 
 add_task(async function test_site_visited() {
   let subChangePromise = promiseObserverNotification(
     PushServiceComponent.subscriptionChangeTopic,
-    (subject, data) => data == 'https://example.xyz/expired-quota-exceeded'
+    (subject, data) => data == "https://example.xyz/expired-quota-exceeded"
   );
 
   await visitURI(quotaURI, Date.now());
-  PushService.observe(null, 'idle-daily', '');
+  PushService.observe(null, "idle-daily", "");
 
   await subChangePromise;
 });
 
 add_task(async function test_perm_restored() {
   let subChangePromise = promiseObserverNotification(
     PushServiceComponent.subscriptionChangeTopic,
-    (subject, data) => data == 'https://example.info/expired-perm-revoked'
+    (subject, data) => data == "https://example.info/expired-perm-revoked"
   );
 
-  Services.perms.add(permURI, 'desktop-notification',
+  Services.perms.add(permURI, "desktop-notification",
     Ci.nsIPermissionManager.ALLOW_ACTION);
 
   await subChangePromise;
 });
--- a/dom/push/test/xpcshell/test_notification_ack.js
+++ b/dom/push/test/xpcshell/test_notification_ack.js
@@ -1,47 +1,47 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-'use strict';
+"use strict";
 
 const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
 
-var userAgentID = '5ab1d1df-7a3d-4024-a469-b9e1bb399fad';
+var userAgentID = "5ab1d1df-7a3d-4024-a469-b9e1bb399fad";
 
 function run_test() {
   do_get_profile();
   setPrefs({userAgentID});
   run_next_test();
 }
 
 add_task(async function test_notification_ack() {
   let db = PushServiceWebSocket.newPushDB();
-  registerCleanupFunction(() => {return db.drop().then(_ => db.close());});
+  registerCleanupFunction(() => { return db.drop().then(_ => db.close()); });
   let records = [{
-    channelID: '21668e05-6da8-42c9-b8ab-9cc3f4d5630c',
-    pushEndpoint: 'https://example.com/update/1',
-    scope: 'https://example.org/1',
-    originAttributes: '',
+    channelID: "21668e05-6da8-42c9-b8ab-9cc3f4d5630c",
+    pushEndpoint: "https://example.com/update/1",
+    scope: "https://example.org/1",
+    originAttributes: "",
     version: 1,
     quota: Infinity,
     systemRecord: true,
   }, {
-    channelID: '9a5ff87f-47c9-4215-b2b8-0bdd38b4b305',
-    pushEndpoint: 'https://example.com/update/2',
-    scope: 'https://example.org/2',
-    originAttributes: '',
+    channelID: "9a5ff87f-47c9-4215-b2b8-0bdd38b4b305",
+    pushEndpoint: "https://example.com/update/2",
+    scope: "https://example.org/2",
+    originAttributes: "",
     version: 2,
     quota: Infinity,
     systemRecord: true,
   }, {
-    channelID: '5477bfda-22db-45d4-9614-fee369630260',
-    pushEndpoint: 'https://example.com/update/3',
-    scope: 'https://example.org/3',
-    originAttributes: '',
+    channelID: "5477bfda-22db-45d4-9614-fee369630260",
+    pushEndpoint: "https://example.com/update/3",
+    scope: "https://example.org/3",
+    originAttributes: "",
     version: 3,
     quota: Infinity,
     systemRecord: true,
   }];
   for (let record of records) {
     await db.put(record);
   }
 
@@ -54,72 +54,72 @@ add_task(async function test_notificatio
   let ackPromise = new Promise(resolve => ackDone = resolve);
   PushService.init({
     serverURI: "wss://push.example.org/",
     db,
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(request) {
           equal(request.uaid, userAgentID,
-            'Should send matching device IDs in handshake');
+            "Should send matching device IDs in handshake");
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             uaid: userAgentID,
-            status: 200
+            status: 200,
           }));
           this.serverSendMsg(JSON.stringify({
-            messageType: 'notification',
+            messageType: "notification",
             updates: [{
-              channelID: '21668e05-6da8-42c9-b8ab-9cc3f4d5630c',
-              version: 2
-            }]
+              channelID: "21668e05-6da8-42c9-b8ab-9cc3f4d5630c",
+              version: 2,
+            }],
           }));
         },
         onACK(request) {
-          equal(request.messageType, 'ack', 'Should send acknowledgements');
+          equal(request.messageType, "ack", "Should send acknowledgements");
           let updates = request.updates;
           switch (++acks) {
           case 1:
             deepEqual([{
-              channelID: '21668e05-6da8-42c9-b8ab-9cc3f4d5630c',
+              channelID: "21668e05-6da8-42c9-b8ab-9cc3f4d5630c",
               version: 2,
               code: 100,
-            }], updates, 'Wrong updates for acknowledgement 1');
+            }], updates, "Wrong updates for acknowledgement 1");
             this.serverSendMsg(JSON.stringify({
-              messageType: 'notification',
+              messageType: "notification",
               updates: [{
-                channelID: '9a5ff87f-47c9-4215-b2b8-0bdd38b4b305',
-                version: 4
+                channelID: "9a5ff87f-47c9-4215-b2b8-0bdd38b4b305",
+                version: 4,
               }, {
-                channelID: '5477bfda-22db-45d4-9614-fee369630260',
-                version: 6
-              }]
+                channelID: "5477bfda-22db-45d4-9614-fee369630260",
+                version: 6,
+              }],
             }));
             break;
 
           case 2:
             deepEqual([{
-              channelID: '9a5ff87f-47c9-4215-b2b8-0bdd38b4b305',
+              channelID: "9a5ff87f-47c9-4215-b2b8-0bdd38b4b305",
               version: 4,
               code: 100,
-            }], updates, 'Wrong updates for acknowledgement 2');
+            }], updates, "Wrong updates for acknowledgement 2");
             break;
 
           case 3:
             deepEqual([{
-              channelID: '5477bfda-22db-45d4-9614-fee369630260',
+              channelID: "5477bfda-22db-45d4-9614-fee369630260",
               version: 6,
               code: 100,
-            }], updates, 'Wrong updates for acknowledgement 3');
+            }], updates, "Wrong updates for acknowledgement 3");
             ackDone();
             break;
 
           default:
-            ok(false, 'Unexpected acknowledgement ' + acks);
+            ok(false, "Unexpected acknowledgement " + acks);
           }
-        }
+        },
       });
-    }
+    },
   });
 
   await notifyPromise;
   await ackPromise;
 });
--- a/dom/push/test/xpcshell/test_notification_data.js
+++ b/dom/push/test/xpcshell/test_notification_data.js
@@ -1,277 +1,277 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-'use strict';
+"use strict";
 
 const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
 
 let db;
-let userAgentID = 'f5b47f8d-771f-4ea3-b999-91c135f8766d';
+let userAgentID = "f5b47f8d-771f-4ea3-b999-91c135f8766d";
 
 function run_test() {
   do_get_profile();
   setPrefs({
-    userAgentID: userAgentID,
+    userAgentID,
   });
   run_next_test();
 }
 
 function putRecord(channelID, scope, publicKey, privateKey, authSecret) {
   return db.put({
-    channelID: channelID,
-    pushEndpoint: 'https://example.org/push/' + channelID,
-    scope: scope,
+    channelID,
+    pushEndpoint: "https://example.org/push/" + channelID,
+    scope,
     pushCount: 0,
     lastPush: 0,
-    originAttributes: '',
+    originAttributes: "",
     quota: Infinity,
     systemRecord: true,
     p256dhPublicKey: ChromeUtils.base64URLDecode(publicKey, {
       padding: "reject",
     }),
     p256dhPrivateKey: privateKey,
     authenticationSecret: ChromeUtils.base64URLDecode(authSecret, {
       padding: "reject",
     }),
   });
 }
 
 let ackDone;
 let server;
 add_task(async function test_notification_ack_data_setup() {
   db = PushServiceWebSocket.newPushDB();
-  registerCleanupFunction(() => {return db.drop().then(_ => db.close());});
+  registerCleanupFunction(() => { return db.drop().then(_ => db.close()); });
 
   await putRecord(
-    'subscription1',
-    'https://example.com/page/1',
-    'BPCd4gNQkjwRah61LpdALdzZKLLnU5UAwDztQ5_h0QsT26jk0IFbqcK6-JxhHAm-rsHEwy0CyVJjtnfOcqc1tgA',
+    "subscription1",
+    "https://example.com/page/1",
+    "BPCd4gNQkjwRah61LpdALdzZKLLnU5UAwDztQ5_h0QsT26jk0IFbqcK6-JxhHAm-rsHEwy0CyVJjtnfOcqc1tgA",
     {
-      crv: 'P-256',
-      d: '1jUPhzVsRkzV0vIzwL4ZEsOlKdNOWm7TmaTfzitJkgM',
+      crv: "P-256",
+      d: "1jUPhzVsRkzV0vIzwL4ZEsOlKdNOWm7TmaTfzitJkgM",
       ext: true,
       key_ops: ["deriveBits"],
       kty: "EC",
-      x: '8J3iA1CSPBFqHrUul0At3NkosudTlQDAPO1Dn-HRCxM',
-      y: '26jk0IFbqcK6-JxhHAm-rsHEwy0CyVJjtnfOcqc1tgA'
+      x: "8J3iA1CSPBFqHrUul0At3NkosudTlQDAPO1Dn-HRCxM",
+      y: "26jk0IFbqcK6-JxhHAm-rsHEwy0CyVJjtnfOcqc1tgA",
     },
-    'c_sGN6uCv9Hu7JOQT34jAQ'
+    "c_sGN6uCv9Hu7JOQT34jAQ"
   );
   await putRecord(
-    'subscription2',
-    'https://example.com/page/2',
-    'BPnWyUo7yMnuMlyKtERuLfWE8a09dtdjHSW2lpC9_BqR5TZ1rK8Ldih6ljyxVwnBA-nygQHGRpEmu1jV5K8437E',
+    "subscription2",
+    "https://example.com/page/2",
+    "BPnWyUo7yMnuMlyKtERuLfWE8a09dtdjHSW2lpC9_BqR5TZ1rK8Ldih6ljyxVwnBA-nygQHGRpEmu1jV5K8437E",
     {
-      crv: 'P-256',
-      d: 'lFm4nPsUKYgNGBJb5nXXKxl8bspCSp0bAhCYxbveqT4',
+      crv: "P-256",
+      d: "lFm4nPsUKYgNGBJb5nXXKxl8bspCSp0bAhCYxbveqT4",
       ext: true,
       key_ops: ["deriveBits"],
-      kty: 'EC',
-      x: '-dbJSjvIye4yXIq0RG4t9YTxrT1212MdJbaWkL38GpE',
-      y: '5TZ1rK8Ldih6ljyxVwnBA-nygQHGRpEmu1jV5K8437E'
+      kty: "EC",
+      x: "-dbJSjvIye4yXIq0RG4t9YTxrT1212MdJbaWkL38GpE",
+      y: "5TZ1rK8Ldih6ljyxVwnBA-nygQHGRpEmu1jV5K8437E",
     },
-    't3P246Gj9vjKDHHRYaY6hw'
+    "t3P246Gj9vjKDHHRYaY6hw"
   );
   await putRecord(
-    'subscription3',
-    'https://example.com/page/3',
-    'BDhUHITSeVrWYybFnb7ylVTCDDLPdQWMpf8gXhcWwvaaJa6n3YH8TOcH8narDF6t8mKVvg2ioLW-8MH5O4dzGcI',
+    "subscription3",
+    "https://example.com/page/3",
+    "BDhUHITSeVrWYybFnb7ylVTCDDLPdQWMpf8gXhcWwvaaJa6n3YH8TOcH8narDF6t8mKVvg2ioLW-8MH5O4dzGcI",
     {
-      crv: 'P-256',
-      d: 'Q1_SE1NySTYzjbqgWwPgrYh7XRg3adqZLkQPsy319G8',
+      crv: "P-256",
+      d: "Q1_SE1NySTYzjbqgWwPgrYh7XRg3adqZLkQPsy319G8",
       ext: true,
       key_ops: ["deriveBits"],
-      kty: 'EC',
-      x: 'OFQchNJ5WtZjJsWdvvKVVMIMMs91BYyl_yBeFxbC9po',
-      y: 'Ja6n3YH8TOcH8narDF6t8mKVvg2ioLW-8MH5O4dzGcI'
+      kty: "EC",
+      x: "OFQchNJ5WtZjJsWdvvKVVMIMMs91BYyl_yBeFxbC9po",
+      y: "Ja6n3YH8TOcH8narDF6t8mKVvg2ioLW-8MH5O4dzGcI",
     },
-    'E0qiXGWvFSR0PS352ES1_Q'
+    "E0qiXGWvFSR0PS352ES1_Q"
   );
 
   let setupDone;
   let setupDonePromise = new Promise(r => setupDone = r);
 
   PushService.init({
     serverURI: "wss://push.example.org/",
     db,
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(request) {
           equal(request.uaid, userAgentID,
-                'Should send matching device IDs in handshake');
+                "Should send matching device IDs in handshake");
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             uaid: userAgentID,
             status: 200,
             use_webpush: true,
           }));
           server = this;
           setupDone();
         },
         onACK(request) {
           if (ackDone) {
             ackDone(request);
           }
-        }
+        },
       });
-    }
+    },
   });
   await setupDonePromise;
 });
 
 add_task(async function test_notification_ack_data() {
   let allTestData = [
     {
-      channelID: 'subscription1',
-      version: 'v1',
+      channelID: "subscription1",
+      version: "v1",
       send: {
         headers: {
           encryption_key: 'keyid="notification1"; dh="BO_tgGm-yvYAGLeRe16AvhzaUcpYRiqgsGOlXpt0DRWDRGGdzVLGlEVJMygqAUECarLnxCiAOHTP_znkedrlWoU"',
           encryption: 'keyid="notification1";salt="uAZaiXpOSfOLJxtOCZ09dA"',
-          encoding: 'aesgcm128',
+          encoding: "aesgcm128",
         },
-        data: 'NwrrOWPxLE8Sv5Rr0Kep7n0-r_j3rsYrUw_CXPo',
-        version: 'v1',
+        data: "NwrrOWPxLE8Sv5Rr0Kep7n0-r_j3rsYrUw_CXPo",
+        version: "v1",
       },
       ackCode: 100,
       receive: {
-        scope: 'https://example.com/page/1',
-        data: 'Some message'
-      }
+        scope: "https://example.com/page/1",
+        data: "Some message",
+      },
     },
     {
-      channelID: 'subscription2',
-      version: 'v2',
+      channelID: "subscription2",
+      version: "v2",
       send: {
         headers: {
           encryption_key: 'keyid="notification2"; dh="BKVdQcgfncpNyNWsGrbecX0zq3eHIlHu5XbCGmVcxPnRSbhjrA6GyBIeGdqsUL69j5Z2CvbZd-9z1UBH0akUnGQ"',
           encryption: 'keyid="notification2";salt="vFn3t3M_k42zHBdpch3VRw"',
-          encoding: 'aesgcm128',
+          encoding: "aesgcm128",
         },
-        data: 'Zt9dEdqgHlyAL_l83385aEtb98ZBilz5tgnGgmwEsl5AOCNgesUUJ4p9qUU',
+        data: "Zt9dEdqgHlyAL_l83385aEtb98ZBilz5tgnGgmwEsl5AOCNgesUUJ4p9qUU",
       },
       ackCode: 100,
       receive: {
-        scope: 'https://example.com/page/2',
-        data: 'Some message'
-      }
+        scope: "https://example.com/page/2",
+        data: "Some message",
+      },
     },
     {
-      channelID: 'subscription3',
-      version: 'v3',
+      channelID: "subscription3",
+      version: "v3",
       send: {
         headers: {
           encryption_key: 'keyid="notification3";dh="BD3xV_ACT8r6hdIYES3BJj1qhz9wyv7MBrG9vM2UCnjPzwE_YFVpkD-SGqE-BR2--0M-Yf31wctwNsO1qjBUeMg"',
           encryption: 'keyid="notification3"; salt="DFq188piWU7osPBgqn4Nlg"; rs=24',
-          encoding: 'aesgcm128',
+          encoding: "aesgcm128",
         },
-        data: 'LKru3ZzxBZuAxYtsaCfaj_fehkrIvqbVd1iSwnwAUgnL-cTeDD-83blxHXTq7r0z9ydTdMtC3UjAcWi8LMnfY-BFzi0qJAjGYIikDA',
+        data: "LKru3ZzxBZuAxYtsaCfaj_fehkrIvqbVd1iSwnwAUgnL-cTeDD-83blxHXTq7r0z9ydTdMtC3UjAcWi8LMnfY-BFzi0qJAjGYIikDA",
       },
       ackCode: 100,
       receive: {
-        scope: 'https://example.com/page/3',
-        data: 'Some message'
-      }
+        scope: "https://example.com/page/3",
+        data: "Some message",
+      },
     },
     // A message encoded with `aesgcm` (2 bytes of padding, authenticated).
     {
-      channelID: 'subscription1',
-      version: 'v5',
+      channelID: "subscription1",
+      version: "v5",
       send: {
         headers: {
           crypto_key: 'keyid=v4;dh="BMh_vsnqu79ZZkMTYkxl4gWDLdPSGE72Lr4w2hksSFW398xCMJszjzdblAWXyhSwakRNEU_GopAm4UGzyMVR83w"',
           encryption: 'keyid="v4";salt="C14Wb7rQTlXzrgcPHtaUzw"',
-          encoding: 'aesgcm',
+          encoding: "aesgcm",
         },
-        data: 'pus4kUaBWzraH34M-d_oN8e0LPpF_X6acx695AMXovDe',
+        data: "pus4kUaBWzraH34M-d_oN8e0LPpF_X6acx695AMXovDe",
       },
       ackCode: 100,
       receive: {
-        scope: 'https://example.com/page/1',
-        data: 'Another message'
-      }
+        scope: "https://example.com/page/1",
+        data: "Another message",
+      },
     },
     // A message with 17 bytes of padding and rs of 24
     {
-      channelID: 'subscription2',
-      version: 'v5',
+      channelID: "subscription2",
+      version: "v5",
       send: {
         headers: {
           crypto_key: 'keyid="v5"; dh="BOp-DpyR9eLY5Ci11_loIFqeHzWfc_0evJmq7N8NKzgp60UAMMM06XIi2VZp2_TSdw1omk7E19SyeCCwRp76E-U"',
           encryption: 'keyid=v5;salt="TvjOou1TqJOQY_ZsOYV3Ww";rs=24',
-          encoding: 'aesgcm',
+          encoding: "aesgcm",
         },
-        data: 'rG9WYQ2ZwUgfj_tMlZ0vcIaNpBN05FW-9RUBZAM-UUZf0_9eGpuENBpUDAw3mFmd2XJpmvPvAtLVs54l3rGwg1o',
+        data: "rG9WYQ2ZwUgfj_tMlZ0vcIaNpBN05FW-9RUBZAM-UUZf0_9eGpuENBpUDAw3mFmd2XJpmvPvAtLVs54l3rGwg1o",
       },
       ackCode: 100,
       receive: {
-        scope: 'https://example.com/page/2',
-        data: 'Some message'
-      }
+        scope: "https://example.com/page/2",
+        data: "Some message",
+      },
     },
     // A message without key identifiers.
     {
-      channelID: 'subscription3',
-      version: 'v6',
+      channelID: "subscription3",
+      version: "v6",
       send: {
         headers: {
           crypto_key: 'dh="BEEjwWbF5jZKCgW0kmUWgG-wNcRvaa9_3zZElHAF8przHwd4cp5_kQsc-IMNZcVA0iUix31jxuMOytU-5DwWtyQ"',
-          encryption: 'salt=aAQcr2khAksgNspPiFEqiQ',
-          encoding: 'aesgcm',
+          encryption: "salt=aAQcr2khAksgNspPiFEqiQ",
+          encoding: "aesgcm",
         },
-        data: 'pEYgefdI-7L46CYn5dR9TIy2AXGxe07zxclbhstY',
+        data: "pEYgefdI-7L46CYn5dR9TIy2AXGxe07zxclbhstY",
       },
       ackCode: 100,
       receive: {
-        scope: 'https://example.com/page/3',
-        data: 'Some message'
-      }
+        scope: "https://example.com/page/3",
+        data: "Some message",
+      },
     },
     // A malformed encrypted message.
     {
-      channelID: 'subscription3',
-      version: 'v7',
+      channelID: "subscription3",
+      version: "v7",
       send: {
         headers: {
-          crypto_key: 'dh=AAAAAAAA',
-          encryption: 'salt=AAAAAAAA',
+          crypto_key: "dh=AAAAAAAA",
+          encryption: "salt=AAAAAAAA",
         },
-        data: 'AAAAAAAA',
+        data: "AAAAAAAA",
       },
       ackCode: 101,
       receive: null,
     },
   ];
 
   let sendAndReceive = testData => {
     let messageReceived = testData.receive ? promiseObserverNotification(PushServiceComponent.pushTopic, (subject, data) => {
       let notification = subject.QueryInterface(Ci.nsIPushMessage).data;
       equal(notification.text(), testData.receive.data,
-            'Check data for notification ' + testData.version);
+            "Check data for notification " + testData.version);
       equal(data, testData.receive.scope,
-            'Check scope for notification ' + testData.version);
+            "Check scope for notification " + testData.version);
       return true;
     }) : Promise.resolve();
 
     let ackReceived = new Promise(resolve => ackDone = resolve)
         .then(ackData => {
           deepEqual({
-            messageType: 'ack',
+            messageType: "ack",
             updates: [{
               channelID: testData.channelID,
               version: testData.version,
               code: testData.ackCode,
             }],
-          }, ackData, 'Check updates for acknowledgment ' + testData.version);
+          }, ackData, "Check updates for acknowledgment " + testData.version);
         });
 
     let msg = JSON.parse(JSON.stringify(testData.send));
-    msg.messageType = 'notification';
+    msg.messageType = "notification";
     msg.channelID = testData.channelID;
     msg.version = testData.version;
     server.serverSendMsg(JSON.stringify(msg));
 
     return Promise.all([messageReceived, ackReceived]);
   };
 
   await allTestData.reduce((p, testData) => {
--- a/dom/push/test/xpcshell/test_notification_duplicate.js
+++ b/dom/push/test/xpcshell/test_notification_duplicate.js
@@ -1,88 +1,88 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-'use strict';
+"use strict";
 
 const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
 
-const userAgentID = '1500e7d9-8cbe-4ee6-98da-7fa5d6a39852';
+const userAgentID = "1500e7d9-8cbe-4ee6-98da-7fa5d6a39852";
 
 function run_test() {
   do_get_profile();
   setPrefs({
     maxRecentMessageIDsPerSubscription: 4,
-    userAgentID: userAgentID,
+    userAgentID,
   });
   run_next_test();
 }
 
 // Should acknowledge duplicate notifications, but not notify apps.
 add_task(async function test_notification_duplicate() {
   let db = PushServiceWebSocket.newPushDB();
-  registerCleanupFunction(() => {return db.drop().then(_ => db.close());});
+  registerCleanupFunction(() => { return db.drop().then(_ => db.close()); });
   let records = [{
-    channelID: 'has-recents',
-    pushEndpoint: 'https://example.org/update/1',
-    scope: 'https://example.com/1',
+    channelID: "has-recents",
+    pushEndpoint: "https://example.org/update/1",
+    scope: "https://example.com/1",
     originAttributes: "",
-    recentMessageIDs: ['dupe'],
+    recentMessageIDs: ["dupe"],
     quota: Infinity,
     systemRecord: true,
   }, {
-    channelID: 'no-recents',
-    pushEndpoint: 'https://example.org/update/2',
-    scope: 'https://example.com/2',
+    channelID: "no-recents",
+    pushEndpoint: "https://example.org/update/2",
+    scope: "https://example.com/2",
     originAttributes: "",
     quota: Infinity,
     systemRecord: true,
   }, {
-    channelID: 'dropped-recents',
-    pushEndpoint: 'https://example.org/update/3',
-    scope: 'https://example.com/3',
-    originAttributes: '',
-    recentMessageIDs: ['newest', 'newer', 'older', 'oldest'],
+    channelID: "dropped-recents",
+    pushEndpoint: "https://example.org/update/3",
+    scope: "https://example.com/3",
+    originAttributes: "",
+    recentMessageIDs: ["newest", "newer", "older", "oldest"],
     quota: Infinity,
     systemRecord: true,
   }];
   for (let record of records) {
     await db.put(record);
   }
 
   let testData = [{
-    channelID: 'has-recents',
+    channelID: "has-recents",
     updates: 1,
     acks: [{
-      version: 'dupe',
+      version: "dupe",
       code: 102,
     }, {
-      version: 'not-dupe',
+      version: "not-dupe",
       code: 100,
     }],
-    recents: ['not-dupe', 'dupe'],
+    recents: ["not-dupe", "dupe"],
   }, {
-    channelID: 'no-recents',
+    channelID: "no-recents",
     updates: 1,
     acks: [{
-      version: 'not-dupe',
+      version: "not-dupe",
       code: 100,
     }],
-    recents: ['not-dupe'],
+    recents: ["not-dupe"],
   }, {
-    channelID: 'dropped-recents',
+    channelID: "dropped-recents",
     acks: [{
-      version: 'overflow',
+      version: "overflow",
       code: 100,
     }, {
-      version: 'oldest',
+      version: "oldest",
       code: 100,
     }],
     updates: 2,
-    recents: ['oldest', 'overflow', 'newest', 'newer'],
+    recents: ["oldest", "overflow", "newest", "newer"],
   }];
 
   let expectedUpdates = testData.reduce((sum, {updates}) => sum + updates, 0);
   let notifiedScopes = [];
   let notifyPromise = promiseObserverNotification(PushServiceComponent.pushTopic, (subject, data) => {
     notifiedScopes.push(data);
     return notifiedScopes.length == expectedUpdates;
   });
@@ -92,46 +92,45 @@ add_task(async function test_notificatio
   let ackPromise = new Promise(resolve => ackDone = after(expectedAcks, resolve));
   PushService.init({
     serverURI: "wss://push.example.org/",
     db,
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(request) {
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             status: 200,
             uaid: userAgentID,
             use_webpush: true,
           }));
           for (let {channelID, acks} of testData) {
             for (let {version} of acks) {
               this.serverSendMsg(JSON.stringify({
-                messageType: 'notification',
-                channelID: channelID,
-                version: version,
-              }))
+                messageType: "notification",
+                channelID,
+                version,
+              }));
             }
           }
         },
         onACK(request) {
           let [ack] = request.updates;
           let expectedData = testData.find(test =>
             test.channelID == ack.channelID);
           ok(expectedData, `Unexpected channel ${ack.channelID}`);
-          let expectedAck = expectedData.acks.find(expectedAck =>
-            expectedAck.version == ack.version);
+          let expectedAck = expectedData.acks.find(a => a.version == ack.version);
           ok(expectedAck, `Unexpected ack for message ${
             ack.version} on ${ack.channelID}`);
           equal(expectedAck.code, ack.code, `Wrong ack status for message ${
             ack.version} on ${ack.channelID}`);
           ackDone();
         },
       });
-    }
+    },
   });
 
   await notifyPromise;
   await ackPromise;
 
   for (let {channelID, recents} of testData) {
     let record = await db.getByKeyID(channelID);
     deepEqual(record.recentMessageIDs, recents,
--- a/dom/push/test/xpcshell/test_notification_error.js
+++ b/dom/push/test/xpcshell/test_notification_error.js
@@ -1,51 +1,51 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-'use strict';
+"use strict";
 
 const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
 
-const userAgentID = '3c7462fc-270f-45be-a459-b9d631b0d093';
+const userAgentID = "3c7462fc-270f-45be-a459-b9d631b0d093";
 
 function run_test() {
   do_get_profile();
   setPrefs({
-    userAgentID: userAgentID,
+    userAgentID,
   });
   run_next_test();
 }
 
 add_task(async function test_notification_error() {
   let db = PushServiceWebSocket.newPushDB();
-  registerCleanupFunction(() => {return db.drop().then(_ => db.close());});
+  registerCleanupFunction(() => { return db.drop().then(_ => db.close()); });
 
-  let originAttributes = '';
+  let originAttributes = "";
   let records = [{
-    channelID: 'f04f1e46-9139-4826-b2d1-9411b0821283',
-    pushEndpoint: 'https://example.org/update/success-1',
-    scope: 'https://example.com/a',
-    originAttributes: originAttributes,
+    channelID: "f04f1e46-9139-4826-b2d1-9411b0821283",
+    pushEndpoint: "https://example.org/update/success-1",
+    scope: "https://example.com/a",
+    originAttributes,
     version: 1,
     quota: Infinity,
     systemRecord: true,
   }, {
-    channelID: '3c3930ba-44de-40dc-a7ca-8a133ec1a866',
-    pushEndpoint: 'https://example.org/update/error',
-    scope: 'https://example.com/b',
-    originAttributes: originAttributes,
+    channelID: "3c3930ba-44de-40dc-a7ca-8a133ec1a866",
+    pushEndpoint: "https://example.org/update/error",
+    scope: "https://example.com/b",
+    originAttributes,
     version: 2,
     quota: Infinity,
     systemRecord: true,
   }, {
-    channelID: 'b63f7bef-0a0d-4236-b41e-086a69dfd316',
-    pushEndpoint: 'https://example.org/update/success-2',
-    scope: 'https://example.com/c',
-    originAttributes: originAttributes,
+    channelID: "b63f7bef-0a0d-4236-b41e-086a69dfd316",
+    pushEndpoint: "https://example.org/update/success-2",
+    scope: "https://example.com/c",
+    originAttributes,
     version: 3,
     quota: Infinity,
     systemRecord: true,
   }];
   for (let record of records) {
     await db.put(record);
   }
 
@@ -54,64 +54,64 @@ add_task(async function test_notificatio
     scopes.push(data) == 2);
 
   let ackDone;
   let ackPromise = new Promise(resolve => ackDone = after(records.length, resolve));
   PushService.init({
     serverURI: "wss://push.example.org/",
     db: makeStub(db, {
       getByKeyID(prev, channelID) {
-        if (channelID == '3c3930ba-44de-40dc-a7ca-8a133ec1a866') {
-          return Promise.reject('splines not reticulated');
+        if (channelID == "3c3930ba-44de-40dc-a7ca-8a133ec1a866") {
+          return Promise.reject("splines not reticulated");
         }
         return prev.call(this, channelID);
-      }
+      },
     }),
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(request) {
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             status: 200,
             uaid: userAgentID,
           }));
           this.serverSendMsg(JSON.stringify({
-            messageType: 'notification',
+            messageType: "notification",
             updates: records.map(({channelID, version}) =>
-              ({channelID, version: ++version}))
+              ({channelID, version: ++version})),
           }));
         },
         // Should acknowledge all received updates, even if updating
         // IndexedDB fails.
-        onACK: ackDone
+        onACK: ackDone,
       });
-    }
+    },
   });
 
   await notifyPromise;
-  ok(scopes.includes('https://example.com/a'),
-    'Missing scope for notification A');
-  ok(scopes.includes('https://example.com/c'),
-    'Missing scope for notification C');
+  ok(scopes.includes("https://example.com/a"),
+    "Missing scope for notification A");
+  ok(scopes.includes("https://example.com/c"),
+    "Missing scope for notification C");
 
   await ackPromise;
 
-  let aRecord = await db.getByIdentifiers({scope: 'https://example.com/a',
-                                           originAttributes: originAttributes });
-  equal(aRecord.channelID, 'f04f1e46-9139-4826-b2d1-9411b0821283',
-    'Wrong channel ID for record A');
+  let aRecord = await db.getByIdentifiers({scope: "https://example.com/a",
+                                           originAttributes });
+  equal(aRecord.channelID, "f04f1e46-9139-4826-b2d1-9411b0821283",
+    "Wrong channel ID for record A");
   strictEqual(aRecord.version, 2,
-    'Should return the new version for record A');
+    "Should return the new version for record A");
 
-  let bRecord = await db.getByIdentifiers({scope: 'https://example.com/b',
-                                           originAttributes: originAttributes });
-  equal(bRecord.channelID, '3c3930ba-44de-40dc-a7ca-8a133ec1a866',
-    'Wrong channel ID for record B');
+  let bRecord = await db.getByIdentifiers({scope: "https://example.com/b",
+                                           originAttributes });
+  equal(bRecord.channelID, "3c3930ba-44de-40dc-a7ca-8a133ec1a866",
+    "Wrong channel ID for record B");
   strictEqual(bRecord.version, 2,
-    'Should return the previous version for record B');
+    "Should return the previous version for record B");
 
-  let cRecord = await db.getByIdentifiers({scope: 'https://example.com/c',
-                                           originAttributes: originAttributes });
-  equal(cRecord.channelID, 'b63f7bef-0a0d-4236-b41e-086a69dfd316',
-    'Wrong channel ID for record C');
+  let cRecord = await db.getByIdentifiers({scope: "https://example.com/c",
+                                           originAttributes });
+  equal(cRecord.channelID, "b63f7bef-0a0d-4236-b41e-086a69dfd316",
+    "Wrong channel ID for record C");
   strictEqual(cRecord.version, 4,
-    'Should return the new version for record C');
+    "Should return the new version for record C");
 });
--- a/dom/push/test/xpcshell/test_notification_http2.js
+++ b/dom/push/test/xpcshell/test_notification_http2.js
@@ -1,43 +1,38 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-'use strict';
+"use strict";
 
 const {PushDB, PushService, PushServiceHttp2} = serviceExports;
 
-var prefs;
-
 var serverPort = -1;
 
 function run_test() {
   serverPort = getTestServerPort();
 
   do_get_profile();
   setPrefs({
-    'testing.allowInsecureServerURL': true,
+    "testing.allowInsecureServerURL": true,
   });
-  prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
-
   // Set to allow the cert presented by our H2 server
-  var oldPref = prefs.getIntPref("network.http.speculative-parallel-limit");
-  prefs.setIntPref("network.http.speculative-parallel-limit", 0);
-  prefs.setBoolPref("dom.push.enabled", true);
-  prefs.setBoolPref("dom.push.connection.enabled", true);
+  var oldPref = Services.prefs.getIntPref("network.http.speculative-parallel-limit");
+  Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
+  Services.prefs.setBoolPref("dom.push.enabled", true);
+  Services.prefs.setBoolPref("dom.push.connection.enabled", true);
 
   trustHttp2CA();
 
-  prefs.setIntPref("network.http.speculative-parallel-limit", oldPref);
+  Services.prefs.setIntPref("network.http.speculative-parallel-limit", oldPref);
 
   run_next_test();
 }
 
 add_task(async function test_pushNotifications() {
-
   // /pushNotifications/subscription1 will send a message with no rs and padding
   // length 1.
   // /pushNotifications/subscription2 will send a message with no rs and padding
   // length 16.
   // /pushNotifications/subscription3 will send a message with rs equal 24 and
   // padding length 16.
   // /pushNotifications/subscription4 will send a message with no rs and padding
   // length 256.
@@ -45,132 +40,136 @@ add_task(async function test_pushNotific
   let db = PushServiceHttp2.newPushDB();
   registerCleanupFunction(() => {
     return db.drop().then(_ => db.close());
   });
 
   var serverURL = "https://localhost:" + serverPort;
 
   let records = [{
-    subscriptionUri: serverURL + '/pushNotifications/subscription1',
-    pushEndpoint: serverURL + '/pushEndpoint1',
-    pushReceiptEndpoint: serverURL + '/pushReceiptEndpoint1',
-    scope: 'https://example.com/page/1',
-    p256dhPublicKey: 'BPCd4gNQkjwRah61LpdALdzZKLLnU5UAwDztQ5_h0QsT26jk0IFbqcK6-JxhHAm-rsHEwy0CyVJjtnfOcqc1tgA',
+    subscriptionUri: serverURL + "/pushNotifications/subscription1",
+    pushEndpoint: serverURL + "/pushEndpoint1",
+    pushReceiptEndpoint: serverURL + "/pushReceiptEndpoint1",
+    scope: "https://example.com/page/1",
+    p256dhPublicKey: "BPCd4gNQkjwRah61LpdALdzZKLLnU5UAwDztQ5_h0QsT26jk0IFbqcK6-JxhHAm-rsHEwy0CyVJjtnfOcqc1tgA",
     p256dhPrivateKey: {
-      crv: 'P-256',
-      d: '1jUPhzVsRkzV0vIzwL4ZEsOlKdNOWm7TmaTfzitJkgM',
+      crv: "P-256",
+      d: "1jUPhzVsRkzV0vIzwL4ZEsOlKdNOWm7TmaTfzitJkgM",
       ext: true,
       key_ops: ["deriveBits"],
       kty: "EC",
-      x: '8J3iA1CSPBFqHrUul0At3NkosudTlQDAPO1Dn-HRCxM',
-      y: '26jk0IFbqcK6-JxhHAm-rsHEwy0CyVJjtnfOcqc1tgA'
+      x: "8J3iA1CSPBFqHrUul0At3NkosudTlQDAPO1Dn-HRCxM",
+      y: "26jk0IFbqcK6-JxhHAm-rsHEwy0CyVJjtnfOcqc1tgA",
     },
     originAttributes: ChromeUtils.originAttributesToSuffix(
       { appId: Ci.nsIScriptSecurityManager.NO_APP_ID, inIsolatedMozBrowser: false }),
     quota: Infinity,
     systemRecord: true,
   }, {
-    subscriptionUri: serverURL + '/pushNotifications/subscription2',
-    pushEndpoint: serverURL + '/pushEndpoint2',
-    pushReceiptEndpoint: serverURL + '/pushReceiptEndpoint2',
-    scope: 'https://example.com/page/2',
-    p256dhPublicKey: 'BPnWyUo7yMnuMlyKtERuLfWE8a09dtdjHSW2lpC9_BqR5TZ1rK8Ldih6ljyxVwnBA-nygQHGRpEmu1jV5K8437E',
+    subscriptionUri: serverURL + "/pushNotifications/subscription2",
+    pushEndpoint: serverURL + "/pushEndpoint2",
+    pushReceiptEndpoint: serverURL + "/pushReceiptEndpoint2",
+    scope: "https://example.com/page/2",
+    p256dhPublicKey: "BPnWyUo7yMnuMlyKtERuLfWE8a09dtdjHSW2lpC9_BqR5TZ1rK8Ldih6ljyxVwnBA-nygQHGRpEmu1jV5K8437E",
     p256dhPrivateKey: {
-      crv: 'P-256',
-      d: 'lFm4nPsUKYgNGBJb5nXXKxl8bspCSp0bAhCYxbveqT4',
+      crv: "P-256",
+      d: "lFm4nPsUKYgNGBJb5nXXKxl8bspCSp0bAhCYxbveqT4",
       ext: true,
       key_ops: ["deriveBits"],
-      kty: 'EC',
-      x: '-dbJSjvIye4yXIq0RG4t9YTxrT1212MdJbaWkL38GpE',
-      y: '5TZ1rK8Ldih6ljyxVwnBA-nygQHGRpEmu1jV5K8437E'
+      kty: "EC",
+      x: "-dbJSjvIye4yXIq0RG4t9YTxrT1212MdJbaWkL38GpE",
+      y: "5TZ1rK8Ldih6ljyxVwnBA-nygQHGRpEmu1jV5K8437E",
     },
     originAttributes: ChromeUtils.originAttributesToSuffix(
       { appId: Ci.nsIScriptSecurityManager.NO_APP_ID, inIsolatedMozBrowser: false }),
     quota: Infinity,
     systemRecord: true,
   }, {
-    subscriptionUri: serverURL + '/pushNotifications/subscription3',
-    pushEndpoint: serverURL + '/pushEndpoint3',
-    pushReceiptEndpoint: serverURL + '/pushReceiptEndpoint3',
-    scope: 'https://example.com/page/3',
-    p256dhPublicKey: 'BDhUHITSeVrWYybFnb7ylVTCDDLPdQWMpf8gXhcWwvaaJa6n3YH8TOcH8narDF6t8mKVvg2ioLW-8MH5O4dzGcI',
+    subscriptionUri: serverURL + "/pushNotifications/subscription3",
+    pushEndpoint: serverURL + "/pushEndpoint3",
+    pushReceiptEndpoint: serverURL + "/pushReceiptEndpoint3",
+    scope: "https://example.com/page/3",
+    p256dhPublicKey: "BDhUHITSeVrWYybFnb7ylVTCDDLPdQWMpf8gXhcWwvaaJa6n3YH8TOcH8narDF6t8mKVvg2ioLW-8MH5O4dzGcI",
     p256dhPrivateKey: {
-      crv: 'P-256',
-      d: 'Q1_SE1NySTYzjbqgWwPgrYh7XRg3adqZLkQPsy319G8',
+      crv: "P-256",
+      d: "Q1_SE1NySTYzjbqgWwPgrYh7XRg3adqZLkQPsy319G8",
       ext: true,
       key_ops: ["deriveBits"],
-      kty: 'EC',
-      x: 'OFQchNJ5WtZjJsWdvvKVVMIMMs91BYyl_yBeFxbC9po',
-      y: 'Ja6n3YH8TOcH8narDF6t8mKVvg2ioLW-8MH5O4dzGcI'
+      kty: "EC",
+      x: "OFQchNJ5WtZjJsWdvvKVVMIMMs91BYyl_yBeFxbC9po",
+      y: "Ja6n3YH8TOcH8narDF6t8mKVvg2ioLW-8MH5O4dzGcI",
     },
     originAttributes: ChromeUtils.originAttributesToSuffix(
       { appId: Ci.nsIScriptSecurityManager.NO_APP_ID, inIsolatedMozBrowser: false }),
     quota: Infinity,
     systemRecord: true,
   }, {
-    subscriptionUri: serverURL + '/pushNotifications/subscription4',
-    pushEndpoint: serverURL + '/pushEndpoint4',
-    pushReceiptEndpoint: serverURL + '/pushReceiptEndpoint4',
-    scope: 'https://example.com/page/4',
-    p256dhPublicKey: ChromeUtils.base64URLDecode('BEcvDzkWCrUtjU_wygL98sbQCQrW1lY9irtgGnlCc4B0JJXLCHB9MTM73qD6GZYfL0YOvKo8XLOflh-J4dMGklU', {
+    subscriptionUri: serverURL + "/pushNotifications/subscription4",
+    pushEndpoint: serverURL + "/pushEndpoint4",
+    pushReceiptEndpoint: serverURL + "/pushReceiptEndpoint4",
+    scope: "https://example.com/page/4",
+    p256dhPublicKey: ChromeUtils.base64URLDecode("BEcvDzkWCrUtjU_wygL98sbQCQrW1lY9irtgGnlCc4B0JJXLCHB9MTM73qD6GZYfL0YOvKo8XLOflh-J4dMGklU", {
       padding: "reject",
     }),
     p256dhPrivateKey: {
-      crv: 'P-256',
-      d: 'fWi7tZaX0Pk6WnLrjQ3kiRq_g5XStL5pdH4pllNCqXw',
+      crv: "P-256",
+      d: "fWi7tZaX0Pk6WnLrjQ3kiRq_g5XStL5pdH4pllNCqXw",
       ext: true,
       key_ops: ["deriveBits"],
-      kty: 'EC',
-      x: 'Ry8PORYKtS2NT_DKAv3yxtAJCtbWVj2Ku2AaeUJzgHQ',
-      y: 'JJXLCHB9MTM73qD6GZYfL0YOvKo8XLOflh-J4dMGklU'
+      kty: "EC",
+      x: "Ry8PORYKtS2NT_DKAv3yxtAJCtbWVj2Ku2AaeUJzgHQ",
+      y: "JJXLCHB9MTM73qD6GZYfL0YOvKo8XLOflh-J4dMGklU",
     },
-    authenticationSecret: ChromeUtils.base64URLDecode('cwDVC1iwAn8E37mkR3tMSg', {
+    authenticationSecret: ChromeUtils.base64URLDecode("cwDVC1iwAn8E37mkR3tMSg", {
       padding: "reject",
     }),
     originAttributes: ChromeUtils.originAttributesToSuffix(
       { appId: Ci.nsIScriptSecurityManager.NO_APP_ID, inIsolatedMozBrowser: false }),
     quota: Infinity,
     systemRecord: true,
   }];
 
   for (let record of records) {
     await db.put(record);
   }
 
   let notifyPromise = Promise.all([
     promiseObserverNotification(PushServiceComponent.pushTopic, function(subject, data) {
       var message = subject.QueryInterface(Ci.nsIPushMessage).data;
-      if (message && (data == "https://example.com/page/1")){
+      if (message && (data == "https://example.com/page/1")) {
         equal(message.text(), "Some message", "decoded message is incorrect");
         return true;
       }
+      return false;
     }),
     promiseObserverNotification(PushServiceComponent.pushTopic, function(subject, data) {
       var message = subject.QueryInterface(Ci.nsIPushMessage).data;
-      if (message && (data == "https://example.com/page/2")){
+      if (message && (data == "https://example.com/page/2")) {
         equal(message.text(), "Some message", "decoded message is incorrect");
         return true;
       }
+      return false;
     }),
     promiseObserverNotification(PushServiceComponent.pushTopic, function(subject, data) {
       var message = subject.QueryInterface(Ci.nsIPushMessage).data;
-      if (message && (data == "https://example.com/page/3")){
+      if (message && (data == "https://example.com/page/3")) {
         equal(message.text(), "Some message", "decoded message is incorrect");
         return true;
       }
+      return false;
     }),
     promiseObserverNotification(PushServiceComponent.pushTopic, function(subject, data) {
       var message = subject.QueryInterface(Ci.nsIPushMessage).data;
-      if (message && (data == "https://example.com/page/4")){
+      if (message && (data == "https://example.com/page/4")) {
         equal(message.text(), "Yet another message", "decoded message is incorrect");
         return true;
       }
+      return false;
     }),
   ]);
 
   PushService.init({
     serverURI: serverURL,
-    db
+    db,
   });
 
   await notifyPromise;
 });
--- a/dom/push/test/xpcshell/test_notification_incomplete.js
+++ b/dom/push/test/xpcshell/test_notification_incomplete.js
@@ -1,63 +1,63 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-'use strict';
+"use strict";
 
 const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
 
-const userAgentID = '1ca1cf66-eeb4-4df7-87c1-d5c92906ab90';
+const userAgentID = "1ca1cf66-eeb4-4df7-87c1-d5c92906ab90";
 
 function run_test() {
   do_get_profile();
   setPrefs({
-    userAgentID: userAgentID,
+    userAgentID,
   });
   run_next_test();
 }
 
 add_task(async function test_notification_incomplete() {
   let db = PushServiceWebSocket.newPushDB();
-  registerCleanupFunction(() => {return db.drop().then(_ => db.close());});
+  registerCleanupFunction(() => { return db.drop().then(_ => db.close()); });
   let records = [{
-    channelID: '123',
-    pushEndpoint: 'https://example.org/update/1',
-    scope: 'https://example.com/page/1',
+    channelID: "123",
+    pushEndpoint: "https://example.org/update/1",
+    scope: "https://example.com/page/1",
     version: 1,
-    originAttributes: '',
+    originAttributes: "",
     quota: Infinity,
   }, {
-    channelID: '3ad1ed95-d37a-4d88-950f-22cbe2e240d7',
-    pushEndpoint: 'https://example.org/update/2',
-    scope: 'https://example.com/page/2',
+    channelID: "3ad1ed95-d37a-4d88-950f-22cbe2e240d7",
+    pushEndpoint: "https://example.org/update/2",
+    scope: "https://example.com/page/2",
     version: 1,
-    originAttributes: '',
+    originAttributes: "",
     quota: Infinity,
   }, {
-    channelID: 'd239498b-1c85-4486-b99b-205866e82d1f',
-    pushEndpoint: 'https://example.org/update/3',
-    scope: 'https://example.com/page/3',
+    channelID: "d239498b-1c85-4486-b99b-205866e82d1f",
+    pushEndpoint: "https://example.org/update/3",
+    scope: "https://example.com/page/3",
     version: 3,
-    originAttributes: '',
+    originAttributes: "",
     quota: Infinity,
   }, {
-    channelID: 'a50de97d-b496-43ce-8b53-05522feb78db',
-    pushEndpoint: 'https://example.org/update/4',
-    scope: 'https://example.com/page/4',
+    channelID: "a50de97d-b496-43ce-8b53-05522feb78db",
+    pushEndpoint: "https://example.org/update/4",
+    scope: "https://example.com/page/4",
     version: 10,
-    originAttributes: '',
+    originAttributes: "",
     quota: Infinity,
   }];
   for (let record of records) {
     await db.put(record);
   }
 
   function observeMessage(subject, topic, data) {
-    ok(false, 'Should not deliver malformed updates');
+    ok(false, "Should not deliver malformed updates");
   }
   registerCleanupFunction(() =>
     Services.obs.removeObserver(observeMessage, PushServiceComponent.pushTopic));
   Services.obs.addObserver(observeMessage, PushServiceComponent.pushTopic);
 
   let notificationDone;
   let notificationPromise = new Promise(resolve => notificationDone = after(2, resolve));
   let prevHandler = PushServiceWebSocket._handleNotificationReply;
@@ -67,64 +67,64 @@ add_task(async function test_notificatio
   };
   PushService.init({
     serverURI: "wss://push.example.org/",
     db,
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(request) {
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             status: 200,
             uaid: userAgentID,
           }));
           this.serverSendMsg(JSON.stringify({
             // Missing "updates" field; should ignore message.
-            messageType: 'notification'
+            messageType: "notification",
           }));
           this.serverSendMsg(JSON.stringify({
-            messageType: 'notification',
+            messageType: "notification",
             updates: [{
               // Wrong channel ID field type.
               channelID: 123,
-              version: 3
+              version: 3,
             }, {
               // Missing version field.
-              channelID: '3ad1ed95-d37a-4d88-950f-22cbe2e240d7'
+              channelID: "3ad1ed95-d37a-4d88-950f-22cbe2e240d7",
             }, {
               // Wrong version field type.
-              channelID: 'd239498b-1c85-4486-b99b-205866e82d1f',
-              version: true
+              channelID: "d239498b-1c85-4486-b99b-205866e82d1f",
+              version: true,
             }, {
               // Negative versions should be ignored.
-              channelID: 'a50de97d-b496-43ce-8b53-05522feb78db',
-              version: -5
-            }]
+              channelID: "a50de97d-b496-43ce-8b53-05522feb78db",
+              version: -5,
+            }],
           }));
         },
         onACK() {
-          ok(false, 'Should not acknowledge malformed updates');
-        }
+          ok(false, "Should not acknowledge malformed updates");
+        },
       });
-    }
+    },
   });
 
   await notificationPromise;
 
   let storeRecords = await db.getAllKeyIDs();
   storeRecords.sort(({pushEndpoint: a}, {pushEndpoint: b}) =>
     compareAscending(a, b));
   recordsAreEqual(records, storeRecords);
 });
 
 function recordIsEqual(a, b) {
-  strictEqual(a.channelID, b.channelID, 'Wrong channel ID in record');
-  strictEqual(a.pushEndpoint, b.pushEndpoint, 'Wrong push endpoint in record');
-  strictEqual(a.scope, b.scope, 'Wrong scope in record');
-  strictEqual(a.version, b.version, 'Wrong version in record');
+  strictEqual(a.channelID, b.channelID, "Wrong channel ID in record");
+  strictEqual(a.pushEndpoint, b.pushEndpoint, "Wrong push endpoint in record");
+  strictEqual(a.scope, b.scope, "Wrong scope in record");
+  strictEqual(a.version, b.version, "Wrong version in record");
 }
 
 function recordsAreEqual(a, b) {
-  equal(a.length, b.length, 'Mismatched record count');
+  equal(a.length, b.length, "Mismatched record count");
   for (let i = 0; i < a.length; i++) {
     recordIsEqual(a[i], b[i]);
   }
 }
--- a/dom/push/test/xpcshell/test_notification_version_string.js
+++ b/dom/push/test/xpcshell/test_notification_version_string.js
@@ -1,69 +1,69 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-'use strict';
+"use strict";
 
 const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
 
-const userAgentID = 'ba31ac13-88d4-4984-8e6b-8731315a7cf8';
+const userAgentID = "ba31ac13-88d4-4984-8e6b-8731315a7cf8";
 
 function run_test() {
   do_get_profile();
   setPrefs({
-    userAgentID: userAgentID,
+    userAgentID,
   });
   run_next_test();
 }
 
 add_task(async function test_notification_version_string() {
   let db = PushServiceWebSocket.newPushDB();
-  registerCleanupFunction(() => {return db.drop().then(_ => db.close());});
+  registerCleanupFunction(() => { return db.drop().then(_ => db.close()); });
   await db.put({
-    channelID: '6ff97d56-d0c0-43bc-8f5b-61b855e1d93b',
-    pushEndpoint: 'https://example.org/updates/1',
-    scope: 'https://example.com/page/1',
-    originAttributes: '',
+    channelID: "6ff97d56-d0c0-43bc-8f5b-61b855e1d93b",
+    pushEndpoint: "https://example.org/updates/1",
+    scope: "https://example.com/page/1",
+    originAttributes: "",
     version: 2,
     quota: Infinity,
     systemRecord: true,
   });
 
   let notifyPromise = promiseObserverNotification(PushServiceComponent.pushTopic);
 
   let ackDone;
   let ackPromise = new Promise(resolve => ackDone = resolve);
   PushService.init({
     serverURI: "wss://push.example.org/",
     db,
     makeWebSocket(uri) {
       return new MockWebSocket(uri, {
         onHello(request) {
           this.serverSendMsg(JSON.stringify({
-            messageType: 'hello',
+            messageType: "hello",
             status: 200,
             uaid: userAgentID,
           }));
           this.serverSendMsg(JSON.stringify({
-            messageType: 'notification',
+            messageType: "notification",
             updates: [{
-              channelID: '6ff97d56-d0c0-43bc-8f5b-61b855e1d93b',
-              version: '4'
-            }]
+              channelID: "6ff97d56-d0c0-43bc-8f5b-61b855e1d93b",
+              version: "4",
+            }],
           }));
         },
-        onACK: ackDone
+        onACK: ackDone,
       });
-    }
+    },
   });
 
-  let {subject: message, data: scope} = await notifyPromise;
+  let {subject: message} = await notifyPromise;
   equal(message.QueryInterface(Ci.nsIPushMessage).data, null,
-    'Unexpected data for Simple Push message');
+    "Unexpected data for Simple Push message");
 
   await ackPromise;
 
   let storeRecord = await db.getByKeyID(
-    '6ff97d56-d0c0-43bc-8f5b-61b855e1d93b');
-  strictEqual(storeRecord.version, 4, 'Wrong record version');
-  equal(storeRecord.quota, Infinity, 'Wrong quota');
+    "6ff97d56-d0c0-43bc-8f5b-61b855e1d93b");
+  strictEqual(storeRecord.version, 4, "Wrong record version");
+  equal(storeRecord.quota, Infinity, "Wrong quota");
 });
--- a/dom/push/test/xpcshell/test_observer_data.js
+++ b/dom/push/test/xpcshell/test_observer_data.js
@@ -1,43 +1,39 @@
-'use strict';
+"use strict";
 
-var pushNotifier = Cc['@mozilla.org/push/Notifier;1']
+var pushNotifier = Cc["@mozilla.org/push/Notifier;1"]
                      .getService(Ci.nsIPushNotifier);
 var systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
 
-function run_test() {
-  run_next_test();
-}
-
 add_task(async function test_notifyWithData() {
   let textData = '{"hello":"world"}';
-  let payload = new TextEncoder('utf-8').encode(textData);
+  let payload = new TextEncoder("utf-8").encode(textData);
 
   let notifyPromise =
     promiseObserverNotification(PushServiceComponent.pushTopic);
-  pushNotifier.notifyPushWithData('chrome://notify-test', systemPrincipal,
-    '' /* messageId */, payload.length, payload);
+  pushNotifier.notifyPushWithData("chrome://notify-test", systemPrincipal,
+    "" /* messageId */, payload.length, payload);
 
   let data = (await notifyPromise).subject.QueryInterface(
     Ci.nsIPushMessage).data;
   deepEqual(data.json(), {
-    hello: 'world',
-  }, 'Should extract JSON values');
+    hello: "world",
+  }, "Should extract JSON values");
   deepEqual(data.binary(), Array.from(payload),
-    'Should extract raw binary data');
-  equal(data.text(), textData, 'Should extract text data');
+    "Should extract raw binary data");
+  equal(data.text(), textData, "Should extract text data");
 });
 
 add_task(async function test_empty_notifyWithData() {
   let notifyPromise =
     promiseObserverNotification(PushServiceComponent.pushTopic);
-  pushNotifier.notifyPushWithData('chrome://notify-test', systemPrincipal,
-    '' /* messageId */, 0, null);
+  pushNotifier.notifyPushWithData("chrome://notify-test", systemPrincipal,
+    "" /* messageId */, 0, null);
 
   let data = (await notifyPromise).subject.QueryInterface(
     Ci.nsIPushMessage).data;
   throws(_ => data.json(),
     /InvalidStateError/,
-    'Should throw an error when parsing an empty string as JSON');
-  strictEqual(data.text(), '', 'Should return an empty string');
-  deepEqual(data.binary(), [], 'Should return an empty array');
+    "Should throw an error when parsing an empty string as JSON");
+  strictEqual(data.text(), "", "Should return an empty string");
+  deepEqual(data.binary(), [], "Should return an empty array");
 });
--- a/dom/push/test/xpcshell/test_observer_remoting.js
+++ b/dom/push/test/xpcshell/test_observer_remoting.js
@@ -1,45 +1,45 @@
-'use strict';
+"use strict";
 
-const pushNotifier = Cc['@mozilla.org/push/Notifier;1']
+const pushNotifier = Cc["@mozilla.org/push/Notifier;1"]
                        .getService(Ci.nsIPushNotifier);
 
 add_task(async function test_observer_remoting() {
   do_get_profile();
   if (isParent) {
     await testInParent();
   } else {
     await testInChild();
   }
 });
 
 const childTests = [{
-  text: 'Hello from child!',
+  text: "Hello from child!",
   principal: Services.scriptSecurityManager.getSystemPrincipal(),
 }];
 
 const parentTests = [{
-  text: 'Hello from parent!',
+  text: "Hello from parent!",
   principal: Services.scriptSecurityManager.getSystemPrincipal(),
 }];
 
 async function testInParent() {
   setPrefs();
   // Register observers for notifications from the child, then run the test in
   // the child and wait for the notifications.
   let promiseNotifications = childTests.reduce(
     (p, test) => p.then(_ => waitForNotifierObservers(test, /* shouldNotify = */ false)),
     Promise.resolve()
   );
-  let promiseFinished = run_test_in_child('./test_observer_remoting.js');
+  let promiseFinished = run_test_in_child("./test_observer_remoting.js");
   await promiseNotifications;
 
   // Wait until the child is listening for notifications from the parent.
-  await do_await_remote_message('push_test_observer_remoting_child_ready');
+  await do_await_remote_message("push_test_observer_remoting_child_ready");
 
   // Fire an observer notification in the parent that should be forwarded to
   // the child.
   await parentTests.reduce(
     (p, test) => p.then(_ => waitForNotifierObservers(test, /* shouldNotify = */ true)),
     Promise.resolve()
   );
 
@@ -56,58 +56,58 @@ async function testInChild() {
   );
 
   // Register observers for notifications from the parent, let the parent know
   // we're ready, and wait for the notifications.
   let promiseNotifierObservers = parentTests.reduce(
     (p, test) => p.then(_ => waitForNotifierObservers(test, /* shouldNotify = */ false)),
     Promise.resolve()
   );
-  do_send_remote_message('push_test_observer_remoting_child_ready');
+  do_send_remote_message("push_test_observer_remoting_child_ready");
   await promiseNotifierObservers;
 }
 
 var waitForNotifierObservers = async function({ text, principal }, shouldNotify = false) {
   let notifyPromise = promiseObserverNotification(
     PushServiceComponent.pushTopic);
   let subChangePromise = promiseObserverNotification(
     PushServiceComponent.subscriptionChangeTopic);
   let subModifiedPromise = promiseObserverNotification(
     PushServiceComponent.subscriptionModifiedTopic);
 
-  let scope = 'chrome://test-scope';
-  let data = new TextEncoder('utf-8').encode(text);
+  let scope = "chrome://test-scope";
+  let data = new TextEncoder("utf-8").encode(text);
 
   if (shouldNotify) {
-    pushNotifier.notifyPushWithData(scope, principal, '', data.length, data);
+    pushNotifier.notifyPushWithData(scope, principal, "", data.length, data);
     pushNotifier.notifySubscriptionChange(scope, principal);
     pushNotifier.notifySubscriptionModified(scope, principal);
   }
 
   let {
     data: notifyScope,
     subject: notifySubject,
   } = await notifyPromise;
   equal(notifyScope, scope,
-    'Should fire push notifications with the correct scope');
+    "Should fire push notifications with the correct scope");
   let message = notifySubject.QueryInterface(Ci.nsIPushMessage);
   equal(message.principal, principal,
-    'Should include the principal in the push message');
-  strictEqual(message.data.text(), text, 'Should include data');
+    "Should include the principal in the push message");
+  strictEqual(message.data.text(), text, "Should include data");
 
   let {
     data: subChangeScope,
     subject: subChangePrincipal,
   } = await subChangePromise;
   equal(subChangeScope, scope,
-    'Should fire subscription change notifications with the correct scope');
+    "Should fire subscription change notifications with the correct scope");
   equal(subChangePrincipal, principal,
-    'Should pass the principal as the subject of a change notification');
+    "Should pass the principal as the subject of a change notification");
 
   let {
     data: subModifiedScope,
     subject: subModifiedPrincipal,
   } = await subModifiedPromise;