/** * *************************************************************************** * 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.aop; import static com.qcadoo.mes.states.aop.RunForStateTransitionAspect.WILDCARD_STATE; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.junit.Before; import org.junit.Test; import org.mockito.MockitoAnnotations; import com.qcadoo.mes.states.MockStateChangeDescriber; import com.qcadoo.mes.states.StateChangeContext; import com.qcadoo.mes.states.StateChangeEntityDescriber; import com.qcadoo.mes.states.StateChangeTest; import com.qcadoo.mes.states.annotation.RunForStateTransition; import com.qcadoo.mes.states.annotation.RunForStateTransitions; import com.qcadoo.mes.states.annotation.RunInPhase; import com.qcadoo.model.api.Entity; public class RunForStateTransitionAspectTest extends StateChangeTest { private static final String SOURCE_STATE_1 = "sourceState01"; private static final String SOURCE_STATE_2 = "sourceState02"; private static final String TARGET_STATE_1 = "targetState01"; private static final String TARGET_STATE_2 = "targetState02"; private static final String MARKED_1 = "marked01"; private static final String MARKED_2 = "marked02"; private static final String MARKED_3 = "marked03"; private static final String MARKED_4 = "marked04"; private static final String MARKED_5 = "marked05"; private static final String MARKED_MANY_1 = "markedMany01"; private static final String MARKED_MANY_2 = "markedMany02"; private TestStateChangeServiceAspect testService; @Test public final void checkAnnotationSelectorPointcutDefinition() throws NoSuchMethodException { final Class<?> clazz = RunForStateTransitions.class; assertEquals("com.qcadoo.mes.states.annotation.RunForStateTransitions", clazz.getCanonicalName()); } @Aspect public static class TestStateChangeServiceAspect extends AbstractStateChangeAspect { @Override public void changeState(final StateChangeContext stateChangeContext) { // Do nothing } @Override public StateChangeEntityDescriber getChangeEntityDescriber() { return new MockStateChangeDescriber(); } @Override protected void changeStatePhase(final StateChangeContext stateChangeContext, final int phaseNumber) { } } @Aspect public static class TestStateChangeListenerAspect extends AbstractStateListenerAspect { @RunInPhase(1) @RunForStateTransition(sourceState = SOURCE_STATE_1, targetState = TARGET_STATE_1) @org.aspectj.lang.annotation.Before("changeStateExecution(stateChangeContext)") public void markEntity1(final StateChangeContext stateChangeContext) { final Entity stateChange = stateChangeContext.getStateChangeEntity(); stateChange.setField(MARKED_1, true); } @RunInPhase(1) @RunForStateTransition(sourceState = SOURCE_STATE_1, targetState = WILDCARD_STATE) @org.aspectj.lang.annotation.Before("changeStateExecution(stateChangeContext)") public void markEntity2(final StateChangeContext stateChangeContext) { final Entity stateChange = stateChangeContext.getStateChangeEntity(); stateChange.setField(MARKED_2, true); } @RunInPhase(1) @RunForStateTransition(sourceState = WILDCARD_STATE, targetState = TARGET_STATE_1) @org.aspectj.lang.annotation.Before("changeStateExecution(stateChangeContext)") public void markEntity3(final StateChangeContext stateChangeContext) { final Entity stateChange = stateChangeContext.getStateChangeEntity(); stateChange.setField(MARKED_3, true); } @RunInPhase(1) @RunForStateTransition(sourceState = WILDCARD_STATE, targetState = WILDCARD_STATE) @org.aspectj.lang.annotation.Before("changeStateExecution(stateChangeContext)") public void markEntity4(final StateChangeContext stateChangeContext) { final Entity stateChange = stateChangeContext.getStateChangeEntity(); stateChange.setField(MARKED_4, true); } @RunInPhase(1) @RunForStateTransitions({ @RunForStateTransition(sourceState = WILDCARD_STATE, targetState = TARGET_STATE_2) }) @org.aspectj.lang.annotation.Before("changeStateExecution(stateChangeContext)") public void markEntity5(final StateChangeContext stateChangeContext) { final Entity stateChange = stateChangeContext.getStateChangeEntity(); stateChange.setField(MARKED_5, true); } @RunInPhase(1) @RunForStateTransitions({ @RunForStateTransition(sourceState = SOURCE_STATE_1, targetState = TARGET_STATE_1), @RunForStateTransition(sourceState = SOURCE_STATE_2, targetState = TARGET_STATE_2) }) @org.aspectj.lang.annotation.Before("changeStateExecution(stateChangeContext)") public void markEntityMany1(final StateChangeContext stateChangeContext) { final Entity stateChange = stateChangeContext.getStateChangeEntity(); stateChange.setField(MARKED_MANY_1, true); } @RunInPhase(1) @RunForStateTransitions({ @RunForStateTransition(sourceState = "undefinedSource1", targetState = "undefinedTarget1"), @RunForStateTransition(sourceState = "undefinedSource2", targetState = "undefinedTarget2") }) @RunForStateTransition(sourceState = WILDCARD_STATE, targetState = WILDCARD_STATE) @org.aspectj.lang.annotation.Before("changeStateExecution(stateChangeContext)") public void markEntityMany2(final StateChangeContext stateChangeContext) { final Entity stateChange = stateChangeContext.getStateChangeEntity(); stateChange.setField(MARKED_MANY_2, true); } @Pointcut("this(TestStateChangeServiceAspect)") protected void targetServicePointcut() { } } @Before public final void init() { MockitoAnnotations.initMocks(this); testService = new TestStateChangeServiceAspect(); stubStateChangeEntity(DESCRIBER); stubStateChangeContext(); } protected void stubStateChangeEntityStates(final String sourceState, final String targetState) { stubEntityField(stateChangeEntity, DESCRIBER.getSourceStateFieldName(), sourceState); stubEntityField(stateChangeEntity, DESCRIBER.getTargetStateFieldName(), targetState); } @Test public final void shouldRunIfMatchTransition1() { // given stubStateChangeEntityStates(SOURCE_STATE_1, TARGET_STATE_1); // when testService.changeState(stateChangeContext); // then verify(stateChangeEntity).setField(MARKED_1, true); verify(stateChangeEntity).setField(MARKED_2, true); verify(stateChangeEntity).setField(MARKED_3, true); verify(stateChangeEntity).setField(MARKED_4, true); verify(stateChangeEntity, never()).setField(MARKED_5, true); verify(stateChangeEntity).setField(MARKED_MANY_1, true); verify(stateChangeEntity, never()).setField(MARKED_MANY_2, true); } @Test public final void shouldRunIfMatchTransition2() { // given stubStateChangeEntityStates(SOURCE_STATE_2, TARGET_STATE_2); // when testService.changeState(stateChangeContext); // then verify(stateChangeEntity, never()).setField(MARKED_1, true); verify(stateChangeEntity, never()).setField(MARKED_2, true); verify(stateChangeEntity, never()).setField(MARKED_3, true); verify(stateChangeEntity).setField(MARKED_4, true); verify(stateChangeEntity).setField(MARKED_5, true); verify(stateChangeEntity).setField(MARKED_MANY_1, true); verify(stateChangeEntity, never()).setField(MARKED_MANY_2, true); } @Test public final void shouldRunIfMatchTransition3() { // given stubStateChangeEntityStates(SOURCE_STATE_2, TARGET_STATE_1); // when testService.changeState(stateChangeContext); // then verify(stateChangeEntity, never()).setField(MARKED_1, true); verify(stateChangeEntity, never()).setField(MARKED_2, true); verify(stateChangeEntity).setField(MARKED_3, true); verify(stateChangeEntity).setField(MARKED_4, true); verify(stateChangeEntity, never()).setField(MARKED_5, true); verify(stateChangeEntity, never()).setField(MARKED_MANY_1, true); verify(stateChangeEntity, never()).setField(MARKED_MANY_2, true); } @Test public final void shouldRunIfMatchTransition4() { // given stubStateChangeEntityStates("unsupported", "unsupported"); // when testService.changeState(stateChangeContext); // then verify(stateChangeEntity, never()).setField(MARKED_1, true); verify(stateChangeEntity, never()).setField(MARKED_2, true); verify(stateChangeEntity, never()).setField(MARKED_3, true); verify(stateChangeEntity).setField(MARKED_4, true); verify(stateChangeEntity, never()).setField(MARKED_5, true); verify(stateChangeEntity, never()).setField(MARKED_MANY_1, true); verify(stateChangeEntity, never()).setField(MARKED_MANY_2, true); } @Test public final void shouldRunIfMatchTransition5() { // given stubStateChangeEntityStates(SOURCE_STATE_1, TARGET_STATE_2); // when testService.changeState(stateChangeContext); // then verify(stateChangeEntity, never()).setField(MARKED_1, true); verify(stateChangeEntity).setField(MARKED_2, true); verify(stateChangeEntity, never()).setField(MARKED_3, true); verify(stateChangeEntity).setField(MARKED_4, true); verify(stateChangeEntity).setField(MARKED_5, true); verify(stateChangeEntity, never()).setField(MARKED_MANY_1, true); verify(stateChangeEntity, never()).setField(MARKED_MANY_2, true); } }