From 1be072f440054810a9257999d80379b15735e662 Mon Sep 17 00:00:00 2001 From: Dominik Adam Przybysz Date: Wed, 10 Dec 2014 22:07:26 +0100 Subject: [PATCH] Add support for each http method --- .../mockserver/server/ContextExecutor.groovy | 5 +- .../mockserver/server/HttpMockServer.groovy | 4 + .../pl/touk/mockserver/server/Mock.groovy | 2 +- .../client/AddMockRequestData.groovy | 16 +- .../client/ControlServerClient.groovy | 7 +- .../server/MockServerIntegrationTest.groovy | 182 ++++++++++++++++-- 6 files changed, 192 insertions(+), 24 deletions(-) diff --git a/src/main/groovy/pl/touk/mockserver/server/ContextExecutor.groovy b/src/main/groovy/pl/touk/mockserver/server/ContextExecutor.groovy index 5c3af82..5cc4873 100644 --- a/src/main/groovy/pl/touk/mockserver/server/ContextExecutor.groovy +++ b/src/main/groovy/pl/touk/mockserver/server/ContextExecutor.groovy @@ -18,10 +18,9 @@ class ContextExecutor { HttpExchange ex -> String input = ex.requestBody.text println "Mock received input" - GPathResult inputXml = new XmlSlurper().parseText(input) for (Mock mock : mocks){ - GPathResult xml = inputXml try { + GPathResult xml = input ? new XmlSlurper().parseText(input) : null if (mock.soap) { if(xml.name() == 'Envelope' && xml.Body.size() > 0){ xml = getSoapBodyContent(xml) @@ -29,7 +28,7 @@ class ContextExecutor { continue } } - if (xml != null && mock.predicate(xml)) { + if (ex.requestMethod == mock.method && mock.predicate(xml)) { ex.sendResponseHeaders(mock.statusCode, 0) println "Mock ${mock.name} invoked" ++mock.counter diff --git a/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy b/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy index a2d6245..1757c3f 100644 --- a/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy +++ b/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy @@ -57,6 +57,10 @@ class HttpMockServer { if(statusCode){ mock.statusCode = Integer.valueOf(statusCode) } + String method = request.method + if(method){ + mock.method = method + } HttpServerWraper child = childServers.find { it.port == mockPort } if (!child) { child = new HttpServerWraper(mockPort) diff --git a/src/main/groovy/pl/touk/mockserver/server/Mock.groovy b/src/main/groovy/pl/touk/mockserver/server/Mock.groovy index e250616..9f21d6b 100644 --- a/src/main/groovy/pl/touk/mockserver/server/Mock.groovy +++ b/src/main/groovy/pl/touk/mockserver/server/Mock.groovy @@ -11,7 +11,7 @@ class Mock { Closure responseOk = { xml -> '' } boolean soap = false int statusCode = 200 - //TODO add http method - default POST + String method = 'POST' //TODO add request headers - default [:] //TODO add response headers - default [:] int counter = 0 diff --git a/src/test/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy b/src/test/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy index 3cf3c02..003381f 100644 --- a/src/test/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy +++ b/src/test/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy @@ -10,14 +10,24 @@ class AddMockRequestData { String response Boolean soap Integer statusCode + Method method - void setPredicate(String predicate){ + void setPredicate(String predicate) { this.predicate = StringEscapeUtils.escapeXml11(predicate) } - void setResponse(String response){ + void setResponse(String response) { this.response = StringEscapeUtils.escapeXml11(response) } - + enum Method { + POST, + GET, + DELETE, + PUT, + TRACE, + HEAD, + OPTIONS, + PATCH + } } diff --git a/src/test/groovy/pl/touk/mockserver/client/ControlServerClient.groovy b/src/test/groovy/pl/touk/mockserver/client/ControlServerClient.groovy index 3b56c38..9aa6976 100644 --- a/src/test/groovy/pl/touk/mockserver/client/ControlServerClient.groovy +++ b/src/test/groovy/pl/touk/mockserver/client/ControlServerClient.groovy @@ -55,10 +55,11 @@ class ControlServerClient { ${data.name} ${data.path} ${data.port} - ${data.predicate != null ? "${data.predicate}" : ''} - ${data.response != null ? "${data.response}" : ''} + ${data.predicate ? "${data.predicate}" : ''} + ${data.response ? "${data.response}" : ''} ${data.soap != null ? "${data.soap}" : ''} - ${data.statusCode != null ? "${data.statusCode}" : ''} + ${data.statusCode ? "${data.statusCode}" : ''} + ${data.method ? "${data.method}" : ''} """, ContentType.create("text/xml", "UTF-8")) } diff --git a/src/test/groovy/pl/touk/mockserver/server/MockServerIntegrationTest.groovy b/src/test/groovy/pl/touk/mockserver/server/MockServerIntegrationTest.groovy index 63e2538..1d01a52 100644 --- a/src/test/groovy/pl/touk/mockserver/server/MockServerIntegrationTest.groovy +++ b/src/test/groovy/pl/touk/mockserver/server/MockServerIntegrationTest.groovy @@ -1,8 +1,7 @@ package pl.touk.mockserver.server import groovy.util.slurpersupport.GPathResult -import org.apache.http.client.methods.CloseableHttpResponse -import org.apache.http.client.methods.HttpPost +import org.apache.http.client.methods.* import org.apache.http.entity.ContentType import org.apache.http.entity.StringEntity import org.apache.http.impl.client.CloseableHttpClient @@ -257,7 +256,7 @@ class MockServerIntegrationTest extends Specification { secondXmlResponse.name() == 'invalidInput' } - def "should inform that there was problem during adding mock - invalid port"(){ + def "should inform that there was problem during adding mock - invalid port"() { when: controlServerClient.addMock(new AddMockRequestData( name: 'testSoap', @@ -271,21 +270,176 @@ class MockServerIntegrationTest extends Specification { thrown(InvalidMockDefinitionException) } - //TODO def "should dispatch rest mock with post method"(){} + def "should dispatch rest mock with get method"() { + given: + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest', + path: '/testEndpoint', + port: 9999, + response: '''{xml -> ""}''' + )) + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest2', + path: '/testEndpoint', + port: 9999, + response: '''{xml -> ""}''', + method: AddMockRequestData.Method.GET + )) + HttpGet restGet = new HttpGet('http://localhost:9999/testEndpoint') + when: + CloseableHttpResponse response = client.execute(restGet) + then: + GPathResult restPostResponse = Util.extractXmlResponse(response) + restPostResponse.name() == 'getResponse' + } + + def "should dispatch rest mock with trace method"() { + given: + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest', + path: '/testEndpoint', + port: 9999, + response: '''{xml -> ""}''' + )) + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest2', + path: '/testEndpoint', + port: 9999, + response: '''{xml -> ""}''', + method: AddMockRequestData.Method.TRACE + )) + HttpTrace restTrace = new HttpTrace('http://localhost:9999/testEndpoint') + when: + CloseableHttpResponse response = client.execute(restTrace) + then: + GPathResult restPostResponse = Util.extractXmlResponse(response) + restPostResponse.name() == 'traceResponse' + } + + def "should dispatch rest mock with head method"() { + given: + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest', + path: '/testEndpoint', + port: 9999, + response: '''{xml -> ""}''' + )) + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest2', + path: '/testEndpoint', + port: 9999, + method: AddMockRequestData.Method.HEAD + )) + HttpHead restHead = new HttpHead('http://localhost:9999/testEndpoint') + when: + CloseableHttpResponse response = client.execute(restHead) + then: + response.statusLine.statusCode == 200 + EntityUtils.consumeQuietly(response.entity) + //TODO check headers + } + + def "should dispatch rest mock with options method"() { + given: + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest', + path: '/testEndpoint', + port: 9999, + response: '''{xml -> ""}''' + )) + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest2', + path: '/testEndpoint', + port: 9999, + method: AddMockRequestData.Method.OPTIONS + )) + HttpOptions restOptions = new HttpOptions('http://localhost:9999/testEndpoint') + when: + CloseableHttpResponse response = client.execute(restOptions) + then: + response.statusLine.statusCode == 200 + EntityUtils.consumeQuietly(response.entity) + } + + def "should dispatch rest mock with put method"() { + given: + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest', + path: '/test1', + port: 9999, + response: '''{xml -> ""}''' + )) + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest2', + path: '/test1', + port: 9999, + predicate: '''{xml -> xml.name() == 'request1'}''', + response: '''{xml -> ""}''', + method: AddMockRequestData.Method.PUT + )) + HttpPut request = new HttpPut('http://localhost:9999/test1') + request.entity = new StringEntity('', ContentType.create("text/xml", "UTF-8")) + when: + CloseableHttpResponse response = client.execute(request) + then: + GPathResult secondXmlResponse = Util.extractXmlResponse(response) + secondXmlResponse.name() == 'goodResponseRest1' + } + + def "should dispatch rest mock with delete method"() { + given: + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest', + path: '/test1', + port: 9999, + response: '''{xml -> ""}''' + )) + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest2', + path: '/test1', + port: 9999, + response: '''{xml -> ""}''', + method: AddMockRequestData.Method.DELETE + )) + HttpDelete request = new HttpDelete('http://localhost:9999/test1') + when: + CloseableHttpResponse response = client.execute(request) + then: + GPathResult secondXmlResponse = Util.extractXmlResponse(response) + secondXmlResponse.name() == 'goodResponseRest1' + } + + def "should dispatch rest mock with patch method"() { + given: + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest', + path: '/test1', + port: 9999, + response: '''{xml -> ""}''' + )) + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest2', + path: '/test1', + port: 9999, + predicate: '''{xml -> xml.name() == 'request1'}''', + response: '''{xml -> ""}''', + method: AddMockRequestData.Method.PATCH + )) + HttpPatch request = new HttpPatch('http://localhost:9999/test1') + request.entity = new StringEntity('', ContentType.create("text/xml", "UTF-8")) + when: + CloseableHttpResponse response = client.execute(request) + then: + GPathResult secondXmlResponse = Util.extractXmlResponse(response) + secondXmlResponse.name() == 'goodResponseRest1' + } + //TODO def "should dispatch rest mock with post method and request headers"(){} //TODO def "should dispatch rest mock with post method and response headers"(){} - //TODO def "should dispatch rest mock with get method"(){} - //TODO def "should dispatch rest mock with get method and request headers"(){} - //TODO def "should dispatch rest mock with get method and response headers"(){} - //TODO def "should dispatch rest mock with put method"(){} - //TODO def "should dispatch rest mock with put method and request headers"(){} - //TODO def "should dispatch rest mock with put method and response headers"(){} - //TODO def "should dispatch rest mock with delete method"(){} - //TODO def "should dispatch rest mock with delete method and request headers"(){} - //TODO def "should dispatch rest mock with delete method and response headers"(){} - //TODO def "should dispatch rest mocks with all methods"(){} //TODO def "should get mock report"(){} //TODO def "should get list mocks"(){} //TODO def "should validate mock when creating" + + //TODO def "should handle json input and output"(){} }