package net.petrikainulainen.springdata.jpa.todo; import com.nitorcreations.junit.runners.NestedRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; import static info.solidsoft.mockito.java8.AssertionMatcher.assertArg; import static net.petrikainulainen.springdata.jpa.todo.TodoAssert.assertThatTodoEntry; import static net.petrikainulainen.springdata.jpa.todo.TodoDTOAssert.assertThatTodoDTO; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; import static org.mockito.BDDMockito.given; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; /** * @author Petri Kainulainen */ @RunWith(NestedRunner.class) public class RepositoryTodoServiceTest { private static final String CREATED_BY_USER = "createdByUser"; private static final String CREATION_TIME = "2014-12-24T22:28:39+02:00"; private static final String DESCRIPTION = "description"; private static final Long ID = 20L; private static final String MODIFIED_BY_USER = "modifiedByUser"; private static final String MODIFICATION_TIME = "2014-12-24T22:29:05+02:00"; private static final String TITLE = "title"; private static final String UPDATED_DESCRIPTION = "updatedDescription"; private static final String UPDATED_TITLE = "updatedTitle"; private TodoRepository repository; private RepositoryTodoService service; @Before public void setUp() { repository = mock(TodoRepository.class); service = new RepositoryTodoService(repository); } public class Create { @Before public void returnNewTodoEntry() { given(repository.save(isA(Todo.class))).willAnswer( invocationOnMock -> new TodoBuilder() .createdByUser(CREATED_BY_USER) .creationTime(CREATION_TIME) .description(DESCRIPTION) .id(ID) .modifiedByUser(MODIFIED_BY_USER) .modificationTime(MODIFICATION_TIME) .title(TITLE) .build() ); } @Test public void shouldPersistNewTodoEntryWithCorrectInformation() { TodoDTO newTodoEntry = new TodoDTOBuilder() .description(DESCRIPTION) .title(TITLE) .build(); service.create(newTodoEntry); verify(repository, times(1)).save( assertArg(persisted -> assertThatTodoEntry(persisted) .hasNoCreationAuditFieldValues() .hasDescription(DESCRIPTION) .hasNoId() .hasNoModificationAuditFieldValues() .hasTitle(TITLE) ) ); verifyNoMoreInteractions(repository); } @Test public void shouldReturnTheInformationOfPersistedTodoEntry() { TodoDTO newTodoEntry = new TodoDTOBuilder() .description(DESCRIPTION) .title(TITLE) .build(); TodoDTO created = service.create(newTodoEntry); assertThatTodoDTO(created) .hasDescription(DESCRIPTION) .hasId(ID) .hasTitle(TITLE) .wasCreatedAt(CREATION_TIME) .wasCreatedByUser(CREATED_BY_USER) .wasModifiedAt(MODIFICATION_TIME) .wasModifiedByUser(MODIFIED_BY_USER); } } public class Delete { public class WhenTodoEntryIsNotFound { @Before public void returnNoTodoEntry() { given(repository.deleteById(ID)).willReturn(Optional.empty()); } @Test public void shouldThrowExceptionWithCorrectId() { Throwable thrown = catchThrowable(() -> service.delete(ID)); assertThat(thrown).isExactlyInstanceOf(TodoNotFoundException.class); TodoNotFoundException ex = (TodoNotFoundException) thrown; assertThat(ex.getId()).isEqualTo(ID); } } public class WhenTodoEntryIsFound { private Todo deleted; @Before public void returnDeletedTodoEntry() { deleted = new TodoBuilder() .createdByUser(CREATED_BY_USER) .creationTime(CREATION_TIME) .description(DESCRIPTION) .id(ID) .modifiedByUser(MODIFIED_BY_USER) .modificationTime(MODIFICATION_TIME) .title(TITLE) .build(); given(repository.deleteById(ID)).willReturn(Optional.of(deleted)); } @Test public void shouldDeleteFoundTodoEntry() { service.delete(ID); verify(repository, times(1)).deleteById(ID); } @Test public void shouldReturnTheInformationOfDeletedTodoEntry() { TodoDTO deleted = service.delete(ID); assertThatTodoDTO(deleted) .hasDescription(DESCRIPTION) .hasId(ID) .hasTitle(TITLE) .wasCreatedAt(CREATION_TIME) .wasCreatedByUser(CREATED_BY_USER) .wasModifiedAt(MODIFICATION_TIME) .wasModifiedByUser(MODIFIED_BY_USER); } } } public class FindAll { public class WhenNoTodoEntryAreFound { @Before public void returnNoTodoEntries() { given(repository.findAll()).willReturn(new ArrayList<>()); } @Test public void shouldReturnEmptyList() { List<TodoDTO> todoEntries = service.findAll(); assertThat(todoEntries).isEmpty(); } } public class WhenOneTodoEntryIsFound { @Before public void returnOneTodoEntry() { Todo found = new TodoBuilder() .id(ID) .createdByUser(CREATED_BY_USER) .creationTime(CREATION_TIME) .description(DESCRIPTION) .modifiedByUser(MODIFIED_BY_USER) .modificationTime(MODIFICATION_TIME) .title(TITLE) .build(); given(repository.findAll()).willReturn(Arrays.asList(found)); } @Test public void shouldReturnOneTodoEntry() { List<TodoDTO> todoEntries = service.findAll(); assertThat(todoEntries).hasSize(1); } @Test public void shouldReturnInformationOfFoundTodoEntry() { TodoDTO todoEntry = service.findAll().get(0); assertThatTodoDTO(todoEntry) .hasId(ID) .hasTitle(TITLE) .hasDescription(DESCRIPTION) .wasCreatedAt(CREATION_TIME) .wasCreatedByUser(CREATED_BY_USER) .wasModifiedAt(MODIFICATION_TIME) .wasModifiedByUser(MODIFIED_BY_USER); } } } public class FindOne { public class WhenTodoEntryIsNotFound { @Before public void returnNoTodoEntry() { given(repository.findOne(ID)).willReturn(Optional.empty()); } @Test public void shouldThrowExceptionWithCorrectId() { Throwable thrown = catchThrowable(() -> service.findById(ID)); assertThat(thrown).isExactlyInstanceOf(TodoNotFoundException.class); TodoNotFoundException exception = (TodoNotFoundException) thrown; assertThat(exception.getId()).isEqualTo(ID); } } public class WhenTodoEntryIsFound { @Before public void returnFoundTodoEntry() { Todo found = new TodoBuilder() .id(ID) .createdByUser(CREATED_BY_USER) .creationTime(CREATION_TIME) .description(DESCRIPTION) .modifiedByUser(MODIFIED_BY_USER) .modificationTime(MODIFICATION_TIME) .title(TITLE) .build(); given(repository.findOne(ID)).willReturn(Optional.of(found)); } @Test public void shouldReturnInformationOfFoundTodoEntry() { TodoDTO returned = service.findById(ID); assertThatTodoDTO(returned) .hasDescription(DESCRIPTION) .hasId(ID) .hasTitle(TITLE) .wasCreatedAt(CREATION_TIME) .wasCreatedByUser(CREATED_BY_USER) .wasModifiedAt(MODIFICATION_TIME) .wasModifiedByUser(MODIFIED_BY_USER); } } } public class Update { public class WhenTodoEntryIsNotFound { @Before public void returnNoTodoEntry() { given(repository.findOne(ID)).willReturn(Optional.empty()); } @Test public void shouldThrowExceptionWithCorrectId() { TodoDTO updatedTodoEntry = new TodoDTOBuilder() .id(ID) .build(); Throwable thrown = catchThrowable(() -> service.update(updatedTodoEntry)); assertThat(thrown).isExactlyInstanceOf(TodoNotFoundException.class); TodoNotFoundException exception = (TodoNotFoundException) thrown; assertThat(exception.getId()).isEqualTo(ID); } } public class WhenTodoEntryIsFound { private Todo updated; @Before public void returnUpdatedTodoEntry() { updated = new TodoBuilder() .createdByUser(CREATED_BY_USER) .creationTime(CREATION_TIME) .description(DESCRIPTION) .id(ID) .modifiedByUser(MODIFIED_BY_USER) .modificationTime(MODIFICATION_TIME) .title(TITLE) .build(); given(repository.findOne(ID)).willReturn(Optional.of(updated)); } @Test public void shouldUpdateTitleAndDescription() { TodoDTO updatedTodoEntry = new TodoDTOBuilder() .id(ID) .description(UPDATED_DESCRIPTION) .title(UPDATED_TITLE) .build(); service.update(updatedTodoEntry); assertThatTodoEntry(updated) .hasDescription(UPDATED_DESCRIPTION) .hasTitle(UPDATED_TITLE); } @Test public void shouldNotUpdateIdOrAuditInformation() { TodoDTO updatedTodoEntry = new TodoDTOBuilder() .id(ID) .description(UPDATED_DESCRIPTION) .title(UPDATED_TITLE) .build(); service.update(updatedTodoEntry); assertThatTodoEntry(updated) .hasId(ID) .wasCreatedAt(CREATION_TIME) .wasCreatedByUser(CREATED_BY_USER) .wasModifiedAt(MODIFICATION_TIME) .wasModifiedByUser(MODIFIED_BY_USER); } @Test public void shouldReturnInformationOfUpdatedTodoEntry() { TodoDTO updatedTodoEntry = new TodoDTOBuilder() .id(ID) .description(UPDATED_DESCRIPTION) .title(UPDATED_TITLE) .build(); TodoDTO returnedTodoEntry = service.update(updatedTodoEntry); assertThatTodoDTO(returnedTodoEntry) .hasDescription(UPDATED_DESCRIPTION) .hasId(ID) .hasTitle(UPDATED_TITLE) .wasCreatedAt(CREATION_TIME) .wasCreatedByUser(CREATED_BY_USER) .wasModifiedAt(MODIFICATION_TIME) .wasModifiedByUser(MODIFIED_BY_USER); } } } }