From 45c3a7524e6fd8f2556f191af2f033111c76dd4b Mon Sep 17 00:00:00 2001 From: Rob Wu Date: Fri, 14 Jul 2017 17:14:18 +0200 Subject: [PATCH] Bug 1362448 - Support "incognito" in downloads.create r=aswan MozReview-Commit-ID: HN3x6eFT9xB --HG-- extra : rebase_source : 304d5317dc950a90c63d1f46b3f42f68d0d9927a --- .../components/extensions/ext-downloads.js | 1 + .../extensions/schemas/downloads.json | 6 + .../xpcshell/test_ext_downloads_download.js | 11 ++ .../xpcshell/test_ext_downloads_private.js | 116 ++++++++++++++++++ .../test/xpcshell/xpcshell-common.ini | 2 + 5 files changed, 136 insertions(+) create mode 100644 toolkit/components/extensions/test/xpcshell/test_ext_downloads_private.js diff --git a/toolkit/components/extensions/ext-downloads.js b/toolkit/components/extensions/ext-downloads.js index 1615d2bb6f92..b018ce6e9978 100644 --- a/toolkit/components/extensions/ext-downloads.js +++ b/toolkit/components/extensions/ext-downloads.js @@ -527,6 +527,7 @@ this.downloads = class extends ExtensionAPI { .then(target => { const source = { url: options.url, + isPrivate: options.incognito, }; if (options.method || options.headers || options.body) { diff --git a/toolkit/components/extensions/schemas/downloads.json b/toolkit/components/extensions/schemas/downloads.json index 422a4444db13..3e89ca66d369 100644 --- a/toolkit/components/extensions/schemas/downloads.json +++ b/toolkit/components/extensions/schemas/downloads.json @@ -377,6 +377,12 @@ "optional": true, "type": "string" }, + "incognito": { + "description": "Whether to associate the download with a private browsing session.", + "optional": true, + "default": false, + "type": "boolean" + }, "conflictAction": { "$ref": "FilenameConflictAction", "optional": true diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_downloads_download.js b/toolkit/components/extensions/test/xpcshell/test_ext_downloads_download.js index 2e20d4f9e4a9..02527627c96c 100644 --- a/toolkit/components/extensions/test/xpcshell/test_ext_downloads_download.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_downloads_download.js @@ -266,6 +266,17 @@ add_task(async function test_downloads() { url: BASE + "dir/", }, "download", 8, "normal url with empty filename"); + // Check that the "incognito" property is supported. + await testDownload({ + url: FILE_URL, + incognito: false, + }, FILE_NAME, FILE_LEN, "incognito=false"); + + await testDownload({ + url: FILE_URL, + incognito: true, + }, FILE_NAME, FILE_LEN, "incognito=true"); + await extension.unload(); }); diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_downloads_private.js b/toolkit/components/extensions/test/xpcshell/test_ext_downloads_private.js new file mode 100644 index 000000000000..a965a6c69003 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_downloads_private.js @@ -0,0 +1,116 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +"use strict"; + +Cu.import("resource://gre/modules/Downloads.jsm"); + +const server = createHttpServer(); +server.registerDirectory("/data/", do_get_file("data")); + +const BASE = `http://localhost:${server.identity.primaryPort}/data`; +const TXT_FILE = "file_download.txt"; +const TXT_URL = BASE + "/" + TXT_FILE; + +function setup() { + let downloadDir = FileUtils.getDir("TmpD", ["downloads"]); + downloadDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); + do_print(`Using download directory ${downloadDir.path}`); + + Services.prefs.setIntPref("browser.download.folderList", 2); + Services.prefs.setComplexValue("browser.download.dir", Ci.nsIFile, downloadDir); + + do_register_cleanup(() => { + Services.prefs.clearUserPref("browser.download.folderList"); + Services.prefs.clearUserPref("browser.download.dir"); + + let entries = downloadDir.directoryEntries; + while (entries.hasMoreElements()) { + let entry = entries.getNext().QueryInterface(Ci.nsIFile); + ok(false, `Leftover file ${entry.path} in download directory`); + entry.remove(false); + } + + downloadDir.remove(false); + }); +} + +add_task(async function test_private_download() { + setup(); + + let extension = ExtensionTestUtils.loadExtension({ + background: async function() { + function promiseEvent(eventTarget, accept) { + return new Promise(resolve => { + eventTarget.addListener(function listener(data) { + if (accept && !accept(data)) { + return; + } + eventTarget.removeListener(listener); + resolve(data); + }); + }); + } + let startTestPromise = promiseEvent(browser.test.onMessage); + let onCreatedPromise = promiseEvent(browser.downloads.onCreated); + let onDonePromise = promiseEvent(browser.downloads.onChanged, + delta => delta.state && delta.state.current === "complete"); + + browser.test.sendMessage("ready"); + let {url, filename} = await startTestPromise; + + browser.test.log("Starting private download"); + let downloadId = await browser.downloads.download({ + url, + filename, + incognito: true, + }); + + browser.test.log("Waiting for downloads.onCreated"); + let createdItem = await onCreatedPromise; + + browser.test.log("Waiting for completion notification"); + await onDonePromise; + + // test_ext_downloads_download.js already tests whether the file exists + // in the file system. Here we will only verify that the downloads API + // behaves in a meaningful way. + + let [downloadItem] = await browser.downloads.search({id: downloadId}); + browser.test.assertEq(url, createdItem.url, "onCreated url should match"); + browser.test.assertEq(url, downloadItem.url, "download url should match"); + browser.test.assertTrue(createdItem.incognito, + "created download should be private"); + browser.test.assertTrue(downloadItem.incognito, + "stored download should be private"); + + browser.test.log("Removing downloaded file"); + browser.test.assertTrue(downloadItem.exists, "downloaded file exists"); + await browser.downloads.removeFile(downloadId); + + // Disabled because the assertion fails - https://bugzil.la/1381031 + // let [downloadItem2] = await browser.downloads.search({id: downloadId}); + // browser.test.assertFalse(downloadItem2.exists, "file should be deleted"); + + browser.test.log("Erasing private download from history"); + let erasePromise = promiseEvent(browser.downloads.onErased); + await browser.downloads.erase({id: downloadId}); + browser.test.assertEq(downloadId, await erasePromise, + "onErased should be fired for the erased private download"); + + browser.test.notifyPass("private download test done"); + }, + manifest: { + permissions: ["downloads"], + }, + }); + + await extension.startup(); + await extension.awaitMessage("ready"); + extension.sendMessage({ + url: TXT_URL, + filename: TXT_FILE, + }); + + await extension.awaitFinish("private download test done"); + await extension.unload(); +}); diff --git a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini index f016213538be..364b716eeb1b 100644 --- a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini +++ b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini @@ -22,6 +22,8 @@ skip-if = os == "android" # Containers are not exposed to android. skip-if = os == "android" [test_ext_downloads_misc.js] skip-if = os == "android" || (os=='linux' && bits==32) # linux32: bug 1324870 +[test_ext_downloads_private.js] +skip-if = os == "android" [test_ext_downloads_search.js] skip-if = os == "android" [test_ext_experiments.js]