tests for link in email & subscription status

This commit is contained in:
Andre Heber
2024-02-26 21:25:26 +01:00
parent ff0fb28e4b
commit f4f16d621d
7 changed files with 133 additions and 12 deletions

View File

@ -7,7 +7,7 @@ use lettre::{
address::AddressError, message::{header::ContentType, Mailbox}, transport::smtp::authentication::Credentials, Message, SmtpTransport, Transport
};
use crate::domain::{NewSubscriber, SubscriberEmail, SubscriberName};
use crate::{domain::{NewSubscriber, SubscriberEmail, SubscriberName}, email_client::EmailClient};
#[derive(Deserialize)]
pub struct FormData {
@ -17,13 +17,17 @@ pub struct FormData {
#[tracing::instrument(
name = "Adding a new subscriber",
skip(form, connection_pool),
skip(form, connection_pool, email_client),
fields(
subscriber_email = %form.email,
subscriber_name = %form.name
)
)]
pub async fn subscribe(form: web::Form<FormData>, connection_pool: web::Data<Pool<Postgres>>) -> HttpResponse {
pub async fn subscribe(
form: web::Form<FormData>,
connection_pool: web::Data<Pool<Postgres>>,
email_client: web::Data<EmailClient>,
) -> HttpResponse {
let new_subscriber = match form.0.try_into() {
Ok(subscriber) => subscriber,
Err(_) => return HttpResponse::BadRequest().finish(),
@ -32,11 +36,39 @@ pub async fn subscribe(form: web::Form<FormData>, connection_pool: web::Data<Poo
Ok(_) => (),
Err(_) => return HttpResponse::InternalServerError().finish(),
}
match send_mail(&new_subscriber) {
Ok(_) => HttpResponse::Ok().finish(),
Err(_) => HttpResponse::InternalServerError().finish(),
if send_confirmation_email(&email_client, new_subscriber).await.is_err() {
return HttpResponse::InternalServerError().finish();
}
HttpResponse::Ok().finish()
}
#[tracing::instrument(
name = "Send a confirmation email to the new subscriber",
skip(email_client, new_subscriber)
)]
pub async fn send_confirmation_email(
email_client: &EmailClient,
new_subscriber: NewSubscriber,
) -> Result<(), reqwest::Error> {
let confirmation_link = "https://my-api.com/subscriptions/confirm";
let plain_body = &format!(
"Welcome to our newsletter!\n\
Visit {} to confirm your subscription.",
confirmation_link
);
let html_body = &format!(
"Welcome to our newsletter!<br />\
Click <a href=\"{}\">here</a> to confirm your subscription.",
confirmation_link
);
email_client
.send_email(
new_subscriber.email,
"Welcome!",
html_body,
plain_body,
)
.await
}
#[tracing::instrument(
@ -105,7 +137,7 @@ async fn insert_subscriber(new_subscriber: &NewSubscriber, connection_pool: &Poo
query!(
r#"
INSERT INTO subscriptions (id, email, name, subscribed_at, status)
VALUES ($1, $2, $3, $4, 'confirmed')
VALUES ($1, $2, $3, $4, 'pending_confirmation')
"#,
Uuid::new_v4(),
new_subscriber.email.as_ref(),

View File

@ -48,8 +48,8 @@ impl Application {
timeout,
);
let port = config.application.port;
let listener = TcpListener::bind(format!("{}:{}", config.application.host, port))?;
let listener = TcpListener::bind(format!("{}:{}", config.application.host, config.application.port))?;
let port = listener.local_addr().unwrap().port();
let server = run(listener, connection_pool, email_client)?;
Ok(Self { port, server })
}