omaha_client/http_request/
mock.rs1use crate::http_request::{Body, Error, HttpRequest, Request, Response, to_bytes};
10use futures::future::BoxFuture;
11use futures::prelude::*;
12use http::StatusCode;
13use pretty_assertions::assert_eq;
14use std::{cell::RefCell, collections::VecDeque, rc::Rc};
15
16#[cfg(test)]
17use futures::executor::block_on;
18
19#[derive(Debug, Default)]
20pub struct MockHttpRequest {
21 requests: Rc<RefCell<Vec<Request<Body>>>>,
23 responses: VecDeque<Result<Response<Vec<u8>>, Error>>,
25}
26
27impl HttpRequest for MockHttpRequest {
28 fn request(&mut self, req: Request<Body>) -> BoxFuture<'_, Result<Response<Vec<u8>>, Error>> {
29 self.requests.borrow_mut().push(req);
30
31 future::ready(if let Some(resp) = self.responses.pop_front() {
32 resp
33 } else {
34 Ok(Response::builder().status(StatusCode::INTERNAL_SERVER_ERROR).body(vec![]).unwrap())
36 })
37 .boxed()
38 }
39}
40
41impl MockHttpRequest {
42 pub fn new(res: Response<Vec<u8>>) -> Self {
43 Self { responses: vec![Ok(res)].into(), ..Default::default() }
44 }
45
46 pub fn empty() -> Self {
47 Default::default()
48 }
49
50 pub fn from_request_cell(request: Rc<RefCell<Vec<Request<Body>>>>) -> Self {
51 Self { requests: request, ..Default::default() }
52 }
53
54 pub fn get_request_cell(&self) -> Rc<RefCell<Vec<Request<Body>>>> {
55 Rc::clone(&self.requests)
56 }
57
58 pub fn add_response(&mut self, res: Response<Vec<u8>>) {
59 self.responses.push_back(Ok(res));
60 }
61
62 pub fn add_error(&mut self, error: Error) {
63 self.responses.push_back(Err(error));
64 }
65
66 pub fn assert_method(&self, method: &hyper::Method) {
67 assert_eq!(method, self.requests.borrow().last().unwrap().method());
68 }
69
70 pub fn assert_uri(&self, uri: &str) {
71 assert_eq!(
72 &uri.parse::<hyper::Uri>().unwrap(),
73 self.requests.borrow().last().unwrap().uri()
74 );
75 }
76
77 pub fn assert_header(&self, key: &str, value: &str) {
78 let requests = self.requests.borrow();
79 let request = requests.last().unwrap();
80 let headers = request.headers();
81 assert!(headers.contains_key(key));
82 assert_eq!(headers[key], value);
83 }
84
85 fn take_request(&self) -> Request<Body> {
86 self.requests.borrow_mut().pop().unwrap()
87 }
88
89 pub async fn assert_body(&self, body: &[u8]) {
90 let bytes = to_bytes(self.take_request()).await.unwrap();
91 assert_eq!(body, &bytes);
92 }
93
94 pub async fn assert_body_str(&self, body: &str) {
95 let bytes = to_bytes(self.take_request()).await.unwrap();
96 assert_eq!(body, String::from_utf8_lossy(&bytes));
97 }
98}
99
100#[test]
101fn test_mock() {
102 let res_body = vec![1, 2, 3];
103 let mut mock = MockHttpRequest::new(Response::new(res_body.clone()));
104
105 let req_body = vec![4, 5, 6];
106 let uri = "https://mock.uri/";
107 let req =
108 Request::get(uri).header("X-Custom-Foo", "Bar").body(req_body.clone().into()).unwrap();
109 block_on(async {
110 let response = mock.request(req).await.unwrap();
111 assert_eq!(res_body, response.into_body());
112
113 mock.assert_method(&hyper::Method::GET);
114 mock.assert_uri(uri);
115 mock.assert_header("X-Custom-Foo", "Bar");
116 mock.assert_body(req_body.as_slice()).await;
117 });
118}
119
120#[test]
121fn test_missing_response() {
122 let res_body = vec![1, 2, 3];
123 let mut mock = MockHttpRequest::new(Response::new(res_body.clone()));
124 block_on(async {
125 let response = mock.request(Request::default()).await.unwrap();
126 assert_eq!(res_body, response.into_body());
127
128 let response2 = mock.request(Request::default()).await.unwrap();
129 assert_eq!(response2.status(), hyper::StatusCode::INTERNAL_SERVER_ERROR);
130 });
131}
132
133#[test]
134fn test_multiple_responses() {
135 let res_body = vec![1, 2, 3];
136 let mut mock = MockHttpRequest::new(Response::new(res_body.clone()));
137 let res_body2 = vec![4, 5, 6];
138 mock.add_response(Response::new(res_body2.clone()));
139
140 block_on(async {
141 let response = mock.request(Request::default()).await.unwrap();
142 assert_eq!(res_body, response.into_body());
143
144 let response2 = mock.request(Request::default()).await.unwrap();
145 assert_eq!(res_body2, response2.into_body());
146 });
147}