1. 增加集成测试

This commit is contained in:
黄昕 2024-03-08 16:52:33 +08:00
parent fb01673af6
commit 60df58164d
16 changed files with 1064 additions and 85 deletions

View File

@ -2,6 +2,7 @@ package com.cf.cs.authentication.interceptor;
import com.cf.cs.base.misc.ApiContextUtils;
import com.cf.cs.base.misc.HelperUtils;
import com.cf.cs.protocol.misc.ProtocolJsonUtils;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
@ -61,7 +62,7 @@ public class RequestBodyCacheWrapper extends HttpServletRequestWrapper {
}
try {
Object obj = HelperUtils.jsonGetObject(stringBuilder.toString(), Object.class);
Object obj = ProtocolJsonUtils.jsonGetObject(stringBuilder.toString(), Object.class);
body = HelperUtils.getJson(obj);
Enumeration<String> enumeration = request.getHeaderNames();

View File

@ -2,8 +2,8 @@ package com.cf.cs.authentication.misc;
import com.cf.cs.base.common.CommonEnumHandler;
import com.cf.cs.base.common.ErrorCode;
import com.cf.cs.base.misc.HelperUtils;
import com.cf.cs.database.service.OperationLogDataBaseService;
import com.cf.cs.protocol.misc.ProtocolJsonUtils;
import com.cf.cs.protocol.pojo.po.BaseRespStatus;
import com.cf.cs.protocol.pojo.vo.ProtocolResp;
import jakarta.servlet.ServletOutputStream;
@ -41,7 +41,7 @@ public class SecurityResponseUtils {
logService.securityOperationLog(request, ret, error, readme);
}
outputStream.write(HelperUtils.getJsonBytes(ret));
outputStream.write(ProtocolJsonUtils.getJsonBytes(ret));
outputStream.flush();
outputStream.close();
}
@ -69,7 +69,7 @@ public class SecurityResponseUtils {
logService.securityOperationLog(request, ret, CommonEnumHandler.codeOf(ErrorCode.class, rsp.getStatus()), readme);
}
outputStream.write(HelperUtils.getJsonBytes(ProtocolResp.result(rsp)));
outputStream.write(ProtocolJsonUtils.getJsonBytes(ProtocolResp.result(rsp)));
outputStream.flush();
outputStream.close();
}

View File

