diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy index 5eb8f81d45..0f74866305 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy @@ -33,7 +33,7 @@ class RecursiveFilesConverter { File newGroovyFile = createTargetFileWithProperName(absoluteTargetPath, sourceFile) newGroovyFile.text = convertedContent } catch (Exception e) { - throw new ConversionAccurestException("Unable to convertion of ${sourceFile.name}", e) + throw new ConversionAccurestException("Unable to make convertion of ${sourceFile.name}", e) } } } 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 689edb3d9a..2b377c7e3a 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,6 +1,8 @@ package io.codearte.accurest.wiremock + import groovy.io.FileType import groovy.json.JsonOutput +import groovy.json.JsonParserType import groovy.json.JsonSlurper import groovy.xml.XmlUtil import io.codearte.accurest.dsl.GroovyDsl @@ -14,7 +16,7 @@ class WireMockToDslConverter { } private String convertFromWireMockStub(String wireMockStringStub) { - Object wireMockStub = new JsonSlurper().parseText(wireMockStringStub) + Object wireMockStub = parseStubDefinition(wireMockStringStub) def request = wireMockStub.request def response = wireMockStub.response def bodyPatterns = request.bodyPatterns @@ -55,6 +57,10 @@ class WireMockToDslConverter { """ } + private Object parseStubDefinition(String wireMockStringStub) { + new JsonSlurper().setType(JsonParserType.LAX).parseText(wireMockStringStub) + } + private String buildHeader(String method, Object value) { switch (method) { case 'equalTo': 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 9cb1e9813f..cec123a88d 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy @@ -24,7 +24,7 @@ class WireMockToDslConverterSpec extends Specification { }, "response": { "status": 200, - "body": "{ \\"id\\": { \\"value\\": \\"132\\" }, \\"surname\\": \\"Kowalsky\\", \\"name\\": \\"Jan\\", \\"created\\": \\"2014-02-02 12:23:43\\" }", + "body": '{"id": { "value": "132" }, "surname": "Kowalsky", "name": "Jan", "created": "2014-02-02 12:23:43" }', "headers": { "Content-Type": "text/plain" } @@ -74,7 +74,7 @@ class WireMockToDslConverterSpec extends Specification { } - def 'should convert WireMock stub with response body containing simple JSON'() { + def 'should convert WireMock stub with response body containing JSON with escaped double quotes'() { given: String wireMockStub = '''\ { @@ -193,7 +193,7 @@ class WireMockToDslConverterSpec extends Specification { }, "response": { "status": 200, - "body": "[ {\\"a\\":1, \\"c\\":\\"3\\"}, \\"b\\", \\"a\\" ]", + "body": '[ {"a":1, "c":"3"}, "b", "a" ]', "headers": { "Content-Type": "application/json" } @@ -232,7 +232,6 @@ class WireMockToDslConverterSpec extends Specification { }""") == expectedGroovyDsl } - def 'should convert WireMock stub with response body containing a nested list'() { given: String wireMockStub = '''\ @@ -248,7 +247,7 @@ class WireMockToDslConverterSpec extends Specification { }, "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}]" + "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}]' } } ''' @@ -306,7 +305,7 @@ class WireMockToDslConverterSpec extends Specification { "method": "POST", "url": "/test", "bodyPatterns": [{ - "equalTo": "{\\"property1\\":\\"abc\\",\\"property2\\":\\"2017-01\\",\\"property3\\":\\"666\\",\\"property4\\":1428566412}" + "equalTo": '{"property1":"abc", "property2":"2017-01", "property3":"666", "property4":1428566412}' }] }, "response": { @@ -386,7 +385,7 @@ class WireMockToDslConverterSpec extends Specification { "url" : "/test", "method" : "POST", "bodyPatterns" : [ { - "equalToJson" : "{\\"pan\\":\\"4855141150107894\\",\\"expirationDate\\":\\"2017-01\\",\\"dcvx\\":\\"178\\"}", + "equalToJson" : '{"pan":"4855141150107894", "expirationDate":"2017-01", "dcvx":"178"}', "jsonCompareMode" : "LENIENT" } ] }, @@ -427,7 +426,7 @@ class WireMockToDslConverterSpec extends Specification { "url" : "/test", "method" : "POST", "bodyPatterns" : [ { - "equalTo" : "{\\"pan\\":\\"4855141150107894\\",\\"expirationDate\\":\\"2017-01\\",\\"dcvx\\":\\"178\\"}" + "equalTo" : '{"pan":"4855141150107894", "expirationDate":"2017-01", "dcvx":"178"}' } ] }, "response" : { @@ -502,5 +501,4 @@ class WireMockToDslConverterSpec extends Specification { void stubMappingIsValidWireMockStub(String mappingDefinition) { StubMapping.buildFrom(mappingDefinition) } - } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 7e7bb697bc..1b26c272ab 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -81,8 +81,10 @@ class SpockMethodBodyBuilder { addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') if (responseBody instanceof List) { processArrayElements(responseBody, "", blockBuilder) - } else { + } else if (responseBody instanceof Map) { processMapElement(responseBody, blockBuilder, "") + } else { + processBodyElement(blockBuilder, '', responseBody) } } else if (contentType == ContentType.XML) { addLine('def responseBody = new XmlSlurper().parseText(response.body.asString())') diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index 59b4d726ee..b42cadcf5c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -34,6 +34,9 @@ class ContentUtils { * @return JSON structure with replaced client / server side parts */ public static Object extractValue(GString bodyAsValue, ContentType contentType, Closure valueProvider) { + if (bodyAsValue.isEmpty()){ + return bodyAsValue + } if (contentType == ContentType.JSON) { return extractValueForJSON(bodyAsValue, valueProvider) } @@ -164,6 +167,9 @@ class ContentUtils { } public static boolean isJsonType(GString gstring) { + if (gstring.isEmpty()) { + return false + } GString stringWithoutValues = new GStringImpl( gstring.values.collect({ it instanceof String || it instanceof GString ? it.toString() : escapeJson(it.toString()) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy index 964f03811b..49c1d94981 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -286,5 +286,24 @@ class SpockMethodBuilderSpec extends Specification { spockTest.contains('responseBody.property2 == "b"') } - + def "should generate test for empty body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method('POST') + url("/ws/payments") + body("") + } + response { + status 406 + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains(".body('')") + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy index e7e6886b5d..12aca1f271 100755 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy @@ -111,7 +111,11 @@ class WireMockGroovyDslSpec extends WireMockSpec { headers { header("Content-Type": 'application/x-www-form-urlencoded') } - body("""paymentType=INCOMING&transferType=BANK&amount=${value(client(regex('[0-9]{3}\\.[0-9]{2}')), server(500.00))}&bookingDate=${value(client(regex('[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])')), server('2015-05-18'))}""") + body("""paymentType=INCOMING&transferType=BANK&amount=${ + value(client(regex('[0-9]{3}\\.[0-9]{2}')), server(500.00)) + }&bookingDate=${ + value(client(regex('[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])')), server('2015-05-18')) + }""") } response { status 204 @@ -290,7 +294,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { } ''') and: - stubMappingIsValidWireMockStub(wireMockStub) + stubMappingIsValidWireMockStub(wireMockStub) } def 'should use equalToJson when content type ends with json'() { @@ -349,7 +353,9 @@ class WireMockGroovyDslSpec extends WireMockSpec { headers { header "Content-Type", "customtype/xml" } - body """${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""" + body """${value(client('Jozo'), server('Denis'))}${ + value(client(""), server('1234567890')) + }""" } response { status 200 @@ -389,7 +395,9 @@ class WireMockGroovyDslSpec extends WireMockSpec { request { method 'GET' url "/users" - body """${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""" + body """${value(client('Jozo'), server('Denis'))}${ + value(client(""), server('1234567890')) + }""" } response { status 200 @@ -427,7 +435,9 @@ class WireMockGroovyDslSpec extends WireMockSpec { } response { status 200 - body """${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""" + body """${value(client('Jozo'), server('Denis'))}${ + value(client(""), server('1234567890')) + }""" } } when: @@ -490,7 +500,9 @@ class WireMockGroovyDslSpec extends WireMockSpec { request { method 'GET' url "/users" - body equalToXml("""${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""") + body equalToXml("""${value(client('Jozo'), server('Denis'))}${ + value(client(""), server('1234567890')) + }""") } response { status 200 @@ -522,28 +534,28 @@ class WireMockGroovyDslSpec extends WireMockSpec { def 'should convert groovy dsl stub with regexp Body as String to wireMock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { - request { - method('GET') - url $(client(regex('/[0-9]{2}')), server('/12')) - body """ + request { + method('GET') + url $(client(regex('/[0-9]{2}')), server('/12')) + body """ { "personalId": "${value(client(regex('^[0-9]{11}$')), server('57593728525'))}" } """ - } - response { - status 200 - body("""\ + } + response { + status 200 + body("""\ { "name": "Jan" } """ - ) - headers { - header 'Content-Type': 'text/plain' + ) + headers { + header 'Content-Type': 'text/plain' + } } } - } when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: @@ -827,43 +839,43 @@ class WireMockGroovyDslSpec extends WireMockSpec { def "should not allow regexp in query parameter for server value"() { when: - GroovyDsl.make { - request { - method 'GET' - url("abc") { - queryParameters { - parameter 'age': $(client(notMatching("^\\w*\$")), server(regex(".*"))) - } - } - } - response { - status 200 - } - } + GroovyDsl.make { + request { + method 'GET' + url("abc") { + queryParameters { + parameter 'age': $(client(notMatching("^\\w*\$")), server(regex(".*"))) + } + } + } + response { + status 200 + } + } then: - def e = thrown(IllegalStateException) - e.message.contains "Query parameter 'age' can't be a pattern for the server side" + def e = thrown(IllegalStateException) + e.message.contains "Query parameter 'age' can't be a pattern for the server side" } def "should not allow query parameter unresolvable for a server value"() { when: - GroovyDsl.make { - request { - method 'GET' - urlPath("users") { - queryParameters { - parameter 'age': notMatching("^\\w*\$") - parameter 'name': matching("Denis.*") - } - } - } - response { - status 200 - } - } + GroovyDsl.make { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'age': notMatching("^\\w*\$") + parameter 'name': matching("Denis.*") + } + } + } + response { + status 200 + } + } then: - def e = thrown(IllegalStateException) - e.message.contains "Query parameter 'age' can't be of a matching type: NOT_MATCHING for the server side" + def e = thrown(IllegalStateException) + e.message.contains "Query parameter 'age' can't be of a matching type: NOT_MATCHING for the server side" } def "should not allow query parameter with a different absent variation for server/client"() { @@ -874,45 +886,45 @@ class WireMockGroovyDslSpec extends WireMockSpec { e.message.contains "Absent cannot only be used only on one side" where: dsl << [ - { - request { - method 'GET' - urlPath("users") { - queryParameters { - parameter 'name': $(client(absent()), server("")) + { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'name': $(client(absent()), server("")) + } } } - } - response { - status 200 - } - }, - { - request { - method 'GET' - urlPath("users") { - queryParameters { - parameter 'name': $(client(""), server(absent())) + response { + status 200 + } + }, + { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'name': $(client(""), server(absent())) + } } } - } - response { - status 200 - } - }, - { - request { - method 'GET' - urlPath("users") { - queryParameters { - parameter 'name': $(client(absent()), server(matching("abc"))) + response { + status 200 + } + }, + { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'name': $(client(absent()), server(matching("abc"))) + } } } + response { + status 200 + } } - response { - status 200 - } - } ] } @@ -1107,6 +1119,39 @@ class WireMockGroovyDslSpec extends WireMockSpec { ''') } + def "should generate stub for empty body"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('POST') + url("test") + body("") + } + response { + status 406 + } + } + when: + def json = toWireMockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "POST", + "url": "test", + "bodyPatterns": [ + { + "equalTo": "" + } + ] + }, + "response": { + "status": 406 + } + } +''') + } + String toJsonString(value) { new JsonBuilder(value).toPrettyString() } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index ee5c91b466..48929c705b 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -2,9 +2,6 @@ buildscript { repositories { mavenCentral() } - dependencies { - classpath "io.codearte.accurest:accurest-gradle-plugin:$accurestVersion" - } } apply plugin: 'groovy' @@ -49,7 +46,6 @@ dependencies { testCompile "org.spockframework:spock-spring:0.7-groovy-2.0" testCompile "com.jayway.restassured:rest-assured:$restAssuredVersion" testCompile "com.jayway.restassured:spring-mock-mvc:$restAssuredVersion" - testCompile "io.codearte.accurest:accurest-core:$accurestVersion" testCompile "javax.servlet:javax.servlet-api:3.0.1" //provided testCompile "ch.qos.logback:logback-classic:1.1.2" } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties index 6e02ac3599..71fcc0538e 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties @@ -1,5 +1,4 @@ groupId=com.ofg jacksonMapper=1.9.13 restAssuredVersion=2.4.0 -accurestVersion=0.4.1 springVersion=4.1.4.RELEASE \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index 90478ca0bd..068c0f6e47 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -5,7 +5,6 @@ buildscript { } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.1.RELEASE") - classpath 'io.codearte.accurest:accurest-gradle-plugin:0.6.2' } } diff --git a/build.gradle b/build.gradle index 835037077f..8b8d47bb77 100644 --- a/build.gradle +++ b/build.gradle @@ -91,7 +91,7 @@ project(':accurest-core') { compile 'org.apache.commons:commons-lang3:[3.3,)' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' - testCompile 'com.github.tomakehurst:wiremock:1.53' + testCompile 'com.github.tomakehurst:wiremock:1.57' } } @@ -101,7 +101,7 @@ project(':accurest-converters') { compile 'org.apache.commons:commons-lang3:[3.0,)' compile 'commons-io:commons-io:[2.0,)' compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger - testCompile 'com.github.tomakehurst:wiremock:1.53' + testCompile 'com.github.tomakehurst:wiremock:1.57' testCompile 'org.hamcrest:hamcrest-all:1.3' } }