package jnpf.dmsService;
|
|
import jnpf.exception.DataException;
|
import jnpf.flowable.entity.TemplateNodeEntity;
|
import org.junit.jupiter.api.Test;
|
|
import java.net.URLEncoder;
|
import java.nio.charset.StandardCharsets;
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.List;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
class DmsQianpiyeNodeOrderTest {
|
@Test
|
void followsConnectionsDespiteReversedCreationTimesIdsAndXmlTaskOrder() {
|
List<TemplateNodeEntity> nodes = DmsQianpiyeFlowFixtures.steps("node");
|
Collections.rotate(nodes, 3);
|
assertEquals(List.of("node0", "node1", "node2", "node3", "node4", "node5", "node6", "node7"),
|
codes(DmsQianpiyeNodeOrder.order(DmsQianpiyeFlowFixtures.version("v", "node").getFlowXml(), nodes)));
|
}
|
|
@Test
|
void ordersBothBranchesBeforeTheirJoinAndIncludesTheOptionalTrainingStepOnce() {
|
List<TemplateNodeEntity> nodes = DmsQianpiyeFlowFixtures.steps("node").subList(0, 5);
|
String xml = """
|
<b:definitions xmlns:b="http://www.omg.org/spec/BPMN/20100524/MODEL">
|
<b:process id="flow">
|
<b:startEvent id="node0"/>
|
<b:sequenceFlow sourceRef="node0" targetRef="fork"/>
|
<b:sequenceFlow sourceRef="fork" targetRef="node1"/>
|
<b:sequenceFlow sourceRef="fork" targetRef="node2"/>
|
<b:sequenceFlow sourceRef="node1" targetRef="join"/>
|
<b:sequenceFlow sourceRef="node2" targetRef="join"/>
|
<b:sequenceFlow sourceRef="join" targetRef="node3"/>
|
<b:sequenceFlow sourceRef="node3" targetRef="training-choice"/>
|
<b:sequenceFlow sourceRef="training-choice" targetRef="end"/>
|
<b:sequenceFlow sourceRef="training-choice" targetRef="node4"/>
|
<b:sequenceFlow sourceRef="node4" targetRef="end"/>
|
</b:process>
|
</b:definitions>
|
""";
|
assertEquals(List.of("node0", "node1", "node2", "node3", "node4"),
|
codes(DmsQianpiyeNodeOrder.order(xml, nodes)));
|
}
|
|
@Test
|
void handlesEncodedXmlAndLoopsWithoutDuplicatingSteps() {
|
String xml = DmsQianpiyeFlowFixtures.linearXml("node0", "node1", "node2")
|
.replace("</process>", "<sequenceFlow sourceRef=\"node2\" targetRef=\"node1\"/></process>");
|
assertEquals(List.of("node0", "node1", "node2"), codes(DmsQianpiyeNodeOrder.order(
|
URLEncoder.encode(xml, StandardCharsets.UTF_8), DmsQianpiyeFlowFixtures.steps("node").subList(0, 3))));
|
}
|
|
@Test
|
void rejectsMissingOrInvalidConnectionsInsteadOfAssigningArbitraryStepNumbers() {
|
List<TemplateNodeEntity> nodes = DmsQianpiyeFlowFixtures.steps("node");
|
assertThrows(DataException.class, () -> DmsQianpiyeNodeOrder.order(null, nodes));
|
assertThrows(DataException.class, () -> DmsQianpiyeNodeOrder.order("<invalid>", nodes));
|
assertThrows(DataException.class, () -> DmsQianpiyeNodeOrder.order(
|
"<!DOCTYPE definitions [<!ENTITY external SYSTEM 'file:///nonexistent'>]>"
|
+ DmsQianpiyeFlowFixtures.version("v", "node").getFlowXml(), nodes));
|
assertThrows(DataException.class, () -> DmsQianpiyeNodeOrder.order(
|
DmsQianpiyeFlowFixtures.linearXml("node0", "node1"), nodes));
|
}
|
|
@Test
|
void preservesGlobalFormMetadataWithoutMakingItAnApprovalStep() {
|
List<TemplateNodeEntity> nodes = new ArrayList<>(DmsQianpiyeFlowFixtures.steps("node"));
|
TemplateNodeEntity global = new TemplateNodeEntity();
|
global.setNodeCode("global");
|
global.setNodeType("global");
|
global.setFormId("form-id");
|
nodes.add(0, global);
|
List<TemplateNodeEntity> ordered = DmsQianpiyeNodeOrder.order(
|
DmsQianpiyeFlowFixtures.version("v", "node").getFlowXml(), nodes);
|
assertEquals(global, ordered.getLast());
|
assertEquals(9, ordered.size());
|
}
|
|
private List<String> codes(List<TemplateNodeEntity> nodes) {
|
return nodes.stream().map(TemplateNodeEntity::getNodeCode).toList();
|
}
|
}
|