// Copyright (C) 2020 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.rest.change;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.extensions.restapi.testing.AttentionSetUpdateSubject.assertThat;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.server.project.testing.TestLabels.labelBuilder;
import static com.google.gerrit.server.project.testing.TestLabels.value;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.truth.Correspondence;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.UseClockStep;
import com.google.gerrit.acceptance.VerifyNoPiiInChangeNotes;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
import com.google.gerrit.acceptance.testsuite.change.ChangeOperations;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.AttentionSetUpdate;
import com.google.gerrit.entities.AttentionSetUpdate.Operation;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.LabelId;
import com.google.gerrit.entities.LabelType;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.PatchSetApproval;
import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.api.changes.AttentionSetInput;
import com.google.gerrit.extensions.api.changes.CustomKeyedValuesInput;
import com.google.gerrit.extensions.api.changes.DeleteReviewerInput;
import com.google.gerrit.extensions.api.changes.DeleteVoteInput;
import com.google.gerrit.extensions.api.changes.HashtagsInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.ReviewerInput;
import com.google.gerrit.extensions.api.groups.GroupInput;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo.EmailStrategy;
import com.google.gerrit.extensions.client.ReviewerState;
import com.google.gerrit.extensions.client.Side;
import com.google.gerrit.extensions.common.AttentionSetInfo;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.server.account.ServiceUserClassifier;
import com.google.gerrit.server.change.ReaddOwnerUtil;
import com.google.gerrit.server.project.testing.TestLabels;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.restapi.change.GetAttentionSet;
import com.google.gerrit.server.util.AccountTemplateUtil;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gerrit.testing.FakeEmailSender.Message;
import com.google.gerrit.testing.TestCommentHelper;
import com.google.gerrit.truth.NullAwareCorrespondence;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.LongSupplier;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;

@NoHttpd
@UseClockStep(clockStepUnit = TimeUnit.MINUTES)
@VerifyNoPiiInChangeNotes(true)
public class AttentionSetIT extends AbstractDaemonTest {

  @Inject private ChangeOperations changeOperations;
  @Inject private AccountOperations accountOperations;
  @Inject private RequestScopeOperations requestScopeOperations;

  @Inject private TestCommentHelper testCommentHelper;
  @Inject private Provider<InternalChangeQuery> changeQueryProvider;
  @Inject private ProjectOperations projectOperations;
  @Inject private GetAttentionSet getAttentionSet;
  @Inject private ReaddOwnerUtil readdOwnerUtil;

  /** Simulates a fake clock. Uses second granularity. */
  private static class FakeClock implements LongSupplier {
    Instant now = Instant.now();

    @Override
    public long getAsLong() {
      return TimeUnit.SECONDS.toMillis(now.getEpochSecond());
    }

    Instant now() {
      return Instant.ofEpochSecond(now.getEpochSecond());
    }

    void advance(Duration duration) {
      now = now.plus(duration);
    }
  }

  private FakeClock fakeClock = new FakeClock();

  @Before
  public void setUp() {
    TimeUtil.setCurrentMillisSupplier(fakeClock);
  }

  @Test
  public void emptyAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void addUser() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    int accountId =
        change(r).addToAttentionSet(new AttentionSetInput(admin.email(), "first"))._accountId;
    assertThat(accountId).isEqualTo(admin.id().get());
    AttentionSetUpdate expectedAttentionSetUpdate =
        AttentionSetUpdate.createFromRead(
            fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.ADD, "first");
    assertThat(r.getChange().attentionSet()).containsExactly(expectedAttentionSetUpdate);

    // Second add is ignored.
    accountId =
        change(r).addToAttentionSet(new AttentionSetInput(admin.email(), "second"))._accountId;
    assertThat(accountId).isEqualTo(admin.id().get());
    assertThat(r.getChange().attentionSet()).containsExactly(expectedAttentionSetUpdate);

