/* * 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 SF 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.phms.sling.scripting.handlebars; import java.io.StringReader; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptException; import javax.script.SimpleScriptContext; import org.phms.sling.handlebars.HandlebarsScriptEngineFactory; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HandlebarsScriptEngineFactoryTest { public class Person { private Name firstName; private Name lastName; public Person(String firstName, String lastName) { this.firstName = new Name(firstName); this.lastName = new Name(lastName); } public Name getFirstName() { return firstName; } public Name getLastName() { return lastName; } } public class Name { private String _name; public Name(String name) { this._name = name; } public String getName() { return _name; } } private static final Logger LOGGER = LoggerFactory.getLogger(HandlebarsScriptEngineFactoryTest.class); private HandlebarsScriptEngineFactory scriptEngineFactory; @Before public void before() { scriptEngineFactory = new HandlebarsScriptEngineFactory(); } @Test public void testProperties() { Assert.assertEquals("HandlebarsScriptEngineFactory", scriptEngineFactory.getEngineName()); Assert.assertEquals("0", scriptEngineFactory.getEngineVersion()); Assert.assertArrayEquals(new String[] { "handlebars" }, scriptEngineFactory.getExtensions().toArray()); Assert.assertEquals("handlebars", scriptEngineFactory.getLanguageName()); Assert.assertEquals("1.0", scriptEngineFactory.getLanguageVersion()); Assert.assertArrayEquals(new String[] { "text/x-handlebars" }, scriptEngineFactory.getMimeTypes().toArray()); } @Test public void testScriptEngine() throws ScriptException { ScriptEngine scriptEngine = scriptEngineFactory.getScriptEngine(); LOGGER.info("Script engine is {} ", scriptEngine); StringReader reader = new StringReader(" Something really Simple"); StringWriter writer = new StringWriter(); SimpleScriptContext scriptContext = new SimpleScriptContext(); Bindings bindings = scriptEngine.createBindings(); scriptContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE); scriptContext.setWriter(writer); LOGGER.info("Calling with {} ", scriptContext); Object o = scriptEngine.eval(reader, scriptContext); Assert.assertNull(o); Assert.assertEquals(" Something really Simple", writer.toString()); } /** * Test a simple binding. * @throws ScriptException */ @Test public void testTemplateSimpleBinding() throws ScriptException { ScriptEngine scriptEngine = scriptEngineFactory.getScriptEngine(); LOGGER.info("Script engine is {} ", scriptEngine); StringReader reader = new StringReader( " Something really Simple with {{ replace_me }}"); StringWriter writer = new StringWriter(); SimpleScriptContext scriptContext = new SimpleScriptContext(); Bindings bindings = scriptEngine.createBindings(); scriptContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE); scriptContext.setWriter(writer); bindings.put("replace_me", "Hello World!"); LOGGER.info("Calling with {} ", scriptContext); Object o = scriptEngine.eval(reader, scriptContext); Assert.assertNull(o); Assert.assertEquals(" Something really Simple with Hello World!", writer.toString()); } /** * Test a simple map binding. * @throws ScriptException */ @Test public void testTemplateMapBinding() throws ScriptException { ScriptEngine scriptEngine = scriptEngineFactory.getScriptEngine(); LOGGER.info("Script engine is {} ", scriptEngine); StringReader reader = new StringReader( " Something really Simple with {{ replace_me.name }}"); StringWriter writer = new StringWriter(); SimpleScriptContext scriptContext = new SimpleScriptContext(); Bindings bindings = scriptEngine.createBindings(); scriptContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE); scriptContext.setWriter(writer); Map<String, Object> replace_me = new HashMap<String, Object>(); replace_me.put("name", "ieb"); bindings.put("replace_me", replace_me); LOGGER.info("Calling with {} ", scriptContext); Object o = scriptEngine.eval(reader, scriptContext); Assert.assertNull(o); Assert.assertEquals(" Something really Simple with ieb", writer.toString()); } /** * Tests that its possible to access bean getters by name using dotted * annotation. * * @throws ScriptException */ @Test public void testTemplateMethodBinding() throws ScriptException { ScriptEngine scriptEngine = scriptEngineFactory.getScriptEngine(); LOGGER.info("Script engine is {} ", scriptEngine); StringReader reader = new StringReader( " Something really Simple with {{ replace_me.name }}"); StringWriter writer = new StringWriter(); SimpleScriptContext scriptContext = new SimpleScriptContext(); Bindings bindings = scriptEngine.createBindings(); scriptContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE); scriptContext.setWriter(writer); bindings.put("replace_me", new Name("ian")); LOGGER.info("Calling with {} ", scriptContext); Object o = scriptEngine.eval(reader, scriptContext); Assert.assertNull(o); Assert.assertEquals(" Something really Simple with ian", writer.toString()); } /** * Tests value binding through multiple beans. * @throws ScriptException */ @Test public void testTemplateDeepMethodBinding() throws ScriptException { ScriptEngine scriptEngine = scriptEngineFactory.getScriptEngine(); LOGGER.info("Script engine is {} ", scriptEngine); StringReader reader = new StringReader( " Something really Simple with {{ replace_me.firstName.name }} {{ replace_me.lastName.name }}"); StringWriter writer = new StringWriter(); SimpleScriptContext scriptContext = new SimpleScriptContext(); Bindings bindings = scriptEngine.createBindings(); scriptContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE); scriptContext.setWriter(writer); bindings.put("replace_me", new Person("ian", "boston")); LOGGER.info("Calling with {} ", scriptContext); Object o = scriptEngine.eval(reader, scriptContext); Assert.assertNull(o); Assert.assertEquals(" Something really Simple with ian boston", writer.toString()); } /** * Test for safe defaults to XXS strings. * @throws ScriptException */ @Test public void testTemplateDeepMethodBindingXSS() throws ScriptException { ScriptEngine scriptEngine = scriptEngineFactory.getScriptEngine(); LOGGER.info("Script engine is {} ", scriptEngine); StringReader reader = new StringReader( " Something really Simple with {{ replace_me.firstName.name }} {{ replace_me.lastName.name }}"); StringWriter writer = new StringWriter(); SimpleScriptContext scriptContext = new SimpleScriptContext(); Bindings bindings = scriptEngine.createBindings(); scriptContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE); scriptContext.setWriter(writer); bindings.put("replace_me", new Person( "ian<script type=\"text/javascript", "\">alert('GotYa!');</script>boston")); LOGGER.info("Calling with {} ", scriptContext); Object o = scriptEngine.eval(reader, scriptContext); Assert.assertNull(o); Assert.assertEquals( " Something really Simple with ian<script type="text/javascript ">alert('GotYa!');</script>boston", writer.toString()); } /** * Tests ability to escape to raw output when required. * @throws ScriptException */ @Test public void testTemplateDeepMethodBindingRaw() throws ScriptException { ScriptEngine scriptEngine = scriptEngineFactory.getScriptEngine(); LOGGER.info("Script engine is {} ", scriptEngine); StringReader reader = new StringReader( " Something really Simple with {{{ replace_me.firstName.name }}} {{{ replace_me.lastName.name }}}"); StringWriter writer = new StringWriter(); SimpleScriptContext scriptContext = new SimpleScriptContext(); Bindings bindings = scriptEngine.createBindings(); scriptContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE); scriptContext.setWriter(writer); bindings.put("replace_me", new Person( "ian<script type=\"text/javascript", "\">alert('GotYa!');</script>boston")); LOGGER.info("Calling with {} ", scriptContext); Object o = scriptEngine.eval(reader, scriptContext); Assert.assertNull(o); Assert.assertEquals( " Something really Simple with ian<script type=\"text/javascript \">alert('GotYa!');</script>boston", writer.toString()); } }