<commit_before>/*
 * 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.test.page;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.xwiki.cache.Cache;
import org.xwiki.cache.CacheManager;
import org.xwiki.cache.config.CacheConfiguration;
import org.xwiki.context.Execution;
import org.xwiki.context.ExecutionContext;
import org.xwiki.context.ExecutionContextManager;
import org.xwiki.environment.Environment;
import org.xwiki.job.event.status.JobProgressManager;
import org.xwiki.management.JMXBeanRegistration;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.SpaceReference;
import org.xwiki.query.Query;
import org.xwiki.rendering.internal.transformation.MutableRenderingContext;
import org.xwiki.rendering.syntax.Syntax;
import org.xwiki.rendering.transformation.RenderingContext;
import org.xwiki.resource.internal.entity.EntityResourceActionLister;
import org.xwiki.test.annotation.AfterComponent;
import org.xwiki.test.annotation.BeforeComponent;
import org.xwiki.test.mockito.MockitoComponentManagerRule;
import org.xwiki.velocity.VelocityManager;

import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.internal.cache.rendering.RenderingCache;
import com.xpn.xwiki.test.MockitoOldcoreRule;
import com.xpn.xwiki.test.reference.ReferenceComponentList;
import com.xpn.xwiki.web.XWikiServletRequestStub;
import com.xpn.xwiki.web.XWikiServletResponseStub;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
 * Tests that wishes to unit test wiki page should extend this class and call {@link #renderPage(DocumentReference)}
 * to load and render a page located in the classpath.
 *
 * @version $Id$
 * @since 7.3M1
 */
@PageComponentList
@ReferenceComponentList
public class PageTest
{
    /**
     * Page tests use the Oldcore rule to configure some base mocks (such as XWiki).
     */
    @Rule
    public MockitoOldcoreRule oldcore = new MockitoOldcoreRule();

    /**
     * The stubbed request used to simulate a real Servlet Request.
     */
    protected XWikiServletRequestStub request;

    /**
     * The stubbed response used to simulate a real Servlet Response.
     */
    protected XWikiServletResponseStub response;

    /**
     * The mocked XWiki instance, provided for ease of use (can also be retrieved through {@link #oldcore}).
     */
    protected XWiki xwiki;

    /**
     * The configured XWiki Context, provided for ease of use (can also be retrieved through {@link #oldcore}).
     */
    protected XWikiContext context;

    /**
     * The Component Manager to use for getting Component instances or registering Mock Components in the test,
     * provided for ease of use (can also be retrieved through {@link #oldcore}).
     */
    protected MockitoComponentManagerRule mocker = oldcore.getMocker();

    /**
     * Set up components before Components declared in {@link org.xwiki.test.annotation.ComponentList} are handled.
     *
     * @throws Exception in case of errors
     */
    @BeforeComponent
    public void setUpComponentsForPageTest() throws Exception
    {
        mocker.registerMockComponent(JMXBeanRegistration.class);
        mocker.registerMockComponent(Environment.class);
        mocker.registerMockComponent(JobProgressManager.class);
        mocker.registerMockComponent(RenderingCache.class);
        mocker.registerMockComponent(EntityResourceActionLister.class);

        CacheManager cacheManager = mocker.registerMockComponent(CacheManager.class);
        when(cacheManager.createNewCache(any(CacheConfiguration.class))).thenReturn(mock(Cache.class));
    }

    /**
     * Set up of Components after the Components declared in {@link org.xwiki.test.annotation.ComponentList} have been
     * handled but before {@link MockitoOldcoreRule#before(Class)} has been called (i.e. before it has created Mocks
     * and configured Components).
     *
     * @throws Exception in case of errors
     */
    @AfterComponent
    public void configureComponentsBeforeOldcoreRuleForPageTest() throws Exception
    {
        // Configure the Execution Context
        ExecutionContext ec = new ExecutionContext();
        mocker.<Execution>getInstance(Execution.class).setContext(ec);
    }

