카드 정산 업무 규칙과 전환 불변식 추출 (codex-bais-final3-20260713-192718-BAIS-SPRING-ANA-CARD-001)
This commit is contained in:
parent
68a4df5aaf
commit
b83a09660f
1 changed files with 193 additions and 0 deletions
|
|
@ -0,0 +1,193 @@
|
|||
package com.bais.card.settlement;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import java.math.BigDecimal;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* SettlementCalculator 단위 테스트
|
||||
* 불변식 검증: BRAND_SETTLEMENT_*, IRD_*, ISSUER_FEE_*, AMOUNT_*, ROUNDING_MODE
|
||||
*/
|
||||
@DisplayName("SettlementCalculator 불변식 테스트")
|
||||
class SettlementCalculatorTest {
|
||||
|
||||
private SettlementCalculator calculator;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
calculator = new SettlementCalculator();
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("브랜드 정산 불변식 테스트")
|
||||
class BrandSettlementTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("BRAND_SETTLEMENT_FORMULA: 정산금 = 승인금액 - 취소금액 - 수수료")
|
||||
void testSettlementFormula() {
|
||||
BigDecimal approved = new BigDecimal("100000");
|
||||
BigDecimal cancelled = new BigDecimal("10000");
|
||||
BigDecimal rate = new BigDecimal("0.02");
|
||||
|
||||
SettlementCalculator.BrandSettlementResult result =
|
||||
calculator.calculateBrandSettlement(approved, cancelled, rate);
|
||||
|
||||
assertEquals(new BigDecimal("2000.00"), result.getCommission());
|
||||
assertEquals(new BigDecimal("88000.00"), result.getSettlementAmount());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("BRAND_SETTLEMENT_NON_NEGATIVE: 정산금은 0 이상")
|
||||
void testSettlementNonNegative() {
|
||||
SettlementCalculator.BrandSettlementResult result =
|
||||
calculator.calculateBrandSettlement(
|
||||
new BigDecimal("10000"), new BigDecimal("20000"), new BigDecimal("0.02"));
|
||||
assertEquals(BigDecimal.ZERO.setScale(2), result.getSettlementAmount());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("BRAND_COMMISSION_RATE_DEFAULT: 미지정 시 0.02")
|
||||
void testDefaultCommissionRate() {
|
||||
SettlementCalculator.BrandSettlementResult result =
|
||||
calculator.calculateBrandSettlement(
|
||||
new BigDecimal("100000"), BigDecimal.ZERO, null);
|
||||
assertEquals(new BigDecimal("0.02"), result.getCommissionRate());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("IRD 불변식 테스트")
|
||||
class IrdTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("IRD_FORMULA: IRD = 승인금액 * IRD율")
|
||||
void testIrdFormula() {
|
||||
BigDecimal ird = calculator.calculateIRD(
|
||||
new BigDecimal("100000"), new BigDecimal("0.015"));
|
||||
assertEquals(new BigDecimal("1500.00"), ird);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("IRD_RATE_DEFAULT: 미지정 시 0.015")
|
||||
void testDefaultIrdRate() {
|
||||
BigDecimal ird = calculator.calculateIRD(new BigDecimal("100000"), null);
|
||||
assertEquals(new BigDecimal("1500.00"), ird);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("IRD_NON_NEGATIVE: IRD는 0 이상")
|
||||
void testIrdNonNegative() {
|
||||
BigDecimal ird = calculator.calculateIRD(
|
||||
new BigDecimal("100000"), new BigDecimal("-0.015"));
|
||||
assertTrue(ird.compareTo(BigDecimal.ZERO) >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("발급사 수수료 불변식 테스트")
|
||||
class IssuerFeeTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("ISSUER_FEE_FORMULA: 발급사 수수료 = IRD * 발급사 수수료율")
|
||||
void testIssuerFeeFormula() {
|
||||
BigDecimal fee = calculator.calculateIssuerFee(
|
||||
new BigDecimal("1500.00"), new BigDecimal("0.005"));
|
||||
assertEquals(new BigDecimal("7.50"), fee);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ISSUER_FEE_RATE_DEFAULT: 미지정 시 0.005")
|
||||
void testDefaultIssuerFeeRate() {
|
||||
BigDecimal fee = calculator.calculateIssuerFee(new BigDecimal("1500.00"), null);
|
||||
assertEquals(new BigDecimal("7.50"), fee);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ISSUER_SETTLEMENT_FORMULA: 발급사 정산금 = IRD - 발급사 수수료")
|
||||
void testIssuerSettlementFormula() {
|
||||
SettlementCalculator.IssuerSettlementResult result =
|
||||
calculator.calculateIssuerSettlement(
|
||||
new BigDecimal("1500.00"), new BigDecimal("0.005"));
|
||||
assertEquals(new BigDecimal("7.50"), result.getIssuerFee());
|
||||
assertEquals(new BigDecimal("1492.50"), result.getIssuerSettlement());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("공통 금액 검증 불변식 테스트")
|
||||
class AmountValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("AMOUNT_NOT_NULL: null 시 IllegalArgumentException")
|
||||
void testNullAmount() {
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
calculator.calculateBrandSettlement(null, BigDecimal.ZERO, new BigDecimal("0.02")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("AMOUNT_NON_NEGATIVE: 음수 시 IllegalArgumentException")
|
||||
void testNegativeAmount() {
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
calculator.calculateBrandSettlement(
|
||||
new BigDecimal("-100000"), BigDecimal.ZERO, new BigDecimal("0.02")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("AMOUNT_MAX_LIMIT: 최대 한도 초과 시 IllegalArgumentException")
|
||||
void testAmountExceedsMaxLimit() {
|
||||
BigDecimal exceedsMax = new BigDecimal("999999999999.99").add(BigDecimal.ONE);
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
calculator.calculateBrandSettlement(
|
||||
exceedsMax, BigDecimal.ZERO, new BigDecimal("0.02")));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("금액 정밀도 불변식 테스트")
|
||||
class PrecisionTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("AMOUNT_SCALE: 소수점 2자리")
|
||||
void testAmountScale() {
|
||||
SettlementCalculator.BrandSettlementResult result =
|
||||
calculator.calculateBrandSettlement(
|
||||
new BigDecimal("100000"), BigDecimal.ZERO, new BigDecimal("0.023456"));
|
||||
assertEquals(2, result.getCommission().scale());
|
||||
assertEquals(new BigDecimal("2345.60"), result.getCommission());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ROUNDING_MODE: HALF_UP 반올림")
|
||||
void testHalfUpRounding() {
|
||||
SettlementCalculator.BrandSettlementResult result =
|
||||
calculator.calculateBrandSettlement(
|
||||
new BigDecimal("100000"), BigDecimal.ZERO, new BigDecimal("0.023455"));
|
||||
assertEquals(new BigDecimal("2345.50"), result.getCommission());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("전체 정산 흐름 테스트")
|
||||
class FullSettlementTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("전체 정산 계산 통합 테스트")
|
||||
void testFullSettlement() {
|
||||
SettlementCalculator.FullSettlementResult result =
|
||||
calculator.calculateFullSettlement(
|
||||
new BigDecimal("100000"),
|
||||
new BigDecimal("10000"),
|
||||
new BigDecimal("0.02"),
|
||||
new BigDecimal("0.015"),
|
||||
new BigDecimal("0.005"));
|
||||
|
||||
assertNotNull(result.getBrandSettlement());
|
||||
assertNotNull(result.getIrd());
|
||||
assertNotNull(result.getIssuerSettlement());
|
||||
assertEquals(new BigDecimal("1500.00"), result.getIrd());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue