FakeHttpLayer.java revision 5ed9c8041b5f927c930d50edef58c5378d12f89c
1package com.xtremelabs.robolectric.tester.org.apache.http;
2
3import org.apache.http.Header;
4import org.apache.http.HttpException;
5import org.apache.http.HttpHost;
6import org.apache.http.HttpRequest;
7import org.apache.http.HttpResponse;
8import org.apache.http.client.RequestDirector;
9import org.apache.http.protocol.HttpContext;
10
11import javax.xml.ws.http.HTTPException;
12import java.io.IOException;
13import java.util.ArrayList;
14import java.util.List;
15
16public class FakeHttpLayer {
17    List<HttpResponse> pendingHttpResponses = new ArrayList<HttpResponse>();
18    List<HttpRequestInfo> httpRequestInfos = new ArrayList<HttpRequestInfo>();
19    List<HttpEntityStub.ResponseRule> httpResponseRules = new ArrayList<HttpEntityStub.ResponseRule>();
20    HttpResponse defaultHttpResponse;
21    private HttpResponse defaultResponse;
22
23    public void addPendingHttpResponse(int statusCode, String responseBody) {
24        addPendingHttpResponse(new TestHttpResponse(statusCode, responseBody));
25    }
26
27    public void addPendingHttpResponseWithContentType(int statusCode, String responseBody, Header contentType) {
28        addPendingHttpResponse(new TestHttpResponse(statusCode, responseBody, contentType));
29    }
30
31    public void addPendingHttpResponse(HttpResponse httpResponse) {
32        pendingHttpResponses.add(httpResponse);
33    }
34
35    public void addHttpResponseRule(String method, String uri, HttpResponse response) {
36        addHttpResponseRule(new DefaultRequestMatcher(method, uri), response);
37    }
38
39    public void addHttpResponseRule(String uri, HttpResponse response) {
40        addHttpResponseRule(new UriRequestMatcher(uri), response);
41    }
42
43    public void addHttpResponseRule(String uri, String response) {
44        addHttpResponseRule(new UriRequestMatcher(uri), new TestHttpResponse(200, response));
45    }
46
47    public void addHttpResponseRule(RequestMatcher requestMatcher, HttpResponse response) {
48        addHttpResponseRule(new RequestMatcherResponseRule(requestMatcher, response));
49    }
50
51    public void addHttpResponseRule(HttpEntityStub.ResponseRule responseRule) {
52        httpResponseRules.add(responseRule);
53    }
54
55    public void setDefaultHttpResponse(HttpResponse defaultHttpResponse) {
56        this.defaultHttpResponse = defaultHttpResponse;
57    }
58
59    public void setDefaultHttpResponse(int statusCode, String responseBody) {
60        setDefaultHttpResponse(new TestHttpResponse(statusCode, responseBody));
61    }
62
63    private HttpResponse findResponse(HttpRequest httpRequest) throws HttpException, IOException {
64        if (!pendingHttpResponses.isEmpty()) {
65            return pendingHttpResponses.remove(0);
66        }
67
68        for (HttpEntityStub.ResponseRule httpResponseRule : httpResponseRules) {
69            if (httpResponseRule.matches(httpRequest)) {
70                return httpResponseRule.getResponse();
71            }
72        }
73
74        return defaultHttpResponse;
75    }
76
77    public HttpResponse emulateRequest(HttpHost httpHost, HttpRequest httpRequest, HttpContext httpContext, RequestDirector requestDirector) throws HttpException, IOException {
78        HttpResponse httpResponse = findResponse(httpRequest);
79
80        if (httpResponse == null) {
81            throw new RuntimeException("Unexpected call to execute, no pending responses are available. See Robolectric.addPendingResponse().");
82        }
83
84        httpRequestInfos.add(new HttpRequestInfo(httpRequest, httpHost, httpContext, requestDirector));
85
86        return httpResponse;
87    }
88    public boolean hasPendingResponses() {
89        return !pendingHttpResponses.isEmpty();
90    }
91
92    public boolean hasRequestInfos() {
93        return !httpRequestInfos.isEmpty();
94    }
95
96    public boolean hasResponseRules() {
97        return !httpResponseRules.isEmpty();
98    }
99
100    public boolean hasRequestMatchingRule(RequestMatcher rule) {
101        for (HttpRequestInfo requestInfo : httpRequestInfos) {
102            if (rule.matches(requestInfo.httpRequest)) {
103                return true;
104            }
105        }
106        return false;
107    }
108
109    public HttpResponse getDefaultResponse() {
110        return defaultResponse;
111    }
112
113    public HttpRequestInfo getSentHttpRequestInfo(int index) {
114        return httpRequestInfos.get(index);
115    }
116    public void clearHttpResponseRules() {
117        httpResponseRules.clear();
118    }
119
120    public static class RequestMatcherResponseRule implements HttpEntityStub.ResponseRule {
121        private RequestMatcher requestMatcher;
122        private HttpResponse responseToGive;
123        private IOException ioException;
124        private HTTPException httpException;
125
126        public RequestMatcherResponseRule(RequestMatcher requestMatcher, HttpResponse responseToGive) {
127            this.requestMatcher = requestMatcher;
128            this.responseToGive = responseToGive;
129        }
130
131        public RequestMatcherResponseRule(RequestMatcher requestMatcher, IOException ioException) {
132            this.requestMatcher = requestMatcher;
133            this.ioException = ioException;
134        }
135
136        public RequestMatcherResponseRule(RequestMatcher requestMatcher, HTTPException httpException) {
137            this.requestMatcher = requestMatcher;
138            this.httpException = httpException;
139        }
140
141        @Override public boolean matches(HttpRequest request) {
142            return requestMatcher.matches(request);
143        }
144
145        @Override public HttpResponse getResponse() throws HttpException, IOException {
146            if (httpException != null) throw httpException;
147            if (ioException != null) throw ioException;
148            return responseToGive;
149        }
150    }
151
152    public static class DefaultRequestMatcher implements RequestMatcher {
153        private String method;
154        private String uri;
155
156        public DefaultRequestMatcher(String method, String uri) {
157            this.method = method;
158            this.uri = uri;
159        }
160
161        @Override public boolean matches(HttpRequest request) {
162            return request.getRequestLine().getMethod().equals(method) &&
163                    request.getRequestLine().getUri().equals(uri);
164        }
165    }
166
167    public static class UriRequestMatcher implements RequestMatcher {
168        private String uri;
169
170        public UriRequestMatcher(String uri) {
171            this.uri = uri;
172        }
173
174        @Override public boolean matches(HttpRequest request) {
175            return request.getRequestLine().getUri().equals(uri);
176        }
177    }
178}
179