package com.yummynoodlebar.web.controller;
import static com.yummynoodlebar.web.controller.fixture.WebDataFixture.newOrder;
import static com.yummynoodlebar.web.controller.fixture.WebDataFixture.standardWebMenuItem;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import com.yummynoodlebar.core.services.OrderService;
import com.yummynoodlebar.events.orders.CreateOrderEvent;
import com.yummynoodlebar.web.domain.Basket;
public class CheckoutIntegrationTest {
private static final String POST_CODE = "90210";
private static final String ADDRESS1 = "Where they live";
private static final String CUSTOMER_NAME = "Customer Name";
private static final String CHECKOUT_VIEW = "/WEB-INF/views/checkout.html";
MockMvc mockMvc;
@InjectMocks
CheckoutController controller;
@Mock
OrderService orderService;
//{!begin init}
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
controller.setBasket(new Basket());
mockMvc = standaloneSetup(controller).setViewResolvers(viewResolver())
.build();
}
private InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views");
viewResolver.setSuffix(".html");
return viewResolver;
}
//{!end init}
@Test
public void thatBasketIsPopulated() throws Exception {
mockMvc.perform(get("/checkout")).andExpect(
model().attributeExists("basket"));
}
@Test
public void thatCheckoutViewIsCorrect() throws Exception {
mockMvc.perform(get("/checkout"))
.andExpect(forwardedUrl(CHECKOUT_VIEW));
}
@Test
public void thatRedirectsToOrderOnSuccess() throws Exception {
UUID id = UUID.randomUUID();
when(orderService.createOrder(any(CreateOrderEvent.class))).thenReturn(newOrder(id));
mockMvc.perform(
post("/checkout").param("name", CUSTOMER_NAME)
.param("address1", ADDRESS1)
.param("postcode", POST_CODE))
.andExpect(status().isMovedTemporarily())
.andExpect(redirectedUrl("/order/" + id.toString()));
}
@Test
public void thatSendsCorrectOrderEventOnSuccess() throws Exception {
UUID id = UUID.randomUUID();
when(orderService.createOrder(any(CreateOrderEvent.class))).thenReturn(newOrder(id));
mockMvc.perform(post("/checkout")
.param("name", CUSTOMER_NAME)
.param("address1", ADDRESS1)
.param("postcode", POST_CODE))
.andDo(print());
//@formatter:off
verify(orderService).createOrder(Matchers.<CreateOrderEvent>argThat(
allOf(
org.hamcrest.Matchers.<CreateOrderEvent>hasProperty("details",
hasProperty("dateTimeOfSubmission", notNullValue())),
org.hamcrest.Matchers.<CreateOrderEvent>hasProperty("details",
hasProperty("name", equalTo(CUSTOMER_NAME))),
org.hamcrest.Matchers.<CreateOrderEvent>hasProperty("details",
hasProperty("address1", equalTo(ADDRESS1))),
org.hamcrest.Matchers.<CreateOrderEvent>hasProperty("details",
hasProperty("postcode", equalTo(POST_CODE)))
)));
//@formatter:on
}
@Test
public void thatBasketIsEmptyOnSuccess() throws Exception {
UUID id = UUID.randomUUID();
when(orderService.createOrder(any(CreateOrderEvent.class))).thenReturn(newOrder(id));
controller.getBasket().add(standardWebMenuItem());
mockMvc.perform(
post("/checkout").param("name", CUSTOMER_NAME)
.param("address1", ADDRESS1)
.param("postcode", POST_CODE));
assertThat(controller.getBasket().getItems(), is(empty()));
}
@Test
public void thatReturnsToCheckoutIfValidationFail() throws Exception {
UUID id = UUID.randomUUID();
when(orderService.createOrder(any(CreateOrderEvent.class))).thenReturn(
newOrder(id));
mockMvc.perform(post("/checkout").param("postcode", POST_CODE))
.andExpect(forwardedUrl(CHECKOUT_VIEW));
}
}