From e0f72ab6ab5c413d5294e5a2ab9fd7cd32d059e1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 13 Feb 2015 17:34:13 +0100 Subject: [PATCH] [#10] Working Wiremock To Dsl Converter - fixed character escaping and other minor bugs Still we have to know how to escape special characters that JSON doesn't recognize --- .../wiremock/WiremockToDslConverter.groovy | 90 ++++++-- .../WiremockToDslConverterSpec.groovy | 215 ++++++++++++++++++ .../accurest/dsl/internal/Body.groovy | 33 ++- .../accurest/dsl/internal/Common.groovy | 18 ++ .../accurest/dsl/internal/Response.groovy | 8 + 5 files changed, 337 insertions(+), 27 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index f7d2311d75..36cde449f6 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -1,7 +1,7 @@ package io.codearte.accurest.wiremock +import groovy.io.FileType import groovy.json.JsonSlurper -import io.coderate.accurest.dsl.GroovyDsl class WiremockToDslConverter { static String fromWiremockStub(String wiremockStringStub) { @@ -14,24 +14,24 @@ class WiremockToDslConverter { def response = wiremockStub.response return """\ request { - ${request.method ? "method '$request.method'" : ""} - ${request.url ? "url '$request.url'" : ""} - ${request.urlPattern ? "urlPattern '$request.urlPattern'" : ""} - ${request.urlPath ? "urlPath '$request.urlPath'" : ""} + ${request.method ? "method '''$request.method'''" : ""} + ${request.url ? "url '''$request.url'''" : ""} + ${request.urlPattern ? "urlPattern '''$request.urlPattern'''" : ""} + ${request.urlPath ? "urlPath '''$request.urlPath'''" : ""} ${request.headers ? """headers { ${request.headers.collect { - def assertion = it.value - String headerName = it.key as String - def entry = assertion.entrySet().first() - """header('$headerName').$entry.key('$entry.value')\n""" - }.join('') + def assertion = it.value + String headerName = it.key as String + def entry = assertion.entrySet().first() + """header('''$headerName''').$entry.key('''$entry.value''')\n""" + }.join('') } } """ : ""} } response { ${response.status ? "status $response.status" : ""} - ${response.body ? "body( ${response.body.entrySet().collectAll(withQuotedStringElements()).inject([:], appendToMap())})" : ""} + ${response.body ? "body( ${buildBody(response.body)})" : ""} ${response.headers ? """headers { ${response.headers.collect { "header('$it.key': '${it.value}')\n" }.join('')} } @@ -40,12 +40,42 @@ class WiremockToDslConverter { """ } - private Closure withQuotedStringElements() { - return { [(it.key): convert(it.value)] } + private Object buildBody(Map responseBody) { + return responseBody.entrySet().collectAll(withQuotedMapStringElements()).inject([:], appendToIterable()) } - private Closure appendToMap() { - return { acc, el -> acc << el } + private Object buildBody(List responseBody) { + return responseBody.collectAll(withQuotedStringElements()).inject([], appendToIterable()) + } + + private Object buildBody(Integer responseBody) { + return responseBody + } + + private Object buildBody(String responseBody) { + try { + return buildBody(new JsonSlurper().parseText(responseBody)) + } catch (Exception e) { + return """'''$responseBody'''""" + } + } + + private Closure withQuotedMapStringElements() { + return { + [(it.key): convert(it.value)] + } + } + + private Closure withQuotedStringElements() { + return { + convert(it) + } + } + + private Closure appendToIterable() { + return { + acc, el -> acc << el + } } private Object convert(Object element) { @@ -53,23 +83,39 @@ class WiremockToDslConverter { } private Object convert(String element) { - return """ "$element" """ + return quoteString(element) + } + + private String quoteString(String element) { + if (element =~ /^".*"$/) { + return element + } + return """'''$element'''""" } private Object convert(List element) { - return element.collect { convert(it) } + return element.collect { + convert(it) + } } private Object convert(Map element) { - return element.collectEntries { [(it.key) : convert(it.value)] } + return element.collectEntries { + [(it.key) : convert(it.value)] + } } - static int main(String[] args) { + static void main(String[] args) { String rootOfFolderWithStubs = args[0] - new File(rootOfFolderWithStubs).eachFileRecurse { + new File(rootOfFolderWithStubs).eachFileRecurse(FileType.FILES) { try { - GroovyDsl stub = fromWiremockStub(it.text) - new File(it.parent, it.name.replaceAll('json', 'groovy')).text + if(!it.name.endsWith('json')) { + return + } + String wiremockStub = fromWiremockStub(it.text) + File newGroovyFile = new File(it.parent, it.name.replaceAll('json', 'groovy')) + println("Creating new groovy file [$newGroovyFile.path]") + newGroovyFile.text = wiremockStub } catch (Exception e) { System.err.println(e) } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index 099d0fb621..8128727d49 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -73,4 +73,219 @@ class WiremockToDslConverterSpec extends Specification { $groovyDsl }""") == expectedGroovyDsl } + + + def 'should convert Wiremock stub with body containing simple JSON'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "DELETE", + "urlPattern": "/credit-card-verification-data/[0-9]+", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.mymoid-adapter.v2+json; charset=UTF-8" + } + } + }, + "response": { + "status": 200, + "body": "{\"status\": \"OK\"}", + "headers": { + "Content-Type": "application/json" + } + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'DELETE' + urlPattern '/credit-card-verification-data/[0-9]+' + headers { + header('Content-Type').equalTo('application/vnd.mymoid-adapter.v2+json; charset=UTF-8') + } + } + response { + status 200 + body ( + status : "OK" + ) + headers { + header 'Content-Type': 'application/json' + + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl + } + + def 'should convert Wiremock stub with body containing integer'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "POST", + "url": "/charge/count", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.creditcard-reporter.v1+json" + } + } + }, + "response": { + "status": 200, + "body": 200, + "headers": { + "Content-Type": "application/json" + } + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/charge/count' + headers { + header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + } + } + response { + status 200 + body ( 200 ) + headers { + header 'Content-Type': 'application/json' + + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl + } + + def 'should convert Wiremock stub with body as a list'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "POST", + "url": "/charge/count", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.creditcard-reporter.v1+json" + } + } + }, + "response": { + "status": 200, + "body": [ + {"a":1, "c":"3"}, + "b", + "a" + ], + "headers": { + "Content-Type": "application/json" + } + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/charge/count' + headers { + header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + } + } + response { + status 200 + body ([ + [a: 1, c: '3'], + 'b', + 'c' + ]) + headers { + header 'Content-Type': 'application/json' + + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl + } + + + def 'should convert Wiremock stub with body containing a nested list'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "POST", + "url": "/charge/search?pageNumber=0&size=2147483647", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.creditcard-reporter.v1+json" + } + } + }, + "response": { + "status": 200, + "body":"[{\\"amount\\":1.01,\\"name\\":\\"Name\\",\\"info\\":{\\"title\\":\\"title1\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null},{\\"amount\\":2.01,\\"name\\":\\"Name2\\",\\"info\\":{\\"title\\":\\"title2\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null}]" + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/charge/search?pageNumber=0&size=2147483647' + headers { + header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + } + } + response { + status 200 + body ([ + [amount:1.01, + name: "Name" , + info: [title:"title1", + payload:null], + booleanvalue:true, + user:null], + [amount:2.01, + name: "Name2" , + info: [title:"title2", + payload:null], + booleanvalue:true, + user:null] + ]) + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl + } + } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index e3b75c9eb4..1a3b331bb3 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -1,14 +1,15 @@ package io.coderate.accurest.dsl.internal -import groovy.transform.CompileStatic + import groovy.transform.EqualsAndHashCode import groovy.transform.ToString -@CompileStatic @ToString(includePackage = false, includeFields = true) @EqualsAndHashCode(includeFields = true) class Body { - private final Map body + private Map body + private DslProperty bodyAsValue + private List bodyAsList Body() { this.body = [:] @@ -18,13 +19,35 @@ class Body { this.body = body } - Map forClientSide() { + Body(List bodyAsList) { + this.bodyAsList = bodyAsList + } + + Body(Object bodyAsValue) { + this.bodyAsValue = new DslProperty(bodyAsValue) + } + + Body(DslProperty bodyAsValue) { + this.bodyAsValue = bodyAsValue + } + + Object forClientSide() { + if(bodyAsValue) { + return bodyAsValue.clientValue + } else if(bodyAsList) { + bodyAsList.collect { it.clientValue } + } return body.collectEntries { Map.Entry entry -> [(entry.key) : entry.value.clientValue] } as Map } - Map forServerSide() { + Object forServerSide() { + if(bodyAsValue) { + return bodyAsValue.serverValue + } else if(bodyAsList) { + bodyAsList.collect { it.serverValue } + } return body.collectEntries { Map.Entry entry -> [(entry.key) : entry.value.serverValue] } as Map diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy index fc5135af33..9afb7e115c 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy @@ -18,10 +18,28 @@ class Common { } as Map } + List convertObjectsToDslProperties(List body) { + return body.collect { + Object element -> toDslProperty(element) + } as List + } + DslProperty toDslProperty(Object property) { return new DslProperty(property) } + DslProperty toDslProperty(Map property) { + return new DslProperty(property.collectEntries { + [(it.key) : toDslProperty(it.value)] + }) + } + + DslProperty toDslProperty(List property) { + return new DslProperty(property.collect { + toDslProperty(it) + }) + } + DslProperty toDslProperty(DslProperty property) { return property } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy index 660863c1b0..46827b9875 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy @@ -41,6 +41,14 @@ class Response extends Common { this.body = new Body(convertObjectsToDslProperties(body)) } + void body(List body) { + this.body = new Body(convertObjectsToDslProperties(body)) + } + + void body(Object bodyAsValue) { + this.body = new Body(bodyAsValue) + } + Body getBody() { return body }