@ -12,6 +12,7 @@ import com.cf.cs.base.misc.HelperUtils;
import com.cf.cs.base.pojo.po.JwtCache;
import com.cf.cs.database.service.OperationLogDataBaseService;
import com.cf.cs.protocol.config.ProtocolConfigure;
import com.cf.cs.protocol.misc.ProtocolJsonUtils;
import com.cf.cs.protocol.pojo.dto.LoginReq;
import com.cf.cs.protocol.pojo.dto.ProtocolReq;
import com.cf.cs.protocol.pojo.po.BaseRespStatus;
@ -71,8 +72,8 @@ public class JwtCustomUsernamePassword extends UsernamePasswordAuthenticationFil
}
try {
ProtocolReq<LoginReq> loginReq = HelperUtils.jsonGetObject(request.getInputStream(),
new TypeReference<>() {
ProtocolReq<LoginReq> loginReq = ProtocolJsonUtils.jsonGetObject(request.getInputStream(),
new TypeReference<>() {
});
List<String> validate = HelperUtils.validate(loginReq, ValidGroups.ProtocolCommonValid.class,
ValidGroups.LogoutReqValid.class);

View File

@ -4,9 +4,7 @@ package com.cf.cs.base.misc;
import com.cf.cs.base.common.ConstValue;
import com.cf.cs.base.config.ObjectMapperProvider;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
@ -20,7 +18,6 @@ import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.time.LocalDateTime;
@ -40,6 +37,18 @@ import java.util.Set;
public class HelperUtils {
private static final ObjectMapper OBJ_MAPPER = ObjectMapperProvider.getMapper();
/**
* Gets json.
*
* @param <T> the type parameter
* @param obj the obj
* @return the json
* @throws JsonProcessingException the json processing exception
*/
public static <T> String getJson(T obj) throws JsonProcessingException {
return OBJ_MAPPER.writeValueAsString(obj);
}
/**
* Truncate string string.
*
@ -132,82 +141,6 @@ public class HelperUtils {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
/**
* Gets json.
*
* @param <T> the type parameter
* @param obj the obj
* @return the json
* @throws JsonProcessingException the json processing exception
*/
public static <T> String getJson(T obj) throws JsonProcessingException {
return OBJ_MAPPER.writeValueAsString(obj);
}
/**
* Get json bytes byte [ ].
*
* @param <T> the type parameter
* @param obj the obj
* @param charset the charset
* @return the byte [ ]
* @throws JsonProcessingException the json processing exception
*/
public static <T> byte[] getJsonBytes(T obj, Charset charset) throws JsonProcessingException {
return OBJ_MAPPER.writeValueAsString(obj).getBytes(charset);
}
/**
* Get json bytes byte [ ].
*
* @param <T> the type parameter
* @param obj the obj
* @return the byte [ ]
* @throws JsonProcessingException the json processing exception
*/
public static <T> byte[] getJsonBytes(T obj) throws JsonProcessingException {
return OBJ_MAPPER.writeValueAsString(obj).getBytes(StandardCharsets.UTF_8);
}
/**
* Json get object object.
*
* @param <T> the type parameter
* @param json the json
* @param valueType the value type
* @return the object
* @throws JsonProcessingException the json processing exception
*/
public static <T> Object jsonGetObject(String json, Class<T> valueType) throws JsonProcessingException {
return OBJ_MAPPER.readValue(json, valueType);
}
/**
* Json get object t.
*
* @param <T> the type parameter
* @param is the is
* @param valueTypeRef the value type ref
* @return the t
* @throws IOException the io exception
*/
public static <T> T jsonGetObject(ServletInputStream is, TypeReference<T> valueTypeRef) throws IOException {
return OBJ_MAPPER.readValue(inputStream2String(is), valueTypeRef);
}
/**
* Json get object t.
*
* @param <T> the type parameter
* @param json the json
* @param valueTypeRef the value type ref
* @return the t
* @throws IOException the io exception
*/
public static <T> T jsonGetObject(String json, TypeReference<T> valueTypeRef) throws IOException {
return OBJ_MAPPER.readValue(json, valueTypeRef);
}
/**
* Validate list.
*

86
cs-integrate-test/pom.xml Normal file
View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cf.cs</groupId>
<artifactId>IntegrateService</artifactId>
<version>0.0.1-dev</version>
</parent>
<artifactId>cs-integrate-test</artifactId>
<name>cs-integrate-test</name>
<description>cs-integrate-test</description>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-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.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.11</version>
</dependency>
<dependency>
<groupId>com.cf.cs</groupId>
<artifactId>cs-restful</artifactId>
<version>${cs-package.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
<skip>false</skip>
<includes>
<include>**/*.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.11</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,13 @@
package com.cf.cs.integratetest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CsIntegrateTestApplication {
public static void main(String[] args) {
SpringApplication.run(CsIntegrateTestApplication.class, args);
}
}

View File

@ -0,0 +1,16 @@
package com.cf.cs.integratetest;
import com.cf.cs.integratetest.controller.CommonFrameworkApiTest;
import com.cf.cs.integratetest.controller.OperationLogApiTest;
import com.cf.cs.integratetest.controller.PermissionManagerApiTest;
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,
PermissionManagerApiTest.class})
@DisplayName("接口集成测试")
@Suite
public class IntegrationTestSuite {
}

View File

@ -0,0 +1,171 @@
package com.cf.cs.integratetest.common;
import com.cf.cs.base.common.ConstValue;
import com.cf.cs.base.common.ErrorCode;
import com.cf.cs.base.common.ProtoCryptoType;
import com.cf.cs.base.misc.HelperUtils;
import com.cf.cs.protocol.config.ProtocolConfigure;
import com.cf.cs.protocol.pojo.dto.LoginReq;
import com.cf.cs.protocol.pojo.dto.ProtocolReq;
import com.cf.cs.protocol.pojo.po.BaseRespStatus;
import com.cf.cs.protocol.pojo.vo.LoginResp;
import com.cf.cs.protocol.pojo.vo.ProtocolResp;
import com.cf.cs.protocol.service.ProtocolSecurityService;
import jakarta.annotation.Resource;
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;
@Resource
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> 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());
}
public <T extends BaseRespStatus> void AssertValidCommonResp(T resp) {
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());
}
}

