summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/mochitest/test_ext_storage_cleanup.html
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /toolkit/components/extensions/test/mochitest/test_ext_storage_cleanup.html
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/extensions/test/mochitest/test_ext_storage_cleanup.html')
-rw-r--r--toolkit/components/extensions/test/mochitest/test_ext_storage_cleanup.html277
1 files changed, 277 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/mochitest/test_ext_storage_cleanup.html b/toolkit/components/extensions/test/mochitest/test_ext_storage_cleanup.html
new file mode 100644
index 0000000000..33029cf61e
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/test_ext_storage_cleanup.html
@@ -0,0 +1,277 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>WebExtension test</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
+ <script type="text/javascript" src="head.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+
+<script type="text/javascript">
+"use strict";
+
+const { ExtensionStorageIDB } = SpecialPowers.ChromeUtils.importESModule(
+ "resource://gre/modules/ExtensionStorageIDB.sys.mjs"
+);
+
+const storageTestHelpers = {
+ storageLocal: {
+ async writeData() {
+ await browser.storage.local.set({hello: "world"});
+ browser.test.sendMessage("finished");
+ },
+
+ async readData() {
+ const matchBrowserStorage = await browser.storage.local.get("hello").then(result => {
+ return (Object.keys(result).length == 1 && result.hello == "world");
+ });
+
+ browser.test.sendMessage("results", {matchBrowserStorage});
+ },
+
+ assertResults({results, keepOnUninstall}) {
+ if (keepOnUninstall) {
+ is(results.matchBrowserStorage, true, "browser.storage.local data is still present");
+ } else {
+ is(results.matchBrowserStorage, false, "browser.storage.local data was cleared");
+ }
+ },
+ },
+ storageSync: {
+ async writeData() {
+ await browser.storage.sync.set({hello: "world"});
+ browser.test.sendMessage("finished");
+ },
+
+ async readData() {
+ const matchBrowserStorage = await browser.storage.sync.get("hello").then(result => {
+ return (Object.keys(result).length == 1 && result.hello == "world");
+ });
+
+ browser.test.sendMessage("results", {matchBrowserStorage});
+ },
+
+ assertResults({results, keepOnUninstall}) {
+ if (keepOnUninstall) {
+ is(results.matchBrowserStorage, true, "browser.storage.sync data is still present");
+ } else {
+ is(results.matchBrowserStorage, false, "browser.storage.sync data was cleared");
+ }
+ },
+ },
+ webAPIs: {
+ async readData() {
+ let matchLocalStorage = (localStorage.getItem("hello") == "world");
+
+ let idbPromise = new Promise((resolve, reject) => {
+ let req = indexedDB.open("test");
+ req.onerror = e => {
+ reject(new Error(`indexedDB open failed with ${e.errorCode}`));
+ };
+
+ req.onupgradeneeded = e => {
+ // no database, data is not present
+ resolve(false);
+ };
+
+ req.onsuccess = e => {
+ let db = e.target.result;
+ let transaction = db.transaction("store", "readwrite");
+ let addreq = transaction.objectStore("store").get("hello");
+ addreq.onerror = addreqError => {
+ reject(new Error(`read from indexedDB failed with ${addreqError.errorCode}`));
+ };
+ addreq.onsuccess = () => {
+ let match = (addreq.result.value == "world");
+ resolve(match);
+ };
+ };
+ });
+
+ await idbPromise.then(matchIDB => {
+ let result = {matchLocalStorage, matchIDB};
+ browser.test.sendMessage("results", result);
+ });
+ },
+
+ async writeData() {
+ localStorage.setItem("hello", "world");
+
+ let idbPromise = new Promise((resolve, reject) => {
+ let req = indexedDB.open("test");
+ req.onerror = e => {
+ reject(new Error(`indexedDB open failed with ${e.errorCode}`));
+ };
+
+ req.onupgradeneeded = e => {
+ let db = e.target.result;
+ db.createObjectStore("store", {keyPath: "name"});
+ };
+
+ req.onsuccess = e => {
+ let db = e.target.result;
+ let transaction = db.transaction("store", "readwrite");
+ let addreq = transaction.objectStore("store")
+ .add({name: "hello", value: "world"});
+ addreq.onerror = addreqError => {
+ reject(new Error(`add to indexedDB failed with ${addreqError.errorCode}`));
+ };
+ addreq.onsuccess = () => {
+ resolve();
+ };
+ };
+ });
+
+ await idbPromise.then(() => {
+ browser.test.sendMessage("finished");
+ });
+ },
+
+ assertResults({results, keepOnUninstall}) {
+ if (keepOnUninstall) {
+ is(results.matchLocalStorage, true, "localStorage data is still present");
+ is(results.matchIDB, true, "indexedDB data is still present");
+ } else {
+ is(results.matchLocalStorage, false, "localStorage data was cleared");
+ is(results.matchIDB, false, "indexedDB data was cleared");
+ }
+ },
+ },
+};
+
+async function test_uninstall({extensionId, writeData, readData, assertResults}) {
+ // Set the pref to prevent cleaning up storage on uninstall in a separate prefEnv
+ // so we can pop it below, leaving flags set in the previous prefEnvs unmodified.
+ await SpecialPowers.pushPrefEnv({
+ set: [["extensions.webextensions.keepStorageOnUninstall", true]],
+ });
+
+ let extension = ExtensionTestUtils.loadExtension({
+ background: writeData,
+ manifest: {
+ browser_specific_settings: {gecko: {id: extensionId}},
+ permissions: ["storage"],
+ },
+ useAddonManager: "temporary",
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("finished");
+ await extension.unload();
+
+ // Check that we can still see data we wrote to storage but clear the
+ // "leave storage" flag so our storaged gets cleared on the next uninstall.
+ // This effectively tests the keepUuidOnUninstall logic, which ensures
+ // that when we read storage again and check that it is cleared, that
+ // it is actually a meaningful test!
+ await SpecialPowers.popPrefEnv();
+
+ extension = ExtensionTestUtils.loadExtension({
+ background: readData,
+ manifest: {
+ browser_specific_settings: {gecko: {id: extensionId}},
+ permissions: ["storage"],
+ },
+ useAddonManager: "temporary",
+ });
+
+ await extension.startup();
+ let results = await extension.awaitMessage("results");
+
+ assertResults({results, keepOnUninstall: true});
+
+ await extension.unload();
+
+ // Read again. This time, our data should be gone.
+ extension = ExtensionTestUtils.loadExtension({
+ background: readData,
+ manifest: {
+ browser_specific_settings: {gecko: {id: extensionId}},
+ permissions: ["storage"],
+ },
+ useAddonManager: "temporary",
+ });
+
+ await extension.startup();
+ results = await extension.awaitMessage("results");
+
+ assertResults({results, keepOnUninstall: false});
+
+ await extension.unload();
+}
+
+
+add_task(async function test_setup_keep_uuid_on_uninstall() {
+ // Use a test-only pref to leave the addonid->uuid mapping around after
+ // uninstall so that we can re-attach to the same storage (this prefEnv
+ // is kept for this entire file and cleared automatically once all the
+ // tests in this file have been executed).
+ await SpecialPowers.pushPrefEnv({
+ set: [["extensions.webextensions.keepUuidOnUninstall", true]],
+ });
+});
+
+// Test extension indexedDB and localStorage storages get cleaned up when the
+// extension is uninstalled.
+add_task(async function test_uninstall_with_webapi_storages() {
+ await test_uninstall({
+ extensionId: "storage.cleanup-WebAPIStorages@tests.mozilla.org",
+ ...(storageTestHelpers.webAPIs),
+ });
+});
+
+// Test browser.storage.local with JSONFile backend gets cleaned up when the
+// extension is uninstalled.
+add_task(async function test_uninistall_with_storage_local_file_backend() {
+ await SpecialPowers.pushPrefEnv({
+ set: [[ExtensionStorageIDB.BACKEND_ENABLED_PREF, false]],
+ });
+
+ await test_uninstall({
+ extensionId: "storage.cleanup-JSONFileBackend@tests.mozilla.org",
+ ...(storageTestHelpers.storageLocal),
+ });
+
+ await SpecialPowers.popPrefEnv();
+});
+
+// Repeat the cleanup test when the storage.local IndexedDB backend is enabled.
+add_task(async function test_uninistall_with_storage_local_idb_backend() {
+ await SpecialPowers.pushPrefEnv({
+ set: [[ExtensionStorageIDB.BACKEND_ENABLED_PREF, true]],
+ });
+
+ await test_uninstall({
+ extensionId: "storage.cleanup-IDBBackend@tests.mozilla.org",
+ ...(storageTestHelpers.storageLocal),
+ });
+
+ await SpecialPowers.popPrefEnv();
+});
+
+// Legacy storage.sync backend is still being used on GeckoView builds.
+const storageSyncOldKintoBackend = SpecialPowers.Services.prefs.getBoolPref(
+ "webextensions.storage.sync.kinto",
+ false
+);
+
+// Verify browser.storage.sync rust backend is also cleared on uninstall.
+async function test_uninistall_with_storage_sync() {
+ await test_uninstall({
+ extensionId: "storage.cleanup-sync@tests.mozilla.org",
+ ...(storageTestHelpers.storageSync),
+ });
+}
+
+// NOTE: ideally we would be using a skip_if option on the add_task call,
+// but we don't support that in the add_task defined in mochitest-plain.
+if (!storageSyncOldKintoBackend) {
+ add_task(test_uninistall_with_storage_sync);
+}
+
+</script>
+
+</body>
+</html>