All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.javalite.activeweb.ViewSpec Maven / Gradle / Ivy

package org.javalite.activeweb;


import com.google.inject.Injector;
import org.javalite.activeweb.freemarker.ContentTL;
import org.javalite.activeweb.freemarker.FreeMarkerTag;
import org.javalite.activeweb.freemarker.FreeMarkerTemplateManager;
import org.junit.After;
import org.junit.Before;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;

import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.javalite.common.Collections.map;

/**
 * This is a spec used to test templates and custom tags.
 *
 * @author Max Artyukhov
 */
public abstract class ViewSpec extends SpecHelper {

    private FreeMarkerTemplateManager manager;

    public ViewSpec(){
        manager = new FreeMarkerTemplateManager();
        manager.setTemplateLocation("src/main/webapp/WEB-INF/views");
    }


    @Before
    public final void beforeTest(){
        MockHttpServletRequest request = new MockHttpServletRequest();
        request.setContextPath("/test_context");
        RequestContext.setTLs(request, new MockHttpServletResponse(), new MockFilterConfig(), new AppContext(), new RequestVo(), null);
    }

    @After
    public final void afterTest(){
        RequestContext.clear();
    }

    /**
     * By default the template location is set to src/main/webapp/WEB-INF/views.
     * However in some cases you want to have test templates that are different
     * from runtime templates. In those cases you can override that default
     * location with your value,
     *
     * @param templateLocation location of your templates relative to the directory
     * where test is executed, usually a root of your Maven module
     */
    @Override
    public void setTemplateLocation(String templateLocation){
        manager.setTemplateLocation(templateLocation);
    }

    /**
     * Sets injector for tags if they require dependencies.
     *
     * @param injector injector to source dependencies form.
     */
    @Override
    protected void setInjector(Injector injector){
        Configuration.setInjector(injector);
    }

    /**
     * Use to register a tag before the test.
     *
     * @param name name of tag as used in a template.
     * @param tag tag instance
     */
    @Override
    protected void registerTag(String name, FreeMarkerTag tag) {
        manager.registerTag(name, tag);
        Injector injector = Configuration.getInjector();
        if(injector != null)
            injector.injectMembers(tag);
    }

    /**
     * Renders a template by name
     *
     * @param templateName name of template to render
     * @return rendered template
     */
    protected String render(String templateName) {
        return render(templateName, new HashMap());
    }

    /**
     * Renders a template by name
     *
     * @param templateName name of template to render
     * @param values values to be passed into template
     * @return rendered template content as string
     */
    protected String render(String templateName, Map values) {
        StringWriter stringWriter = new StringWriter();

        ParamCopy.copyInto(values);

        manager.merge(values, templateName, stringWriter);
        return stringWriter.toString();
    }

/**
     * Renders a template by name.
     *
     * @param templateName name of template to render
     * @param namesAndValues - list of names and values, where first, third, etc argument is a name and second,
     * fourth, etc. argument is a corresponding value.
     * @return rendered template content as string
     */
    protected String render(String templateName, String ... namesAndValues) {
        return render(templateName, map(namesAndValues));
    }




    /**
     * This method is only needed as a hint to the {@link org.javalite.activeweb.freemarker.LinkToTag}. If the link_to
     * tag is used in a template without the controller attribute, it needs a current controller in context
     * to generate a proper link. At runtime as well as in controller tests, a controller is always present in context, and
     * link_to works as expected. However, since view specs are executed outside of controller execution,
     * if you have a link_to in the template you are testing, you will need to provide a clue to your view
     * before the test is executed.
     *
     * @param controllerClass controller class to aid to the link_to tag to generate a proper link.
     */
    protected  void setCurrentController(Class controllerClass){
        try{
            AppController instance = controllerClass.getDeclaredConstructor().newInstance();
            RequestContext.setRoute(new Route(instance));

        }catch(Exception e){
            throw new ViewException(e);
        }
    }


    /**
     * This method returns chunks of content that was assigned from a tested template. Call this method after rendering a view
     * in order to verify that the view did set appropriate text chunks with the {@link org.javalite.activeweb.freemarker.ContentForTag}
     * when it is used in a template, example:
     * 
     * 
     *<@content for="title">Book title</@content>
     * 
     * 
* * @param name name of a content piece as was specified by the "for" attribute of the "content" tag. * @return piece of content assigned from "content" tag if one was used in a tested view. */ protected List contentFor(String name){ return ContentTL.getAllContent().get(name); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy