/** * *************************************************************************** * Copyright (c) 2010 Qcadoo Limited * Project: Qcadoo MES * Version: 1.4 * * This file is part of Qcadoo. * * Qcadoo is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation; either version 3 of the License, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *************************************************************************** */ package com.qcadoo.mes.states; import static com.qcadoo.mes.states.constants.StateChangeStatus.FAILURE; import static org.apache.commons.lang3.ArrayUtils.EMPTY_STRING_ARRAY; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import java.util.List; import java.util.Map; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.qcadoo.mes.states.constants.StateChangeStatus; import com.qcadoo.mes.states.exception.StateChangeException; import com.qcadoo.mes.states.messages.MessageService; import com.qcadoo.model.api.Entity; import com.qcadoo.model.api.validators.ErrorMessage; public class StateChangeContextTest extends StateChangeTest { @Mock private MessageService messageService; @Mock private Entity savedOwner; private StateChangeEntityDescriber describer; private StateChangeContext stateChangeContext; private static final String FIELD_1_NAME = "field_1"; private static final String FIELD_1_MESSAGE_1 = "field_1_message_1"; private static final String GLOBAL_MESSAGE_1 = "global_message_1"; @Before public final void init() { MockitoAnnotations.initMocks(this); describer = new MockStateChangeDescriber(stateChangeDD); stubStateChangeEntity(describer); stubOwner(); stubBelongsToField(stateChangeEntity, describer.getOwnerFieldName(), owner); stateChangeContext = new StateChangeContextImpl(stateChangeEntity, describer, messageService); } @Test public final void shouldSave() { // when stateChangeContext.save(); // then verify(stateChangeDD, atLeastOnce()).save(stateChangeEntity); verify(messageService, never()).addValidationError(Mockito.eq(stateChangeContext), Mockito.anyString(), Mockito.anyString(), Mockito.any(String[].class)); verify(messageService, never()).addValidationError(Mockito.eq(stateChangeContext), Mockito.eq((String) null), Mockito.anyString(), Mockito.any(String[].class)); verify(stateChangeEntity, never()).setField(describer.getStatusFieldName(), FAILURE.getStringValue()); } @Test public final void shouldThrowExceptionIfConstructorGetInvalidStateChangeEntity() { // given given(stateChangeEntity.isValid()).willReturn(false); // when try { new StateChangeContextImpl(stateChangeEntity, describer, messageService); Assert.fail(); } catch (IllegalArgumentException e) { } } @Test public final void shouldMarkExistingDatabaseEntityAsInvalidIfConstructorGetInvalidStateChangeEntity() { // given final Entity existingStateChangeEntity = mock(Entity.class); given(stateChangeEntity.isValid()).willReturn(false); given(stateChangeEntity.getId()).willReturn(1L); given(stateChangeDD.get(Mockito.any(Long.class))).willReturn(existingStateChangeEntity); given(existingStateChangeEntity.isValid()).willReturn(true); final Map<String, ErrorMessage> fieldErrorsMap = Maps.newHashMap(); final ErrorMessage fieldErrorMessage = buildErrorMessage(FIELD_1_MESSAGE_1); fieldErrorsMap.put(FIELD_1_NAME, fieldErrorMessage); given(stateChangeEntity.getErrors()).willReturn(fieldErrorsMap); final List<ErrorMessage> globalErrors = Lists.newArrayList(); final ErrorMessage globalErrorMessage = buildErrorMessage(GLOBAL_MESSAGE_1); globalErrors.add(globalErrorMessage); given(stateChangeEntity.getGlobalErrors()).willReturn(globalErrors); // when new StateChangeContextImpl(stateChangeEntity, describer, messageService); // then verify(messageService).addValidationError(Mockito.any(StateChangeContext.class), Mockito.eq(FIELD_1_NAME), Mockito.eq(FIELD_1_MESSAGE_1)); verify(messageService).addValidationError(Mockito.any(StateChangeContext.class), Mockito.eq((String) null), Mockito.eq(GLOBAL_MESSAGE_1)); verify(existingStateChangeEntity).setField(describer.getStatusFieldName(), FAILURE.getStringValue()); } @Test public final void shouldMarkEntityAsInvalidAndSetStateToFailureIfStateChangeEntityIsInvalidAfterSave() { // given final Entity savedStateChangeEntity = mock(Entity.class); given(stateChangeEntity.isValid()).willReturn(true); given(savedStateChangeEntity.isValid()).willReturn(true, false); given(stateChangeDD.save(stateChangeEntity)).willReturn(savedStateChangeEntity); final Map<String, ErrorMessage> fieldErrorsMap = Maps.newHashMap(); final ErrorMessage fieldErrorMessage = buildErrorMessage(FIELD_1_MESSAGE_1); fieldErrorsMap.put(FIELD_1_NAME, fieldErrorMessage); given(savedStateChangeEntity.getErrors()).willReturn(fieldErrorsMap); final List<ErrorMessage> globalErrors = Lists.newArrayList(); final ErrorMessage globalErrorMessage = buildErrorMessage(GLOBAL_MESSAGE_1); globalErrors.add(globalErrorMessage); given(savedStateChangeEntity.getGlobalErrors()).willReturn(globalErrors); // when stateChangeContext.save(); // then verify(messageService).addValidationError(stateChangeContext, FIELD_1_NAME, FIELD_1_MESSAGE_1, EMPTY_STRING_ARRAY); verify(messageService).addValidationError(stateChangeContext, null, GLOBAL_MESSAGE_1, EMPTY_STRING_ARRAY); verify(stateChangeEntity).setField(describer.getStatusFieldName(), FAILURE.getStringValue()); } @Test public final void shouldMarkEntityAsFailureAndRethrowExceptionIfOwnerValidatorThrowsException() { // given given(ownerDD.save(owner)).willThrow(new RuntimeException()); try { // when stateChangeContext.setOwner(owner); } catch (StateChangeException e) { // then verify(stateChangeEntity).setField(describer.getStatusFieldName(), FAILURE.getStringValue()); } } @Test public final void shouldSaveAndSetOwnerEntity() { // given given(owner.isValid()).willReturn(true); given(savedOwner.isValid()).willReturn(true); given(ownerDD.save(owner)).willReturn(savedOwner); // when stateChangeContext.setOwner(owner); // then verify(ownerDD).save(owner); verify(stateChangeEntity, never()).setField(describer.getOwnerFieldName(), owner); verify(stateChangeEntity).setField(describer.getOwnerFieldName(), savedOwner); verify(messageService, never()).addValidationError(Mockito.eq(stateChangeContext), Mockito.anyString(), Mockito.anyString(), Mockito.any(String[].class)); verify(messageService, never()).addValidationError(Mockito.eq(stateChangeContext), Mockito.eq((String) null), Mockito.anyString(), Mockito.any(String[].class)); verify(stateChangeEntity, never()).setField(describer.getStatusFieldName(), StateChangeStatus.FAILURE.getStringValue()); } @Test public final void shouldNotSaveAndSetAlreadyInvalidOwnerEntity() { // given given(owner.isValid()).willReturn(false); given(ownerDD.save(owner)).willReturn(owner); final Map<String, ErrorMessage> fieldErrorsMap = Maps.newHashMap(); final ErrorMessage fieldErrorMessage = buildErrorMessage(FIELD_1_MESSAGE_1); fieldErrorsMap.put(FIELD_1_NAME, fieldErrorMessage); given(owner.getErrors()).willReturn(fieldErrorsMap); final List<ErrorMessage> globalErrors = Lists.newArrayList(); final ErrorMessage globalErrorMessage = buildErrorMessage(GLOBAL_MESSAGE_1); globalErrors.add(globalErrorMessage); given(owner.getGlobalErrors()).willReturn(globalErrors); // when stateChangeContext.setOwner(owner); // then verify(ownerDD, never()).save(owner); verify(stateChangeEntity, never()).setField(describer.getOwnerFieldName(), owner); verify(stateChangeEntity, never()).setField(describer.getOwnerFieldName(), savedOwner); verify(messageService).addValidationError(stateChangeContext, FIELD_1_NAME, FIELD_1_MESSAGE_1, EMPTY_STRING_ARRAY); verify(messageService).addValidationError(stateChangeContext, null, GLOBAL_MESSAGE_1, EMPTY_STRING_ARRAY); verify(stateChangeEntity).setField(describer.getStatusFieldName(), StateChangeStatus.FAILURE.getStringValue()); } @Test public final void shouldAddMessagesOnlyOnce() { // given given(owner.isValid()).willReturn(false); given(ownerDD.save(owner)).willReturn(owner); final Map<String, ErrorMessage> fieldErrorsMap = Maps.newHashMap(); final ErrorMessage fieldErrorMessage = buildErrorMessage(FIELD_1_MESSAGE_1); fieldErrorsMap.put(FIELD_1_NAME, fieldErrorMessage); given(owner.getErrors()).willReturn(fieldErrorsMap); final List<ErrorMessage> globalErrors = Lists.newArrayList(); final ErrorMessage globalErrorMessage = buildErrorMessage(GLOBAL_MESSAGE_1); globalErrors.add(globalErrorMessage); given(owner.getGlobalErrors()).willReturn(globalErrors); // when stateChangeContext.setOwner(owner); stateChangeContext.setOwner(owner); // then verify(ownerDD, never()).save(owner); verify(stateChangeEntity, never()).setField(describer.getOwnerFieldName(), owner); verify(stateChangeEntity, never()).setField(describer.getOwnerFieldName(), savedOwner); verify(messageService).addValidationError(stateChangeContext, FIELD_1_NAME, FIELD_1_MESSAGE_1, EMPTY_STRING_ARRAY); verify(messageService).addValidationError(stateChangeContext, null, GLOBAL_MESSAGE_1, EMPTY_STRING_ARRAY); verify(stateChangeEntity).setField(describer.getStatusFieldName(), StateChangeStatus.FAILURE.getStringValue()); } @Test public final void shouldSaveButNotSetJustInvalidateOwnerEntity() { // given given(owner.isValid()).willReturn(true); given(ownerDD.save(owner)).willReturn(savedOwner); given(savedOwner.isValid()).willReturn(false); final Map<String, ErrorMessage> fieldErrorsMap = Maps.newHashMap(); final ErrorMessage fieldErrorMessage = buildErrorMessage(FIELD_1_MESSAGE_1); fieldErrorsMap.put(FIELD_1_NAME, fieldErrorMessage); given(savedOwner.getErrors()).willReturn(fieldErrorsMap); final List<ErrorMessage> globalErrors = Lists.newArrayList(); final ErrorMessage globalErrorMessage = buildErrorMessage(GLOBAL_MESSAGE_1); globalErrors.add(globalErrorMessage); given(savedOwner.getGlobalErrors()).willReturn(globalErrors); // when stateChangeContext.setOwner(owner); // then verify(ownerDD).save(owner); verify(stateChangeEntity, never()).setField(describer.getOwnerFieldName(), owner); verify(stateChangeEntity, never()).setField(describer.getOwnerFieldName(), savedOwner); verify(messageService).addValidationError(stateChangeContext, FIELD_1_NAME, FIELD_1_MESSAGE_1, EMPTY_STRING_ARRAY); verify(messageService).addValidationError(stateChangeContext, null, GLOBAL_MESSAGE_1, EMPTY_STRING_ARRAY); verify(stateChangeEntity).setField(describer.getStatusFieldName(), StateChangeStatus.FAILURE.getStringValue()); } @Test public final void shouldCopyValidationErrorMessagesFromEntity() { // given given(owner.isValid()).willReturn(false); final Map<String, ErrorMessage> fieldErrorsMap = Maps.newHashMap(); final ErrorMessage fieldErrorMessage = buildErrorMessage(FIELD_1_MESSAGE_1); fieldErrorsMap.put(FIELD_1_NAME, fieldErrorMessage); given(owner.getErrors()).willReturn(fieldErrorsMap); final List<ErrorMessage> globalErrors = Lists.newArrayList(); final ErrorMessage globalErrorMessage = buildErrorMessage(GLOBAL_MESSAGE_1); globalErrors.add(globalErrorMessage); given(owner.getGlobalErrors()).willReturn(globalErrors); // when stateChangeContext.setOwner(owner); // then verify(messageService).addValidationError(stateChangeContext, FIELD_1_NAME, FIELD_1_MESSAGE_1, EMPTY_STRING_ARRAY); verify(messageService).addValidationError(stateChangeContext, null, GLOBAL_MESSAGE_1, EMPTY_STRING_ARRAY); } private ErrorMessage buildErrorMessage(final String message) { return new ErrorMessage(message, EMPTY_STRING_ARRAY); } }