// Copyright (C) 2016 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.gerrit.acceptance.server.event; import static com.google.common.truth.Truth.assertThat; import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS; import static com.google.gerrit.server.project.Util.category; import static com.google.gerrit.server.project.Util.value; import com.google.gerrit.acceptance.AbstractDaemonTest; import com.google.gerrit.acceptance.NoHttpd; import com.google.gerrit.acceptance.PushOneCommit; import com.google.gerrit.common.data.LabelType; import com.google.gerrit.common.data.Permission; import com.google.gerrit.extensions.api.changes.ReviewInput; import com.google.gerrit.extensions.common.ApprovalInfo; import com.google.gerrit.extensions.common.ChangeInfo; import com.google.gerrit.extensions.common.LabelInfo; import com.google.gerrit.extensions.events.CommentAddedListener; import com.google.gerrit.extensions.registration.DynamicSet; import com.google.gerrit.extensions.registration.RegistrationHandle; import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.server.git.ProjectConfig; import com.google.gerrit.server.project.Util; import com.google.inject.Inject; import org.junit.After; import org.junit.Before; import org.junit.Test; @NoHttpd public class CommentAddedEventIT extends AbstractDaemonTest { @Inject private DynamicSet<CommentAddedListener> source; private final LabelType label = category("CustomLabel", value(1, "Positive"), value(0, "No score"), value(-1, "Negative")); private final LabelType pLabel = category("CustomLabel2", value(1, "Positive"), value(0, "No score")); private RegistrationHandle eventListenerRegistration; private CommentAddedListener.Event lastCommentAddedEvent; @Before public void setUp() throws Exception { ProjectConfig cfg = projectCache.checkedGet(project).getConfig(); AccountGroup.UUID anonymousUsers = systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID(); Util.allow(cfg, Permission.forLabel(label.getName()), -1, 1, anonymousUsers, "refs/heads/*"); Util.allow(cfg, Permission.forLabel(pLabel.getName()), 0, 1, anonymousUsers, "refs/heads/*"); saveProjectConfig(project, cfg); eventListenerRegistration = source.add( new CommentAddedListener() { @Override public void onCommentAdded(Event event) { lastCommentAddedEvent = event; } }); } @After public void cleanup() { eventListenerRegistration.remove(); } private void saveLabelConfig() throws Exception { ProjectConfig cfg = projectCache.checkedGet(project).getConfig(); cfg.getLabelSections().put(label.getName(), label); cfg.getLabelSections().put(pLabel.getName(), pLabel); saveProjectConfig(project, cfg); } /* Need to lookup info for the label under test since there can be multiple * labels defined. By default Gerrit already has a Code-Review label. */ private ApprovalValues getApprovalValues(LabelType label) { ApprovalValues res = new ApprovalValues(); ApprovalInfo info = lastCommentAddedEvent.getApprovals().get(label.getName()); if (info != null) { res.value = info.value; } info = lastCommentAddedEvent.getOldApprovals().get(label.getName()); if (info != null) { res.oldValue = info.value; } return res; } @Test public void newChangeWithVote() throws Exception { saveLabelConfig(); // push a new change with -1 vote PushOneCommit.Result r = createChange(); ReviewInput reviewInput = new ReviewInput().label(label.getName(), (short) -1); revision(r).review(reviewInput); ApprovalValues attr = getApprovalValues(label); assertThat(attr.oldValue).isEqualTo(0); assertThat(attr.value).isEqualTo(-1); assertThat(lastCommentAddedEvent.getComment()) .isEqualTo(String.format("Patch Set 1: %s-1", label.getName())); } @Test public void newPatchSetWithVote() throws Exception { saveLabelConfig(); // push a new change PushOneCommit.Result r = createChange(); ReviewInput reviewInput = new ReviewInput().message(label.getName()); revision(r).review(reviewInput); // push a new revision with +1 vote ChangeInfo c = get(r.getChangeId()); r = amendChange(c.changeId); reviewInput = new ReviewInput().label(label.getName(), (short) 1); revision(r).review(reviewInput); ApprovalValues attr = getApprovalValues(label); assertThat(attr.oldValue).isEqualTo(0); assertThat(attr.value).isEqualTo(1); assertThat(lastCommentAddedEvent.getComment()) .isEqualTo(String.format("Patch Set 2: %s+1", label.getName())); } @Test public void reviewChange() throws Exception { saveLabelConfig(); // push a change PushOneCommit.Result r = createChange(); // review with message only, do not apply votes ReviewInput reviewInput = new ReviewInput().message(label.getName()); revision(r).review(reviewInput); // reply message only so vote is shown as 0 ApprovalValues attr = getApprovalValues(label); assertThat(attr.oldValue).isNull(); assertThat(attr.value).isEqualTo(0); assertThat(lastCommentAddedEvent.getComment()) .isEqualTo(String.format("Patch Set 1:\n\n%s", label.getName())); // transition from un-voted to -1 vote reviewInput = new ReviewInput().label(label.getName(), -1); revision(r).review(reviewInput); attr = getApprovalValues(label); assertThat(attr.oldValue).isEqualTo(0); assertThat(attr.value).isEqualTo(-1); assertThat(lastCommentAddedEvent.getComment()) .isEqualTo(String.format("Patch Set 1: %s-1", label.getName())); // transition vote from -1 to 0 reviewInput = new ReviewInput().label(label.getName(), 0); revision(r).review(reviewInput); attr = getApprovalValues(label); assertThat(attr.oldValue).isEqualTo(-1); assertThat(attr.value).isEqualTo(0); assertThat(lastCommentAddedEvent.getComment()) .isEqualTo(String.format("Patch Set 1: -%s", label.getName())); // transition vote from 0 to 1 reviewInput = new ReviewInput().label(label.getName(), 1); revision(r).review(reviewInput); attr = getApprovalValues(label); assertThat(attr.oldValue).isEqualTo(0); assertThat(attr.value).isEqualTo(1); assertThat(lastCommentAddedEvent.getComment()) .isEqualTo(String.format("Patch Set 1: %s+1", label.getName())); // transition vote from 1 to -1 reviewInput = new ReviewInput().label(label.getName(), -1); revision(r).review(reviewInput); attr = getApprovalValues(label); assertThat(attr.oldValue).isEqualTo(1); assertThat(attr.value).isEqualTo(-1); assertThat(lastCommentAddedEvent.getComment()) .isEqualTo(String.format("Patch Set 1: %s-1", label.getName())); // review with message only, do not apply votes reviewInput = new ReviewInput().message(label.getName()); revision(r).review(reviewInput); attr = getApprovalValues(label); assertThat(attr.oldValue).isNull(); // no vote change so not included assertThat(attr.value).isEqualTo(-1); assertThat(lastCommentAddedEvent.getComment()) .isEqualTo(String.format("Patch Set 1:\n\n%s", label.getName())); } @Test public void reviewChange_MultipleVotes() throws Exception { saveLabelConfig(); PushOneCommit.Result r = createChange(); ReviewInput reviewInput = new ReviewInput().label(label.getName(), -1); reviewInput.message = label.getName(); revision(r).review(reviewInput); ChangeInfo c = get(r.getChangeId()); LabelInfo q = c.labels.get(label.getName()); assertThat(q.all).hasSize(1); ApprovalValues labelAttr = getApprovalValues(label); assertThat(labelAttr.oldValue).isEqualTo(0); assertThat(labelAttr.value).isEqualTo(-1); assertThat(lastCommentAddedEvent.getComment()) .isEqualTo(String.format("Patch Set 1: %s-1\n\n%s", label.getName(), label.getName())); // there should be 3 approval labels (label, pLabel, and CRVV) assertThat(lastCommentAddedEvent.getApprovals()).hasSize(3); // check the approvals that were not voted on ApprovalValues pLabelAttr = getApprovalValues(pLabel); assertThat(pLabelAttr.oldValue).isNull(); assertThat(pLabelAttr.value).isEqualTo(0); LabelType crLabel = LabelType.withDefaultValues("Code-Review"); ApprovalValues crlAttr = getApprovalValues(crLabel); assertThat(crlAttr.oldValue).isNull(); assertThat(crlAttr.value).isEqualTo(0); // update pLabel approval reviewInput = new ReviewInput().label(pLabel.getName(), 1); reviewInput.message = pLabel.getName(); revision(r).review(reviewInput); c = get(r.getChangeId()); q = c.labels.get(label.getName()); assertThat(q.all).hasSize(1); pLabelAttr = getApprovalValues(pLabel); assertThat(pLabelAttr.oldValue).isEqualTo(0); assertThat(pLabelAttr.value).isEqualTo(1); assertThat(lastCommentAddedEvent.getComment()) .isEqualTo(String.format("Patch Set 1: %s+1\n\n%s", pLabel.getName(), pLabel.getName())); // check the approvals that were not voted on labelAttr = getApprovalValues(label); assertThat(labelAttr.oldValue).isNull(); assertThat(labelAttr.value).isEqualTo(-1); crlAttr = getApprovalValues(crLabel); assertThat(crlAttr.oldValue).isNull(); assertThat(crlAttr.value).isEqualTo(0); } private static class ApprovalValues { Integer value; Integer oldValue; } }