Extract test context and withContext to extensions, r?markh draft
authorEthan Glasser-Camp <eglassercamp@mozilla.com>
Mon, 18 Jul 2016 15:04:12 -0400
changeset 400748 f0525d914253bd82a51321d1d11d4921f39858f6
parent 400747 09de144abee47d8971ff1ec6c07f5db6b27559f6
child 400749 6df78b07989044f0e5aad62ced1982aefbc44ab2
push id26269
push usereglassercamp@mozilla.com
push dateMon, 15 Aug 2016 17:28:13 +0000
reviewersmarkh
milestone50.0a1
Extract test context and withContext to extensions, r?markh Also define withSyncContext, which is only useful as long as we have a preference that controls whether this API is even available. MozReview-Commit-ID: CvhKqLLekvC
services/sync/tests/unit/head_helpers.js
services/sync/tests/unit/test_extension_storage_tracker.js
services/sync/tests/unit/xpcshell.ini
toolkit/components/extensions/test/xpcshell/head_sync.js
toolkit/components/extensions/test/xpcshell/xpcshell.ini
--- a/services/sync/tests/unit/head_helpers.js
+++ b/services/sync/tests/unit/head_helpers.js
@@ -70,16 +70,34 @@ function ExtensionsTestPath(path) {
 function loadAddonTestFunctions() {
   const path = ExtensionsTestPath("/head_addons.js");
   let file = do_get_file(path);
   let uri = Services.io.newFileURI(file);
   Services.scriptloader.loadSubScript(uri.spec, gGlobalScope);
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
 }
 
+function webExtensionsTestPath(path) {
+  if (path[0] != "/") {
+    throw Error("Path must begin with '/': " + path);
+  }
+
+  return "../../../../toolkit/components/extensions/test/xpcshell" + path;
+}
+
+/**
+ * Loads the WebExtension test functions by importing its test file.
+ */
+function loadWebExtensionTestFunctions() {
+  const path = webExtensionsTestPath("/head_sync.js");
+  let file = do_get_file(path);
+  let uri = Services.io.newFileURI(file);
+  Services.scriptloader.loadSubScript(uri.spec, gGlobalScope);
+}
+
 function getAddonInstall(name) {
   let f = do_get_file(ExtensionsTestPath("/addons/" + name + ".xpi"));
   let cb = Async.makeSyncCallback();
   AddonManager.getInstallForFile(f, cb);
 
   return Async.waitForSyncCallback(cb);
 }
 
--- a/services/sync/tests/unit/test_extension_storage_tracker.js
+++ b/services/sync/tests/unit/test_extension_storage_tracker.js
@@ -4,70 +4,33 @@
 "use strict";
 
 Cu.import("resource://services-sync/constants.js");
 Cu.import("resource://services-sync/engines.js");
 Cu.import("resource://services-sync/engines/extension-storage.js");
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://gre/modules/ExtensionStorageSync.jsm");
-Cu.import("resource://gre/modules/ExtensionUtils.jsm");
-
-var {
-  BaseContext,
-} = ExtensionUtils;
 
 Service.engineManager.register(ExtensionStorageEngine);
 const engine = Service.engineManager.get("extension-storage");
 do_get_profile();   // so we can use FxAccounts
-
-class Context extends BaseContext {
-  constructor(principal) {
-    super();
-    Object.defineProperty(this, "principal", {
-      value: principal,
-      configurable: true,
-    });
-    this.sandbox = Cu.Sandbox(principal, {wantXrays: false});
-    this.extension = {id: "test@web.extension"};
-  }
-
-  get cloneScope() {
-    return this.sandbox;
-  }
-}
-
-function* withContext(f) {
-  const STORAGE_SYNC_PREF = "extension.storage.sync.enabled";
-  const ssm = Services.scriptSecurityManager;
-  const PRINCIPAL1 = ssm.createCodebasePrincipalFromOrigin("http://www.example.org");
-  const context = new Context(PRINCIPAL1);
-
-  let prefs = Services.prefs;
-  try {
-    prefs.setBoolPref(STORAGE_SYNC_PREF, true);
-    yield* f(context);
-  } finally {
-    prefs.clearUserPref(STORAGE_SYNC_PREF);
-    context.unload();
-  }
-
-}
+loadWebExtensionTestFunctions();
 
 add_task(function* test_changing_extension_storage_changes_score() {
   const tracker = engine._tracker;
   const extensionId = "my-extension-id";
   Svc.Obs.notify("weave:engine:start-tracking");
-  yield* withContext(function*(context) {
+  yield* withSyncContext(function*(context) {
     yield ExtensionStorageSync.set(extensionId, {"a": "b"}, context);
   });
   do_check_eq(tracker.score, SCORE_INCREMENT_MEDIUM);
 
   tracker.resetScore();
-  yield* withContext(function*(context) {
+  yield* withSyncContext(function*(context) {
     yield ExtensionStorageSync.remove(extensionId, "a", context);
   });
   do_check_eq(tracker.score, SCORE_INCREMENT_MEDIUM);
 
   Svc.Obs.notify("weave:engine:stop-tracking");
 });
 
 function run_test() {
--- a/services/sync/tests/unit/xpcshell.ini
+++ b/services/sync/tests/unit/xpcshell.ini
@@ -9,16 +9,17 @@ support-files =
   fake_login_manager.js
   missing-sourceuri.xml
   missing-xpi-search.xml
   places_v10_from_v11.sqlite
   rewrite-search.xml
   sync_ping_schema.json
   !/services/common/tests/unit/head_helpers.js
   !/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
+  !/toolkit/components/extensions/test/xpcshell/head_sync.js
 
 # The manifest is roughly ordered from low-level to high-level. When making
 # systemic sweeping changes, this makes it easier to identify errors closer to
 # the source.
 
 # Ensure we can import everything.
 [test_load_modules.js]
 
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/head_sync.js
@@ -0,0 +1,59 @@
+/* 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/. */
+
+Components.utils.import("resource://gre/modules/Services.jsm", this);
+Components.utils.import("resource://gre/modules/ExtensionUtils.jsm", this);
+
+var {
+  BaseContext,
+} = ExtensionUtils;
+
+class Context extends BaseContext {
+  constructor(principal) {
+    super();
+    Object.defineProperty(this, "principal", {
+      value: principal,
+      configurable: true,
+    });
+    this.sandbox = Components.utils.Sandbox(principal, {wantXrays: false});
+    this.extension = {id: "test@web.extension"};
+  }
+
+  get cloneScope() {
+    return this.sandbox;
+  }
+}
+
+/**
+ * Call the given function with a newly-constructed context.
+ * Unload the context on the way out.
+ */
+function* withContext(f) {
+  const ssm = Services.scriptSecurityManager;
+  const PRINCIPAL1 = ssm.createCodebasePrincipalFromOrigin("http://www.example.org");
+  const context = new Context(PRINCIPAL1);
+  try {
+    yield* f(context);
+  } finally {
+    context.unload();
+  }
+}
+
+/**
+ * Like withContext(), but also turn on the "storage.sync" pref for
+ * the duration of the function.
+ * Calls to this function can be replaced with calls to withContext
+ * once the pref becomes on by default.
+ */
+function* withSyncContext(f) {
+  const STORAGE_SYNC_PREF = "extension.storage.sync.enabled";
+  let prefs = Services.prefs;
+
+  try {
+    prefs.setBoolPref(STORAGE_SYNC_PREF, true);
+    yield* withContext(f);
+  } finally {
+    prefs.clearUserPref(STORAGE_SYNC_PREF);
+  }
+}
--- a/toolkit/components/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/components/extensions/test/xpcshell/xpcshell.ini
@@ -1,10 +1,10 @@
 [DEFAULT]
-head = head.js
+head = head.js head_sync.js
 tail =
 firefox-appdir = browser
 skip-if = toolkit == 'gonk' || appname == "thunderbird"
 
 [test_csp_custom_policies.js]
 [test_csp_validator.js]
 [test_locale_data.js]
 [test_locale_converter.js]