From 20d80f8f6584561427224e6e1187e9e5a4dfc5e7 Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:32:06 +0800 Subject: [PATCH] refactor: using index mechanisms to optimize comment queries (#5453) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area core /milestone 2.14.x #### What this PR does / why we need it: 使用索引机制优化评论数据查询以提高效率 how to test it? - 测试 console 评论列表和筛选条件是否正确 - 测试主题端评论显示是否正确 #### Does this PR introduce a user-facing change? ```release-note 使用索引机制优化评论数据查询以提高效率 ``` --- .../app/core/extension/content/Comment.java | 8 + .../extension/index/query/QueryFactory.java | 2 +- .../app/content/comment/CommentQuery.java | 199 ++-------- .../content/comment/CommentServiceImpl.java | 42 +- .../run/halo/app/infra/SchemeInitializer.java | 66 +++- .../theme/endpoint/CommentFinderEndpoint.java | 32 +- .../finders/CommentPublicQueryService.java | 5 +- .../impl/CommentPublicQueryServiceImpl.java | 138 +++---- .../app/content/comment/CommentQueryTest.java | 361 ------------------ .../comment/CommentServiceImplTest.java | 59 +-- .../endpoint/CommentFinderEndpointTest.java | 24 +- .../CommentPublicQueryServiceImplTest.java | 99 ----- ...mentPublicQueryServiceIntegrationTest.java | 318 +++++++++++++++ .../modules/contents/comments/CommentList.vue | 30 +- ...i-console-halo-run-v1alpha1-comment-api.ts | 108 ------ 15 files changed, 542 insertions(+), 949 deletions(-) delete mode 100644 application/src/test/java/run/halo/app/content/comment/CommentQueryTest.java create mode 100644 application/src/test/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceIntegrationTest.java diff --git a/api/src/main/java/run/halo/app/core/extension/content/Comment.java b/api/src/main/java/run/halo/app/core/extension/content/Comment.java index 2233a127a6..1d58182830 100644 --- a/api/src/main/java/run/halo/app/core/extension/content/Comment.java +++ b/api/src/main/java/run/halo/app/core/extension/content/Comment.java @@ -116,6 +116,10 @@ public static class CommentOwner { public String getAnnotation(String key) { return annotations == null ? null : annotations.get(key); } + + public static String ownerIdentity(String kind, String name) { + return kind + "#" + name; + } } @Data @@ -132,6 +136,10 @@ public static class CommentStatus { private Boolean hasNewReply; } + public static String toSubjectRefKey(Ref subjectRef) { + return subjectRef.getGroup() + "/" + subjectRef.getKind() + "/" + subjectRef.getName(); + } + public static int getUnreadReplyCount(List replies, Instant lastReadTime) { if (CollectionUtils.isEmpty(replies)) { return 0; diff --git a/api/src/main/java/run/halo/app/extension/index/query/QueryFactory.java b/api/src/main/java/run/halo/app/extension/index/query/QueryFactory.java index 741d96c508..84cbac20ca 100644 --- a/api/src/main/java/run/halo/app/extension/index/query/QueryFactory.java +++ b/api/src/main/java/run/halo/app/extension/index/query/QueryFactory.java @@ -120,7 +120,7 @@ public static Query and(Collection queries) { return new And(queries); } - public static And and(Query query1, Query query2) { + public static Query and(Query query1, Query query2) { Collection queries = Arrays.asList(query1, query2); return new And(queries); } diff --git a/application/src/main/java/run/halo/app/content/comment/CommentQuery.java b/application/src/main/java/run/halo/app/content/comment/CommentQuery.java index a5bc893a24..a84ea2cef2 100644 --- a/application/src/main/java/run/halo/app/content/comment/CommentQuery.java +++ b/application/src/main/java/run/halo/app/content/comment/CommentQuery.java @@ -1,29 +1,24 @@ package run.halo.app.content.comment; -import static java.util.Comparator.comparing; -import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; -import static run.halo.app.extension.router.selector.SelectorUtil.labelAndFieldSelectorToPredicate; +import static run.halo.app.extension.index.query.QueryFactory.and; +import static run.halo.app.extension.index.query.QueryFactory.contains; +import static run.halo.app.extension.index.query.QueryFactory.equal; +import static run.halo.app.extension.router.selector.SelectorUtil.labelAndFieldSelectorToListOptions; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Schema; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.function.Function; -import java.util.function.Predicate; import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Sort; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.server.ServerWebExchange; +import run.halo.app.core.extension.User; import run.halo.app.core.extension.content.Comment; import run.halo.app.core.extension.endpoint.SortResolver; -import run.halo.app.extension.Comparators; -import run.halo.app.extension.Extension; -import run.halo.app.extension.Ref; +import run.halo.app.extension.ListOptions; +import run.halo.app.extension.PageRequest; +import run.halo.app.extension.PageRequestImpl; import run.halo.app.extension.router.IListRequest; +import run.halo.app.extension.router.selector.FieldSelector; /** * Query criteria for comment list. @@ -34,12 +29,6 @@ public class CommentQuery extends IListRequest.QueryListRequest { private final ServerWebExchange exchange; - static final Function LAST_REPLY_TIME_FUNC = - comment -> { - Instant lastReplyTime = comment.getStatusOrDefault().getLastReplyTime(); - return Optional.ofNullable(lastReplyTime) - .orElse(comment.getSpec().getCreationTime()); - }; public CommentQuery(ServerRequest request) { super(request.queryParams()); @@ -52,26 +41,6 @@ public String getKeyword() { return StringUtils.isBlank(keyword) ? null : keyword; } - @Schema(description = "Comments approved.") - public Boolean getApproved() { - return convertBooleanOrNull(queryParams.getFirst("approved")); - } - - @Schema(description = "The comment is hidden from the theme side.") - public Boolean getHidden() { - return convertBooleanOrNull(queryParams.getFirst("hidden")); - } - - @Schema(description = "Send notifications when there are new replies.") - public Boolean getAllowNotification() { - return convertBooleanOrNull(queryParams.getFirst("allowNotification")); - } - - @Schema(description = "Comment top display.") - public Boolean getTop() { - return convertBooleanOrNull(queryParams.getFirst("top")); - } - @Schema(description = "Commenter kind.") public String getOwnerKind() { String ownerKind = queryParams.getFirst("ownerKind"); @@ -84,18 +53,6 @@ public String getOwnerName() { return StringUtils.isBlank(ownerName) ? null : ownerName; } - @Schema(description = "Comment subject kind.") - public String getSubjectKind() { - String subjectKind = queryParams.getFirst("subjectKind"); - return StringUtils.isBlank(subjectKind) ? null : subjectKind; - } - - @Schema(description = "Comment subject name.") - public String getSubjectName() { - String subjectName = queryParams.getFirst("subjectName"); - return StringUtils.isBlank(subjectName) ? null : subjectName; - } - @ArraySchema(uniqueItems = true, arraySchema = @Schema(name = "sort", description = "Sort property and direction of the list result. Supported fields: " @@ -104,139 +61,35 @@ public String getSubjectName() { implementation = String.class, example = "creationTimestamp,desc")) public Sort getSort() { - return SortResolver.defaultInstance.resolve(exchange); + var sort = SortResolver.defaultInstance.resolve(exchange); + return sort.and(Sort.by("spec.creationTime", "metadata.name").descending()); } - /** - * Build a comparator from the query. - * - * @return comparator - */ - public Comparator toComparator() { - var sort = getSort(); - var creationTimestampOrder = sort.getOrderFor("creationTimestamp"); - List> comparators = new ArrayList<>(); - if (creationTimestampOrder != null) { - Comparator comparator = - comparing(comment -> comment.getMetadata().getCreationTimestamp()); - if (creationTimestampOrder.isDescending()) { - comparator = comparator.reversed(); - } - comparators.add(comparator); - } - - var replyCountOrder = sort.getOrderFor("replyCount"); - if (replyCountOrder != null) { - Comparator comparator = comparing( - comment -> defaultIfNull(comment.getStatusOrDefault().getReplyCount(), 0)); - if (replyCountOrder.isDescending()) { - comparator = comparator.reversed(); - } - comparators.add(comparator); - } - - var lastReplyTimeOrder = sort.getOrderFor("lastReplyTime"); - if (lastReplyTimeOrder == null) { - lastReplyTimeOrder = new Sort.Order(Sort.Direction.DESC, "lastReplyTime"); - } - Comparator comparator = comparing(LAST_REPLY_TIME_FUNC, - Comparators.nullsComparator(lastReplyTimeOrder.isAscending())); - if (lastReplyTimeOrder.isDescending()) { - comparator = comparator.reversed(); - } - comparators.add(comparator); - comparators.add(Comparators.compareCreationTimestamp(false)); - comparators.add(Comparators.compareName(true)); - return comparators.stream() - .reduce(Comparator::thenComparing) - .orElse(null); + public PageRequest toPageRequest() { + return PageRequestImpl.of(getPage(), getSize(), getSort()); } /** - * Build a predicate from the query. - * - * @return predicate + * Convert to list options. */ - Predicate toPredicate() { - Predicate predicate = comment -> true; + public ListOptions toListOptions() { + var listOptions = + labelAndFieldSelectorToListOptions(getLabelSelector(), getFieldSelector()); + var fieldQuery = listOptions.getFieldSelector().query(); String keyword = getKeyword(); - if (keyword != null) { - predicate = predicate.and(comment -> { - String raw = comment.getSpec().getRaw(); - return StringUtils.containsIgnoreCase(raw, keyword); - }); - } - - Boolean approved = getApproved(); - if (approved != null) { - predicate = - predicate.and(comment -> Objects.equals(comment.getSpec().getApproved(), approved)); - } - Boolean hidden = getHidden(); - if (hidden != null) { - predicate = - predicate.and(comment -> Objects.equals(comment.getSpec().getHidden(), hidden)); - } - - Boolean top = getTop(); - if (top != null) { - predicate = predicate.and(comment -> Objects.equals(comment.getSpec().getTop(), top)); - } - - Boolean allowNotification = getAllowNotification(); - if (allowNotification != null) { - predicate = predicate.and( - comment -> Objects.equals(comment.getSpec().getAllowNotification(), - allowNotification)); - } - - String ownerKind = getOwnerKind(); - if (ownerKind != null) { - predicate = predicate.and(comment -> { - Comment.CommentOwner owner = comment.getSpec().getOwner(); - return Objects.equals(owner.getKind(), ownerKind); - }); + if (StringUtils.isNotBlank(keyword)) { + fieldQuery = and(fieldQuery, contains("spec.raw", keyword)); } String ownerName = getOwnerName(); - if (ownerName != null) { - predicate = predicate.and(comment -> { - Comment.CommentOwner owner = comment.getSpec().getOwner(); - if (Comment.CommentOwner.KIND_EMAIL.equals(owner.getKind())) { - return Objects.equals(owner.getKind(), ownerKind) - && (StringUtils.containsIgnoreCase(owner.getName(), ownerName) - || StringUtils.containsIgnoreCase(owner.getDisplayName(), ownerName)); - } - return Objects.equals(owner.getKind(), ownerKind) - && StringUtils.containsIgnoreCase(owner.getName(), ownerName); - }); - } - - String subjectKind = getSubjectKind(); - if (subjectKind != null) { - predicate = predicate.and(comment -> { - Ref subjectRef = comment.getSpec().getSubjectRef(); - return Objects.equals(subjectRef.getKind(), subjectKind); - }); + if (StringUtils.isNotBlank(ownerName)) { + String ownerKind = StringUtils.defaultIfBlank(getOwnerKind(), User.KIND); + fieldQuery = and(fieldQuery, + equal("spec.owner", Comment.CommentOwner.ownerIdentity(ownerKind, ownerName))); } - String subjectName = getSubjectName(); - if (subjectName != null) { - predicate = predicate.and(comment -> { - Ref subjectRef = comment.getSpec().getSubjectRef(); - return Objects.equals(subjectRef.getKind(), subjectKind) - && StringUtils.containsIgnoreCase(subjectRef.getName(), subjectName); - }); - } - - Predicate labelAndFieldSelectorPredicate = - labelAndFieldSelectorToPredicate(getLabelSelector(), - getFieldSelector()); - return predicate.and(labelAndFieldSelectorPredicate); - } - - private Boolean convertBooleanOrNull(String value) { - return StringUtils.isBlank(value) ? null : Boolean.parseBoolean(value); + listOptions.setFieldSelector(FieldSelector.of(fieldQuery)); + return listOptions; } } diff --git a/application/src/main/java/run/halo/app/content/comment/CommentServiceImpl.java b/application/src/main/java/run/halo/app/content/comment/CommentServiceImpl.java index 51762ae320..77e4595609 100644 --- a/application/src/main/java/run/halo/app/content/comment/CommentServiceImpl.java +++ b/application/src/main/java/run/halo/app/content/comment/CommentServiceImpl.java @@ -50,9 +50,8 @@ public CommentServiceImpl(ReactiveExtensionClient client, @Override public Mono> listComment(CommentQuery commentQuery) { - return this.client.list(Comment.class, commentQuery.toPredicate(), - commentQuery.toComparator(), - commentQuery.getPage(), commentQuery.getSize()) + return this.client.listBy(Comment.class, commentQuery.toListOptions(), + commentQuery.toPageRequest()) .flatMap(comments -> Flux.fromStream(comments.get() .map(this::toListedComment)) .concatMap(Function.identity()) @@ -138,32 +137,21 @@ private Mono fetchCurrentUser() { } private Mono toListedComment(Comment comment) { - ListedComment.ListedCommentBuilder commentBuilder = ListedComment.builder() - .comment(comment); - return Mono.just(commentBuilder) - .flatMap(builder -> { - Comment.CommentOwner owner = comment.getSpec().getOwner(); - // not empty - return getCommentOwnerInfo(owner) - .map(builder::owner); - }) - .flatMap(builder -> getCommentSubject(comment.getSpec().getSubjectRef()) - .map(subject -> { - builder.subject(subject); - return builder; - }) - .switchIfEmpty(Mono.just(builder)) - ) - .map(ListedComment.ListedCommentBuilder::build) - .flatMap(lc -> fetchStats(comment) - .doOnNext(lc::setStats) - .thenReturn(lc)); + var builder = ListedComment.builder().comment(comment); + // not empty + var ownerInfoMono = getCommentOwnerInfo(comment.getSpec().getOwner()) + .doOnNext(builder::owner); + var subjectMono = getCommentSubject(comment.getSpec().getSubjectRef()) + .doOnNext(builder::subject); + var statsMono = fetchStats(comment.getMetadata().getName()) + .doOnNext(builder::stats); + return Mono.when(ownerInfoMono, subjectMono, statsMono) + .then(Mono.fromSupplier(builder::build)); } - Mono fetchStats(Comment comment) { - Assert.notNull(comment, "The comment must not be null."); - String name = comment.getMetadata().getName(); - return counterService.getByName(MeterUtils.nameOf(Comment.class, name)) + Mono fetchStats(String commentName) { + Assert.notNull(commentName, "The commentName must not be null."); + return counterService.getByName(MeterUtils.nameOf(Comment.class, commentName)) .map(counter -> CommentStats.builder() .upvote(counter.getUpvote()) .build() diff --git a/application/src/main/java/run/halo/app/infra/SchemeInitializer.java b/application/src/main/java/run/halo/app/infra/SchemeInitializer.java index 649bd3ea80..e5fcc67de4 100644 --- a/application/src/main/java/run/halo/app/infra/SchemeInitializer.java +++ b/application/src/main/java/run/halo/app/infra/SchemeInitializer.java @@ -1,5 +1,7 @@ package run.halo.app.infra; +import static org.apache.commons.lang3.BooleanUtils.isTrue; +import static org.apache.commons.lang3.BooleanUtils.toStringTrueFalse; import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; import static run.halo.app.extension.index.IndexAttributeFactory.multiValueAttribute; import static run.halo.app.extension.index.IndexAttributeFactory.simpleAttribute; @@ -206,7 +208,69 @@ public void onApplicationEvent(@NonNull ApplicationContextInitializedEvent event ) ); }); - schemeManager.register(Comment.class); + schemeManager.register(Comment.class, indexSpecs -> { + indexSpecs.add(new IndexSpec() + .setName("spec.creationTime") + .setIndexFunc(simpleAttribute(Comment.class, + comment -> comment.getSpec().getCreationTime().toString()) + )); + indexSpecs.add(new IndexSpec() + .setName("spec.approved") + .setIndexFunc(simpleAttribute(Comment.class, + comment -> toStringTrueFalse(isTrue(comment.getSpec().getApproved()))) + )); + indexSpecs.add(new IndexSpec() + .setName("spec.owner") + .setIndexFunc(simpleAttribute(Comment.class, comment -> { + var owner = comment.getSpec().getOwner(); + return Comment.CommentOwner.ownerIdentity(owner.getKind(), owner.getName()); + }))); + indexSpecs.add(new IndexSpec() + .setName("spec.subjectRef") + .setIndexFunc(simpleAttribute(Comment.class, + comment -> Comment.toSubjectRefKey(comment.getSpec().getSubjectRef())) + )); + indexSpecs.add(new IndexSpec() + .setName("spec.top") + .setIndexFunc(simpleAttribute(Comment.class, + comment -> toStringTrueFalse(isTrue(comment.getSpec().getTop()))) + )); + indexSpecs.add(new IndexSpec() + .setName("spec.hidden") + .setIndexFunc(simpleAttribute(Comment.class, + comment -> toStringTrueFalse(isTrue(comment.getSpec().getHidden()))) + )); + indexSpecs.add(new IndexSpec() + .setName("spec.priority") + .setIndexFunc(simpleAttribute(Comment.class, + comment -> { + var isTop = comment.getSpec().getTop(); + // only top comments have priority + if (!isTop) { + return "0"; + } + return defaultIfNull(comment.getSpec().getPriority(), 0).toString(); + }) + )); + indexSpecs.add(new IndexSpec() + .setName("spec.raw") + .setIndexFunc(simpleAttribute(Comment.class, + comment -> comment.getSpec().getRaw()) + )); + indexSpecs.add(new IndexSpec() + .setName("status.lastReplyTime") + .setIndexFunc(simpleAttribute(Comment.class, comment -> { + var lastReplyTime = comment.getStatusOrDefault().getLastReplyTime(); + return defaultIfNull(lastReplyTime, + comment.getSpec().getCreationTime()).toString(); + }))); + indexSpecs.add(new IndexSpec() + .setName("status.replyCount") + .setIndexFunc(simpleAttribute(Comment.class, comment -> { + var replyCount = comment.getStatusOrDefault().getReplyCount(); + return defaultIfNull(replyCount, 0).toString(); + }))); + }); schemeManager.register(Reply.class); schemeManager.register(SinglePage.class); // storage.halo.run diff --git a/application/src/main/java/run/halo/app/theme/endpoint/CommentFinderEndpoint.java b/application/src/main/java/run/halo/app/theme/endpoint/CommentFinderEndpoint.java index 1621f6e115..37f9fd3d8a 100644 --- a/application/src/main/java/run/halo/app/theme/endpoint/CommentFinderEndpoint.java +++ b/application/src/main/java/run/halo/app/theme/endpoint/CommentFinderEndpoint.java @@ -1,7 +1,6 @@ package run.halo.app.theme.endpoint; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; -import static java.util.Comparator.comparing; import static org.apache.commons.lang3.BooleanUtils.isFalse; import static org.apache.commons.lang3.BooleanUtils.isTrue; import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; @@ -16,8 +15,6 @@ import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Schema; -import java.util.ArrayList; -import java.util.Comparator; import java.util.List; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; @@ -43,9 +40,10 @@ import run.halo.app.core.extension.content.Reply; import run.halo.app.core.extension.endpoint.CustomEndpoint; import run.halo.app.core.extension.endpoint.SortResolver; -import run.halo.app.extension.Comparators; import run.halo.app.extension.GroupVersion; import run.halo.app.extension.ListResult; +import run.halo.app.extension.PageRequest; +import run.halo.app.extension.PageRequestImpl; import run.halo.app.extension.Ref; import run.halo.app.extension.router.IListRequest; import run.halo.app.extension.router.QueryParamBuildUtil; @@ -213,9 +211,7 @@ private boolean checkReplyOwner(Reply reply, Boolean onlySystemUser) { Mono listComments(ServerRequest request) { CommentQuery commentQuery = new CommentQuery(request); - var comparator = commentQuery.toComparator(); - return commentPublicQueryService.list(commentQuery.toRef(), commentQuery.getPage(), - commentQuery.getSize(), comparator) + return commentPublicQueryService.list(commentQuery.toRef(), commentQuery.toPageRequest()) .flatMap(list -> ServerResponse.ok().bodyValue(list)); } @@ -302,26 +298,12 @@ Ref toRef() { return ref; } - String emptyToNull(String str) { - return StringUtils.isBlank(str) ? null : str; + public PageRequest toPageRequest() { + return PageRequestImpl.of(getPage(), getSize(), getSort()); } - public Comparator toComparator() { - var sort = getSort(); - var ctOrder = sort.getOrderFor("creationTimestamp"); - List> comparators = new ArrayList<>(); - if (ctOrder != null) { - Comparator comparator = - comparing(comment -> comment.getMetadata().getCreationTimestamp()); - if (ctOrder.isDescending()) { - comparator = comparator.reversed(); - } - comparators.add(comparator); - comparators.add(Comparators.compareName(true)); - } - return comparators.stream() - .reduce(Comparator::thenComparing) - .orElse(null); + String emptyToNull(String str) { + return StringUtils.isBlank(str) ? null : str; } } diff --git a/application/src/main/java/run/halo/app/theme/finders/CommentPublicQueryService.java b/application/src/main/java/run/halo/app/theme/finders/CommentPublicQueryService.java index 0876681e83..ab00919ebf 100644 --- a/application/src/main/java/run/halo/app/theme/finders/CommentPublicQueryService.java +++ b/application/src/main/java/run/halo/app/theme/finders/CommentPublicQueryService.java @@ -3,9 +3,9 @@ import java.util.Comparator; import org.springframework.lang.Nullable; import reactor.core.publisher.Mono; -import run.halo.app.core.extension.content.Comment; import run.halo.app.core.extension.content.Reply; import run.halo.app.extension.ListResult; +import run.halo.app.extension.PageRequest; import run.halo.app.extension.Ref; import run.halo.app.theme.finders.vo.CommentVo; import run.halo.app.theme.finders.vo.ReplyVo; @@ -21,8 +21,7 @@ public interface CommentPublicQueryService { Mono> list(Ref ref, @Nullable Integer page, @Nullable Integer size); - Mono> list(Ref ref, @Nullable Integer page, - @Nullable Integer size, @Nullable Comparator comparator); + Mono> list(Ref ref, @Nullable PageRequest pageRequest); Mono> listReply(String commentName, @Nullable Integer page, @Nullable Integer size); diff --git a/application/src/main/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceImpl.java b/application/src/main/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceImpl.java index 8336ee93c1..34bdf2bf5f 100644 --- a/application/src/main/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceImpl.java +++ b/application/src/main/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceImpl.java @@ -2,34 +2,42 @@ import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; +import static run.halo.app.extension.index.query.QueryFactory.and; +import static run.halo.app.extension.index.query.QueryFactory.equal; +import static run.halo.app.extension.index.query.QueryFactory.or; import java.security.Principal; -import java.time.Instant; import java.util.Comparator; import java.util.List; -import java.util.Objects; +import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.data.domain.Sort; import org.springframework.lang.Nullable; import org.springframework.security.core.context.ReactiveSecurityContextHolder; import org.springframework.security.core.context.SecurityContext; import org.springframework.stereotype.Component; 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; import run.halo.app.core.extension.service.UserService; import run.halo.app.extension.AbstractExtension; +import run.halo.app.extension.ListOptions; import run.halo.app.extension.ListResult; +import run.halo.app.extension.PageRequest; +import run.halo.app.extension.PageRequestImpl; import run.halo.app.extension.ReactiveExtensionClient; import run.halo.app.extension.Ref; +import run.halo.app.extension.index.query.QueryFactory; +import run.halo.app.extension.router.selector.FieldSelector; import run.halo.app.infra.AnonymousUserConst; import run.halo.app.metrics.CounterService; import run.halo.app.metrics.MeterUtils; @@ -43,6 +51,7 @@ * comment public query service implementation. * * @author LIlGG + * @author guqing */ @Component @RequiredArgsConstructor @@ -61,30 +70,31 @@ public Mono getByName(String name) { @Override public Mono> list(Ref ref, Integer page, Integer size) { - return list(ref, page, size, defaultComparator()); + return list(ref, PageRequestImpl.of(pageNullSafe(page), sizeNullSafe(size), defaultSort())); } @Override - public Mono> list(Ref ref, Integer page, Integer size, - Comparator comparator) { - final Comparator commentComparator = - Objects.isNull(comparator) ? defaultComparator() - : comparator.thenComparing(defaultComparator()); - return fixedCommentPredicate(ref) - .flatMap(fixedPredicate -> - client.list(Comment.class, fixedPredicate, - commentComparator, - pageNullSafe(page), sizeNullSafe(size)) - .flatMap(list -> Flux.fromStream(list.get().map(this::toCommentVo)) + public Mono> list(Ref ref, PageRequest pageParam) { + var pageRequest = Optional.ofNullable(pageParam) + .map(page -> page.withSort(page.getSort().and(defaultSort()))) + .orElse(PageRequestImpl.ofSize(0)); + return fixedCommentFieldQuery(ref) + .flatMap(fixedFieldQuery -> { + var listOptions = new ListOptions(); + listOptions.setFieldSelector(fixedFieldQuery); + return client.listBy(Comment.class, listOptions, pageRequest) + .flatMap(listResult -> Flux.fromStream(listResult.get()) + .map(this::toCommentVo) .concatMap(Function.identity()) .collectList() - .map(commentVos -> new ListResult<>(list.getPage(), list.getSize(), - list.getTotal(), + .map(commentVos -> new ListResult<>(listResult.getPage(), + listResult.getSize(), + listResult.getTotal(), commentVos) ) - ) - .defaultIfEmpty(new ListResult<>(page, size, 0L, List.of())) - ); + ); + }) + .defaultIfEmpty(ListResult.emptyResult()); } @Override @@ -193,28 +203,31 @@ private Mono getOwnerInfo(Comment.CommentOwner owner) { .map(OwnerInfo::from); } - private Mono> fixedCommentPredicate(@Nullable Ref ref) { - Predicate basePredicate = - comment -> comment.getMetadata().getDeletionTimestamp() == null; - if (ref != null) { - basePredicate = basePredicate - .and(comment -> comment.getSpec().getSubjectRef().equals(ref)); - } - - // is approved and not hidden - Predicate approvedPredicate = - comment -> BooleanUtils.isFalse(comment.getSpec().getHidden()) - && BooleanUtils.isTrue(comment.getSpec().getApproved()); - return getCurrentUserWithoutAnonymous() - .map(username -> { - Predicate isOwner = comment -> { - Comment.CommentOwner owner = comment.getSpec().getOwner(); - return owner != null && StringUtils.equals(username, owner.getName()); - }; - return approvedPredicate.or(isOwner); + private Mono fixedCommentFieldQuery(@Nullable Ref ref) { + return Mono.fromSupplier( + () -> { + var baseQuery = QueryFactory.isNull("metadata.deletionTimestamp"); + if (ref != null) { + baseQuery = + and(baseQuery, + equal("spec.subjectRef", Comment.toSubjectRefKey(ref))); + } + return baseQuery; + }) + .flatMap(query -> { + var approvedQuery = and( + equal("spec.approved", BooleanUtils.TRUE), + equal("spec.hidden", BooleanUtils.FALSE) + ); + // we should list all comments that the user owns + return getCurrentUserWithoutAnonymous() + .map(username -> or(approvedQuery, equal("spec.owner", + Comment.CommentOwner.ownerIdentity(User.KIND, username))) + ) + .defaultIfEmpty(approvedQuery) + .map(compositeQuery -> and(query, compositeQuery)); }) - .defaultIfEmpty(approvedPredicate) - .map(basePredicate::and); + .map(FieldSelector::of); } private Mono> fixedReplyPredicate(String commentName) { @@ -247,43 +260,12 @@ Mono getCurrentUserWithoutAnonymous() { .filter(username -> !AnonymousUserConst.PRINCIPAL.equals(username)); } - static Comparator defaultComparator() { - 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()); - - // c1 top = true && c2 top = false - if (c1Top && !c2Top) { - return -1; - } - - // c1 top = false && c2 top = true - if (!c1Top && c2Top) { - return 1; - } - // c1 top = c2 top = true || c1 top = c2 top = false - var priorityComparator = Comparator.comparing( - comment -> defaultIfNull(comment.getSpec().getPriority(), 0)); - - var creationTimeComparator = Comparator.comparing( - comment -> comment.getSpec().getCreationTime(), - Comparators.nullsHigh(Comparator.reverseOrder())); - - var nameComparator = Comparator.comparing( - comment -> comment.getMetadata().getName()); - - if (c1Top) { - return priorityComparator.thenComparing(creationTimeComparator) - .thenComparing(nameComparator) - .compare(c1, c2); - } - return creationTimeComparator.thenComparing(nameComparator).compare(c1, c2); - } + static Sort defaultSort() { + return Sort.by(Sort.Order.desc("spec.top"), + Sort.Order.asc("spec.priority"), + Sort.Order.desc("spec.creationTime"), + Sort.Order.asc("metadata.name") + ); } int pageNullSafe(Integer page) { diff --git a/application/src/test/java/run/halo/app/content/comment/CommentQueryTest.java b/application/src/test/java/run/halo/app/content/comment/CommentQueryTest.java deleted file mode 100644 index 6fb78b1bdf..0000000000 --- a/application/src/test/java/run/halo/app/content/comment/CommentQueryTest.java +++ /dev/null @@ -1,361 +0,0 @@ -package run.halo.app.content.comment; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.mock; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import lombok.NonNull; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.mock.web.reactive.function.server.MockServerRequest; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.server.ServerWebExchange; -import run.halo.app.core.extension.content.Comment; -import run.halo.app.extension.Metadata; - -/** - * Tests for {@link CommentQuery}. - * - * @author guqing - * @since 2.0.0 - */ -@ExtendWith(MockitoExtension.class) -class CommentQueryTest { - - @Test - void getKeyword() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("keyword", "test"); - CommentQuery commentQuery = getCommentQuery(queryParams); - assertThat(commentQuery.getKeyword()).isEqualTo("test"); - queryParams.clear(); - - queryParams.add("keyword", ""); - assertThat(commentQuery.getKeyword()).isNull(); - queryParams.clear(); - - queryParams.add("keyword", null); - assertThat(commentQuery.getKeyword()).isNull(); - queryParams.clear(); - } - - @Test - void getApproved() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("approved", "true"); - CommentQuery commentQuery = getCommentQuery(queryParams); - assertThat(commentQuery.getApproved()).isTrue(); - queryParams.clear(); - - queryParams.add("approved", ""); - assertThat(commentQuery.getApproved()).isNull(); - queryParams.clear(); - - queryParams.add("approved", "1"); - assertThat(commentQuery.getApproved()).isFalse(); - queryParams.clear(); - } - - @NonNull - private CommentQuery getCommentQuery(MultiValueMap queryParams) { - ServerWebExchange exchange = mock(ServerWebExchange.class); - MockServerRequest request = MockServerRequest.builder() - .queryParams(queryParams) - .exchange(exchange) - .build(); - ServerHttpRequest httpRequest = mock(ServerHttpRequest.class); - lenient().when(exchange.getRequest()).thenReturn(httpRequest); - lenient().when(httpRequest.getQueryParams()).thenReturn(queryParams); - return new CommentQuery(request); - } - - @Test - void getHidden() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("hidden", "true"); - CommentQuery commentQuery = getCommentQuery(queryParams); - assertThat(commentQuery.getHidden()).isTrue(); - queryParams.clear(); - - queryParams.add("hidden", ""); - assertThat(commentQuery.getHidden()).isNull(); - queryParams.clear(); - - queryParams.add("hidden", "1"); - assertThat(commentQuery.getHidden()).isFalse(); - queryParams.clear(); - } - - @Test - void getAllowNotification() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("allowNotification", "true"); - CommentQuery commentQuery = getCommentQuery(queryParams); - assertThat(commentQuery.getAllowNotification()).isTrue(); - queryParams.clear(); - - queryParams.add("allowNotification", ""); - assertThat(commentQuery.getAllowNotification()).isNull(); - queryParams.clear(); - - queryParams.add("allowNotification", "1"); - assertThat(commentQuery.getAllowNotification()).isFalse(); - queryParams.clear(); - } - - @Test - void getTop() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("top", "true"); - CommentQuery commentQuery = getCommentQuery(queryParams); - assertThat(commentQuery.getTop()).isTrue(); - queryParams.clear(); - - queryParams.add("top", ""); - assertThat(commentQuery.getTop()).isNull(); - queryParams.clear(); - - queryParams.add("top", "1"); - assertThat(commentQuery.getTop()).isFalse(); - queryParams.clear(); - } - - @Test - void getOwnerKind() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("ownerKind", "test-owner-kind"); - CommentQuery commentQuery = getCommentQuery(queryParams); - assertThat(commentQuery.getOwnerKind()).isEqualTo("test-owner-kind"); - queryParams.clear(); - - queryParams.add("ownerKind", ""); - assertThat(commentQuery.getOwnerKind()).isNull(); - queryParams.clear(); - - queryParams.add("ownerKind", null); - assertThat(commentQuery.getOwnerKind()).isNull(); - queryParams.clear(); - } - - @Test - void getOwnerName() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("ownerName", "test-owner-name"); - CommentQuery commentQuery = getCommentQuery(queryParams); - assertThat(commentQuery.getOwnerName()).isEqualTo("test-owner-name"); - queryParams.clear(); - - queryParams.add("ownerName", ""); - assertThat(commentQuery.getOwnerName()).isNull(); - queryParams.clear(); - - queryParams.add("ownerName", null); - assertThat(commentQuery.getOwnerName()).isNull(); - queryParams.clear(); - } - - @Test - void getSubjectKind() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("subjectKind", "test-subject-kind"); - CommentQuery commentQuery = getCommentQuery(queryParams); - assertThat(commentQuery.getSubjectKind()).isEqualTo("test-subject-kind"); - queryParams.clear(); - - queryParams.add("subjectKind", ""); - assertThat(commentQuery.getSubjectKind()).isNull(); - queryParams.clear(); - - queryParams.add("subjectKind", null); - assertThat(commentQuery.getSubjectKind()).isNull(); - queryParams.clear(); - } - - @Test - void getSubjectName() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("subjectName", "test-subject-name"); - CommentQuery commentQuery = getCommentQuery(queryParams); - assertThat(commentQuery.getSubjectName()).isEqualTo("test-subject-name"); - queryParams.clear(); - - queryParams.add("subjectName", ""); - assertThat(commentQuery.getSubjectName()).isNull(); - queryParams.clear(); - - queryParams.add("subjectName", null); - assertThat(commentQuery.getSubjectName()).isNull(); - queryParams.clear(); - } - - @Nested - class CommentSortTest { - @Test - void sortByCreateTimeAsc() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.set("sort", "creationTimestamp,asc"); - CommentQuery commentQuery = getCommentQuery(queryParams); - Comparator createTimeSorter = commentQuery.toComparator(); - List commentNames = comments().stream() - .sorted(createTimeSorter) - .map(comment -> comment.getMetadata().getName()) - .toList(); - assertThat(commentNames).isEqualTo(List.of("B", "C", "A")); - } - - @Test - void sortByCreateTimeDesc() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("sort", "creationTimestamp,desc"); - Comparator createTimeSorter = getCommentQuery(queryParams).toComparator(); - List commentNames = comments().stream() - .sorted(createTimeSorter) - .map(comment -> comment.getMetadata().getName()) - .toList(); - assertThat(commentNames).isEqualTo(List.of("A", "B", "C")); - } - - @Test - void sortByReplyCountAsc() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("sort", "replyCount,asc"); - Comparator comparator = getCommentQuery(queryParams).toComparator(); - List commentNames = comments().stream() - .sorted(comparator) - .map(comment -> comment.getMetadata().getName()) - .toList(); - assertThat(commentNames).isEqualTo(List.of("A", "B", "C")); - } - - @Test - void sortByReplyCountDesc() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("sort", "replyCount,desc"); - Comparator comparator = getCommentQuery(queryParams).toComparator(); - List commentNames = comments().stream() - .sorted(comparator) - .map(comment -> comment.getMetadata().getName()) - .toList(); - assertThat(commentNames).isEqualTo(List.of("C", "B", "A")); - } - - @Test - void sortByLastReplyTimeAsc() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("sort", "lastReplyTime,asc"); - Comparator comparator = getCommentQuery(queryParams).toComparator(); - List commentNames = comments().stream() - .sorted(comparator) - .map(comment -> comment.getMetadata().getName()) - .toList(); - assertThat(commentNames).isEqualTo(List.of("C", "A", "B")); - } - - @Test - void sortByLastReplyTimeDesc() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("sort", "lastReplyTime,desc"); - Comparator comparator = getCommentQuery(queryParams).toComparator(); - List commentNames = comments().stream() - .sorted(comparator) - .map(comment -> comment.getMetadata().getName()) - .toList(); - assertThat(commentNames).isEqualTo(List.of("B", "A", "C")); - } - - @Test - void sortByDefaultDesc() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - Comparator comparator = getCommentQuery(queryParams).toComparator(); - List commentNames = comments().stream() - .sorted(comparator) - .map(comment -> comment.getMetadata().getName()) - .toList(); - assertThat(commentNames).isEqualTo(List.of("B", "A", "C")); - - List commentList = commentsIncludeNoReply().stream() - .sorted(comparator) - .map(comment -> comment.getMetadata().getName()) - .toList(); - assertThat(commentList).isEqualTo(List.of("D", "E", "B", "A", "C")); - } - - List comments() { - final Instant now = Instant.now(); - Comment commentA = new Comment(); - commentA.setMetadata(new Metadata()); - 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)); - // reply count - commentA.getStatus().setReplyCount(3); - - Comment commentB = new Comment(); - commentB.setMetadata(new Metadata()); - commentB.getMetadata().setName("B"); - commentB.getMetadata().setCreationTimestamp(now.plusSeconds(5)); - commentB.setSpec(new Comment.CommentSpec()); - 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()); - commentC.getMetadata().setName("C"); - - commentC.getMetadata().setCreationTimestamp(now.plusSeconds(5)); - - commentC.setSpec(new Comment.CommentSpec()); - 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); - } - - List commentsIncludeNoReply() { - - final Instant now = Instant.now(); - Comment commentD = new Comment(); - commentD.setMetadata(new Metadata()); - commentD.getMetadata().setName("D"); - - 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(); - commentE.setMetadata(new Metadata()); - 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()); - comments.add(commentD); - comments.add(commentE); - - return comments; - } - } -} \ No newline at end of file diff --git a/application/src/test/java/run/halo/app/content/comment/CommentServiceImplTest.java b/application/src/test/java/run/halo/app/content/comment/CommentServiceImplTest.java index 81c8a0e9c3..47078eb80b 100644 --- a/application/src/test/java/run/halo/app/content/comment/CommentServiceImplTest.java +++ b/application/src/test/java/run/halo/app/content/comment/CommentServiceImplTest.java @@ -1,8 +1,6 @@ package run.halo.app.content.comment; -import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; @@ -12,7 +10,6 @@ import java.util.List; import java.util.Map; -import java.util.function.Predicate; import org.json.JSONException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -37,8 +34,10 @@ import run.halo.app.core.extension.content.Comment; import run.halo.app.core.extension.content.Post; import run.halo.app.core.extension.service.UserService; +import run.halo.app.extension.ListOptions; import run.halo.app.extension.ListResult; import run.halo.app.extension.Metadata; +import run.halo.app.extension.PageRequest; import run.halo.app.extension.ReactiveExtensionClient; import run.halo.app.extension.Ref; import run.halo.app.infra.SystemConfigurableEnvironmentFetcher; @@ -81,13 +80,13 @@ void setUp() { lenient().when(environmentFetcher.fetchComment()).thenReturn(Mono.just(commentSetting)); ListResult comments = new ListResult<>(1, 10, 3, comments()); - when(client.list(eq(Comment.class), any(), any(), anyInt(), anyInt())) + when(client.listBy(eq(Comment.class), any(ListOptions.class), any(PageRequest.class))) .thenReturn(Mono.just(comments)); when(userService.getUserOrGhost(eq("A-owner"))) - .thenReturn(Mono.just(createUser("A-owner"))); + .thenReturn(Mono.just(createUser("A-owner"))); when(userService.getUserOrGhost(eq("B-owner"))) - .thenReturn(Mono.just(createUser("B-owner"))); + .thenReturn(Mono.just(createUser("B-owner"))); when(client.fetch(eq(User.class), eq("C-owner"))) .thenReturn(Mono.empty()); @@ -128,8 +127,7 @@ void listComment() { ServerHttpRequest httpRequest = mock(ServerHttpRequest.class); when(exchange.getRequest()).thenReturn(httpRequest); when(httpRequest.getQueryParams()).thenReturn(queryParams); - Mono> listResultMono = - commentService.listComment(new CommentQuery(request)); + final var listResultMono = commentService.listComment(new CommentQuery(request)); Counter counterA = new Counter(); counterA.setUpvote(3); String commentACounter = MeterUtils.nameOf(Comment.class, "A"); @@ -170,7 +168,7 @@ void create() throws JSONException { ArgumentCaptor captor = ArgumentCaptor.forClass(Comment.class); when(client.fetch(eq(User.class), eq("B-owner"))) - .thenReturn(Mono.just(createUser("B-owner"))); + .thenReturn(Mono.just(createUser("B-owner"))); Comment commentToCreate = commentRequest.toComment(); commentToCreate.getMetadata().setName("fake"); Mono commentMono = commentService.create(commentToCreate); @@ -214,49 +212,6 @@ void create() throws JSONException { true); } - @Test - void commentPredicate() { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("keyword", "hello"); - queryParams.add("approved", "true"); - queryParams.add("hidden", "false"); - queryParams.add("allowNotification", "true"); - queryParams.add("top", "false"); - queryParams.add("ownerKind", "User"); - queryParams.add("ownerName", "fake-user"); - queryParams.add("subjectKind", "Post"); - queryParams.add("subjectName", "fake-post"); - - MockServerRequest request = MockServerRequest.builder() - .queryParams(queryParams) - .exchange(mock(ServerWebExchange.class)) - .build(); - final Predicate predicate = new CommentQuery(request).toPredicate(); - - Comment comment = comment("A"); - comment.getSpec().setRaw("hello-world"); - comment.getSpec().setApproved(true); - comment.getSpec().setHidden(false); - comment.getSpec().setAllowNotification(true); - comment.getSpec().setTop(false); - Comment.CommentOwner commentOwner = new Comment.CommentOwner(); - commentOwner.setKind("User"); - commentOwner.setName("fake-user"); - commentOwner.setDisplayName("fake-user-display-name"); - comment.getSpec().setOwner(commentOwner); - comment.getSpec().setSubjectRef(Ref.of(post())); - assertThat(predicate.test(comment)).isTrue(); - - queryParams.remove("keyword"); - queryParams.add("keyword", "nothing"); - request = MockServerRequest.builder() - .queryParams(queryParams) - .exchange(mock(ServerWebExchange.class)) - .build(); - final Predicate predicateTwo = new CommentQuery(request).toPredicate(); - assertThat(predicateTwo.test(comment)).isFalse(); - } - private List comments() { Comment a = comment("A"); a.getSpec().getOwner().setKind(Comment.CommentOwner.KIND_EMAIL); diff --git a/application/src/test/java/run/halo/app/theme/endpoint/CommentFinderEndpointTest.java b/application/src/test/java/run/halo/app/theme/endpoint/CommentFinderEndpointTest.java index 0eb416c758..997b4d3c8d 100644 --- a/application/src/test/java/run/halo/app/theme/endpoint/CommentFinderEndpointTest.java +++ b/application/src/test/java/run/halo/app/theme/endpoint/CommentFinderEndpointTest.java @@ -31,6 +31,7 @@ import run.halo.app.core.extension.content.Comment; import run.halo.app.core.extension.content.Reply; import run.halo.app.extension.ListResult; +import run.halo.app.extension.PageRequest; import run.halo.app.extension.Ref; import run.halo.app.infra.SystemConfigurableEnvironmentFetcher; import run.halo.app.theme.finders.CommentFinder; @@ -77,7 +78,7 @@ void setUp() { @Test void listComments() { - when(commentPublicQueryService.list(any(), anyInt(), anyInt(), any())) + when(commentPublicQueryService.list(any(), any(PageRequest.class))) .thenReturn(Mono.just(new ListResult<>(1, 10, 0, List.of()))); Ref ref = new Ref(); @@ -86,21 +87,20 @@ void listComments() { ref.setKind("Post"); ref.setName("test"); webTestClient.get() - .uri(uriBuilder -> { - return uriBuilder.path("/comments") - .queryParam("group", ref.getGroup()) - .queryParam("version", ref.getVersion()) - .queryParam("kind", ref.getKind()) - .queryParam("name", ref.getName()) - .queryParam("page", 1) - .queryParam("size", 10) - .build(); - }) + .uri(uriBuilder -> uriBuilder.path("/comments") + .queryParam("group", ref.getGroup()) + .queryParam("version", ref.getVersion()) + .queryParam("kind", ref.getKind()) + .queryParam("name", ref.getName()) + .queryParam("page", 1) + .queryParam("size", 10) + .build()) .exchange() .expectStatus() .isOk(); ArgumentCaptor refCaptor = ArgumentCaptor.forClass(Ref.class); - verify(commentPublicQueryService, times(1)).list(refCaptor.capture(), eq(1), eq(10), any()); + verify(commentPublicQueryService, times(1)) + .list(refCaptor.capture(), any(PageRequest.class)); Ref value = refCaptor.getValue(); assertThat(value).isEqualTo(ref); } diff --git a/application/src/test/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceImplTest.java b/application/src/test/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceImplTest.java index c4a3eaf20f..3a283fdbe2 100644 --- a/application/src/test/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceImplTest.java +++ b/application/src/test/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceImplTest.java @@ -9,7 +9,6 @@ import java.util.HashMap; import java.util.List; import java.util.function.Predicate; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.json.JSONException; import org.junit.jupiter.api.BeforeEach; @@ -33,7 +32,6 @@ 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; @@ -70,103 +68,6 @@ void setUp() { @Nested class ListCommentTest { - @Test - void listWhenUserNotLogin() { - // Mock - mockWhenListComment(); - - Ref ref = Ref.of("fake-post", GroupVersionKind.fromExtension(Post.class)); - commentPublicQueryService.list(ref, 1, 10) - .as(StepVerifier::create) - .consumeNextWith(listResult -> { - assertThat(listResult.getTotal()).isEqualTo(2); - assertThat(listResult.getItems().size()).isEqualTo(2); - assertThat(listResult.getItems().get(0).getMetadata().getName()) - .isEqualTo("comment-approved"); - }) - .verifyComplete(); - } - - @Test - @WithMockUser(username = AnonymousUserConst.PRINCIPAL) - void listWhenUserIsAnonymous() { - // Mock - mockWhenListComment(); - - Ref ref = Ref.of("fake-post", GroupVersionKind.fromExtension(Post.class)); - commentPublicQueryService.list(ref, 1, 10) - .as(StepVerifier::create) - .consumeNextWith(listResult -> { - assertThat(listResult.getTotal()).isEqualTo(2); - assertThat(listResult.getItems().size()).isEqualTo(2); - assertThat(listResult.getItems().get(0).getMetadata().getName()) - .isEqualTo("comment-approved"); - assertThat(listResult.getItems().get(0).getStats().getUpvote()).isEqualTo(9); - }) - .verifyComplete(); - } - - @Test - @WithMockUser(username = "fake-user") - void listWhenUserLoggedIn() { - mockWhenListComment(); - - Ref ref = Ref.of("fake-post", GroupVersionKind.fromExtension(Post.class)); - commentPublicQueryService.list(ref, 1, 10) - .as(StepVerifier::create) - .consumeNextWith(listResult -> { - assertThat(listResult.getTotal()).isEqualTo(3); - assertThat(listResult.getItems().size()).isEqualTo(3); - assertThat(listResult.getItems().get(0).getMetadata().getName()) - .isEqualTo("comment-not-approved"); - assertThat(listResult.getItems().get(1).getMetadata().getName()) - .isEqualTo("comment-approved"); - }) - .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(CommentPublicQueryServiceImpl.defaultComparator()) - .map(Comment::getMetadata) - .map(MetadataOperator::getName) - .collect(Collectors.joining(", ")); - assertThat(result).isEqualTo("1, 2, 4, 3, 5, 6, 10, 14, 9, 8, 7, 11, 12, 13"); - } - @Test void desensitizeComment() throws JSONException { var commentOwner = new Comment.CommentOwner(); diff --git a/application/src/test/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceIntegrationTest.java b/application/src/test/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceIntegrationTest.java new file mode 100644 index 0000000000..43074706af --- /dev/null +++ b/application/src/test/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceIntegrationTest.java @@ -0,0 +1,318 @@ +package run.halo.app.theme.finders.impl; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Instant; +import java.util.List; +import java.util.stream.Collectors; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.annotation.DirtiesContext; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; +import run.halo.app.core.extension.User; +import run.halo.app.core.extension.content.Comment; +import run.halo.app.core.extension.content.Post; +import run.halo.app.extension.Extension; +import run.halo.app.extension.ExtensionStoreUtil; +import run.halo.app.extension.GroupVersionKind; +import run.halo.app.extension.ListOptions; +import run.halo.app.extension.ReactiveExtensionClient; +import run.halo.app.extension.Ref; +import run.halo.app.extension.SchemeManager; +import run.halo.app.extension.index.IndexerFactory; +import run.halo.app.extension.store.ReactiveExtensionStoreClient; +import run.halo.app.infra.AnonymousUserConst; +import run.halo.app.infra.utils.JsonUtils; + +@DirtiesContext +@SpringBootTest +class CommentPublicQueryServiceIntegrationTest { + + @Autowired + private SchemeManager schemeManager; + + @Autowired + private ReactiveExtensionClient client; + + @Autowired + private ReactiveExtensionStoreClient storeClient; + + @Autowired + private IndexerFactory indexerFactory; + + Mono deleteImmediately(Extension extension) { + var name = extension.getMetadata().getName(); + var scheme = schemeManager.get(extension.getClass()); + // un-index + var indexer = indexerFactory.getIndexer(extension.groupVersionKind()); + indexer.unIndexRecord(extension.getMetadata().getName()); + + // delete from db + var storeName = ExtensionStoreUtil.buildStoreName(scheme, name); + return storeClient.delete(storeName, extension.getMetadata().getVersion()) + .thenReturn(extension); + } + + @Nested + class CommentListTest { + private final List storedComments = commentsForStore(); + + @Autowired + private CommentPublicQueryServiceImpl commentPublicQueryService; + + @BeforeEach + void setUp() { + Flux.fromIterable(storedComments) + .flatMap(comment -> client.create(comment)) + .as(StepVerifier::create) + .expectNextCount(storedComments.size()) + .verifyComplete(); + } + + @AfterEach + void tearDown() { + Flux.fromIterable(storedComments) + .flatMap(CommentPublicQueryServiceIntegrationTest.this::deleteImmediately) + .as(StepVerifier::create) + .expectNextCount(storedComments.size()) + .verifyComplete(); + } + + @Test + void listWhenUserNotLogin() { + Ref ref = Ref.of("fake-post", GroupVersionKind.fromExtension(Post.class)); + commentPublicQueryService.list(ref, 1, 10) + .as(StepVerifier::create) + .consumeNextWith(listResult -> { + assertThat(listResult.getTotal()).isEqualTo(2); + assertThat(listResult.getItems().size()).isEqualTo(2); + assertThat(listResult.getItems().get(0).getMetadata().getName()) + .isEqualTo("comment-approved"); + }) + .verifyComplete(); + } + + @Test + @WithMockUser(username = AnonymousUserConst.PRINCIPAL) + void listWhenUserIsAnonymous() { + Ref ref = Ref.of("fake-post", GroupVersionKind.fromExtension(Post.class)); + commentPublicQueryService.list(ref, 1, 10) + .as(StepVerifier::create) + .consumeNextWith(listResult -> { + assertThat(listResult.getTotal()).isEqualTo(2); + assertThat(listResult.getItems().size()).isEqualTo(2); + assertThat(listResult.getItems().get(0).getMetadata().getName()) + .isEqualTo("comment-approved"); + }) + .verifyComplete(); + } + + @Test + @WithMockUser(username = "fake-user") + void listWhenUserLoggedIn() { + Ref ref = Ref.of("fake-post", GroupVersionKind.fromExtension(Post.class)); + commentPublicQueryService.list(ref, 1, 10) + .as(StepVerifier::create) + .consumeNextWith(listResult -> { + assertThat(listResult.getTotal()).isEqualTo(3); + assertThat(listResult.getItems().size()).isEqualTo(3); + assertThat(listResult.getItems().get(0).getMetadata().getName()) + .isEqualTo("comment-approved"); + assertThat(listResult.getItems().get(1).getMetadata().getName()) + .isEqualTo("comment-approved-but-another-owner"); + assertThat(listResult.getItems().get(2).getMetadata().getName()) + .isEqualTo("comment-not-approved"); + }) + .verifyComplete(); + } + + List commentsForStore() { + // Mock + Comment commentNotApproved = fakeComment(); + commentNotApproved.getMetadata().setName("comment-not-approved"); + commentNotApproved.getSpec().setApproved(false); + + Comment commentApproved = fakeComment(); + commentApproved.getMetadata().setName("comment-approved"); + commentApproved.getSpec().setApproved(true); + + Comment notApprovedWithAnonymous = fakeComment(); + notApprovedWithAnonymous.getMetadata().setName("comment-not-approved-anonymous"); + notApprovedWithAnonymous.getSpec().setApproved(false); + notApprovedWithAnonymous.getSpec().getOwner().setName(AnonymousUserConst.PRINCIPAL); + + Comment commentApprovedButAnotherOwner = fakeComment(); + commentApprovedButAnotherOwner.getMetadata() + .setName("comment-approved-but-another-owner"); + commentApprovedButAnotherOwner.getSpec().setApproved(true); + commentApprovedButAnotherOwner.getSpec().getOwner().setName("another"); + + Comment commentNotApprovedAndAnotherOwner = fakeComment(); + commentNotApprovedAndAnotherOwner.getMetadata() + .setName("comment-not-approved-and-another"); + commentNotApprovedAndAnotherOwner.getSpec().setApproved(false); + commentNotApprovedAndAnotherOwner.getSpec().getOwner().setName("another"); + + Comment notApprovedAndAnotherRef = fakeComment(); + notApprovedAndAnotherRef.getMetadata() + .setName("comment-not-approved-and-another-ref"); + notApprovedAndAnotherRef.getSpec().setApproved(false); + Ref anotherRef = + Ref.of("another-fake-post", GroupVersionKind.fromExtension(Post.class)); + notApprovedAndAnotherRef.getSpec().setSubjectRef(anotherRef); + + return List.of( + commentNotApproved, + commentApproved, + commentApprovedButAnotherOwner, + commentNotApprovedAndAnotherOwner, + notApprovedWithAnonymous, + notApprovedAndAnotherRef + ); + } + + Comment fakeComment() { + Comment comment = createComment(); + comment.getMetadata().setDeletionTimestamp(null); + comment.getMetadata().setName("fake-comment"); + + comment.getSpec().setRaw("fake-raw"); + comment.getSpec().setContent("fake-content"); + comment.getSpec().setHidden(false); + comment.getSpec() + .setSubjectRef(Ref.of("fake-post", GroupVersionKind.fromExtension(Post.class))); + Comment.CommentOwner commentOwner = new Comment.CommentOwner(); + commentOwner.setKind(User.KIND); + commentOwner.setName("fake-user"); + commentOwner.setDisplayName("fake-display-name"); + comment.getSpec().setOwner(commentOwner); + return comment; + } + } + + @Nested + class CommentDefaultSortTest { + private final List commentList = createCommentList(); + + @BeforeEach + void setUp() { + Flux.fromIterable(commentList) + .flatMap(comment -> client.create(comment)) + .as(StepVerifier::create) + .expectNextCount(commentList.size()) + .verifyComplete(); + } + + @AfterEach + void tearDown() { + Flux.fromIterable(commentList) + .flatMap(CommentPublicQueryServiceIntegrationTest.this::deleteImmediately) + .as(StepVerifier::create) + .expectNextCount(commentList.size()) + .verifyComplete(); + } + + @Test + void sortTest() { + var comments = + client.listAll(Comment.class, new ListOptions(), + CommentPublicQueryServiceImpl.defaultSort()) + .collectList() + .block(); + assertThat(comments).isNotNull(); + + var result = comments.stream() + .map(comment -> comment.getMetadata().getName()) + .collect(Collectors.joining(", ")); + assertThat(result).isEqualTo("1, 2, 4, 3, 5, 6, 9, 10, 14, 8, 7, 11, 12, 13"); + } + + List createCommentList() { + // 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", now, false, 0); + var comment12 = commentForCompare("12", now, false, 1); + var comment13 = commentForCompare("13", now, false, 3); + var comment14 = commentForCompare("14", now.plusSeconds(3), false, 3); + + return List.of(comment1, comment2, comment3, comment4, comment5, comment6, comment7, + comment8, comment9, comment10, comment11, comment12, comment13, comment14); + } + + Comment commentForCompare(String name, Instant creationTime, boolean top, int priority) { + var comment = createComment(); + comment.getMetadata().setName(name); + comment.getMetadata().setCreationTimestamp(creationTime); + comment.getSpec().setCreationTime(creationTime); + comment.getSpec().setTop(top); + comment.getSpec().setPriority(priority); + return comment; + } + } + + Comment createComment() { + return JsonUtils.jsonToObject(""" + { + "spec": { + "raw": "fake-raw", + "content": "fake-content", + "owner": { + "kind": "User", + "name": "fake-user" + }, + "userAgent": "", + "ipAddress": "", + "approvedTime": "2024-02-28T09:15:16.095Z", + "creationTime": "2024-02-28T06:23:42.923294424Z", + "priority": 0, + "top": false, + "allowNotification": false, + "approved": true, + "hidden": false, + "subjectRef": { + "group": "content.halo.run", + "version": "v1alpha1", + "kind": "SinglePage", + "name": "67" + }, + "lastReadTime": "2024-02-29T03:39:04.230Z" + }, + "apiVersion": "content.halo.run/v1alpha1", + "kind": "Comment", + "metadata": { + "name": "fake-comment", + "creationTimestamp": "2024-02-28T06:23:42.923439037Z" + } + } + """, Comment.class); + } +} diff --git a/ui/console-src/modules/contents/comments/CommentList.vue b/ui/console-src/modules/contents/comments/CommentList.vue index 8910acf5cb..abd116a887 100644 --- a/ui/console-src/modules/contents/comments/CommentList.vue +++ b/ui/console-src/modules/contents/comments/CommentList.vue @@ -89,10 +89,22 @@ const { keyword, ], queryFn: async () => { + const fieldSelectorMap: Record = { + "spec.approved": selectedApprovedStatus.value, + }; + + const fieldSelector = Object.entries(fieldSelectorMap) + .map(([key, value]) => { + if (value !== undefined) { + return `${key}=${value}`; + } + }) + .filter(Boolean) as string[]; + const { data } = await apiClient.comment.listComments({ + fieldSelector, page: page.value, size: size.value, - approved: selectedApprovedStatus.value, sort: [selectedSort.value].filter(Boolean) as string[], keyword: keyword.value, ownerName: selectedUser.value, @@ -105,10 +117,10 @@ const { return data.items; }, refetchInterval(data) { - const deletingComments = data?.filter( + const hasDeletingData = data?.some( (comment) => !!comment.comment.metadata.deletionTimestamp ); - return deletingComments?.length ? 1000 : false; + return hasDeletingData ? 1000 : false; }, }); @@ -299,33 +311,33 @@ const handleApproveInBatch = async () => { label: t( 'core.comment.filters.sort.items.last_reply_time_desc' ), - value: 'lastReplyTime,desc', + value: 'status.lastReplyTime,desc', }, { label: t( 'core.comment.filters.sort.items.last_reply_time_asc' ), - value: 'lastReplyTime,asc', + value: 'status.lastReplyTime,asc', }, { label: t( 'core.comment.filters.sort.items.reply_count_desc' ), - value: 'replyCount,desc', + value: 'status.replyCount,desc', }, { label: t('core.comment.filters.sort.items.reply_count_asc'), - value: 'replyCount,asc', + value: 'status.replyCount,asc', }, { label: t( 'core.comment.filters.sort.items.create_time_desc' ), - value: 'creationTimestamp,desc', + value: 'metadata.creationTimestamp,desc', }, { label: t('core.comment.filters.sort.items.create_time_asc'), - value: 'creationTimestamp,asc', + value: 'metadata.creationTimestamp,asc', }, ]" /> diff --git a/ui/packages/api-client/src/api/api-console-halo-run-v1alpha1-comment-api.ts b/ui/packages/api-client/src/api/api-console-halo-run-v1alpha1-comment-api.ts index 15335c66d3..85c796a256 100644 --- a/ui/packages/api-client/src/api/api-console-halo-run-v1alpha1-comment-api.ts +++ b/ui/packages/api-client/src/api/api-console-halo-run-v1alpha1-comment-api.ts @@ -179,10 +179,7 @@ export const ApiConsoleHaloRunV1alpha1CommentApiAxiosParamCreator = function ( }, /** * List comments. - * @param {boolean} [allowNotification] Send notifications when there are new replies. - * @param {boolean} [approved] Comments approved. * @param {Array} [fieldSelector] Field selector for filtering. - * @param {boolean} [hidden] The comment is hidden from the theme side. * @param {string} [keyword] Comments filtered by keyword. * @param {Array} [labelSelector] Label selector for filtering. * @param {string} [ownerKind] Commenter kind. @@ -190,17 +187,11 @@ export const ApiConsoleHaloRunV1alpha1CommentApiAxiosParamCreator = function ( * @param {number} [page] The page number. Zero indicates no page. * @param {number} [size] Size of one page. Zero indicates no limit. * @param {Array} [sort] Sort property and direction of the list result. Supported fields: creationTimestamp,replyCount,lastReplyTime - * @param {string} [subjectKind] Comment subject kind. - * @param {string} [subjectName] Comment subject name. - * @param {boolean} [top] Comment top display. * @param {*} [options] Override http request option. * @throws {RequiredError} */ listComments: async ( - allowNotification?: boolean, - approved?: boolean, fieldSelector?: Array, - hidden?: boolean, keyword?: string, labelSelector?: Array, ownerKind?: string, @@ -208,9 +199,6 @@ export const ApiConsoleHaloRunV1alpha1CommentApiAxiosParamCreator = function ( page?: number, size?: number, sort?: Array, - subjectKind?: string, - subjectName?: string, - top?: boolean, options: AxiosRequestConfig = {} ): Promise => { const localVarPath = `/apis/api.console.halo.run/v1alpha1/comments`; @@ -237,22 +225,10 @@ export const ApiConsoleHaloRunV1alpha1CommentApiAxiosParamCreator = function ( // http bearer authentication required await setBearerAuthToObject(localVarHeaderParameter, configuration); - if (allowNotification !== undefined) { - localVarQueryParameter["allowNotification"] = allowNotification; - } - - if (approved !== undefined) { - localVarQueryParameter["approved"] = approved; - } - if (fieldSelector) { localVarQueryParameter["fieldSelector"] = fieldSelector; } - if (hidden !== undefined) { - localVarQueryParameter["hidden"] = hidden; - } - if (keyword !== undefined) { localVarQueryParameter["keyword"] = keyword; } @@ -281,18 +257,6 @@ export const ApiConsoleHaloRunV1alpha1CommentApiAxiosParamCreator = function ( localVarQueryParameter["sort"] = Array.from(sort); } - if (subjectKind !== undefined) { - localVarQueryParameter["subjectKind"] = subjectKind; - } - - if (subjectName !== undefined) { - localVarQueryParameter["subjectName"] = subjectName; - } - - if (top !== undefined) { - localVarQueryParameter["top"] = top; - } - setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; @@ -371,10 +335,7 @@ export const ApiConsoleHaloRunV1alpha1CommentApiFp = function ( }, /** * List comments. - * @param {boolean} [allowNotification] Send notifications when there are new replies. - * @param {boolean} [approved] Comments approved. * @param {Array} [fieldSelector] Field selector for filtering. - * @param {boolean} [hidden] The comment is hidden from the theme side. * @param {string} [keyword] Comments filtered by keyword. * @param {Array} [labelSelector] Label selector for filtering. * @param {string} [ownerKind] Commenter kind. @@ -382,17 +343,11 @@ export const ApiConsoleHaloRunV1alpha1CommentApiFp = function ( * @param {number} [page] The page number. Zero indicates no page. * @param {number} [size] Size of one page. Zero indicates no limit. * @param {Array} [sort] Sort property and direction of the list result. Supported fields: creationTimestamp,replyCount,lastReplyTime - * @param {string} [subjectKind] Comment subject kind. - * @param {string} [subjectName] Comment subject name. - * @param {boolean} [top] Comment top display. * @param {*} [options] Override http request option. * @throws {RequiredError} */ async listComments( - allowNotification?: boolean, - approved?: boolean, fieldSelector?: Array, - hidden?: boolean, keyword?: string, labelSelector?: Array, ownerKind?: string, @@ -400,9 +355,6 @@ export const ApiConsoleHaloRunV1alpha1CommentApiFp = function ( page?: number, size?: number, sort?: Array, - subjectKind?: string, - subjectName?: string, - top?: boolean, options?: AxiosRequestConfig ): Promise< ( @@ -411,10 +363,7 @@ export const ApiConsoleHaloRunV1alpha1CommentApiFp = function ( ) => AxiosPromise > { const localVarAxiosArgs = await localVarAxiosParamCreator.listComments( - allowNotification, - approved, fieldSelector, - hidden, keyword, labelSelector, ownerKind, @@ -422,9 +371,6 @@ export const ApiConsoleHaloRunV1alpha1CommentApiFp = function ( page, size, sort, - subjectKind, - subjectName, - top, options ); return createRequestFunction( @@ -492,10 +438,7 @@ export const ApiConsoleHaloRunV1alpha1CommentApiFactory = function ( ): AxiosPromise { return localVarFp .listComments( - requestParameters.allowNotification, - requestParameters.approved, requestParameters.fieldSelector, - requestParameters.hidden, requestParameters.keyword, requestParameters.labelSelector, requestParameters.ownerKind, @@ -503,9 +446,6 @@ export const ApiConsoleHaloRunV1alpha1CommentApiFactory = function ( requestParameters.page, requestParameters.size, requestParameters.sort, - requestParameters.subjectKind, - requestParameters.subjectName, - requestParameters.top, options ) .then((request) => request(axios, basePath)); @@ -554,20 +494,6 @@ export interface ApiConsoleHaloRunV1alpha1CommentApiCreateReplyRequest { * @interface ApiConsoleHaloRunV1alpha1CommentApiListCommentsRequest */ export interface ApiConsoleHaloRunV1alpha1CommentApiListCommentsRequest { - /** - * Send notifications when there are new replies. - * @type {boolean} - * @memberof ApiConsoleHaloRunV1alpha1CommentApiListComments - */ - readonly allowNotification?: boolean; - - /** - * Comments approved. - * @type {boolean} - * @memberof ApiConsoleHaloRunV1alpha1CommentApiListComments - */ - readonly approved?: boolean; - /** * Field selector for filtering. * @type {Array} @@ -575,13 +501,6 @@ export interface ApiConsoleHaloRunV1alpha1CommentApiListCommentsRequest { */ readonly fieldSelector?: Array; - /** - * The comment is hidden from the theme side. - * @type {boolean} - * @memberof ApiConsoleHaloRunV1alpha1CommentApiListComments - */ - readonly hidden?: boolean; - /** * Comments filtered by keyword. * @type {string} @@ -630,27 +549,6 @@ export interface ApiConsoleHaloRunV1alpha1CommentApiListCommentsRequest { * @memberof ApiConsoleHaloRunV1alpha1CommentApiListComments */ readonly sort?: Array; - - /** - * Comment subject kind. - * @type {string} - * @memberof ApiConsoleHaloRunV1alpha1CommentApiListComments - */ - readonly subjectKind?: string; - - /** - * Comment subject name. - * @type {string} - * @memberof ApiConsoleHaloRunV1alpha1CommentApiListComments - */ - readonly subjectName?: string; - - /** - * Comment top display. - * @type {boolean} - * @memberof ApiConsoleHaloRunV1alpha1CommentApiListComments - */ - readonly top?: boolean; } /** @@ -709,10 +607,7 @@ export class ApiConsoleHaloRunV1alpha1CommentApi extends BaseAPI { ) { return ApiConsoleHaloRunV1alpha1CommentApiFp(this.configuration) .listComments( - requestParameters.allowNotification, - requestParameters.approved, requestParameters.fieldSelector, - requestParameters.hidden, requestParameters.keyword, requestParameters.labelSelector, requestParameters.ownerKind, @@ -720,9 +615,6 @@ export class ApiConsoleHaloRunV1alpha1CommentApi extends BaseAPI { requestParameters.page, requestParameters.size, requestParameters.sort, - requestParameters.subjectKind, - requestParameters.subjectName, - requestParameters.top, options ) .then((request) => request(this.axios, this.basePath));