View File

@ -0,0 +1,47 @@
package com.cf.cs.integratetest.controller;
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.DisplayName;
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
@DisplayName("获取版本信息")
void testGetVersion() throws Exception {
VersionResp resp = (VersionResp) performanceRestful(RequestMethod.GET, null, "/api/version", new Class[]{VersionResp.class});
AssertValidCommonResp(resp);
Assertions.assertNotNull(resp.getVersion());
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
@DisplayName("获取版本信息(POST)")
void testGetVersionV2() throws Exception {
VersionResp resp = (VersionResp) performanceRestful(RequestMethod.POST, null, "/api/version", new Class[]{VersionResp.class});
AssertValidCommonResp(resp);
Assertions.assertNotNull(resp.getVersion());
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,107 @@
package com.cf.cs.integratetest.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.OperationLogDetailsReq;
import com.cmhi.cf.restapi.pojo.dto.OperationLogReq;
import com.cmhi.cf.restapi.pojo.po.OperationLogSummary;
import com.cmhi.cf.restapi.pojo.vo.OperationLogDetailsResp;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestMethodOrder;
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.ArrayList;
import java.util.List;
@ExtendWith({SpringExtension.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@Transactional
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class OperationLogApiTest extends TestBaseAuthentication {
private final List<Long> optIdArray = new ArrayList<>();
@Test
@Order(1)
@DisplayName("获取操作日志摘要(分页)")
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;
AssertValidCommonResp(resp);
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());
optIdArray.add(o.getId());
});
}
@Test
@Order(2)
@DisplayName("获取操作日志详情")
void testGetDetails() throws Exception {
Assertions.assertFalse(optIdArray.isEmpty());
OperationLogDetailsReq req = new OperationLogDetailsReq(optIdArray);
Object obj = performanceRestful(RequestMethod.POST, req, "/api/operation/details",
new Class[] {OperationLogDetailsResp.class});
Assertions.assertNotNull(obj);
OperationLogDetailsResp resp = (OperationLogDetailsResp) obj;
AssertValidCommonResp(resp);
Assertions.assertNotNull(resp.getOperationLog());
Assertions.assertFalse(resp.getOperationLog().isEmpty());
resp.getOperationLog().forEach(k -> {
Assertions.assertEquals(k.getStatus(), ErrorCode.ERR_OK.getCode());
AssertValidString(k.getRequest());
AssertValidString(k.getResult());
AssertValidString(k.getRequestHeaders());
Assertions.assertNotNull(k.getId());
});
}
}

View File

