在 b369527 之上增量移植 FL2.0 后端能力,不改既有线级停发/指派预览/流程图入口:
- 部门目录:FlowDepartmentController(/admin/department/{groups,options,resolve,members})
+ UserBaseDepartmentDirectory(先按会话校域解析引用,再读成员;目录不可用 fail-closed)
- 退回重提 D14:POST /oapi/flow/instance/{instanceId}/resubmit,仅原提交人 CAS 路径放行,
OAPI 侧 submitterId 路径继续 fail-closed
- 授权管理:/api/flow/admin/usage-grant/{schoolList,summary}(校域取管理员会话,无 schId 入参)
- 来源主体:解析器派生 ub-app:{applicationInfo.id},不再读取 UserBase 的 sourcePrincipalId 字段
- 回调来源策略:SELF 身份强校验;NULL 来源不广播;复合幂等键 (event_id,reg_id)
- 测试夹具:许可/主体/开通桩按新契约修正,FlowEngineIT/FormalApplyCommandIT/
CallbackDispatchIT/OapiFlowContractIT 共 117 例在真实 MySQL 8 通过
不含:FlSourceAuthorizationTest(其断言的两个 Repository 派生方法属另一实现线)
This commit is contained in:
@@ -42,14 +42,12 @@ class OapiFlowApplyDefVersionTest {
|
||||
|
||||
private static final Long SCH_ID = 1L;
|
||||
private static final String FLOW_GUID = "g-assign";
|
||||
private static final String SOURCE_ID = "11111111-2222-3333-4444-555555555555";
|
||||
|
||||
private FlwDefRepository defRepository;
|
||||
private FlowInstanceService instanceService;
|
||||
private AssigneeResolver assigneeResolver;
|
||||
private OapiFlowService service;
|
||||
private FlwInstanceRepository instances;
|
||||
private OpenApiAppClient appClient;
|
||||
|
||||
@BeforeEach
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -58,29 +56,24 @@ class OapiFlowApplyDefVersionTest {
|
||||
instanceService = mock(FlowInstanceService.class);
|
||||
assigneeResolver = mock(AssigneeResolver.class);
|
||||
instances = mock(FlwInstanceRepository.class);
|
||||
appClient = mock(OpenApiAppClient.class);
|
||||
com.fasterxml.jackson.databind.node.ObjectNode registered =
|
||||
new ObjectMapper().createObjectNode()
|
||||
.put("id", 100009)
|
||||
.put("appCode", "flow-center")
|
||||
.put("sourcePrincipalId", SOURCE_ID);
|
||||
when(appClient.getAppByKey(any())).thenReturn(registered);
|
||||
service = new OapiFlowService(defRepository, instances,
|
||||
mock(FlwTaskRepository.class), mock(FlwCcRepository.class),
|
||||
mock(FlwCallbackRegRepository.class), instanceService, mock(FlowTaskService.class),
|
||||
mock(FlowEngine.class), assigneeResolver, new ObjectMapper(),
|
||||
mock(OpenApiUserClient.class), appClient,
|
||||
mock(OpenApiUserClient.class), mock(OpenApiAppClient.class),
|
||||
mock(DiagramTokenService.class), mock(ObjectProvider.class));
|
||||
// F01:来源解析与使用许可在真实装配中由 Spring 注入,单测按同一契约显式装配
|
||||
org.springframework.test.util.ReflectionTestUtils.setField(
|
||||
service, "sourcePrincipalResolver", new FlowSourcePrincipalResolver(appClient));
|
||||
FlowUsageGrantGuard guard = mock(FlowUsageGrantGuard.class);
|
||||
when(guard.requireNewApplyGrant(anyLong(), any(),
|
||||
any(FlowSourcePrincipalResolver.Principal.class))).thenReturn(100009);
|
||||
service.setUsageGrantGuard(guard);
|
||||
// 本校校验在单测里关闭(@Value 字段未注入=默认 false),引擎出参给一个既有办件
|
||||
when(instanceService.apply(any(FlowInstanceService.ApplyCommand.class)))
|
||||
.thenReturn(new FlowInstanceService.ApplyOutcome(500L, false));
|
||||
// F01/F02:来源主体解析与使用许可闸在生产装配里必然存在;单测手工构造服务时必须显式注入
|
||||
// 测试替身,否则 apply 会因"闸门未装配/来源不可解析"被 fail-closed 拒(那是期望行为,不是靶子)。
|
||||
FlowSourcePrincipalResolver stubPrincipals = mock(FlowSourcePrincipalResolver.class);
|
||||
when(stubPrincipals.resolve(org.mockito.ArgumentMatchers.anyString()))
|
||||
.thenReturn(new FlowSourcePrincipalResolver.Principal(
|
||||
"ub-app:18", 18, "100018", "flow-test"));
|
||||
org.springframework.test.util.ReflectionTestUtils.setField(service, "sourcePrincipalResolver", stubPrincipals);
|
||||
service.setUsageGrantGuard(mock(FlowUsageGrantGuard.class));
|
||||
|
||||
}
|
||||
|
||||
private static FlwDef publishedDef(int version) {
|
||||
|
||||
Reference in New Issue
Block a user