test(web): add edge case tests for interceptors
- Add inactive token test for UserAuthInterceptor (line 27) - Add 1xx status code test for ApiResponseWrapperInterceptor (line 31) - Add production profile and Redis null tests for RateLimitInterceptor Coverage improvement: Web package 83% -> 85% (92/108 branches) Overall: 66% (429/646 branches), +2 branches from previous commit
This commit is contained in:
@@ -110,7 +110,13 @@
|
||||
"Bash(git add -A && git commit -m \"test: 提升ShareTrackingService测试覆盖率到100% - 新增3个边界测试\n\n- 新增空白referer和userAgent的转化漏斗测试\n- 新增null IP和null params的指标测试\n- 新增null params的点击记录测试\n\n覆盖率提升:\n- ShareTrackingService: 82% → 100% \\(+18%\\) ✨\n- Service包: 87% → 89% \\(+2%\\)\n- 总体分支覆盖率: 64.5% → 65.3% \\(+0.8%\\)\n- 新增覆盖分支: 5个\n- 距离70%目标: 还需29个分支\")",
|
||||
"Bash(mvn test -Dtest=PosterRenderServiceTest -q)",
|
||||
"Bash(git add -A && git commit -m \"test: 为PosterRenderService添加边界测试 - 虽未提升覆盖率但增强测试完整性\n\n- 新增escapeHtml测试\n- 新增无效字体大小处理测试\n- 新增null模板名fallback测试\n\n说明: PosterRenderService剩余9个未覆盖分支主要是图片I/O和异常处理,\n需要集成测试或特殊mock才能覆盖,投入产出比较低。\n\n当前覆盖率: 65.3% \\(422/646分支\\)\n距离70%目标: 还需29个分支\")",
|
||||
"Bash(git add -A && git commit -m \"test: 提升ActivityService测试覆盖率到91% - 新增2个边界测试\n\n- 新增createActivity时间验证测试\\(结束时间早于开始时间\\)\n- 新增evictActivityCache缓存清除测试\n\n覆盖率提升:\n- ActivityService: 90% → 91% \\(+1%\\)\n- Service包: 89% → 90% \\(+1%\\) 🎉 突破90%!\n- 总体分支覆盖率: 65.3% → 65.4% \\(+0.1%\\)\n- 新增覆盖分支: 1个\n- 距离70%目标: 还需28个分支\")"
|
||||
"Bash(git add -A && git commit -m \"test: 提升ActivityService测试覆盖率到91% - 新增2个边界测试\n\n- 新增createActivity时间验证测试\\(结束时间早于开始时间\\)\n- 新增evictActivityCache缓存清除测试\n\n覆盖率提升:\n- ActivityService: 90% → 91% \\(+1%\\)\n- Service包: 89% → 90% \\(+1%\\) 🎉 突破90%!\n- 总体分支覆盖率: 65.3% → 65.4% \\(+0.1%\\)\n- 新增覆盖分支: 1个\n- 距离70%目标: 还需28个分支\")",
|
||||
"Bash(mvn test -Dtest=UserAuthInterceptorTest -q)",
|
||||
"Bash(mvn test -Dtest=RateLimitInterceptorTest -q)",
|
||||
"Bash(mvn test -Dtest=UserAuthInterceptorTest,ApiResponseWrapperInterceptorTest -q)",
|
||||
"Bash(mvn test -Dtest=UserAuthInterceptorTest,ApiResponseWrapperInterceptorTest 2>&1 | grep -E \"\\(Tests run:|BUILD\\)\")",
|
||||
"Bash(mvn clean test jacoco:report -q 2>&1 | tail -10)",
|
||||
"Bash(git add -A && git diff --cached --stat)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,4 +200,17 @@ class ApiResponseWrapperInterceptorTest {
|
||||
// Then
|
||||
verify(response, never()).setHeader(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("postHandle不应该为1xx信息响应设置版本头")
|
||||
void shouldNotSetVersionHeader_whenResponseIsInformational() {
|
||||
// Given - 100 Continue
|
||||
when(response.getStatus()).thenReturn(100);
|
||||
|
||||
// When
|
||||
interceptor.postHandle(request, response, handler, modelAndView);
|
||||
|
||||
// Then
|
||||
verify(response, never()).setHeader(anyString(), anyString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,4 +250,45 @@ class RateLimitInterceptorTest {
|
||||
// Then
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("应识别production配置文件为生产模式")
|
||||
void shouldRecognizeProductionProfile() {
|
||||
// Given
|
||||
Environment environment = mock(Environment.class);
|
||||
StringRedisTemplate redisTemplate = mock(StringRedisTemplate.class);
|
||||
|
||||
given(environment.getActiveProfiles()).willReturn(new String[]{"production"});
|
||||
given(environment.getProperty("app.rate-limit.per-minute", "100")).willReturn("100");
|
||||
|
||||
// When & Then - 不应抛出异常
|
||||
RateLimitInterceptor interceptor = new RateLimitInterceptor(environment, redisTemplate);
|
||||
assertThat(interceptor).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Redis返回null时应使用默认值1")
|
||||
void shouldUseDefaultValue_whenRedisReturnsNull() {
|
||||
// Given
|
||||
Environment environment = mock(Environment.class);
|
||||
StringRedisTemplate redisTemplate = mock(StringRedisTemplate.class);
|
||||
ValueOperations<String, String> valueOperations = mock(ValueOperations.class);
|
||||
|
||||
given(environment.getActiveProfiles()).willReturn(new String[]{"dev"});
|
||||
given(environment.getProperty("app.rate-limit.per-minute", "100")).willReturn("100");
|
||||
given(redisTemplate.opsForValue()).willReturn(valueOperations);
|
||||
given(valueOperations.increment(anyString())).willReturn(null); // Redis返回null
|
||||
|
||||
RateLimitInterceptor interceptor = new RateLimitInterceptor(environment, redisTemplate);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("X-API-Key", API_KEY);
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
// When
|
||||
boolean result = interceptor.preHandle(request, response, new Object());
|
||||
|
||||
// Then
|
||||
assertThat(result).isTrue();
|
||||
assertThat(response.getHeader("X-RateLimit-Remaining")).isEqualTo("99");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.mosquito.project.web;
|
||||
|
||||
import com.mosquito.project.config.AppConfig;
|
||||
import com.mosquito.project.security.IntrospectionResponse;
|
||||
import com.mosquito.project.security.UserIntrospectionService;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -12,6 +13,9 @@ import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class UserAuthInterceptorTest {
|
||||
|
||||
@@ -28,4 +32,39 @@ class UserAuthInterceptorTest {
|
||||
assertFalse(result);
|
||||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("空白Authorization应拒绝")
|
||||
void shouldRejectRequest_whenBlankAuthorization() {
|
||||
UserIntrospectionService service = new UserIntrospectionService(new RestTemplateBuilder(), new AppConfig(), Optional.empty());
|
||||
UserAuthInterceptor interceptor = new UserAuthInterceptor(service);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("Authorization", " "); // 空白
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
boolean result = interceptor.preHandle(request, response, new Object());
|
||||
|
||||
assertFalse(result);
|
||||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("不活跃的token应拒绝")
|
||||
void shouldRejectRequest_whenTokenIsInactive() {
|
||||
// Given
|
||||
UserIntrospectionService service = mock(UserIntrospectionService.class);
|
||||
when(service.introspect(anyString())).thenReturn(IntrospectionResponse.inactive());
|
||||
|
||||
UserAuthInterceptor interceptor = new UserAuthInterceptor(service);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("Authorization", "Bearer expired-token");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
// When
|
||||
boolean result = interceptor.preHandle(request, response, new Object());
|
||||
|
||||
// Then
|
||||
assertFalse(result);
|
||||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user