From 241fe4953fdc9ba61156610f7a16777eeb0fad1f Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sat, 6 Apr 2024 14:20:38 +0300 Subject: [PATCH] test(wiremoc): add tests --- Cargo.lock | 324 +++++++++++++++------------------ Cargo.toml | 14 +- config/base.toml | 5 + config/production.toml | 4 + src/config.rs | 15 ++ src/domain/subscriber_email.rs | 2 +- src/email_client.rs | 121 ++++++++++++ src/lib.rs | 1 + src/main.rs | 13 +- src/routes/mod.rs | 7 +- src/routes/subscibtions.rs | 2 +- tests/health_check.rs | 14 +- 12 files changed, 334 insertions(+), 188 deletions(-) create mode 100644 src/email_client.rs diff --git a/Cargo.lock b/Cargo.lock index 4c861d2..fd12094 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,6 +60,16 @@ dependencies = [ "libc", ] +[[package]] +name = "assert-json-diff" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "async-trait" version = "0.1.79" @@ -265,16 +275,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -330,6 +330,24 @@ dependencies = [ "typenum", ] +[[package]] +name = "deadpool" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb84100978c1c7b37f09ed3ce3e5f843af02c2a2c431bae5b19230dad2c1b490" +dependencies = [ + "async-trait", + "deadpool-runtime", + "num_cpus", + "tokio", +] + +[[package]] +name = "deadpool-runtime" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63dfa964fe2a66f3fde91fc70b267fe193d822c7e603e2a675a49a7f46ad3f49" + [[package]] name = "der" version = "0.7.8" @@ -377,15 +395,6 @@ dependencies = [ "serde", ] -[[package]] -name = "encoding_rs" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" -dependencies = [ - "cfg-if", -] - [[package]] name = "env_logger" version = "0.7.1" @@ -467,21 +476,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.1" @@ -491,6 +485,21 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.30" @@ -535,6 +544,17 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "futures-sink" version = "0.3.30" @@ -553,8 +573,10 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ + "futures-channel", "futures-core", "futures-io", + "futures-macro", "futures-sink", "futures-task", "memchr", @@ -765,18 +787,19 @@ dependencies = [ ] [[package]] -name = "hyper-tls" -version = "0.6.0" +name = "hyper-rustls" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ - "bytes", - "http-body-util", + "futures-util", + "http", "hyper", "hyper-util", - "native-tls", + "rustls 0.22.3", + "rustls-pki-types", "tokio", - "tokio-native-tls", + "tokio-rustls", "tower-service", ] @@ -1000,24 +1023,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "nom" version = "7.1.3" @@ -1116,50 +1121,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "openssl" -version = "0.10.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" -dependencies = [ - "bitflags 2.5.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.55", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "overload" version = "0.1.1" @@ -1460,37 +1421,36 @@ checksum = "e333b1eb9fe677f6893a9efcb0d277a2d3edd83f358a236b657c32301dc6e5f6" dependencies = [ "base64", "bytes", - "encoding_rs", "futures-core", "futures-util", - "h2", "http", "http-body", "http-body-util", "hyper", - "hyper-tls", + "hyper-rustls", "hyper-util", "ipnet", "js-sys", "log", "mime", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", + "rustls 0.22.3", "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", - "tokio-native-tls", + "tokio-rustls", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots 0.26.1", "winreg", ] @@ -1555,10 +1515,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "ring", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.2", + "subtle", + "zeroize", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -1568,6 +1542,12 @@ dependencies = [ "base64", ] +[[package]] +name = "rustls-pki-types" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -1578,6 +1558,17 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustls-webpki" +version = "0.102.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -1590,15 +1581,6 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" -[[package]] -name = "schannel" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" -dependencies = [ - "windows-sys 0.52.0", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -1625,29 +1607,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "security-framework" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "serde" version = "1.0.197" @@ -1752,15 +1711,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - [[package]] name = "signature" version = "2.2.0" @@ -1873,7 +1823,7 @@ dependencies = [ "once_cell", "paste", "percent-encoding", - "rustls", + "rustls 0.21.10", "rustls-pemfile", "serde", "serde_json", @@ -1886,7 +1836,7 @@ dependencies = [ "tracing", "url", "uuid", - "webpki-roots", + "webpki-roots 0.25.4", ] [[package]] @@ -2082,27 +2032,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tempfile" version = "3.10.1" @@ -2202,11 +2131,10 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot", "pin-project-lite", - "signal-hook-registry", "socket2", "tokio-macros", + "tracing", "windows-sys 0.48.0", ] @@ -2222,12 +2150,13 @@ dependencies = [ ] [[package]] -name = "tokio-native-tls" -version = "0.3.1" +name = "tokio-rustls" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "native-tls", + "rustls 0.22.3", + "rustls-pki-types", "tokio", ] @@ -2646,6 +2575,15 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "webpki-roots" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "whoami" version = "1.5.1" @@ -2838,6 +2776,30 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "wiremock" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec874e1eef0df2dcac546057fe5e29186f09c378181cd7b635b4b7bcc98e9d81" +dependencies = [ + "assert-json-diff", + "async-trait", + "base64", + "deadpool", + "futures", + "http", + "http-body-util", + "hyper", + "hyper-util", + "log", + "once_cell", + "regex", + "serde", + "serde_json", + "tokio", + "url", +] + [[package]] name = "zero2prod" version = "0.1.0" @@ -2854,6 +2816,7 @@ dependencies = [ "secrecy", "serde", "serde-aux", + "serde_json", "sqlx", "tokio", "tower-http", @@ -2864,6 +2827,7 @@ dependencies = [ "unicode-segmentation", "uuid", "validator", + "wiremock", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0ea349e..e51580f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,12 @@ sqlx = { version = "0.7", default-features = false, features = [ "chrono", "migrate", ] } -tokio = { version = "1.36", features = ["full"] } +tokio = { version = "1.36", features = [ + "rt", + "macros", + "tracing", + "rt-multi-thread", +] } uuid = { version = "1.8", features = ["v4", "serde"] } tracing = { version = "0.1", features = ["log"] } tracing-subscriber = { version = "0.3", features = ["registry", "env-filter"] } @@ -39,13 +44,18 @@ serde-aux = "4" unicode-segmentation = "1" claims = "0.7" validator = "0.16" +reqwest = { version = "0.12", default-features = false, features = [ + "json", + "rustls-tls", +] } [dev-dependencies] -reqwest = "0.12" once_cell = "1.19" fake = "~2.3" quickcheck = "0.9" quickcheck_macros = "0.9" +wiremock = "0.6" +serde_json = "1" [package.metadata.clippy] warn = [ diff --git a/config/base.toml b/config/base.toml index dfb02df..d0beb30 100644 --- a/config/base.toml +++ b/config/base.toml @@ -7,3 +7,8 @@ port = 5432 username = "postgres" password = "password" database_name = "newsletter" + +[email_client] +base_url = "localhost" +sender_email = "test@gmail.com" +auth_token = "super-secret-token" diff --git a/config/production.toml b/config/production.toml index 9775701..c980dc6 100644 --- a/config/production.toml +++ b/config/production.toml @@ -3,3 +3,7 @@ host = "0.0.0.0" [database] require_ssl = true + +[email_client] +base_url = "localhost" +sender_email = "zero2prod@kristofers.xyz" # FIX: swap to postmark diff --git a/src/config.rs b/src/config.rs index e12c04f..01e43fa 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,10 +8,13 @@ use sqlx::{ ConnectOptions, }; +use crate::domain::SubscriberEmail; + #[derive(Debug, Deserialize)] pub struct Settings { pub database: DatabaseSettings, pub application: ApplicationSettings, + pub email_client: EmailClientSettings, } #[derive(Debug, Deserialize)] @@ -37,6 +40,18 @@ pub enum Environment { Local, Production, } +#[derive(Debug, Deserialize)] +pub struct EmailClientSettings { + pub base_url: String, + pub sender_email: String, + pub auth_token: Secret, +} + +impl EmailClientSettings { + pub fn sender(&self) -> Result { + self.sender_email.clone().try_into() + } +} pub fn get_config() -> Result { let base_path = std::env::current_dir().expect("Failed to determine current directory"); diff --git a/src/domain/subscriber_email.rs b/src/domain/subscriber_email.rs index d99bcfd..47c6d58 100644 --- a/src/domain/subscriber_email.rs +++ b/src/domain/subscriber_email.rs @@ -2,7 +2,7 @@ use std::str::FromStr; use validator::validate_email; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct SubscriberEmail(String); impl TryFrom for SubscriberEmail { diff --git a/src/email_client.rs b/src/email_client.rs new file mode 100644 index 0000000..ac125c1 --- /dev/null +++ b/src/email_client.rs @@ -0,0 +1,121 @@ +use reqwest::{Client, Url}; +use secrecy::{ExposeSecret, Secret}; +use serde::Serialize; + +use crate::domain::SubscriberEmail; + +#[derive(Debug, Clone)] +pub struct EmailClient { + http_client: Client, + base_url: String, + sender: SubscriberEmail, + auth_token: Secret, +} + +impl EmailClient { + pub fn new(base_url: String, sender: SubscriberEmail, auth_token: Secret) -> Self { + Self { + http_client: Client::new(), + base_url, + sender, + auth_token, + } + } + pub async fn send_email( + &self, + recipient: SubscriberEmail, + subject: &str, + html_content: &str, + text_content: &str, + ) -> Result<(), reqwest::Error> { + let url = Url::parse(&self.base_url) + .and_then(|path| path.join("email")) + .unwrap(); + let request_body = SendEmailRequest { + from: self.sender.as_ref().to_owned(), + to: recipient.as_ref().to_owned(), + subject: subject.to_owned(), + html_body: html_content.to_owned(), + text_body: text_content.to_owned(), + }; + let builder = self + .http_client + .post(url) + .header("X-Postmark-Server-Token", self.auth_token.expose_secret()) + .json(&request_body) + .send() + .await?; + Ok(()) + } +} + +#[derive(Serialize)] +#[serde(rename_all = "PascalCase")] +struct SendEmailRequest { + from: String, + to: String, + subject: String, + html_body: String, + text_body: String, +} + +#[cfg(test)] +mod tests { + + use fake::{ + faker::{ + internet::en::SafeEmail, + lorem::en::{Paragraph, Sentence}, + }, + Fake, Faker, + }; + use serde_json; + use wiremock::{ + matchers::{header, header_exists, method, path}, + Match, Mock, MockServer, ResponseTemplate, + }; + + struct SendEmailBodyMatcher; + + impl Match for SendEmailBodyMatcher { + fn matches(&self, request: &wiremock::Request) -> bool { + match serde_json::from_slice::(&request.body) { + Err(_) => false, + Ok(body) => { + dbg!(&body); + body.get("From").is_some() + && body.get("To").is_some() + && body.get("Subject").is_some() + && body.get("HtmlBody").is_some() + && body.get("TextBody").is_some() + } + } + } + } + + use super::*; + #[tokio::test] + async fn send_email_sends_the_expectred_request() { + let mock_server = MockServer::start().await; + let sender = SafeEmail().fake::().try_into().unwrap(); + let email_client = EmailClient::new(mock_server.uri(), sender, Secret::new(Faker.fake())); + + Mock::given(header_exists("X-Postmark-Server-Token")) + .and(header("Content-Type", "application/json")) + .and(path("/email")) + .and(method("POST")) + .and(SendEmailBodyMatcher) + .respond_with(ResponseTemplate::new(200)) + .expect(1) + .mount(&mock_server) + .await; + + let subscriber_email = SafeEmail().fake::().try_into().unwrap(); + let subject = Sentence(1..2).fake::(); + dbg!(&subject); + let content = Paragraph(1..10).fake::(); + let _ = email_client + .send_email(subscriber_email, &subject, &content, &content) + .await; + } +} diff --git a/src/lib.rs b/src/lib.rs index f24afc4..208a42f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ pub mod config; pub mod domain; +pub mod email_client; pub mod routes; pub mod telemetry; diff --git a/src/main.rs b/src/main.rs index 18482d2..7cabb06 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use sqlx::postgres::PgPoolOptions; use tokio::net::TcpListener; use zero2prod::{ config::get_config, + email_client::EmailClient, routes::route, telemetry::{get_subscriber, init_subscriber}, }; @@ -17,5 +18,15 @@ async fn main() -> Result<(), std::io::Error> { .await .expect("Failed to bind port 8000."); - axum::serve(listener, route(pool)).await + let sender_email = config + .email_client + .sender() + .expect("Invalid sender email adress"); + let email_client = EmailClient::new( + config.email_client.base_url, + sender_email, + config.email_client.auth_token, + ); + + axum::serve(listener, route(pool, email_client)).await } diff --git a/src/routes/mod.rs b/src/routes/mod.rs index afb985f..f4e7633 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -19,11 +19,14 @@ use tower_http::{classify::ServerErrorsFailureClass, trace::TraceLayer}; use tracing::{info_span, Span}; use uuid::Uuid; -pub fn route(state: PgPool) -> Router { +use crate::email_client::EmailClient; + +pub fn route(pool: PgPool, email_client: EmailClient) -> Router { Router::new() .route("/health_check", get(health_check)) .route("/subscriptions", post(subscribe)) - .with_state(state) + .with_state(pool) + .with_state(email_client) .layer( TraceLayer::new_for_http() .make_span_with(|request: &Request<_>| { diff --git a/src/routes/subscibtions.rs b/src/routes/subscibtions.rs index 2e17737..b00acd6 100644 --- a/src/routes/subscibtions.rs +++ b/src/routes/subscibtions.rs @@ -5,7 +5,7 @@ use sqlx::PgPool; use tracing::error; use uuid::Uuid; -use crate::domain::{NewSubscriber, SubscriberEmail, SubscriberName}; +use crate::domain::NewSubscriber; #[derive(Deserialize)] pub struct FormData { diff --git a/tests/health_check.rs b/tests/health_check.rs index fc110a3..bcb74a8 100644 --- a/tests/health_check.rs +++ b/tests/health_check.rs @@ -5,6 +5,7 @@ use tokio::net::TcpListener; use uuid::Uuid; use zero2prod::{ config::{get_config, DatabaseSettings}, + email_client::EmailClient, routes::route, telemetry::{get_subscriber, init_subscriber}, }; @@ -140,8 +141,19 @@ async fn spawn_app() -> TestApp { let pool = configure_database(&config.database).await; let pool_clone = pool.clone(); + + let sender_email = config + .email_client + .sender() + .expect("Invalid sender email adress"); + let email_client = EmailClient::new( + config.email_client.base_url, + sender_email, + config.email_client.auth_token, + ); + let _ = tokio::spawn(async move { - axum::serve(listener, route(pool_clone)) + axum::serve(listener, route(pool_clone, email_client)) .await .expect("Failed to bind address.") });