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    #[test]
19    fn it_fetches_data_correctly_with_ureq_client() {
20        let api_response = "gitignore template for rust";
21        let mut server = Server::new();
22        let base_url = server.url();
23        let uri = "/api/rust";
24
25        let mock = server
26            .mock("GET", uri)
27            .with_status(200)
28            .with_body(api_response)
29            .create();
30
31        let client = UreqClient::default();
32        let expected: Result<String, ProgramError> =
33            Ok(String::from(api_response));
34        let actual = client.get(&format!("{base_url}{uri}"));
35
36        mock.assert();
37        assert_eq!(actual, expected);
38    }
39
40    #[test]
41    fn it_fetches_data_correctly_with_ureq_client_and_server_url() {
42        let api_response = "gitignore template for rust";
43        let mut server = Server::new();
44        let base_url = server.url();
45        let uri = "/api/rust";
46
47        let mock = server
48            .mock("GET", uri)
49            .with_status(200)
50            .with_body(api_response)
51            .create();
52
53        let client = UreqClient {
54            server_url: base_url,
55        };
56        let expected: Result<String, ProgramError> =
57            Ok(String::from(api_response));
58        let actual = client.get(uri);
59
60        mock.assert();
61        assert_eq!(actual, expected);
62    }
63
64    #[test]
65    fn it_gracefully_fails_if_non_200_response_with_ureq_client() {
66        let api_response = "error response";
67        let mut server = Server::new();
68        let base_url = server.url();
69        let uri = "/api/rust";
70
71        let mock = server
72            .mock("GET", uri)
73            .with_status(400)
74            .with_body(api_response)
75            .create();
76
77        let client = UreqClient::default();
78        let expected: Result<String, ProgramError> = Err(ProgramError {
79            message: String::from(
80                "An error occurred during the API call: http status: 400",
81            ),
82            exit_status: 2,
83        });
84        let actual = client.get(&format!("{base_url}{uri}"));
85
86        mock.assert();
87        assert_eq!(actual, expected);
88    }
89
90    #[test]
91    fn it_gracefully_fails_if_body_parsing_issue_with_ureq_client() {
92        let mut server = Server::new();
93        let base_url = server.url();
94        let uri = "/api/rust";
95
96        let mock = server
97            .mock("GET", uri)
98            .with_status(200)
99            .with_body(vec![0, 159, 146, 150])
100            .create();
101
102        let client = UreqClient::default();
103        let expected: Result<String, ProgramError> = Err(ProgramError {
104            message: String::from("An error occurred during body parsing"),
105            exit_status: 3,
106        });
107        let actual = client.get(&format!("{base_url}{uri}"));
108
109        mock.assert();
110        assert_eq!(actual, expected);
111    }
112
113    #[test]
114    fn it_returns_given_result_with_mock_client() {
115        let client = MockClient {
116            response: Ok(String::from("success response")),
117        };
118
119        let expected: Result<String, ProgramError> =
120            Ok(String::from("success response"));
121        let actual = client.get("/api/rust");
122
123        assert_eq!(actual, expected);
124    }
125}