Skip to content

Commit e76f08a

Browse files
committed
Merge pull request #342 from johnrengelman/filter-injection
GRAILS-8976 enable autowiring of Filters during unit test
2 parents c3827c1 + c14cc70 commit e76f08a

File tree

4 files changed

+106
-8
lines changed

4 files changed

+106
-8
lines changed

grails-plugin-filters/src/main/groovy/org/codehaus/groovy/grails/plugins/web/filters/FilterConfig.groovy

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,43 +74,48 @@ class FilterConfig extends ControllersApi {
7474
*/
7575
def propertyMissing(String propertyName) {
7676
// Delegate to the parent definition if it has this property.
77-
if (filtersDefinition.metaClass.hasProperty(filtersDefinition, propertyName)) {
77+
if (wiredFiltersDefinition.metaClass.hasProperty(wiredFiltersDefinition, propertyName)) {
7878
def getterName = GrailsClassUtils.getGetterName(propertyName)
79-
metaClass."$getterName" = {-> delegate.filtersDefinition.getProperty(propertyName) }
80-
return filtersDefinition."$propertyName"
79+
metaClass."$getterName" = {-> delegate.wiredFiltersDefinition.getProperty(propertyName) }
80+
return wiredFiltersDefinition."$propertyName"
8181
}
8282

8383
throw new MissingPropertyException(propertyName, filtersDefinition.getClass())
8484
}
8585

86+
def getWiredFiltersDefinition() {
87+
final grailsFilter = grailsApplication.getArtefact(FiltersConfigArtefactHandler.TYPE, filtersDefinition.class.name)
88+
applicationContext."${grailsFilter.fullName}"
89+
}
90+
8691
/**
8792
* When the filter does not have a particular method, it passes
8893
* the call on to the filter definition class.
8994
*/
9095
def methodMissing(String methodName, args) {
9196
// Delegate to the parent definition if it has this method.
92-
List<MetaMethod> respondsTo = filtersDefinition.metaClass.respondsTo(filtersDefinition, methodName, args)
97+
List<MetaMethod> respondsTo = wiredFiltersDefinition.metaClass.respondsTo(wiredFiltersDefinition, methodName, args)
9398
if (respondsTo) {
9499
// Use DelegateMetaMethod to proxy calls to actual MetaMethod for subsequent calls to this method
95100
DelegateMetaMethod dmm=new DelegateMetaMethod(respondsTo[0], FilterConfigDelegateMetaMethodTargetStrategy.instance)
96101
// register the metamethod to EMC
97102
metaClass.registerInstanceMethod(dmm)
98103

99104
// for this invocation we still have to make the call
100-
return respondsTo[0].invoke(filtersDefinition, args)
105+
return respondsTo[0].invoke(wiredFiltersDefinition, args)
101106
}
102107

103108
// Ideally, we would throw a MissingMethodException here
104109
// whether the filter config is intialised or not. However,
105110
// if it's in the initialisation phase, the MME gets swallowed somewhere.
106111
if (!initialised) {
107112
throw new IllegalStateException(
108-
"Invalid filter definition in ${filtersDefinition.getClass().name} - trying "
113+
"Invalid filter definition in ${wiredFiltersDefinition.getClass().name} - trying "
109114
+ "to call method '${methodName}' outside of an interceptor.")
110115
}
111116

112117
// The required method was not found on the parent filter definition either.
113-
throw new MissingMethodException(methodName, filtersDefinition.getClass(), args)
118+
throw new MissingMethodException(methodName, wiredFiltersDefinition.getClass(), args)
114119
}
115120

116121
String toString() {"FilterConfig[$name, scope=$scope]"}

grails-plugin-testing/src/main/groovy/grails/test/mixin/web/FiltersUnitTestMixin.groovy

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ class FiltersUnitTestMixin extends ControllerUnitTestMixin {
8686
arguments = [FiltersConfigArtefactHandler.TYPE, grailsFilter.fullName]
8787

8888
}
89-
"$grailsFilter.fullName"(grailsFilter.clazz)
89+
"$grailsFilter.fullName"(grailsFilter.clazz) { bean ->
90+
bean.scope = 'prototype'
91+
bean.autowire = true
92+
}
9093
}
9194

9295

grails-plugin-testing/src/test/groovy/grails/test/mixin/FiltersUnitTestMixinTests.groovy

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package grails.test.mixin
22

3+
import grails.test.GrailsMock
34
import grails.test.mixin.web.FiltersUnitTestMixin
45
import org.junit.Before
56
import org.junit.Test
7+
import org.springframework.beans.factory.config.MethodInvokingFactoryBean
68

79
@TestMixin(FiltersUnitTestMixin)
810
class FiltersUnitTestMixinTests {
911

1012
AuthorController controller
13+
GrailsMock autowiredServiceMock
1114

1215
@Before
1316
void setUp() {
@@ -72,6 +75,46 @@ class FiltersUnitTestMixinTests {
7275
assert request.filterView == null
7376
assert request.exception != null
7477
}
78+
79+
@Test
80+
void testFilterIsAutoWired() {
81+
defineBeans {
82+
autowiredService(MethodInvokingFactoryBean) {
83+
targetObject = this
84+
targetMethod = 'mockAutowiredService'
85+
}
86+
}
87+
mockFilters(AutowiredFilters)
88+
89+
withFilters(action:"list") {
90+
controller.list()
91+
}
92+
93+
autowiredServiceMock.verify()
94+
}
95+
96+
@Test
97+
void testFilterIsAutoWiredWithBeansDefinedAfterMocking() {
98+
mockFilters(AutowiredFilters)
99+
defineBeans {
100+
autowiredService(MethodInvokingFactoryBean) {
101+
targetObject = this
102+
targetMethod = 'mockAutowiredService'
103+
}
104+
}
105+
106+
withFilters(action:"list") {
107+
controller.list()
108+
}
109+
110+
autowiredServiceMock.verify()
111+
}
112+
113+
AutowiredService mockAutowiredService() {
114+
this.autowiredServiceMock = mockFor(AutowiredService)
115+
this.autowiredServiceMock.demand.setupSession(1) {}
116+
return this.autowiredServiceMock.createMock()
117+
}
75118
}
76119

77120
class AuthorController {
@@ -124,4 +167,22 @@ class ExceptionThrowingFilters {
124167
}
125168
}
126169
}
170+
}
171+
172+
class AutowiredFilters {
173+
174+
def autowiredService
175+
176+
def filters = {
177+
all(controller:"author", action:"list") {
178+
before = {
179+
autowiredService.setupSession()
180+
}
181+
}
182+
}
183+
}
184+
185+
class AutowiredService {
186+
187+
void setupSession() {}
127188
}

grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/filters/FiltersUnitTestSpec.groovy

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.codehaus.groovy.grails.web.filters
22

3+
import org.springframework.beans.factory.config.MethodInvokingFactoryBean
4+
35
import javax.servlet.http.HttpServletResponse
46
import grails.artefact.Artefact
57
import grails.test.mixin.TestFor
@@ -10,7 +12,17 @@ import spock.lang.Specification
1012
@TestFor(UserController)
1113
@Mock(AuthenticationFilters)
1214
class FiltersUnitTestSpec extends Specification{
15+
SecurityService securityServiceMock
16+
1317
void "test filters are applied for a unit test"() {
18+
given:"A mock for the injected security service"
19+
securityServiceMock = Mock(SecurityService)
20+
defineBeans {
21+
securityService(MethodInvokingFactoryBean) {
22+
targetObject = this
23+
targetMethod = 'getSecurityServiceMock'
24+
}
25+
}
1426
when:"A filter is used around a controller"
1527
params.username = ''
1628
withFilters(action: "create") {
@@ -19,6 +31,7 @@ class FiltersUnitTestSpec extends Specification{
1931
}
2032
then:"Check that the filter logic is applied"
2133
400 == response.status
34+
1 * securityServiceMock.isAuthorized() >> true
2235
}
2336

2437
void "test filters relay exceptions"() {
@@ -86,9 +99,17 @@ class UserController {
8699

87100
@Artefact("Filters")
88101
class AuthenticationFilters {
102+
103+
def securityService
104+
89105
def filters = {
90106
create(controller: 'user', action: 'create') {
91107
before = {
108+
if (!securityService.isAuthorized()) {
109+
render(status: HttpServletResponse.SC_UNAUTHORIZED)
110+
return false
111+
}
112+
92113
if (params.username == '') {
93114
render(status: HttpServletResponse.SC_BAD_REQUEST)
94115
return false
@@ -110,4 +131,12 @@ class AuthenticationFilters {
110131
}
111132
}
112133
}
134+
}
135+
136+
@Artefact("Service")
137+
class SecurityService {
138+
139+
boolean isAuthorized() {
140+
return true
141+
}
113142
}

0 commit comments

Comments
 (0)