This commit is contained in:
2026-08-14 12:50:37 +08:00
parent 91e781b3ff
commit ce6963a25e
46 changed files with 664 additions and 76 deletions
@@ -0,0 +1,53 @@
package com.baiyue.finance;
import com.baiyue.common.core.api.ApiResponse;
import com.baiyue.common.core.api.PageResult;
import com.baiyue.finance.client.IamCustomerClient;
import com.baiyue.finance.dto.FinancePhase1Dtos.AccountSummary;
import com.baiyue.finance.service.FinanceCustomerAccountService;
import com.baiyue.finance.service.FinanceEventException;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class FinanceCustomerAccountServiceTest {
@Test
void listsMasterCustomersWithZeroFinanceMetricsAndForwardsSearchFields() {
JdbcTemplate jdbc = mock(JdbcTemplate.class);
IamCustomerClient iam = mock(IamCustomerClient.class);
when(jdbc.queryForList(anyString(), any(Object[].class))).thenReturn(List.of());
when(iam.page("internal-token", 1, 20, "Alice", "ACTIVE", 900000000000000001L))
.thenReturn(ApiResponse.success(new PageResult<>(List.of(
new IamCustomerClient.Customer(900000000000000001L, "TEN-001", "Alice Trading", "ACTIVE", "Alice", "13800138000")),
1, 20, 1, 1)));
var result = new FinanceCustomerAccountService(jdbc, iam, "internal-token")
.list(1, 20, " Alice ", "active", 900000000000000001L);
AccountSummary row = result.data().get(0);
assertThat(row.customerCode()).isEqualTo("TEN-001");
assertThat(row.contactName()).isEqualTo("Alice");
assertThat(row.contactPhone()).isEqualTo("13800138000");
assertThat(row.outstandingReceivable()).isZero();
assertThat(row.pendingBilling()).isZero();
verify(iam).page("internal-token", 1, 20, "Alice", "ACTIVE", 900000000000000001L);
}
@Test
void rejectsUnsupportedFinanceAccountStatus() {
var service = new FinanceCustomerAccountService(mock(JdbcTemplate.class), mock(IamCustomerClient.class), "token");
assertThatThrownBy(() -> service.list(1, 20, null, "PENDING", null))
.isInstanceOf(FinanceEventException.class)
.extracting(error -> ((FinanceEventException) error).code())
.isEqualTo("FIN-REQ-400");
}
}
@@ -7,6 +7,7 @@ import com.baiyue.finance.dto.FinancePhase1Dtos.FeeSourceDetail;
import com.baiyue.finance.dto.FinancePhase1Dtos.PageEnvelope;
import com.baiyue.finance.service.FinanceEventException;
import com.baiyue.finance.service.FinancePhase1OperationService;
import com.baiyue.finance.service.FinanceCustomerAccountService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -39,21 +40,22 @@ import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class FinancePhase1OperationBehaviorTest {
@Mock FinancePhase1OperationService operationService;
@Mock FinanceCustomerAccountService customerAccountService;
@Test
void controllerDelegatesFiveFrozenOperationsAndUsesAuthenticatedOperator() {
FinancePhase1OperationController controller = new FinancePhase1OperationController(operationService);
FinancePhase1OperationController controller = new FinancePhase1OperationController(operationService, customerAccountService);
AuthenticatedUser user = new AuthenticatedUser(71L, null, null, null, "finance", "ADMIN", "WEB", Set.of());
var review = new FinancePhase1Dtos.ReviewRequest("APPROVE", "核对无误", 0);
var inclusion = new FinancePhase1Dtos.SettlementInclusionRequest(true, "进入本期结算", 1);
controller.listDerivedCustomerAccounts(1, 20, "柏悦", "ACTIVE");
controller.listDerivedCustomerAccounts(1, 20, "柏悦", "ACTIVE", 9L);
controller.listDerivedCustomerAccountLedger(9L, 2, 50, "RECEIPT", LocalDate.of(2026, 8, 1), LocalDate.of(2026, 8, 31));
controller.getFinanceFeeSource(88L);
controller.reviewFinanceFeeSource(user, 88L, "review-key", review);
controller.updateFeeSourceSettlementInclusion(user, 88L, "include-key", inclusion);
verify(operationService).listDerivedCustomerAccounts(1, 20, "柏悦", "ACTIVE");
verify(customerAccountService).list(1, 20, "柏悦", "ACTIVE", 9L);
verify(operationService).listDerivedCustomerAccountLedger(eq(9L), eq(2), eq(50), eq("RECEIPT"), any(), any());
verify(operationService).getFinanceFeeSource(88L);
verify(operationService).reviewFinanceFeeSource(88L, 71L, "review-key", review);
@@ -93,6 +95,8 @@ class FinancePhase1OperationBehaviorTest {
assertThat(result.page().total()).isEqualTo(1);
assertThat(result.requestId()).isNotBlank();
assertThat(result.traceId()).isNotBlank();
assertThat(jdbc.accountListSql).contains("p.customer_name_snapshot");
assertThat(jdbc.accountListSql).doesNotContain("CAST(c.customer_id AS CHAR)");
}
@Test
@@ -234,6 +238,7 @@ class FinancePhase1OperationBehaviorTest {
private static final class AccountJdbc extends JdbcTemplate {
private final List<Long> ledgerCustomerIds = new ArrayList<>();
private String accountListSql = "";
@Override
public <T> T queryForObject(String sql, Class<T> requiredType, Object... args) {
@@ -245,6 +250,7 @@ class FinancePhase1OperationBehaviorTest {
@SuppressWarnings("unchecked")
public <T> List<T> query(String sql, RowMapper<T> rowMapper, Object... args) {
if (sql.startsWith("SELECT c.customer_id")) {
accountListSql = sql;
return (List<T>) List.of(new FinancePhase1Dtos.AccountSummary(
9L, "9", "客户9", null, null, new BigDecimal("100.00"),
new BigDecimal("20.00"), new BigDecimal("30.00"), BigDecimal.ZERO,