From 9de40f42b924aa652021f2e370b4a74b4332f0b1 Mon Sep 17 00:00:00 2001 From: guqing Date: Thu, 16 Feb 2023 18:38:35 +0800 Subject: [PATCH 1/2] fix: reply ordering for theme-side --- .../app/theme/finders/impl/CommentFinderImpl.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/run/halo/app/theme/finders/impl/CommentFinderImpl.java b/src/main/java/run/halo/app/theme/finders/impl/CommentFinderImpl.java index fd2c5d0db2..aecb2a4c78 100644 --- a/src/main/java/run/halo/app/theme/finders/impl/CommentFinderImpl.java +++ b/src/main/java/run/halo/app/theme/finders/impl/CommentFinderImpl.java @@ -70,12 +70,14 @@ public Mono> list(Ref ref, Integer page, Integer size) { @Override public Mono> listReply(String commentName, Integer page, Integer size) { - Comparator comparator = - Comparator.comparing(reply -> reply.getMetadata().getCreationTimestamp()); + Function approvedTime = reply -> reply.getSpec().getApprovedTime(); + Function createTime = reply -> reply.getMetadata().getCreationTimestamp(); + Comparator comparator = Comparator.nullsLast(Comparator.comparing(approvedTime)) + .thenComparing(createTime); return fixedReplyPredicate(commentName) .flatMap(fixedPredicate -> client.list(Reply.class, fixedPredicate, - comparator.reversed(), pageNullSafe(page), sizeNullSafe(size)) + comparator, pageNullSafe(page), sizeNullSafe(size)) .flatMap(list -> Flux.fromStream(list.get().map(this::toReplyVo)) .concatMap(Function.identity()) .collectList() @@ -170,12 +172,16 @@ static Comparator defaultComparator() { comment -> Objects.requireNonNullElse(comment.getSpec().getTop(), false); Function priority = comment -> Objects.requireNonNullElse(comment.getSpec().getPriority(), 0); + Function approvedTime = + comment -> comment.getSpec().getApprovedTime(); Function creationTimestamp = comment -> comment.getMetadata().getCreationTimestamp(); Function name = comment -> comment.getMetadata().getName(); + // comments sorted in descending order return Comparator.comparing(top) .thenComparing(priority) + .thenComparing(Comparator.nullsLast(Comparator.comparing(approvedTime))) .thenComparing(creationTimestamp) .thenComparing(name) .reversed(); From 90e27ea099de57a093af1145643da702d9d57ff4 Mon Sep 17 00:00:00 2001 From: guqing Date: Fri, 17 Feb 2023 18:53:19 +0800 Subject: [PATCH 2/2] refactor: add creation time for comment and reply --- .../content/comment/CommentServiceImpl.java | 3 + .../app/content/comment/CommentSorter.java | 12 ++-- .../app/content/comment/ReplyService.java | 20 +++++++ .../app/content/comment/ReplyServiceImpl.java | 13 ++--- .../app/core/extension/content/Comment.java | 21 ++++++- .../reconciler/CommentReconciler.java | 12 +--- .../app/metrics/ReplyEventReconciler.java | 26 ++++----- .../theme/finders/impl/CommentFinderImpl.java | 58 +++++++++++-------- .../comment/CommentServiceImplTest.java | 1 + .../content/comment/CommentSorterTest.java | 10 +++- .../app/content/comment/ReplyServiceTest.java | 52 +++++++++++++++++ .../finders/impl/CommentFinderImplTest.java | 57 ++++++++++++++++++ 12 files changed, 218 insertions(+), 67 deletions(-) create mode 100644 src/test/java/run/halo/app/content/comment/ReplyServiceTest.java diff --git a/src/main/java/run/halo/app/content/comment/CommentServiceImpl.java b/src/main/java/run/halo/app/content/comment/CommentServiceImpl.java index c72cb29c24..aa40beb665 100644 --- a/src/main/java/run/halo/app/content/comment/CommentServiceImpl.java +++ b/src/main/java/run/halo/app/content/comment/CommentServiceImpl.java @@ -93,6 +93,9 @@ public Mono create(Comment comment) { if (comment.getSpec().getOwner() != null) { return Mono.just(comment); } + if (comment.getSpec().getCreationTime() == null) { + comment.getSpec().setCreationTime(Instant.now()); + } // populate owner from current user return fetchCurrentUser() .map(this::toCommentOwner) diff --git a/src/main/java/run/halo/app/content/comment/CommentSorter.java b/src/main/java/run/halo/app/content/comment/CommentSorter.java index 62d3a08e2d..5c7e8be9d9 100644 --- a/src/main/java/run/halo/app/content/comment/CommentSorter.java +++ b/src/main/java/run/halo/app/content/comment/CommentSorter.java @@ -30,12 +30,12 @@ static Comparator from(CommentSorter sorter, Boolean ascending) { static Comparator from(CommentSorter sorter) { if (sorter == null) { - return defaultCommentComparator(); + return lastReplyTimeComparator(); } if (CREATE_TIME.equals(sorter)) { Function comparatorFunc = - comment -> comment.getMetadata().getCreationTimestamp(); - return Comparator.comparing(comparatorFunc) + comment -> comment.getSpec().getCreationTime(); + return Comparator.comparing(comparatorFunc, Comparators.nullsLow()) .thenComparing(name); } @@ -65,12 +65,12 @@ static CommentSorter convertFrom(String sort) { return null; } - static Comparator defaultCommentComparator() { + static Comparator lastReplyTimeComparator() { Function comparatorFunc = comment -> { Instant lastReplyTime = comment.getStatusOrDefault().getLastReplyTime(); - return Optional.ofNullable( - lastReplyTime).orElse(comment.getMetadata().getCreationTimestamp()); + return Optional.ofNullable(lastReplyTime) + .orElse(comment.getSpec().getCreationTime()); }; return Comparator.comparing(comparatorFunc, Comparators.nullsLow()) .thenComparing(name); diff --git a/src/main/java/run/halo/app/content/comment/ReplyService.java b/src/main/java/run/halo/app/content/comment/ReplyService.java index cf4ca145b6..2010f229ee 100644 --- a/src/main/java/run/halo/app/content/comment/ReplyService.java +++ b/src/main/java/run/halo/app/content/comment/ReplyService.java @@ -1,5 +1,9 @@ package run.halo.app.content.comment; +import java.time.Instant; +import java.util.Comparator; +import java.util.function.Function; +import org.springframework.util.comparator.Comparators; import reactor.core.publisher.Mono; import run.halo.app.core.extension.content.Reply; import run.halo.app.extension.ListResult; @@ -15,4 +19,20 @@ public interface ReplyService { Mono create(String commentName, Reply reply); Mono> list(ReplyQuery query); + + /** + * Ascending order by creation time. + * + * @return reply comparator + */ + static Comparator creationTimeAscComparator() { + Function creationTime = reply -> reply.getSpec().getCreationTime(); + Function metadataCreationTime = + reply -> reply.getMetadata().getCreationTimestamp(); + // ascending order by creation time + // asc nulls high will be placed at the end + return Comparator.comparing(creationTime, Comparators.nullsHigh()) + .thenComparing(metadataCreationTime) + .thenComparing(reply -> reply.getMetadata().getName()); + } } diff --git a/src/main/java/run/halo/app/content/comment/ReplyServiceImpl.java b/src/main/java/run/halo/app/content/comment/ReplyServiceImpl.java index 4cff27e633..271d49b893 100644 --- a/src/main/java/run/halo/app/content/comment/ReplyServiceImpl.java +++ b/src/main/java/run/halo/app/content/comment/ReplyServiceImpl.java @@ -3,7 +3,6 @@ import static run.halo.app.extension.router.selector.SelectorUtil.labelAndFieldSelectorToPredicate; import java.time.Instant; -import java.util.Comparator; import java.util.function.Function; import java.util.function.Predicate; import org.apache.commons.lang3.BooleanUtils; @@ -51,6 +50,9 @@ public Mono create(String commentName, Reply reply) { if (reply.getSpec().getPriority() == null) { reply.getSpec().setPriority(0); } + if (reply.getSpec().getCreationTime() == null) { + reply.getSpec().setCreationTime(Instant.now()); + } return environmentFetcher.fetchComment() .map(commentSetting -> { if (Boolean.FALSE.equals(commentSetting.getEnable())) { @@ -104,7 +106,8 @@ private boolean checkReplyOwner(Reply reply, Boolean onlySystemUser) { @Override public Mono> list(ReplyQuery query) { - return client.list(Reply.class, getReplyPredicate(query), defaultComparator(), + return client.list(Reply.class, getReplyPredicate(query), + ReplyService.creationTimeAscComparator(), query.getPage(), query.getSize()) .flatMap(list -> Flux.fromStream(list.get() .map(this::toListedReply)) @@ -140,12 +143,6 @@ private Mono getOwnerInfo(Reply reply) { "Unsupported owner kind: " + owner.getKind()); } - Comparator defaultComparator() { - Function createTime = reply -> reply.getMetadata().getCreationTimestamp(); - return Comparator.comparing(createTime) - .thenComparing(reply -> reply.getMetadata().getName()); - } - Predicate getReplyPredicate(ReplyQuery query) { Predicate predicate = reply -> true; if (query.getCommentName() != null) { diff --git a/src/main/java/run/halo/app/core/extension/content/Comment.java b/src/main/java/run/halo/app/core/extension/content/Comment.java index 967f2eddfe..e4bfd720bc 100644 --- a/src/main/java/run/halo/app/core/extension/content/Comment.java +++ b/src/main/java/run/halo/app/core/extension/content/Comment.java @@ -1,5 +1,7 @@ package run.halo.app.core.extension.content; +import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; + import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.v3.oas.annotations.media.Schema; import java.time.Instant; @@ -70,6 +72,11 @@ public static class BaseCommentSpec { private Instant approvedTime; + /** + * The user-defined creation time default is metadata.creationTimestamp. + */ + private Instant creationTime; + @Schema(required = true, defaultValue = "0") private Integer priority; @@ -84,6 +91,15 @@ public static class BaseCommentSpec { @Schema(required = true, defaultValue = "false") private Boolean hidden; + + /** + * If the creation time is null, use approvedTime. + * + * @return if creationTime is null returned approved time, otherwise creationTime. + */ + public Instant getCreationTime() { + return defaultIfNull(creationTime, approvedTime); + } } @Data @@ -130,8 +146,9 @@ public static int getUnreadReplyCount(List replies, Instant lastReadTime) if (lastReadTime == null) { return true; } - return existingReply.getMetadata().getCreationTimestamp() - .isAfter(lastReadTime); + Instant creationTime = defaultIfNull(existingReply.getSpec().getCreationTime(), + existingReply.getMetadata().getCreationTimestamp()); + return creationTime.isAfter(lastReadTime); }) .count(); return (int) unreadReplyCount; diff --git a/src/main/java/run/halo/app/core/extension/reconciler/CommentReconciler.java b/src/main/java/run/halo/app/core/extension/reconciler/CommentReconciler.java index ce95e1c08e..32222fc2f8 100644 --- a/src/main/java/run/halo/app/core/extension/reconciler/CommentReconciler.java +++ b/src/main/java/run/halo/app/core/extension/reconciler/CommentReconciler.java @@ -1,16 +1,15 @@ package run.halo.app.core.extension.reconciler; import java.time.Instant; -import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Function; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.ObjectUtils; import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; +import run.halo.app.content.comment.ReplyService; import run.halo.app.core.extension.Counter; import run.halo.app.core.extension.content.Comment; import run.halo.app.core.extension.content.Constant; @@ -110,7 +109,7 @@ private void updateUnReplyCountIfNecessary(Comment comment) { List replies = client.list(Reply.class, reply -> commentName.equals(reply.getSpec().getCommentName()) && reply.getMetadata().getDeletionTimestamp() == null, - defaultReplyComparator()); + ReplyService.creationTimeAscComparator()); // calculate unread reply count comment.getStatusOrDefault() @@ -181,11 +180,4 @@ private GroupVersionKind groupVersionKind(Ref ref) { } return new GroupVersionKind(ref.getGroup(), ref.getVersion(), ref.getKind()); } - - Comparator defaultReplyComparator() { - Function createTime = reply -> reply.getMetadata().getCreationTimestamp(); - return Comparator.comparing(createTime) - .thenComparing(reply -> reply.getMetadata().getName()) - .reversed(); - } } diff --git a/src/main/java/run/halo/app/metrics/ReplyEventReconciler.java b/src/main/java/run/halo/app/metrics/ReplyEventReconciler.java index 6d1074f5a7..f1da43872d 100644 --- a/src/main/java/run/halo/app/metrics/ReplyEventReconciler.java +++ b/src/main/java/run/halo/app/metrics/ReplyEventReconciler.java @@ -1,14 +1,15 @@ package run.halo.app.metrics; +import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; + import java.time.Duration; import java.time.Instant; -import java.util.Comparator; import java.util.List; -import java.util.function.Function; import lombok.extern.slf4j.Slf4j; import org.springframework.context.SmartLifecycle; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; +import run.halo.app.content.comment.ReplyService; import run.halo.app.core.extension.content.Comment; import run.halo.app.core.extension.content.Reply; import run.halo.app.event.post.ReplyEvent; @@ -51,20 +52,24 @@ public Result reconcile(ReplyEvent request) { .filter(comment -> comment.getMetadata().getDeletionTimestamp() == null) .ifPresent(comment -> { + // order by reply creation time desc to get first as last reply time List replies = client.list(Reply.class, record -> commentName.equals(record.getSpec().getCommentName()) && record.getMetadata().getDeletionTimestamp() == null, - defaultReplyComparator()); + ReplyService.creationTimeAscComparator().reversed()); Comment.CommentStatus status = comment.getStatusOrDefault(); // total reply count status.setReplyCount(replies.size()); // calculate last reply time - if (!replies.isEmpty()) { - Instant lastReplyTime = replies.get(0).getMetadata().getCreationTimestamp(); - status.setLastReplyTime(lastReplyTime); - } + Instant lastReplyTime = replies.stream() + .findFirst() + .map(reply -> defaultIfNull(reply.getSpec().getCreationTime(), + reply.getMetadata().getCreationTimestamp()) + ) + .orElse(null); + status.setLastReplyTime(lastReplyTime); Instant lastReadTime = comment.getSpec().getLastReadTime(); status.setUnreadReplyCount(Comment.getUnreadReplyCount(replies, lastReadTime)); @@ -74,13 +79,6 @@ record -> commentName.equals(record.getSpec().getCommentName()) return new Result(false, null); } - Comparator defaultReplyComparator() { - Function createTime = reply -> reply.getMetadata().getCreationTimestamp(); - return Comparator.comparing(createTime) - .thenComparing(reply -> reply.getMetadata().getName()) - .reversed(); - } - @Override public Controller setupWith(ControllerBuilder builder) { return new DefaultController<>( diff --git a/src/main/java/run/halo/app/theme/finders/impl/CommentFinderImpl.java b/src/main/java/run/halo/app/theme/finders/impl/CommentFinderImpl.java index aecb2a4c78..fd389b98a9 100644 --- a/src/main/java/run/halo/app/theme/finders/impl/CommentFinderImpl.java +++ b/src/main/java/run/halo/app/theme/finders/impl/CommentFinderImpl.java @@ -1,10 +1,8 @@ package run.halo.app.theme.finders.impl; import java.security.Principal; -import java.time.Instant; import java.util.Comparator; import java.util.List; -import java.util.Objects; import java.util.function.Function; import java.util.function.Predicate; import org.apache.commons.lang3.BooleanUtils; @@ -13,9 +11,11 @@ import org.springframework.security.core.context.ReactiveSecurityContextHolder; import org.springframework.security.core.context.SecurityContext; import org.springframework.util.Assert; +import org.springframework.util.comparator.Comparators; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import run.halo.app.content.comment.OwnerInfo; +import run.halo.app.content.comment.ReplyService; import run.halo.app.core.extension.User; import run.halo.app.core.extension.content.Comment; import run.halo.app.core.extension.content.Reply; @@ -70,14 +70,11 @@ public Mono> list(Ref ref, Integer page, Integer size) { @Override public Mono> listReply(String commentName, Integer page, Integer size) { - Function approvedTime = reply -> reply.getSpec().getApprovedTime(); - Function createTime = reply -> reply.getMetadata().getCreationTimestamp(); - Comparator comparator = Comparator.nullsLast(Comparator.comparing(approvedTime)) - .thenComparing(createTime); return fixedReplyPredicate(commentName) .flatMap(fixedPredicate -> client.list(Reply.class, fixedPredicate, - comparator, pageNullSafe(page), sizeNullSafe(size)) + ReplyService.creationTimeAscComparator(), pageNullSafe(page), + sizeNullSafe(size)) .flatMap(list -> Flux.fromStream(list.get().map(this::toReplyVo)) .concatMap(Function.identity()) .collectList() @@ -168,23 +165,36 @@ Mono getCurrentUserWithoutAnonymous() { } static Comparator defaultComparator() { - Function top = - comment -> Objects.requireNonNullElse(comment.getSpec().getTop(), false); - Function priority = - comment -> Objects.requireNonNullElse(comment.getSpec().getPriority(), 0); - Function approvedTime = - comment -> comment.getSpec().getApprovedTime(); - Function creationTimestamp = - comment -> comment.getMetadata().getCreationTimestamp(); - Function name = - comment -> comment.getMetadata().getName(); - // comments sorted in descending order - return Comparator.comparing(top) - .thenComparing(priority) - .thenComparing(Comparator.nullsLast(Comparator.comparing(approvedTime))) - .thenComparing(creationTimestamp) - .thenComparing(name) - .reversed(); + return new CommentComparator(); + } + + static class CommentComparator implements Comparator { + @Override + public int compare(Comment c1, Comment c2) { + boolean c1Top = BooleanUtils.isTrue(c1.getSpec().getTop()); + boolean c2Top = BooleanUtils.isTrue(c2.getSpec().getTop()); + if (c1Top == c2Top) { + int c1Priority = ObjectUtils.defaultIfNull(c1.getSpec().getPriority(), 0); + int c2Priority = ObjectUtils.defaultIfNull(c2.getSpec().getPriority(), 0); + if (c1Top) { + // 都置顶 + return Integer.compare(c1Priority, c2Priority); + } + + // 两个评论不置顶根据 creationTime 降序排列 + return Comparator.comparing( + (Comment comment) -> comment.getSpec().getCreationTime(), + Comparators.nullsLow()) + .thenComparing((Comment comment) -> comment.getMetadata().getName()) + .compare(c2, c1); + } else if (c1Top) { + // 只有 c1 置顶,c1 排前面 + return -1; + } else { + // 只有c2置顶, c2排在前面 + return 1; + } + } } int pageNullSafe(Integer page) { diff --git a/src/test/java/run/halo/app/content/comment/CommentServiceImplTest.java b/src/test/java/run/halo/app/content/comment/CommentServiceImplTest.java index 01f601eedb..7640eefab3 100644 --- a/src/test/java/run/halo/app/content/comment/CommentServiceImplTest.java +++ b/src/test/java/run/halo/app/content/comment/CommentServiceImplTest.java @@ -127,6 +127,7 @@ void create() throws JSONException { verify(client, times(1)).create(captor.capture()); Comment comment = captor.getValue(); + comment.getSpec().setCreationTime(null); JSONAssert.assertEquals(""" { "spec": { diff --git a/src/test/java/run/halo/app/content/comment/CommentSorterTest.java b/src/test/java/run/halo/app/content/comment/CommentSorterTest.java index 20f5a50e7b..0fa7bc0200 100644 --- a/src/test/java/run/halo/app/content/comment/CommentSorterTest.java +++ b/src/test/java/run/halo/app/content/comment/CommentSorterTest.java @@ -102,7 +102,7 @@ void sortByLastReplyTimeDesc() { @Test void sortByDefaultDesc() { - Comparator defaultComparator = CommentSorter.defaultCommentComparator().reversed(); + Comparator defaultComparator = CommentSorter.lastReplyTimeComparator().reversed(); List commentNames = comments().stream() .sorted(defaultComparator) .map(comment -> comment.getMetadata().getName()) @@ -124,8 +124,9 @@ List comments() { commentA.getMetadata().setName("A"); // create time commentA.getMetadata().setCreationTimestamp(now.plusSeconds(10)); - commentA.setSpec(new Comment.CommentSpec()); + commentA.getSpec().setCreationTime(commentA.getMetadata().getCreationTimestamp()); + commentA.setStatus(new Comment.CommentStatus()); // last reply time commentA.getStatus().setLastReplyTime(now.plusSeconds(5)); @@ -140,6 +141,7 @@ List comments() { commentB.setStatus(new Comment.CommentStatus()); commentB.getStatus().setLastReplyTime(now.plusSeconds(15)); commentB.getStatus().setReplyCount(8); + commentB.getSpec().setCreationTime(commentB.getMetadata().getCreationTimestamp()); Comment commentC = new Comment(); commentC.setMetadata(new Metadata()); @@ -151,6 +153,7 @@ List comments() { commentC.setStatus(new Comment.CommentStatus()); commentC.getStatus().setLastReplyTime(now.plusSeconds(3)); commentC.getStatus().setReplyCount(10); + commentC.getSpec().setCreationTime(commentC.getMetadata().getCreationTimestamp()); return List.of(commentA, commentB, commentC); } @@ -165,6 +168,7 @@ List commentsIncludeNoReply() { commentD.getMetadata().setCreationTimestamp(now.plusSeconds(50)); commentD.setSpec(new Comment.CommentSpec()); + commentD.getSpec().setCreationTime(commentD.getMetadata().getCreationTimestamp()); commentD.setStatus(new Comment.CommentStatus()); Comment commentE = new Comment(); @@ -172,8 +176,8 @@ List commentsIncludeNoReply() { commentE.getMetadata().setName("E"); commentE.getMetadata().setCreationTimestamp(now.plusSeconds(20)); - commentE.setSpec(new Comment.CommentSpec()); + commentE.getSpec().setCreationTime(commentE.getMetadata().getCreationTimestamp()); commentE.setStatus(new Comment.CommentStatus()); List comments = new ArrayList<>(comments()); diff --git a/src/test/java/run/halo/app/content/comment/ReplyServiceTest.java b/src/test/java/run/halo/app/content/comment/ReplyServiceTest.java new file mode 100644 index 0000000000..7fea22487f --- /dev/null +++ b/src/test/java/run/halo/app/content/comment/ReplyServiceTest.java @@ -0,0 +1,52 @@ +package run.halo.app.content.comment; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Instant; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import run.halo.app.core.extension.content.Reply; +import run.halo.app.extension.Metadata; + +/** + * Tests for {@link ReplyService}. + * + * @author guqing + * @since 2.0.0 + */ +class ReplyServiceTest { + private final Instant now = Instant.now(); + + @Test + void creationTimeAscComparator() { + // creation time: + // 1. now + 5s, name: 1 + // 2. now + 3s, name: 2 + // 3. now + 3s, name: 3 + // 5. now + 1s, name: 4 + // 6. now - 1s, name: 5 + // 7. null, name: 6 + Reply reply1 = createReply("1", now.plusSeconds(5)); + Reply reply2 = createReply("2", now.plusSeconds(3)); + Reply reply3 = createReply("3", now.plusSeconds(3)); + Reply reply4 = createReply("4", now.plusSeconds(1)); + Reply reply5 = createReply("5", now.minusSeconds(1)); + Reply reply6 = createReply("6", null); + String result = Stream.of(reply1, reply2, reply3, reply4, reply5, reply6) + .sorted(ReplyService.creationTimeAscComparator()) + .map(reply -> reply.getMetadata().getName()) + .collect(Collectors.joining(", ")); + assertThat(result).isEqualTo("5, 4, 2, 3, 1, 6"); + } + + Reply createReply(String name, Instant creationTime) { + Reply reply = new Reply(); + reply.setMetadata(new Metadata()); + reply.getMetadata().setName(name); + reply.getMetadata().setCreationTimestamp(now); + reply.setSpec(new Reply.ReplySpec()); + reply.getSpec().setCreationTime(creationTime); + return reply; + } +} \ No newline at end of file diff --git a/src/test/java/run/halo/app/theme/finders/impl/CommentFinderImplTest.java b/src/test/java/run/halo/app/theme/finders/impl/CommentFinderImplTest.java index ce4f0d022e..a7cf6dceb2 100644 --- a/src/test/java/run/halo/app/theme/finders/impl/CommentFinderImplTest.java +++ b/src/test/java/run/halo/app/theme/finders/impl/CommentFinderImplTest.java @@ -5,8 +5,10 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; +import java.time.Instant; import java.util.List; import java.util.function.Predicate; +import java.util.stream.Collectors; import java.util.stream.Stream; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -25,6 +27,7 @@ import run.halo.app.extension.GroupVersionKind; import run.halo.app.extension.ListResult; import run.halo.app.extension.Metadata; +import run.halo.app.extension.MetadataOperator; import run.halo.app.extension.ReactiveExtensionClient; import run.halo.app.extension.Ref; import run.halo.app.infra.AnonymousUserConst; @@ -100,6 +103,60 @@ void listWhenUserLoggedIn() { .verifyComplete(); } + + @Test + void commentComparator() { + // 1, now + 1s, top, 0 + // 2, now + 2s, top, 1 + // 3, now + 3s, top, 2 + // 4, now + 4s, top, 2 + // 5, now + 4s, top, 3 + // 6, now + 1s, no, 0 + // 7, now + 2s, no, 0 + // 8, now + 3s, no, 0 + // 9, now + 3s, no, 0 + // 10, null, no, 0 + // 11, null, no, 1 + // 12, null, no, 3 + // 13, now + 3s, no, 3 + Instant now = Instant.now(); + var comment1 = commentForCompare("1", now.plusSeconds(1), true, 0); + var comment2 = commentForCompare("2", now.plusSeconds(2), true, 1); + var comment3 = commentForCompare("3", now.plusSeconds(3), true, 2); + var comment4 = commentForCompare("4", now.plusSeconds(4), true, 2); + var comment5 = commentForCompare("5", now.plusSeconds(4), true, 3); + var comment6 = commentForCompare("6", now.plusSeconds(4), true, 3); + var comment7 = commentForCompare("7", now.plusSeconds(1), false, 0); + var comment8 = commentForCompare("8", now.plusSeconds(2), false, 0); + var comment9 = commentForCompare("9", now.plusSeconds(3), false, 0); + var comment10 = commentForCompare("10", now.plusSeconds(3), false, 0); + var comment11 = commentForCompare("11", null, false, 0); + var comment12 = commentForCompare("12", null, false, 1); + var comment13 = commentForCompare("13", null, false, 3); + var comment14 = commentForCompare("14", now.plusSeconds(3), false, 3); + + var result = Stream.of(comment1, comment2, comment3, comment4, comment5, comment6, + comment7, comment8, comment9, comment10, comment11, comment12, comment13, + comment14) + .sorted(CommentFinderImpl.defaultComparator()) + .map(Comment::getMetadata) + .map(MetadataOperator::getName) + .collect(Collectors.joining(", ")); + assertThat(result).isEqualTo("1, 2, 3, 4, 5, 6, 9, 14, 10, 8, 7, 13, 12, 11"); + } + + Comment commentForCompare(String name, Instant creationTime, boolean top, int priority) { + Comment comment = new Comment(); + comment.setMetadata(new Metadata()); + comment.getMetadata().setName(name); + comment.getMetadata().setCreationTimestamp(Instant.now()); + comment.setSpec(new Comment.CommentSpec()); + comment.getSpec().setCreationTime(creationTime); + comment.getSpec().setTop(top); + comment.getSpec().setPriority(priority); + return comment; + } + @SuppressWarnings("unchecked") private void mockWhenListComment() { // Mock