package net.petrikainulainen.spring.datajpa.controller;
import net.petrikainulainen.spring.datajpa.dto.PersonDTO;
import net.petrikainulainen.spring.datajpa.dto.SearchDTO;
import net.petrikainulainen.spring.datajpa.model.Person;
import net.petrikainulainen.spring.datajpa.model.PersonTestUtil;
import net.petrikainulainen.spring.datajpa.service.PersonNotFoundException;
import net.petrikainulainen.spring.datajpa.service.PersonService;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.support.BindingAwareModelMap;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.mvc.support.RedirectAttributesModelMap;
import java.util.*;
import static junit.framework.Assert.*;
import static org.mockito.Mockito.*;
/**
* @author Petri Kainulainen
*/
public class PersonControllerTest extends AbstractTestController {
private static final String FIELD_NAME_FIRST_NAME = "firstName";
private static final String FIELD_NAME_LAST_NAME = "lastName";
private static final int PAGE_INDEX = 1;
private static final long PERSON_COUNT = 4;
private static final Long PERSON_ID = Long.valueOf(5);
private static final String FIRST_NAME = "Foo";
private static final String FIRST_NAME_UPDATED = "FooUpdated";
private static final String LAST_NAME = "Bar";
private static final String LAST_NAME_UPDATED = "BarUpdated";
private static final String SEARCH_TERM = "foo";
private PersonController controller;
private PersonService personServiceMock;
@Override
public void setUpTest() {
controller = new PersonController();
controller.setMessageSource(getMessageSourceMock());
personServiceMock = mock(PersonService.class);
controller.setPersonService(personServiceMock);
}
@Test
public void count() {
SearchDTO searchCriteria = createSearchDTO();
when(personServiceMock.count(searchCriteria.getSearchTerm())).thenReturn(PERSON_COUNT);
long personCount = controller.count(searchCriteria);
verify(personServiceMock, times(1)).count(searchCriteria.getSearchTerm());
verifyNoMoreInteractions(personServiceMock);
assertEquals(PERSON_COUNT, personCount);
}
@Test
public void delete() throws PersonNotFoundException {
Person deleted = PersonTestUtil.createModelObject(PERSON_ID, FIRST_NAME, LAST_NAME);
when(personServiceMock.delete(PERSON_ID)).thenReturn(deleted);
initMessageSourceForFeedbackMessage(PersonController.FEEDBACK_MESSAGE_KEY_PERSON_DELETED);
RedirectAttributes attributes = new RedirectAttributesModelMap();
String view = controller.delete(PERSON_ID, attributes);
verify(personServiceMock, times(1)).delete(PERSON_ID);
verifyNoMoreInteractions(personServiceMock);
assertFeedbackMessage(attributes, PersonController.FEEDBACK_MESSAGE_KEY_PERSON_DELETED);
String expectedView = createExpectedRedirectViewPath(PersonController.REQUEST_MAPPING_LIST);
assertEquals(expectedView, view);
}
@Test
public void deleteWhenPersonIsNotFound() throws PersonNotFoundException {
when(personServiceMock.delete(PERSON_ID)).thenThrow(new PersonNotFoundException());
initMessageSourceForErrorMessage(PersonController.ERROR_MESSAGE_KEY_DELETED_PERSON_WAS_NOT_FOUND);
RedirectAttributes attributes = new RedirectAttributesModelMap();
String view = controller.delete(PERSON_ID, attributes);
verify(personServiceMock, times(1)).delete(PERSON_ID);
verifyNoMoreInteractions(personServiceMock);
assertErrorMessage(attributes, PersonController.ERROR_MESSAGE_KEY_DELETED_PERSON_WAS_NOT_FOUND);
String expectedView = createExpectedRedirectViewPath(PersonController.REQUEST_MAPPING_LIST);
assertEquals(expectedView, view);
}
@Test
public void searchWhenNoPersonsIsFound() {
SearchDTO searchCriteria = createSearchDTO();
List<Person> expected = new ArrayList<Person>();
when(personServiceMock.search(searchCriteria.getSearchTerm(), searchCriteria.getPageIndex())).thenReturn(expected);
List<PersonDTO> actual = controller.search(searchCriteria);
verify(personServiceMock, times(1)).search(searchCriteria.getSearchTerm(), searchCriteria.getPageIndex());
verifyNoMoreInteractions(personServiceMock);
assertDtos(expected, actual);
}
@Test
public void search() {
SearchDTO searchCriteria = createSearchDTO();
List<Person> expected = createModels();
when(personServiceMock.search(searchCriteria.getSearchTerm(), searchCriteria.getPageIndex())).thenReturn(expected);
List<PersonDTO> actual = controller.search(searchCriteria);
verify(personServiceMock, times(1)).search(searchCriteria.getSearchTerm(), searchCriteria.getPageIndex());
verifyNoMoreInteractions(personServiceMock);
assertDtos(expected, actual);
}
private List<Person> createModels() {
List<Person> persons = new ArrayList<Person>();
for (int index = 0; index < PERSON_COUNT; index++) {
Person person = Person.getBuilder(FIRST_NAME, LAST_NAME).build();
person.setId(PERSON_ID);
persons.add(person);
}
return persons;
}
private void assertDtos(List<Person> expected, List<PersonDTO> actual) {
assertEquals(expected.size(), actual.size());
for (int index = 0; index < expected.size(); index++) {
Person model = expected.get(index);
PersonDTO dto = actual.get(index);
assertEquals(model.getId(), dto.getId());
assertEquals(model.getFirstName(), dto.getFirstName());
assertEquals(model.getLastName(), dto.getLastName());
}
}
private SearchDTO createSearchDTO() {
SearchDTO dto = new SearchDTO();
dto.setPageIndex(PAGE_INDEX);
dto.setSearchTerm(SEARCH_TERM);
return dto;
}
@Test
public void showCreatePersonForm() {
Model model = new BindingAwareModelMap();
String view = controller.showCreatePersonForm(model);
verifyZeroInteractions(personServiceMock);
assertEquals(PersonController.PERSON_ADD_FORM_VIEW, view);
PersonDTO added = (PersonDTO) model.asMap().get(PersonController.MODEL_ATTIRUTE_PERSON);
assertNotNull(added);
assertNull(added.getId());
assertNull(added.getFirstName());
assertNull(added.getLastName());
}
@Test
public void submitCreatePersonForm() {
MockHttpServletRequest mockRequest = new MockHttpServletRequest("/person/create", "POST");
PersonDTO created = PersonTestUtil.createDTO(PERSON_ID, FIRST_NAME, LAST_NAME);
Person model = PersonTestUtil.createModelObject(PERSON_ID, FIRST_NAME, LAST_NAME);
when(personServiceMock.create(created)).thenReturn(model);
initMessageSourceForFeedbackMessage(PersonController.FEEDBACK_MESSAGE_KEY_PERSON_CREATED);
RedirectAttributes attributes = new RedirectAttributesModelMap();
BindingResult result = bindAndValidate(mockRequest, created);
String view = controller.submitCreatePersonForm(created, result, attributes);
verify(personServiceMock, times(1)).create(created);
verifyNoMoreInteractions(personServiceMock);
String expectedViewPath = createExpectedRedirectViewPath(PersonController.REQUEST_MAPPING_LIST);
assertEquals(expectedViewPath, view);
assertFeedbackMessage(attributes, PersonController.FEEDBACK_MESSAGE_KEY_PERSON_CREATED);
verify(personServiceMock, times(1)).create(created);
verifyNoMoreInteractions(personServiceMock);
}
@Test
public void submitEmptyCreatePersonForm() {
MockHttpServletRequest mockRequest = new MockHttpServletRequest("/person/create", "POST");
PersonDTO created = new PersonDTO();
RedirectAttributes attributes = new RedirectAttributesModelMap();
BindingResult result = bindAndValidate(mockRequest, created);
String view = controller.submitCreatePersonForm(created, result, attributes);
verifyZeroInteractions(personServiceMock);
assertEquals(PersonController.PERSON_ADD_FORM_VIEW, view);
assertFieldErrors(result, FIELD_NAME_FIRST_NAME, FIELD_NAME_LAST_NAME);
}
@Test
public void submitCreatePersonFormWithEmptyFirstName() {
MockHttpServletRequest mockRequest = new MockHttpServletRequest("/person/create", "POST");
PersonDTO created = PersonTestUtil.createDTO(null, null, LAST_NAME);
RedirectAttributes attributes = new RedirectAttributesModelMap();
BindingResult result = bindAndValidate(mockRequest, created);
String view = controller.submitCreatePersonForm(created, result, attributes);
verifyZeroInteractions(personServiceMock);
assertEquals(PersonController.PERSON_ADD_FORM_VIEW, view);
assertFieldErrors(result, FIELD_NAME_FIRST_NAME);
}
@Test
public void submitCreatePersonFormWithEmptyLastName() {
MockHttpServletRequest mockRequest = new MockHttpServletRequest("/person/create", "POST");
PersonDTO created = PersonTestUtil.createDTO(null, FIRST_NAME, null);
RedirectAttributes attributes = new RedirectAttributesModelMap();
BindingResult result = bindAndValidate(mockRequest, created);
String view = controller.submitCreatePersonForm(created, result, attributes);
verifyZeroInteractions(personServiceMock);
assertEquals(PersonController.PERSON_ADD_FORM_VIEW, view);
assertFieldErrors(result, FIELD_NAME_LAST_NAME);
}
@Test
public void showEditPersonForm() {
Person person = PersonTestUtil.createModelObject(PERSON_ID, FIRST_NAME, LAST_NAME);
when(personServiceMock.findById(PERSON_ID)).thenReturn(person);
Model model = new BindingAwareModelMap();
RedirectAttributes attributes = new RedirectAttributesModelMap();
String view = controller.showEditPersonForm(PERSON_ID, model, attributes);
verify(personServiceMock, times(1)).findById(PERSON_ID);
verifyNoMoreInteractions(personServiceMock);
assertEquals(PersonController.PERSON_EDIT_FORM_VIEW, view);
PersonDTO formObject = (PersonDTO) model.asMap().get(PersonController.MODEL_ATTIRUTE_PERSON);
assertNotNull(formObject);
assertEquals(person.getId(), formObject.getId());
assertEquals(person.getFirstName(), formObject.getFirstName());
assertEquals(person.getLastName(), formObject.getLastName());
}
@Test
public void showEditPersonFormWhenPersonIsNotFound() {
when(personServiceMock.findById(PERSON_ID)).thenReturn(null);
initMessageSourceForErrorMessage(PersonController.ERROR_MESSAGE_KEY_EDITED_PERSON_WAS_NOT_FOUND);
Model model = new BindingAwareModelMap();
RedirectAttributes attributes = new RedirectAttributesModelMap();
String view = controller.showEditPersonForm(PERSON_ID, model, attributes);
verify(personServiceMock, times(1)).findById(PERSON_ID);
verifyNoMoreInteractions(personServiceMock);
String expectedView = createExpectedRedirectViewPath(PersonController.REQUEST_MAPPING_LIST);
assertEquals(expectedView, view);
assertErrorMessage(attributes, PersonController.ERROR_MESSAGE_KEY_EDITED_PERSON_WAS_NOT_FOUND);
}
@Test
public void submitEditPersonForm() throws PersonNotFoundException {
MockHttpServletRequest mockRequest = new MockHttpServletRequest("/person/edit", "POST");
PersonDTO updated = PersonTestUtil.createDTO(PERSON_ID, FIRST_NAME_UPDATED, LAST_NAME_UPDATED);
Person person = PersonTestUtil.createModelObject(PERSON_ID, FIRST_NAME_UPDATED, LAST_NAME_UPDATED);
when(personServiceMock.update(updated)).thenReturn(person);
initMessageSourceForFeedbackMessage(PersonController.FEEDBACK_MESSAGE_KEY_PERSON_EDITED);
BindingResult bindingResult = bindAndValidate(mockRequest, updated);
RedirectAttributes attributes = new RedirectAttributesModelMap();
String view = controller.submitEditPersonForm(updated, bindingResult, attributes);
verify(personServiceMock, times(1)).update(updated);
verifyNoMoreInteractions(personServiceMock);
String expectedView = createExpectedRedirectViewPath(PersonController.REQUEST_MAPPING_LIST);
assertEquals(expectedView, view);
assertFeedbackMessage(attributes, PersonController.FEEDBACK_MESSAGE_KEY_PERSON_EDITED);
assertEquals(updated.getFirstName(), person.getFirstName());
assertEquals(updated.getLastName(), person.getLastName());
}
@Test
public void submitEditPersonFormWhenPersonIsNotFound() throws PersonNotFoundException {
MockHttpServletRequest mockRequest = new MockHttpServletRequest("/person/edit", "POST");
PersonDTO updated = PersonTestUtil.createDTO(PERSON_ID, FIRST_NAME_UPDATED, LAST_NAME_UPDATED);
when(personServiceMock.update(updated)).thenThrow(new PersonNotFoundException());
initMessageSourceForErrorMessage(PersonController.ERROR_MESSAGE_KEY_EDITED_PERSON_WAS_NOT_FOUND);
BindingResult bindingResult = bindAndValidate(mockRequest, updated);
RedirectAttributes attributes = new RedirectAttributesModelMap();
String view = controller.submitEditPersonForm(updated, bindingResult, attributes);
verify(personServiceMock, times(1)).update(updated);
verifyNoMoreInteractions(personServiceMock);
String expectedView = createExpectedRedirectViewPath(PersonController.REQUEST_MAPPING_LIST);
assertEquals(expectedView, view);
assertErrorMessage(attributes, PersonController.ERROR_MESSAGE_KEY_EDITED_PERSON_WAS_NOT_FOUND);
}
@Test
public void submitEmptyEditPersonForm() {
MockHttpServletRequest mockRequest = new MockHttpServletRequest("/person/edit", "POST");
PersonDTO updated = PersonTestUtil.createDTO(PERSON_ID, null, null);
BindingResult bindingResult = bindAndValidate(mockRequest, updated);
RedirectAttributes attributes = new RedirectAttributesModelMap();
String view = controller.submitEditPersonForm(updated, bindingResult, attributes);
verifyZeroInteractions(personServiceMock);
assertEquals(PersonController.PERSON_EDIT_FORM_VIEW, view);
assertFieldErrors(bindingResult, FIELD_NAME_FIRST_NAME, FIELD_NAME_LAST_NAME);
}
@Test
public void submitEditPersonFormWhenFirstNameIsEmpty() {
MockHttpServletRequest mockRequest = new MockHttpServletRequest("/person/edit", "POST");
PersonDTO updated = PersonTestUtil.createDTO(PERSON_ID, null, LAST_NAME_UPDATED);
BindingResult bindingResult = bindAndValidate(mockRequest, updated);
RedirectAttributes attributes = new RedirectAttributesModelMap();
String view = controller.submitEditPersonForm(updated, bindingResult, attributes);
verifyZeroInteractions(personServiceMock);
assertEquals(PersonController.PERSON_EDIT_FORM_VIEW, view);
assertFieldErrors(bindingResult, FIELD_NAME_FIRST_NAME);
}
@Test
public void submitEditPersonFormWhenLastNameIsEmpty() {
MockHttpServletRequest mockRequest = new MockHttpServletRequest("/person/edit", "POST");
PersonDTO updated = PersonTestUtil.createDTO(PERSON_ID, FIRST_NAME_UPDATED, null);
BindingResult bindingResult = bindAndValidate(mockRequest, updated);
RedirectAttributes attributes = new RedirectAttributesModelMap();
String view = controller.submitEditPersonForm(updated, bindingResult, attributes);
verifyZeroInteractions(personServiceMock);
assertEquals(PersonController.PERSON_EDIT_FORM_VIEW, view);
assertFieldErrors(bindingResult, FIELD_NAME_LAST_NAME);
}
@Test
public void showList() {
List<Person> persons = new ArrayList<Person>();
when(personServiceMock.findAll()).thenReturn(persons);
Model model = new BindingAwareModelMap();
String view = controller.showList(model);
verify(personServiceMock, times(1)).findAll();
verifyNoMoreInteractions(personServiceMock);
assertEquals(PersonController.PERSON_LIST_VIEW, view);
assertEquals(persons, model.asMap().get(PersonController.MODEL_ATTRIBUTE_PERSONS));
SearchDTO searchCriteria = (SearchDTO) model.asMap().get(PersonController.MODEL_ATTRIBUTE_SEARCH_CRITERIA);
assertNotNull(searchCriteria);
assertNull(searchCriteria.getSearchTerm());
}
@Test
public void showSearchResultPage() {
SearchDTO searchCriteria = createSearchDTO();
Model model = new BindingAwareModelMap();
String view = controller.showSearchResultPage(searchCriteria, model);
SearchDTO modelAttribute = (SearchDTO) model.asMap().get(PersonController.MODEL_ATTRIBUTE_SEARCH_CRITERIA);
assertEquals(searchCriteria.getPageIndex(), modelAttribute.getPageIndex());
assertEquals(searchCriteria.getSearchTerm(), modelAttribute.getSearchTerm());
assertEquals(PersonController.PERSON_SEARCH_RESULT_VIEW, view);
}
}