gitignore_template_generator/http_client/
api.rs1use crate::ProgramError;
2pub use crate::http_client::impls::{MockClient, UreqClient};
3
4pub trait HttpClient {
5 fn get(&self, url: &str) -> Result<String, ProgramError>;
6}
7
8#[cfg(test)]
9mod tests {
10 use super::*;
11 use crate::constant;
12 use mockito::Server;
13
14 mod ureq_client {
15 use super::*;
16
17 mod get {
18 use super::*;
19
20 mod success {
21 use super::*;
22
23 #[test]
24 fn it_fetches_data_as_string_when_200_response() {
25 let mut mock_server = Server::new();
26 let mock_body = "gitignore template for rust";
27 let mock_uri = "/api/rust";
28 let mock = mock_server
29 .mock("GET", mock_uri)
30 .with_status(200)
31 .with_body(mock_body)
32 .create();
33
34 let server_url = mock_server.url();
35 let http_client = UreqClient::default();
36
37 let actual =
38 http_client.get(&format!("{server_url}{mock_uri}"));
39 let expected: Result<String, ProgramError> =
40 Ok(String::from(mock_body));
41
42 mock.assert();
43 assert_eq!(actual, expected);
44 }
45
46 #[test]
47 fn it_fetches_data_as_string_from_given_server_url_when_200() {
48 let mut mock_server = Server::new();
49 let mock_body = "gitignore template for rust";
50 let mock_uri = "/api/rust";
51 let mock = mock_server
52 .mock("GET", mock_uri)
53 .with_status(200)
54 .with_body(mock_body)
55 .create();
56
57 let server_url = mock_server.url();
58 let http_client = UreqClient { server_url };
59
60 let actual = http_client.get(mock_uri);
61 let expected: Result<String, ProgramError> =
62 Ok(String::from(mock_body));
63
64 mock.assert();
65 assert_eq!(actual, expected);
66 }
67 }
68
69 mod failure {
70 use crate::ErrorKind;
71
72 use super::*;
73
74 #[test]
75 fn it_fails_with_api_call_error_when_400_response() {
76 let mut mock_server = Server::new();
77 let mock_body = "error response";
78 let mock_uri = "/api/rust";
79 let mock = mock_server
80 .mock("GET", mock_uri)
81 .with_status(400)
82 .with_body(mock_body)
83 .create();
84
85 let server_url = mock_server.url();
86 let http_client = UreqClient::default();
87
88 let actual =
89 http_client.get(&format!("{server_url}{mock_uri}"));
90 let expected: Result<String, ProgramError> =
91 Err(ProgramError {
92 message: constant::error_messages::API_CALL_FAILURE
93 .replace(
94 "{error}",
95 constant::error_messages::HTTP_400,
96 ),
97 exit_status: constant::exit_status::GENERIC,
98 styled_message: None,
99 error_kind: ErrorKind::Other,
100 });
101
102 mock.assert();
103 assert_eq!(actual, expected);
104 }
105
106 #[test]
107 fn it_fails_with_body_parsing_error_when_invalid_body() {
108 let mut mock_server = Server::new();
109 let mock_body = vec![0, 159, 146, 150];
110 let mock_uri = "/api/rust";
111 let mock = mock_server
112 .mock("GET", mock_uri)
113 .with_status(200)
114 .with_body(mock_body)
115 .create();
116
117 let server_url = mock_server.url();
118 let http_client = UreqClient::default();
119
120 let actual =
121 http_client.get(&format!("{server_url}{mock_uri}"));
122 let expected: Result<String, ProgramError> =
123 Err(ProgramError {
124 message: String::from(
125 constant::error_messages::BODY_PARSING_ISSUE,
126 ),
127 exit_status:
128 constant::exit_status::BODY_PARSING_ISSUE,
129 styled_message: None,
130 error_kind: ErrorKind::Other,
131 });
132
133 mock.assert();
134 assert_eq!(actual, expected);
135 }
136 }
137 }
138 }
139
140 mod mock_client {
141 use super::*;
142
143 mod get {
144 use super::*;
145
146 mod success {
147 use crate::ErrorKind;
148
149 use super::*;
150
151 #[test]
152 fn it_returns_ok_mocked_response() {
153 let result_content = "success response";
154 let http_client = MockClient {
155 response: Ok(String::from(result_content)),
156 };
157
158 let actual = http_client.get("/api/rust");
159 let expected: Result<String, ProgramError> =
160 Ok(String::from(result_content));
161
162 assert_eq!(actual, expected);
163 }
164
165 #[test]
166 fn it_returns_error_mocked_response() {
167 let result_content = "error response";
168 let http_client = MockClient {
169 response: Err(ProgramError {
170 message: String::from(result_content),
171 exit_status: constant::exit_status::GENERIC,
172 styled_message: None,
173 error_kind: ErrorKind::Other,
174 }),
175 };
176
177 let actual = http_client.get("/api/rust");
178 let expected: Result<String, ProgramError> =
179 Err(ProgramError {
180 message: String::from(result_content),
181 exit_status: constant::exit_status::GENERIC,
182 styled_message: None,
183 error_kind: ErrorKind::Other,
184 });
185
186 assert_eq!(actual, expected);
187 }
188 }
189 }
190 }
191}