Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
// TODO(Bug 1789718): adapt to synthetic addon type implemented by the SitePermAddonProvider
// or remove if redundant, after the deprecated XPIProvider-based implementation is also removed.
const { AddonManager } = ChromeUtils.importESModule(
);
const { TestUtils } = ChromeUtils.importESModule(
);
const { TelemetryController } = ChromeUtils.importESModule(
);
const { TelemetryTestUtils } = ChromeUtils.importESModule(
);
AddonTestUtils.init(this);
AddonTestUtils.overrideCertDB();
AddonTestUtils.createAppInfo(
"xpcshell@tests.mozilla.org",
"XPCShell",
"42",
"42"
);
const l10n = new Localization([
"toolkit/global/extensions.ftl",
"toolkit/global/extensionPermissions.ftl",
"branding/brand.ftl",
]);
// Localization resources need to be first iterated outside a test
l10n.formatValue("webext-perms-sideload-text");
// Lazily import ExtensionParent to allow AddonTestUtils.createAppInfo to
// override Services.appinfo.
ChromeUtils.defineESModuleGetters(this, {
});
async function _test_manifest(manifest, expectedError) {
ExtensionTestUtils.failOnSchemaWarnings(false);
let normalized = await ExtensionTestUtils.normalizeManifest(
manifest,
"manifest.WebExtensionSitePermissionsManifest"
);
ExtensionTestUtils.failOnSchemaWarnings(true);
if (expectedError) {
ok(
normalized.error.includes(expectedError),
`The manifest error ${JSON.stringify(
normalized.error
)} must contain ${JSON.stringify(expectedError)}`
);
} else {
equal(normalized.error, undefined, "Should not have an error");
}
equal(normalized.errors.length, 0, "Should have no warning");
}
add_setup(async () => {
// Telemetry test setup needed to ensure that the builtin events are defined
// and they can be collected and verified.
await TelemetryController.testSetup();
// This is actually only needed on Android, because it does not properly support unified telemetry
// and so, if not enabled explicitly here, it would make these tests to fail when running on
// release builds.
const oldCanRecordBase = Services.telemetry.canRecordBase;
Services.telemetry.canRecordBase = true;
registerCleanupFunction(() => {
Services.telemetry.canRecordBase = oldCanRecordBase;
});
});
add_task(async function test_manifest_site_permissions() {
await _test_manifest({
site_permissions: ["midi"],
install_origins: ["http://example.com"],
});
await _test_manifest({
site_permissions: ["midi-sysex"],
install_origins: ["http://example.com"],
});
await _test_manifest(
{
site_permissions: ["unknown_site_permission"],
install_origins: ["http://example.com"],
},
`Error processing site_permissions.0: Invalid enumeration value "unknown_site_permission"`
);
await _test_manifest(
{
site_permissions: ["unknown_site_permission"],
install_origins: [],
},
`Error processing install_origins: Array requires at least 1 items;`
);
await _test_manifest(
{
site_permissions: ["unknown_site_permission"],
},
`Property "install_origins" is required`
);
await _test_manifest(
{
install_origins: ["http://example.com"],
},
`Property "site_permissions" is required`
);
// test any extra manifest entries not part of a site permissions addon will cause an error.
await _test_manifest(
{
site_permissions: ["midi"],
install_origins: ["http://example.com"],
permissions: ["webRequest"],
},
`Unexpected property`
);
});
add_task(async function test_sitepermission_telemetry() {
await AddonTestUtils.promiseStartupManager();
Services.telemetry.clearEvents();
const addon_id = "webmidi@test";
const origin = "https://example.com";
const permName = "midi";
let site_permission = {
"manifest.json": {
name: "test Site Permission",
version: "1.0",
manifest_version: 2,
browser_specific_settings: {
gecko: { id: addon_id },
},
install_origins: [origin],
site_permissions: [permName],
},
};
let [, { addon }] = await Promise.all([
TestUtils.topicObserved("webextension-sitepermissions-startup"),
AddonTestUtils.promiseInstallXPI(site_permission),
]);
await addon.uninstall();
await TelemetryTestUtils.assertEvents(
[
[
"addonsManager",
"install",
"siteperm_deprecated",
/.*/,
{
step: "started",
addon_id,
},
],
[
"addonsManager",
"install",
"siteperm_deprecated",
/.*/,
{
step: "completed",
addon_id,
},
],
["addonsManager", "uninstall", "siteperm_deprecated", addon_id],
],
{
category: "addonsManager",
method: /^install|uninstall$/,
}
);
await AddonTestUtils.promiseShutdownManager();
});
async function _test_ext_site_permissions(site_permissions, install_origins) {
ExtensionTestUtils.failOnSchemaWarnings(false);
let extension = ExtensionTestUtils.loadExtension({
manifest: {
install_origins,
site_permissions,
},
});
await extension.startup();
await extension.unload();
ExtensionTestUtils.failOnSchemaWarnings(true);
}
add_task(async function test_ext_site_permissions() {
await _test_ext_site_permissions(["midi"], ["http://example.com"]);
await _test_ext_site_permissions(
["midi"],
).catch(e => {
Assert.ok(
e.message.includes(
"Error processing install_origins: Array requires at most 1 items; you have 2"
),
"Site permissions can only contain one install origin: "
);
});
});
add_task(async function test_sitepermission_type() {
await AddonTestUtils.promiseStartupManager();
// Test more than one perm to make sure both are added.
// While this is allowed, midi-sysex overrides.
let perms = ["midi", "midi-sysex"];
let id = "@test-permission";
let origin = "http://example.com";
let uri = Services.io.newURI(origin);
let principal = Services.scriptSecurityManager.createContentPrincipal(
uri,
{}
);
// give the site some other permission (geo)
Services.perms.addFromPrincipal(
principal,
"geo",
Services.perms.ALLOW_ACTION,
Services.perms.EXPIRE_NEVER
);
let assertGeo = () => {
Assert.equal(
Services.perms.testExactPermissionFromPrincipal(principal, "geo"),
Ci.nsIPermissionManager.ALLOW_ACTION,
"site still has geo permission"
);
};
let checkPerms = (perms, action, msg) => {
for (let permName of perms) {
let permission = Services.perms.testExactPermissionFromPrincipal(
principal,
permName
);
Assert.equal(permission, action, `${permName}: ${msg}`);
}
};
checkPerms(
perms,
Ci.nsIPermissionManager.UNKNOWN_ACTION,
"no permission for site"
);
let site_permission = {
"manifest.json": {
name: "test Site Permission",
version: "1.0",
manifest_version: 2,
browser_specific_settings: {
gecko: {
id,
},
},
install_origins: [origin],
site_permissions: perms,
},
};
let [, { addon }] = await Promise.all([
TestUtils.topicObserved("webextension-sitepermissions-startup"),
AddonTestUtils.promiseInstallXPI(site_permission),
]);
checkPerms(
perms,
Ci.nsIPermissionManager.ALLOW_ACTION,
"extension enabled permission for site"
);
assertGeo();
// Test the permission is retained on restart.
await AddonTestUtils.promiseRestartManager();
addon = await AddonManager.getAddonByID(id);
checkPerms(
perms,
Ci.nsIPermissionManager.ALLOW_ACTION,
"extension enabled permission for site"
);
assertGeo();
// Test that a removed permission is added on restart
Services.perms.removeFromPrincipal(principal, perms[0]);
await AddonTestUtils.promiseRestartManager();
addon = await AddonManager.getAddonByID(id);
checkPerms(
perms,
Ci.nsIPermissionManager.ALLOW_ACTION,
"extension enabled permission for site"
);
assertGeo();
// Test that a changed permission is not changed on restart
Services.perms.addFromPrincipal(
principal,
perms[0],
Services.perms.DENY_ACTION,
Services.perms.EXPIRE_NEVER
);
await AddonTestUtils.promiseRestartManager();
addon = await AddonManager.getAddonByID(id);
checkPerms(
[perms[0]],
Ci.nsIPermissionManager.DENY_ACTION,
"extension enabled permission for site"
);
checkPerms(
[perms[1]],
Ci.nsIPermissionManager.ALLOW_ACTION,
"extension enabled permission for site"
);
assertGeo();
// Test permission removal when addon disabled
await addon.disable();
checkPerms(
perms,
Ci.nsIPermissionManager.UNKNOWN_ACTION,
"no permission for site"
);
assertGeo();
// Enabling an addon will always force ALLOW_ACTION
await addon.enable();
checkPerms(
perms,
Ci.nsIPermissionManager.ALLOW_ACTION,
"extension enabled permission for site"
);
assertGeo();
// Test permission removal when addon uninstalled
await addon.uninstall();
checkPerms(
perms,
Ci.nsIPermissionManager.UNKNOWN_ACTION,
"no permission for site"
);
assertGeo();
});
add_task(async function test_site_permissions_have_localization_strings() {
await ExtensionParent.apiManager.lazyInit();
const SCHEMA_SITE_PERMISSIONS = Schemas.getPermissionNames([
"SitePermission",
]);
ok(SCHEMA_SITE_PERMISSIONS.length, "we have site permissions");
for (const perm of SCHEMA_SITE_PERMISSIONS) {
const l10nId = `webext-site-perms-${perm}`;
try {
const str = await l10n.formatValue(l10nId);
ok(str.length, `Found localization string for '${perm}' site permission`);
} catch (e) {
ok(false, `Site permission missing '${perm}'`);
}
}
});