From 619e237487430c359ed97e7f10d44d61c8323f98 Mon Sep 17 00:00:00 2001 From: Dev Jethava Date: Tue, 15 Oct 2024 16:34:02 +0530 Subject: [PATCH] Cover unit test for use case UpdateCartItemUseCase.kt --- .../impl/UpdateCartItemUseCaseImpl.kt | 15 ++ .../impl/UpdateCartItemUseCaseImplTest.kt | 133 +++++++++++++++++- 2 files changed, 144 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/hieuwu/groceriesstore/domain/usecases/impl/UpdateCartItemUseCaseImpl.kt b/app/src/main/java/com/hieuwu/groceriesstore/domain/usecases/impl/UpdateCartItemUseCaseImpl.kt index b9a6ec82..8510e467 100644 --- a/app/src/main/java/com/hieuwu/groceriesstore/domain/usecases/impl/UpdateCartItemUseCaseImpl.kt +++ b/app/src/main/java/com/hieuwu/groceriesstore/domain/usecases/impl/UpdateCartItemUseCaseImpl.kt @@ -18,6 +18,16 @@ class UpdateCartItemUseCaseImpl @Inject constructor( @IoDispatcher private val ioDispatcher: CoroutineDispatcher ) : UpdateCartItemUseCase { override suspend fun updateLineItem(lineItemModel: LineItemModel) { + // Check if the quantity is valid + if (lineItemModel.quantity == null || lineItemModel.quantity!! <= 0) { + throw IllegalArgumentException("Quantity must be greater than zero.") + } + + // Check if the ID is valid + if (lineItemModel.id == null) { + throw IllegalArgumentException("Line item ID cannot be null.") + } + withContext(ioDispatcher) { if (lineItemModel.quantity != null && lineItemModel.id != null) { productRepository.updateLineItemQuantityById( @@ -29,6 +39,11 @@ class UpdateCartItemUseCaseImpl @Inject constructor( } override suspend fun removeLineItem(lineItemModel: LineItemModel) { + // Check if the ID is valid + if (lineItemModel.id == null) { + throw IllegalArgumentException("Line item ID cannot be null.") + } + withContext(ioDispatcher) { if (lineItemModel.id != null) { productRepository.removeLineItemById(lineItemModel.id!!) diff --git a/app/src/test/java/com/hieuwu/groceriesstore/domain/usecases/impl/UpdateCartItemUseCaseImplTest.kt b/app/src/test/java/com/hieuwu/groceriesstore/domain/usecases/impl/UpdateCartItemUseCaseImplTest.kt index e23282c6..8474fa8d 100644 --- a/app/src/test/java/com/hieuwu/groceriesstore/domain/usecases/impl/UpdateCartItemUseCaseImplTest.kt +++ b/app/src/test/java/com/hieuwu/groceriesstore/domain/usecases/impl/UpdateCartItemUseCaseImplTest.kt @@ -39,6 +39,9 @@ class UpdateCartItemUseCaseImplTest { ) } + /** + * Test for updating line item with a valid value + */ @Test fun updateLineItem_correctValue_whenExecute_thenCallProductRepository() { runBlocking { @@ -49,17 +52,24 @@ class UpdateCartItemUseCaseImplTest { } } - @Test + /** + * Test for updateLineItem when quantity is null + * Should throw IllegalArgumentException because quantity must be greater than zero + */ + @Test(expected = IllegalArgumentException::class) fun updateLineItem_quantityNull_whenExecute_thenCallProductRepository() { runBlocking { val input = LineItemModel(1L, null, null, null, null, null) testee.updateLineItem(input) - Mockito.verifyNoInteractions(mockedOrderRepository) +// Mockito.verifyNoInteractions(mockedOrderRepository) } } - @Test + /** + * Test for null ID should throw IllegalArgumentException + */ + @Test(expected = IllegalArgumentException::class) fun updateLineItem_idNull_whenExecute_thenCallProductRepository() { runBlocking { val input = LineItemModel(null, null, null, null, null, 1) @@ -69,6 +79,9 @@ class UpdateCartItemUseCaseImplTest { } } + /** + * Test for removing line item with a valid ID + */ @Test fun removeLineItem_correctValue_whenExecute_thenCallProductRepository() { runBlocking { @@ -79,7 +92,10 @@ class UpdateCartItemUseCaseImplTest { } } - @Test + /** + * Test for null ID when removing line item should throw IllegalArgumentException + */ + @Test(expected = IllegalArgumentException::class) fun removeLineItem_null_whenExecute_thenCallProductRepository() { runBlocking { val input = LineItemModel(null, null, null, null, null, null) @@ -89,6 +105,9 @@ class UpdateCartItemUseCaseImplTest { } } + /** + * Test for retrieving a non-empty cart + */ @Test fun getCurrentCartNotEmpty_whenExecute_thenReturnOrdersInCart() { val mockOrder = OrderModel( @@ -114,6 +133,9 @@ class UpdateCartItemUseCaseImplTest { } } + /** + * Test for retrieving an empty cart + */ @Test fun getCurrentCartEmpty_whenExecute_thenReturnNull() { whenever(mockedOrderRepository.getOneOrderByStatus(OrderStatus.IN_CART)).thenReturn(flow { @@ -126,4 +148,107 @@ class UpdateCartItemUseCaseImplTest { } } } + + /** + * Edge case for updateLineItem with minimum quantity + */ + @Test + fun updateLineItem_minQuantity_whenExecute_thenCallProductRepository() { + runBlocking { + val input = LineItemModel(1L, null, null, null, null, 1) // minimum valid quantity + testee.updateLineItem(input) + + verify(mockedProductRepository).updateLineItemQuantityById(1, input.id!!) + } + } + + /** + * Edge case for updateLineItem with maximum quantity + */ + @Test + fun updateLineItem_maxQuantity_whenExecute_thenCallProductRepository() { + runBlocking { + val input = LineItemModel(1L, null, null, null, null, 1000) // maximum valid quantity + testee.updateLineItem(input) + + verify(mockedProductRepository).updateLineItemQuantityById(1000, input.id!!) + } + } + + /** + * Test for updateLineItem when invalid quantity + */ + @Test(expected = IllegalArgumentException::class) + fun updateLineItem_invalidQuantity_whenExecute_thenThrowException() { + runBlocking { + val input = LineItemModel(1L, null, null, null, null, -1) // invalid quantity + testee.updateLineItem(input) + } + } + + /** + * Test for updateLineItem when Zero quantity + */ + @Test(expected = IllegalArgumentException::class) + fun updateLineItem_zeroQuantity_whenExecute_thenThrowException() { + runBlocking { + val input = LineItemModel(1L, null, null, null, null, 0) // zero quantity + testee.updateLineItem(input) + } + } + + /** + * Test removeLineItem with null values + */ + @Test(expected = IllegalArgumentException::class) + fun removeLineItem_nullId_whenExecute_thenThrowException() { + runBlocking { + val input = LineItemModel(null, null, null, null, null, null) + testee.removeLineItem(input) + } + } + + /** + * Test getCurrentCart with a populated cart + */ + @Test + fun getCurrentCartWithItems_whenExecute_thenReturnCorrectCart() { + val mockOrder = OrderModel( + id = "123", + status = OrderStatus.IN_CART.value, + address = "Test Address", + lineItemList = mutableListOf( + LineItemModel(1L, null, null, null, null, 2), + LineItemModel(2L, null, null, null, null, 3) + ), + createdAt = "2024-10-15" + ) + whenever(mockedOrderRepository.getOneOrderByStatus(OrderStatus.IN_CART)).thenReturn(flow { + emit(mockOrder) + }) + runBlocking { + val result = testee.getCurrentCart() + + result.collect { order -> + TestCase.assertNotNull(order) + TestCase.assertEquals(order?.lineItemList?.size, 2) + TestCase.assertEquals(order?.id, "123") + TestCase.assertEquals(order?.address, "Test Address") + } + } + } + + /** + * Verify interaction with OrderRepository during removeLineItem + */ + @Test + fun removeLineItem_correctValue_whenExecute_thenNoInteractionWithOrderRepository() { + runBlocking { + val input = LineItemModel(1L, null, null, null, null, null) + testee.removeLineItem(input) + + verify(mockedProductRepository).removeLineItemById(input.id!!) + Mockito.verifyNoInteractions(mockedOrderRepository) + } + } } \ No newline at end of file