/** * Copyright 2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 the "License"; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. **/ package io.neba.core.resourcemodels.mapping; import io.neba.api.annotations.PostMapping; import io.neba.api.annotations.PreMapping; import io.neba.core.resourcemodels.metadata.ResourceModelMetaData; import org.apache.sling.api.resource.Resource; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.beans.factory.BeanFactory; import static org.assertj.core.api.Assertions.assertThat; /** * @author Olaf Otto */ @RunWith(MockitoJUnitRunner.class) public class ModelProcessorTest { private boolean throwExceptionDuringPreMapping; private boolean throwExceptionDuringPostMapping; /** * @author Olaf Otto */ private class TestModel { @PostMapping public void publicPostMapping() { postMappingWasCalled(); } @PostMapping protected void protectedPostMapping() { postMappingWasCalled(); } @PostMapping private void privatePostMapping() { postMappingWasCalled(); } @PostMapping void packagePrivatePostMapping() { postMappingWasCalled(); } @PreMapping public void publicPreMapping() { preMappingWasCalled(); } @PreMapping protected void protectedPreMapping() { preMappingWasCalled(); } @PreMapping private void privatePreMapping() { preMappingWasCalled(); } @PreMapping void packagePrivatePreMapping() { preMappingWasCalled(); } } @Mock private BeanFactory factory; @Mock private Resource resource; private int timesPostMappingCalled; private int timesPreMappingCalled; private TestModel model; private ResourceModelMetaData metadata; @InjectMocks private ModelProcessor testee; @Before public void setUp() throws Exception { this.throwExceptionDuringPostMapping = false; this.throwExceptionDuringPreMapping = false; this.timesPostMappingCalled = 0; this.timesPreMappingCalled = 0; } @Test public void testPreMapping() throws Exception { withModel(new TestModel()); processBeforeMapping(); assertPostMappingMethodsAreNotInvoked(); assertPreMappingMethodsAreInvoked(); } @Test public void testPostMapping() throws Exception { withModel(new TestModel()); processAfterMapping(); assertPreMappingMethodsAreNotInvoked(); assertPostMappingMethodsAreInvoked(); } @Test public void testHandlingOfExceptionDuringPreMappingPhase() throws Exception { withModel(new TestModel()); withExceptionDuringPreMappingMethodInvocation(); processBeforeMapping(); } @Test public void testHandlingOfExceptionDuringPostMappingPhase() throws Exception { withModel(new TestModel()); withExceptionDuringPostMappingMethodInvocation(); processAfterMapping(); } private void withExceptionDuringPostMappingMethodInvocation() { this.throwExceptionDuringPostMapping = true; } private void withExceptionDuringPreMappingMethodInvocation() { this.throwExceptionDuringPreMapping = true; } private void postMappingWasCalled() { if (throwExceptionDuringPostMapping) { throw new RuntimeException("THIS IS AN EXPECTED TEST EXCEPTION"); } this.timesPostMappingCalled++; } private void preMappingWasCalled() { if (throwExceptionDuringPreMapping) { throw new RuntimeException("THIS IS AN EXPECTED TEST EXCEPTION"); } this.timesPreMappingCalled++; } private void assertPreMappingMethodsAreNotInvoked() { assertThat(this.timesPreMappingCalled).isZero(); } private void assertPreMappingMethodsAreInvoked() { assertThat(this.timesPreMappingCalled).isEqualTo(this.metadata.getPreMappingMethods().length); } private void assertPostMappingMethodsAreNotInvoked() { assertThat(this.timesPostMappingCalled).isZero(); } private void assertPostMappingMethodsAreInvoked() { assertThat(this.timesPostMappingCalled).isEqualTo(this.metadata.getPostMappingMethods().length); } private void withModel(final TestModel testModel) { this.model = testModel; this.metadata = new ResourceModelMetaData(this.model.getClass()); } private void processBeforeMapping() { this.testee.processBeforeMapping(this.metadata, this.model); } private void processAfterMapping() { this.testee.processAfterMapping(this.metadata, this.model); } }