@ -0,0 +1,224 @@
package com.cf.cs.integratetest.controller;
import com.cmhi.cf.authentication.pojo.dto.IdArrayReq;
import com.cmhi.cf.authentication.pojo.dto.RegisterResourceReq;
import com.cmhi.cf.authentication.pojo.dto.UserIdReq;
import com.cmhi.cf.authentication.pojo.po.ResourceInfo;
import com.cmhi.cf.authentication.pojo.vo.GetRoleResp;
import com.cmhi.cf.authentication.pojo.vo.RegisterResourceResp;
import com.cmhi.cf.authentication.pojo.vo.UserResPermInfoResp;
import com.cmhi.cf.common.ErrorCode;
import com.cmhi.cf.common.TestBaseAuthentication;
import com.cmhi.cf.database.authentication.entity.User;
import com.cmhi.cf.database.authentication.service.UserService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
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.ArrayList;
import java.util.List;
import java.util.UUID;
@ExtendWith({SpringExtension.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@Transactional
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class PermissionManagerApiTest extends TestBaseAuthentication {
private final List<String> addResUid = new ArrayList<>();
@Autowired
private UserService userService;
@Test
@DisplayName("获取当前用户资源信息")
void testGetCurrentUserResourcePermission() throws Exception {
UserResPermInfoResp resp = (UserResPermInfoResp) performanceRestful(RequestMethod.GET, null, "/api/permission/resourcePermission",
new Class[] {UserResPermInfoResp.class});
AssertValidCommonResp(resp);
Assertions.assertNotNull(resp.getResPermission());
AssertValidString(resp.getUserId());
AssertValidString(resp.getUsername());
Assertions.assertFalse(resp.getResPermission().isEmpty());
resp.getResPermission().forEach(k -> {
Assertions.assertNotNull(k.getId());
AssertValidString(k.getHttpMethod());
AssertValidString(k.getPath());
AssertValidString(k.getName());
Assertions.assertNotNull(k.getResTypeId());
Assertions.assertNotNull(k.getEnable());
});
}
@Test
@DisplayName("获取用户资源信息")
void testGetUserResourcePermission() throws Exception {
User user = userService.getAccountUserByName("admin");
Assertions.assertNotNull(user);
AssertValidString(user.getUid());
UserResPermInfoResp resp = (UserResPermInfoResp) performanceRestful(RequestMethod.POST, new UserIdReq(user.getUid()),
"/api/permission/resourcePermission",
new Class[] {UserResPermInfoResp.class});
AssertValidCommonResp(resp);
Assertions.assertNotNull(resp.getResPermission());
AssertValidString(resp.getUserId());
AssertValidString(resp.getUsername());
Assertions.assertFalse(resp.getResPermission().isEmpty());
resp.getResPermission().forEach(k -> {
Assertions.assertNotNull(k.getId());
AssertValidString(k.getHttpMethod());
AssertValidString(k.getPath());
AssertValidString(k.getName());
Assertions.assertNotNull(k.getResTypeId());
Assertions.assertNotNull(k.getEnable());
});
}
@Test
@DisplayName("不存在的用户获取资源信息")
void testGetUserResourcePermission_UserServiceGetAccountUserByUidReturnsNull() {
User user = userService.getAccountUserByUid("ff99fd68-14bf-4fd6-9320-bab85839245c");
Assertions.assertNull(user);
}
@Test
@DisplayName("获取用户资源信息, 当前用户无资源")
void testGetUserResourcePermission_UserServiceGetUserResourcePermReturnsNoItems() throws Exception {
User user = userService.getAccountUserByName("guest");
Assertions.assertNotNull(user);
AssertValidString(user.getUid());
UserResPermInfoResp resp = (UserResPermInfoResp) performanceRestful(RequestMethod.POST, new UserIdReq(user.getUid()),
"/api/permission/resourcePermission",
new Class[] {UserResPermInfoResp.class});
AssertValidCommonResp(resp);
Assertions.assertNotNull(resp.getResPermission());
AssertValidString(resp.getUserId());
AssertValidString(resp.getUsername());
Assertions.assertFalse(resp.getResPermission().isEmpty());
resp.getResPermission().forEach(k -> {
Assertions.assertNotNull(k.getId());
AssertValidString(k.getHttpMethod());
AssertValidString(k.getPath());
AssertValidString(k.getName());
Assertions.assertNotNull(k.getResTypeId());
Assertions.assertNotNull(k.getEnable());
Assertions.assertFalse(k.getEnable());
});
}
@Test
@DisplayName("获取当前所有用户组")
void testGetAllRoles() throws Exception {
GetRoleResp resp = (GetRoleResp) performanceRestful(RequestMethod.GET, null, "/api/permission/allRoles",
new Class[] {GetRoleResp.class});
AssertValidCommonResp(resp);
Assertions.assertNotNull(resp.getRoles());
Assertions.assertFalse(resp.getRoles().isEmpty());
resp.getRoles().forEach(k -> {
Assertions.assertNotNull(k.getId());
AssertValidString(k.getDescription());
Assertions.assertNotNull(k.getName());
Assertions.assertNotNull(k.getAvailable());
});
}
@Test
@DisplayName("删除不存在的资源")
void testRemoveResourceById_UserServiceReturnsNoItems() throws Exception {
List<String> rid = new ArrayList<>();
for (int i = 0; i < 10; i++) {
rid.add(UUID.randomUUID().toString());
}
IdArrayReq req = new IdArrayReq(rid);
RegisterResourceResp resp = (RegisterResourceResp) performanceRestful(RequestMethod.DELETE, req,
"/api/permission/resource",
new Class[] {RegisterResourceResp.class});
AssertValidCommonResp(resp);
Assertions.assertNotNull(resp.getResult());
Assertions.assertEquals(resp.getResult().size(), rid.size());
resp.getResult().forEach(k -> {
Assertions.assertEquals(k.getStatus(), ErrorCode.ERR_NOSUCHITEM.getCode());
Assertions.assertNotNull(k.getRid());
});
}
@Test
@DisplayName("注册新资源")
void testRegisterResource() throws Exception {
addResUid.clear();
List<ResourceInfo> resList = new ArrayList<>();
resList.add(ResourceInfo.builder()
.path("/api/custom/show")
.name("show")
.resTypeId(0)
.httpMethod(new ArrayList<>() {{add("POST");}})
.build());
resList.add(ResourceInfo.builder()
.path("/api/custom/List")
.name("List")
.resTypeId(1)
.httpMethod(new ArrayList<>() {{add("PUT");}})
.build());
RegisterResourceReq req = RegisterResourceReq.builder()
.resources(resList)
.build();
RegisterResourceResp resp = (RegisterResourceResp) performanceRestful(RequestMethod.PUT, req,
"/api/permission/resource",
new Class[] {RegisterResourceResp.class});
AssertValidCommonResp(resp);
Assertions.assertNotNull(resp.getResult());
Assertions.assertEquals(resp.getResult().size(), resList.size());
resp.getResult().forEach(k -> {
AssertValidCommonResp(k);
AssertValidString(k.getRid());
AssertValidString(k.getPath());
AssertValidString(k.getHttpMethod());
Assertions.assertNotNull(k.getResTypeId());
addResUid.add(k.getRid());
});
}
@Test
@DisplayName("删除资源")
void testRemoveResourceById() throws Exception {
testRegisterResource();
IdArrayReq req = new IdArrayReq(addResUid);
RegisterResourceResp resp = (RegisterResourceResp) performanceRestful(RequestMethod.DELETE, req,
"/api/permission/resource",
new Class[] {RegisterResourceResp.class});
AssertValidCommonResp(resp);
Assertions.assertNotNull(resp.getResult());
Assertions.assertEquals(resp.getResult().size(), addResUid.size());
resp.getResult().forEach(k -> {
AssertValidCommonResp(k);
AssertValidString(k.getRid());
Assertions.assertTrue(addResUid.contains(k.getRid()));
});
}
}

View File

@ -0,0 +1,38 @@
package com.cf.cs.integratetest.controller;
import com.cmhi.cf.common.TestBaseAuthentication;
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;
@ExtendWith({SpringExtension.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@Transactional
public class SystemDictControllerTest extends TestBaseAuthentication {
@Test
void testGetEnumDictionary() throws Exception {
}
@Test
void testGetEnumDictionary_DictionaryServiceReturnsNoItems() throws Exception {
}
@Test
void testGetEnumDictionaryContent() throws Exception {
}
@Test
void testGetEnumDictionaryContent_DictionaryServiceReturnsNoItems() throws Exception {
}
@Test
void testCreateNewDictionary() throws Exception {
}
}

View File

@ -0,0 +1,43 @@
package com.cf.cs.integratetest.controller;
import com.cmhi.cf.common.TestBaseAuthentication;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestMethodOrder;
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;
@ExtendWith({SpringExtension.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@Transactional
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class UserManagerApiTest extends TestBaseAuthentication {
@Test
void testGetUserInfoById() throws Exception {
}
@Test
void testGetAllUserInfoPaged() throws Exception {
}
@Test
void testGetCurrentUserInfo() throws Exception {
}
@Test
void testCreateNewUser() throws Exception {
}
@Test
void testRemoveUser() throws Exception {
}
}

View File

@ -0,0 +1,119 @@
package com.cf.cs.protocol.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;
/**
* The type Json parameterized type.
*
* @author xajhuang @163.com
*/
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 = (var3 != null ? var3 : var1.getDeclaringClass());
this.validateConstructorArguments();
}
private void validateConstructorArguments() {
TypeVariable<?>[] var1 = this.rawType.getTypeParameters();
if (var1.length != this.actualTypeArguments.length) {
throw new MalformedParameterizedTypeException();
}
}
@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);
}
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;
for (Type var6 : this.actualTypeArguments) {
if (!var2) {
var1.append(", ");
}
var1.append(var6.getTypeName());
var2 = false;
}
var1.append(">");
}
return var1.toString();
}
/**
* Make json parameterized type.
*
* @param var0 the var 0
* @param var1 the var 1
* @param var2 the var 2
* @return the json parameterized type
*/
public static JsonParameterizedType make(Class<?> var0, Type[] var1, Type var2) {
return new JsonParameterizedType(var0, var1, var2);
}
}

