Fix Delete vote button not checking removable_labels.
Whether or not a vote can be removed by a current user is controlled by
removable_labels field of ChangeInfo. Frontend code however was
erroneously checking removable_reviewers instead.
Bug: Google b/447150520
Release-Notes: skip
Change-Id: Ib9b46c533ca27c2edea8fc3dc99602ffb4a6ee6b
diff --git a/polygerrit-ui/app/api/rest-api.ts b/polygerrit-ui/app/api/rest-api.ts
index cb09c45..ec117f8 100644
--- a/polygerrit-ui/app/api/rest-api.ts
+++ b/polygerrit-ui/app/api/rest-api.ts
@@ -402,6 +402,9 @@
labels?: LabelNameToInfoMap;
permitted_labels?: LabelNameToValuesMap;
removable_reviewers?: AccountInfo[];
+ removable_labels?: {
+ [labelName: string]: {[labelValue: string]: AccountInfo[]};
+ };
// This is documented as optional, but actually always set.
reviewers: Reviewers;
pending_reviewers?: AccountInfo[];
diff --git a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.ts b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.ts
index 44eda05..28f6d6e 100644
--- a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.ts
+++ b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.ts
@@ -170,7 +170,7 @@
></gr-account-chip>
${noVoteYet
? this.renderVoteAbility(reviewer)
- : html`${this.renderRemoveVote(reviewer)}`}
+ : html`${this.renderRemoveVote(reviewer, approvalInfo)}`}
</div>`;
}
@@ -187,12 +187,16 @@
return html`<span class="no-votes">No votes</span>`;
}
- private renderRemoveVote(reviewer: AccountInfo) {
+ private renderRemoveVote(
+ reviewer: AccountInfo,
+ approvalInfo: ApprovalInfo | undefined
+ ) {
const accountId = reviewer._account_id;
const canDeleteVote = this.canDeleteVote(
reviewer,
this.mutable,
- this.change
+ this.change,
+ approvalInfo
);
if (!accountId || !canDeleteVote) return;
@@ -253,22 +257,30 @@
/**
* A user is able to delete a vote iff the mutable property is true and the
- * reviewer that left the vote exists in the list of removable_reviewers
+ * reviewer that left the vote exists in the list of removable_labels
* received from the backend.
*/
private canDeleteVote(
- reviewer: ApprovalInfo,
+ reviewer: AccountInfo,
mutable: boolean,
- change?: ParsedChangeInfo
+ change?: ParsedChangeInfo,
+ approvalInfo?: ApprovalInfo
) {
- if (!mutable || !change || !change.removable_reviewers) {
+ if (
+ !mutable ||
+ !change ||
+ !approvalInfo ||
+ !approvalInfo.value ||
+ !change.removable_labels
+ ) {
return false;
}
- const removable = change.removable_reviewers;
- if (removable.find(r => r._account_id === reviewer?._account_id)) {
- return true;
+ const removableAccounts =
+ change.removable_labels[this.label]?.[valueString(approvalInfo.value)];
+ if (!removableAccounts) {
+ return false;
}
- return false;
+ return removableAccounts.find(r => r._account_id === reviewer?._account_id);
}
private async onDeleteVote(accountId: AccountId) {
diff --git a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.ts b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.ts
index 0514b68..14561ea 100644
--- a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.ts
@@ -90,7 +90,7 @@
await element.updateComplete;
assert.isUndefined(query<GrButton>(element, 'gr-button'));
- element.change!.removable_reviewers = [account];
+ element.change!.removable_labels = {'Code-Review': {'+1': [account]}};
element.mutable = true;
await element.updateComplete;
assert.isDefined(query<GrButton>(element, 'gr-button'));
@@ -100,7 +100,7 @@
const mock = mockPromise();
const deleteResponse = mock.then(() => new Response(null, {status: 200}));
const deleteStub = stubRestApi('deleteVote').returns(deleteResponse);
- element.change!.removable_reviewers = [account];
+ element.change!.removable_labels = {'Code-Review': {'+1': [account]}};
element.change!.labels!['Code-Review'] = {
...label,
recommended: account,