From ce9c33c8163a3078aca12f3efaee41401970f7fa Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Wed, 8 Mar 2023 17:22:11 +0800 Subject: [PATCH] fix: posts and pages cannot be counted for visits (#3471) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind bug /area core /milestone 2.3.x #### What this PR does / why we need it: 修复文章和自定义页面缺失 name 模型属性导致的访问量无法计数问题 此为 2.3.0 引入的问题 see #3300 how to test it? 1. 切换文章的路由为不带 name 的规则 2. 访问文章看 `/apis/api.halo.run/v1alpha1/trackers/counter` API 是否有如下参数,且 name 值正确 ```json { "group": "content.halo.run", "plural": "posts", "name": "335", "hostname": "localhost", "screen": "1920x1080", "language": "zh-CN", "url": "/?p=halo-150-released", "referrer": "http://localhost:8090/?p=how-to-development-a-halo-plugin" } ``` 3. 观察文章访问量是否有增加 4. 重复上述 2、3 步骤检查自定义页面的访问量功能是否正确 #### Which issue(s) this PR fixes: Fixes #3448 #### Does this PR introduce a user-facing change? ```release-note 修复文章和自定义页面缺失属性导致的访问量无法计数问题 ``` --- .../app/theme/router/SinglePageRoute.java | 1 + .../router/factories/PostRouteFactory.java | 1 + .../app/theme/router/SinglePageRouteTest.java | 101 ++++++++++++++++++ .../factories/PostRouteFactoryTest.java | 2 + 4 files changed, 105 insertions(+) create mode 100644 src/test/java/run/halo/app/theme/router/SinglePageRouteTest.java diff --git a/src/main/java/run/halo/app/theme/router/SinglePageRoute.java b/src/main/java/run/halo/app/theme/router/SinglePageRoute.java index 7e611b6042..eddbddbadb 100644 --- a/src/main/java/run/halo/app/theme/router/SinglePageRoute.java +++ b/src/main/java/run/halo/app/theme/router/SinglePageRoute.java @@ -127,6 +127,7 @@ HandlerFunction handlerFunction(String name) { return request -> singlePageFinder.getByName(name) .flatMap(singlePageVo -> { Map model = new HashMap<>(); + model.put("name", singlePageVo.getMetadata().getName()); model.put("groupVersionKind", gvk); model.put("plural", getPlural()); model.put(ModelConst.TEMPLATE_ID, DefaultTemplateEnum.SINGLE_PAGE.getValue()); diff --git a/src/main/java/run/halo/app/theme/router/factories/PostRouteFactory.java b/src/main/java/run/halo/app/theme/router/factories/PostRouteFactory.java index 75a0868bd8..e72573b660 100644 --- a/src/main/java/run/halo/app/theme/router/factories/PostRouteFactory.java +++ b/src/main/java/run/halo/app/theme/router/factories/PostRouteFactory.java @@ -102,6 +102,7 @@ private Mono postResponse(ServerRequest request, return postVoMono .flatMap(postVo -> { Map model = new HashMap<>(); + model.put("name", postVo.getMetadata().getName()); model.put(ModelConst.TEMPLATE_ID, DefaultTemplateEnum.POST.getValue()); model.put("groupVersionKind", GroupVersionKind.fromExtension(Post.class)); GVK gvk = Post.class.getAnnotation(GVK.class); diff --git a/src/test/java/run/halo/app/theme/router/SinglePageRouteTest.java b/src/test/java/run/halo/app/theme/router/SinglePageRouteTest.java new file mode 100644 index 0000000000..f8de4f79fa --- /dev/null +++ b/src/test/java/run/halo/app/theme/router/SinglePageRouteTest.java @@ -0,0 +1,101 @@ +package run.halo.app.theme.router; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import java.util.Map; +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.MediaType; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.web.reactive.function.server.HandlerFunction; +import org.springframework.web.reactive.function.server.HandlerStrategies; +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 org.springframework.web.reactive.result.view.ViewResolver; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; +import run.halo.app.core.extension.content.SinglePage; +import run.halo.app.extension.GroupVersionKind; +import run.halo.app.extension.Metadata; +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.factories.ModelConst; + +/** + * Tests for {@link SinglePageRoute}. + * + * @author guqing + * @since 2.0.0 + */ +@ExtendWith(MockitoExtension.class) +class SinglePageRouteTest { + + @Mock + private ViewNameResolver viewNameResolver; + + @Mock + private SinglePageFinder singlePageFinder; + + @Mock + protected ViewResolver viewResolver; + + @InjectMocks + private SinglePageRoute singlePageRoute; + + @Test + void handlerFunction() { + // fix gh-3448 + when(viewNameResolver.resolveViewNameOrDefault(any(), any(), any())) + .thenReturn(Mono.just(DefaultTemplateEnum.POST.getValue())); + + String pageName = "fake-page"; + when(viewResolver.resolveViewName(any(), any())) + .thenReturn(Mono.just(new EmptyView() { + @Override + public Mono render(Map model, MediaType contentType, + ServerWebExchange exchange) { + assertThat(model).containsKey(ModelConst.TEMPLATE_ID); + assertThat(model.get(ModelConst.TEMPLATE_ID)) + .isEqualTo(DefaultTemplateEnum.SINGLE_PAGE.getValue()); + assertThat(model.get("name")) + .isEqualTo(pageName); + assertThat(model.get("plural")).isEqualTo("singlepages"); + assertThat(model.get("singlePage")).isNotNull(); + assertThat(model.get("groupVersionKind")) + .isEqualTo(GroupVersionKind.fromExtension(SinglePage.class)); + return super.render(model, contentType, exchange); + } + })); + + SinglePage singlePage = new SinglePage(); + singlePage.setMetadata(new Metadata()); + singlePage.getMetadata().setName(pageName); + singlePage.setSpec(new SinglePage.SinglePageSpec()); + when(singlePageFinder.getByName(eq(pageName))) + .thenReturn(Mono.just(SinglePageVo.from(singlePage))); + + HandlerFunction handlerFunction = + singlePageRoute.handlerFunction(pageName); + RouterFunction routerFunction = + RouterFunctions.route().GET("/archives/{name}", handlerFunction).build(); + + WebTestClient webTestClient = WebTestClient.bindToRouterFunction(routerFunction) + .handlerStrategies(HandlerStrategies.builder() + .viewResolver(viewResolver) + .build()) + .build(); + + webTestClient.get() + .uri("/archives/fake-name") + .exchange() + .expectStatus().isOk(); + } +} diff --git a/src/test/java/run/halo/app/theme/router/factories/PostRouteFactoryTest.java b/src/test/java/run/halo/app/theme/router/factories/PostRouteFactoryTest.java index b2a76906d5..2f31d62399 100644 --- a/src/test/java/run/halo/app/theme/router/factories/PostRouteFactoryTest.java +++ b/src/test/java/run/halo/app/theme/router/factories/PostRouteFactoryTest.java @@ -75,6 +75,8 @@ public Mono render(Map model, MediaType contentType, assertThat(model).containsKey(ModelConst.TEMPLATE_ID); assertThat(model.get(ModelConst.TEMPLATE_ID)) .isEqualTo(DefaultTemplateEnum.POST.getValue()); + assertThat(model.get("name")) + .isEqualTo(post.getMetadata().getName()); assertThat(model.get("plural")).isEqualTo("posts"); assertThat(model.get("post")).isNotNull(); assertThat(model.get("groupVersionKind"))