Skip to content

Commit 9c8defc

Browse files
committed
Add unit tests for recent RestfulApiController changes
1 parent e08b62e commit 9c8defc

2 files changed

Lines changed: 130 additions & 4 deletions

File tree

grails-app/controllers/net/hedtech/restfulapi/RestfulApiController.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ class RestfulApiController {
699699
if (content != null) {
700700
String responseMediaType = representation.mediaType
701701
String apiVersionMediaType = representation.apiVersion?.mediaType
702-
if (overrideGenericMediaType && genericMediaTypeList.contains(responseMediaType)) {
702+
if (apiVersionMediaType && overrideGenericMediaType && genericMediaTypeList.contains(responseMediaType)) {
703703
responseMediaType = apiVersionMediaType
704704
}
705705
responseHolder.addHeader( mediaTypeHeader, responseMediaType )

test/test-restful-api/test/unit/net/hedtech/restfulapi/RestfulApiControllerSpec.groovy

Lines changed: 129 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import grails.converters.JSON
2121
import grails.converters.XML
2222
import grails.test.mixin.*
2323

24+
import net.hedtech.restfulapi.apiversioning.BasicApiVersionParser
2425
import net.hedtech.restfulapi.config.*
2526
import net.hedtech.restfulapi.extractors.*
2627
import net.hedtech.restfulapi.extractors.configuration.*
@@ -2160,11 +2161,11 @@ class RestfulApiControllerSpec extends Specification {
21602161
unsupportedMediaTypeMethods = ['application/vnd.hedtech.v0+json': ['create','update','delete'],
21612162
'application/vnd.hedtech.v1+json': ['delete']]
21622163
representation {
2164+
mediaTypes = ['application/vnd.hedtech.v0+json',
2165+
'application/vnd.hedtech.v1+json',
2166+
'application/vnd.hedtech.v2+json']
21632167
representationMetadata = [filters: ["filter1", "filter2"]]
21642168
marshallers {
2165-
mediaTypes = ['application/vnd.hedtech.v0+json',
2166-
'application/vnd.hedtech.v1+json',
2167-
'application/vnd.hedtech.v2+json']
21682169
jsonBeanMarshaller {}
21692170
}
21702171
jsonExtractor {}
@@ -2264,6 +2265,131 @@ class RestfulApiControllerSpec extends Specification {
22642265
'delete' | 'application/json' | 'application/vnd.hedtech.v1+json' | false | true | []
22652266
}
22662267

2268+
@Unroll
2269+
def "Test API Versioning"() {
2270+
setup:
2271+
config.restfulApiConfig =
2272+
{
2273+
resource 'things' config {
2274+
methods = ['list', 'show', 'create', 'update', 'delete']
2275+
representation {
2276+
mediaTypes = ['application/vnd.hedtech.v1+json',
2277+
'application/vnd.hedtech.v2+json',
2278+
'application/vnd.hedtech+json']
2279+
marshallers {
2280+
jsonBeanMarshaller {}
2281+
}
2282+
jsonExtractor {}
2283+
}
2284+
representation {
2285+
mediaTypes = ['application/vnd.hedtech.v3.0.0+json',
2286+
'application/vnd.hedtech.v3.1.0+json',
2287+
'application/json']
2288+
marshallers {
2289+
jsonBeanMarshaller {}
2290+
}
2291+
jsonExtractor {}
2292+
}
2293+
representation {
2294+
mediaTypes = ['application/vnd.hedtech.custom+json']
2295+
marshallers {
2296+
jsonBeanMarshaller {}
2297+
}
2298+
jsonExtractor {}
2299+
}
2300+
}
2301+
}
2302+
defineBeans {
2303+
apiVersionParser(BasicApiVersionParser)
2304+
}
2305+
def genericMediaTypeList = ['application/json', 'application/vnd.hedtech+json', 'application/vnd.hedtech.custom+json']
2306+
if (override) {
2307+
controller.metaClass.getOverrideGenericMediaType = {-> override}
2308+
controller.metaClass.getGenericMediaTypeList = {-> genericMediaTypeList}
2309+
}
2310+
controller.init()
2311+
2312+
def mock = Mock(ThingService)
2313+
mock.list(_) >> { serviceReturn }
2314+
mock.count(_) >> { serviceReturn.size() }
2315+
mock.show(_) >> { serviceReturn }
2316+
mock.create(_,_) >> { serviceReturn }
2317+
mock.update(_,_) >> { serviceReturn }
2318+
mock.delete(_,_) >> {}
2319+
controller.metaClass.getService = {-> mock}
2320+
mockCacheHeaders()
2321+
params.pluralizedResourceName = 'things'
2322+
params.id = 1
2323+
def httpMethod = calculateHttpMethod(controllerMethod)
2324+
2325+
when:
2326+
request.addHeader('Accept', mediaType)
2327+
request.addHeader('Content-Type', mediaType)
2328+
request.method = httpMethod
2329+
controller."$controllerMethod"()
2330+
2331+
then:
2332+
(controllerMethod == 'create' ? 201 : 200) == response.status
2333+
mediaTypeHeader == response.getHeader('X-hedtech-Media-Type')
2334+
apiVersion == request.getAttribute(RepresentationRequestAttributes.RESPONSE_REPRESENTATION)?.apiVersion?.version
2335+
(httpMethod == 'GET' ? null : apiVersion) == request.getAttribute(RepresentationRequestAttributes.REQUEST_REPRESENTATION)?.apiVersion?.version
2336+
2337+
where:
2338+
controllerMethod | serviceReturn | override | mediaType | apiVersion | mediaTypeHeader
2339+
'list' | ['foo'] | false | 'application/json' | null | 'application/json'
2340+
'show' | [name:'foo'] | false | 'application/json' | null | 'application/json'
2341+
'create' | [name:'foo'] | false | 'application/json' | null | 'application/json'
2342+
'update' | [name:'foo'] | false | 'application/json' | null | 'application/json'
2343+
'delete' | null | false | 'application/json' | null | null
2344+
// test override=true with generic mediaType=application/json
2345+
'list' | ['foo'] | true | 'application/json' | 'v3.1.0' | 'application/vnd.hedtech.v3.1.0+json'
2346+
'show' | [name:'foo'] | true | 'application/json' | 'v3.1.0' | 'application/vnd.hedtech.v3.1.0+json'
2347+
'create' | [name:'foo'] | true | 'application/json' | 'v3.1.0' | 'application/vnd.hedtech.v3.1.0+json'
2348+
'update' | [name:'foo'] | true | 'application/json' | 'v3.1.0' | 'application/vnd.hedtech.v3.1.0+json'
2349+
'delete' | null | true | 'application/json' | null | null
2350+
// test override=true with generic mediaType=application/vnd.hedtech+json
2351+
'list' | ['foo'] | true | 'application/vnd.hedtech+json' | 'v2' | 'application/vnd.hedtech.v2+json'
2352+
'show' | [name:'foo'] | true | 'application/vnd.hedtech+json' | 'v2' | 'application/vnd.hedtech.v2+json'
2353+
'create' | [name:'foo'] | true | 'application/vnd.hedtech+json' | 'v2' | 'application/vnd.hedtech.v2+json'
2354+
'update' | [name:'foo'] | true | 'application/vnd.hedtech+json' | 'v2' | 'application/vnd.hedtech.v2+json'
2355+
'delete' | null | true | 'application/vnd.hedtech+json' | null | null
2356+
// test override=true with generic mediaType=application/vnd.hedtech.custom+json
2357+
'list' | ['foo'] | true | 'application/vnd.hedtech.custom+json' | null | 'application/vnd.hedtech.custom+json'
2358+
'show' | [name:'foo'] | true | 'application/vnd.hedtech.custom+json' | null | 'application/vnd.hedtech.custom+json'
2359+
'create' | [name:'foo'] | true | 'application/vnd.hedtech.custom+json' | null | 'application/vnd.hedtech.custom+json'
2360+
'update' | [name:'foo'] | true | 'application/vnd.hedtech.custom+json' | null | 'application/vnd.hedtech.custom+json'
2361+
'delete' | null | true | 'application/vnd.hedtech.custom+json' | null | null
2362+
// test override=true with actual mediaType=application/vnd.hedtech.v1+json
2363+
'list' | ['foo'] | true | 'application/vnd.hedtech.v1+json' | 'v1' | 'application/vnd.hedtech.v1+json'
2364+
'show' | [name:'foo'] | true | 'application/vnd.hedtech.v1+json' | 'v1' | 'application/vnd.hedtech.v1+json'
2365+
'create' | [name:'foo'] | true | 'application/vnd.hedtech.v1+json' | 'v1' | 'application/vnd.hedtech.v1+json'
2366+
'update' | [name:'foo'] | true | 'application/vnd.hedtech.v1+json' | 'v1' | 'application/vnd.hedtech.v1+json'
2367+
'delete' | null | true | 'application/vnd.hedtech.v1+json' | null | null
2368+
}
2369+
2370+
private calculateHttpMethod(String controllerMethod) {
2371+
def httpMethod
2372+
switch (controllerMethod) {
2373+
case 'list':
2374+
httpMethod = 'GET'
2375+
break
2376+
case 'show':
2377+
httpMethod = 'GET'
2378+
break
2379+
case 'create':
2380+
httpMethod = 'POST'
2381+
break
2382+
case 'update':
2383+
httpMethod = 'PUT'
2384+
break
2385+
case 'delete':
2386+
httpMethod = 'DELETE'
2387+
break
2388+
default:
2389+
fail("Unable to set request.method based on controllerMethod: " + controllerMethod)
2390+
}
2391+
return httpMethod
2392+
}
22672393

22682394
private void mockCacheHeaders() {
22692395
def cacheHeadersService = new CacheHeadersService()

0 commit comments

Comments
 (0)