Squash email comments to account for multi-block comments

When sending HTML emails to Gerrit, comments can span multiple HTML
blocks. In this case, we want to squash those comments and separate them
by two newlines to make a new paragraph.

Bug: Issue 6541
Change-Id: Ic3801a830aecefc4c374280cfa34e1e751c2557d
This commit is contained in:
Patrick Hiesel
2017-06-22 11:15:58 +02:00
parent 7e300a405d
commit e70ee68de7
3 changed files with 60 additions and 6 deletions

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.mail.receive;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;
import com.google.gerrit.reviewdb.client.Comment;
@@ -99,21 +100,46 @@ public class HtmlParser {
content = ParserUtil.trimQuotation(content);
// TODO(hiesel) Add more sanitizer
if (!Strings.isNullOrEmpty(content)) {
parsedComments.add(
new MailComment(content, null, null, MailComment.CommentType.CHANGE_MESSAGE));
appendOrAddNewComment(
new MailComment(content, null, null, MailComment.CommentType.CHANGE_MESSAGE),
parsedComments);
}
} else if (lastEncounteredComment == null) {
parsedComments.add(
appendOrAddNewComment(
new MailComment(
content, lastEncounteredFileName, null, MailComment.CommentType.FILE_COMMENT));
content, lastEncounteredFileName, null, MailComment.CommentType.FILE_COMMENT),
parsedComments);
} else {
parsedComments.add(
appendOrAddNewComment(
new MailComment(
content, null, lastEncounteredComment, MailComment.CommentType.INLINE_COMMENT));
content, null, lastEncounteredComment, MailComment.CommentType.INLINE_COMMENT),
parsedComments);
}
}
}
}
return parsedComments;
}
/**
* When parsing HTML content, we need to append comments prematurely since we are parsing
* block-by-block and never know what comes next. This can result in a comment being parsed as two
* comments when it spans multiple blocks. This method takes care of merging those blocks or
* adding a new comment to the list of appropriate.
*/
private static void appendOrAddNewComment(MailComment comment, List<MailComment> comments) {
if (comments.isEmpty()) {
comments.add(comment);
return;
}
MailComment lastComment = Iterables.getLast(comments);
if (comment.isSameCommentPath(lastComment)) {
// Merge the two comments
lastComment.message += "\n\n" + comment.message;
return;
}
comments.add(comment);
}
}

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.mail.receive;
import com.google.gerrit.reviewdb.client.Comment;
import java.util.Objects;
/** A comment parsed from inbound email */
public class MailComment {
@@ -37,4 +38,14 @@ public class MailComment {
this.inReplyTo = inReplyTo;
this.type = type;
}
/**
* Checks if the provided comment concerns the same exact spot in the change. This is basically an
* equals method except that the message is not checked.
*/
public boolean isSameCommentPath(MailComment c) {
return Objects.equals(fileName, c.fileName)
&& Objects.equals(inReplyTo, c.inReplyTo)
&& Objects.equals(type, c.type);
}
}

View File

@@ -105,6 +105,23 @@ public abstract class HtmlParserTest extends AbstractParserTest {
assertInlineComment("Also have a comment here.", parsedComments.get(1), comments.get(3));
}
@Test
public void commentsSpanningMultipleBlocks() {
String htmlMessage =
"This is a very long test comment. <div><br></div><div>Now this is a new paragraph yay.</div>";
String txtMessage = "This is a very long test comment.\n\nNow this is a new paragraph yay.";
MailMessage.Builder b = newMailMessageBuilder();
b.htmlContent(newHtmlBody(htmlMessage, null, null, htmlMessage, htmlMessage, null, null));
List<Comment> comments = defaultComments();
List<MailComment> parsedComments = HtmlParser.parse(b.build(), comments, CHANGE_URL);
assertThat(parsedComments).hasSize(3);
assertChangeMessage(txtMessage, parsedComments.get(0));
assertFileComment(txtMessage, parsedComments.get(1), comments.get(1).key.filename);
assertInlineComment(txtMessage, parsedComments.get(2), comments.get(3));
}
/**
* Create an html message body with the specified comments.
*