package com.syzton.sunread.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 com.syzton.sunread.todo.dto.TodoDTO; import com.syzton.sunread.config.ApplicationContext; import com.syzton.sunread.TestUtil; import com.syzton.sunread.todo.dto.TodoDTOBuilder; import com.syzton.sunread.todo.model.Todo; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; 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 static org.hamcrest.Matchers.*; 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.jsonPath; 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 = {ApplicationContext.class}) //@ContextConfiguration(locations = {"classpath:exampleApplicationContext.xml"}) @WebAppConfiguration @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, DbUnitTestExecutionListener.class }) @DatabaseSetup("toDoData.xml") @Ignore public class ITTodoControllerTest { @Resource private WebApplicationContext webApplicationContext; private MockMvc mockMvc; @Before public void setUp() { mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); } @Test @ExpectedDatabase("toDoData.xml") public void add_EmptyTodoEntry_ShouldReturnValidationErrorForTitle() throws Exception { TodoDTO added = new TodoDTO(); mockMvc.perform(post("/api/todo") .contentType(TestUtil.APPLICATION_JSON_UTF8) .content(TestUtil.convertObjectToJsonBytes(added)) ) .andExpect(status().isBadRequest()) .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8)) .andExpect(jsonPath("$.fieldErrors", hasSize(1))) .andExpect(jsonPath("$.fieldErrors[0].path", is("title"))) .andExpect(jsonPath("$.fieldErrors[0].message", is("The title cannot be empty."))); } @Test @ExpectedDatabase("toDoData.xml") public void add_TitleAndDescriptionAreTooLong_ShouldReturnValidationErrorsForTitleAndDescription() throws Exception { String title = TestUtil.createStringWithLength(Todo.MAX_LENGTH_TITLE + 1); String description = TestUtil.createStringWithLength(Todo.MAX_LENGTH_DESCRIPTION + 1); TodoDTO added = new TodoDTOBuilder() .description(description) .title(title) .build(); mockMvc.perform(post("/api/todo") .contentType(TestUtil.APPLICATION_JSON_UTF8) .content(TestUtil.convertObjectToJsonBytes(added)) ) .andExpect(status().isBadRequest()) .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8)) .andExpect(jsonPath("$.fieldErrors", hasSize(2))) .andExpect(jsonPath("$.fieldErrors[*].path", containsInAnyOrder("title", "description"))) .andExpect(jsonPath("$.fieldErrors[*].message", containsInAnyOrder( "The maximum length of the description is 500 characters.", "The maximum length of the title is 100 characters." ))); } @Test @ExpectedDatabase(value="toDoData-add-expected.xml", assertionMode = DatabaseAssertionMode.NON_STRICT) public void add_NewTodoEntry_ShouldAddTodoEntryAndReturnAddedEntry() throws Exception { TodoDTO added = new TodoDTOBuilder() .description("description") .title("title") .build(); mockMvc.perform(post("/api/todo") .contentType(TestUtil.APPLICATION_JSON_UTF8) .content(TestUtil.convertObjectToJsonBytes(added)) ) .andExpect(status().isOk()) .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8)) .andExpect(jsonPath("$.id", is(3))) .andExpect(jsonPath("$.description", is("description"))) .andExpect(jsonPath("$.title", is("title"))); } @Test @ExpectedDatabase("toDoData-delete-expected.xml") public void deleteById_TodoEntryFound_ShouldDeleteTodoEntryAndReturnIt() throws Exception { mockMvc.perform(delete("/api/todo/{id}", 1L)) .andExpect(status().isOk()) .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8)) .andExpect(jsonPath("$.id", is(1))) .andExpect(jsonPath("$.description", is("Lorem ipsum"))) .andExpect(jsonPath("$.title", is("Foo"))); } @Test @ExpectedDatabase("toDoData.xml") public void deleteById_TodoIsNotFound_ShouldReturnHttpStatusCode404() throws Exception { mockMvc.perform(delete("/api/todo/{id}", 3L)) .andExpect(status().isNotFound()); } @Test @ExpectedDatabase("toDoData.xml") public void findAll_TodosFound_ShouldReturnFoundTodoEntries() throws Exception { mockMvc.perform(get("/api/todo")) .andExpect(status().isOk()) .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8)) .andExpect(jsonPath("$", hasSize(2))) .andExpect(jsonPath("$[0].id", is(1))) .andExpect(jsonPath("$[0].description", is("Lorem ipsum"))) .andExpect(jsonPath("$[0].title", is("Foo"))) .andExpect(jsonPath("$[1].id", is(2))) .andExpect(jsonPath("$[1].description", is("Lorem ipsum"))) .andExpect(jsonPath("$[1].title", is("Bar"))); } @Test @ExpectedDatabase("toDoData.xml") public void findById_TodoEntryFound_ShouldReturnFoundTodoEntry() throws Exception { mockMvc.perform(get("/api/todo/{id}", 1L)) .andExpect(status().isOk()) .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8)) .andExpect(jsonPath("$.id", is(1))) .andExpect(jsonPath("$.description", is("Lorem ipsum"))) .andExpect(jsonPath("$.title", is("Foo"))); } @Test @ExpectedDatabase("toDoData.xml") public void findById_TodoEntryNotFound_ShouldReturnHttpStatusCode404() throws Exception { mockMvc.perform(get("/api/todo/{id}", 3L)) .andExpect(status().isNotFound()); } @Test @ExpectedDatabase("toDoData.xml") public void update_EmptyTodoEntry_ShouldReturnValidationErrorForTitle() throws Exception { TodoDTO updated = new TodoDTOBuilder() .id(1L) .build(); mockMvc.perform(put("/api/todo/{id}", 1L) .contentType(TestUtil.APPLICATION_JSON_UTF8) .content(TestUtil.convertObjectToJsonBytes(updated)) ) .andExpect(status().isBadRequest()) .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8)) .andExpect(jsonPath("$.fieldErrors", hasSize(1))) .andExpect(jsonPath("$.fieldErrors[0].path", is("title"))) .andExpect(jsonPath("$.fieldErrors[0].message", is("The title cannot be empty."))); } @Test @ExpectedDatabase("toDoData.xml") public void update_TitleAndDescriptionAreTooLong_ShouldReturnValidationErrorsForTitleAndDescription() throws Exception { String title = TestUtil.createStringWithLength(Todo.MAX_LENGTH_TITLE + 1); String description = TestUtil.createStringWithLength(Todo.MAX_LENGTH_DESCRIPTION + 1); TodoDTO updated = new TodoDTOBuilder() .id(1L) .description(description) .title(title) .build(); mockMvc.perform(put("/api/todo/{id}", 1L) .contentType(TestUtil.APPLICATION_JSON_UTF8) .content(TestUtil.convertObjectToJsonBytes(updated)) ) .andExpect(status().isBadRequest()) .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8)) .andExpect(jsonPath("$.fieldErrors", hasSize(2))) .andExpect(jsonPath("$.fieldErrors[*].path", containsInAnyOrder("title", "description"))) .andExpect(jsonPath("$.fieldErrors[*].message", containsInAnyOrder( "The maximum length of the description is 500 characters.", "The maximum length of the title is 100 characters." ))); } @Test @ExpectedDatabase("toDoData.xml") public void update_TodoEntryNotFound_ShouldReturnHttpStatusCode404() throws Exception { TodoDTO updated = new TodoDTOBuilder() .id(3L) .description("description") .title("title") .build(); mockMvc.perform(put("/api/todo/{id}", 3L) .contentType(TestUtil.APPLICATION_JSON_UTF8) .content(TestUtil.convertObjectToJsonBytes(updated)) ) .andExpect(status().isNotFound()); } @Test @ExpectedDatabase(value="toDoData-update-expected.xml", assertionMode = DatabaseAssertionMode.NON_STRICT) public void update_TodoEntryFound_ShouldUpdateTodoEntryAndReturnIt() throws Exception { TodoDTO updated = new TodoDTOBuilder() .id(1L) .description("description") .title("title") .build(); mockMvc.perform(put("/api/todo/{id}", 1L) .contentType(TestUtil.APPLICATION_JSON_UTF8) .content(TestUtil.convertObjectToJsonBytes(updated)) ) .andExpect(status().isOk()) .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8)) .andExpect(jsonPath("$.id", is(1))) .andExpect(jsonPath("$.description", is("description"))) .andExpect(jsonPath("$.title", is("title"))); } }