Bug 1541449 - storage.local API should fire onChanged event when falsey values are removed. r=mixedpuppy a=pascalc
authorLuca Greco <lgreco@mozilla.com>
Thu, 04 Apr 2019 12:06:44 +0000
changeset 523161 8f56f6681da40857faa243da02f4d1fcb1dfaf2d
parent 523160 37c5083230c5128f5c66ed88549e4471572d0e18
child 523162 afc3ac77b7750eae6581dae4cdf65b0678e8bea2
push id11081
push userapavel@mozilla.com
push dateSat, 13 Apr 2019 23:59:06 +0000
treeherdermozilla-beta@d9a704ef4623 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmixedpuppy, pascalc
bugs1541449
milestone67.0
Bug 1541449 - storage.local API should fire onChanged event when falsey values are removed. r=mixedpuppy a=pascalc Differential Revision: https://phabricator.services.mozilla.com/D25949
toolkit/components/extensions/ExtensionStorageIDB.jsm
toolkit/components/extensions/test/xpcshell/test_ext_storage.js
--- a/toolkit/components/extensions/ExtensionStorageIDB.jsm
+++ b/toolkit/components/extensions/ExtensionStorageIDB.jsm
@@ -283,26 +283,29 @@ class ExtensionStorageLocalIDB extends I
       return null;
     }
 
     const changes = {};
     let changed = false;
 
     const objectStore = this.objectStore(IDB_DATA_STORENAME, "readwrite");
 
-    for (let key of keys) {
-      let oldValue = await objectStore.get(key);
-      changes[key] = {oldValue};
+    let promises = [];
 
-      if (oldValue) {
-        changed = true;
-      }
+    for (let key of keys) {
+      promises.push(objectStore.getKey(key).then(async foundKey => {
+        if (foundKey === key) {
+          changed = true;
+          changes[key] = {oldValue: await objectStore.get(key)};
+          return objectStore.delete(key);
+        }
+      }));
+    }
 
-      await objectStore.delete(key);
-    }
+    await Promise.all(promises);
 
     return changed ? changes : null;
   }
 
   /**
    * Asynchronously clears all storage entries.
    *
    * @returns {Promise<Object>}
--- a/toolkit/components/extensions/test/xpcshell/test_ext_storage.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_storage.js
@@ -269,16 +269,43 @@ async function test_background_page_stor
           areaName,
           {"test-prop1": {oldValue: "value1"}, "test-prop2": {oldValue: "value2"}},
           "remove array");
 
         data = await storage.get(["test-prop1", "test-prop2"]);
         browser.test.assertFalse("test-prop1" in data, "prop1 absent (remove array)");
         browser.test.assertFalse("test-prop2" in data, "prop2 absent (remove array)");
 
+        // Test that removing a falsey value fires the onChanged event.
+        await storage.set({
+          "test-falsey-value-bool": false,
+          "test-falsey-value-string": "",
+          "test-falsey-value-number": 0,
+        });
+        await checkChanges(
+          areaName,
+          {
+            "test-falsey-value-bool": {newValue: false},
+            "test-falsey-value-string": {newValue: ""},
+            "test-falsey-value-number": {newValue: 0},
+          },
+          "set falsey values");
+
+        await storage.remove([
+          "test-falsey-value-bool", "test-falsey-value-string", "test-falsey-value-number",
+        ]);
+        await checkChanges(
+          areaName,
+          {
+            "test-falsey-value-bool": {oldValue: false},
+            "test-falsey-value-string": {oldValue: ""},
+            "test-falsey-value-number": {oldValue: 0},
+          },
+          "remove falsey value");
+
         // test storage.clear
         await storage.set({"test-prop1": "value1", "test-prop2": "value2"});
         // Make sure that set() handler happened before we clear the
         // promise again.
         await globalChanges;
 
         clearGlobalChanges();
         await storage.clear();