新疆后端项目
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.renkang</groupId>
|
||||
<artifactId>functional-modules</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>renkang-test</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-base-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.renkang;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.UnavailableSecurityManagerException;
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.subject.support.SubjectThreadState;
|
||||
import org.apache.shiro.util.LifecycleUtils;
|
||||
import org.apache.shiro.util.ThreadState;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
|
||||
/**
|
||||
* @author Jiang Shunzhi
|
||||
*/
|
||||
public abstract class AbstractShiroTest {
|
||||
|
||||
private static ThreadState subjectThreadState;
|
||||
|
||||
public AbstractShiroTest() {
|
||||
}
|
||||
|
||||
private static void doClearSubject() {
|
||||
if (subjectThreadState != null) {
|
||||
subjectThreadState.clear();
|
||||
subjectThreadState = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected static org.apache.shiro.mgt.SecurityManager getSecurityManager() {
|
||||
return SecurityUtils.getSecurityManager();
|
||||
}
|
||||
|
||||
protected static void setSecurityManager(org.apache.shiro.mgt.SecurityManager securityManager) {
|
||||
SecurityUtils.setSecurityManager(securityManager);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDownShiro() {
|
||||
doClearSubject();
|
||||
try {
|
||||
SecurityManager securityManager = getSecurityManager();
|
||||
LifecycleUtils.destroy(securityManager);
|
||||
} catch (UnavailableSecurityManagerException e) {
|
||||
//we don't care about this when cleaning up the test environment
|
||||
//(for example, maybe the subclass is a unit test and it didn't
|
||||
// need a SecurityManager instance because it was using only
|
||||
// mock Subject instances)
|
||||
}
|
||||
setSecurityManager(null);
|
||||
}
|
||||
|
||||
protected Subject getSubject() {
|
||||
return SecurityUtils.getSubject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows subclasses to set the currently executing {@link Subject} instance.
|
||||
*
|
||||
* @param subject the Subject instance
|
||||
*/
|
||||
protected void setSubject(Subject subject) {
|
||||
clearSubject();
|
||||
subjectThreadState = createThreadState(subject);
|
||||
subjectThreadState.bind();
|
||||
}
|
||||
|
||||
protected ThreadState createThreadState(Subject subject) {
|
||||
return new SubjectThreadState(subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears Shiro's thread state, ensuring the thread remains clean for future test execution.
|
||||
*/
|
||||
protected void clearSubject() {
|
||||
doClearSubject();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.renkang;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import lombok.Getter;
|
||||
import org.apache.shiro.UnavailableSecurityManagerException;
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.jeecg.common.api.CommonAPI;
|
||||
import org.jeecg.common.config.mqtoken.UserTokenContext;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.TokenUtils;
|
||||
import org.jeecg.config.shiro.JwtToken;
|
||||
import org.jeecg.config.shiro.TokenThreadLocal;
|
||||
import org.jeecg.global.GlobalUtils;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Shunzhi Jiang
|
||||
* @since 2024/11/9
|
||||
*/
|
||||
public abstract class AbstractTestSupport extends AbstractShiroTest {
|
||||
|
||||
|
||||
@Autowired
|
||||
@Getter
|
||||
private CommonAPI commonAPI;
|
||||
|
||||
@Autowired
|
||||
@Getter
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
protected Subject adminSubject() {
|
||||
Subject subject = new Subject.Builder().buildSubject();
|
||||
String temporaryToken = GlobalUtils.getTemporaryToken();
|
||||
TokenThreadLocal.setToken(temporaryToken);
|
||||
UserTokenContext.setToken(temporaryToken);
|
||||
subject.login(new JwtToken(temporaryToken));
|
||||
return subject;
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
protected void setAdminSubject() {
|
||||
checkSecurityManager();
|
||||
setSubject(adminSubject());
|
||||
}
|
||||
|
||||
protected void checkSecurityManager() {
|
||||
try {
|
||||
getSecurityManager();
|
||||
} catch (UnavailableSecurityManagerException e) {
|
||||
setSecurityManager(applicationContext.getBean(SecurityManager.class));
|
||||
}
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
protected void clearTokenCache() {
|
||||
String token = getToken();
|
||||
redisUtil.del(CommonConstant.FAKE_USER_KEY_PREFIX + token, CommonConstant.PREFIX_USER_TOKEN + token);
|
||||
TokenThreadLocal.clear();
|
||||
UserTokenContext.remove();
|
||||
}
|
||||
|
||||
protected String getToken() {
|
||||
return TokenThreadLocal.getToken();
|
||||
}
|
||||
|
||||
protected <T> T getBean(Class<T> clazz) {
|
||||
return applicationContext.getBean(clazz);
|
||||
}
|
||||
|
||||
protected void fakeUser(String userId) {
|
||||
LoginUser loginUserById = TokenUtils.getLoginUserById(userId, commonAPI, redisUtil);
|
||||
if (Objects.isNull(loginUserById)) {
|
||||
throw new RuntimeException("未获取到模拟用户数据");
|
||||
}
|
||||
Subject subject = getSubject();
|
||||
Object principal = subject.getPrincipal();
|
||||
BeanUtil.copyProperties(loginUserById, principal);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.renkang;
|
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
/**
|
||||
* @author Jiang Shunzhi
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@ActiveProfiles("ut")
|
||||
public class DefaultTestSupport extends AbstractTestSupport {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.renkang;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.TokenUtils;
|
||||
import org.jeecg.config.shiro.ShiroRealm;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.RequestBuilder;
|
||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Shunzhi Jiang
|
||||
* @since 2024/11/9
|
||||
*/
|
||||
@AutoConfigureMockMvc
|
||||
public class MockMvcTestSupport extends DefaultTestSupport {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Autowired
|
||||
private ShiroRealm shiroRealm;
|
||||
|
||||
protected MockHttpServletRequestBuilder requestBuilder(HttpMethod httpMethod, String url) {
|
||||
return MockMvcRequestBuilders.request(httpMethod, url)
|
||||
.header(CommonConstant.X_ACCESS_TOKEN, getToken());
|
||||
}
|
||||
|
||||
protected MockMvc getMockMvc() {
|
||||
return mockMvc;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fakeUser(String userId) {
|
||||
LoginUser loginUserById = TokenUtils.getLoginUserById(userId, getCommonAPI(), getRedisUtil());
|
||||
if (Objects.isNull(loginUserById)) {
|
||||
throw new RuntimeException("未获取到模拟用户数据");
|
||||
}
|
||||
Subject subject = getSubject();
|
||||
Object principal = subject.getPrincipal();
|
||||
BeanUtil.copyProperties(loginUserById, principal);
|
||||
super.fakeUser(userId);
|
||||
String token = getToken();
|
||||
getRedisUtil().set(CommonConstant.FAKE_USER_KEY_PREFIX + token, loginUserById);
|
||||
getRedisUtil().expire(CommonConstant.FAKE_USER_KEY_PREFIX + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
|
||||
shiroRealm.getAuthorizationCache().remove(userId);
|
||||
}
|
||||
|
||||
protected MvcResult mockPrint(RequestBuilder requestBuilder) throws Exception {
|
||||
return getMockMvc().perform(requestBuilder)
|
||||
.andDo(MockMvcResultHandlers.print())
|
||||
.andReturn();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user