feat(admin): 剧集列表接口支持分页
This commit is contained in:
1 parent
5227762aeb
commit
0143fa036c
5 files changed
+322
-26
No files matched your search
+9
-5
@@ -2,6 +2,7 @@
|
||||
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.PageResult;
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.content.dal.entity.Drama;
|
||||
import com.fruitshorts.content.service.DramaService;
|
||||
@@ -39,12 +40,15 @@ public class EpisodeController {
|
||||
private final CommentService commentService;
|
||||
private final DramaService dramaService;
|
||||
|
||||
@Operation(summary = "剧集列表")
|
||||
@Operation(summary = "剧集列表(分页)")
|
||||
@GetMapping
|
||||
@PreAuthorize("@ss.hasPermission('episode:list')")
|
||||
public Result<List<EpisodeRespVO>> list(@RequestParam Long dramaId,
|
||||
@RequestParam(required = false) String status) {
|
||||
List<EpisodeRespVO> episodes = episodeService.listByDrama(dramaId, status);
|
||||
public Result<PageResult<EpisodeRespVO>> list(@RequestParam Long dramaId,
|
||||
@RequestParam(required = false) String status,
|
||||
@RequestParam(required = false) Integer pageIndex,
|
||||
@RequestParam(required = false) Integer pageSize) {
|
||||
PageResult<EpisodeRespVO> page = episodeService.pageByDrama(dramaId, status, pageIndex, pageSize);
|
||||
List<EpisodeRespVO> episodes = page.getList();
|
||||
Map<Long, Long> commentCounts = commentService.countByEpisodes(
|
||||
episodes.stream().map(EpisodeRespVO::getId).toList());
|
||||
Drama drama = dramaService.getExisting(dramaId);
|
||||
@@ -53,7 +57,7 @@ public class EpisodeController {
|
||||
episode.setFavoriteCount(drama.getFavoriteCount());
|
||||
episode.setHeat(drama.getViewCount());
|
||||
});
|
||||
return Result.ok(episodes);
|
||||
return Result.ok(new PageResult<>(page.getTotal(), episodes));
|
||||
}
|
||||
|
||||
@Operation(summary = "新建剧集")
|
||||
|
||||
+101
-16
@@ -3,6 +3,7 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.admin.support.ControllerContractSupport;
|
||||
import com.fruitshorts.common.pojo.PageResult;
|
||||
import com.fruitshorts.content.dal.entity.Drama;
|
||||
import com.fruitshorts.content.service.DramaService;
|
||||
import com.fruitshorts.content.service.EpisodeService;
|
||||
@@ -10,20 +11,30 @@ import com.fruitshorts.content.vo.EpisodeRespVO;
|
||||
import com.fruitshorts.interaction.service.CommentService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/** K89:后台剧集列表按集回填点赞/评论,并带所属剧收藏/热度。 */
|
||||
/** 后台剧集列表:互动数量回填 + 分页契约。 */
|
||||
class EpisodeControllerContractTest {
|
||||
|
||||
private static final long DRAMA_ID = 5L;
|
||||
private static final int DEFAULT_PAGE_SIZE = 100;
|
||||
|
||||
private EpisodeService episodeService;
|
||||
private CommentService commentService;
|
||||
private DramaService dramaService;
|
||||
@@ -36,34 +47,108 @@ class EpisodeControllerContractTest {
|
||||
dramaService = mock(DramaService.class);
|
||||
mockMvc = ControllerContractSupport.mockMvcOf(
|
||||
new EpisodeController(episodeService, commentService, dramaService));
|
||||
Drama drama = new Drama();
|
||||
drama.setFavoriteCount(88L);
|
||||
drama.setViewCount(1000L);
|
||||
given(dramaService.getExisting(DRAMA_ID)).willReturn(drama);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_return_episode_and_drama_interaction_counts() throws Exception {
|
||||
given(episodeService.listByDrama(5L, null)).willReturn(List.of(
|
||||
episode(11L, 10L),
|
||||
episode(12L, 20L)));
|
||||
given(episodeService.pageByDrama(eq(DRAMA_ID), isNull(), isNull(), isNull()))
|
||||
.willReturn(new PageResult<>(2L, List.of(episode(11L, 10L), episode(12L, 20L))));
|
||||
given(commentService.countByEpisodes(List.of(11L, 12L)))
|
||||
.willReturn(Map.of(11L, 3L));
|
||||
Drama drama = new Drama();
|
||||
drama.setFavoriteCount(88L);
|
||||
drama.setViewCount(1000L);
|
||||
given(dramaService.getExisting(5L)).willReturn(drama);
|
||||
|
||||
mockMvc.perform(get("/admin/episodes").param("dramaId", "5"))
|
||||
mockMvc.perform(get("/admin/episodes").param("dramaId", String.valueOf(DRAMA_ID)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data[0].likeCount").value("10"))
|
||||
.andExpect(jsonPath("$.data[0].commentCount").value("3"))
|
||||
.andExpect(jsonPath("$.data[0].favoriteCount").value("88"))
|
||||
.andExpect(jsonPath("$.data[0].heat").value("1000"))
|
||||
.andExpect(jsonPath("$.data[1].likeCount").value("20"))
|
||||
.andExpect(jsonPath("$.data[1].commentCount").value("0"));
|
||||
.andExpect(jsonPath("$.data.total").value(2))
|
||||
.andExpect(jsonPath("$.data.list[0].likeCount").value("10"))
|
||||
.andExpect(jsonPath("$.data.list[0].commentCount").value("3"))
|
||||
.andExpect(jsonPath("$.data.list[0].favoriteCount").value("88"))
|
||||
.andExpect(jsonPath("$.data.list[0].heat").value("1000"))
|
||||
.andExpect(jsonPath("$.data.list[1].likeCount").value("20"))
|
||||
.andExpect(jsonPath("$.data.list[1].commentCount").value("0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_use_default_page_size_100_when_page_size_omitted() throws Exception {
|
||||
given(episodeService.pageByDrama(eq(DRAMA_ID), isNull(), isNull(), isNull()))
|
||||
.willReturn(PageResult.empty());
|
||||
given(commentService.countByEpisodes(List.of())).willReturn(Map.of());
|
||||
|
||||
mockMvc.perform(get("/admin/episodes").param("dramaId", String.valueOf(DRAMA_ID)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.total").value(0))
|
||||
.andExpect(jsonPath("$.data.list").isArray())
|
||||
.andExpect(jsonPath("$.data.list").isEmpty());
|
||||
|
||||
ArgumentCaptor<Integer> pageIndexCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||
ArgumentCaptor<Integer> pageSizeCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||
verify(episodeService).pageByDrama(
|
||||
eq(DRAMA_ID), isNull(), pageIndexCaptor.capture(), pageSizeCaptor.capture());
|
||||
assertThat(pageIndexCaptor.getValue()).isNull();
|
||||
assertThat(pageSizeCaptor.getValue()).isNull();
|
||||
assertThat(DEFAULT_PAGE_SIZE).isEqualTo(100);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_return_non_overlapping_ids_when_second_page_requested() throws Exception {
|
||||
List<EpisodeRespVO> page1 = List.of(episode(1L, 1L), episode(2L, 2L));
|
||||
List<EpisodeRespVO> page2 = List.of(episode(3L, 3L), episode(4L, 4L));
|
||||
given(episodeService.pageByDrama(DRAMA_ID, null, 1, 2))
|
||||
.willReturn(new PageResult<>(4L, page1));
|
||||
given(episodeService.pageByDrama(DRAMA_ID, null, 2, 2))
|
||||
.willReturn(new PageResult<>(4L, page2));
|
||||
given(commentService.countByEpisodes(List.of(1L, 2L))).willReturn(Map.of());
|
||||
given(commentService.countByEpisodes(List.of(3L, 4L))).willReturn(Map.of());
|
||||
|
||||
mockMvc.perform(get("/admin/episodes")
|
||||
.param("dramaId", String.valueOf(DRAMA_ID))
|
||||
.param("pageIndex", "1")
|
||||
.param("pageSize", "2"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.total").value(4))
|
||||
.andExpect(jsonPath("$.data.list.length()").value(2));
|
||||
|
||||
String page2Body = mockMvc.perform(get("/admin/episodes")
|
||||
.param("dramaId", String.valueOf(DRAMA_ID))
|
||||
.param("pageIndex", "2")
|
||||
.param("pageSize", "2"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.total").value(4))
|
||||
.andExpect(jsonPath("$.data.list[0].id").value("3"))
|
||||
.andExpect(jsonPath("$.data.list[1].id").value("4"))
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getContentAsString();
|
||||
|
||||
Set<Long> page1Ids = page1.stream().map(EpisodeRespVO::getId).collect(Collectors.toSet());
|
||||
Set<Long> page2Ids = page2.stream().map(EpisodeRespVO::getId).collect(Collectors.toSet());
|
||||
assertThat(page1Ids).doesNotContainAnyElementsOf(page2Ids);
|
||||
assertThat(page2Body).contains("\"id\":\"3\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_return_empty_list_with_correct_total_when_page_out_of_range() throws Exception {
|
||||
given(episodeService.pageByDrama(DRAMA_ID, null, 99, 100))
|
||||
.willReturn(new PageResult<>(5L, List.of()));
|
||||
given(commentService.countByEpisodes(List.of())).willReturn(Map.of());
|
||||
|
||||
mockMvc.perform(get("/admin/episodes")
|
||||
.param("dramaId", String.valueOf(DRAMA_ID))
|
||||
.param("pageIndex", "99")
|
||||
.param("pageSize", "100"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.total").value(5))
|
||||
.andExpect(jsonPath("$.data.list").isArray())
|
||||
.andExpect(jsonPath("$.data.list").isEmpty());
|
||||
}
|
||||
|
||||
private EpisodeRespVO episode(Long id, Long likeCount) {
|
||||
EpisodeRespVO episode = new EpisodeRespVO();
|
||||
episode.setId(id);
|
||||
episode.setDramaId(5L);
|
||||
episode.setDramaId(DRAMA_ID);
|
||||
episode.setLikeCount(likeCount);
|
||||
return episode;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user