summaryrefslogtreecommitdiffstats
path: root/widget/windows/tests/unit/test_windows_alert_service.js
diff options
context:
space:
mode:
Diffstat (limited to 'widget/windows/tests/unit/test_windows_alert_service.js')
-rw-r--r--widget/windows/tests/unit/test_windows_alert_service.js314
1 files changed, 314 insertions, 0 deletions
diff --git a/widget/windows/tests/unit/test_windows_alert_service.js b/widget/windows/tests/unit/test_windows_alert_service.js
new file mode 100644
index 0000000000..0924dcbb6e
--- /dev/null
+++ b/widget/windows/tests/unit/test_windows_alert_service.js
@@ -0,0 +1,314 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * Test that Windows alert notifications generate expected XML.
+ */
+
+var { AppConstants } = ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+);
+
+let gProfD = do_get_profile();
+
+// Setup that allows to use the profile service in xpcshell tests,
+// lifted from `toolkit/profile/xpcshell/head.js`.
+function setupProfileService() {
+ let gDataHome = gProfD.clone();
+ gDataHome.append("data");
+ gDataHome.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
+ let gDataHomeLocal = gProfD.clone();
+ gDataHomeLocal.append("local");
+ gDataHomeLocal.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
+
+ let xreDirProvider = Cc["@mozilla.org/xre/directory-provider;1"].getService(
+ Ci.nsIXREDirProvider
+ );
+ xreDirProvider.setUserDataDirectory(gDataHome, false);
+ xreDirProvider.setUserDataDirectory(gDataHomeLocal, true);
+}
+
+add_setup(setupProfileService);
+
+function makeAlert(options) {
+ var alert = Cc["@mozilla.org/alert-notification;1"].createInstance(
+ Ci.nsIAlertNotification
+ );
+ alert.init(
+ options.name,
+ options.imageURL,
+ options.title,
+ options.text,
+ options.textClickable,
+ options.cookie,
+ options.dir,
+ options.lang,
+ options.data,
+ options.principal,
+ options.inPrivateBrowsing,
+ options.requireInteraction,
+ options.silent,
+ options.vibrate || []
+ );
+ if (options.actions) {
+ alert.actions = options.actions;
+ }
+ return alert;
+}
+
+function testAlert(when, { serverEnabled, profD, isBackgroundTaskMode } = {}) {
+ let argumentString = (argument, launchUrl, privilegedName) => {
+ // 
 is "\n".
+ let s = ``;
+ if (serverEnabled) {
+ s += `program
${AppConstants.MOZ_APP_NAME}`;
+ } else {
+ s += `invalid key
invalid value`;
+ }
+ if (serverEnabled && profD) {
+ s += `
profile
${profD.path}`;
+ }
+ if (serverEnabled && launchUrl) {
+ s += `
launchUrl
${launchUrl}`;
+ }
+ if (serverEnabled && privilegedName) {
+ s += `
privilegedName
${privilegedName}`;
+ }
+ if (serverEnabled) {
+ s += "
windowsTag
";
+ }
+ if (argument) {
+ s += `
action
${argument}`;
+ }
+ return s;
+ };
+
+ let settingsAction = hostport => {
+ return isBackgroundTaskMode
+ ? ""
+ : `<action content="Notification settings" arguments="${argumentString(
+ "settings",
+ hostport
+ )}" placement="contextmenu"/>`;
+ };
+
+ let alertsService = Cc["@mozilla.org/system-alerts-service;1"]
+ .getService(Ci.nsIAlertsService)
+ .QueryInterface(Ci.nsIWindowsAlertsService);
+
+ let name = "name";
+ let title = "title";
+ let text = "text";
+ let imageURL = "file:///image.png";
+ let actions = [
+ { action: "action1", title: "title1", iconURL: "file:///iconURL1.png" },
+ { action: "action2", title: "title2", iconURL: "file:///iconURL2.png" },
+ ];
+
+ let alert = makeAlert({ name, title, text });
+ let expected = `<toast launch="${argumentString()}"><visual><binding template="ToastText03"><text id="1">title</text><text id="2">text</text></binding></visual><actions>${settingsAction()}</actions></toast>`;
+ Assert.equal(
+ expected.replace("<actions></actions>", "<actions/>"),
+ alertsService.getXmlStringForWindowsAlert(alert),
+ when
+ );
+
+ alert = makeAlert({ name, title, text, imageURL });
+ expected = `<toast launch="${argumentString()}"><visual><binding template="ToastImageAndText03"><image id="1" src="file:///image.png"/><text id="1">title</text><text id="2">text</text></binding></visual><actions>${settingsAction()}</actions></toast>`;
+ Assert.equal(
+ expected.replace("<actions></actions>", "<actions/>"),
+ alertsService.getXmlStringForWindowsAlert(alert),
+ when
+ );
+
+ alert = makeAlert({ name, title, text, imageURL, requireInteraction: true });
+ expected = `<toast scenario="reminder" launch="${argumentString()}"><visual><binding template="ToastImageAndText03"><image id="1" src="file:///image.png"/><text id="1">title</text><text id="2">text</text></binding></visual><actions>${settingsAction()}</actions></toast>`;
+ Assert.equal(
+ expected.replace("<actions></actions>", "<actions/>"),
+ alertsService.getXmlStringForWindowsAlert(alert),
+ when
+ );
+
+ alert = makeAlert({ name, title, text, imageURL, actions });
+ expected = `<toast launch="${argumentString()}"><visual><binding template="ToastImageAndText03"><image id="1" src="file:///image.png"/><text id="1">title</text><text id="2">text</text></binding></visual><actions>${settingsAction()}<action content="title1" arguments="${argumentString(
+ "action1"
+ )}"/><action content="title2" arguments="${argumentString(
+ "action2"
+ )}"/></actions></toast>`;
+ Assert.equal(
+ expected.replace("<actions></actions>", "<actions/>"),
+ alertsService.getXmlStringForWindowsAlert(alert),
+ when
+ );
+
+ // Chrome privileged alerts can use `windowsSystemActivationType`.
+ let systemActions = [
+ {
+ action: "dismiss",
+ title: "dismissTitle",
+ windowsSystemActivationType: true,
+ },
+ {
+ action: "snooze",
+ title: "snoozeTitle",
+ windowsSystemActivationType: true,
+ },
+ ];
+ let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
+ alert = makeAlert({
+ name,
+ title,
+ text,
+ imageURL,
+ principal: systemPrincipal,
+ actions: systemActions,
+ });
+ let settingsActionWithPrivilegedName = isBackgroundTaskMode
+ ? ""
+ : `<action content="Notification settings" arguments="${argumentString(
+ "settings",
+ null,
+ name
+ )}" placement="contextmenu"/>`;
+ expected = `<toast launch="${argumentString(
+ null,
+ null,
+ name
+ )}"><visual><binding template="ToastGeneric"><image id="1" src="file:///image.png"/><text id="1">title</text><text id="2">text</text></binding></visual><actions>${settingsActionWithPrivilegedName}<action content="dismissTitle" arguments="dismiss" activationType="system"/><action content="snoozeTitle" arguments="snooze" activationType="system"/></actions></toast>`;
+ Assert.equal(
+ expected,
+ alertsService.getXmlStringForWindowsAlert(alert),
+ when
+ );
+
+ // But content unprivileged alerts can't use `windowsSystemActivationType`.
+ let launchUrl = "https://example.com/foo/bar.html";
+ const principaluri = Services.io.newURI(launchUrl);
+ const principal = Services.scriptSecurityManager.createContentPrincipal(
+ principaluri,
+ {}
+ );
+
+ alert = makeAlert({
+ name,
+ title,
+ text,
+ imageURL,
+ actions: systemActions,
+ principal,
+ });
+ expected = `<toast launch="${argumentString(
+ null,
+ principaluri.hostPort
+ )}"><visual><binding template="ToastImageAndText04"><image id="1" src="file:///image.png"/><text id="1">title</text><text id="2">text</text><text id="3" placement="attribution">via example.com</text></binding></visual><actions><action content="Disable notifications from example.com" arguments="${argumentString(
+ "snooze",
+ principaluri.hostPort
+ )}" placement="contextmenu"/>${settingsAction(
+ principaluri.hostPort
+ )}<action content="dismissTitle" arguments="${argumentString(
+ "dismiss",
+ principaluri.hostPort
+ )}"/><action content="snoozeTitle" arguments="${argumentString(
+ "snooze",
+ principaluri.hostPort
+ )}"/></actions></toast>`;
+ Assert.equal(
+ expected,
+ alertsService.getXmlStringForWindowsAlert(alert),
+ when
+ );
+
+ // Chrome privileged alerts can set a launch URL.
+ alert = makeAlert({
+ name,
+ title,
+ text,
+ imageURL,
+ principal: systemPrincipal,
+ });
+ alert.launchURL = launchUrl;
+ let settingsActionWithLaunchUrl = isBackgroundTaskMode
+ ? ""
+ : `<action content="Notification settings" arguments="${argumentString(
+ "settings",
+ launchUrl,
+ name
+ )}" placement="contextmenu"/>`;
+ expected = `<toast launch="${argumentString(
+ null,
+ launchUrl,
+ name
+ )}"><visual><binding template="ToastGeneric"><image id="1" src="file:///image.png"/><text id="1">title</text><text id="2">text</text></binding></visual><actions>${settingsActionWithLaunchUrl}</actions></toast>`;
+ Assert.equal(
+ expected.replace("<actions></actions>", "<actions/>"),
+ alertsService.getXmlStringForWindowsAlert(alert),
+ when
+ );
+}
+
+add_task(async () => {
+ Services.prefs.deleteBranch(
+ "alerts.useSystemBackend.windows.notificationserver.enabled"
+ );
+ testAlert("when notification server pref is unset", {
+ profD: gProfD,
+ });
+
+ Services.prefs.setBoolPref(
+ "alerts.useSystemBackend.windows.notificationserver.enabled",
+ false
+ );
+ testAlert("when notification server pref is false", { profD: gProfD });
+
+ Services.prefs.setBoolPref(
+ "alerts.useSystemBackend.windows.notificationserver.enabled",
+ true
+ );
+ testAlert("when notification server pref is true", {
+ serverEnabled: true,
+ profD: gProfD,
+ });
+});
+
+let condition = {
+ skip_if: () => !AppConstants.MOZ_BACKGROUNDTASKS,
+};
+
+add_task(condition, async () => {
+ const bts = Cc["@mozilla.org/backgroundtasks;1"]?.getService(
+ Ci.nsIBackgroundTasks
+ );
+
+ // Pretend that this is a background task.
+ bts.overrideBackgroundTaskNameForTesting("taskname");
+
+ Services.prefs.setBoolPref(
+ "alerts.useSystemBackend.windows.notificationserver.enabled",
+ true
+ );
+ testAlert(
+ "when notification server pref is true in background task, no default profile",
+ { serverEnabled: true, isBackgroundTaskMode: true }
+ );
+
+ let profileService = Cc["@mozilla.org/toolkit/profile-service;1"].getService(
+ Ci.nsIToolkitProfileService
+ );
+
+ let profilePath = do_get_profile();
+ profilePath.append(`test_windows_alert_service`);
+ let profile = profileService.createUniqueProfile(
+ profilePath,
+ "test_windows_alert_service"
+ );
+
+ profileService.defaultProfile = profile;
+
+ testAlert(
+ "when notification server pref is true in background task, default profile",
+ { serverEnabled: true, isBackgroundTaskMode: true, profD: profilePath }
+ );
+
+ // No longer a background task,
+ bts.overrideBackgroundTaskNameForTesting("");
+});