Files
flow-center-service/src/test/java/com/yunhai/flowcenter/service/DiagramImageServiceTest.java
T

97 lines
4.1 KiB
Java

package com.yunhai.flowcenter.service;
import com.yunhai.flowcenter.model.FlowModels;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* 流程图服务端出图(2026-09-16 "CAS 验证码式嵌入"):
* renderPng 恒出非空 PNG;布局对环/孤儿/缺失端点防御出图(外部 img 场景无错误页可跳)。
*/
class DiagramImageServiceTest {
private final DiagramImageService service = new DiagramImageService();
private FlowModels.NodeVo node(String id, String type, String label, String sub, String state) {
FlowModels.NodeVo n = new FlowModels.NodeVo();
n.setId(id);
n.setType(type);
n.setLabel(label);
n.setSubLabel(sub);
n.setState(state);
return n;
}
private FlowModels.EdgeVo edge(String from, String to, String name) {
FlowModels.EdgeVo e = new FlowModels.EdgeVo();
e.setFrom(from);
e.setTo(to);
e.setName(name);
return e;
}
private FlowModels.DiagramVo vo(List<FlowModels.NodeVo> nodes, List<FlowModels.EdgeVo> edges) {
FlowModels.DiagramVo vo = new FlowModels.DiagramVo();
vo.setName("教师入职审批");
vo.setMode("auto");
vo.setNodes(nodes);
vo.setEdges(edges);
return vo;
}
@Test
void render_instanceVo_producesPngWithStateColors() {
List<FlowModels.NodeVo> nodes = new ArrayList<>(Arrays.asList(
node("n1", "START", "开始", null, null),
node("n2", "APPROVAL", "审核节点", "张三、李四 · 任一人通过", null),
node("n3", "APPROVAL", "科室审批", "教学处 · 3人 · 时限24h", "active"),
node("n4", "END", "结束", null, null)));
List<FlowModels.EdgeVo> edges = new ArrayList<>(Arrays.asList(
edge("n1", "n2", null), edge("n2", "n3", null), edge("n3", "n4", null)));
byte[] png = service.renderPng(vo(nodes, edges));
// PNG 头 89 50 4E 47
assertEquals(0x89, png[0] & 0xFF);
assertEquals(0x50, png[1] & 0xFF);
assertTrue(png.length > 2000, "渲染结果过小,疑似空图");
// 状态无关的纯定义图也恒出图(flowGuid 口径)
for (FlowModels.NodeVo n : nodes) {
n.setState(null);
}
assertNotEquals(0, service.renderPng(vo(nodes, edges)).length);
}
@Test
void smoke_writeSamplePng_forVisualCheck() throws Exception {
List<FlowModels.NodeVo> nodes = new ArrayList<>(Arrays.asList(
node("n1", "START", "开始", null, null),
node("n2", "APPROVAL", "教师入职审批", "刘文娟 · 时限48h", "done"),
node("n3", "APPROVAL", "科室审批", "教学处 · 云海小学001 · 任一人通过 · 时限24h", "active"),
node("n4", "END", "结束", null, null)));
List<FlowModels.EdgeVo> edges = new ArrayList<>(Arrays.asList(
edge("n1", "n2", null), edge("n2", "n3", "同意"), edge("n3", "n4", null)));
java.nio.file.Files.write(
java.nio.file.Paths.get("target", "diagram-smoke.png"),
service.renderPng(vo(nodes, edges)));
}
@Test
void render_defensive_missingEndpointAndCycle_stillProducesImage() {
// 成环 + 指向不存在端点的边:不抛,仍出图(外部 img 场景防御)
List<FlowModels.NodeVo> nodes = new ArrayList<>(Arrays.asList(
node("n1", "START", "开始", null, null),
node("n2", "APPROVAL", "审核节点", null, "done"),
node("n3", "APPROVAL", "孤儿节点", null, null)));
List<FlowModels.EdgeVo> edges = new ArrayList<>(Arrays.asList(
edge("n1", "n2", null), edge("n2", "n1", null), edge("n2", "ghost", null)));
assertDoesNotThrow(() -> service.renderPng(vo(nodes, edges)));
}
}