feat(apply): 用户面撤回/进度/流程图后端中转 + 大厅HallController + flowEnabled 三态(SDK withdraw/progress/diagramUrl)
build / build-push (push) Successful in 1m11s
build / build-push (push) Successful in 1m11s
This commit is contained in:
@@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -149,6 +150,100 @@ class FlowCenterClientFacadeTest {
|
||||
org.junit.jupiter.api.Assertions.assertNotNull(client().getFlow(3L, "guid-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("撤回:走门面 → /oapi/flow/instance/{id}/withdraw + schId/submitterId(对端复核身份)")
|
||||
void withdraw_goesThroughFacade() {
|
||||
client().withdraw(3L, 77L, 201);
|
||||
|
||||
ArgumentCaptor<Map<String, String>> query = ArgumentCaptor.forClass(Map.class);
|
||||
verify(openCall).post(eq(TARGET), eq("/oapi/flow/instance/77/withdraw"), query.capture(),
|
||||
isNull(), eq(Void.class));
|
||||
assertEquals("3", query.getValue().get("schId"));
|
||||
assertEquals("201", query.getValue().get("submitterId"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("进度:走门面 → /oapi/flow/progress?instanceId=&schId=")
|
||||
void progress_goesThroughFacade() {
|
||||
SvcModels.FlowProgressVo stub = new SvcModels.FlowProgressVo();
|
||||
stub.setInstanceId(77L);
|
||||
when(openCall.get(eq(TARGET), eq("/oapi/flow/progress"), anyMap(),
|
||||
eq(SvcModels.FlowProgressVo.class))).thenReturn(stub);
|
||||
|
||||
assertEquals(Long.valueOf(77L), client().progress(3L, 77L, null, null).getInstanceId());
|
||||
|
||||
ArgumentCaptor<Map<String, String>> query = ArgumentCaptor.forClass(Map.class);
|
||||
verify(openCall).get(eq(TARGET), eq("/oapi/flow/progress"), query.capture(),
|
||||
eq(SvcModels.FlowProgressVo.class));
|
||||
assertEquals("77", query.getValue().get("instanceId"));
|
||||
assertEquals("3", query.getValue().get("schId"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("流程图:换图 + 取图两步都在后端;token 不出后端(前端拿不到,也不需要 flow-center 地址)")
|
||||
void diagramImage_tokenStaysInBackend() {
|
||||
SvcModels.FlowDiagramVo url = new SvcModels.FlowDiagramVo();
|
||||
url.setImgUrl("/open/flow/diagram/img?token=tok-abc");
|
||||
url.setExpiresIn(300);
|
||||
when(openCall.get(eq(TARGET), eq("/oapi/flow/diagram/url"), anyMap(),
|
||||
eq(SvcModels.FlowDiagramVo.class))).thenReturn(url);
|
||||
byte[] png = new byte[]{(byte) 0x89, 'P', 'N', 'G'};
|
||||
when(openCall.download(eq(TARGET), eq("/open/flow/diagram/img"),
|
||||
eq(java.util.Collections.singletonMap("token", "tok-abc")))).thenReturn(png);
|
||||
|
||||
assertEquals(png, client().diagramImage(3L, 77L, null, "dept"));
|
||||
|
||||
ArgumentCaptor<Map<String, String>> query = ArgumentCaptor.forClass(Map.class);
|
||||
verify(openCall).get(eq(TARGET), eq("/oapi/flow/diagram/url"), query.capture(),
|
||||
eq(SvcModels.FlowDiagramVo.class));
|
||||
assertEquals("77", query.getValue().get("instanceId"));
|
||||
assertEquals("dept", query.getValue().get("mode"));
|
||||
verify(openCall).download(eq(TARGET), eq("/open/flow/diagram/img"),
|
||||
eq(java.util.Collections.singletonMap("token", "tok-abc")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("tokenOf:只认 ?token= 段,容忍尾部其它参数;无 token 返回 null(不拼出脏地址)")
|
||||
void tokenOf_parsesTokenOnly() {
|
||||
assertEquals("abc", FlowCenterClient.tokenOf("/open/flow/diagram/img?token=abc"));
|
||||
assertEquals("abc", FlowCenterClient.tokenOf("/open/flow/diagram/img?token=abc&x=1"));
|
||||
assertEquals("abc", FlowCenterClient.tokenOf("http://h/flow-center/open/flow/diagram/img?token=abc"));
|
||||
org.junit.jupiter.api.Assertions.assertNull(FlowCenterClient.tokenOf("/open/flow/diagram/img"));
|
||||
org.junit.jupiter.api.Assertions.assertNull(FlowCenterClient.tokenOf(null));
|
||||
org.junit.jupiter.api.Assertions.assertNull(FlowCenterClient.tokenOf("/x?token="));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("目录未配:撤回落 legacy base-url(ad-hoc TargetSpec POST,行为不变)")
|
||||
void withdraw_fallsBackToLegacy() {
|
||||
YschOpenCall legacyCall = mock(YschOpenCall.class);
|
||||
when(legacyCall.hasTarget(TARGET)).thenReturn(false);
|
||||
|
||||
new FlowCenterClient(legacyCall, objectMapper, true, LEGACY_BASE).withdraw(3L, 77L, 201);
|
||||
|
||||
ArgumentCaptor<Map<String, String>> query = ArgumentCaptor.forClass(Map.class);
|
||||
verify(legacyCall).post(any(com.yunhai.platform.openapi.core.TargetSpec.class),
|
||||
eq("/oapi/flow/instance/77/withdraw"), query.capture(), isNull(), eq(Void.class));
|
||||
assertEquals("201", query.getValue().get("submitterId"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("enabled=false:三个新方法一律抛「未接入」(不静默成功让前端误判)")
|
||||
void disabledClient_rejectsNewActions() {
|
||||
YschOpenCall noDirectory = mock(YschOpenCall.class);
|
||||
when(noDirectory.hasTarget(TARGET)).thenReturn(false);
|
||||
FlowCenterClient c = new FlowCenterClient(noDirectory, objectMapper, false, "");
|
||||
|
||||
com.yunhai.platform.apistd.BizException withdrawEx =
|
||||
org.junit.jupiter.api.Assertions.assertThrows(com.yunhai.platform.apistd.BizException.class,
|
||||
() -> c.withdraw(3L, 77L, 201));
|
||||
org.junit.jupiter.api.Assertions.assertTrue(withdrawEx.getMessage().contains("流程中心未接入"));
|
||||
org.junit.jupiter.api.Assertions.assertThrows(com.yunhai.platform.apistd.BizException.class,
|
||||
() -> c.progress(3L, 77L, null, null));
|
||||
org.junit.jupiter.api.Assertions.assertThrows(com.yunhai.platform.apistd.BizException.class,
|
||||
() -> c.diagramImage(3L, 77L, null, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("目录未配:回落 legacy svchall.flow.base-url(迁移期兼容,行为不变)")
|
||||
void fallsBackToLegacyWhenDirectoryMissing() {
|
||||
|
||||
Reference in New Issue
Block a user