    // Only one email since the second add was ignored.
    String emailBody = Iterables.getOnlyElement(sender.getMessages()).body();
    assertThat(emailBody)
        .contains(
            String.format(
                "%s requires the attention of %s to this change.\n The reason is: first.",
                user.fullName(), admin.fullName()));
  }

  @Test
  public void addUserWithTemplateReason() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    String manualReason = "Added by " + AccountTemplateUtil.getAccountTemplate(user.id());
    int accountId =
        change(r).addToAttentionSet(new AttentionSetInput(admin.email(), manualReason))._accountId;
    assertThat(accountId).isEqualTo(admin.id().get());
    AttentionSetUpdate expectedAttentionSetUpdate =
        AttentionSetUpdate.createFromRead(
            fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.ADD, manualReason);
    assertThat(r.getChange().attentionSet()).containsExactly(expectedAttentionSetUpdate);
    AttentionSetInfo attentionSetInfo =
        Iterables.getOnlyElement(change(r).get().attentionSet.values());
    assertThat(attentionSetInfo.reason).isEqualTo(manualReason);
    assertThat(attentionSetInfo.reasonAccount).isEqualTo(getAccountInfo(user.id()));
    assertThat(attentionSetInfo.account).isEqualTo(getAccountInfo(admin.id()));

    AttentionSetInfo getAttentionSetInfo =
        Iterables.getOnlyElement(
            getAttentionSet.apply(parseChangeResource(r.getChangeId())).value());
    assertThat(getAttentionSetInfo.reason).isEqualTo(manualReason);
    assertThat(getAttentionSetInfo.reasonAccount).isEqualTo(getAccountInfo(user.id()));
    assertThat(getAttentionSetInfo.account).isEqualTo(getAccountInfo(admin.id()));
  }

  @Test
  public void addUserWithTemplateReasonMultipleAccounts() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    String manualReason =
        String.format(
            "Added by %s with user %s",
            AccountTemplateUtil.getAccountTemplate(user.id()),
            AccountTemplateUtil.getAccountTemplate(admin.id()));
    int accountId =
        change(r).addToAttentionSet(new AttentionSetInput(admin.email(), manualReason))._accountId;
    assertThat(accountId).isEqualTo(admin.id().get());
    AttentionSetUpdate expectedAttentionSetUpdate =
        AttentionSetUpdate.createFromRead(
            fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.ADD, manualReason);
    assertThat(r.getChange().attentionSet()).containsExactly(expectedAttentionSetUpdate);
    AttentionSetInfo attentionSetInfo =
        Iterables.getOnlyElement(change(r).get().attentionSet.values());
    assertThat(attentionSetInfo.reason).isEqualTo(manualReason);
    assertThat(attentionSetInfo.reasonAccount).isNull();
    assertThat(attentionSetInfo.account).isEqualTo(getAccountInfo(admin.id()));

    AttentionSetInfo getAttentionSetInfo =
        Iterables.getOnlyElement(
            getAttentionSet.apply(parseChangeResource(r.getChangeId())).value());
    assertThat(getAttentionSetInfo.reason).isEqualTo(manualReason);
    assertThat(getAttentionSetInfo.reasonAccount).isNull();
    assertThat(getAttentionSetInfo.account).isEqualTo(getAccountInfo(admin.id()));
  }

  @Test
  public void reviewWithManuallyAddedUserAndTemplateReason() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    String manualReason = "Review by " + AccountTemplateUtil.getAccountTemplate(user.id());
    ReviewInput reviewInput =
        ReviewInput.create().addUserToAttentionSet(user.email(), manualReason);

    change(r).current().review(reviewInput);
    AttentionSetInfo attentionSetInfo = change(r).get().attentionSet.get(user.id().get());
    assertThat(attentionSetInfo.reason).isEqualTo(manualReason);
    assertThat(attentionSetInfo.reasonAccount).isEqualTo(getAccountInfo(user.id()));
    assertThat(attentionSetInfo.account).isEqualTo(getAccountInfo(user.id()));
  }

  @Test
  public void addMultipleUsers() throws Exception {
    PushOneCommit.Result r = createChange();
    Instant timestamp1 = fakeClock.now();
    // implictly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());
    fakeClock.advance(Duration.ofSeconds(42));
    Instant timestamp2 = fakeClock.now();
    int accountId2 =
        change(r)
            .addToAttentionSet(new AttentionSetInput(admin.id().toString(), "manual update"))
            ._accountId;
    assertThat(accountId2).isEqualTo(admin.id().get());

    AttentionSetUpdate expectedAttentionSetUpdate1 =
        AttentionSetUpdate.createFromRead(
            timestamp1, user.id(), AttentionSetUpdate.Operation.ADD, "Reviewer was added");
    AttentionSetUpdate expectedAttentionSetUpdate2 =
        AttentionSetUpdate.createFromRead(
            timestamp2, admin.id(), AttentionSetUpdate.Operation.ADD, "manual update");
    assertThat(r.getChange().attentionSet())
        .containsExactly(expectedAttentionSetUpdate1, expectedAttentionSetUpdate2);
  }

  @Test
  public void removeUser() throws Exception {
    PushOneCommit.Result r = createChange();
    // implictly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());
    sender.clear();
    requestScopeOperations.setApiUser(user.id());

    fakeClock.advance(Duration.ofSeconds(42));
    change(r).attention(user.id().toString()).remove(new AttentionSetInput("removed"));
    AttentionSetUpdate expectedAttentionSetUpdate =
        AttentionSetUpdate.createFromRead(
            fakeClock.now(), user.id(), AttentionSetUpdate.Operation.REMOVE, "removed");
    assertThat(r.getChange().attentionSet()).containsExactly(expectedAttentionSetUpdate);

    // The removal also shows up in AttentionSetInfo.
    AttentionSetInfo attentionSetInfo =
        Iterables.getOnlyElement(change(r).get().removedFromAttentionSet.values());
    assertThat(attentionSetInfo.reason).isEqualTo("removed");
    assertThat(attentionSetInfo.account).isEqualTo(getAccountInfo(user.id()));

    // Second removal is ignored.
    fakeClock.advance(Duration.ofSeconds(42));
    change(r).attention(user.id().toString()).remove(new AttentionSetInput("removed again"));
    assertThat(r.getChange().attentionSet()).containsExactly(expectedAttentionSetUpdate);

    // Only one email since the second remove was ignored.
    String emailBody = Iterables.getOnlyElement(sender.getMessages()).body();
    assertThat(emailBody)
        .contains(
            user.fullName()
                + " removed themselves from the attention set of this change.\n"
                + " The reason is: removed.");
  }

  @Test
  public void removeUserWithInvalidUserInput() throws Exception {
    PushOneCommit.Result r = createChange();
    // implictly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());

    BadRequestException exception =
        assertThrows(
            BadRequestException.class,
            () ->
                change(r)
                    .attention(user.id().toString())
                    .remove(new AttentionSetInput("invalid user", "reason")));
    assertThat(exception.getMessage())
        .isEqualTo(
            "invalid user doesn't exist or is not active on the change as an owner, "
                + "uploader, reviewer, or cc so they can't be added to the attention set");

    exception =
        assertThrows(
            BadRequestException.class,
            () ->
                change(r)
                    .attention(user.id().toString())
                    .remove(new AttentionSetInput(admin.email(), "reason")));
    assertThat(exception.getMessage())
        .isEqualTo(
            "The field \"user\" must be empty, or must match the user specified in the URL.");
  }

  @Test
  public void abandonRemovesUsers() throws Exception {
    PushOneCommit.Result r = createChange();
    // implictly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());
    change(r).addToAttentionSet(new AttentionSetInput(admin.email(), "admin"));

    change(r).abandon();

    AttentionSetUpdate userUpdate =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(userUpdate).hasAccountIdThat().isEqualTo(user.id());
    assertThat(userUpdate).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(userUpdate).hasReasonThat().isEqualTo("Change was abandoned");

    AttentionSetUpdate adminUpdate =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(adminUpdate).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(adminUpdate).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(adminUpdate).hasReasonThat().isEqualTo("Change was abandoned");
  }

  @Test
  public void workInProgressRemovesUsers() throws Exception {
    PushOneCommit.Result r = createChange();
    // implictly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());

    change(r).setWorkInProgress();

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was marked work in progress");
  }

  @Test
  public void submitRemovesUsersForAllSubmittedChanges() throws Exception {
    PushOneCommit.Result r1 = createChange("refs/heads/master", "file1", "content");

    // implictly adds the user to the attention set when adding as reviewer
    change(r1).current().review(ReviewInput.approve().reviewer(user.email()));
    PushOneCommit.Result r2 = createChange("refs/heads/master", "file2", "content");
    change(r2).current().review(ReviewInput.approve().reviewer(user.email()));

    change(r2).current().submit();

    // Attention set updates that relate to the admin (the person who replied) are filtered out.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r1, user));

    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was submitted");

    // Attention set updates that relate to the admin (the person who replied) are filtered out.
    attentionSet = Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r2, user));

    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was submitted");
  }

  @Test
  public void robotSubmitsRemovesUsers() throws Exception {
    PushOneCommit.Result r = createChange("refs/heads/master", "file1", "content");

    // implictly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());

    TestAccount robot =
        accountCreator.create(
            "robot2",
            "robot2@example.com",
            "Ro Bot",
            "Ro",
            ServiceUserClassifier.SERVICE_USERS,
            "Administrators");
    requestScopeOperations.setApiUser(robot.id());
    change(r).current().review(ReviewInput.approve());
    change(r).current().submit();

    // Attention set updates that relate to the admin (the person who replied) are filtered out.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));

    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was submitted");
  }

  @Test
  public void addedReviewersAreAddedToAttentionSetOnMergedChanges() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).current().review(ReviewInput.approve());
    change(r).current().submit();

    change(r).addReviewer(user.email());
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));

    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");
  }

  @Test
  public void reviewersAddedAndRemovedFromAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();

    change(r).addReviewer(user.id().toString());

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");

    change(r).reviewer(user.email()).remove();

    attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer/Cc was removed");
  }

  @Test
  public void removedCcRemovedFromAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();

    // Add cc
    ReviewerInput input = new ReviewerInput();
    input.reviewer = user.email();
    input.state = ReviewerState.CC;
    change(r).addReviewer(input);

    // Add them to the attention set
    AttentionSetInput attentionSetInput = new AttentionSetInput();
    attentionSetInput.user = user.email();
    attentionSetInput.reason = "reason";
    change(r).addToAttentionSet(attentionSetInput);

    // Remove them from cc
    change(r).reviewer(user.email()).remove();

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer/Cc was removed");
  }

  @Test
  public void reviewersAddedAndRemovedByEmailFromAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();

    change(r).addReviewer(user.email());

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");

    change(r).reviewer(user.email()).remove();

    attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer/Cc was removed");
  }

  @Test
  public void reviewersInWorkProgressNotAddedToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    change(r).addReviewer(user.email());

    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void addingReviewerWhileMarkingWorkInProgressDoesntAddToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    ReviewInput reviewInput = ReviewInput.create().setWorkInProgress(true);
    ReviewerInput reviewerInput = new ReviewerInput();
    reviewerInput.state = ReviewerState.REVIEWER;
    reviewerInput.reviewer = user.email();
    reviewInput.reviewers = ImmutableList.of(reviewerInput);

    change(r).current().review(reviewInput);
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void reviewersAddedAsReviewersAgainAreNotAddedToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();

    change(r).addReviewer(user.id().toString());
    change(r)
        .attention(user.id().toString())
        .remove(new AttentionSetInput("removed and not re-added when re-adding as reviewer"));

    change(r).addReviewer(user.id().toString());

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet)
        .hasReasonThat()
        .isEqualTo("removed and not re-added when re-adding as reviewer");
  }

  @Test
  public void ccsAreIgnored() throws Exception {
    PushOneCommit.Result r = createChange();
    ReviewerInput reviewerInput = new ReviewerInput();
    reviewerInput.state = ReviewerState.CC;
    reviewerInput.reviewer = user.email();

    change(r).addReviewer(reviewerInput);

    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void ccsConsideredSameAsRemovedForExistingReviewers() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addReviewer(user.email());

    ReviewerInput reviewerInput = new ReviewerInput();
    reviewerInput.state = ReviewerState.CC;
    reviewerInput.reviewer = user.email();
    change(r).addReviewer(reviewerInput);

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer/Cc was removed");
  }

  @Test
  public void robotReadyForReviewAddsAllReviewersToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    change(r).addReviewer(user.email());

    TestAccount robot =
        accountCreator.create(
            "robot1",
            "robot1@example.com",
            "Ro Bot",
            "Ro",
            ServiceUserClassifier.SERVICE_USERS,
            "Administrators");
    requestScopeOperations.setApiUser(robot.id());
    change(r).setReadyForReview();
    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was marked ready for review");
  }

  @Test
  public void readyForReviewAddsAllReviewersToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    change(r).addReviewer(user.email());

    change(r).setReadyForReview();
    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was marked ready for review");
  }

  @Test
  public void readyForReviewHasNoEffectOnReadyChanges() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r)
        .current()
        .review(ReviewInput.create().reviewer(user.email()).blockAutomaticAttentionSetRules());

    change(r).current().review(ReviewInput.create().setWorkInProgress(false));
    assertThat(r.getChange().attentionSet()).isEmpty();

    change(r).current().review(ReviewInput.create().setReady(true));
    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void workInProgressHasNoEffectOnWorkInProgressChanges() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r)
        .current()
        .review(
            ReviewInput.create()
                .reviewer(user.email())
                .setWorkInProgress(true)
                .addUserToAttentionSet(user.email(), /* reason= */ "reason"));

    change(r).current().review(ReviewInput.create().setWorkInProgress(true));
    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");

    change(r).current().review(ReviewInput.create().setReady(false));
    attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void rebaseDoesNotAddToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    change(r).addReviewer(user.email());

    // create an unrelated change so that we can rebase
    testRepo.reset("HEAD~1");
    PushOneCommit.Result unrelated = createChange();
    gApi.changes().id(unrelated.getChangeId()).current().review(ReviewInput.approve());
    gApi.changes().id(unrelated.getChangeId()).current().submit();

    gApi.changes().id(r.getChangeId()).rebase();

    // rebase has no impact on the attention set
    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void readyForReviewWhileRemovingReviewerRemovesThemToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    change(r).addReviewer(user.email());

    ReviewInput reviewInput = ReviewInput.create().setReady(true);
    ReviewerInput reviewerInput = new ReviewerInput();
    reviewerInput.state = ReviewerState.CC;
    reviewerInput.reviewer = user.email();
    reviewInput.reviewers = ImmutableList.of(reviewerInput);
    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "reason"));
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer/Cc was removed");
  }

  @Test
  public void readyForReviewWhileAddingReviewerAddsThemToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();

    ReviewInput reviewInput = ReviewInput.create().setReady(true).reviewer(user.email());
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");
  }

  @Test
  public void reviewersAreNotAddedForNoReasonBecauseOfAHashtagUpdate() throws Exception {
    PushOneCommit.Result r = createChange();
    // implicitly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());

    change(r).attention(user.id().toString()).remove(new AttentionSetInput("removed"));

    HashtagsInput hashtagsInput = new HashtagsInput();
    hashtagsInput.add = ImmutableSet.of("tag");
    change(r).setHashtags(hashtagsInput);

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("removed");
  }

  @Test
  public void reviewersAreNotAddedForNoReasonBecauseOfACustomKeyedValuesUpdate() throws Exception {
    PushOneCommit.Result r = createChange();
    // implicitly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());

    change(r).attention(user.id().toString()).remove(new AttentionSetInput("removed"));

    CustomKeyedValuesInput customKeyedValuesInput = new CustomKeyedValuesInput();
    customKeyedValuesInput.add = ImmutableMap.of("key1", "value1");
    change(r).setCustomKeyedValues(customKeyedValuesInput);

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("removed");
  }

  @Test
  public void reviewAddsManuallyAddedUserToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    ReviewInput reviewInput = ReviewInput.create().addUserToAttentionSet(user.email(), "reason");

    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");

    // No emails for adding to attention set were sent.
    assertThat(sender.getMessages()).isEmpty();
  }

  @Test
  public void reviewRemovesManuallyRemovedUserFromAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    // implictly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());
    requestScopeOperations.setApiUser(user.id());
    sender.clear();

    ReviewInput reviewInput =
        ReviewInput.create().removeUserFromAttentionSet(user.email(), "reason");
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");

    // No emails for removing from attention set were sent.
    assertThat(sender.getMessages()).isEmpty();
  }

  @Test
  public void reviewWithManualAdditionToAttentionSetFailsWithoutReason() throws Exception {
    PushOneCommit.Result r = createChange();
    // implictly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());

    ReviewInput reviewInput = ReviewInput.create().addUserToAttentionSet(user.email(), "");

    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> change(r).current().review(reviewInput));

    assertThat(exception.getMessage()).isEqualTo("missing field: reason");
  }

  @Test
  public void reviewWithManualAdditionToAttentionSetFailsWithoutUser() throws Exception {
    PushOneCommit.Result r = createChange();
    ReviewInput reviewInput = ReviewInput.create().addUserToAttentionSet("", "reason");

    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> change(r).current().review(reviewInput));

    assertThat(exception.getMessage()).isEqualTo("missing field: user");
  }

  @Test
  public void reviewAddReviewerWhileRemovingFromAttentionSetJustRemovesUser() throws Exception {
    PushOneCommit.Result r = createChange();
    // implictly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());

    ReviewInput reviewInput =
        ReviewInput.create()
            .reviewer(user.email())
            .removeUserFromAttentionSet(user.email(), "reason");

    change(r).current().review(reviewInput);

    // Attention set updates that relate to the admin (the person who replied) are filtered out.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void cantAddAndRemoveSameUser() throws Exception {
    PushOneCommit.Result r = createChange();
    ReviewInput reviewInput =
        ReviewInput.create()
            .removeUserFromAttentionSet(user.email(), "reason")
            .addUserToAttentionSet(user.username(), "reason");

    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> change(r).current().review(reviewInput));

    assertThat(exception.getMessage())
        .isEqualTo(
            "user1 can not be added/removed twice, and can not be added and removed at the same"
                + " time");
  }

  @Test
  public void cantRemoveSameUserTwice() throws Exception {
    PushOneCommit.Result r = createChange();
    ReviewInput reviewInput =
        ReviewInput.create()
            .removeUserFromAttentionSet(user.email(), "reason1")
            .removeUserFromAttentionSet(user.username(), "reason2");

    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> change(r).current().review(reviewInput));

    assertThat(exception.getMessage())
        .isEqualTo(
            "user1 can not be added/removed twice, and can not be added and removed at the same"
                + " time");
  }

  @Test
  public void reviewDoesNotAddReviewerWithoutAutomaticRules() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    ReviewInput reviewInput = ReviewInput.recommend().blockAutomaticAttentionSetRules();

    change(r).current().review(reviewInput);
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void reviewDoesNotAddReviewer() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    ReviewInput reviewInput = ReviewInput.recommend();

    change(r).current().review(reviewInput);
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void cantAddSameUserTwice() throws Exception {
    PushOneCommit.Result r = createChange();
    ReviewInput reviewInput =
        ReviewInput.create()
            .addUserToAttentionSet(user.email(), "reason1")
            .addUserToAttentionSet(user.username(), "reason2");

    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> change(r).current().review(reviewInput));

    assertThat(exception.getMessage())
        .isEqualTo(
            "user1 can not be added/removed twice, and can not be added and removed at the same"
                + " time");
  }

  @Test
  public void reviewRemoveFromAttentionSetWhileMarkingReadyForReviewJustRemovesUser()
      throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    change(r).addReviewer(user.email());
    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "reason"));

    ReviewInput reviewInput =
        ReviewInput.create().setReady(true).removeUserFromAttentionSet(user.email(), "reason");

    change(r).current().review(reviewInput);

    // Attention set updates that relate to the admin (the person who replied) are filtered out.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void reviewAddToAttentionSetWhileMarkingWorkInProgressJustAddsUser() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addReviewer(user.email());

    ReviewInput reviewInput =
        ReviewInput.create().setWorkInProgress(true).addUserToAttentionSet(user.email(), "reason");

    change(r).attention(user.email()).remove(new AttentionSetInput("removal"));
    change(r).current().review(reviewInput);

    // Attention set updates that relate to the admin (the person who replied) are filtered out.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void reviewRemovesUserFromAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(admin.email(), "reason"));

    ReviewInput reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("removed on reply");
  }

  @Test
  public void reviewAddUserToAttentionSetWhileReplyingJustAddsUser() throws Exception {
    PushOneCommit.Result r = createChange();

    ReviewInput reviewInput = ReviewInput.create().addUserToAttentionSet(admin.email(), "reason");
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void reviewWhileAddingThemselvesAsReviewerStillRemovesThem() throws Exception {
    PushOneCommit.Result r = createChange();

    requestScopeOperations.setApiUser(user.id());

    // add the user to the attention set.
    change(r)
        .current()
        .review(
            ReviewInput.create()
                .reviewer(user.email(), ReviewerState.CC, true)
                .addUserToAttentionSet(user.email(), "reason"));

    // add the user as reviewer but still be removed on reply.
    ReviewInput reviewInput = ReviewInput.create().reviewer(user.email());
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("removed on reply");
  }

  @Test
  public void reviewWhileAddingThemselvesAsReviewerDoesNotAddThem() throws Exception {
    PushOneCommit.Result r = createChange();

    requestScopeOperations.setApiUser(user.id());

    ReviewInput reviewInput = ReviewInput.create().reviewer(user.email());
    change(r).current().review(reviewInput);

    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void repliesAddsOwner() throws Exception {
    PushOneCommit.Result r = createChange();

    requestScopeOperations.setApiUser(user.id());

    ReviewInput reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Someone else replied on the change");
  }

  @Test
  public void robotRepliesDoNotAddToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addReviewer(user.email());

    TestAccount robot =
        accountCreator.create(
            "robot1",
            "robot1@example.com",
            "Ro Bot",
            "Ro",
            ServiceUserClassifier.SERVICE_USERS,
            "Administrators");
    requestScopeOperations.setApiUser(robot.id());

    ReviewInput reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    assertThat(getAttentionSetUpdatesForUser(r, admin)).isEmpty();
  }

  @Test
  public void repliesDoNotAddOwnerWhenChangeIsClosed() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).abandon();
    requestScopeOperations.setApiUser(user.id());

    ReviewInput reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    assertThat(getAttentionSetUpdatesForUser(r, admin)).isEmpty();
  }

  @Test
  public void repliesDoNotAddOwnerWhenChangeIsWorkInProgress() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    requestScopeOperations.setApiUser(user.id());

    ReviewInput reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    assertThat(getAttentionSetUpdatesForUser(r, admin)).isEmpty();
  }

  @Test
  public void repliesDoNotAddOwnerWhenChangeIsBecomingWorkInProgress() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(accountCreator.admin2().id());

    ReviewInput reviewInput = ReviewInput.create().setWorkInProgress(true);
    change(r).current().review(reviewInput);

    assertThat(getAttentionSetUpdatesForUser(r, admin)).isEmpty();
  }

  @Test
  public void repliesAddOwnerWhenChangeIsBecomingReadyForReview() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setWorkInProgress();
    requestScopeOperations.setApiUser(accountCreator.admin2().id());

    ReviewInput reviewInput = ReviewInput.create().setReady(true);
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Someone else replied on the change");
  }

  @Test
  public void repliesAddsOwnerAndUploader() throws Exception {
    // Create change with owner: admin
    PushOneCommit.Result r = createChange();
    r = amendChangeWithUploader(r, project, user);

    TestAccount user2 = accountCreator.user2();
    requestScopeOperations.setApiUser(user2.id());

    change(r).attention(user.email()).remove(new AttentionSetInput("reason"));
    ReviewInput reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    reviewInput = new ReviewInput();
    change(r).current().review(reviewInput);

    // Uploader added
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Someone else replied on the change");

    // Owner added
    attentionSet = Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Someone else replied on the change");
  }

  @Test
  public void reviewIgnoresRobotCommentsForAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    testCommentHelper.addRobotComment(
        r.getChangeId(),
        TestCommentHelper.createRobotCommentInputWithMandatoryFields(Patch.COMMIT_MSG));

    requestScopeOperations.setApiUser(admin.id());
    change(r)
        .current()
        .review(
            reviewInReplyToComment(
                Iterables.getOnlyElement(
                        gApi.changes().id(r.getChangeId()).current().robotCommentsAsList())
                    .id));
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void reviewAddsAllUsersInCommentThread() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    change(r).current().review(reviewWithComment());

    TestAccount user2 = accountCreator.user2();

    requestScopeOperations.setApiUser(user2.id());
    change(r)
        .current()
        .review(
            reviewInReplyToComment(
                Iterables.getOnlyElement(
                        gApi.changes().id(r.getChangeId()).current().commentsAsList())
                    .id));

    change(r).attention(user.email()).remove(new AttentionSetInput("removal"));
    requestScopeOperations.setApiUser(admin.id());
    change(r)
        .current()
        .review(
            reviewInReplyToComment(
                gApi.changes().id(r.getChangeId()).current().commentsAsList().get(1).id));

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet)
        .hasReasonThat()
        .isEqualTo("Someone else replied on a comment you posted");

    attentionSet = Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user2));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user2.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet)
        .hasReasonThat()
        .isEqualTo("Someone else replied on a comment you posted");
  }

  @Test
  public void reviewAddsAllUsersInCommentThreadWhenOriginalCommentIsARobotComment()
      throws Exception {
    PushOneCommit.Result result = createChange();
    testCommentHelper.addRobotComment(
        result.getChangeId(),
        TestCommentHelper.createRobotCommentInputWithMandatoryFields(Patch.COMMIT_MSG));

    requestScopeOperations.setApiUser(user.id());
    // Reply to the robot comment.
    change(result)
        .current()
        .review(
            reviewInReplyToComment(
                Iterables.getOnlyElement(
                        gApi.changes().id(result.getChangeId()).current().robotCommentsAsList())
                    .id));

    requestScopeOperations.setApiUser(admin.id());
    // Reply to the human comment. which was a reply to the robot comment.
    change(result)
        .current()
        .review(
            reviewInReplyToComment(
                Iterables.getOnlyElement(
                        gApi.changes().id(result.getChangeId()).current().commentsAsList())
                    .id));

    // The user which replied to the robot comment was added to the attention set.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(result, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet)
        .hasReasonThat()
        .isEqualTo("Someone else replied on a comment you posted");
  }

  @Test
  public void reviewAddsAllUsersInCommentThreadEvenOfDifferentChildBranch() throws Exception {
    Account.Id changeOwner = accountOperations.newAccount().create();
    Change.Id changeId = changeOperations.newChange().owner(changeOwner).create();
    Account.Id user1 = accountOperations.newAccount().create();
    Account.Id user2 = accountOperations.newAccount().create();
    Account.Id user3 = accountOperations.newAccount().create();
    Account.Id user4 = accountOperations.newAccount().create();
    // Add users as reviewers.
    gApi.changes().id(changeId.get()).addReviewer(user1.toString());
    gApi.changes().id(changeId.get()).addReviewer(user2.toString());
    gApi.changes().id(changeId.get()).addReviewer(user3.toString());
    gApi.changes().id(changeId.get()).addReviewer(user4.toString());
    // Add a comment thread with branches. Such threads occur if people reply in parallel without
    // having seen/loaded the reply of another person.
    String root =
        changeOperations.change(changeId).currentPatchset().newComment().author(user1).create();
    String sibling1 =
        changeOperations
            .change(changeId)
            .currentPatchset()
            .newComment()
            .author(user2)
            .parentUuid(root)
            .create();
    String sibling2 =
        changeOperations
            .change(changeId)
            .currentPatchset()
            .newComment()
            .author(user3)
            .parentUuid(root)
            .create();
    changeOperations
        .change(changeId)
        .currentPatchset()
        .newComment()
        .author(user4)
        .parentUuid(sibling2)
        .create();
    // Clear the attention set. Necessary as we used Gerrit APIs above which affect the attention
    // set.
    AttentionSetInput clearAttention = new AttentionSetInput("clear attention set");
    gApi.changes().id(changeId.get()).attention(user1.toString()).remove(clearAttention);
    gApi.changes().id(changeId.get()).attention(user2.toString()).remove(clearAttention);
    gApi.changes().id(changeId.get()).attention(user3.toString()).remove(clearAttention);
    gApi.changes().id(changeId.get()).attention(user4.toString()).remove(clearAttention);

    requestScopeOperations.setApiUser(changeOwner);
    // Simulate that this reply is a child of sibling1 and thus parallel to sibling2 and its child.
    gApi.changes().id(changeId.get()).current().review(reviewInReplyToComment(sibling1));

    List<AttentionSetUpdate> attentionSetUpdates = getAttentionSetUpdates(changeId);
    assertThat(attentionSetUpdates)
        .comparingElementsUsing(hasAccount())
        .containsExactly(user1, user2, user3, user4);
  }

  @Test
  public void reviewAddsAllUsersInCommentThreadWhenPostedAsDraft() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    change(r).current().review(reviewWithComment());

    requestScopeOperations.setApiUser(admin.id());
    testCommentHelper.addDraft(
        r.getChangeId(),
        testCommentHelper.newDraft(
            "message",
            Iterables.getOnlyElement(gApi.changes().id(r.getChangeId()).current().commentsAsList())
                .id));

    ReviewInput reviewInput = new ReviewInput();
    reviewInput.drafts = ReviewInput.DraftHandling.PUBLISH;
    change(r).current().review(reviewInput);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet)
        .hasReasonThat()
        .isEqualTo("Someone else replied on a comment you posted");
  }

  @Test
  public void reviewDoesNotAddUsersInACommentThreadThatAreNotActiveInTheChange() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    change(r).current().review(reviewWithComment());
    change(r).reviewer(user.id().toString()).remove(new DeleteReviewerInput());

    requestScopeOperations.setApiUser(admin.id());
    change(r)
        .current()
        .review(
            reviewInReplyToComment(
                Iterables.getOnlyElement(
                        gApi.changes().id(r.getChangeId()).current().commentsAsList())
                    .id));

    // The user was to be added, but was not added since that user is no longer a
    // reviewer/cc/owner/uploader.
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void ownerRepliesWhileRemovingReviewerRemovesFromAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addReviewer(user.email());

    ReviewInput reviewInput = ReviewInput.create().reviewer(user.email(), ReviewerState.CC, false);
    change(r).current().review(reviewInput);

    // cc removed
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer/Cc was removed");
  }

  @Test
  public void uploaderRepliesAddsOwner() throws Exception {
    PushOneCommit.Result r = createChange();
    r = amendChangeWithUploader(r, project, user);

    // Add reviewer and cc
    TestAccount reviewer = accountCreator.user2();
    TestAccount cc = accountCreator.admin2();
    ReviewInput reviewInput = new ReviewInput().blockAutomaticAttentionSetRules();
    reviewInput = reviewInput.reviewer(reviewer.email());
    reviewInput.reviewer(cc.email(), ReviewerState.CC, false);
    change(r).current().review(reviewInput);

    requestScopeOperations.setApiUser(user.id());

    change(r).current().review(new ReviewInput());

    // Reviewer and CC not added since the uploader didn't reply to their comments
    assertThat(getAttentionSetUpdatesForUser(r, cc)).isEmpty();
    assertThat(getAttentionSetUpdatesForUser(r, reviewer)).isEmpty();

    // Owner added
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Someone else replied on the change");
  }

  @Test
  public void repliesWhileAddingAsReviewerStillRemovesUser() throws Exception {
    PushOneCommit.Result r = createChange();
    // implictly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());

    change(r).addToAttentionSet(new AttentionSetInput(user.email(), "remove"));

    requestScopeOperations.setApiUser(user.id());
    ReviewInput reviewInput = ReviewInput.recommend();
    change(r).current().review(reviewInput);

    // reviewer removed
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("removed on reply");
  }

  @Test
  public void attentionSetUnchangedWithIgnoreAutomaticAttentionSetRules() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(admin.email(), "reason"));
    change(r)
        .current()
        .review(
            ReviewInput.create()
                .reviewer(admin.email(), ReviewerState.CC, false)
                .blockAutomaticAttentionSetRules());

    // admin is still in the attention set, although replies remove from attention set, and removing
    // from reviewer also should remove from attention set.
    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void ownerNotAddedAsReviewerToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).current().review(ReviewInput.approve());
    assertThat(getAttentionSetUpdatesForUser(r, admin)).isEmpty();
  }

  @Test
  public void ownerNotAddedAsReviewerToAttentionSetWithoutAutomaticRules() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).current().review(ReviewInput.approve().blockAutomaticAttentionSetRules());
    assertThat(getAttentionSetUpdatesForUser(r, admin)).isEmpty();
  }

  @Test
  public void uploaderNotAddedAsReviewerToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    amendChangeWithUploader(r, project, user);
    requestScopeOperations.setApiUser(user.id());

    change(r).current().review(ReviewInput.recommend());
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void uploaderNotAddedAsReviewerToAttentionSetWithoutAutomaticRules() throws Exception {
    PushOneCommit.Result r = createChange();
    amendChangeWithUploader(r, project, user);
    requestScopeOperations.setApiUser(user.id());

    change(r).current().review(ReviewInput.recommend().blockAutomaticAttentionSetRules());
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void attentionSetStillChangesWithIgnoreAutomaticAttentionSetRulesWithInputList()
      throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).addToAttentionSet(new AttentionSetInput(admin.email(), "reason"));
    change(r)
        .current()
        .review(
            ReviewInput.create()
                .removeUserFromAttentionSet(admin.email(), "removed")
                .blockAutomaticAttentionSetRules());

    // Admin is still removed although we block default attention set rules, since we remove
    // the admin manually.
    AttentionSetUpdate attentionSet = Iterables.getOnlyElement(r.getChange().attentionSet());
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("removed");
  }

  @Test
  public void robotsNotAddedToAttentionSet() throws Exception {
    TestAccount robot =
        accountCreator.create(
            "robot1", "robot1@example.com", "Ro Bot", "Ro", ServiceUserClassifier.SERVICE_USERS);
    PushOneCommit.Result r = createChange();
    // Make the robot active on the change.
    change(r).addReviewer(robot.email());

    // Throw an error when adding a robot explicitly.
    BadRequestException exception =
        assertThrows(
            BadRequestException.class,
            () -> change(r).addToAttentionSet(new AttentionSetInput(robot.email(), "reason")));
    assertThat(exception.getMessage())
        .isEqualTo(
            "robot1@example.com is a robot, and robots can't be added to the attention set.");

    // Robots are not added implicitly.
    change(r).addReviewer(robot.email());
    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void robotAddingAReviewerChangeAttentionSet() throws Exception {
    TestAccount robot =
        accountCreator.create(
            "robot2", "robot2@example.com", "Ro Bot", "Ro", ServiceUserClassifier.SERVICE_USERS);
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(robot.id());
    change(r).addReviewer(user.id().toString());

    // Bots can still change the attention set, just not when replying.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");
  }

  @Test
  public void robotReviewDoesNotChangeAttentionSet() throws Exception {
    TestAccount robot =
        accountCreator.create(
            "robot2", "robot2@example.com", "Ro Bot", "Ro", ServiceUserClassifier.SERVICE_USERS);
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(robot.id());
    change(r).current().review(ReviewInput.recommend());

    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void robotReviewWithNegativeLabelDoesNotAddOwnerOnWorkInProgressChanges()
      throws Exception {
    TestAccount robot =
        accountCreator.create(
            "robot2", "robot2@example.com", "Ro Bot", "Ro", ServiceUserClassifier.SERVICE_USERS);
    PushOneCommit.Result r = createChange();
    gApi.changes().id(r.getChangeId()).setWorkInProgress();

    requestScopeOperations.setApiUser(robot.id());
    change(r).current().review(ReviewInput.dislike());

    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void robotReviewWithNegativeLabelAddsOwner() throws Exception {
    TestAccount robot =
        accountCreator.create(
            "robot2", "robot2@example.com", "Ro Bot", "Ro", ServiceUserClassifier.SERVICE_USERS);
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(robot.id());
    change(r).current().review(ReviewInput.dislike());

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("A robot voted negatively on a label");
  }

  @Test
  public void robotReviewWithNegativeLabelDoesntAddOwnerIfChangeIsMerged() throws Exception {
    TestAccount robot =
        accountCreator.create(
            "robot2", "robot2@example.com", "Ro Bot", "Ro", ServiceUserClassifier.SERVICE_USERS);

    PushOneCommit.Result r = createChange();

    // The robot votes with Code-Review-1 on patch set 1.
    // Without this vote the robot cannot (re-)apply a negative vote on the change after it was
    // merged change later.
    requestScopeOperations.setApiUser(robot.id());
    change(r).revision(1).review(ReviewInput.dislike());

    // Amend the change so that patch set 2 gets created.
    requestScopeOperations.setApiUser(admin.id());
    amendChange(r.getChangeId()).assertOkStatus();

    // Approve the change.
    approve(r.getChangeId());

    // User adds a comment so that the admin user is added to the attention set.
    // This has to be a comment from a user, since comments from robots do not trigger attention set
    // updates.
    requestScopeOperations.setApiUser(user.id());
    ReviewInput reviewInput = new ReviewInput();
    reviewInput.message = "A comment";
    change(r).current().review(reviewInput);

    // Verify that the admin user was added to the attention set.
    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Someone else replied on the change");

    // Submit the change.
    requestScopeOperations.setApiUser(admin.id());
    change(r).current().submit();

    // Verify that the attention set was cleared on submit.
    attentionSet = Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was submitted");

    // Re-apply the negative robot vote on patch set 1.
    // Note it's possible to a apply a negative vote on merged changes if it wasn't already present
    // since we disallow downgrading votes on merged changes (e.g. downgrade from not present aka 0
    // to -1 is not allowed).
    requestScopeOperations.setApiUser(robot.id());
    change(r).revision(1).review(ReviewInput.dislike());

    // Verify that re-applying the negative robot vote on patch set 1 didn't add the admin user
    // back to the attention set.
    attentionSet = Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Change was submitted");
  }

  @Test
  public void robotCommentDoesNotAddOwnerOnClosedChanges() throws Exception {
    TestAccount robot =
        accountCreator.create(
            "robot2", "robot2@example.com", "Ro Bot", "Ro", ServiceUserClassifier.SERVICE_USERS);
    PushOneCommit.Result r = createChange();
    gApi.changes().id(r.getChangeId()).abandon();

    requestScopeOperations.setApiUser(robot.id());
    ReviewInput reviewInput = new ReviewInput();
    ReviewInput.RobotCommentInput robotCommentInput =
        TestCommentHelper.createRobotCommentInputWithMandatoryFields("a.txt");
    reviewInput.robotComments = ImmutableMap.of("a.txt", ImmutableList.of(robotCommentInput));
    change(r).current().review(reviewInput);

    assertThat(r.getChange().attentionSet()).isEmpty();
  }

  @Test
  public void robotCanChangeAttentionSetExplicitly() throws Exception {
    TestAccount robot =
        accountCreator.create(
            "robot2", "robot2@example.com", "Ro Bot", "Ro", ServiceUserClassifier.SERVICE_USERS);
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(robot.id());
    change(r).current().review(new ReviewInput().addUserToAttentionSet(admin.email(), "reason"));

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("reason");
  }

  @Test
  public void addUsersToAttentionSetInPrivateChanges() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setPrivate(true);

    // implictly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");
  }

  @Test
  public void addUsersAsReviewerAndAttentionSetInPrivateChanges() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).setPrivate(true);
    change(r).current().review(new ReviewInput().reviewer(user.email()));

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Reviewer was added");
  }

  @Test
  public void addToAttentionSetEmail_withTemplateReason() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());
    String templateReason = "Added by " + AccountTemplateUtil.getAccountTemplate(user.id());
    int accountId =
        change(r)
            .addToAttentionSet(new AttentionSetInput(admin.email(), templateReason))
            ._accountId;

    assertThat(accountId).isEqualTo(admin.id().get());
    String emailBody = Iterables.getOnlyElement(sender.getMessages()).body();
    assertThat(emailBody)
        .contains(
            String.format(
                "%s requires the attention of %s to this change.\n The reason is: Added by %s.",
                user.fullName(), admin.fullName(), user.getNameEmail()));
  }

  @Test
  public void removeFromAttentionSetEmail_withTemplateReason() throws Exception {
    PushOneCommit.Result r = createChange();
    // implicitly adds the user to the attention set when adding as reviewer
    change(r).addReviewer(user.email());
    sender.clear();
    requestScopeOperations.setApiUser(user.id());

    String templateReason = "Removed by " + AccountTemplateUtil.getAccountTemplate(user.id());
    change(r).attention(user.id().toString()).remove(new AttentionSetInput(templateReason));

    String emailBody = Iterables.getOnlyElement(sender.getMessages()).body();
    assertThat(emailBody)
        .contains(
            String.format(
                "%s removed themselves from the attention set of this change.\n"
                    + " The reason is: Removed by %s.",
                user.fullName(), user.getNameEmail()));
  }

  @Test
  public void attentionSetEmailFooter() throws Exception {
    PushOneCommit.Result r = createChange();

    // Add user to attention set. They receive an email with the attention footer.
    change(r).addReviewer(user.id().toString());
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .contains("Gerrit-Attention: " + user.fullName());
    sender.clear();

    // Irrelevant reply, User is still in the attention set.
    change(r).current().review(ReviewInput.approve());
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .contains("Gerrit-Attention: " + user.fullName());
    sender.clear();

    // Abandon the change which removes user from attention set; there is an email but without the
    // attention footer.
    change(r).abandon();
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .doesNotContain("Gerrit-Attention: " + user.fullName());
    sender.clear();
  }

  @Test
  public void attentionSetEmailHeader() throws Exception {
    PushOneCommit.Result r = createChange();
    TestAccount user2 = accountCreator.user2();

    // The pattern ensures the header mentions the attention set requirements in any order.
    Pattern attentionSetHeaderPattern =
        Pattern.compile(
            String.format(
                "Attention is currently required from: (%s|%s), (%s|%s).",
                user2.fullName(), user.fullName(), user.fullName(), user2.fullName()));
    // Add user and user2 to the attention set.
    change(r)
        .current()
        .review(
            ReviewInput.create().reviewer(user.email()).reviewer(accountCreator.user2().email()));
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .containsMatch(attentionSetHeaderPattern);
    assertThat(Iterables.getOnlyElement(sender.getMessages()).htmlBody())
        .containsMatch(attentionSetHeaderPattern);
    sender.clear();

    // Irrelevant reply, User and User2 are still in the attention set.
    change(r).current().review(ReviewInput.approve());
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .containsMatch(attentionSetHeaderPattern);
    assertThat(Iterables.getOnlyElement(sender.getMessages()).htmlBody())
        .containsMatch(attentionSetHeaderPattern);
    sender.clear();

    // Abandon the change which removes user from attention set; there is an email but without the
    // attention footer.
    change(r).abandon();
    assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
        .doesNotContain("Attention is currently required");
    assertThat(Iterables.getOnlyElement(sender.getMessages()).htmlBody())
        .doesNotContain("Attention is currently required");
    sender.clear();
  }

  @Test
  public void attentionSetWithEmailFilter() throws Exception {
    PushOneCommit.Result r = createChange();

    // Add preference for the user such that they only receive an email on changes that require
    // their attention.
    setEmailStrategyForUser(EmailStrategy.ATTENTION_SET_ONLY);

    // Add user to attention set. They receive an email since they are in the attention set.
    change(r).addReviewer(user.id().toString());
    assertThat(sender.getMessages()).isNotEmpty();
    sender.clear();

    // Irrelevant reply, User is still in the attention set, thus got another email.
    change(r).current().review(ReviewInput.approve());
    assertThat(sender.getMessages()).isNotEmpty();
    sender.clear();

    // Abandon the change which removes user from attention set; the user doesn't receive an email
    // since they are not in the attention set.
    change(r).abandon();
    assertThat(sender.getMessages()).isEmpty();
  }

  @Test
  public void attentionSetWithEmailFilterFiltersNewPatchsets() throws Exception {
    PushOneCommit.Result r = createChange();

    // Add preference for the user such that they only receive an email on changes that require
    // their attention.
    requestScopeOperations.setApiUser(user.id());
    GeneralPreferencesInfo prefs = gApi.accounts().self().getPreferences();
    prefs.emailStrategy = EmailStrategy.ATTENTION_SET_ONLY;
    gApi.accounts().self().setPreferences(prefs);
    requestScopeOperations.setApiUser(admin.id());

    // Add user to reviewers but not to the attention set
    change(r)
        .current()
        .review(
            ReviewInput.create()
                .reviewer(user.email())
                .removeUserFromAttentionSet(user.email(), "reason"));
    sender.clear();

    // amending a change doesn't send an email when user is not in the attention set.
    amendChange(r.getChangeId());
    assertThat(sender.getMessages()).isEmpty();
  }

  @Test
  public void attentionSetWithEmailFilterStillReceivesSubmitEmail() throws Exception {
    PushOneCommit.Result r = createChange();

    // Add preference for the user such that they only receive an email on changes that require
    // their attention.
    requestScopeOperations.setApiUser(user.id());
    GeneralPreferencesInfo prefs = gApi.accounts().self().getPreferences();
    prefs.emailStrategy = EmailStrategy.ATTENTION_SET_ONLY;
    gApi.accounts().self().setPreferences(prefs);
    requestScopeOperations.setApiUser(admin.id());

    // Add user to reviewers but not to the attention set
    change(r)
        .current()
        .review(
            ReviewInput.approve()
                .reviewer(user.email())
                .removeUserFromAttentionSet(user.email(), "reason"));
    sender.clear();

    // submitting the change sends an email even when user is not in the attention set.
    change(r).current().submit();
    assertThat(sender.getMessages()).isNotEmpty();
  }

  @Test
  public void attentionSetWithEmailFilterImpactingOnlyChangeEmails() throws Exception {
    // Add preference for the user such that they only receive an email on changes that require
    // their attention.
    setEmailStrategyForUser(EmailStrategy.ATTENTION_SET_ONLY);

    // Ensure emails that don't relate to changes are still sent.
    gApi.accounts().id(user.id().get()).generateHttpPassword();
    assertThat(sender.getMessages()).isNotEmpty();
  }

  @Test
  public void cannotAddIrrelevantUserToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();

    BadRequestException exception =
        assertThrows(
            BadRequestException.class,
            () -> change(r).addToAttentionSet(new AttentionSetInput(user.email(), "reason")));
    assertThat(exception.getMessage())
        .isEqualTo(
            String.format(
                "%s doesn't exist or is not active on the change as an owner, uploader, reviewer, "
                    + "or cc so they can't be added to the attention set",
                user.email()));
  }

  @Test
  public void cannotAddNonExistingUserToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();

    BadRequestException exception =
        assertThrows(
            BadRequestException.class,
            () -> change(r).addToAttentionSet(new AttentionSetInput("INVALID USER", "reason")));
    assertThat(exception.getMessage())
        .isEqualTo(
            "INVALID USER doesn't exist or is not active on the change as an owner,"
                + " uploader, reviewer, or cc so they can't be added to the attention set");
  }

  @Test
  public void cannotRemoveIrrelevantUserToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();

    BadRequestException exception =
        assertThrows(
            BadRequestException.class,
            () -> change(r).attention(user.email()).remove(new AttentionSetInput("reason")));
    assertThat(exception.getMessage())
        .isEqualTo(
            String.format(
                "%s doesn't exist or is not active on the change as an owner, uploader, reviewer, "
                    + "or cc so they can't be added to the attention set",
                user.email()));
  }

  @Test
  public void cannotRemoveIrrelevantUserToAttentionSetWithUserInInput() throws Exception {
    PushOneCommit.Result r = createChange();

    BadRequestException exception =
        assertThrows(
            BadRequestException.class,
            () ->
                change(r)
                    .attention(user.email())
                    .remove(new AttentionSetInput(user.email(), "reason")));
    assertThat(exception.getMessage())
        .isEqualTo(
            String.format(
                "%s doesn't exist or is not active on the change as an owner, uploader, reviewer, "
                    + "or cc so they can't be added to the attention set",
                user.email()));
  }

  @Test
  public void cannotRemoveNonExistingUser() throws Exception {
    PushOneCommit.Result r = createChange();

    BadRequestException exception =
        assertThrows(
            BadRequestException.class,
            () -> change(r).attention("INVALID USER").remove(new AttentionSetInput("reason")));
    assertThat(exception.getMessage())
        .isEqualTo(
            "INVALID USER doesn't exist or is not active on the change as an owner,"
                + " uploader, reviewer, or cc so they can't be added to the attention set");
  }

  @Test
  public void irrelevantUsersAddedToAttentionSetAreIgnoredOnReply() throws Exception {
    PushOneCommit.Result r = createChange();

    change(r).current().review(ReviewInput.create().addUserToAttentionSet(user.email(), "reason"));
    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void newReviewerCanBeAddedToTheAttentionSetManually() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r)
        .current()
        .review(
            ReviewInput.create()
                .reviewer(user.email())
                .addUserToAttentionSet(user.email(), "reason")
                .blockAutomaticAttentionSetRules());
    assertThat(Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user)).operation())
        .isEqualTo(Operation.ADD);
  }

  @Test
  public void newReviewerCanBeAddedToTheAttentionSetAutomatically() throws Exception {
    PushOneCommit.Result r = createChange();
    change(r).current().review(ReviewInput.create().reviewer(user.email()));
    assertThat(Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user)).operation())
        .isEqualTo(Operation.ADD);
  }

  @GerritConfig(name = "accounts.visibility", value = "NONE")
  public void onReplyCanAddInvisibleUsersToAttentionSetOnVisibleChanges() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());

    // admin is invisible to the user, but they can still add them to the attention set since they
    // see the change.
    change(r).current().review(ReviewInput.create().addUserToAttentionSet(admin.email(), "reason"));
    assertThat(Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin)).operation())
        .isEqualTo(Operation.ADD);
  }

  @Test
  public void onReplyNonExistingUsersAreSilentlyIgnored() throws Exception {
    PushOneCommit.Result r = createChange();

    change(r)
        .current()
        .review(ReviewInput.create().addUserToAttentionSet("INVALID USER", "reason"));
    assertThat(getAttentionSetUpdates(r.getChange().getId())).isEmpty();
  }

  @Test
  public void usersNotPartOfTheChangeAreNeverInTheAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    gApi.changes().id(r.getChangeId()).addReviewer(user.email());

    AttentionSetUpdate attentionSetUpdate =
        Iterables.getOnlyElement(getAttentionSetUpdates(r.getChange().getId()));
    assertThat(attentionSetUpdate).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSetUpdate).hasOperationThat().isEqualTo(Operation.ADD);

    ReviewInput reviewInput = ReviewInput.create();
    reviewInput.reviewer(user.email(), ReviewerState.REMOVED, /* confirmed= */ true);
    reviewInput.ignoreAutomaticAttentionSetRules = true;
    change(r).current().review(reviewInput);

    // user removed from the attention set although we ignored automatic attention set rules.
    attentionSetUpdate = Iterables.getOnlyElement(getAttentionSetUpdates(r.getChange().getId()));
    assertThat(attentionSetUpdate).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSetUpdate).hasOperationThat().isEqualTo(Operation.REMOVE);
    assertThat(attentionSetUpdate)
        .hasReasonThat()
        .isEqualTo("Only change owner, uploader, reviewers, and cc can be in the attention set");
  }

  @Test
  @GerritConfig(name = "accounts.visibility", value = "NONE")
  public void canModifyAttentionSetForInvisibleUsersOnVisibleChanges() throws Exception {
    PushOneCommit.Result r = createChange();
    requestScopeOperations.setApiUser(user.id());

    // admin is invisible to the user, but they can still add them to the attention set since they
    // see the change.
    change(r).addToAttentionSet(new AttentionSetInput(admin.email(), "reason"));
    assertThat(Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin)).operation())
        .isEqualTo(Operation.ADD);

    // admin is invisible to the user, but they can still remove them to the attention set since
    // they see the change.
    change(r).attention(admin.id().toString()).remove(new AttentionSetInput("removed"));
    assertThat(Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin)).operation())
        .isEqualTo(Operation.REMOVE);
  }

  @Test
  public void deleteSelfVotesDoesNotAddToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    approve(r.getChangeId());
    gApi.changes()
        .id(r.getChangeId())
        .current()
        .reviewer(admin.id().toString())
        .deleteVote(LabelId.CODE_REVIEW);

    assertThat(getAttentionSetUpdates(r.getChange().getId())).isEmpty();
  }

  @Test
  public void deleteVotesDoesNotAffectAttentionSetWhenIgnoreAutomaticRulesIsSet() throws Exception {
    PushOneCommit.Result r = createChange();

    requestScopeOperations.setApiUser(user.id());
    recommend(r.getChangeId());

    requestScopeOperations.setApiUser(admin.id());

    DeleteVoteInput deleteVoteInput = new DeleteVoteInput();
    deleteVoteInput.label = LabelId.CODE_REVIEW;

    // set this to true to not change the attention set.
    deleteVoteInput.ignoreAutomaticAttentionSetRules = true;

    gApi.changes()
        .id(r.getChangeId())
        .current()
        .reviewer(user.id().toString())
        .deleteVote(deleteVoteInput);

    assertThat(getAttentionSetUpdatesForUser(r, user)).isEmpty();
  }

  @Test
  public void deleteVotesOfOthersAddThemToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();

    requestScopeOperations.setApiUser(user.id());
    recommend(r.getChangeId());

    requestScopeOperations.setApiUser(admin.id());
    gApi.changes()
        .id(r.getChangeId())
        .current()
        .reviewer(user.id().toString())
        .deleteVote(LabelId.CODE_REVIEW);

    AttentionSetUpdate attentionSet =
        Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user));
    assertThat(attentionSet).hasAccountIdThat().isEqualTo(user.id());
    assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
    assertThat(attentionSet).hasReasonThat().isEqualTo("Their vote was deleted");
  }

  @Test
  public void accountsWithNoReadPermissionIgnoredOnReply() throws Exception {
    // Create a group with user.
    GroupInput groupInput = new GroupInput();
    groupInput.name = name("User");
    groupInput.members = ImmutableList.of(String.valueOf(user.id()));
    GroupInfo group = gApi.groups().create(groupInput).get();

    PushOneCommit.Result r = createChange();
    gApi.changes().id(r.getChangeId()).addReviewer(user.email());

    // remove read permission for user.
    projectOperations
        .project(project)
        .forUpdate()
        .add(block(Permission.READ).ref("refs/*").group(AccountGroup.uuid(group.id)))
        .update();

    // removing user without permissions from attention set is allowed on reply.
    gApi.changes()
        .id(r.getChangeId())
        .current()
        .review(new ReviewInput().removeUserFromAttentionSet(user.email(), "reason"));

    // Add user to attention throws an exception.
    assertThrows(
        AuthException.class,
        () -> change(r).addToAttentionSet(new AttentionSetInput(user.email(), "reason")));

    // Add user to attention set is ignored on reply.
    gApi.changes()
        .id(r.getChangeId())
        .current()
        .review(new ReviewInput().addUserToAttentionSet(user.email(), "reason"));
    assertThat(Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, user)).operation())
        .isEqualTo(Operation.REMOVE);
  }

  @Test
  public void outsideAttentionSet_watchProjectEmailReceived() throws Exception {
    setEmailStrategyForUser(EmailStrategy.ATTENTION_SET_ONLY);

    requestScopeOperations.setApiUser(user.id());
    watch(project.get());

    createChange();

    assertThat(sender.getMessages()).isNotEmpty();
    sender.clear();
  }

  @Test
  public void approverOfOutdatedApprovalAddedToAttentionSet() throws Exception {
    PushOneCommit.Result r = createChange();
    assertThat(r.getChange().attentionSet()).isEmpty();

    // Add an approval that gets outdated when a new patch set is created (i.e. an approval that is
    // not copied).
    requestScopeOperations.setApiUser(user.id());
    recommend(r.getChangeId());
    requestScopeOperations.setApiUser(admin.id());

    // Voting added the admin user to the attention set.
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                admin.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"));

    // Remove admin user from attention set.
    change(r).attention(admin.id().toString()).remove(new AttentionSetInput("removed"));
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.REMOVE, "removed"));

    // Amend the change, this removes the vote from user, as it is not copied to the new patch set.
    sender.clear();
    r = amendChange(r.getChangeId(), "refs/for/master", admin, testRepo);
    r.assertOkStatus();

    // Verify that the approval has been removed.
    assertThat(r.getChange().currentApprovals()).isEmpty();

    // User got added to the attention set because users approval got outdated and was removed and
    // user now needs to re-review the change and renew the approval.
    assertThat(r.getChange().attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.REMOVE, "removed"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                user.id(),
                AttentionSetUpdate.Operation.ADD,
                "Vote got outdated and was removed: Code-Review+1"));

    // Expect that the email notification contains the outdated vote.
    Message message = Iterables.getOnlyElement(sender.getMessages());
    assertThat(message.body())
        .contains(
            String.format(
                "Attention is currently required from: %s.\n"
                    + "\n"
                    + "Hello %s, \n"
                    + "\n"
                    + "I'd like you to reexamine a change."
                    + " Please visit",
                user.fullName(), user.fullName()));
    assertThat(message.body())
        .contains(
            String.format(
                "The following approvals got outdated and were removed:\n"
                    + "Code-Review+1 by %s\n",
                user.fullName()));
    assertThat(message.htmlBody())
        .contains(
            String.format(
                "<p> Attention is currently required from: %s. </p>\n"
                    + "<p>%s <strong>uploaded patch set #2</strong> to this change.</p>",
                user.fullName(), admin.fullName()));
    assertThat(message.htmlBody())
        .contains(
            String.format(
                "View Change</a></p>"
                    + "<p>The following approvals got outdated and were removed:\n"
                    + "Code-Review+1 by %s</p>",
                user.fullName()));
  }

  @Test
  public void approverOfMultipleOutdatedApprovalsAddedToAttentionSet() throws Exception {
    // Create a Verify and a Foo-Var label and allow voting on it.
    try (ProjectConfigUpdate u = updateProject(project)) {
      LabelType.Builder verified =
          labelBuilder(
              LabelId.VERIFIED, value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
      u.getConfig().upsertLabelType(verified.build());

      LabelType.Builder fooBar =
          labelBuilder("Foo-Bar", value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
      u.getConfig().upsertLabelType(fooBar.build());

      u.save();
    }
    projectOperations
        .project(project)
        .forUpdate()
        .add(
            allowLabel(LabelId.VERIFIED)
                .ref(RefNames.REFS_HEADS + "*")
                .group(REGISTERED_USERS)
                .range(-1, 1))
        .add(
            allowLabel("Foo-Bar")
                .ref(RefNames.REFS_HEADS + "*")
                .group(REGISTERED_USERS)
                .range(-1, 1))
        .update();

    PushOneCommit.Result r = createChange();
    assertThat(r.getChange().attentionSet()).isEmpty();

    // Add multiple approvals from one user that gets outdated when a new patch set is created (i.e.
    // approvals that are not copied).
    requestScopeOperations.setApiUser(user.id());
    recommend(r.getChangeId());
    gApi.changes()
        .id(r.getChangeId())
        .current()
        .review(new ReviewInput().label(LabelId.VERIFIED, 1));
    gApi.changes().id(r.getChangeId()).current().review(new ReviewInput().label("Foo-Bar", -1));
    requestScopeOperations.setApiUser(admin.id());

    // Voting added the admin user to the attention set.
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                admin.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"));

    // Remove admin user from attention set.
    change(r).attention(admin.id().toString()).remove(new AttentionSetInput("removed"));
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.REMOVE, "removed"));

    // Amend the change, this removes the vote from user, as it is not copied to the new patch set.
    sender.clear();
    r = amendChange(r.getChangeId(), "refs/for/master", admin, testRepo);
    r.assertOkStatus();

    // Verify that the approvals have been removed.
    assertThat(r.getChange().currentApprovals()).isEmpty();

    // User got added to the attention set because users approvals got outdated and were removed and
    // user now needs to re-review the change and renew the approvals.
    assertThat(r.getChange().attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.REMOVE, "removed"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                user.id(),
                AttentionSetUpdate.Operation.ADD,
                "Votes got outdated and were removed: Code-Review+1, Foo-Bar-1, Verified+1"));

    // Expect that the email notification contains the outdated votes.
    Message message = Iterables.getOnlyElement(sender.getMessages());
    assertThat(message.body())
        .contains(
            String.format(
                "Attention is currently required from: %s.\n"
                    + "\n"
                    + "Hello %s, \n"
                    + "\n"
                    + "I'd like you to reexamine a change."
                    + " Please visit",
                user.fullName(), user.fullName()));
    assertThat(message.body())
        .contains(
            String.format(
                "The following approvals got outdated and were removed:\n"
                    + "Code-Review+1 by %s, Foo-Bar-1 by %s, Verified+1 by %s\n",
                user.fullName(), user.fullName(), user.fullName()));
    assertThat(message.htmlBody())
        .contains(
            String.format(
                "<p> Attention is currently required from: %s. </p>\n"
                    + "<p>%s <strong>uploaded patch set #2</strong> to this change.</p>",
                user.fullName(), admin.fullName()));
    assertThat(message.htmlBody())
        .contains(
            String.format(
                "View Change</a></p>"
                    + "<p>The following approvals got outdated and were removed:\n"
                    + "Code-Review+1 by %s, Foo-Bar-1 by %s, Verified+1 by %s</p>",
                user.fullName(), user.fullName(), user.fullName()));
  }

  @Test
  public void multipleApproverOfOutdatedApprovalsAddedToAttentionSet() throws Exception {
    // Create Verify label and allow voting on it.
    try (ProjectConfigUpdate u = updateProject(project)) {
      LabelType.Builder verified =
          labelBuilder(
              LabelId.VERIFIED, value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
      u.getConfig().upsertLabelType(verified.build());
      u.save();
    }
    projectOperations
        .project(project)
        .forUpdate()
        .add(
            allowLabel(LabelId.VERIFIED)
                .ref(RefNames.REFS_HEADS + "*")
                .group(REGISTERED_USERS)
                .range(-1, 1))
        .update();

    PushOneCommit.Result r = createChange();
    assertThat(r.getChange().attentionSet()).isEmpty();

    // Add approvals from multiple users that gets outdated when a new patch set is created (i.e.
    // approvals that are not copied).
    requestScopeOperations.setApiUser(user.id());
    recommend(r.getChangeId());
    TestAccount user2 = accountCreator.user2();
    requestScopeOperations.setApiUser(user2.id());
    gApi.changes()
        .id(r.getChangeId())
        .current()
        .review(new ReviewInput().label(LabelId.VERIFIED, 1));
    requestScopeOperations.setApiUser(admin.id());

    // Voting added the admin user to the attention set.
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                admin.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"));

    // Remove admin user from attention set.
    change(r).attention(admin.id().toString()).remove(new AttentionSetInput("removed"));
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.REMOVE, "removed"));

    // Amend the change, this removes the vote from user, as it is not copied to the new patch set.
    sender.clear();
    r = amendChange(r.getChangeId(), "refs/for/master", admin, testRepo);
    r.assertOkStatus();

    // Verify that the approvals have been removed.
    assertThat(r.getChange().currentApprovals()).isEmpty();

    // User got added to the attention set because users approvals got outdated and were removed and
    // user now needs to re-review the change and renew the approvals.
    assertThat(r.getChange().attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.REMOVE, "removed"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                user.id(),
                AttentionSetUpdate.Operation.ADD,
                "Vote got outdated and was removed: Code-Review+1"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                user2.id(),
                AttentionSetUpdate.Operation.ADD,
                "Vote got outdated and was removed: Verified+1"));

    // Expect that the email notification contains the outdated votes.
    assertThat(sender.getMessages()).hasSize(1);
    Message message = Iterables.getOnlyElement(sender.getMessages());
    assertThat(message.body())
        .contains(
            String.format(
                "Attention is currently required from: %s, %s.\n"
                    + "\n"
                    + "Hello %s, %s, \n"
                    + "\n"
                    + "I'd like you to reexamine a change."
                    + " Please visit",
                user.fullName(), user2.fullName(), user.fullName(), user2.fullName()));
    assertThat(message.body())
        .contains(
            String.format(
                "The following approvals got outdated and were removed:\n"
                    + "Code-Review+1 by %s, Verified+1 by %s\n",
                user.fullName(), user2.fullName()));
    assertThat(message.htmlBody())
        .contains(
            String.format(
                "<p> Attention is currently required from: %s, %s. </p>\n"
                    + "<p>%s <strong>uploaded patch set #2</strong> to this change.</p>",
                user.fullName(), user2.fullName(), admin.fullName()));
    assertThat(message.htmlBody())
        .contains(
            String.format(
                "View Change</a></p>"
                    + "<p>The following approvals got outdated and were removed:\n"
                    + "Code-Review+1 by %s, Verified+1 by %s</p>",
                user.fullName(), user2.fullName()));
  }

  @Test
  public void robotApproverOfOutdatedApprovalIsNotAddedToAttentionSet() throws Exception {
    // Create robot account
    TestAccount robot =
        accountCreator.create(
            "robot-X",
            "robot-x@example.com",
            "Ro Bot X",
            "RoX",
            ServiceUserClassifier.SERVICE_USERS,
            "Administrators");

    PushOneCommit.Result r = createChange();
    assertThat(r.getChange().attentionSet()).isEmpty();

    // Add an approval by a robot that gets outdated when a new patch set is created (i.e. an
    // approval that is not copied).
    requestScopeOperations.setApiUser(robot.id());
    recommend(r.getChangeId());
    requestScopeOperations.setApiUser(admin.id());

    // A robot vote doesn't add the admin user to the attention set.
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet()).isEmpty();

    // Amend the change, this removes the vote from the robot, as it is not copied to the new patch
    // set.
    sender.clear();
    r = amendChange(r.getChangeId(), "refs/for/master", admin, testRepo);
    r.assertOkStatus();

    // Verify that the approval has been removed.
    assertThat(r.getChange().currentApprovals()).isEmpty();

    // The robot was not added to the attention set because users service users are never added to
    // the attention set.
    assertThat(r.getChange().attentionSet()).isEmpty();

    // Verify the email for the new patch set.
    Message message = Iterables.getOnlyElement(sender.getMessages());
    String emailBody = message.body();
    assertThat(emailBody)
        .doesNotContain(
            String.format("Attention is currently required from: %s", robot.fullName()));
    assertThat(emailBody)
        .contains(
            String.format(
                "Hello %s, \n\nI'd like you to reexamine a change. Please visit",
                robot.fullName()));
    assertThat(emailBody)
        .contains(
            String.format(
                "The following approvals got outdated and were removed:\nCode-Review+1 by %s",
                robot.fullName()));
    assertThat(message.htmlBody())
        .doesNotContain(
            String.format("Attention is currently required from: %s", robot.fullName()));
    assertThat(message.htmlBody())
        .contains(
            String.format(
                "<p>%s <strong>uploaded patch set #2</strong> to this change.</p>",
                admin.fullName()));
    assertThat(message.htmlBody())
        .contains(
            String.format(
                "View Change</a></p>"
                    + "<p>The following approvals got outdated and were removed:\n"
                    + "Code-Review+1 by %s</p>",
                robot.fullName()));
  }

  @Test
  public void approverOfCopiedApprovelNotAddedToAttentionSet() throws Exception {
    // Allow user to make veto votes.
    projectOperations
        .project(project)
        .forUpdate()
        .add(
            allowLabel(LabelId.CODE_REVIEW)
                .ref(RefNames.REFS_HEADS + "*")
                .group(REGISTERED_USERS)
                .range(-2, 1))
        .update();

    PushOneCommit.Result r = createChange();
    assertThat(r.getChange().attentionSet()).isEmpty();

    // Add a veto vote that will be copied over to a new patch set.
    requestScopeOperations.setApiUser(user.id());
    gApi.changes()
        .id(r.getChangeId())
        .current()
        .review(new ReviewInput().label(LabelId.CODE_REVIEW, -2));
    requestScopeOperations.setApiUser(admin.id());

    // Voting added the admin user to the attention set.
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                admin.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"));

    // Remove admin user from attention set.
    change(r).attention(admin.id().toString()).remove(new AttentionSetInput("removed"));
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.REMOVE, "removed"));

    // Amend the change, this copies the vote from user to the new patch set.
    sender.clear();
    r = amendChange(r.getChangeId(), "refs/for/master", admin, testRepo);
    r.assertOkStatus();

    // Verify that the approval has been copied.
    List<PatchSetApproval> approvalsPs2 = r.getChange().currentApprovals();
    assertThat(approvalsPs2).hasSize(1);
    assertThat(Iterables.getOnlyElement(approvalsPs2).copied()).isTrue();

    // Attention set wasn't changed.
    assertThat(r.getChange().attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.REMOVE, "removed"));

    // Verify the email for the new patch set.
    Message message = Iterables.getOnlyElement(sender.getMessages());
    assertThat(message.body())
        .doesNotContain(String.format("Attention is currently required from: %s", user.fullName()));
    assertThat(message.body())
        .contains(
            String.format(
                "Hello %s, \n\nI'd like you to reexamine a change. Please visit", user.fullName()));
    assertThat(message.body())
        .doesNotContain("The following approvals got outdated and were removed:");
    assertThat(message.htmlBody())
        .doesNotContain(String.format("Attention is currently required from: %s", user.fullName()));
    assertThat(message.htmlBody())
        .contains(
            String.format(
                "<p>%s <strong>uploaded patch set #2</strong> to this change.</p>",
                admin.fullName()));
    assertThat(message.htmlBody())
        .doesNotContain("The following approvals got outdated and were removed:");
  }

  @Test
  public void ownerAndUploaderAreAddedToAttentionSetWhenChangeBecomesUnsubmittable_approvalRemoved()
      throws Exception {
    // Allow all users to approve.
    projectOperations
        .project(project)
        .forUpdate()
        .add(
            allowLabel(TestLabels.codeReview().getName())
                .ref(RefNames.REFS_HEADS + "*")
                .group(REGISTERED_USERS)
                .range(-1, 2))
        .update();

    // Create change with admin as the owner and upload a new patch set with user as uploader.
    PushOneCommit.Result r = createChange();
    r = amendChangeWithUploader(r, project, user);
    r.assertOkStatus();

    // Attention set is empty.
    assertThat(r.getChange().attentionSet()).isEmpty();

    // Approve the change.
    TestAccount approver = accountCreator.user2();
    requestScopeOperations.setApiUser(approver.id());
    approve(r.getChangeId());
    requestScopeOperations.setApiUser(admin.id());

    // Voting added the owner (admin) and the uploader (user) to the attention set.
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                admin.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                user.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"));

    // Remove the owner (admin) and the uploader (user) from the attention set.
    change(r).attention(admin.id().toString()).remove(new AttentionSetInput("removed"));
    change(r).attention(user.id().toString()).remove(new AttentionSetInput("removed"));
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.REMOVE, "removed"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), user.id(), AttentionSetUpdate.Operation.REMOVE, "removed"));

    // Revoke the approval
    requestScopeOperations.setApiUser(approver.id());
    sender.clear();
    gApi.changes().id(r.getChangeId()).current().review(ReviewInput.noScore());

    // Removing the approval added the owner (admin) and the uploader (user) to the attention set.
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                admin.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                user.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"));

    // Verify the email notification that has been sent for removing the approval.
    Message message = Iterables.getOnlyElement(sender.getMessages());
    assertThat(message.body())
        .contains(
            String.format(
                "Attention is currently required from: %s, %s.\n"
                    + "\n"
                    + "%s has posted comments on this change.",
                admin.fullName(), user.fullName(), approver.fullName()));
    assertThat(message.body()).doesNotContain("\nPatch Set 2: Code-Review+2\n");
    assertThat(message.body())
        .contains("The change is no longer submittable: Code-Review is unsatisfied now.\n");
  }

  @Test
  public void
      ownerAndUploaderAreAddedToAttentionSetWhenChangeBecomesUnsubmittable_approvalDowngraded()
          throws Exception {
    // Allow all users to approve.
    projectOperations
        .project(project)
        .forUpdate()
        .add(
            allowLabel(TestLabels.codeReview().getName())
                .ref(RefNames.REFS_HEADS + "*")
                .group(REGISTERED_USERS)
                .range(-1, 2))
        .update();

    // Create change with admin as the owner and upload a new patch set with user as uploader.
    PushOneCommit.Result r = createChange();
    r = amendChangeWithUploader(r, project, user);
    r.assertOkStatus();

    // Attention set is empty.
    assertThat(r.getChange().attentionSet()).isEmpty();

    // Approve the change.
    TestAccount approver = accountCreator.user2();
    requestScopeOperations.setApiUser(approver.id());
    approve(r.getChangeId());
    requestScopeOperations.setApiUser(admin.id());

    // Voting added the owner (admin) and the uploader (user) to the attention set.
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                admin.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                user.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"));

    // Remove the owner (admin) and the uploader (user) from the attention set.
    change(r).attention(admin.id().toString()).remove(new AttentionSetInput("removed"));
    change(r).attention(user.id().toString()).remove(new AttentionSetInput("removed"));
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.REMOVE, "removed"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), user.id(), AttentionSetUpdate.Operation.REMOVE, "removed"));

    // Downgrade the approval
    requestScopeOperations.setApiUser(approver.id());
    sender.clear();
    recommend(r.getChangeId());

    // Changing the approval added the owner (admin) and the uploader (user) to the attention set.
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                admin.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                user.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"));

    // Verify the email notification that has been sent for downgrading the approval.
    Message message = Iterables.getOnlyElement(sender.getMessages());
    assertThat(message.body())
        .contains(
            String.format(
                "Attention is currently required from: %s, %s.\n"
                    + "\n"
                    + "%s has posted comments on this change.",
                admin.fullName(), user.fullName(), approver.fullName()));
    assertThat(message.body()).doesNotContain("\nPatch Set 2: Code-Review+2\n");
    assertThat(message.body()).contains("\nPatch Set 2: Code-Review+1\n");
    assertThat(message.body())
        .contains("The change is no longer submittable: Code-Review is unsatisfied now.\n");
  }

  @Test
  public void ownerAndUploaderAreAddedToAttentionSetWhenChangeBecomesUnsubmittable_vetoApplied()
      throws Exception {
    // Allow all users to approve and veto.
    projectOperations
        .project(project)
        .forUpdate()
        .add(
            allowLabel(TestLabels.codeReview().getName())
                .ref(RefNames.REFS_HEADS + "*")
                .group(REGISTERED_USERS)
                .range(-2, 2))
        .update();

    // Create change with admin as the owner and upload a new patch set with user as uploader.
    PushOneCommit.Result r = createChange();
    r = amendChangeWithUploader(r, project, user);
    r.assertOkStatus();

    // Attention set is empty.
    assertThat(r.getChange().attentionSet()).isEmpty();

    // Approve the change.
    TestAccount approver = accountCreator.user2();
    requestScopeOperations.setApiUser(approver.id());
    approve(r.getChangeId());
    requestScopeOperations.setApiUser(admin.id());

    // Voting added the owner (admin) and the uploader (user) to the attention set.
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                admin.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                user.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"));

    // Remove the owner (admin) and the uploader (user) from the attention set.
    change(r).attention(admin.id().toString()).remove(new AttentionSetInput("removed"));
    change(r).attention(user.id().toString()).remove(new AttentionSetInput("removed"));
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), admin.id(), AttentionSetUpdate.Operation.REMOVE, "removed"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(), user.id(), AttentionSetUpdate.Operation.REMOVE, "removed"));

    // Apply veto by another user.
    TestAccount approver2 = accountCreator.user2();
    sender.clear();
    requestScopeOperations.setApiUser(approver2.id());
    gApi.changes().id(r.getChangeId()).current().review(ReviewInput.reject());

    // Adding the veto approval added the owner (admin) and the uploader (user) to the attention
    // set.
    assertThat(changeDataFactory.create(project, r.getChange().getId()).attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                admin.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"),
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                user.id(),
                AttentionSetUpdate.Operation.ADD,
                "Someone else replied on the change"));

    // Verify the email notification that has been sent for adding the veto.
    Message message = Iterables.getOnlyElement(sender.getMessages());
    assertThat(message.body())
        .contains(
            String.format(
                "Attention is currently required from: %s, %s.\n"
                    + "\n"
                    + "%s has posted comments on this change.",
                admin.fullName(), user.fullName(), approver.fullName()));
    assertThat(message.body()).contains("\nPatch Set 2: Code-Review-2\n");
    assertThat(message.body())
        .contains("The change is no longer submittable: Code-Review is unsatisfied now.\n");
  }

  @Test
  @GerritConfig(name = "attentionSet.readdOwnerAfter", value = "1w")
  @GerritConfig(name = "attentionSet.readdOwnerMessage", value = "Owner has been added")
  public void readdOwnerForInactiveOpenChanges() throws Exception {
    // create 2 changes where the owner will be added to the attention-set
    PushOneCommit.Result r1 = createChange();
    PushOneCommit.Result r2 = createChange();

    // ... because they are older than 1 week
    fakeClock.advance(Duration.ofDays(7));

    // create 1 change where the owner should not be added to the attention-set
    PushOneCommit.Result r3 = createChange();

    assertThat(r1.getChange().attentionSet()).isEmpty();
    assertThat(r2.getChange().attentionSet()).isEmpty();
    assertThat(r3.getChange().attentionSet()).isEmpty();

    sender.clear();
    readdOwnerUtil.readdOwnerForInactiveOpenChanges(batchUpdateFactory);
    assertThat(r1.getChange().attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                admin.id(),
                AttentionSetUpdate.Operation.ADD,
                "Owner has been added"));
    assertThat(r2.getChange().attentionSet())
        .containsExactly(
            AttentionSetUpdate.createFromRead(
                fakeClock.now(),
                admin.id(),
                AttentionSetUpdate.Operation.ADD,
                "Owner has been added"));
    assertThat(r3.getChange().attentionSet()).isEmpty();
    assertThat(sender.getMessages()).hasSize(2);
  }

  private void setEmailStrategyForUser(EmailStrategy es) throws Exception {
    requestScopeOperations.setApiUser(user.id());
    GeneralPreferencesInfo prefs = gApi.accounts().self().getPreferences();
    prefs.emailStrategy = es;
    gApi.accounts().self().setPreferences(prefs);
    requestScopeOperations.setApiUser(admin.id());
  }

  private List<AttentionSetUpdate> getAttentionSetUpdatesForUser(
      PushOneCommit.Result r, TestAccount account) {
    return getAttentionSetUpdates(r.getChange().getId()).stream()
        .filter(a -> a.account().equals(account.id()))
        .collect(Collectors.toList());
  }

  private List<AttentionSetUpdate> getAttentionSetUpdates(Change.Id changeId) {
    List<ChangeData> changeData = changeQueryProvider.get().byLegacyChangeId(changeId);
    if (changeData.size() != 1) {
      throw new IllegalStateException(
          String.format("Not exactly one change found for ID %s.", changeId));
    }
    return new ArrayList<>(Iterables.getOnlyElement(changeData).attentionSet());
  }

  private ReviewInput reviewWithComment() {
    return reviewInReplyToComment(null);
  }

  private ReviewInput reviewInReplyToComment(@Nullable String id) {
    ReviewInput.CommentInput comment = new ReviewInput.CommentInput();
    comment.side = Side.REVISION;
    comment.path = Patch.COMMIT_MSG;
    comment.message = "comment";
    comment.setUpdated(TimeUtil.now());
    comment.inReplyTo = id;
    ReviewInput reviewInput = new ReviewInput();
    reviewInput.comments = ImmutableMap.of(Patch.COMMIT_MSG, ImmutableList.of(comment));
    return reviewInput;
  }

  private Correspondence<AttentionSetUpdate, Account.Id> hasAccount() {
    return NullAwareCorrespondence.transforming(AttentionSetUpdate::account, "hasAccount");
  }
}
