新增二维码生成接口及工具类

This commit is contained in:
2025-08-19 00:05:14 +08:00
parent 3d33e42aae
commit bddda435de
18 changed files with 2382 additions and 5 deletions

View File

@@ -0,0 +1,102 @@
package com.gxwebsoft.common.core.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gxwebsoft.common.core.dto.qr.CreateEncryptedQrCodeRequest;
import com.gxwebsoft.common.core.utils.EncryptedQrCodeUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import java.util.HashMap;
import java.util.Map;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
/**
* QR码控制器测试
*
* @author WebSoft
* @since 2025-08-18
*/
@WebMvcTest(QrCodeController.class)
public class QrCodeControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private EncryptedQrCodeUtil encryptedQrCodeUtil;
@Autowired
private ObjectMapper objectMapper;
@Test
public void testCreateEncryptedQrCodeWithValidRequest() throws Exception {
// 准备测试数据
CreateEncryptedQrCodeRequest request = new CreateEncryptedQrCodeRequest();
request.setData("test data");
request.setWidth(200);
request.setHeight(200);
request.setExpireMinutes(30L);
request.setBusinessType("TEST");
Map<String, Object> mockResult = new HashMap<>();
mockResult.put("qrCodeBase64", "base64_encoded_image");
mockResult.put("token", "test_token");
when(encryptedQrCodeUtil.generateEncryptedQrCode(anyString(), anyInt(), anyInt(), anyLong(), anyString()))
.thenReturn(mockResult);
// 执行测试
mockMvc.perform(post("/api/qr-code/create-encrypted-qr-code")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(200))
.andExpect(jsonPath("$.message").value("生成加密二维码成功"))
.andExpect(jsonPath("$.data.qrCodeBase64").value("base64_encoded_image"))
.andExpect(jsonPath("$.data.token").value("test_token"));
}
@Test
public void testCreateEncryptedQrCodeWithInvalidRequest() throws Exception {
// 准备无效的测试数据data为空
CreateEncryptedQrCodeRequest request = new CreateEncryptedQrCodeRequest();
request.setData(""); // 空字符串,应该触发验证失败
request.setWidth(200);
request.setHeight(200);
request.setExpireMinutes(30L);
// 执行测试
mockMvc.perform(post("/api/qr-code/create-encrypted-qr-code")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(500))
.andExpect(jsonPath("$.message").value("数据不能为空"));
}
@Test
public void testCreateEncryptedQrCodeWithInvalidSize() throws Exception {
// 准备无效的测试数据(尺寸超出范围)
CreateEncryptedQrCodeRequest request = new CreateEncryptedQrCodeRequest();
request.setData("test data");
request.setWidth(2000); // 超出最大值1000
request.setHeight(200);
request.setExpireMinutes(30L);
// 执行测试
mockMvc.perform(post("/api/qr-code/create-encrypted-qr-code")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(500))
.andExpect(jsonPath("$.message").value("宽度不能大于1000像素"));
}
}

View File

@@ -0,0 +1,136 @@
package com.gxwebsoft.common.core.utils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import javax.annotation.Resource;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
/**
* 加密二维码工具类测试
*
* @author WebSoft
* @since 2025-08-18
*/
@SpringBootTest
@ActiveProfiles("dev")
public class EncryptedQrCodeUtilTest {
@Resource
private EncryptedQrCodeUtil encryptedQrCodeUtil;
@Test
public void testGenerateAndDecryptData() {
// 测试数据
String originalData = "https://www.example.com/user/123";
Long expireMinutes = 30L;
// 生成加密数据
Map<String, String> encryptedInfo = encryptedQrCodeUtil.generateEncryptedData(originalData, expireMinutes);
assertNotNull(encryptedInfo);
assertNotNull(encryptedInfo.get("token"));
assertNotNull(encryptedInfo.get("encryptedData"));
assertEquals(expireMinutes.toString(), encryptedInfo.get("expireMinutes"));
// 解密数据
String decryptedData = encryptedQrCodeUtil.decryptData(
encryptedInfo.get("token"),
encryptedInfo.get("encryptedData")
);
assertEquals(originalData, decryptedData);
}
@Test
public void testGenerateEncryptedQrCode() {
// 测试数据
String originalData = "测试二维码数据";
int width = 300;
int height = 300;
Long expireMinutes = 60L;
// 生成加密二维码
Map<String, Object> result = encryptedQrCodeUtil.generateEncryptedQrCode(
originalData, width, height, expireMinutes
);
assertNotNull(result);
assertNotNull(result.get("qrCodeBase64"));
assertNotNull(result.get("token"));
assertEquals(originalData, result.get("originalData"));
assertEquals(expireMinutes.toString(), result.get("expireMinutes"));
}
@Test
public void testTokenValidation() {
// 生成测试数据
String originalData = "token验证测试";
Map<String, String> encryptedInfo = encryptedQrCodeUtil.generateEncryptedData(originalData, 30L);
String token = encryptedInfo.get("token");
// 验证token有效性
assertTrue(encryptedQrCodeUtil.isTokenValid(token));
// 使token失效
encryptedQrCodeUtil.invalidateToken(token);
// 再次验证token应该无效
assertFalse(encryptedQrCodeUtil.isTokenValid(token));
}
@Test
public void testInvalidToken() {
// 测试无效token
assertFalse(encryptedQrCodeUtil.isTokenValid("invalid_token"));
assertFalse(encryptedQrCodeUtil.isTokenValid(""));
assertFalse(encryptedQrCodeUtil.isTokenValid(null));
}
@Test
public void testDecryptWithInvalidToken() {
// 测试用无效token解密
assertThrows(RuntimeException.class, () -> {
encryptedQrCodeUtil.decryptData("invalid_token", "encrypted_data");
});
}
@Test
public void testGenerateEncryptedQrCodeWithBusinessType() {
// 测试数据
String originalData = "用户登录数据";
int width = 200;
int height = 200;
Long expireMinutes = 30L;
String businessType = "LOGIN";
// 生成带业务类型的加密二维码
Map<String, Object> result = encryptedQrCodeUtil.generateEncryptedQrCode(
originalData, width, height, expireMinutes, businessType
);
assertNotNull(result);
assertNotNull(result.get("qrCodeBase64"));
assertNotNull(result.get("token"));
assertEquals(originalData, result.get("originalData"));
assertEquals(expireMinutes.toString(), result.get("expireMinutes"));
assertEquals(businessType, result.get("businessType"));
System.out.println("=== 带BusinessType的二维码生成测试 ===");
System.out.println("原始数据: " + originalData);
System.out.println("业务类型: " + businessType);
System.out.println("Token: " + result.get("token"));
System.out.println("二维码Base64长度: " + ((String)result.get("qrCodeBase64")).length());
// 验证不传businessType的情况
Map<String, Object> resultWithoutType = encryptedQrCodeUtil.generateEncryptedQrCode(
originalData, width, height, expireMinutes
);
assertNull(resultWithoutType.get("businessType"));
System.out.println("不传BusinessType时的结果: " + resultWithoutType.get("businessType"));
}
}