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