use of com.google.gerrit.extensions.api.changes.ReviewerInput in project gerrit by GerritCodeReview.
the class AccountIT method addExistingReviewersUsingPostReview.
@Test
public void addExistingReviewersUsingPostReview() throws Exception {
PushOneCommit.Result r = createChange();
// First reviewer added to the change
ReviewInput input = new ReviewInput();
input.reviewers = new ArrayList<>(1);
ReviewerInput reviewerInput = new ReviewerInput();
reviewerInput.reviewer = user.email();
input.reviewers.add(reviewerInput);
gApi.changes().id(r.getChangeId()).current().review(input);
List<Message> messages = sender.getMessages();
assertThat(messages).hasSize(1);
Message message = messages.get(0);
assertThat(message.rcpt()).containsExactly(user.getNameEmail());
assertMailReplyTo(message, admin.email());
sender.clear();
// Second reviewer and existing reviewer added to the change
ReviewInput input2 = new ReviewInput();
input2.reviewers = new ArrayList<>(2);
ReviewerInput reviewerInput2 = new ReviewerInput();
reviewerInput2.reviewer = user.email();
input2.reviewers.add(reviewerInput2);
ReviewerInput reviewerInput3 = new ReviewerInput();
TestAccount user2 = accountCreator.user2();
reviewerInput3.reviewer = user2.email();
input2.reviewers.add(reviewerInput3);
gApi.changes().id(r.getChangeId()).current().review(input2);
List<Message> messages2 = sender.getMessages();
assertThat(messages2).hasSize(1);
Message message2 = messages2.get(0);
assertThat(message2.rcpt()).containsExactly(user.getNameEmail(), user2.getNameEmail());
assertMailReplyTo(message, admin.email());
sender.clear();
// Existing reviewers re-added to the change: no notifications
ReviewInput input3 = new ReviewInput();
input3.reviewers = new ArrayList<>(2);
ReviewerInput reviewerInput4 = new ReviewerInput();
reviewerInput4.reviewer = user.email();
input3.reviewers.add(reviewerInput4);
ReviewerInput reviewerInput5 = new ReviewerInput();
reviewerInput5.reviewer = user2.email();
input3.reviewers.add(reviewerInput5);
gApi.changes().id(r.getChangeId()).current().review(input3);
List<Message> messages3 = sender.getMessages();
assertThat(messages3).isEmpty();
}
use of com.google.gerrit.extensions.api.changes.ReviewerInput in project gerrit by GerritCodeReview.
the class OutgoingEmailIT method messageIdHeaderFromChangeUpdate.
@Test
public void messageIdHeaderFromChangeUpdate() throws Exception {
Repository repository = repoManager.openRepository(project);
PushOneCommit.Result result = createChange();
ReviewerInput reviewerInput = new ReviewerInput();
reviewerInput.reviewer = user.email();
gApi.changes().id(result.getChangeId()).addReviewer(reviewerInput);
sender.clear();
gApi.changes().id(result.getChangeId()).abandon();
assertThat(getMessageId(sender)).isEqualTo(withPrefixAndSuffixForMessageId(repository.getRefDatabase().exactRef(result.getChange().getId().toRefPrefix() + "meta").getObjectId().getName() + "-HTML"));
sender.clear();
gApi.changes().id(result.getChangeId()).restore();
assertThat(getMessageId(sender)).isEqualTo(withPrefixAndSuffixForMessageId(repository.getRefDatabase().exactRef(result.getChange().getId().toRefPrefix() + "meta").getObjectId().getName() + "-HTML"));
}
use of com.google.gerrit.extensions.api.changes.ReviewerInput in project gerrit by GerritCodeReview.
the class PostReview method apply.
public Response<ReviewResult> apply(RevisionResource revision, ReviewInput input, Instant ts) throws RestApiException, UpdateException, IOException, PermissionBackendException, ConfigInvalidException, PatchListNotAvailableException {
// Respect timestamp, but truncate at change created-on time.
ts = Ordering.natural().max(ts, revision.getChange().getCreatedOn());
if (revision.getEdit().isPresent()) {
throw new ResourceConflictException("cannot post review on edit");
}
ProjectState projectState = projectCache.get(revision.getProject()).orElseThrow(illegalState(revision.getProject()));
LabelTypes labelTypes = projectState.getLabelTypes(revision.getNotes());
logger.atFine().log("strict label checking is %s", (strictLabels ? "enabled" : "disabled"));
metrics.draftHandling.increment(input.drafts == null ? "N/A" : input.drafts.name());
input.drafts = firstNonNull(input.drafts, DraftHandling.KEEP);
logger.atFine().log("draft handling = %s", input.drafts);
if (input.onBehalfOf != null) {
revision = onBehalfOf(revision, labelTypes, input);
}
if (input.labels != null) {
checkLabels(revision, labelTypes, input.labels);
}
if (input.comments != null) {
input.comments = cleanUpComments(input.comments);
checkComments(revision, input.comments);
}
if (input.draftIdsToPublish != null) {
checkDraftIds(revision, input.draftIdsToPublish, input.drafts);
}
if (input.robotComments != null) {
input.robotComments = cleanUpComments(input.robotComments);
checkRobotComments(revision, input.robotComments);
}
if (input.notify == null) {
input.notify = defaultNotify(revision.getChange(), input);
}
logger.atFine().log("notify handling = %s", input.notify);
Map<String, ReviewerResult> reviewerJsonResults = null;
List<ReviewerModification> reviewerResults = Lists.newArrayList();
boolean hasError = false;
boolean confirm = false;
if (input.reviewers != null) {
reviewerJsonResults = Maps.newHashMap();
for (ReviewerInput reviewerInput : input.reviewers) {
ReviewerModification result = reviewerModifier.prepare(revision.getNotes(), revision.getUser(), reviewerInput, true);
reviewerJsonResults.put(reviewerInput.reviewer, result.result);
if (result.result.error != null) {
logger.atFine().log("Adding %s as reviewer failed: %s", reviewerInput.reviewer, result.result.error);
hasError = true;
continue;
}
if (result.result.confirm != null) {
logger.atFine().log("Adding %s as reviewer requires confirmation", reviewerInput.reviewer);
confirm = true;
continue;
}
logger.atFine().log("Adding %s as reviewer was prepared", reviewerInput.reviewer);
reviewerResults.add(result);
}
}
ReviewResult output = new ReviewResult();
output.reviewers = reviewerJsonResults;
if (hasError || confirm) {
output.error = ERROR_ADDING_REVIEWER;
return Response.withStatusCode(SC_BAD_REQUEST, output);
}
output.labels = input.labels;
try (BatchUpdate bu = updateFactory.create(revision.getChange().getProject(), revision.getUser(), ts)) {
Account account = revision.getUser().asIdentifiedUser().getAccount();
boolean ccOrReviewer = false;
if (input.labels != null && !input.labels.isEmpty()) {
ccOrReviewer = input.labels.values().stream().anyMatch(v -> v != 0);
if (ccOrReviewer) {
logger.atFine().log("calling user is cc/reviewer on the change due to voting on a label");
}
}
if (!ccOrReviewer) {
// Check if user was already CCed or reviewing prior to this review.
ReviewerSet currentReviewers = approvalsUtil.getReviewers(revision.getChangeResource().getNotes());
ccOrReviewer = currentReviewers.all().contains(account.id());
if (ccOrReviewer) {
logger.atFine().log("calling user is already cc/reviewer on the change");
}
}
// Apply reviewer changes first. Revision emails should be sent to the
// updated set of reviewers. Also keep track of whether the user added
// themselves as a reviewer or to the CC list.
logger.atFine().log("adding reviewer additions");
for (ReviewerModification reviewerResult : reviewerResults) {
// Send a single batch email below.
reviewerResult.op.suppressEmail();
// Send events below, if possible as batch.
reviewerResult.op.suppressEvent();
bu.addOp(revision.getChange().getId(), reviewerResult.op);
if (!ccOrReviewer && reviewerResult.reviewers.contains(account)) {
logger.atFine().log("calling user is explicitly added as reviewer or CC");
ccOrReviewer = true;
}
}
if (!ccOrReviewer) {
// User posting this review isn't currently in the reviewer or CC list,
// isn't being explicitly added, and isn't voting on any label.
// Automatically CC them on this change so they receive replies.
logger.atFine().log("CCing calling user");
ReviewerModification selfAddition = reviewerModifier.ccCurrentUser(revision.getUser(), revision);
selfAddition.op.suppressEmail();
selfAddition.op.suppressEvent();
bu.addOp(revision.getChange().getId(), selfAddition.op);
}
// Add WorkInProgressOp if requested.
if ((input.ready || input.workInProgress) && didWorkInProgressChange(revision.getChange().isWorkInProgress(), input)) {
if (input.ready && input.workInProgress) {
output.error = ERROR_WIP_READY_MUTUALLY_EXCLUSIVE;
return Response.withStatusCode(SC_BAD_REQUEST, output);
}
revision.getChangeResource().permissions().check(ChangePermission.TOGGLE_WORK_IN_PROGRESS_STATE);
if (input.ready) {
output.ready = true;
}
logger.atFine().log("setting work-in-progress to %s", input.workInProgress);
WorkInProgressOp wipOp = workInProgressOpFactory.create(input.workInProgress, new WorkInProgressOp.Input());
wipOp.suppressEmail();
bu.addOp(revision.getChange().getId(), wipOp);
}
// Add the review op.
logger.atFine().log("posting review");
bu.addOp(revision.getChange().getId(), new Op(projectState, revision.getPatchSet().id(), input));
// Notify based on ReviewInput, ignoring the notify settings from any ReviewerInputs.
NotifyResolver.Result notify = notifyResolver.resolve(input.notify, input.notifyDetails);
bu.setNotify(notify);
// Adjust the attention set based on the input
replyAttentionSetUpdates.updateAttentionSet(bu, revision.getNotes(), input, revision.getUser());
bu.execute();
// Re-read change to take into account results of the update.
ChangeData cd = changeDataFactory.create(revision.getProject(), revision.getChange().getId());
for (ReviewerModification reviewerResult : reviewerResults) {
reviewerResult.gatherResults(cd);
}
// Sending emails and events from ReviewersOps was suppressed so we can send a single batch
// email/event here.
batchEmailReviewers(revision.getUser(), revision.getChange(), reviewerResults, notify);
batchReviewerEvents(revision.getUser(), cd, revision.getPatchSet(), reviewerResults, ts);
}
return Response.ok(output);
}
use of com.google.gerrit.extensions.api.changes.ReviewerInput in project gerrit by GerritCodeReview.
the class PutAssignee method addAssigneeAsCC.
private ReviewerModification addAssigneeAsCC(ChangeResource rsrc, String assignee) throws IOException, PermissionBackendException, ConfigInvalidException {
ReviewerInput reviewerInput = new ReviewerInput();
reviewerInput.reviewer = assignee;
reviewerInput.state = ReviewerState.CC;
reviewerInput.confirmed = true;
reviewerInput.notify = NotifyHandling.NONE;
return reviewerModifier.prepare(rsrc.getNotes(), rsrc.getUser(), reviewerInput, false);
}
use of com.google.gerrit.extensions.api.changes.ReviewerInput in project gerrit by GerritCodeReview.
the class ChangeIT method nonVotingReviewerStaysAfterSubmit.
@Test
public void nonVotingReviewerStaysAfterSubmit() throws Exception {
LabelType verified = label(LabelId.VERIFIED, value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
String heads = "refs/heads/*";
try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig().upsertLabelType(verified);
u.save();
}
projectOperations.project(project).forUpdate().add(allowLabel(verified.getName()).ref(heads).group(CHANGE_OWNER).range(-1, 1)).add(allowLabel(LabelId.CODE_REVIEW).ref(heads).group(REGISTERED_USERS).range(-2, +2)).update();
// Set Code-Review+2 and Verified+1 as admin (change owner)
PushOneCommit.Result r = createChange();
String changeId = r.getChangeId();
String commit = r.getCommit().name();
ReviewInput input = ReviewInput.approve();
input.label(verified.getName(), 1);
gApi.changes().id(changeId).revision(commit).review(input);
// Reviewers should only be "admin"
ChangeInfo c = gApi.changes().id(changeId).get();
assertThat(getReviewers(c.reviewers.get(REVIEWER))).containsExactlyElementsIn(ImmutableSet.of(admin.id()));
assertThat(c.reviewers.get(CC)).isNull();
// Add the user as reviewer
ReviewerInput in = new ReviewerInput();
in.reviewer = user.email();
gApi.changes().id(changeId).addReviewer(in);
c = gApi.changes().id(changeId).get();
assertThat(getReviewers(c.reviewers.get(REVIEWER))).containsExactlyElementsIn(ImmutableSet.of(admin.id(), user.id()));
// Approve the change as user, then remove the approval
// (only to confirm that the user does have Code-Review+2 permission)
requestScopeOperations.setApiUser(user.id());
gApi.changes().id(changeId).revision(commit).review(ReviewInput.approve());
gApi.changes().id(changeId).revision(commit).review(ReviewInput.noScore());
// Submit the change
requestScopeOperations.setApiUser(admin.id());
gApi.changes().id(changeId).revision(commit).submit();
// User should still be on the change
c = gApi.changes().id(changeId).get();
assertThat(getReviewers(c.reviewers.get(REVIEWER))).containsExactlyElementsIn(ImmutableSet.of(admin.id(), user.id()));
}
Aggregations