1、多 key 默认拼成 1 条企微通知 2、UTF-8 超过 4096 字节 → 按 key 拆开,每条带完整抬头,依次发送 3、条间间隔 200ms,降低机器人限频风险 4、CI 控制台会标明「超长已按 key 拆为 N 条」并逐条打印
This commit is contained in:
@@ -7,6 +7,7 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
@@ -55,11 +56,15 @@ class ReportBuilderTest {
|
||||
|
||||
String md = new ReportBuilder("[缓存结构变更]").toMarkdown(report);
|
||||
|
||||
// Key:颜色 + 行内代码(与 ReportBuilder.appendKeyLine 一致)
|
||||
assertTrue(md.contains(
|
||||
"- Key --> <font color=\"warning\">`saas:period-config:migration:current`</font>"));
|
||||
"- <font color=\"warning\">`Key --> saas:period-config:migration:current`</font>"));
|
||||
|
||||
int oldSection = md.indexOf("> **value值由:**");
|
||||
int newSection = md.indexOf("> **变更为:**");
|
||||
assertTrue(oldSection >= 0, "应包含「value值由」段落,实际 markdown:\n" + md);
|
||||
assertTrue(newSection > oldSection, "应包含「变更为」段落且在旧值之后,实际 markdown:\n" + md);
|
||||
|
||||
int oldSection = md.indexOf("value 值从");
|
||||
int newSection = md.indexOf("变更为");
|
||||
String oldPart = md.substring(oldSection, newSection);
|
||||
String newPart = md.substring(newSection);
|
||||
|
||||
@@ -126,6 +131,8 @@ class ReportBuilderTest {
|
||||
assertTrue(console.contains("======== 字段明细 ========"));
|
||||
assertTrue(console.contains("**删除字段**: x"));
|
||||
assertTrue(console.contains("<font color=\"warning\">\"x\":\"\"</font>"));
|
||||
assertTrue(console.contains("> **value值由:**"));
|
||||
assertTrue(console.contains("> **变更为:**"));
|
||||
assertFalse(console.contains("`{\"x\":\"\"}`"));
|
||||
}
|
||||
|
||||
@@ -138,4 +145,77 @@ class ReportBuilderTest {
|
||||
assertTrue(out.contains("<font color=\"warning\">\"dbName\":\"\"</font>"));
|
||||
assertFalse(out.contains("<font color=\"warning\">\"id\":\"\"</font>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleSmallKeysStayInOneWeComMessage() {
|
||||
CheckReport report = baseReport();
|
||||
report.getKeyChanges().add(simpleKey("k-a", "{\"a\":\"\"}", "{\"a\":\"\",\"x\":\"\"}", "x"));
|
||||
report.getKeyChanges().add(simpleKey("k-b", "{\"b\":\"\"}", "{\"b\":\"\",\"y\":\"\"}", "y"));
|
||||
|
||||
List<String> messages = new ReportBuilder("[缓存结构变更]").toWeComMessages(report);
|
||||
assertEquals(1, messages.size());
|
||||
assertTrue(messages.get(0).contains("k-a"));
|
||||
assertTrue(messages.get(0).contains("k-b"));
|
||||
assertTrue(ReportBuilder.utf8Bytes(messages.get(0)) <= ReportBuilder.WECOM_MARKDOWN_MAX_BYTES);
|
||||
}
|
||||
|
||||
@Test
|
||||
void oversizedMultiKeysSplitOneMessagePerKey() {
|
||||
CheckReport report = baseReport();
|
||||
// 两侧骨架各约 1.8KB,两条拼在一起超 4096;单条仍应落在上限内
|
||||
String fat = fatJson(1800);
|
||||
report.getKeyChanges().add(simpleKey("fat-key-1", fat, fat + "1", null));
|
||||
report.getKeyChanges().add(simpleKey("fat-key-2", fat, fat + "2", null));
|
||||
|
||||
List<String> messages = new ReportBuilder("[缓存结构变更]").toWeComMessages(report);
|
||||
assertEquals(2, messages.size(), "超长应按 key 拆成 2 条");
|
||||
assertTrue(messages.get(0).contains("fat-key-1"));
|
||||
assertFalse(messages.get(0).contains("fat-key-2"));
|
||||
assertTrue(messages.get(1).contains("fat-key-2"));
|
||||
assertFalse(messages.get(1).contains("fat-key-1"));
|
||||
assertTrue(ReportBuilder.utf8Bytes(messages.get(0)) <= ReportBuilder.WECOM_MARKDOWN_MAX_BYTES);
|
||||
assertTrue(ReportBuilder.utf8Bytes(messages.get(1)) <= ReportBuilder.WECOM_MARKDOWN_MAX_BYTES);
|
||||
// 抬头在每条中重复
|
||||
assertTrue(messages.get(0).contains("## [缓存结构变更] jnpf-java-cloud"));
|
||||
assertTrue(messages.get(1).contains("## [缓存结构变更] jnpf-java-cloud"));
|
||||
|
||||
String console = new ReportBuilder("[缓存结构变更]").toConsole(report);
|
||||
assertTrue(console.contains("超长已按 key 拆为 2 条"));
|
||||
}
|
||||
|
||||
private static CheckReport baseReport() {
|
||||
CheckReport report = new CheckReport();
|
||||
report.setRepository("jnpf-java-cloud");
|
||||
report.setBranch("feature/x");
|
||||
report.setOldSha("aaa11111");
|
||||
report.setNewSha("bbb22222");
|
||||
report.setModifier("dongzi");
|
||||
report.setModifyTime("2026-07-14 12:00:00");
|
||||
return report;
|
||||
}
|
||||
|
||||
private static KeyStructureChange simpleKey(String pattern, String oldJson, String newJson,
|
||||
String addedField) {
|
||||
KeyStructureChange key = new KeyStructureChange();
|
||||
key.setKeyPattern(pattern);
|
||||
key.setOldSkeletonJson(oldJson);
|
||||
key.setNewSkeletonJson(newJson);
|
||||
if (addedField != null) {
|
||||
SchemaChange added = new SchemaChange(ChangeType.FIELD_ADDED);
|
||||
added.setFieldPath(addedField);
|
||||
added.setKeyPattern(pattern);
|
||||
key.getFieldDetails().add(added);
|
||||
// 保证 hasChanges / 控制台字段明细有数据
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
private static String fatJson(int minChars) {
|
||||
StringBuilder sb = new StringBuilder("{\"pad\":\"");
|
||||
while (sb.length() < minChars) {
|
||||
sb.append('x');
|
||||
}
|
||||
sb.append("\"}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user