Enforce exact published form version contracts
Local review candidate only. Explicitly selected inherited prerequisites and prior repair patches; unrelated WIP and independent MQ fixes are excluded. No push or deployment authorized.
This commit is contained in:
@@ -4,6 +4,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.yunhai.flowcenter.entity.FlwDef;
|
||||
import com.yunhai.flowcenter.engine.FlowEngine;
|
||||
import com.yunhai.flowcenter.enums.FlwEnums;
|
||||
import com.yunhai.flowcenter.enums.FormBindingErrorCode;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import com.yunhai.flowcenter.repository.FlwCallbackRegRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwDefRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwInstanceRepository;
|
||||
@@ -45,13 +48,12 @@ import static org.mockito.Mockito.when;
|
||||
* 取消关联=两列同时清空(留一个没人认领的版本号是下一轮误用的起点);</li>
|
||||
* <li><b>发布取确切版本</b>:带版本的关联走 {@code schema?uuid=&version=};
|
||||
* <b>中心返回的坐标与请求不符即阻断发布</b>,而不是把错的快照嵌进 def 版本行;
|
||||
* 本列之前就已关联的存量行(formVersion=NULL)继续走"当前发布版"旧口径,行为逐字不变;</li>
|
||||
* 存量 UUID-only 行发布与启用同样阻断,必须重新绑定明确版本;</li>
|
||||
* <li><b>目录客户端的调用形态</b>:命名目标 {@code form-center} + 查询里带 schId/page/pageSize,
|
||||
* 空 data 按"目录不可用"拒(不给一个看起来正常的空列表掩盖授权没配)。</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>注:{@code FlowDefAdminServicePublishContractTest}/{@code FlowDefAdminServiceSaveTest} 钉的是
|
||||
* 改造前既有形态(两参 fetchSchema 与 8 参 save),本类只补 v3 新增的那几条,不改它们的断言。</p>
|
||||
* <p>发布与启用按同一错误码分类;表达式三查测试同时使用明确版本。</p>
|
||||
*/
|
||||
@DisplayName("流程定义绑定表单中心 - v3 单测(TASK_1)")
|
||||
class FlFormBindingTest {
|
||||
@@ -134,6 +136,7 @@ class FlFormBindingTest {
|
||||
@DisplayName("成对提交:uuid 与 version 一起落行")
|
||||
void pairIsSavedTogether() {
|
||||
when(defRepository.findById(9L)).thenReturn(Optional.of(draft(null, null)));
|
||||
when(schemaClient.fetchSchema(SCH, "FU1", 3)).thenReturn(snapshot("FU1", 3));
|
||||
|
||||
FlwDef saved = service.save(SCH, 9L, "work-leave", "请假", SIMPLE_JSON,
|
||||
null, null, null, "FU1", 3);
|
||||
@@ -198,7 +201,6 @@ class FlFormBindingTest {
|
||||
FlwDef published = service.publish(SCH, 9L);
|
||||
|
||||
verify(schemaClient).fetchSchema(SCH, "FU1", 3);
|
||||
verify(schemaClient, never()).fetchSchema(anyLong(), anyString());
|
||||
assertTrue(published.getContentJson().contains("\"formContract\""), published.getContentJson());
|
||||
assertTrue(published.getContentJson().contains("FU1"));
|
||||
}
|
||||
@@ -214,22 +216,112 @@ class FlFormBindingTest {
|
||||
|
||||
BizException e = assertThrows(BizException.class, () -> service.publish(SCH, 9L));
|
||||
|
||||
assertEquals(FormBindingErrorCode.SCHEMA_CONTRACT_VIOLATION.getCode(), e.getErrorCode().getCode());
|
||||
assertTrue(e.getMessage().contains("核验失败"), e.getMessage());
|
||||
assertTrue(e.getMessage().contains("发布已阻断"), e.getMessage());
|
||||
assertEquals(FlwEnums.DefStatus.DRAFT.getCode(), def.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("存量行(本列之前已关联、无版本):继续走当前发布版旧口径")
|
||||
void legacyRowWithoutVersionKeepsOldBehaviour() {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {false, true})
|
||||
@DisplayName("缺版本:发布和启用均阻断,不回落当前版本")
|
||||
void missingVersionBlocksPublishAndEnable(boolean enable) {
|
||||
FlwDef def = draft("FU1", null);
|
||||
if (enable) def.setStatus(FlwEnums.DefStatus.DISABLED.getCode());
|
||||
when(defRepository.findById(9L)).thenReturn(Optional.of(def));
|
||||
when(schemaClient.fetchSchema(SCH, "FU1")).thenReturn(snapshot("FU1", 9));
|
||||
|
||||
service.publish(SCH, 9L);
|
||||
BizException ex = assertThrows(BizException.class, () -> changeStatus(enable));
|
||||
|
||||
verify(schemaClient).fetchSchema(SCH, "FU1");
|
||||
assertEquals(FormBindingErrorCode.VERSION_REQUIRED.getCode(), ex.getErrorCode().getCode());
|
||||
assertEquals(enable ? FlwEnums.DefStatus.DISABLED.getCode() : FlwEnums.DefStatus.DRAFT.getCode(), def.getStatus());
|
||||
verify(schemaClient, never()).fetchSchema(anyLong(), anyString(), any());
|
||||
verify(defRepository, never()).save(any());
|
||||
}
|
||||
|
||||
private FlwDef changeStatus(boolean enable) {
|
||||
return enable ? service.enable(SCH, 9L) : service.publish(SCH, 9L);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {false, true})
|
||||
void invalidVersionBlocksPublishAndEnable(boolean enable) {
|
||||
FlwDef def = draft("FU1", 0);
|
||||
if (enable) def.setStatus(FlwEnums.DefStatus.DISABLED.getCode());
|
||||
when(defRepository.findById(9L)).thenReturn(Optional.of(def));
|
||||
BizException ex = assertThrows(BizException.class, () -> changeStatus(enable));
|
||||
assertEquals(FormBindingErrorCode.INVALID_COORDINATE.getCode(), ex.getErrorCode().getCode());
|
||||
verify(schemaClient, never()).fetchSchema(anyLong(), anyString(), any());
|
||||
verify(defRepository, never()).save(any());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {false, true})
|
||||
void orphanVersionBlocksPublishAndEnable(boolean enable) {
|
||||
FlwDef def = draft(null, 3);
|
||||
if (enable) def.setStatus(FlwEnums.DefStatus.DISABLED.getCode());
|
||||
when(defRepository.findById(9L)).thenReturn(Optional.of(def));
|
||||
BizException ex = assertThrows(BizException.class, () -> changeStatus(enable));
|
||||
assertEquals(FormBindingErrorCode.INVALID_COORDINATE.getCode(), ex.getErrorCode().getCode());
|
||||
verify(defRepository, never()).save(any());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {false, true})
|
||||
void schemaFailuresHaveDistinctStableCodesAndDoNotWrite(boolean enable) {
|
||||
FlwDef def = draft("FU1", 3);
|
||||
if (enable) def.setStatus(FlwEnums.DefStatus.DISABLED.getCode());
|
||||
when(defRepository.findById(9L)).thenReturn(Optional.of(def));
|
||||
RuntimeException[] failures = {
|
||||
new FormCenterSchemaClient.SchemaUnavailableException("timeout", null),
|
||||
new FormCenterSchemaClient.SchemaContractViolationException("wrong version"),
|
||||
new FormCenterSchemaClient.SchemaResourceUnavailableException(null),
|
||||
new FormCenterSchemaClient.SchemaAccessDeniedException(null)
|
||||
};
|
||||
FormBindingErrorCode[] codes = {FormBindingErrorCode.SCHEMA_UNAVAILABLE,
|
||||
FormBindingErrorCode.SCHEMA_CONTRACT_VIOLATION, FormBindingErrorCode.RESOURCE_UNAVAILABLE,
|
||||
FormBindingErrorCode.ACCESS_DENIED};
|
||||
for (int i = 0; i < failures.length; i++) {
|
||||
when(schemaClient.fetchSchema(SCH, "FU1", 3)).thenThrow(failures[i]);
|
||||
BizException ex = assertThrows(BizException.class, () -> changeStatus(enable));
|
||||
assertEquals(codes[i].getCode(), ex.getErrorCode().getCode());
|
||||
assertSame(failures[i], ex.getCause());
|
||||
assertEquals(enable ? FlwEnums.DefStatus.DISABLED.getCode() : FlwEnums.DefStatus.DRAFT.getCode(), def.getStatus());
|
||||
assertEquals(FLOW_JSON, def.getContentJson());
|
||||
org.mockito.Mockito.reset(schemaClient);
|
||||
}
|
||||
verify(defRepository, never()).save(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void enableUsesExactVersionAndPreservesPublishedSnapshot() {
|
||||
FlwDef def = draft("FU1", 3);
|
||||
def.setStatus(FlwEnums.DefStatus.DISABLED.getCode());
|
||||
def.setContentJson(FLOW_JSON.substring(0, FLOW_JSON.length() - 1)
|
||||
+ ",\"formContract\":{\"formUuid\":\"FU1\",\"formVersion\":3,\"fields\":[]}}");
|
||||
String frozenJson = def.getContentJson();
|
||||
when(defRepository.findById(9L)).thenReturn(Optional.of(def));
|
||||
when(schemaClient.fetchSchema(SCH, "FU1", 3)).thenReturn(snapshot("FU1", 3));
|
||||
FlwDef enabled = service.enable(SCH, 9L);
|
||||
assertEquals(FlwEnums.DefStatus.PUBLISHED.getCode(), enabled.getStatus());
|
||||
assertEquals(frozenJson, enabled.getContentJson());
|
||||
verify(schemaClient).fetchSchema(SCH, "FU1", 3);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"oops", "3.5", "3.0", "2147483648", "", "true"})
|
||||
void malformedVersionAtHttpBoundaryHasStableCode(String value) {
|
||||
FlowAdminGuard guard = mock(FlowAdminGuard.class);
|
||||
when(guard.requireAdmin(any(), any())).thenReturn(SCH);
|
||||
com.yunhai.flowcenter.controller.api.FlowAdminController controller =
|
||||
new com.yunhai.flowcenter.controller.api.FlowAdminController(guard, service,
|
||||
null, null, null, null, null, null, new ObjectMapper(), null, null, null);
|
||||
Map<String, Object> body = new LinkedHashMap<>();
|
||||
body.put("formUuid", "FU1");
|
||||
body.put("formVersion", value);
|
||||
BizException ex = assertThrows(BizException.class, () -> controller.defSave(null, body));
|
||||
assertEquals(FormBindingErrorCode.INVALID_COORDINATE.getCode(), ex.getErrorCode().getCode());
|
||||
verify(defRepository, never()).save(any());
|
||||
org.mockito.Mockito.verifyNoInteractions(schemaClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -240,7 +332,6 @@ class FlFormBindingTest {
|
||||
|
||||
service.publish(SCH, 9L);
|
||||
|
||||
verify(schemaClient, never()).fetchSchema(anyLong(), anyString());
|
||||
verify(schemaClient, never()).fetchSchema(anyLong(), anyString(), any());
|
||||
}
|
||||
|
||||
|
||||
+12
-9
@@ -85,6 +85,7 @@ class FlowDefAdminServicePublishContractTest {
|
||||
d.setAppKey("notice");
|
||||
d.setContentJson(JSON);
|
||||
d.setFormUuid(formUuid);
|
||||
d.setFormVersion(formUuid == null ? null : 3);
|
||||
return d;
|
||||
}
|
||||
|
||||
@@ -115,7 +116,7 @@ class FlowDefAdminServicePublishContractTest {
|
||||
@Test
|
||||
void publishEmbedsFormContractSnapshotIntoVersionRow() throws Exception {
|
||||
when(defRepository.findById(9L)).thenReturn(java.util.Optional.of(draft("FU1")));
|
||||
when(schemaClient.fetchSchema(SCH, "FU1")).thenReturn(snapshot());
|
||||
when(schemaClient.fetchSchema(SCH, "FU1", 3)).thenReturn(snapshot());
|
||||
|
||||
FlwDef published = service.publish(SCH, 9L);
|
||||
|
||||
@@ -134,7 +135,7 @@ class FlowDefAdminServicePublishContractTest {
|
||||
// 出口条件改成引用快照外变量
|
||||
d.setContentJson(JSON.replace("grade == 'g1'", "level == 'high'"));
|
||||
when(defRepository.findById(9L)).thenReturn(java.util.Optional.of(d));
|
||||
when(schemaClient.fetchSchema(SCH, "FU1")).thenReturn(snapshot());
|
||||
when(schemaClient.fetchSchema(SCH, "FU1", 3)).thenReturn(snapshot());
|
||||
|
||||
BizException ex = assertThrows(BizException.class, () -> service.publish(SCH, 9L));
|
||||
assertTrue(ex.getMessage().contains("level"), "红牌要点名未知变量:" + ex.getMessage());
|
||||
@@ -147,7 +148,7 @@ class FlowDefAdminServicePublishContractTest {
|
||||
FlwDef d = draft("FU1");
|
||||
d.setContentJson(JSON.replace("grade == 'g1'", "reason > 3"));
|
||||
when(defRepository.findById(9L)).thenReturn(java.util.Optional.of(d));
|
||||
when(schemaClient.fetchSchema(SCH, "FU1")).thenReturn(snapshot());
|
||||
when(schemaClient.fetchSchema(SCH, "FU1", 3)).thenReturn(snapshot());
|
||||
|
||||
BizException ex = assertThrows(BizException.class, () -> service.publish(SCH, 9L));
|
||||
assertTrue(ex.getMessage().contains("类型桶查②") && ex.getMessage().contains("reason"),
|
||||
@@ -159,7 +160,7 @@ class FlowDefAdminServicePublishContractTest {
|
||||
FlwDef d = draft("FU1");
|
||||
d.setContentJson(JSON.replace("grade == 'g1'", "days == 'three'"));
|
||||
when(defRepository.findById(9L)).thenReturn(java.util.Optional.of(d));
|
||||
when(schemaClient.fetchSchema(SCH, "FU1")).thenReturn(snapshot());
|
||||
when(schemaClient.fetchSchema(SCH, "FU1", 3)).thenReturn(snapshot());
|
||||
|
||||
BizException ex = assertThrows(BizException.class, () -> service.publish(SCH, 9L));
|
||||
assertTrue(ex.getMessage().contains("类型桶查②") && ex.getMessage().contains("days"),
|
||||
@@ -171,7 +172,7 @@ class FlowDefAdminServicePublishContractTest {
|
||||
FlwDef d = draft("FU1");
|
||||
d.setContentJson(JSON.replace("grade == 'g1'", "grade == 'g9'"));
|
||||
when(defRepository.findById(9L)).thenReturn(java.util.Optional.of(d));
|
||||
when(schemaClient.fetchSchema(SCH, "FU1")).thenReturn(snapshot());
|
||||
when(schemaClient.fetchSchema(SCH, "FU1", 3)).thenReturn(snapshot());
|
||||
|
||||
BizException ex = assertThrows(BizException.class, () -> service.publish(SCH, 9L));
|
||||
assertTrue(ex.getMessage().contains("域查③") && ex.getMessage().contains("g9"),
|
||||
@@ -184,7 +185,7 @@ class FlowDefAdminServicePublishContractTest {
|
||||
FlwDef d = draft("FU1");
|
||||
d.setContentJson(JSON.replace("grade == 'g1'", "days >= 2.5"));
|
||||
when(defRepository.findById(9L)).thenReturn(java.util.Optional.of(d));
|
||||
when(schemaClient.fetchSchema(SCH, "FU1")).thenReturn(snapshot());
|
||||
when(schemaClient.fetchSchema(SCH, "FU1", 3)).thenReturn(snapshot());
|
||||
|
||||
assertEquals(FlwEnums.DefStatus.PUBLISHED.getCode(), service.publish(SCH, 9L).getStatus());
|
||||
}
|
||||
@@ -195,7 +196,7 @@ class FlowDefAdminServicePublishContractTest {
|
||||
FlwDef d = draft("FU1");
|
||||
d.setContentJson(JSON.replace("grade == 'g1'", "bizType == 'x'"));
|
||||
when(defRepository.findById(9L)).thenReturn(java.util.Optional.of(d));
|
||||
when(schemaClient.fetchSchema(SCH, "FU1")).thenReturn(snapshot());
|
||||
when(schemaClient.fetchSchema(SCH, "FU1", 3)).thenReturn(snapshot());
|
||||
|
||||
assertEquals(FlwEnums.DefStatus.PUBLISHED.getCode(), service.publish(SCH, 9L).getStatus());
|
||||
}
|
||||
@@ -208,16 +209,18 @@ class FlowDefAdminServicePublishContractTest {
|
||||
|
||||
assertEquals(FlwEnums.DefStatus.PUBLISHED.getCode(), published.getStatus());
|
||||
assertEquals(JSON, published.getContentJson(), "存量线 content_json 一字不动");
|
||||
verify(schemaClient, never()).fetchSchema(anyLong(), anyString());
|
||||
verify(schemaClient, never()).fetchSchema(anyLong(), anyString(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void schemaUnavailableBlocksPublishAsRetryableBizError() {
|
||||
when(defRepository.findById(9L)).thenReturn(java.util.Optional.of(draft("FU1")));
|
||||
when(schemaClient.fetchSchema(SCH, "FU1"))
|
||||
when(schemaClient.fetchSchema(SCH, "FU1", 3))
|
||||
.thenThrow(new FormCenterSchemaClient.SchemaUnavailableException("timeout", null));
|
||||
|
||||
BizException ex = assertThrows(BizException.class, () -> service.publish(SCH, 9L));
|
||||
assertEquals(com.yunhai.flowcenter.enums.FormBindingErrorCode.SCHEMA_UNAVAILABLE.getCode(),
|
||||
ex.getErrorCode().getCode());
|
||||
assertTrue(ex.getMessage().contains("快照拉取失败"), "发布阻断文案可辨认:" + ex.getMessage());
|
||||
verify(defRepository, never()).save(any());
|
||||
}
|
||||
|
||||
@@ -2,6 +2,12 @@ package com.yunhai.flowcenter.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.yunhai.platform.openapi.core.YschOpenCall;
|
||||
import com.yunhai.platform.openapi.core.OpenApiException;
|
||||
import com.yunhai.platform.openapi.core.OpenApiErrorCode;
|
||||
import com.yunhai.platform.utils.exception.DException;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.junit.jupiter.params.provider.NullSource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -72,7 +78,7 @@ class FormCenterSchemaClientTest {
|
||||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class)))
|
||||
.thenReturn(schemaData("U1", 3, Arrays.asList("STUDENT", "TEACHER")));
|
||||
|
||||
Map<String, Object> snap = client.fetchSchema(27L, "U1");
|
||||
Map<String, Object> snap = client.fetchSchema(27L, "U1", 3);
|
||||
|
||||
assertEquals("U1", snap.get("formUuid"));
|
||||
assertEquals(3, snap.get("formVersion"));
|
||||
@@ -88,11 +94,11 @@ class FormCenterSchemaClientTest {
|
||||
|
||||
@Test
|
||||
void legacySingleStringAudienceIsWrappedAsArray() {
|
||||
Map<String, Object> data = schemaData("U1", 1, null);
|
||||
Map<String, Object> data = schemaData("U1", 3, null);
|
||||
data.put("audience", "STUDENT");
|
||||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class))).thenReturn(data);
|
||||
|
||||
Map<String, Object> snap = client.fetchSchema(27L, "U1");
|
||||
Map<String, Object> snap = client.fetchSchema(27L, "U1", 3);
|
||||
|
||||
assertEquals(Arrays.asList("STUDENT"), snap.get("audience"),
|
||||
"C5 切换窗口的旧单值串按一元素数组容错");
|
||||
@@ -104,7 +110,7 @@ class FormCenterSchemaClientTest {
|
||||
.thenThrow(new RuntimeException("connect refused"));
|
||||
|
||||
assertThrows(FormCenterSchemaClient.SchemaUnavailableException.class,
|
||||
() -> client.fetchSchema(27L, "U1"));
|
||||
() -> client.fetchSchema(27L, "U1", 3));
|
||||
verify(openCall, times(FormCenterSchemaClient.MAX_ATTEMPTS))
|
||||
.get(anyString(), anyString(), anyMap(), eq(Map.class));
|
||||
}
|
||||
@@ -115,7 +121,77 @@ class FormCenterSchemaClientTest {
|
||||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class))).thenReturn(null);
|
||||
|
||||
assertThrows(FormCenterSchemaClient.SchemaUnavailableException.class,
|
||||
() -> client.fetchSchema(27L, "U1"));
|
||||
assertTrue(true);
|
||||
() -> client.fetchSchema(27L, "U1", 3));
|
||||
verify(openCall, times(FormCenterSchemaClient.MAX_ATTEMPTS))
|
||||
.get(anyString(), anyString(), anyMap(), eq(Map.class));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@NullSource
|
||||
@ValueSource(strings = {"0", "-1", "4", "3.5", "wrong", "2147483648"})
|
||||
void malformedOrWrongReturnedVersionIsContractFailureWithoutRetry(String returnedVersion) {
|
||||
Map<String, Object> data = schemaData("U1", 3, Arrays.asList("STUDENT"));
|
||||
data.put("version", returnedVersion);
|
||||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class))).thenReturn(data);
|
||||
assertThrows(FormCenterSchemaClient.SchemaContractViolationException.class,
|
||||
() -> client.fetchSchema(27L, "U1", 3));
|
||||
verify(openCall, times(1)).get(anyString(), anyString(), anyMap(), eq(Map.class));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@NullSource
|
||||
@ValueSource(strings = {"", "U2"})
|
||||
void missingOrWrongReturnedUuidIsContractFailureWithoutRetry(String returnedUuid) {
|
||||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class)))
|
||||
.thenReturn(schemaData(returnedUuid, 3, Arrays.asList("STUDENT")));
|
||||
assertThrows(FormCenterSchemaClient.SchemaContractViolationException.class,
|
||||
() -> client.fetchSchema(27L, "U1", 3));
|
||||
verify(openCall, times(1)).get(anyString(), anyString(), anyMap(), eq(Map.class));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {0, -1})
|
||||
void illegalRequestedVersionMakesNoRemoteCall(int version) {
|
||||
assertThrows(IllegalArgumentException.class, () -> client.fetchSchema(27L, "U1", version));
|
||||
org.mockito.Mockito.verifyNoInteractions(openCall);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resourceRejectionUsesEnvelopeCodeAndDoesNotRetry() {
|
||||
// SDK 实际携带 OpenApiErrorCode,不会转换成本地 ErrorCode 枚举;文案刻意无关键词。
|
||||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class)))
|
||||
.thenThrow(new DException(new OpenApiErrorCode(2, "opaque")));
|
||||
assertThrows(FormCenterSchemaClient.SchemaResourceUnavailableException.class,
|
||||
() -> client.fetchSchema(27L, "U1", 3));
|
||||
verify(openCall, times(1)).get(anyString(), anyString(), anyMap(), eq(Map.class));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {3, 4})
|
||||
void authRejectionDoesNotBlindlyRetry(int code) {
|
||||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class)))
|
||||
.thenThrow(new DException(new OpenApiErrorCode(code, "opaque")));
|
||||
assertThrows(FormCenterSchemaClient.SchemaAccessDeniedException.class,
|
||||
() -> client.fetchSchema(27L, "U1", 3));
|
||||
verify(openCall, times(1)).get(anyString(), anyString(), anyMap(), eq(Map.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void http404DoesNotBlindlyRetry() {
|
||||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class)))
|
||||
.thenThrow(new OpenApiException("opaque", 404, ""));
|
||||
assertThrows(FormCenterSchemaClient.SchemaResourceUnavailableException.class,
|
||||
() -> client.fetchSchema(27L, "U1", 3));
|
||||
verify(openCall, times(1)).get(anyString(), anyString(), anyMap(), eq(Map.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void internalRemoteFailureRemainsRetryable() {
|
||||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class)))
|
||||
.thenThrow(new DException(new OpenApiErrorCode(6, "opaque")));
|
||||
assertThrows(FormCenterSchemaClient.SchemaUnavailableException.class,
|
||||
() -> client.fetchSchema(27L, "U1", 3));
|
||||
verify(openCall, times(FormCenterSchemaClient.MAX_ATTEMPTS))
|
||||
.get(anyString(), anyString(), anyMap(), eq(Map.class));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user