[#5] Implemented Request and Response with headers and body (not yet fully though ;) )

This commit is contained in:
Marcin Grzejszczak
2015-02-12 00:33:22 +01:00
parent 759e9a163d
commit 4898470613
10 changed files with 315 additions and 183 deletions

View File

@@ -8,19 +8,25 @@ import io.coderate.accurest.dsl.internal.WithValuePattern
@CompileStatic
abstract class BaseWiremockStubStrategy {
protected Map buildClientHeadersSection(Headers headers) {
return createHeadersSection(headers) {
Map.Entry<String, WithValuePattern> entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)]
if (!headers) {
return null
}
return withAssertionHeaders(headers) {
Map.Entry<String, WithValuePattern> entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)]
} << headers?.valueHeaders()
}
protected Map buildServerHeadersSection(Headers headers) {
return createHeadersSection(headers) {
Map.Entry<String, WithValuePattern> entry -> [(entry.key): buildServerHeaderFromValuePattern(entry.value)]
if (!headers) {
return null
}
return withAssertionHeaders(headers) {
Map.Entry<String, WithValuePattern> entry -> [(entry.key): buildServerHeaderFromValuePattern(entry.value)]
} << headers.valueHeaders()
}
private Map createHeadersSection(Headers headers, Closure closure) {
return headers?.entries()?.collectEntries(closure)
private Map withAssertionHeaders(Headers headers, Closure closure) {
return headers?.assertionEntries()?.collectEntries(closure)
}
private Map buildClientHeaderFromValuePattern(WithValuePattern valuePattern) {

View File

@@ -1,10 +1,11 @@
package io.coderate.accurest.dsl
import groovy.json.JsonOutput
import groovy.transform.CompileStatic
import groovy.transform.PackageScope
import io.coderate.accurest.dsl.internal.Request
@CompileStatic
@PackageScope
class WiremockRequestStubStrategy extends BaseWiremockStubStrategy {
private final Request request
@@ -13,31 +14,23 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy {
this.request = groovyDsl.request
}
String toWiremockClientStub() {
return JsonOutput.toJson(buildClientRequest(request))
}
String toWiremockServerStub() {
return JsonOutput.toJson(buildServerRequest(request))
}
private Map buildClientRequest(Request request) {
return getRequestSection(request,
@PackageScope Map buildClientRequestContent() {
return buildRequestContent(request,
{ request.urlPattern?.toClientSide() },
{ buildClientHeadersSection(request.headers) })
}
private Map buildServerRequest(Request request) {
return getRequestSection(request,
@PackageScope Map buildServerRequestContent() {
return buildRequestContent(request,
{ request.urlPattern?.toServerSide() },
{ buildServerHeadersSection(request.headers) })
}
private Map<String, Map<String, Object>> getRequestSection(Request request, Closure<String> buildUrlPattern, Closure<Map> buildHeaders) {
return [request: [method : request.method,
url : request.url,
urlPattern: buildUrlPattern(),
urlPath : request.urlPath,
headers : buildHeaders()].findAll { it.value }]
private Map<String, Object> buildRequestContent(Request request, Closure<String> buildUrlPattern, Closure<Map> buildHeaders) {
return [method : request.method,
url : request.url,
urlPattern: buildUrlPattern(),
urlPath : request.urlPath,
headers : buildHeaders()].findAll { it.value }
}
}

View File

@@ -1,37 +1,35 @@
package io.coderate.accurest.dsl
import groovy.json.JsonOutput
import groovy.transform.CompileStatic
import groovy.transform.PackageScope
import io.coderate.accurest.dsl.internal.Response
@CompileStatic
@PackageScope
class WiremockResponseStubStrategy extends BaseWiremockStubStrategy {
Response response
private final Response response
WiremockResponseStubStrategy(GroovyDsl groovyDsl) { //TODO: Or Response?
WiremockResponseStubStrategy(GroovyDsl groovyDsl) {
this.response = groovyDsl.response
}
String toWiremockClientStub() {
return JsonOutput.toJson(buildClientResponse(response))
@PackageScope Map buildClientResponseContent() {
return buildResponseContent(response,
{ response.getBody().forClientSide() },
{ buildClientHeadersSection(response.headers) })
}
private Map buildClientResponse(Response response) {
return getResponseSection(response, { "TODO" }, { buildClientHeadersSection(response.headers) })
@PackageScope Map buildServerResponseContent() {
return buildResponseContent(response,
{ response.getBody().forServerSide() },
{ buildServerHeadersSection(response.headers) })
}
String toWiremockServerStub() {
return JsonOutput.toJson(buildServerResponse(response))
private Map<String, Object> buildResponseContent(Response response, Closure<Map<String, Object>> buildBody, Closure<Map> buildHeaders) {
return [status : response.status,
body : buildBody(),
headers: buildHeaders()].findAll { it.value }
}
private Map buildServerResponse(Response response) {
return getResponseSection(response, { "TODO" }, { buildServerHeadersSection(response.headers) })
}
private Map<String, Map<String, Object>> getResponseSection(Response response, Closure<String> buildUrlPattern, Closure<Map> buildHeaders) {
return [response: [status : response.status,
headers: buildHeaders()]
.findAll { it.value }]
}
}

View File

@@ -0,0 +1,26 @@
package io.coderate.accurest.dsl
import groovy.json.JsonOutput
import groovy.transform.CompileStatic
@CompileStatic
class WiremockStubStrategy {
private final WiremockRequestStubStrategy wiremockRequestStubStrategy
private final WiremockResponseStubStrategy wiremockResponseStubStrategy
WiremockStubStrategy(GroovyDsl groovyDsl) {
this.wiremockRequestStubStrategy = new WiremockRequestStubStrategy(groovyDsl)
this.wiremockResponseStubStrategy = new WiremockResponseStubStrategy(groovyDsl)
}
String toWiremockClientStub() {
return JsonOutput.toJson([request: wiremockRequestStubStrategy.buildClientRequestContent(),
response: wiremockResponseStubStrategy.buildClientResponseContent()])
}
String toWiremockServerStub() {
return JsonOutput.toJson([request: wiremockRequestStubStrategy.buildServerRequestContent(),
response: wiremockResponseStubStrategy.buildServerResponseContent()])
}
}

View File

@@ -0,0 +1,24 @@
package io.coderate.accurest.dsl.internal
import groovy.transform.CompileStatic
@CompileStatic
class Body {
private final Map<String, DslProperty> body
Body() {
this.body = [:]
}
Body(Map<String, DslProperty> body) {
this.body = body
}
Map<String, Object> forClientSide() {
return body.collectEntries { Map.Entry<String, DslProperty> entry -> [(entry.key) : entry.value.clientValue] } as Map<String, Object>
}
Map<String, Object> forServerSide() {
return body.collectEntries { Map.Entry<String, DslProperty> entry -> [(entry.key) : entry.value.serverValue] } as Map<String, Object>
}
}

View File

@@ -0,0 +1,19 @@
package io.coderate.accurest.dsl.internal
import groovy.transform.CompileStatic
@CompileStatic
class DslProperty {
final Object clientValue
final Object serverValue
DslProperty(Object clientValue, Object serverValue) {
this.clientValue = clientValue
this.serverValue = serverValue
}
DslProperty(Object singleValue) {
this.clientValue = singleValue
this.serverValue = singleValue
}
}

View File

@@ -2,15 +2,25 @@ package io.coderate.accurest.dsl.internal
class Headers {
private Map<String, WithValuePattern> headers = [:]
private Map<String, WithValuePattern> assertionHeaders = [:]
private Map<String, String> valueHeaders = [:]
WithValuePattern header(String headerName) {
WithValuePattern withValuePattern = new WithValuePattern()
headers[headerName] = withValuePattern
assertionHeaders[headerName] = withValuePattern
return withValuePattern
}
Set<Map.Entry<String, WithValuePattern>> entries() {
return Collections.unmodifiableSet(headers.entrySet())
void header(Map<String, String> singleHeader) {
Map.Entry<String, String> first = singleHeader.entrySet().first()
valueHeaders[first?.key] = first?.value
}
Map<String, String> valueHeaders() {
return Collections.unmodifiableMap(valueHeaders)
}
Set<Map.Entry<String, WithValuePattern>> assertionEntries() {
return Collections.unmodifiableSet(assertionHeaders.entrySet())
}
}

View File

@@ -7,8 +7,12 @@ import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure
@TypeChecked
class Response {
private static final String CLIENT_PROP_KEY = 'client'
private static final String SERVER_PROP_KEY = 'server'
private int status
private Headers headers
private Body body = new Body()
void status(int status) {
this.status = status
@@ -19,6 +23,29 @@ class Response {
delegateToClosure(closure, headers)
}
void body(Map<String, Object> body) {
this.body = new Body(convertObjectsToDslProperties(body))
}
private Map<String, DslProperty> convertObjectsToDslProperties(Map<String, Object> body) {
return body.collectEntries {
Map.Entry<String, Object> entry ->
[(entry.key): entry.value instanceof DslProperty ? entry.value : new DslProperty(entry.value)]
} as Map<String, DslProperty>
}
DslProperty property(Map<String, Object> properties) {
return new DslProperty(properties[CLIENT_PROP_KEY], properties[SERVER_PROP_KEY])
}
DslProperty $(Map<String, Object> properties) {
return property(properties)
}
Body getBody() {
return body
}
int getStatus() {
return status
}

View File

@@ -3,7 +3,6 @@ package io.codearte.accurest.dsl
import groovy.json.JsonSlurper
import io.coderate.accurest.dsl.GroovyDsl
import io.coderate.accurest.dsl.WiremockResponseStubStrategy
import spock.lang.Ignore
import spock.lang.Specification
class WiremockGroovyDslResponseSpec extends Specification {
@@ -15,25 +14,19 @@ class WiremockGroovyDslResponseSpec extends Specification {
status 200
}
}
when:
String wiremockStub = new WiremockResponseStubStrategy(dsl)."toWiremock${side}Stub"()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(expectedStub)
expect:
new WiremockResponseStubStrategy(dsl)."build${side}ResponseContent"() == new JsonSlurper().parseText(expectedStub)
where:
side << ['Client', 'Server']
expectedStub << ['''
{
"response": {
"status": 200
}
"status": 200
}
''',
'''
{
"response": {
"status": 200
}
"status": 200
}
''']
}
@@ -43,49 +36,69 @@ class WiremockGroovyDslResponseSpec extends Specification {
GroovyDsl dsl = GroovyDsl.make {
response {
headers {
header('Content-Type').equalTo('text/xml')
header('Content-Type').matches {
client('text/xml')
server('text/*')
}
}
status 200
}
}
when:
String wiremockStub = new WiremockResponseStubStrategy(dsl).toWiremockClientStub()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText('''
expect:
new WiremockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText('''
{
"response": {
"headers": {
"Content-Type": {
"equalTo": "text/xml"
"matches": "text/xml"
},
},
"status": 200
}
}
''')
}
@Ignore("Not implemented yet")
def 'should generate headers for response for server side'() {
given:
GroovyDsl dsl = GroovyDsl.make {
response {
status 200
headers {
header('Content-Type').equalTo('text/xml')
header('Content-Type').matches {
client('text/xml')
server('text/*')
}
}
}
}
when:
String wiremockStub = new WiremockResponseStubStrategy(dsl).toWiremockClientStub()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText('''
expect:
new WiremockResponseStubStrategy(dsl).buildServerResponseContent() == new JsonSlurper().parseText('''
{
"response": {
"status": 200,
"headers":
"Content-Type": "text/xml"
"status": 200,
"headers": {
"Content-Type": {
"matches": "text/*"
}
}
}
''')
}
def 'should generate an exact header for response for both sides '() {
given:
GroovyDsl dsl = GroovyDsl.make {
response {
status 200
headers {
header 'Content-Type': 'text/xml'
}
}
}
expect:
new WiremockResponseStubStrategy(dsl).buildServerResponseContent() == new JsonSlurper().parseText('''
{
"status": 200,
"headers": {
"Content-Type": "text/xml"
}
}
''')

View File

@@ -3,40 +3,38 @@ package io.codearte.accurest.dsl
import groovy.json.JsonSlurper
import io.coderate.accurest.dsl.GroovyDsl
import io.coderate.accurest.dsl.WiremockRequestStubStrategy
import io.coderate.accurest.dsl.WiremockStubStrategy
import spock.lang.Ignore
import spock.lang.Specification
class WiremockGroovyDslSpec extends Specification {
// TODO: add alias instead of placeholder
@Ignore
def 'should convert groovy dsl stub to wiremock stub'() {
def 'should convert groovy dsl stub to wiremock stub for the client side'() {
given:
GroovyDsl dsl = GroovyDsl.make {
request {
method('GET')
urlPattern {
client('/[0-9]{2}')
server('/12')
GroovyDsl groovyDsl = GroovyDsl.make {
request {
method('GET')
urlPattern {
client('/[0-9]{2}')
server('/12')
}
}
response {
status(200)
body (
id : property(client: '123', server: { regex('[0-9]+') } ),
name: 'Jan',
created : $(client: '2014-02-02 12:23:43', server: { currentDate(it) })
)
headers {
header('Content-Type': 'text/plain')
}
}
}
response {
status(200)
body {
withPlaceholder(client: '2015-01-14', server: '$anyInt($it)')
withTemplate('''
{
"date" : "$placeholder0"
}
''')
}
headers {
Content-Type('text/plain')
}
}
}
expect:
dsl.toWiremockClientStub() == '''
when:
String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText('''
{
"request": {
"method": "GET",
@@ -44,13 +42,63 @@ class WiremockGroovyDslSpec extends Specification {
},
"response": {
"status": 200,
"body": "2015-01-14",
"body": {
"id": "123",
"name": "Jan",
"created" : "2014-02-02 12:23:43"
},
"headers": {
"Content-Type": "text/plain"
}
}
}
'''
''')
}
def 'should convert groovy dsl stub to wiremock stub for the server side'() {
given:
GroovyDsl groovyDsl = GroovyDsl.make {
request {
method('GET')
urlPattern {
client('/[0-9]{2}')
server('/12')
}
}
response {
status(200)
body (
id : property(client: '123', server: '321' ),
name: 'Jan',
created : $(client: '2014-02-02 12:23:43', server: '1999-01-01 01:23:45')
)
headers {
header('Content-Type': 'text/plain')
}
}
}
when:
String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText('''
{
"request": {
"method": "GET",
"urlPattern": "/12"
},
"response": {
"status": 200,
"body": {
"id": "321",
"name": "Jan",
"created" : "1999-01-01 01:23:45"
},
"headers": {
"Content-Type": "text/plain"
}
}
}
''')
}
def "should generate stub with GET"() {
@@ -60,14 +108,10 @@ class WiremockGroovyDslSpec extends Specification {
method("GET")
}
}
when:
String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText('''
expect:
new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText('''
{
"request":{
"method":"GET"
}
"method":"GET"
}
''')
}
@@ -80,15 +124,11 @@ class WiremockGroovyDslSpec extends Specification {
url("/sth")
}
}
when:
String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText('''
expect:
new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText('''
{
"request":{
"method":"GET",
"url":"/sth"
}
"method":"GET",
"url":"/sth"
}
''')
}
@@ -102,14 +142,10 @@ class WiremockGroovyDslSpec extends Specification {
}
}
}
when:
String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText('''
expect:
new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText('''
{
"request":{
"urlPattern":"/^[0-9]{2}$"
}
"urlPattern":"/^[0-9]{2}$"
}
''')
}
@@ -124,14 +160,10 @@ class WiremockGroovyDslSpec extends Specification {
}
}
}
when:
String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockServerStub()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText('''
expect:
new WiremockRequestStubStrategy(groovyDsl).buildServerRequestContent() == new JsonSlurper().parseText('''
{
"request":{
"urlPattern":"/12"
}
"urlPattern":"/12"
}
''')
}
@@ -143,14 +175,10 @@ class WiremockGroovyDslSpec extends Specification {
urlPath ('/12')
}
}
when:
String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText('''
expect:
new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText('''
{
"request":{
"urlPath":"/12"
}
"urlPath":"/12"
}
''')
}
@@ -162,14 +190,10 @@ class WiremockGroovyDslSpec extends Specification {
urlPath ('/12')
}
}
when:
String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockServerStub()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText('''
expect:
new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText('''
{
"request":{
"urlPath":"/12"
}
"urlPath":"/12"
}
''')
}
@@ -195,25 +219,21 @@ class WiremockGroovyDslSpec extends Specification {
}
}
}
when:
String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText('''
expect:
new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText('''
{
"request":{
"headers": {
"Content-Type": {
"equalTo": "text/xml"
},
"Accept": {
"matches": "text/.*"
},
"etag": {
"doesNotMatch": "abcd.*"
},
"X-Custom-Header": {
"contains": "2134"
}
"headers": {
"Content-Type": {
"equalTo": "text/xml"
},
"Accept": {
"matches": "text/.*"
},
"etag": {
"doesNotMatch": "abcd.*"
},
"X-Custom-Header": {
"contains": "2134"
}
}
}
@@ -241,25 +261,21 @@ class WiremockGroovyDslSpec extends Specification {
}
}
}
when:
String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockServerStub()
then:
new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText('''
expect:
new WiremockRequestStubStrategy(groovyDsl).buildServerRequestContent() == new JsonSlurper().parseText('''
{
"request":{
"headers": {
"Content-Type": {
"equalTo": "text/xml"
},
"Accept": {
"matches": "text/plain"
},
"etag": {
"doesNotMatch": "abcdef"
},
"X-Custom-Header": {
"contains": "121345"
}
"headers": {
"Content-Type": {
"equalTo": "text/xml"
},
"Accept": {
"matches": "text/plain"
},
"etag": {
"doesNotMatch": "abcdef"
},
"X-Custom-Header": {
"contains": "121345"
}
}
}