test(media): 覆盖转码产物查询接口

This commit is contained in:
Zhou Weidong committed 2026-10-22 14:10:15 +08:00
1 parent f66eae5baf
commit 090f149b31
10 files changed
+625

No files matched your search

@@ -0,0 +1,52 @@
// Author: fruit.com.cn
package com.fruitshorts.admin.controller;
import com.fruitshorts.admin.service.DashboardService;
import com.fruitshorts.admin.support.ControllerContractSupport;
import com.fruitshorts.admin.vo.TranscodeDashboardRespVO;
import com.fruitshorts.media.vo.TranscodeQueueStatsVO;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.test.web.servlet.MockMvc;
import java.util.List;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
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;
class DashboardTranscodeContractTest {
private DashboardService dashboardService;
private MockMvc mockMvc;
@BeforeEach
void setUp() {
dashboardService = mock(DashboardService.class);
mockMvc = ControllerContractSupport.mockMvcOf(
new DashboardAdminController(dashboardService));
}
@Test
void should_return_typed_queue_and_failed_tasks() throws Exception {
TranscodeQueueStatsVO queue = new TranscodeQueueStatsVO(
10L, 2L, 1L, 5L, 1L, 1L, 20L);
TranscodeDashboardRespVO vo = new TranscodeDashboardRespVO();
vo.setQueue(queue);
vo.setFailedTasks(List.of());
vo.setNotes(List.of("queue total"));
given(dashboardService.transcode()).willReturn(vo);
mockMvc.perform(get("/admin/dashboard/transcode"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.queue.total").value(10))
.andExpect(jsonPath("$.data.queue.queued").value(2))
.andExpect(jsonPath("$.data.queue.running").value(1))
.andExpect(jsonPath("$.data.queue.success").value(5))
.andExpect(jsonPath("$.data.queue.failed").value(1))
.andExpect(jsonPath("$.data.failedTasks").isArray());
}
}
@@ -0,0 +1,61 @@
// Author: fruit.com.cn
package com.fruitshorts.admin.controller;
import com.fruitshorts.admin.service.EpisodeTranscodeAdminService;
import com.fruitshorts.admin.support.ControllerContractSupport;
import com.fruitshorts.admin.vo.EpisodeTranscodeRespVO;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
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;
class EpisodeTranscodeContractTest {
private EpisodeTranscodeAdminService service;
private MockMvc mockMvc;
@BeforeEach
void setUp() {
service = mock(EpisodeTranscodeAdminService.class);
mockMvc = ControllerContractSupport.mockMvcOf(
new EpisodeTranscodeController(service));
}
@Test
void should_return_aggregated_episode_transcode_state() throws Exception {
EpisodeTranscodeRespVO vo = new EpisodeTranscodeRespVO();
vo.setEpisodeId(31L);
vo.setMediaAssetId(88L);
vo.setTaskId(8L);
vo.setStatus("SUCCESS");
vo.setProgress(100);
given(service.detail(31L)).willReturn(vo);
mockMvc.perform(get("/admin/episodes/31/transcode"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(0))
.andExpect(jsonPath("$.data.episodeId").value("31"))
.andExpect(jsonPath("$.data.mediaAssetId").value("88"))
.andExpect(jsonPath("$.data.status").value("SUCCESS"))
.andExpect(jsonPath("$.data.progress").value(100));
}
@Test
void should_return_explicit_empty_state_when_episode_has_no_video() throws Exception {
EpisodeTranscodeRespVO vo = new EpisodeTranscodeRespVO();
vo.setEpisodeId(31L);
vo.setStatus("NO_VIDEO");
given(service.detail(31L)).willReturn(vo);
mockMvc.perform(get("/admin/episodes/31/transcode"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.status").value("NO_VIDEO"))
.andExpect(jsonPath("$.data.renditions").isEmpty());
}
}
@@ -0,0 +1,90 @@
// Author: fruit.com.cn
package com.fruitshorts.admin.controller;
import com.fruitshorts.admin.support.ControllerContractSupport;
import com.fruitshorts.common.exception.ErrorCode;
import com.fruitshorts.common.exception.ServiceException;
import com.fruitshorts.common.pojo.PageResult;
import com.fruitshorts.media.service.MediaTranscodeOutputService;
import com.fruitshorts.media.vo.MediaRenditionRespVO;
import com.fruitshorts.media.vo.MediaThumbnailRespVO;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.test.web.servlet.MockMvc;
import java.util.List;
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;
class MediaTranscodeOutputContractTest {
private MediaTranscodeOutputService outputService;
private MockMvc mockMvc;
@BeforeEach
void setUp() {
outputService = mock(MediaTranscodeOutputService.class);
mockMvc = ControllerContractSupport.mockMvcOf(
new MediaTranscodeOutputController(outputService));
}
@Test
void should_return_typed_rendition_list() throws Exception {
MediaRenditionRespVO vo = new MediaRenditionRespVO();
vo.setQuality("1080p");
vo.setQualityName("1080P");
vo.setResolution("1920x1080");
vo.setVideoBitrateKbps(5000);
vo.setVideoCodec("H.264");
vo.setAudioCodec("AAC");
vo.setContainer("HLS");
vo.setHlsUrl("/files/master.m3u8");
vo.setSizeBytes(4096L);
vo.setStatus("ready");
given(outputService.renditions(88L)).willReturn(List.of(vo));
mockMvc.perform(get("/admin/media/88/renditions"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(0))
.andExpect(jsonPath("$.data[0].quality").value("1080p"))
.andExpect(jsonPath("$.data[0].resolution").value("1920x1080"))
.andExpect(jsonPath("$.data[0].videoBitrateKbps").value(5000))
.andExpect(jsonPath("$.data[0].hlsUrl").value("/files/master.m3u8"));
}
@Test
void should_return_not_found_for_missing_media() throws Exception {
given(outputService.renditions(404L))
.willThrow(new ServiceException(ErrorCode.DATA_NOT_FOUND, "媒资不存在"));
mockMvc.perform(get("/admin/media/404/renditions"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(ErrorCode.DATA_NOT_FOUND.getCode()))
.andExpect(jsonPath("$.message").value("媒资不存在"));
}
@Test
void should_return_empty_thumbnail_status_without_error() throws Exception {
MediaThumbnailRespVO vo = new MediaThumbnailRespVO();
vo.setStatus("EMPTY");
vo.setPageIndex(1);
vo.setPageSize(100);
vo.setFrames(PageResult.empty());
given(outputService.thumbnails(88L, 1, 100)).willReturn(vo);
mockMvc.perform(get("/admin/media/88/thumbnails"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(0))
.andExpect(jsonPath("$.data.status").value("EMPTY"))
.andExpect(jsonPath("$.data.frames.total").value(0))
.andExpect(jsonPath("$.data.frames.list").isEmpty());
verify(outputService).thumbnails(88L, 1, 100);
}
}
@@ -0,0 +1,54 @@
// Author: fruit.com.cn
package com.fruitshorts.admin.service;
import com.fruitshorts.content.dal.entity.DramaEpisode;
import com.fruitshorts.content.dal.mapper.DramaEpisodeMapper;
import com.fruitshorts.media.service.MediaTranscodeOutputService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
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.verifyNoInteractions;
class EpisodeTranscodeAdminServiceTest {
private DramaEpisodeMapper episodeMapper;
private MediaTranscodeOutputService outputService;
private EpisodeTranscodeAdminService service;
@BeforeEach
void setUp() {
episodeMapper = mock(DramaEpisodeMapper.class);
outputService = mock(MediaTranscodeOutputService.class);
service = new EpisodeTranscodeAdminService(episodeMapper, outputService);
}
@Test
void should_return_episode_not_found_state_without_aggregating_media() {
given(episodeMapper.selectById(404L)).willReturn(null);
var result = service.detail(404L);
assertThat(result.getStatus()).isEqualTo("EPISODE_NOT_FOUND");
assertThat(result.getEpisodeId()).isEqualTo(404L);
assertThat(result.getRenditions()).isEmpty();
verifyNoInteractions(outputService);
}
@Test
void should_return_no_video_state_when_episode_video_url_is_blank() {
DramaEpisode episode = new DramaEpisode();
episode.setId(31L);
episode.setVideoUrl("");
given(episodeMapper.selectById(31L)).willReturn(episode);
var result = service.detail(31L);
assertThat(result.getStatus()).isEqualTo("NO_VIDEO");
assertThat(result.getRenditions()).isEmpty();
verifyNoInteractions(outputService);
}
}