Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

"use strict";
const { AddonManager } = ChromeUtils.importESModule(
"resource://gre/modules/AddonManager.sys.mjs"
);
const { ExtensionPermissions } = ChromeUtils.importESModule(
"resource://gre/modules/ExtensionPermissions.sys.mjs"
);
ChromeUtils.defineESModuleGetters(this, {
ExtensionParent: "resource://gre/modules/ExtensionParent.sys.mjs",
});
AddonTestUtils.init(this);
AddonTestUtils.overrideCertDB();
AddonTestUtils.createAppInfo(
"xpcshell@tests.mozilla.org",
"XPCShell",
"1",
"42"
);
Services.prefs.setBoolPref(
"extensions.dataCollectionPermissions.enabled",
true
);
let OptionalPermissions;
add_setup(async () => {
// FOG needs a profile and to be initialized.
do_get_profile();
Services.fog.initializeFOG();
Services.fog.testResetFOG();
// Bug 1646182: Force ExtensionPermissions to run in rkv mode, the legacy
// storage mode will run in xpcshell-legacy-ep.toml
await ExtensionPermissions._uninit();
Services.prefs.setBoolPref(
"extensions.webextOptionalPermissionPrompts",
false
);
registerCleanupFunction(() => {
Services.prefs.clearUserPref("extensions.webextOptionalPermissionPrompts");
});
await AddonTestUtils.promiseStartupManager();
AddonTestUtils.usePrivilegedSignatures = false;
// We want to get a list of optional permissions prior to loading an extension,
// so we'll get ExtensionParent to do that for us.
await ExtensionParent.apiManager.lazyInit();
// These permissions have special behaviors and/or are not mapped directly to an
// api namespace. They will have their own tests for specific behavior.
let ignore = [
"activeTab",
"clipboardRead",
"clipboardWrite",
"declarativeNetRequestFeedback",
"devtools",
"downloads.open",
"geolocation",
"management",
"menus.overrideContext",
"nativeMessaging",
"scripting",
"search",
"tabHide",
"tabs",
"trialML",
"webRequestAuthProvider",
"webRequestBlocking",
"webRequestFilterResponse",
"webRequestFilterResponse.serviceWorkerScript",
];
// "OptionalOnlyPermission" is not included in the list below, because a test
// below tries to request all permissions at once. That is not supported when
// optional-only. See test_ext_permissions_optional_only.js instead.
OptionalPermissions = Schemas.getPermissionNames([
"OptionalPermission",
"OptionalPermissionNoPrompt",
]).filter(n => !ignore.includes(n));
});
add_task(async function test_api_on_permissions_changed() {
async function background() {
let manifest = browser.runtime.getManifest();
let permObj = { permissions: manifest.optional_permissions, origins: [] };
function verifyPermissions(enabled) {
for (let perm of manifest.optional_permissions) {
browser.test.assertEq(
enabled,
!!browser[perm],
`${perm} API is ${
enabled ? "injected" : "removed"
} after permission request`
);
}
}
browser.permissions.onAdded.addListener(details => {
browser.test.assertEq(
JSON.stringify(details.permissions),
JSON.stringify(manifest.optional_permissions),
"expected permissions added"
);
verifyPermissions(true);
browser.test.sendMessage("added");
});
browser.permissions.onRemoved.addListener(details => {
browser.test.assertEq(
JSON.stringify(details.permissions),
JSON.stringify(manifest.optional_permissions),
"expected permissions removed"
);
verifyPermissions(false);
browser.test.sendMessage("removed");
});
browser.test.onMessage.addListener((msg, enabled) => {
if (msg === "request") {
browser.permissions.request(permObj);
} else if (msg === "verify_access") {
verifyPermissions(enabled);
browser.test.sendMessage("verified");
} else if (msg === "revoke") {
browser.permissions.remove(permObj);
}
});
}
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
optional_permissions: OptionalPermissions,
},
useAddonManager: "permanent",
});
await extension.startup();
function addPermissions() {
extension.sendMessage("request");
return extension.awaitMessage("added");
}
function removePermissions() {
extension.sendMessage("revoke");
return extension.awaitMessage("removed");
}
function verifyPermissions(enabled) {
extension.sendMessage("verify_access", enabled);
return extension.awaitMessage("verified");
}
await withHandlingUserInput(extension, async () => {
await addPermissions();
await removePermissions();
await addPermissions();
});
// reset handlingUserInput for the restart
extensionHandlers.delete(extension);
// Verify access on restart
await AddonTestUtils.promiseRestartManager();
await extension.awaitBackgroundStarted();
await verifyPermissions(true);
await withHandlingUserInput(extension, async () => {
await removePermissions();
});
// Add private browsing to be sure it doesn't come through.
let permObj = {
permissions: OptionalPermissions.concat("internal:privateBrowsingAllowed"),
origins: [],
};
// enable the permissions while the addon is running
await ExtensionPermissions.add(extension.id, permObj, extension.extension);
await extension.awaitMessage("added");
await verifyPermissions(true);
// disable the permissions while the addon is running
await ExtensionPermissions.remove(extension.id, permObj, extension.extension);
await extension.awaitMessage("removed");
await verifyPermissions(false);
// Add private browsing to test internal permission. If it slips through,
// we would get an error for an additional added message.
await ExtensionPermissions.add(
extension.id,
{ permissions: ["internal:privateBrowsingAllowed"], origins: [] },
extension.extension
);
// disable the addon and re-test revoking permissions.
await withHandlingUserInput(extension, async () => {
await addPermissions();
});
let addon = await AddonManager.getAddonByID(extension.id);
await addon.disable();
await ExtensionPermissions.remove(extension.id, permObj);
await addon.enable();
await extension.awaitStartup();
await verifyPermissions(false);
let perms = await ExtensionPermissions.get(extension.id);
equal(perms.permissions.length, 0, "no permissions on startup");
await extension.unload();
});
add_task(async function test_geo_permissions() {
async function background() {
const permObj = { permissions: ["geolocation"] };
browser.test.onMessage.addListener(async msg => {
if (msg === "request") {
await browser.permissions.request(permObj);
} else if (msg === "remove") {
await browser.permissions.remove(permObj);
}
let result = await browser.permissions.contains(permObj);
browser.test.sendMessage("done", result);
});
}
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
browser_specific_settings: { gecko: { id: "geo-test@test" } },
optional_permissions: ["geolocation"],
},
useAddonManager: "permanent",
});
await extension.startup();
let policy = WebExtensionPolicy.getByID(extension.id);
let principal = policy.extension.principal;
equal(
Services.perms.testPermissionFromPrincipal(principal, "geo"),
Services.perms.UNKNOWN_ACTION,
"geolocation not allowed on install"
);
await withHandlingUserInput(extension, async () => {
extension.sendMessage("request");
ok(await extension.awaitMessage("done"), "permission granted");
equal(
Services.perms.testPermissionFromPrincipal(principal, "geo"),
Services.perms.ALLOW_ACTION,
"geolocation allowed after requested"
);
extension.sendMessage("remove");
ok(!(await extension.awaitMessage("done")), "permission revoked");
equal(
Services.perms.testPermissionFromPrincipal(principal, "geo"),
Services.perms.UNKNOWN_ACTION,
"geolocation not allowed after removed"
);
// re-grant to test update removal
extension.sendMessage("request");
ok(await extension.awaitMessage("done"), "permission granted");
equal(
Services.perms.testPermissionFromPrincipal(principal, "geo"),
Services.perms.ALLOW_ACTION,
"geolocation allowed after re-requested"
);
});
// We should not have geo permission after this upgrade.
await extension.upgrade({
manifest: {
browser_specific_settings: { gecko: { id: "geo-test@test" } },
},
useAddonManager: "permanent",
});
equal(
Services.perms.testPermissionFromPrincipal(principal, "geo"),
Services.perms.UNKNOWN_ACTION,
"geolocation not allowed after upgrade"
);
await extension.unload();
});
add_task(async function test_browserSetting_permissions() {
async function background() {
const permObj = { permissions: ["browserSettings"] };
browser.test.onMessage.addListener(async msg => {
if (msg === "request") {
await browser.permissions.request(permObj);
await browser.browserSettings.cacheEnabled.set({ value: false });
} else if (msg === "remove") {
await browser.permissions.remove(permObj);
}
browser.test.sendMessage("done");
});
}
function cacheIsEnabled() {
return (
Services.prefs.getBoolPref("browser.cache.disk.enable") &&
Services.prefs.getBoolPref("browser.cache.memory.enable")
);
}
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
optional_permissions: ["browserSettings"],
},
useAddonManager: "permanent",
});
await extension.startup();
ok(cacheIsEnabled(), "setting is not set after startup");
await withHandlingUserInput(extension, async () => {
extension.sendMessage("request");
await extension.awaitMessage("done");
ok(!cacheIsEnabled(), "setting was set after request");
extension.sendMessage("remove");
await extension.awaitMessage("done");
ok(cacheIsEnabled(), "setting is reset after remove");
extension.sendMessage("request");
await extension.awaitMessage("done");
ok(!cacheIsEnabled(), "setting was set after request");
});
await ExtensionPermissions._uninit();
extensionHandlers.delete(extension);
await AddonTestUtils.promiseRestartManager();
await extension.awaitBackgroundStarted();
await withHandlingUserInput(extension, async () => {
extension.sendMessage("remove");
await extension.awaitMessage("done");
ok(cacheIsEnabled(), "setting is reset after remove");
});
await extension.unload();
});
add_task(async function test_privacy_permissions() {
async function background() {
const permObj = { permissions: ["privacy"] };
browser.test.onMessage.addListener(async msg => {
if (msg === "request") {
await browser.permissions.request(permObj);
await browser.privacy.websites.trackingProtectionMode.set({
value: "always",
});
} else if (msg === "remove") {
await browser.permissions.remove(permObj);
}
browser.test.sendMessage("done");
});
}
function hasSetting() {
return Services.prefs.getBoolPref("privacy.trackingprotection.enabled");
}
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
optional_permissions: ["privacy"],
},
useAddonManager: "permanent",
});
await extension.startup();
ok(!hasSetting(), "setting is not set after startup");
await withHandlingUserInput(extension, async () => {
extension.sendMessage("request");
await extension.awaitMessage("done");
ok(hasSetting(), "setting was set after request");
extension.sendMessage("remove");
await extension.awaitMessage("done");
ok(!hasSetting(), "setting is reset after remove");
extension.sendMessage("request");
await extension.awaitMessage("done");
ok(hasSetting(), "setting was set after request");
});
await ExtensionPermissions._uninit();
extensionHandlers.delete(extension);
await AddonTestUtils.promiseRestartManager();
await extension.awaitBackgroundStarted();
await withHandlingUserInput(extension, async () => {
extension.sendMessage("remove");
await extension.awaitMessage("done");
ok(!hasSetting(), "setting is reset after remove");
});
await extension.unload();
});
add_task(
{ pref_set: [["extensions.eventPages.enabled", true]] },
async function test_permissions_event_page() {
let extension = ExtensionTestUtils.loadExtension({
useAddonManager: "permanent",
manifest: {
optional_permissions: ["privacy"],
background: { persistent: false },
},
background() {
browser.permissions.onAdded.addListener(details => {
browser.test.sendMessage("added", details);
});
browser.permissions.onRemoved.addListener(details => {
browser.test.sendMessage("removed", details);
});
},
});
await extension.startup();
let events = ["onAdded", "onRemoved"];
for (let event of events) {
assertPersistentListeners(extension, "permissions", event, {
primed: false,
});
}
await extension.terminateBackground();
for (let event of events) {
assertPersistentListeners(extension, "permissions", event, {
primed: true,
});
}
let permObj = {
permissions: ["privacy"],
origins: [],
data_collection: [],
};
// enable the permissions while the background is stopped
await ExtensionPermissions.add(
extension.id,
// Prevent `permObj` from being mutated.
{ ...permObj },
extension.extension
);
let details = await extension.awaitMessage("added");
Assert.deepEqual(permObj, details, "got added event");
// Restart and test that permission removal wakes the background.
await AddonTestUtils.promiseRestartManager();
await extension.awaitStartup();
for (let event of events) {
assertPersistentListeners(extension, "permissions", event, {
primed: true,
});
}
// remove the permissions while the background is stopped
await ExtensionPermissions.remove(
extension.id,
// Prevent `permObj` from being mutated.
{ ...permObj },
extension.extension
);
details = await extension.awaitMessage("removed");
Assert.deepEqual(permObj, details, "got removed event");
await extension.unload();
}
);
add_task(
{
pref_set: [
["extensions.background.idle.timeout", 100],
["extensions.webextOptionalPermissionPrompts", true],
],
},
async function test_permissions_request_idle_suspend() {
info("Test that permissions.request() keeps bg page alive.");
let pr = Glean.extensionsCounters.eventPageIdleResult.permissions_request;
let before = pr.testGetValue() ?? 0;
info(`Glean value permissions_request before: ${before}`);
async function background() {
browser.test.onMessage.addListener(async () => {
browser.test.log("Calling permissions.request().");
await browser.permissions.request({ permissions: ["browserSettings"] });
browser.test.log("permissions.request() resolved.");
browser.test.sendMessage("done");
});
}
let extension = ExtensionTestUtils.loadExtension({
manifest: {
manifest_version: 3,
optional_permissions: ["browserSettings"],
},
background,
});
await extension.startup();
function obs(subject, _topic) {
info("Waiting 200ms, normally the bg page would idle out.");
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
setTimeout(() => subject.wrappedJSObject.resolve(true), 200);
}
info("Setup permissions prompt observer.");
Services.obs.addObserver(obs, "webextension-optional-permission-prompt");
await withHandlingUserInput(extension, async () => {
extension.sendMessage("request");
await extension.awaitMessage("done");
});
info("permissions.request() resolved successfully, bg page not suspended.");
let count = pr.testGetValue() - before;
// Because this "counter" measures time in increments of
// background.idle.timeout, we know it should take at least 200ms,
// but we need to leave slack of up to 500ms for slow test runs.
ok(count >= 2 && count <= 5, `permissions_request counter: ${count}.`);
Services.obs.removeObserver(obs, "webextension-optional-permission-prompt");
await extension.unload();
}
);
add_task(async function test_getAll_with_data_collection() {
async function background() {
browser.test.onMessage.addListener(async msg => {
browser.test.assertEq("getAll", msg, "expected correct message");
const permissions = await browser.permissions.getAll();
browser.test.sendMessage("all", permissions);
});
browser.permissions.onAdded.addListener(details => {
browser.test.sendMessage("added", details);
});
browser.permissions.onRemoved.addListener(details => {
browser.test.sendMessage("removed", details);
});
browser.test.sendMessage("ready");
}
const extension = ExtensionTestUtils.loadExtension({
manifest: {
manifest_version: 3,
permissions: ["bookmarks"],
browser_specific_settings: {
gecko: {
data_collection_permissions: {
// "none" shouldn't be added to the list of data collection
// permissions returned by `getAll()`.
required: ["none"],
optional: ["technicalAndInteraction", "locationInfo"],
},
},
},
},
background,
});
await extension.startup();
await extension.awaitMessage("ready");
const getAllAndVerifyDataCollection = async expected => {
extension.sendMessage("getAll");
const permissions = await extension.awaitMessage("all");
Assert.deepEqual(
permissions,
{
permissions: ["bookmarks"],
origins: [],
data_collection: expected,
},
"expected permissions with data collection"
);
};
// Pretend the T&I permission was granted at install time.
let perms = {
permissions: [],
origins: [],
data_collection: ["technicalAndInteraction"],
};
await ExtensionPermissions.add(extension.id, perms, extension.extension);
let added = await extension.awaitMessage("added");
Assert.deepEqual(
added,
{
permissions: [],
origins: [],
data_collection: ["technicalAndInteraction"],
},
"expected new permissions granted"
);
await getAllAndVerifyDataCollection(["technicalAndInteraction"]);
// Grant another optional data collection permission.
perms = {
permissions: [],
origins: [],
data_collection: ["technicalAndInteraction", "locationInfo"],
};
await ExtensionPermissions.add(extension.id, perms, extension.extension);
added = await extension.awaitMessage("added");
Assert.deepEqual(
added,
{
permissions: [],
origins: [],
data_collection: ["locationInfo"],
},
"expected new permissions granted"
);
await getAllAndVerifyDataCollection([
"technicalAndInteraction",
"locationInfo",
]);
// Revoke all optional data collection permissions.
await ExtensionPermissions.remove(extension.id, perms, extension.extension);
const removed = await extension.awaitMessage("removed");
Assert.deepEqual(
removed,
{
permissions: [],
origins: [],
data_collection: ["technicalAndInteraction", "locationInfo"],
},
"expected permissions revoked"
);
await getAllAndVerifyDataCollection([]);
await extension.unload();
});
add_task(async function test_getAll_with_required_data_collection() {
async function background() {
browser.test.onMessage.addListener(async msg => {
browser.test.assertEq("getAll", msg, "expected correct message");
const permissions = await browser.permissions.getAll();
browser.test.sendMessage("all", permissions);
});
browser.test.sendMessage("ready");
}
const extension = ExtensionTestUtils.loadExtension({
manifest: {
manifest_version: 3,
permissions: ["bookmarks"],
browser_specific_settings: {
gecko: {
data_collection_permissions: {
required: ["bookmarksInfo"],
optional: ["technicalAndInteraction", "locationInfo"],
},
},
},
},
background,
});
await extension.startup();
await extension.awaitMessage("ready");
extension.sendMessage("getAll");
let permissions = await extension.awaitMessage("all");
Assert.deepEqual(
permissions,
{
permissions: ["bookmarks"],
origins: [],
data_collection: ["bookmarksInfo"],
},
"expected permissions with required data collection"
);
let perms = {
permissions: [],
origins: [],
data_collection: ["technicalAndInteraction"],
};
await ExtensionPermissions.add(extension.id, perms, extension.extension);
extension.sendMessage("getAll");
permissions = await extension.awaitMessage("all");
Assert.deepEqual(
permissions,
{
permissions: ["bookmarks"],
origins: [],
data_collection: ["bookmarksInfo", "technicalAndInteraction"],
},
"expected permissions with newly added data collection"
);
await extension.unload();
});
add_task(async function test_request_with_data_collection() {
async function background() {
browser.test.onMessage.addListener(async msg => {
if (msg === "request-good") {
await browser.permissions.request({
data_collection: ["technicalAndInteraction"],
});
const permissions = await browser.permissions.getAll();
browser.test.sendMessage(`${msg}:done`, permissions);
return;
}
if (msg === "request-invalid") {
try {
browser.permissions.request({
data_collection: ["invalid-permission"],
});
browser.test.fail("expected error");
} catch (err) {
browser.test.assertTrue(
/Error processing data_collection.0: Value "invalid-permission" must either:/.test(
err.message
),
"expected error"
);
}
browser.test.sendMessage(`${msg}:done`);
return;
}
if (msg === "request-bad") {
await browser.test.assertRejects(
browser.permissions.request({
data_collection: ["healthInfo"],
}),
/Cannot request data collection permission healthInfo since it was not declared in data_collection_permissions.optional/,
"Expected rejection"
);
browser.test.sendMessage(`${msg}:done`);
return;
}
browser.test.fail(`Got unexpected msg "${msg}"`);
});
browser.test.sendMessage("ready");
}
const extension = ExtensionTestUtils.loadExtension({
manifest: {
manifest_version: 2,
browser_specific_settings: {
gecko: {
data_collection_permissions: {
optional: ["technicalAndInteraction", "locationInfo"],
},
},
},
},
background,
});
await extension.startup();
await extension.awaitMessage("ready");
await withHandlingUserInput(extension, async () => {
extension.sendMessage("request-bad");
await extension.awaitMessage("request-bad:done");
});
await withHandlingUserInput(extension, async () => {
extension.sendMessage("request-invalid");
await extension.awaitMessage("request-invalid:done");
});
let permissions;
await withHandlingUserInput(extension, async () => {
extension.sendMessage("request-good");
permissions = await extension.awaitMessage("request-good:done");
});
Assert.deepEqual(
permissions,
{
permissions: [],
origins: [],
data_collection: ["technicalAndInteraction"],
},
"expected permissions with data collection"
);
// Reequest the same permission again, which should be already granted.
await withHandlingUserInput(extension, async () => {
extension.sendMessage("request-good");
permissions = await extension.awaitMessage("request-good:done");
});
Assert.deepEqual(
permissions,
{
permissions: [],
origins: [],
data_collection: ["technicalAndInteraction"],
},
"expected permissions with data collection"
);
await extension.unload();
});
add_task(async function test_contains_data_collection() {
async function background() {
browser.test.onMessage.addListener(async (msg, arg) => {
if (msg === "contains") {
const result = await browser.permissions.contains(arg);
browser.test.sendMessage(`${msg}:done`, result);
return;
}
if (msg === "request") {
await browser.permissions.request(arg);
browser.test.sendMessage(`${msg}:done`);
return;
}
if (msg === "remove") {
await browser.permissions.remove(arg);
browser.test.sendMessage(`${msg}:done`);
return;
}
browser.test.fail(`Got unexpected msg "${msg}"`);
});
browser.test.sendMessage("ready");
}
const extension = ExtensionTestUtils.loadExtension({
manifest: {
manifest_version: 2,
optional_permissions: ["bookmarks", "http://*.mozilla.org/*"],
browser_specific_settings: {
gecko: {
data_collection_permissions: {
optional: ["technicalAndInteraction", "locationInfo"],
},
},
},
},
background,
});
await extension.startup();
await extension.awaitMessage("ready");
// A list of permission objects with various combination of api/data
// collection permissions and origins. This will be used in different
// assertions below.
const PERMS = [
{ permissions: ["bookmarks"] },
{ origins: ["http://*.mozilla.org/*"] },
{ permissions: ["bookmarks"], origins: ["http://*.mozilla.org/*"] },
{ data_collection: ["technicalAndInteraction"] },
{ data_collection: ["locationInfo"] },
{ data_collection: ["technicalAndInteraction", "locationInfo"] },
{
permissions: ["bookmarks"],
data_collection: ["technicalAndInteraction", "locationInfo"],
},
{
permissions: ["bookmarks"],
data_collection: ["locationInfo"],
},
{
permissions: ["bookmarks"],
origins: ["http://*.mozilla.org/*"],
data_collection: ["technicalAndInteraction", "locationInfo"],
},
];
let result;
for (const perms of PERMS) {
extension.sendMessage("contains", perms);
result = await extension.awaitMessage("contains:done");
ok(!result, "Expected permission to not be granted");
}
info("request a single data collection permission");
await withHandlingUserInput(extension, async () => {
extension.sendMessage("request", {
data_collection: ["technicalAndInteraction"],
});
await extension.awaitMessage("request:done");
});
extension.sendMessage("contains", {
data_collection: ["technicalAndInteraction"],
});
result = await extension.awaitMessage("contains:done");
ok(result, "Expected permission to be granted");
extension.sendMessage("contains", {
permissions: ["bookmarks"],
data_collection: ["technicalAndInteraction"],
});
result = await extension.awaitMessage("contains:done");
ok(!result, "Expected false because bookmarks isn't granted");
info("request an API permission");
await withHandlingUserInput(extension, async () => {
extension.sendMessage("request", {
permissions: ["bookmarks"],
});
await extension.awaitMessage("request:done");
});
extension.sendMessage("contains", {
permissions: ["bookmarks"],
data_collection: ["technicalAndInteraction"],
});
result = await extension.awaitMessage("contains:done");
ok(result, "Expected permissions to be granted");
extension.sendMessage("contains", {
origins: ["http://*.mozilla.org/*"],
data_collection: ["technicalAndInteraction"],
});
result = await extension.awaitMessage("contains:done");
ok(!result, "Expected false because origin isn't granted");
info("remove data collection permission");
extension.sendMessage("remove", {
data_collection: ["technicalAndInteraction"],
});
await extension.awaitMessage("remove:done");
extension.sendMessage("contains", {
data_collection: ["technicalAndInteraction"],
});
result = await extension.awaitMessage("contains:done");
ok(!result, "Expected permission to not be granted");
info("request all optional permissions");
await withHandlingUserInput(extension, async () => {
extension.sendMessage("request", {
permissions: ["bookmarks"],
origins: ["http://*.mozilla.org/*"],
data_collection: ["technicalAndInteraction", "locationInfo"],
});
await extension.awaitMessage("request:done");
});
for (const perms of PERMS) {
extension.sendMessage("contains", perms);
result = await extension.awaitMessage("contains:done");
ok(result, "Expected permission to be granted");
}
info("remove all");
extension.sendMessage("remove", {
permissions: ["bookmarks"],
origins: ["http://*.mozilla.org/*"],
data_collection: ["technicalAndInteraction", "locationInfo"],
});
await extension.awaitMessage("remove:done");
for (const perms of PERMS) {
extension.sendMessage("contains", perms);
result = await extension.awaitMessage("contains:done");
ok(!result, "Expected permission to not be granted");
}
await extension.unload();
});
// This test verifies that data collection permissions are taken into account when
// an extension is installed before the `extensions.dataCollectionPermissions.enabled`
// pref is enabled.
add_task(
{ pref_set: [["extensions.dataCollectionPermissions.enabled", false]] },
async function test_database_updated_for_data_collection() {
const extension = ExtensionTestUtils.loadExtension({
manifest: {
manifest_version: 2,
browser_specific_settings: {
gecko: {
id: "@updated-db-ext",
data_collection_permissions: {
required: ["locationInfo"],
},
},
},
},
useAddonManager: "permanent",
});
await extension.startup();
const addon = await AddonManager.getAddonByID(extension.id);
ok(addon, "Expected add-on wrapper");
Assert.deepEqual(
addon.userPermissions,
{ permissions: [], origins: [], data_collection: [] },
"Expected no permissions"
);
// Flip the pref.
let observePromise = TestUtils.topicObserved(
"xpi-provider:database-updated"
);
Services.prefs.setBoolPref(
"extensions.dataCollectionPermissions.enabled",
true
);
await observePromise;
Assert.deepEqual(
addon.userPermissions,
{ permissions: [], origins: [], data_collection: ["locationInfo"] },
"Expected data collection permissions"
);
// Flip the pref back to `false`. We do not rebuild the DB in this case.
Services.prefs.setBoolPref(
"extensions.dataCollectionPermissions.enabled",
false
);
Assert.deepEqual(
addon.userPermissions,
{ permissions: [], origins: [], data_collection: ["locationInfo"] },
"Expected data collection permissions"
);
await extension.unload();
}
);