summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/xpcshell/test_ext_alarms.js
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/xpcshell/test_ext_alarms.js
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/xpcshell/test_ext_alarms.js')
-rw-r--r--toolkit/components/extensions/test/xpcshell/test_ext_alarms.js346
1 files changed, 346 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_alarms.js b/toolkit/components/extensions/test/xpcshell/test_ext_alarms.js
new file mode 100644
index 0000000000..892a82e2e3
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_alarms.js
@@ -0,0 +1,346 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
+"use strict";
+
+AddonTestUtils.init(this);
+AddonTestUtils.overrideCertDB();
+AddonTestUtils.createAppInfo(
+ "xpcshell@tests.mozilla.org",
+ "XPCShell",
+ "1",
+ "43"
+);
+
+add_task(
+ {
+ // TODO(Bug 1725478): remove the skip if once webidl API bindings will be hidden based on permissions.
+ skip_if: () => ExtensionTestUtils.isInBackgroundServiceWorkerTests(),
+ },
+ async function test_alarm_without_permissions() {
+ function backgroundScript() {
+ browser.test.assertTrue(
+ !browser.alarms,
+ "alarm API is not available when the alarm permission is not required"
+ );
+ browser.test.notifyPass("alarms_permission");
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ background: `(${backgroundScript})()`,
+ manifest: {
+ permissions: [],
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitFinish("alarms_permission");
+ await extension.unload();
+ }
+);
+
+add_task(async function test_alarm_clear_non_matching_name() {
+ async function backgroundScript() {
+ let ALARM_NAME = "test_ext_alarms";
+
+ browser.alarms.create(ALARM_NAME, { when: Date.now() + 2000000 });
+
+ let wasCleared = await browser.alarms.clear(ALARM_NAME + "1");
+ browser.test.assertFalse(wasCleared, "alarm was not cleared");
+
+ let alarms = await browser.alarms.getAll();
+ browser.test.assertEq(1, alarms.length, "alarm was not removed");
+ browser.test.notifyPass("alarm-clear");
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ background: `(${backgroundScript})()`,
+ manifest: {
+ permissions: ["alarms"],
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitFinish("alarm-clear");
+ await extension.unload();
+});
+
+add_task(async function test_alarm_get_and_clear_single_argument() {
+ async function backgroundScript() {
+ browser.alarms.create({ when: Date.now() + 2000000 });
+
+ let alarm = await browser.alarms.get();
+ browser.test.assertEq("", alarm.name, "expected alarm returned");
+
+ let wasCleared = await browser.alarms.clear();
+ browser.test.assertTrue(wasCleared, "alarm was cleared");
+
+ let alarms = await browser.alarms.getAll();
+ browser.test.assertEq(0, alarms.length, "alarm was removed");
+
+ browser.test.notifyPass("alarm-single-arg");
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ background: `(${backgroundScript})()`,
+ manifest: {
+ permissions: ["alarms"],
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitFinish("alarm-single-arg");
+ await extension.unload();
+});
+
+// This test case covers the behavior of browser.alarms.create when the
+// first optional argument (the alarm name) is passed explicitly as null
+// or undefined instead of being omitted.
+add_task(async function test_alarm_name_arg_null_or_undefined() {
+ async function backgroundScript(alarmName) {
+ browser.alarms.create(alarmName, { when: Date.now() + 2000000 });
+
+ let alarm = await browser.alarms.get();
+ browser.test.assertTrue(alarm, "got an alarm");
+ browser.test.assertEq("", alarm.name, "expected alarm returned");
+
+ let wasCleared = await browser.alarms.clear();
+ browser.test.assertTrue(wasCleared, "alarm was cleared");
+
+ let alarms = await browser.alarms.getAll();
+ browser.test.assertEq(0, alarms.length, "alarm was removed");
+
+ browser.test.notifyPass("alarm-test-done");
+ }
+
+ for (const alarmName of [null, undefined]) {
+ info(`Test alarm.create with alarm name ${alarmName}`);
+ let extension = ExtensionTestUtils.loadExtension({
+ background: `(${backgroundScript})(${alarmName})`,
+ manifest: {
+ permissions: ["alarms"],
+ },
+ });
+ await extension.startup();
+ await extension.awaitFinish("alarm-test-done");
+ await extension.unload();
+ }
+});
+
+add_task(async function test_get_get_all_clear_all_alarms() {
+ async function backgroundScript() {
+ const ALARM_NAME = "test_alarm";
+
+ let suffixes = [0, 1, 2];
+
+ for (let suffix of suffixes) {
+ browser.alarms.create(ALARM_NAME + suffix, {
+ when: Date.now() + (suffix + 1) * 10000,
+ });
+ }
+
+ let alarms = await browser.alarms.getAll();
+ browser.test.assertEq(
+ suffixes.length,
+ alarms.length,
+ "expected number of alarms were found"
+ );
+ alarms.forEach((alarm, index) => {
+ browser.test.assertEq(
+ ALARM_NAME + index,
+ alarm.name,
+ "alarm has the expected name"
+ );
+ });
+
+ for (let suffix of suffixes) {
+ let alarm = await browser.alarms.get(ALARM_NAME + suffix);
+ browser.test.assertEq(
+ ALARM_NAME + suffix,
+ alarm.name,
+ "alarm has the expected name"
+ );
+ browser.test.sendMessage(`get-${suffix}`);
+ }
+
+ let wasCleared = await browser.alarms.clear(ALARM_NAME + suffixes[0]);
+ browser.test.assertTrue(wasCleared, "alarm was cleared");
+
+ alarms = await browser.alarms.getAll();
+ browser.test.assertEq(2, alarms.length, "alarm was removed");
+
+ let alarm = await browser.alarms.get(ALARM_NAME + suffixes[0]);
+ browser.test.assertEq(undefined, alarm, "non-existent alarm is undefined");
+ browser.test.sendMessage(`get-invalid`);
+
+ wasCleared = await browser.alarms.clearAll();
+ browser.test.assertTrue(wasCleared, "alarms were cleared");
+
+ alarms = await browser.alarms.getAll();
+ browser.test.assertEq(0, alarms.length, "no alarms exist");
+ browser.test.sendMessage("clearAll");
+ browser.test.sendMessage("clear");
+ browser.test.sendMessage("getAll");
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ background: `(${backgroundScript})()`,
+ manifest: {
+ permissions: ["alarms"],
+ },
+ });
+
+ await Promise.all([
+ extension.startup(),
+ extension.awaitMessage("getAll"),
+ extension.awaitMessage("get-0"),
+ extension.awaitMessage("get-1"),
+ extension.awaitMessage("get-2"),
+ extension.awaitMessage("clear"),
+ extension.awaitMessage("get-invalid"),
+ extension.awaitMessage("clearAll"),
+ ]);
+ await extension.unload();
+});
+
+function getAlarmExtension(alarmCreateOptions, extOpts = {}) {
+ info(
+ `Test alarms.create fires with options: ${JSON.stringify(
+ alarmCreateOptions
+ )}`
+ );
+
+ function backgroundScript(createOptions) {
+ let ALARM_NAME = "test_ext_alarms";
+ let timer;
+
+ browser.alarms.onAlarm.addListener(alarm => {
+ browser.test.assertEq(
+ ALARM_NAME,
+ alarm.name,
+ "alarm has the expected name"
+ );
+ clearTimeout(timer);
+ browser.test.sendMessage("alarms-create-with-options");
+ });
+
+ browser.alarms.create(ALARM_NAME, createOptions);
+
+ timer = setTimeout(async () => {
+ browser.test.fail("alarm fired within expected time");
+ let wasCleared = await browser.alarms.clear(ALARM_NAME);
+ browser.test.assertTrue(wasCleared, "alarm was cleared");
+ browser.test.sendMessage("alarms-create-with-options");
+ }, 10000);
+ }
+
+ let { persistent, useAddonManager } = extOpts;
+ return ExtensionTestUtils.loadExtension({
+ useAddonManager,
+ // Pass the alarms.create options to the background page.
+ background: `(${backgroundScript})(${JSON.stringify(alarmCreateOptions)})`,
+ manifest: {
+ permissions: ["alarms"],
+ background: { persistent },
+ },
+ });
+}
+
+async function test_alarm_fires_with_options(alarmCreateOptions) {
+ let extension = getAlarmExtension(alarmCreateOptions);
+
+ await extension.startup();
+ await extension.awaitMessage("alarms-create-with-options");
+
+ // Defer unloading the extension so the asynchronous event listener
+ // reply finishes.
+ await new Promise(resolve => setTimeout(resolve, 0));
+ await extension.unload();
+}
+
+add_task(async function test_alarm_fires() {
+ Services.prefs.setBoolPref(
+ "privacy.resistFingerprinting.reduceTimerPrecision.jitter",
+ false
+ );
+
+ await test_alarm_fires_with_options({ delayInMinutes: 0.01 });
+ await test_alarm_fires_with_options({ when: Date.now() + 1000 });
+ await test_alarm_fires_with_options({ delayInMinutes: -10 });
+ await test_alarm_fires_with_options({ when: Date.now() - 1000 });
+
+ Services.prefs.clearUserPref(
+ "privacy.resistFingerprinting.reduceTimerPrecision.jitter"
+ );
+});
+
+function trackEvents(wrapper) {
+ let events = new Map();
+ for (let event of ["background-script-event", "start-background-script"]) {
+ events.set(event, false);
+ wrapper.extension.once(event, () => events.set(event, true));
+ }
+ return events;
+}
+
+add_task(
+ {
+ // TODO(Bug 1748665): remove the skip once background service worker is also
+ // woken up by persistent listeners.
+ skip_if: () => ExtensionTestUtils.isInBackgroundServiceWorkerTests(),
+ pref_set: [
+ ["privacy.resistFingerprinting.reduceTimerPrecision.jitter", false],
+ ["extensions.eventPages.enabled", true],
+ ],
+ },
+ async function test_alarm_persists() {
+ await AddonTestUtils.promiseStartupManager();
+
+ let extension = getAlarmExtension(
+ { periodInMinutes: 0.01 },
+ { useAddonManager: "permanent", persistent: false }
+ );
+ info(`wait startup`);
+ await extension.startup();
+ assertPersistentListeners(extension, "alarms", "onAlarm", {
+ primed: false,
+ });
+ info(`wait first alarm`);
+ await extension.awaitMessage("alarms-create-with-options");
+
+ await extension.terminateBackground({ disableResetIdleForTest: true });
+ ok(
+ !extension.extension.backgroundContext,
+ "Background Extension context should have been destroyed"
+ );
+
+ assertPersistentListeners(extension, "alarms", "onAlarm", {
+ primed: true,
+ });
+
+ // Test an early startup event
+ let events = trackEvents(extension);
+ ok(
+ !events.get("background-script-event"),
+ "Should not have received a background script event"
+ );
+ ok(
+ !events.get("start-background-script"),
+ "Background script should not be started"
+ );
+
+ info("waiting for alarm to wake background");
+ await extension.awaitMessage("alarms-create-with-options");
+ ok(
+ events.get("background-script-event"),
+ "Should have received a background script event"
+ );
+ ok(
+ events.get("start-background-script"),
+ "Background script should be started"
+ );
+
+ await extension.unload();
+ await AddonTestUtils.promiseShutdownManager();
+ }
+);