From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../xpcshell/test_ext_downloads_partitionKey.js | 199 +++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 toolkit/components/extensions/test/xpcshell/test_ext_downloads_partitionKey.js (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_downloads_partitionKey.js') diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_downloads_partitionKey.js b/toolkit/components/extensions/test/xpcshell/test_ext_downloads_partitionKey.js new file mode 100644 index 0000000000..3326ed0ce9 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_downloads_partitionKey.js @@ -0,0 +1,199 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +"use strict"; + +const { Downloads } = ChromeUtils.importESModule( + "resource://gre/modules/Downloads.sys.mjs" +); + +const server = createHttpServer(); +server.registerDirectory("/data/", do_get_file("data")); + +const BASE = `http://localhost:${server.identity.primaryPort}/data`; +const TEST_FILE = "file_download.txt"; +const TEST_URL = BASE + "/" + TEST_FILE; + +// We use different cookieBehaviors so that we can verify if we use the correct +// cookieBehavior if option.incognito is set. Note that we need to set a +// non-default value to the private cookieBehavior because the private +// cookieBehavior will mirror the regular cookieBehavior if the private pref is +// default value and the regular pref is non-default value. To avoid affecting +// the test by mirroring, we set the private cookieBehavior to a non-default +// value. +const TEST_REGULAR_COOKIE_BEHAVIOR = + Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER; +const TEST_PRIVATE_COOKIE_BEHAVIOR = Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN; + +let downloadDir; + +function observeDownloadChannel(uri, partitionKey, isPrivate) { + return new Promise(resolve => { + let observer = { + observe(subject, topic, data) { + if (topic === "http-on-modify-request") { + let httpChannel = subject.QueryInterface(Ci.nsIHttpChannel); + if (httpChannel.URI.spec != uri) { + return; + } + + let reqLoadInfo = httpChannel.loadInfo; + let cookieJarSettings = reqLoadInfo.cookieJarSettings; + + // Check the partitionKey of the cookieJarSettings. + equal( + cookieJarSettings.partitionKey, + partitionKey, + "The loadInfo has the correct paritionKey" + ); + + // Check the cookieBehavior of the cookieJarSettings. + equal( + cookieJarSettings.cookieBehavior, + isPrivate + ? TEST_PRIVATE_COOKIE_BEHAVIOR + : TEST_REGULAR_COOKIE_BEHAVIOR, + "The loadInfo has the correct cookieBehavior" + ); + + Services.obs.removeObserver(observer, "http-on-modify-request"); + resolve(); + } + }, + }; + + Services.obs.addObserver(observer, "http-on-modify-request"); + }); +} + +async function waitForDownloads() { + let list = await Downloads.getList(Downloads.ALL); + let downloads = await list.getAll(); + + let inprogress = downloads.filter(dl => !dl.stopped); + return Promise.all(inprogress.map(dl => dl.whenSucceeded())); +} + +function backgroundScript() { + browser.test.onMessage.addListener(async (msg, ...args) => { + if (msg == "download.request") { + let options = args[0]; + + try { + let id = await browser.downloads.download(options); + browser.test.sendMessage("download.done", { status: "success", id }); + } catch (error) { + browser.test.sendMessage("download.done", { + status: "error", + errmsg: error.message, + }); + } + } + }); + + browser.test.sendMessage("ready"); +} + +// Remove a file in the downloads directory. +function remove(filename, recursive = false) { + let file = downloadDir.clone(); + file.append(filename); + file.remove(recursive); +} + +add_task(function setup() { + downloadDir = FileUtils.getDir("TmpD", ["downloads"]); + downloadDir.createUnique( + Ci.nsIFile.DIRECTORY_TYPE, + FileUtils.PERMS_DIRECTORY + ); + info(`Using download directory ${downloadDir.path}`); + + Services.prefs.setIntPref("browser.download.folderList", 2); + Services.prefs.setComplexValue( + "browser.download.dir", + Ci.nsIFile, + downloadDir + ); + Services.prefs.setBoolPref("privacy.partition.network_state", true); + + Services.prefs.setIntPref( + "network.cookie.cookieBehavior", + TEST_REGULAR_COOKIE_BEHAVIOR + ); + Services.prefs.setIntPref( + "network.cookie.cookieBehavior.pbmode", + TEST_PRIVATE_COOKIE_BEHAVIOR + ); + + registerCleanupFunction(() => { + Services.prefs.clearUserPref("browser.download.folderList"); + Services.prefs.clearUserPref("browser.download.dir"); + Services.prefs.clearUserPref("privacy.partition.network_state"); + Services.prefs.clearUserPref("network.cookie.cookieBehavior"); + Services.prefs.clearUserPref("network.cookie.cookieBehavior.pbmode"); + + let entries = downloadDir.directoryEntries; + while (entries.hasMoreElements()) { + let entry = entries.nextFile; + info(`Leftover file ${entry.path} in download directory`); + ok(false, `Leftover file ${entry.path} in download directory`); + entry.remove(false); + } + + downloadDir.remove(false); + }); +}); + +add_task(async function test() { + let extension = ExtensionTestUtils.loadExtension({ + background: `(${backgroundScript})()`, + manifest: { + permissions: ["downloads"], + }, + incognitoOverride: "spanning", + }); + + function download(options) { + extension.sendMessage("download.request", options); + return extension.awaitMessage("download.done"); + } + + async function testDownload(url, partitionKey, isPrivate) { + let options = { url, incognito: isPrivate }; + + let promiseObserveDownloadChannel = observeDownloadChannel( + url, + partitionKey, + isPrivate + ); + + let msg = await download(options); + equal(msg.status, "success", `downloads.download() works`); + + await promiseObserveDownloadChannel; + await waitForDownloads(); + } + + await extension.startup(); + await extension.awaitMessage("ready"); + info("extension started"); + + // Call download() to check partitionKey of the download channel for the + // regular browsing mode. + await testDownload( + TEST_URL, + `(http,localhost,${server.identity.primaryPort})`, + false + ); + remove(TEST_FILE); + + // Call download again for the private browsing mode. + await testDownload( + TEST_URL, + `(http,localhost,${server.identity.primaryPort})`, + true + ); + remove(TEST_FILE); + + await extension.unload(); +}); -- cgit v1.2.3