View File

@ -0,0 +1,179 @@
package com.cf.cs.protocol.misc;
import com.cf.cs.base.config.ObjectMapperProvider;
import com.cf.cs.base.misc.HelperUtils;
import com.cf.cs.protocol.pojo.po.BaseRespStatus;
import com.cf.cs.protocol.pojo.vo.ProtocolResp;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletInputStream;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Stack;
/**
* The type Protocol json utils.
*
* @author xajhuang @163.com
*/
public class ProtocolJsonUtils {
private static final ObjectMapper OBJ_MAPPER = ObjectMapperProvider.getMapper();
/**
* Get json bytes byte [ ].
*
* @param <T> the type parameter
* @param obj the obj
* @param charset the charset
* @return the byte [ ]
* @throws JsonProcessingException the json processing exception
*/
public static <T> byte[] getJsonBytes(T obj, Charset charset) throws JsonProcessingException {
return OBJ_MAPPER.writeValueAsString(obj).getBytes(charset);
}
/**
* Get json bytes byte [ ].
*
* @param <T> the type parameter
* @param obj the obj
* @return the byte [ ]
* @throws JsonProcessingException the json processing exception
*/
public static <T> byte[] getJsonBytes(T obj) throws JsonProcessingException {
return OBJ_MAPPER.writeValueAsString(obj).getBytes(StandardCharsets.UTF_8);
}
/**
* Json get object object.
*
* @param <T> the type parameter
* @param json the json
* @param valueType the value type
* @return the object
* @throws JsonProcessingException the json processing exception
*/
public static <T> Object jsonGetObject(String json, Class<T> valueType) throws JsonProcessingException {
return OBJ_MAPPER.readValue(json, valueType);
}
/**
* Json get object t.
*
* @param <T> the type parameter
* @param is the is
* @param valueTypeRef the value type ref
* @return the t
* @throws IOException the io exception
*/
public static <T> T jsonGetObject(ServletInputStream is, TypeReference<T> valueTypeRef) throws IOException {
return OBJ_MAPPER.readValue(HelperUtils.inputStream2String(is), valueTypeRef);
}
/**
* Json get object t.
*
* @param <T> the type parameter
* @param json the json
* @param valueTypeRef the value type ref
* @return the t
* @throws IOException the io exception
*/
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() {
@Override
public Type[] getActualTypeArguments() {
// 返回实际类型参数例如List<String>的String
return new Type[] {c};
}
@Override
public Type getRawType() {
// 返回原始类型例如List
return ProtocolResp.class;
}
@Override
public Type getOwnerType() {
// 返回类型所在的类对于顶级类是null
return null;
}
};
}
/**
* Json get protocol resp protocol resp.
*
* @param <T> the type parameter
* @param jsonString the json string
* @param subClass the sub class
* @return the protocol resp
* @throws JsonProcessingException the json processing exception
*/
public static <T> ProtocolResp<? extends BaseRespStatus> jsonGetProtocolResp(String jsonString,
Class<T> subClass) throws JsonProcessingException {
return OBJ_MAPPER.readValue(jsonString, new TypeReference<>() {
@Override
public Type getType() {
return createRespType(subClass);
}
});
}
private static Type createRespType(Class<?>[] c) {
if (c.length == 1) {
return createRespType(c[0]);
}
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;
}
/**
* Json get protocol resp protocol resp.
*
* @param jsonString the json string
* @param subClass the sub class
* @return the protocol resp
* @throws JsonProcessingException the json processing exception
*/
public static ProtocolResp<? extends BaseRespStatus> jsonGetProtocolResp(String jsonString,
Class<?>[] subClass) throws JsonProcessingException {
return OBJ_MAPPER.readValue(jsonString, new TypeReference<>() {
@Override
public Type getType() {
return createRespType(subClass);
}
});
}
}

View File

@ -33,6 +33,7 @@
<module>cs-database</module>
<module>cs-authentication</module>
<module>cs-restful</module>
<module>cs-integrate-test</module>
</modules>
<dependencies>