Skip to content

Commit

Permalink
Mock: manage headers using RequestHeaders (#706)
Browse files Browse the repository at this point in the history
* feat(feign-mock): add RequestHeaders class to manage headers

* feat(feign-mock): use google code style formatting

* feat(feign-mock): remove system.out

* feat(RequestKey): add deprecated headers builder + format code

* feat(feign-mock): format pom correctly

* feat(feign-mock): format pom correctly

* fix(feign-mock): undo some typo and no-op change
  • Loading branch information
pboutes authored and velo committed May 17, 2018
1 parent 8117fcf commit fb825f2
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 42 deletions.
8 changes: 3 additions & 5 deletions mock/src/main/java/feign/mock/MockClient.java
Expand Up @@ -19,7 +19,6 @@
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
Expand All @@ -45,8 +44,6 @@ public RequestResponse(RequestKey requestKey, Response.Builder responseBuilder)

}

public static final Map<String, Collection<String>> EMPTY_HEADERS = Collections.emptyMap();

private final List<RequestResponse> responses = new ArrayList<RequestResponse>();

private final Map<RequestKey, List<Request>> requests = new HashMap<RequestKey, List<Request>>();
Expand Down Expand Up @@ -196,7 +193,7 @@ public MockClient add(RequestKey requestKey, int status, String responseBody) {

public MockClient add(RequestKey requestKey, int status, byte[] responseBody) {
return add(requestKey,
Response.builder().status(status).reason("Mocked").headers(EMPTY_HEADERS)
Response.builder().status(status).reason("Mocked").headers(RequestHeaders.EMPTY)
.body(responseBody));
}

Expand Down Expand Up @@ -255,7 +252,7 @@ public void verifyNever(HttpMethod method, String url) {

/**
* To be called in an &#64;After method:
*
*
* <pre>
* &#64;After
* public void tearDown() {
Expand All @@ -276,4 +273,5 @@ public void resetRequests() {
requests.clear();
}


}
121 changes: 121 additions & 0 deletions mock/src/main/java/feign/mock/RequestHeaders.java
@@ -0,0 +1,121 @@
/**
* Copyright 2012-2018 The Feign Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package feign.mock;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class RequestHeaders {

public static class Builder {

private Map<String, Collection<String>> headers = new HashMap<String, Collection<String>>();

private Builder() {}

public Builder add(String key, Collection<String> values) {
if (!headers.containsKey(key)) {
headers.put(key, values);
} else {
Collection<String> previousValues = headers.get(key);
previousValues.addAll(values);
headers.put(key, previousValues);
}
return this;
}

public Builder add(String key, String value) {
if (!headers.containsKey(key)) {
headers.put(key, new ArrayList<String>(Arrays.asList(value)));
} else {
final Collection<String> values = headers.get(key);
values.add(value);
headers.put(key, values);
}
return this;
}

public RequestHeaders build() {
return new RequestHeaders(this);
}

}

public static final Map<String, Collection<String>> EMPTY = Collections.emptyMap();

public static Builder builder() {
return new Builder();
}

public static RequestHeaders of(Map<String, Collection<String>> headers) {
return new RequestHeaders(headers);
}

private Map<String, Collection<String>> headers;

private RequestHeaders(Builder builder) {
this.headers = builder.headers;
}

private RequestHeaders(Map<String, Collection<String>> headers) {
this.headers = headers;
}

public int size() {
return headers.size();
}

public int sizeOf(String key) {
if (!headers.containsKey(key)) {
return 0;
}
return headers.get(key).size();
}

public Collection<String> fetch(String key) {
return headers.get(key);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final RequestHeaders other = (RequestHeaders) obj;
return this.headers.equals(other.headers);
}

@Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (Map.Entry<String, Collection<String>> entry : headers.entrySet()) {
builder.append(entry).append(',').append(' ');
}
if (builder.length() > 0) {
return builder.substring(0, builder.length() - 2);
}
return "no";
}

}
36 changes: 22 additions & 14 deletions mock/src/main/java/feign/mock/RequestKey.java
Expand Up @@ -31,7 +31,7 @@ public static class Builder {

private final String url;

private Map<String, Collection<String>> headers;
private RequestHeaders headers;

private Charset charset;

Expand All @@ -42,7 +42,13 @@ private Builder(HttpMethod method, String url) {
this.url = url;
}

@Deprecated
public Builder headers(Map<String, Collection<String>> headers) {
this.headers = RequestHeaders.of(headers);
return this;
}

public Builder headers(RequestHeaders headers) {
this.headers = headers;
return this;
}
Expand Down Expand Up @@ -87,7 +93,7 @@ private static String buildUrl(Request request) {

private final String url;

private final Map<String, Collection<String>> headers;
private final RequestHeaders headers;

private final Charset charset;

Expand All @@ -104,7 +110,7 @@ private RequestKey(Builder builder) {
private RequestKey(Request request) {
this.method = HttpMethod.valueOf(request.method());
this.url = buildUrl(request);
this.headers = request.headers();
this.headers = RequestHeaders.of(request.headers());
this.charset = request.charset();
this.body = request.body();
}
Expand All @@ -117,7 +123,7 @@ public String getUrl() {
return url;
}

public Map<String, Collection<String>> getHeaders() {
public RequestHeaders getHeaders() {
return headers;
}

Expand All @@ -140,21 +146,23 @@ public int hashCode() {

@Override
public boolean equals(Object obj) {
if (this == obj)
if (this == obj) {
return true;
if (obj == null)
}
if (obj == null) {
return false;
if (getClass() != obj.getClass())
}
if (getClass() != obj.getClass()) {
return false;
}
final RequestKey other = (RequestKey) obj;
if (method != other.method)
if (method != other.method) {
return false;
}
if (url == null) {
if (other.url != null)
return false;
} else if (!url.equals(other.url))
return false;
return true;
return other.url == null;
} else
return url.equals(other.url);
}

public boolean equalsExtended(Object obj) {
Expand All @@ -173,7 +181,7 @@ public boolean equalsExtended(Object obj) {
@Override
public String toString() {
return String.format("Request [%s %s: %s headers and %s]", method, url,
headers == null ? "without" : "with " + headers.size(),
headers == null ? "without" : "with " + headers,
charset == null ? "no charset" : "charset " + charset);
}

Expand Down
15 changes: 10 additions & 5 deletions mock/src/test/java/feign/mock/MockClientSequentialTest.java
Expand Up @@ -31,6 +31,7 @@
import feign.Body;
import feign.Feign;
import feign.FeignException;
import feign.Headers;
import feign.Param;
import feign.RequestLine;
import feign.Response;
Expand All @@ -42,6 +43,7 @@ public class MockClientSequentialTest {

interface GitHub {

@Headers({"Name: {owner}"})
@RequestLine("GET /repos/{owner}/{repo}/contributors")
List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);

Expand Down Expand Up @@ -89,26 +91,29 @@ public Object decode(Response response, Type type)
}

private GitHub githubSequential;

private MockClient mockClientSequential;

@Before
public void setup() throws IOException {
try (InputStream input = getClass().getResourceAsStream("/fixtures/contributors.json")) {
byte[] data = toByteArray(input);

RequestHeaders headers = RequestHeaders
.builder()
.add("Name", "netflix")
.build();
mockClientSequential = new MockClient(true);
githubSequential = Feign.builder().decoder(new AssertionDecoder(new GsonDecoder()))
.client(mockClientSequential
.add(HttpMethod.GET, "/repos/netflix/feign/contributors", HttpsURLConnection.HTTP_OK,
data)
.add(RequestKey
.builder(HttpMethod.GET, "/repos/netflix/feign/contributors")
.headers(headers).build(), HttpsURLConnection.HTTP_OK, data)
.add(HttpMethod.GET, "/repos/netflix/feign/contributors?client_id=55",
HttpsURLConnection.HTTP_NOT_FOUND)
.add(HttpMethod.GET, "/repos/netflix/feign/contributors?client_id=7 7",
HttpsURLConnection.HTTP_INTERNAL_ERROR, new ByteArrayInputStream(data))
.add(HttpMethod.GET, "/repos/netflix/feign/contributors",
Response.builder().status(HttpsURLConnection.HTTP_OK)
.headers(MockClient.EMPTY_HEADERS).body(data)))
.headers(RequestHeaders.EMPTY).body(data)))
.target(new MockTarget<>(GitHub.class));
}
}
Expand Down
1 change: 0 additions & 1 deletion mock/src/test/java/feign/mock/MockClientTest.java
Expand Up @@ -91,7 +91,6 @@ public Object decode(Response response, Type type)
}

private GitHub github;

private MockClient mockClient;

@Before
Expand Down
2 changes: 1 addition & 1 deletion mock/src/test/java/feign/mock/MockTargetTest.java
Expand Up @@ -14,7 +14,7 @@
package feign.mock;

import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.*;
import static org.junit.Assert.assertThat;
import org.junit.Before;
import org.junit.Test;

Expand Down

0 comments on commit fb825f2

Please sign in to comment.