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

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
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 static org.eclipse.jgit.lib.Constants.HEAD;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.acceptance.testsuite.change.ChangeOperations;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.LabelId;
import com.google.gerrit.entities.LabelType;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.api.changes.RebaseInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.ReviewInput.CommentInput;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.server.project.testing.TestLabels;
import com.google.inject.Inject;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Before;
import org.junit.Test;

public class SubmitWithStickyApprovalDiffIT extends AbstractDaemonTest {
  @Inject private ProjectOperations projectOperations;
  @Inject private ChangeOperations changeOperations;

  @Before
  public void setup() throws Exception {
    try (ProjectConfigUpdate u = updateProject(project)) {
      // Overwrite "Code-Review" label that is inherited from All-Projects.
      // This way changes to the "Code Review" label don't affect other tests.
      // Also make the vote sticky.
      LabelType.Builder codeReview =
          labelBuilder(
              LabelId.CODE_REVIEW,
              value(2, "Looks good to me, approved"),
              value(1, "Looks good to me, but someone else must approve"),
              value(0, "No score"),
              value(-1, "I would prefer this is not submitted as is"),
              value(-2, "This shall not be submitted"));
      codeReview.setCopyCondition("is:ANY");
      u.getConfig().upsertLabelType(codeReview.build());
      u.save();
    }
    projectOperations
        .project(project)
        .forUpdate()
        .add(
            allowLabel(TestLabels.codeReview().getName())
                .ref(RefNames.REFS_HEADS + "*")
                .group(REGISTERED_USERS)
                .range(-2, 2))
        .update();
  }

  @Test
  public void diffChangeMessageOnSubmitWithStickyVote_modifiedFileWithReplaces() throws Exception {
    Change.Id changeId =
        changeOperations
            .newChange()
            .project(project)
            .file("file")
            .content("content\naa\nsF\naa\naaa\nsomething\nfoo\nbla\ndeletedEnd")
            .create();

    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());

    changeOperations
        .change(changeId)
        .newPatchset()
        .file("file")
        .content("content\naa\nsS\naa\naaa\ndifferent\nfoo\nbla")
        .create();

    // add a reviewer to ensure an email is sent.
    gApi.changes().id(changeId.get()).addReviewer(user.email());

    gApi.changes().id(changeId.get()).current().submit();

