gitignore_template_generator/http_client/
api.rs

1pub use crate::http_client::impls::{MockClient, UreqClient};
2
3#[derive(Clone, PartialEq, Debug)]
4pub struct ProgramError {
5    pub message: String,
6    pub exit_status: i32,
7}
8
9pub trait HttpClient {
10    fn get(&self, url: &str) -> Result<String, ProgramError>;
11}
12
13#[cfg(test)]
14mod tests {
15    use super::*;
16    use mockito::Server;
17
18    mod ureq_client {
19        use super::*;
20
21        mod get {
22            use super::*;
23
24            #[test]
25            fn it_fetches_data_correctly_with_ureq_client() {
26                let api_response = "gitignore template for rust";
27                let mut server = Server::new();
28                let base_url = server.url();
29                let uri = "/api/rust";
30
31                let mock = server
32                    .mock("GET", uri)
33                    .with_status(200)
34                    .with_body(api_response)
35                    .create();
36
37                let client = UreqClient::default();
38                let expected: Result<String, ProgramError> =
39                    Ok(String::from(api_response));
40                let actual = client.get(&format!("{base_url}{uri}"));
41
42                mock.assert();
43                assert_eq!(actual, expected);
44            }
45
46            #[test]
47            fn it_fetches_data_correctly_with_ureq_client_and_server_url() {
48                let api_response = "gitignore template for rust";
49                let mut server = Server::new();
50                let base_url = server.url();
51                let uri = "/api/rust";
52
53                let mock = server
54                    .mock("GET", uri)
55                    .with_status(200)
56                    .with_body(api_response)
57                    .create();
58
59                let client = UreqClient {
60                    server_url: base_url,
61                };
62                let expected: Result<String, ProgramError> =
63                    Ok(String::from(api_response));
64                let actual = client.get(uri);
65
66                mock.assert();
67                assert_eq!(actual, expected);
68            }
69
70            #[test]
71            fn it_gracefully_fails_if_non_200_response_with_ureq_client() {
72                let api_response = "error response";
73                let mut server = Server::new();
74                let base_url = server.url();
75                let uri = "/api/rust";
76
77                let mock = server
78                    .mock("GET", uri)
79                    .with_status(400)
80                    .with_body(api_response)
81                    .create();
82
83                let client = UreqClient::default();
84                let expected: Result<String, ProgramError> = Err(
85                    ProgramError {
86                        message: String::from(
87                            "An error occurred during the API call: http status: 400",
88                        ),
89                        exit_status: 2,
90                    },
91                );
92                let actual = client.get(&format!("{base_url}{uri}"));
93
94                mock.assert();
95                assert_eq!(actual, expected);
96            }
97
98            #[test]
99            fn it_gracefully_fails_if_body_parsing_issue_with_ureq_client() {
100                let mut server = Server::new();
101                let base_url = server.url();
102                let uri = "/api/rust";
103
104                let mock = server
105                    .mock("GET", uri)
106                    .with_status(200)
107                    .with_body(vec![0, 159, 146, 150])
108                    .create();
109
110                let client = UreqClient::default();
111                let expected: Result<String, ProgramError> =
112                    Err(ProgramError {
113                        message: String::from(
114                            "An error occurred during body parsing",
115                        ),
116                        exit_status: 3,
117                    });
118                let actual = client.get(&format!("{base_url}{uri}"));
119
120                mock.assert();
121                assert_eq!(actual, expected);
122            }
123        }
124    }
125
126    mod mock_client {
127        use super::*;
128
129        mod get {
130            use super::*;
131
132            #[test]
133            fn it_returns_given_result_with_mock_client() {
134                let client = MockClient {
135                    response: Ok(String::from("success response")),
136                };
137
138                let expected: Result<String, ProgramError> =
139                    Ok(String::from("success response"));
140                let actual = client.get("/api/rust");
141
142                assert_eq!(actual, expected);
143            }
144        }
145    }
146}