diff options
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_experiments.js')
-rw-r--r-- | toolkit/components/extensions/test/xpcshell/test_ext_experiments.js | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_experiments.js b/toolkit/components/extensions/test/xpcshell/test_ext_experiments.js new file mode 100644 index 0000000000..cc3cd33534 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_experiments.js @@ -0,0 +1,377 @@ +"use strict"; + +/* globals browser */ +const { AddonSettings } = ChromeUtils.import( + "resource://gre/modules/addons/AddonSettings.jsm" +); + +AddonTestUtils.init(this); +AddonTestUtils.overrideCertDB(); +AddonTestUtils.createAppInfo( + "xpcshell@tests.mozilla.org", + "XPCShell", + "1", + "42" +); + +add_task(async function setup() { + AddonTestUtils.overrideCertDB(); + await ExtensionTestUtils.startAddonManager(); +}); + +let fooExperimentAPIs = { + foo: { + schema: "schema.json", + parent: { + scopes: ["addon_parent"], + script: "parent.js", + paths: [["experiments", "foo", "parent"]], + }, + child: { + scopes: ["addon_child"], + script: "child.js", + paths: [["experiments", "foo", "child"]], + }, + }, +}; + +let fooExperimentFiles = { + "schema.json": JSON.stringify([ + { + namespace: "experiments.foo", + types: [ + { + id: "Meh", + type: "object", + properties: {}, + }, + ], + functions: [ + { + name: "parent", + type: "function", + async: true, + parameters: [], + }, + { + name: "child", + type: "function", + parameters: [], + returns: { type: "string" }, + }, + ], + }, + ]), + + /* globals ExtensionAPI */ + "parent.js": () => { + this.foo = class extends ExtensionAPI { + getAPI(context) { + return { + experiments: { + foo: { + parent() { + return Promise.resolve("parent"); + }, + }, + }, + }; + } + }; + }, + + "child.js": () => { + this.foo = class extends ExtensionAPI { + getAPI(context) { + return { + experiments: { + foo: { + child() { + return "child"; + }, + }, + }, + }; + } + }; + }, +}; + +async function testFooExperiment() { + browser.test.assertEq( + "object", + typeof browser.experiments, + "typeof browser.experiments" + ); + + browser.test.assertEq( + "object", + typeof browser.experiments.foo, + "typeof browser.experiments.foo" + ); + + browser.test.assertEq( + "function", + typeof browser.experiments.foo.child, + "typeof browser.experiments.foo.child" + ); + + browser.test.assertEq( + "function", + typeof browser.experiments.foo.parent, + "typeof browser.experiments.foo.parent" + ); + + browser.test.assertEq( + "child", + browser.experiments.foo.child(), + "foo.child()" + ); + + browser.test.assertEq( + "parent", + await browser.experiments.foo.parent(), + "await foo.parent()" + ); +} + +async function testFooFailExperiment() { + browser.test.assertEq( + "object", + typeof browser.experiments, + "typeof browser.experiments" + ); + + browser.test.assertEq( + "undefined", + typeof browser.experiments.foo, + "typeof browser.experiments.foo" + ); +} + +add_task(async function test_bundled_experiments() { + let testCases = [ + { isSystem: true, temporarilyInstalled: true, shouldHaveExperiments: true }, + { + isSystem: true, + temporarilyInstalled: false, + shouldHaveExperiments: true, + }, + { + isPrivileged: true, + temporarilyInstalled: true, + shouldHaveExperiments: true, + }, + { + isPrivileged: true, + temporarilyInstalled: false, + shouldHaveExperiments: true, + }, + { + isPrivileged: false, + temporarilyInstalled: true, + shouldHaveExperiments: AddonSettings.EXPERIMENTS_ENABLED, + }, + { + isPrivileged: false, + temporarilyInstalled: false, + shouldHaveExperiments: AppConstants.MOZ_APP_NAME == "thunderbird", + }, + ]; + + async function background(shouldHaveExperiments) { + if (shouldHaveExperiments) { + await testFooExperiment(); + } else { + await testFooFailExperiment(); + } + + browser.test.notifyPass("background.experiments.foo"); + } + + for (let testCase of testCases) { + let extension = ExtensionTestUtils.loadExtension({ + isPrivileged: testCase.isPrivileged, + isSystem: testCase.isSystem, + temporarilyInstalled: testCase.temporarilyInstalled, + + manifest: { + experiment_apis: fooExperimentAPIs, + }, + + background: ` + ${testFooExperiment} + ${testFooFailExperiment} + (${background})(${testCase.shouldHaveExperiments}); + `, + + files: fooExperimentFiles, + }); + + if (testCase.temporarilyInstalled && !testCase.shouldHaveExperiments) { + ExtensionTestUtils.failOnSchemaWarnings(false); + await Assert.rejects( + extension.startup(), + /Using 'experiment_apis' requires a privileged add-on/, + "startup failed without experimental api access" + ); + ExtensionTestUtils.failOnSchemaWarnings(true); + } else { + await extension.startup(); + + await extension.awaitFinish("background.experiments.foo"); + + await extension.unload(); + } + } +}); + +add_task(async function test_unbundled_experiments() { + async function background() { + await testFooExperiment(); + + browser.test.assertEq( + "object", + typeof browser.experiments.crunk, + "typeof browser.experiments.crunk" + ); + + browser.test.assertEq( + "function", + typeof browser.experiments.crunk.child, + "typeof browser.experiments.crunk.child" + ); + + browser.test.assertEq( + "function", + typeof browser.experiments.crunk.parent, + "typeof browser.experiments.crunk.parent" + ); + + browser.test.assertEq( + "crunk-child", + browser.experiments.crunk.child(), + "crunk.child()" + ); + + browser.test.assertEq( + "crunk-parent", + await browser.experiments.crunk.parent(), + "await crunk.parent()" + ); + + browser.test.notifyPass("background.experiments.crunk"); + } + + let extension = ExtensionTestUtils.loadExtension({ + isPrivileged: true, + + manifest: { + experiment_apis: fooExperimentAPIs, + + permissions: ["experiments.crunk"], + }, + + background: ` + ${testFooExperiment} + (${background})(); + `, + + files: fooExperimentFiles, + }); + + let apiExtension = ExtensionTestUtils.loadExtension({ + isPrivileged: true, + + manifest: { + browser_specific_settings: { + gecko: { id: "crunk@experiments.addons.mozilla.org" }, + }, + + experiment_apis: { + crunk: { + schema: "schema.json", + parent: { + scopes: ["addon_parent"], + script: "parent.js", + paths: [["experiments", "crunk", "parent"]], + }, + child: { + scopes: ["addon_child"], + script: "child.js", + paths: [["experiments", "crunk", "child"]], + }, + }, + }, + }, + + files: { + "schema.json": JSON.stringify([ + { + namespace: "experiments.crunk", + types: [ + { + id: "Meh", + type: "object", + properties: {}, + }, + ], + functions: [ + { + name: "parent", + type: "function", + async: true, + parameters: [], + }, + { + name: "child", + type: "function", + parameters: [], + returns: { type: "string" }, + }, + ], + }, + ]), + + "parent.js": () => { + this.crunk = class extends ExtensionAPI { + getAPI(context) { + return { + experiments: { + crunk: { + parent() { + return Promise.resolve("crunk-parent"); + }, + }, + }, + }; + } + }; + }, + + "child.js": () => { + this.crunk = class extends ExtensionAPI { + getAPI(context) { + return { + experiments: { + crunk: { + child() { + return "crunk-child"; + }, + }, + }, + }; + } + }; + }, + }, + }); + + await apiExtension.startup(); + await extension.startup(); + + await extension.awaitFinish("background.experiments.crunk"); + + await extension.unload(); + await apiExtension.unload(); +}); |