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