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