orderIds);
+
}
diff --git a/src/main/java/com/bazaar/orders/service/CleanupService.java b/src/main/java/com/bazaar/orders/service/CleanupService.java
index 3c61052..fd7b4ff 100644
--- a/src/main/java/com/bazaar/orders/service/CleanupService.java
+++ b/src/main/java/com/bazaar/orders/service/CleanupService.java
@@ -8,8 +8,11 @@
import com.bazaar.orders.model.OrderItem;
import com.bazaar.orders.model.OrderPayment;
import com.bazaar.orders.repository.OrderItemRepository;
+import com.bazaar.orders.repository.OrderItemReviewRepository;
import com.bazaar.orders.repository.OrderPaymentRepository;
import com.bazaar.orders.repository.OrderRepository;
+import com.bazaar.orders.repository.OrderReviewRepository;
+import com.bazaar.orders.repository.OrderStatusHistoryRepository;
import lombok.RequiredArgsConstructor;
@@ -35,6 +38,12 @@ public class CleanupService {
private final OrderItemRepository orderItemRepository;
+ private final OrderItemReviewRepository orderItemReviewRepository;
+
+ private final OrderReviewRepository orderReviewRepository;
+
+ private final OrderStatusHistoryRepository orderStatusHistoryRepository;
+
/**
* Performs an atomic cleanup of a single abandoned payment.
*
@@ -60,6 +69,7 @@ public void orderPaymentCleanup(OrderPayment payment) {
List orders = orderRepository.findByOrderPaymentId(payment.getId());
List orderIds = orders.stream().map(Order::getId).toList();
List orderItems = orderItemRepository.findByOrderIdIn(orderIds);
+ List orderItemIds = orderItems.stream().map(OrderItem::getId).toList();
List stockRequests = orderItems.stream()
.map(UpdateProductStockRequestDTO::fromOrderItem)
@@ -67,6 +77,9 @@ public void orderPaymentCleanup(OrderPayment payment) {
rabbitMQProducer.send(new UpdateProductsStockRequestDTO(stockRequests), RabbitMQConfig.ROUTING_KEY_RESTORE);
+ orderItemReviewRepository.deleteByOrderItemIdIn(orderItemIds);
+ orderReviewRepository.deleteByOrderIdIn(orderIds);
+ orderStatusHistoryRepository.deleteByOrderIdIn(orderIds);
orderItemRepository.deleteAll(orderItems);
orderRepository.deleteAll(orders);
orderPaymentRepository.delete(payment);
diff --git a/src/main/java/com/bazaar/orders/service/MercadoPagoService.java b/src/main/java/com/bazaar/orders/service/MercadoPagoService.java
index caa101d..eb93bb4 100644
--- a/src/main/java/com/bazaar/orders/service/MercadoPagoService.java
+++ b/src/main/java/com/bazaar/orders/service/MercadoPagoService.java
@@ -12,6 +12,7 @@
import com.bazaar.orders.model.Order;
import com.bazaar.orders.model.OrderItem;
import com.bazaar.orders.model.OrderPayment;
+
import com.mercadopago.client.payment.PaymentClient;
import com.mercadopago.client.preference.PreferenceBackUrlsRequest;
import com.mercadopago.client.preference.PreferenceClient;
diff --git a/src/main/java/com/bazaar/orders/service/ReviewsService.java b/src/main/java/com/bazaar/orders/service/ReviewsService.java
index 02149e7..3292f40 100644
--- a/src/main/java/com/bazaar/orders/service/ReviewsService.java
+++ b/src/main/java/com/bazaar/orders/service/ReviewsService.java
@@ -121,7 +121,6 @@ public OrderReviewDTO getOrderReview(Long orderId, Long userId) {
return OrderReviewDTO.fromOrderReview(getExistingOrderReview(orderId, userId), getUserProfile(userId));
}
-
/**
* Retrieves the detailed review associated with an order and user.
* @param orderId identifier of the reviewed order.
@@ -135,14 +134,13 @@ public OrderDetailedReviewDTO getDetailedOrderReview(final Long orderId, final L
OrderReview orderReview = getExistingOrderReview(orderId, userId);
List orderItems = orderItemReviewRepository.findAllByOrderId(orderId);
- List itemReviewDTOs = orderItems.stream()
- .map(review -> {
- var userProfile = getUserProfile(review.getUserId());
- return OrderItemReviewDTO.fromOrderItemReview(review, userProfile);
- })
- .toList();
+ List itemReviewDTOs = orderItems.stream().map(review -> {
+ var userProfile = getUserProfile(review.getUserId());
+ return OrderItemReviewDTO.fromOrderItemReview(review, userProfile);
+ }).toList();
- return OrderDetailedReviewDTO.fromOrderReview(orderReview, itemReviewDTOs, getUserProfile(orderReview.getUserId()));
+ return OrderDetailedReviewDTO.fromOrderReview(orderReview, itemReviewDTOs,
+ getUserProfile(orderReview.getUserId()));
}
@@ -154,7 +152,7 @@ public OrderDetailedReviewDTO getDetailedOrderReview(final Long orderId, final L
* @return list of created {@link OrderItemReviewDTO}.
*/
public List createOrderItemsReview(Long orderId, Long userId,
- CreateOrderItemsReviewRequestDTO request) {
+ CreateOrderItemsReviewRequestDTO request) {
checkUserStatus(userId);
validateOrder(orderId);
@@ -232,13 +230,10 @@ public List getProductReviews(Long productId) {
List orderItemIds = orderItems.stream().map(OrderItem::getId).toList();
- return orderItemReviewRepository.findAllByOrderItemIdIn(orderItemIds)
- .stream()
- .map(review -> {
- var userProfile = getUserProfile(review.getUserId());
- return OrderItemReviewDTO.fromOrderItemReview(review, userProfile);
- })
- .toList();
+ return orderItemReviewRepository.findAllByOrderItemIdIn(orderItemIds).stream().map(review -> {
+ var userProfile = getUserProfile(review.getUserId());
+ return OrderItemReviewDTO.fromOrderItemReview(review, userProfile);
+ }).toList();
}
/**
@@ -258,11 +253,7 @@ public List getSellerReviews(final Long sellerId) {
* @param sellerId identifier of the reviewed product.
* @return list of {@link OrderReviewDTO}.
*/
- @Cacheable(
- value = "sellerReputation",
- key = "#sellerId",
- sync = true
- )
+ @Cacheable(value = "sellerReputation", key = "#sellerId", sync = true)
public SellerReputationDTO getSellerReputation(final Long sellerId) {
logger.info("Calculating reputation for seller with id {}", sellerId);
return orderReviewRepository.getSellerReputation(sellerId);
@@ -319,13 +310,10 @@ private Long getOrderItemId(Long orderId, Long productId) {
* @return list of saved {@link OrderItemReviewDTO}.
*/
private List saveOrderItemReviews(List reviews) {
- return orderItemReviewRepository.saveAll(reviews)
- .stream()
- .map(review -> {
- var userProfile = getUserProfile(review.getUserId());
- return OrderItemReviewDTO.fromOrderItemReview(review, userProfile);
- })
- .toList();
+ return orderItemReviewRepository.saveAll(reviews).stream().map(review -> {
+ var userProfile = getUserProfile(review.getUserId());
+ return OrderItemReviewDTO.fromOrderItemReview(review, userProfile);
+ }).toList();
}
/**
diff --git a/src/test/java/com/bazaar/orders/config/MercadoPagoConfigTests.java b/src/test/java/com/bazaar/orders/config/MercadoPagoConfigTests.java
new file mode 100644
index 0000000..072403e
--- /dev/null
+++ b/src/test/java/com/bazaar/orders/config/MercadoPagoConfigTests.java
@@ -0,0 +1,65 @@
+package com.bazaar.orders.config;
+
+import org.mockito.Mockito;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+
+import com.mercadopago.client.payment.PaymentClient;
+import com.mercadopago.client.preference.PreferenceClient;
+import com.mercadopago.resources.payment.Payment;
+import com.mercadopago.resources.preference.Preference;
+
+import jakarta.annotation.PostConstruct;
+
+@Configuration
+@Profile("stress")
+public class MercadoPagoConfigTests {
+
+ @Value("${mercadopago.access.token}")
+ private String accessToken;
+
+ @PostConstruct
+ public void configMercadoPago() {
+ com.mercadopago.MercadoPagoConfig.setAccessToken(accessToken);
+ }
+
+ @Bean
+ public PaymentClient paymentClient() throws Exception {
+ PaymentClient client = Mockito.mock(PaymentClient.class);
+
+ Mockito.when(client.get(Mockito.anyLong())).thenAnswer(invocation -> {
+ Thread.sleep(250);
+
+ Long paymentId = invocation.getArgument(0);
+
+ Payment payment = Mockito.mock(Payment.class);
+
+ Mockito.when(payment.getExternalReference()).thenReturn("REQ-STRESS-" + paymentId);
+
+ Mockito.when(payment.getStatus()).thenReturn("approved");
+
+ return payment;
+ });
+
+ return client;
+ }
+
+ @Bean
+ public PreferenceClient preferenceClient() throws Exception {
+ PreferenceClient client = Mockito.mock(PreferenceClient.class);
+
+ Mockito.when(client.create(Mockito.any())).thenAnswer(invocation -> {
+ Thread.sleep(250);
+
+ Preference preference = Mockito.mock(Preference.class);
+ Mockito.when(preference.getInitPoint()).thenReturn("https://www.mercadopago.com.ar/sandbox/init/fake");
+
+ return preference;
+ });
+
+ return client;
+ }
+
+}
diff --git a/src/test/java/com/bazaar/orders/controller/ReviewsControllerTest.java b/src/test/java/com/bazaar/orders/controller/ReviewsControllerTest.java
index 25c225a..0e8e9b2 100644
--- a/src/test/java/com/bazaar/orders/controller/ReviewsControllerTest.java
+++ b/src/test/java/com/bazaar/orders/controller/ReviewsControllerTest.java
@@ -95,7 +95,7 @@ private String orderItemReviewJson(Long productId, int rating, String comment) {
@Test
void testCreateOrderReviewSuccess() {
when(userClient.getUserProfile(2L))
- .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
mockArrivedOrder(9L);
@@ -152,7 +152,7 @@ void testCreateOrderReviewInvalidRating() {
@Test
void testGetOrderReviewSuccess() {
when(userClient.getUserProfile(1L))
- .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
mockArrivedOrder(2L);
@@ -191,16 +191,14 @@ void testGetOrderReviewForbidden() {
@Test
void testGetDetailedOrderReviewSuccess() {
when(userClient.getUserProfile(1L))
- .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
mockArrivedOrder(15L);
mockOrderItem(15L, 2L, 4L);
- postOrderReview(15L, 1L,
- sellerReviewJson(5L, 5, "Excellent seller"));
+ postOrderReview(15L, 1L, sellerReviewJson(5L, 5, "Excellent seller"));
- postOrderItemsReview(15L, 1L,
- orderItemReviewJson(2L, 4, "Nice product"));
+ postOrderItemsReview(15L, 1L, orderItemReviewJson(2L, 4, "Nice product"));
var response = getDetailedOrderReview(15L, 1L);
@@ -208,32 +206,22 @@ void testGetDetailedOrderReviewSuccess() {
String body = response.getBody();
- assertEquals(5,
- ((Number) JsonPath.read(body, "$.data.rating")).intValue());
+ assertEquals(5, ((Number) JsonPath.read(body, "$.data.rating")).intValue());
- assertEquals("Excellent seller",
- JsonPath.read(body, "$.data.comment"));
+ assertEquals("Excellent seller", JsonPath.read(body, "$.data.comment"));
- assertEquals(1,
- ((Number) JsonPath.read(body, "$.data.itemReviews.length()")).intValue());
+ assertEquals(1, ((Number) JsonPath.read(body, "$.data.itemReviews.length()")).intValue());
- assertEquals(4,
- ((Number) JsonPath.read(body, "$.data.itemReviews[0].rating")).intValue());
+ assertEquals(4, ((Number) JsonPath.read(body, "$.data.itemReviews[0].rating")).intValue());
- assertEquals("Nice product",
- JsonPath.read(body, "$.data.itemReviews[0].comment"));
+ assertEquals("Nice product", JsonPath.read(body, "$.data.itemReviews[0].comment"));
}
@Test
void testGetDetailedOrderReviewForbidden() {
when(userClient.getUserStatus(1L))
- .thenReturn(
- new ApiResponse<>(
- new UserStatusResponseDTO(
- 1L,
- "MOCKED",
- UserStatus.BLOCKED)));
+ .thenReturn(new ApiResponse<>(new UserStatusResponseDTO(1L, "MOCKED", UserStatus.BLOCKED)));
var response = getDetailedOrderReview(1L, 1L);
@@ -251,7 +239,7 @@ void testGetDetailedOrderReviewNotFound() {
@Test
void testUpsertOrderReviewSuccess() {
when(userClient.getUserProfile(1L))
- .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
mockArrivedOrder(1L);
@@ -273,7 +261,7 @@ void testUpsertOrderReviewSuccess() {
@Test
void testUpsertOrderReviewForbidden() {
when(userClient.getUserProfile(1L))
- .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
mockArrivedOrder(1L);
@@ -293,7 +281,7 @@ void testUpsertOrderReviewForbidden() {
@Test
void testCreateOrderItemsReviewSuccess() {
when(userClient.getUserProfile(1L))
- .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
mockOrderItem(1L, 6L, 7L);
@@ -340,7 +328,7 @@ void testCreateOrderItemsReviewInvalidOrderItem() {
@Test
void testGetOrderItemReviewSuccess() {
when(userClient.getUserProfile(1L))
- .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
mockOrderItem(1L, 2L, 40L);
@@ -375,7 +363,7 @@ void testGetOrderItemReviewForbidden() {
@Test
void testGetProductReviewsSuccess() {
when(userClient.getUserProfile(1L))
- .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
var orderItem = mockOrderItem(1L, 2L, 8L);
@@ -399,14 +387,11 @@ void testGetProductReviewsSuccess() {
@Test
void testGetSellerReviewsSuccess() {
when(userClient.getUserProfile(1L))
- .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
mockArrivedOrder(25L);
- postOrderReview(
- 25L,
- 1L,
- sellerReviewJson(9L, 5, "Excellent seller"));
+ postOrderReview(25L, 1L, sellerReviewJson(9L, 5, "Excellent seller"));
var response = getSellerReviews(9L, 1L);
@@ -414,17 +399,13 @@ void testGetSellerReviewsSuccess() {
String body = response.getBody();
- assertEquals(1,
- ((Number) JsonPath.read(body, "$.data.length()")).intValue());
+ assertEquals(1, ((Number) JsonPath.read(body, "$.data.length()")).intValue());
- assertEquals(5,
- ((Number) JsonPath.read(body, "$.data[0].rating")).intValue());
+ assertEquals(5, ((Number) JsonPath.read(body, "$.data[0].rating")).intValue());
- assertEquals("Excellent seller",
- JsonPath.read(body, "$.data[0].comment"));
+ assertEquals("Excellent seller", JsonPath.read(body, "$.data[0].comment"));
- assertEquals(9L,
- ((Number) JsonPath.read(body, "$.data[0].sellerId")).longValue());
+ assertEquals(9L, ((Number) JsonPath.read(body, "$.data[0].sellerId")).longValue());
}
@Test
@@ -436,32 +417,23 @@ void testGetSellerReviewsEmpty() {
String body = response.getBody();
- assertEquals(0,
- ((Number) JsonPath.read(body, "$.data.length()")).intValue());
+ assertEquals(0, ((Number) JsonPath.read(body, "$.data.length()")).intValue());
}
@Test
void testGetSellerReviewsMultipleUsers() {
when(userClient.getUserProfile(1L))
- .thenReturn(new ApiResponse<>(
- new UserProfileResponseDTO("juan", "perez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
when(userClient.getUserProfile(2L))
- .thenReturn(new ApiResponse<>(
- new UserProfileResponseDTO("maria", "gomez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("maria", "gomez", null, null, null)));
mockArrivedOrder(100L);
mockArrivedOrder(200L);
- postOrderReview(
- 100L,
- 1L,
- sellerReviewJson(8L, 5, "Excellent seller"));
+ postOrderReview(100L, 1L, sellerReviewJson(8L, 5, "Excellent seller"));
- postOrderReview(
- 200L,
- 2L,
- sellerReviewJson(8L, 4, "Very good seller"));
+ postOrderReview(200L, 2L, sellerReviewJson(8L, 4, "Very good seller"));
var response = getSellerReviews(8L, 1L);
@@ -469,8 +441,7 @@ void testGetSellerReviewsMultipleUsers() {
String body = response.getBody();
- assertEquals(2,
- ((Number) JsonPath.read(body, "$.data.length()")).intValue());
+ assertEquals(2, ((Number) JsonPath.read(body, "$.data.length()")).intValue());
List ratings = JsonPath.read(body, "$.data[*].rating");
assertTrue(ratings.contains(5));
@@ -484,25 +455,17 @@ void testGetSellerReviewsMultipleUsers() {
@Test
void testGetSellerReputationSuccess() {
when(userClient.getUserProfile(1L))
- .thenReturn(new ApiResponse<>(
- new UserProfileResponseDTO("juan", "perez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("juan", "perez", null, null, null)));
when(userClient.getUserProfile(2L))
- .thenReturn(new ApiResponse<>(
- new UserProfileResponseDTO("maria", "gomez", null, null, null)));
+ .thenReturn(new ApiResponse<>(new UserProfileResponseDTO("maria", "gomez", null, null, null)));
mockArrivedOrder(102L);
mockArrivedOrder(202L);
- postOrderReview(
- 102L,
- 1L,
- sellerReviewJson(10L, 5, "Excellent seller"));
+ postOrderReview(102L, 1L, sellerReviewJson(10L, 5, "Excellent seller"));
- postOrderReview(
- 202L,
- 2L,
- sellerReviewJson(10L, 4, "Very good seller"));
+ postOrderReview(202L, 2L, sellerReviewJson(10L, 4, "Very good seller"));
getSellerReputation(10L);
getSellerReputation(10L);
@@ -516,17 +479,11 @@ void testGetSellerReputationSuccess() {
String body = response.getBody();
- assertEquals(
- 10L,
- ((Number) JsonPath.read(body, "$.data.sellerId")).longValue());
+ assertEquals(10L, ((Number) JsonPath.read(body, "$.data.sellerId")).longValue());
- assertEquals(
- 4.5,
- ((Number) JsonPath.read(body, "$.data.averageRating")).doubleValue());
+ assertEquals(4.5, ((Number) JsonPath.read(body, "$.data.averageRating")).doubleValue());
- assertEquals(
- 2,
- ((Number) JsonPath.read(body, "$.data.totalReviews")).intValue());
+ assertEquals(2, ((Number) JsonPath.read(body, "$.data.totalReviews")).intValue());
}
@Test
@@ -538,17 +495,11 @@ void testGetSellerReputationWithoutReviews() {
String body = response.getBody();
- assertEquals(
- 999L,
- ((Number) JsonPath.read(body, "$.data.sellerId")).longValue());
+ assertEquals(999L, ((Number) JsonPath.read(body, "$.data.sellerId")).longValue());
- assertEquals(
- 0.0,
- ((Number) JsonPath.read(body, "$.data.averageRating")).doubleValue());
+ assertEquals(0.0, ((Number) JsonPath.read(body, "$.data.averageRating")).doubleValue());
- assertEquals(
- 0,
- ((Number) JsonPath.read(body, "$.data.totalReviews")).intValue());
+ assertEquals(0, ((Number) JsonPath.read(body, "$.data.totalReviews")).intValue());
}
}
\ No newline at end of file
diff --git a/src/test/java/com/bazaar/orders/testConfig/AbstractTest.java b/src/test/java/com/bazaar/orders/testConfig/AbstractTest.java
index a13af7f..17bfa01 100644
--- a/src/test/java/com/bazaar/orders/testConfig/AbstractTest.java
+++ b/src/test/java/com/bazaar/orders/testConfig/AbstractTest.java
@@ -368,15 +368,15 @@ protected ResponseEntity getOrderReview(Long orderId, Long userId) {
protected ResponseEntity getDetailedOrderReview(Long orderId, Long userId) {
var result = webTestClient.get()
- .uri("/reviews/orders/%d/detailed".formatted(orderId))
- .header("X-User-Id", userId.toString())
- .exchange()
- .expectBody(String.class)
- .returnResult();
+ .uri("/reviews/orders/%d/detailed".formatted(orderId))
+ .header("X-User-Id", userId.toString())
+ .exchange()
+ .expectBody(String.class)
+ .returnResult();
return ResponseEntity.status(result.getStatus())
- .headers(result.getResponseHeaders())
- .body(result.getResponseBody());
+ .headers(result.getResponseHeaders())
+ .body(result.getResponseBody());
}
protected ResponseEntity putOrderReview(Long orderId, Long userId, String requestJson) {
@@ -442,28 +442,28 @@ protected ResponseEntity getProductReviews(Long productId, Long userId)
protected ResponseEntity getSellerReviews(Long sellerId, Long userId) {
var result = webTestClient.get()
- .uri("/reviews/seller/%d".formatted(sellerId))
- .header("X-User-Id", userId.toString())
- .exchange()
- .expectBody(String.class)
- .returnResult();
+ .uri("/reviews/seller/%d".formatted(sellerId))
+ .header("X-User-Id", userId.toString())
+ .exchange()
+ .expectBody(String.class)
+ .returnResult();
return ResponseEntity.status(result.getStatus())
- .headers(result.getResponseHeaders())
- .body(result.getResponseBody());
+ .headers(result.getResponseHeaders())
+ .body(result.getResponseBody());
}
protected ResponseEntity getSellerReputation(Long sellerId) {
var result = webTestClient.get()
- .uri("/reviews/seller/%d/reputation".formatted(sellerId))
- .exchange()
- .expectBody(String.class)
- .returnResult();
+ .uri("/reviews/seller/%d/reputation".formatted(sellerId))
+ .exchange()
+ .expectBody(String.class)
+ .returnResult();
return ResponseEntity.status(result.getStatus())
- .headers(result.getResponseHeaders())
- .body(result.getResponseBody());
+ .headers(result.getResponseHeaders())
+ .body(result.getResponseBody());
}
public void assertPageResponse(String body, Integer page, Integer size, Integer totalElements, Integer totalPages) {