Skip to content

Commit

Permalink
fix: fixes #2
Browse files Browse the repository at this point in the history
  • Loading branch information
artamonovkirill committed Jun 14, 2018
1 parent cfd15b3 commit b8139f6
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 79 deletions.
45 changes: 45 additions & 0 deletions src/integration-test/groovy/com/tomtom/http/HttpClientIT.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,51 @@ class HttpClientIT extends Specification {
response.statusCode == OK
}

def 'Executes an options'() {
given:
service.givenThat(
options(urlEqualTo('/path'))
.willReturn(
aResponse().withStatus(OK)))

when:
def response = http.options(
url: "http://localhost:${service.port()}/path")

then:
response.statusCode == OK
}

def 'Executes a trace'() {
given:
service.givenThat(
trace(urlEqualTo('/path'))
.willReturn(
aResponse().withStatus(OK)))

when:
def response = http.trace(
url: "http://localhost:${service.port()}/path")

then:
response.statusCode == OK
}

def 'Executes a patch'() {
given:
service.givenThat(
patch(urlEqualTo('/path'))
.willReturn(
aResponse().withStatus(OK)))

when:
def response = http.patch(
url: "http://localhost:${service.port()}/path")

then:
response.statusCode == OK
}

def 'Parses response'() {
given:
service.givenThat(
Expand Down
84 changes: 57 additions & 27 deletions src/main/groovy/com/tomtom/http/HttpClient.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package com.tomtom.http

import com.fasterxml.jackson.databind.ObjectMapper
import com.tomtom.http.response.Response
import org.apache.http.client.HttpClient as ApacheHttpClient
import org.apache.http.conn.ssl.NoopHostnameVerifier
import org.apache.http.conn.ssl.TrustStrategy
import org.apache.http.impl.client.HttpClientBuilder
Expand All @@ -38,7 +39,7 @@ class HttpClient {
true
}
}).build()
private final org.apache.http.client.HttpClient client
private final ApacheHttpClient client

