From c97ce11837aed0446f99ecc17c02546f5033935f Mon Sep 17 00:00:00 2001 From: Dominik Adam Przybysz Date: Fri, 12 Dec 2014 19:16:09 +0100 Subject: [PATCH] Add request headers validation --- .../mockserver/server/ContextExecutor.groovy | 5 ++- .../mockserver/server/HttpMockServer.groovy | 4 +++ .../pl/touk/mockserver/server/Mock.groovy | 2 +- .../client/AddMockRequestData.groovy | 5 +++ .../client/ControlServerClient.groovy | 1 + .../server/MockServerIntegrationTest.groovy | 36 +++++++++++++++++-- 6 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/main/groovy/pl/touk/mockserver/server/ContextExecutor.groovy b/src/main/groovy/pl/touk/mockserver/server/ContextExecutor.groovy index a061e5d..d9df1df 100644 --- a/src/main/groovy/pl/touk/mockserver/server/ContextExecutor.groovy +++ b/src/main/groovy/pl/touk/mockserver/server/ContextExecutor.groovy @@ -28,7 +28,10 @@ class ContextExecutor { continue } } - if (ex.requestMethod == mock.method && mock.predicate(xml)) { + Map headers = ex.requestHeaders.collectEntries { [it.key.toLowerCase(), it.value.join(',')] } + if (ex.requestMethod == mock.method && + mock.predicate(xml) && + mock.requestHeaders(headers)) { println "Mock ${mock.name} invoked" ++mock.counter String response = mock.responseOk(xml) diff --git a/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy b/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy index ca53bb0..7ef83b2 100644 --- a/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy +++ b/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy @@ -65,6 +65,10 @@ class HttpMockServer { if(responseHeaders){ mock.responseHeaders = Eval.me(responseHeaders) as Closure } + String requestHeaders = request.requestHeaders + if(requestHeaders){ + mock.requestHeaders = Eval.me(requestHeaders) as Closure + } 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 2ae87cb..a94ee1e 100644 --- a/src/main/groovy/pl/touk/mockserver/server/Mock.groovy +++ b/src/main/groovy/pl/touk/mockserver/server/Mock.groovy @@ -12,7 +12,7 @@ class Mock { boolean soap = false int statusCode = 200 String method = 'POST' - //TODO add request headers - default [:] + Closure requestHeaders = {hs -> true} Closure responseHeaders = {xml -> [:]} int counter = 0 //TODO add historical invocations diff --git a/src/test/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy b/src/test/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy index e386d2d..a2aa728 100644 --- a/src/test/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy +++ b/src/test/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy @@ -12,6 +12,7 @@ class AddMockRequestData { Integer statusCode Method method String responseHeaders + String requestHeaders void setPredicate(String predicate) { this.predicate = StringEscapeUtils.escapeXml11(predicate) @@ -25,6 +26,10 @@ class AddMockRequestData { this.responseHeaders = StringEscapeUtils.escapeXml11(responseHeaders) } + void setRequestHeaders(String requestHeaders) { + this.requestHeaders = StringEscapeUtils.escapeXml11(requestHeaders) + } + enum Method { POST, GET, diff --git a/src/test/groovy/pl/touk/mockserver/client/ControlServerClient.groovy b/src/test/groovy/pl/touk/mockserver/client/ControlServerClient.groovy index 4e6f021..576f1ab 100644 --- a/src/test/groovy/pl/touk/mockserver/client/ControlServerClient.groovy +++ b/src/test/groovy/pl/touk/mockserver/client/ControlServerClient.groovy @@ -61,6 +61,7 @@ class ControlServerClient { ${data.statusCode ? "${data.statusCode}" : ''} ${data.method ? "${data.method}" : ''} ${data.responseHeaders ? "${data.responseHeaders}" : ''} + ${data.requestHeaders ? "${data.requestHeaders}" : ''} """, 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 2edd88f..8ecc9a3 100644 --- a/src/test/groovy/pl/touk/mockserver/server/MockServerIntegrationTest.groovy +++ b/src/test/groovy/pl/touk/mockserver/server/MockServerIntegrationTest.groovy @@ -441,19 +441,49 @@ class MockServerIntegrationTest extends Specification { port: 9999, predicate: '''{xml -> xml.name() == 'request'}''', response: '''{xml -> ""}''', - responseHeaders: '''{ xml -> [input:"${xml.name()}"]}''' + responseHeaders: '''{ xml -> ['Input-Name':"${xml.name()}"]}''' )) HttpPost restPost = new HttpPost('http://localhost:9999/testEndpoint') restPost.entity = new StringEntity('', ContentType.create("text/xml", "UTF-8")) when: CloseableHttpResponse response = client.execute(restPost) then: - response.allHeaders.findAll { it.name == 'Input' && it.value == 'request' } + response.allHeaders.findAll { it.name.toLowerCase() == 'input-name' && it.value == 'request' } GPathResult restPostResponse = Util.extractXmlResponse(response) restPostResponse.name() == 'goodResponse' } - //TODO def "should dispatch rest mock with post method and request headers"(){} + def "should add mock that accepts only when certain headers exists"() { + given: + controlServerClient.addMock(new AddMockRequestData( + name: 'testRest', + path: '/testEndpoint', + port: 9999, + response: '''{xml -> ""}''', + requestHeaders: '''{ hs -> hs['user-agent']?.startsWith('Mozilla') && + hs.pragma == 'no-cache'}''' + )) + HttpPost restPost = new HttpPost('http://localhost:9999/testEndpoint') + restPost.entity = new StringEntity('', ContentType.create("text/xml", "UTF-8")) + restPost.addHeader('User-Agent', 'Mozilla/5.0') + restPost.addHeader('Pragma', 'no-cache') + HttpPost badRestPost = new HttpPost('http://localhost:9999/testEndpoint') + badRestPost.entity = new StringEntity('', ContentType.create("text/xml", "UTF-8")) + badRestPost.addHeader('Pragma', 'no-cache') + when: + CloseableHttpResponse badResponse = client.execute(badRestPost) + then: + GPathResult badRestPostResponse = Util.extractXmlResponse(badResponse) + badRestPostResponse.name() == 'invalidInput' + when: + CloseableHttpResponse response = client.execute(restPost) + then: + GPathResult restPostResponse = Util.extractXmlResponse(response) + restPostResponse.name() == 'goodResponse' + } + + //TODO def "should dispatch rest mock with get method and query params"(){} + //TODO def "should dispatch rest mock with get method and parameters"(){} //TODO def "should dispatch rest mock with post method, response headers and request headers"(){} //TODO def "should get mock report"(){}