Merge branch 'feature/standard-message-djb'
This commit is contained in:
+1
-1
Submodule elink-online-common updated: 024b24af49...d81aeeef67
+1
-1
Submodule elink-online-transformer updated: c8a58fdf5b...17f6df5068
@@ -205,6 +205,9 @@ public class StandardMessageCoordinatorDJB extends DefaultStandardMessageCoordin
|
||||
InterfaceMapper mapper = manager.getMapper();
|
||||
mapper.setResponseType(responseMessage, STDMessageKeys.RESPONSE_TYPE_CODE_N);
|
||||
|
||||
// 요청응답구분 = 응답(R) — dman_rspn_dvcd 기본값이 S(요청)이므로 반드시 설정
|
||||
mapper.setSendRecvDivision(responseMessage, STDMessageKeys.SEND_RECV_CD_RECV);
|
||||
|
||||
// MSG 영역 활성화
|
||||
StandardItem msgItem = responseMessage.findItem("MSG");
|
||||
if (msgItem != null) {
|
||||
|
||||
@@ -16,10 +16,9 @@ SEND_TIME=HEAD.frst_mesg_dman_time
|
||||
RECV_TIME=HEAD.mesg_rspn_time
|
||||
SYSTEM_TYPE=HEAD.trnm_sys_dvcd
|
||||
TIMEOUT=HEAD.gnrz_tmot_tktm
|
||||
INST_CODE=HEAD.eai_node_dvcd
|
||||
INST_CODE=HEAD.xtis_cd
|
||||
USER_ID=HEAD.tlrno
|
||||
REQ_SYS_CODE=HEAD.chnl_tycd
|
||||
# MSG 영역 (응답 시 활성화)
|
||||
REQ_SYS_CODE=
|
||||
ERROR_CODE=MSG.MAIN_MSG.outp_msg_cd
|
||||
ERROR_MSG=MSG.MAIN_MSG.outp_msg_ctnt
|
||||
RESPONSE_TYPE=HEAD.procs_rslt_dvcd
|
||||
|
||||
@@ -0,0 +1,544 @@
|
||||
package com.eactive.eai.custom.message;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import com.eactive.eai.common.monitor.EAIServiceMonitor;
|
||||
import com.eactive.eai.common.property.PropManager;
|
||||
import com.eactive.eai.common.server.EAIServerManager;
|
||||
import com.eactive.eai.common.util.ApplicationContextProvider;
|
||||
import com.eactive.eai.message.StandardItem;
|
||||
import com.eactive.eai.message.StandardMessage;
|
||||
import com.eactive.eai.message.manager.StandardMessageManager;
|
||||
import com.eactive.eai.message.parser.JsonReader;
|
||||
import com.eactive.eai.message.parser.StandardReader;
|
||||
import com.eactive.eai.message.service.InterfaceMapper;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
|
||||
/**
|
||||
* DJBank 표준전문 FLAT 직렬화/파싱 흐름 통합 테스트
|
||||
*
|
||||
* 검증 시나리오:
|
||||
* 1. FlatReader 등록 확인
|
||||
* 2. 비ERP 요청 FLAT 왕복 — HEAD 보존, EZDATA/MSG 바이트 미포함
|
||||
* 3. ERP 요청 FLAT 왕복 — EZDATA 포함 보존
|
||||
* 4. 오류 응답 FLAT 왕복 — MSG EM 포함 보존
|
||||
* 5. 정상 응답 FLAT 왕복 — MSG NM 포함 보존
|
||||
* 6. 거래로그 시나리오 — FLAT 바이트 길이 검증 (조건부 블록 포함 여부)
|
||||
*
|
||||
* 핵심 버그 (EZDATA FLAT 오류):
|
||||
* JSON 파싱 시 JSON에 없는 조건부 블록(EZDATA, MSG)은 isHidden=false 로 남는다.
|
||||
* toByteArray() GROUP 케이스에서 size=0 이면서 refPath/refValue 가 있는 경우
|
||||
* isHidden 체크만으로는 불충분 → FLAT에 비활성 블록 바이트가 잘못 포함된다.
|
||||
*
|
||||
* 수정: toByteArray() / getBytesDataLength() GROUP 케이스를
|
||||
* toJson() 과 동일하게 size==0 이면 무조건 skip 으로 변경
|
||||
* (StandardItem.java 두 곳)
|
||||
*/
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class StandardMessageFlatFlowTest {
|
||||
|
||||
private static final String TEST_GUID =
|
||||
"20260420" + "120000" + "000" + "EAI" + "01" + "123456789012" + "000001";
|
||||
// 8+6+3+3+2+12+6 = 40자
|
||||
|
||||
private static final String TEST_IF_ID = "IF_DJBTEST_FLAT01";
|
||||
private static final String TEST_TX_ID = "TXTEST000003";
|
||||
private static final String FLAT_CHARSET = "euc-kr";
|
||||
|
||||
/** 비ERP 요청 JSON — dman_rspn_dvcd=S, corp_tlwn_virt_brcd 미설정 */
|
||||
private static final String NON_ERP_REQ_JSON =
|
||||
"{"
|
||||
+ "\"HEAD\":{"
|
||||
+ "\"nxgn_stnd_idfr\":\"JERA\","
|
||||
+ "\"guid\":\"" + TEST_GUID + "\","
|
||||
+ "\"guid_prgs_no\":\"1\","
|
||||
+ "\"stnd_mesg_ver\":\"R10\","
|
||||
+ "\"ortr_guid\":\"" + TEST_GUID + "\","
|
||||
+ "\"dman_rspn_dvcd\":\"S\","
|
||||
+ "\"if_id\":\"" + TEST_IF_ID + "\","
|
||||
+ "\"procs_rslt_dvcd\":\"S\","
|
||||
+ "\"tx_id\":\"" + TEST_TX_ID + "\","
|
||||
+ "\"chnl_tycd\":\"EAI\","
|
||||
+ "\"hmab_dvcd\":\"1\","
|
||||
+ "\"trnm_sys_dvcd\":\"OPA\","
|
||||
+ "\"frst_trnm_sys_dvcd\":\"OPA\","
|
||||
+ "\"sys_env_dvcd\":\"D\","
|
||||
+ "\"frst_mesg_dman_dt\":\"20260420\","
|
||||
+ "\"frst_mesg_dman_time\":\"120000000\""
|
||||
+ "},"
|
||||
+ "\"DATA\":{"
|
||||
+ "\"data_dvcd\":\"IO\","
|
||||
+ "\"data_scop_len\":\"00000037\","
|
||||
+ "\"BIZ_DATA\":{\"acct_no\":\"123456789\",\"amt\":\"100000\"}"
|
||||
+ "}"
|
||||
+ "}";
|
||||
|
||||
/** ERP 요청 JSON — corp_tlwn_virt_brcd=ERP, EZDATA 포함 */
|
||||
private static final String ERP_REQ_JSON =
|
||||
"{"
|
||||
+ "\"HEAD\":{"
|
||||
+ "\"nxgn_stnd_idfr\":\"JERA\","
|
||||
+ "\"guid\":\"" + TEST_GUID + "\","
|
||||
+ "\"guid_prgs_no\":\"1\","
|
||||
+ "\"stnd_mesg_ver\":\"R10\","
|
||||
+ "\"ortr_guid\":\"" + TEST_GUID + "\","
|
||||
+ "\"dman_rspn_dvcd\":\"S\","
|
||||
+ "\"if_id\":\"" + TEST_IF_ID + "\","
|
||||
+ "\"procs_rslt_dvcd\":\"S\","
|
||||
+ "\"tx_id\":\"" + TEST_TX_ID + "\","
|
||||
+ "\"chnl_tycd\":\"EAI\","
|
||||
+ "\"hmab_dvcd\":\"1\","
|
||||
+ "\"corp_tlwn_virt_brcd\":\"ERP\","
|
||||
+ "\"trnm_sys_dvcd\":\"OPA\","
|
||||
+ "\"frst_trnm_sys_dvcd\":\"OPA\","
|
||||
+ "\"sys_env_dvcd\":\"D\","
|
||||
+ "\"frst_mesg_dman_dt\":\"20260420\","
|
||||
+ "\"frst_mesg_dman_time\":\"120000000\""
|
||||
+ "},"
|
||||
+ "\"EZDATA\":{"
|
||||
+ "\"login_mhod_dvcd\":\"1\","
|
||||
+ "\"elfn_bnkn_dvcd\":\"01\","
|
||||
+ "\"usr_no\":\"USR0000000000001\","
|
||||
+ "\"rgsr_id\":\"REG_ID_000000001\","
|
||||
+ "\"secu_media_dvcd\":\"00\","
|
||||
+ "\"secu_media_sta_dvcd\":\"00\","
|
||||
+ "\"brll_srcd_yn\":\"N\","
|
||||
+ "\"next_data_exis_yn\":\"N\","
|
||||
+ "\"page_no\":\"00001\","
|
||||
+ "\"page_size\":\"00020\","
|
||||
+ "\"dup_tx_yn\":\"N\""
|
||||
+ "},"
|
||||
+ "\"DATA\":{"
|
||||
+ "\"data_dvcd\":\"IO\","
|
||||
+ "\"data_scop_len\":\"00000037\","
|
||||
+ "\"BIZ_DATA\":{\"acct_no\":\"987654321\",\"amt\":\"500000\"}"
|
||||
+ "}"
|
||||
+ "}";
|
||||
|
||||
private StandardMessageManager manager;
|
||||
private InterfaceMapper mapper;
|
||||
private StandardReader flatReader;
|
||||
private JsonReader jsonReader;
|
||||
private StandardMessageCoordinatorDJB coordinator;
|
||||
|
||||
@BeforeAll
|
||||
void setUpAll() throws Exception {
|
||||
PropManager mockPropManager = Mockito.mock(PropManager.class);
|
||||
Mockito.when(mockPropManager.getProperty(anyString(), anyString(), anyString()))
|
||||
.thenAnswer(new Answer<String>() {
|
||||
public String answer(InvocationOnMock inv) { return (String) inv.getArguments()[2]; }
|
||||
});
|
||||
|
||||
EAIServerManager mockServer = Mockito.mock(EAIServerManager.class);
|
||||
Mockito.when(mockServer.isPEAIServer()).thenReturn(false);
|
||||
Mockito.when(mockServer.isSEAIServer()).thenReturn(false);
|
||||
Mockito.when(mockServer.isMCI()).thenReturn(false);
|
||||
Mockito.when(mockServer.getLocalServerName()).thenReturn("TEST_SERVER");
|
||||
Mockito.when(mockServer.getGroupInstId()).thenReturn("TEST_INST");
|
||||
|
||||
EAIServiceMonitor mockMonitor = Mockito.mock(EAIServiceMonitor.class);
|
||||
Mockito.when(mockMonitor.isTimeOutCodes(anyString())).thenReturn(false);
|
||||
Mockito.when(mockMonitor.isBizErrorCodes(anyString())).thenReturn(false);
|
||||
|
||||
ApplicationContext mockCtx = Mockito.mock(ApplicationContext.class);
|
||||
Mockito.when(mockCtx.getBean(EAIServerManager.class)).thenReturn(mockServer);
|
||||
Mockito.when(mockCtx.getBean(PropManager.class)).thenReturn(mockPropManager);
|
||||
Mockito.when(mockCtx.getBean(EAIServiceMonitor.class)).thenReturn(mockMonitor);
|
||||
|
||||
Field ctxField = ApplicationContextProvider.class.getDeclaredField("context");
|
||||
ctxField.setAccessible(true);
|
||||
ctxField.set(null, mockCtx);
|
||||
|
||||
System.setProperty(StandardMessageManager.STANDARD_MESSAGE_CONFIG,
|
||||
"src/test/resources/standard-message-config-test.properties");
|
||||
manager = StandardMessageManager.getInstance();
|
||||
manager.init();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
mapper = manager.getMapper();
|
||||
flatReader = manager.getReader("FLAT");
|
||||
jsonReader = (JsonReader) manager.getReader("JSON");
|
||||
coordinator = new StandardMessageCoordinatorDJB();
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 1. FlatReader 등록 확인
|
||||
// ================================================================
|
||||
|
||||
@Test
|
||||
void FlatReader_등록_확인() {
|
||||
assertNotNull(flatReader, "FlatReader가 등록되지 않음 (reader.FLAT 설정 확인)");
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 2. 비ERP 요청 FLAT 왕복 — HEAD 보존, EZDATA/MSG 비포함
|
||||
//
|
||||
// [버그] 수정 전: EZDATA(1500B) + MSG(10B) 가 FLAT에 잘못 포함
|
||||
// → FlatReader 파싱 시 overflow 예외 발생
|
||||
// [수정] StandardItem.toByteArray() GROUP 케이스: size==0 이면 무조건 skip
|
||||
// ================================================================
|
||||
|
||||
@Test
|
||||
void 비ERP요청_FLAT_파싱_예외없음() throws Exception {
|
||||
StandardMessage src = parseJson(NON_ERP_REQ_JSON);
|
||||
String flatStr = src.toFixedString(false, FLAT_CHARSET);
|
||||
|
||||
StandardMessage dst = manager.getStandardMessage();
|
||||
assertDoesNotThrow(() -> flatReader.parse(dst, flatStr),
|
||||
"비ERP FLAT 파싱 중 예외 발생 — EZDATA 바이트 오버플로우 버그 확인 필요\n"
|
||||
+ "원인: StandardItem.toByteArray() GROUP size==0 skip 조건 미적용");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 비ERP요청_FLAT_왕복_HEAD_guid_보존() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(NON_ERP_REQ_JSON));
|
||||
|
||||
assertEquals(TEST_GUID, dst.findItemValue("HEAD.guid").trim(),
|
||||
"FLAT 왕복 후 HEAD.guid 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 비ERP요청_FLAT_왕복_HEAD_if_id_보존() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(NON_ERP_REQ_JSON));
|
||||
|
||||
assertEquals(TEST_IF_ID, dst.findItemValue("HEAD.if_id").trim(),
|
||||
"FLAT 왕복 후 HEAD.if_id 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 비ERP요청_FLAT_왕복_HEAD_dman_rspn_dvcd_S() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(NON_ERP_REQ_JSON));
|
||||
|
||||
assertEquals("S", dst.findItemValue("HEAD.dman_rspn_dvcd").trim(),
|
||||
"FLAT 왕복 후 HEAD.dman_rspn_dvcd 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 비ERP요청_FLAT_왕복_HEAD_stnd_mesg_ver_R10() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(NON_ERP_REQ_JSON));
|
||||
|
||||
assertEquals("R10", dst.findItemValue("HEAD.stnd_mesg_ver").trim(),
|
||||
"FLAT 왕복 후 HEAD.stnd_mesg_ver 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 비ERP요청_FLAT_왕복_DATA_data_dvcd_IO() throws Exception {
|
||||
// [버그] 수정 전: MSG 바이트가 잘못 포함 → DATA.data_dvcd 자리에 MSG 바이트 읽힘 ("NM")
|
||||
StandardMessage dst = flatRoundTrip(parseJson(NON_ERP_REQ_JSON));
|
||||
|
||||
assertEquals("IO", dst.findItemValue("DATA.data_dvcd").trim(),
|
||||
"FLAT 왕복 후 DATA.data_dvcd 불일치 — MSG 바이트 오염 가능성");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 비ERP요청_FLAT_왕복_EZDATA_비활성() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(NON_ERP_REQ_JSON));
|
||||
|
||||
StandardItem ezdataItem = dst.findItem("EZDATA");
|
||||
assertTrue(ezdataItem == null || ezdataItem.isHidden() || ezdataItem.getSize() == 0,
|
||||
"비ERP FLAT 왕복 후 EZDATA 블록이 활성 상태이면 안 됨");
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 3. ERP 요청 FLAT 왕복 — EZDATA 포함
|
||||
// ================================================================
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_파싱_예외없음() throws Exception {
|
||||
StandardMessage src = parseJson(ERP_REQ_JSON);
|
||||
String flatStr = src.toFixedString(false, FLAT_CHARSET);
|
||||
|
||||
StandardMessage dst = manager.getStandardMessage();
|
||||
assertDoesNotThrow(() -> flatReader.parse(dst, flatStr),
|
||||
"ERP FLAT 파싱 중 예외 발생");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_왕복_HEAD_guid_보존() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(ERP_REQ_JSON));
|
||||
|
||||
assertEquals(TEST_GUID, dst.findItemValue("HEAD.guid").trim(),
|
||||
"ERP FLAT 왕복 후 HEAD.guid 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_왕복_HEAD_corp_tlwn_virt_brcd_ERP() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(ERP_REQ_JSON));
|
||||
|
||||
assertEquals("ERP", dst.findItemValue("HEAD.corp_tlwn_virt_brcd").trim(),
|
||||
"ERP FLAT 왕복 후 HEAD.corp_tlwn_virt_brcd 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_왕복_EZDATA_활성() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(ERP_REQ_JSON));
|
||||
|
||||
StandardItem ezdataItem = dst.findItem("EZDATA");
|
||||
assertNotNull(ezdataItem, "ERP FLAT 왕복 후 EZDATA 블록 없음");
|
||||
assertFalse(ezdataItem.isHidden(), "ERP FLAT 왕복 후 EZDATA 블록이 hidden 상태");
|
||||
assertTrue(ezdataItem.getSize() > 0, "ERP FLAT 왕복 후 EZDATA 블록 size가 0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_왕복_EZDATA_login_mhod_dvcd_보존() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(ERP_REQ_JSON));
|
||||
|
||||
assertEquals("1", dst.findItemValue("EZDATA.login_mhod_dvcd").trim(),
|
||||
"ERP FLAT 왕복 후 EZDATA.login_mhod_dvcd 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_왕복_EZDATA_elfn_bnkn_dvcd_보존() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(ERP_REQ_JSON));
|
||||
|
||||
assertEquals("01", dst.findItemValue("EZDATA.elfn_bnkn_dvcd").trim(),
|
||||
"ERP FLAT 왕복 후 EZDATA.elfn_bnkn_dvcd 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_왕복_EZDATA_usr_no_보존() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(ERP_REQ_JSON));
|
||||
|
||||
assertEquals("USR0000000000001", dst.findItemValue("EZDATA.usr_no").trim(),
|
||||
"ERP FLAT 왕복 후 EZDATA.usr_no 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_왕복_EZDATA_rgsr_id_보존() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(ERP_REQ_JSON));
|
||||
|
||||
assertEquals("REG_ID_000000001", dst.findItemValue("EZDATA.rgsr_id").trim(),
|
||||
"ERP FLAT 왕복 후 EZDATA.rgsr_id 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_왕복_EZDATA_secu_media_dvcd_보존() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(ERP_REQ_JSON));
|
||||
|
||||
assertEquals("00", dst.findItemValue("EZDATA.secu_media_dvcd").trim(),
|
||||
"ERP FLAT 왕복 후 EZDATA.secu_media_dvcd 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_왕복_EZDATA_dup_tx_yn_보존() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(ERP_REQ_JSON));
|
||||
|
||||
assertEquals("N", dst.findItemValue("EZDATA.dup_tx_yn").trim(),
|
||||
"ERP FLAT 왕복 후 EZDATA.dup_tx_yn 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_왕복_EZDATA_NUMBER_page_no_보존() throws Exception {
|
||||
// page_no 는 NUMBER 타입: "00001" → toTypeValue() 선행 0 제거 → "1"
|
||||
StandardMessage dst = flatRoundTrip(parseJson(ERP_REQ_JSON));
|
||||
|
||||
String pageNo = dst.findItemValue("EZDATA.page_no").trim();
|
||||
assertFalse(pageNo.isEmpty(), "ERP FLAT 왕복 후 EZDATA.page_no가 비어 있음");
|
||||
assertEquals(1, Integer.parseInt(pageNo),
|
||||
"ERP FLAT 왕복 후 EZDATA.page_no 값 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_왕복_EZDATA_NUMBER_page_size_보존() throws Exception {
|
||||
// page_size 는 NUMBER 타입: "00020" → "20"
|
||||
StandardMessage dst = flatRoundTrip(parseJson(ERP_REQ_JSON));
|
||||
|
||||
String pageSize = dst.findItemValue("EZDATA.page_size").trim();
|
||||
assertFalse(pageSize.isEmpty(), "ERP FLAT 왕복 후 EZDATA.page_size가 비어 있음");
|
||||
assertEquals(20, Integer.parseInt(pageSize),
|
||||
"ERP FLAT 왕복 후 EZDATA.page_size 값 불일치");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ERP요청_FLAT_왕복_DATA_data_dvcd_IO() throws Exception {
|
||||
// [버그] 수정 전: MSG 바이트가 잘못 포함 → DATA.data_dvcd 자리에 MSG 바이트 읽힘
|
||||
StandardMessage dst = flatRoundTrip(parseJson(ERP_REQ_JSON));
|
||||
|
||||
assertEquals("IO", dst.findItemValue("DATA.data_dvcd").trim(),
|
||||
"ERP FLAT 왕복 후 DATA.data_dvcd 불일치 — MSG 바이트 오염 가능성");
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 4. 오류 응답 FLAT 왕복 — MSG EM 포함
|
||||
// coordinateSetStandardMessageError() → MSG.size=1, MAIN_MSG.size=1
|
||||
// ================================================================
|
||||
|
||||
@Test
|
||||
void 오류응답_FLAT_파싱_예외없음() throws Exception {
|
||||
StandardMessage src = manager.getStandardMessage();
|
||||
coordinator.coordinateSetStandardMessageError(src, mapper, "RECEAICMM999", "테스트 오류");
|
||||
String flatStr = src.toFixedString(false, FLAT_CHARSET);
|
||||
|
||||
StandardMessage dst = manager.getStandardMessage();
|
||||
assertDoesNotThrow(() -> flatReader.parse(dst, flatStr),
|
||||
"오류응답 FLAT 파싱 중 예외 발생");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 오류응답_FLAT_왕복_HEAD_procs_rslt_dvcd_F() throws Exception {
|
||||
StandardMessage src = manager.getStandardMessage();
|
||||
coordinator.coordinateSetStandardMessageError(src, mapper, "RECEAICMM999", "테스트 오류");
|
||||
|
||||
assertEquals("F", flatRoundTrip(src).findItemValue("HEAD.procs_rslt_dvcd").trim(),
|
||||
"오류응답 FLAT 왕복 후 HEAD.procs_rslt_dvcd가 F가 아님");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 오류응답_FLAT_왕복_MSG_msg_dvcd_EM() throws Exception {
|
||||
StandardMessage src = manager.getStandardMessage();
|
||||
coordinator.coordinateSetStandardMessageError(src, mapper, "RECEAICMM999", "테스트 오류");
|
||||
|
||||
assertEquals("EM", flatRoundTrip(src).findItemValue("MSG.msg_dvcd").trim(),
|
||||
"오류응답 FLAT 왕복 후 MSG.msg_dvcd가 EM이 아님");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 오류응답_FLAT_왕복_MSG_outp_atrb_cd_1_팝업() throws Exception {
|
||||
StandardMessage src = manager.getStandardMessage();
|
||||
coordinator.coordinateSetStandardMessageError(src, mapper, "RECEAICMM999", "테스트 오류");
|
||||
|
||||
assertEquals("1", flatRoundTrip(src).findItemValue("MSG.MAIN_MSG.outp_atrb_cd").trim(),
|
||||
"오류응답 FLAT 왕복 후 MSG.MAIN_MSG.outp_atrb_cd가 1(팝업)이 아님");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 오류응답_FLAT_왕복_MSG_MAIN_MSG_활성() throws Exception {
|
||||
StandardMessage src = manager.getStandardMessage();
|
||||
coordinator.coordinateSetStandardMessageError(src, mapper, "RECEAICMM999", "테스트 오류");
|
||||
|
||||
StandardItem mainMsgItem = flatRoundTrip(src).findItem("MSG.MAIN_MSG");
|
||||
assertNotNull(mainMsgItem, "오류응답 FLAT 왕복 후 MSG.MAIN_MSG 블록 없음");
|
||||
assertTrue(mainMsgItem.getSize() > 0,
|
||||
"오류응답 FLAT 왕복 후 MSG.MAIN_MSG size가 0");
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 5. 정상 응답 FLAT 왕복 — MSG NM 포함
|
||||
// coordinateAfterRecvNonStdSyncResponse() → MSG.size=1, MAIN_MSG.size=1
|
||||
// ================================================================
|
||||
|
||||
@Test
|
||||
void 정상응답_FLAT_파싱_예외없음() throws Exception {
|
||||
StandardMessage src = manager.getStandardMessage();
|
||||
coordinator.coordinateAfterRecvNonStdSyncResponse(src);
|
||||
String flatStr = src.toFixedString(false, FLAT_CHARSET);
|
||||
|
||||
StandardMessage dst = manager.getStandardMessage();
|
||||
assertDoesNotThrow(() -> flatReader.parse(dst, flatStr),
|
||||
"정상응답 FLAT 파싱 중 예외 발생");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 정상응답_FLAT_왕복_MSG_msg_dvcd_NM() throws Exception {
|
||||
StandardMessage src = manager.getStandardMessage();
|
||||
coordinator.coordinateAfterRecvNonStdSyncResponse(src);
|
||||
|
||||
assertEquals("NM", flatRoundTrip(src).findItemValue("MSG.msg_dvcd").trim(),
|
||||
"정상응답 FLAT 왕복 후 MSG.msg_dvcd가 NM이 아님");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 정상응답_FLAT_왕복_MSG_활성() throws Exception {
|
||||
StandardMessage src = manager.getStandardMessage();
|
||||
coordinator.coordinateAfterRecvNonStdSyncResponse(src);
|
||||
StandardMessage dst = flatRoundTrip(src);
|
||||
|
||||
StandardItem msgItem = dst.findItem("MSG");
|
||||
assertNotNull(msgItem, "정상응답 FLAT 왕복 후 MSG 블록 없음");
|
||||
assertFalse(msgItem.isHidden(), "정상응답 FLAT 왕복 후 MSG 블록이 hidden 상태");
|
||||
assertTrue(msgItem.getSize() > 0, "정상응답 FLAT 왕복 후 MSG 블록 size가 0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 정상응답_FLAT_왕복_MSG_MAIN_MSG_활성() throws Exception {
|
||||
StandardMessage src = manager.getStandardMessage();
|
||||
coordinator.coordinateAfterRecvNonStdSyncResponse(src);
|
||||
|
||||
StandardItem mainMsgItem = flatRoundTrip(src).findItem("MSG.MAIN_MSG");
|
||||
assertNotNull(mainMsgItem, "정상응답 FLAT 왕복 후 MSG.MAIN_MSG 블록 없음");
|
||||
assertTrue(mainMsgItem.getSize() > 0,
|
||||
"정상응답 FLAT 왕복 후 MSG.MAIN_MSG size가 0");
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 6. 거래로그 시나리오 — FLAT 바이트 길이로 조건부 블록 포함 여부 검증
|
||||
//
|
||||
// [버그] 수정 전: 비ERP 에도 EZDATA(1500B) 포함 → ERP 와 길이 동일
|
||||
// [수정] 비ERP FLAT < ERP FLAT (EZDATA 1500바이트 차이)
|
||||
// ================================================================
|
||||
|
||||
@Test
|
||||
void 거래로그_비ERP_FLAT_길이가_ERP_FLAT_보다_짧음() throws Exception {
|
||||
byte[] nonErpBytes = parseJson(NON_ERP_REQ_JSON)
|
||||
.toFixedString(false, FLAT_CHARSET).getBytes(FLAT_CHARSET);
|
||||
byte[] erpBytes = parseJson(ERP_REQ_JSON)
|
||||
.toFixedString(false, FLAT_CHARSET).getBytes(FLAT_CHARSET);
|
||||
|
||||
// EZDATA = 1500바이트 — ERP FLAT 이 비ERP FLAT 보다 길어야 함
|
||||
// 버그 발생 시: 둘 다 EZDATA 포함 → 길이 동일 → 검증 실패
|
||||
assertTrue(erpBytes.length > nonErpBytes.length,
|
||||
String.format("ERP FLAT 길이(%d) > 비ERP FLAT 길이(%d) 이어야 함 (EZDATA 1500B 차이)",
|
||||
erpBytes.length, nonErpBytes.length));
|
||||
}
|
||||
|
||||
@Test
|
||||
void 거래로그_요청_FLAT_길이가_응답_FLAT_보다_짧음() throws Exception {
|
||||
// 요청(dman_rspn_dvcd=S): MSG 비활성 / 응답: MSG 활성 → 응답이 더 긺
|
||||
StandardMessage rspMsg = manager.getStandardMessage();
|
||||
coordinator.coordinateAfterRecvNonStdSyncResponse(rspMsg);
|
||||
|
||||
byte[] reqBytes = parseJson(NON_ERP_REQ_JSON)
|
||||
.toFixedString(false, FLAT_CHARSET).getBytes(FLAT_CHARSET);
|
||||
byte[] rspBytes = rspMsg.toFixedString(false, FLAT_CHARSET).getBytes(FLAT_CHARSET);
|
||||
|
||||
// 버그 발생 시: 요청도 MSG 바이트 포함 → 길이 역전 가능
|
||||
assertTrue(rspBytes.length > reqBytes.length,
|
||||
String.format("응답 FLAT 길이(%d) > 요청 FLAT 길이(%d) 이어야 함 (MSG 블록 포함 여부)",
|
||||
rspBytes.length, reqBytes.length));
|
||||
}
|
||||
|
||||
@Test
|
||||
void 비ERP요청_FLAT_왕복_HEAD_chnl_tycd_EAI값확인() throws Exception {
|
||||
StandardMessage dst = flatRoundTrip(parseJson(NON_ERP_REQ_JSON));
|
||||
|
||||
assertEquals("EAI", dst.findItemValue("HEAD.chnl_tycd").trim(),
|
||||
"FLAT 왕복 후 HEAD.chnl_tycd EAI 확인");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ================================================================
|
||||
// helpers
|
||||
// ================================================================
|
||||
|
||||
private StandardMessage parseJson(String json) throws Exception {
|
||||
StandardMessage msg = manager.getStandardMessage();
|
||||
jsonReader.parse(msg, json);
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* FLAT 왕복: src → toFixedString(false, euc-kr) → FlatReader.parse() → dst
|
||||
* STDMessageDAO.addRestoreSTDMessage / getRestoreSTDMessage 와 동일한 흐름
|
||||
*/
|
||||
private StandardMessage flatRoundTrip(StandardMessage src) throws Exception {
|
||||
String flatStr = src.toFixedString(false, FLAT_CHARSET);
|
||||
StandardMessage dst = manager.getStandardMessage();
|
||||
flatReader.parse(dst, flatStr);
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user