feat: cancel running instances as CANCELLED without initiator checks

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
0264408
2026-09-16 09:47:58 +08:00
co-authored by Cursor
parent 30047f3612
commit 8bc628613d
11 changed files with 138 additions and 28 deletions
@@ -266,6 +266,28 @@ class JdbcOrdoEngineIntegrationTest {
assertThrows(InstanceAlreadyCompletedException.class, () -> engine.withdraw(instance.id(), "alice"));
}
@Test
void adminCanCancelARunningInstance() {
ProcessInstance instance = engine.start("leave", "alice");
engine.approve(engine.findPendingTasksByInstanceId(instance.id()).get(0).id(), "maria");
ProcessInstance cancelled = engine.cancel(instance.id(), "admin", "policy");
assertEquals(ProcessStatus.CANCELLED, cancelled.status());
assertEquals(NOW, cancelled.finishedAt());
assertTrue(engine.findPendingTasksByInstanceId(instance.id()).isEmpty());
ApprovalTask hrTask = engine.findTasks(instance.id()).stream()
.filter(task -> task.stepId().equals("hr"))
.findFirst()
.orElseThrow();
assertEquals(TaskStatus.SKIPPED, hrTask.status());
assertEquals("admin", hrTask.action().actor());
assertEquals("policy", hrTask.action().comment());
assertTrue(engine.queryHistory(instance.id(), new PageRequest(0, 20)).content().stream()
.anyMatch(event -> event.type() == ProcessEventType.INSTANCE_CANCELLED));
assertThrows(InstanceAlreadyCompletedException.class, () -> engine.withdraw(instance.id(), "alice"));
}
@Test
void persistHistoryAndActionExecutions() {
OrdoEngine actionEngine = new DefaultOrdoEngine(Clock.fixed(NOW, ZoneOffset.UTC), AssigneeResolver.direct(),