| /******************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 org.apache.sling.scripting.sightly.impl.engine; |
| |
| import java.io.StringWriter; |
| import java.util.HashMap; |
| import java.util.Hashtable; |
| import java.util.List; |
| import java.util.Map; |
| import javax.script.Bindings; |
| import javax.script.ScriptContext; |
| import javax.script.ScriptEngine; |
| import javax.script.ScriptException; |
| import javax.script.SimpleBindings; |
| |
| import org.apache.sling.api.resource.ResourceResolver; |
| import org.apache.sling.api.scripting.SlingBindings; |
| import org.apache.sling.scripting.sightly.java.compiler.RenderUnit; |
| import org.apache.sling.testing.mock.osgi.MockOsgi; |
| import org.apache.sling.testing.mock.sling.MockSling; |
| import org.apache.sling.testing.mock.sling.junit.SlingContext; |
| import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.mockito.ArgumentCaptor; |
| import org.mockito.internal.util.reflection.Whitebox; |
| import org.osgi.framework.BundleContext; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.mockito.Mockito.*; |
| |
| |
| public class SightlyCompiledScriptTest { |
| |
| @Rule |
| public final SlingContext slingContext = new SlingContext(); |
| |
| /** |
| * Tests that SlingBindings are correctly handled by compiled scripts, by setting them from the script context to the request |
| * attributes. |
| * @throws ScriptException |
| */ |
| @Test |
| public void testEvalSlingBindings() throws ScriptException { |
| ScriptEngine scriptEngine = mock(ScriptEngine.class); |
| final RenderUnit renderUnit = mock(RenderUnit.class); |
| Whitebox.setInternalState(renderUnit, "subTemplates", new HashMap<String, Object>()); |
| final BundleContext bundleContext = MockOsgi.newBundleContext(); |
| bundleContext.registerService(ExtensionRegistryService.class.getName(), mock(ExtensionRegistryService.class), new |
| Hashtable<String, Object>()); |
| ResourceResolver resourceResolver = MockSling.newResourceResolver(bundleContext); |
| final MockSlingHttpServletRequest request = spy(new MockSlingHttpServletRequest(resourceResolver, bundleContext)); |
| SightlyCompiledScript compiledScript = spy(new SightlyCompiledScript(scriptEngine, renderUnit)); |
| ScriptContext scriptContext = mock(ScriptContext.class); |
| StringWriter writer = new StringWriter(); |
| when(scriptContext.getWriter()).thenReturn(writer); |
| Bindings scriptContextBindings = new SimpleBindings(){{ |
| put("test", "testValue"); |
| put(SlingBindings.REQUEST, request); |
| put(SlingBindings.SLING, MockSling.newSlingScriptHelper(bundleContext)); |
| }}; |
| SlingBindings oldBindings = new SlingBindings(); |
| oldBindings.put("old", "oldValue"); |
| request.setAttribute(SlingBindings.class.getName(), oldBindings); |
| when(scriptContext.getBindings(ScriptContext.ENGINE_SCOPE)).thenReturn(scriptContextBindings); |
| compiledScript.eval(scriptContext); |
| ArgumentCaptor<SlingBindings> slingBindingsArgumentCaptor = ArgumentCaptor.forClass(SlingBindings.class); |
| ArgumentCaptor<String> attributeNameArgumentCaptor = ArgumentCaptor.forClass(String.class); |
| |
| // request.setAttribute should have been invoked 3 times: once here, twice in the compiled script |
| verify(request, times(3)).setAttribute(attributeNameArgumentCaptor.capture(), slingBindingsArgumentCaptor.capture()); |
| List<SlingBindings> slingBindingsValues = slingBindingsArgumentCaptor.getAllValues(); |
| int invocation = 1; |
| for (SlingBindings bindings : slingBindingsValues) { |
| switch (invocation) { |
| case 1: |
| assertEquals(oldBindings, bindings); |
| break; |
| case 2: |
| assertEquals(3, bindings.size()); |
| for (Map.Entry<String, Object> entry : scriptContextBindings.entrySet()) { |
| assertEquals(entry.getValue(), bindings.get(entry.getKey())); |
| } |
| break; |
| case 3: |
| assertEquals(oldBindings, bindings); |
| } |
| invocation++; |
| } |
| for (String key : attributeNameArgumentCaptor.getAllValues()) { |
| assertEquals(SlingBindings.class.getName(), key); |
| } |
| } |
| } |