diff options
Diffstat (limited to 'src/ip_service.rs')
| -rw-r--r-- | src/ip_service.rs | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/ip_service.rs b/src/ip_service.rs new file mode 100644 index 0000000..8e2bee8 --- /dev/null +++ b/src/ip_service.rs @@ -0,0 +1,74 @@ +use reqwest::Url; +use std::error::Error; +use std::net::IpAddr; +use std::str::FromStr; + +pub struct IpService {} + +impl IpService { + async fn resolve(config: &impl IpServiceConfiguration) -> Result<IpAddr, Box<dyn Error>> { + let response = reqwest::get(config.get_service_url()).await.unwrap(); + Ok(IpAddr::from_str(&response.text().await.unwrap())?) + } +} + +pub trait IpServiceConfiguration { + fn get_service_url(&self) -> Url; +} + +#[cfg(test)] +mod tests { + use super::*; + use std::net::Ipv4Addr; + use wiremock::matchers::{method, path}; + use wiremock::{Mock, MockServer, ResponseTemplate}; + + async fn setup_ipv4_service(service_path: &str, response: &str) -> MockServer { + let service = MockServer::start().await; + + Mock::given(method("GET")) + .and(path(service_path)) + .respond_with( + ResponseTemplate::new(200) + .insert_header("Content-Type", "text/plain; charset=utf-8") + .set_body_string(response), + ) + .mount(&service) + .await; + + service + } + + #[tokio::test] + async fn successful_ipv4_address_resolution() -> Result<(), Box<dyn Error>> { + let service_path = "get-my-ip-address"; + let service_response = "17.5.7.8"; + + let ip_service = setup_ipv4_service(service_path, service_response).await; + let service_config = MockConfig::new(&ip_service, service_path); + + let actual = IpService::resolve(&service_config).await?; + assert_eq!(actual, IpAddr::V4(Ipv4Addr::new(17, 5, 7, 8))); + + assert_eq!(1, ip_service.received_requests().await.unwrap().len()); + + Ok(()) + } + + struct MockConfig { + service_url: Url, + } + + impl MockConfig { + fn new(server: &MockServer, path: &str) -> Self { + Self { + service_url: Url::parse(format!("{}/{}", server.uri(), path).as_str()).unwrap(), + } + } + } + impl IpServiceConfiguration for MockConfig { + fn get_service_url(&self) -> Url { + self.service_url.clone() + } + } +} |