    assertDiffChangeMessageAndEmailWithStickyApproval(
        Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message,
        /* file= */ "file",
        /* insertions= */ 3,
        /* deletions= */ 4,
        /* expectedFileDiff= */ "@@ -1,9 +1,8 @@\n"
            + " content\n"
            + " aa\n"
            + "-sF\n"
            + "+sS\n"
            + " aa\n"
            + " aaa\n"
            + "-something\n"
            + "+different\n"
            + " foo\n"
            + "-bla\n"
            + "-deletedEnd\n"
            + "+bla",
        /* oldFileName= */ null);
  }

  @Test
  public void diffChangeMessageOnSubmitWithStickyVote_ignoreDiffFromRebaseAdditions()
      throws Exception {
    ObjectId initial = repo().exactRef(HEAD).getLeaf().getObjectId();
    Change.Id changeId =
        changeOperations
            .newChange()
            .project(project)
            .file("file")
            .content("line1\nline2\nline3\nline4")
            .create();

    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());
    changeOperations
        .change(changeId)
        .newPatchset()
        .file("file")
        .content("line012\nline1\nline2\nline3\nline4")
        .create();

    // add a reviewer to ensure an email is sent.
    gApi.changes().id(changeId.get()).addReviewer(user.email());

    testRepo.reset(initial);

    // create 2 unrelated changes and rebase on top of them. Those rebases should be ignored.
    // The changes add files.
    Change.Id unrelated =
        changeOperations.newChange().project(project).file("a").content("a").create();
    gApi.changes().id(unrelated.get()).current().review(ReviewInput.approve());
    gApi.changes().id(unrelated.get()).current().submit();
    unrelated = changeOperations.newChange().project(project).file("z").content("z").create();
    gApi.changes().id(unrelated.get()).current().review(ReviewInput.approve());
    gApi.changes().id(unrelated.get()).current().submit();

    RebaseInput rebaseInput = new RebaseInput();
    rebaseInput.base = gApi.changes().id(unrelated.get()).current().commit(true).commit;
    gApi.changes().id(changeId.get()).current().rebase(rebaseInput);

    gApi.changes().id(changeId.get()).current().submit();

    assertDiffChangeMessageAndEmailWithStickyApproval(
        Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message,
        /* file= */ "file",
        /* insertions= */ 1,
        /* deletions= */ 0,
        /* expectedFileDiff= */ "@@ -1,3 +1,4 @@\n"
            + "+line012\n"
            + " line1\n"
            + " line2\n"
            + " line3",
        /* oldFileName= */ null);
  }

  @Test
  public void diffChangeMessageOnSubmitWithStickyVote_ignoreDiffFromRebaseRenames()
      throws Exception {
    Change.Id setup = changeOperations.newChange().project(project).file("a").content("a").create();
    gApi.changes().id(setup.get()).current().review(ReviewInput.approve());
    gApi.changes().id(setup.get()).current().submit();

    setup = changeOperations.newChange().project(project).file("z").content("z").create();
    gApi.changes().id(setup.get()).current().review(ReviewInput.approve());
    gApi.changes().id(setup.get()).current().submit();

    ObjectId initial = repo().exactRef(HEAD).getLeaf().getObjectId();
    Change.Id changeId =
        changeOperations
            .newChange()
            .project(project)
            .file("file")
            .content("line1\nline2\nline3\nline4")
            .create();

    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());
    changeOperations
        .change(changeId)
        .newPatchset()
        .file("file")
        .content("line012\nline1\nline2\nline3\nline4")
        .create();

    // add a reviewer to ensure an email is sent.
    gApi.changes().id(changeId.get()).addReviewer(user.email());

    testRepo.reset(initial);

    // create 2 unrelated changes and rebase on top of them. Those rebases should be ignored.
    // The changes rename files.
    Change.Id unrelated =
        changeOperations.newChange().project(project).file("a").renameTo("aa").create();
    gApi.changes().id(unrelated.get()).current().review(ReviewInput.approve());
    gApi.changes().id(unrelated.get()).current().submit();
    unrelated = changeOperations.newChange().project(project).file("z").renameTo("zz").create();
    gApi.changes().id(unrelated.get()).current().review(ReviewInput.approve());
    gApi.changes().id(unrelated.get()).current().submit();

    RebaseInput rebaseInput = new RebaseInput();
    rebaseInput.base = gApi.changes().id(unrelated.get()).current().commit(true).commit;
    gApi.changes().id(changeId.get()).current().rebase(rebaseInput);

    gApi.changes().id(changeId.get()).current().submit();

    assertDiffChangeMessageAndEmailWithStickyApproval(
        Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message,
        /* file= */ "file",
        /* insertions= */ 1,
        /* deletions= */ 0,
        /* expectedFileDiff= */ "@@ -1,3 +1,4 @@\n"
            + "+line012\n"
            + " line1\n"
            + " line2\n"
            + " line3",
        /* oldFileName= */ null);
  }

  @Test
  public void diffChangeMessageOnSubmitWithStickyVote_ignoreDiffFromRebaseDeletions()
      throws Exception {
    Change.Id setup = changeOperations.newChange().project(project).file("a").content("a").create();
    gApi.changes().id(setup.get()).current().review(ReviewInput.approve());
    gApi.changes().id(setup.get()).current().submit();

    setup = changeOperations.newChange().project(project).file("z").content("z").create();
    gApi.changes().id(setup.get()).current().review(ReviewInput.approve());
    gApi.changes().id(setup.get()).current().submit();

    ObjectId initial = repo().exactRef(HEAD).getLeaf().getObjectId();
    Change.Id changeId =
        changeOperations
            .newChange()
            .project(project)
            .file("file")
            .content("line1\nline2\nline3\nline4")
            .create();

    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());
    changeOperations
        .change(changeId)
        .newPatchset()
        .file("file")
        .content("line012\nline1\nline2\nline3\nline4")
        .create();

    // add a reviewer to ensure an email is sent.
    gApi.changes().id(changeId.get()).addReviewer(user.email());

    testRepo.reset(initial);
    // create 2 unrelated changes and rebase on top of them. Those rebases should be ignored.
    // The changes delete files.
    Change.Id unrelated = changeOperations.newChange().project(project).file("a").delete().create();
    gApi.changes().id(unrelated.get()).current().review(ReviewInput.approve());
    gApi.changes().id(unrelated.get()).current().submit();
    unrelated = changeOperations.newChange().project(project).file("z").delete().create();
    gApi.changes().id(unrelated.get()).current().review(ReviewInput.approve());
    gApi.changes().id(unrelated.get()).current().submit();

    RebaseInput rebaseInput = new RebaseInput();
    rebaseInput.base = gApi.changes().id(unrelated.get()).current().commit(true).commit;
    gApi.changes().id(changeId.get()).current().rebase(rebaseInput);

    gApi.changes().id(changeId.get()).current().submit();

    assertDiffChangeMessageAndEmailWithStickyApproval(
        Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message,
        /* file= */ "file",
        /* insertions= */ 1,
        /* deletions= */ 0,
        /* expectedFileDiff= */ "@@ -1,3 +1,4 @@\n"
            + "+line012\n"
            + " line1\n"
            + " line2\n"
            + " line3",
        /* oldFileName= */ null);
  }

  @Test
  public void diffChangeMessageOnSubmitWithStickyVote_modifiedFileWithInsertionAndDeletion()
      throws Exception {
    Change.Id changeId =
        changeOperations
            .newChange()
            .project(project)
            .file("file")
            .content("content\naa\nbb\ncc\ndd\nee\nff\nTODELETE1\nTODELETE2\ngg\nend")
            .create();
    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());

    changeOperations
        .change(changeId)
        .newPatchset()
        .file("file")
        .content("content\naa\nbb\ncc\nINSERTION\nINSERTED\nVERY\nLONG\ndd\nee\nff\ngg\nend")
        .create();

    // add a reviewer to ensure an email is sent.
    gApi.changes().id(changeId.get()).addReviewer(user.email());

    gApi.changes().id(changeId.get()).current().submit();

    assertDiffChangeMessageAndEmailWithStickyApproval(
        Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message,
        /* file= */ "file",
        /* insertions= */ 4,
        /* deletions= */ 2,
        /* expectedFileDiff= */ "@@ -2,10 +2,12 @@\n"
            + " aa\n"
            + " bb\n"
            + " cc\n"
            + "+INSERTION\n"
            + "+INSERTED\n"
            + "+VERY\n"
            + "+LONG\n"
            + " dd\n"
            + " ee\n"
            + " ff\n"
            + "-TODELETE1\n"
            + "-TODELETE2\n"
            + " gg\n"
            + " end",
        /* oldFileName= */ null);
  }

  @Test
  @GerritConfig(name = "change.cumulativeCommentSizeLimit", value = "10k")
  public void autoGeneratedPostSubmitDiffIsPartOfTheCommentSizeLimit() throws Exception {
    Change.Id changeId =
        changeOperations.newChange().project(project).file("file").content("content").create();
    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());
    String content = new String(new char[800]).replace("\0", "a");
    changeOperations.change(changeId).newPatchset().file("file").content(content).create();

    // Post a submit diff that is almost the cumulativeCommentSizeLimit
    gApi.changes().id(changeId.get()).current().submit();
    assertThat(Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message)
        .doesNotContain("The diff is too large to show. Please review the diff");

    // unrelated comment and change message posting doesn't work, since the post submit diff is
    // counted towards the cumulativeCommentSizeLimit for unrelated follow-up comments.
    // 800 + 9500 > 10k.
    String message = new String(new char[9500]).replace("\0", "a");
    ReviewInput reviewInput = new ReviewInput().message(message);
    CommentInput commentInput = new CommentInput();
    commentInput.line = 1;
    commentInput.path = "file";
    reviewInput.comments = ImmutableMap.of("file", ImmutableList.of(commentInput));

    BadRequestException thrown =
        assertThrows(
            BadRequestException.class,
            () -> gApi.changes().id(changeId.get()).current().review(reviewInput));
    assertThat(thrown)
        .hasMessageThat()
        .contains("Exceeding maximum cumulative size of comments and change messages");
  }

  @Test
  public void postSubmitDiffCannotBeTooBig() throws Exception {
    Change.Id changeId =
        changeOperations.newChange().project(project).file("file").content("content").create();
    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());

    // max post submit diff size is 300k
    String content = new String(new char[320000]).replace("\0", "a");

    changeOperations.change(changeId).newPatchset().file("file").content(content).create();

    // Post submit diff is over the postSubmitDiffSizeLimit (300k).
    gApi.changes().id(changeId.get()).current().submit();
    assertThat(Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message)
        .isEqualTo(
            "Change has been successfully merged\n\n1 is the latest approved patch-set.\nThe "
                + "change was submitted with unreviewed changes in the following "
                + "files:\n\n```\nThe name of the file: file\nInsertions: 1, Deletions: 1.\n\nThe"
                + " diff is too large to show. Please review the diff.\n```\n");
  }

  @Test
  @GerritConfig(name = "change.cumulativeCommentSizeLimit", value = "10k")
  public void postSubmitDiffCannotBeTooBigWithLargeComments() throws Exception {
    Change.Id changeId =
        changeOperations.newChange().project(project).file("file").content("content").create();
    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());

    // unrelated comment taking up most of the space, making post submit diff shorter.
    String message = new String(new char[9700]).replace("\0", "a");
    ReviewInput reviewInput = new ReviewInput().message(message);
    CommentInput commentInput = new CommentInput();
    commentInput.line = 1;
    commentInput.path = "file";
    reviewInput.comments = ImmutableMap.of("file", ImmutableList.of(commentInput));
    gApi.changes().id(changeId.get()).current().review(reviewInput);

    String content = new String(new char[500]).replace("\0", "a");
    changeOperations.change(changeId).newPatchset().file("file").content(content).create();

    // Post submit diff is over the cumulativeCommentSizeLimit, since the comment took most of
    // the space (even though the post submit diff is not limited).
    gApi.changes().id(changeId.get()).current().submit();
    assertThat(Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message)
        .isEqualTo(
            "Change has been successfully merged\n\n1 is the latest approved patch-set.\nThe "
                + "change was submitted with unreviewed changes in the following "
                + "files:\n\n```\nThe name of the file: file\nInsertions: 1, Deletions: 1.\n\nThe"
                + " diff is too large to show. Please review the diff.\n```\n");
  }

  @Test
  public void diffChangeMessageOnSubmitWithStickyVote_addedFile() throws Exception {
    Change.Id changeId = changeOperations.newChange().project(project).create();
    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());

    changeOperations
        .change(changeId)
        .newPatchset()
        .file("file")
        .content("content\nmore content\nlast content")
        .create();

    // add a reviewer to ensure an email is sent.
    gApi.changes().id(changeId.get()).addReviewer(user.email());

    gApi.changes().id(changeId.get()).current().submit();

    assertDiffChangeMessageAndEmailWithStickyApproval(
        Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message,
        /* file= */ "file",
        /* insertions= */ 3,
        /* deletions= */ 0,
        /* expectedFileDiff= */ "@@ -0,0 +1,3 @@\n+content\n+more content\n+last content",
        /* oldFileName= */ null);
  }

  @Test
  public void diffChangeMessageOnSubmitWithStickyVote_addedMultipleFiles() throws Exception {
    Change.Id changeId = changeOperations.newChange().project(project).create();
    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());

    changeOperations
        .change(changeId)
        .newPatchset()
        .file("file")
        .content("content1\nmore content\nlast content")
        .create();

    changeOperations
        .change(changeId)
        .newPatchset()
        .file("otherFile")
        .content("content2\nmore content\nlast content")
        .create();

    // add a reviewer to ensure an email is sent.
    gApi.changes().id(changeId.get()).addReviewer(user.email());

    gApi.changes().id(changeId.get()).current().submit();

    assertDiffChangeMessageAndEmailWithStickyApproval(
        Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message,
        /* file1= */ "otherFile",
        /* insertions1= */ 3,
        /* deletions1= */ 0,
        /* expectedFileDiff1= */ "@@ -0,0 +1,3 @@\n+content2\n+more content\n+last content",
        /* oldFileName1= */ null,
        /* file2= */ "file",
        /* insertions2= */ 3,
        /* deletions2= */ 0,
        /* expectedFileDiff2= */ "@@ -0,0 +1,3 @@\n+content1\n+more content\n+last content",
        /* oldFileName2= */ null);
  }

  @Test
  public void diffChangeMessageOnSubmitWithStickyVote_removedFile() throws Exception {
    Change.Id changeId =
        changeOperations
            .newChange()
            .project(project)
            .file("file")
            .content("content\nmore content\nlast content")
            .create();
    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());

    changeOperations.change(changeId).newPatchset().file("file").delete().create();

    // add a reviewer to ensure an email is sent.
    gApi.changes().id(changeId.get()).addReviewer(user.email());

    gApi.changes().id(changeId.get()).current().submit();

    assertDiffChangeMessageAndEmailWithStickyApproval(
        Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message,
        /* file= */ "file",
        /* insertions= */ 0,
        /* deletions= */ 3,
        /* expectedFileDiff= */ "@@ -1,3 +0,0 @@\n-content\n-more content\n-last content",
        /* oldFileName= */ null);
  }

  @Test
  public void diffChangeMessageOnSubmitWithStickyVote_renamedFile() throws Exception {
    Change.Id changeId =
        changeOperations
            .newChange()
            .project(project)
            .file("file")
            .content("content\nmoreContent")
            .create();
    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());

    changeOperations.change(changeId).newPatchset().file("file").renameTo("new_file").create();

    // add a reviewer to ensure an email is sent.
    gApi.changes().id(changeId.get()).addReviewer(user.email());

    gApi.changes().id(changeId.get()).current().submit();

    assertDiffChangeMessageAndEmailWithStickyApproval(
        Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message,
        /* file= */ "new_file",
        /* insertions= */ 0,
        /* deletions= */ 0,
        /* expectedFileDiff= */ "",
        /* oldFileName= */ "file");
  }

  @Test
  public void noDiffChangeMessageOnSubmitWhenVotedOnLastPatchset() throws Exception {
    Change.Id changeId =
        changeOperations
            .newChange()
            .project(project)
            .file("file")
            .content("content\nmoreContent")
            .create();
    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());

    changeOperations.change(changeId).newPatchset().file("file").renameTo("new_file").create();

    // Approve last patch-set again, although there is already a +2 on the change (since it's
    // sticky).
    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());
    gApi.changes().id(changeId.get()).current().submit();

    assertThat(Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message.trim())
        .isEqualTo("Change has been successfully merged");
  }

  @Test
  public void diffChangeMessageOnSubmitWithStickyVote_approvedPatchset() throws Exception {
    Change.Id changeId = changeOperations.newChange().project(project).create();
    changeOperations.change(changeId).newPatchset().create();

    // approve patch-set 2
    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());

    // create patch-set 3
    changeOperations.change(changeId).newPatchset().create();

    gApi.changes().id(changeId.get()).current().submit();

    // patch-set 2 was the latest approved one.
    assertThat(Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message)
        .contains("2 is the latest approved patch-set.");
  }

  @Test
  public void diffChangeMessageOnSubmitWithStickyVote_noChanges() throws Exception {
    Change.Id changeId = changeOperations.newChange().project(project).create();
    gApi.changes().id(changeId.get()).current().review(ReviewInput.approve());

    // no file changed
    changeOperations.change(changeId).newPatchset().create();

    gApi.changes().id(changeId.get()).current().submit();

    // No other content in the message since the diff is the same.
    assertThat(Iterables.getLast(gApi.changes().id(changeId.get()).messages()).message)
        .isEqualTo(
            "Change has been successfully merged\n\n1 is the latest approved patch-set.\n"
                + "No files were changed between the latest approved patch-set and the submitted"
                + " one.\n");
  }

  private void assertDiffChangeMessageAndEmailWithStickyApproval(
      String message,
      String file,
      int insertions,
      int deletions,
      String expectedFileDiff,
      String oldFileName) {
    assertDiffChangeMessageAndEmailWithStickyApproval(
        message,
        file,
        insertions,
        deletions,
        expectedFileDiff,
        oldFileName,
        /* file2= */ null,
        /* insertions2= */ 0,
        /* deletions2 =
         */ 0,
        /* expectedFileDiff2= */ null,
        /* oldFileName2= */ null);
  }

  private void assertDiffChangeMessageAndEmailWithStickyApproval(
      String message,
      String file1,
      int insertions1,
      int deletions1,
      String expectedFileDiff1,
      String oldFileName1,
      String file2,
      int insertions2,
      int deletions2,
      String expectedFileDiff2,
      String oldFileName2) {
    String beginningOfMessage =
        "1 is the latest approved patch-set.\n"
            + "The change was submitted with unreviewed changes in the following files:\n"
            + "\n";
    String fileDiff1 = fileDiff(expectedFileDiff1, oldFileName1, file1, insertions1, deletions1);
    String expectedMessage1 = beginningOfMessage + fileDiff1;
    String expectedMessage2 = "";
    Set<String> expectedChangeMessages = new HashSet<>();
    if (file2 != null) {
      String fileDiff2 = fileDiff(expectedFileDiff2, oldFileName2, file2, insertions2, deletions2);
      expectedMessage2 = beginningOfMessage + fileDiff2 + fileDiff1;
      String expectedChangeMessage2 = "Change has been successfully merged\n\n" + expectedMessage2;
      expectedMessage1 += fileDiff2;
      expectedChangeMessages.add(expectedChangeMessage2.trim());
    }
    String expectedChangeMessage1 = "Change has been successfully merged\n\n" + expectedMessage1;
    expectedChangeMessage1 = expectedChangeMessage1.trim();
    expectedChangeMessages.add(expectedChangeMessage1.trim());

    // The order of appearance in the diff for multiple files is not defined, so check both
    // possible orders.
    assertThat(expectedChangeMessages).contains(message.trim());
    String email = Iterables.getLast(sender.getMessages()).body();
    if (email.contains(expectedMessage1) || expectedMessage2.isEmpty()) {
      assertThat(email).contains(expectedMessage1.trim());
    } else {
      assertThat(email).contains(expectedMessage2.trim());
    }
  }

  private String fileDiff(
      String expectedFileDiff, String oldFileName, String file, int insertions, int deletions) {
    String expectedMessage =
        "```\n"
            + String.format("The name of the file: %s\n", file)
            + String.format("Insertions: %d, Deletions: %d.\n\n", insertions, deletions);

    if (oldFileName != null) {
      expectedMessage += String.format("The file %s was renamed to %s\n", oldFileName, file);
    }
    expectedMessage += expectedFileDiff;
    expectedMessage += "\n```\n";
    return expectedMessage;
  }
}
