diff --git a/src/test/java/com/acquirex/cardapproval/CardAcquisitionApprovalApplicationTests.java b/src/test/java/com/acquirex/cardapproval/CardAcquisitionApprovalApplicationTests.java new file mode 100644 index 0000000..c42210f --- /dev/null +++ b/src/test/java/com/acquirex/cardapproval/CardAcquisitionApprovalApplicationTests.java @@ -0,0 +1,145 @@ +package com.acquirex.cardapproval; + +import com.acquirex.cardapproval.domain.AcquisitionApproval; +import com.acquirex.cardapproval.domain.AcquisitionApproval.ApprovalStatus; +import com.acquirex.cardapproval.domain.AcquisitionApprovalRepository; +import com.acquirex.cardapproval.service.AcquisitionApprovalService; +import com.acquirex.cardapproval.service.AcquisitionApprovalService.AcquisitionApprovalException; +import com.acquirex.cardapproval.service.AcquisitionApprovalService.AcquisitionApprovalRequest; +import com.acquirex.cardapproval.service.AcquisitionApprovalService.AcquisitionApprovalResponse; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Spring Boot 3.x 카드 매입 승인 서비스 통합 테스트 + */ +@SpringBootTest +@ActiveProfiles("test") +@Transactional +class CardAcquisitionApprovalApplicationTests { + + @Autowired + private AcquisitionApprovalService service; + + @Autowired + private AcquisitionApprovalRepository repository; + + private AcquisitionApprovalRequest validRequest; + + @BeforeEach + void setUp() { + validRequest = AcquisitionApprovalRequest.builder() + .merchantId("MERCHANT001") + .cardNumber("1234567890123456") + .acquisitionAmount(new BigDecimal("50000")) + .approvalAmount(new BigDecimal("50000")) + .approvalNumber("APPR" + System.currentTimeMillis()) + .acquisitionDatetime(LocalDateTime.now()) + .build(); + } + + @Test + @DisplayName("애플리케이션 컨텍스트 로드 성공") + void contextLoads() { + assertThat(service).isNotNull(); + assertThat(repository).isNotNull(); + } + + @Test + @DisplayName("매입 승인 요청 처리 성공") + void processAcquisition_Success() { + AcquisitionApprovalResponse response = service.processAcquisition(validRequest); + + assertThat(response).isNotNull(); + assertThat(response.getId()).isNotNull(); + assertThat(response.getMerchantId()).isEqualTo("MERCHANT001"); + assertThat(response.getApprovalStatus()).isEqualTo(ApprovalStatus.APPROVED); + assertThat(response.getCancelYn()).isEqualTo("N"); + } + + @Test + @DisplayName("매입 금액과 승인 금액 불일치 시 예외 발생") + void processAcquisition_AmountMismatch_ThrowsException() { + validRequest.setApprovalAmount(new BigDecimal("40000")); + + assertThatThrownBy(() -> service.processAcquisition(validRequest)) + .isInstanceOf(AcquisitionApprovalException.class) + .hasFieldOrPropertyWithValue("errorCode", "AMOUNT_MISMATCH"); + } + + @Test + @DisplayName("매입 취소 처리 성공") + void cancelAcquisition_Success() { + AcquisitionApprovalResponse created = service.processAcquisition(validRequest); + AcquisitionApprovalResponse cancelled = service.cancelAcquisition(created.getId(), "고객 요청"); + + assertThat(cancelled.getCancelYn()).isEqualTo("Y"); + assertThat(cancelled.getApprovalStatus()).isEqualTo(ApprovalStatus.CANCELLED); + assertThat(cancelled.getCancelReason()).isEqualTo("고객 요청"); + assertThat(cancelled.getCancelDatetime()).isNotNull(); + } + + @Test + @DisplayName("이미 취소된 건 재취소 시 예외 발생") + void cancelAcquisition_AlreadyCancelled_ThrowsException() { + AcquisitionApprovalResponse created = service.processAcquisition(validRequest); + service.cancelAcquisition(created.getId(), "첫 번째 취소"); + + assertThatThrownBy(() -> service.cancelAcquisition(created.getId(), "두 번째 취소")) + .isInstanceOf(AcquisitionApprovalException.class) + .hasFieldOrPropertyWithValue("errorCode", "ALREADY_CANCELLED"); + } + + @Test + @DisplayName("존재하지 않는 매입 승인 조회 시 예외 발생") + void getAcquisition_NotFound_ThrowsException() { + assertThatThrownBy(() -> service.getAcquisition(99999L)) + .isInstanceOf(AcquisitionApprovalException.class) + .hasFieldOrPropertyWithValue("errorCode", "NOT_FOUND"); + } + + @Test + @DisplayName("가맹점별 매입 승인 목록 조회 성공") + void getAcquisitionsByMerchant_Success() { + service.processAcquisition(validRequest); + + List responses = service.getAcquisitionsByMerchant("MERCHANT001"); + + assertThat(responses).isNotEmpty(); + assertThat(responses).allMatch(r -> r.getMerchantId().equals("MERCHANT001")); + } + + @Test + @DisplayName("엔티티 취소 메서드 동작 확인") + void entityCancelMethod_WorksCorrectly() { + AcquisitionApproval approval = AcquisitionApproval.builder() + .merchantId("TEST") + .cardNumber("1234") + .acquisitionAmount(new BigDecimal("1000")) + .approvalAmount(new BigDecimal("1000")) + .approvalNumber("TEST001") + .acquisitionDatetime(LocalDateTime.now()) + .approvalStatus(ApprovalStatus.APPROVED) + .cancelYn("N") + .build(); + + approval.cancel("테스트 취소"); + + assertThat(approval.getCancelYn()).isEqualTo("Y"); + assertThat(approval.getCancelReason()).isEqualTo("테스트 취소"); + assertThat(approval.getCancelDatetime()).isNotNull(); + assertThat(approval.getApprovalStatus()).isEqualTo(ApprovalStatus.CANCELLED); + } +} \ No newline at end of file