    /**
     * @param documentReference the reference of the Document to load from the ClassLoader
     * @return the loaded document
     * @throws Exception in case of errors
     */
    protected XWikiDocument loadPage(DocumentReference documentReference) throws Exception
    {
        List<String> path = new ArrayList<>();
        for (SpaceReference spaceReference : documentReference.getSpaceReferences()) {
            path.add(spaceReference.getName());
        }
        path.add(documentReference.getName() + ".xml");
        XWikiDocument document = new XWikiDocument(documentReference);
        document.fromXML(getClass().getClassLoader().getResourceAsStream(StringUtils.join(path, '/')));
        this.xwiki.saveDocument(document, "registering document", true, this.context);
        return document;
    }

    /**
     * @param reference the reference of the Document to load and render (and thus load from the Classloader)
     * @return the result of rendering the Document corresponding to the passed reference
     * @throws Exception in case of errors
     */
    protected String renderPage(DocumentReference reference) throws Exception
    {
        return loadPage(reference).getRenderedContent(this.context);
    }

    /**
     * Sets the Syntax with which the Document to test will be rendered into. If not called, the Document will be
     * rendered as XHTML.
     *
     * @param syntax the Syntax to render the Document into
     * @throws Exception in case of errors
     */
    protected void setOutputSyntax(Syntax syntax) throws Exception
    {
        MutableRenderingContext renderingContext = mocker.getInstance(RenderingContext.class);
        renderingContext.push(renderingContext.getTransformation(), renderingContext.getXDOM(),
            renderingContext.getDefaultSyntax(), "test", renderingContext.isRestricted(), syntax);
    }

    /**
     * Configures the various Components and their mocks with default values for page tests.
     *<commit_msg>XWIKI-13650: $subHeading appearing in rendering syntax help page * Improve setup so that $doc in script in wiki pages is rendererd properly<commit_after>/*
 * 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.test.page;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.xwiki.cache.Cache;
import org.xwiki.cache.CacheManager;
import org.xwiki.cache.config.CacheConfiguration;
import org.xwiki.context.Execution;
import org.xwiki.context.ExecutionContext;
import org.xwiki.context.ExecutionContextManager;
import org.xwiki.environment.Environment;
import org.xwiki.job.event.status.JobProgressManager;
import org.xwiki.management.JMXBeanRegistration;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.SpaceReference;
import org.xwiki.query.Query;
import org.xwiki.rendering.internal.transformation.MutableRenderingContext;
import org.xwiki.rendering.syntax.Syntax;
import org.xwiki.rendering.transformation.RenderingContext;
import org.xwiki.resource.internal.entity.EntityResourceActionLister;
import org.xwiki.test.annotation.AfterComponent;
import org.xwiki.test.annotation.BeforeComponent;
import org.xwiki.test.mockito.MockitoComponentManagerRule;
import org.xwiki.velocity.VelocityManager;

import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.internal.cache.rendering.RenderingCache;
import com.xpn.xwiki.test.MockitoOldcoreRule;
import com.xpn.xwiki.test.reference.ReferenceComponentList;
import com.xpn.xwiki.web.XWikiServletRequestStub;
import com.xpn.xwiki.web.XWikiServletResponseStub;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
 * Tests that wishes to unit test wiki page should extend this class and call {@link #renderPage(DocumentReference)}
 * to load and render a page located in the classpath.
 *
 * @version $Id$
 * @since 7.3M1
 */
@PageComponentList
@ReferenceComponentList
public class PageTest
{
    /**
     * Page tests use the Oldcore rule to configure some base mocks (such as XWiki).
     */
    @Rule
    public MockitoOldcoreRule oldcore = new MockitoOldcoreRule();

    /**
     * The stubbed request used to simulate a real Servlet Request.
     */
    protected XWikiServletRequestStub request;

    /**
     * The stubbed response used to simulate a real Servlet Response.
     */
    protected XWikiServletResponseStub response;

