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