package jnpf.bizcommon.audit.service.sign;
|
|
/**
|
* {@link AuditSignMetaData#parse} 的纯 JVM 断言——覆盖真实生产样本 + 降级路径。
|
*
|
* <p>骨架与 {@link AuditSignFieldProbe} 同族(mvn -o + javac + 直调 main)。
|
* 四条真实样本取自 {@code lims_sign.meta_data}(2026-08-01 只读查询,字段顺序、值均原样保留,
|
* 未做任何简化——line-by-line 与库里实际存的 JSON 一致,见 task-6-report.md 的行为验证章节)。
|
*
|
* <p>runner:{@code tasks/audit-sign-field-checks.sh}
|
*/
|
public final class AuditSignMetaDataProbe {
|
|
private static int pass;
|
private static int fail;
|
|
/** f_id=853033878464640709,复核动作,is_review_button=true。 */
|
private static final String SAMPLE_REVIEW_1 =
|
"{\"is_review_button\":true,\"biz_button\":\"复核\",\"biz_data\":[{\"id\":\"852927614623561029\","
|
+ "\"flowId\":\"\",\"bian_hao\":\"1\",\"beizhu\":\"111\",\"tijiao_ren\":\"349057407209541\","
|
+ "\"fuhe_ren\":\"817410893825462789\",\"biz_sign\":\"853023946319214277\","
|
+ "\"fuhe_sign\":\"852927419957524037\"}],\"biz_form_id\":\"852852941198079301\","
|
+ "\"biz_module\":\"\",\"biz_title\":\"\",\"is_biz_form\":true}";
|
|
/** f_id=853030727456011973,同一张单子的第二次复核提交,形态与上一条一致。 */
|
private static final String SAMPLE_REVIEW_2 =
|
"{\"is_review_button\":true,\"biz_button\":\"复核\",\"biz_data\":[{\"id\":\"852927614623561029\","
|
+ "\"flowId\":\"\",\"bian_hao\":\"1\",\"beizhu\":\"111\",\"tijiao_ren\":\"349057407209541\","
|
+ "\"fuhe_ren\":\"817410893825462789\",\"biz_sign\":\"853023946319214277\","
|
+ "\"fuhe_sign\":\"852927419957524037\"}],\"biz_form_id\":\"852852941198079301\","
|
+ "\"biz_module\":\"\",\"biz_title\":\"\",\"is_biz_form\":true}";
|
|
/** f_id=853027186830096069,批量按钮、非复核,biz_data 是列表行快照(多个 *_jnpfId 影子字段)。 */
|
private static final String SAMPLE_BATCH_BUTTON =
|
"{\"is_review_button\":false,\"biz_button\":\"批量按钮\",\"biz_data\":[{\"bian_hao_jnpfId\":\"1\","
|
+ "\"flowTaskId\":\"852927614623561029\",\"tijiao_ren_jnpfId\":\"349057407209541\","
|
+ "\"beizhu_jnpfId\":\"111\",\"biz_sign_jnpfId\":null,\"biz_sign\":null,\"bian_hao\":\"1\","
|
+ "\"f_flow_task_id\":\"852927614623561029\",\"tijiao_ren\":\"管理员/admin\","
|
+ "\"fuhe_ren\":\"wuyong/wuyong\",\"fuhe_ren_jnpfId\":\"817410893825462789\",\"fuhe_sign\":null,"
|
+ "\"fuhe_sign_jnpfId\":null,\"f_version\":2,\"beizhu\":\"111\",\"f_id\":\"852927614623561029\","
|
+ "\"id\":\"852927614623561029\",\"_id\":null,\"f_flow_id\":null,\"flowId\":null}],"
|
+ "\"biz_form_id\":\"852852941198079301\",\"biz_module\":\"\",\"biz_title\":\"\","
|
+ "\"is_biz_form\":false}";
|
|
/** f_id=853026858244126405,列表按钮、非复核——与批量按钮样本仅 biz_button 不同,其余同构。 */
|
private static final String SAMPLE_LIST_BUTTON =
|
"{\"is_review_button\":false,\"biz_button\":\"列表按钮\",\"biz_data\":[{\"bian_hao_jnpfId\":\"1\","
|
+ "\"flowTaskId\":\"852927614623561029\",\"tijiao_ren_jnpfId\":\"349057407209541\","
|
+ "\"beizhu_jnpfId\":\"111\",\"biz_sign_jnpfId\":null,\"biz_sign\":null,\"bian_hao\":\"1\","
|
+ "\"f_flow_task_id\":\"852927614623561029\",\"tijiao_ren\":\"管理员/admin\","
|
+ "\"fuhe_ren\":\"wuyong/wuyong\",\"fuhe_ren_jnpfId\":\"817410893825462789\",\"fuhe_sign\":null,"
|
+ "\"fuhe_sign_jnpfId\":null,\"f_version\":2,\"beizhu\":\"111\",\"f_id\":\"852927614623561029\","
|
+ "\"id\":\"852927614623561029\",\"_id\":null,\"f_flow_id\":null,\"flowId\":null}],"
|
+ "\"biz_form_id\":\"852852941198079301\",\"biz_module\":\"\",\"biz_title\":\"\","
|
+ "\"is_biz_form\":false}";
|
|
public static void main(String[] args) {
|
realReviewSamplesParseCorrectly();
|
realNonReviewSamplesParseCorrectly();
|
nullAndBlankReturnEmpty();
|
malformedJsonNeverThrows();
|
missingKeysDegradeGracefully();
|
blankBizButtonTreatedAsAbsent();
|
System.out.println("=== meta_data 动作语义断言:" + pass + " 通过 / " + fail + " 失败 ===");
|
if (fail > 0) {
|
System.exit(1);
|
}
|
}
|
|
/** M1 真实复核样本:biz_button="复核"、is_review_button=true、rawBizData 非空。 */
|
private static void realReviewSamplesParseCorrectly() {
|
for (String json : new String[] {SAMPLE_REVIEW_1, SAMPLE_REVIEW_2}) {
|
AuditSignMetaData md = AuditSignMetaData.parse(json);
|
check("M1 复核样本 biz_button=复核", "复核".equals(md.bizButton()), "实际 " + md.bizButton());
|
check("M1 复核样本 isReviewButton=true", md.isReviewButton(), "实际 " + md.isReviewButton());
|
check("M1 复核样本 rawBizData 非空", md.rawBizData() != null, "实际 null");
|
}
|
}
|
|
/** M2 真实非复核样本(批量按钮/列表按钮):is_review_button=false,按钮名各自透传。 */
|
private static void realNonReviewSamplesParseCorrectly() {
|
AuditSignMetaData batch = AuditSignMetaData.parse(SAMPLE_BATCH_BUTTON);
|
check("M2 批量按钮样本 biz_button=批量按钮", "批量按钮".equals(batch.bizButton()), "实际 " + batch.bizButton());
|
check("M2 批量按钮样本 isReviewButton=false", !batch.isReviewButton(), "实际 " + batch.isReviewButton());
|
|
AuditSignMetaData list = AuditSignMetaData.parse(SAMPLE_LIST_BUTTON);
|
check("M2 列表按钮样本 biz_button=列表按钮", "列表按钮".equals(list.bizButton()), "实际 " + list.bizButton());
|
check("M2 列表按钮样本 isReviewButton=false", !list.isReviewButton(), "实际 " + list.isReviewButton());
|
}
|
|
/** M3 null / 空串 / 纯空白:一律返回 EMPTY,三个 getter 都是「拿不到」的零值。 */
|
private static void nullAndBlankReturnEmpty() {
|
for (String json : new String[] {null, "", " "}) {
|
AuditSignMetaData md = AuditSignMetaData.parse(json);
|
check("M3 null/空串/空白 → EMPTY", md == AuditSignMetaData.EMPTY, "json=[" + json + "] 实际未返回 EMPTY 实例");
|
check("M3 EMPTY.bizButton()==null", md.bizButton() == null, "实际 " + md.bizButton());
|
check("M3 EMPTY.isReviewButton()==false", !md.isReviewButton(), "实际 " + md.isReviewButton());
|
check("M3 EMPTY.rawBizData()==null", md.rawBizData() == null, "实际 " + md.rawBizData());
|
}
|
}
|
|
/** M4 非 JSON 字符串:解析失败必须降级为 EMPTY,绝不能抛异常炸穿调用方(brief 硬约束)。 */
|
private static void malformedJsonNeverThrows() {
|
String[] garbage = {"{not json", "not even braces", "{\"a\":}", "[]", "null", "123"};
|
for (String json : garbage) {
|
try {
|
AuditSignMetaData md = AuditSignMetaData.parse(json);
|
check("M4 非法 JSON 不抛异常,返回非空对象 [" + json + "]", md != null, "实际 null");
|
} catch (Throwable t) {
|
fail++;
|
System.out.println(" ❌ M4 非法 JSON 抛出异常 [" + json + "] —— " + t);
|
}
|
}
|
}
|
|
/** M5 合法 JSON 但没有 biz_button/is_review_button 键:降级为拿不到,不是抛异常也不是瞎猜。 */
|
private static void missingKeysDegradeGracefully() {
|
AuditSignMetaData md = AuditSignMetaData.parse("{\"foo\":\"bar\"}");
|
check("M5 缺键时 bizButton()==null", md.bizButton() == null, "实际 " + md.bizButton());
|
check("M5 缺键时 isReviewButton()==false", !md.isReviewButton(), "实际 " + md.isReviewButton());
|
}
|
|
/** M6 biz_button 为空串:视同「拿不到」返回 null,而不是把空串当成一个有效按钮名往下传。 */
|
private static void blankBizButtonTreatedAsAbsent() {
|
AuditSignMetaData md = AuditSignMetaData.parse("{\"biz_button\":\"\",\"is_review_button\":false}");
|
check("M6 biz_button 空串 → bizButton()==null", md.bizButton() == null, "实际 [" + md.bizButton() + "]");
|
}
|
|
private static void check(String name, boolean ok, String detail) {
|
if (ok) {
|
pass++;
|
System.out.println(" ✅ " + name);
|
} else {
|
fail++;
|
System.out.println(" ❌ " + name + " —— " + detail);
|
}
|
}
|
}
|