org.xwiki.flamingo.test.ui.HTMLExportTest.java Source code

Java tutorial

Introduction

Here is the source code for org.xwiki.flamingo.test.ui.HTMLExportTest.java

Source

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.xwiki.flamingo.test.ui;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Rule;
import org.junit.Test;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.test.ui.AbstractTest;
import org.xwiki.test.ui.SuperAdminAuthenticationRule;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
 * Verify that the HTML export features works fine.
 *
 * @version $Id: 84a3ebbeb8d5a051cc84b0af4ca7d48fb0a6b6f0 $
 */
public class HTMLExportTest extends AbstractTest {
    @Rule
    public SuperAdminAuthenticationRule adminAuthenticationRule = new SuperAdminAuthenticationRule(getUtil());

    private interface PageValidator {
        void validate(ZipInputStream zis, ZipEntry entry) throws Exception;

        void assertResult();
    }

    private class TopPageValidator implements PageValidator {
        private boolean result;

        @Override
        public void validate(ZipInputStream zis, ZipEntry entry) throws Exception {
            if (entry.getName().equals("pages/xwiki/TopPage/WebHome.html")) {
                String content = IOUtils.toString(zis, Charset.defaultCharset());

                // Verify that the content was rendered properly
                assertTrue("Title should have contained 'Top content'", content.contains("Top content"));
                assertTrue("Content should have contained 'Top title: Creator'",
                        content.contains("Top title: Creator"));
                this.result = true;
            }
        }

        @Override
        public void assertResult() {
            assertTrue("Failed to find the pages/xwiki/TopPage/WebHome.html entry", this.result);
        }
    }

    private class NestedPageValidator implements PageValidator {
        private boolean result;

        @Override
        public void validate(ZipInputStream zis, ZipEntry entry) throws Exception {
            if (entry.getName().equals("pages/xwiki/TopPage/NestedPage/WebHome.html")) {
                String content = IOUtils.toString(zis, Charset.defaultCharset());

                // Verify that the link to a locally exported page is correct
                assertTrue("Content should have contained a local link to the Top page",
                        content.contains("<a href=\"../../../../pages/xwiki/TopPage/WebHome.html\">top</a>"));
                this.result = true;
            }
        }

        @Override
        public void assertResult() {
            assertTrue("Failed to find the pages/xwiki/TopPage/NestedPage/WebHome.html entry", this.result);
        }
    }

    @Test
    public void exportHTML() throws Exception {
        // Step 1: Create 2 pages that we'll then export

        EntityReference topReference = getUtil().resolveDocumentReference("TopPage.WebHome");
        getUtil().deletePage(topReference);
        EntityReference nestedReference = getUtil().resolveDocumentReference("TopPage.NestedPage.WebHome");
        getUtil().deletePage(nestedReference);

        // Note: Verify that Velocity is correctly evaluated
        getUtil().createPage(topReference, "Top content", "Top title: $services.localization.render('creator')");
        // Note: we define a link to the top page to verify that the export will resolve the links locally when the
        // page linked is part of the export.
        getUtil().createPage(nestedReference, "[[top>>TopPage.WebHome]]", "Nested Page");

        // Step 2: Call the export URL to get the ZIP and to assert its content, when no "pages" query string param is
        //         used (only the TopPage will be exported)
        assertHTMLExportURL("http://localhost:8080/xwiki/bin/export/TopPage/WebHome?format=html",
                Arrays.asList(new TopPageValidator()));

        // Step 3: Call the export URL to get the ZIP and to assert its content, when a "pages" query string param is
        //         used with some regex
        assertHTMLExportURL("http://localhost:8080/xwiki/bin/export/UnexistingSpace/UnexistingPage?format=html"
                + "&pages=TopPage.%25", Arrays.asList(new TopPageValidator(), new NestedPageValidator()));
    }

    private void assertHTMLExportURL(String htmlExportURL, List<PageValidator> validators) throws Exception {
        URL url = new URL(htmlExportURL);

        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        InputStream is = connection.getInputStream();
        ZipInputStream zis = new ZipInputStream(is);

        boolean foundResourcesDirectory = false;
        boolean foundSkinsDirectory = false;
        boolean foundSkinCSS = false;
        boolean foundWebjars = false;

        // We must read the full stream as otherwise if we close it before we've fully read it
        // then the server side will get a broken pipe since it's still trying to send data on it.
        for (ZipEntry entry; (entry = zis.getNextEntry()) != null; zis.closeEntry()) {
            for (PageValidator validator : validators) {
                validator.validate(zis, entry);
            }
            if (entry.getName().endsWith(".vm")) {
                fail("There shouldn't be any *.vm files in the generated zip!");
            } else if (entry.getName().endsWith(".less")) {
                fail("There shouldn't be any *.less files in the generated zip!");
            } else if (entry.getName().equals("xwiki.properties")) {
                fail("There shouldn't be any xwiki.properties file in the generated zip!");
            } else if (entry.getName().startsWith("resources/")) {
                foundResourcesDirectory = true;
                IOUtils.readLines(zis, Charset.defaultCharset());
            } else if (entry.getName().startsWith("skins/")) {
                foundSkinsDirectory = true;
                // Verify that the skin is correctly going to be applied by verifying the flamingo/style.css file is
                // found and is correctly referenced. This fixes https://jira.xwiki.org/browse/XWIKI-9145
                if (entry.getName().equals("skins/flamingo/style.css")) {
                    assertSkinIsActive(IOUtils.readLines(zis, Charset.defaultCharset()));
                    foundSkinCSS = true;
                } else {
                    IOUtils.readLines(zis, Charset.defaultCharset());
                }
            } else if (entry.getName().startsWith("webjars")) {
                // We verify here that webjars URLs have been properly exported
                foundWebjars = true;
                IOUtils.readLines(zis, Charset.defaultCharset());
            } else {
                IOUtils.readLines(zis, Charset.defaultCharset());
            }
        }

        for (PageValidator validator : validators) {
            validator.assertResult();
        }
        assertTrue("Failed to find the resources/ directory entry", foundResourcesDirectory);
        assertTrue("Failed to find the skins/ directory entry", foundSkinsDirectory);
        assertTrue("Failed to find the link to colibri.css in style.css", foundSkinCSS);
        assertTrue("Failed to find webjar resources in the HTML export", foundWebjars);

        zis.close();
    }

    private void assertSkinIsActive(List<String> content) throws Exception {
        assertTrue("style.css is not the one output by the flamingo skin",
                StringUtils.join(content.toArray()).contains("skin-flamingo"));
    }
}