@@ -10,14 +10,84 @@ import org.grails.web.mapping.DefaultUrlMappingInfo
1010import org.grails.web.mapping.mvc.GrailsControllerUrlMappings
1111import org.grails.web.mapping.mvc.UrlMappingsHandlerMapping
1212import org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter
13+ import org.grails.web.util.WebUtils
1314import org.springframework.web.context.request.RequestContextHolder
1415import org.springframework.web.servlet.view.InternalResourceView
16+ import spock.lang.Issue
1517
1618/**
1719 * Created by graemerocher on 26/05/14.
1820 */
1921class UrlMappingsHandlerMappingSpec extends AbstractUrlMappingsSpec {
2022
23+ void " Test that when a request coming from a 404 forward is matched the correct action is executed" () {
24+ given :" A URL mapping definition that has a 404 mapping"
25+ def grailsApplication = new DefaultGrailsApplication (FooController )
26+ grailsApplication. initialise()
27+ def holder = getUrlMappingsHolder {
28+ " /foo/bar" (controller :" foo" , action :" bar" )
29+ " /foo/error" (controller :" foo" , action :" error" )
30+ " 404" (controller : " foo" , action :" notFound" )
31+ }
32+
33+ holder = new GrailsControllerUrlMappings (grailsApplication, holder)
34+ def handler = new UrlMappingsHandlerMapping (holder)
35+
36+ when :" A request that contains a 404 error status code is handled"
37+ def webRequest = GrailsWebMockUtil . bindMockWebRequest()
38+ webRequest. renderView = true
39+ def request = webRequest. request
40+ request. setRequestURI(" /foo/notThere" )
41+ request. setAttribute(WebUtils . ERROR_STATUS_CODE_ATTRIBUTE , " 404" )
42+ def handlerChain = handler. getHandler(request)
43+
44+ then :" The handler chain is not null"
45+ handlerChain != null
46+
47+ when :" A HandlerAdapter is used"
48+ def handlerAdapter = new UrlMappingsInfoHandlerAdapter ()
49+ def result = handlerAdapter. handle(request, webRequest. response, handlerChain. handler)
50+
51+ then :" The controller action that is mapped to the 404 handler is executed"
52+ webRequest. response. contentAsString == ' Not Found'
53+ }
54+
55+ @Issue (' https://github.com/grails/grails-core/issues/10149' )
56+ void " Test that when an include request from within a 404 forward is matched" () {
57+ given :" A URL mapping definition that has a 404 mapping"
58+ def grailsApplication = new DefaultGrailsApplication (FooController )
59+ grailsApplication. initialise()
60+ def holder = getUrlMappingsHolder {
61+ " /foo/bar" (controller :" foo" , action :" bar" )
62+ " /foo/error" (controller :" foo" , action :" error" )
63+ " 404" (controller : " foo" , action :" notFound" )
64+ }
65+
66+ holder = new GrailsControllerUrlMappings (grailsApplication, holder)
67+ def handler = new UrlMappingsHandlerMapping (holder)
68+
69+ when :" A request arrives that is an include within a 404 forward request"
70+ def webRequest = GrailsWebMockUtil . bindMockWebRequest()
71+ webRequest. renderView = true
72+ def request = webRequest. request
73+ request. setRequestURI(" /foo/notThere" )
74+ request. setAttribute(WebUtils . ERROR_STATUS_CODE_ATTRIBUTE , " 404" )
75+ request. setAttribute(WebUtils . INCLUDE_REQUEST_URI_ATTRIBUTE , " /foo/bar" )
76+ def handlerChain = handler. getHandler(request)
77+
78+ then :" The handler chain is not null"
79+ handlerChain != null
80+
81+ when :" A HandlerAdapter is used"
82+ def handlerAdapter = new UrlMappingsInfoHandlerAdapter ()
83+ def result = handlerAdapter. handle(request, webRequest. response, handlerChain. handler)
84+
85+ then :" The correct action was executed to handle the include"
86+ result. viewName == ' bar'
87+ result. model == [foo :' bar' ]
88+
89+ }
90+
2191 void " Test that a matched URL returns a URLMappingInfo" () {
2292
2393 given :
@@ -93,4 +163,9 @@ class FooController {
93163 def error () {
94164 RequestContextHolder . currentRequestAttributes(). response. sendError(405 )
95165 }
166+
167+ @Action
168+ def notFound () {
169+ RequestContextHolder . currentRequestAttributes(). response. writer << " Not Found"
170+ }
96171}
0 commit comments