package com.tourguide.modules.finance.service;
|
|
import com.alibaba.fastjson.JSONObject;
|
import com.tourguide.common.huifu.biz.DouGongWithdrawBiz;
|
import com.tourguide.common.huifu.biz.FenZhangUtil;
|
import com.tourguide.modules.finance.entity.GuideWithdrawal;
|
import com.tourguide.modules.finance.entity.GuideWithdrawalAccount;
|
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.Test;
|
|
import java.math.BigDecimal;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.when;
|
|
class GuideWithdrawalPayoutServiceTest {
|
private GuideWithdrawalStateService stateService;
|
private GuideSettlementService settlementService;
|
private FenZhangUtil fenZhangUtil;
|
private DouGongWithdrawBiz withdrawBiz;
|
private GuideWithdrawalPayoutService service;
|
|
@BeforeEach
|
void setUp() {
|
stateService = mock(GuideWithdrawalStateService.class);
|
settlementService = mock(GuideSettlementService.class);
|
fenZhangUtil = mock(FenZhangUtil.class);
|
withdrawBiz = mock(DouGongWithdrawBiz.class);
|
service = new GuideWithdrawalPayoutService(
|
stateService, settlementService, fenZhangUtil, withdrawBiz);
|
}
|
|
@Test
|
void approveShouldTransferFromPlatformBeforeSubmittingCash() throws Exception {
|
GuideWithdrawal transferring = withdrawal("TRANSFERRING");
|
transferring.setTransferReqSeqId("TF001");
|
transferring.setTransferReqDate("20260817");
|
GuideWithdrawal cash = withdrawal("PROCESSING");
|
cash.setCashReqSeqId("CW001");
|
cash.setCashReqDate("20260817");
|
GuideWithdrawalAccount account = account();
|
when(stateService.prepareTransfer(20L, null, "admin")).thenReturn(transferring);
|
when(stateService.prepareCash(20L)).thenReturn(cash);
|
when(stateService.find(20L)).thenReturn(cash);
|
when(settlementService.requireApprovedCard(8L, 10)).thenReturn(account);
|
Map<String, Object> transferResponse = new HashMap<>();
|
transferResponse.put("resp_code", "00000000");
|
transferResponse.put("trans_stat", "S");
|
transferResponse.put("hf_seq_id", "HF-TF-1");
|
when(fenZhangUtil.fenzhang("TF001", "20260817", "200.00", "HF100"))
|
.thenReturn(transferResponse);
|
JSONObject cashResponse = new JSONObject();
|
cashResponse.put("resp_code", "00000100");
|
cashResponse.put("resp_desc", "受理成功");
|
when(withdrawBiz.encashment(new BigDecimal("200.00"), "HF100", "TOKEN100",
|
"CW001", "20260817")).thenReturn(cashResponse);
|
|
service.approve(20L, null, "admin");
|
|
verify(stateService).markTransferred(20L, "HF-TF-1");
|
verify(withdrawBiz).encashment(new BigDecimal("200.00"), "HF100", "TOKEN100",
|
"CW001", "20260817");
|
}
|
|
@Test
|
void transferFailureShouldNeverSubmitCash() throws Exception {
|
GuideWithdrawal transferring = withdrawal("TRANSFERRING");
|
transferring.setTransferReqSeqId("TF001");
|
transferring.setTransferReqDate("20260817");
|
when(stateService.prepareTransfer(20L, null, "admin")).thenReturn(transferring);
|
when(stateService.find(20L)).thenReturn(transferring);
|
when(settlementService.requireApprovedCard(8L, 10)).thenReturn(account());
|
Map<String, Object> response = new HashMap<>();
|
response.put("resp_code", "100001");
|
response.put("resp_desc", "主账户余额不足");
|
when(fenZhangUtil.fenzhang("TF001", "20260817", "200.00", "HF100"))
|
.thenReturn(response);
|
|
service.approve(20L, null, "admin");
|
|
verify(stateService).markTransferFailed(20L, "主账户划账失败:主账户余额不足");
|
verify(withdrawBiz, never()).encashment(
|
org.mockito.ArgumentMatchers.any(), anyString(), anyString(), anyString(), anyString());
|
}
|
|
@Test
|
void transferredRecordWithCashSequenceShouldQueryOriginalRequestInsteadOfResubmitting() {
|
GuideWithdrawal transferred = withdrawal("TRANSFERRED");
|
transferred.setCashReqSeqId("CW001");
|
transferred.setCashReqDate("20260818");
|
GuideWithdrawal processing = withdrawal("PROCESSING");
|
processing.setCashReqSeqId("CW001");
|
processing.setCashReqDate("20260818");
|
when(stateService.find(20L)).thenReturn(transferred);
|
when(stateService.resumeCashQuery(20L)).thenReturn(processing);
|
when(settlementService.requireApprovedCard(8L, 10)).thenReturn(account());
|
JSONObject queryResponse = new JSONObject();
|
queryResponse.put("resp_code", "00000000");
|
queryResponse.put("trans_stat", "S");
|
when(withdrawBiz.query("HF100", "20260818", "CW001")).thenReturn(queryResponse);
|
|
service.advance(20L);
|
|
verify(stateService).resumeCashQuery(20L);
|
verify(withdrawBiz).query("HF100", "20260818", "CW001");
|
verify(withdrawBiz, never()).encashment(any(), anyString(), anyString(), anyString(), anyString());
|
verify(stateService).markApproved(20L, null);
|
}
|
|
@Test
|
void cashQueryShouldApproveWhenProviderReturnsCashStatus() {
|
GuideWithdrawal processing = withdrawal("PROCESSING");
|
processing.setCashReqSeqId("CW001");
|
processing.setCashReqDate("20260818");
|
when(stateService.find(20L)).thenReturn(processing);
|
when(settlementService.requireApprovedCard(8L, 10)).thenReturn(account());
|
JSONObject queryResponse = new JSONObject();
|
queryResponse.put("resp_code", "00000000");
|
queryResponse.put("cash_status", "S");
|
when(withdrawBiz.query("HF100", "20260818", "CW001")).thenReturn(queryResponse);
|
|
service.advance(20L);
|
|
verify(stateService).markApproved(20L, null);
|
}
|
|
@Test
|
void cashQueryShouldUseSavedHuiFuSequence() {
|
GuideWithdrawal processing = withdrawal("PROCESSING");
|
processing.setCashReqSeqId("CW001");
|
processing.setCashReqDate("20260818");
|
processing.setCashHfSeqId("HF-CASH-1");
|
when(stateService.find(20L)).thenReturn(processing);
|
when(settlementService.requireApprovedCard(8L, 10)).thenReturn(account());
|
JSONObject queryResponse = new JSONObject();
|
queryResponse.put("trans_stat", "S");
|
when(withdrawBiz.query("HF100", "20260818", "CW001", "HF-CASH-1"))
|
.thenReturn(queryResponse);
|
|
service.advance(20L);
|
|
verify(withdrawBiz).query("HF100", "20260818", "CW001", "HF-CASH-1");
|
verify(stateService).markApproved(20L, null);
|
}
|
|
@Test
|
void cashQueryBusinessErrorShouldRemainProcessing() {
|
GuideWithdrawal processing = withdrawal("PROCESSING");
|
processing.setCashReqSeqId("CW001");
|
processing.setCashReqDate("20260818");
|
when(stateService.find(20L)).thenReturn(processing);
|
when(settlementService.requireApprovedCard(8L, 10)).thenReturn(account());
|
JSONObject queryResponse = new JSONObject();
|
queryResponse.put("resp_code", "20000100");
|
queryResponse.put("resp_desc", "查询服务暂不可用");
|
when(withdrawBiz.query("HF100", "20260818", "CW001")).thenReturn(queryResponse);
|
|
service.advance(20L);
|
|
verify(stateService).markCashPending(20L, null,
|
"导游账户取现查询失败:查询服务暂不可用");
|
verify(stateService, never()).markCashRetry(any(), anyString());
|
}
|
|
private GuideWithdrawal withdrawal(String status) {
|
GuideWithdrawal withdrawal = new GuideWithdrawal();
|
withdrawal.setId(20L);
|
withdrawal.setGuideId(8L);
|
withdrawal.setBankCardId(10);
|
withdrawal.setAmount(new BigDecimal("200.00"));
|
withdrawal.setStatus(status);
|
return withdrawal;
|
}
|
|
private GuideWithdrawalAccount account() {
|
GuideWithdrawalAccount account = new GuideWithdrawalAccount();
|
account.setHuifuId("HF100");
|
account.setTokenNo("TOKEN100");
|
return account;
|
}
|
}
|