summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/xpcshell/test_ext_dnr_private_browsing.js
blob: e9e7f90b0148e462b8fecc21858949ece72470a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"use strict";

const server = createHttpServer({ hosts: ["example.com"] });
server.registerPathHandler("/", (req, res) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader("Access-Control-Max-Age", "0");
});

add_setup(() => {
  Services.prefs.setBoolPref("extensions.manifestV3.enabled", true);
  Services.prefs.setBoolPref("extensions.dnr.enabled", true);
});

async function startDNRExtension({ privateBrowsingAllowed }) {
  let extension = ExtensionTestUtils.loadExtension({
    incognitoOverride: privateBrowsingAllowed ? "spanning" : undefined,
    async background() {
      await browser.declarativeNetRequest.updateSessionRules({
        addRules: [{ id: 1, condition: {}, action: { type: "block" } }],
      });
      browser.test.sendMessage("dnr_registered");
    },
    manifest: {
      manifest_version: 3,
      permissions: ["declarativeNetRequest"],
      browser_specific_settings: { gecko: { id: "@dnr-ext" } },
    },
  });
  await extension.startup();
  await extension.awaitMessage("dnr_registered");
  return extension;
}

async function testMatchedByDNR(privateBrowsing) {
  let contentPage = await ExtensionTestUtils.loadContentPage(
    "http://example.com/?page",
    { privateBrowsing }
  );
  let wasRequestBlocked = await contentPage.legacySpawn(null, async () => {
    try {
      await content.fetch("http://example.com/?fetch");
      return false;
    } catch (e) {
      // Request blocked by DNR rule from startDNRExtension().
      return true;
    }
  });
  await contentPage.close();
  return wasRequestBlocked;
}

add_task(async function private_browsing_not_allowed_by_default() {
  let extension = await startDNRExtension({ privateBrowsingAllowed: false });
  Assert.equal(
    await testMatchedByDNR(false),
    true,
    "DNR applies to non-private browsing requests by default"
  );
  Assert.equal(
    await testMatchedByDNR(true),
    false,
    "DNR not applied to private browsing requests by default"
  );
  await extension.unload();
});

add_task(async function private_browsing_allowed() {
  let extension = await startDNRExtension({ privateBrowsingAllowed: true });
  Assert.equal(
    await testMatchedByDNR(false),
    true,
    "DNR applies to non-private requests regardless of privateBrowsingAllowed"
  );
  Assert.equal(
    await testMatchedByDNR(true),
    true,
    "DNR applied to private browsing requests when privateBrowsingAllowed"
  );
  await extension.unload();
});

add_task(
  { pref_set: [["extensions.dnr.feedback", true]] },
  async function testMatchOutcome_unaffected_by_privateBrowsing() {
    let extensionWithoutPrivateBrowsingAllowed = await startDNRExtension({});
    let extension = ExtensionTestUtils.loadExtension({
      incognitoOverride: "spanning",
      manifest: {
        manifest_version: 3,
        permissions: ["declarativeNetRequest", "declarativeNetRequestFeedback"],
      },
      files: {
        "page.html": `<!DOCTYPE html><script src="page.js"></script>`,
        "page.js": async () => {
          browser.test.assertTrue(
            browser.extension.inIncognitoContext,
            "Extension page is opened in a private browsing context"
          );
          browser.test.assertDeepEq(
            {
              matchedRules: [
                { ruleId: 1, rulesetId: "_session", extensionId: "@dnr-ext" },
              ],
            },
            // testMatchOutcome does not offer a way to specify the private
            // browsing mode of a request. Confirm that testMatchOutcome always
            // simulates requests in normal private browsing mode, even if the
            // testMatchOutcome method itself is called from an extension page
            // in private browsing mode.
            await browser.declarativeNetRequest.testMatchOutcome(
              { url: "http://example.com/?simulated_request", type: "image" },
              { includeOtherExtensions: true }
            ),
            "testMatchOutcome includes DNR from extensions without pbm access"
          );
          browser.test.sendMessage("done");
        },
      },
    });
    await extension.startup();
    let contentPage = await ExtensionTestUtils.loadContentPage(
      `moz-extension://${extension.uuid}/page.html`,
      { privateBrowsing: true }
    );
    await extension.awaitMessage("done");
    await contentPage.close();
    await extension.unload();
    await extensionWithoutPrivateBrowsingAllowed.unload();
  }
);