static_http_cache/
reqwest_mock.rs1use std::error;
7use std::fmt;
8
9pub trait HttpResponse: std::io::Read + fmt::Debug
13where
14 Self: ::std::marker::Sized,
15{
16 fn headers(&self) -> &reqwest::header::HeaderMap;
18
19 fn status(&self) -> reqwest::StatusCode;
21
22 fn error_for_status(self) -> Result<Self, Box<dyn error::Error>>;
24}
25
26impl HttpResponse for reqwest::blocking::Response {
34 fn headers(&self) -> &reqwest::header::HeaderMap {
35 self.headers()
36 }
37 fn status(&self) -> reqwest::StatusCode {
38 self.status()
39 }
40 fn error_for_status(self) -> Result<Self, Box<dyn error::Error>> {
41 Ok(self.error_for_status()?)
42 }
43}
44
45pub trait Client {
49 type Response: HttpResponse;
51
52 fn execute(
54 &self,
55 request: reqwest::blocking::Request,
56 ) -> Result<Self::Response, Box<dyn error::Error>>;
57}
58
59impl Client for reqwest::blocking::Client {
60 type Response = reqwest::blocking::Response;
61
62 fn execute(
63 &self,
64 request: reqwest::blocking::Request,
65 ) -> Result<Self::Response, Box<dyn error::Error>> {
66 Ok(self.execute(request)?)
67 }
68}
69
70#[cfg(test)]
71pub mod tests {
72 use reqwest;
73
74 use std::cell;
75 use std::fmt;
76 use std::io;
77
78 use std::error::Error;
79 use std::io::Read;
80
81 #[derive(Debug, Eq, PartialEq, Hash)]
82 pub struct FakeError;
83
84 impl fmt::Display for FakeError {
85 fn fmt(
86 &self,
87 f: &mut ::std::fmt::Formatter,
88 ) -> Result<(), ::std::fmt::Error> {
89 f.write_str("FakeError")?;
90 Ok(())
91 }
92 }
93
94 impl Error for FakeError {
95 fn description(&self) -> &str {
96 "Something Ooo occurred"
97 }
98 fn cause(&self) -> Option<&dyn Error> {
99 None
100 }
101 }
102
103 #[derive(Clone, Debug)]
104 pub struct FakeResponse {
105 pub status: reqwest::StatusCode,
106 pub headers: reqwest::header::HeaderMap,
107 pub body: io::Cursor<Vec<u8>>,
108 }
109
110 impl super::HttpResponse for FakeResponse {
111 fn headers(&self) -> &reqwest::header::HeaderMap {
112 &self.headers
113 }
114 fn status(&self) -> reqwest::StatusCode {
115 self.status
116 }
117 fn error_for_status(self) -> Result<Self, Box<dyn Error>> {
118 if !self.status.is_client_error() && !self.status.is_server_error()
119 {
120 Ok(self)
121 } else {
122 Err(Box::new(FakeError))
123 }
124 }
125 }
126
127 impl Read for FakeResponse {
128 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
129 self.body.read(buf)
130 }
131 }
132
133 pub struct FakeClient {
134 pub expected_url: reqwest::Url,
135 pub expected_headers: reqwest::header::HeaderMap,
136 pub response: FakeResponse,
137 called: cell::Cell<bool>,
138 }
139
140 impl FakeClient {
141 pub fn new(
142 expected_url: reqwest::Url,
143 expected_headers: reqwest::header::HeaderMap,
144 response: FakeResponse,
145 ) -> FakeClient {
146 let called = cell::Cell::new(false);
147 FakeClient {
148 expected_url,
149 expected_headers,
150 response,
151 called,
152 }
153 }
154
155 pub fn assert_called(self) {
156 assert!(self.called.get());
157 }
158 }
159
160 impl super::Client for FakeClient {
161 type Response = FakeResponse;
162
163 fn execute(
164 &self,
165 request: reqwest::blocking::Request,
166 ) -> Result<Self::Response, Box<dyn Error>> {
167 assert_eq!(request.method(), &reqwest::Method::GET);
168 assert_eq!(request.url(), &self.expected_url);
169 assert_eq!(request.headers(), &self.expected_headers);
170
171 self.called.set(true);
172
173 Ok(self.response.clone())
174 }
175 }
176
177 pub struct BrokenClient<F>
178 where
179 F: Fn() -> Box<dyn Error>,
180 {
181 pub expected_url: reqwest::Url,
182 pub expected_headers: reqwest::header::HeaderMap,
183 pub make_error: F,
184 called: cell::Cell<bool>,
185 }
186
187 impl<F> BrokenClient<F>
188 where
189 F: Fn() -> Box<dyn Error>,
190 {
191 pub fn new(
192 expected_url: reqwest::Url,
193 expected_headers: reqwest::header::HeaderMap,
194 make_error: F,
195 ) -> BrokenClient<F> {
196 let called = cell::Cell::new(false);
197 BrokenClient {
198 expected_url,
199 expected_headers,
200 make_error,
201 called,
202 }
203 }
204
205 pub fn assert_called(self) {
206 assert!(self.called.get());
207 }
208 }
209
210 impl<F> super::Client for BrokenClient<F>
211 where
212 F: Fn() -> Box<dyn Error>,
213 {
214 type Response = FakeResponse;
215
216 fn execute(
217 &self,
218 request: reqwest::blocking::Request,
219 ) -> Result<Self::Response, Box<dyn Error>> {
220 assert_eq!(request.method(), &reqwest::Method::GET);
221 assert_eq!(request.url(), &self.expected_url);
222 assert_eq!(request.headers(), &self.expected_headers);
223
224 self.called.set(true);
225
226 Err((self.make_error)())
227 }
228 }
229}