package net.petrikainulainen.spring.datasolr.todo.controller;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.ExpectedDatabase;
import com.github.springtestdbunit.assertion.DatabaseAssertionMode;
import net.petrikainulainen.spring.datasolr.config.ExampleApplicationContext;
import net.petrikainulainen.spring.datasolr.config.TestSolrContext;
import net.petrikainulainen.spring.datasolr.todo.TodoTestUtil;
import net.petrikainulainen.spring.datasolr.todo.dto.TodoDTO;
import net.petrikainulainen.spring.datasolr.todo.model.Todo;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import javax.annotation.Resource;
import javax.sql.DataSource;
import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.server.samples.context.SecurityRequestPostProcessors.userDetailsService;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
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.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* This test uses the annotation based application context configuration.
* @author Petri Kainulainen
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ExampleApplicationContext.class, TestSolrContext.class})
//@ContextConfiguration(locations = {"classpath:exampleApplicationContext.xml", "classpath:exampleApplicationContext-test.xml"})
@WebAppConfiguration
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class })
@DatabaseSetup("toDoData.xml")
public class ITTodoControllerTest {
@Resource
private FilterChainProxy springSecurityFilterChain;
@Resource
private WebApplicationContext webApplicationContext;
@Resource
private DataSource datasource;
private MockMvc mockMvc;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.addFilter(springSecurityFilterChain)
.build();
}
@Test
@ExpectedDatabase("toDoData.xml")
public void addAsAnonymous_AllFieldsOk_ShouldReturnStatusUnauthorized() throws Exception {
TodoDTO added = TodoTestUtil.createDTO(null, "description", "title");
mockMvc.perform(post("/api/todo")
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(added))
)
.andExpect(status().isUnauthorized());
}
@Test
@ExpectedDatabase(value="toDoData-add-expected.xml", assertionMode = DatabaseAssertionMode.NON_STRICT)
public void addAsUser_AllFieldsOk_ShouldReturnAddedTodo() throws Exception {
TodoDTO added = TodoTestUtil.createDTO(null, "description", "title");
mockMvc.perform(post("/api/todo")
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(added))
.with(userDetailsService(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.CORRECT_USERNAME))
)
.andExpect(status().isOk())
.andExpect(content().contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8))
.andExpect(content().string("{\"id\":3,\"description\":\"description\",\"title\":\"title\"}"));
}
@Test
@ExpectedDatabase("toDoData.xml")
public void addAsAnonymous_EmptyTodo_ShouldReturnStatusBadRequest() throws Exception {
TodoDTO added = TodoTestUtil.createDTO(null, "", "");
mockMvc.perform(post("/api/todo")
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(added))
)
.andExpect(status().isBadRequest());
}
@Test
@ExpectedDatabase("toDoData.xml")
public void addAsUser_EmptyTodo_ShouldReturnFormValidationErrors() throws Exception {
TodoDTO added = TodoTestUtil.createDTO(null, "", "");
mockMvc.perform(post("/api/todo")
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(added))
.with(userDetailsService(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.CORRECT_USERNAME))
)
.andExpect(status().isBadRequest())
.andExpect(content().contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8))
.andExpect(content().string("{\"fieldErrors\":[{\"path\":\"title\",\"message\":\"The title cannot be empty.\"}]}"));
}
@Test
@ExpectedDatabase("toDoData.xml")
public void addAsAnonymous_TitleAndDescriptionAreTooLong_ShouldReturnStatusBadRequest() throws Exception {
String title = TodoTestUtil.createStringWithLength(Todo.MAX_LENGTH_TITLE + 1);
String description = TodoTestUtil.createStringWithLength(Todo.MAX_LENGTH_DESCRIPTION + 1);
TodoDTO added = TodoTestUtil.createDTO(null, description, title);
mockMvc.perform(post("/api/todo")
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(added))
)
.andExpect(status().isBadRequest());
}
@Test
@ExpectedDatabase("toDoData.xml")
public void addAsUser_TitleAndDescriptionAreTooLong_ShouldReturnFormValidationErrors() throws Exception {
String title = TodoTestUtil.createStringWithLength(Todo.MAX_LENGTH_TITLE + 1);
String description = TodoTestUtil.createStringWithLength(Todo.MAX_LENGTH_DESCRIPTION + 1);
TodoDTO added = TodoTestUtil.createDTO(null, description, title);
mockMvc.perform(post("/api/todo")
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(added))
.with(userDetailsService(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.CORRECT_USERNAME))
)
.andExpect(status().isBadRequest())
.andExpect(content().contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8))
.andExpect(content().string(startsWith("{\"fieldErrors\":[")))
.andExpect(content().string(allOf(
containsString("{\"path\":\"description\",\"message\":\"The maximum length of the description is 500 characters.\"}"),
containsString("{\"path\":\"title\",\"message\":\"The maximum length of the title is 100 characters.\"}")
)))
.andExpect(content().string(endsWith("]}")));
}
@Test
@ExpectedDatabase("toDoData.xml")
public void deleteByIdAsAnonymous_TodoFound_ShouldReturnStatusUnauthorized() throws Exception {
mockMvc.perform(delete("/api/todo/{id}", 1L))
.andExpect(status().isUnauthorized());
}
@Test
@ExpectedDatabase("toDoData-delete-expected.xml")
public void deleteByIdAsUser_TodoFound_ShouldReturnDeletedUser() throws Exception {
mockMvc.perform(delete("/api/todo/{id}", 1L)
.with(userDetailsService(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.CORRECT_USERNAME))
)
.andExpect(status().isOk())
.andExpect(content().contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8))
.andExpect(content().string("{\"id\":1,\"description\":\"Lorem ipsum\",\"title\":\"Foo\"}"));
}
@Test
@ExpectedDatabase("toDoData.xml")
public void deleteByIdAsAnonymous_TodoIsNotFound_ShouldReturnStatusUnauthorized() throws Exception {
mockMvc.perform(delete("/api/todo/{id}", 3L))
.andExpect(status().isUnauthorized());
}
@Test
@ExpectedDatabase("toDoData.xml")
public void deleteByIdAsUser_TodoIsNotFound_ShouldReturnStatusNotFound() throws Exception {
mockMvc.perform(delete("/api/todo/{id}", 3L)
.with(userDetailsService(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.CORRECT_USERNAME))
)
.andExpect(status().isNotFound());
}
@Test
@ExpectedDatabase("toDoData.xml")
public void findAllAsAnonymous_ShouldReturnStatusUnauthorized() throws Exception {
mockMvc.perform(get("/api/todo"))
.andExpect(status().isUnauthorized());
}
@Test
@ExpectedDatabase("toDoData.xml")
public void findAllAsUser_ShouldReturnTodoList() throws Exception {
mockMvc.perform(get("/api/todo")
.with(userDetailsService(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.CORRECT_USERNAME))
)
.andExpect(status().isOk())
.andExpect(content().contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8))
.andExpect(content().string("[{\"id\":1,\"description\":\"Lorem ipsum\",\"title\":\"Foo\"},{\"id\":2,\"description\":\"Lorem ipsum\",\"title\":\"Bar\"}]"));
}
@Test
@ExpectedDatabase("toDoData.xml")
public void findByIdAsAnonymous_TodoFound_ShouldReturnStatusUnauthorized() throws Exception {
mockMvc.perform(get("/api/todo/{id}", 1L))
.andExpect(status().isUnauthorized());
}
@Test
@ExpectedDatabase("toDoData.xml")
public void findByIdAsUser_TodoFound_ShouldReturnTodo() throws Exception {
mockMvc.perform(get("/api/todo/{id}", 1L)
.with(userDetailsService(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.CORRECT_USERNAME))
)
.andExpect(status().isOk())
.andExpect(content().contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8))
.andExpect(content().string("{\"id\":1,\"description\":\"Lorem ipsum\",\"title\":\"Foo\"}"));
}
@Test
@ExpectedDatabase("toDoData.xml")
public void findByIdAsAnonymous_TodoIsNotFound_ShouldReturnStatusUnauthorized() throws Exception {
mockMvc.perform(get("/api/todo/{id}", 3L))
.andExpect(status().isUnauthorized());
}
@Test
@ExpectedDatabase("toDoData.xml")
public void findByIdAsUser_TodoIsNotFound_ShouldReturnStatusNotFound() throws Exception {
mockMvc.perform(get("/api/todo/{id}", 3L)
.with(userDetailsService(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.CORRECT_USERNAME))
)
.andExpect(status().isNotFound());
}
@Test
@ExpectedDatabase(value="toDoData.xml")
public void updateAsAnonymous_TodoFound_ShouldReturnStatusUnauthorized() throws Exception {
TodoDTO updated = TodoTestUtil.createDTO(1L, "description", "title");
mockMvc.perform(put("/api/todo/{id}", 1L)
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(updated))
)
.andExpect(status().isUnauthorized());
}
@Test
@ExpectedDatabase(value="toDoData-update-expected.xml", assertionMode = DatabaseAssertionMode.NON_STRICT)
public void updateAsUser_TodoFound_ShouldReturnUpdatedTodo() throws Exception {
TodoDTO updated = TodoTestUtil.createDTO(1L, "description", "title");
mockMvc.perform(put("/api/todo/{id}", 1L)
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(updated))
.with(userDetailsService(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.CORRECT_USERNAME))
)
.andExpect(status().isOk())
.andExpect(content().contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8))
.andExpect(content().string("{\"id\":1,\"description\":\"description\",\"title\":\"title\"}"));
}
@Test
@ExpectedDatabase("toDoData.xml")
public void updateAsAnonymous_TodoEmpty_ShouldReturnStatusBadRequest() throws Exception {
TodoDTO updated = TodoTestUtil.createDTO(1L, "", "");
mockMvc.perform(put("/api/todo/{id}", 1L)
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(updated))
)
.andExpect(status().isBadRequest());
}
@Test
@ExpectedDatabase("toDoData.xml")
public void updateUser_EmptyTodo_ShouldReturnFormValidationErrors() throws Exception {
TodoDTO updated = TodoTestUtil.createDTO(1L, "", "");
mockMvc.perform(put("/api/todo/{id}", 1L)
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(updated))
.with(userDetailsService(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.CORRECT_USERNAME))
)
.andExpect(status().isBadRequest())
.andExpect(content().contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8))
.andExpect(content().string("{\"fieldErrors\":[{\"path\":\"title\",\"message\":\"The title cannot be empty.\"}]}"));
}
@Test
@ExpectedDatabase("toDoData.xml")
public void updateAsAnonymous_TitleAndDescriptionAreTooLong_ShouldReturnStatusBadRequest() throws Exception {
String title = TodoTestUtil.createStringWithLength(Todo.MAX_LENGTH_TITLE + 1);
String description = TodoTestUtil.createStringWithLength(Todo.MAX_LENGTH_DESCRIPTION + 1);
TodoDTO updated = TodoTestUtil.createDTO(1L, description, title);
mockMvc.perform(put("/api/todo/{id}", 1L)
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(updated))
)
.andExpect(status().isBadRequest());
}
@Test
@ExpectedDatabase("toDoData.xml")
public void updateAsUser_TitleAndDescriptionAreTooLong_ShouldReturnFormValidationErrors() throws Exception {
String title = TodoTestUtil.createStringWithLength(Todo.MAX_LENGTH_TITLE + 1);
String description = TodoTestUtil.createStringWithLength(Todo.MAX_LENGTH_DESCRIPTION + 1);
TodoDTO updated = TodoTestUtil.createDTO(1L, description, title);
mockMvc.perform(put("/api/todo/{id}", 1L)
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(updated))
.with(userDetailsService(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.CORRECT_USERNAME))
)
.andExpect(status().isBadRequest())
.andExpect(content().contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8))
.andExpect(content().string(startsWith("{\"fieldErrors\":[")))
.andExpect(content().string(allOf(
containsString("{\"path\":\"description\",\"message\":\"The maximum length of the description is 500 characters.\"}"),
containsString("{\"path\":\"title\",\"message\":\"The maximum length of the title is 100 characters.\"}")
)))
.andExpect(content().string(endsWith("]}")));
}
@Test
@ExpectedDatabase("toDoData.xml")
public void updateAsAnonymous_TodoIsNotFound_ShouldReturnStatusUnauthorized() throws Exception {
TodoDTO updated = TodoTestUtil.createDTO(3L, "description", "title");
mockMvc.perform(put("/api/todo/{id}", 3L)
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(updated))
)
.andExpect(status().isUnauthorized());
}
@Test
@ExpectedDatabase("toDoData.xml")
public void updateAsUser_TodoIsNotFound_ShouldReturnStatusNotFound() throws Exception {
TodoDTO updated = TodoTestUtil.createDTO(3L, "description", "title");
mockMvc.perform(put("/api/todo/{id}", 3L)
.contentType(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.APPLICATION_JSON_UTF8)
.content(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.convertObjectToJsonBytes(updated))
.with(userDetailsService(net.petrikainulainen.spring.datasolr.IntegrationTestUtil.CORRECT_USERNAME))
)
.andExpect(status().isNotFound());
}
}