summaryrefslogtreecommitdiffstats
path: root/toolkit/components/cookiebanners/test/browser/browser_cookieinjector.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/cookiebanners/test/browser/browser_cookieinjector.js')
-rw-r--r--toolkit/components/cookiebanners/test/browser/browser_cookieinjector.js625
1 files changed, 625 insertions, 0 deletions
diff --git a/toolkit/components/cookiebanners/test/browser/browser_cookieinjector.js b/toolkit/components/cookiebanners/test/browser/browser_cookieinjector.js
new file mode 100644
index 0000000000..58fdab7114
--- /dev/null
+++ b/toolkit/components/cookiebanners/test/browser/browser_cookieinjector.js
@@ -0,0 +1,625 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { SiteDataTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/SiteDataTestUtils.sys.mjs"
+);
+
+const DOMAIN_A = "example.com";
+const DOMAIN_B = "example.org";
+const DOMAIN_C = "example.net";
+
+const ORIGIN_A = "https://" + DOMAIN_A;
+const ORIGIN_A_SUB = `https://test1.${DOMAIN_A}`;
+const ORIGIN_B = "https://" + DOMAIN_B;
+const ORIGIN_C = "https://" + DOMAIN_C;
+
+const TEST_COOKIE_HEADER_URL =
+ getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content",
+ "https://example.com"
+ ) + "testCookieHeader.sjs";
+
+/**
+ * Tests that the test domains have no cookies set.
+ */
+function assertNoCookies() {
+ ok(
+ !SiteDataTestUtils.hasCookies(ORIGIN_A),
+ "Should not set any cookies for ORIGIN_A"
+ );
+ ok(
+ !SiteDataTestUtils.hasCookies(ORIGIN_B),
+ "Should not set any cookies for ORIGIN_B"
+ );
+ ok(
+ !SiteDataTestUtils.hasCookies(ORIGIN_C),
+ "Should not set any cookies for ORIGIN_C"
+ );
+}
+
+/**
+ * Loads a list of urls consecutively from the same tab.
+ * @param {string[]} urls - List of urls to load.
+ */
+async function visitTestSites(urls = [ORIGIN_A, ORIGIN_B, ORIGIN_C]) {
+ let tab = BrowserTestUtils.addTab(gBrowser, "about:blank");
+
+ for (let url of urls) {
+ await BrowserTestUtils.loadURIString(tab.linkedBrowser, url);
+ await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+ }
+
+ BrowserTestUtils.removeTab(tab);
+}
+
+add_setup(cookieInjectorTestSetup);
+
+/**
+ * Tests that no cookies are set if the cookie injection component is disabled
+ * by pref, but the cookie banner service is enabled.
+ */
+add_task(async function test_cookie_injector_disabled() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["cookiebanners.service.mode", Ci.nsICookieBannerService.MODE_REJECT],
+ ["cookiebanners.cookieInjector.enabled", false],
+ ],
+ });
+
+ insertTestCookieRules();
+
+ await visitTestSites();
+ assertNoCookies();
+
+ await SiteDataTestUtils.clear();
+});
+
+/**
+ * Tests that no cookies are set if the cookie injection component is enabled
+ * by pref, but the cookie banner service is disabled or in detect-only mode.
+ */
+add_task(async function test_cookie_banner_service_disabled() {
+ // Enable in PBM so the service is always initialized.
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ [
+ "cookiebanners.service.mode.privateBrowsing",
+ Ci.nsICookieBannerService.MODE_REJECT,
+ ],
+ ],
+ });
+
+ for (let [serviceMode, detectOnly] of [
+ [Ci.nsICookieBannerService.MODE_DISABLED, false],
+ [Ci.nsICookieBannerService.MODE_DISABLED, true],
+ [Ci.nsICookieBannerService.MODE_REJECT, true],
+ [Ci.nsICookieBannerService.MODE_REJECT_OR_ACCEPT, true],
+ ]) {
+ info(`Testing with serviceMode=${serviceMode}; detectOnly=${detectOnly}`);
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["cookiebanners.service.mode", serviceMode],
+ ["cookiebanners.cookieInjector.enabled", true],
+ ["cookiebanners.service.detectOnly", detectOnly],
+ ],
+ });
+
+ await visitTestSites();
+ assertNoCookies();
+
+ await SiteDataTestUtils.clear();
+ await SpecialPowers.popPrefEnv();
+ }
+});
+
+/**
+ * Tests that we don't inject cookies if there are no matching rules.
+ */
+add_task(async function test_no_rules() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["cookiebanners.service.mode", Ci.nsICookieBannerService.MODE_REJECT],
+ ["cookiebanners.cookieInjector.enabled", true],
+ ],
+ });
+
+ info("Clearing existing rules");
+ Services.cookieBanners.resetRules(false);
+
+ await visitTestSites();
+ assertNoCookies();
+
+ await SiteDataTestUtils.clear();
+});
+
+/**
+ * Tests that inject the correct cookies for matching rules and MODE_REJECT.
+ */
+add_task(async function test_mode_reject() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["cookiebanners.service.mode", Ci.nsICookieBannerService.MODE_REJECT],
+ ["cookiebanners.cookieInjector.enabled", true],
+ ],
+ });
+
+ insertTestCookieRules();
+
+ await visitTestSites();
+
+ ok(
+ SiteDataTestUtils.hasCookies(ORIGIN_A, [
+ {
+ key: `cookieConsent_${DOMAIN_A}_1`,
+ value: "optOut1",
+ },
+ {
+ key: `cookieConsent_${DOMAIN_A}_2`,
+ value: "optOut2",
+ },
+ ]),
+ "Should set opt-out cookies for ORIGIN_A"
+ );
+ ok(
+ !SiteDataTestUtils.hasCookies(ORIGIN_B),
+ "Should not set any cookies for ORIGIN_B"
+ );
+ // RULE_A also includes DOMAIN_C.
+ ok(
+ SiteDataTestUtils.hasCookies(ORIGIN_C, [
+ {
+ key: `cookieConsent_${DOMAIN_A}_1`,
+ value: "optOut1",
+ },
+ {
+ key: `cookieConsent_${DOMAIN_A}_2`,
+ value: "optOut2",
+ },
+ ]),
+ "Should set opt-out cookies for ORIGIN_C"
+ );
+
+ await SiteDataTestUtils.clear();
+});
+
+/**
+ * Tests that inject the correct cookies for matching rules and
+ * MODE_REJECT_OR_ACCEPT.
+ */
+add_task(async function test_mode_reject_or_accept() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ [
+ "cookiebanners.service.mode",
+ Ci.nsICookieBannerService.MODE_REJECT_OR_ACCEPT,
+ ],
+ ["cookiebanners.cookieInjector.enabled", true],
+ ],
+ });
+
+ insertTestCookieRules();
+
+ await visitTestSites();
+
+ ok(
+ SiteDataTestUtils.hasCookies(ORIGIN_A, [
+ {
+ key: `cookieConsent_${DOMAIN_A}_1`,
+ value: "optOut1",
+ },
+ {
+ key: `cookieConsent_${DOMAIN_A}_2`,
+ value: "optOut2",
+ },
+ ]),
+ "Should set opt-out cookies for ORIGIN_A"
+ );
+ ok(
+ SiteDataTestUtils.hasCookies(ORIGIN_B, [
+ {
+ key: `cookieConsent_${DOMAIN_B}_1`,
+ value: "optIn1",
+ },
+ ]),
+ "Should set opt-in cookies for ORIGIN_B"
+ );
+ // Rule a also includes DOMAIN_C
+ ok(
+ SiteDataTestUtils.hasCookies(ORIGIN_C, [
+ {
+ key: `cookieConsent_${DOMAIN_A}_1`,
+ value: "optOut1",
+ },
+ {
+ key: `cookieConsent_${DOMAIN_A}_2`,
+ value: "optOut2",
+ },
+ ]),
+ "Should set opt-out cookies for ORIGIN_C"
+ );
+
+ await SiteDataTestUtils.clear();
+});
+
+/**
+ * Test that embedded third-parties do not trigger cookie injection.
+ */
+add_task(async function test_embedded_third_party() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ [
+ "cookiebanners.service.mode",
+ Ci.nsICookieBannerService.MODE_REJECT_OR_ACCEPT,
+ ],
+ ["cookiebanners.cookieInjector.enabled", true],
+ ],
+ });
+
+ insertTestCookieRules();
+
+ info("Loading example.com with an iframe for example.org.");
+ await BrowserTestUtils.withNewTab("https://example.com", async browser => {
+ await SpecialPowers.spawn(browser, [], async () => {
+ let iframe = content.document.createElement("iframe");
+ iframe.src = "https://example.org";
+ content.document.body.appendChild(iframe);
+ await ContentTaskUtils.waitForEvent(iframe, "load");
+ });
+ });
+
+ ok(
+ SiteDataTestUtils.hasCookies(ORIGIN_A, [
+ {
+ key: `cookieConsent_${DOMAIN_A}_1`,
+ value: "optOut1",
+ },
+ {
+ key: `cookieConsent_${DOMAIN_A}_2`,
+ value: "optOut2",
+ },
+ ]),
+ "Should set opt-out cookies for top-level ORIGIN_A"
+ );
+ ok(
+ !SiteDataTestUtils.hasCookies(ORIGIN_B),
+ "Should not set any cookies for embedded ORIGIN_B"
+ );
+
+ await SiteDataTestUtils.clear();
+});
+
+/**
+ * Test that the injected cookies are present in the cookie header for the
+ * initial top level document request.
+ */
+add_task(async function test_cookie_header_and_document() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["cookiebanners.service.mode", Ci.nsICookieBannerService.MODE_REJECT],
+ ["cookiebanners.cookieInjector.enabled", true],
+ ],
+ });
+ insertTestCookieRules();
+
+ await BrowserTestUtils.withNewTab(TEST_COOKIE_HEADER_URL, async browser => {
+ await SpecialPowers.spawn(browser, [], async () => {
+ const EXPECTED_COOKIE_STR =
+ "cookieConsent_example.com_1=optOut1; cookieConsent_example.com_2=optOut2";
+ is(
+ content.document.body.innerText,
+ EXPECTED_COOKIE_STR,
+ "Sent the correct cookie header."
+ );
+ is(
+ content.document.cookie,
+ EXPECTED_COOKIE_STR,
+ "document.cookie has the correct cookie string."
+ );
+ });
+ });
+
+ await SiteDataTestUtils.clear();
+});
+
+/**
+ * Test that cookies get properly injected for private browsing mode.
+ */
+add_task(async function test_pbm() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ [
+ "cookiebanners.service.mode.privateBrowsing",
+ Ci.nsICookieBannerService.MODE_REJECT,
+ ],
+ ["cookiebanners.cookieInjector.enabled", true],
+ ],
+ });
+ insertTestCookieRules();
+
+ let pbmWindow = await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ });
+ let tab = BrowserTestUtils.addTab(pbmWindow.gBrowser, "about:blank");
+ await BrowserTestUtils.loadURIString(tab.linkedBrowser, ORIGIN_A);
+ await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+
+ ok(
+ SiteDataTestUtils.hasCookies(
+ tab.linkedBrowser.contentPrincipal.origin,
+ [
+ {
+ key: `cookieConsent_${DOMAIN_A}_1`,
+ value: "optOut1",
+ },
+ {
+ key: `cookieConsent_${DOMAIN_A}_2`,
+ value: "optOut2",
+ },
+ ],
+ true
+ ),
+ "Should set opt-out cookies for top-level ORIGIN_A in private browsing."
+ );
+
+ ok(
+ !SiteDataTestUtils.hasCookies(ORIGIN_A),
+ "Should not set any cookies for ORIGIN_A without PBM origin attribute."
+ );
+ ok(
+ !SiteDataTestUtils.hasCookies(ORIGIN_B),
+ "Should not set any cookies for ORIGIN_B"
+ );
+
+ await BrowserTestUtils.closeWindow(pbmWindow);
+ await SiteDataTestUtils.clear();
+});
+
+/**
+ * Test that cookies get properly injected for container tabs.
+ */
+add_task(async function test_container_tab() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ [
+ "cookiebanners.service.mode",
+ Ci.nsICookieBannerService.MODE_REJECT_OR_ACCEPT,
+ ],
+ ["cookiebanners.cookieInjector.enabled", true],
+ ],
+ });
+ insertTestCookieRules();
+
+ info("Loading ORIGIN_B in a container tab.");
+ let tab = BrowserTestUtils.addTab(gBrowser, ORIGIN_B, {
+ userContextId: 1,
+ });
+ await BrowserTestUtils.loadURIString(tab.linkedBrowser, ORIGIN_B);
+ await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+
+ ok(
+ !SiteDataTestUtils.hasCookies(ORIGIN_A),
+ "Should not set any cookies for ORIGIN_A"
+ );
+ ok(
+ SiteDataTestUtils.hasCookies(tab.linkedBrowser.contentPrincipal.origin, [
+ {
+ key: `cookieConsent_${DOMAIN_B}_1`,
+ value: "optIn1",
+ },
+ ]),
+ "Should set opt-out cookies for top-level ORIGIN_B in user context 1."
+ );
+ ok(
+ !SiteDataTestUtils.hasCookies(ORIGIN_B),
+ "Should not set any cookies for ORIGIN_B in default user context"
+ );
+
+ BrowserTestUtils.removeTab(tab);
+ await SiteDataTestUtils.clear();
+});
+
+/**
+ * Test that if there is already a cookie with the given key, we don't overwrite
+ * it. If the rule sets the unsetValue field, this cookie may be overwritten if
+ * the value matches.
+ */
+add_task(async function test_no_overwrite() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ [
+ "cookiebanners.service.mode",
+ Ci.nsICookieBannerService.MODE_REJECT_OR_ACCEPT,
+ ],
+ ["cookiebanners.cookieInjector.enabled", true],
+ ],
+ });
+
+ insertTestCookieRules();
+
+ info("Pre-setting a cookie that should not be overwritten.");
+ SiteDataTestUtils.addToCookies({
+ origin: ORIGIN_A,
+ host: `.${DOMAIN_A}`,
+ path: "/",
+ name: `cookieConsent_${DOMAIN_A}_1`,
+ value: "KEEPME",
+ });
+
+ info("Pre-setting a cookie that should be overwritten, based on its value");
+ SiteDataTestUtils.addToCookies({
+ origin: ORIGIN_B,
+ host: `.${DOMAIN_B}`,
+ path: "/",
+ name: `cookieConsent_${DOMAIN_B}_1`,
+ value: "UNSET",
+ });
+
+ await visitTestSites();
+
+ ok(
+ SiteDataTestUtils.hasCookies(ORIGIN_A, [
+ {
+ key: `cookieConsent_${DOMAIN_A}_1`,
+ value: "KEEPME",
+ },
+ {
+ key: `cookieConsent_${DOMAIN_A}_2`,
+ value: "optOut2",
+ },
+ ]),
+ "Should retain pre-set opt-in cookies for ORIGIN_A, but write new secondary cookie from rules."
+ );
+ ok(
+ SiteDataTestUtils.hasCookies(ORIGIN_B, [
+ {
+ key: `cookieConsent_${DOMAIN_B}_1`,
+ value: "optIn1",
+ },
+ ]),
+ "Should have overwritten cookie for ORIGIN_B, based on its value and the unsetValue rule property."
+ );
+
+ await SiteDataTestUtils.clear();
+});
+
+/**
+ * Tests that cookies are injected for the base domain when visiting a
+ * subdomain.
+ */
+add_task(async function test_subdomain() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["cookiebanners.service.mode", Ci.nsICookieBannerService.MODE_REJECT],
+ ["cookiebanners.cookieInjector.enabled", true],
+ ],
+ });
+
+ insertTestCookieRules();
+
+ await visitTestSites([ORIGIN_A_SUB, ORIGIN_B]);
+
+ ok(
+ SiteDataTestUtils.hasCookies(ORIGIN_A, [
+ {
+ key: `cookieConsent_${DOMAIN_A}_1`,
+ value: "optOut1",
+ },
+ {
+ key: `cookieConsent_${DOMAIN_A}_2`,
+ value: "optOut2",
+ },
+ ]),
+ "Should set opt-out cookies for ORIGIN_A when visiting subdomain."
+ );
+ ok(
+ !SiteDataTestUtils.hasCookies(ORIGIN_B),
+ "Should not set any cookies for ORIGIN_B"
+ );
+
+ await SiteDataTestUtils.clear();
+});
+
+add_task(async function test_site_preference() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["cookiebanners.service.mode", Ci.nsICookieBannerService.MODE_REJECT],
+ ["cookiebanners.cookieInjector.enabled", true],
+ ],
+ });
+
+ insertTestCookieRules();
+
+ await visitTestSites();
+
+ ok(
+ !SiteDataTestUtils.hasCookies(ORIGIN_B),
+ "Should not set any cookies for ORIGIN_B"
+ );
+
+ info("Set the site preference of example.org to MODE_REJECT_OR_ACCEPT.");
+ let uri = Services.io.newURI(ORIGIN_B);
+ Services.cookieBanners.setDomainPref(
+ uri,
+ Ci.nsICookieBannerService.MODE_REJECT_OR_ACCEPT,
+ false
+ );
+
+ await visitTestSites();
+ ok(
+ SiteDataTestUtils.hasCookies(ORIGIN_B, [
+ {
+ key: `cookieConsent_${DOMAIN_B}_1`,
+ value: "optIn1",
+ },
+ ]),
+ "Should set opt-in cookies for ORIGIN_B"
+ );
+
+ Services.cookieBanners.removeAllDomainPrefs(false);
+ await SiteDataTestUtils.clear();
+});
+
+add_task(async function test_site_preference_pbm() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ [
+ "cookiebanners.service.mode.privateBrowsing",
+ Ci.nsICookieBannerService.MODE_REJECT,
+ ],
+ ["cookiebanners.cookieInjector.enabled", true],
+ ],
+ });
+
+ insertTestCookieRules();
+
+ let pbmWindow = await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ });
+ let tab = BrowserTestUtils.addTab(pbmWindow.gBrowser, "about:blank");
+ await BrowserTestUtils.loadURIString(tab.linkedBrowser, ORIGIN_B);
+ await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+
+ ok(
+ !SiteDataTestUtils.hasCookies(
+ tab.linkedBrowser.contentPrincipal.origin,
+ null,
+ true
+ ),
+ "Should not set any cookies for ORIGIN_B in the private window"
+ );
+
+ info(
+ "Set the site preference of example.org to MODE_REJECT_OR_ACCEPT. in the private window."
+ );
+ let uri = Services.io.newURI(ORIGIN_B);
+ Services.cookieBanners.setDomainPref(
+ uri,
+ Ci.nsICookieBannerService.MODE_REJECT_OR_ACCEPT,
+ true
+ );
+
+ await BrowserTestUtils.loadURIString(tab.linkedBrowser, ORIGIN_B);
+ await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+
+ ok(
+ SiteDataTestUtils.hasCookies(
+ tab.linkedBrowser.contentPrincipal.origin,
+ [
+ {
+ key: `cookieConsent_${DOMAIN_B}_1`,
+ value: "optIn1",
+ },
+ ],
+ true
+ ),
+ "Should set opt-in cookies for ORIGIN_B"
+ );
+
+ Services.cookieBanners.removeAllDomainPrefs(true);
+ BrowserTestUtils.removeTab(tab);
+ await BrowserTestUtils.closeWindow(pbmWindow);
+ await SiteDataTestUtils.clear();
+});