mirror of https://github.com/halo-dev/halo
feat: theme template route filling necessary data to request model (#2393)
* feat: add archives data * refactor: route strategy to populate necessary data * refactor: next page url does not exceed the total number of pagespull/2397/head^2
parent
9331f31d58
commit
1d73228b1f
|
@ -66,7 +66,9 @@ public class PostFinderImpl implements PostFinder {
|
|||
if (post == null) {
|
||||
return null;
|
||||
}
|
||||
return getPostVo(post);
|
||||
PostVo postVo = getPostVo(post);
|
||||
postVo.setContent(content(postName));
|
||||
return postVo;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -57,6 +57,7 @@ public class SinglePageFinderImpl implements SinglePageFinder {
|
|||
contributorFinder.getContributors(page.getStatus().getContributors());
|
||||
SinglePageVo pageVo = SinglePageVo.from(page);
|
||||
pageVo.setContributors(contributors);
|
||||
pageVo.setContent(content(pageName));
|
||||
return pageVo;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package run.halo.app.theme.finders.vo;
|
|||
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
|
@ -11,6 +12,7 @@ import lombok.experimental.SuperBuilder;
|
|||
* @since 2.0.0
|
||||
*/
|
||||
@Getter
|
||||
@ToString
|
||||
@SuperBuilder
|
||||
public class BaseCategoryVo {
|
||||
String name;
|
||||
|
|
|
@ -3,6 +3,7 @@ package run.halo.app.theme.finders.vo;
|
|||
import java.util.List;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
import run.halo.app.core.extension.Category;
|
||||
|
@ -15,6 +16,7 @@ import run.halo.app.core.extension.Category;
|
|||
*/
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@ToString(callSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class CategoryTreeVo extends BaseCategoryVo {
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ import run.halo.app.core.extension.Post;
|
|||
@EqualsAndHashCode(callSuper = true)
|
||||
public class PostVo extends BasePostVo {
|
||||
|
||||
ContentVo content;
|
||||
|
||||
List<CategoryVo> categories;
|
||||
|
||||
List<TagVo> tags;
|
||||
|
@ -53,6 +55,7 @@ public class PostVo extends BasePostVo {
|
|||
.permalink(postStatus.getPermalink())
|
||||
.excerpt(postStatus.getExcerpt())
|
||||
.contributors(List.of())
|
||||
.content(new ContentVo(null, null))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ import run.halo.app.core.extension.SinglePage;
|
|||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SinglePageVo extends BasePostVo {
|
||||
|
||||
ContentVo content;
|
||||
|
||||
/**
|
||||
* Convert {@link SinglePage} to {@link SinglePageVo}.
|
||||
*
|
||||
|
@ -49,6 +51,7 @@ public class SinglePageVo extends BasePostVo {
|
|||
.permalink(pageStatus.getPermalink())
|
||||
.excerpt(pageStatus.getExcerpt())
|
||||
.contributors(List.of())
|
||||
.content(new ContentVo(null, null))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -35,13 +36,13 @@ public class TemplateRouteManager implements ApplicationListener<ApplicationRead
|
|||
private final ReentrantReadWriteLock.WriteLock writeLock =
|
||||
new ReentrantReadWriteLock().writeLock();
|
||||
private final Map<String, RouterFunction<ServerResponse>> routerFunctionMap = new HashMap<>();
|
||||
private final PermalinkIndexer permalinkIndexer;
|
||||
private final PermalinkPatternProvider permalinkPatternProvider;
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
public TemplateRouteManager(PermalinkIndexer permalinkIndexer,
|
||||
PermalinkPatternProvider permalinkPatternProvider) {
|
||||
this.permalinkIndexer = permalinkIndexer;
|
||||
public TemplateRouteManager(PermalinkPatternProvider permalinkPatternProvider,
|
||||
ApplicationContext applicationContext) {
|
||||
this.permalinkPatternProvider = permalinkPatternProvider;
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public Map<String, RouterFunction<ServerResponse>> getRouterFunctionMap() {
|
||||
|
@ -85,6 +86,9 @@ public class TemplateRouteManager implements ApplicationListener<ApplicationRead
|
|||
String pattern = getPatternByTemplateName(templateName);
|
||||
RouterFunction<ServerResponse> routeFunction = templateRouterStrategy(templateName)
|
||||
.getRouteFunction(templateName, pattern);
|
||||
if (routeFunction == null) {
|
||||
throw new IllegalStateException("Router function must not be null");
|
||||
}
|
||||
writeLock.lock();
|
||||
try {
|
||||
routerFunctionMap.put(templateName, routeFunction);
|
||||
|
@ -106,15 +110,16 @@ public class TemplateRouteManager implements ApplicationListener<ApplicationRead
|
|||
if (value == null) {
|
||||
throw new NotFoundException("Unknown template: " + template);
|
||||
}
|
||||
|
||||
return switch (value) {
|
||||
case INDEX -> new IndexRouteStrategy();
|
||||
case POST -> new PostRouteStrategy(permalinkIndexer);
|
||||
case ARCHIVES -> new ArchivesRouteStrategy();
|
||||
case TAGS -> new TagsRouteStrategy();
|
||||
case TAG -> new TagRouteStrategy(permalinkIndexer);
|
||||
case CATEGORIES -> new CategoriesRouteStrategy();
|
||||
case CATEGORY -> new CategoryRouteStrategy(permalinkIndexer);
|
||||
case SINGLE_PAGE -> new SinglePageRouteStrategy(permalinkIndexer);
|
||||
case INDEX -> applicationContext.getBean(IndexRouteStrategy.class);
|
||||
case POST -> applicationContext.getBean(PostRouteStrategy.class);
|
||||
case ARCHIVES -> applicationContext.getBean(ArchivesRouteStrategy.class);
|
||||
case TAGS -> applicationContext.getBean(TagsRouteStrategy.class);
|
||||
case TAG -> applicationContext.getBean(TagRouteStrategy.class);
|
||||
case CATEGORIES -> applicationContext.getBean(CategoriesRouteStrategy.class);
|
||||
case CATEGORY -> applicationContext.getBean(CategoryRouteStrategy.class);
|
||||
case SINGLE_PAGE -> applicationContext.getBean(SinglePageRouteStrategy.class);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
package run.halo.app.theme.router;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import run.halo.app.extension.ListResult;
|
||||
import run.halo.app.infra.utils.PathUtils;
|
||||
|
||||
/**
|
||||
* The {@link TemplateRouterStrategy} for generate {@link RouterFunction} specific to the template.
|
||||
|
@ -13,4 +19,86 @@ import org.springframework.web.reactive.function.server.ServerResponse;
|
|||
public interface TemplateRouterStrategy {
|
||||
|
||||
RouterFunction<ServerResponse> getRouteFunction(String template, String pattern);
|
||||
|
||||
class PageUrlUtils {
|
||||
public static final String PAGE_PART = "page";
|
||||
|
||||
public static int pageNum(ServerRequest request) {
|
||||
String pageNum = request.pathVariables().get(PageUrlUtils.PAGE_PART);
|
||||
return NumberUtils.toInt(pageNum, 1);
|
||||
}
|
||||
|
||||
public static long totalPage(ListResult<?> list) {
|
||||
return (list.getTotal() - 1) / list.getSize() + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets next page url with path.
|
||||
*
|
||||
* @param path request path
|
||||
* @return request path with next page part
|
||||
*/
|
||||
public static String nextPageUrl(String path, long total) {
|
||||
String[] segments = StringUtils.split(path, "/");
|
||||
long defaultPage = Math.min(2, Math.max(total, 1));
|
||||
if (segments.length > 1) {
|
||||
String pagePart = segments[segments.length - 2];
|
||||
if (PAGE_PART.equals(pagePart)) {
|
||||
int pageNumIndex = segments.length - 1;
|
||||
String pageNum = segments[pageNumIndex];
|
||||
segments[pageNumIndex] = toNextPage(pageNum, total);
|
||||
return PathUtils.combinePath(segments);
|
||||
}
|
||||
return appendPagePart(PathUtils.combinePath(segments), defaultPage);
|
||||
}
|
||||
return appendPagePart(PathUtils.combinePath(segments), defaultPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets previous page url with path.
|
||||
*
|
||||
* @param path request path
|
||||
* @return request path with previous page part
|
||||
*/
|
||||
public static String prevPageUrl(String path) {
|
||||
String[] segments = StringUtils.split(path, "/");
|
||||
if (segments.length > 1) {
|
||||
String pagePart = segments[segments.length - 2];
|
||||
if (PAGE_PART.equals(pagePart)) {
|
||||
int pageNumIndex = segments.length - 1;
|
||||
String pageNum = segments[pageNumIndex];
|
||||
int prevPage = toPrevPage(pageNum);
|
||||
segments[pageNumIndex] = String.valueOf(prevPage);
|
||||
if (prevPage == 1) {
|
||||
segments = ArrayUtils.subarray(segments, 0, pageNumIndex - 1);
|
||||
}
|
||||
if (segments.length == 0) {
|
||||
return "/";
|
||||
}
|
||||
return PathUtils.combinePath(segments);
|
||||
}
|
||||
}
|
||||
return StringUtils.defaultString(path, "/");
|
||||
}
|
||||
|
||||
private static String appendPagePart(String path, long page) {
|
||||
return PathUtils.combinePath(path, PAGE_PART, String.valueOf(page));
|
||||
}
|
||||
|
||||
private static String toNextPage(String pageStr, long total) {
|
||||
long page = Math.min(parseInt(pageStr) + 1, Math.max(total, 1));
|
||||
return String.valueOf(page);
|
||||
}
|
||||
|
||||
private static int toPrevPage(String pageStr) {
|
||||
return Math.max(parseInt(pageStr) - 1, 1);
|
||||
}
|
||||
|
||||
private static int parseInt(String pageStr) {
|
||||
if (!NumberUtils.isParsable(pageStr)) {
|
||||
throw new IllegalArgumentException("Page number must be a number");
|
||||
}
|
||||
return NumberUtils.toInt(pageStr, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package run.halo.app.theme.router;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import run.halo.app.extension.ListResult;
|
||||
|
||||
/**
|
||||
* Page wrapper with next and previous url.
|
||||
*
|
||||
* @param <T> the type of the list item.
|
||||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Getter
|
||||
@ToString(callSuper = true)
|
||||
public class UrlContextListResult<T> extends ListResult<T> {
|
||||
private final String nextUrl;
|
||||
private final String prevUrl;
|
||||
|
||||
public UrlContextListResult(int page, int size, long total, List<T> items, String nextUrl,
|
||||
String prevUrl) {
|
||||
super(page, size, total, items);
|
||||
this.nextUrl = nextUrl;
|
||||
this.prevUrl = prevUrl;
|
||||
}
|
||||
|
||||
public static class Builder<T> {
|
||||
private int page;
|
||||
private int size;
|
||||
private long total;
|
||||
private List<T> items;
|
||||
private String nextUrl;
|
||||
private String prevUrl;
|
||||
|
||||
public Builder<T> page(int page) {
|
||||
this.page = page;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> size(int size) {
|
||||
this.size = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> total(long total) {
|
||||
this.total = total;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> items(List<T> items) {
|
||||
this.items = items;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> nextUrl(String nextUrl) {
|
||||
this.nextUrl = nextUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> prevUrl(String prevUrl) {
|
||||
this.prevUrl = prevUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign value with list result.
|
||||
*
|
||||
* @param listResult list result
|
||||
* @return builder
|
||||
*/
|
||||
public Builder<T> listResult(ListResult<T> listResult) {
|
||||
this.page = listResult.getPage();
|
||||
this.size = listResult.getSize();
|
||||
this.total = listResult.getTotal();
|
||||
this.items = listResult.getItems();
|
||||
return this;
|
||||
}
|
||||
|
||||
public UrlContextListResult<T> build() {
|
||||
return new UrlContextListResult<>(page, size, total, items, nextUrl, prevUrl);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,14 +2,24 @@ package run.halo.app.theme.router.strategy;
|
|||
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
|
||||
import static run.halo.app.theme.router.TemplateRouterStrategy.PageUrlUtils.pageNum;
|
||||
import static run.halo.app.theme.router.TemplateRouterStrategy.PageUrlUtils.totalPage;
|
||||
|
||||
import java.util.Map;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
import run.halo.app.infra.utils.PathUtils;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.PostFinder;
|
||||
import run.halo.app.theme.finders.vo.PostVo;
|
||||
import run.halo.app.theme.router.TemplateRouterStrategy;
|
||||
import run.halo.app.theme.router.UrlContextListResult;
|
||||
|
||||
/**
|
||||
* The {@link ArchivesRouteStrategy} for generate {@link RouterFunction} specific to the template
|
||||
|
@ -18,7 +28,13 @@ import run.halo.app.theme.router.TemplateRouterStrategy;
|
|||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Component
|
||||
public class ArchivesRouteStrategy implements TemplateRouterStrategy {
|
||||
private final PostFinder postFinder;
|
||||
|
||||
public ArchivesRouteStrategy(PostFinder postFinder) {
|
||||
this.postFinder = postFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RouterFunction<ServerResponse> getRouteFunction(String template, String prefix) {
|
||||
|
@ -29,6 +45,18 @@ public class ArchivesRouteStrategy implements TemplateRouterStrategy {
|
|||
.or(GET(PathUtils.combinePath(prefix, "/{year}/{month}/page/{page}")))
|
||||
.and(accept(MediaType.TEXT_HTML)),
|
||||
request -> ServerResponse.ok()
|
||||
.render(DefaultTemplateEnum.ARCHIVES.getValue()));
|
||||
.render(DefaultTemplateEnum.ARCHIVES.getValue(),
|
||||
Map.of("posts", postList(request))));
|
||||
}
|
||||
|
||||
private Mono<UrlContextListResult<PostVo>> postList(ServerRequest request) {
|
||||
String path = request.path();
|
||||
return Mono.defer(() -> Mono.just(postFinder.list(pageNum(request), 10)))
|
||||
.publishOn(Schedulers.boundedElastic())
|
||||
.map(list -> new UrlContextListResult.Builder<PostVo>()
|
||||
.listResult(list)
|
||||
.nextUrl(PageUrlUtils.nextPageUrl(path, totalPage(list)))
|
||||
.prevUrl(PageUrlUtils.prevPageUrl(path))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,19 @@ package run.halo.app.theme.router.strategy;
|
|||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
import run.halo.app.infra.utils.PathUtils;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.CategoryFinder;
|
||||
import run.halo.app.theme.finders.vo.CategoryTreeVo;
|
||||
import run.halo.app.theme.router.TemplateRouterStrategy;
|
||||
|
||||
/**
|
||||
|
@ -18,7 +25,13 @@ import run.halo.app.theme.router.TemplateRouterStrategy;
|
|||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Component
|
||||
public class CategoriesRouteStrategy implements TemplateRouterStrategy {
|
||||
private final CategoryFinder categoryFinder;
|
||||
|
||||
public CategoriesRouteStrategy(CategoryFinder categoryFinder) {
|
||||
this.categoryFinder = categoryFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RouterFunction<ServerResponse> getRouteFunction(String template, String prefix) {
|
||||
|
@ -26,6 +39,12 @@ public class CategoriesRouteStrategy implements TemplateRouterStrategy {
|
|||
.route(GET(PathUtils.combinePath(prefix))
|
||||
.and(accept(MediaType.TEXT_HTML)),
|
||||
request -> ServerResponse.ok()
|
||||
.render(DefaultTemplateEnum.CATEGORIES.getValue()));
|
||||
.render(DefaultTemplateEnum.CATEGORIES.getValue(),
|
||||
Map.of("categories", categories())));
|
||||
}
|
||||
|
||||
private Mono<List<CategoryTreeVo>> categories() {
|
||||
return Mono.defer(() -> Mono.just(categoryFinder.listAsTree()))
|
||||
.publishOn(Schedulers.boundedElastic());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,19 +2,30 @@ package run.halo.app.theme.router.strategy;
|
|||
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
|
||||
import static run.halo.app.theme.router.TemplateRouterStrategy.PageUrlUtils.pageNum;
|
||||
import static run.halo.app.theme.router.TemplateRouterStrategy.PageUrlUtils.totalPage;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
import run.halo.app.core.extension.Category;
|
||||
import run.halo.app.extension.GroupVersionKind;
|
||||
import run.halo.app.infra.utils.PathUtils;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.CategoryFinder;
|
||||
import run.halo.app.theme.finders.PostFinder;
|
||||
import run.halo.app.theme.finders.vo.CategoryVo;
|
||||
import run.halo.app.theme.finders.vo.PostVo;
|
||||
import run.halo.app.theme.router.PermalinkIndexer;
|
||||
import run.halo.app.theme.router.TemplateRouterStrategy;
|
||||
import run.halo.app.theme.router.UrlContextListResult;
|
||||
|
||||
/**
|
||||
* The {@link CategoryRouteStrategy} for generate {@link RouterFunction} specific to the template
|
||||
|
@ -23,12 +34,19 @@ import run.halo.app.theme.router.TemplateRouterStrategy;
|
|||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Component
|
||||
public class CategoryRouteStrategy implements TemplateRouterStrategy {
|
||||
|
||||
private final PermalinkIndexer permalinkIndexer;
|
||||
private final PostFinder postFinder;
|
||||
|
||||
public CategoryRouteStrategy(PermalinkIndexer permalinkIndexer) {
|
||||
private final CategoryFinder categoryFinder;
|
||||
|
||||
public CategoryRouteStrategy(PermalinkIndexer permalinkIndexer, PostFinder postFinder,
|
||||
CategoryFinder categoryFinder) {
|
||||
this.permalinkIndexer = permalinkIndexer;
|
||||
this.postFinder = postFinder;
|
||||
this.categoryFinder = categoryFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -47,7 +65,26 @@ public class CategoryRouteStrategy implements TemplateRouterStrategy {
|
|||
String categoryName = permalinkIndexer.getNameBySlug(gvk, slug);
|
||||
return ServerResponse.ok()
|
||||
.render(DefaultTemplateEnum.CATEGORY.getValue(),
|
||||
Map.of("name", categoryName));
|
||||
Map.of("name", categoryName,
|
||||
"posts", postListByCategoryName(categoryName, request),
|
||||
"category", categoryByName(categoryName)));
|
||||
});
|
||||
}
|
||||
|
||||
private Mono<UrlContextListResult<PostVo>> postListByCategoryName(String name,
|
||||
ServerRequest request) {
|
||||
String path = request.path();
|
||||
return Mono.defer(() -> Mono.just(postFinder.listByCategory(pageNum(request), 10, name)))
|
||||
.publishOn(Schedulers.boundedElastic())
|
||||
.map(list -> new UrlContextListResult.Builder<PostVo>()
|
||||
.listResult(list)
|
||||
.nextUrl(PageUrlUtils.nextPageUrl(path, totalPage(list)))
|
||||
.prevUrl(PageUrlUtils.prevPageUrl(path))
|
||||
.build());
|
||||
}
|
||||
|
||||
private Mono<CategoryVo> categoryByName(String name) {
|
||||
return Mono.defer(() -> Mono.just(categoryFinder.getByName(name)))
|
||||
.publishOn(Schedulers.boundedElastic());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,23 @@ package run.halo.app.theme.router.strategy;
|
|||
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
|
||||
import static run.halo.app.theme.router.TemplateRouterStrategy.PageUrlUtils.pageNum;
|
||||
import static run.halo.app.theme.router.TemplateRouterStrategy.PageUrlUtils.totalPage;
|
||||
|
||||
import java.util.Map;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.PostFinder;
|
||||
import run.halo.app.theme.finders.vo.PostVo;
|
||||
import run.halo.app.theme.router.TemplateRouterStrategy;
|
||||
import run.halo.app.theme.router.UrlContextListResult;
|
||||
|
||||
/**
|
||||
* The {@link IndexRouteStrategy} for generate {@link RouterFunction} specific to the template
|
||||
|
@ -17,14 +27,33 @@ import run.halo.app.theme.router.TemplateRouterStrategy;
|
|||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Component
|
||||
public class IndexRouteStrategy implements TemplateRouterStrategy {
|
||||
|
||||
private final PostFinder postFinder;
|
||||
|
||||
public IndexRouteStrategy(PostFinder postFinder) {
|
||||
this.postFinder = postFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RouterFunction<ServerResponse> getRouteFunction(String template, String pattern) {
|
||||
return RouterFunctions
|
||||
.route(GET("/").or(GET("/page/{page}"))
|
||||
.and(accept(MediaType.TEXT_HTML)),
|
||||
request -> ServerResponse.ok()
|
||||
.render(DefaultTemplateEnum.INDEX.getValue()));
|
||||
.render(DefaultTemplateEnum.INDEX.getValue(),
|
||||
Map.of("posts", postList(request))));
|
||||
}
|
||||
|
||||
private Mono<UrlContextListResult<PostVo>> postList(ServerRequest request) {
|
||||
String path = request.path();
|
||||
return Mono.defer(() -> Mono.just(postFinder.list(pageNum(request), 10)))
|
||||
.publishOn(Schedulers.boundedElastic())
|
||||
.map(list -> new UrlContextListResult.Builder<PostVo>()
|
||||
.listResult(list)
|
||||
.nextUrl(PageUrlUtils.nextPageUrl(path, totalPage(list)))
|
||||
.prevUrl(PageUrlUtils.prevPageUrl(path))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.server.PathContainer;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
|
@ -17,10 +18,14 @@ import org.springframework.web.reactive.function.server.RouterFunctions;
|
|||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import org.springframework.web.util.pattern.PathPattern;
|
||||
import org.springframework.web.util.pattern.PathPatternParser;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
import run.halo.app.content.permalinks.ExtensionLocator;
|
||||
import run.halo.app.core.extension.Post;
|
||||
import run.halo.app.extension.GroupVersionKind;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.PostFinder;
|
||||
import run.halo.app.theme.finders.vo.PostVo;
|
||||
import run.halo.app.theme.router.PermalinkIndexer;
|
||||
import run.halo.app.theme.router.TemplateRouterStrategy;
|
||||
|
||||
|
@ -31,11 +36,14 @@ import run.halo.app.theme.router.TemplateRouterStrategy;
|
|||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Component
|
||||
public class PostRouteStrategy implements TemplateRouterStrategy {
|
||||
private final PermalinkIndexer permalinkIndexer;
|
||||
private final PostFinder postFinder;
|
||||
|
||||
public PostRouteStrategy(PermalinkIndexer permalinkIndexer) {
|
||||
public PostRouteStrategy(PermalinkIndexer permalinkIndexer, PostFinder postFinder) {
|
||||
this.permalinkIndexer = permalinkIndexer;
|
||||
this.postFinder = postFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -86,17 +94,23 @@ public class PostRouteStrategy implements TemplateRouterStrategy {
|
|||
PathPattern parse = PathPatternParser.defaultInstance.parse(pattern);
|
||||
PathPattern.PathMatchInfo pathMatchInfo =
|
||||
parse.matchAndExtract(PathContainer.parsePath(request.path()));
|
||||
Map<String, String> uriVariables = new HashMap<>();
|
||||
uriVariables.put(PostRequestParamPredicate.NAME_PARAM,
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
model.put(PostRequestParamPredicate.NAME_PARAM,
|
||||
extensionLocator.name());
|
||||
if (pathMatchInfo != null) {
|
||||
uriVariables.putAll(pathMatchInfo.getUriVariables());
|
||||
model.putAll(pathMatchInfo.getUriVariables());
|
||||
}
|
||||
model.put("post", postByName(extensionLocator.name()));
|
||||
return ServerResponse.ok()
|
||||
.render(DefaultTemplateEnum.POST.getValue(), uriVariables);
|
||||
.render(DefaultTemplateEnum.POST.getValue(), model);
|
||||
});
|
||||
}
|
||||
|
||||
private Mono<PostVo> postByName(String name) {
|
||||
return Mono.defer(() -> Mono.just(postFinder.getByName(name)))
|
||||
.publishOn(Schedulers.boundedElastic());
|
||||
}
|
||||
|
||||
class PostRequestParamPredicate {
|
||||
static final String NAME_PARAM = "name";
|
||||
static final String SLUG_PARAM = "slug";
|
||||
|
|
|
@ -7,14 +7,19 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
import run.halo.app.core.extension.SinglePage;
|
||||
import run.halo.app.extension.GroupVersionKind;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.SinglePageFinder;
|
||||
import run.halo.app.theme.finders.vo.SinglePageVo;
|
||||
import run.halo.app.theme.router.PermalinkIndexer;
|
||||
import run.halo.app.theme.router.TemplateRouterStrategy;
|
||||
|
||||
|
@ -25,12 +30,16 @@ import run.halo.app.theme.router.TemplateRouterStrategy;
|
|||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Component
|
||||
public class SinglePageRouteStrategy implements TemplateRouterStrategy {
|
||||
|
||||
private final PermalinkIndexer permalinkIndexer;
|
||||
private final SinglePageFinder singlePageFinder;
|
||||
|
||||
public SinglePageRouteStrategy(PermalinkIndexer permalinkIndexer) {
|
||||
public SinglePageRouteStrategy(PermalinkIndexer permalinkIndexer,
|
||||
SinglePageFinder singlePageFinder) {
|
||||
this.permalinkIndexer = permalinkIndexer;
|
||||
this.singlePageFinder = singlePageFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,7 +62,14 @@ public class SinglePageRouteStrategy implements TemplateRouterStrategy {
|
|||
return ServerResponse.notFound().build();
|
||||
}
|
||||
return ServerResponse.ok()
|
||||
.render(DefaultTemplateEnum.SINGLE_PAGE.getValue(), Map.of("name", name));
|
||||
.render(DefaultTemplateEnum.SINGLE_PAGE.getValue(),
|
||||
Map.of("name", name,
|
||||
"singlePage", singlePageByName(name)));
|
||||
});
|
||||
}
|
||||
|
||||
private Mono<SinglePageVo> singlePageByName(String name) {
|
||||
return Mono.defer(() -> Mono.just(singlePageFinder.getByName(name)))
|
||||
.publishOn(Schedulers.boundedElastic());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,19 +2,30 @@ package run.halo.app.theme.router.strategy;
|
|||
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
|
||||
import static run.halo.app.theme.router.TemplateRouterStrategy.PageUrlUtils.pageNum;
|
||||
import static run.halo.app.theme.router.TemplateRouterStrategy.PageUrlUtils.totalPage;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
import run.halo.app.core.extension.Tag;
|
||||
import run.halo.app.extension.GroupVersionKind;
|
||||
import run.halo.app.infra.utils.PathUtils;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.PostFinder;
|
||||
import run.halo.app.theme.finders.TagFinder;
|
||||
import run.halo.app.theme.finders.vo.PostVo;
|
||||
import run.halo.app.theme.finders.vo.TagVo;
|
||||
import run.halo.app.theme.router.PermalinkIndexer;
|
||||
import run.halo.app.theme.router.TemplateRouterStrategy;
|
||||
import run.halo.app.theme.router.UrlContextListResult;
|
||||
|
||||
/**
|
||||
* The {@link TagRouteStrategy} for generate {@link RouterFunction} specific to the template
|
||||
|
@ -23,12 +34,19 @@ import run.halo.app.theme.router.TemplateRouterStrategy;
|
|||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Component
|
||||
public class TagRouteStrategy implements TemplateRouterStrategy {
|
||||
|
||||
private final PermalinkIndexer permalinkIndexer;
|
||||
private final PostFinder postFinder;
|
||||
|
||||
public TagRouteStrategy(PermalinkIndexer permalinkIndexer) {
|
||||
private final TagFinder tagFinder;
|
||||
|
||||
public TagRouteStrategy(PermalinkIndexer permalinkIndexer, PostFinder postFinder,
|
||||
TagFinder tagFinder) {
|
||||
this.permalinkIndexer = permalinkIndexer;
|
||||
this.postFinder = postFinder;
|
||||
this.tagFinder = tagFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,7 +64,27 @@ public class TagRouteStrategy implements TemplateRouterStrategy {
|
|||
}
|
||||
String name = permalinkIndexer.getNameBySlug(gvk, slug);
|
||||
return ServerResponse.ok()
|
||||
.render(DefaultTemplateEnum.TAG.getValue(), Map.of("name", name));
|
||||
.render(DefaultTemplateEnum.TAG.getValue(),
|
||||
Map.of("name", name,
|
||||
"posts", postList(request, name),
|
||||
"tag", tagByName(name))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private Mono<UrlContextListResult<PostVo>> postList(ServerRequest request, String name) {
|
||||
String path = request.path();
|
||||
return Mono.defer(() -> Mono.just(postFinder.listByTag(pageNum(request), 10, name)))
|
||||
.publishOn(Schedulers.boundedElastic())
|
||||
.map(list -> new UrlContextListResult.Builder<PostVo>()
|
||||
.listResult(list)
|
||||
.nextUrl(PageUrlUtils.nextPageUrl(path, totalPage(list)))
|
||||
.prevUrl(PageUrlUtils.prevPageUrl(path))
|
||||
.build());
|
||||
}
|
||||
|
||||
private Mono<TagVo> tagByName(String name) {
|
||||
return Mono.defer(() -> Mono.just(tagFinder.getByName(name)))
|
||||
.publishOn(Schedulers.boundedElastic());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,19 @@ package run.halo.app.theme.router.strategy;
|
|||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
import run.halo.app.infra.utils.PathUtils;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.TagFinder;
|
||||
import run.halo.app.theme.finders.vo.TagVo;
|
||||
import run.halo.app.theme.router.TemplateRouterStrategy;
|
||||
|
||||
/**
|
||||
|
@ -18,8 +25,15 @@ import run.halo.app.theme.router.TemplateRouterStrategy;
|
|||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Component
|
||||
public class TagsRouteStrategy implements TemplateRouterStrategy {
|
||||
|
||||
private final TagFinder tagFinder;
|
||||
|
||||
public TagsRouteStrategy(TagFinder tagFinder) {
|
||||
this.tagFinder = tagFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RouterFunction<ServerResponse> getRouteFunction(String template, String prefix) {
|
||||
String pattern = PathUtils.combinePath(prefix);
|
||||
|
@ -27,6 +41,13 @@ public class TagsRouteStrategy implements TemplateRouterStrategy {
|
|||
.route(GET(pattern)
|
||||
.and(accept(MediaType.TEXT_HTML)),
|
||||
request -> ServerResponse.ok()
|
||||
.render(DefaultTemplateEnum.TAGS.getValue()));
|
||||
.render(DefaultTemplateEnum.TAGS.getValue(),
|
||||
Map.of("tags", tags()))
|
||||
);
|
||||
}
|
||||
|
||||
private Mono<List<TagVo>> tags() {
|
||||
return Mono.defer(() -> Mono.just(tagFinder.listAll()))
|
||||
.publishOn(Schedulers.boundedElastic());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package run.halo.app.theme.router;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Map;
|
||||
|
@ -8,10 +9,14 @@ import org.junit.jupiter.api.BeforeEach;
|
|||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.TagFinder;
|
||||
import run.halo.app.theme.router.strategy.TagsRouteStrategy;
|
||||
|
||||
/**
|
||||
* Tests for {@link TemplateRouteManager}.
|
||||
|
@ -26,16 +31,22 @@ class TemplateRouteManagerTest {
|
|||
private PermalinkPatternProvider permalinkPatternProvider;
|
||||
|
||||
@Mock
|
||||
private PermalinkIndexer permalinkIndexer;
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private TemplateRouteManager templateRouteManager;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
templateRouteManager = new TemplateRouteManager(permalinkIndexer, permalinkPatternProvider);
|
||||
templateRouteManager = new TemplateRouteManager(permalinkPatternProvider,
|
||||
applicationContext);
|
||||
|
||||
when(permalinkPatternProvider.getPattern(DefaultTemplateEnum.TAGS))
|
||||
.thenReturn("/tags");
|
||||
|
||||
TagFinder tagFinder = Mockito.mock(TagFinder.class);
|
||||
when(applicationContext.getBean(eq(TagsRouteStrategy.class)))
|
||||
.thenReturn(new TagsRouteStrategy(tagFinder));
|
||||
|
||||
templateRouteManager.register(DefaultTemplateEnum.TAGS.getValue());
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package run.halo.app.theme.router;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link TemplateRouterStrategy}.
|
||||
*
|
||||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class TemplateRouterStrategyTest {
|
||||
|
||||
@Nested
|
||||
class PageUrlUtils {
|
||||
static String s = "/tags";
|
||||
static String s1 = "/tags/page/1";
|
||||
static String s2 = "/tags/page/2";
|
||||
static String s3 = "/tags/y/m/page/2";
|
||||
static String s4 = "/tags/y/m";
|
||||
static String s5 = "/tags/y/m/page/3";
|
||||
|
||||
@Test
|
||||
void nextPageUrl() {
|
||||
long totalPage = 10;
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.nextPageUrl(s, totalPage))
|
||||
.isEqualTo("/tags/page/2");
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.nextPageUrl(s2, totalPage))
|
||||
.isEqualTo("/tags/page/3");
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.nextPageUrl(s3, totalPage))
|
||||
.isEqualTo("/tags/y/m/page/3");
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.nextPageUrl(s4, totalPage))
|
||||
.isEqualTo("/tags/y/m/page/2");
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.nextPageUrl(s5, totalPage))
|
||||
.isEqualTo("/tags/y/m/page/4");
|
||||
|
||||
// The number of pages does not exceed the total number of pages
|
||||
totalPage = 1;
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.nextPageUrl("/tags/page/1", totalPage))
|
||||
.isEqualTo("/tags/page/1");
|
||||
|
||||
totalPage = 0;
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.nextPageUrl("/tags", totalPage))
|
||||
.isEqualTo("/tags/page/1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void prevPageUrl() {
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.prevPageUrl(s))
|
||||
.isEqualTo("/tags");
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.prevPageUrl(s1))
|
||||
.isEqualTo("/tags");
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.prevPageUrl(s2))
|
||||
.isEqualTo("/tags");
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.prevPageUrl(s3))
|
||||
.isEqualTo("/tags/y/m");
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.prevPageUrl(s4))
|
||||
.isEqualTo("/tags/y/m");
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.prevPageUrl(s5))
|
||||
.isEqualTo("/tags/y/m/page/2");
|
||||
|
||||
assertThat(TemplateRouterStrategy.PageUrlUtils.prevPageUrl("/page/2"))
|
||||
.isEqualTo("/");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,11 +2,14 @@ package run.halo.app.theme.router.strategy;
|
|||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
@ -17,6 +20,8 @@ import org.springframework.web.reactive.function.server.ServerResponse;
|
|||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.PostFinder;
|
||||
import run.halo.app.theme.router.UrlContextListResult;
|
||||
|
||||
/**
|
||||
* Tests for {@link ArchivesRouteStrategy}.
|
||||
|
@ -29,12 +34,16 @@ class ArchivesRouteStrategyTest {
|
|||
|
||||
@Mock
|
||||
private ViewResolver viewResolver;
|
||||
@Mock
|
||||
private PostFinder postFinder;
|
||||
|
||||
@InjectMocks
|
||||
private ArchivesRouteStrategy archivesRouteStrategy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
archivesRouteStrategy = new ArchivesRouteStrategy();
|
||||
lenient().when(postFinder.list(any(), any())).thenReturn(
|
||||
new UrlContextListResult<>(1, 10, 1, List.of(), null, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -2,11 +2,14 @@ package run.halo.app.theme.router.strategy;
|
|||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
@ -17,6 +20,7 @@ import org.springframework.web.reactive.function.server.ServerResponse;
|
|||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.CategoryFinder;
|
||||
|
||||
/**
|
||||
* Tests for {@link CategoriesRouteStrategy}.
|
||||
|
@ -29,11 +33,16 @@ class CategoriesRouteStrategyTest {
|
|||
@Mock
|
||||
private ViewResolver viewResolver;
|
||||
|
||||
@Mock
|
||||
private CategoryFinder categoryFinder;
|
||||
|
||||
@InjectMocks
|
||||
private CategoriesRouteStrategy categoriesRouteStrategy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
categoriesRouteStrategy = new CategoriesRouteStrategy();
|
||||
lenient().when(categoryFinder.listAsTree())
|
||||
.thenReturn(List.of());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package run.halo.app.theme.router.strategy;
|
||||
|
||||
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.when;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
@ -17,7 +20,9 @@ import org.springframework.web.reactive.function.server.RouterFunction;
|
|||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.extension.ListResult;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.PostFinder;
|
||||
import run.halo.app.theme.router.PermalinkIndexer;
|
||||
|
||||
/**
|
||||
|
@ -34,17 +39,23 @@ class CategoryRouteStrategyTest {
|
|||
@Mock
|
||||
private ViewResolver viewResolver;
|
||||
|
||||
@Mock
|
||||
private PostFinder postFinder;
|
||||
|
||||
@InjectMocks
|
||||
private CategoryRouteStrategy categoryRouteStrategy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
categoryRouteStrategy = new CategoryRouteStrategy(permalinkIndexer);
|
||||
when(permalinkIndexer.getSlugs(any()))
|
||||
.thenReturn(List.of("category-slug-1", "category-slug-2"));
|
||||
when(permalinkIndexer.getNameBySlug(any(), eq("category-slug-1")))
|
||||
.thenReturn("category-name-1");
|
||||
when(permalinkIndexer.getNameBySlug(any(), eq("category-slug-2")))
|
||||
.thenReturn("category-name-2");
|
||||
|
||||
lenient().when(postFinder.listByCategory(anyInt(), anyInt(), any()))
|
||||
.thenReturn(new ListResult<>(1, 10, 0, List.of()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
package run.halo.app.theme.router.strategy;
|
||||
|
||||
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.when;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
@ -16,7 +20,9 @@ import org.springframework.web.reactive.function.server.RouterFunction;
|
|||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.extension.ListResult;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.PostFinder;
|
||||
|
||||
/**
|
||||
* Tests for {@link IndexRouteStrategy}.
|
||||
|
@ -29,11 +35,16 @@ class IndexRouteStrategyTest {
|
|||
@Mock
|
||||
private ViewResolver viewResolver;
|
||||
|
||||
@Mock
|
||||
private PostFinder postFinder;
|
||||
|
||||
@InjectMocks
|
||||
private IndexRouteStrategy indexRouteStrategy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
indexRouteStrategy = new IndexRouteStrategy();
|
||||
lenient().when(postFinder.list(anyInt(), anyInt()))
|
||||
.thenReturn(new ListResult<>(1, 10, 0, List.of()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.List;
|
|||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
@ -18,10 +19,13 @@ import org.springframework.web.reactive.function.server.RouterFunction;
|
|||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.content.TestPost;
|
||||
import run.halo.app.content.permalinks.ExtensionLocator;
|
||||
import run.halo.app.core.extension.Post;
|
||||
import run.halo.app.extension.GroupVersionKind;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.PostFinder;
|
||||
import run.halo.app.theme.finders.vo.PostVo;
|
||||
import run.halo.app.theme.router.PermalinkIndexer;
|
||||
|
||||
/**
|
||||
|
@ -39,11 +43,15 @@ class PostRouteStrategyTest {
|
|||
@Mock
|
||||
private PermalinkIndexer permalinkIndexer;
|
||||
|
||||
@Mock
|
||||
private PostFinder postFinder;
|
||||
|
||||
@InjectMocks
|
||||
private PostRouteStrategy postRouteStrategy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
postRouteStrategy = new PostRouteStrategy(permalinkIndexer);
|
||||
lenient().when(postFinder.getByName(any())).thenReturn(PostVo.from(TestPost.postV1()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package run.halo.app.theme.router.strategy;
|
||||
|
||||
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.when;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
@ -17,7 +20,9 @@ import org.springframework.web.reactive.function.server.RouterFunction;
|
|||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.extension.ListResult;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.SinglePageFinder;
|
||||
import run.halo.app.theme.router.PermalinkIndexer;
|
||||
|
||||
/**
|
||||
|
@ -35,11 +40,16 @@ class SinglePageRouteStrategyTest {
|
|||
@Mock
|
||||
private ViewResolver viewResolver;
|
||||
|
||||
@Mock
|
||||
private SinglePageFinder singlePageFinder;
|
||||
|
||||
@InjectMocks
|
||||
private SinglePageRouteStrategy strategy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
strategy = new SinglePageRouteStrategy(permalinkIndexer);
|
||||
lenient().when(singlePageFinder.list(anyInt(), anyInt()))
|
||||
.thenReturn(new ListResult<>(1, 10, 0, List.of()));
|
||||
when(permalinkIndexer.getPermalinks(any()))
|
||||
.thenReturn(List.of("/fake-slug"));
|
||||
when(permalinkIndexer.getNameBySlug(any(), eq("fake-slug")))
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package run.halo.app.theme.router.strategy;
|
||||
|
||||
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.when;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
@ -17,7 +20,9 @@ import org.springframework.web.reactive.function.server.RouterFunction;
|
|||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.extension.ListResult;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.PostFinder;
|
||||
import run.halo.app.theme.router.PermalinkIndexer;
|
||||
|
||||
/**
|
||||
|
@ -31,15 +36,18 @@ class TagRouteStrategyTest {
|
|||
|
||||
@Mock
|
||||
private PermalinkIndexer permalinkIndexer;
|
||||
|
||||
@Mock
|
||||
private PostFinder postFinder;
|
||||
@Mock
|
||||
private ViewResolver viewResolver;
|
||||
|
||||
@InjectMocks
|
||||
private TagRouteStrategy tagRouteStrategy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
tagRouteStrategy = new TagRouteStrategy(permalinkIndexer);
|
||||
lenient().when(postFinder.listByTag(anyInt(), anyInt(), any()))
|
||||
.thenReturn(new ListResult<>(1, 10, 0, List.of()));
|
||||
when(permalinkIndexer.getSlugs(any()))
|
||||
.thenReturn(List.of("fake-slug"));
|
||||
when(permalinkIndexer.getNameBySlug(any(), eq("fake-slug")))
|
||||
|
|
|
@ -2,11 +2,14 @@ package run.halo.app.theme.router.strategy;
|
|||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
@ -17,6 +20,7 @@ import org.springframework.web.reactive.function.server.ServerResponse;
|
|||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.theme.DefaultTemplateEnum;
|
||||
import run.halo.app.theme.finders.TagFinder;
|
||||
|
||||
/**
|
||||
* Tests for {@link TagsRouteStrategy}.
|
||||
|
@ -30,11 +34,15 @@ class TagsRouteStrategyTest {
|
|||
@Mock
|
||||
private ViewResolver viewResolver;
|
||||
|
||||
@Mock
|
||||
private TagFinder tagFinder;
|
||||
|
||||
@InjectMocks
|
||||
private TagsRouteStrategy tagsRouteStrategy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
tagsRouteStrategy = new TagsRouteStrategy();
|
||||
lenient().when(tagFinder.listAll()).thenReturn(List.of());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue