diff options
Diffstat (limited to '')
15 files changed, 1918 insertions, 0 deletions
diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/head.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/head.js new file mode 100644 index 0000000000..2fcf00a21b --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/head.js @@ -0,0 +1,140 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const lazy = {}; + +const { Preferences } = ChromeUtils.importESModule( + "resource://gre/modules/Preferences.sys.mjs" +); +const { updateAppInfo, getAppInfo } = ChromeUtils.importESModule( + "resource://testing-common/AppInfo.sys.mjs" +); +const { FileTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/FileTestUtils.sys.mjs" +); +const { PermissionTestUtils } = ChromeUtils.import( + "resource://testing-common/PermissionTestUtils.jsm" +); +ChromeUtils.defineESModuleGetters(lazy, { + SearchTestUtils: "resource://testing-common/SearchTestUtils.sys.mjs", +}); +const { EnterprisePolicyTesting } = ChromeUtils.importESModule( + "resource://testing-common/EnterprisePolicyTesting.sys.mjs" +); + +updateAppInfo({ + name: "XPCShell", + ID: "xpcshell@tests.mozilla.org", + version: "48", + platformVersion: "48", +}); + +// This initializes the policy engine for xpcshell tests +let policies = Cc["@mozilla.org/enterprisepolicies;1"].getService( + Ci.nsIObserver +); +policies.observe(null, "policies-startup", null); + +async function setupPolicyEngineWithJson(json, customSchema) { + if (typeof json != "object") { + let filePath = do_get_file(json ? json : "non-existing-file.json").path; + return EnterprisePolicyTesting.setupPolicyEngineWithJson( + filePath, + customSchema + ); + } + return EnterprisePolicyTesting.setupPolicyEngineWithJson(json, customSchema); +} + +/** + * Loads a new enterprise policy, and re-initialise the search service + * with the new policy. Also waits for the search service to write the settings + * file to disk. + * + * @param {object} policy + * The enterprise policy to use. + * @param {object} customSchema + * A custom schema to use to validate the enterprise policy. + */ +async function setupPolicyEngineWithJsonWithSearch(json, customSchema) { + Services.search.wrappedJSObject.reset(); + if (typeof json != "object") { + let filePath = do_get_file(json ? json : "non-existing-file.json").path; + await EnterprisePolicyTesting.setupPolicyEngineWithJson( + filePath, + customSchema + ); + } else { + await EnterprisePolicyTesting.setupPolicyEngineWithJson(json, customSchema); + } + let settingsWritten = lazy.SearchTestUtils.promiseSearchNotification( + "write-settings-to-disk-complete" + ); + await Services.search.init(); + return settingsWritten; +} + +function checkLockedPref(prefName, prefValue) { + equal( + Preferences.locked(prefName), + true, + `Pref ${prefName} is correctly locked` + ); + equal( + Preferences.get(prefName), + prefValue, + `Pref ${prefName} has the correct value` + ); +} + +function checkUnlockedPref(prefName, prefValue) { + equal( + Preferences.locked(prefName), + false, + `Pref ${prefName} is correctly unlocked` + ); + equal( + Preferences.get(prefName), + prefValue, + `Pref ${prefName} has the correct value` + ); +} + +function checkUserPref(prefName, prefValue) { + equal( + Preferences.get(prefName), + prefValue, + `Pref ${prefName} has the correct value` + ); +} + +function checkClearPref(prefName, prefValue) { + equal( + Services.prefs.prefHasUserValue(prefName), + false, + `Pref ${prefName} has no user value` + ); +} + +function checkDefaultPref(prefName, prefValue) { + let defaultPrefBranch = Services.prefs.getDefaultBranch(""); + let prefType = defaultPrefBranch.getPrefType(prefName); + notEqual( + prefType, + Services.prefs.PREF_INVALID, + `Pref ${prefName} is set on the default branch` + ); +} + +function checkUnsetPref(prefName) { + let defaultPrefBranch = Services.prefs.getDefaultBranch(""); + let prefType = defaultPrefBranch.getPrefType(prefName); + equal( + prefType, + Services.prefs.PREF_INVALID, + `Pref ${prefName} is not set on the default branch` + ); +} diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_3rdparty.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_3rdparty.js new file mode 100644 index 0000000000..b9dabb758d --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_3rdparty.js @@ -0,0 +1,22 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +add_setup(async function () { + await setupPolicyEngineWithJson({ + policies: { + "3rdparty": { + Extensions: { + "3rdparty-policy@mozilla.com": { + string: "value", + }, + }, + }, + }, + }); + + let extensionPolicy = Services.policies.getExtensionPolicy( + "3rdparty-policy@mozilla.com" + ); + deepEqual(extensionPolicy, { string: "value" }); +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_appupdatepin.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_appupdatepin.js new file mode 100644 index 0000000000..01e3810a05 --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_appupdatepin.js @@ -0,0 +1,80 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { TelemetryTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/TelemetryTestUtils.sys.mjs" +); + +/** + * Note that these tests only ensure that the pin is properly added to the + * update URL and to the telemetry. They do not test that the update applied + * will be of the correct version. This is because we are not attempting to have + * Thunderbird check if the update provided is valid given the pin, we are leaving + * it to the update server (Balrog) to find and serve the correct version. + */ + +async function test_update_pin(pinString, pinIsValid = true) { + await setupPolicyEngineWithJson({ + policies: { + AppUpdateURL: "https://www.example.com/update.xml", + AppUpdatePin: pinString, + }, + }); + Services.telemetry.clearScalars(); + + equal( + Services.policies.status, + Ci.nsIEnterprisePolicies.ACTIVE, + "Engine is active" + ); + + let policies = Services.policies.getActivePolicies(); + equal( + "AppUpdatePin" in policies, + pinIsValid, + "AppUpdatePin policy should only be active if the pin was valid." + ); + + let checker = Cc["@mozilla.org/updates/update-checker;1"].getService( + Ci.nsIUpdateChecker + ); + let updateURL = await checker.getUpdateURL(checker.BACKGROUND_CHECK); + + let expected = pinIsValid + ? `https://www.example.com/update.xml?pin=${pinString}` + : "https://www.example.com/update.xml"; + + equal(updateURL, expected, "App Update URL should match expected URL."); + + let scalars = TelemetryTestUtils.getProcessScalars("parent", false, true); + if (pinIsValid) { + TelemetryTestUtils.assertScalar( + scalars, + "update.version_pin", + pinString, + "Update pin telemetry should be set" + ); + } else { + TelemetryTestUtils.assertScalarUnset(scalars, "update.version_pin"); + } +} + +add_task(async function test_app_update_pin() { + await test_update_pin("102."); + await test_update_pin("102.0."); + await test_update_pin("102.1."); + await test_update_pin("102.1.1", false); + await test_update_pin("102.1.1.", false); + await test_update_pin("102", false); + await test_update_pin("foobar", false); + await test_update_pin("-102.1.", false); + await test_update_pin("102.-1.", false); + await test_update_pin("102a.1.", false); + await test_update_pin("102.1a.", false); + await test_update_pin("0102.1.", false); + // Should not accept version numbers that will never be in Balrog's pinning + // table (i.e. versions before 102.0). + await test_update_pin("101.1.", false); +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_appupdateurl.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_appupdateurl.js new file mode 100644 index 0000000000..48d04e1a8d --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_appupdateurl.js @@ -0,0 +1,25 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_app_update_URL() { + await setupPolicyEngineWithJson({ + policies: { + AppUpdateURL: "https://www.example.com/", + }, + }); + + equal( + Services.policies.status, + Ci.nsIEnterprisePolicies.ACTIVE, + "Engine is active" + ); + + let checker = Cc["@mozilla.org/updates/update-checker;1"].getService( + Ci.nsIUpdateChecker + ); + let expected = await checker.getUpdateURL(checker.BACKGROUND_CHECK); + + equal("https://www.example.com/", expected, "Correct app update URL"); +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_bug1658259.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_bug1658259.js new file mode 100644 index 0000000000..1449e664c2 --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_bug1658259.js @@ -0,0 +1,44 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_bug1658259_1() { + await setupPolicyEngineWithJson({ + policies: { + OfferToSaveLogins: false, + OfferToSaveLoginsDefault: true, + }, + }); + checkLockedPref("signon.rememberSignons", false); +}); + +add_task(async function test_bug1658259_2() { + await setupPolicyEngineWithJson({ + policies: { + OfferToSaveLogins: true, + OfferToSaveLoginsDefault: false, + }, + }); + checkLockedPref("signon.rememberSignons", true); +}); + +add_task(async function test_bug1658259_3() { + await setupPolicyEngineWithJson({ + policies: { + OfferToSaveLoginsDefault: true, + OfferToSaveLogins: false, + }, + }); + checkLockedPref("signon.rememberSignons", false); +}); + +add_task(async function test_bug1658259_4() { + await setupPolicyEngineWithJson({ + policies: { + OfferToSaveLoginsDefault: false, + OfferToSaveLogins: true, + }, + }); + checkLockedPref("signon.rememberSignons", true); +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_clear_blocked_cookies.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_clear_blocked_cookies.js new file mode 100644 index 0000000000..17149f787f --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_clear_blocked_cookies.js @@ -0,0 +1,118 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +const HOSTNAME_DOMAIN = "browser_policy_clear_blocked_cookies.com"; +const ORIGIN_DOMAIN = "browser_policy_clear_blocked_cookies.org"; + +add_setup(async function () { + const expiry = Date.now() + 24 * 60 * 60; + Services.cookies.add( + HOSTNAME_DOMAIN, + "/", + "secure", + "true", + true, + false, + false, + expiry, + {}, + Ci.nsICookie.SAMESITE_NONE, + Ci.nsICookie.SCHEME_HTTPS + ); + Services.cookies.add( + HOSTNAME_DOMAIN, + "/", + "insecure", + "true", + false, + false, + false, + expiry, + {}, + Ci.nsICookie.SAMESITE_NONE, + Ci.nsICookie.SCHEME_HTTP + ); + Services.cookies.add( + ORIGIN_DOMAIN, + "/", + "secure", + "true", + true, + false, + false, + expiry, + {}, + Ci.nsICookie.SAMESITE_NONE, + Ci.nsICookie.SCHEME_HTTPS + ); + Services.cookies.add( + ORIGIN_DOMAIN, + "/", + "insecure", + "true", + false, + false, + false, + expiry, + {}, + Ci.nsICookie.SAMESITE_NONE, + Ci.nsICookie.SCHEME_HTTP + ); + Services.cookies.add( + "example.net", + "/", + "secure", + "true", + true, + false, + false, + expiry, + {}, + Ci.nsICookie.SAMESITE_NONE, + Ci.nsICookie.SCHEME_HTTPS + ); + await setupPolicyEngineWithJson({ + policies: { + Cookies: { + Block: [`http://${HOSTNAME_DOMAIN}`, `https://${ORIGIN_DOMAIN}:8080`], + }, + }, + }); +}); + +function retrieve_all_cookies(host) { + const values = []; + for (let cookie of Services.cookies.getCookiesFromHost(host, {})) { + values.push({ + host: cookie.host, + name: cookie.name, + path: cookie.path, + }); + } + return values; +} + +add_task(async function test_cookies_for_blocked_sites_cleared() { + const cookies = { + hostname: retrieve_all_cookies(HOSTNAME_DOMAIN), + origin: retrieve_all_cookies(ORIGIN_DOMAIN), + keep: retrieve_all_cookies("example.net"), + }; + const expected = { + hostname: [], + origin: [], + keep: [{ host: "example.net", name: "secure", path: "/" }], + }; + equal( + JSON.stringify(cookies), + JSON.stringify(expected), + "All stored cookies for blocked origins should be cleared" + ); +}); + +add_task(function teardown() { + for (let host of [HOSTNAME_DOMAIN, ORIGIN_DOMAIN, "example.net"]) { + Services.cookies.removeCookiesWithOriginAttributes("{}", host); + } +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_macosparser_unflatten.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_macosparser_unflatten.js new file mode 100644 index 0000000000..096852612c --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_macosparser_unflatten.js @@ -0,0 +1,110 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +let { macOSPoliciesParser } = ChromeUtils.importESModule( + "resource://gre/modules/policies/macOSPoliciesParser.sys.mjs" +); + +add_task(async function test_object_unflatten() { + // Note: these policies are just examples and they won't actually + // run through the policy engine on this test. We're just testing + // that the unflattening algorithm produces the correct output. + let input = { + DisplayBookmarksToolbar: true, + + Homepage__URL: "https://www.mozilla.org", + Homepage__Locked: "true", + Homepage__Additional__0: "https://extra-homepage-1.example.com", + Homepage__Additional__1: "https://extra-homepage-2.example.com", + + WebsiteFilter__Block__0: "*://*.example.org/*", + WebsiteFilter__Block__1: "*://*.example.net/*", + WebsiteFilter__Exceptions__0: "*://*.example.org/*exception*", + + Permissions__Camera__Allow__0: "https://www.example.com", + + Permissions__Notifications__Allow__0: "https://www.example.com", + Permissions__Notifications__Allow__1: "https://www.example.org", + Permissions__Notifications__Block__0: "https://www.example.net", + + Permissions__Notifications__BlockNewRequests: true, + Permissions__Notifications__Locked: true, + + Bookmarks__0__Title: "Bookmark 1", + Bookmarks__0__URL: "https://bookmark1.example.com", + + Bookmarks__1__Title: "Bookmark 2", + Bookmarks__1__URL: "https://bookmark2.example.com", + Bookmarks__1__Folder: "Folder", + }; + + let expected = { + DisplayBookmarksToolbar: true, + + Homepage: { + URL: "https://www.mozilla.org", + Locked: "true", + Additional: [ + "https://extra-homepage-1.example.com", + "https://extra-homepage-2.example.com", + ], + }, + + WebsiteFilter: { + Block: ["*://*.example.org/*", "*://*.example.net/*"], + Exceptions: ["*://*.example.org/*exception*"], + }, + + Permissions: { + Camera: { + Allow: ["https://www.example.com"], + }, + + Notifications: { + Allow: ["https://www.example.com", "https://www.example.org"], + Block: ["https://www.example.net"], + BlockNewRequests: true, + Locked: true, + }, + }, + + Bookmarks: [ + { + Title: "Bookmark 1", + URL: "https://bookmark1.example.com", + }, + { + Title: "Bookmark 2", + URL: "https://bookmark2.example.com", + Folder: "Folder", + }, + ], + }; + + let unflattened = macOSPoliciesParser.unflatten(input); + + deepEqual(unflattened, expected, "Input was unflattened correctly."); +}); + +add_task(async function test_array_unflatten() { + let input = { + Foo__1: 1, + Foo__5: 5, + Foo__10: 10, + Foo__30: 30, + Foo__51: 51, // This one should not be included as the limit is 50 + }; + + let unflattened = macOSPoliciesParser.unflatten(input); + equal(unflattened.Foo.length, 31, "Array size is correct"); + + let expected = { + Foo: [, 1, , , , 5], // eslint-disable-line no-sparse-arrays + }; + expected.Foo[10] = 10; + expected.Foo[30] = 30; + + deepEqual(unflattened, expected, "Array was unflattened correctly."); +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_policy_search_engine.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_policy_search_engine.js new file mode 100644 index 0000000000..be16829867 --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_policy_search_engine.js @@ -0,0 +1,490 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +const { SearchTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/SearchTestUtils.sys.mjs" +); +const { TestUtils } = ChromeUtils.importESModule( + "resource://testing-common/TestUtils.sys.mjs" +); +var { AddonTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/AddonTestUtils.sys.mjs" +); + +Services.prefs.setBoolPref("browser.search.log", true); +SearchTestUtils.init(this); + +AddonTestUtils.init(this, false); +AddonTestUtils.createAppInfo( + "xpcshell@tests.mozilla.org", + "XPCShell", + "48", + "48" +); + +add_setup(async () => { + await AddonTestUtils.promiseStartupManager(); + await Services.search.init(); + console.log("done init"); +}); + +add_task(async function test_install_and_set_default() { + // Make sure we are starting in an expected state to avoid false positive + // test results. + Assert.notEqual( + (await Services.search.getDefault()).name, + "MozSearch", + "Default search engine should not be MozSearch when test starts" + ); + Assert.equal( + Services.search.getEngineByName("Foo"), + null, + 'Engine "Foo" should not be present when test starts' + ); + + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Add: [ + { + Name: "MozSearch", + URLTemplate: "http://example.com/?q={searchTerms}", + }, + ], + Default: "MozSearch", + }, + }, + }); + // Get in line, because the Search policy callbacks are async. + await TestUtils.waitForTick(); + + // If this passes, it means that the new search engine was properly installed + // *and* was properly set as the default. + Assert.equal( + (await Services.search.getDefault()).name, + "MozSearch", + "Specified search engine should be the default" + ); + + // Clean up + await setupPolicyEngineWithJsonWithSearch({}); + EnterprisePolicyTesting.resetRunOnceState(); +}); + +add_task(async function test_install_and_set_default_private() { + // Make sure we are starting in an expected state to avoid false positive + // test results. + Assert.notEqual( + (await Services.search.getDefaultPrivate()).name, + "MozSearch", + "Default search engine should not be MozSearch when test starts" + ); + Assert.equal( + Services.search.getEngineByName("Foo"), + null, + 'Engine "Foo" should not be present when test starts' + ); + + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Add: [ + { + Name: "MozSearch", + URLTemplate: "http://example.com/?q={searchTerms}", + }, + ], + DefaultPrivate: "MozSearch", + }, + }, + }); + // Get in line, because the Search policy callbacks are async. + await TestUtils.waitForTick(); + + // If this passes, it means that the new search engine was properly installed + // *and* was properly set as the default. + Assert.equal( + (await Services.search.getDefaultPrivate()).name, + "MozSearch", + "Specified search engine should be the default private engine" + ); + + // Clean up + await setupPolicyEngineWithJsonWithSearch({}); + EnterprisePolicyTesting.resetRunOnceState(); +}); + +// Same as the last test, but with "PreventInstalls" set to true to make sure +// it does not prevent search engines from being installed properly +add_task(async function test_install_and_set_default_prevent_installs() { + Assert.notEqual( + (await Services.search.getDefault()).name, + "MozSearch", + "Default search engine should not be MozSearch when test starts" + ); + Assert.equal( + Services.search.getEngineByName("Foo"), + null, + 'Engine "Foo" should not be present when test starts' + ); + + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Add: [ + { + Name: "MozSearch", + URLTemplate: "http://example.com/?q={searchTerms}", + }, + ], + Default: "MozSearch", + PreventInstalls: true, + }, + }, + }); + // Get in line, because the Search policy callbacks are async. + await TestUtils.waitForTick(); + + Assert.equal( + (await Services.search.getDefault()).name, + "MozSearch", + "Specified search engine should be the default" + ); + + // Clean up + await setupPolicyEngineWithJsonWithSearch({}); + EnterprisePolicyTesting.resetRunOnceState(); +}); + +add_task(async function test_install_and_remove() { + let iconURL = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="; + + Assert.equal( + Services.search.getEngineByName("Foo"), + null, + 'Engine "Foo" should not be present when test starts' + ); + + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Add: [ + { + Name: "Foo", + URLTemplate: "http://example.com/?q={searchTerms}", + IconURL: iconURL, + }, + ], + }, + }, + }); + // Get in line, because the Search policy callbacks are async. + await TestUtils.waitForTick(); + + // If this passes, it means that the new search engine was properly installed + + let engine = Services.search.getEngineByName("Foo"); + Assert.notEqual(engine, null, "Specified search engine should be installed"); + + Assert.equal( + engine.wrappedJSObject.iconURI.spec, + iconURL, + "Icon should be present" + ); + Assert.equal( + engine.wrappedJSObject.queryCharset, + "UTF-8", + "Should default to utf-8" + ); + + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Remove: ["Foo"], + }, + }, + }); + // Get in line, because the Search policy callbacks are async. + await TestUtils.waitForTick(); + + // If this passes, it means that the specified engine was properly removed + Assert.equal( + Services.search.getEngineByName("Foo"), + null, + "Specified search engine should not be installed" + ); + + await setupPolicyEngineWithJsonWithSearch({}); + EnterprisePolicyTesting.resetRunOnceState(); +}); + +add_task(async function test_install_post_method_engine() { + Assert.equal( + Services.search.getEngineByName("Post"), + null, + 'Engine "Post" should not be present when test starts' + ); + + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Add: [ + { + Name: "Post", + Method: "POST", + PostData: "q={searchTerms}&anotherParam=yes", + URLTemplate: "http://example.com/", + }, + ], + }, + }, + }); + // Get in line, because the Search policy callbacks are async. + await TestUtils.waitForTick(); + + let engine = Services.search.getEngineByName("Post"); + Assert.notEqual(engine, null, "Specified search engine should be installed"); + + Assert.equal( + engine.wrappedJSObject._urls[0].method, + "POST", + "Method should be POST" + ); + + let submission = engine.getSubmission("term", "text/html"); + Assert.notEqual(submission.postData, null, "Post data should not be null"); + + let scriptableInputStream = Cc[ + "@mozilla.org/scriptableinputstream;1" + ].createInstance(Ci.nsIScriptableInputStream); + scriptableInputStream.init(submission.postData); + Assert.equal( + scriptableInputStream.read(scriptableInputStream.available()), + "q=term&anotherParam=yes", + "Post data should be present" + ); + + await setupPolicyEngineWithJsonWithSearch({}); + EnterprisePolicyTesting.resetRunOnceState(); +}); + +add_task(async function test_install_with_encoding() { + // Make sure we are starting in an expected state to avoid false positive + // test results. + Assert.equal( + Services.search.getEngineByName("Encoding"), + null, + 'Engine "Encoding" should not be present when test starts' + ); + + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Add: [ + { + Name: "Encoding", + Encoding: "windows-1252", + URLTemplate: "http://example.com/?q={searchTerms}", + }, + ], + }, + }, + }); + // Get in line, because the Search policy callbacks are async. + await TestUtils.waitForTick(); + + let engine = Services.search.getEngineByName("Encoding"); + Assert.equal( + engine.wrappedJSObject.queryCharset, + "windows-1252", + "Should have correct encoding" + ); + + // Clean up + await setupPolicyEngineWithJsonWithSearch({}); + EnterprisePolicyTesting.resetRunOnceState(); +}); + +add_task(async function test_install_and_update() { + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Add: [ + { + Name: "ToUpdate", + URLTemplate: "http://initial.example.com/?q={searchTerms}", + }, + ], + }, + }, + }); + // Get in line, because the Search policy callbacks are async. + await TestUtils.waitForTick(); + + let engine = Services.search.getEngineByName("ToUpdate"); + Assert.notEqual(engine, null, "Specified search engine should be installed"); + + Assert.equal( + engine.getSubmission("test").uri.spec, + "http://initial.example.com/?q=test", + "Initial submission URL should be correct." + ); + + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Add: [ + { + Name: "ToUpdate", + URLTemplate: "http://update.example.com/?q={searchTerms}", + }, + ], + }, + }, + }); + // Get in line, because the Search policy callbacks are async. + await TestUtils.waitForTick(); + + engine = Services.search.getEngineByName("ToUpdate"); + Assert.notEqual(engine, null, "Specified search engine should be installed"); + + Assert.equal( + engine.getSubmission("test").uri.spec, + "http://update.example.com/?q=test", + "Updated Submission URL should be correct." + ); + + // Clean up + await setupPolicyEngineWithJsonWithSearch({}); + EnterprisePolicyTesting.resetRunOnceState(); +}); + +add_task(async function test_install_with_suggest() { + // Make sure we are starting in an expected state to avoid false positive + // test results. + Assert.equal( + Services.search.getEngineByName("Suggest"), + null, + 'Engine "Suggest" should not be present when test starts' + ); + + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Add: [ + { + Name: "Suggest", + URLTemplate: "http://example.com/?q={searchTerms}", + SuggestURLTemplate: "http://suggest.example.com/?q={searchTerms}", + }, + ], + }, + }, + }); + // Get in line, because the Search policy callbacks are async. + await TestUtils.waitForTick(); + + let engine = Services.search.getEngineByName("Suggest"); + + Assert.equal( + engine.getSubmission("test", "application/x-suggestions+json").uri.spec, + "http://suggest.example.com/?q=test", + "Updated Submission URL should be correct." + ); + + // Clean up + await setupPolicyEngineWithJsonWithSearch({}); + EnterprisePolicyTesting.resetRunOnceState(); +}); + +add_task(async function test_install_and_restart_keeps_settings() { + // Make sure we are starting in an expected state to avoid false positive + // test results. + Assert.equal( + Services.search.getEngineByName("Settings"), + null, + 'Engine "Settings" should not be present when test starts' + ); + + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Add: [ + { + Name: "Settings", + URLTemplate: "http://example.com/?q={searchTerms}", + }, + ], + }, + }, + }); + // Get in line, because the Search policy callbacks are async. + await TestUtils.waitForTick(); + + let settingsWritten = SearchTestUtils.promiseSearchNotification( + "write-settings-to-disk-complete" + ); + let engine = Services.search.getEngineByName("Settings"); + engine.hidden = true; + engine.alias = "settings"; + await settingsWritten; + + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Add: [ + { + Name: "Settings", + URLTemplate: "http://example.com/?q={searchTerms}", + }, + ], + }, + }, + }); + + engine = Services.search.getEngineByName("Settings"); + + Assert.ok(engine.hidden, "Should have kept the engine hidden after restart"); + Assert.equal( + engine.alias, + "settings", + "Should have kept the engine alias after restart" + ); + + // Clean up + await setupPolicyEngineWithJsonWithSearch({}); + EnterprisePolicyTesting.resetRunOnceState(); +}); + +add_task(async function test_reset_default() { + await setupPolicyEngineWithJsonWithSearch({ + policies: { + SearchEngines: { + Remove: ["DuckDuckGo"], + }, + }, + }); + // Get in line, because the Search policy callbacks are async. + await TestUtils.waitForTick(); + + let engine = Services.search.getEngineByName("DuckDuckGo"); + + Assert.equal( + engine.hidden, + true, + "Application specified engine should be hidden." + ); + + await Services.search.restoreDefaultEngines(); + + engine = Services.search.getEngineByName("DuckDuckGo"); + Assert.equal( + engine.hidden, + false, + "Application specified engine should not be hidden" + ); + + EnterprisePolicyTesting.resetRunOnceState(); +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_preferences.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_preferences.js new file mode 100644 index 0000000000..6ad883fe42 --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_preferences.js @@ -0,0 +1,255 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const OLD_PREFERENCES_TESTS = [ + { + policies: { + Preferences: { + "network.IDN_show_punycode": true, + "accessibility.force_disabled": 1, + "security.default_personal_cert": "Select Automatically", + // "geo.enabled": 1, + "extensions.getAddons.showPane": 0, + }, + }, + lockedPrefs: { + "network.IDN_show_punycode": true, + "accessibility.force_disabled": 1, + "security.default_personal_cert": "Select Automatically", + // "geo.enabled": true, + "extensions.getAddons.showPane": false, + }, + }, +]; + +const NEW_PREFERENCES_TESTS = [ + { + policies: { + Preferences: { + "browser.policies.test.default.boolean": { + Value: true, + Status: "default", + }, + "browser.policies.test.default.string": { + Value: "string", + Status: "default", + }, + "browser.policies.test.default.number": { + Value: 11, + Status: "default", + }, + "browser.policies.test.locked.boolean": { + Value: true, + Status: "locked", + }, + "browser.policies.test.locked.string": { + Value: "string", + Status: "locked", + }, + "browser.policies.test.locked.number": { + Value: 11, + Status: "locked", + }, + "browser.policies.test.user.boolean": { + Value: true, + Status: "user", + }, + "browser.policies.test.user.string": { + Value: "string", + Status: "user", + }, + "browser.policies.test.user.number": { + Value: 11, + Status: "user", + }, + "mail.openMessageBehavior": { + Value: 1, + Status: "locked", + }, + "mailnews.display.prefer_plaintext": { + Value: true, + Status: "locked", + }, + "chat.enabled": { + Value: false, + Status: "locked", + }, + "calendar.agenda.days": { + Value: 21, + Status: "locked", + }, + }, + }, + defaultPrefs: { + "browser.policies.test.default.boolean": true, + "browser.policies.test.default.string": "string", + "browser.policies.test.default.number": 11, + }, + lockedPrefs: { + "browser.policies.test.locked.boolean": true, + "browser.policies.test.locked.string": "string", + "browser.policies.test.locked.number": 11, + "mail.openMessageBehavior": 1, + "mailnews.display.prefer_plaintext": true, + "chat.enabled": false, + "calendar.agenda.days": 21, + }, + userPrefs: { + "browser.policies.test.user.boolean": true, + "browser.policies.test.user.string": "string", + "browser.policies.test.user.number": 11, + }, + }, + { + policies: { + Preferences: { + "browser.policies.test.user.boolean": { + Status: "clear", + }, + "browser.policies.test.user.string": { + Status: "clear", + }, + "browser.policies.test.user.number": { + Status: "clear", + }, + }, + }, + + clearPrefs: { + "browser.policies.test.user.boolean": true, + "browser.policies.test.user.string": "string", + "browser.policies.test.user.number": 11, + }, + }, +]; + +const BAD_PREFERENCES_TESTS = [ + { + policies: { + Preferences: { + "not.a.valid.branch": { + Value: true, + Status: "default", + }, + "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer": + { + Value: true, + Status: "default", + }, + }, + }, + defaultPrefs: { + "not.a.valid.branch": true, + "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer": true, + }, + }, +]; + +add_task(async function test_old_preferences() { + for (let test of OLD_PREFERENCES_TESTS) { + await setupPolicyEngineWithJson({ + policies: test.policies, + }); + + info("Checking policy: " + Object.keys(test.policies)[0]); + + for (let [prefName, prefValue] of Object.entries(test.lockedPrefs || {})) { + checkLockedPref(prefName, prefValue); + } + } +}); + +add_task(async function test_new_preferences() { + for (let test of NEW_PREFERENCES_TESTS) { + await setupPolicyEngineWithJson({ + policies: test.policies, + }); + + info("Checking policy: " + Object.keys(test.policies)[0]); + + for (let [prefName, prefValue] of Object.entries(test.lockedPrefs || {})) { + checkLockedPref(prefName, prefValue); + } + + for (let [prefName, prefValue] of Object.entries(test.defaultPrefs || {})) { + checkDefaultPref(prefName, prefValue); + } + + for (let [prefName, prefValue] of Object.entries(test.userPrefs || {})) { + checkUserPref(prefName, prefValue); + } + + for (let [prefName, prefValue] of Object.entries(test.clearPrefs || {})) { + checkClearPref(prefName, prefValue); + } + } +}); + +add_task(async function test_bad_preferences() { + for (let test of BAD_PREFERENCES_TESTS) { + await setupPolicyEngineWithJson({ + policies: test.policies, + }); + + info("Checking policy: " + Object.keys(test.policies)[0]); + + for (let prefName of Object.entries(test.defaultPrefs || {})) { + checkUnsetPref(prefName); + } + } +}); + +add_task(async function test_user_default_preference() { + Services.prefs + .getDefaultBranch("") + .setBoolPref("browser.policies.test.override", true); + + await setupPolicyEngineWithJson({ + policies: { + Preferences: { + "browser.policies.test.override": { + Value: true, + Status: "user", + }, + }, + }, + }); + + checkUserPref("browser.policies.test.override", true); +}); + +add_task(async function test_security_preference() { + await setupPolicyEngineWithJson({ + policies: { + Preferences: { + "security.this.should.not.work": { + Value: true, + Status: "default", + }, + }, + }, + }); + + checkUnsetPref("security.this.should.not.work"); +}); + +add_task(async function test_bug_1666836() { + await setupPolicyEngineWithJson({ + policies: { + Preferences: { + "browser.tabs.warnOnClose": { + Value: 0, + Status: "default", + }, + }, + }, + }); + + equal( + Preferences.get("browser.tabs.warnOnClose"), + false, + `browser.tabs.warnOnClose should be false` + ); +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_proxy.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_proxy.js new file mode 100644 index 0000000000..ef5ad1e178 --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_proxy.js @@ -0,0 +1,122 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +add_task(async function test_proxy_modes_and_autoconfig() { + // Directly test the proxy Mode and AutoconfigURL parameters through + // the API instead of the policy engine, because the test harness + // uses these prefs, and changing them interfere with the harness. + + // Checks that every Mode value translates correctly to the expected pref value + let { ProxyPolicies, PROXY_TYPES_MAP } = ChromeUtils.importESModule( + "resource:///modules/policies/ProxyPolicies.sys.mjs" + ); + + for (let [mode, expectedValue] of PROXY_TYPES_MAP) { + ProxyPolicies.configureProxySettings({ Mode: mode }, (_, value) => { + equal(value, expectedValue, "Correct proxy mode"); + }); + } + + let autoconfigURL = new URL("data:text/plain,test"); + ProxyPolicies.configureProxySettings( + { AutoConfigURL: autoconfigURL }, + (_, value) => { + equal(value, autoconfigURL.href, "AutoconfigURL correctly set"); + } + ); +}); + +add_task(async function test_proxy_boolean_settings() { + // Tests that both false and true values are correctly set and locked + await setupPolicyEngineWithJson({ + policies: { + Proxy: { + UseProxyForDNS: false, + AutoLogin: false, + }, + }, + }); + + checkUnlockedPref("network.proxy.socks_remote_dns", false); + checkUnlockedPref("signon.autologin.proxy", false); + + await setupPolicyEngineWithJson({ + policies: { + Proxy: { + UseProxyForDNS: true, + AutoLogin: true, + }, + }, + }); + + checkUnlockedPref("network.proxy.socks_remote_dns", true); + checkUnlockedPref("signon.autologin.proxy", true); +}); + +add_task(async function test_proxy_socks_and_passthrough() { + await setupPolicyEngineWithJson({ + policies: { + Proxy: { + SOCKSVersion: 4, + Passthrough: "a, b, c", + }, + }, + }); + + checkUnlockedPref("network.proxy.socks_version", 4); + checkUnlockedPref("network.proxy.no_proxies_on", "a, b, c"); +}); + +add_task(async function test_proxy_addresses() { + function checkProxyPref(proxytype, address, port) { + checkUnlockedPref(`network.proxy.${proxytype}`, address); + checkUnlockedPref(`network.proxy.${proxytype}_port`, port); + } + + await setupPolicyEngineWithJson({ + policies: { + Proxy: { + HTTPProxy: "http.proxy.example.com:10", + SSLProxy: "ssl.proxy.example.com:30", + SOCKSProxy: "socks.proxy.example.com:40", + }, + }, + }); + + checkProxyPref("http", "http.proxy.example.com", 10); + checkProxyPref("ssl", "ssl.proxy.example.com", 30); + checkProxyPref("socks", "socks.proxy.example.com", 40); + + // Do the same, but now use the UseHTTPProxyForAllProtocols option + // and check that it takes effect. + await setupPolicyEngineWithJson({ + policies: { + Proxy: { + HTTPProxy: "http.proxy.example.com:10", + // FTP support was removed in bug 1574475 + // Setting an FTPProxy should result in a warning but should not fail + FTPProxy: "ftp.proxy.example.com:20", + SSLProxy: "ssl.proxy.example.com:30", + SOCKSProxy: "socks.proxy.example.com:40", + UseHTTPProxyForAllProtocols: true, + }, + }, + }); + + checkProxyPref("http", "http.proxy.example.com", 10); + checkProxyPref("ssl", "http.proxy.example.com", 10); + checkProxyPref("socks", "http.proxy.example.com", 10); + + // Make sure the FTPProxy setting did nothing + Assert.equal( + Preferences.has("network.proxy.ftp"), + false, + "network.proxy.ftp should not be set" + ); + Assert.equal( + Preferences.has("network.proxy.ftp_port"), + false, + "network.proxy.ftp_port should not be set" + ); +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_requestedlocales.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_requestedlocales.js new file mode 100644 index 0000000000..6c298cee5a --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_requestedlocales.js @@ -0,0 +1,47 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const REQ_LOC_CHANGE_EVENT = "intl:requested-locales-changed"; + +function promiseLocaleChanged(requestedLocale) { + return new Promise(resolve => { + let localeObserver = { + observe(aSubject, aTopic, aData) { + switch (aTopic) { + case REQ_LOC_CHANGE_EVENT: + let reqLocs = Services.locale.requestedLocales; + equal(reqLocs[0], requestedLocale); + Services.obs.removeObserver(localeObserver, REQ_LOC_CHANGE_EVENT); + resolve(); + } + }, + }; + Services.obs.addObserver(localeObserver, REQ_LOC_CHANGE_EVENT); + }); +} + +add_task(async function test_requested_locale_array() { + let originalLocales = Services.locale.requestedLocales; + let localePromise = promiseLocaleChanged("de"); + await setupPolicyEngineWithJson({ + policies: { + RequestedLocales: ["de"], + }, + }); + await localePromise; + Services.locale.requestedLocales = originalLocales; +}); + +add_task(async function test_requested_locale_string() { + let originalLocales = Services.locale.requestedLocales; + let localePromise = promiseLocaleChanged("fr"); + await setupPolicyEngineWithJson({ + policies: { + RequestedLocales: "fr", + }, + }); + await localePromise; + Services.locale.requestedLocales = originalLocales; +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_runOnce_helper.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_runOnce_helper.js new file mode 100644 index 0000000000..c8e73b3422 --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_runOnce_helper.js @@ -0,0 +1,21 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +let { runOnce } = ChromeUtils.importESModule( + "resource:///modules/policies/Policies.sys.mjs" +); + +let runCount = 0; +function callback() { + runCount++; +} + +add_task(async function test_runonce_helper() { + runOnce("test_action", callback); + equal(runCount, 1, "Callback ran for the first time."); + + runOnce("test_action", callback); + equal(runCount, 1, "Callback didn't run again."); +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_simple_pref_policies.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_simple_pref_policies.js new file mode 100644 index 0000000000..90da242a72 --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_simple_pref_policies.js @@ -0,0 +1,378 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* + * Use this file to add tests to policies that are + * simple pref flips. + * + * It's best to make a test to actually test the feature + * instead of the pref flip, but if that feature is well + * covered by tests, including that its pref actually works, + * it's OK to have the policy test here just to ensure + * that the right pref values are set. + */ + +const POLICIES_TESTS = [ + /* + * Example: + * { + * // Policies to be set at once through the engine + * policies: { "DisableFoo": true, "ConfigureBar": 42 }, + * + * // Locked prefs to check + * lockedPrefs: { "feature.foo": false }, + * + * // Unlocked prefs to check + * unlockedPrefs: { "bar.baz": 42 } + * }, + */ + + // POLICY: RememberPasswords + { + policies: { OfferToSaveLogins: false }, + lockedPrefs: { "signon.rememberSignons": false }, + }, + { + policies: { OfferToSaveLogins: true }, + lockedPrefs: { "signon.rememberSignons": true }, + }, + + // POLICY: DisableSecurityBypass + { + policies: { + DisableSecurityBypass: { + InvalidCertificate: true, + SafeBrowsing: true, + }, + }, + lockedPrefs: { + "security.certerror.hideAddException": true, + "browser.safebrowsing.allowOverride": false, + }, + }, + + // POLICY: DisableBuiltinPDFViewer + { + policies: { DisableBuiltinPDFViewer: true }, + lockedPrefs: { "pdfjs.disabled": true }, + }, + + // POLICY: Authentication + { + policies: { + Authentication: { + SPNEGO: ["a.com", "b.com"], + Delegated: ["a.com", "b.com"], + NTLM: ["a.com", "b.com"], + AllowNonFQDN: { + SPNEGO: true, + NTLM: true, + }, + AllowProxies: { + SPNEGO: false, + NTLM: false, + }, + PrivateBrowsing: true, + }, + }, + lockedPrefs: { + "network.negotiate-auth.trusted-uris": "a.com, b.com", + "network.negotiate-auth.delegation-uris": "a.com, b.com", + "network.automatic-ntlm-auth.trusted-uris": "a.com, b.com", + "network.automatic-ntlm-auth.allow-non-fqdn": true, + "network.negotiate-auth.allow-non-fqdn": true, + "network.automatic-ntlm-auth.allow-proxies": false, + "network.negotiate-auth.allow-proxies": false, + "network.auth.private-browsing-sso": true, + }, + }, + + // POLICY: Authentication (unlocked) + { + policies: { + Authentication: { + SPNEGO: ["a.com", "b.com"], + Delegated: ["a.com", "b.com"], + NTLM: ["a.com", "b.com"], + AllowNonFQDN: { + SPNEGO: true, + NTLM: true, + }, + AllowProxies: { + SPNEGO: false, + NTLM: false, + }, + PrivateBrowsing: true, + Locked: false, + }, + }, + unlockedPrefs: { + "network.negotiate-auth.trusted-uris": "a.com, b.com", + "network.negotiate-auth.delegation-uris": "a.com, b.com", + "network.automatic-ntlm-auth.trusted-uris": "a.com, b.com", + "network.automatic-ntlm-auth.allow-non-fqdn": true, + "network.negotiate-auth.allow-non-fqdn": true, + "network.automatic-ntlm-auth.allow-proxies": false, + "network.negotiate-auth.allow-proxies": false, + "network.auth.private-browsing-sso": true, + }, + }, + + // POLICY: Certificates (true) + { + policies: { + Certificates: { + ImportEnterpriseRoots: true, + }, + }, + lockedPrefs: { + "security.enterprise_roots.enabled": true, + }, + }, + + // POLICY: Certificates (false) + { + policies: { + Certificates: { + ImportEnterpriseRoots: false, + }, + }, + lockedPrefs: { + "security.enterprise_roots.enabled": false, + }, + }, + + // POLICY: InstallAddons.Default (block addon installs) + { + policies: { + InstallAddonsPermission: { + Default: false, + }, + }, + lockedPrefs: { + "xpinstall.enabled": false, + }, + }, + + // POLICY: DNSOverHTTPS Locked + { + policies: { + DNSOverHTTPS: { + Enabled: true, + ProviderURL: "http://example.com/provider", + ExcludedDomains: ["example.com", "example.org"], + Locked: true, + }, + }, + lockedPrefs: { + "network.trr.mode": 2, + "network.trr.uri": "http://example.com/provider", + "network.trr.excluded-domains": "example.com,example.org", + }, + }, + + // POLICY: DNSOverHTTPS Unlocked + { + policies: { + DNSOverHTTPS: { + Enabled: false, + ProviderURL: "http://example.com/provider", + ExcludedDomains: ["example.com", "example.org"], + }, + }, + unlockedPrefs: { + "network.trr.mode": 5, + "network.trr.uri": "http://example.com/provider", + "network.trr.excluded-domains": "example.com,example.org", + }, + }, + + // POLICY: SSLVersionMin/SSLVersionMax (1) + { + policies: { + SSLVersionMin: "tls1", + SSLVersionMax: "tls1.1", + }, + lockedPrefs: { + "security.tls.version.min": 1, + "security.tls.version.max": 2, + }, + }, + + // POLICY: SSLVersionMin/SSLVersionMax (2) + { + policies: { + SSLVersionMin: "tls1.2", + SSLVersionMax: "tls1.3", + }, + lockedPrefs: { + "security.tls.version.min": 3, + "security.tls.version.max": 4, + }, + }, + + // POLICY: CaptivePortal + { + policies: { + CaptivePortal: false, + }, + lockedPrefs: { + "network.captive-portal-service.enabled": false, + }, + }, + + // POLICY: NetworkPrediction + { + policies: { + NetworkPrediction: false, + }, + lockedPrefs: { + "network.dns.disablePrefetch": true, + "network.dns.disablePrefetchFromHTTPS": true, + }, + }, + + // POLICY: ExtensionUpdate + { + policies: { + ExtensionUpdate: false, + }, + lockedPrefs: { + "extensions.update.enabled": false, + }, + }, + + // POLICY: OfferToSaveLoginsDefault + { + policies: { + OfferToSaveLoginsDefault: false, + }, + unlockedPrefs: { + "signon.rememberSignons": false, + }, + }, + + // POLICY: PDFjs + + { + policies: { + PDFjs: { + Enabled: false, + EnablePermissions: true, + }, + }, + lockedPrefs: { + "pdfjs.disabled": true, + "pdfjs.enablePermissions": true, + }, + }, + + // POLICY: DisabledCiphers + { + policies: { + DisabledCiphers: { + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: false, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: false, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: false, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: false, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: false, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: false, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: false, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: false, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: false, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: false, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA: false, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA: false, + TLS_RSA_WITH_AES_128_GCM_SHA256: false, + TLS_RSA_WITH_AES_256_GCM_SHA384: false, + TLS_RSA_WITH_AES_128_CBC_SHA: false, + TLS_RSA_WITH_AES_256_CBC_SHA: false, + TLS_RSA_WITH_3DES_EDE_CBC_SHA: false, + }, + }, + lockedPrefs: { + "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256": true, + "security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256": true, + "security.ssl3.ecdhe_ecdsa_chacha20_poly1305_sha256": true, + "security.ssl3.ecdhe_rsa_chacha20_poly1305_sha256": true, + "security.ssl3.ecdhe_ecdsa_aes_256_gcm_sha384": true, + "security.ssl3.ecdhe_rsa_aes_256_gcm_sha384": true, + "security.ssl3.ecdhe_rsa_aes_128_sha": true, + "security.ssl3.ecdhe_ecdsa_aes_128_sha": true, + "security.ssl3.ecdhe_rsa_aes_256_sha": true, + "security.ssl3.ecdhe_ecdsa_aes_256_sha": true, + "security.ssl3.dhe_rsa_aes_128_sha": true, + "security.ssl3.dhe_rsa_aes_256_sha": true, + "security.ssl3.rsa_aes_128_gcm_sha256": true, + "security.ssl3.rsa_aes_256_gcm_sha384": true, + "security.ssl3.rsa_aes_128_sha": true, + "security.ssl3.rsa_aes_256_sha": true, + "security.ssl3.deprecated.rsa_des_ede3_sha": true, + }, + }, + + { + policies: { + DisabledCiphers: { + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: true, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: true, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: true, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: true, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: true, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: true, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: true, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: true, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA: true, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA: true, + TLS_RSA_WITH_AES_128_GCM_SHA256: true, + TLS_RSA_WITH_AES_256_GCM_SHA384: true, + TLS_RSA_WITH_AES_128_CBC_SHA: true, + TLS_RSA_WITH_AES_256_CBC_SHA: true, + TLS_RSA_WITH_3DES_EDE_CBC_SHA: true, + }, + }, + lockedPrefs: { + "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256": false, + "security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256": false, + "security.ssl3.ecdhe_ecdsa_chacha20_poly1305_sha256": false, + "security.ssl3.ecdhe_rsa_chacha20_poly1305_sha256": false, + "security.ssl3.ecdhe_ecdsa_aes_256_gcm_sha384": false, + "security.ssl3.ecdhe_rsa_aes_256_gcm_sha384": false, + "security.ssl3.ecdhe_rsa_aes_128_sha": false, + "security.ssl3.ecdhe_ecdsa_aes_128_sha": false, + "security.ssl3.ecdhe_rsa_aes_256_sha": false, + "security.ssl3.ecdhe_ecdsa_aes_256_sha": false, + "security.ssl3.dhe_rsa_aes_128_sha": false, + "security.ssl3.dhe_rsa_aes_256_sha": false, + "security.ssl3.rsa_aes_128_gcm_sha256": false, + "security.ssl3.rsa_aes_256_gcm_sha384": false, + "security.ssl3.rsa_aes_128_sha": false, + "security.ssl3.rsa_aes_256_sha": false, + "security.ssl3.deprecated.rsa_des_ede3_sha": false, + }, + }, +]; + +add_task(async function test_policy_simple_prefs() { + for (let test of POLICIES_TESTS) { + await setupPolicyEngineWithJson({ + policies: test.policies, + }); + + info("Checking policy: " + Object.keys(test.policies)[0]); + + for (let [prefName, prefValue] of Object.entries(test.lockedPrefs || {})) { + checkLockedPref(prefName, prefValue); + } + + for (let [prefName, prefValue] of Object.entries( + test.unlockedPrefs || {} + )) { + checkUnlockedPref(prefName, prefValue); + } + } +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/test_sorted_alphabetically.js b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_sorted_alphabetically.js new file mode 100644 index 0000000000..0d246c850c --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/test_sorted_alphabetically.js @@ -0,0 +1,48 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +function checkArrayIsSorted(array, msg) { + let sorted = true; + let sortedArray = array.slice().sort(function (a, b) { + return a.localeCompare(b); + }); + + for (let i = 0; i < array.length; i++) { + if (array[i] != sortedArray[i]) { + sorted = false; + break; + } + } + ok(sorted, msg); +} + +add_task(async function test_policies_sorted() { + let { schema } = ChromeUtils.importESModule( + "resource:///modules/policies/schema.sys.mjs" + ); + let { Policies } = ChromeUtils.importESModule( + "resource:///modules/policies/Policies.sys.mjs" + ); + + checkArrayIsSorted( + Object.keys(schema.properties), + "policies-schema.json is alphabetically sorted." + ); + checkArrayIsSorted( + Object.keys(Policies), + "Policies.jsm is alphabetically sorted." + ); +}); + +add_task(async function check_naming_conventions() { + let { schema } = ChromeUtils.importESModule( + "resource:///modules/policies/schema.sys.mjs" + ); + equal( + Object.keys(schema.properties).some(key => key.includes("__")), + false, + "Can't use __ in a policy name as it's used as a delimiter" + ); +}); diff --git a/comm/mail/components/enterprisepolicies/tests/xpcshell/xpcshell.ini b/comm/mail/components/enterprisepolicies/tests/xpcshell/xpcshell.ini new file mode 100644 index 0000000000..ab47cca7bd --- /dev/null +++ b/comm/mail/components/enterprisepolicies/tests/xpcshell/xpcshell.ini @@ -0,0 +1,18 @@ +[DEFAULT] +firefox-appdir = browser +head = head.js + +[test_3rdparty.js] +[test_appupdatepin.js] +[test_appupdateurl.js] +[test_bug1658259.js] +[test_clear_blocked_cookies.js] +[test_macosparser_unflatten.js] +skip-if = os != 'mac' +[test_policy_search_engine.js] +[test_preferences.js] +[test_proxy.js] +[test_requestedlocales.js] +[test_runOnce_helper.js] +[test_simple_pref_policies.js] +[test_sorted_alphabetically.js] |