OCT 1. 增加集成测试框架

This commit is contained in:
黄昕 2024-02-05 16:29:53 +08:00
parent a3cccb6e12
commit c64615f22b
13 changed files with 769 additions and 9 deletions

View File

@ -67,6 +67,12 @@
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite-engine</artifactId>
<version>1.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>

View File

@ -5,6 +5,7 @@ import com.cmhi.cf.restapi.annotation.DecryptionProtocol;
import com.cmhi.cf.restapi.annotation.EncryptionProtocol;
import com.cmhi.cf.restapi.annotation.OperationLogAnnotation;
import com.cmhi.cf.restapi.pojo.base.BaseRespStatus;
import com.cmhi.cf.restapi.pojo.po.VersionInfo;
import com.cmhi.cf.restapi.pojo.vo.ProtocolResp;
import com.cmhi.cf.restapi.pojo.vo.VersionResp;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -31,7 +32,14 @@ public class CommonFrameworkApi {
@OperationLogAnnotation(OperationModule = "通用模块", OperationType = "读取", OperationDesc = "获取当前系统版本信息")
public ProtocolResp<? extends BaseRespStatus> getVersion() {
return ProtocolResp.result(VersionResp.builder()
.version(prgVer)
.version(VersionInfo.builder()
.commitId(prgVer.getCommitId())
.commitDescribe(prgVer.getCommitDescribe())
.commitTime(prgVer.getCommitTime())
.tagName(prgVer.getTagName())
.buildTime(prgVer.getBuildTime())
.gitBranch(prgVer.getGitBranch())
.build())
.build());
}
@ -41,7 +49,14 @@ public class CommonFrameworkApi {
@OperationLogAnnotation(OperationModule = "通用模块", OperationType = "读取", OperationDesc = "获取当前系统版本信息")
public ProtocolResp<? extends BaseRespStatus> getVersionV2() {
return ProtocolResp.result(VersionResp.builder()
.version(prgVer)
.version(VersionInfo.builder()
.commitId(prgVer.getCommitId())
.commitDescribe(prgVer.getCommitDescribe())
.commitTime(prgVer.getCommitTime())
.tagName(prgVer.getTagName())
.buildTime(prgVer.getBuildTime())
.gitBranch(prgVer.getGitBranch())
.build())
.build());
}
}

View File

@ -28,11 +28,13 @@ import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
public class HelperUtils {
public static final String UN_EXPECT_REGEX_CHARS = "^((?!(--|\\s|\\*|%|\\+|'|;])).)*$";
@ -41,7 +43,7 @@ public class HelperUtils {
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
public static String truncateString(String orgString, int maxLength) {
if(!stringNotEmptyOrNull(orgString) || orgString.length() <= maxLength) {
if (!stringNotEmptyOrNull(orgString) || orgString.length() <= maxLength) {
return orgString;
} else {
return orgString.substring(0, maxLength - 4) + "...";
@ -114,6 +116,9 @@ public class HelperUtils {
return OBJ_MAPPER.readValue(inputStream2String(is), valueTypeRef);
}
public static <T> T jsonGetObject(String json, TypeReference<T> valueTypeRef) throws IOException {
return OBJ_MAPPER.readValue(json, valueTypeRef);
}
private static <T> Type createRespType(Class<T> c) {
return new ParameterizedType() {
@ -137,9 +142,50 @@ public class HelperUtils {
};
}
public static <T> ProtocolResp<? extends BaseRespStatus> jsonGetProtocolResp(String reqJson,
public static <T> ProtocolResp<? extends BaseRespStatus> jsonGetProtocolResp(String jsonString,
Class<T> subClass) throws JsonProcessingException {
return OBJ_MAPPER.readValue(reqJson, new TypeReference<>() {
return OBJ_MAPPER.readValue(jsonString, new TypeReference<>() {
@Override
public Type getType() {
return createRespType(subClass);
}
});
}
private static <T> Type createRespType(Class<?>[] c) {
if (c.length == 1) {
return JsonParameterizedType.make(ProtocolResp.class,
new Type[] {c[0]},
ProtocolResp.class.getDeclaringClass());
}
Stack<Class<?>> st = new Stack<>();
Arrays.stream(c).forEach(st::push);
Class<?> fc = st.pop();
Class<?> sc = st.pop();
JsonParameterizedType type = JsonParameterizedType.make(sc,
new Type[] {fc},
sc.getDeclaringClass());
while (!st.isEmpty()) {
Class<?> mc = st.pop();
type = JsonParameterizedType.make(mc,
new Type[] {type},
mc.getDeclaringClass());
}
type = JsonParameterizedType.make(ProtocolResp.class,
new Type[] {type},
ProtocolResp.class.getDeclaringClass());
return type;
}
public static <T> ProtocolResp<? extends BaseRespStatus> jsonGetProtocolResp(String jsonString,
Class<?>[] subClass) throws JsonProcessingException {
return OBJ_MAPPER.readValue(jsonString, new TypeReference<>() {
@Override
public Type getType() {
return createRespType(subClass);
@ -193,7 +239,7 @@ public class HelperUtils {
String localhostIp = "127.0.0.1";
// 客户端与服务器同为一台机器获取的 ip 有时候是 ipv6 格式
String localhostIpv6 = "0:0:0:0:0:0:0:1";
String separator = ",";
String separator = ",";
if (request == null) {
return "unknown";

View File

@ -0,0 +1,112 @@
package com.cmhi.cf.misc;
import java.lang.reflect.MalformedParameterizedTypeException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.Objects;
public class JsonParameterizedType implements ParameterizedType {
private final Type[] actualTypeArguments;
private final Class<?> rawType;
private final Type ownerType;
private JsonParameterizedType(Class<?> var1, Type[] var2, Type var3) {
this.actualTypeArguments = var2;
this.rawType = var1;
this.ownerType = (Type)(var3 != null ? var3 : var1.getDeclaringClass());
this.validateConstructorArguments();
}
private void validateConstructorArguments() {
TypeVariable[] var1 = this.rawType.getTypeParameters();
if (var1.length != this.actualTypeArguments.length) {
throw new MalformedParameterizedTypeException();
} else {
for(int var2 = 0; var2 < this.actualTypeArguments.length; ++var2) {
}
}
}
@Override
public Type[] getActualTypeArguments() {
return this.actualTypeArguments.clone();
}
@Override
public Type getRawType() {
return this.rawType;
}
@Override
public Type getOwnerType() {
return this.ownerType;
}
@Override
public boolean equals(Object var1) {
if (var1 instanceof ParameterizedType var2) {
if (this == var2) {
return true;
} else {
Type var3 = var2.getOwnerType();
Type var4 = var2.getRawType();
return Objects.equals(this.ownerType, var3) && Objects.equals(this.rawType, var4) && Arrays.equals(this.actualTypeArguments, var2.getActualTypeArguments());
}
} else {
return false;
}
}
@Override
public int hashCode() {
return Arrays.hashCode(this.actualTypeArguments) ^ Objects.hashCode(this.ownerType) ^ Objects.hashCode(this.rawType);
}
@Override
public String toString() {
StringBuilder var1 = new StringBuilder();
if (this.ownerType != null) {
if (this.ownerType instanceof Class) {
var1.append(((Class)this.ownerType).getName());
} else {
var1.append(this.ownerType.toString());
}
var1.append("$");
if (this.ownerType instanceof JsonParameterizedType) {
var1.append(this.rawType.getName().replace(((JsonParameterizedType)this.ownerType).rawType.getName() + "$", ""));
} else {
var1.append(this.rawType.getSimpleName());
}
} else {
var1.append(this.rawType.getName());
}
if (this.actualTypeArguments != null && this.actualTypeArguments.length > 0) {
var1.append("<");
boolean var2 = true;
Type[] var3 = this.actualTypeArguments;
int var4 = var3.length;
for(int var5 = 0; var5 < var4; ++var5) {
Type var6 = var3[var5];
if (!var2) {
var1.append(", ");
}
var1.append(var6.getTypeName());
var2 = false;
}
var1.append(">");
}
return var1.toString();
}
public static JsonParameterizedType make(Class<?> var0, Type[] var1, Type var2) {
return new JsonParameterizedType(var0, var1, var2);
}
}

View File

@ -3,15 +3,19 @@ package com.cmhi.cf.restapi.pojo.base;
import com.cmhi.cf.restapi.pojo.po.PageResults;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@EqualsAndHashCode(callSuper = true)
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({"items", "status", "message"})
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BasePageResultResp<T> extends BaseRespStatus {
private PageResults<T> items;
}

View File

@ -0,0 +1,19 @@
package com.cmhi.cf.restapi.pojo.po;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VersionInfo {
private String commitId;
private String commitDescribe;
private String commitTime;
private String tagName;
private String buildTime;
private String gitBranch;
}

View File

@ -1,16 +1,20 @@
package com.cmhi.cf.restapi.pojo.vo;
import com.cmhi.cf.configure.ProjectGitVersionInfo;
import com.cmhi.cf.restapi.pojo.base.BaseRespStatus;
import com.cmhi.cf.restapi.pojo.po.VersionInfo;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@EqualsAndHashCode(callSuper = true)
@Data
@JsonPropertyOrder({"version", "status", "message"})
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VersionResp extends BaseRespStatus {
private ProjectGitVersionInfo version;
private VersionInfo version;
}

View File

@ -1,9 +1,16 @@
package com.cmhi.cf.tools;
import com.cmhi.cf.misc.JsonParameterizedType;
import com.cmhi.cf.restapi.pojo.base.BasePageResultResp;
import com.cmhi.cf.restapi.pojo.po.OperationLogSummary;
import com.cmhi.cf.restapi.pojo.vo.ProtocolResp;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.jsonpath.JsonPath;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Type;
import java.util.UUID;
@Slf4j
@ -27,8 +34,164 @@ public class ToolsTest {
@Test
public void testGenUuid() {
for(int i = 10; i < 100; i++) {
for (int i = 10; i < 100; i++) {
log.info("{}: {}", i, UUID.randomUUID());
}
}
@Test
public void jsonToObject() throws Exception {
final String json = """
{
"ver": 1,
"cryptoType": 0,
"timeStamp": 1707101107092,
"code": 200,
"msgContent": {
"items": {
"pageNumber": 1,
"pageSize": 10,
"totalPage": 1,
"totalRow": 7,
"items": [
{
"id": 1,
"module": "系统安全模块",
"operationType": "认证/鉴权",
"operationStatus": "成功",
"description": "[admin] login",
"requestIp": "172.21.96.1",
"callFunction": "login",
"httpMethod": "POST",
"httpPath": "/api/login",
"userId": 1,
"expendTime": 453,
"transmitDelay": 139,
"operationTime": "2024-02-05T02:23:57.589+00:00"
},
{
"id": 3,
"module": "系统安全模块",
"operationType": "认证/鉴权",
"operationStatus": "成功",
"description": "[admin] login",
"requestIp": "172.21.96.1",
"callFunction": "login",
"httpMethod": "POST",
"httpPath": "/api/login",
"userId": 1,
"expendTime": 464,
"transmitDelay": 128,
"operationTime": "2024-02-05T02:24:32.212+00:00"
},
{
"id": 5,
"module": "系统安全模块",
"operationType": "认证/鉴权",
"operationStatus": "成功",
"description": "[admin] login",
"requestIp": "172.21.96.1",
"callFunction": "login",
"httpMethod": "POST",
"httpPath": "/api/login",
"userId": 1,
"expendTime": 435,
"transmitDelay": 137,
"operationTime": "2024-02-05T02:25:39.344+00:00"
},
{
"id": 7,
"module": "系统安全模块",
"operationType": "认证/鉴权",
"operationStatus": "成功",
"description": "[admin] login",
"requestIp": "172.21.96.1",
"callFunction": "login",
"httpMethod": "POST",
"httpPath": "/api/login",
"userId": 1,
"expendTime": 470,
"transmitDelay": 129,
"operationTime": "2024-02-05T02:26:37.216+00:00"
},
{
"id": 9,
"module": "系统安全模块",
"operationType": "认证/鉴权",
"operationStatus": "成功",
"description": "[admin] login",
"requestIp": "172.21.96.1",
"callFunction": "login",
"httpMethod": "POST",
"httpPath": "/api/login",
"userId": 1,
"expendTime": 411,
"transmitDelay": 124,
"operationTime": "2024-02-05T02:39:48.214+00:00"
},
{
"id": 11,
"module": "系统安全模块",
"operationType": "认证/鉴权",
"operationStatus": "成功",
"description": "[admin] login",
"requestIp": "172.21.96.1",
"callFunction": "login",
"httpMethod": "POST",
"httpPath": "/api/login",
"userId": 1,
"expendTime": 468,
"transmitDelay": 124,
"operationTime": "2024-02-05T02:40:16.012+00:00"
},
{
"id": 13,
"module": "系统安全模块",
"operationType": "认证/鉴权",
"operationStatus": "成功",
"description": "[admin] login",
"requestIp": "172.21.96.1",
"callFunction": "login",
"httpMethod": "POST",
"httpPath": "/api/login",
"userId": 1,
"expendTime": 473,
"transmitDelay": 121,
"operationTime": "2024-02-05T02:45:05.815+00:00"
}
]
},
"status": 0,
"message": [
"成功"
]
}
}
""";
ProtocolResp<BasePageResultResp<OperationLogSummary>> ret = null;
JsonParameterizedType type = JsonParameterizedType.make(BasePageResultResp.class,
new java.lang.Class[] {OperationLogSummary.class},
BasePageResultResp.class.getDeclaringClass());
ret = new ObjectMapper().readValue(json, new TypeReference<>() {
@Override
public Type getType() {
return JsonParameterizedType.make(ProtocolResp.class,
new java.lang.Class[] {(Class) type.getRawType()},
ProtocolResp.class.getDeclaringClass());
}
});
log.info("{}", ret);
ret = new ObjectMapper().readValue(json, new TypeReference<>() {
});
log.info("{}", ret);
Class<?>[] classes = { String.class, Integer.class, Double.class };
}
}

View File

@ -0,0 +1,11 @@
import com.cmhi.cf.controller.CommonFrameworkApiTest;
import com.cmhi.cf.controller.OperationLogApiTest;
import org.junit.jupiter.api.DisplayName;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;
@SelectClasses({CommonFrameworkApiTest.class, OperationLogApiTest.class})
@DisplayName("接口集成测试")
@Suite
public class IntegrationTestSuite {
}

View File

@ -0,0 +1,158 @@
package com.cmhi.cf.common;
import com.cmhi.cf.authentication.pojo.dto.LoginReq;
import com.cmhi.cf.authentication.pojo.vo.LoginResp;
import com.cmhi.cf.misc.HelperUtils;
import com.cmhi.cf.restapi.config.ProtoCryptoType;
import com.cmhi.cf.restapi.config.ProtocolConfigure;
import com.cmhi.cf.restapi.pojo.dto.ProtocolReq;
import com.cmhi.cf.restapi.pojo.vo.ProtocolResp;
import com.cmhi.cf.restapi.service.ProtocolSecurityService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.TestInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.Objects;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public abstract class TestBaseAuthentication {
protected static final ThreadLocal<HttpHeaders> headersThreadLocal = new ThreadLocal<>();
@Autowired
protected MockMvc mockMvc;
@Autowired
private ProtocolSecurityService securityService;
public HttpHeaders getHeaders() {
return headersThreadLocal.get();
}
@BeforeAll
public void setUpClass() throws Exception {
LoginReq logReq = LoginReq.builder()
.username("admin")
.password("8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918")
.build();
ProtocolReq<LoginReq> loginPro = new ProtocolReq<>();
loginPro.setMsgContent(logReq);
loginPro.setVer(1);
loginPro.setTimeStamp(System.currentTimeMillis());
loginPro.setCryptoType(ProtocolConfigure.SECURITY_PROTOCOL_TYPE);
MvcResult mvcResult = mockMvc.perform(post("/api/login")
.contentType(MediaType.APPLICATION_JSON) // Set the content type to JSON
.content(HelperUtils.getJson(loginPro))) // Pass the JSON request body
.andExpect(status().isOk()) // Expect that the status is 200 OK
.andReturn();
// 假设JWT在响应体中返回您需要根据实际情况调整此行代码
String respJson = mvcResult.getResponse().getContentAsString();
Assertions.assertNotNull(respJson);
Assertions.assertNotEquals(respJson.length(), 0);
ProtocolResp<?> resp = HelperUtils.jsonGetProtocolResp(respJson, LoginResp.class);
Assertions.assertNotNull(resp);
Assertions.assertNotNull(resp.getMsgContent());
Assertions.assertEquals(resp.getCode(), HttpStatus.OK.value());
LoginResp loginResp = (LoginResp) resp.getMsgContent();
Assertions.assertEquals(loginResp.getStatus(), ErrorCode.ERR_OK.getCode());
Assertions.assertNotNull(loginResp.getToken());
Assertions.assertNotEquals(loginResp.getToken().length(), 0);
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
headers.add(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate, br");
headers.setBearerAuth(loginResp.getToken());
headersThreadLocal.set(headers);
}
public <T, K> Object performanceRestful(RequestMethod reqType, T reqObject, String urlPath, Class<?>[] subRespClass) throws Exception {
MockHttpServletRequestBuilder build = createMockMvcBuilder(urlPath, reqType);
if (Objects.nonNull(reqObject)) {
String sendMsgContent;
ProtocolReq<T> reqInfo = new ProtocolReq<>();
reqInfo.setVer(ConstValue.Protocol.VERSION);
reqInfo.setCryptoType(ProtocolConfigure.SECURITY_PROTOCOL_TYPE);
reqInfo.setTimeStamp(System.currentTimeMillis());
reqInfo.setMsgContent(reqObject);
if (ProtocolConfigure.SECURITY_PROTOCOL_TYPE != ProtoCryptoType.CRYPTO_NONE.getValue()) {
String cipherText = securityService.encryptProtocolString(HelperUtils.getJson(reqObject),
ProtocolConfigure.SECURITY_PROTOCOL_TYPE);
ProtocolReq<String> cipherInfo = new ProtocolReq<>();
cipherInfo.setVer(reqInfo.getVer());
cipherInfo.setCryptoType(reqInfo.getCryptoType());
cipherInfo.setTimeStamp(System.currentTimeMillis());
cipherInfo.setMsgContent(cipherText);
sendMsgContent = HelperUtils.getJson(cipherInfo);
} else {
sendMsgContent = HelperUtils.getJson(reqInfo);
}
build.content(sendMsgContent);
}
String rspValue = mockMvc.perform(build)
.andDo(print())
.andReturn()
.getResponse()
.getContentAsString();
AssertValidString(rspValue);
rspValue = securityService.decryptProtocol(rspValue);
AssertValidString(rspValue);
ProtocolResp<?> resp = HelperUtils.jsonGetProtocolResp(rspValue, subRespClass);
Assertions.assertNotNull(resp);
Assertions.assertNotNull(resp.getMsgContent());
Assertions.assertEquals(resp.getCode(), HttpStatus.OK.value());
return resp.getMsgContent();
}
private MockHttpServletRequestBuilder createMockMvcBuilder(String uri, RequestMethod reqType) {
MockHttpServletRequestBuilder build = switch (reqType) {
case PUT -> MockMvcRequestBuilders.put(uri);
case GET -> MockMvcRequestBuilders.get(uri);
case DELETE -> MockMvcRequestBuilders.delete(uri);
default -> MockMvcRequestBuilders.post(uri);
};
build.accept(MediaType.APPLICATION_JSON);
build.headers(getHeaders());
return build;
}
public void AssertValidString(String str) {
Assertions.assertNotNull(str);
Assertions.assertFalse(str.isEmpty());
}
}

View File

@ -0,0 +1,89 @@
package com.cmhi.cf.common.authentication;
import com.cmhi.cf.authentication.pojo.dto.LoginReq;
import com.cmhi.cf.misc.HelperUtils;
import com.cmhi.cf.restapi.config.ProtocolConfigure;
import com.cmhi.cf.restapi.pojo.dto.ProtocolReq;
import jakarta.annotation.Resource;
import lombok.Getter;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultMatcher;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ExtendWith({SpringExtension.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
public class TestCommonExtension implements BeforeEachCallback {
@Getter
private static final TestRestTemplate restTemplate = new TestRestTemplate();
private static final ThreadLocal<HttpHeaders> headersThreadLocal = new ThreadLocal<>();
@Resource
private MockMvc mockMvc;
public static HttpHeaders getHeaders() {
return headersThreadLocal.get();
}
@Override
public void beforeEach(ExtensionContext extensionContext) throws Exception {
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
//headers.add(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate, br");
LoginReq logReq = LoginReq.builder()
.username("admin")
.password("8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918")
.build();
ProtocolReq<LoginReq> loginPro = new ProtocolReq<>();
loginPro.setMsgContent(logReq);
loginPro.setVer(1);
loginPro.setTimeStamp(System.currentTimeMillis());
loginPro.setCryptoType(ProtocolConfigure.SECURITY_PROTOCOL_TYPE);
MvcResult mvcResult = mockMvc.perform(post("/api/login")
.contentType(MediaType.APPLICATION_JSON) // Set the content type to JSON
.content(HelperUtils.getJson(loginPro))) // Pass the JSON request body
.andExpect(status().isOk()) // Expect that the status is 200 OK
.andExpect((ResultMatcher) content().contentType(
MediaType.APPLICATION_JSON)) // Optional: Expect JSON response
.andReturn();
// HttpEntity<String> formEntity = new HttpEntity<>(HelperUtils.getJson(loginPro), headers);
//
// ResponseEntity<String> response = restTemplate.postForEntity(CommonConfigure.BASEURL + "/api/login", formEntity, String.class);
// Assertions.assertNotNull(response);
//
// ProtocolResp<?> resp = HelperUtils.jsonGetProtocolResp(response.getBody(), LoginResp.class);
// Assertions.assertNotNull(resp);
// Assertions.assertNotNull(resp.getMsgContent());
// Assertions.assertEquals(resp.getCode(), HttpStatus.OK.value());
//
// LoginResp loginResp = (LoginResp) resp.getMsgContent();
//
// Assertions.assertEquals(loginResp.getStatus(), ErrorCode.ERR_OK.getCode());
// Assertions.assertNotNull(loginResp.getToken());
// Assertions.assertNotEquals(loginResp.getToken().length(), 0);
//
// headers.setBearerAuth(loginResp.getToken());
//
headersThreadLocal.set(headers);
}
}

View File

@ -0,0 +1,53 @@
package com.cmhi.cf.controller;
import com.cmhi.cf.common.ErrorCode;
import com.cmhi.cf.common.TestBaseAuthentication;
import com.cmhi.cf.restapi.pojo.vo.VersionResp;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMethod;
@ExtendWith({SpringExtension.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@Transactional
public class CommonFrameworkApiTest extends TestBaseAuthentication {
@Test
void testGetVersion() throws Exception {
VersionResp resp = (VersionResp) performanceRestful(RequestMethod.GET, null, "/api/version", new Class[]{VersionResp.class});
Assertions.assertNotNull(resp);
Assertions.assertNotNull(resp.getVersion());
Assertions.assertNotNull(resp.getStatus());
Assertions.assertNotNull(resp.getMessage());
Assertions.assertNotEquals(resp.getMessage().length, 0);
Assertions.assertEquals(resp.getStatus(), ErrorCode.ERR_OK.getCode());
Assertions.assertNotNull(resp.getVersion().getTagName());
AssertValidString(resp.getVersion().getCommitId());
AssertValidString(resp.getVersion().getCommitDescribe());
AssertValidString(resp.getVersion().getCommitTime());
AssertValidString(resp.getVersion().getBuildTime());
AssertValidString(resp.getVersion().getGitBranch());
}
@Test
void testGetVersionV2() throws Exception {
VersionResp resp = (VersionResp) performanceRestful(RequestMethod.POST, null, "/api/version", new Class[]{VersionResp.class});
Assertions.assertNotNull(resp);
Assertions.assertNotNull(resp.getVersion());
Assertions.assertNotNull(resp.getStatus());
Assertions.assertNotNull(resp.getMessage());
Assertions.assertNotEquals(resp.getMessage().length, 0);
Assertions.assertEquals(resp.getStatus(), ErrorCode.ERR_OK.getCode());
Assertions.assertNotNull(resp.getVersion().getTagName());
AssertValidString(resp.getVersion().getCommitId());
AssertValidString(resp.getVersion().getCommitDescribe());
AssertValidString(resp.getVersion().getCommitTime());
AssertValidString(resp.getVersion().getBuildTime());
AssertValidString(resp.getVersion().getGitBranch());
}
}

View File

@ -0,0 +1,80 @@
package com.cmhi.cf.controller;
import com.cmhi.cf.common.ErrorCode;
import com.cmhi.cf.common.TestBaseAuthentication;
import com.cmhi.cf.restapi.pojo.base.BasePageResultResp;
import com.cmhi.cf.restapi.pojo.dto.OperationLogReq;
import com.cmhi.cf.restapi.pojo.po.OperationLogSummary;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.List;
@ExtendWith({SpringExtension.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@Transactional
public class OperationLogApiTest extends TestBaseAuthentication {
@Test
void testGetSummary() throws Exception {
final long pageSize = 10L;
final long pageNumber = 1L;
OperationLogReq req = new OperationLogReq();
req.setPageNumber(pageNumber);
req.setPageSize(pageSize);
req.setTotalSize(-1L);
Object obj = performanceRestful(RequestMethod.POST, req, "/api/operation/summary",
new Class[] {BasePageResultResp.class, OperationLogSummary.class});
Assertions.assertNotNull(obj);
BasePageResultResp<?> resp = (BasePageResultResp<?>) obj;
Assertions.assertNotNull(resp);
Assertions.assertNotNull(resp.getStatus());
Assertions.assertNotNull(resp.getMessage());
Assertions.assertNotEquals(resp.getMessage().length, 0);
Assertions.assertEquals(resp.getStatus(), ErrorCode.ERR_OK.getCode());
Assertions.assertNotNull(resp.getItems());
Assertions.assertFalse(resp.getItems().getItems().isEmpty());
Assertions.assertEquals(resp.getItems().getPageSize(), pageSize);
Assertions.assertEquals(resp.getItems().getPageNumber(), pageNumber);
Assertions.assertTrue(resp.getItems().getTotalPage() > 0);
Assertions.assertTrue(resp.getItems().getTotalRow() > 0);
List<?> items = resp.getItems().getItems();
for (Object o : items) {
Assertions.assertNotNull(o);
}
resp.getItems().getItems().forEach(k -> {
Assertions.assertInstanceOf(OperationLogSummary.class, k);
OperationLogSummary o = (OperationLogSummary) k;
Assertions.assertNotNull(o);
Assertions.assertNotNull(o.getId());
Assertions.assertNotNull(o.getOperationTime());
AssertValidString(o.getModule());
AssertValidString(o.getOperationType());
AssertValidString(o.getOperationStatus());
AssertValidString(o.getDescription());
AssertValidString(o.getRequestIp());
AssertValidString(o.getHttpMethod());
AssertValidString(o.getHttpPath());
});
}
@Test
void testGetDetails() throws Exception {
}
@Test
void testGetDetails_OperationLogServiceReturnsNoItems() throws Exception {
}
}