Extract AdminOrderWorkflowService and status rules API; split AdminPage into composables and components; share order status constants; update tests. Co-authored-by: Cursor <cursoragent@cursor.com>
256 lines
8.6 KiB
Java
256 lines
8.6 KiB
Java
package se.bilhalsning.service;
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
import org.junit.jupiter.api.extension.ExtendWith;
|
|
import org.mockito.ArgumentCaptor;
|
|
import org.mockito.Captor;
|
|
import org.mockito.InjectMocks;
|
|
import org.mockito.Mock;
|
|
import org.mockito.junit.jupiter.MockitoExtension;
|
|
import se.bilhalsning.entity.Order;
|
|
import se.bilhalsning.entity.OrderStatus;
|
|
import se.bilhalsning.exception.InvalidOrderStateException;
|
|
import se.bilhalsning.exception.OrderNotFoundException;
|
|
import se.bilhalsning.repository.OrderRepository;
|
|
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.UUID;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
import static org.mockito.ArgumentMatchers.any;
|
|
import static org.mockito.Mockito.*;
|
|
|
|
@ExtendWith(MockitoExtension.class)
|
|
class OrderServiceTest {
|
|
|
|
@Mock
|
|
private OrderRepository orderRepository;
|
|
|
|
@Mock
|
|
private OrderNotificationService orderNotificationService;
|
|
|
|
@InjectMocks
|
|
private OrderService orderService;
|
|
|
|
@Captor
|
|
private ArgumentCaptor<Order> orderCaptor;
|
|
|
|
@Test
|
|
void shouldCreateOrderWithPendingPaymentStatus() {
|
|
UUID userId = UUID.randomUUID();
|
|
when(orderRepository.save(any(Order.class))).thenAnswer(inv -> inv.getArgument(0));
|
|
|
|
Order result = orderService.createOrder(userId, "ABC123", "Hej fin bil!");
|
|
|
|
assertEquals(OrderStatus.PENDING_PAYMENT, result.getStatus());
|
|
verify(orderRepository).save(orderCaptor.capture());
|
|
assertEquals(OrderStatus.PENDING_PAYMENT, orderCaptor.getValue().getStatus());
|
|
}
|
|
|
|
@Test
|
|
void shouldGenerateIdOnCreate() {
|
|
UUID userId = UUID.randomUUID();
|
|
when(orderRepository.save(any(Order.class))).thenAnswer(inv -> {
|
|
Order order = inv.getArgument(0);
|
|
if (order.getId() == null) {
|
|
order.setId(UUID.randomUUID());
|
|
}
|
|
return order;
|
|
});
|
|
|
|
Order result = orderService.createOrder(userId, "ABC123", "Test text");
|
|
|
|
assertNotNull(result.getId());
|
|
}
|
|
|
|
@Test
|
|
void shouldNormalizePlateToUppercase() {
|
|
UUID userId = UUID.randomUUID();
|
|
when(orderRepository.save(any(Order.class))).thenAnswer(inv -> inv.getArgument(0));
|
|
|
|
Order result = orderService.createOrder(userId, "abc123", "Test text");
|
|
|
|
assertEquals("ABC123", result.getPlate());
|
|
}
|
|
|
|
@Test
|
|
void shouldTrimPlateWhitespace() {
|
|
UUID userId = UUID.randomUUID();
|
|
when(orderRepository.save(any(Order.class))).thenAnswer(inv -> inv.getArgument(0));
|
|
|
|
Order result = orderService.createOrder(userId, " ABC123 ", "Test text");
|
|
|
|
assertEquals("ABC123", result.getPlate());
|
|
}
|
|
|
|
@Test
|
|
void shouldSetAllFieldsOnCreate() {
|
|
UUID userId = UUID.randomUUID();
|
|
when(orderRepository.save(any(Order.class))).thenAnswer(inv -> inv.getArgument(0));
|
|
|
|
Order result = orderService.createOrder(userId, "ABC123", "Hej fin bil!");
|
|
|
|
assertEquals(userId, result.getUserId());
|
|
assertEquals("ABC123", result.getPlate());
|
|
assertEquals("Hej fin bil!", result.getLetterText());
|
|
assertNull(result.getAmountPaid());
|
|
assertNull(result.getTrackingId());
|
|
}
|
|
|
|
@Test
|
|
void shouldReturnOrdersByUserId() {
|
|
UUID userId = UUID.randomUUID();
|
|
Order order1 = new Order();
|
|
Order order2 = new Order();
|
|
when(orderRepository.findByUserIdOrderByCreatedAtDesc(userId))
|
|
.thenReturn(List.of(order1, order2));
|
|
|
|
List<Order> result = orderService.getOrdersByUserId(userId);
|
|
|
|
assertEquals(2, result.size());
|
|
verify(orderRepository).findByUserIdOrderByCreatedAtDesc(userId);
|
|
}
|
|
|
|
@Test
|
|
void shouldReturnOrderById() {
|
|
UUID orderId = UUID.randomUUID();
|
|
Order order = new Order();
|
|
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
|
|
|
|
Order result = orderService.getOrderById(orderId);
|
|
|
|
assertSame(order, result);
|
|
}
|
|
|
|
@Test
|
|
void shouldThrowWhenOrderNotFound() {
|
|
UUID orderId = UUID.randomUUID();
|
|
when(orderRepository.findById(orderId)).thenReturn(Optional.empty());
|
|
|
|
assertThrows(OrderNotFoundException.class,
|
|
() -> orderService.getOrderById(orderId));
|
|
}
|
|
|
|
@Test
|
|
void shouldCancelOrderWhenPendingPayment() {
|
|
UUID orderId = UUID.randomUUID();
|
|
UUID userId = UUID.randomUUID();
|
|
Order order = new Order();
|
|
order.setId(orderId);
|
|
order.setUserId(userId);
|
|
order.setStatus(OrderStatus.PENDING_PAYMENT);
|
|
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
|
|
when(orderRepository.save(any(Order.class))).thenAnswer(inv -> inv.getArgument(0));
|
|
|
|
Order result = orderService.cancelOrder(orderId, userId);
|
|
|
|
assertEquals(OrderStatus.CANCELLED, result.getStatus());
|
|
}
|
|
|
|
@Test
|
|
void shouldThrowWhenCancellingNonPendingOrder() {
|
|
UUID orderId = UUID.randomUUID();
|
|
UUID userId = UUID.randomUUID();
|
|
Order order = new Order();
|
|
order.setId(orderId);
|
|
order.setUserId(userId);
|
|
order.setStatus(OrderStatus.PROCESSING);
|
|
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
|
|
|
|
assertThrows(InvalidOrderStateException.class,
|
|
() -> orderService.cancelOrder(orderId, userId));
|
|
}
|
|
|
|
@Test
|
|
void shouldThrowWhenCancellingOtherUsersOrder() {
|
|
UUID orderId = UUID.randomUUID();
|
|
UUID ownerId = UUID.randomUUID();
|
|
UUID otherUserId = UUID.randomUUID();
|
|
Order order = new Order();
|
|
order.setId(orderId);
|
|
order.setUserId(ownerId);
|
|
order.setStatus(OrderStatus.PENDING_PAYMENT);
|
|
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
|
|
|
|
assertThrows(OrderNotFoundException.class,
|
|
() -> orderService.cancelOrder(orderId, otherUserId));
|
|
}
|
|
|
|
@Test
|
|
void shouldUpdatePendingOrderLetterText() {
|
|
UUID orderId = UUID.randomUUID();
|
|
UUID userId = UUID.randomUUID();
|
|
Order order = new Order();
|
|
order.setId(orderId);
|
|
order.setUserId(userId);
|
|
order.setStatus(OrderStatus.PENDING_PAYMENT);
|
|
order.setLetterText("Old text");
|
|
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
|
|
when(orderRepository.save(any(Order.class))).thenAnswer(inv -> inv.getArgument(0));
|
|
|
|
Order result = orderService.updatePendingOrder(orderId, userId, "New text");
|
|
|
|
assertEquals("New text", result.getLetterText());
|
|
}
|
|
|
|
@Test
|
|
void shouldThrowWhenUpdatingNonPendingOrder() {
|
|
UUID orderId = UUID.randomUUID();
|
|
UUID userId = UUID.randomUUID();
|
|
Order order = new Order();
|
|
order.setId(orderId);
|
|
order.setUserId(userId);
|
|
order.setStatus(OrderStatus.PROCESSING);
|
|
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
|
|
|
|
assertThrows(InvalidOrderStateException.class,
|
|
() -> orderService.updatePendingOrder(orderId, userId, "New text"));
|
|
}
|
|
|
|
@Test
|
|
void shouldConfirmPaymentForPendingOrder() {
|
|
UUID orderId = UUID.randomUUID();
|
|
UUID userId = UUID.randomUUID();
|
|
Order order = new Order();
|
|
order.setId(orderId);
|
|
order.setUserId(userId);
|
|
order.setStatus(OrderStatus.PENDING_PAYMENT);
|
|
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
|
|
when(orderRepository.save(any(Order.class))).thenAnswer(inv -> inv.getArgument(0));
|
|
|
|
Order result = orderService.confirmPayment(orderId, userId);
|
|
|
|
assertEquals(OrderStatus.PROCESSING, result.getStatus());
|
|
}
|
|
|
|
@Test
|
|
void shouldThrowWhenConfirmingPaymentForNonPendingOrder() {
|
|
UUID orderId = UUID.randomUUID();
|
|
UUID userId = UUID.randomUUID();
|
|
Order order = new Order();
|
|
order.setId(orderId);
|
|
order.setUserId(userId);
|
|
order.setStatus(OrderStatus.CANCELLED);
|
|
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
|
|
|
|
assertThrows(InvalidOrderStateException.class,
|
|
() -> orderService.confirmPayment(orderId, userId));
|
|
}
|
|
|
|
@Test
|
|
void shouldThrowWhenConfirmingPaymentForOtherUsersOrder() {
|
|
UUID orderId = UUID.randomUUID();
|
|
UUID ownerId = UUID.randomUUID();
|
|
UUID otherUserId = UUID.randomUUID();
|
|
Order order = new Order();
|
|
order.setId(orderId);
|
|
order.setUserId(ownerId);
|
|
order.setStatus(OrderStatus.PENDING_PAYMENT);
|
|
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
|
|
|
|
assertThrows(OrderNotFoundException.class,
|
|
() -> orderService.confirmPayment(orderId, otherUserId));
|
|
}
|
|
|
|
}
|