bug 1245644 add chrome.downloads.removeFile r?kmag draft
authorStuart Colville <scolville@mozilla.com>
Mon, 14 Mar 2016 16:22:24 +0100
changeset 342849 dce43bb20d12fc9a748c3b8551f364030639fb8e
parent 341573 77258bd00fa310a72fc0de17c9b51cf9a2f96fd2
child 516632 d0b8869731eca1e3b9088d7847e05209cd2f2e62
push id13468
push userbmo:scolville@mozilla.com
push dateMon, 21 Mar 2016 12:33:12 +0000
reviewerskmag
bugs1245644
milestone48.0a1
bug 1245644 add chrome.downloads.removeFile r?kmag MozReview-Commit-ID: 4picapXsv2x
toolkit/components/extensions/ext-downloads.js
toolkit/components/extensions/schemas/downloads.json
toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_misc.html
--- a/toolkit/components/extensions/ext-downloads.js
+++ b/toolkit/components/extensions/ext-downloads.js
@@ -469,16 +469,33 @@ extensions.registerSchemaAPI("downloads"
             download.tryToKeepPartialData = true;
             download.start();
 
             const item = DownloadMap.newFromDownload(download, extension);
             return item.id;
           });
       },
 
+      removeFile(id) {
+        return DownloadMap.lazyInit().then(() => {
+          let item;
+          try {
+            item = DownloadMap.fromId(id);
+          } catch (err) {
+            return Promise.reject({message: `Invalid download id ${id}`});
+          }
+          if (item.state !== "complete") {
+            return Promise.reject({message: `Cannot remove incomplete download id ${id}`});
+          }
+          return OS.File.remove(item.filename, {ignoreAbsent: false}).catch((err) => {
+            return Promise.reject({message: `Could not remove download id ${item.id} because the file doesn't exist`});
+          });
+        });
+      },
+
       search(query) {
         return queryHelper(query)
           .then(items => items.map(item => item.serialize()));
       },
 
       pause(id) {
         return DownloadMap.lazyInit().then(() => {
           let item = DownloadMap.fromId(id);
--- a/toolkit/components/extensions/schemas/downloads.json
+++ b/toolkit/components/extensions/schemas/downloads.json
@@ -605,18 +605,18 @@
                 "type": "array"
               }
             ]
           }
         ]
       },
       {
         "name": "removeFile",
+        "async": "callback",
         "type": "function",
-        "unsupported": true,
         "parameters": [
           {
             "name": "downloadId",
             "type": "integer"
           },
           {
             "name": "callback",
             "type": "function",
--- a/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_misc.html
+++ b/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_misc.html
@@ -460,16 +460,135 @@ add_task(function* test_pausecancel() {
   is(msg.result[0].state, "interrupted", "download.state is correct");
   is(msg.result[0].paused, false, "download.paused is correct");
   is(msg.result[0].canResume, false, "download.canResume is correct");
   is(msg.result[0].error, "USER_CANCELED", "download.error is correct");
   is(msg.result[0].totalBytes, INT_TOTAL_LEN, "download.totalBytes is correct");
   is(msg.result[0].exists, false, "download.exists is correct");
 });
 
+add_task(function* test_file_removal() {
+  let msg = yield runInExtension("download", {url: TXT_URL});
+  is(msg.status, "success", "download() succeeded");
+  const id = msg.result;
+
+  msg = yield runInExtension("waitForEvents", [
+    {type: "onCreated", data: {id, url: TXT_URL}},
+    {
+      type: "onChanged",
+      data: {
+        id,
+        state: {
+          previous: "in_progress",
+          current: "complete",
+        },
+      },
+    },
+  ]);
+
+  is(msg.status, "success", "got onCreated and onChanged events");
+
+  msg = yield runInExtension("removeFile", id);
+  is(msg.status, "success", "removeFile() succeeded");
+
+  msg = yield runInExtension("removeFile", id);
+  is(msg.status, "error", "removeFile() fails since the file was already removed.");
+  ok(/file doesn't exist/.test(msg.errmsg), "removeFile() failed on removed file.");
+
+  msg = yield runInExtension("removeFile", 1000);
+  ok(/Invalid download id/.test(msg.errmsg), "removeFile() failed due to non-existent id");
+});
+
+add_task(function* test_removal_of_incomplete_download() {
+  let msg = yield runInExtension("download", {url: INTERRUPTIBLE_URL});
+  is(msg.status, "success", "download() succeeded");
+  const id = msg.result;
+
+  let progressPromise = waitForProgress(INTERRUPTIBLE_URL, INT_PARTIAL_LEN);
+
+  msg = yield runInExtension("waitForEvents", [
+    {type: "onCreated", data: {id}},
+  ]);
+  is(msg.status, "success", "got created and changed events");
+
+  yield progressPromise;
+  info(`download reached ${INT_PARTIAL_LEN} bytes`);
+
+  msg = yield runInExtension("pause", id);
+  is(msg.status, "success", "pause() succeeded");
+
+  msg = yield runInExtension("waitForEvents", [
+    {
+      type: "onChanged",
+      data: {
+        id,
+        state: {
+          previous: "in_progress",
+          current: "interrupted",
+        },
+        paused: {
+          previous: false,
+          current: true,
+        },
+        canResume: {
+          previous: false,
+          current: true,
+        },
+      },
+    }]);
+  is(msg.status, "success", "got onChanged event corresponding to pause");
+
+  msg = yield runInExtension("removeFile", id);
+  is(msg.status, "error", "removeFile() on paused download failed");
+
+  ok(/Cannot remove incomplete download/.test(msg.errmsg), "removeFile() failed due to download being incomplete");
+
+  msg = yield runInExtension("resume", id);
+  is(msg.status, "success", "resume() succeeded");
+
+  msg = yield runInExtension("waitForEvents", [
+    {
+      type: "onChanged",
+      data: {
+        id,
+        state: {
+          previous: "interrupted",
+          current: "in_progress",
+        },
+        paused: {
+          previous: true,
+          current: false,
+        },
+        canResume: {
+          previous: true,
+          current: false,
+        },
+        error: {
+          previous: "USER_CANCELED",
+          current: null,
+        },
+      },
+    },
+    {
+      type: "onChanged",
+      data: {
+        id,
+        state: {
+          previous: "in_progress",
+          current: "complete",
+        },
+      },
+    },
+  ]);
+  is(msg.status, "success", "got onChanged events for resume and complete");
+
+  msg = yield runInExtension("removeFile", id);
+  is(msg.status, "success", "removeFile() succeeded following completion of resumed download.");
+});
+
 // Test erase().  We don't do elaborate testing of the query handling
 // since it uses the exact same engine as search() which is tested
 // more thoroughly in test_chrome_ext_downloads_search.html
 add_task(function* test_erase() {
   yield clearDownloads();
 
   let ids = {};
   let msg = yield runInExtension("download", {url: TXT_URL});