package com.baiyue.finance; import com.baiyue.finance.dto.FinanceReadModels.FeePoolItem; import com.baiyue.finance.service.FinanceQueryService; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; class FinanceFeePoolDirectionBehaviorTest { @Test void receivablePoolNeverContainsPayableSource() { DirectionJdbc jdbc = new DirectionJdbc(); FinanceQueryService service = new FinanceQueryService(jdbc, new ObjectMapper()); List result = service.feePool(7L, "RECEIVABLE"); assertThat(result).isNotEmpty().allMatch(item -> "RECEIVABLE".equals(item.direction())); assertThat(jdbc.sourceDirections).containsExactly("RECEIVABLE"); assertThat(jdbc.costQueryCount).isZero(); } @Test void payablePoolNeverContainsReceivableSource() { DirectionJdbc jdbc = new DirectionJdbc(); FinanceQueryService service = new FinanceQueryService(jdbc, new ObjectMapper()); List result = service.feePool(7L, "PAYABLE"); assertThat(result).isNotEmpty().allMatch(item -> "PAYABLE".equals(item.direction())); assertThat(jdbc.sourceDirections).containsExactly("PAYABLE"); assertThat(jdbc.costQueryCount).isZero(); } private static final class DirectionJdbc extends JdbcTemplate { private final List sourceDirections = new ArrayList<>(); private int costQueryCount; @Override @SuppressWarnings("unchecked") public List query(String sql, RowMapper mapper, Object... args) { if (sql.contains("FROM fin_fee_source")) { String direction = String.valueOf(args[1]); sourceDirections.add(direction); return (List) List.of(item(direction, "FIRSTLEG_FEE", 1L)); } if (sql.contains("FROM fin_cost")) { costQueryCount++; return (List) List.of(item("PAYABLE", "MANUAL_COST", 2L)); } return List.of(); } private static FeePoolItem item(String direction, String sourceType, long sourceId) { return new FeePoolItem(direction + ":" + sourceId, 7L, direction, sourceType, sourceId, 1, 11L, 21L, null, "清关费", new BigDecimal("100.00"), "CNY", "PAYABLE".equals(direction) ? "ON_ACCOUNT" : null, null, null, null, List.of(), "AVAILABLE", LocalDateTime.of(2026, 8, 11, 1, 0)); } } }