카드 매입 승인 경로 Spring Boot 3 전환 #5

Closed
forge-bot wants to merge 8 commits from forge/ACX-E2E-1785394564819-attempt-6-run-ca40abcdb5d2 into main
Showing only changes of commit 059df148fb - Show all commits

View file

@ -0,0 +1,160 @@
package com.acquirex;
import com.acquirex.domain.Acquisition;
import com.acquirex.domain.AcquisitionStatus;
import com.acquirex.exception.AcquisitionNotFoundException;
import com.acquirex.exception.InvalidAcquisitionStateException;
import com.acquirex.service.AcquisitionRequest;
import com.acquirex.service.AcquisitionResponse;
import com.acquirex.service.AcquisitionService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
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.Mockito.*;
/**
* AcquisitionService 단위 테스트 - Spring Boot 3 마이그레이션 검증
*/
@ExtendWith(MockitoExtension.class)
class AcquisitionServiceTest {
@Mock
private com.acquirex.service.AcquisitionRepository acquisitionRepository;
private AcquisitionService acquisitionService;
private AcquisitionRequest validRequest;
private Acquisition pendingAcquisition;
@BeforeEach
void setUp() {
acquisitionService = new AcquisitionService(acquisitionRepository);
validRequest = AcquisitionRequest.builder()
.merchantId("MERCHANT001")
.cardNumber("1234567890123456")
.amount(new BigDecimal("50000.00"))
.build();
pendingAcquisition = Acquisition.builder()
.id(1L).merchantId("MERCHANT001").cardNumber("123456****3456")
.amount(new BigDecimal("50000.00")).transactionId("TXN123456789")
.status(AcquisitionStatus.PENDING).createdAt(LocalDateTime.now()).build();
}
@Test
@DisplayName("매입 요청 등록 성공 - Spring Boot 3 Jakarta Validation")
void registerAcquisition_Success() {
when(acquisitionRepository.save(any(Acquisition.class))).thenAnswer(invocation -> {
Acquisition saved = invocation.getArgument(0);
saved.setId(1L);
saved.setCreatedAt(LocalDateTime.now());
return saved;
});
AcquisitionResponse response = acquisitionService.registerAcquisition(validRequest);
assertThat(response).isNotNull();
assertThat(response.getMerchantId()).isEqualTo("MERCHANT001");
assertThat(response.getAmount()).isEqualByComparingTo(new BigDecimal("50000.00"));
assertThat(response.getStatus()).isEqualTo(AcquisitionStatus.PENDING);
assertThat(response.getCardNumber()).isEqualTo("123456****3456");
verify(acquisitionRepository, times(1)).save(any(Acquisition.class));
}
@Test
@DisplayName("매입 승인 처리 성공 - Spring Boot 3 @Transactional")
void approveAcquisition_Success() {
when(acquisitionRepository.findByTransactionId("TXN123456789")).thenReturn(Optional.of(pendingAcquisition));
when(acquisitionRepository.save(any(Acquisition.class))).thenAnswer(invocation -> invocation.getArgument(0));
AcquisitionResponse response = acquisitionService.approveAcquisition("TXN123456789");
assertThat(response).isNotNull();
assertThat(response.getStatus()).isEqualTo(AcquisitionStatus.APPROVED);
assertThat(response.getApprovalCode()).isNotNull();
assertThat(response.getApprovalCode()).hasSize(6);
}
@Test
@DisplayName("매입 승인 실패 - 매입 정보 없음")
void approveAcquisition_NotFound() {
when(acquisitionRepository.findByTransactionId("INVALID_TXN")).thenReturn(Optional.empty());
assertThatThrownBy(() -> acquisitionService.approveAcquisition("INVALID_TXN"))
.isInstanceOf(AcquisitionNotFoundException.class)
.hasMessageContaining("INVALID_TXN");
}
@Test
@DisplayName("매입 승인 실패 - 이미 승인된 매입")
void approveAcquisition_AlreadyApproved() {
pendingAcquisition.setStatus(AcquisitionStatus.APPROVED);
when(acquisitionRepository.findByTransactionId("TXN123456789")).thenReturn(Optional.of(pendingAcquisition));
assertThatThrownBy(() -> acquisitionService.approveAcquisition("TXN123456789"))
.isInstanceOf(InvalidAcquisitionStateException.class)
.hasMessageContaining("APPROVED");
}
@Test
@DisplayName("매입 거절 처리 성공")
void rejectAcquisition_Success() {
when(acquisitionRepository.findByTransactionId("TXN123456789")).thenReturn(Optional.of(pendingAcquisition));
when(acquisitionRepository.save(any(Acquisition.class))).thenAnswer(invocation -> invocation.getArgument(0));
AcquisitionResponse response = acquisitionService.rejectAcquisition("TXN123456789", "한도 초과");
assertThat(response).isNotNull();
assertThat(response.getStatus()).isEqualTo(AcquisitionStatus.REJECTED);
}
@Test
@DisplayName("매입 정보 조회 성공")
void getAcquisition_Success() {
when(acquisitionRepository.findByTransactionId("TXN123456789")).thenReturn(Optional.of(pendingAcquisition));
AcquisitionResponse response = acquisitionService.getAcquisition("TXN123456789");
assertThat(response).isNotNull();
assertThat(response.getTransactionId()).isEqualTo("TXN123456789");
}
@Test
@DisplayName("가맹점별 매입 목록 조회 성공")
void getAcquisitionsByMerchant_Success() {
Acquisition acquisition2 = Acquisition.builder()
.id(2L).merchantId("MERCHANT001").cardNumber("987654****3210")
.amount(new BigDecimal("30000.00")).transactionId("TXN987654321")
.status(AcquisitionStatus.PENDING).createdAt(LocalDateTime.now()).build();
when(acquisitionRepository.findByMerchantId("MERCHANT001")).thenReturn(Arrays.asList(pendingAcquisition, acquisition2));
List<AcquisitionResponse> responses = acquisitionService.getAcquisitionsByMerchant("MERCHANT001");
assertThat(responses).hasSize(2);
assertThat(responses).extracting(AcquisitionResponse::getMerchantId).containsOnly("MERCHANT001");
}
@Test
@DisplayName("대기 중인 매입 목록 조회 성공")
void getPendingAcquisitions_Success() {
when(acquisitionRepository.findByStatus(AcquisitionStatus.PENDING)).thenReturn(Arrays.asList(pendingAcquisition));
List<AcquisitionResponse> responses = acquisitionService.getPendingAcquisitions();
assertThat(responses).hasSize(1);
assertThat(responses.get(0).getStatus()).isEqualTo(AcquisitionStatus.PENDING);
}
}