diff --git a/src/test/java/org/folio/dcb/service/BorrowingLibraryServiceTest.java b/src/test/java/org/folio/dcb/service/BorrowingLibraryServiceTest.java index c2ed0eee..24fe0159 100644 --- a/src/test/java/org/folio/dcb/service/BorrowingLibraryServiceTest.java +++ b/src/test/java/org/folio/dcb/service/BorrowingLibraryServiceTest.java @@ -1,5 +1,7 @@ package org.folio.dcb.service; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.folio.dcb.domain.dto.DcbTransaction.RoleEnum.BORROWER; import static org.folio.dcb.domain.dto.TransactionStatus.StatusEnum.AWAITING_PICKUP; import static org.folio.dcb.domain.dto.TransactionStatus.StatusEnum.CANCELLED; @@ -12,8 +14,6 @@ import static org.folio.dcb.utils.EntityUtils.createDcbTransactionByRole; import static org.folio.dcb.utils.EntityUtils.createServicePointRequest; import static org.folio.dcb.utils.EntityUtils.createTransactionEntity; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; @@ -55,7 +55,7 @@ void testTransactionStatusUpdateFromOpenToAwaitingPickup() { borrowingLibraryService.updateTransactionStatus(transactionEntity, transactionStatus); verify(circulationService).checkInByBarcode(any()); - assertEquals(AWAITING_PICKUP, transactionEntity.getStatus()); + assertThat(transactionEntity.getStatus()).isEqualTo(AWAITING_PICKUP); verify(transactionRepository).save(any()); } @@ -69,7 +69,7 @@ void testTransactionStatusUpdateFromCreatedToOpen() { borrowingLibraryService.updateTransactionStatus(transactionEntity, transactionStatus); verify(circulationService).checkInByBarcode(any(), any()); - assertEquals(OPEN, transactionEntity.getStatus()); + assertThat(transactionEntity.getStatus()).isEqualTo(OPEN); } @Test @@ -77,20 +77,21 @@ void testTransactionStatusUpdateWithIncorrectStatus() { var transactionEntity = createTransactionEntity(); transactionEntity.setStatus(CREATED); var transactionStatus = TransactionStatus.builder().status(AWAITING_PICKUP).build(); - assertThrows(IllegalArgumentException.class, () -> - borrowingLibraryService.updateTransactionStatus(transactionEntity, transactionStatus)); + assertThatThrownBy(() -> borrowingLibraryService.updateTransactionStatus(transactionEntity, transactionStatus)) + .isInstanceOf(IllegalArgumentException.class); } @Test void createTransactionTest() { var servicePointRequest = createServicePointRequest(); var dcbTransaction = createDcbTransactionByRole(BORROWER); + assertThat(dcbTransaction.getPickup()).isNotNull(); servicePointRequest.setId(UUID.randomUUID().toString()); when(servicePointService.createServicePointIfNotExists(dcbTransaction)).thenReturn(servicePointRequest); borrowingLibraryService.createCirculation(DCB_TRANSACTION_ID, dcbTransaction); - assertEquals(servicePointRequest.getId(), dcbTransaction.getPickup().getServicePointId()); + assertThat(dcbTransaction.getPickup().getServicePointId()).isEqualTo(servicePointRequest.getId()); verify(baseLibraryService).createBorrowingLibraryTransaction( DCB_TRANSACTION_ID, dcbTransaction, servicePointRequest.getId()); } @@ -103,7 +104,7 @@ void testTransactionStatusUpdateFromItemCheckedInToClosed() { borrowingLibraryService.updateTransactionStatus(transactionEntity, transactionStatus); - assertEquals(CLOSED, transactionEntity.getStatus()); + assertThat(transactionEntity.getStatus()).isEqualTo(CLOSED); } @Test @@ -116,7 +117,7 @@ void testTransactionStatusUpdateFromAwaitingPickupToItemCheckedOut() { borrowingLibraryService.updateTransactionStatus(transactionEntity, transactionStatus); verify(circulationService).checkOutByBarcode(any()); - assertEquals(ITEM_CHECKED_OUT, transactionEntity.getStatus()); + assertThat(transactionEntity.getStatus()).isEqualTo(ITEM_CHECKED_OUT); } @Test @@ -129,7 +130,7 @@ void testTransactionStatusUpdateFromItemCheckedOutToItemCheckedIn() { borrowingLibraryService.updateTransactionStatus(transactionEntity, transactionStatus); verify(circulationService).checkInByBarcode(any(), any()); - assertEquals(ITEM_CHECKED_IN, transactionEntity.getStatus()); + assertThat(transactionEntity.getStatus()).isEqualTo(ITEM_CHECKED_IN); } @Test @@ -148,7 +149,7 @@ void testTransactionStatusUpdateFromItemCheckedOutToItemCheckedInWithFoundByLibr borrowingLibraryService.updateTransactionStatus(transactionEntity, transactionStatus); verify(circulationService).checkInByBarcode(any(), any(), eq(ClaimedReturnedResolution.FOUND_BY_LIBRARY)); - assertEquals(ITEM_CHECKED_IN, transactionEntity.getStatus()); + assertThat(transactionEntity.getStatus()).isEqualTo(ITEM_CHECKED_IN); } @Test @@ -167,7 +168,7 @@ void testTransactionStatusUpdateFromItemCheckedOutToItemCheckedInWithReturnedByP borrowingLibraryService.updateTransactionStatus(transactionEntity, transactionStatus); verify(circulationService).checkInByBarcode(any(), any(), eq(ClaimedReturnedResolution.RETURNED_BY_PATRON)); - assertEquals(ITEM_CHECKED_IN, transactionEntity.getStatus()); + assertThat(transactionEntity.getStatus()).isEqualTo(ITEM_CHECKED_IN); } @Test diff --git a/src/test/java/org/folio/dcb/service/LendingLibraryServiceTest.java b/src/test/java/org/folio/dcb/service/LendingLibraryServiceTest.java index a21d8d4d..f8443119 100644 --- a/src/test/java/org/folio/dcb/service/LendingLibraryServiceTest.java +++ b/src/test/java/org/folio/dcb/service/LendingLibraryServiceTest.java @@ -1,6 +1,10 @@ package org.folio.dcb.service; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.folio.dcb.domain.dto.DcbTransaction.RoleEnum.LENDER; +import static org.folio.dcb.domain.dto.TransactionStatus.StatusEnum.CREATED; +import static org.folio.dcb.domain.dto.TransactionStatus.StatusEnum.OPEN; import static org.folio.dcb.utils.EntityUtils.CIRCULATION_REQUEST_ID; import static org.folio.dcb.utils.EntityUtils.DCB_TRANSACTION_ID; import static org.folio.dcb.utils.EntityUtils.createCirculationRequest; @@ -9,25 +13,21 @@ import static org.folio.dcb.utils.EntityUtils.createTransactionEntity; import static org.folio.dcb.utils.EntityUtils.createTransactionStatus; import static org.folio.dcb.utils.EntityUtils.createUser; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.UUID; import org.folio.dcb.domain.dto.TransactionStatus; +import org.folio.dcb.domain.dto.TransactionStatus.StatusEnum; import org.folio.dcb.domain.dto.TransactionStatusResponse; -import org.folio.dcb.domain.entity.TransactionEntity; import org.folio.dcb.repository.TransactionRepository; import org.folio.dcb.service.impl.BaseLibraryService; import org.folio.dcb.service.impl.CirculationServiceImpl; import org.folio.dcb.service.impl.LendingLibraryServiceImpl; import org.folio.dcb.service.impl.RequestServiceImpl; import org.folio.dcb.service.impl.UserServiceImpl; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -48,78 +48,91 @@ class LendingLibraryServiceTest { @Test void createTransactionTest() { - var user = createUser(); var dcbTransaction = createDcbTransactionByRole(LENDER); - var servicePoint = createServicePointRequest(); - servicePoint.setId(UUID.randomUUID().toString()); - - when(userService.fetchOrCreateUser(any())) - .thenReturn(user); - when(servicePointService.createServicePointIfNotExists(dcbTransaction)) - .thenReturn(servicePoint); - when(requestService.createRequestBasedOnItemStatus(any(), any(), anyString())) - .thenReturn(createCirculationRequest()); + assertThat(dcbTransaction.getPatron()).isNotNull(); + assertThat(dcbTransaction.getItem()).isNotNull(); + assertThat(dcbTransaction.getPickup()).isNotNull(); + + var user = createUser(); + var servicePoint = createServicePointRequest().id(UUID.randomUUID().toString()); + + when(userService.fetchOrCreateUser(any())).thenReturn(user); + when(servicePointService.createServicePointIfNotExists(dcbTransaction)).thenReturn(servicePoint); + when(requestService.createRequestBasedOnItemStatus(any(), any(), any())).thenReturn(createCirculationRequest()); doNothing().when(baseLibraryService).saveDcbTransaction(any(), any(), any()); var response = lendingLibraryService.createCirculation(DCB_TRANSACTION_ID, dcbTransaction); - Assertions.assertEquals(TransactionStatusResponse.StatusEnum.CREATED, response.getStatus()); + + assertThat(response.getStatus()).isEqualTo(TransactionStatusResponse.StatusEnum.CREATED); verify(userService).fetchOrCreateUser(dcbTransaction.getPatron()); verify(requestService).createRequestBasedOnItemStatus( user, dcbTransaction.getItem(), dcbTransaction.getPickup().getServicePointId()); verify(baseLibraryService).saveDcbTransaction(DCB_TRANSACTION_ID, dcbTransaction, CIRCULATION_REQUEST_ID); - assertEquals(servicePoint.getId(), dcbTransaction.getPickup().getServicePointId()); + assertThat(dcbTransaction.getPickup().getServicePointId()).isEqualTo(servicePoint.getId()); } @Test void transactionStatusFromOpenToAwaitingTest() { - TransactionEntity dcbTransaction = createTransactionEntity(); + var dcbTransaction = createTransactionEntity(); dcbTransaction.setStatus(TransactionStatus.StatusEnum.OPEN); doNothing().when(circulationService).checkInByBarcode(dcbTransaction); - lendingLibraryService.updateTransactionStatus(dcbTransaction, - TransactionStatus.builder().status(TransactionStatus.StatusEnum.AWAITING_PICKUP).build()); + var awaitingPickupStatus = TransactionStatus.builder().status(StatusEnum.AWAITING_PICKUP).build(); - verify(circulationService).checkInByBarcode(dcbTransaction); + lendingLibraryService.updateTransactionStatus(dcbTransaction, awaitingPickupStatus); - Assertions.assertEquals(TransactionStatus.StatusEnum.AWAITING_PICKUP, dcbTransaction.getStatus()); + assertThat(dcbTransaction.getStatus()).isEqualTo(TransactionStatus.StatusEnum.AWAITING_PICKUP); + verify(circulationService).checkInByBarcode(dcbTransaction); } @Test void transactionStatusFromAwaitingToCheckoutTest() { - TransactionEntity dcbTransaction = createTransactionEntity(); + var dcbTransaction = createTransactionEntity(); dcbTransaction.setStatus(TransactionStatus.StatusEnum.AWAITING_PICKUP); doNothing().when(circulationService).checkOutByBarcode(dcbTransaction); - lendingLibraryService.updateTransactionStatus(dcbTransaction, - TransactionStatus.builder().status(TransactionStatus.StatusEnum.ITEM_CHECKED_OUT).build()); + var checkedOutStatus = TransactionStatus.builder().status(StatusEnum.ITEM_CHECKED_OUT).build(); - verify(circulationService).checkOutByBarcode(dcbTransaction); + lendingLibraryService.updateTransactionStatus(dcbTransaction, checkedOutStatus); - Assertions.assertEquals(TransactionStatus.StatusEnum.ITEM_CHECKED_OUT, dcbTransaction.getStatus()); + verify(circulationService).checkOutByBarcode(dcbTransaction); + assertThat(dcbTransaction.getStatus()).isEqualTo(TransactionStatus.StatusEnum.ITEM_CHECKED_OUT); } @Test void transactionStatusFromCheckoutToCheckInTest() { - TransactionEntity dcbTransaction = createTransactionEntity(); + var dcbTransaction = createTransactionEntity(); dcbTransaction.setStatus(TransactionStatus.StatusEnum.ITEM_CHECKED_OUT); - lendingLibraryService.updateTransactionStatus(dcbTransaction, - TransactionStatus.builder().status(TransactionStatus.StatusEnum.ITEM_CHECKED_IN).build()); - - Assertions.assertEquals(TransactionStatus.StatusEnum.ITEM_CHECKED_IN, dcbTransaction.getStatus()); + var checkedInStatus = TransactionStatus.builder().status(StatusEnum.ITEM_CHECKED_IN).build(); + lendingLibraryService.updateTransactionStatus(dcbTransaction, checkedInStatus); + assertThat(dcbTransaction.getStatus()).isEqualTo(TransactionStatus.StatusEnum.ITEM_CHECKED_IN); } @Test void transactionStatusFromCreatedToCancelledTest() { - TransactionEntity dcbTransaction = createTransactionEntity(); + var dcbTransaction = createTransactionEntity(); dcbTransaction.setStatus(TransactionStatus.StatusEnum.CREATED); - lendingLibraryService.updateTransactionStatus(dcbTransaction, - TransactionStatus.builder().status(TransactionStatus.StatusEnum.CANCELLED).build()); + var cancelledStatus = TransactionStatus.builder().status(StatusEnum.CANCELLED).build(); + lendingLibraryService.updateTransactionStatus(dcbTransaction, cancelledStatus); verify(baseLibraryService).cancelTransactionRequest(dcbTransaction); } @Test void updateTransactionWithWrongStatusTest() { - TransactionEntity transactionEntity = createTransactionEntity(); - TransactionStatus transactionStatus = createTransactionStatus(TransactionStatus.StatusEnum.AWAITING_PICKUP); - assertThrows(IllegalArgumentException.class, - () -> lendingLibraryService.updateTransactionStatus(transactionEntity, transactionStatus)); + var transactionEntity = createTransactionEntity(); + var transactionStatus = createTransactionStatus(TransactionStatus.StatusEnum.AWAITING_PICKUP); + assertThatThrownBy(() -> lendingLibraryService.updateTransactionStatus(transactionEntity, transactionStatus)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testUpdateTransactionStatusFromCreatedToOpenShouldUpdateEntity() { + // TestMate-1bbc6de8d11f860bac864b25fad8e5ad + var dcbTransaction = createTransactionEntity(); + dcbTransaction.setStatus(CREATED); + var transactionStatus = createTransactionStatus(OPEN); + + lendingLibraryService.updateTransactionStatus(dcbTransaction, transactionStatus); + + assertThat(dcbTransaction.getStatus()).isEqualTo(OPEN); + verify(transactionRepository).save(dcbTransaction); } } diff --git a/src/test/java/org/folio/dcb/service/TransactionAuditServiceTest.java b/src/test/java/org/folio/dcb/service/TransactionAuditServiceTest.java index 932e8683..46224ddc 100644 --- a/src/test/java/org/folio/dcb/service/TransactionAuditServiceTest.java +++ b/src/test/java/org/folio/dcb/service/TransactionAuditServiceTest.java @@ -1,13 +1,14 @@ package org.folio.dcb.service; import static org.assertj.core.api.Assertions.assertThat; +import static org.folio.dcb.domain.dto.DcbTransaction.RoleEnum.BORROWER; import static org.folio.dcb.domain.dto.DcbTransaction.RoleEnum.LENDER; import static org.folio.dcb.utils.EntityUtils.DCB_TRANSACTION_ID; import static org.folio.dcb.utils.EntityUtils.borrowerDcbTransaction; import static org.folio.dcb.utils.EntityUtils.createDcbTransactionByRole; import static org.folio.dcb.utils.EntityUtils.createTransactionAuditEntity; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -34,18 +35,18 @@ class TransactionAuditServiceTest { @Test void logTheErrorForExistedTransactionAuditTest() { - when(repository.findLatestTransactionAuditEntityByDcbTransactionId(any())) - .thenReturn(Optional.of(createTransactionAuditEntity())); + var searchResult = Optional.of(createTransactionAuditEntity()); + when(repository.findLatestTransactionAuditEntityByDcbTransactionId(any())).thenReturn(searchResult); transactionAuditService.logErrorIfTransactionAuditExists(DCB_TRANSACTION_ID, "error_message"); - verify(transactionMapper, times(0)).mapToEntity(any(), any()); + verify(transactionMapper, never()).mapToEntity(any(), any()); verify(repository).save(any()); } @Test void logTheErrorForNotExistedTransactionAuditTest() { + var transaction = createDcbTransactionByRole(LENDER); when(repository.findLatestTransactionAuditEntityByDcbTransactionId(any())).thenReturn(Optional.empty()); - transactionAuditService.logErrorIfTransactionAuditNotExists( - DCB_TRANSACTION_ID, createDcbTransactionByRole(LENDER), "error_message"); + transactionAuditService.logErrorIfTransactionAuditNotExists(DCB_TRANSACTION_ID, transaction, "error_message"); verify(repository).save(any()); } @@ -92,4 +93,46 @@ void logErrorIfTransactionAuditNotExists_positive_transactionObjectIsNull() { .contains("role = null") .contains("error message = null object error"); } + + @Test + void testLogErrorIfTransactionAuditNotExistsWhenAuditExistsShouldLogDuplicateError() { + // TestMate-fa5231f9fd8fb40f55082244d97512b7 + var errorMsg = "Duplicate ID"; + var dcbTransaction = createDcbTransactionByRole(BORROWER); + var existingAudit = createTransactionAuditEntity(); + var searchResult = Optional.of(existingAudit); + var auditCaptor = ArgumentCaptor.forClass(TransactionAuditEntity.class); + when(repository.findLatestTransactionAuditEntityByDcbTransactionId(DCB_TRANSACTION_ID)).thenReturn(searchResult); + when(repository.save(auditCaptor.capture())).then(inv -> inv.getArgument(0)); + + transactionAuditService.logErrorIfTransactionAuditNotExists(DCB_TRANSACTION_ID, dcbTransaction, errorMsg); + + var savedAudit = auditCaptor.getValue(); + assertThat(savedAudit.getAction()).isEqualTo("DUPLICATE_ERROR"); + assertThat(savedAudit.getTransactionId()).isEqualTo("-1"); + assertThat(savedAudit.getBefore()).isNull(); + assertThat(savedAudit.getAfter()).isNull(); + assertThat(savedAudit.getErrorMessage()).isEqualTo(String.format( + "dcbTransactionId = %s; role = %s; error message = %s.", DCB_TRANSACTION_ID, BORROWER, errorMsg)); + } + + @Test + void testLogErrorIfTransactionAuditNotExistsWhenDcbTransactionIsNull() { + // TestMate-dbb7ede2a4d44cf4e63907539abcc619 + var dcbTransactionId = "trn-456"; + var errorMsg = "Null payload"; + var auditCaptor = ArgumentCaptor.forClass(TransactionAuditEntity.class); + when(repository.findLatestTransactionAuditEntityByDcbTransactionId(dcbTransactionId)).thenReturn(Optional.empty()); + when(repository.save(auditCaptor.capture())).then(inv -> inv.getArgument(0)); + + transactionAuditService.logErrorIfTransactionAuditNotExists(dcbTransactionId, null, errorMsg); + + var savedAudit = auditCaptor.getValue(); + assertThat(savedAudit.getAction()).isEqualTo("ERROR"); + assertThat(savedAudit.getTransactionId()).isEqualTo(dcbTransactionId); + assertThat(savedAudit.getBefore()).isNull(); + assertThat(savedAudit.getAfter()).isNull(); + assertThat(savedAudit.getErrorMessage()).isEqualTo( + "dcbTransactionId = trn-456; role = null; error message = Null payload."); + } } diff --git a/src/test/java/org/folio/dcb/service/TransactionServiceTest.java b/src/test/java/org/folio/dcb/service/TransactionServiceTest.java index 14670115..81755fe9 100644 --- a/src/test/java/org/folio/dcb/service/TransactionServiceTest.java +++ b/src/test/java/org/folio/dcb/service/TransactionServiceTest.java @@ -1,10 +1,15 @@ package org.folio.dcb.service; +import static java.util.Objects.requireNonNull; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.folio.dcb.domain.dto.DcbTransaction.RoleEnum.BORROWER; import static org.folio.dcb.domain.dto.DcbTransaction.RoleEnum.BORROWING_PICKUP; import static org.folio.dcb.domain.dto.DcbTransaction.RoleEnum.LENDER; +import static org.folio.dcb.domain.dto.DcbTransaction.RoleEnum.PICKUP; import static org.folio.dcb.domain.dto.TransactionStatus.StatusEnum.AWAITING_PICKUP; import static org.folio.dcb.domain.dto.TransactionStatus.StatusEnum.CLOSED; +import static org.folio.dcb.domain.dto.TransactionStatus.StatusEnum.CREATED; import static org.folio.dcb.domain.dto.TransactionStatus.StatusEnum.ITEM_CHECKED_IN; import static org.folio.dcb.domain.dto.TransactionStatus.StatusEnum.ITEM_CHECKED_OUT; import static org.folio.dcb.domain.dto.TransactionStatus.StatusEnum.OPEN; @@ -18,9 +23,8 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import java.time.OffsetDateTime; @@ -47,56 +51,65 @@ import org.folio.dcb.integration.circulation.CirculationClient; import org.folio.dcb.repository.TransactionAuditRepository; import org.folio.dcb.repository.TransactionRepository; +import org.folio.dcb.service.impl.BaseLibraryService; import org.folio.dcb.service.impl.LendingLibraryServiceImpl; import org.folio.dcb.service.impl.TransactionsServiceImpl; import org.folio.spring.exception.NotFoundException; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.mockito.ArgumentCaptor; -import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; @ExtendWith(MockitoExtension.class) class TransactionServiceTest { - @InjectMocks private TransactionsServiceImpl transactionsService; - - @Mock(name = "lendingLibraryService") - private LendingLibraryServiceImpl lendingLibraryService; - + private TransactionsServiceImpl transactionsService; + @Mock private LendingLibraryServiceImpl lendingLibraryService; @Mock private TransactionRepository transactionRepository; @Mock private StatusProcessorService statusProcessorService; @Mock private TransactionAuditRepository transactionAuditRepository; @Mock private TransactionMapper transactionMapper; @Mock private CirculationClient circulationClient; @Mock private CirculationLoanPolicyStorageClient circulationLoanPolicyStorageClient; + @Mock private LibraryService pickupLibraryService; + @Mock private LibraryService borrowingPickupLibraryService; + @Mock private LibraryService borrowingLibraryService; + @Mock private BaseLibraryService baseLibraryService; + + @BeforeEach + void setUp() { + transactionsService = new TransactionsServiceImpl(lendingLibraryService, borrowingPickupLibraryService, + pickupLibraryService, borrowingLibraryService, transactionRepository, statusProcessorService, transactionMapper, + transactionAuditRepository, baseLibraryService, circulationClient, circulationLoanPolicyStorageClient); + } @Test void renewLoanByTransactionIdTest() { - when(transactionRepository.findById(anyString())) - .thenReturn(Optional.ofNullable(buildTransactionToRenew(ITEM_CHECKED_OUT, LENDER))); + var entityByIdResult = Optional.ofNullable(buildTransactionToRenew(ITEM_CHECKED_OUT, LENDER)); + when(transactionRepository.findById(anyString())).thenReturn(entityByIdResult); when(circulationClient.renewById(any())).thenReturn(buildTestRenewBleResponse()); when(circulationLoanPolicyStorageClient.getById(anyString())).thenReturn(buildTestLoanPolicy()); when(circulationClient.renewById(any())).thenReturn(buildTestRenewBleResponse()); when(circulationLoanPolicyStorageClient.getById(anyString())).thenReturn(buildTestLoanPolicy()); transactionsService.renewLoanByTransactionId(DCB_TRANSACTION_ID); - verify(circulationClient, times(1)).renewById(any()); - verify(circulationLoanPolicyStorageClient, times(1)).getById(any()); + verify(circulationClient).renewById(any()); + verify(circulationLoanPolicyStorageClient).getById(any()); } @Test void renewLoanByTransactionIdShouldThrowNotFoundExceptionWhenRenewResponseNull() { + var entityByIdResult = Optional.of(buildTransactionToRenew(ITEM_CHECKED_OUT, LENDER)); when(circulationClient.renewById(any(RenewByIdRequest.class))).thenReturn(null); - when(transactionRepository.findById(anyString())).thenReturn(Optional.of( - buildTransactionToRenew(ITEM_CHECKED_OUT, LENDER))); - assertThrows(NotFoundException.class, () -> transactionsService.renewLoanByTransactionId( - DCB_TRANSACTION_ID)); + when(transactionRepository.findById(anyString())).thenReturn(entityByIdResult); + assertThrows(NotFoundException.class, () -> transactionsService.renewLoanByTransactionId(DCB_TRANSACTION_ID)); } @Test @@ -105,8 +118,7 @@ void renewLoanByTransactionIdShouldThrowNotFoundExceptionWhenLoanPolicyResponseN buildTransactionToRenew(ITEM_CHECKED_OUT, LENDER))); when(circulationClient.renewById(any())).thenReturn(buildTestRenewBleResponse()); when(circulationLoanPolicyStorageClient.getById(anyString())).thenReturn(null); - assertThrows(NotFoundException.class, () -> transactionsService.renewLoanByTransactionId( - DCB_TRANSACTION_ID)); + assertThrows(NotFoundException.class, () -> transactionsService.renewLoanByTransactionId(DCB_TRANSACTION_ID)); } @ParameterizedTest @@ -123,10 +135,8 @@ private static Stream renewLoanByTransactionIdShouldThrowExceptionTes Arguments.of(buildTransactionToRenew(CLOSED, LENDER), StatusException.class), Arguments.of(buildTransactionToRenew(AWAITING_PICKUP, LENDER), StatusException.class), Arguments.of(buildTransactionToRenew(AWAITING_PICKUP, LENDER), StatusException.class), - Arguments.of(buildTransactionToRenew(ITEM_CHECKED_OUT, BORROWER), - IllegalArgumentException.class), - Arguments.of(buildTransactionToRenew(ITEM_CHECKED_OUT, BORROWING_PICKUP), - IllegalArgumentException.class) + Arguments.of(buildTransactionToRenew(ITEM_CHECKED_OUT, BORROWER), IllegalArgumentException.class), + Arguments.of(buildTransactionToRenew(ITEM_CHECKED_OUT, BORROWING_PICKUP), IllegalArgumentException.class) ); } @@ -154,40 +164,34 @@ private static RenewByIdResponse buildTestRenewBleResponse() { @Test void createLendingCirculationRequestTest() { - when(lendingLibraryService.createCirculation(any(), any())) - .thenReturn(createTransactionResponse()); - transactionsService.createCirculationRequest(DCB_TRANSACTION_ID, - createDcbTransactionByRole(LENDER)); - verify(lendingLibraryService).createCirculation(DCB_TRANSACTION_ID, - createDcbTransactionByRole(LENDER)); + when(lendingLibraryService.createCirculation(any(), any())).thenReturn(createTransactionResponse()); + transactionsService.createCirculationRequest(DCB_TRANSACTION_ID, createDcbTransactionByRole(LENDER)); + verify(lendingLibraryService).createCirculation(DCB_TRANSACTION_ID, createDcbTransactionByRole(LENDER)); } @Test void shouldReturnAnyTransactionStatusById() { var transactionIdUnique = UUID.randomUUID().toString(); - when(transactionRepository.findById(transactionIdUnique)) - .thenReturn(Optional.ofNullable(TransactionEntity.builder() - .status(StatusEnum.CREATED) - .role(LENDER) - .build())); + var transactionEntity = TransactionEntity.builder() + .status(CREATED) + .role(LENDER) + .build(); + when(transactionRepository.findById(transactionIdUnique)).thenReturn(Optional.ofNullable(transactionEntity)); var trnInstance = transactionsService.getTransactionStatusById(transactionIdUnique); - assertNotNull(trnInstance); - assertEquals(TransactionStatusResponse.StatusEnum.CREATED, trnInstance.getStatus()); + + assertThat(trnInstance).isNotNull(); + assertThat(trnInstance.getStatus()).isEqualTo(TransactionStatusResponse.StatusEnum.CREATED); } @Test void getTransactionStatusByIdNotFoundExceptionTest() { var transactionIdUnique = UUID.randomUUID().toString(); - when(transactionRepository.findById(transactionIdUnique)) - .thenReturn(Optional.empty()); + when(transactionRepository.findById(transactionIdUnique)).thenReturn(Optional.empty()); - var error = assertThrows( - NotFoundException.class, - () -> transactionsService.getTransactionStatusById(transactionIdUnique) - ); - - assertEquals(String.format("DCB Transaction was not found by id= %s ", transactionIdUnique), error.getMessage()); + assertThatThrownBy(() -> transactionsService.getTransactionStatusById(transactionIdUnique)) + .isInstanceOf(NotFoundException.class) + .hasMessage("DCB Transaction was not found by id= %s ", transactionIdUnique); } /** @@ -197,8 +201,8 @@ void getTransactionStatusByIdNotFoundExceptionTest() { void createTransactionWithExistingTransactionIdTest() { var dcbTransaction = createDcbTransactionByRole(LENDER); when(transactionRepository.existsById(DCB_TRANSACTION_ID)).thenReturn(true); - assertThrows(ResourceAlreadyExistException.class, () -> - transactionsService.createCirculationRequest(DCB_TRANSACTION_ID, dcbTransaction)); + assertThatThrownBy(() -> transactionsService.createCirculationRequest(DCB_TRANSACTION_ID, dcbTransaction)) + .isInstanceOf(ResourceAlreadyExistException.class); } @Test @@ -207,20 +211,15 @@ void updateTransactionEntityLenderTest() { dcbTransactionEntity.setStatus(StatusEnum.OPEN); dcbTransactionEntity.setRole(LENDER); - when(transactionRepository.findById(DCB_TRANSACTION_ID)).thenReturn( - Optional.of(dcbTransactionEntity)); + when(transactionRepository.findById(DCB_TRANSACTION_ID)).thenReturn(Optional.of(dcbTransactionEntity)); when(statusProcessorService.lendingChainProcessor(StatusEnum.OPEN, ITEM_CHECKED_OUT)) .thenReturn(List.of(StatusEnum.AWAITING_PICKUP, ITEM_CHECKED_OUT)); - doNothing().when(lendingLibraryService) - .updateTransactionStatus(dcbTransactionEntity, TransactionStatus.builder().status( - StatusEnum.AWAITING_PICKUP).build()); - doNothing().when(lendingLibraryService) - .updateTransactionStatus(dcbTransactionEntity, TransactionStatus.builder().status( - ITEM_CHECKED_OUT).build()); + doNothing().when(lendingLibraryService).updateTransactionStatus(dcbTransactionEntity, + TransactionStatus.builder().status(StatusEnum.AWAITING_PICKUP).build()); + var itemCheckedOutStatus = TransactionStatus.builder().status(ITEM_CHECKED_OUT).build(); + doNothing().when(lendingLibraryService).updateTransactionStatus(dcbTransactionEntity, itemCheckedOutStatus); - transactionsService.updateTransactionStatus(DCB_TRANSACTION_ID, - TransactionStatus.builder().status( - ITEM_CHECKED_OUT).build()); + transactionsService.updateTransactionStatus(DCB_TRANSACTION_ID, itemCheckedOutStatus); verify(statusProcessorService).lendingChainProcessor(StatusEnum.OPEN, ITEM_CHECKED_OUT); } @@ -229,34 +228,28 @@ void updateTransactionEntityLenderTest() { void updateTransactionEntityErrorTest() { var dcbTransactionEntity = createTransactionEntity(); dcbTransactionEntity.setStatus(StatusEnum.OPEN); - when(transactionRepository.findById(DCB_TRANSACTION_ID)).thenReturn( - Optional.of(dcbTransactionEntity)); + when(transactionRepository.findById(DCB_TRANSACTION_ID)).thenReturn(Optional.of(dcbTransactionEntity)); var openTransactionStatus = TransactionStatus.builder().status(StatusEnum.OPEN).build(); - assertThrows(StatusException.class, - () -> transactionsService.updateTransactionStatus(DCB_TRANSACTION_ID, openTransactionStatus)); + assertThatThrownBy(() -> transactionsService.updateTransactionStatus(DCB_TRANSACTION_ID, openTransactionStatus)) + .isInstanceOf(StatusException.class); dcbTransactionEntity.setStatus(StatusEnum.ITEM_CHECKED_IN); - var cancelledTransactionStatus = TransactionStatus.builder() - .status(StatusEnum.CANCELLED) - .build(); - assertThrows(StatusException.class, - () -> transactionsService.updateTransactionStatus(DCB_TRANSACTION_ID, - cancelledTransactionStatus)); + var cancelledTxStatus = TransactionStatus.builder().status(StatusEnum.CANCELLED).build(); + assertThatThrownBy(() -> transactionsService.updateTransactionStatus(DCB_TRANSACTION_ID, cancelledTxStatus)) + .isInstanceOf(StatusException.class); dcbTransactionEntity.setStatus(ITEM_CHECKED_OUT); - assertThrows(StatusException.class, - () -> transactionsService.updateTransactionStatus(DCB_TRANSACTION_ID, - cancelledTransactionStatus)); + assertThatThrownBy(() -> transactionsService.updateTransactionStatus(DCB_TRANSACTION_ID, cancelledTxStatus)) + .isInstanceOf(StatusException.class); } @Test void getTransactionStatusListTest() { var startDate = OffsetDateTime.now().minusDays(1L); var endDate = OffsetDateTime.now(); - Page pageMock = mock(Page.class); - when(transactionAuditRepository.findUpdatedTransactionsByDateRange(any(), any(), any())) - .thenReturn(pageMock); + var pageMock = Mockito.>mock(); + when(transactionAuditRepository.findUpdatedTransactionsByDateRange(any(), any(), any())).thenReturn(pageMock); when(pageMock.getTotalElements()).thenReturn(10L); when(transactionMapper.mapToDto(pageMock)) .thenReturn(List.of(TransactionStatusResponseList @@ -292,18 +285,136 @@ void getTransactionStatusListTest() { @Test void shouldVerifyLocationCodeWhenCreatingCirculationRequest() { - when(lendingLibraryService.createCirculation(any(), any())) - .thenReturn(createTransactionResponse()); - DcbTransaction dcbTransaction = createDcbTransactionByRole(LENDER); - Optional.ofNullable(dcbTransaction.getItem()).ifPresent(dcbItem -> dcbItem.setLocationCode("TEST_LOCATION_CODE")); + when(lendingLibraryService.createCirculation(any(), any())).thenReturn(createTransactionResponse()); + var dcbTransaction = createDcbTransactionByRole(LENDER); + requireNonNull(dcbTransaction.getItem()).setLocationCode("TEST_LOCATION_CODE"); transactionsService.createCirculationRequest(DCB_TRANSACTION_ID, dcbTransaction); verify(lendingLibraryService).createCirculation(DCB_TRANSACTION_ID, dcbTransaction); var dcbTransactionArgumentCaptor = ArgumentCaptor.forClass(DcbTransaction.class); - verify(lendingLibraryService, times(1)).createCirculation(any(), dcbTransactionArgumentCaptor.capture()); + verify(lendingLibraryService).createCirculation(any(), dcbTransactionArgumentCaptor.capture()); DcbTransaction dcbTransactionActual = dcbTransactionArgumentCaptor.getValue(); assertNotNull(dcbTransactionActual.getItem()); assertNotNull(dcbTransactionActual.getItem().getLocationCode()); assertEquals("TEST_LOCATION_CODE", dcbTransactionActual.getItem().getLocationCode()); } + + @Test + void createCirculationRequestShouldDelegateToBorrowingPickupService() { + // TestMate-0a2a9520399d5c7abefe2604abee8bb1 + var transaction = createDcbTransactionByRole(BORROWING_PICKUP); + var expectedResponse = createTransactionResponse(); + when(transactionRepository.existsById(DCB_TRANSACTION_ID)).thenReturn(false); + when(borrowingPickupLibraryService.createCirculation(DCB_TRANSACTION_ID, transaction)).thenReturn(expectedResponse); + + var actualResponse = transactionsService.createCirculationRequest(DCB_TRANSACTION_ID, transaction); + + assertThat(actualResponse).isEqualTo(expectedResponse); + verify(transactionRepository).existsById(DCB_TRANSACTION_ID); + verify(borrowingPickupLibraryService).createCirculation(DCB_TRANSACTION_ID, transaction); + verifyNoInteractions(lendingLibraryService, pickupLibraryService, borrowingLibraryService); + } + + @Test + void createCirculationRequestShouldDelegateToPickupService() { + // TestMate-597be30571329e3ce0267cdfff9dfb08 + var transaction = createDcbTransactionByRole(PICKUP); + var expectedResponse = createTransactionResponse(); + when(transactionRepository.existsById(DCB_TRANSACTION_ID)).thenReturn(false); + when(pickupLibraryService.createCirculation(DCB_TRANSACTION_ID, transaction)).thenReturn(expectedResponse); + + var actualResponse = transactionsService.createCirculationRequest(DCB_TRANSACTION_ID, transaction); + + assertThat(actualResponse).isEqualTo(expectedResponse); + verify(transactionRepository).existsById(DCB_TRANSACTION_ID); + verify(pickupLibraryService).createCirculation(DCB_TRANSACTION_ID, transaction); + verifyNoInteractions(lendingLibraryService, borrowingPickupLibraryService, borrowingLibraryService); + } + + @Test + void createCirculationRequestShouldDelegateToBorrowerService() { + // TestMate-7d4eb902b0fe10bf7674b7be235df7bd + var dcbTransaction = createDcbTransactionByRole(BORROWER); + var expectedResponse = createTransactionResponse(); + when(transactionRepository.existsById(DCB_TRANSACTION_ID)).thenReturn(false); + when(borrowingLibraryService.createCirculation(DCB_TRANSACTION_ID, dcbTransaction)).thenReturn(expectedResponse); + + var actualResponse = transactionsService.createCirculationRequest(DCB_TRANSACTION_ID, dcbTransaction); + + assertThat(actualResponse).isEqualTo(expectedResponse); + verify(transactionRepository).existsById(DCB_TRANSACTION_ID); + verify(borrowingLibraryService).createCirculation(DCB_TRANSACTION_ID, dcbTransaction); + verifyNoInteractions(lendingLibraryService, borrowingPickupLibraryService, pickupLibraryService); + } + + @Test + void updateTransactionStatusWhenTransactionNotFoundShouldThrowException() { + // TestMate-dcfec3a2e25a9cd96051a6cf26412215 + var nonExistentId = UUID.randomUUID().toString(); + when(transactionRepository.findById(nonExistentId)).thenReturn(Optional.empty()); + + var status = new TransactionStatus().status(OPEN); + assertThatThrownBy(() -> transactionsService.updateTransactionStatus(nonExistentId, status)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Transaction with id %s not found", nonExistentId); + + verify(transactionRepository).findById(nonExistentId); + } + + @Test + void updateTransactionStatusForBorrowerRoleShouldUseBorrowingChainProcessor() { + // TestMate-e08c55185fe8d0dcaa3a2fd733caef67 + var dcbTransactionEntity = createTransactionEntity(); + dcbTransactionEntity.setStatus(OPEN); + dcbTransactionEntity.setRole(BORROWER); + var statusChain = List.of(AWAITING_PICKUP, ITEM_CHECKED_OUT); + when(transactionRepository.findById(DCB_TRANSACTION_ID)).thenReturn(Optional.of(dcbTransactionEntity)); + when(statusProcessorService.borrowingChainProcessor(OPEN, ITEM_CHECKED_OUT)).thenReturn(statusChain); + doNothing().when(borrowingLibraryService).updateTransactionStatus(any(), any()); + + var targetStatus = new TransactionStatus().status(ITEM_CHECKED_OUT); + var response = transactionsService.updateTransactionStatus(DCB_TRANSACTION_ID, targetStatus); + + assertThat(response.getStatus()).isEqualTo(TransactionStatusResponse.StatusEnum.ITEM_CHECKED_OUT); + verify(statusProcessorService).borrowingChainProcessor(OPEN, ITEM_CHECKED_OUT); + verify(borrowingLibraryService).updateTransactionStatus(dcbTransactionEntity, + TransactionStatus.builder().status(AWAITING_PICKUP).build()); + verify(borrowingLibraryService).updateTransactionStatus(dcbTransactionEntity, targetStatus); + verifyNoInteractions(lendingLibraryService, pickupLibraryService, borrowingPickupLibraryService); + } + + @Test + void updateTransactionStatus_positive_borrowingPickupRole() { + // TestMate-beca7b72cfab01b9d15502559ed19169 + var dcbTransactionEntity = createTransactionEntity(); + dcbTransactionEntity.setId(DCB_TRANSACTION_ID); + dcbTransactionEntity.setStatus(CREATED); + dcbTransactionEntity.setRole(BORROWING_PICKUP); + when(transactionRepository.findById(DCB_TRANSACTION_ID)).thenReturn(Optional.of(dcbTransactionEntity)); + + var targetStatus = new TransactionStatus().status(OPEN); + var response = transactionsService.updateTransactionStatus(DCB_TRANSACTION_ID, targetStatus); + + assertThat(response.getStatus()).isEqualTo(TransactionStatusResponse.StatusEnum.OPEN); + verify(borrowingPickupLibraryService).updateTransactionStatus(dcbTransactionEntity, targetStatus); + verifyNoInteractions(pickupLibraryService, statusProcessorService, lendingLibraryService, borrowingLibraryService); + } + + @Test + void updateTransactionStatus_positive_pickupRole() { + // TestMate-beca7b72cfab01b9d15502559ed19169 + var dcbTransactionEntity = createTransactionEntity(); + dcbTransactionEntity.setId(DCB_TRANSACTION_ID); + dcbTransactionEntity.setStatus(CREATED); + dcbTransactionEntity.setRole(PICKUP); + when(transactionRepository.findById(DCB_TRANSACTION_ID)).thenReturn(Optional.of(dcbTransactionEntity)); + + var targetStatus = new TransactionStatus().status(OPEN); + var response = transactionsService.updateTransactionStatus(DCB_TRANSACTION_ID, targetStatus); + + assertThat(response.getStatus()).isEqualTo(TransactionStatusResponse.StatusEnum.OPEN); + verify(pickupLibraryService).updateTransactionStatus(dcbTransactionEntity, targetStatus); + verifyNoInteractions(borrowingPickupLibraryService, statusProcessorService, + lendingLibraryService, borrowingLibraryService); + } }