aboutsummaryrefslogtreecommitdiff
path: root/src/ip_service.rs
diff options
context:
space:
mode:
authorGus Power <gus@infinitesidequests.com>2025-05-12 10:52:28 +0100
committerGus Power <gus@infinitesidequests.com>2025-05-12 10:52:28 +0100
commit1d6fd8359fddbae8aeac17b90ed50d41143ffbb6 (patch)
tree7872e1e112ea9ed440caecad9755da751de59ccd /src/ip_service.rs
parente1f43bb48b23338ce103dc92a53a13e72021299d (diff)
skeleton dyndns service, split into ip and dyndns modules
Diffstat (limited to 'src/ip_service.rs')
-rw-r--r--src/ip_service.rs74
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()
+ }
+ }
+}