diff --git a/src/test/java/com/acquirex/ApprovalServiceTest.java b/src/test/java/com/acquirex/ApprovalServiceTest.java new file mode 100644 index 0000000..5facdf5 --- /dev/null +++ b/src/test/java/com/acquirex/ApprovalServiceTest.java @@ -0,0 +1,150 @@ +package com.acquirex; + +import com.acquirex.domain.AcquisitionCard; +import com.acquirex.domain.ApprovalRequest; +import com.acquirex.dto.ApprovalRequestDto; +import com.acquirex.dto.ApprovalResponseDto; +import com.acquirex.repository.AcquisitionCardRepository; +import com.acquirex.repository.ApprovalRequestRepository; +import com.acquirex.service.ApprovalService; +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.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class ApprovalServiceTest { + + @Mock + private ApprovalRequestRepository approvalRequestRepository; + + @Mock + private AcquisitionCardRepository acquisitionCardRepository; + + private ApprovalService approvalService; + private ApprovalRequestDto validRequestDto; + private AcquisitionCard testCard; + private ApprovalRequest testRequest; + + @BeforeEach + void setUp() { + approvalService = new ApprovalService(approvalRequestRepository, acquisitionCardRepository); + + validRequestDto = new ApprovalRequestDto(); + validRequestDto.setCardNumber("1234567890123456"); + validRequestDto.setCardCompanyCode("KB"); + validRequestDto.setMerchantNumber("123456789012345"); + validRequestDto.setAmount(new BigDecimal("50000.00")); + validRequestDto.setVat(new BigDecimal("5000.00")); + + testCard = new AcquisitionCard(); + testCard.setId(1L); + testCard.setCardNumber("1234567890123456"); + testCard.setCardCompanyCode("KB"); + testCard.setMerchantNumber("123456789012345"); + testCard.setStatus(AcquisitionCard.CardStatus.PENDING); + + testRequest = new ApprovalRequest(); + testRequest.setId(1L); + testRequest.setCardId(1L); + testRequest.setTransactionId("TX12345678"); + testRequest.setAmount(new BigDecimal("50000.00")); + testRequest.setVat(new BigDecimal("5000.00")); + testRequest.setApprovalStatus(ApprovalRequest.ApprovalStatus.REQUESTED); + } + + @Test + @DisplayName("매입 승인 요청 성공 - 기존 카드") + void requestApproval_WithExistingCard_Success() { + when(acquisitionCardRepository.findByCardNumberAndCardCompanyCode(any(), any())) + .thenReturn(Optional.of(testCard)); + when(approvalRequestRepository.save(any(ApprovalRequest.class))).thenReturn(testRequest); + + ApprovalResponseDto response = approvalService.requestApproval(validRequestDto); + + assertNotNull(response); + assertEquals("TX12345678", response.getTransactionId()); + assertEquals("REQUESTED", response.getStatus()); + verify(acquisitionCardRepository, never()).save(any()); + verify(approvalRequestRepository, times(1)).save(any()); + } + + @Test + @DisplayName("매입 승인 요청 성공 - 신규 카드") + void requestApproval_WithNewCard_Success() { + when(acquisitionCardRepository.findByCardNumberAndCardCompanyCode(any(), any())) + .thenReturn(Optional.empty()); + when(acquisitionCardRepository.save(any(AcquisitionCard.class))).thenReturn(testCard); + when(approvalRequestRepository.save(any(ApprovalRequest.class))).thenReturn(testRequest); + + ApprovalResponseDto response = approvalService.requestApproval(validRequestDto); + + assertNotNull(response); + assertEquals("REQUESTED", response.getStatus()); + verify(acquisitionCardRepository, times(1)).save(any()); + } + + @Test + @DisplayName("매입 승인 처리 성공") + void approveRequest_Success() { + when(approvalRequestRepository.findById(1L)).thenReturn(Optional.of(testRequest)); + when(approvalRequestRepository.save(any(ApprovalRequest.class))) + .thenAnswer(invocation -> invocation.getArgument(0)); + + ApprovalResponseDto response = approvalService.approveRequest(1L); + + assertNotNull(response); + assertEquals("APPROVED", response.getStatus()); + assertNotNull(response.getApprovalNumber()); + assertNotNull(response.getApprovedAt()); + } + + @Test + @DisplayName("매입 승인 처리 실패 - 요청 없음") + void approveRequest_NotFound() { + when(approvalRequestRepository.findById(999L)).thenReturn(Optional.empty()); + assertThrows(IllegalArgumentException.class, () -> approvalService.approveRequest(999L)); + } + + @Test + @DisplayName("매입 승인 처리 실패 - 이미 처리됨") + void approveRequest_AlreadyProcessed() { + testRequest.setApprovalStatus(ApprovalRequest.ApprovalStatus.APPROVED); + when(approvalRequestRepository.findById(1L)).thenReturn(Optional.of(testRequest)); + assertThrows(IllegalStateException.class, () -> approvalService.approveRequest(1L)); + } + + @Test + @DisplayName("매입 승인 거절 성공") + void rejectRequest_Success() { + when(approvalRequestRepository.findById(1L)).thenReturn(Optional.of(testRequest)); + when(approvalRequestRepository.save(any(ApprovalRequest.class))) + .thenAnswer(invocation -> invocation.getArgument(0)); + + ApprovalResponseDto response = approvalService.rejectRequest(1L, "한도 초과"); + + assertNotNull(response); + assertEquals("REJECTED", response.getStatus()); + } + + @Test + @DisplayName("승인 상태 조회 성공") + void getApprovalStatus_Success() { + when(approvalRequestRepository.findById(1L)).thenReturn(Optional.of(testRequest)); + + ApprovalResponseDto response = approvalService.getApprovalStatus(1L); + + assertNotNull(response); + assertEquals(1L, response.getApprovalId()); + assertEquals("TX12345678", response.getTransactionId()); + } +} \ No newline at end of file