diff --git a/src/routes/subscriptions.rs b/src/routes/subscriptions.rs index 49b2099..434cdfc 100644 --- a/src/routes/subscriptions.rs +++ b/src/routes/subscriptions.rs @@ -29,10 +29,28 @@ async fn subscribe(State(app_state): State, Form(form): Form } }; - match insert_subscriber(&new_subscriber, &app_state.db_pool).await { - Ok(_) => StatusCode::OK, - Err(_) => StatusCode::INTERNAL_SERVER_ERROR, + if insert_subscriber(&new_subscriber, &app_state.db_pool) + .await + .is_err() + { + return StatusCode::INTERNAL_SERVER_ERROR; } + + if app_state + .email_client + .send_email( + new_subscriber.email, + "Welcome!", + "Welcome to our newsletter!", + "Welcome to our newsletter!", + ) + .await + .is_err() + { + return StatusCode::INTERNAL_SERVER_ERROR; + } + + StatusCode::OK } #[tracing::instrument( diff --git a/tests/api/helpers.rs b/tests/api/helpers.rs index ed93556..7de15fc 100644 --- a/tests/api/helpers.rs +++ b/tests/api/helpers.rs @@ -3,6 +3,7 @@ use reqwest::{Client, Response}; use sqlx::{Connection, Executor, PgConnection, PgPool}; use std::net::SocketAddr; use uuid::Uuid; +use wiremock::MockServer; use zero2prod::{ configuration::{get_configuration, DatabaseSettings}, startup::{get_connection_pool, Application}, @@ -26,6 +27,7 @@ static FAILED_TO_EXECUTE_REQUEST: &'static str = "Failed to execute request"; pub struct TestApp { pub address: SocketAddr, pub db_pool: PgPool, + pub email_server: MockServer, client: Client, } @@ -38,6 +40,9 @@ impl TestApp { config.application.port = 0; let db_pool = configure_database(&config.database).await; + let email_server = MockServer::start().await; + config.email_client.base_url = email_server.uri(); + let app = Application::build(config).await; let address = app.local_addr(); @@ -46,6 +51,7 @@ impl TestApp { Self { address, db_pool, + email_server, client: Client::new(), } } diff --git a/tests/api/subscriptions.rs b/tests/api/subscriptions.rs index bfb6ada..9c97410 100644 --- a/tests/api/subscriptions.rs +++ b/tests/api/subscriptions.rs @@ -1,3 +1,8 @@ +use wiremock::{ + matchers::{method, path}, + Mock, ResponseTemplate, +}; + use crate::helpers::TestApp; #[tokio::test] @@ -6,6 +11,12 @@ async fn subscribe_returns_a_200_for_valid_form_data() { let app = TestApp::spawn().await; let body = "name=Imi%C4%99%20Nazwisko&email=imie.nazwisko%40example.com"; + Mock::given(path("/email")) + .and(method("POST")) + .respond_with(ResponseTemplate::new(200)) + .mount(&app.email_server) + .await; + // when let response = app.post_subscriptions(body.into()).await; @@ -75,3 +86,22 @@ async fn subscribe_returns_a_400_when_data_is_missing() { assert!(saved.is_none()); } } + +#[tokio::test] +async fn subscribe_sends_a_confirmation_email_for_valid_data() { + // given + let app = TestApp::spawn().await; + let body = "name=Imi%C4%99%20Nazwisko&email=imie.nazwisko%40example.com"; + + Mock::given(path("/email")) + .and(method("POST")) + .respond_with(ResponseTemplate::new(200)) + .expect(1) + .mount(&app.email_server) + .await; + + // when + app.post_subscriptions(body.into()).await; + + // then assert +}