package com.rongyichuang.judge;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import org.junit.jupiter.api.Test;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
import org.springframework.boot.test.web.server.LocalServerPort;
|
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.MediaType;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
import javax.sql.DataSource;
|
import java.util.Collections;
|
import java.util.List;
|
import java.util.Map;
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
/**
|
* 评委模块正确流程测试
|
* 按照正确的业务流程:
|
* 1. 获取标签列表
|
* 2. 保存评委信息(包含majorIds)
|
* 3. 获取COS上传凭证
|
* 4. 上传头像到COS
|
* 5. 保存媒体记录(关联到评委)
|
* 6. 验证数据完整性
|
*/
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
public class JudgeCorrectFlowTest {
|
|
@LocalServerPort
|
private int port;
|
|
@Autowired
|
private TestRestTemplate restTemplate;
|
|
@Autowired
|
private DataSource dataSource;
|
|
private JdbcTemplate jdbcTemplate;
|
private ObjectMapper objectMapper = new ObjectMapper();
|
|
@Test
|
void testCorrectJudgeCreationFlow() throws Exception {
|
jdbcTemplate = new JdbcTemplate(dataSource);
|
|
System.out.println("=== 开始正确的评委创建流程测试 ===");
|
|
// 步骤1: 获取可用标签列表
|
System.out.println("\n步骤1: 获取标签列表");
|
List<Map<String, Object>> availableTags = getAvailableTags();
|
assertTrue(availableTags.size() > 0, "应该有可用的标签");
|
System.out.println("✓ 获取到 " + availableTags.size() + " 个标签");
|
|
// 步骤2: 保存评委信息(包含majorIds)
|
System.out.println("\n步骤2: 保存评委信息");
|
String judgeId = saveJudgeInfo(availableTags);
|
assertNotNull(judgeId, "评委ID不应为空");
|
System.out.println("✓ 评委保存成功,ID: " + judgeId);
|
|
// 步骤3: 获取COS上传凭证(模拟)
|
System.out.println("\n步骤3: 获取COS上传凭证");
|
Map<String, Object> uploadCredentials = getUploadCredentials();
|
assertNotNull(uploadCredentials, "上传凭证不应为空");
|
System.out.println("✓ 获取上传凭证成功");
|
|
// 步骤4: 模拟上传头像到COS
|
System.out.println("\n步骤4: 上传头像到COS");
|
String cosPath = simulateUploadToCOS(uploadCredentials);
|
assertNotNull(cosPath, "COS路径不应为空");
|
System.out.println("✓ 头像上传到COS成功,路径: " + cosPath);
|
|
// 步骤5: 保存媒体记录(关联到评委)
|
System.out.println("\n步骤5: 保存媒体记录");
|
String mediaId = saveMediaRecord(cosPath, judgeId);
|
assertNotNull(mediaId, "媒体ID不应为空");
|
System.out.println("✓ 媒体记录保存成功,ID: " + mediaId);
|
|
// 步骤6: 验证数据完整性
|
System.out.println("\n步骤6: 验证数据完整性");
|
verifyDataIntegrity(judgeId, mediaId);
|
System.out.println("✓ 数据完整性验证通过");
|
|
System.out.println("\n=== 正确流程测试成功 ===");
|
printTestSummary(judgeId, mediaId);
|
}
|
|
/**
|
* 步骤1: 获取可用标签列表
|
*/
|
private List<Map<String, Object>> getAvailableTags() throws Exception {
|
String query = """
|
query {
|
tagsByCategory(category: "major") {
|
id
|
name
|
code
|
}
|
}
|
""";
|
|
Map<String, String> request = Collections.singletonMap("query", query);
|
String response = postGraphQL(request);
|
|
Map<String, Object> responseMap = objectMapper.readValue(response, Map.class);
|
|
// 检查是否有错误
|
if (responseMap.containsKey("errors")) {
|
System.out.println("GraphQL错误: " + responseMap.get("errors"));
|
throw new RuntimeException("GraphQL查询失败: " + responseMap.get("errors"));
|
}
|
|
Map<String, Object> data = (Map<String, Object>) responseMap.get("data");
|
@SuppressWarnings("unchecked")
|
List<Map<String, Object>> tags = (List<Map<String, Object>>) data.get("tagsByCategory");
|
|
if (tags == null || tags.isEmpty()) {
|
// 如果没有专业标签,获取所有标签
|
String allTagsQuery = """
|
query {
|
tags {
|
id
|
name
|
code
|
}
|
}
|
""";
|
|
Map<String, String> allTagsRequest = Collections.singletonMap("query", allTagsQuery);
|
String allTagsResponse = postGraphQL(allTagsRequest);
|
Map<String, Object> allTagsResponseMap = objectMapper.readValue(allTagsResponse, Map.class);
|
Map<String, Object> allTagsData = (Map<String, Object>) allTagsResponseMap.get("data");
|
|
@SuppressWarnings("unchecked")
|
List<Map<String, Object>> allTags = (List<Map<String, Object>>) allTagsData.get("tags");
|
|
return allTags != null ? allTags.stream().limit(3).toList() : Collections.emptyList();
|
}
|
|
return tags;
|
}
|
|
/**
|
* 步骤2: 保存评委信息(包含majorIds)
|
*/
|
private String saveJudgeInfo(List<Map<String, Object>> availableTags) throws Exception {
|
// 选择前2个标签作为专业标签
|
List<String> selectedTagIds = availableTags.stream()
|
.limit(2)
|
.map(tag -> tag.get("id").toString())
|
.toList();
|
|
String tagIdsStr = "[" + String.join(", ", selectedTagIds) + "]";
|
|
// 使用时间戳生成唯一电话号码
|
String uniquePhone = "139" + String.valueOf(System.currentTimeMillis()).substring(5);
|
|
String mutation = String.format("""
|
mutation {
|
saveJudge(input: {
|
name: "王五"
|
phone: "%s"
|
gender: 1
|
description: "高级技术专家,专注于云计算和大数据领域。"
|
majorIds: %s
|
}) {
|
id
|
name
|
phone
|
gender
|
description
|
specialties {
|
id
|
name
|
code
|
}
|
}
|
}
|
""", uniquePhone, tagIdsStr);
|
|
Map<String, String> request = Collections.singletonMap("query", mutation);
|
String response = postGraphQL(request);
|
|
Map<String, Object> responseMap = objectMapper.readValue(response, Map.class);
|
|
// 检查是否有错误
|
if (responseMap.containsKey("errors")) {
|
System.out.println("GraphQL错误: " + responseMap.get("errors"));
|
throw new RuntimeException("保存评委失败: " + responseMap.get("errors"));
|
}
|
|
@SuppressWarnings("unchecked")
|
Map<String, Object> judgeData = (Map<String, Object>)
|
((Map<String, Object>) responseMap.get("data")).get("saveJudge");
|
|
Object idObj = judgeData.get("id");
|
return idObj != null ? idObj.toString() : null;
|
}
|
|
/**
|
* 步骤3: 获取COS上传凭证(模拟)
|
*/
|
private Map<String, Object> getUploadCredentials() throws Exception {
|
// 这里应该调用实际的获取上传凭证的GraphQL查询
|
// 目前模拟返回凭证信息
|
return Map.of(
|
"secretId", "mock_secret_id",
|
"secretKey", "mock_secret_key",
|
"sessionToken", "mock_session_token",
|
"bucket", "ryc-avatars",
|
"region", "ap-beijing",
|
"expiredTime", System.currentTimeMillis() + 3600000
|
);
|
}
|
|
/**
|
* 步骤4: 模拟上传头像到COS
|
*/
|
private String simulateUploadToCOS(Map<String, Object> credentials) {
|
// 模拟上传logo.jpg到腾讯云COS
|
// 实际应用中这里会使用腾讯云SDK上传文件
|
String timestamp = String.valueOf(System.currentTimeMillis());
|
return "avatars/judge_" + timestamp + "_logo.jpg";
|
}
|
|
/**
|
* 步骤5: 保存媒体记录(关联到评委)
|
*/
|
private String saveMediaRecord(String cosPath, String judgeId) throws Exception {
|
String mutation = String.format("""
|
mutation {
|
saveMedia(input: {
|
name: "logo.jpg"
|
path: "%s"
|
fileSize: 2048
|
fileExt: "jpg"
|
mediaType: 1
|
targetType: 1
|
targetId: %s
|
}) {
|
id
|
name
|
path
|
targetType
|
targetId
|
}
|
}
|
""", cosPath, judgeId);
|
|
Map<String, String> request = Collections.singletonMap("query", mutation);
|
String response = postGraphQL(request);
|
|
Map<String, Object> responseMap = objectMapper.readValue(response, Map.class);
|
|
// 检查是否有错误
|
if (responseMap.containsKey("errors")) {
|
System.out.println("GraphQL错误: " + responseMap.get("errors"));
|
throw new RuntimeException("保存媒体记录失败: " + responseMap.get("errors"));
|
}
|
|
@SuppressWarnings("unchecked")
|
Map<String, Object> mediaData = (Map<String, Object>)
|
((Map<String, Object>) responseMap.get("data")).get("saveMedia");
|
|
Object idObj = mediaData.get("id");
|
return idObj != null ? idObj.toString() : null;
|
}
|
|
/**
|
* 步骤6: 验证数据完整性
|
*/
|
private void verifyDataIntegrity(String judgeId, String mediaId) {
|
// 验证评委基本信息
|
String judgeSql = "SELECT * FROM t_judge WHERE id = ? AND state = 1";
|
Map<String, Object> judge = jdbcTemplate.queryForMap(judgeSql, Long.parseLong(judgeId));
|
|
assertEquals("王五", judge.get("name"));
|
assertTrue(((String) judge.get("phone")).startsWith("139")); // 验证电话号码格式
|
assertEquals(1, judge.get("gender")); // 男性
|
assertTrue(((String) judge.get("description")).contains("高级技术专家"));
|
|
// 验证媒体记录
|
String mediaSql = "SELECT * FROM t_media WHERE id = ? AND state = 1";
|
Map<String, Object> media = jdbcTemplate.queryForMap(mediaSql, Long.parseLong(mediaId));
|
|
assertEquals("logo.jpg", media.get("name"));
|
assertEquals(1, media.get("target_type")); // 评委头像
|
assertEquals(Long.parseLong(judgeId), ((Number) media.get("target_id")).longValue());
|
assertTrue(((String) media.get("path")).contains("avatars/"));
|
assertTrue(((String) media.get("path")).contains("logo.jpg"));
|
|
// 验证标签关联
|
String tagSql = "SELECT COUNT(*) FROM t_judge_tag WHERE judge_id = ? AND state = 1";
|
Integer tagCount = jdbcTemplate.queryForObject(tagSql, Integer.class, Long.parseLong(judgeId));
|
assertTrue(tagCount >= 2, "应该至少有2个标签关联");
|
|
System.out.println(" ✓ 评委基本信息正确");
|
System.out.println(" ✓ 头像媒体记录正确,关联到评委ID: " + judgeId);
|
System.out.println(" ✓ 标签关联记录正确 (" + tagCount + "个)");
|
}
|
|
/**
|
* 打印测试总结
|
*/
|
private void printTestSummary(String judgeId, String mediaId) {
|
System.out.println("\n=== 测试总结 ===");
|
System.out.println("评委ID: " + judgeId);
|
System.out.println("媒体ID: " + mediaId);
|
|
// 查询最终数据
|
String judgeSql = "SELECT * FROM t_judge WHERE id = ? AND state = 1";
|
Map<String, Object> judge = jdbcTemplate.queryForMap(judgeSql, Long.parseLong(judgeId));
|
|
String mediaSql = "SELECT * FROM t_media WHERE id = ? AND state = 1";
|
Map<String, Object> media = jdbcTemplate.queryForMap(mediaSql, Long.parseLong(mediaId));
|
|
System.out.println("评委姓名: " + judge.get("name"));
|
System.out.println("联系电话: " + judge.get("phone"));
|
System.out.println("性别: " + (Integer.valueOf(1).equals(judge.get("gender")) ? "男" : "女"));
|
System.out.println("头像路径: " + media.get("path"));
|
System.out.println("媒体关联: target_type=" + media.get("target_type") + ", target_id=" + media.get("target_id"));
|
|
System.out.println("\n✅ 正确的业务流程测试成功!");
|
System.out.println("✅ 1. 先保存评委信息 ✓");
|
System.out.println("✅ 2. 再上传头像到COS ✓");
|
System.out.println("✅ 3. 最后保存媒体记录并关联评委 ✓");
|
}
|
|
/**
|
* 发送GraphQL请求
|
*/
|
private String postGraphQL(Map<String, String> requestBody) {
|
HttpHeaders headers = new HttpHeaders();
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
HttpEntity<Map<String, String>> entity = new HttpEntity<>(requestBody, headers);
|
String url = "http://localhost:" + port + "/graphql";
|
|
var response = restTemplate.postForEntity(url, entity, String.class);
|
|
if (response.getStatusCode().is2xxSuccessful() && response.hasBody()) {
|
return response.getBody();
|
} else {
|
throw new RuntimeException("GraphQL request failed with status: " +
|
response.getStatusCode() + " and body: " + response.getBody());
|
}
|
}
|
}
|