summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html')
-rw-r--r--toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html259
1 files changed, 259 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html b/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html
new file mode 100644
index 0000000000..4b5d90814c
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html
@@ -0,0 +1,259 @@
+<!doctype html>
+<html>
+<head>
+ <title>Test downloads.download() saveAs option</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="chrome://mochikit/content/tests/SimpleTest/ExtensionTestUtils.js"></script>
+ <script src="head.js"></script>
+ <link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body>
+
+<script type="text/javascript">
+"use strict";
+
+const {FileUtils} = ChromeUtils.importESModule(
+ "resource://gre/modules/FileUtils.sys.mjs"
+);
+
+const PROMPTLESS_DOWNLOAD_PREF = "browser.download.useDownloadDir";
+
+const DOWNLOAD_FILENAME = "file_download.nonext.txt";
+const DEFAULT_SUBDIR = "subdir";
+
+// We need to be able to distinguish files downloaded by the file picker from
+// files downloaded without it.
+let pickerDir;
+let pbPickerDir; // for incognito downloads
+let defaultDir;
+
+add_task(async function setup() {
+ // Reset DownloadLastDir preferences in case other tests set them.
+ SpecialPowers.Services.obs.notifyObservers(
+ null,
+ "browser:purge-session-history"
+ );
+
+ // Set up temporary directories.
+ let downloadDir = FileUtils.getDir("TmpD", ["downloads"]);
+ pickerDir = downloadDir.clone();
+ pickerDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
+ info(`Using file picker download directory ${pickerDir.path}`);
+ pbPickerDir = downloadDir.clone();
+ pbPickerDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
+ info(`Using private browsing file picker download directory ${pbPickerDir.path}`);
+ defaultDir = downloadDir.clone();
+ defaultDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
+ info(`Using default download directory ${defaultDir.path}`);
+ let subDir = defaultDir.clone();
+ subDir.append(DEFAULT_SUBDIR);
+ subDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
+
+ isnot(pickerDir.path, defaultDir.path,
+ "Should be able to distinguish between files saved with or without the file picker");
+ isnot(pickerDir.path, pbPickerDir.path,
+ "Should be able to distinguish between files saved in and out of private browsing mode");
+
+ await SpecialPowers.pushPrefEnv({"set": [
+ ["browser.download.folderList", 2],
+ ["browser.download.dir", defaultDir.path],
+ ]});
+
+ SimpleTest.registerCleanupFunction(async () => {
+ await SpecialPowers.popPrefEnv();
+ pickerDir.remove(true);
+ pbPickerDir.remove(true);
+ defaultDir.remove(true); // This also removes DEFAULT_SUBDIR.
+ });
+});
+
+add_task(async function test_downloads_saveAs() {
+ const pickerFile = pickerDir.clone();
+ pickerFile.append(DOWNLOAD_FILENAME);
+
+ const pbPickerFile = pbPickerDir.clone();
+ pbPickerFile.append(DOWNLOAD_FILENAME);
+
+ const defaultFile = defaultDir.clone();
+ defaultFile.append(DOWNLOAD_FILENAME);
+
+ const {MockFilePicker} = SpecialPowers;
+ MockFilePicker.init(window);
+
+ function mockFilePickerCallback(expectedStartingDir, pickedFile) {
+ return fp => {
+ // Assert that the downloads API correctly sets the starting directory.
+ ok(fp.displayDirectory.equals(expectedStartingDir), "Got the expected FilePicker displayDirectory");
+
+ // Assert that the downloads API configures both default properties.
+ is(fp.defaultString, DOWNLOAD_FILENAME, "Got the expected FilePicker defaultString");
+ is(fp.defaultExtension, "txt", "Got the expected FilePicker defaultExtension");
+
+ MockFilePicker.setFiles([pickedFile]);
+ };
+ }
+
+ function background() {
+ const url = URL.createObjectURL(new Blob(["file content"]));
+ browser.test.onMessage.addListener(async (filename, saveAs, isPrivate) => {
+ try {
+ let options = {
+ url,
+ filename,
+ incognito: isPrivate,
+ };
+ // Only define the saveAs option if the argument was actually set
+ if (saveAs !== undefined) {
+ options.saveAs = saveAs;
+ }
+ let id = await browser.downloads.download(options);
+ browser.downloads.onChanged.addListener(delta => {
+ if (delta.id == id && delta.state.current === "complete") {
+ browser.test.sendMessage("done", {ok: true, id});
+ }
+ });
+ } catch ({message}) {
+ browser.test.sendMessage("done", {ok: false, message});
+ }
+ });
+ browser.test.sendMessage("ready");
+ }
+
+ const manifest = {
+ background,
+ incognitoOverride: "spanning",
+ manifest: {permissions: ["downloads"]},
+ };
+ const extension = ExtensionTestUtils.loadExtension(manifest);
+
+ await extension.startup();
+ await extension.awaitMessage("ready");
+
+ // options should have the following properties:
+ // saveAs (Boolean or undefined)
+ // isPrivate (Boolean)
+ // fileName (string)
+ // expectedStartingDir (nsIFile)
+ // destinationFile (nsIFile)
+ async function testExpectFilePicker(options) {
+ ok(!options.destinationFile.exists(), "the file should have been cleaned up properly previously");
+
+ MockFilePicker.showCallback = mockFilePickerCallback(
+ options.expectedStartingDir,
+ options.destinationFile
+ );
+ MockFilePicker.returnValue = MockFilePicker.returnOK;
+
+ extension.sendMessage(options.fileName, options.saveAs, options.isPrivate);
+ let result = await extension.awaitMessage("done");
+ ok(result.ok, `downloads.download() works with saveAs=${options.saveAs}`);
+
+ ok(options.destinationFile.exists(), "the file exists.");
+ is(options.destinationFile.fileSize, 12, "downloaded file is the correct size");
+ options.destinationFile.remove(false);
+ MockFilePicker.reset();
+
+ // Test the user canceling the save dialog.
+ MockFilePicker.returnValue = MockFilePicker.returnCancel;
+
+ extension.sendMessage(options.fileName, options.saveAs, options.isPrivate);
+ result = await extension.awaitMessage("done");
+
+ ok(!result.ok, "download rejected if the user cancels the dialog");
+ is(result.message, "Download canceled by the user", "with the correct message");
+ ok(!options.destinationFile.exists(), "file was not downloaded");
+ MockFilePicker.reset();
+ }
+
+ async function testNoFilePicker(saveAs) {
+ ok(!defaultFile.exists(), "the file should have been cleaned up properly previously");
+
+ extension.sendMessage(DOWNLOAD_FILENAME, saveAs, false);
+ let result = await extension.awaitMessage("done");
+ ok(result.ok, `downloads.download() works with saveAs=${saveAs}`);
+
+ ok(defaultFile.exists(), "the file exists.");
+ is(defaultFile.fileSize, 12, "downloaded file is the correct size");
+ defaultFile.remove(false);
+ }
+
+ info("Testing that saveAs=true uses the file picker as expected");
+ let expectedStartingDir = defaultDir;
+ let fpOptions = {
+ saveAs: true,
+ isPrivate: false,
+ fileName: DOWNLOAD_FILENAME,
+ expectedStartingDir: expectedStartingDir,
+ destinationFile: pickerFile,
+ };
+ await testExpectFilePicker(fpOptions);
+
+ info("Testing that saveas=true reuses last file picker directory");
+ fpOptions.expectedStartingDir = pickerDir;
+ await testExpectFilePicker(fpOptions);
+
+ info("Testing that saveAs=true in PB reuses last directory");
+ let nonPBStartingDir = fpOptions.expectedStartingDir;
+ fpOptions.isPrivate = true;
+ fpOptions.destinationFile = pbPickerFile;
+ await testExpectFilePicker(fpOptions);
+
+ info("Testing that saveAs=true in PB uses a separate last directory");
+ fpOptions.expectedStartingDir = pbPickerDir;
+ await testExpectFilePicker(fpOptions);
+
+ info("Testing that saveAs=true in Permanent PB mode ignores the incognito option");
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.privatebrowsing.autostart", true]],
+ });
+ fpOptions.isPrivate = false;
+ fpOptions.expectedStartingDir = pbPickerDir;
+ await testExpectFilePicker(fpOptions);
+
+ info("Testing that saveas=true reuses the non-PB last directory after private download");
+ await SpecialPowers.popPrefEnv();
+ fpOptions.isPrivate = false;
+ fpOptions.expectedStartingDir = nonPBStartingDir;
+ fpOptions.destinationFile = pickerFile;
+ await testExpectFilePicker(fpOptions);
+
+ info("Testing that saveAs=true does not reuse last directory when filename contains a path separator");
+ fpOptions.fileName = DEFAULT_SUBDIR + "/" + DOWNLOAD_FILENAME;
+ let destinationFile = defaultDir.clone();
+ destinationFile.append(DEFAULT_SUBDIR);
+ fpOptions.expectedStartingDir = destinationFile.clone();
+ destinationFile.append(DOWNLOAD_FILENAME);
+ fpOptions.destinationFile = destinationFile;
+ await testExpectFilePicker(fpOptions);
+
+ info("Testing that saveAs=false does not use the file picker");
+ fpOptions.saveAs = false;
+ await testNoFilePicker(fpOptions.saveAs);
+
+ // When saveAs is not set, the behavior should be determined by the Firefox
+ // pref that normally determines whether the "Save As" prompt should be
+ // displayed.
+ info(`Testing that the file picker is used when saveAs is not specified ` +
+ `but ${PROMPTLESS_DOWNLOAD_PREF} is disabled`);
+ fpOptions.saveAs = undefined;
+ await SpecialPowers.pushPrefEnv({"set": [
+ [PROMPTLESS_DOWNLOAD_PREF, false],
+ ]});
+ await testExpectFilePicker(fpOptions);
+
+ info(`Testing that the file picker is NOT used when saveAs is not ` +
+ `specified but ${PROMPTLESS_DOWNLOAD_PREF} is enabled`);
+ await SpecialPowers.popPrefEnv();
+ await SpecialPowers.pushPrefEnv({"set": [
+ [PROMPTLESS_DOWNLOAD_PREF, true],
+ ]});
+ await testNoFilePicker(fpOptions.saveAs);
+
+ await extension.unload();
+ MockFilePicker.cleanup();
+});
+
+</script>
+
+</body>
+</html>