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

grails.plugin.json.view.test.JsonViewTest.groovy Maven / Gradle / Ivy

Go to download

Provides additional view technologies to the Grails framework, including JSON and Markup views.

The newest version!
package grails.plugin.json.view.test

import grails.core.GrailsApplication
import grails.plugin.json.view.JsonViewConfiguration
import grails.plugin.json.view.JsonViewTemplateEngine
import grails.plugin.json.view.api.JsonView
import grails.plugin.json.view.api.jsonapi.DefaultJsonApiIdRenderer
import grails.plugin.json.view.api.jsonapi.JsonApiIdRenderStrategy
import grails.views.api.HttpView
import grails.views.api.http.Response
import grails.web.mapping.LinkGenerator
import grails.web.mime.MimeUtility
import groovy.json.JsonSlurper
import groovy.text.Template
import groovy.transform.CompileStatic
import org.grails.datastore.mapping.keyvalue.mapping.config.KeyValueMappingContext
import org.grails.datastore.mapping.model.MappingContext
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.MessageSource
import org.springframework.context.support.StaticMessageSource
import org.springframework.http.HttpStatus

/**
 * A trait that test classes can implement to add support for easily testing JSON views
 *
 * @author Graeme Rocher
 * @since 1.1.0
 */

@CompileStatic
trait JsonViewTest {

    @Autowired(required = false)
    MessageSource messageSource = new StaticMessageSource()

    @Autowired(required = false)
    MappingContext mappingContext = {
        def ctx = new KeyValueMappingContext("test")
        ctx.setCanInitializeEntities(true)
        return ctx
    }()

    @Autowired(required = false)
    MimeUtility mimeUtility

    @Autowired(required = false)
    LinkGenerator linkGenerator = new TestLinkGenerator(mappingContext)

    @Autowired(required = false)
    JsonViewConfiguration viewConfiguration = new JsonViewConfiguration()

    @Autowired(required = false)
    void setGrailsApplication(GrailsApplication grailsApplication) {
        viewConfiguration.setGrailsApplication(grailsApplication)
    }

    @Autowired(required = false)
    JsonApiIdRenderStrategy jsonApiIdRenderStrategy = new DefaultJsonApiIdRenderer()

    @Lazy JsonViewTemplateEngine templateEngine = {

        def templateEngine = new JsonViewTemplateEngine(viewConfiguration, Thread.currentThread().contextClassLoader)
        if(messageSource != null) {
            templateEngine.setMessageSource(messageSource)
        }
        templateEngine.setLinkGenerator(linkGenerator)
        if(mimeUtility != null) {
            templateEngine.setMimeUtility(mimeUtility)
        }
        if(mappingContext != null) {
            templateEngine.setMappingContext(mappingContext)
        }
        templateEngine.setJsonApiIdRenderStrategy(jsonApiIdRenderStrategy)
        return templateEngine
    }()

    /**
     * Render a template for the given source
     *
     * @param source The raw source of the template
     * @param model The model
     *
     * @return The result
     */
    JsonRenderResult render(String source) {
        render(source, Collections.emptyMap(), null)
    }

    /**
     * Render a template for the given source
     *
     * @param source The raw source of the template
     * @param model The model
     *
     * @return The result
     */
    JsonRenderResult render(String source, Map model) {
        render(source, model, null)
    }

    /**
     * Render a template for the given source
     *
     * @param source The raw source of the template
     * @param model The model
     * @param configurer The configurer
     *
     * @return The result
     */
    JsonRenderResult render(String source, Map model, @DelegatesTo(TestRequestConfigurer) Closure configurer) {
        def template = templateEngine.createTemplate(source)
        return produceResult(template, model, configurer)
    }

    /**
     * Render a template for the given source
     *
     * @param source The raw source of the template
     * @param model The model
     * @param configurer The configurer
     *
     * @return The result
     */
    JsonRenderResult render(String source, @DelegatesTo(TestRequestConfigurer) Closure configurer) {
        def template = templateEngine.createTemplate(source)
        return produceResult(template, Collections.emptyMap(), configurer)
    }
    /**
     * Render one of the GSON views in the grails-app/views directory for the given arguments
     *
     * @param arguments The named arguments: 'template', 'view' and 'model'
     *
     * @return The render result
     */
    JsonRenderResult render(Map arguments) {
        render arguments, null
    }

    /**
     * Render one of the GSON views in the grails-app/views directory for the given arguments
     *
     * @param arguments The named arguments: 'template', 'view' and 'model'
     * @param configurer The configurer for modifying the request state of the view
     *
     * @return The render result
     */
    JsonRenderResult render(Map arguments, @DelegatesTo(TestRequestConfigurer) Closure configurer) {

        String viewUri
        if( arguments.template ) {
            viewUri = templateEngine
                            .viewUriResolver
                            .resolveTemplateUri(null, arguments.template.toString())

        }
        else if( arguments.view ) {
            viewUri = arguments.view.toString()
        }
        else {
            throw new IllegalArgumentException("Either a 'view' or 'template' argument is required!")

        }
        def template = templateEngine.resolveTemplate(viewUri)

        if(template == null) {
            throw new IllegalArgumentException("No view or template found for URI $viewUri")
        }

        def model = arguments.model instanceof Map ? (Map)arguments.model : [:]
        return produceResult(template, model, configurer)
    }

    private JsonRenderResult produceResult(Template template, Map model, Closure configurer) {
        JsonView writable = (JsonView) template.make(model)
        if (configurer != null) {
            def rc = new TestRequestConfigurer(writable)
            configurer.delegate = rc
            configurer.call()
        }

        def result = new JsonRenderResult()
        if (writable instanceof HttpView) {
            def httpView = (HttpView) writable
            httpView.setResponse(new TestHttpResponse(result))
        }

        def sw = new StringWriter()
        writable.writeTo(sw)
        def str = sw.toString()
        result.jsonText = str
        result.json = new JsonSlurper().parseText(str)
        return result
    }

    static class TestHttpResponse implements Response {
        final JsonRenderResult result

        TestHttpResponse(JsonRenderResult result) {
            this.result = result
        }

        @Override
        void header(String name, String value) {
            result.headers[name] = value
        }

        @Override
        void header(Map nameAndValue) {
            result.headers.putAll(nameAndValue)
        }

        @Override
        void headers(Map namesAndValues) {
            result.headers.putAll(namesAndValues)
        }

        @Override
        void contentType(String contentType) {
            result.contentType = contentType
        }

        @Override
        void encoding(String encoding) {
            // ignore
        }

        @Override
        void status(int status) {
            result.status = HttpStatus.valueOf(status)
        }

        @Override
        void status(int status, String message) {
            result.status = HttpStatus.valueOf(status)
            result.message = message
        }

        @Override
        void status(HttpStatus status) {
            result.status = status
            result.message = status.getReasonPhrase()
        }

        @Override
        void status(HttpStatus status, String message) {
            result.status = status
            result.message = message
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy