Only send one newchange email from PostReviewer
This is a revision of change If45290b87 with updated tests that no longer need to take NoteDB into account separately. The PostReview REST endpoint translates each new reviewer in the request into invocations of the PostReviewers REST endpoint, which would send a newchange email each time a reviewer is successfully added. Because the PostReview endpoint allows several Reviewers and CC'd users in batch, prevent the PostReviewers sub-calls from sending emails, and send one newchange email at the end. Tests are updated to reflect fewer emails being sent and to reflect CC'd user names no-longer appearing in the email salutation. Bug: Issue 4563 Change-Id: I1cfd56ac1a2d107b9f6aae58ed056a1a458410af
This commit is contained in:
committed by
David Ostrovsky
parent
21fcf7d567
commit
92cba85254
@@ -288,35 +288,22 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
|
|||||||
|
|
||||||
// Verify emails were sent to added reviewers.
|
// Verify emails were sent to added reviewers.
|
||||||
List<Message> messages = sender.getMessages();
|
List<Message> messages = sender.getMessages();
|
||||||
assertThat(messages).hasSize(3);
|
assertThat(messages).hasSize(2);
|
||||||
// First email to user.
|
|
||||||
Message m = messages.get(0);
|
Message m = messages.get(0);
|
||||||
if (notesMigration.readChanges()) {
|
assertThat(m.rcpt())
|
||||||
assertThat(m.rcpt()).containsExactly(user.emailAddress);
|
.containsExactly(user.emailAddress,observer.emailAddress);
|
||||||
} else {
|
assertThat(m.body())
|
||||||
assertThat(m.rcpt()).containsExactly(
|
.contains(admin.fullName + " has posted comments on this change.");
|
||||||
user.emailAddress, observer.emailAddress);
|
assertThat(m.body())
|
||||||
}
|
.contains("Change subject: " + PushOneCommit.SUBJECT + "\n");
|
||||||
|
assertThat(m.body()).contains("Patch Set 1: Code-Review+2");
|
||||||
|
|
||||||
|
m = messages.get(1);
|
||||||
|
assertThat(m.rcpt())
|
||||||
|
.containsExactly(user.emailAddress, observer.emailAddress);
|
||||||
assertThat(m.body()).contains("Hello " + user.fullName + ",\n");
|
assertThat(m.body()).contains("Hello " + user.fullName + ",\n");
|
||||||
assertThat(m.body()).contains("I'd like you to do a code review.");
|
assertThat(m.body()).contains("I'd like you to do a code review.");
|
||||||
assertThat(m.body()).contains("Change subject: " + PushOneCommit.SUBJECT + "\n");
|
|
||||||
// Second email to reviewer and observer.
|
|
||||||
m = messages.get(1);
|
|
||||||
if (notesMigration.readChanges()) {
|
|
||||||
assertThat(m.rcpt()).containsExactly(user.emailAddress, observer.emailAddress);
|
|
||||||
assertThat(m.body()).contains(admin.fullName + " has uploaded a new change for review.");
|
|
||||||
} else {
|
|
||||||
assertThat(m.rcpt()).containsExactly(user.emailAddress, observer.emailAddress);
|
|
||||||
assertThat(m.body()).contains("Hello " + observer.fullName + ",\n");
|
|
||||||
assertThat(m.body()).contains("I'd like you to do a code review.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Third email is review to user and observer.
|
|
||||||
m = messages.get(2);
|
|
||||||
assertThat(m.rcpt()).containsExactly(user.emailAddress, observer.emailAddress);
|
|
||||||
assertThat(m.body()).contains(admin.fullName + " has posted comments on this change.");
|
|
||||||
assertThat(m.body()).contains("Change subject: " + PushOneCommit.SUBJECT + "\n");
|
|
||||||
assertThat(m.body()).contains("Patch Set 1: Code-Review+2\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import com.google.gerrit.extensions.api.changes.ReviewInput;
|
|||||||
import com.google.gerrit.extensions.api.changes.ReviewInput.CommentInput;
|
import com.google.gerrit.extensions.api.changes.ReviewInput.CommentInput;
|
||||||
import com.google.gerrit.extensions.api.changes.ReviewInput.DraftHandling;
|
import com.google.gerrit.extensions.api.changes.ReviewInput.DraftHandling;
|
||||||
import com.google.gerrit.extensions.api.changes.ReviewResult;
|
import com.google.gerrit.extensions.api.changes.ReviewResult;
|
||||||
|
import com.google.gerrit.extensions.client.ReviewerState;
|
||||||
import com.google.gerrit.extensions.client.Side;
|
import com.google.gerrit.extensions.client.Side;
|
||||||
import com.google.gerrit.extensions.restapi.AuthException;
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
import com.google.gerrit.extensions.restapi.BadRequestException;
|
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||||
@@ -54,6 +55,8 @@ import com.google.gerrit.extensions.restapi.RestApiException;
|
|||||||
import com.google.gerrit.extensions.restapi.RestModifyView;
|
import com.google.gerrit.extensions.restapi.RestModifyView;
|
||||||
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
|
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
|
||||||
import com.google.gerrit.extensions.restapi.Url;
|
import com.google.gerrit.extensions.restapi.Url;
|
||||||
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
|
import com.google.gerrit.reviewdb.client.Change;
|
||||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||||
import com.google.gerrit.reviewdb.client.CommentRange;
|
import com.google.gerrit.reviewdb.client.CommentRange;
|
||||||
import com.google.gerrit.reviewdb.client.Patch;
|
import com.google.gerrit.reviewdb.client.Patch;
|
||||||
@@ -181,6 +184,9 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
|
|||||||
if (input.reviewers != null) {
|
if (input.reviewers != null) {
|
||||||
reviewerJsonResults = Maps.newHashMap();
|
reviewerJsonResults = Maps.newHashMap();
|
||||||
for (AddReviewerInput reviewerInput : input.reviewers) {
|
for (AddReviewerInput reviewerInput : input.reviewers) {
|
||||||
|
// Prevent notifications because setting reviewers is batched.
|
||||||
|
reviewerInput.notify = NotifyHandling.NONE;
|
||||||
|
|
||||||
PostReviewers.Addition result = postReviewers.prepareApplication(
|
PostReviewers.Addition result = postReviewers.prepareApplication(
|
||||||
revision.getChangeResource(), reviewerInput);
|
revision.getChangeResource(), reviewerInput);
|
||||||
reviewerJsonResults.put(reviewerInput.reviewer, result.result);
|
reviewerJsonResults.put(reviewerInput.reviewer, result.result);
|
||||||
@@ -218,11 +224,27 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
|
|||||||
for (PostReviewers.Addition reviewerResult : reviewerResults) {
|
for (PostReviewers.Addition reviewerResult : reviewerResults) {
|
||||||
reviewerResult.gatherResults();
|
reviewerResult.gatherResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emailReviewers(revision.getChange(), reviewerResults, input.notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response.ok(output);
|
return Response.ok(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void emailReviewers(Change change,
|
||||||
|
List<PostReviewers.Addition> reviewerAdditions, NotifyHandling notify) {
|
||||||
|
List<Account.Id> to = new ArrayList<>();
|
||||||
|
List<Account.Id> cc = new ArrayList<>();
|
||||||
|
for (PostReviewers.Addition addition : reviewerAdditions) {
|
||||||
|
if (addition.op.state == ReviewerState.REVIEWER) {
|
||||||
|
to.addAll(addition.op.reviewers.keySet());
|
||||||
|
} else if (addition.op.state == ReviewerState.CC) {
|
||||||
|
cc.addAll(addition.op.reviewers.keySet());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
postReviewers.emailReviewers(change, to, cc, notify);
|
||||||
|
}
|
||||||
|
|
||||||
private RevisionResource onBehalfOf(RevisionResource rev, ReviewInput in)
|
private RevisionResource onBehalfOf(RevisionResource rev, ReviewInput in)
|
||||||
throws BadRequestException, AuthException, UnprocessableEntityException,
|
throws BadRequestException, AuthException, UnprocessableEntityException,
|
||||||
OrmException {
|
OrmException {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package com.google.gerrit.server.change;
|
|||||||
import static com.google.gerrit.extensions.client.ReviewerState.CC;
|
import static com.google.gerrit.extensions.client.ReviewerState.CC;
|
||||||
import static com.google.gerrit.extensions.client.ReviewerState.REVIEWER;
|
import static com.google.gerrit.extensions.client.ReviewerState.REVIEWER;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
@@ -359,7 +360,14 @@ public class PostReviewers
|
|||||||
if (addedCCs == null) {
|
if (addedCCs == null) {
|
||||||
addedCCs = new ArrayList<>();
|
addedCCs = new ArrayList<>();
|
||||||
}
|
}
|
||||||
emailReviewers(rsrc.getChange(), addedReviewers, addedCCs, notify);
|
List<Account.Id> accounts = Lists.transform(addedReviewers,
|
||||||
|
new Function<PatchSetApproval, Account.Id>() {
|
||||||
|
public Account.Id apply(PatchSetApproval psa) {
|
||||||
|
return psa.getAccountId();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
emailReviewers(rsrc.getChange(), accounts, addedCCs, notify);
|
||||||
if (!addedReviewers.isEmpty()) {
|
if (!addedReviewers.isEmpty()) {
|
||||||
for (PatchSetApproval psa : addedReviewers) {
|
for (PatchSetApproval psa : addedReviewers) {
|
||||||
Account account = accountCache.get(psa.getAccountId()).getAccount();
|
Account account = accountCache.get(psa.getAccountId()).getAccount();
|
||||||
@@ -371,7 +379,7 @@ public class PostReviewers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void emailReviewers(Change change, List<PatchSetApproval> added,
|
public void emailReviewers(Change change, Collection<Account.Id> added,
|
||||||
Collection<Account.Id> copied, NotifyHandling notify) {
|
Collection<Account.Id> copied, NotifyHandling notify) {
|
||||||
if (added.isEmpty() && copied.isEmpty()) {
|
if (added.isEmpty() && copied.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@@ -382,9 +390,9 @@ public class PostReviewers
|
|||||||
// The user knows they added themselves, don't bother emailing them.
|
// The user knows they added themselves, don't bother emailing them.
|
||||||
List<Account.Id> toMail = Lists.newArrayListWithCapacity(added.size());
|
List<Account.Id> toMail = Lists.newArrayListWithCapacity(added.size());
|
||||||
Account.Id userId = user.get().getAccountId();
|
Account.Id userId = user.get().getAccountId();
|
||||||
for (PatchSetApproval psa : added) {
|
for (Account.Id id : added) {
|
||||||
if (!psa.getAccountId().equals(userId)) {
|
if (!id.equals(userId)) {
|
||||||
toMail.add(psa.getAccountId());
|
toMail.add(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<Account.Id> toCopy = Lists.newArrayListWithCapacity(copied.size());
|
List<Account.Id> toCopy = Lists.newArrayListWithCapacity(copied.size());
|
||||||
|
|||||||
Reference in New Issue
Block a user