final RequestBuilder builder
final ResponseParser parser
Expand All @@ -55,19 +56,15 @@ class HttpClient {
*/
HttpClient(
Map properties) {
client = properties['client'] as org.apache.http.client.HttpClient ?:
defaultClient()
client = properties['client'] as ApacheHttpClient ?: defaultClient()

def mapper = properties['mapper'] as ObjectMapper ?:
new ObjectMapper()
def mapper = properties['mapper'] as ObjectMapper ?: new ObjectMapper()
def builderParams = [mapper: mapper]
def baseUrl = properties['baseUrl'] as String
if (baseUrl) builderParams += [baseUrl: baseUrl]

builder = properties['builder'] as RequestBuilder ?:
new RequestBuilder(builderParams)
parser = properties['parser'] as ResponseParser ?:
new ResponseParser(mapper: mapper)
builder = properties['builder'] as RequestBuilder ?: new RequestBuilder(builderParams)
parser = properties['parser'] as ResponseParser ?: new ResponseParser(mapper: mapper)
}

private defaultClient() {
Expand All @@ -93,8 +90,7 @@ class HttpClient {
*/
Response head(
Map properties) {
def all = properties +
[method: 'head']
def all = properties + [method: 'head']
performRequest all
}

Expand All @@ -107,10 +103,8 @@ class HttpClient {
* &emsp;<b>expecting</b> - a class to deserialize response body to. If not specified, response body is a {@link String}<br/>
* &emsp;<b>of</b> - a subclass to deserialize response body to. Use to deserialize generic responses like {@link Collection}<{@link Map}>.
*/
Response get(
Map properties) {
def all = properties +
[method: 'get']
Response get(Map properties) {
def all = properties + [method: 'get']
performRequest all
}

Expand All @@ -123,10 +117,8 @@ class HttpClient {
* &emsp;<b>expecting</b> - a class to deserialize response body to. If not specified, response body is a {@link String}<br/>
* &emsp;<b>of</b> - a subclass to deserialize response body to. Use to deserialize generic responses like {@link Collection}<{@link Map}>.
*/
Response post(
Map properties) {
def all = properties +
[method: 'post']
Response post(Map properties) {
def all = properties + [method: 'post']
performRequest all
}

Expand All @@ -139,10 +131,8 @@ class HttpClient {
* &emsp;<b>expecting</b> - a class to deserialize response body to. If not specified, response body is a {@link String}<br/>
* &emsp;<b>of</b> - a subclass to deserialize response body to. Use to deserialize generic responses like {@link Collection}<{@link Map}>.
*/
Response put(
Map properties) {
def all = properties +
[method: 'put']
Response put(Map properties) {
def all = properties + [method: 'put']
performRequest all
}

Expand All @@ -155,10 +145,50 @@ class HttpClient {
* &emsp;<b>expecting</b> - a class to deserialize response body to. If not specified, response body is a {@link String}<br/>
* &emsp;<b>of</b> - a subclass to deserialize response body to. Use to deserialize generic responses like {@link Collection}<{@link Map}>.
*/
Response delete(
Map properties) {
def all = properties +
[method: 'delete']
Response delete(Map properties) {
def all = properties + [method: 'delete']
performRequest all
}

/**
* Possible properties:<br/>
* &emsp;<b>path</b> - a request path (appended to a base url defined at {@link #HttpClient(Map)} constructor)<br/>
* &emsp;<b>url</b> - a full request url (overrides path and base url)<br/>
* &emsp;<b>headers</b> as {@link Map}<br/>
* &emsp;<b>body</b> - a request body. Anything except {@link String} is serialized to a <a href="https://en.wikipedia.org/wiki/JSON">json</a>.<br/>
* &emsp;<b>expecting</b> - a class to deserialize response body to. If not specified, response body is a {@link String}<br/>
* &emsp;<b>of</b> - a subclass to deserialize response body to. Use to deserialize generic responses like {@link Collection}<{@link Map}>.
*/
Response trace(Map properties) {
def all = properties + [method: 'trace']
performRequest all
}

/**
* Possible properties:<br/>
* &emsp;<b>path</b> - a request path (appended to a base url defined at {@link #HttpClient(Map)} constructor)<br/>
* &emsp;<b>url</b> - a full request url (overrides path and base url)<br/>
* &emsp;<b>headers</b> as {@link Map}<br/>
* &emsp;<b>body</b> - a request body. Anything except {@link String} is serialized to a <a href="https://en.wikipedia.org/wiki/JSON">json</a>.<br/>
* &emsp;<b>expecting</b> - a class to deserialize response body to. If not specified, response body is a {@link String}<br/>
* &emsp;<b>of</b> - a subclass to deserialize response body to. Use to deserialize generic responses like {@link Collection}<{@link Map}>.
*/
Response patch(Map properties) {
def all = properties + [method: 'patch']
performRequest all
}

/**
* Possible properties:<br/>
* &emsp;<b>path</b> - a request path (appended to a base url defined at {@link #HttpClient(Map)} constructor)<br/>
* &emsp;<b>url</b> - a full request url (overrides path and base url)<br/>
* &emsp;<b>headers</b> as {@link Map}<br/>
* &emsp;<b>body</b> - a request body. Anything except {@link String} is serialized to a <a href="https://en.wikipedia.org/wiki/JSON">json</a>.<br/>
* &emsp;<b>expecting</b> - a class to deserialize response body to. If not specified, response body is a {@link String}<br/>
* &emsp;<b>of</b> - a subclass to deserialize response body to. Use to deserialize generic responses like {@link Collection}<{@link Map}>.
*/
Response options(Map properties) {
def all = properties + [method: 'options']
performRequest all
}

Expand Down
9 changes: 7 additions & 2 deletions src/main/groovy/com/tomtom/http/RequestBuilder.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,14 @@ class RequestBuilder {
return new HttpPut(url)
case 'delete':
return new HttpDelete(url)
case 'options':
return new HttpOptions(url)
case 'patch':
return new HttpPatch(url)
case 'trace':
return new HttpTrace(url)
default:
throw new UnsupportedOperationException(
"$method not supported")
throw new UnsupportedOperationException("$method not supported")
}
}

Expand Down
96 changes: 75 additions & 21 deletions src/test/groovy/com/tomtom/http/HttpClientSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ class HttpClientSpec extends Specification {
def mapper = new ObjectMapper()

when:
def http = new HttpClient(
mapper: mapper)
def http = new HttpClient(mapper: mapper)

then:
http.builder.mapper == mapper
Expand All @@ -62,13 +61,12 @@ class HttpClientSpec extends Specification {
parser: parser)

when:
def actual = http.get(
url: 'url')
def actual = http.get(url: 'foo')

then:
actual == response
1 * builder.request([
url : 'url',
url : 'foo',
method: 'get']
) >> request
1 * client.execute(request) >> httpResponse
Expand All @@ -88,12 +86,11 @@ class HttpClientSpec extends Specification {
parser: parser)

when:
http.post(
url: 'url')
http.post(url: 'foo')

then:
1 * builder.request([
url : 'url',
url : 'foo',
method: 'post'])
}

Expand All @@ -109,12 +106,11 @@ class HttpClientSpec extends Specification {
parser: parser)

when:
http.head(
url: 'url')
http.head(url: 'foo')

then:
1 * builder.request([
url : 'url',
url : 'foo',
method: 'head'])
}

Expand All @@ -130,12 +126,11 @@ class HttpClientSpec extends Specification {
parser: parser)

when:
http.put(
url: 'url')
http.put(url: 'foo')

then:
1 * builder.request([
url : 'url',
url : 'foo',
method: 'put'])
}

Expand All @@ -151,15 +146,74 @@ class HttpClientSpec extends Specification {
parser: parser)

when:
http.delete(
url: 'url')
http.delete(url: 'foo')

then:
1 * builder.request([
url : 'url',
url : 'foo',
method: 'delete'])
}

def 'Executes an options request'() {
given:
def builder = Mock RequestBuilder
def client = Mock org.apache.http.client.HttpClient
def parser = Mock ResponseParser
and:
def http = new HttpClient(
builder: builder,
client: client,
parser: parser)

when:
http.options(url: 'foo')

then:
1 * builder.request([
url : 'foo',
method: 'options'])
}

def 'Executes a trace request'() {
given:
def builder = Mock RequestBuilder
def client = Mock org.apache.http.client.HttpClient
def parser = Mock ResponseParser
and:
def http = new HttpClient(
builder: builder,
client: client,
parser: parser)

when:
http.trace(url: 'foo')

then:
1 * builder.request([
url : 'foo',
method: 'trace'])
}

def 'Executes a patch request'() {
given:
def builder = Mock RequestBuilder
def client = Mock org.apache.http.client.HttpClient
def parser = Mock ResponseParser
and:
def http = new HttpClient(
builder: builder,
client: client,
parser: parser)

when:
http.patch(url: 'foo')

then:
1 * builder.request([
url : 'foo',
method: 'patch'])
}

def 'Passes expected value'() {
given:
def builder = Mock RequestBuilder
Expand All @@ -173,7 +227,7 @@ class HttpClientSpec extends Specification {

when:
http.get(
url: 'url',
url: 'foo',
expecting: Map)

then:
Expand All @@ -193,7 +247,7 @@ class HttpClientSpec extends Specification {

when:
http.get(
url: 'url',
url: 'foo',
expecting: List, of: Map)

then:
Expand All @@ -203,10 +257,10 @@ class HttpClientSpec extends Specification {
def 'Allows to set base url'() {
when:
def http = new HttpClient(
baseUrl: 'base')
baseUrl: 'foo')

then:
http.builder.baseUrl == 'base'
http.builder.baseUrl == 'foo'
}

}
Loading

0 comments on commit b8139f6

Please sign in to comment.