refactor: 统一实体/限流AOP化/精简日志/文件归位
This commit is contained in:
1 parent
0dce433849
commit
6b6c06370f
71 files changed
+751
-914
No files matched your search
@@ -0,0 +1,61 @@
|
||||
package com.youlai.boot.auth.service.impl;
|
||||
|
||||
import com.youlai.boot.common.exception.BusinessException;
|
||||
import com.youlai.boot.common.result.ResultCode;
|
||||
import com.youlai.boot.framework.captcha.service.CaptchaService;
|
||||
import com.youlai.boot.framework.integration.sms.enums.SmsTypeEnum;
|
||||
import com.youlai.boot.framework.integration.sms.service.SmsService;
|
||||
import com.youlai.boot.framework.security.token.TokenManager;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AuthServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
@Mock
|
||||
private TokenManager tokenManager;
|
||||
|
||||
@Mock
|
||||
private SmsService smsService;
|
||||
|
||||
@Mock
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Mock
|
||||
private CaptchaService captchaService;
|
||||
|
||||
@Test
|
||||
void should_not_cache_sms_code_when_send_fails() {
|
||||
when(smsService.sendSms(eq("13800138000"), eq(SmsTypeEnum.LOGIN), any(Map.class))).thenReturn(false);
|
||||
|
||||
AuthServiceImpl authService = new AuthServiceImpl(
|
||||
authenticationManager,
|
||||
tokenManager,
|
||||
smsService,
|
||||
redisTemplate,
|
||||
captchaService
|
||||
);
|
||||
|
||||
assertThatThrownBy(() -> authService.sendSmsCode("13800138000"))
|
||||
.isInstanceOf(BusinessException.class)
|
||||
.hasMessage("短信验证码发送失败");
|
||||
|
||||
verify(redisTemplate, never()).opsForValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.youlai.boot.file.service.impl;
|
||||
|
||||
import com.youlai.boot.common.exception.BusinessException;
|
||||
import com.youlai.boot.file.config.LocalFileProperties;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
class LocalFileServiceTest {
|
||||
|
||||
@TempDir
|
||||
Path storagePath;
|
||||
|
||||
@Test
|
||||
void should_reject_path_outside_storage_root() {
|
||||
LocalFileProperties properties = new LocalFileProperties();
|
||||
properties.setStoragePath(storagePath.toString());
|
||||
LocalFileService fileService = new LocalFileService(properties);
|
||||
|
||||
assertThatThrownBy(() -> fileService.deleteFile("../secret.txt"))
|
||||
.isInstanceOf(BusinessException.class)
|
||||
.hasMessage("文件路径不属于当前本地存储配置");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.youlai.boot.framework.web.advice;
|
||||
|
||||
import com.youlai.boot.common.result.Result;
|
||||
import com.youlai.boot.common.result.ResultCode;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class GlobalExceptionHandlerTest {
|
||||
|
||||
@Test
|
||||
void should_not_expose_unknown_exception_message() throws Exception {
|
||||
GlobalExceptionHandler handler = new GlobalExceptionHandler();
|
||||
|
||||
Result<Void> result = handler.handleException(new IllegalStateException("database password leaked"));
|
||||
|
||||
assertThat(result.getCode()).isEqualTo(ResultCode.SYSTEM_ERROR.getCode());
|
||||
assertThat(result.getMsg()).isEqualTo("系统异常,请稍后重试");
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.youlai.boot.framework.web.config;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class OperationLogExecutorConfigTest {
|
||||
|
||||
@Test
|
||||
void should_create_operation_log_executor() {
|
||||
Executor executor = new OperationLogExecutorConfig().operationLogExecutor();
|
||||
|
||||
assertThat(executor).isInstanceOf(ThreadPoolTaskExecutor.class);
|
||||
ThreadPoolTaskExecutor taskExecutor = (ThreadPoolTaskExecutor) executor;
|
||||
assertThat(taskExecutor.getThreadNamePrefix()).isEqualTo("operation-log-");
|
||||
assertThat(taskExecutor.getCorePoolSize()).isEqualTo(1);
|
||||
assertThat(taskExecutor.getMaxPoolSize()).isEqualTo(2);
|
||||
assertThat(taskExecutor.getThreadPoolExecutor().getQueue().remainingCapacity()).isEqualTo(1000);
|
||||
assertThat(taskExecutor.getThreadPoolExecutor().getRejectedExecutionHandler())
|
||||
.isInstanceOf(ThreadPoolExecutor.CallerRunsPolicy.class);
|
||||
|
||||
taskExecutor.shutdown();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.youlai.boot.security.filter;
|
||||
|
||||
import com.youlai.boot.common.constant.SecurityConstants;
|
||||
import com.youlai.boot.common.result.ResultCode;
|
||||
import com.youlai.boot.framework.security.filter.TokenAuthenticationFilter;
|
||||
import com.youlai.boot.framework.security.token.TokenManager;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.mock.web.MockFilterChain;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TokenAuthenticationFilterTest {
|
||||
|
||||
@Mock
|
||||
private TokenManager tokenManager;
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_clear_context_and_return_unauthorized_when_token_validation_fails() throws Exception {
|
||||
String token = "invalid-token";
|
||||
when(tokenManager.validateToken(token)).thenThrow(new IllegalStateException("token store unavailable"));
|
||||
SecurityContextHolder.getContext().setAuthentication(new org.springframework.security.authentication.TestingAuthenticationToken("old", null));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/api/v1/users");
|
||||
request.addHeader(HttpHeaders.AUTHORIZATION, SecurityConstants.BEARER_TOKEN_PREFIX + token);
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
new TokenAuthenticationFilter(tokenManager).doFilter(request, response, new MockFilterChain());
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(401);
|
||||
assertThat(response.getContentAsString()).contains(ResultCode.ACCESS_TOKEN_INVALID.getCode());
|
||||
assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user