/* * Copyright 2013 eXo Platform SAS * * 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 juzu.test; import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; import com.gargoylesoftware.htmlunit.Page; import com.gargoylesoftware.htmlunit.WebClient; import juzu.impl.bridge.DescriptorBuilder; import juzu.impl.common.Name; import juzu.impl.common.RunMode; import juzu.impl.fs.Visitor; import juzu.impl.fs.spi.ReadWriteFileSystem; import juzu.impl.inject.spi.InjectorProvider; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.ByteArrayAsset; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.asset.UrlAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.runner.RunWith; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URI; import java.net.URL; import java.util.ArrayList; /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */ @RunWith(Arquillian.class) public abstract class AbstractWebTestCase extends AbstractTestCase { /** . */ private static Name applicationName; /** . */ private static String path; /** . */ private static boolean asDefault; /** . */ private static CompilerAssert<File, File> compiler; /** . */ private static boolean servlet; /** * Returns the currently deployed application name. * * @return the application name */ public static Name getApplicationName() { return applicationName; } /** * Returns true if the currently application name should be the defaulted. * * @return the as default value */ public static boolean asDefault() { return asDefault; } /** * Returns the compiler for the currently deployed web application. * * @return the compiler */ public static CompilerAssert<File, File> getCompiler() { return compiler; } private static WebArchive createDeployment(boolean asDefault, Iterable<String> applicationNames) { // ArrayList<Name> applicationQNs = new ArrayList<Name>(); Name packageQN = null; for (String applicationName : applicationNames) { Name applicationQN = Name.parse(applicationName); applicationQNs.add(applicationQN); packageQN = packageQN == null ? applicationQN : packageQN.getPrefix(applicationQN); } // Compile classes CompilerAssert<File, File> compiler = compiler(false, packageQN); compiler.assertCompile(); // ReadWriteFileSystem<File> classOutput = compiler.getClassOutput(); // Create war final WebArchive war = ShrinkWrap.create(WebArchive.class, "juzu.war"); // Add output to war try { classOutput.traverse(new Visitor.Default<File>() { /** . */ StringBuffer path = new StringBuffer(); @Override public void enterDir(File dir, String name) throws IOException { if (name.isEmpty()) { path.append("classes/"); } else { path.append(name).append('/'); } } @Override public void leaveDir(File dir, String name) throws IOException { if (name.isEmpty()) { path.setLength(0); } else { path.setLength(path.length() - name.length() - 1); } } @Override public void file(File file, String name) throws IOException { path.append(name); String target = path.toString(); path.setLength(path.length() - name.length()); war.addAsWebInfResource(new ByteArrayAsset(new FileInputStream(file)), target); } }); } catch (IOException e) { throw failure(e); } // Set static state that we may need later AbstractWebTestCase.applicationName = applicationQNs.size() > 0 ? applicationQNs.get(0) : null; AbstractWebTestCase.asDefault = asDefault; AbstractWebTestCase.compiler = compiler; // return war; } public static WebArchive createServletDeployment(String applicationName) { return createServletDeployment(false, applicationName); } public static WebArchive createServletDeployment(InjectorProvider injector, String applicationName) { return createServletDeployment(DescriptorBuilder.DEFAULT.injector(injector).servletApp(applicationName), false); } public static WebArchive createServletDeployment(boolean asDefault, String applicationName) { return createServletDeployment(RunMode.PROD, asDefault, applicationName); } public static WebArchive createServletDeployment(String urlPattern, boolean asDefault, String applicationName) { return createServletDeployment(DescriptorBuilder.DEFAULT.servletApp(applicationName, urlPattern), asDefault); } public static WebArchive createServletDeployment(InjectorProvider injector, String urlPattern, boolean asDefault, String applicationName) { return createServletDeployment(DescriptorBuilder.DEFAULT.injector(injector).servletApp(applicationName, urlPattern), asDefault); } public static WebArchive createServletDeployment( RunMode runMode, boolean asDefault, String applicationName) { return createServletDeployment(DescriptorBuilder.DEFAULT.runMode(runMode).servletApp(applicationName), asDefault); } public static WebArchive createServletDeployment( InjectorProvider injector, RunMode runMode, boolean asDefault, String applicationName) { return createServletDeployment(DescriptorBuilder.DEFAULT.runMode(runMode).injector(injector).servletApp(applicationName), asDefault); } public static WebArchive createServletDeployment(DescriptorBuilder config, boolean asDefault) { // Create war String path; String urlPattern = config.getURLPattern(); if ("/".equals(urlPattern)) { path = ""; } else if ("/*".equals(urlPattern)) { throw failure("Not yet implemented"); } else if (urlPattern.startsWith("/") && urlPattern.endsWith("/*")) { path = urlPattern.substring(1, urlPattern.length() - 1); } else { throw failure("Illegal url pattern " + urlPattern); } // WebArchive war = createDeployment(asDefault, config.getApplications()); AbstractWebTestCase.path = path; AbstractWebTestCase.servlet = true; // Descriptor String servlet = config.toWebXml(); // Descriptor war.setWebXML(new StringAsset(servlet)); // return war; } public static WebArchive createPortletDeployment(String packageName, URL portletXML) { return createPortletDeployment(DescriptorBuilder.DEFAULT.portletApp(packageName, "JuzuPortlet"), new UrlAsset(portletXML)); } public static WebArchive createPortletDeployment(String packageName) { return createPortletDeployment(InjectorProvider.GUICE, RunMode.PROD, packageName); } public static WebArchive createPortletDeployment(InjectorProvider injector, String packageName) { return createPortletDeployment(injector, RunMode.PROD, packageName); } public static WebArchive createPortletDeployment(RunMode runMode, String packageName) { return createPortletDeployment(InjectorProvider.GUICE, runMode, packageName); } public static WebArchive createPortletDeployment(InjectorProvider injector, RunMode runMode, String packageName) { return createPortletDeployment(DescriptorBuilder.DEFAULT.injector(injector).runMode(runMode), packageName); } public static WebArchive createPortletDeployment(DescriptorBuilder config, String packageName) { config = config.portletApp(packageName, "JuzuPortlet"); return createPortletDeployment(config, new StringAsset(config.toPortletXml())); } public static WebArchive createPortletDeployment(DescriptorBuilder config, Asset portletXML) { // WebArchive war = createDeployment(asDefault, config.getApplications()); AbstractWebTestCase.path = null; AbstractWebTestCase.servlet = false; // String sourcePath; try { sourcePath = config.getRunMode().isDynamic() ? getCompiler().getSourcePath().getRoot().getCanonicalFile().getAbsolutePath() : ""; } catch (IOException e) { throw failure("Could not read obtain source path", e); } // if (sourcePath != null) { config = config.sourcePath(sourcePath); } // web.xml descriptor config = config.embedPortletContainer(); war.setWebXML(new StringAsset(config.toWebXml())); war.addAsWebInfResource(portletXML, "portlet.xml"); // return war; } @ArquillianResource protected URL deploymentURL; /** * Returns the URL for portlet unit test. * * @return the base portlet URL */ public URL getPortletURL() { try { return deploymentURL.toURI().resolve("embed/JuzuPortlet").toURL(); } catch (Exception e) { throw failure(e); } } /** * Returns the URL for servlet unit test. * * @return the base servlet URL */ public URL getServletURL() { return getServletURL(""); } /** * Returns the URL for servlet unit test and the specified path. * * @return the base servlet URL */ public URL getServletURL(String path) { // Remove any leading / if (path.startsWith("/")) { path = path.substring(1); } // URI base; try { URI uri = deploymentURL.toURI(); // uri = uri.resolve(AbstractWebTestCase.path); // if (asDefault) { base = uri; } else { base = uri.resolve(getApplicationName().getIdentifier()); } base = base.resolve(path); return base.toURL(); } catch (Exception e) { throw failure("Could not build application url " + path, e); } } public void assertInternalError() { WebClient client = new WebClient(); try { Page page = client.getPage(deploymentURL + "/juzu"); throw failure("Was expecting an internal error instead of page " + page.toString()); } catch (FailingHttpStatusCodeException e) { assertEquals(500, e.getStatusCode()); } catch (IOException e) { throw failure("Was not expecting io exception", e); } } public UserAgent assertInitialPage() { return new UserAgent(applicationURL()); } public URL applicationURL() { if (servlet) { return getServletURL(); } else { return getPortletURL(); } } public URL applicationURL(String path) { if (servlet) { return getServletURL(path); } else { throw failure("Cannot invoke portlet test with a path: " + path); } } public static int getContainerPort() { String port = System.getProperty("tomcat.http.port"); if (port == null) { throw failure("No port set"); } else { try { return Integer.parseInt(port); } catch (NumberFormatException e) { throw failure("Could not parse port " + port); } } } }