Commit c3f891b5 authored by Emma Zuehlcke's avatar Emma Zuehlcke
Browse files

Bug 1785872 - Extend tests for global CookieBannerRules. r=timhuang

parent cc99189a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
[browser_bannerClicking.js]
support-files =
    file_banner.html
    file_banner_b.html
    file_delayed_banner.html
[browser_cookiebannerservice.js]
[browser_cookieinjector.js]
+203 −19
Original line number Diff line number Diff line
@@ -18,6 +18,12 @@ const TEST_PATH = getRootDirectory(gTestPath).replace(

const TEST_PAGE_A = TEST_ORIGIN_A + TEST_PATH + "file_banner.html";
const TEST_PAGE_B = TEST_ORIGIN_B + TEST_PATH + "file_banner.html";
// Page C has a different banner element ID than A and B.
const TEST_PAGE_C = TEST_ORIGIN_C + TEST_PATH + "file_banner_b.html";

function genUUID() {
  return Services.uuid.generateUUID().number.slice(1, -1);
}

/**
 * A helper function returns a promise which resolves when the banner clicking
@@ -47,12 +53,16 @@ function promiseBannerClickingFinish(domain) {
 * @param {BrowsingContext} bc - the browsing context
 * @param {boolean} visible - if the banner should be visible.
 * @param {boolean} expected - the expected banner click state.
 * @param {string} [bannerId] - id of the cookie banner element.
 */
async function verifyBannerState(bc, visible, expected) {
async function verifyBannerState(bc, visible, expected, bannerId = "banner") {
  info("Verify the cookie banner state.");

  await SpecialPowers.spawn(bc, [visible, expected], (visible, expected) => {
    let banner = content.document.getElementById("banner");
  await SpecialPowers.spawn(
    bc,
    [visible, expected, bannerId],
    (visible, expected, bannerId) => {
      let banner = content.document.getElementById(bannerId);

      is(
        banner.checkVisibility({
@@ -66,19 +76,28 @@ async function verifyBannerState(bc, visible, expected) {
      let result = content.document.getElementById("result");

      is(result.textContent, expected, "The build click state is correct.");
  });
    }
  );
}

/**
 * A helper function to open the test page and verify the banner state.
 *
 * @param {Window} win - the chrome window object.
 * @param {Window} [win] - the chrome window object.
 * @param {String} domain - the domain of the testing page.
 * @param {String} testURL - the url of the testing page.
 * @param {boolean} visible - if the banner should be visible.
 * @param {boolean} expected - the expected banner click state.
 * @param {string} [bannerId] - id of the cookie banner element.
 */
async function openPageAndVerify({ win, domain, testURL, visible, expected }) {
async function openPageAndVerify({
  win = window,
  domain,
  testURL,
  visible,
  expected,
  bannerId = "banner",
}) {
  info(`Opening ${testURL}`);
  let promise = promiseBannerClickingFinish(domain);

@@ -86,7 +105,7 @@ async function openPageAndVerify({ win, domain, testURL, visible, expected }) {

  await promise;

  await verifyBannerState(tab.linkedBrowser, visible, expected);
  await verifyBannerState(tab.linkedBrowser, visible, expected, bannerId);

  BrowserTestUtils.removeTab(tab);
}
@@ -143,27 +162,56 @@ function insertTestRules() {

  info("Inserting test rules.");

  info("Add opt-out click rule for DOMAIN_A.");
  let ruleA = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleA.id = genUUID();
  ruleA.domain = TEST_DOMAIN_A;

  ruleA.addClickRule("div#banner", null, "button#optOut", "button#optIn");
  Services.cookieBanners.insertRule(ruleA);

  // An opt-in click rule for DOMAIN_B.
  info("Add opt-in click rule for DOMAIN_B.");
  let ruleB = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleB.id = genUUID();
  ruleB.domain = TEST_DOMAIN_B;

  ruleB.addClickRule("div#banner", null, null, "button#optIn");
  Services.cookieBanners.insertRule(ruleB);

  info("Add global ruleC which targets a non-existing banner (presence).");
  let ruleC = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleC.id = genUUID();
  ruleC.domain = "*";
  ruleC.addClickRule("div#nonExistingBanner", null, null, "button#optIn");
  Services.cookieBanners.insertRule(ruleC);

  info("Add global ruleD which targets a non-existing banner (presence).");
  let ruleD = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleD.id = genUUID();
  ruleD.domain = "*";
  ruleD.addClickRule(
    "div#nonExistingBanner2",
    null,
    "button#optOut",
    "button#optIn"
  );
  Services.cookieBanners.insertRule(ruleD);
}

add_setup(async function() {
  await SpecialPowers.pushPrefEnv({
    set: [
      // Enable debug logging.
      ["cookiebanners.listService.logLevel", "Debug"],
      ["cookiebanners.bannerClicking.logLevel", "Debug"],
      ["cookiebanners.bannerClicking.testing", true],
      ["cookiebanners.bannerClicking.timeout", 500],
      ["cookiebanners.bannerClicking.enabled", true],
@@ -383,3 +431,139 @@ add_task(async function test_embedded_iframe_pbm() {

  await BrowserTestUtils.closeWindow(pbmWindow);
});

/**
 * Test the banner clicking with global rules and MODE_REJECT.
 */
add_task(async function test_clicking_global_rules() {
  await SpecialPowers.pushPrefEnv({
    set: [
      ["cookiebanners.service.mode", Ci.nsICookieBannerService.MODE_REJECT],
      ["cookiebanners.service.enableGlobalRules", true],
    ],
  });

  info("Clearing existing rules");
  Services.cookieBanners.resetRules(false);

  info("Inserting global test rules.");

  info(
    "Add global ruleA which targets an existing banner (presence) with existing buttons. This rule should handle the banner."
  );
  let ruleA = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleA.id = genUUID();
  ruleA.domain = "*";
  ruleA.addClickRule("div#banner", null, "button#optOut", "button#optIn");
  Services.cookieBanners.insertRule(ruleA);

  info(
    "Add global ruleC which targets an existing banner (presence) but non-existing buttons."
  );
  let ruleC = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleC.id = genUUID();
  ruleC.domain = "*";
  ruleC.addClickRule(
    "div#banner",
    null,
    "button#nonExistingOptOut",
    "button#nonExistingOptIn"
  );
  Services.cookieBanners.insertRule(ruleC);

  info("Add global ruleD which targets a non-existing banner (presence).");
  let ruleD = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleD.id = genUUID();
  ruleD.domain = "*";
  ruleD.addClickRule("div#nonExistingBanner", null, null, "button#optIn");
  Services.cookieBanners.insertRule(ruleD);

  info("The global rule ruleA should handle both test pages with div#banner.");
  await openPageAndVerify({
    domain: TEST_DOMAIN_A,
    testURL: TEST_PAGE_A,
    visible: false,
    expected: "OptOut",
  });
  await openPageAndVerify({
    domain: TEST_DOMAIN_B,
    testURL: TEST_PAGE_B,
    visible: false,
    expected: "OptOut",
  });

  info("No global rule should handle TEST_PAGE_C with div#bannerB.");
  await openPageAndVerify({
    domain: TEST_DOMAIN_C,
    testURL: TEST_PAGE_C,
    visible: true,
    expected: "NoClick",
    bannerId: "bannerB",
  });

  info("Test delayed banner handling with global rules.");
  let TEST_PAGE =
    TEST_ORIGIN_A + TEST_PATH + "file_delayed_banner.html?delay=100";
  await openPageAndVerify({
    domain: TEST_DOMAIN_A,
    testURL: TEST_PAGE,
    visible: false,
    expected: "OptOut",
  });
});

/**
 * Test that domain-specific rules take precedence over global rules.
 */
add_task(async function test_clicking_global_rules_precedence() {
  await SpecialPowers.pushPrefEnv({
    set: [
      [
        "cookiebanners.service.mode",
        Ci.nsICookieBannerService.MODE_REJECT_OR_ACCEPT,
      ],
      ["cookiebanners.service.enableGlobalRules", true],
    ],
  });

  info("Clearing existing rules");
  Services.cookieBanners.resetRules(false);

  info("Inserting global test rules.");

  info(
    "Add global ruleA which targets an existing banner (presence) with existing buttons."
  );
  let ruleGlobal = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleGlobal.id = genUUID();
  ruleGlobal.domain = "*";
  ruleGlobal.addClickRule("div#banner", null, "button#optOut", null);
  Services.cookieBanners.insertRule(ruleGlobal);

  info("Add domain specific rule which also targets the existing banner.");
  let ruleDomain = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleDomain.id = genUUID();
  ruleDomain.domain = TEST_DOMAIN_A;
  ruleDomain.addClickRule("div#banner", null, null, "button#optIn");
  Services.cookieBanners.insertRule(ruleDomain);

  info("Test that the domain-specific rule applies, not the global one.");
  await openPageAndVerify({
    domain: TEST_DOMAIN_A,
    testURL: TEST_PAGE_A,
    visible: false,
    // Because of the way the rules are setup OptOut would mean the global rule
    // applies, opt-in means the domain specific rule applies.
    expected: "OptIn",
  });
});
+200 −9
Original line number Diff line number Diff line
@@ -3,6 +3,10 @@

"use strict";

function genUUID() {
  return Services.uuid.generateUUID().number.slice(1, -1);
}

add_setup(async function() {
  registerCleanupFunction(() => {
    Services.prefs.clearUserPref("cookiebanners.service.mode");
@@ -47,6 +51,7 @@ add_task(async function test_enabled_pref() {
  let rule = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  rule.id = genUUID();
  rule.domain = "example.com";

  Assert.throws(
@@ -54,15 +59,15 @@ add_task(async function test_enabled_pref() {
      Services.cookieBanners.insertRule(rule);
    },
    /NS_ERROR_NOT_AVAILABLE/,
    "Should have thrown NS_ERROR_NOT_AVAILABLE for rules insertRule."
    "Should have thrown NS_ERROR_NOT_AVAILABLE for insertRule."
  );

  Assert.throws(
    () => {
      Services.cookieBanners.removeRuleForDomain("example.com");
      Services.cookieBanners.removeRule(rule);
    },
    /NS_ERROR_NOT_AVAILABLE/,
    "Should have thrown NS_ERROR_NOT_AVAILABLE for rules removeRuleForDomain."
    "Should have thrown NS_ERROR_NOT_AVAILABLE for removeRule."
  );

  Assert.throws(
@@ -76,7 +81,7 @@ add_task(async function test_enabled_pref() {
  );
  Assert.throws(
    () => {
      Services.cookieBanners.getClickRuleForDomain("example.com");
      Services.cookieBanners.getClickRulesForDomain("example.com");
    },
    /NS_ERROR_NOT_AVAILABLE/,
    "Should have thrown NS_ERROR_NOT_AVAILABLE for rules getClickRuleForDomain."
@@ -272,7 +277,14 @@ add_task(async function test_insertAndGetRule() {
  is(rule.cookiesOptIn.length, 0, "Should have no opt-in cookies.");

  info("Getting the click rule for example.com.");
  let clickRule = Services.cookieBanners.getClickRuleForDomain("example.com");
  let clickRules = Services.cookieBanners.getClickRulesForDomain("example.com");
  is(
    clickRules.length,
    1,
    "There should be one domain-specific click rule for example.com"
  );
  let [clickRule] = clickRules;

  is(
    clickRule.presence,
    "div#presence",
@@ -301,7 +313,15 @@ add_task(async function test_insertAndGetRule() {
  );

  info("Getting the click rule for example.org.");
  let clickRule2 = Services.cookieBanners.getClickRuleForDomain("example.org");
  let clickRules2 = Services.cookieBanners.getClickRulesForDomain(
    "example.org"
  );
  is(
    clickRules2.length,
    1,
    "There should be one domain-specific click rule for example.org"
  );
  let [clickRule2] = clickRules2;
  is(
    clickRule2.presence,
    "div#presence",
@@ -368,6 +388,7 @@ add_task(async function test_removeRule() {
  let rule = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  rule.id = genUUID();
  rule.domain = "example.com";

  Services.cookieBanners.insertRule(rule);
@@ -375,6 +396,7 @@ add_task(async function test_removeRule() {
  let rule2 = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  rule2.id = genUUID();
  rule2.domain = "example.org";

  Services.cookieBanners.insertRule(rule2);
@@ -386,7 +408,12 @@ add_task(async function test_removeRule() {
  );

  info("Removing rule for non existent example.net");
  Services.cookieBanners.removeRuleForDomain("example.net");
  let ruleExampleNet = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleExampleNet.id = genUUID();
  ruleExampleNet.domain = "example.net";
  Services.cookieBanners.removeRule(ruleExampleNet);

  is(
    Services.cookieBanners.rules.length,
@@ -394,8 +421,22 @@ add_task(async function test_removeRule() {
    "Cookie banner service still has two rules."
  );

  info("Removing rule for non example.com");
  Services.cookieBanners.removeRuleForDomain("example.com");
  info("Removing rule for non existent global rule.");
  let ruleGlobal = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleGlobal.id = genUUID();
  ruleGlobal.domain = "*";
  Services.cookieBanners.removeRule(ruleGlobal);

  is(
    Services.cookieBanners.rules.length,
    2,
    "Cookie banner service still has two rules."
  );

  info("Removing rule for example.com");
  Services.cookieBanners.removeRule(rule);

  is(
    Services.cookieBanners.rules.length,
@@ -497,3 +538,153 @@ add_task(async function test_overwriteRule() {
  // Cleanup.
  Services.cookieBanners.resetRules(false);
});

add_task(async function test_globalRules() {
  info("Enabling cookie banner service with MODE_REJECT");
  await SpecialPowers.pushPrefEnv({
    set: [
      ["cookiebanners.service.mode", Ci.nsICookieBannerService.MODE_REJECT],
      ["cookiebanners.service.enableGlobalRules", true],
    ],
  });

  info("Clear any preexisting rules");
  Services.cookieBanners.resetRules(false);

  is(
    Services.cookieBanners.rules.length,
    0,
    "Cookie banner service has no rules initially."
  );

  info("Insert a site-specific rule for example.com");
  let rule = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  rule.id = genUUID();
  rule.domain = "example.com";
  rule.addCookie(
    true,
    "foo",
    "new",
    "example.com",
    "/",
    3600,
    "",
    false,
    false,
    false,
    0,
    0
  );
  rule.addClickRule("#cookieBannerExample", "#btnOptOut", "#btnOptIn");
  Services.cookieBanners.insertRule(rule);

  info(
    "Insert a global rule with a cookie and a click rule. The cookie rule shouldn't be used."
  );
  let ruleGlobalA = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleGlobalA.id = genUUID();
  ruleGlobalA.domain = "*";
  ruleGlobalA.addCookie(
    true,
    "foo",
    "new",
    "example.net",
    "/",
    3600,
    "",
    false,
    false,
    false,
    0,
    0
  );
  ruleGlobalA.addClickRule("#globalCookieBanner", "#btnOptOut", "#btnOptIn");
  Services.cookieBanners.insertRule(ruleGlobalA);

  info("Insert a second global rule");
  let ruleGlobalB = Cc["@mozilla.org/cookie-banner-rule;1"].createInstance(
    Ci.nsICookieBannerRule
  );
  ruleGlobalB.id = genUUID();
  ruleGlobalB.domain = "*";
  ruleGlobalB.addClickRule("#globalCookieBannerB", "#btnOptOutB", "#btnOptIn");
  Services.cookieBanners.insertRule(ruleGlobalB);

  is(
    Services.cookieBanners.rules.length,
    3,
    "Cookie Banner Service has three rules."
  );

  is(
    Services.cookieBanners.getCookiesForURI(
      Services.io.newURI("http://example.com")
    ).length,
    1,
    "There should be a cookie rule for example.com"
  );

  is(
    Services.cookieBanners.getClickRulesForDomain("example.com").length,
    1,
    "There should be a a click rule for example.com"
  );

  is(
    Services.cookieBanners.getCookiesForURI(
      Services.io.newURI("http://thishasnorule.com")
    ).length,
    0,
    "There should be no cookie rule for thishasnorule.com"
  );

  let clickRules = Services.cookieBanners.getClickRulesForDomain(
    Services.io.newURI("http://thishasnorule.com")
  );
  is(
    clickRules.length,
    2,
    "There should be two click rules for thishasnorule.com"
  );
  ok(
    clickRules.every(rule => rule.presence.startsWith("#globalCookieBanner")),
    "The returned click rules should be global rules."
  );

  info("Disabling global rules");
  await SpecialPowers.pushPrefEnv({
    set: [["cookiebanners.service.enableGlobalRules", false]],
  });

  is(
    Services.cookieBanners.rules.length,
    1,
    "Cookie Banner Service has 1 rule."
  );

  is(
    Services.cookieBanners.rules[0].id,
    rule.id,
    "It should be the domain specific rule"
  );

  is(
    Services.cookieBanners.getCookiesForURI(
      Services.io.newURI("http://thishasnorule.com")
    ).length,
    0,
    "There should be no cookie rule for thishasnorule.com"
  );

  is(
    Services.cookieBanners.getClickRulesForDomain(
      Services.io.newURI("http://thishasnorule.com")
    ).length,
    0,
    "There should be no click rules for thishasnorule.com since global rules are disabled"
  );
});
+22 −0
Original line number Diff line number Diff line
<html>
<head>
  <title>A top-level page with cookie banner</title>
  <script>
    function clickOptOut() {
      document.getElementById("result").textContent = "OptOut";
    }

    function clickOptIn() {
      document.getElementById("result").textContent = "OptIn";
    }
  </script>
</head>
<body>
  <h1>This is the top-level page</h1>
  <div id="bannerB">
    <button id="optOut" onclick="clickOptOut()">OptOut</button>
    <button id="optIn" onclick="clickOptIn()">OptIn</button>
  </div>
  <p id="result">NoClick</p>
</body>
</html>
+48 −18
Original line number Diff line number Diff line
@@ -19,8 +19,12 @@ let rulesInserted = [];
let rulesRemoved = [];
let insertCallback = null;

function genUUID() {
  return Services.uuid.generateUUID().number.slice(1, -1);
}

const RULE_A_ORIGINAL = {
  id: "example.com",
  id: genUUID(),
  click: {
    optOut: "#fooOut",
    presence: "#foobar",
@@ -39,7 +43,7 @@ const RULE_A_ORIGINAL = {
};

const RULE_B = {
  id: "example.org",
  id: genUUID(),
  click: {
    optOut: "#fooOutB",
    presence: "#foobarB",
@@ -57,7 +61,7 @@ const RULE_B = {
};

const RULE_C = {
  id: "example.net",
  id: genUUID(),
  click: {
    optOut: "#fooOutC",
    presence: "#foobarC",
@@ -76,7 +80,7 @@ const RULE_C = {
};

const RULE_A_UPDATED = {
  id: "example.com",
  id: RULE_A_ORIGINAL,
  click: {
    optOut: "#fooOut",
    optIn: "#barIn",
@@ -99,7 +103,7 @@ const RULE_A_UPDATED = {
};

const INVALID_RULE_CLICK = {
  id: "foobar.com",
  id: genUUID(),
  domain: "foobar.com",
  click: {
    presence: 1,
@@ -109,6 +113,26 @@ const INVALID_RULE_CLICK = {

const INVALID_RULE_EMPTY = {};

const RULE_D_GLOBAL = {
  id: genUUID(),
  click: {
    optOut: "#globalOptOutD",
    presence: "#globalBannerD",
  },
  domain: "*",
  cookies: {},
};

const RULE_E_GLOBAL = {
  id: genUUID(),
  click: {
    optOut: "#globalOptOutE",
    presence: "#globalBannerE",
  },
  domain: "*",
  cookies: {},
};

// Testing with RemoteSettings requires a profile.
do_get_profile();

@@ -117,8 +141,8 @@ add_setup(async () => {
  Services.prefs.setStringPref("cookiebanners.listService.logLevel", "Debug");

  // Stub some nsICookieBannerService methods for easy testing.
  let removeRuleForDomain = sinon.stub().callsFake(domain => {
    rulesRemoved.push(domain);
  let removeRule = sinon.stub().callsFake(rule => {
    rulesRemoved.push(rule);
  });

  let insertRule = sinon.stub().callsFake(rule => {
@@ -127,7 +151,7 @@ add_setup(async () => {
  });

  let oldCookieBanners = Services.cookieBanners;
  Services.cookieBanners = { insertRule, removeRuleForDomain, resetRules() {} };
  Services.cookieBanners = { insertRule, removeRule, resetRules() {} };

  // Remove stubs on test end.
  registerCleanupFunction(() => {
@@ -247,10 +271,10 @@ add_task(async function test_remotesettings_sync() {
  await cookieBannerListService.initForTest();

  const payload = {
    current: [RULE_A_ORIGINAL, RULE_C],
    created: [RULE_B],
    current: [RULE_A_ORIGINAL, RULE_C, RULE_D_GLOBAL],
    created: [RULE_B, RULE_E_GLOBAL],
    updated: [{ old: RULE_A_ORIGINAL, new: RULE_A_UPDATED }],
    deleted: [RULE_C],
    deleted: [RULE_C, RULE_D_GLOBAL],
  };

  Assert.equal(rulesInserted.length, 0, "No inserted rules initially.");
@@ -259,12 +283,13 @@ add_task(async function test_remotesettings_sync() {
  info("Dispatching artificial RemoteSettings sync event");
  await RemoteSettings(COLLECTION_NAME).emit("sync", { data: payload });

  Assert.equal(rulesInserted.length, 2, "Two inserted rules after sync.");
  Assert.equal(rulesRemoved.length, 1, "One removed rules after sync.");
  Assert.equal(rulesInserted.length, 3, "Three inserted rules after sync.");
  Assert.equal(rulesRemoved.length, 2, "Two removed rules after sync.");

  let ruleA = rulesInserted.find(rule => rule.domain == RULE_A_UPDATED.domain);
  let ruleB = rulesInserted.find(rule => rule.domain == RULE_B.domain);
  let ruleCDomain = rulesRemoved[0];
  let ruleA = rulesInserted.find(rule => rule.id == RULE_A_UPDATED.id);
  let ruleB = rulesInserted.find(rule => rule.id == RULE_B.id);
  let ruleE = rulesInserted.find(rule => rule.id == RULE_E_GLOBAL.id);
  let ruleC = rulesRemoved[0];

  info("Testing that service inserted updated version of RULE_A.");
  Assert.equal(
@@ -292,8 +317,13 @@ add_task(async function test_remotesettings_sync() {
    );
  }

  Assert.equal(ruleB.domain, RULE_B.domain, "Should have inserted RULE_B");
  Assert.equal(ruleCDomain, RULE_C.domain, "Should have removed RULE_C");
  Assert.equal(ruleB.id, RULE_B.id, "Should have inserted RULE_B");
  Assert.equal(ruleC.id, RULE_C.id, "Should have removed RULE_C");
  Assert.equal(
    ruleE.id,
    RULE_E_GLOBAL.id,
    "Should have inserted RULE_E_GLOBAL"
  );

  // Cleanup
  cookieBannerListService.shutdown();