/** * 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.api.tags.tags; import io.neba.api.Constants; import io.neba.api.resourcemodels.ResourceModelProvider; import io.neba.api.tags.DefineObjectsTag; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.scripting.SlingBindings; import org.apache.sling.api.scripting.SlingScriptHelper; 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 javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.TagSupport; import java.util.Map; import static org.apache.sling.api.scripting.SlingBindings.SLING; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; /** * @author Olaf Otto */ @RunWith(MockitoJUnitRunner.class) public class DefineObjectsTagTest { @Mock private PageContext context; @Mock private SlingHttpServletRequest request; @Mock private Resource resource; @Mock private SlingBindings bindings; @Mock private SlingScriptHelper sling; @Mock private ResourceModelProvider resourceModelProvider; private int tagExecutionReturnCode; private Object model = new Object(); private String desiredModelName; @InjectMocks private DefineObjectsTag testee; @Before public void prepareTag() { doReturn(this.resource).when(this.request).getResource(); doReturn(this.request).when(this.context).getRequest(); doReturn(this.sling).when(this.bindings).get(eq(SLING)); doReturn(this.resourceModelProvider).when(this.sling).getService(eq(ResourceModelProvider.class)); doReturn(this.model).when(this.resourceModelProvider).resolveMostSpecificModel(eq(this.resource)); doReturn(this.model).when(this.resourceModelProvider).resolveMostSpecificModelIncludingModelsForBaseTypes(eq(this.resource)); doReturn(this.model).when(this.resourceModelProvider).resolveMostSpecificModelWithBeanName(eq(this.resource), anyString()); withBindings(this.bindings); this.testee.setPageContext(this.context); } @Test public void testCopyingOfBindingsIntoPageContext() throws Exception { withBinding("foo", "bar"); withBinding("foo2", "bar2"); executeTag(); verifyAllBindingsAreCopiedIntoPageContext(); assertTagEvaluationReturnsContinueWithPage(); } @Test public void testResolutionOfGenericModelWithBaseTypesEnabled() throws Exception { enableBaseTypeSupport(); executeTag(); verifyResourceIsAdaptedToMostSpecificModelIncludingBaseTypes(); verifyGenericModelIsAddedToPageContext(); } @Test public void testResolutionOfGenericModelWithoutBaseTypes() throws Exception { executeTag(); verifyResourceIsAdaptedToMostSpecificModel(); verifyGenericModelIsAddedToPageContext(); } @Test public void testResolutionOfGenericModelWithExplicitModelBeanName() throws Exception { withDesiredModelNamed("name"); executeTag(); verifyResourceIsAdaptedToMostSpecificModelWithProvidedBeanName(); verifyGenericModelIsAddedToPageContext(); } @Test public void testResolutionOfGenericModelWithEmptyModelBeanName() throws Exception { withDesiredModelNamed(" "); executeTag(); verifyResourceIsAdaptedToMostSpecificModel(); verifyGenericModelIsAddedToPageContext(); } @Test(expected = IllegalStateException.class) public void testHandlingOfMissingProvider() throws Exception { withMissingProviderService(); executeTag(); } private void withMissingProviderService() { doReturn(null).when(this.sling).getService(eq(ResourceModelProvider.class)); } private void verifyResourceIsAdaptedToMostSpecificModelWithProvidedBeanName() { verify(this.resourceModelProvider).resolveMostSpecificModelWithBeanName(eq(this.resource), eq(this.desiredModelName)); } private void withDesiredModelNamed(String name) { this.desiredModelName = name; this.testee.setUseModelNamed(name); } private void verifyResourceIsAdaptedToMostSpecificModelIncludingBaseTypes() { verify(this.resourceModelProvider).resolveMostSpecificModelIncludingModelsForBaseTypes(eq(this.resource)); } private void verifyResourceIsAdaptedToMostSpecificModel() { verify(this.resourceModelProvider).resolveMostSpecificModel(eq(this.resource)); } private void enableBaseTypeSupport() { this.testee.setIncludeGenericBaseTypes(true); } private void verifyGenericModelIsAddedToPageContext() { verify(this.context).setAttribute(eq(Constants.MODEL), eq(this.model)); } private void withBindings(SlingBindings bindings) { when(this.request.getAttribute(eq(SlingBindings.class.getName()))).thenReturn(bindings); } private void assertTagEvaluationReturnsContinueWithPage() { assertThat(this.tagExecutionReturnCode, is(TagSupport.EVAL_PAGE)); } private void verifyAllBindingsAreCopiedIntoPageContext() { for (Map.Entry<String, Object> e : this.bindings.entrySet()) { verify(this.context, times(1)).setAttribute(eq(e.getKey()), eq(e.getValue())); } } private void executeTag() throws JspException { this.tagExecutionReturnCode = this.testee.doEndTag(); } private void withBinding(String key, String value) { this.bindings.put(key, value); } }