    /**
     * The mocked XWiki instance, provided for ease of use (can also be retrieved through {@link #oldcore}).
     */
    protected XWiki xwiki;

    /**
     * The configured XWiki Context, provided for ease of use (can also be retrieved through {@link #oldcore}).
     */
    protected XWikiContext context;

    /**
     * The Component Manager to use for getting Component instances or registering Mock Components in the test,
     * provided for ease of use (can also be retrieved through {@link #oldcore}).
     */
    protected MockitoComponentManagerRule mocker = oldcore.getMocker();

    /**
     * Set up components before Components declared in {@link org.xwiki.test.annotation.ComponentList} are handled.
     *
     * @throws Exception in case of errors
     */
    @BeforeComponent
    public void setUpComponentsForPageTest() throws Exception
    {
        mocker.registerMockComponent(JMXBeanRegistration.class);
        mocker.registerMockComponent(Environment.class);
        mocker.registerMockComponent(JobProgressManager.class);
        mocker.registerMockComponent(RenderingCache.class);
        mocker.registerMockComponent(EntityResourceActionLister.class);

        CacheManager cacheManager = mocker.registerMockComponent(CacheManager.class);
        when(cacheManager.createNewCache(any(CacheConfiguration.class))).thenReturn(mock(Cache.class));
    }

    /**
     * Set up of Components after the Components declared in {@link org.xwiki.test.annotation.ComponentList} have been
     * handled but before {@link MockitoOldcoreRule#before(Class)} has been called (i.e. before it has created Mocks
     * and configured Components).
     *
     * @throws Exception in case of errors
     */
    @AfterComponent
    public void configureComponentsBeforeOldcoreRuleForPageTest() throws Exception
    {
        // Configure the Execution Context
        ExecutionContext ec = new ExecutionContext();
        mocker.<Execution>getInstance(Execution.class).setContext(ec);
    }

    /**
     * @param documentReference the reference of the Document to load from the ClassLoader
     * @return the loaded document
     * @throws Exception in case of errors
     */
    protected XWikiDocument loadPage(DocumentReference documentReference) throws Exception
    {
        List<String> path = new ArrayList<>();
        for (SpaceReference spaceReference : documentReference.getSpaceReferences()) {
            path.add(spaceReference.getName());
        }
        path.add(documentReference.getName() + ".xml");
        XWikiDocument document = new XWikiDocument(documentReference);
        document.fromXML(getClass().getClassLoader().getResourceAsStream(StringUtils.join(path, '/')));
        this.xwiki.saveDocument(document, "registering document", true, this.context);
        return document;
    }

    /**
     * @param reference the reference of the Document to load and render (and thus load from the Classloader)
     * @return the result of rendering the Document corresponding to the passed reference
     * @throws Exception in case of errors
     */
    protected String renderPage(DocumentReference reference) throws Exception
    {
        XWikiDocument doc = loadPage(reference);

        // Set up the current doc in the context so that $doc is bound in scripts
        context.setDoc(doc);

        return doc.getRenderedContent(this.context);
    }

    /**
     * Sets the Syntax with which the Document to test will be rendered into. If not called, the Document will be
     * rendered as XHTML.
     *
     * @param syntax the Syntax to render the Document into
     * @throws Exception in case of errors
     */
    protected void setOutputSyntax(Syntax syntax) throws Exception
    {
        MutableRenderingContext renderingContext = mocker.getInstance(RenderingContext.class);
        renderingContext.push(renderingContext.getTransformation(), renderingContext.getXDOM(),
            renderingContext.getDefaultSyntax(), "test", renderingContext.isRestricted(), syntax);
    }

    /**
     * Configures the various Components and their mocks with default values for page tests.
     *
{'fraction_non_alphanumeric': 0.08300132802124834, 'fraction_numerical': 0.002456839309428951, 'mean_word_length': 3.798024848677923, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4829706', 'n_tokens_mistral': 3993, 'n_tokens_neox': 3944, 'n_words': 1269}