diff --git a/src/main/java/com/github/prominence/carrepair/formatter/OrderStatusFormatter.java b/src/main/java/com/github/prominence/carrepair/formatter/OrderStatusFormatter.java index 43eb233..c62a670 100644 --- a/src/main/java/com/github/prominence/carrepair/formatter/OrderStatusFormatter.java +++ b/src/main/java/com/github/prominence/carrepair/formatter/OrderStatusFormatter.java @@ -16,6 +16,7 @@ public class OrderStatusFormatter implements Formatter { @Override public OrderStatus parse(String text, Locale locale) { + if (text == null) return null; final OrderStatus parsedOrderStatus = OrderStatus.valueOf(text.toUpperCase()); logger.trace("Parsing String[{}] to OrderStatus instance: {}.", () -> text, () -> parsedOrderStatus); return parsedOrderStatus; @@ -23,6 +24,7 @@ public class OrderStatusFormatter implements Formatter { @Override public String print(OrderStatus object, Locale locale) { + if (object == null) return null; final String formattedOrderStatus = StringUtils.capitalize(object.toString().toLowerCase()); logger.trace("Formatting OrderStatus[{}] to String instance: {}.", () -> object, () -> formattedOrderStatus); return formattedOrderStatus; diff --git a/src/main/java/com/github/prominence/carrepair/service/OrderService.java b/src/main/java/com/github/prominence/carrepair/service/OrderService.java index dd8aba9..b381efd 100644 --- a/src/main/java/com/github/prominence/carrepair/service/OrderService.java +++ b/src/main/java/com/github/prominence/carrepair/service/OrderService.java @@ -24,16 +24,14 @@ public class OrderService { private OrderRepository orderRepository; private ClientService clientService; private MechanicService mechanicService; - private SmartValidator smartValidator; private OrderValidator orderValidator; private OrderMapper orderMapper; - public OrderService(OrderRepository orderRepository, ClientService clientService, MechanicService mechanicService, SmartValidator smartValidator, + public OrderService(OrderRepository orderRepository, ClientService clientService, MechanicService mechanicService, OrderValidator orderValidator, OrderMapper orderMapper) { this.orderRepository = orderRepository; this.clientService = clientService; this.mechanicService = mechanicService; - this.smartValidator = smartValidator; this.orderValidator = orderValidator; this.orderMapper = orderMapper; } @@ -101,7 +99,6 @@ public class OrderService { order.setMechanicLastName(mechanic.getLastName()); }); } - smartValidator.validate(order, bindingResult); orderValidator.validate(order, bindingResult); } diff --git a/src/main/java/com/github/prominence/carrepair/validation/OrderValidator.java b/src/main/java/com/github/prominence/carrepair/validation/OrderValidator.java index d44a599..63745cb 100644 --- a/src/main/java/com/github/prominence/carrepair/validation/OrderValidator.java +++ b/src/main/java/com/github/prominence/carrepair/validation/OrderValidator.java @@ -10,6 +10,7 @@ import org.apache.logging.log4j.Logger; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; +import org.springframework.validation.SmartValidator; import org.springframework.validation.Validator; import java.time.LocalDateTime; @@ -21,10 +22,12 @@ public class OrderValidator implements Validator { private CustomDateTimeFormatter customDateTimeFormatter; private OrderStatusFormatter orderStatusFormatter; + private SmartValidator smartValidator; - public OrderValidator(CustomDateTimeFormatter customDateTimeFormatter, OrderStatusFormatter orderStatusFormatter) { + public OrderValidator(CustomDateTimeFormatter customDateTimeFormatter, OrderStatusFormatter orderStatusFormatter, SmartValidator smartValidator) { this.customDateTimeFormatter = customDateTimeFormatter; this.orderStatusFormatter = orderStatusFormatter; + this.smartValidator = smartValidator; } @Override @@ -36,6 +39,8 @@ public class OrderValidator implements Validator { public void validate(Object o, Errors errors) { OrderDto order = (OrderDto) o; + smartValidator.validate(order, errors); + Locale locale = LocaleContextHolder.getLocale(); OrderStatus orderStatus = orderStatusFormatter.parse(order.getOrderStatus(), locale); diff --git a/src/test/java/com/github/prominence/carrepair/service/OrderServiceIntegrationTest.java b/src/test/java/com/github/prominence/carrepair/service/OrderServiceIntegrationTest.java index 36eee5e..4b2d049 100644 --- a/src/test/java/com/github/prominence/carrepair/service/OrderServiceIntegrationTest.java +++ b/src/test/java/com/github/prominence/carrepair/service/OrderServiceIntegrationTest.java @@ -47,9 +47,6 @@ public class OrderServiceIntegrationTest { @Autowired private MechanicService mechanicService; - @MockBean - private SmartValidator smartValidator; - @MockBean private OrderValidator orderValidator; @@ -246,7 +243,6 @@ public class OrderServiceIntegrationTest { orderService.fetchNestedObjectsAndValidate(orderDto, orderDto.getClientId(), orderDto.getMechanicId(), bindingResult); // then - verify(smartValidator, times(1)).validate(orderDto, bindingResult); verify(orderValidator, times(1)).validate(orderDto, bindingResult); } diff --git a/src/test/java/com/github/prominence/carrepair/validation/OrderValidatorUnitTest.java b/src/test/java/com/github/prominence/carrepair/validation/OrderValidatorUnitTest.java new file mode 100644 index 0000000..293e6c6 --- /dev/null +++ b/src/test/java/com/github/prominence/carrepair/validation/OrderValidatorUnitTest.java @@ -0,0 +1,156 @@ +package com.github.prominence.carrepair.validation; + +import com.github.prominence.carrepair.enums.OrderStatus; +import com.github.prominence.carrepair.formatter.CustomDateTimeFormatter; +import com.github.prominence.carrepair.formatter.OrderStatusFormatter; +import com.github.prominence.carrepair.model.dto.OrderDto; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.validation.BindingResult; +import org.springframework.validation.SmartValidator; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import static org.mockito.Mockito.*; + +@RunWith(SpringRunner.class) +@ContextConfiguration +@Import({OrderValidator.class, CustomDateTimeFormatter.class, OrderStatusFormatter.class}) +public class OrderValidatorUnitTest { + + @Configuration + public static class Config { + @Bean + public SmartValidator smartValidator() { + return new LocalValidatorFactoryBean(); + } + } + + @Autowired + private OrderValidator orderValidator; + + @Autowired + private CustomDateTimeFormatter customDateTimeFormatter; + + @Autowired + private OrderStatusFormatter orderStatusFormatter; + + @Test + public void whenValidateEmptyOrderDto_thenPushErrors() { + // given + BindingResult bindingResult = mock(BindingResult.class); + when(bindingResult.getObjectName()).thenReturn("mock"); + OrderDto orderDto = new OrderDto(); + + // when + orderValidator.validate(orderDto, bindingResult); + + // then + verify(bindingResult, atLeastOnce()).addError(any()); + } + + @Test + public void whenFinishedOnIsSetButNotAccepted_thenPushError() { + // given + BindingResult bindingResult = mock(BindingResult.class); + when(bindingResult.getObjectName()).thenReturn("mock"); + OrderDto orderDto = getTestOrderDto(); + + // when + orderValidator.validate(orderDto, bindingResult); + + // then + verify(bindingResult, times(1)).rejectValue(eq("finishedOnDate"), anyString()); + } + + @Test + public void whenFinishedOnIsNotSetAndAccepted_thenPushError() { + // given + BindingResult bindingResult = mock(BindingResult.class); + when(bindingResult.getObjectName()).thenReturn("mock"); + OrderDto orderDto = getTestOrderDto(); + orderDto.setFinishedOnDate(null); + orderDto.setOrderStatus(orderStatusFormatter.print(OrderStatus.ACCEPTED, null)); + + // when + orderValidator.validate(orderDto, bindingResult); + + // then + verify(bindingResult, times(1)).rejectValue(eq("orderStatus"), anyString()); + } + + @Test + public void whenFinishedOnIsNotSetAndNotAccepted_thenPushError() { + // given + BindingResult bindingResult = mock(BindingResult.class); + when(bindingResult.getObjectName()).thenReturn("mock"); + OrderDto orderDto = getTestOrderDto(); + orderDto.setFinishedOnDate(null); + + // when + orderValidator.validate(orderDto, bindingResult); + + // then + verify(bindingResult, never()).rejectValue(eq("orderStatus"), anyString()); + } + + @Test + public void whenFinishedOnIsBeforeCreatedOn_thenPushError() { + // given + BindingResult bindingResult = mock(BindingResult.class); + when(bindingResult.getObjectName()).thenReturn("mock"); + OrderDto orderDto = getTestOrderDto(); + orderDto.setOrderStatus(orderStatusFormatter.print(OrderStatus.ACCEPTED, null)); + orderDto.setCreatedOnDate(customDateTimeFormatter.print(LocalDateTime.now().plusDays(2), null)); + orderDto.setFinishedOnDate(customDateTimeFormatter.print(LocalDateTime.now(), null)); + + // when + orderValidator.validate(orderDto, bindingResult); + + // then + verify(bindingResult, times(1)).rejectValue(eq("finishedOnDate"), anyString()); + } + + @Test + public void whenAllIsCorrect_thenNoErrors() { + // given + BindingResult bindingResult = mock(BindingResult.class); + when(bindingResult.getObjectName()).thenReturn("mock"); + OrderDto orderDto = getTestOrderDto(); + orderDto.setOrderStatus(orderStatusFormatter.print(OrderStatus.ACCEPTED, null)); + + // when + orderValidator.validate(orderDto, bindingResult); + + // then + verify(bindingResult, never()).rejectValue(anyString(), anyString()); + } + + private OrderDto getTestOrderDto() { + OrderDto orderDto = new OrderDto(); + orderDto.setId(4L); + orderDto.setMechanicId(3L); + orderDto.setMechanicFirstName("213"); + orderDto.setMechanicMiddleName("1231"); + orderDto.setMechanicLastName("qewqwe"); + orderDto.setClientId(4L); + orderDto.setClientFirstName("adsas"); + orderDto.setClientMiddleName("Sdas"); + orderDto.setClientLastName("asdasd"); + orderDto.setDescription("asdasdasdsad"); + orderDto.setTotalPrice(BigDecimal.TEN); + orderDto.setOrderStatus(orderStatusFormatter.print(OrderStatus.DONE, null)); + orderDto.setCreatedOnDate(customDateTimeFormatter.print(LocalDateTime.now(), null)); + orderDto.setFinishedOnDate(customDateTimeFormatter.print(LocalDateTime.now().plusDays(1), null)); + + return orderDto; + } +}