test: 提升ShareTrackingService测试覆盖率到100% - 新增3个边界测试

- 新增空白referer和userAgent的转化漏斗测试
- 新增null IP和null params的指标测试
- 新增null params的点击记录测试

覆盖率提升:
- ShareTrackingService: 82% → 100% (+18%) 
- Service包: 87% → 89% (+2%)
- 总体分支覆盖率: 64.5% → 65.3% (+0.8%)
- 新增覆盖分支: 5个
- 距离70%目标: 还需29个分支
This commit is contained in:
Your Name
2026-03-03 16:54:54 +08:00
parent 52175fde22
commit f92818c73e
2 changed files with 96 additions and 1 deletions

View File

@@ -323,4 +323,97 @@ class ShareTrackingServiceTest {
click.setCreatedAt(OffsetDateTime.now(ZoneOffset.UTC));
return click;
}
@Test
@DisplayName("获取转化漏斗 - 处理空白referer和userAgent")
void shouldHandleBlankRefererAndUserAgent_InConversionFunnel() {
// Given
OffsetDateTime startTime = OffsetDateTime.now(ZoneOffset.UTC).minusDays(1);
OffsetDateTime endTime = OffsetDateTime.now(ZoneOffset.UTC);
List<LinkClickEntity> clicks = new ArrayList<>();
LinkClickEntity click1 = new LinkClickEntity();
click1.setCode(SHORT_CODE);
click1.setIp(IP);
click1.setUserAgent(" "); // blank userAgent
click1.setReferer(" "); // blank referer
click1.setCreatedAt(OffsetDateTime.now(ZoneOffset.UTC));
LinkClickEntity click2 = new LinkClickEntity();
click2.setCode(SHORT_CODE);
click2.setIp(IP);
click2.setUserAgent(null); // null userAgent
click2.setReferer("https://example.com");
click2.setCreatedAt(OffsetDateTime.now(ZoneOffset.UTC));
clicks.add(click1);
clicks.add(click2);
when(linkClickRepository.findByActivityIdAndCreatedAtBetween(ACTIVITY_ID, startTime, endTime))
.thenReturn(clicks);
// When
Map<String, Object> result = shareTrackingService.getConversionFunnel(ACTIVITY_ID, startTime, endTime);
// Then
assertEquals(2L, result.get("totalClicks"));
assertEquals(1L, result.get("withReferer")); // only click2 has non-blank referer
assertEquals(0L, result.get("withUserAgent")); // both are null or blank
}
@Test
@DisplayName("获取分享指标 - 处理null IP和null params")
void shouldHandleNullIpAndNullParams_InMetrics() {
// Given
OffsetDateTime startTime = OffsetDateTime.now(ZoneOffset.UTC).minusDays(1);
OffsetDateTime endTime = OffsetDateTime.now(ZoneOffset.UTC);
List<LinkClickEntity> clicks = new ArrayList<>();
LinkClickEntity click1 = new LinkClickEntity();
click1.setCode(SHORT_CODE);
click1.setIp(null); // null IP
click1.setUserAgent(USER_AGENT);
click1.setParams(null); // null params
click1.setCreatedAt(OffsetDateTime.now(ZoneOffset.UTC));
LinkClickEntity click2 = new LinkClickEntity();
click2.setCode(SHORT_CODE);
click2.setIp("192.168.1.1");
click2.setUserAgent(USER_AGENT);
click2.setParams(null); // null params
click2.setCreatedAt(OffsetDateTime.now(ZoneOffset.UTC));
clicks.add(click1);
clicks.add(click2);
when(linkClickRepository.findByActivityIdAndCreatedAtBetween(ACTIVITY_ID, startTime, endTime))
.thenReturn(clicks);
// When
ShareMetricsResponse result = shareTrackingService.getShareMetrics(ACTIVITY_ID, startTime, endTime);
// Then
assertEquals(2L, result.getTotalClicks());
assertEquals(1L, result.getUniqueVisitors()); // only click2 has IP
// Both clicks should have "unknown" source due to null params
Map<String, Long> expectedSources = Map.of("unknown", 2L);
assertEquals(expectedSources, result.getSourceDistribution());
}
@Test
@DisplayName("记录点击 - 处理null params不抛异常")
void shouldHandleNullParams_WhenRecordClick() {
// When
shareTrackingService.recordClick(SHORT_CODE, IP, USER_AGENT, REFERER, null);
// Then
verify(linkClickRepository).save(argThat(entity -> {
assertEquals(SHORT_CODE, entity.getCode());
assertNull(entity.getParams()); // params should remain null
return true;
}));
}
}