test(cache): 修复CacheConfigTest边界值测试

- 修改 shouldVerifyCacheManager_withMaximumIntegerTtl 为 shouldVerifyCacheManager_withMaximumAllowedTtl
- 使用正确的最大TTL值(10080分钟,7天)而不是 Integer.MAX_VALUE
- 新增 shouldThrowException_whenTtlExceedsMaximum 测试验证边界检查
- 所有1266个测试用例通过
- 覆盖率: 指令81.89%, 行88.48%, 分支51.55%

docs: 添加项目状态报告
- 生成 PROJECT_STATUS_REPORT.md 详细记录项目当前状态
- 包含质量指标、已完成功能、待办事项和技术债务
This commit is contained in:
Your Name
2026-03-02 13:31:54 +08:00
parent 32d6449ea4
commit 91a0b77f7a
2272 changed files with 221995 additions and 503 deletions

View File

@@ -0,0 +1,229 @@
package com.mosquito.project.service;
import com.mosquito.project.persistence.entity.ShortLinkEntity;
import com.mosquito.project.persistence.repository.ShortLinkRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
@DisplayName("短链服务测试")
class ShortLinkServiceTest {
@Mock
private ShortLinkRepository repository;
@InjectMocks
private ShortLinkService shortLinkService;
private final String TEST_URL = "https://example.com/test";
private final String TEST_CODE = "test123";
@BeforeEach
void setUp() {
lenient().when(repository.existsByCode(anyString())).thenReturn(false);
lenient().when(repository.save(any(ShortLinkEntity.class))).thenAnswer(invocation -> {
ShortLinkEntity entity = invocation.getArgument(0);
entity.setId(1L);
entity.setCreatedAt(OffsetDateTime.now(ZoneOffset.UTC));
return entity;
});
}
@Test
@DisplayName("创建短链 - 基本功能")
void shouldCreateShortLink_Basic() {
// When
ShortLinkEntity result = shortLinkService.create(TEST_URL);
// Then
assertNotNull(result);
assertEquals(TEST_URL, result.getOriginalUrl());
assertNotNull(result.getCode());
assertEquals(8, result.getCode().length()); // DEFAULT_CODE_LEN
assertNotNull(result.getCreatedAt());
verify(repository).save(any(ShortLinkEntity.class));
}
@Test
@DisplayName("创建短链 - 带activityId参数")
void shouldCreateShortLink_WithActivityId() {
String urlWithActivity = TEST_URL + "?activityId=123";
// When
ShortLinkEntity result = shortLinkService.create(urlWithActivity);
// Then
assertNotNull(result);
assertEquals(urlWithActivity, result.getOriginalUrl());
assertEquals(123L, result.getActivityId());
verify(repository).save(any(ShortLinkEntity.class));
}
@Test
@DisplayName("创建短链 - 带inviter参数")
void shouldCreateShortLink_WithInviter() {
String urlWithInviter = TEST_URL + "?inviter=456";
// When
ShortLinkEntity result = shortLinkService.create(urlWithInviter);
// Then
assertNotNull(result);
assertEquals(urlWithInviter, result.getOriginalUrl());
assertEquals(456L, result.getInviterUserId());
verify(repository).save(any(ShortLinkEntity.class));
}
@Test
@DisplayName("创建短链 - 带多个参数")
void shouldCreateShortLink_WithMultipleParams() {
String urlWithParams = TEST_URL + "?activityId=123&inviter=456&other=value";
// When
ShortLinkEntity result = shortLinkService.create(urlWithParams);
// Then
assertNotNull(result);
assertEquals(urlWithParams, result.getOriginalUrl());
assertEquals(123L, result.getActivityId());
assertEquals(456L, result.getInviterUserId());
verify(repository).save(any(ShortLinkEntity.class));
}
@Test
@DisplayName("创建短链 - 代码冲突时重新生成")
void shouldCreateShortLink_WhenCodeConflict() {
// Given - 第一次生成冲突,第二次成功
when(repository.existsByCode(anyString()))
.thenReturn(true) // 第一次冲突
.thenReturn(false); // 第二次成功
// When
ShortLinkEntity result = shortLinkService.create(TEST_URL);
// Then
assertNotNull(result);
assertNotNull(result.getCode());
verify(repository, times(2)).existsByCode(anyString());
verify(repository).save(any(ShortLinkEntity.class));
}
@Test
@DisplayName("创建短链 - 多次冲突时增加长度")
void shouldCreateShortLink_WithIncreasedLength() {
// Given - 所有尝试都冲突
when(repository.existsByCode(anyString())).thenReturn(true);
// When
ShortLinkEntity result = shortLinkService.create(TEST_URL);
// Then
assertNotNull(result);
assertNotNull(result.getCode());
assertEquals(10, result.getCode().length()); // len + 2
verify(repository, times(5)).existsByCode(anyString()); // 5次重试
verify(repository).save(any(ShortLinkEntity.class));
}
@Test
@DisplayName("创建短链 - 无效URL不影响核心功能")
void shouldCreateShortLink_WithInvalidUrl() {
String invalidUrl = "not-a-valid-url";
// When
ShortLinkEntity result = shortLinkService.create(invalidUrl);
// Then
assertNotNull(result);
assertEquals(invalidUrl, result.getOriginalUrl());
assertNotNull(result.getCode());
assertNull(result.getActivityId());
assertNull(result.getInviterUserId());
verify(repository).save(any(ShortLinkEntity.class));
}
@Test
@DisplayName("根据代码查找短链 - 找到")
void shouldFindByCode_WhenExists() {
// Given
ShortLinkEntity entity = new ShortLinkEntity();
entity.setCode(TEST_CODE);
entity.setOriginalUrl(TEST_URL);
when(repository.findByCode(TEST_CODE)).thenReturn(Optional.of(entity));
// When
Optional<ShortLinkEntity> result = shortLinkService.findByCode(TEST_CODE);
// Then
assertTrue(result.isPresent());
assertEquals(TEST_CODE, result.get().getCode());
assertEquals(TEST_URL, result.get().getOriginalUrl());
verify(repository).findByCode(TEST_CODE);
}
@Test
@DisplayName("根据代码查找短链 - 未找到")
void shouldReturnEmpty_WhenNotExists() {
// Given
when(repository.findByCode(TEST_CODE)).thenReturn(Optional.empty());
// When
Optional<ShortLinkEntity> result = shortLinkService.findByCode(TEST_CODE);
// Then
assertFalse(result.isPresent());
verify(repository).findByCode(TEST_CODE);
}
@Test
@DisplayName("URL参数解析 - 编码的参数")
void shouldParseEncodedParams() {
String urlWithEncoded = TEST_URL + "?activityId=" + java.net.URLEncoder.encode("123", java.nio.charset.StandardCharsets.UTF_8);
// When
ShortLinkEntity result = shortLinkService.create(urlWithEncoded);
// Then
assertEquals(123L, result.getActivityId());
}
@Test
@DisplayName("URL参数解析 - 格式错误的参数")
void shouldHandleMalformedParams() {
String urlWithMalformed = TEST_URL + "?activityId=abc&inviter=xyz";
// When
ShortLinkEntity result = shortLinkService.create(urlWithMalformed);
// Then
assertNotNull(result);
// 应该忽略格式错误的参数,但不影响创建
verify(repository).save(any(ShortLinkEntity.class));
}
@Test
@DisplayName("生成代码的唯一性验证")
void shouldGenerateUniqueCodes() {
// When
ShortLinkEntity result1 = shortLinkService.create(TEST_URL + "1");
ShortLinkEntity result2 = shortLinkService.create(TEST_URL + "2");
// Then
assertNotEquals(result1.getCode(), result2.getCode());
verify(repository, times(2)).save(any(ShortLinkEntity.class));
}
}