Delete special label field values when removing labels

Currently, PG only removes the matching vote from the `all` property
when removing a label via the change-metadata. This was causing issues
with Commit Queue, which expected the special field to properly
correspond to the votes in `all` (e.g. `recommended`, `approved`).

Now, we iterate over the properties of the label and remove the
applicable special field corresponding to the account ID of the vote
that was removed.

Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=713194
Change-Id: I7009d09741e4ee722ca03b495c56a08c57da3fab
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
index 8435692..58938af 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
@@ -196,16 +196,24 @@
       this._xhrPromise =
           this.$.restAPI.deleteVote(this.change.id, accountID, labelName)
           .then(function(response) {
-        if (!response.ok) { return response; }
-
-        var labels = this.change.labels[labelName].all || [];
-        for (var i = 0; i < labels.length; i++) {
-          if (labels[i]._account_id === accountID) {
-            this.splice(['change.labels', labelName, 'all'], i, 1);
-            break;
-          }
-        }
-      }.bind(this));
+            if (!response.ok) { return response; }
+            var label = this.change.labels[labelName];
+            var labels = label.all || [];
+            for (var i = 0; i < labels.length; i++) {
+              if (labels[i]._account_id === accountID) {
+                for (var key in label) {
+                  if (label.hasOwnProperty(key) &&
+                      label[key]._account_id === accountID) {
+                    // Remove special label field, keeping change label values
+                    // in sync with the backend.
+                    this.set(['change.labels', labelName, key], null);
+                  }
+                }
+                this.splice(['change.labels', labelName, 'all'], i, 1);
+                break;
+              }
+            }
+          }.bind(this));
     },
 
     _computeShowLabelStatus: function(change) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
index e8e22f9..c531c79 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
@@ -244,8 +244,9 @@
           {
             _account_id: 1,
             name: 'bojack',
-          }
+          },
         ];
+        element.change.labels.test.recommended = {_account_id: 1};
         element.mutable = true;
         flushAsynchronousOperations();
         var button = element.$$('gr-account-chip').$$('gr-button');
@@ -256,6 +257,7 @@
           assert.deepEqual(path, ['change.labels', 'test', 'all']);
           assert.equal(index, 0);
           assert.equal(length, 1);
+          assert.notOk(element.change.labels.test.recommended);
           spliceStub.restore();
           done();
         });