Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 95673bbc5e
Fetching contributors…

Cannot retrieve contributors at this time

218 lines (185 sloc) 8.788 kb
/*
* Copyright 2004-2005 the original author or authors.
*
* 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 grails.test
import grails.util.GrailsWebUtil
import org.apache.commons.lang.StringUtils
import org.codehaus.groovy.grails.commons.DefaultGrailsApplication
import org.codehaus.groovy.grails.commons.GrailsApplication
import org.codehaus.groovy.grails.commons.GrailsClassUtils
import org.codehaus.groovy.grails.plugins.web.mapping.UrlMappingsGrailsPlugin
import org.codehaus.groovy.grails.support.MockApplicationContext
import org.codehaus.groovy.grails.web.mapping.DefaultUrlMappingEvaluator
import org.codehaus.groovy.grails.web.mapping.DefaultUrlMappingsHolder
import org.codehaus.groovy.grails.web.multipart.ContentLengthAwareCommonsMultipartResolver
import org.springframework.core.io.support.PathMatchingResourcePatternResolver
import org.springframework.web.context.WebApplicationContext
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.servlet.DispatcherServlet
import org.codehaus.groovy.grails.commons.GrailsControllerClass
import org.springframework.web.context.ServletContextAware
import javax.servlet.ServletContext
import org.codehaus.groovy.grails.commons.GrailsClassUtils
import org.springframework.beans.BeanUtils
/**
* @author Luke Daley
*/
class GrailsUrlMappingsTestCase extends GroovyTestCase {
def webRequest
def mappingsHolder
def controllers
def assertionKeys = ["controller", "action", "view"]
def patternResolver = new PathMatchingResourcePatternResolver()
def classLoader = new GroovyClassLoader()
def mappingEvaluator
def grailsApplication
def createMappingsHolder() {
new DefaultUrlMappingsHolder(
urlMappingEvaluatees.collect {
mappingEvaluator.evaluateMappings((it instanceof Closure) ? it : GrailsClassUtils.getStaticPropertyValue(it, "mappings"))
}.flatten()
)
}
def createControllerMap() {
controllers = [:]
grailsApplication.controllerClasses.each { GrailsControllerClass cc ->
controllers[cc.logicalPropertyName] = cc.newInstance()
}
controllers
}
def getUrlMappingEvaluatees() {
def m = GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(this, "mappings")
if (m == null) {
return grailsApplication.urlMappingsClasses*.clazz
}
if (mappings instanceof Closure || mappings instanceof Class) {
return [mappings]
}
return mappings
}
void setUp() {
webRequest = RequestContextHolder.currentRequestAttributes()
mappingEvaluator = new DefaultUrlMappingEvaluator(webRequest.servletContext)
mappingsHolder = createMappingsHolder()
controllers = createControllerMap()
}
void tearDown() {
RequestContextHolder.resetRequestAttributes()
}
def getActions(controller) {
def instance = controllers[controller]
BeanUtils.getPropertyDescriptors(instance.class).findAll {
GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(instance, it.name) instanceof Closure
}.collect {
StringUtils.substringBeforeLast(it.name, "Flow")
}
}
def getDefaultAction(controllerName) {
def controller = controllers[controllerName]
(controller.class.declaredFields.find { it.name == "defaultAction" }) ? controller.defaultAction : "index"
}
def assertController(controller, url) {
if (!controllers.containsKey(controller)) {
throw new IllegalArgumentException("Url mapping assertion for '$url' failed, '$controller' is not a valid controller")
}
}
def assertAction(controller, action, url) {
if (!getActions(controller).contains(action)) {
throw new IllegalArgumentException("Url mapping assertion for '$url' failed, '$action' is not a valid action of controller '$controller'")
}
}
def assertView(controller, view, url) {
def pathPattern = "grails-app/views/" + ((controller) ? "$controller/" : "") + "${view}.*"
if (!patternResolver.getResources(pathPattern)) {
throw new IllegalArgumentException(
(controller) ? "Url mapping assertion for '$url' failed, '$view' is not a valid view of controller '$controller'" : "Url mapping assertion for '$url' failed, '$view' is not a valid view"
)
}
}
void assertUrlMapping(assertions, url) {
assertUrlMapping(assertions, url, null);
}
void assertUrlMapping(assertions, url, paramAssertions) {
assertForwardUrlMapping(assertions, url, paramAssertions)
if (assertions.controller && !(url instanceof Integer)) {
assertReverseUrlMapping(assertions, url, paramAssertions)
}
}
void assertForwardUrlMapping(assertions, url) {
assertForwardUrlMapping(assertions, url, null)
}
void assertForwardUrlMapping(assertions, url, paramAssertions) {
if (assertions.action && !assertions.controller) {
throw new IllegalArgumentException("Cannot assert action for url mapping without asserting controller")
}
if (assertions.controller) assertController(assertions.controller, url)
if (assertions.action) assertAction(assertions.controller, assertions.action, url)
if (assertions.view) assertView(assertions.controller, assertions.view, url)
def mappingInfos
if (url instanceof Integer) {
mappingInfos = []
def mapping = mappingsHolder.matchStatusCode(url)
if (mapping) mappingInfos << mapping
}
else {
mappingInfos = mappingsHolder.matchAll(url)
}
if (mappingInfos.size() == 0) throw new IllegalArgumentException("url '$url' did not match any mappings")
mappingInfos.find {mapping ->
mapping.configure(webRequest)
for (key in assertionKeys) {
if (assertions.containsKey(key)) {
def expected = assertions[key]
def actual = mapping."${key}Name"
// if this is not a match and there are still more potential matches try the next one
if (!controllers.containsKey(actual) && mappingInfos.size() > 1) return
if (key == "view") {
if (actual[0] == "/") actual = actual.substring(1)
if (expected[0] == "/") expected = expected.substring(1)
}
if (key == "action" && actual == null) actual = getDefaultAction(assertions.controller)
assertEquals("Url mapping $key assertion for '$url' failed", expected, actual)
}
}
if (paramAssertions) {
def params = [:]
paramAssertions.delegate = params
paramAssertions.resolveStrategy = Closure.DELEGATE_ONLY
paramAssertions.call()
params.each {name, value ->
assertEquals("Url mapping '$name' parameter assertion for '$url' failed", value.toString(), mapping.params[name])
}
}
true
}
}
void assertReverseUrlMapping(assertions, url) {
assertReverseUrlMapping(assertions, url, null)
}
void assertReverseUrlMapping(assertions, url, paramAssertions) {
def controller = assertions.controller
def action = assertions.action
def params = [:]
if (paramAssertions) {
paramAssertions.delegate = params
paramAssertions.resolveStrategy = Closure.DELEGATE_ONLY
paramAssertions.call()
}
def urlCreator = mappingsHolder.getReverseMapping(controller, action, params)
assertNotNull("could not create reverse mapping of '$url' for {controller = $controller, action = $action, params = $params}", urlCreator)
def createdUrl = urlCreator.createRelativeURL(controller, action, params, "UTF-8")
assertEquals("reverse mapping assertion for {controller = $controller, action = $action, params = $params}", url, createdUrl)
}
}
Jump to Line
Something went wrong with that request. Please try again.