feat(app-api): 详情补充互动数量字段

This commit is contained in:
Zhou Weidong committed 2026-10-20 12:02:16 +08:00
1 parent 678652cb20
commit 671953bff3
7 files changed
+231 -1

No files matched your search

@@ -89,6 +89,10 @@ class AppCatalogControllerContractTest {
AppDramaDetailVO detail = new AppDramaDetailVO();
detail.setId(42L);
detail.setTitle("命运的相遇");
detail.setViewCount(12400L);
detail.setLikeCount(3200L);
detail.setFavoriteCount(1800L);
detail.setCommentCount(96L);
detail.setEpisodes(List.of());
given(catalogService.dramaDetail(42L)).willReturn(detail);
@@ -97,7 +101,11 @@ class AppCatalogControllerContractTest {
.andExpect(jsonPath("$.code").value(0))
.andExpect(jsonPath("$.data.id").value("42"))
.andExpect(jsonPath("$.data.id").isString())
.andExpect(jsonPath("$.data.title").value("命运的相遇"));
.andExpect(jsonPath("$.data.title").value("命运的相遇"))
.andExpect(jsonPath("$.data.viewCount").value("12400"))
.andExpect(jsonPath("$.data.likeCount").value("3200"))
.andExpect(jsonPath("$.data.favoriteCount").value("1800"))
.andExpect(jsonPath("$.data.commentCount").value("96"));
verify(catalogService).dramaDetail(42L);
}
@@ -0,0 +1,66 @@
// Author: fruit.com.cn
package com.fruitshorts.app.service;
import com.fruitshorts.app.vo.AppDramaDetailVO;
import com.fruitshorts.content.dal.entity.Drama;
import com.fruitshorts.content.service.BannerService;
import com.fruitshorts.content.service.DramaCategoryService;
import com.fruitshorts.content.service.DramaService;
import com.fruitshorts.content.service.EpisodeService;
import com.fruitshorts.interaction.service.CommentService;
import com.fruitshorts.media.service.PlaybackSigner;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* 目录聚合的互动数量装配:详情 VO 的点赞/收藏取短剧计数,评论数取互动域统计。
*/
class AppCatalogServiceTest {
private DramaService dramaService;
private EpisodeService episodeService;
private DramaCategoryService dramaCategoryService;
private CommentService commentService;
private AppCatalogService catalogService;
@BeforeEach
void setUp() {
dramaService = mock(DramaService.class);
episodeService = mock(EpisodeService.class);
BannerService bannerService = mock(BannerService.class);
dramaCategoryService = mock(DramaCategoryService.class);
PlaybackSigner playbackSigner = mock(PlaybackSigner.class);
commentService = mock(CommentService.class);
catalogService = new AppCatalogService(dramaService, episodeService, bannerService,
dramaCategoryService, playbackSigner, commentService);
}
@Test
void should_fill_interaction_counts_when_drama_detail_is_built() {
Drama drama = new Drama();
drama.setId(42L);
drama.setTitle("命运的相遇");
drama.setLikeCount(3200L);
drama.setFavoriteCount(1800L);
drama.setViewCount(12400L);
given(dramaService.getPublished(42L)).willReturn(drama);
given(episodeService.listPublishedByDrama(42L)).willReturn(List.of());
given(dramaCategoryService.listBasic()).willReturn(List.of());
given(commentService.countByDrama(42L)).willReturn(96L);
AppDramaDetailVO detail = catalogService.dramaDetail(42L);
assertThat(detail.getViewCount()).isEqualTo(12400L);
assertThat(detail.getLikeCount()).isEqualTo(3200L);
assertThat(detail.getFavoriteCount()).isEqualTo(1800L);
assertThat(detail.getCommentCount()).isEqualTo(96L);
verify(commentService).countByDrama(42L);
}
}
@@ -0,0 +1,80 @@
// Author: fruit.com.cn
package com.fruitshorts.app.service;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.fruitshorts.content.service.DramaService;
import com.fruitshorts.content.service.EpisodeService;
import com.fruitshorts.interaction.config.InteractionProperties;
import com.fruitshorts.interaction.dal.entity.ContentComment;
import com.fruitshorts.interaction.dal.mapper.ContentAuditRecordMapper;
import com.fruitshorts.interaction.dal.mapper.ContentCommentMapper;
import com.fruitshorts.interaction.dal.mapper.ContentLikeMapper;
import com.fruitshorts.interaction.service.AuditRecorder;
import com.fruitshorts.interaction.service.CommentService;
import com.fruitshorts.interaction.service.SensitiveWordService;
import com.fruitshorts.user.dal.mapper.AppUserMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
* 评论计数口径:按剧统计,排除已删除评论。
*/
class CommentServiceCountTest {
private ContentCommentMapper commentMapper;
private CommentService commentService;
@BeforeAll
static void initTableInfo() {
TableInfoHelper.initTableInfo(
new MapperBuilderAssistant(new MybatisConfiguration(), ""), ContentComment.class);
}
@BeforeEach
void setUp() {
commentMapper = mock(ContentCommentMapper.class);
commentService = new CommentService(
commentMapper,
mock(ContentLikeMapper.class),
mock(ContentAuditRecordMapper.class),
mock(AppUserMapper.class),
mock(DramaService.class),
mock(EpisodeService.class),
mock(SensitiveWordService.class),
mock(AuditRecorder.class),
mock(InteractionProperties.class));
}
@Test
void should_count_comments_of_drama_and_exclude_deleted() {
ArgumentCaptor<Wrapper<ContentComment>> captor = ArgumentCaptor.forClass(Wrapper.class);
given(commentMapper.selectCount(captor.capture())).willReturn(5L);
long count = commentService.countByDrama(7L);
assertThat(count).isEqualTo(5L);
Wrapper<ContentComment> wrapper = captor.getValue();
assertThat(wrapper.getSqlSegment()).contains("drama_id").contains("status");
AbstractWrapper<ContentComment, ?, ?> lambda = (AbstractWrapper<ContentComment, ?, ?>) wrapper;
assertThat(lambda.getParamNameValuePairs().values()).contains(7L, "deleted");
}
@Test
void should_return_zero_without_query_when_drama_id_is_missing() {
assertThat(commentService.countByDrama(null)).isZero();
verify(commentMapper, never()).selectCount(any());
}
}