summaryrefslogtreecommitdiffstats
path: root/toolkit/components/downloads/test/unit/test_DownloadPaths.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/downloads/test/unit/test_DownloadPaths.js')
-rw-r--r--toolkit/components/downloads/test/unit/test_DownloadPaths.js189
1 files changed, 189 insertions, 0 deletions
diff --git a/toolkit/components/downloads/test/unit/test_DownloadPaths.js b/toolkit/components/downloads/test/unit/test_DownloadPaths.js
new file mode 100644
index 0000000000..00fb070669
--- /dev/null
+++ b/toolkit/components/downloads/test/unit/test_DownloadPaths.js
@@ -0,0 +1,189 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Tests for the "DownloadPaths.sys.mjs" JavaScript module.
+ */
+
+function testSanitize(leafName, expectedLeafName, options = {}) {
+ Assert.equal(DownloadPaths.sanitize(leafName, options), expectedLeafName);
+}
+
+function testSplitBaseNameAndExtension(aLeafName, [aBase, aExt]) {
+ var [base, ext] = DownloadPaths.splitBaseNameAndExtension(aLeafName);
+ Assert.equal(base, aBase);
+ Assert.equal(ext, aExt);
+
+ // If we modify the base name and concatenate it with the extension again,
+ // another roundtrip through the function should give a consistent result.
+ // The only exception is when we introduce an extension in a file name that
+ // didn't have one or that ended with one of the special cases like ".gz". If
+ // we avoid using a dot and we introduce at least another special character,
+ // the results are always consistent.
+ [base, ext] = DownloadPaths.splitBaseNameAndExtension("(" + base + ")" + ext);
+ Assert.equal(base, "(" + aBase + ")");
+ Assert.equal(ext, aExt);
+}
+
+function testCreateNiceUniqueFile(aTempFile, aExpectedLeafName) {
+ var createdFile = DownloadPaths.createNiceUniqueFile(aTempFile);
+ Assert.equal(createdFile.leafName, aExpectedLeafName);
+}
+
+add_task(async function test_sanitize() {
+ // Platform-dependent conversion of special characters to spaces.
+ const kSpecialChars = 'A:*?|""<<>>;,+=[]B][=+,;>><<""|?*:C';
+ if (AppConstants.platform == "android") {
+ testSanitize(kSpecialChars, "A B C");
+ testSanitize(" :: Website :: ", "Website");
+ testSanitize("* Website!", "Website!");
+ testSanitize("Website | Page!", "Website Page!");
+ testSanitize("Directory Listing: /a/b/", "Directory Listing _a_b_");
+ } else if (AppConstants.platform == "win") {
+ testSanitize(kSpecialChars, "A ;,+=[]B][=+,; C");
+ testSanitize(" :: Website :: ", "Website");
+ testSanitize("* Website!", "Website!");
+ testSanitize("Website | Page!", "Website Page!");
+ testSanitize("Directory Listing: /a/b/", "Directory Listing _a_b_");
+ } else if (AppConstants.platform == "macosx") {
+ testSanitize(kSpecialChars, "A ;,+=[]B][=+,; C");
+ testSanitize(" :: Website :: ", "Website");
+ testSanitize("* Website!", "Website!");
+ testSanitize("Website | Page!", "Website Page!");
+ testSanitize("Directory Listing: /a/b/", "Directory Listing _a_b_");
+ } else {
+ testSanitize(kSpecialChars, "A ;,+=[]B][=+,; C");
+ testSanitize(" :: Website :: ", "Website");
+ testSanitize("* Website!", "Website!");
+ testSanitize("Website | Page!", "Website Page!");
+ testSanitize("Directory Listing: /a/b/", "Directory Listing _a_b_");
+ }
+
+ // Conversion of consecutive runs of slashes and backslashes to underscores.
+ testSanitize("\\ \\\\Website\\/Page// /", "_ __Website__Page__ _");
+
+ // Removal of leading and trailing whitespace and dots after conversion.
+ testSanitize(" Website ", "Website");
+ testSanitize(". . Website . Page . .", "Website . Page");
+ testSanitize(" File . txt ", "File . txt");
+ testSanitize("\f\n\r\t\v\x00\x1f\x7f\x80\x9f\xa0 . txt", "txt");
+ testSanitize("\u1680\u180e\u2000\u2008\u200a . txt", "txt");
+ testSanitize("\u2028\u2029\u202f\u205f\u3000\ufeff . txt", "txt");
+
+ // Strings with whitespace and dots only.
+ testSanitize(".", "");
+ testSanitize("..", "");
+ testSanitize(" ", "");
+ testSanitize(" . ", "");
+
+ // Stripping of BIDI formatting characters.
+ testSanitize("\u200e \u202b\u202c\u202d\u202etest\x7f\u200f", "_ ____test _");
+ testSanitize("AB\x7f\u202a\x7f\u202a\x7fCD", "AB _ _ CD");
+
+ // Stripping of colons:
+ testSanitize("foo:bar", "foo bar");
+
+ // not compressing whitespaces.
+ testSanitize("foo : bar", "foo bar", { compressWhitespaces: false });
+
+ testSanitize("thing.lnk", "thing.lnk.download");
+ testSanitize("thing.lnk\n", "thing.lnk.download");
+ testSanitize("thing.lnk", "thing.lnk", {
+ allowInvalidFilenames: true,
+ });
+ testSanitize("thing.lnk\n", "thing.lnk", {
+ allowInvalidFilenames: true,
+ });
+ testSanitize("thing.URl", "thing.URl.download");
+ testSanitize("thing.URl \n", "thing.URl", {
+ allowInvalidFilenames: true,
+ });
+
+ testSanitize("thing and more .URl", "thing and more .URl", {
+ allowInvalidFilenames: true,
+ });
+ testSanitize("thing and more .URl ", "thing and more .URl", {
+ compressWhitespaces: false,
+ allowInvalidFilenames: true,
+ });
+
+ testSanitize("thing.local|", "thing.local.download");
+ testSanitize("thing.lo|cal", "thing.lo cal");
+ testSanitize('thing.local/*"', "thing.local_");
+
+ testSanitize("thing.desktoP", "thing.desktoP.download");
+ testSanitize("thing.desktoP \n", "thing.desktoP", {
+ allowInvalidFilenames: true,
+ });
+});
+
+add_task(async function test_splitBaseNameAndExtension() {
+ // Usual file names.
+ testSplitBaseNameAndExtension("base", ["base", ""]);
+ testSplitBaseNameAndExtension("base.ext", ["base", ".ext"]);
+ testSplitBaseNameAndExtension("base.application", ["base", ".application"]);
+ testSplitBaseNameAndExtension("base.x.Z", ["base", ".x.Z"]);
+ testSplitBaseNameAndExtension("base.ext.Z", ["base", ".ext.Z"]);
+ testSplitBaseNameAndExtension("base.ext.gz", ["base", ".ext.gz"]);
+ testSplitBaseNameAndExtension("base.ext.Bz2", ["base", ".ext.Bz2"]);
+ testSplitBaseNameAndExtension("base..ext", ["base.", ".ext"]);
+ testSplitBaseNameAndExtension("base..Z", ["base.", ".Z"]);
+ testSplitBaseNameAndExtension("base. .Z", ["base. ", ".Z"]);
+ testSplitBaseNameAndExtension("base.base.Bz2", ["base.base", ".Bz2"]);
+ testSplitBaseNameAndExtension("base .ext", ["base ", ".ext"]);
+
+ // Corner cases. A name ending with a dot technically has no extension, but
+ // we consider the ending dot separately from the base name so that modifying
+ // the latter never results in an extension being introduced accidentally.
+ // Names beginning with a dot are hidden files on Unix-like platforms and if
+ // their name doesn't contain another dot they should have no extension, but
+ // on Windows the whole name is considered as an extension.
+ testSplitBaseNameAndExtension("base.", ["base", "."]);
+ testSplitBaseNameAndExtension(".ext", ["", ".ext"]);
+
+ // Unusual file names (not recommended as input to the function).
+ testSplitBaseNameAndExtension("base. ", ["base", ". "]);
+ testSplitBaseNameAndExtension("base ", ["base ", ""]);
+ testSplitBaseNameAndExtension("", ["", ""]);
+ testSplitBaseNameAndExtension(" ", [" ", ""]);
+ testSplitBaseNameAndExtension(" . ", [" ", ". "]);
+ testSplitBaseNameAndExtension(" .. ", [" .", ". "]);
+ testSplitBaseNameAndExtension(" .ext", [" ", ".ext"]);
+ testSplitBaseNameAndExtension(" .ext. ", [" .ext", ". "]);
+ testSplitBaseNameAndExtension(" .ext.gz ", [" .ext", ".gz "]);
+});
+
+add_task(async function test_createNiceUniqueFile() {
+ var destDir = FileTestUtils.getTempFile("destdir");
+ destDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
+
+ // Single extension.
+ var tempFile = destDir.clone();
+ tempFile.append("test.txt");
+ testCreateNiceUniqueFile(tempFile, "test.txt");
+ testCreateNiceUniqueFile(tempFile, "test(1).txt");
+ testCreateNiceUniqueFile(tempFile, "test(2).txt");
+
+ // Double extension.
+ tempFile.leafName = "test.tar.gz";
+ testCreateNiceUniqueFile(tempFile, "test.tar.gz");
+ testCreateNiceUniqueFile(tempFile, "test(1).tar.gz");
+ testCreateNiceUniqueFile(tempFile, "test(2).tar.gz");
+
+ // Test automatic shortening of long file names. We don't know exactly how
+ // many characters are removed, because it depends on the name of the folder
+ // where the file is located.
+ tempFile.leafName = new Array(256).join("T") + ".txt";
+ var newFile = DownloadPaths.createNiceUniqueFile(tempFile);
+ Assert.ok(newFile.leafName.length < tempFile.leafName.length);
+ Assert.equal(newFile.leafName.slice(-4), ".txt");
+
+ // Creating a valid file name from an invalid one is not always possible.
+ tempFile.append("file-under-long-directory.txt");
+ try {
+ DownloadPaths.createNiceUniqueFile(tempFile);
+ do_throw("Exception expected with a long parent directory name.");
+ } catch (e) {
+ // An exception is expected, but we don't know which one exactly.
+ }
+});