blob: 83e83700abd0c08e6400eb4a632c5e8fb4a72877 [file] [log] [blame]
// 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.server.change;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import java.time.Instant;
import org.junit.Test;
public class CommentThreadsTest {
@Test
public void threadsAreEmptyWhenNoCommentsAreProvided() {
ImmutableList<HumanComment> comments = ImmutableList.of();
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreads();
ImmutableSet<CommentThread<HumanComment>> expectedThreads = ImmutableSet.of();
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void threadsCanBeCreatedFromSingleRoot() {
HumanComment root = createComment("root");
ImmutableList<HumanComment> comments = ImmutableList.of(root);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreads();
ImmutableSet<CommentThread<HumanComment>> expectedThreads = ImmutableSet.of(toThread(root));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void threadsCanBeCreatedFromUnorderedComments() {
HumanComment root = createComment("root");
HumanComment child1 = asReply(createComment("child1"), "root");
HumanComment child2 = asReply(createComment("child2"), "child1");
HumanComment child3 = asReply(createComment("child3"), "child2");
ImmutableList<HumanComment> comments = ImmutableList.of(child2, child1, root, child3);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreads();
ImmutableSet<CommentThread<HumanComment>> expectedThreads =
ImmutableSet.of(toThread(root, child1, child2, child3));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void childWithNotAvailableParentIsAssumedToBeRoot() {
HumanComment child1 = asReply(createComment("child1"), "root");
ImmutableList<HumanComment> comments = ImmutableList.of(child1);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreads();
ImmutableSet<CommentThread<HumanComment>> expectedThreads = ImmutableSet.of(toThread(child1));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void threadsIgnoreDuplicateRoots() {
HumanComment root = createComment("root");
HumanComment child1 = asReply(createComment("child1"), "root");
ImmutableList<HumanComment> comments = ImmutableList.of(root, root, child1);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreads();
ImmutableSet<CommentThread<HumanComment>> expectedThreads =
ImmutableSet.of(toThread(root, child1));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void threadsIgnoreDuplicateChildren() {
HumanComment root = createComment("root");
HumanComment child1 = asReply(createComment("child1"), "root");
ImmutableList<HumanComment> comments = ImmutableList.of(root, child1, child1);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreads();
ImmutableSet<CommentThread<HumanComment>> expectedThreads =
ImmutableSet.of(toThread(root, child1));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void commentsAreOrderedIntoCorrectThreads() {
HumanComment thread1Root = createComment("thread1Root");
HumanComment thread1Child1 = asReply(createComment("thread1Child1"), "thread1Root");
HumanComment thread1Child2 = asReply(createComment("thread1Child2"), "thread1Child1");
HumanComment thread2Root = createComment("thread2Root");
HumanComment thread2Child1 = asReply(createComment("thread2Child1"), "thread2Root");
ImmutableList<HumanComment> comments =
ImmutableList.of(thread2Root, thread1Child2, thread1Child1, thread1Root, thread2Child1);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreads();
ImmutableSet<CommentThread<HumanComment>> expectedThreads =
ImmutableSet.of(
toThread(thread1Root, thread1Child1, thread1Child2),
toThread(thread2Root, thread2Child1));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void branchedThreadsAreFlattenedAccordingToDate() {
HumanComment root = writtenOn(createComment("root"), Instant.ofEpochMilli(1));
HumanComment sibling1 =
writtenOn(asReply(createComment("sibling1"), "root"), Instant.ofEpochMilli(2));
HumanComment sibling2 =
writtenOn(asReply(createComment("sibling2"), "root"), Instant.ofEpochMilli(3));
HumanComment sibling1Child =
writtenOn(asReply(createComment("sibling1Child"), "sibling1"), Instant.ofEpochMilli(4));
HumanComment sibling2Child =
writtenOn(asReply(createComment("sibling2Child"), "sibling2"), Instant.ofEpochMilli(5));
ImmutableList<HumanComment> comments =
ImmutableList.of(sibling2, sibling2Child, sibling1, sibling1Child, root);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreads();
ImmutableSet<CommentThread<HumanComment>> expectedThreads =
ImmutableSet.of(toThread(root, sibling1, sibling2, sibling1Child, sibling2Child));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void threadsConsiderParentRelationshipStrongerThanDate() {
HumanComment root = writtenOn(createComment("root"), Instant.ofEpochMilli(3));
HumanComment child1 =
writtenOn(asReply(createComment("child1"), "root"), Instant.ofEpochMilli(2));
HumanComment child2 =
writtenOn(asReply(createComment("child2"), "child1"), Instant.ofEpochMilli(1));
ImmutableList<HumanComment> comments = ImmutableList.of(child2, child1, root);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreads();
ImmutableSet<CommentThread<HumanComment>> expectedThreads =
ImmutableSet.of(toThread(root, child1, child2));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void threadsFallBackToUuidOrderIfParentAndDateAreTheSame() {
HumanComment root = writtenOn(createComment("root"), Instant.ofEpochMilli(1));
HumanComment sibling1 =
writtenOn(asReply(createComment("sibling1"), "root"), Instant.ofEpochMilli(2));
HumanComment sibling2 =
writtenOn(asReply(createComment("sibling2"), "root"), Instant.ofEpochMilli(2));
ImmutableList<HumanComment> comments = ImmutableList.of(sibling2, sibling1, root);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreads();
ImmutableSet<CommentThread<HumanComment>> expectedThreads =
ImmutableSet.of(toThread(root, sibling1, sibling2));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void specificThreadsCanBeRequestedByTheirReply() {
HumanComment thread1Root = createComment("thread1Root");
HumanComment thread2Root = createComment("thread2Root");
HumanComment thread1Reply = asReply(createComment("thread1Reply"), "thread1Root");
ImmutableList<HumanComment> comments = ImmutableList.of(thread1Root, thread2Root, thread1Reply);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreadsForChildren(ImmutableList.of(thread1Reply));
ImmutableSet<CommentThread<HumanComment>> expectedThreads =
ImmutableSet.of(toThread(thread1Root, thread1Reply));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void requestedThreadsDoNotNeedToContainReply() {
HumanComment thread1Root = createComment("thread1Root");
HumanComment thread2Root = createComment("thread2Root");
HumanComment thread1Reply = asReply(createComment("thread1Reply"), "thread1Root");
ImmutableList<HumanComment> comments = ImmutableList.of(thread1Root, thread2Root);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreadsForChildren(ImmutableList.of(thread1Reply));
ImmutableSet<CommentThread<HumanComment>> expectedThreads =
ImmutableSet.of(toThread(thread1Root));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void completeThreadCanBeRequestedByReplyToRootComment() {
HumanComment root = createComment("root");
HumanComment child = asReply(createComment("child"), "root");
HumanComment reply = asReply(createComment("reply"), "root");
ImmutableList<HumanComment> comments = ImmutableList.of(root, child);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreadsForChildren(ImmutableList.of(reply));
ImmutableSet<CommentThread<HumanComment>> expectedThreads =
ImmutableSet.of(toThread(root, child));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void completeThreadWithBranchesCanBeRequestedByReplyToIntermediateComment() {
HumanComment root = writtenOn(createComment("root"), Instant.ofEpochMilli(1));
HumanComment sibling1 =
writtenOn(asReply(createComment("sibling1"), "root"), Instant.ofEpochMilli(2));
HumanComment sibling2 =
writtenOn(asReply(createComment("sibling2"), "root"), Instant.ofEpochMilli(3));
HumanComment sibling1Child =
writtenOn(asReply(createComment("sibling1Child"), "sibling1"), Instant.ofEpochMilli(4));
HumanComment sibling2Child =
writtenOn(asReply(createComment("sibling2Child"), "sibling2"), Instant.ofEpochMilli(5));
HumanComment reply = asReply(createComment("sibling1"), "root");
ImmutableList<HumanComment> comments =
ImmutableList.of(root, sibling1, sibling2, sibling1Child, sibling2Child);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreadsForChildren(ImmutableList.of(reply));
ImmutableSet<CommentThread<HumanComment>> expectedThreads =
ImmutableSet.of(toThread(root, sibling1, sibling2, sibling1Child, sibling2Child));
assertThat(commentThreads).isEqualTo(expectedThreads);
}
@Test
public void requestedThreadsAreEmptyIfReplyDoesNotReferToAThread() {
HumanComment root = createComment("root");
HumanComment reply = asReply(createComment("reply"), "invalid");
ImmutableList<HumanComment> comments = ImmutableList.of(root);
ImmutableSet<CommentThread<HumanComment>> commentThreads =
CommentThreads.forComments(comments).getThreadsForChildren(ImmutableList.of(reply));
ImmutableSet<CommentThread<HumanComment>> expectedThreads = ImmutableSet.of();
assertThat(commentThreads).isEqualTo(expectedThreads);
}
private static HumanComment createComment(String commentUuid) {
return new HumanComment(
new Comment.Key(commentUuid, "myFile", 1),
Account.id(100),
Instant.ofEpochMilli(1234),
(short) 1,
"Comment text",
"serverId",
true);
}
private static HumanComment asReply(HumanComment comment, String parentUuid) {
comment.parentUuid = parentUuid;
return comment;
}
private static HumanComment writtenOn(HumanComment comment, Instant writtenOn) {
comment.setWrittenOn(writtenOn);
return comment;
}
private static CommentThread<HumanComment> toThread(HumanComment... comments) {
return CommentThread.<HumanComment>builder().comments(ImmutableList.copyOf(comments)).build();
}
}