/* 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 ? "" : ``; }; 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 = `titletext${settingsAction()}`; Assert.equal( expected.replace("", ""), alertsService.getXmlStringForWindowsAlert(alert), when ); alert = makeAlert({ name, title, text, imageURL }); expected = `titletext${settingsAction()}`; Assert.equal( expected.replace("", ""), alertsService.getXmlStringForWindowsAlert(alert), when ); alert = makeAlert({ name, title, text, imageURL, requireInteraction: true }); expected = `titletext${settingsAction()}`; Assert.equal( expected.replace("", ""), alertsService.getXmlStringForWindowsAlert(alert), when ); alert = makeAlert({ name, title, text, imageURL, actions }); expected = `titletext${settingsAction()}`; Assert.equal( expected.replace("", ""), 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 ? "" : ``; expected = `titletext${settingsActionWithPrivilegedName}`; 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 = `titletextvia example.com${settingsAction( principaluri.hostPort )}`; 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 ? "" : ``; expected = `titletext${settingsActionWithLaunchUrl}`; Assert.equal( expected.replace("", ""), 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(""); });