调整 音频合成, 头衔监测

This commit is contained in:
spllzh
2025-10-06 23:16:59 +08:00
parent 20378e8115
commit 76dedb657a
36 changed files with 1732 additions and 12 deletions

View File

@@ -0,0 +1,265 @@
package com.rj.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import java.nio.charset.StandardCharsets;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
/**
* 头衔上传接口测试
* 测试 FaceDetectController 中的头衔上传功能
*
* @author rj
* @date 2025-01-02
*/
@SpringBootTest
@AutoConfigureWebMvc
@TestPropertySource(properties = {
"minio.endpoint=http://101.35.52.237:19005",
"minio.access-key=minioadmin",
"minio.secret-key=minioadmin",
"minio.bucket-name=car",
"dashscope.api.key=${DASHSCOPE_API_KEY:test-key}"
})
@Slf4j
public class FaceDetectAvatarUploadTest {
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@org.junit.jupiter.api.BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
/**
* 测试头衔上传接口 - 正常情况
*/
@Test
void testAvatarUpload_Success() throws Exception {
log.info("=== 测试头衔上传接口 - 正常情况 ===");
// 1. 创建测试图片文件
String testContent = "这是一个测试图片文件内容";
MockMultipartFile testFile = new MockMultipartFile(
"file",
"test-avatar.jpg",
"image/jpeg",
testContent.getBytes(StandardCharsets.UTF_8)
);
// 2. 调用头衔上传接口
MvcResult result = mockMvc.perform(multipart("/api/face-detect/avatar/upload")
.file(testFile)
.param("userId", "test-user-123")
.param("expiresInSeconds", "3600"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
String responseContent = result.getResponse().getContentAsString();
log.info("头衔上传响应: {}", responseContent);
// 3. 验证响应内容
assertNotNull(responseContent);
assertTrue(responseContent.contains("\"success\":true"));
assertTrue(responseContent.contains("\"originalFileName\":\"test-avatar.jpg\""));
assertTrue(responseContent.contains("\"fileUrl\""));
assertTrue(responseContent.contains("\"shortUrl\""));
assertTrue(responseContent.contains("\"faceDetection\""));
assertTrue(responseContent.contains("\"userId\":\"test-user-123\""));
}
/**
* 测试头衔上传接口 - 空文件
*/
@Test
void testAvatarUpload_EmptyFile() throws Exception {
log.info("=== 测试头衔上传接口 - 空文件 ===");
MockMultipartFile emptyFile = new MockMultipartFile(
"file",
"empty.jpg",
"image/jpeg",
new byte[0]
);
MvcResult result = mockMvc.perform(multipart("/api/face-detect/avatar/upload")
.file(emptyFile))
.andExpect(status().isBadRequest())
.andReturn();
String responseContent = result.getResponse().getContentAsString();
log.info("空文件上传响应: {}", responseContent);
assertTrue(responseContent.contains("\"success\":false"));
assertTrue(responseContent.contains("文件不能为空"));
}
/**
* 测试头衔上传接口 - 非图片文件
*/
@Test
void testAvatarUpload_NonImageFile() throws Exception {
log.info("=== 测试头衔上传接口 - 非图片文件 ===");
MockMultipartFile nonImageFile = new MockMultipartFile(
"file",
"test.txt",
"text/plain",
"这是一个文本文件".getBytes(StandardCharsets.UTF_8)
);
MvcResult result = mockMvc.perform(multipart("/api/face-detect/avatar/upload")
.file(nonImageFile))
.andExpect(status().isBadRequest())
.andReturn();
String responseContent = result.getResponse().getContentAsString();
log.info("非图片文件上传响应: {}", responseContent);
assertTrue(responseContent.contains("\"success\":false"));
assertTrue(responseContent.contains("只支持图片文件格式"));
}
/**
* 测试头衔上传接口 - 大文件
*/
@Test
void testAvatarUpload_LargeFile() throws Exception {
log.info("=== 测试头衔上传接口 - 大文件 ===");
// 创建一个51MB的文件超过50MB限制
byte[] largeContent = new byte[51 * 1024 * 1024];
MockMultipartFile largeFile = new MockMultipartFile(
"file",
"large-image.jpg",
"image/jpeg",
largeContent
);
MvcResult result = mockMvc.perform(multipart("/api/face-detect/avatar/upload")
.file(largeFile))
.andExpect(status().isBadRequest())
.andReturn();
String responseContent = result.getResponse().getContentAsString();
log.info("大文件上传响应: {}", responseContent);
assertTrue(responseContent.contains("\"success\":false"));
assertTrue(responseContent.contains("文件大小不能超过50MB"));
}
/**
* 测试头衔上传接口 - 不同过期时间
*/
@Test
void testAvatarUpload_DifferentExpires() throws Exception {
log.info("=== 测试头衔上传接口 - 不同过期时间 ===");
String testContent = "测试图片内容";
MockMultipartFile testFile = new MockMultipartFile(
"file",
"test-expires.jpg",
"image/jpeg",
testContent.getBytes(StandardCharsets.UTF_8)
);
// 测试5分钟过期时间
MvcResult result = mockMvc.perform(multipart("/api/face-detect/avatar/upload")
.file(testFile)
.param("expiresInSeconds", "300"))
.andExpect(status().isOk())
.andReturn();
String responseContent = result.getResponse().getContentAsString();
log.info("5分钟过期时间响应: {}", responseContent);
assertTrue(responseContent.contains("\"success\":true"));
assertTrue(responseContent.contains("\"shortUrlExpiresInSeconds\":300"));
}
/**
* 测试头衔上传接口 - 带用户ID
*/
@Test
void testAvatarUpload_WithUserId() throws Exception {
log.info("=== 测试头衔上传接口 - 带用户ID ===");
String testContent = "测试图片内容";
MockMultipartFile testFile = new MockMultipartFile(
"file",
"test-user.jpg",
"image/jpeg",
testContent.getBytes(StandardCharsets.UTF_8)
);
MvcResult result = mockMvc.perform(multipart("/api/face-detect/avatar/upload")
.file(testFile)
.param("userId", "user-12345")
.param("expiresInSeconds", "7200"))
.andExpect(status().isOk())
.andReturn();
String responseContent = result.getResponse().getContentAsString();
log.info("带用户ID上传响应: {}", responseContent);
assertTrue(responseContent.contains("\"success\":true"));
assertTrue(responseContent.contains("\"userId\":\"user-12345\""));
assertTrue(responseContent.contains("\"shortUrlExpiresInSeconds\":7200"));
}
/**
* 测试头衔上传接口 - 验证返回的数据结构
*/
@Test
void testAvatarUpload_ResponseStructure() throws Exception {
log.info("=== 测试头衔上传接口 - 验证返回的数据结构 ===");
String testContent = "测试图片内容";
MockMultipartFile testFile = new MockMultipartFile(
"file",
"structure-test.jpg",
"image/jpeg",
testContent.getBytes(StandardCharsets.UTF_8)
);
MvcResult result = mockMvc.perform(multipart("/api/face-detect/avatar/upload")
.file(testFile)
.param("userId", "structure-test-user"))
.andExpect(status().isOk())
.andReturn();
String responseContent = result.getResponse().getContentAsString();
log.info("数据结构测试响应: {}", responseContent);
// 验证必要的字段存在
assertTrue(responseContent.contains("\"success\""));
assertTrue(responseContent.contains("\"message\""));
assertTrue(responseContent.contains("\"originalFileName\""));
assertTrue(responseContent.contains("\"fileSize\""));
assertTrue(responseContent.contains("\"fileUrl\""));
assertTrue(responseContent.contains("\"shortUrl\""));
assertTrue(responseContent.contains("\"shortUrlExpiresAt\""));
assertTrue(responseContent.contains("\"shortUrlExpiresInSeconds\""));
assertTrue(responseContent.contains("\"userId\""));
assertTrue(responseContent.contains("\"faceDetection\""));
}
}

View File

@@ -0,0 +1,241 @@
package com.rj.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rj.service.MinIOService;
import com.rj.utils.MinIOUrlGenerator;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
/**
* MinIO 临时URL接口测试
* 测试 generateTempUrlWithExpires 接口的功能
*
* @author rj
* @date 2025-01-02
*/
@SpringBootTest
@AutoConfigureWebMvc
@TestPropertySource(properties = {
"minio.endpoint=http://101.35.52.237:19005",
"minio.access-key=minioadmin",
"minio.secret-key=minioadmin",
"minio.bucket-name=car"
})
@Slf4j
public class MinIOControllerTempUrlTest {
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
private MinIOService minioService;
@Autowired
private MinIOUrlGenerator urlGenerator;
private MockMvc mockMvc;
private ObjectMapper objectMapper = new ObjectMapper();
@org.junit.jupiter.api.BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
/**
* 测试生成临时URL接口 - 正常情况
*/
@Test
void testGenerateTempUrlWithExpires_Success() throws Exception {
// 1. 先上传一个测试文件
MinIOUrlGenerator.UrlInfo urlInfo = urlGenerator.generateTempUrl("微信图片_20251005120205_56_49.jpg");
log.info("临时url "+urlInfo.toString());
}
/**
* 测试生成临时URL接口 - 文件不存在
*/
@Test
void testGenerateTempUrlWithExpires_FileNotFound() throws Exception {
String nonExistentFile = "non-existent-file-" + System.currentTimeMillis() + ".txt";
int expiresInSeconds = 300;
MvcResult result = mockMvc.perform(get("/minio/temp-url/{fileName}/{expiresInSeconds}",
nonExistentFile, expiresInSeconds))
.andExpect(status().isOk()) // 接口返回200但success为false
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
String responseContent = result.getResponse().getContentAsString();
System.out.println("文件不存在时的响应: " + responseContent);
// 验证响应内容
assertNotNull(responseContent);
assertTrue(responseContent.contains("\"success\":false"));
}
/**
* 测试生成临时URL接口 - 过期时间超出范围
*/
@Test
void testGenerateTempUrlWithExpires_InvalidExpires() throws Exception {
// 先上传一个测试文件
String testFileName = "test-invalid-expires-" + System.currentTimeMillis() + ".txt";
String testContent = "测试文件";
MockMultipartFile testFile = new MockMultipartFile(
"file",
testFileName,
"text/plain",
testContent.getBytes(StandardCharsets.UTF_8)
);
// 上传文件
mockMvc.perform(multipart("/minio/upload")
.file(testFile))
.andExpect(status().isOk());
// 测试过期时间过短小于60秒
MvcResult result1 = mockMvc.perform(get("/minio/temp-url/{fileName}/{expiresInSeconds}",
testFileName, 30)) // 30秒小于最小值60秒
.andExpect(status().isBadRequest())
.andReturn();
System.out.println("过期时间过短的响应: " + result1.getResponse().getContentAsString());
// 测试过期时间过长超过7天
MvcResult result2 = mockMvc.perform(get("/minio/temp-url/{fileName}/{expiresInSeconds}",
testFileName, 604801)) // 超过7天
.andExpect(status().isBadRequest())
.andReturn();
System.out.println("过期时间过长的响应: " + result2.getResponse().getContentAsString());
// 清理测试文件
minioService.deleteFile(testFileName);
}
/**
* 测试边界值 - 最小和最大过期时间
*/
@Test
void testGenerateTempUrlWithExpires_BoundaryValues() throws Exception {
// 先上传一个测试文件
String testFileName = "test-boundary-" + System.currentTimeMillis() + ".txt";
String testContent = "边界值测试文件";
MockMultipartFile testFile = new MockMultipartFile(
"file",
testFileName,
"text/plain",
testContent.getBytes(StandardCharsets.UTF_8)
);
// 上传文件
mockMvc.perform(multipart("/minio/upload")
.file(testFile))
.andExpect(status().isOk());
// 测试最小过期时间60秒
MvcResult result1 = mockMvc.perform(get("/minio/temp-url/{fileName}/{expiresInSeconds}",
testFileName, 60))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andReturn();
System.out.println("最小过期时间测试: " + result1.getResponse().getContentAsString());
// 测试最大过期时间7天
MvcResult result2 = mockMvc.perform(get("/minio/temp-url/{fileName}/{expiresInSeconds}",
testFileName, 604800))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andReturn();
System.out.println("最大过期时间测试: " + result2.getResponse().getContentAsString());
// 清理测试文件
minioService.deleteFile(testFileName);
}
/**
* 从响应中提取临时URL
*/
private String extractTempUrlFromResponse(String responseContent) {
try {
// 简单的JSON解析来提取tempUrl
int startIndex = responseContent.indexOf("\"tempUrl\":\"");
if (startIndex != -1) {
startIndex += 11; // 跳过 "tempUrl":"
int endIndex = responseContent.indexOf("\"", startIndex);
if (endIndex != -1) {
return responseContent.substring(startIndex, endIndex);
}
}
} catch (Exception e) {
System.err.println("提取临时URL失败: " + e.getMessage());
}
return null;
}
/**
* 测试临时URL的可访问性
*/
private void testTempUrlAccessibility(String tempUrl) {
try {
System.out.println("测试临时URL可访问性: " + tempUrl);
URL url = new URL(tempUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000); // 10秒超时
connection.setReadTimeout(10000);
int responseCode = connection.getResponseCode();
System.out.println("临时URL响应码: " + responseCode);
if (responseCode == 200) {
System.out.println("✅ 临时URL可以正常访问");
// 读取响应内容验证
InputStream inputStream = connection.getInputStream();
byte[] buffer = new byte[1024];
int bytesRead = inputStream.read(buffer);
if (bytesRead > 0) {
String content = new String(buffer, 0, bytesRead, StandardCharsets.UTF_8);
System.out.println("文件内容预览: " + content.substring(0, Math.min(100, content.length())));
}
inputStream.close();
} else {
System.out.println("❌ 临时URL无法访问响应码: " + responseCode);
}
connection.disconnect();
} catch (Exception e) {
System.err.println("测试临时URL访问失败: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,213 @@
package com.rj.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rj.dto.VideoSynthesisRequestDto;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
/**
* 视频合成接口测试
*
* @author rj
* @date 2025-01-02
*/
@SpringBootTest
@AutoConfigureWebMvc
@TestPropertySource(properties = {
"dashscope.api.key=${DASHSCOPE_API_KEY:test-key}"
})
@Slf4j
public class VideoSynthesisControllerTest {
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
private ObjectMapper objectMapper;
private MockMvc mockMvc;
@org.junit.jupiter.api.BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
/**
* 测试视频合成接口 - 正常情况
*/
@Test
void testSynthesizeVideo_Success() throws Exception {
log.info("=== 测试视频合成接口 - 正常情况 ===");
// 构建请求参数
VideoSynthesisRequestDto requestDto = new VideoSynthesisRequestDto();
requestDto.setImageUrl("https://example.com/test-image.jpg");
requestDto.setAudioUrl("https://example.com/test-audio.wav");
requestDto.setImageId("img-12345");
requestDto.setAudioId("audio-67890");
requestDto.setOwnerName("张三");
requestDto.setOwnerPhone("13800138000");
requestDto.setModelProvider("dashscope");
requestDto.setTemplateId("normal");
requestDto.setEyeMoveFreq(java.math.BigDecimal.valueOf(0.5));
requestDto.setVideoFps(30);
requestDto.setMouthMoveStrength(java.math.BigDecimal.valueOf(1.0));
requestDto.setPasteBack(true);
requestDto.setHeadMoveStrength(java.math.BigDecimal.valueOf(0.7));
MvcResult result = mockMvc.perform(post("/api/video-synthesis/synthesize")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(requestDto)))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
String responseContent = result.getResponse().getContentAsString();
log.info("视频合成响应: {}", responseContent);
// 验证响应内容
assertNotNull(responseContent);
assertTrue(responseContent.contains("\"requestId\""));
assertTrue(responseContent.contains("\"taskId\""));
assertTrue(responseContent.contains("\"taskStatus\""));
}
/**
* 测试视频合成接口 - 缺少必需参数
*/
@Test
void testSynthesizeVideo_MissingRequiredParams() throws Exception {
log.info("=== 测试视频合成接口 - 缺少必需参数 ===");
// 测试缺少图片URL
VideoSynthesisRequestDto requestDto1 = new VideoSynthesisRequestDto();
requestDto1.setAudioUrl("https://example.com/test-audio.wav");
MvcResult result1 = mockMvc.perform(post("/api/video-synthesis/synthesize")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(requestDto1)))
.andExpect(status().isBadRequest())
.andReturn();
log.info("缺少图片URL响应: {}", result1.getResponse().getContentAsString());
// 测试缺少音频URL
VideoSynthesisRequestDto requestDto2 = new VideoSynthesisRequestDto();
requestDto2.setImageUrl("https://example.com/test-image.jpg");
MvcResult result2 = mockMvc.perform(post("/api/video-synthesis/synthesize")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(requestDto2)))
.andExpect(status().isBadRequest())
.andReturn();
log.info("缺少音频URL响应: {}", result2.getResponse().getContentAsString());
}
/**
* 测试查询合成结果接口
*/
@Test
void testGetSynthesisResult() throws Exception {
log.info("=== 测试查询合成结果接口 ===");
String testRequestId = "test-request-id-12345";
MvcResult result = mockMvc.perform(get("/api/video-synthesis/result/{requestId}", testRequestId))
.andExpect(status().isNotFound()) // 由于测试数据不存在应该返回404
.andReturn();
String responseContent = result.getResponse().getContentAsString();
log.info("查询合成结果响应: {}", responseContent);
}
/**
* 测试根据任务ID查询结果接口
*/
@Test
void testGetSynthesisResultByTaskId() throws Exception {
log.info("=== 测试根据任务ID查询结果接口 ===");
String testTaskId = "test-task-id-12345";
MvcResult result = mockMvc.perform(get("/api/video-synthesis/result/task/{taskId}", testTaskId))
.andExpect(status().isNotFound()) // 由于测试数据不存在应该返回404
.andReturn();
String responseContent = result.getResponse().getContentAsString();
log.info("根据任务ID查询结果响应: {}", responseContent);
}
/**
* 测试视频合成接口 - 使用默认参数
*/
@Test
void testSynthesizeVideo_WithDefaultParams() throws Exception {
log.info("=== 测试视频合成接口 - 使用默认参数 ===");
// 构建请求参数(只设置必需参数,其他使用默认值)
VideoSynthesisRequestDto requestDto = new VideoSynthesisRequestDto();
requestDto.setImageUrl("https://example.com/test-image.jpg");
requestDto.setAudioUrl("https://example.com/test-audio.wav");
MvcResult result = mockMvc.perform(post("/api/video-synthesis/synthesize")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(requestDto)))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
String responseContent = result.getResponse().getContentAsString();
log.info("使用默认参数响应: {}", responseContent);
// 验证响应内容
assertNotNull(responseContent);
assertTrue(responseContent.contains("\"requestId\""));
}
/**
* 测试视频合成接口 - 自定义参数
*/
@Test
void testSynthesizeVideo_WithCustomParams() throws Exception {
log.info("=== 测试视频合成接口 - 自定义参数 ===");
// 构建自定义参数
VideoSynthesisRequestDto requestDto = new VideoSynthesisRequestDto();
requestDto.setImageUrl("https://example.com/custom-image.jpg");
requestDto.setAudioUrl("https://example.com/custom-audio.wav");
requestDto.setTemplateId("custom");
requestDto.setEyeMoveFreq(java.math.BigDecimal.valueOf(0.8));
requestDto.setVideoFps(25);
requestDto.setMouthMoveStrength(java.math.BigDecimal.valueOf(1.2));
requestDto.setPasteBack(false);
requestDto.setHeadMoveStrength(java.math.BigDecimal.valueOf(0.9));
MvcResult result = mockMvc.perform(post("/api/video-synthesis/synthesize")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(requestDto)))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
String responseContent = result.getResponse().getContentAsString();
log.info("自定义参数响应: {}", responseContent);
// 验证响应内容
assertNotNull(responseContent);
assertTrue(responseContent.contains("\"requestId\""));
}
}

View File

@@ -0,0 +1,141 @@
package com.rj.service;
import com.rj.entity.TtsRequestLog;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.LocalDateTime;
/**
* TTS请求日志短链接设置测试
*
* @author rj
* @date 2025-01-02
*/
@Slf4j
@SpringBootTest
public class TtsRequestLogShortUrlTest {
@Autowired
private ITtsRequestLogService ttsRequestLogService;
/**
* 测试根据音频名称设置短链接默认15分钟
*/
@Test
public void testSetShortUrlByAudioNameDefault() {
try {
String audioName = "test_audio_20250102_150000_12345.mp3";
log.info("开始测试根据音频名称设置短链接默认15分钟...");
log.info("音频名称: {}", audioName);
// 先创建一个测试日志记录
TtsRequestLog requestLog = createTestRequestLog(audioName);
boolean saveResult = ttsRequestLogService.saveTtsRequestLog(requestLog);
if (saveResult) {
log.info("测试日志记录保存成功ID: {}", requestLog.getId());
// 测试设置短链接
boolean result = ttsRequestLogService.setShortUrlByAudioName(audioName);
if (result) {
log.info("短链接设置成功!");
// 查询验证
TtsRequestLog updatedLog = ttsRequestLogService.getTtsRequestLogById(requestLog.getId());
if (updatedLog != null) {
log.info("验证结果:");
log.info(" 音频名称: {}", updatedLog.getAudioName());
log.info(" 短链接: {}", updatedLog.getShortUrl());
log.info(" 过期时间: {}", updatedLog.getShortUrlExpireTime());
}
} else {
log.error("短链接设置失败");
}
} else {
log.error("测试日志记录保存失败");
}
} catch (Exception e) {
log.error("测试过程中发生异常: {}", e.getMessage(), e);
}
}
/**
* 测试不存在的音频名称
*/
@Test
public void testSetShortUrlByNonExistentAudioName() {
try {
String audioName = "non_existent_audio.mp3";
log.info("开始测试不存在的音频名称...");
log.info("音频名称: {}", audioName);
// 测试设置短链接
boolean result = ttsRequestLogService.setShortUrlByAudioName(audioName);
if (result) {
log.error("意外成功:不存在的音频名称不应该设置成功");
} else {
log.info("测试通过:不存在的音频名称正确返回失败");
}
} catch (Exception e) {
log.error("测试过程中发生异常: {}", e.getMessage(), e);
}
}
/**
* 测试空音频名称
*/
@Test
public void testSetShortUrlByEmptyAudioName() {
try {
String audioName = "";
log.info("开始测试空音频名称...");
log.info("音频名称: '{}'", audioName);
// 测试设置短链接
boolean result = ttsRequestLogService.setShortUrlByAudioName(audioName);
if (result) {
log.error("意外成功:空音频名称不应该设置成功");
} else {
log.info("测试通过:空音频名称正确返回失败");
}
} catch (Exception e) {
log.error("测试过程中发生异常: {}", e.getMessage(), e);
}
}
/**
* 创建测试用的TTS请求日志
*/
private TtsRequestLog createTestRequestLog(String audioName) {
TtsRequestLog requestLog = new TtsRequestLog();
requestLog.setRequestTime(LocalDateTime.now());
requestLog.setModel("fnlp/MOSS-TTSD-v0.5");
requestLog.setInputText("测试音频文件");
requestLog.setInputLength(6);
requestLog.setVoice("fnlp/MOSS-TTSD-v0.5:claire");
requestLog.setStatus("SUCCESS");
requestLog.setAudioName(audioName);
requestLog.setMinioUrl("http://localhost:9000/audio/" + audioName);
requestLog.setCreatorName("测试用户");
requestLog.setCreatorPhone("13800138000");
requestLog.setCreateTime(LocalDateTime.now());
requestLog.setUpdateTime(LocalDateTime.now());
return requestLog;
}
}

View File

@@ -0,0 +1,114 @@
package com.rj.service;
import com.rj.dto.SiliconFlowTtsRequest;
import com.rj.dto.SiliconFlowTtsResponse;
import com.rj.entity.TtsRequestLog;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.LocalDateTime;
/**
* TTS请求日志音频名称字段测试
*
* @author rj
* @date 2025-01-02
*/
@Slf4j
@SpringBootTest
public class TtsRequestLogWithAudioNameTest {
@Autowired
private ITtsRequestLogService ttsRequestLogService;
@Autowired
private SiliconFlowTtsService siliconFlowTtsService;
/**
* 测试TTS请求并验证音频名称字段
*/
@Test
public void testTtsRequestWithAudioName() {
try {
// 创建TTS请求
SiliconFlowTtsRequest request = new SiliconFlowTtsRequest();
request.setInput("这是一个测试音频文件,用于验证音频名称字段功能。");
request.setModel("fnlp/MOSS-TTSD-v0.5");
request.setVoice("fnlp/MOSS-TTSD-v0.5:claire");
request.setCreatorName("测试用户");
request.setCreatorPhone("13800138000");
log.info("开始TTS请求测试...");
log.info("请求参数: 模型={}, 语音={}, 输入文本={}",
request.getModel(), request.getVoice(), request.getInput());
// 执行TTS请求
SiliconFlowTtsResponse response = siliconFlowTtsService.textToSpeech(request);
if (response.isSuccess()) {
log.info("TTS请求成功");
log.info("响应信息: 格式={}, 采样率={}, 时长={}秒",
response.getFormat(), response.getSampleRate(), response.getDuration());
log.info("MinIO URL: {}", response.getMinioUrl());
log.info("临时URL: {}", response.getShortUrl());
// 验证音频名称字段是否正确保存
// 注意这里需要根据实际的日志ID来查询实际使用时可能需要调整
log.info("请检查数据库中的 tts_request_log 表,确认 audio_name 字段是否正确保存");
} else {
log.error("TTS请求失败: {}", response.getMessage());
}
} catch (Exception e) {
log.error("测试过程中发生异常: {}", e.getMessage(), e);
}
}
/**
* 测试手动创建TTS请求日志并设置音频名称
*/
@Test
public void testManualTtsRequestLogWithAudioName() {
try {
// 创建测试日志
TtsRequestLog requestLog = new TtsRequestLog();
requestLog.setRequestTime(LocalDateTime.now());
requestLog.setModel("fnlp/MOSS-TTSD-v0.5");
requestLog.setInputText("测试音频文件");
requestLog.setInputLength(6);
requestLog.setVoice("fnlp/MOSS-TTSD-v0.5:claire");
requestLog.setStatus("SUCCESS");
requestLog.setAudioName("test_audio_20250102_120000_12345.mp3");
requestLog.setMinioUrl("http://localhost:9000/audio/test_audio_20250102_120000_12345.mp3");
requestLog.setCreatorName("测试用户");
requestLog.setCreatorPhone("13800138000");
requestLog.setCreateTime(LocalDateTime.now());
requestLog.setUpdateTime(LocalDateTime.now());
// 保存到数据库
boolean result = ttsRequestLogService.saveTtsRequestLog(requestLog);
if (result) {
log.info("TTS请求日志保存成功ID: {}", requestLog.getId());
log.info("音频名称: {}", requestLog.getAudioName());
// 查询验证
TtsRequestLog savedLog = ttsRequestLogService.getTtsRequestLogById(requestLog.getId());
if (savedLog != null) {
log.info("查询验证成功,音频名称: {}", savedLog.getAudioName());
} else {
log.error("查询验证失败,未找到保存的日志");
}
} else {
log.error("TTS请求日志保存失败");
}
} catch (Exception e) {
log.error("手动测试过程中发生异常: {}", e.getMessage(), e);
}
}
}