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";
ChromeUtils.defineESModuleGetters(this, {
ExtensionSettingsStore:
"resource://gre/modules/ExtensionSettingsStore.sys.mjs",
});
const { createAppInfo, promiseShutdownManager, promiseStartupManager } =
AddonTestUtils;
AddonTestUtils.init(this);
// Allow for unsigned addons.
AddonTestUtils.overrideCertDB();
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
const ITEMS = {
key1: [
{ key: "key1", value: "val1", id: "@first" },
{ key: "key1", value: "val2", id: "@second" },
{ key: "key1", value: "val3", id: "@third" },
],
key2: [
{ key: "key2", value: "val1-2", id: "@first" },
{ key: "key2", value: "val2-2", id: "@second" },
{ key: "key2", value: "val3-2", id: "@third" },
],
};
const KEY_LIST = Object.keys(ITEMS);
const TEST_TYPE = "myType";
let callbackCount = 0;
function initialValue(key) {
callbackCount++;
return `key:${key}`;
}
add_task(async function test_settings_store() {
await promiseStartupManager();
// Create an array of test framework extension wrappers to install.
let testExtensions = [
ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
browser_specific_settings: { gecko: { id: "@first" } },
},
}),
ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
browser_specific_settings: { gecko: { id: "@second" } },
},
}),
ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
browser_specific_settings: { gecko: { id: "@third" } },
},
}),
];
for (let extension of testExtensions) {
await extension.startup();
}
// Create an array actual Extension objects which correspond to the
// test framework extension wrappers.
let extensions = testExtensions.map(extension => extension.extension);
let expectedCallbackCount = 0;
await Assert.rejects(
ExtensionSettingsStore.getLevelOfControl(1, TEST_TYPE, "key"),
/The ExtensionSettingsStore was accessed before the initialize promise resolved/,
"Accessing the SettingsStore before it is initialized throws an error."
);
// Initialize the SettingsStore.
await ExtensionSettingsStore.initialize();
// Add a setting for the second oldest extension, where it is the only setting for a key.
for (let key of KEY_LIST) {
let extensionIndex = 1;
let itemToAdd = ITEMS[key][extensionIndex];
let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[extensionIndex].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controllable_by_this_extension",
"getLevelOfControl returns correct levelOfControl with no settings set for a key."
);
let item = await ExtensionSettingsStore.addSetting(
extensions[extensionIndex].id,
TEST_TYPE,
itemToAdd.key,
itemToAdd.value,
initialValue
);
expectedCallbackCount++;
equal(
callbackCount,
expectedCallbackCount,
"initialValueCallback called the expected number of times."
);
deepEqual(
item,
itemToAdd,
"Adding initial item for a key returns that item."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(
item,
itemToAdd,
"getSetting returns correct item with only one item in the list."
);
levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[extensionIndex].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controlled_by_this_extension",
"getLevelOfControl returns correct levelOfControl with only one item in the list."
);
ok(
ExtensionSettingsStore.hasSetting(
extensions[extensionIndex].id,
TEST_TYPE,
key
),
"hasSetting returns the correct value when an extension has a setting set."
);
item = await ExtensionSettingsStore.getSetting(
TEST_TYPE,
key,
extensions[extensionIndex].id
);
deepEqual(
item,
itemToAdd,
"getSetting with id returns correct item with only one item in the list."
);
}
// Add a setting for the oldest extension.
for (let key of KEY_LIST) {
let extensionIndex = 0;
let itemToAdd = ITEMS[key][extensionIndex];
let item = await ExtensionSettingsStore.addSetting(
extensions[extensionIndex].id,
TEST_TYPE,
itemToAdd.key,
itemToAdd.value,
initialValue
);
equal(
callbackCount,
expectedCallbackCount,
"initialValueCallback called the expected number of times."
);
equal(
item,
null,
"An older extension adding a setting for a key returns null"
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(
item,
ITEMS[key][1],
"getSetting returns correct item with more than one item in the list."
);
let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[extensionIndex].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controlled_by_other_extensions",
"getLevelOfControl returns correct levelOfControl when another extension is in control."
);
item = await ExtensionSettingsStore.getSetting(
TEST_TYPE,
key,
extensions[extensionIndex].id
);
deepEqual(
item,
itemToAdd,
"getSetting with id returns correct item with more than one item in the list."
);
}
// Reload the settings store to emulate a browser restart.
await ExtensionSettingsStore._reloadFile();
// Add a setting for the newest extension.
for (let key of KEY_LIST) {
let extensionIndex = 2;
let itemToAdd = ITEMS[key][extensionIndex];
let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[extensionIndex].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controllable_by_this_extension",
"getLevelOfControl returns correct levelOfControl for a more recent extension."
);
let item = await ExtensionSettingsStore.addSetting(
extensions[extensionIndex].id,
TEST_TYPE,
itemToAdd.key,
itemToAdd.value,
initialValue
);
equal(
callbackCount,
expectedCallbackCount,
"initialValueCallback called the expected number of times."
);
deepEqual(
item,
itemToAdd,
"Adding item for most recent extension returns that item."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(
item,
itemToAdd,
"getSetting returns correct item with more than one item in the list."
);
levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[extensionIndex].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controlled_by_this_extension",
"getLevelOfControl returns correct levelOfControl when this extension is in control."
);
item = await ExtensionSettingsStore.getSetting(
TEST_TYPE,
key,
extensions[extensionIndex].id
);
deepEqual(
item,
itemToAdd,
"getSetting with id returns correct item with more than one item in the list."
);
}
for (let extension of extensions) {
let items = await ExtensionSettingsStore.getAllForExtension(
extension.id,
TEST_TYPE
);
deepEqual(items, KEY_LIST, "getAllForExtension returns expected keys.");
}
// Attempting to remove a setting that has not been set should *not* throw an exception.
let removeResult = await ExtensionSettingsStore.removeSetting(
extensions[0].id,
"myType",
"unset_key"
);
equal(
removeResult,
null,
"Removing a setting that was not previously set returns null."
);
// Attempting to disable a setting that has not been set should throw an exception.
Assert.throws(
() =>
ExtensionSettingsStore.disable(extensions[0].id, "myType", "unset_key"),
/Cannot alter the setting for myType:unset_key as it does not exist/,
"disable rejects with an unset key."
);
// Attempting to enable a setting that has not been set should throw an exception.
Assert.throws(
() =>
ExtensionSettingsStore.enable(extensions[0].id, "myType", "unset_key"),
/Cannot alter the setting for myType:unset_key as it does not exist/,
"enable rejects with an unset key."
);
let expectedKeys = KEY_LIST;
// Disable the non-top item for a key.
for (let key of KEY_LIST) {
let extensionIndex = 0;
let item = await ExtensionSettingsStore.addSetting(
extensions[extensionIndex].id,
TEST_TYPE,
key,
"new value",
initialValue
);
equal(
callbackCount,
expectedCallbackCount,
"initialValueCallback called the expected number of times."
);
equal(item, null, "Updating non-top item for a key returns null");
item = await ExtensionSettingsStore.disable(
extensions[extensionIndex].id,
TEST_TYPE,
key
);
equal(item, null, "Disabling non-top item for a key returns null.");
let allForExtension = await ExtensionSettingsStore.getAllForExtension(
extensions[extensionIndex].id,
TEST_TYPE
);
deepEqual(
allForExtension,
expectedKeys,
"getAllForExtension returns expected keys after a disable."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(
item,
ITEMS[key][2],
"getSetting returns correct item after a disable."
);
let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[extensionIndex].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controlled_by_other_extensions",
"getLevelOfControl returns correct levelOfControl after disabling of non-top item."
);
}
// Re-enable the non-top item for a key.
for (let key of KEY_LIST) {
let extensionIndex = 0;
let item = await ExtensionSettingsStore.enable(
extensions[extensionIndex].id,
TEST_TYPE,
key
);
equal(item, null, "Enabling non-top item for a key returns null.");
let allForExtension = await ExtensionSettingsStore.getAllForExtension(
extensions[extensionIndex].id,
TEST_TYPE
);
deepEqual(
allForExtension,
expectedKeys,
"getAllForExtension returns expected keys after an enable."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(
item,
ITEMS[key][2],
"getSetting returns correct item after an enable."
);
let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[extensionIndex].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controlled_by_other_extensions",
"getLevelOfControl returns correct levelOfControl after enabling of non-top item."
);
}
// Remove the non-top item for a key.
for (let key of KEY_LIST) {
let extensionIndex = 0;
let item = await ExtensionSettingsStore.removeSetting(
extensions[extensionIndex].id,
TEST_TYPE,
key
);
equal(item, null, "Removing non-top item for a key returns null.");
expectedKeys = expectedKeys.filter(expectedKey => expectedKey != key);
let allForExtension = await ExtensionSettingsStore.getAllForExtension(
extensions[extensionIndex].id,
TEST_TYPE
);
deepEqual(
allForExtension,
expectedKeys,
"getAllForExtension returns expected keys after a removal."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(
item,
ITEMS[key][2],
"getSetting returns correct item after a removal."
);
let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[extensionIndex].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controlled_by_other_extensions",
"getLevelOfControl returns correct levelOfControl after removal of non-top item."
);
ok(
!ExtensionSettingsStore.hasSetting(
extensions[extensionIndex].id,
TEST_TYPE,
key
),
"hasSetting returns the correct value when an extension does not have a setting set."
);
}
for (let key of KEY_LIST) {
// Disable the top item for a key.
let item = await ExtensionSettingsStore.disable(
extensions[2].id,
TEST_TYPE,
key
);
deepEqual(
item,
ITEMS[key][1],
"Disabling top item for a key returns the new top item."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(
item,
ITEMS[key][1],
"getSetting returns correct item after a disable."
);
let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[2].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controllable_by_this_extension",
"getLevelOfControl returns correct levelOfControl after disabling of top item."
);
// Re-enable the top item for a key.
item = await ExtensionSettingsStore.enable(
extensions[2].id,
TEST_TYPE,
key
);
deepEqual(
item,
ITEMS[key][2],
"Re-enabling top item for a key returns the old top item."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(
item,
ITEMS[key][2],
"getSetting returns correct item after an enable."
);
levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[2].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controlled_by_this_extension",
"getLevelOfControl returns correct levelOfControl after re-enabling top item."
);
// Remove the top item for a key.
item = await ExtensionSettingsStore.removeSetting(
extensions[2].id,
TEST_TYPE,
key
);
deepEqual(
item,
ITEMS[key][1],
"Removing top item for a key returns the new top item."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(
item,
ITEMS[key][1],
"getSetting returns correct item after a removal."
);
levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[2].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controllable_by_this_extension",
"getLevelOfControl returns correct levelOfControl after removal of top item."
);
// Add a setting for the current top item.
let itemToAdd = { key, value: `new-${key}`, id: "@second" };
item = await ExtensionSettingsStore.addSetting(
extensions[1].id,
TEST_TYPE,
itemToAdd.key,
itemToAdd.value,
initialValue
);
equal(
callbackCount,
expectedCallbackCount,
"initialValueCallback called the expected number of times."
);
deepEqual(
item,
itemToAdd,
"Updating top item for a key returns that item."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(
item,
itemToAdd,
"getSetting returns correct item after updating."
);
levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[1].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controlled_by_this_extension",
"getLevelOfControl returns correct levelOfControl after updating."
);
// Disable the last remaining item for a key.
let expectedItem = { key, initialValue: initialValue(key) };
// We're using the callback to set the expected value, so we need to increment the
// expectedCallbackCount.
expectedCallbackCount++;
item = await ExtensionSettingsStore.disable(
extensions[1].id,
TEST_TYPE,
key
);
deepEqual(
item,
expectedItem,
"Disabling last item for a key returns the initial value."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(
item,
expectedItem,
"getSetting returns the initial value after all are disabled."
);
levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[1].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controllable_by_this_extension",
"getLevelOfControl returns correct levelOfControl after all are disabled."
);
// Re-enable the last remaining item for a key.
item = await ExtensionSettingsStore.enable(
extensions[1].id,
TEST_TYPE,
key
);
deepEqual(
item,
itemToAdd,
"Re-enabling last item for a key returns the old value."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(
item,
itemToAdd,
"getSetting returns expected value after re-enabling."
);
levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[1].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controlled_by_this_extension",
"getLevelOfControl returns correct levelOfControl after re-enabling."
);
// Remove the last remaining item for a key.
item = await ExtensionSettingsStore.removeSetting(
extensions[1].id,
TEST_TYPE,
key
);
deepEqual(
item,
expectedItem,
"Removing last item for a key returns the initial value."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
deepEqual(item, null, "getSetting returns null after all are removed.");
levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[1].id,
TEST_TYPE,
key
);
equal(
levelOfControl,
"controllable_by_this_extension",
"getLevelOfControl returns correct levelOfControl after all are removed."
);
// Attempting to remove a setting that has had all extensions removed should *not* throw an exception.
removeResult = await ExtensionSettingsStore.removeSetting(
extensions[1].id,
TEST_TYPE,
key
);
equal(
removeResult,
null,
"Removing a setting that has had all extensions removed returns null."
);
}
// Test adding a setting with a value in callbackArgument.
let extensionIndex = 0;
let testKey = "callbackArgumentKey";
let callbackArgumentValue = Date.now();
// Add the setting.
let item = await ExtensionSettingsStore.addSetting(
extensions[extensionIndex].id,
TEST_TYPE,
testKey,
1,
initialValue,
callbackArgumentValue
);
expectedCallbackCount++;
equal(
callbackCount,
expectedCallbackCount,
"initialValueCallback called the expected number of times."
);
// Remove the setting which should return the initial value.
let expectedItem = {
key: testKey,
initialValue: initialValue(callbackArgumentValue),
};
// We're using the callback to set the expected value, so we need to increment the
// expectedCallbackCount.
expectedCallbackCount++;
item = await ExtensionSettingsStore.removeSetting(
extensions[extensionIndex].id,
TEST_TYPE,
testKey
);
deepEqual(
item,
expectedItem,
"Removing last item for a key returns the initial value."
);
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, testKey);
deepEqual(item, null, "getSetting returns null after all are removed.");
item = await ExtensionSettingsStore.getSetting(TEST_TYPE, "not a key");
equal(
item,
null,
"getSetting returns a null item if the setting does not have any records."
);
let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(
extensions[1].id,
TEST_TYPE,
"not a key"
);
equal(
levelOfControl,
"controllable_by_this_extension",
"getLevelOfControl returns correct levelOfControl if the setting does not have any records."
);
for (let extension of testExtensions) {
await extension.unload();
}
await promiseShutdownManager();
});
add_task(async function test_settings_store_setByUser() {
await promiseStartupManager();
// Create an array of test framework extension wrappers to install.
let testExtensions = [
ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
browser_specific_settings: { gecko: { id: "@first" } },
},
}),
ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
browser_specific_settings: { gecko: { id: "@second" } },
},
}),
];
let type = "some_type";
let key = "some_key";
for (let extension of testExtensions) {
await extension.startup();
}
// Create an array actual Extension objects which correspond to the
// test framework extension wrappers.
let [one, two] = testExtensions.map(extension => extension.extension);
let initialCallback = () => "initial";
// Initialize the SettingsStore.
await ExtensionSettingsStore.initialize();
equal(
null,
ExtensionSettingsStore.getSetting(type, key),
"getSetting is initially null"
);
let item = await ExtensionSettingsStore.addSetting(
one.id,
type,
key,
"one",
initialCallback
);
deepEqual(
{ key, value: "one", id: one.id },
item,
"addSetting returns the first set item"
);
item = await ExtensionSettingsStore.addSetting(
two.id,
type,
key,
"two",
initialCallback
);
deepEqual(
{ key, value: "two", id: two.id },
item,
"addSetting returns the second set item"
);
// a user-set selection reverts to precedence order when new
// extension sets the setting.
ExtensionSettingsStore.select(
ExtensionSettingsStore.SETTING_USER_SET,
type,
key
);
deepEqual(
{ key, initialValue: "initial" },
ExtensionSettingsStore.getSetting(type, key),
"getSetting returns the initial value after being set by user"
);
let three = ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
browser_specific_settings: { gecko: { id: "@third" } },
},
});
await three.startup();
item = await ExtensionSettingsStore.addSetting(
three.id,
type,
key,
"three",
initialCallback
);
deepEqual(
{ key, value: "three", id: three.id },
item,
"addSetting returns the third set item"
);
deepEqual(
item,
ExtensionSettingsStore.getSetting(type, key),
"getSetting returns the third set item"
);
ExtensionSettingsStore.select(
ExtensionSettingsStore.SETTING_USER_SET,
type,
key
);
deepEqual(
{ key, initialValue: "initial" },
ExtensionSettingsStore.getSetting(type, key),
"getSetting returns the initial value after being set by user"
);
item = ExtensionSettingsStore.select(one.id, type, key);
deepEqual(
{ key, value: "one", id: one.id },
item,
"selecting an extension returns the first set item after enable"
);
// Disabling a selected item returns to precedence order
ExtensionSettingsStore.disable(one.id, type, key);
deepEqual(
{ key, value: "three", id: three.id },
ExtensionSettingsStore.getSetting(type, key),
"returning to precedence order sets the third set item"
);
// Test that disabling all then enabling one does not take over a user-set setting.
ExtensionSettingsStore.select(
ExtensionSettingsStore.SETTING_USER_SET,
type,
key
);
deepEqual(
{ key, initialValue: "initial" },
ExtensionSettingsStore.getSetting(type, key),
"getSetting returns the initial value after being set by user"
);
ExtensionSettingsStore.disable(three.id, type, key);
ExtensionSettingsStore.disable(two.id, type, key);
deepEqual(
{ key, initialValue: "initial" },
ExtensionSettingsStore.getSetting(type, key),
"getSetting returns the initial value after disabling all extensions"
);
ExtensionSettingsStore.enable(three.id, type, key);
deepEqual(
{ key, initialValue: "initial" },
ExtensionSettingsStore.getSetting(type, key),
"getSetting returns the initial value after enabling one extension"
);
// Ensure that calling addSetting again will not reset a user-set value when
// the extension install date is older than the user-set date.
item = await ExtensionSettingsStore.addSetting(
three.id,
type,
key,
"three",
initialCallback
);
deepEqual(
{ key, initialValue: "initial" },
ExtensionSettingsStore.getSetting(type, key),
"getSetting returns the initial value after calling addSetting for old addon"
);
item = ExtensionSettingsStore.enable(three.id, type, key);
equal(undefined, item, "enabling the active item does not return an item");
deepEqual(
{ key, initialValue: "initial" },
ExtensionSettingsStore.getSetting(type, key),
"getSetting returns the initial value after enabling one extension"
);
ExtensionSettingsStore.removeSetting(three.id, type, key);
ExtensionSettingsStore.removeSetting(two.id, type, key);
ExtensionSettingsStore.removeSetting(one.id, type, key);
equal(
null,
ExtensionSettingsStore.getSetting(type, key),
"getSetting returns null after removing all settings"
);
for (let extension of testExtensions) {
await extension.unload();
}
await promiseShutdownManager();
});
add_task(async function test_settings_store_add_disabled() {
await promiseStartupManager();
let id = "@add-on-disable";
let extension = ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
browser_specific_settings: { gecko: { id } },
},
});
await extension.startup();
await ExtensionSettingsStore.initialize();
await ExtensionSettingsStore.addSetting(
id,
"foo",
"bar",
"set",
() => "not set"
);
let item = ExtensionSettingsStore.getSetting("foo", "bar");
equal(item.id, id, "The add-on is in control");
equal(item.value, "set", "The value is set");
ExtensionSettingsStore.disable(id, "foo", "bar");
item = ExtensionSettingsStore.getSetting("foo", "bar");
equal(item.id, undefined, "The add-on is not in control");
equal(item.initialValue, "not set", "The value is not set");
await ExtensionSettingsStore.addSetting(
id,
"foo",
"bar",
"set",
() => "not set"
);
item = ExtensionSettingsStore.getSetting("foo", "bar");
equal(item.id, id, "The add-on is in control");
equal(item.value, "set", "The value is set");
await extension.unload();
await promiseShutdownManager();
});
add_task(async function test_settings_uninstall_remove() {
await promiseStartupManager();
let id = "@add-on-uninstall";
let extension = ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
browser_specific_settings: { gecko: { id } },
},
});
await extension.startup();
await ExtensionSettingsStore.initialize();
await ExtensionSettingsStore.addSetting(
id,
"foo",
"bar",
"set",
() => "not set"
);
let item = ExtensionSettingsStore.getSetting("foo", "bar");
equal(item.id, id, "The add-on is in control");
equal(item.value, "set", "The value is set");
await extension.unload();
await promiseShutdownManager();
item = ExtensionSettingsStore.getSetting("foo", "bar");
equal(item, null, "The add-on setting was removed");
});
add_task(async function test_exceptions() {
await ExtensionSettingsStore.initialize();
await Assert.rejects(
ExtensionSettingsStore.addSetting(
1,
TEST_TYPE,
"key_not_a_function",
"val1",
"not a function"
),
/initialValueCallback must be a function/,
"addSetting rejects with a callback that is not a function."
);
});
add_task(async function test_get_all_settings() {
await promiseStartupManager();
let testExtensions = [
ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
browser_specific_settings: { gecko: { id: "@first" } },
},
}),
ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
browser_specific_settings: { gecko: { id: "@second" } },
},
}),
];
for (let extension of testExtensions) {
await extension.startup();
}
await ExtensionSettingsStore.initialize();
let items = ExtensionSettingsStore.getAllSettings("foo", "bar");
equal(items.length, 0, "There are no addons controlling this setting yet");
await ExtensionSettingsStore.addSetting(
"@first",
"foo",
"bar",
"set",
() => "not set"
);
items = ExtensionSettingsStore.getAllSettings("foo", "bar");
equal(items.length, 1, "The add-on setting has 1 addon trying to control it");
await ExtensionSettingsStore.addSetting(
"@second",
"foo",
"bar",
"setting",
() => "not set"
);
let item = ExtensionSettingsStore.getSetting("foo", "bar");
equal(item.id, "@second", "The second add-on is in control");
equal(item.value, "setting", "The second value is set");
items = ExtensionSettingsStore.getAllSettings("foo", "bar");
equal(
items.length,
2,
"The add-on setting has 2 addons trying to control it"
);
await ExtensionSettingsStore.removeSetting("@first", "foo", "bar");
items = ExtensionSettingsStore.getAllSettings("foo", "bar");
equal(items.length, 1, "There is only 1 addon controlling this setting");
await ExtensionSettingsStore.removeSetting("@second", "foo", "bar");
items = ExtensionSettingsStore.getAllSettings("foo", "bar");
equal(
items.length,
0,
"There is no longer any addon controlling this setting"
);
for (let extension of testExtensions) {
await extension.unload();
}
await promiseShutdownManager();
});