-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathStubHttpClient.java
More file actions
154 lines (133 loc) · 4.17 KB
/
Copy pathStubHttpClient.java
File metadata and controls
154 lines (133 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package io.facturapi;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
final class StubHttpClient {
static final class QueuedResponse {
final int statusCode;
final byte[] body;
final Map<String, List<String>> headers;
QueuedResponse(int statusCode, byte[] body, Map<String, List<String>> headers) {
this.statusCode = statusCode;
this.body = body;
this.headers = headers;
}
}
static final class RecordedHeaders {
private final Headers headers;
RecordedHeaders(Headers headers) {
this.headers = headers;
}
Optional<String> firstValue(String name) {
return Optional.ofNullable(headers.values(name).stream().findFirst().orElse(null));
}
}
static final class RecordedRequest {
private final Request request;
RecordedRequest(Request request) {
this.request = request;
}
String method() {
return request.method();
}
URI uri() {
return request.url().uri();
}
RecordedHeaders headers() {
return new RecordedHeaders(request.headers());
}
String bodyUtf8() {
RequestBody body = request.body();
if (body == null) {
return "";
}
Buffer buffer = new Buffer();
try {
body.writeTo(buffer);
} catch (IOException e) {
throw new RuntimeException(e);
}
return buffer.readString(StandardCharsets.UTF_8);
}
}
private final Deque<QueuedResponse> queue = new ArrayDeque<>();
private final List<RecordedRequest> requests = new ArrayList<>();
private final OkHttpClient client;
StubHttpClient() {
this.client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
requests.add(new RecordedRequest(request));
QueuedResponse queued = queue.poll();
if (queued == null) {
throw new IOException("No queued response");
}
return buildResponse(request, queued);
}
})
.build();
}
OkHttpClient client() {
return client;
}
void enqueueJson(int statusCode, String json) {
enqueueJson(statusCode, json, Map.of());
}
void enqueueJson(int statusCode, String json, Map<String, List<String>> extraHeaders) {
Map<String, List<String>> headers = new java.util.HashMap<>(extraHeaders);
headers.put("Content-Type", List.of("application/json"));
queue.add(
new QueuedResponse(
statusCode,
json.getBytes(StandardCharsets.UTF_8),
headers
)
);
}
void enqueueBinary(int statusCode, byte[] bytes, String contentType) {
queue.add(new QueuedResponse(statusCode, bytes, Map.of("Content-Type", List.of(contentType))));
}
List<RecordedRequest> requests() {
return requests;
}
private static Response buildResponse(Request request, QueuedResponse queued) {
Headers headers = toHeaders(queued.headers);
MediaType mediaType = headers.get("Content-Type") == null ? null : MediaType.get(headers.get("Content-Type"));
ResponseBody body = ResponseBody.create(queued.body, mediaType);
return new Response.Builder()
.request(request)
.protocol(Protocol.HTTP_1_1)
.code(queued.statusCode)
.message(queued.statusCode >= 200 && queued.statusCode < 300 ? "OK" : "ERROR")
.headers(headers)
.body(body)
.build();
}
private static Headers toHeaders(Map<String, List<String>> headers) {
Headers.Builder builder = new Headers.Builder();
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
for (String value : entry.getValue()) {
builder.add(entry.getKey(), value);
}
}
return builder.build();
}
}