/* * 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.launchpad.webapp.integrationtest; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.sling.commons.testing.integration.HttpTest; import org.apache.sling.commons.testing.junit.Retry; import org.apache.sling.commons.testing.junit.RetryRule; import org.apache.sling.servlets.post.SlingPostConstants; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; /** Test the {link ScriptHelper#include) functionality */ public class JspIncludeTest { private String nodeUrlA; private String testTextA; private String nodeUrlB; private String testTextB; private String nodeUrlC; private String nodeUrlD; private String nodeUrlE; private String nodeUrlF; private String nodeUrlG; private String nodeUrlH; private String nodeUrlI; private String forcedResourceType; private Set<String> toDelete = new HashSet<String>(); /** HTTP tests helper */ private final HttpTest H = new HttpTest(); @Rule public RetryRule retryRule = new RetryRule(); @Before public void setUp() throws Exception { H.setUp(); // Create the test nodes under a path that's specific to this class to // allow collisions final String url = HttpTest.HTTP_BASE_URL + "/" + getClass().getSimpleName() + "/" + System.currentTimeMillis() + SlingPostConstants.DEFAULT_CREATE_SUFFIX; final Map<String,String> props = new HashMap<String,String>(); // Create two test nodes and store their paths testTextA = "Text A " + System.currentTimeMillis(); props.put("text", testTextA); nodeUrlA = H.getTestClient().createNode(url, props); String pathToInclude = nodeUrlA.substring(HttpTest.HTTP_BASE_URL.length()); // Node B stores the path of A, so that the test script can // include A when rendering B testTextB = "Text B " + System.currentTimeMillis(); props.put("text", testTextB); props.put("pathToInclude", pathToInclude); nodeUrlB = H.getTestClient().createNode(url, props); // Node E is like B but with an extension on the include path props.put("pathToInclude", pathToInclude + ".html"); nodeUrlE = H.getTestClient().createNode(url, props); // Node F is used for the max calls detection test props.put("testMaxCalls","true"); nodeUrlF = H.getTestClient().createNode(url, props); // Node C is used for the infinite loop detection test props.remove("pathToInclude"); props.remove("testMaxCalls"); props.put("testInfiniteLoop","true"); nodeUrlC = H.getTestClient().createNode(url, props); // Node D is used for the "force resource type" test forcedResourceType = getClass().getSimpleName() + "/" + System.currentTimeMillis(); props.remove("testInfiniteLoop"); props.put("forceResourceType", forcedResourceType); props.put("pathToInclude", pathToInclude); nodeUrlD = H.getTestClient().createNode(url, props); // Node G is used for the basic "call" test props.remove("forceResourceType"); props.remove("pathToInclude"); props.put("testCallScript", "called-test.jsp"); nodeUrlG = H.getTestClient().createNode(url, props); // Node I is used for the "var" test props.remove("forceResourceType"); props.remove("testCallScript"); props.put("testVarInclude","true"); props.put("pathToInclude", pathToInclude); props.put("VAR_INCLUDE", "VALUE"); nodeUrlI = H.getTestClient().createNode(url, props); // Script for forced resource type H.setScriptPath("/apps/" + forcedResourceType); H.getTestClient().mkdirs(HttpTest.WEBDAV_BASE_URL, H.getScriptPath()); toDelete.add(H.uploadTestScript(H.getScriptPath(),"include-forced.jsp","html.jsp")); // The main rendering script goes under /apps in the repository H.setScriptPath("/apps/nt/unstructured"); H.getTestClient().mkdirs(HttpTest.WEBDAV_BASE_URL, H.getScriptPath()); toDelete.add(H.uploadTestScript(H.getScriptPath(),"include-test.jsp","html.jsp")); toDelete.add(H.uploadTestScript(H.getScriptPath(),"called-test.jsp","called-test.jsp")); // Node H is used for "call" test where the called script is inherited from the supertype String nodeHResourceType = getClass().getSimpleName() + "/" + System.currentTimeMillis(); String nodeHSuperResourceType = getClass().getSimpleName() + "/super" + System.currentTimeMillis(); props.put("sling:resourceType", nodeHResourceType); props.put("sling:resourceSuperType", nodeHSuperResourceType); nodeUrlH = H.getTestClient().createNode(url, props); H.setScriptPath("/apps/" + nodeHResourceType); H.getTestClient().mkdirs(HttpTest.WEBDAV_BASE_URL, H.getScriptPath()); toDelete.add(H.uploadTestScript(H.getScriptPath(),"calling-test.jsp","html.jsp")); H.setScriptPath("/apps/" + nodeHSuperResourceType); H.getTestClient().mkdirs(HttpTest.WEBDAV_BASE_URL, H.getScriptPath()); toDelete.add(H.uploadTestScript(H.getScriptPath(),"called-test.jsp","called-test.jsp")); } @After public void tearDown() throws Exception { H.tearDown(); for(String script : toDelete) { H.getTestClient().delete(script); } } @Test @Retry public void testWithoutInclude() throws IOException { final String content = H.getContent(nodeUrlA + ".html", HttpTest.CONTENT_TYPE_HTML); assertTrue("Content includes JSP marker",content.contains("JSP template")); assertTrue("Content contains formatted test text",content.contains("<p class=\"main\">" + testTextA + "</p>")); assertFalse("Nothing has been included",content.contains("<p>Including")); } @Test @Retry public void testWithInclude() throws IOException { final String content = H.getContent(nodeUrlB + ".html", HttpTest.CONTENT_TYPE_HTML); assertTrue("Content includes JSP marker",content.contains("JSP template")); assertTrue("Content contains formatted test text",content.contains("<p class=\"main\">" + testTextB + "</p>")); assertTrue("Include has been used",content.contains("<p>Including")); assertTrue("Text of node A is included (" + content + ")",content.contains(testTextA)); } @Test @Retry public void testWithIncludeAndExtension() throws IOException { final String content = H.getContent(nodeUrlE + ".html", HttpTest.CONTENT_TYPE_HTML); assertTrue("Content includes JSP marker",content.contains("JSP template")); assertTrue("Content contains formatted test text",content.contains("<p class=\"main\">" + testTextB + "</p>")); assertTrue("Include has been used",content.contains("<p>Including")); assertTrue("Text of node A is included (" + content + ")",content.contains(testTextA)); } @Test @Retry public void testInfiniteLoopDetection() throws IOException { // Node C has a property that causes an infinite include loop, // Sling must indicate the problem in its response final GetMethod get = new GetMethod(nodeUrlC + ".html"); H.getHttpClient().executeMethod(get); final String content = get.getResponseBodyAsString(); assertTrue( "Response contains infinite loop error message", content.contains("org.apache.sling.api.request.RecursionTooDeepException")); // TODO: SLING-515, status is 500 when running the tests as part of the maven build // but 200 if running tests against a separate instance started with mvn jetty:run // final int status = get.getStatusCode(); // assertEquals("Status is 500 for infinite loop",HttpServletResponse.SC_INTERNAL_SERVER_ERROR, status); } @Test @Retry public void testMaxCallsDetection() throws IOException { // Node F has a property that causes over 1000 includes // Sling must indicate the problem in its response final GetMethod get = new GetMethod(nodeUrlF + ".html"); H.getHttpClient().executeMethod(get); final String content = get.getResponseBodyAsString(); assertTrue( "Response contains infinite loop error message", content.contains("org.apache.sling.api.request.TooManyCallsException")); // TODO: SLING-515, status is 500 when running the tests as part of the maven build // but 200 if running tests against a separate instance started with mvn jetty:run // final int status = get.getStatusCode(); // assertEquals("Status is 500 for infinite loop",HttpServletResponse.SC_INTERNAL_SERVER_ERROR, status); } @Test @Retry public void testForcedResourceType() throws IOException { final String content = H.getContent(nodeUrlD + ".html", HttpTest.CONTENT_TYPE_HTML); assertTrue("Content includes JSP marker",content.contains("JSP template")); assertTrue("Content contains formatted test text",content.contains("<p class=\"main\">" + testTextB + "</p>")); assertTrue("Include has been used",content.contains("<p>Including")); assertTrue("Text of node A is included (" + content + ")",content.contains(testTextA)); assertTrue("Resource type has been forced (" + content + ")",content.contains("Forced resource type:" + forcedResourceType)); } @Test @Retry public void testCall() throws IOException { final String content = H.getContent(nodeUrlG + ".html", HttpTest.CONTENT_TYPE_HTML); assertTrue("Content includes JSP marker",content.contains("JSP template")); assertTrue("Content contains formatted test text",content.contains("<p class=\"main\">" + testTextB + "</p>")); assertTrue("Call has been used",content.contains("<p>Calling")); assertTrue("Call has been made",content.contains("called")); } @Test @Retry public void testCallToSupertype() throws IOException { final String content = H.getContent(nodeUrlH + ".html", HttpTest.CONTENT_TYPE_HTML); assertTrue("Content includes JSP marker",content.contains("JSP template")); assertTrue("Call has been made",content.contains("called")); } @Test @Retry public void testVarInclude() throws IOException{ final String content = H.getContent(nodeUrlI + ".html", HttpTest.CONTENT_TYPE_HTML); assertTrue("Content includes Loaded test content:",content.contains("Loaded test content:")); } }