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 fdcc843 commit b0db2dd
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 39 deletions.
5 changes: 1 addition & 4 deletions mock/src/main/java/feign/mock/MockClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,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 @@ -201,7 +198,7 @@ public MockClient add(RequestKey requestKey, int status, byte[] responseBody) {
Response.builder()
.status(status)
.reason("Mocked")
.headers(EMPTY_HEADERS)
.headers(RequestHeaders.EMPTY)
.body(responseBody));
}

Expand Down
119 changes: 119 additions & 0 deletions mock/src/main/java/feign/mock/RequestHeaders.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/**
* Copyright 2012-2018 The Feign Authors
*
* <p>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
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>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";
}
}
37 changes: 25 additions & 12 deletions mock/src/main/java/feign/mock/RequestKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static class Builder {

private final String url;

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

private Charset charset;

Expand All @@ -43,7 +43,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,15 +146,22 @@ public int hashCode() {

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final RequestKey other = (RequestKey) obj;
if (method != other.method) return false;
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 @@ -170,7 +183,7 @@ public String toString() {
"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);
}
}
12 changes: 7 additions & 5 deletions mock/src/test/java/feign/mock/MockClientSequentialTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import feign.Body;
import feign.Feign;
import feign.FeignException;
import feign.Headers;
import feign.Param;
import feign.RequestLine;
import feign.Response;
Expand All @@ -43,6 +44,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,23 +91,23 @@ 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",
RequestKey.builder(HttpMethod.GET, "/repos/netflix/feign/contributors")
.headers(headers)
.build(),
HttpsURLConnection.HTTP_OK,
data)
.add(
Expand All @@ -122,7 +124,7 @@ public void setup() throws IOException {
"/repos/netflix/feign/contributors",
Response.builder()
.status(HttpsURLConnection.HTTP_OK)
.headers(MockClient.EMPTY_HEADERS)
.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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
82 changes: 82 additions & 0 deletions mock/src/test/java/feign/mock/RequestHeadersTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* Copyright 2012-2018 The Feign Authors
*
* <p>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
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>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 static org.assertj.core.api.Assertions.assertThat;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;

public class RequestHeadersTest {

@Test
public void shouldCreateEmptyRequestHeaders() {
RequestHeaders headers = RequestHeaders.builder().build();
assertThat(headers.size()).isEqualTo(0);
}

@Test
public void shouldReturnZeroSizeForUnknownKey() {
RequestHeaders headers = RequestHeaders.builder().build();
assertThat(headers.sizeOf("unknown")).isEqualTo(0);
}

@Test
public void shouldCreateRequestHeadersFromSingleValue() {
RequestHeaders headers =
RequestHeaders.builder().add("header", "val").add("other header", "val2").build();

assertThat(headers.fetch("header")).contains("val");
assertThat(headers.sizeOf("header")).isEqualTo(1);
assertThat(headers.fetch("other header")).contains("val2");
assertThat(headers.sizeOf("other header")).isEqualTo(1);
}

@Test
public void shouldCreateRequestHeadersFromSingleValueAndCollection() {
RequestHeaders headers =
RequestHeaders.builder()
.add("header", "val")
.add("other header", "val2")
.add("header", Arrays.asList("val3", "val4"))
.build();

assertThat(headers.fetch("header")).contains("val", "val3", "val4");
assertThat(headers.sizeOf("header")).isEqualTo(3);
assertThat(headers.fetch("other header")).contains("val2");
assertThat(headers.sizeOf("other header")).isEqualTo(1);
}

@Test
public void shouldCreateRequestHeadersFromHeadersMap() {
Map<String, Collection<String>> map = new HashMap<String, Collection<String>>();
map.put("header", Arrays.asList("val", "val2"));
RequestHeaders headers = RequestHeaders.of(map);
assertThat(headers.size()).isEqualTo(1);
}

@Test
public void shouldPrintHeaders() {
RequestHeaders headers =
RequestHeaders.builder()
.add("header", "val")
.add("other header", "val2")
.add("header", Arrays.asList("val3", "val4"))
.build();
assertThat(headers.toString()).isEqualTo("other header=[val2], header=[val, val3, val4]");
}
}
Loading

0 comments on commit b0db2dd

Please sign in to comment.